From 2fa521c3d15a2e2fd733a8346e30d46cbaa3d889 Mon Sep 17 00:00:00 2001 From: Sen Date: Sun, 4 May 2025 20:27:55 +0200 Subject: [PATCH 001/200] split client and server 1 --- java/src/{game => client}/Game.java | 108 +++--- .../{game/util => client}/PerfSection.java | 4 +- .../network => client}/PlayerController.java | 6 +- .../{game/util => client}/SkinConverter.java | 2 +- java/src/{game/util => client}/Timing.java | 2 +- .../audio/AudioInterface.java | 3 +- .../{game => client}/audio/CodecJOrbis.java | 19 +- .../{game => client}/audio/SoundManager.java | 60 ++- java/src/{game => client}/audio/Volume.java | 32 +- .../{game => client}/audio/jogg/Buffer.java | 2 +- .../{game => client}/audio/jogg/Packet.java | 2 +- .../src/{game => client}/audio/jogg/Page.java | 2 +- .../audio/jogg/StreamState.java | 2 +- .../audio/jogg/SyncState.java | 2 +- .../{game => client}/audio/jorbis/Block.java | 5 +- .../audio/jorbis/ChainingExample.java | 2 +- .../audio/jorbis/CodeBook.java | 4 +- .../audio/jorbis/Comment.java | 5 +- .../audio/jorbis/DecodeExample.java | 7 +- .../{game => client}/audio/jorbis/Drft.java | 2 +- .../audio/jorbis/DspState.java | 2 +- .../{game => client}/audio/jorbis/Floor0.java | 4 +- .../{game => client}/audio/jorbis/Floor1.java | 4 +- .../audio/jorbis/FuncFloor.java | 4 +- .../audio/jorbis/FuncMapping.java | 4 +- .../audio/jorbis/FuncResidue.java | 4 +- .../audio/jorbis/FuncTime.java | 4 +- .../{game => client}/audio/jorbis/Info.java | 5 +- .../audio/jorbis/InfoMode.java | 2 +- .../audio/jorbis/JOrbisException.java | 2 +- .../{game => client}/audio/jorbis/Lookup.java | 2 +- .../{game => client}/audio/jorbis/Lpc.java | 2 +- .../{game => client}/audio/jorbis/Lsp.java | 2 +- .../audio/jorbis/Mapping0.java | 4 +- .../{game => client}/audio/jorbis/Mdct.java | 2 +- .../audio/jorbis/PsyInfo.java | 2 +- .../audio/jorbis/PsyLook.java | 2 +- .../audio/jorbis/Residue0.java | 4 +- .../audio/jorbis/Residue1.java | 2 +- .../audio/jorbis/Residue2.java | 2 +- .../audio/jorbis/StaticCodeBook.java | 4 +- .../{game => client}/audio/jorbis/Time0.java | 4 +- .../{game => client}/audio/jorbis/Util.java | 2 +- .../audio/jorbis/VorbisFile.java | 12 +- .../util => client/gui}/FileCallback.java | 2 +- java/src/{game => client}/gui/Font.java | 6 +- java/src/{game => client}/gui/FontChar.java | 2 +- .../{game/util => client/gui}/Formatter.java | 4 +- java/src/{game => client}/gui/Gui.java | 21 +- java/src/{game => client}/gui/GuiConfirm.java | 10 +- java/src/{game => client}/gui/GuiConnect.java | 15 +- java/src/{game => client}/gui/GuiConsole.java | 17 +- java/src/{game => client}/gui/GuiConvert.java | 18 +- java/src/{game => client}/gui/GuiInfo.java | 6 +- java/src/{game => client}/gui/GuiLoading.java | 8 +- java/src/{game => client}/gui/GuiMenu.java | 25 +- java/src/{game => client}/gui/GuiServer.java | 14 +- .../{game/util => client/gui}/Splashes.java | 2 +- java/src/{game => client}/gui/Style.java | 6 +- .../gui/character/GuiChar.java | 53 +-- .../gui/character/GuiCharacters.java | 20 +- .../gui/character/GuiClass.java | 14 +- .../gui/character/GuiSpecies.java | 14 +- .../gui/container/GuiBrewing.java | 2 +- .../gui/container/GuiChest.java | 4 +- .../gui/container/GuiContainer.java | 17 +- .../gui/container/GuiCrafting.java | 2 +- .../gui/container/GuiDispenser.java | 2 +- .../gui/container/GuiEnchant.java | 2 +- .../gui/container/GuiFurnace.java | 2 +- .../gui/container/GuiHopper.java | 4 +- .../gui/container/GuiHorse.java | 4 +- .../gui/container/GuiInventory.java | 2 +- .../gui/container/GuiMachine.java | 4 +- .../gui/container/GuiMerchant.java | 6 +- .../gui/container/GuiRepair.java | 4 +- .../gui/element/ActButton.java | 6 +- .../src/{game => client}/gui/element/Bar.java | 4 +- .../gui/element/Dropdown.java | 12 +- .../{game => client}/gui/element/Element.java | 22 +- .../{game => client}/gui/element/Fill.java | 6 +- .../{game => client}/gui/element/GuiList.java | 17 +- .../gui/element/InventoryButton.java | 4 +- .../{game => client}/gui/element/Label.java | 4 +- .../gui/element/ListEntry.java | 2 +- .../gui/element/NavButton.java | 8 +- .../gui/element/SelectableButton.java | 4 +- .../{game => client}/gui/element/Slider.java | 8 +- .../{game => client}/gui/element/Switch.java | 6 +- .../{game => client}/gui/element/Textbox.java | 18 +- .../{game => client}/gui/element/Toggle.java | 8 +- .../gui/element/TransparentBox.java | 4 +- .../gui/ingame/GuiGameOver.java | 10 +- .../{game => client}/gui/ingame/GuiSign.java | 10 +- .../gui/options/GuiBinds.java | 12 +- .../gui/options/GuiDisplay.java | 20 +- .../gui/options/GuiOptions.java | 8 +- .../gui/options/GuiSound.java | 8 +- .../gui/options/GuiStyle.java | 24 +- .../src/client/init/EntityRenderRegistry.java | 157 ++++++++ .../renderer/ActiveRenderInfo.java | 2 +- .../renderer/BlockRenderer.java | 21 +- .../renderer/DefaultVertexFormats.java | 2 +- .../{game => client}/renderer/Drawing.java | 8 +- .../renderer/EntityRenderer.java | 16 +- .../{game => client}/renderer/Frustum.java | 2 +- .../{game => client}/renderer/GlState.java | 2 +- .../renderer/ItemModelMesher.java | 10 +- .../renderer/ItemRenderer.java | 17 +- .../{game => client}/renderer/Project.java | 2 +- .../renderer/RegionRenderCache.java | 2 +- .../renderer/RegionRenderCacheBuilder.java | 4 +- .../renderer/RenderBuffer.java | 2 +- .../renderer/RenderGlobal.java | 33 +- .../renderer/Tessellator.java | 2 +- .../renderer/VertexBuffer.java | 2 +- .../renderer/VertexFormat.java | 3 +- .../renderer/VertexFormatElement.java | 2 +- .../renderer/ViewFrustum.java | 4 +- .../renderer/blockmodel}/BakedModel.java | 10 +- .../renderer/blockmodel/BakedQuad.java | 2 +- .../renderer/blockmodel/BlockFaceUV.java | 2 +- .../renderer/blockmodel/BlockPart.java | 6 +- .../renderer/blockmodel/BlockPartFace.java | 4 +- .../blockmodel/BlockPartRotation.java | 4 +- .../renderer/blockmodel/BreakingFour.java | 4 +- .../renderer/blockmodel}/BuiltInModel.java | 7 +- .../renderer/blockmodel/FaceBakery.java | 10 +- .../renderer/blockmodel}/IBakedModel.java | 7 +- .../renderer/blockmodel}/ModelBakery.java | 27 +- .../renderer/blockmodel/ModelBlock.java | 203 +++++++++++ .../renderer/blockmodel/ModelGenerator.java | 13 +- .../renderer/blockmodel}/ModelManager.java | 12 +- .../renderer/blockmodel/MultiStateMap.java | 3 +- .../renderer/blockmodel/SingleStateMap.java | 2 +- .../renderer/blockmodel/StateMap.java | 5 +- .../chunk/ChunkCompileTaskGenerator.java | 5 +- .../renderer/chunk/ChunkRenderDispatcher.java | 13 +- .../renderer/chunk/ChunkRenderWorker.java | 11 +- .../renderer/chunk/CompiledChunk.java | 7 +- .../renderer/chunk/RenderChunk.java | 25 +- .../renderer/chunk/SetVisibility.java | 2 +- .../renderer/chunk/VisGraph.java | 2 +- .../renderer/entity/Render.java | 20 +- .../renderer/entity/RenderArachnoid.java | 6 +- .../renderer/entity/RenderArrow.java | 10 +- .../renderer/entity/RenderBat.java | 4 +- .../renderer/entity/RenderBlockEntity.java | 8 +- .../renderer/entity/RenderBoat.java | 6 +- .../renderer/entity/RenderBullet.java | 10 +- .../renderer/entity/RenderChicken.java | 4 +- .../renderer/entity/RenderCow.java | 4 +- .../renderer/entity/RenderCrystal.java | 6 +- .../renderer/entity/RenderDie.java | 10 +- .../renderer/entity/RenderDragon.java | 8 +- .../renderer/entity/RenderDynamite.java | 2 +- .../renderer/entity/RenderEntity.java | 2 +- .../renderer/entity/RenderEntityItem.java | 14 +- .../renderer/entity/RenderFallingBlock.java | 18 +- .../renderer/entity/RenderFireball.java | 16 +- .../renderer/entity/RenderFish.java | 14 +- .../renderer/entity/RenderFlyingBox.java | 6 +- .../renderer/entity/RenderHorse.java | 9 +- .../renderer/entity/RenderHumanoid.java | 22 +- .../renderer/entity/RenderItem.java | 43 ++- .../renderer/entity/RenderItemEntity.java | 8 +- .../renderer/entity/RenderLeashKnot.java | 6 +- .../renderer/entity/RenderLightning.java | 10 +- .../renderer/entity/RenderLiving.java | 14 +- .../renderer/entity/RenderManager.java | 21 +- .../renderer/entity/RenderMinecart.java | 12 +- .../renderer/entity/RenderMooshroom.java | 6 +- .../renderer/entity/RenderMouse.java | 4 +- .../renderer/entity/RenderNpc.java | 6 +- .../renderer/entity/RenderOcelot.java | 4 +- .../renderer/entity/RenderPig.java | 6 +- .../renderer/entity/RenderPotion.java | 2 +- .../renderer/entity/RenderRabbit.java | 4 +- .../renderer/entity/RenderSheep.java | 6 +- .../renderer/entity/RenderSlime.java | 6 +- .../renderer/entity/RenderSpaceMarine.java | 8 +- .../renderer/entity/RenderSquid.java | 4 +- .../renderer/entity/RenderTntMinecart.java | 8 +- .../renderer/entity/RenderTntPrimed.java | 10 +- .../renderer/entity/RenderWolf.java | 8 +- .../renderer/entity/RenderXpOrb.java | 10 +- .../renderer/entity/RendererLivingEntity.java | 19 +- .../renderer/layers/LayerArachnoidArmor.java | 6 +- .../renderer/layers/LayerArmor.java | 10 +- .../renderer/layers/LayerArrow.java | 10 +- .../renderer/layers/LayerCape.java | 8 +- .../renderer/layers/LayerCharge.java | 8 +- .../renderer/layers/LayerEnderDragonEyes.java | 6 +- .../renderer/layers/LayerEntityBreak.java | 12 +- .../renderer/layers/LayerExtra.java | 15 +- .../renderer/layers/LayerHeldItem.java | 10 +- .../layers/LayerMooshroomMushroom.java | 14 +- .../renderer/layers/LayerPowerRods.java | 8 +- .../renderer/layers/LayerRenderer.java | 2 +- .../renderer/layers/LayerSaddle.java | 6 +- .../renderer/layers/LayerSheepWool.java | 8 +- .../renderer/layers/LayerSlimeGel.java | 10 +- .../renderer/layers/LayerWolfCollar.java | 6 +- .../renderer/model/ModelArachnoid.java | 2 +- .../renderer/model/ModelArmor.java | 2 +- .../renderer/model/ModelBanner.java | 2 +- .../renderer/model/ModelBase.java | 3 +- .../renderer/model/ModelBat.java | 2 +- .../renderer/model/ModelBiped.java | 2 +- .../renderer/model/ModelBoat.java | 2 +- .../renderer/model/ModelBox.java | 4 +- .../renderer/model/ModelCharge.java | 2 +- .../renderer/model/ModelChest.java | 2 +- .../renderer/model/ModelChicken.java | 2 +- .../renderer/model/ModelCow.java | 2 +- .../renderer/model/ModelCrystal.java | 2 +- .../renderer/model/ModelDie.java | 2 +- .../renderer/model/ModelDragon.java | 4 +- .../renderer/model/ModelHead.java | 2 +- .../renderer/model/ModelHorse.java | 2 +- .../renderer/model/ModelHumanoid.java | 2 +- .../renderer/model/ModelHumanoidHead.java | 2 +- .../renderer/model/ModelLargeChest.java | 2 +- .../renderer/model/ModelLeashKnot.java | 2 +- .../renderer/model/ModelMinecart.java | 2 +- .../renderer/model/ModelMouse.java | 2 +- .../renderer/model/ModelOcelot.java | 2 +- .../renderer/model/ModelPig.java | 2 +- .../renderer/model/ModelQuadruped.java | 2 +- .../renderer/model/ModelRabbit.java | 2 +- .../renderer/model/ModelRenderer.java | 7 +- .../renderer/model/ModelSheep1.java | 2 +- .../renderer/model/ModelSheep2.java | 2 +- .../renderer/model/ModelSign.java | 2 +- .../renderer/model/ModelSlime.java | 2 +- .../renderer/model/ModelSpaceMarine.java | 2 +- .../renderer/model/ModelSquid.java | 2 +- .../renderer/model/ModelWolf.java | 2 +- .../renderer/model/PositionTextureVertex.java | 2 +- .../renderer/model/TextureOffset.java | 2 +- .../renderer/model/TexturedQuad.java | 16 +- .../renderer/particle/EffectRenderer.java | 20 +- .../renderer/particle/EntityAuraFX.java | 2 +- .../renderer/particle/EntityBlockDustFX.java | 2 +- .../renderer/particle/EntityBreakingFX.java | 6 +- .../renderer/particle/EntityBubbleFX.java | 2 +- .../renderer/particle/EntityCloudFX.java | 4 +- .../renderer/particle/EntityCrit2FX.java | 4 +- .../renderer/particle/EntityCritFX.java | 2 +- .../renderer/particle/EntityDiggingFX.java | 6 +- .../renderer/particle/EntityDownfallFX.java | 2 +- .../particle/EntityDropParticleFX.java | 3 +- .../EntityEnchantmentTableParticleFX.java | 2 +- .../renderer/particle/EntityExplodeFX.java | 2 +- .../renderer/particle/EntityFX.java | 8 +- .../renderer/particle/EntityFirework.java | 6 +- .../renderer/particle/EntityFishWakeFX.java | 2 +- .../renderer/particle/EntityFlameFX.java | 4 +- .../renderer/particle/EntityFootStepFX.java | 14 +- .../renderer/particle/EntityHeartFX.java | 4 +- .../particle/EntityHugeExplodeFX.java | 5 +- .../particle/EntityLargeExplodeFX.java | 18 +- .../renderer/particle/EntityLavaFX.java | 5 +- .../renderer/particle/EntityNoteFX.java | 4 +- .../particle/EntityParticleEmitter.java | 5 +- .../renderer/particle/EntityPickupFX.java | 10 +- .../renderer/particle/EntityPortalFX.java | 4 +- .../renderer/particle/EntityReddustFX.java | 4 +- .../renderer/particle/EntitySmokeFX.java | 4 +- .../renderer/particle/EntitySnowShovelFX.java | 4 +- .../particle/EntitySpellParticleFX.java | 4 +- .../renderer/particle/EntitySplashFX.java | 2 +- .../renderer/particle/EntitySuspendFX.java | 2 +- .../renderer/particle/IParticleFactory.java | 2 +- .../renderer/texture/DynamicTexture.java | 4 +- .../renderer/texture/EntityTexManager.java | 9 +- .../renderer/texture/IIconCreator.java | 2 +- .../texture/LayeredColorMaskTexture.java | 2 +- .../renderer/texture/LayeredTexture.java | 3 +- .../renderer/texture/SimpleTexture.java | 2 +- .../renderer/texture/Stitcher.java | 2 +- .../renderer/texture/Texture.java | 4 +- .../renderer/texture/TextureAtlasSprite.java | 2 +- .../renderer/texture/TextureManager.java | 5 +- .../renderer/texture/TextureMap.java | 7 +- .../renderer/texture/TextureTicked.java | 2 +- .../renderer/texture/TextureUtil.java | 4 +- .../renderer/ticked/TextureFlamesFX1.java | 4 +- .../renderer/ticked/TextureFlamesFX2.java | 2 +- .../renderer/ticked/TextureLavaFX.java | 4 +- .../renderer/ticked/TextureLavaFlowFX.java | 4 +- .../renderer/ticked/TextureWaterFX.java | 4 +- .../renderer/ticked/TextureWaterFlowFX.java | 4 +- .../tileentity/TileEntityBannerRenderer.java | 11 +- .../tileentity/TileEntityChestRenderer.java | 8 +- .../TileEntityItemStackRenderer.java | 4 +- .../TileEntityMobSpawnerRenderer.java | 4 +- .../tileentity/TileEntityPistonRenderer.java | 18 +- .../TileEntityRendererDispatcher.java | 7 +- .../tileentity/TileEntitySignRenderer.java | 10 +- .../tileentity/TileEntitySkullRenderer.java | 6 +- .../tileentity/TileEntitySpecialRenderer.java | 4 +- java/src/{game => client}/window/Bind.java | 10 +- java/src/{game => client}/window/Button.java | 4 +- .../{game => client}/window/DisplayMode.java | 2 +- java/src/client/window/Input.java | 8 + .../src/{game => client}/window/KeyEvent.java | 2 +- java/src/{game => client}/window/Keysym.java | 2 +- java/src/{game => client}/window/Wheel.java | 4 +- java/src/{game => client}/window/Window.java | 51 ++- .../{game => client}/window/WindowAction.java | 2 +- .../{game => client}/window/WindowEvent.java | 2 +- java/src/game/ai/EntityAIAvoidEntity.java | 3 +- java/src/game/ai/EntityAIEatGrass.java | 2 +- .../game/ai/EntityAIFindEntityNearest.java | 1 - java/src/game/ai/EntityAIMate.java | 2 +- .../game/ai/EntityAIMoveThroughVillage.java | 1 - .../ai/EntityAINearestAttackableTarget.java | 1 - java/src/game/ai/EntityAITakePlace.java | 3 +- java/src/game/ai/EntitySenses.java | 1 - java/src/game/biome/Biome.java | 5 +- java/src/game/block/Block.java | 15 +- java/src/game/block/BlockAnvil.java | 9 +- java/src/game/block/BlockBanner.java | 2 +- .../game/block/BlockBasePressurePlate.java | 9 +- java/src/game/block/BlockBeacon.java | 9 +- java/src/game/block/BlockBed.java | 15 +- java/src/game/block/BlockBedrock.java | 2 +- java/src/game/block/BlockBlackenedSoil.java | 7 +- java/src/game/block/BlockBlueShroom.java | 7 +- java/src/game/block/BlockBookshelf.java | 7 +- java/src/game/block/BlockBrewingStand.java | 27 +- java/src/game/block/BlockBush.java | 2 +- java/src/game/block/BlockButton.java | 10 +- java/src/game/block/BlockCactus.java | 9 +- java/src/game/block/BlockCake.java | 25 +- java/src/game/block/BlockCarpet.java | 9 +- java/src/game/block/BlockCarrot.java | 7 +- java/src/game/block/BlockCauldron.java | 17 +- java/src/game/block/BlockCocoa.java | 15 +- java/src/game/block/BlockColored.java | 7 +- java/src/game/block/BlockCrops.java | 12 +- .../src/game/block/BlockDaylightDetector.java | 10 +- java/src/game/block/BlockDeadBush.java | 7 +- java/src/game/block/BlockDirt.java | 17 +- java/src/game/block/BlockDispenser.java | 9 +- java/src/game/block/BlockDoor.java | 22 +- java/src/game/block/BlockDoublePlant.java | 18 +- java/src/game/block/BlockDragonEgg.java | 9 +- java/src/game/block/BlockDryLeaves.java | 1 - .../src/game/block/BlockEnchantmentTable.java | 9 +- java/src/game/block/BlockFarmland.java | 7 +- java/src/game/block/BlockFence.java | 20 +- java/src/game/block/BlockFenceGate.java | 15 +- java/src/game/block/BlockFire.java | 144 ++++---- java/src/game/block/BlockFloorPortal.java | 10 +- java/src/game/block/BlockFlower.java | 14 +- java/src/game/block/BlockFlowerPot.java | 13 +- java/src/game/block/BlockFurnace.java | 9 +- java/src/game/block/BlockGlass.java | 2 +- java/src/game/block/BlockGrass.java | 11 +- java/src/game/block/BlockHopper.java | 12 +- java/src/game/block/BlockHugeMushroom.java | 35 +- java/src/game/block/BlockIce.java | 2 +- java/src/game/block/BlockJukebox.java | 7 +- java/src/game/block/BlockLadder.java | 9 +- java/src/game/block/BlockLeaves.java | 13 +- java/src/game/block/BlockLeavesBase.java | 2 +- java/src/game/block/BlockLever.java | 11 +- java/src/game/block/BlockLilyPad.java | 7 +- java/src/game/block/BlockLiquid.java | 4 +- java/src/game/block/BlockLog.java | 18 +- java/src/game/block/BlockMelon.java | 7 +- java/src/game/block/BlockMobSpawner.java | 2 +- java/src/game/block/BlockMushroom.java | 7 +- java/src/game/block/BlockMycelium.java | 11 +- java/src/game/block/BlockNote.java | 2 +- java/src/game/block/BlockNuke.java | 7 +- java/src/game/block/BlockPane.java | 41 ++- java/src/game/block/BlockPistonBase.java | 11 +- java/src/game/block/BlockPistonHead.java | 14 +- java/src/game/block/BlockPortal.java | 13 +- java/src/game/block/BlockPortalFrame.java | 9 +- java/src/game/block/BlockPotato.java | 7 +- java/src/game/block/BlockPumpkin.java | 7 +- java/src/game/block/BlockQuartz.java | 19 +- java/src/game/block/BlockRailBase.java | 20 +- java/src/game/block/BlockRailDetector.java | 8 +- java/src/game/block/BlockRailPowered.java | 7 +- .../game/block/BlockRedstoneComparator.java | 17 +- java/src/game/block/BlockRedstoneDiode.java | 2 +- java/src/game/block/BlockRedstoneOre.java | 9 +- .../src/game/block/BlockRedstoneRepeater.java | 47 +-- java/src/game/block/BlockRedstoneTorch.java | 3 +- java/src/game/block/BlockRedstoneWire.java | 100 ++--- java/src/game/block/BlockReed.java | 9 +- java/src/game/block/BlockRock.java | 7 +- java/src/game/block/BlockRotatedPillar.java | 11 +- java/src/game/block/BlockSand.java | 11 +- java/src/game/block/BlockSandStone.java | 15 +- java/src/game/block/BlockSapling.java | 8 +- java/src/game/block/BlockSkull.java | 2 +- java/src/game/block/BlockSlab.java | 64 ++-- java/src/game/block/BlockSlime.java | 9 +- java/src/game/block/BlockSnow.java | 11 +- java/src/game/block/BlockStainedGlass.java | 9 +- .../src/game/block/BlockStainedGlassPane.java | 2 +- java/src/game/block/BlockStairs.java | 19 +- java/src/game/block/BlockStem.java | 23 +- java/src/game/block/BlockStoneBrick.java | 11 +- java/src/game/block/BlockTNT.java | 7 +- java/src/game/block/BlockTallGrass.java | 13 +- java/src/game/block/BlockTianReactor.java | 7 +- java/src/game/block/BlockTianSoil.java | 9 +- java/src/game/block/BlockTorch.java | 13 +- java/src/game/block/BlockTrapDoor.java | 21 +- java/src/game/block/BlockTripWire.java | 55 +-- java/src/game/block/BlockTripWireHook.java | 21 +- java/src/game/block/BlockVine.java | 9 +- java/src/game/block/BlockWall.java | 23 +- java/src/game/block/BlockWarpChest.java | 9 +- java/src/game/block/BlockWart.java | 7 +- java/src/game/block/BlockWeb.java | 9 +- java/src/game/block/BlockWorkbench.java | 7 +- java/src/game/block/LeavesType.java | 4 +- java/src/game/{audio => block}/SoundType.java | 2 +- java/src/game/clipboard/ClipboardPlacer.java | 3 +- java/src/game/color/Colorizer.java | 2 +- java/src/game/color/DyeColor.java | 5 +- java/src/game/command/Command.java | 1 - java/src/game/command/CommandEnvironment.java | 19 +- java/src/game/command/FixedExecutor.java | 2 +- java/src/game/command/PlayerParser.java | 1 + java/src/game/command/WorldParser.java | 1 - .../game/command/commands/CommandAdmin.java | 4 +- .../game/command/commands/CommandHelp.java | 5 +- .../game/command/commands/CommandKick.java | 4 +- .../game/command/commands/CommandMessage.java | 2 +- .../game/command/commands/CommandMilk.java | 3 +- .../command/commands/CommandOfflinetp.java | 3 +- .../game/command/commands/CommandPotion.java | 3 +- .../game/command/commands/CommandRemove.java | 3 +- .../game/command/commands/CommandRevoke.java | 4 +- .../game/command/commands/CommandSpawn.java | 5 +- .../game/command/commands/CommandTele.java | 5 +- .../game/command/commands/CommandTime.java | 4 +- java/src/game/command/commands/CommandTp.java | 3 +- .../game/command/commands/CommandWarp.java | 3 +- .../game/command/commands/CommandWeather.java | 4 +- .../game/command/commands/CommandWorld.java | 3 +- java/src/game/dimension/Dimension.java | 5 +- java/src/game/dimension/Star.java | 1 - java/src/game/enchantment/Enchantment.java | 1 - .../game/enchantment/EnchantmentHelper.java | 1 - java/src/game/entity/DataWatcher.java | 1 - java/src/game/entity/Entity.java | 4 +- java/src/game/entity/EntityTrackerEntry.java | 1 - java/src/game/entity/animal/EntityDragon.java | 3 +- java/src/game/entity/animal/EntityHorse.java | 4 +- .../game/entity/animal/EntityMooshroom.java | 2 +- java/src/game/entity/animal/EntityRabbit.java | 2 +- java/src/game/entity/animal/EntitySheep.java | 3 +- java/src/game/entity/animal/EntityWolf.java | 2 +- .../src/game/entity/attributes/Attribute.java | 1 - java/src/game/entity/item/EntityBoat.java | 2 +- java/src/game/entity/item/EntityFalling.java | 3 +- .../src/game/entity/item/EntityFireworks.java | 2 +- .../game/entity/item/EntityHopperCart.java | 1 - java/src/game/entity/item/EntityItem.java | 2 +- java/src/game/entity/item/EntityNuke.java | 2 +- java/src/game/entity/item/EntityOrb.java | 2 +- java/src/game/entity/item/EntityTnt.java | 2 +- java/src/game/entity/item/EntityTntCart.java | 2 +- java/src/game/entity/item/EntityXp.java | 2 +- java/src/game/entity/npc/Alignment.java | 1 - .../game/entity/npc/EntityChaosMarine.java | 5 +- java/src/game/entity/npc/EntityDarkMage.java | 2 +- java/src/game/entity/npc/EntityGargoyle.java | 2 +- java/src/game/entity/npc/EntityHuman.java | 4 +- java/src/game/entity/npc/EntityMagma.java | 2 +- java/src/game/entity/npc/EntityNPC.java | 33 +- java/src/game/entity/npc/EntityPrimarch.java | 5 +- java/src/game/entity/npc/EntitySlime.java | 2 +- .../game/entity/npc/EntitySpaceMarine.java | 5 +- java/src/game/entity/npc/EntityZombie.java | 1 - java/src/game/entity/npc/SpeciesInfo.java | 5 +- .../game/entity/projectile/EntityArrow.java | 2 +- .../entity/projectile/EntityDynamite.java | 2 +- .../src/game/entity/projectile/EntityEgg.java | 2 +- .../game/entity/projectile/EntityHook.java | 2 +- .../entity/projectile/EntityProjectile.java | 2 +- .../entity/projectile/EntitySnowball.java | 2 +- java/src/game/entity/types/EntityAnimal.java | 5 +- java/src/game/entity/types/EntityLiving.java | 9 +- .../src/game/entity/types/EntityTameable.java | 2 +- .../game/entity/types/EntityThrowable.java | 2 +- java/src/game/init/BlockRegistry.java | 9 +- java/src/game/init/Config.java | 2 +- java/src/game/init/CraftingRegistry.java | 5 +- java/src/game/init/EntityRegistry.java | 111 ------ java/src/game/init/FluidRegistry.java | 5 +- java/src/game/init/ItemRegistry.java | 5 +- java/src/game/init/ObjectIntIdentityMap.java | 2 +- java/src/game/init/RotationRegistry.java | 5 +- java/src/game/init/SmeltingRegistry.java | 3 +- java/src/game/init/SoundEvent.java | 52 +-- java/src/game/init/SpeciesRegistry.java | 1 - java/src/game/init/TileRegistry.java | 1 - java/src/game/init/ToolMaterial.java | 1 - java/src/game/init/UniverseRegistry.java | 7 +- java/src/game/inventory/Container.java | 1 - .../game/inventory/ContainerLocalMenu.java | 1 - java/src/game/inventory/ContainerPlayer.java | 1 - java/src/game/inventory/InventoryBasic.java | 1 - java/src/game/item/Item.java | 14 +- java/src/game/item/ItemArmor.java | 14 +- java/src/game/item/ItemBanner.java | 10 +- java/src/game/item/ItemBlock.java | 17 +- java/src/game/item/ItemBow.java | 9 +- java/src/game/item/ItemBucket.java | 16 +- java/src/game/item/ItemBucketMilk.java | 1 - java/src/game/item/ItemButton.java | 7 +- java/src/game/item/ItemCarrotOnAStick.java | 2 +- java/src/game/item/ItemChargedOrb.java | 2 +- java/src/game/item/ItemChest.java | 10 +- java/src/game/item/ItemCloth.java | 9 +- java/src/game/item/ItemCoal.java | 7 +- java/src/game/item/ItemDie.java | 9 +- java/src/game/item/ItemDoublePlant.java | 7 +- java/src/game/item/ItemDye.java | 9 +- java/src/game/item/ItemDynamite.java | 7 +- java/src/game/item/ItemEditWand.java | 2 +- java/src/game/item/ItemEnchantedBook.java | 2 +- java/src/game/item/ItemFence.java | 7 +- java/src/game/item/ItemFirework.java | 1 - java/src/game/item/ItemFireworkCharge.java | 7 +- java/src/game/item/ItemFishFood.java | 8 +- java/src/game/item/ItemFishingRod.java | 9 +- java/src/game/item/ItemGlassBottle.java | 7 +- java/src/game/item/ItemGunBase.java | 2 +- java/src/game/item/ItemHoe.java | 2 +- java/src/game/item/ItemKey.java | 2 +- java/src/game/item/ItemMagnet.java | 3 +- java/src/game/item/ItemMetal.java | 1 - java/src/game/item/ItemMetalBlock.java | 3 +- java/src/game/item/ItemMonsterPlacer.java | 7 +- java/src/game/item/ItemNpcSpawner.java | 7 +- java/src/game/item/ItemNugget.java | 2 +- java/src/game/item/ItemPiston.java | 7 +- java/src/game/item/ItemPotion.java | 10 +- java/src/game/item/ItemPressurePlate.java | 7 +- java/src/game/item/ItemRecord.java | 7 +- java/src/game/item/ItemRod.java | 2 +- java/src/game/item/ItemSeeds.java | 2 +- java/src/game/item/ItemSkull.java | 10 +- java/src/game/item/ItemSmall.java | 2 +- java/src/game/item/ItemSoup.java | 2 +- java/src/game/item/ItemStack.java | 3 +- java/src/game/item/ItemStick.java | 2 +- java/src/game/item/ItemSword.java | 5 +- java/src/game/item/ItemTiny.java | 2 +- java/src/game/item/ItemTool.java | 5 +- java/src/game/item/ItemWall.java | 9 +- java/src/game/item/ItemWand.java | 2 +- java/src/game/log/Log.java | 1 - java/src/game/log/LogLevel.java | 4 +- .../game/{renderer => model}/BlockLayer.java | 2 +- .../ItemMeshDefinition.java | 2 +- java/src/game/model/Model.java | 177 +++++++++ java/src/game/model/ModelProvider.java | 90 +++++ java/src/game/model/ModelRotation.java | 5 +- .../particle => model}/ParticleType.java | 2 +- .../blockmodel => model}/Transform.java | 6 +- .../blockmodel => model}/Transforms.java | 15 +- java/src/game/nbt/NBTTagList.java | 1 - java/src/game/network/ClientLoginHandler.java | 2 +- java/src/game/network/ClientPlayer.java | 24 +- java/src/game/network/HandshakeHandler.java | 2 +- java/src/game/network/LoginHandler.java | 2 +- java/src/game/network/NetConnection.java | 1 - java/src/game/network/PacketRegistry.java | 1 - java/src/game/network/Player.java | 7 +- java/src/game/packet/CPacketAction.java | 2 +- java/src/game/packet/CPacketBook.java | 2 +- java/src/game/packet/CPacketBreak.java | 2 +- java/src/game/packet/CPacketCheat.java | 2 +- java/src/game/packet/CPacketClick.java | 2 +- java/src/game/packet/CPacketComplete.java | 2 +- java/src/game/packet/CPacketInput.java | 2 +- java/src/game/packet/CPacketMessage.java | 2 +- java/src/game/packet/CPacketPlace.java | 2 +- java/src/game/packet/CPacketPlayer.java | 2 +- java/src/game/packet/CPacketSign.java | 2 +- java/src/game/packet/CPacketSkin.java | 4 +- .../game/packet/LPacketPasswordResponse.java | 2 +- .../packet/S20PacketEntityProperties.java | 1 - java/src/game/packet/S27PacketExplosion.java | 1 - java/src/game/packet/S2APacketParticles.java | 2 +- .../game/packet/S38PacketPlayerListItem.java | 3 +- .../src/game/packet/SPacketCharacterList.java | 4 +- java/src/game/packet/SPacketChunkData.java | 1 - java/src/game/packet/SPacketSkin.java | 2 +- java/src/game/packet/SPacketSpawnPlayer.java | 2 +- java/src/game/pattern/BlockStateHelper.java | 3 +- java/src/game/potion/Potion.java | 2 +- .../game/properties/IStringSerializable.java | 6 - .../game/properties/PropertyDirection.java | 5 +- java/src/game/properties/PropertyEnum.java | 19 +- .../game/renderer/blockmodel/ModelBlock.java | 342 ------------------ java/src/game/rng/WeightedList.java | 3 +- java/src/game/sound/EventType.java | 5 + .../game/{audio => sound}/MovingSound.java | 2 +- .../{audio => sound}/MovingSoundMinecart.java | 2 +- .../MovingSoundMinecartRiding.java | 2 +- .../{audio => sound}/PositionedSound.java | 4 +- java/src/game/{audio => sound}/Sound.java | 6 +- .../src/game/tileentity/TileEntityBanner.java | 3 +- .../src/game/tileentity/TileEntityHopper.java | 1 - .../game/tileentity/TileEntityMobSpawner.java | 2 +- .../src/game/tileentity/TileEntityPiston.java | 1 - java/src/game/util/Identifyable.java | 6 + .../src/game/{renderer => util}/Matrix4f.java | 2 +- java/src/game/util/Util.java | 9 +- java/src/game/{renderer => util}/Vector.java | 2 +- .../src/game/{renderer => util}/Vector3f.java | 2 +- .../src/game/{renderer => util}/Vector4f.java | 2 +- java/src/game/vars/BoolVar.java | 2 +- java/src/game/vars/CVar.java | 2 +- java/src/game/vars/ColorVar.java | 10 +- java/src/game/vars/EnumVar.java | 18 +- java/src/game/vars/FloatVar.java | 2 +- java/src/game/vars/IntVar.java | 2 +- java/src/game/vars/StringVar.java | 4 +- java/src/game/village/Village.java | 3 +- java/src/game/village/VillageCollection.java | 3 +- java/src/game/window/Input.java | 8 - java/src/game/world/BlockPos.java | 1 - java/src/game/world/Chunk.java | 3 +- java/src/game/world/Converter.java | 11 +- java/src/game/world/EmptyChunk.java | 1 - java/src/game/world/Explosion.java | 5 +- java/src/game/world/Facing.java | 9 +- java/src/game/world/Region.java | 3 +- java/src/game/world/Spawner.java | 3 +- java/src/game/world/State.java | 5 +- java/src/game/world/Vec3.java | 6 - java/src/game/world/Weather.java | 1 - java/src/game/world/World.java | 7 +- java/src/game/world/WorldClient.java | 17 +- java/src/game/world/WorldServer.java | 13 +- java/src/game/worldgen/BiomeGenLayered.java | 3 +- java/src/game/worldgen/GeneratorDebug.java | 3 +- .../worldgen/feature/WorldGenDesertWells.java | 3 +- .../worldgen/structure/MapGenStructure.java | 1 - .../worldgen/structure/MapGenStructureIO.java | 1 - .../worldgen/structure/MapGenVillage.java | 3 +- .../worldgen/structure/StructureBridge.java | 1 - .../structure/StructureStronghold.java | 5 +- .../worldgen/structure/StructureVillage.java | 3 +- .../game/worldgen/tree/WorldGenBigTree.java | 3 +- java/src/{game => server}/Server.java | 15 +- 661 files changed, 3058 insertions(+), 2826 deletions(-) rename java/src/{game => client}/Game.java (98%) rename java/src/{game/util => client}/PerfSection.java (96%) rename java/src/{game/network => client}/PlayerController.java (99%) rename java/src/{game/util => client}/SkinConverter.java (99%) rename java/src/{game/util => client}/Timing.java (97%) rename java/src/{game => client}/audio/AudioInterface.java (99%) rename java/src/{game => client}/audio/CodecJOrbis.java (98%) rename java/src/{game => client}/audio/SoundManager.java (79%) rename java/src/{game => client}/audio/Volume.java (70%) rename java/src/{game => client}/audio/jogg/Buffer.java (99%) rename java/src/{game => client}/audio/jogg/Packet.java (98%) rename java/src/{game => client}/audio/jogg/Page.java (99%) rename java/src/{game => client}/audio/jogg/StreamState.java (99%) rename java/src/{game => client}/audio/jogg/SyncState.java (99%) rename java/src/{game => client}/audio/jorbis/Block.java (97%) rename java/src/{game => client}/audio/jorbis/ChainingExample.java (98%) rename java/src/{game => client}/audio/jorbis/CodeBook.java (99%) rename java/src/{game => client}/audio/jorbis/Comment.java (98%) rename java/src/{game => client}/audio/jorbis/DecodeExample.java (98%) rename java/src/{game => client}/audio/jorbis/Drft.java (99%) rename java/src/{game => client}/audio/jorbis/DspState.java (99%) rename java/src/{game => client}/audio/jorbis/Floor0.java (99%) rename java/src/{game => client}/audio/jorbis/Floor1.java (99%) rename java/src/{game => client}/audio/jorbis/FuncFloor.java (96%) rename java/src/{game => client}/audio/jorbis/FuncMapping.java (95%) rename java/src/{game => client}/audio/jorbis/FuncResidue.java (96%) rename java/src/{game => client}/audio/jorbis/FuncTime.java (95%) rename java/src/{game => client}/audio/jorbis/Info.java (99%) rename java/src/{game => client}/audio/jorbis/InfoMode.java (97%) rename java/src/{game => client}/audio/jorbis/JOrbisException.java (97%) rename java/src/{game => client}/audio/jorbis/Lookup.java (99%) rename java/src/{game => client}/audio/jorbis/Lpc.java (99%) rename java/src/{game => client}/audio/jorbis/Lsp.java (99%) rename java/src/{game => client}/audio/jorbis/Mapping0.java (99%) rename java/src/{game => client}/audio/jorbis/Mdct.java (99%) rename java/src/{game => client}/audio/jorbis/PsyInfo.java (98%) rename java/src/{game => client}/audio/jorbis/PsyLook.java (97%) rename java/src/{game => client}/audio/jorbis/Residue0.java (99%) rename java/src/{game => client}/audio/jorbis/Residue1.java (97%) rename java/src/{game => client}/audio/jorbis/Residue2.java (97%) rename java/src/{game => client}/audio/jorbis/StaticCodeBook.java (99%) rename java/src/{game => client}/audio/jorbis/Time0.java (95%) rename java/src/{game => client}/audio/jorbis/Util.java (92%) rename java/src/{game => client}/audio/jorbis/VorbisFile.java (99%) rename java/src/{game/util => client/gui}/FileCallback.java (79%) rename java/src/{game => client}/gui/Font.java (96%) rename java/src/{game => client}/gui/FontChar.java (91%) rename java/src/{game/util => client/gui}/Formatter.java (57%) rename java/src/{game => client}/gui/Gui.java (97%) rename java/src/{game => client}/gui/GuiConfirm.java (87%) rename java/src/{game => client}/gui/GuiConnect.java (97%) rename java/src/{game => client}/gui/GuiConsole.java (97%) rename java/src/{game => client}/gui/GuiConvert.java (95%) rename java/src/{game => client}/gui/GuiInfo.java (98%) rename java/src/{game => client}/gui/GuiLoading.java (96%) rename java/src/{game => client}/gui/GuiMenu.java (95%) rename java/src/{game => client}/gui/GuiServer.java (95%) rename java/src/{game/util => client/gui}/Splashes.java (99%) rename java/src/{game => client}/gui/Style.java (96%) rename java/src/{game => client}/gui/character/GuiChar.java (96%) rename java/src/{game => client}/gui/character/GuiCharacters.java (93%) rename java/src/{game => client}/gui/character/GuiClass.java (90%) rename java/src/{game => client}/gui/character/GuiSpecies.java (90%) rename java/src/{game => client}/gui/container/GuiBrewing.java (97%) rename java/src/{game => client}/gui/container/GuiChest.java (97%) rename java/src/{game => client}/gui/container/GuiContainer.java (99%) rename java/src/{game => client}/gui/container/GuiCrafting.java (97%) rename java/src/{game => client}/gui/container/GuiDispenser.java (98%) rename java/src/{game => client}/gui/container/GuiEnchant.java (99%) rename java/src/{game => client}/gui/container/GuiFurnace.java (98%) rename java/src/{game => client}/gui/container/GuiHopper.java (97%) rename java/src/{game => client}/gui/container/GuiHorse.java (98%) rename java/src/{game => client}/gui/container/GuiInventory.java (98%) rename java/src/{game => client}/gui/container/GuiMachine.java (96%) rename java/src/{game => client}/gui/container/GuiMerchant.java (99%) rename java/src/{game => client}/gui/container/GuiRepair.java (99%) rename java/src/{game => client}/gui/element/ActButton.java (90%) rename java/src/{game => client}/gui/element/Bar.java (98%) rename java/src/{game => client}/gui/element/Dropdown.java (95%) rename java/src/{game => client}/gui/element/Element.java (95%) rename java/src/{game => client}/gui/element/Fill.java (92%) rename java/src/{game => client}/gui/element/GuiList.java (98%) rename java/src/{game => client}/gui/element/InventoryButton.java (88%) rename java/src/{game => client}/gui/element/Label.java (92%) rename java/src/{game => client}/gui/element/ListEntry.java (83%) rename java/src/{game => client}/gui/element/NavButton.java (90%) rename java/src/{game => client}/gui/element/SelectableButton.java (94%) rename java/src/{game => client}/gui/element/Slider.java (98%) rename java/src/{game => client}/gui/element/Switch.java (95%) rename java/src/{game => client}/gui/element/Textbox.java (98%) rename java/src/{game => client}/gui/element/Toggle.java (93%) rename java/src/{game => client}/gui/element/TransparentBox.java (86%) rename java/src/{game => client}/gui/ingame/GuiGameOver.java (84%) rename java/src/{game => client}/gui/ingame/GuiSign.java (88%) rename java/src/{game => client}/gui/options/GuiBinds.java (90%) rename java/src/{game => client}/gui/options/GuiDisplay.java (91%) rename java/src/{game => client}/gui/options/GuiOptions.java (86%) rename java/src/{game => client}/gui/options/GuiSound.java (85%) rename java/src/{game => client}/gui/options/GuiStyle.java (90%) create mode 100644 java/src/client/init/EntityRenderRegistry.java rename java/src/{game => client}/renderer/ActiveRenderInfo.java (99%) rename java/src/{game => client}/renderer/BlockRenderer.java (98%) rename java/src/{game => client}/renderer/DefaultVertexFormats.java (99%) rename java/src/{game => client}/renderer/Drawing.java (99%) rename java/src/{game => client}/renderer/EntityRenderer.java (99%) rename java/src/{game => client}/renderer/Frustum.java (99%) rename java/src/{game => client}/renderer/GlState.java (99%) rename java/src/{game => client}/renderer/ItemModelMesher.java (95%) rename java/src/{game => client}/renderer/ItemRenderer.java (98%) rename java/src/{game => client}/renderer/Project.java (99%) rename java/src/{game => client}/renderer/RegionRenderCache.java (99%) rename java/src/{game => client}/renderer/RegionRenderCacheBuilder.java (92%) rename java/src/{game => client}/renderer/RenderBuffer.java (99%) rename java/src/{game => client}/renderer/RenderGlobal.java (99%) rename java/src/{game => client}/renderer/Tessellator.java (99%) rename java/src/{game => client}/renderer/VertexBuffer.java (97%) rename java/src/{game => client}/renderer/VertexFormat.java (99%) rename java/src/{game => client}/renderer/VertexFormatElement.java (99%) rename java/src/{game => client}/renderer/ViewFrustum.java (98%) rename java/src/{game/model => client/renderer/blockmodel}/BakedModel.java (94%) rename java/src/{game => client}/renderer/blockmodel/BakedQuad.java (93%) rename java/src/{game => client}/renderer/blockmodel/BlockFaceUV.java (94%) rename java/src/{game => client}/renderer/blockmodel/BlockPart.java (92%) rename java/src/{game => client}/renderer/blockmodel/BlockPartFace.java (82%) rename java/src/{game => client}/renderer/blockmodel/BlockPartRotation.java (86%) rename java/src/{game => client}/renderer/blockmodel/BreakingFour.java (95%) rename java/src/{game/model => client/renderer/blockmodel}/BuiltInModel.java (83%) rename java/src/{game => client}/renderer/blockmodel/FaceBakery.java (99%) rename java/src/{game/model => client/renderer/blockmodel}/IBakedModel.java (69%) rename java/src/{game/model => client/renderer/blockmodel}/ModelBakery.java (93%) create mode 100755 java/src/client/renderer/blockmodel/ModelBlock.java rename java/src/{game => client}/renderer/blockmodel/ModelGenerator.java (97%) rename java/src/{game/model => client/renderer/blockmodel}/ModelManager.java (95%) rename java/src/{game => client}/renderer/blockmodel/MultiStateMap.java (98%) rename java/src/{game => client}/renderer/blockmodel/SingleStateMap.java (89%) rename java/src/{game => client}/renderer/blockmodel/StateMap.java (97%) rename java/src/{game => client}/renderer/chunk/ChunkCompileTaskGenerator.java (97%) rename java/src/{game => client}/renderer/chunk/ChunkRenderDispatcher.java (97%) rename java/src/{game => client}/renderer/chunk/ChunkRenderWorker.java (98%) rename java/src/{game => client}/renderer/chunk/CompiledChunk.java (95%) rename java/src/{game => client}/renderer/chunk/RenderChunk.java (96%) rename java/src/{game => client}/renderer/chunk/SetVisibility.java (98%) rename java/src/{game => client}/renderer/chunk/VisGraph.java (99%) rename java/src/{game => client}/renderer/entity/Render.java (98%) rename java/src/{game => client}/renderer/entity/RenderArachnoid.java (94%) rename java/src/{game => client}/renderer/entity/RenderArrow.java (95%) rename java/src/{game => client}/renderer/entity/RenderBat.java (94%) rename java/src/{game => client}/renderer/entity/RenderBlockEntity.java (95%) rename java/src/{game => client}/renderer/entity/RenderBoat.java (94%) rename java/src/{game => client}/renderer/entity/RenderBullet.java (94%) rename java/src/{game => client}/renderer/entity/RenderChicken.java (93%) rename java/src/{game => client}/renderer/entity/RenderCow.java (88%) rename java/src/{game => client}/renderer/entity/RenderCrystal.java (91%) rename java/src/{game => client}/renderer/entity/RenderDie.java (89%) rename java/src/{game => client}/renderer/entity/RenderDragon.java (95%) rename java/src/{game => client}/renderer/entity/RenderDynamite.java (93%) rename java/src/{game => client}/renderer/entity/RenderEntity.java (96%) rename java/src/{game => client}/renderer/entity/RenderEntityItem.java (93%) rename java/src/{game => client}/renderer/entity/RenderFallingBlock.java (88%) rename java/src/{game => client}/renderer/entity/RenderFireball.java (88%) rename java/src/{game => client}/renderer/entity/RenderFish.java (95%) rename java/src/{game => client}/renderer/entity/RenderFlyingBox.java (94%) rename java/src/{game => client}/renderer/entity/RenderHorse.java (94%) rename java/src/{game => client}/renderer/entity/RenderHumanoid.java (96%) rename java/src/{game => client}/renderer/entity/RenderItem.java (90%) rename java/src/{game => client}/renderer/entity/RenderItemEntity.java (90%) rename java/src/{game => client}/renderer/entity/RenderLeashKnot.java (92%) rename java/src/{game => client}/renderer/entity/RenderLightning.java (96%) rename java/src/{game => client}/renderer/entity/RenderLiving.java (95%) rename java/src/{game => client}/renderer/entity/RenderManager.java (96%) rename java/src/{game => client}/renderer/entity/RenderMinecart.java (95%) rename java/src/{game => client}/renderer/entity/RenderMooshroom.java (83%) rename java/src/{game => client}/renderer/entity/RenderMouse.java (85%) rename java/src/{game => client}/renderer/entity/RenderNpc.java (97%) rename java/src/{game => client}/renderer/entity/RenderOcelot.java (95%) rename java/src/{game => client}/renderer/entity/RenderPig.java (83%) rename java/src/{game => client}/renderer/entity/RenderPotion.java (93%) rename java/src/{game => client}/renderer/entity/RenderRabbit.java (94%) rename java/src/{game => client}/renderer/entity/RenderSheep.java (83%) rename java/src/{game => client}/renderer/entity/RenderSlime.java (96%) rename java/src/{game => client}/renderer/entity/RenderSpaceMarine.java (95%) rename java/src/{game => client}/renderer/entity/RenderSquid.java (95%) rename java/src/{game => client}/renderer/entity/RenderTntMinecart.java (92%) rename java/src/{game => client}/renderer/entity/RenderTntPrimed.java (93%) rename java/src/{game => client}/renderer/entity/RenderWolf.java (90%) rename java/src/{game => client}/renderer/entity/RenderXpOrb.java (94%) rename java/src/{game => client}/renderer/entity/RendererLivingEntity.java (98%) rename java/src/{game => client}/renderer/layers/LayerArachnoidArmor.java (80%) rename java/src/{game => client}/renderer/layers/LayerArmor.java (97%) rename java/src/{game => client}/renderer/layers/LayerArrow.java (93%) rename java/src/{game => client}/renderer/layers/LayerCape.java (96%) rename java/src/{game => client}/renderer/layers/LayerCharge.java (92%) rename java/src/{game => client}/renderer/layers/LayerEnderDragonEyes.java (93%) rename java/src/{game => client}/renderer/layers/LayerEntityBreak.java (93%) rename java/src/{game => client}/renderer/layers/LayerExtra.java (96%) rename java/src/{game => client}/renderer/layers/LayerHeldItem.java (93%) rename java/src/{game => client}/renderer/layers/LayerMooshroomMushroom.java (89%) rename java/src/{game => client}/renderer/layers/LayerPowerRods.java (94%) rename java/src/{game => client}/renderer/layers/LayerRenderer.java (90%) rename java/src/{game => client}/renderer/layers/LayerSaddle.java (89%) rename java/src/{game => client}/renderer/layers/LayerSheepWool.java (93%) rename java/src/{game => client}/renderer/layers/LayerSlimeGel.java (86%) rename java/src/{game => client}/renderer/layers/LayerWolfCollar.java (92%) rename java/src/{game => client}/renderer/model/ModelArachnoid.java (99%) rename java/src/{game => client}/renderer/model/ModelArmor.java (98%) rename java/src/{game => client}/renderer/model/ModelBanner.java (96%) rename java/src/{game => client}/renderer/model/ModelBase.java (98%) rename java/src/{game => client}/renderer/model/ModelBat.java (99%) rename java/src/{game => client}/renderer/model/ModelBiped.java (99%) rename java/src/{game => client}/renderer/model/ModelBoat.java (98%) rename java/src/{game => client}/renderer/model/ModelBox.java (99%) rename java/src/{game => client}/renderer/model/ModelCharge.java (94%) rename java/src/{game => client}/renderer/model/ModelChest.java (97%) rename java/src/{game => client}/renderer/model/ModelChicken.java (99%) rename java/src/{game => client}/renderer/model/ModelCow.java (97%) rename java/src/{game => client}/renderer/model/ModelCrystal.java (98%) rename java/src/{game => client}/renderer/model/ModelDie.java (96%) rename java/src/{game => client}/renderer/model/ModelDragon.java (99%) rename java/src/{game => client}/renderer/model/ModelHead.java (98%) rename java/src/{game => client}/renderer/model/ModelHorse.java (99%) rename java/src/{game => client}/renderer/model/ModelHumanoid.java (99%) rename java/src/{game => client}/renderer/model/ModelHumanoidHead.java (97%) rename java/src/{game => client}/renderer/model/ModelLargeChest.java (96%) rename java/src/{game => client}/renderer/model/ModelLeashKnot.java (98%) rename java/src/{game => client}/renderer/model/ModelMinecart.java (98%) rename java/src/{game => client}/renderer/model/ModelMouse.java (99%) rename java/src/{game => client}/renderer/model/ModelOcelot.java (99%) rename java/src/{game => client}/renderer/model/ModelPig.java (90%) rename java/src/{game => client}/renderer/model/ModelQuadruped.java (99%) rename java/src/{game => client}/renderer/model/ModelRabbit.java (99%) rename java/src/{game => client}/renderer/model/ModelRenderer.java (99%) rename java/src/{game => client}/renderer/model/ModelSheep1.java (98%) rename java/src/{game => client}/renderer/model/ModelSheep2.java (98%) rename java/src/{game => client}/renderer/model/ModelSign.java (95%) rename java/src/{game => client}/renderer/model/ModelSlime.java (98%) rename java/src/{game => client}/renderer/model/ModelSpaceMarine.java (99%) rename java/src/{game => client}/renderer/model/ModelSquid.java (98%) rename java/src/{game => client}/renderer/model/ModelWolf.java (99%) rename java/src/{game => client}/renderer/model/PositionTextureVertex.java (90%) rename java/src/{game => client}/renderer/model/TextureOffset.java (92%) rename java/src/{game => client}/renderer/model/TexturedQuad.java (84%) rename java/src/{game => client}/renderer/particle/EffectRenderer.java (97%) rename java/src/{game => client}/renderer/particle/EntityAuraFX.java (98%) rename java/src/{game => client}/renderer/particle/EntityBlockDustFX.java (96%) rename java/src/{game => client}/renderer/particle/EntityBreakingFX.java (98%) rename java/src/{game => client}/renderer/particle/EntityBubbleFX.java (98%) rename java/src/{game => client}/renderer/particle/EntityCloudFX.java (97%) rename java/src/{game => client}/renderer/particle/EntityCrit2FX.java (98%) rename java/src/{game => client}/renderer/particle/EntityCritFX.java (95%) rename java/src/{game => client}/renderer/particle/EntityDiggingFX.java (98%) rename java/src/{game => client}/renderer/particle/EntityDownfallFX.java (99%) rename java/src/{game => client}/renderer/particle/EntityDropParticleFX.java (98%) rename java/src/{game => client}/renderer/particle/EntityEnchantmentTableParticleFX.java (98%) rename java/src/{game => client}/renderer/particle/EntityExplodeFX.java (98%) rename java/src/{game => client}/renderer/particle/EntityFX.java (98%) rename java/src/{game => client}/renderer/particle/EntityFirework.java (99%) rename java/src/{game => client}/renderer/particle/EntityFishWakeFX.java (98%) rename java/src/{game => client}/renderer/particle/EntityFlameFX.java (98%) rename java/src/{game => client}/renderer/particle/EntityFootStepFX.java (92%) rename java/src/{game => client}/renderer/particle/EntityHeartFX.java (97%) rename java/src/{game => client}/renderer/particle/EntityHugeExplodeFX.java (94%) rename java/src/{game => client}/renderer/particle/EntityLargeExplodeFX.java (93%) rename java/src/{game => client}/renderer/particle/EntityLavaFX.java (96%) rename java/src/{game => client}/renderer/particle/EntityNoteFX.java (97%) rename java/src/{game => client}/renderer/particle/EntityParticleEmitter.java (95%) rename java/src/{game => client}/renderer/particle/EntityPickupFX.java (93%) rename java/src/{game => client}/renderer/particle/EntityPortalFX.java (98%) rename java/src/{game => client}/renderer/particle/EntityReddustFX.java (97%) rename java/src/{game => client}/renderer/particle/EntitySmokeFX.java (97%) rename java/src/{game => client}/renderer/particle/EntitySnowShovelFX.java (97%) rename java/src/{game => client}/renderer/particle/EntitySpellParticleFX.java (98%) rename java/src/{game => client}/renderer/particle/EntitySplashFX.java (96%) rename java/src/{game => client}/renderer/particle/EntitySuspendFX.java (98%) rename java/src/{game => client}/renderer/particle/IParticleFactory.java (87%) rename java/src/{game => client}/renderer/texture/DynamicTexture.java (95%) rename java/src/{game => client}/renderer/texture/EntityTexManager.java (98%) rename java/src/{game => client}/renderer/texture/IIconCreator.java (72%) rename java/src/{game => client}/renderer/texture/LayeredColorMaskTexture.java (99%) rename java/src/{game => client}/renderer/texture/LayeredTexture.java (97%) rename java/src/{game => client}/renderer/texture/SimpleTexture.java (95%) rename java/src/{game => client}/renderer/texture/Stitcher.java (99%) rename java/src/{game => client}/renderer/texture/Texture.java (90%) rename java/src/{game => client}/renderer/texture/TextureAtlasSprite.java (99%) rename java/src/{game => client}/renderer/texture/TextureManager.java (95%) rename java/src/{game => client}/renderer/texture/TextureMap.java (99%) rename java/src/{game => client}/renderer/texture/TextureTicked.java (79%) rename java/src/{game => client}/renderer/texture/TextureUtil.java (98%) rename java/src/{game => client}/renderer/ticked/TextureFlamesFX1.java (93%) rename java/src/{game => client}/renderer/ticked/TextureFlamesFX2.java (85%) rename java/src/{game => client}/renderer/ticked/TextureLavaFX.java (94%) rename java/src/{game => client}/renderer/ticked/TextureLavaFlowFX.java (95%) rename java/src/{game => client}/renderer/ticked/TextureWaterFX.java (93%) rename java/src/{game => client}/renderer/ticked/TextureWaterFlowFX.java (94%) rename java/src/{game => client}/renderer/tileentity/TileEntityBannerRenderer.java (96%) rename java/src/{game => client}/renderer/tileentity/TileEntityChestRenderer.java (97%) rename java/src/{game => client}/renderer/tileentity/TileEntityItemStackRenderer.java (97%) rename java/src/{game => client}/renderer/tileentity/TileEntityMobSpawnerRenderer.java (96%) rename java/src/{game => client}/renderer/tileentity/TileEntityPistonRenderer.java (92%) rename java/src/{game => client}/renderer/tileentity/TileEntityRendererDispatcher.java (98%) rename java/src/{game => client}/renderer/tileentity/TileEntitySignRenderer.java (96%) rename java/src/{game => client}/renderer/tileentity/TileEntitySkullRenderer.java (96%) rename java/src/{game => client}/renderer/tileentity/TileEntitySpecialRenderer.java (95%) rename java/src/{game => client}/window/Bind.java (96%) rename java/src/{game => client}/window/Button.java (95%) rename java/src/{game => client}/window/DisplayMode.java (96%) create mode 100644 java/src/client/window/Input.java rename java/src/{game => client}/window/KeyEvent.java (69%) rename java/src/{game => client}/window/Keysym.java (99%) rename java/src/{game => client}/window/Wheel.java (93%) rename java/src/{game => client}/window/Window.java (77%) rename java/src/{game => client}/window/WindowAction.java (84%) rename java/src/{game => client}/window/WindowEvent.java (91%) rename java/src/game/{audio => block}/SoundType.java (94%) rename java/src/game/{renderer => model}/BlockLayer.java (93%) rename java/src/game/{renderer => model}/ItemMeshDefinition.java (83%) create mode 100644 java/src/game/model/Model.java create mode 100644 java/src/game/model/ModelProvider.java rename java/src/game/{renderer/particle => model}/ParticleType.java (99%) rename java/src/game/{renderer/blockmodel => model}/Transform.java (83%) rename java/src/game/{renderer/blockmodel => model}/Transforms.java (91%) delete mode 100755 java/src/game/properties/IStringSerializable.java delete mode 100755 java/src/game/renderer/blockmodel/ModelBlock.java create mode 100644 java/src/game/sound/EventType.java rename java/src/game/{audio => sound}/MovingSound.java (94%) rename java/src/game/{audio => sound}/MovingSoundMinecart.java (98%) rename java/src/game/{audio => sound}/MovingSoundMinecartRiding.java (98%) rename java/src/game/{audio => sound}/PositionedSound.java (88%) rename java/src/game/{audio => sound}/Sound.java (89%) create mode 100755 java/src/game/util/Identifyable.java rename java/src/game/{renderer => util}/Matrix4f.java (99%) rename java/src/game/{renderer => util}/Vector.java (99%) rename java/src/game/{renderer => util}/Vector3f.java (99%) rename java/src/game/{renderer => util}/Vector4f.java (99%) delete mode 100644 java/src/game/window/Input.java rename java/src/{game => server}/Server.java (99%) diff --git a/java/src/game/Game.java b/java/src/client/Game.java similarity index 98% rename from java/src/game/Game.java rename to java/src/client/Game.java index efd3175..be13f94 100755 --- a/java/src/game/Game.java +++ b/java/src/client/Game.java @@ -1,4 +1,4 @@ -package game; +package client; import java.awt.image.BufferedImage; import java.io.BufferedInputStream; @@ -30,21 +30,54 @@ import java.util.concurrent.FutureTask; import java.util.function.Function; import javax.imageio.ImageIO; + import org.lwjgl.opengl.GL11; import org.lwjgl.opengl.GL13; -import game.collect.Lists; -import game.collect.Maps; -import game.future.Futures; -import game.future.ListenableFuture; -import game.future.ListenableFutureTask; - -import game.audio.AudioInterface; -import game.audio.PositionedSound; -import game.audio.SoundManager; -import game.audio.Volume; +import client.audio.AudioInterface; +import client.audio.SoundManager; +import client.audio.Volume; +import client.gui.FileCallback; +import client.gui.Font; +import client.gui.Gui; +import client.gui.GuiConsole; +import client.gui.GuiInfo; +import client.gui.GuiLoading; +import client.gui.GuiMenu; +import client.gui.GuiServer; +import client.gui.Style; +import client.gui.character.GuiChar; +import client.gui.container.GuiContainer; +import client.gui.container.GuiInventory; +import client.gui.element.Textbox; +import client.gui.ingame.GuiGameOver; +import client.renderer.BlockRenderer; +import client.renderer.Drawing; +import client.renderer.EntityRenderer; +import client.renderer.GlState; +import client.renderer.ItemRenderer; +import client.renderer.RenderGlobal; +import client.renderer.blockmodel.ModelBlock; +import client.renderer.blockmodel.ModelManager; +import client.renderer.chunk.RenderChunk; +import client.renderer.entity.RenderItem; +import client.renderer.entity.RenderManager; +import client.renderer.particle.EffectRenderer; +import client.renderer.texture.EntityTexManager; +import client.renderer.texture.TextureManager; +import client.renderer.texture.TextureMap; +import client.window.Bind; +import client.window.Button; +import client.window.DisplayMode; +import client.window.KeyEvent; +import client.window.Keysym; +import client.window.Wheel; +import client.window.Window; +import client.window.WindowEvent; import game.biome.Biome; import game.block.Block; +import game.collect.Lists; +import game.collect.Maps; import game.color.Colorizer; import game.color.TextColor; import game.entity.Entity; @@ -52,19 +85,9 @@ import game.entity.animal.EntityHorse; import game.entity.npc.Energy; import game.entity.npc.EntityNPC; import game.entity.types.EntityLiving; -import game.gui.Font; -import game.gui.Gui; -import game.gui.GuiConsole; -import game.gui.GuiInfo; -import game.gui.GuiLoading; -import game.gui.GuiMenu; -import game.gui.GuiServer; -import game.gui.Style; -import game.gui.character.GuiChar; -import game.gui.container.GuiContainer; -import game.gui.container.GuiInventory; -import game.gui.element.Textbox; -import game.gui.ingame.GuiGameOver; +import game.future.Futures; +import game.future.ListenableFuture; +import game.future.ListenableFutureTask; import game.init.BlockRegistry; import game.init.Config; import game.init.EntityRegistry; @@ -81,13 +104,11 @@ import game.log.Log; import game.log.LogLevel; import game.log.Message; import game.material.Material; -import game.model.ModelManager; +import game.network.ClientLoginHandler; +import game.network.ClientPlayer; import game.network.IThreadListener; import game.network.NetConnection; import game.network.NetHandler.ThreadQuickExitException; -import game.network.ClientLoginHandler; -import game.network.ClientPlayer; -import game.network.PlayerController; import game.packet.CPacketAction; import game.packet.CPacketAction.Action; import game.packet.CPacketCheat; @@ -98,26 +119,12 @@ import game.potion.Potion; import game.potion.PotionEffect; import game.potion.PotionHelper; import game.properties.IProperty; -import game.renderer.BlockRenderer; -import game.renderer.Drawing; -import game.renderer.EntityRenderer; -import game.renderer.GlState; -import game.renderer.ItemRenderer; -import game.renderer.RenderGlobal; -import game.renderer.chunk.RenderChunk; -import game.renderer.entity.RenderItem; -import game.renderer.entity.RenderManager; -import game.renderer.particle.EffectRenderer; -import game.renderer.texture.EntityTexManager; -import game.renderer.texture.TextureManager; -import game.renderer.texture.TextureMap; import game.rng.Random; +import game.sound.EventType; +import game.sound.PositionedSound; import game.util.CharValidator; import game.util.ExtMath; -import game.util.FileCallback; import game.util.FileUtils; -import game.util.PerfSection; -import game.util.Timing; import game.util.Util; import game.vars.BaseVar.VarFunction; import game.vars.BoolVar; @@ -135,14 +142,6 @@ import game.vars.StringVar; import game.vars.StringVar.StringFunction; import game.vars.Variable; import game.vars.Variable.IntType; -import game.window.Bind; -import game.window.Button; -import game.window.DisplayMode; -import game.window.KeyEvent; -import game.window.Keysym; -import game.window.Wheel; -import game.window.Window; -import game.window.WindowEvent; import game.world.BlockPos; import game.world.BoundingBox; import game.world.Chunk; @@ -2359,7 +2358,7 @@ public class Game implements IThreadListener { private void startSound(boolean load) { if(load) - SoundEvent.loadSounds(); + SoundManager.loadSounds(); audio = new AudioInterface(this.soundFrameSize, this.soundBufferSize, !this.soundEnabled); boolean started = audio.start(); Log.flushLog(); @@ -2585,7 +2584,7 @@ public class Game implements IThreadListener { if(func != null) { Bind.disableInput(key); if(!(this.open instanceof GuiLoading)) { - this.soundManager.playSound(new PositionedSound(SoundEvent.CLICK, Volume.GUI)); + this.soundManager.playSound(new PositionedSound(SoundEvent.CLICK, EventType.UI_INTERFACE)); func.runner.execute(key); } } @@ -2598,6 +2597,7 @@ public class Game implements IThreadListener { Util.checkOs(); Log.init(INSTANCE); Window.init(); + ModelBlock.setAsProvider(); Registry.setup("Render thread"); INSTANCE.run(); Window.end(); diff --git a/java/src/game/util/PerfSection.java b/java/src/client/PerfSection.java similarity index 96% rename from java/src/game/util/PerfSection.java rename to java/src/client/PerfSection.java index 581d4bd..f1f9bf5 100644 --- a/java/src/game/util/PerfSection.java +++ b/java/src/client/PerfSection.java @@ -1,4 +1,6 @@ -package game.util; +package client; + +import game.util.Util; public enum PerfSection { TIMING("Timing"), diff --git a/java/src/game/network/PlayerController.java b/java/src/client/PlayerController.java similarity index 99% rename from java/src/game/network/PlayerController.java rename to java/src/client/PlayerController.java index 1646602..1b6d07b 100755 --- a/java/src/game/network/PlayerController.java +++ b/java/src/client/PlayerController.java @@ -1,7 +1,5 @@ -package game.network; +package client; -import game.Game; -import game.audio.PositionedSound; import game.block.Block; import game.entity.Entity; import game.entity.npc.EntityNPC; @@ -11,10 +9,12 @@ import game.item.ItemBlock; import game.item.ItemControl; import game.item.ItemStack; import game.material.Material; +import game.network.ClientPlayer; import game.packet.CPacketAction; import game.packet.CPacketBreak; import game.packet.CPacketClick; import game.packet.CPacketPlace; +import game.sound.PositionedSound; import game.world.BlockPos; import game.world.Facing; import game.world.State; diff --git a/java/src/game/util/SkinConverter.java b/java/src/client/SkinConverter.java similarity index 99% rename from java/src/game/util/SkinConverter.java rename to java/src/client/SkinConverter.java index 5cb618f..c787066 100755 --- a/java/src/game/util/SkinConverter.java +++ b/java/src/client/SkinConverter.java @@ -1,4 +1,4 @@ -package game.util; +package client; import java.awt.Color; import java.awt.Graphics; diff --git a/java/src/game/util/Timing.java b/java/src/client/Timing.java similarity index 97% rename from java/src/game/util/Timing.java rename to java/src/client/Timing.java index 59f312d..96094f3 100644 --- a/java/src/game/util/Timing.java +++ b/java/src/client/Timing.java @@ -1,4 +1,4 @@ -package game.util; +package client; public class Timing { public static long tmr_timer; diff --git a/java/src/game/audio/AudioInterface.java b/java/src/client/audio/AudioInterface.java similarity index 99% rename from java/src/game/audio/AudioInterface.java rename to java/src/client/audio/AudioInterface.java index 1631cb7..a1f8654 100644 --- a/java/src/game/audio/AudioInterface.java +++ b/java/src/client/audio/AudioInterface.java @@ -1,4 +1,4 @@ -package game.audio; +package client.audio; import java.util.Arrays; import java.util.List; @@ -11,7 +11,6 @@ import javax.sound.sampled.LineUnavailableException; import javax.sound.sampled.SourceDataLine; import game.collect.Lists; - import game.log.Log; public class AudioInterface implements Runnable { diff --git a/java/src/game/audio/CodecJOrbis.java b/java/src/client/audio/CodecJOrbis.java similarity index 98% rename from java/src/game/audio/CodecJOrbis.java rename to java/src/client/audio/CodecJOrbis.java index 19a92cf..aa1bfe6 100644 --- a/java/src/game/audio/CodecJOrbis.java +++ b/java/src/client/audio/CodecJOrbis.java @@ -1,15 +1,16 @@ -package game.audio; +package client.audio; import java.io.IOException; import java.io.InputStream; -import game.audio.jogg.Packet; -import game.audio.jogg.Page; -import game.audio.jogg.StreamState; -import game.audio.jogg.SyncState; -import game.audio.jorbis.Block; -import game.audio.jorbis.Comment; -import game.audio.jorbis.DspState; -import game.audio.jorbis.Info; + +import client.audio.jogg.Packet; +import client.audio.jogg.Page; +import client.audio.jogg.StreamState; +import client.audio.jogg.SyncState; +import client.audio.jorbis.Block; +import client.audio.jorbis.Comment; +import client.audio.jorbis.DspState; +import client.audio.jorbis.Info; public class CodecJOrbis { diff --git a/java/src/game/audio/SoundManager.java b/java/src/client/audio/SoundManager.java similarity index 79% rename from java/src/game/audio/SoundManager.java rename to java/src/client/audio/SoundManager.java index d6d3f86..dfd1474 100755 --- a/java/src/game/audio/SoundManager.java +++ b/java/src/client/audio/SoundManager.java @@ -1,19 +1,28 @@ -package game.audio; +package client.audio; +import java.io.BufferedInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Map.Entry; +import client.Game; import game.collect.BiMap; import game.collect.HashBiMap; import game.collect.Lists; import game.collect.Maps; - -import game.Game; import game.entity.npc.EntityNPC; +import game.init.SoundEvent; +import game.log.Log; +import game.rng.Random; +import game.sound.MovingSound; +import game.sound.Sound; import game.util.ExtMath; +import game.util.FileUtils; public class SoundManager { private class Source { @@ -67,6 +76,9 @@ public class SoundManager { } } + private static final Random RANDOM = new Random(); + private static final Map BUFFERS = Maps.newEnumMap(SoundEvent.class); + private final Map playingSounds = HashBiMap.create(); private final Map invPlayingSounds = ((BiMap)this.playingSounds).inverse(); private final List tickableSounds = Lists.newArrayList(); @@ -85,6 +97,46 @@ public class SoundManager { public SoundManager(Game gm) { this.gm = gm; } + + public static void loadSounds() { + for(SoundEvent entry : SoundEvent.values()) { + short[][] buffers = new short[entry.getSounds().length][]; + for(int z = 0; z < entry.getSounds().length; z++) { + String sound = entry.getSounds()[z]; + Log.SOUND.trace("Lade Sound %s", sound); + buffers[z] = readOgg("sounds/" + sound + ".ogg"); + } + BUFFERS.put(entry, buffers); + } + } + + private static short[] readOgg(String filename) { + InputStream in = null; + try { + in = new BufferedInputStream(FileUtils.getResource(filename)); + return CodecJOrbis.readAll(in); + } + catch(FileNotFoundException e) { + Log.IO.error("Fehler beim Lesen von OPUS-Datei '%s': Datei nicht gefunden", filename); + return null; + } + catch(Exception e) { + Log.IO.error("Fehler beim Lesen von OPUS-Datei '%s': %s", filename, e.getMessage()); + return null; + } + finally { + try { + if(in != null) + in.close(); + } + catch(IOException e) { + } + } + } + + private static short[] getBuffer(SoundEvent event) { + return RANDOM.pick(BUFFERS.get(event)); + } public void unload() { @@ -183,7 +235,7 @@ public class SoundManager { if (volume > 0.0F) { String s = String.format("snd-%016x", this.eventId++); - this.sources.put(s, new Source(sound.getSoundLocation().getBuffer(), sound.getChannelType(), sound.canRepeat(), s, sound.getXPosF(), sound.getYPosF(), sound.getZPosF(), sound.getAttenuationType(), attn, volume)); + this.sources.put(s, new Source(getBuffer(sound.getSoundLocation()), Volume.getByType(sound.getChannelType()), sound.canRepeat(), s, sound.getXPosF(), sound.getYPosF(), sound.getZPosF(), sound.getAttenuationType(), attn, volume)); this.playingSoundsStopTime.put(s, this.playTime + 20); this.playingSounds.put(s, sound); if (sound instanceof MovingSound) diff --git a/java/src/game/audio/Volume.java b/java/src/client/audio/Volume.java similarity index 70% rename from java/src/game/audio/Volume.java rename to java/src/client/audio/Volume.java index 794ab45..d41e319 100644 --- a/java/src/game/audio/Volume.java +++ b/java/src/client/audio/Volume.java @@ -1,25 +1,45 @@ -package game.audio; +package client.audio; -import game.Game; +import client.Game; +import client.gui.element.Slider; import game.color.TextColor; -import game.gui.element.Slider; +import game.sound.EventType; import game.vars.CVar; import game.vars.CVarCategory; public enum Volume implements CVar { MASTER("master", "Gesamt"), MUSIC("music", "Musik"), - SFX("sfx", "Geräusche"), - GUI("gui", "Oberfläche"); + SFX("sfx", "Geräusche", EventType.SOUND_EFFECT), + GUI("gui", "Oberfläche", EventType.UI_INTERFACE); + + private static final Volume[] LOOKUP = new Volume[EventType.values().length]; public final String id; public final String name; + public final EventType type; private int value = 100; - private Volume(String id, String name) { + private Volume(String id, String name, EventType type) { this.id = id; this.name = name; + this.type = type; + } + + private Volume(String id, String name) { + this(id, name, null); + } + + static { + for(Volume volume : values()) { + if(volume.type != null) + LOOKUP[volume.type.ordinal()] = volume; + } + } + + public static Volume getByType(EventType type) { + return LOOKUP[type.ordinal()]; } public String getDisplay() { diff --git a/java/src/game/audio/jogg/Buffer.java b/java/src/client/audio/jogg/Buffer.java similarity index 99% rename from java/src/game/audio/jogg/Buffer.java rename to java/src/client/audio/jogg/Buffer.java index 761e609..68fe0fc 100644 --- a/java/src/game/audio/jogg/Buffer.java +++ b/java/src/client/audio/jogg/Buffer.java @@ -24,7 +24,7 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -package game.audio.jogg; +package client.audio.jogg; public class Buffer{ private static final int BUFFER_INCREMENT=256; diff --git a/java/src/game/audio/jogg/Packet.java b/java/src/client/audio/jogg/Packet.java similarity index 98% rename from java/src/game/audio/jogg/Packet.java rename to java/src/client/audio/jogg/Packet.java index 0ede86d..67c8e13 100644 --- a/java/src/game/audio/jogg/Packet.java +++ b/java/src/client/audio/jogg/Packet.java @@ -24,7 +24,7 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -package game.audio.jogg; +package client.audio.jogg; public class Packet{ public byte[] packet_base; diff --git a/java/src/game/audio/jogg/Page.java b/java/src/client/audio/jogg/Page.java similarity index 99% rename from java/src/game/audio/jogg/Page.java rename to java/src/client/audio/jogg/Page.java index a05a403..1b73823 100644 --- a/java/src/game/audio/jogg/Page.java +++ b/java/src/client/audio/jogg/Page.java @@ -24,7 +24,7 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -package game.audio.jogg; +package client.audio.jogg; public class Page{ private static int[] crc_lookup=new int[256]; diff --git a/java/src/game/audio/jogg/StreamState.java b/java/src/client/audio/jogg/StreamState.java similarity index 99% rename from java/src/game/audio/jogg/StreamState.java rename to java/src/client/audio/jogg/StreamState.java index 3339bb3..cc6452b 100644 --- a/java/src/game/audio/jogg/StreamState.java +++ b/java/src/client/audio/jogg/StreamState.java @@ -24,7 +24,7 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -package game.audio.jogg; +package client.audio.jogg; public class StreamState{ byte[] body_data; /* bytes from packet bodies */ diff --git a/java/src/game/audio/jogg/SyncState.java b/java/src/client/audio/jogg/SyncState.java similarity index 99% rename from java/src/game/audio/jogg/SyncState.java rename to java/src/client/audio/jogg/SyncState.java index 58e3743..10c86ea 100644 --- a/java/src/game/audio/jogg/SyncState.java +++ b/java/src/client/audio/jogg/SyncState.java @@ -24,7 +24,7 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -package game.audio.jogg; +package client.audio.jogg; // DECODING PRIMITIVES: packet streaming layer diff --git a/java/src/game/audio/jorbis/Block.java b/java/src/client/audio/jorbis/Block.java similarity index 97% rename from java/src/game/audio/jorbis/Block.java rename to java/src/client/audio/jorbis/Block.java index a96d2e2..249d4d6 100644 --- a/java/src/game/audio/jorbis/Block.java +++ b/java/src/client/audio/jorbis/Block.java @@ -24,9 +24,10 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -package game.audio.jorbis; +package client.audio.jorbis; -import game.audio.jogg.*; +import client.audio.jogg.Buffer; +import client.audio.jogg.Packet; public class Block{ ///necessary stream state for linking to the framing abstraction diff --git a/java/src/game/audio/jorbis/ChainingExample.java b/java/src/client/audio/jorbis/ChainingExample.java similarity index 98% rename from java/src/game/audio/jorbis/ChainingExample.java rename to java/src/client/audio/jorbis/ChainingExample.java index 1270c05..c1d9f3d 100644 --- a/java/src/game/audio/jorbis/ChainingExample.java +++ b/java/src/client/audio/jorbis/ChainingExample.java @@ -24,7 +24,7 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -package game.audio.jorbis; +package client.audio.jorbis; class ChainingExample{ public static void main(String[] arg){ diff --git a/java/src/game/audio/jorbis/CodeBook.java b/java/src/client/audio/jorbis/CodeBook.java similarity index 99% rename from java/src/game/audio/jorbis/CodeBook.java rename to java/src/client/audio/jorbis/CodeBook.java index 40ce7eb..1a85d95 100644 --- a/java/src/game/audio/jorbis/CodeBook.java +++ b/java/src/client/audio/jorbis/CodeBook.java @@ -24,9 +24,9 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -package game.audio.jorbis; +package client.audio.jorbis; -import game.audio.jogg.*; +import client.audio.jogg.Buffer; class CodeBook{ int dim; // codebook dimensions (elements per vector) diff --git a/java/src/game/audio/jorbis/Comment.java b/java/src/client/audio/jorbis/Comment.java similarity index 98% rename from java/src/game/audio/jorbis/Comment.java rename to java/src/client/audio/jorbis/Comment.java index 9ec44c8..85a2a92 100644 --- a/java/src/game/audio/jorbis/Comment.java +++ b/java/src/client/audio/jorbis/Comment.java @@ -24,9 +24,10 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -package game.audio.jorbis; +package client.audio.jorbis; -import game.audio.jogg.*; +import client.audio.jogg.Buffer; +import client.audio.jogg.Packet; // the comments are not part of vorbis_info so that vorbis_info can be // static storage diff --git a/java/src/game/audio/jorbis/DecodeExample.java b/java/src/client/audio/jorbis/DecodeExample.java similarity index 98% rename from java/src/game/audio/jorbis/DecodeExample.java rename to java/src/client/audio/jorbis/DecodeExample.java index 0d5e999..a96c14f 100644 --- a/java/src/game/audio/jorbis/DecodeExample.java +++ b/java/src/client/audio/jorbis/DecodeExample.java @@ -24,9 +24,12 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -package game.audio.jorbis; +package client.audio.jorbis; -import game.audio.jogg.*; +import client.audio.jogg.Packet; +import client.audio.jogg.Page; +import client.audio.jogg.StreamState; +import client.audio.jogg.SyncState; // Takes a vorbis bitstream from stdin and writes raw stereo PCM to // stdout. Decodes simple and chained OggVorbis files from beginning diff --git a/java/src/game/audio/jorbis/Drft.java b/java/src/client/audio/jorbis/Drft.java similarity index 99% rename from java/src/game/audio/jorbis/Drft.java rename to java/src/client/audio/jorbis/Drft.java index 052faea..1bdd82f 100644 --- a/java/src/game/audio/jorbis/Drft.java +++ b/java/src/client/audio/jorbis/Drft.java @@ -24,7 +24,7 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -package game.audio.jorbis; +package client.audio.jorbis; class Drft{ int n; diff --git a/java/src/game/audio/jorbis/DspState.java b/java/src/client/audio/jorbis/DspState.java similarity index 99% rename from java/src/game/audio/jorbis/DspState.java rename to java/src/client/audio/jorbis/DspState.java index 1115570..5ff952c 100644 --- a/java/src/game/audio/jorbis/DspState.java +++ b/java/src/client/audio/jorbis/DspState.java @@ -24,7 +24,7 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -package game.audio.jorbis; +package client.audio.jorbis; public class DspState{ static final float M_PI=3.1415926539f; diff --git a/java/src/game/audio/jorbis/Floor0.java b/java/src/client/audio/jorbis/Floor0.java similarity index 99% rename from java/src/game/audio/jorbis/Floor0.java rename to java/src/client/audio/jorbis/Floor0.java index 7a37aa7..17ab1fd 100644 --- a/java/src/game/audio/jorbis/Floor0.java +++ b/java/src/client/audio/jorbis/Floor0.java @@ -24,9 +24,9 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -package game.audio.jorbis; +package client.audio.jorbis; -import game.audio.jogg.*; +import client.audio.jogg.Buffer; class Floor0 extends FuncFloor{ diff --git a/java/src/game/audio/jorbis/Floor1.java b/java/src/client/audio/jorbis/Floor1.java similarity index 99% rename from java/src/game/audio/jorbis/Floor1.java rename to java/src/client/audio/jorbis/Floor1.java index 70bc6d6..1d7c0ce 100644 --- a/java/src/game/audio/jorbis/Floor1.java +++ b/java/src/client/audio/jorbis/Floor1.java @@ -24,9 +24,9 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -package game.audio.jorbis; +package client.audio.jorbis; -import game.audio.jogg.*; +import client.audio.jogg.Buffer; class Floor1 extends FuncFloor{ static final int floor1_rangedb=140; diff --git a/java/src/game/audio/jorbis/FuncFloor.java b/java/src/client/audio/jorbis/FuncFloor.java similarity index 96% rename from java/src/game/audio/jorbis/FuncFloor.java rename to java/src/client/audio/jorbis/FuncFloor.java index 81b1cc1..1abc43c 100644 --- a/java/src/game/audio/jorbis/FuncFloor.java +++ b/java/src/client/audio/jorbis/FuncFloor.java @@ -24,9 +24,9 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -package game.audio.jorbis; +package client.audio.jorbis; -import game.audio.jogg.*; +import client.audio.jogg.Buffer; abstract class FuncFloor{ diff --git a/java/src/game/audio/jorbis/FuncMapping.java b/java/src/client/audio/jorbis/FuncMapping.java similarity index 95% rename from java/src/game/audio/jorbis/FuncMapping.java rename to java/src/client/audio/jorbis/FuncMapping.java index 2d94876..aa18945 100644 --- a/java/src/game/audio/jorbis/FuncMapping.java +++ b/java/src/client/audio/jorbis/FuncMapping.java @@ -24,9 +24,9 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -package game.audio.jorbis; +package client.audio.jorbis; -import game.audio.jogg.*; +import client.audio.jogg.Buffer; abstract class FuncMapping{ public static FuncMapping[] mapping_P= {new Mapping0()}; diff --git a/java/src/game/audio/jorbis/FuncResidue.java b/java/src/client/audio/jorbis/FuncResidue.java similarity index 96% rename from java/src/game/audio/jorbis/FuncResidue.java rename to java/src/client/audio/jorbis/FuncResidue.java index d0b7aaf..2c405ba 100644 --- a/java/src/game/audio/jorbis/FuncResidue.java +++ b/java/src/client/audio/jorbis/FuncResidue.java @@ -24,9 +24,9 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -package game.audio.jorbis; +package client.audio.jorbis; -import game.audio.jogg.*; +import client.audio.jogg.Buffer; abstract class FuncResidue{ public static FuncResidue[] residue_P= {new Residue0(), new Residue1(), diff --git a/java/src/game/audio/jorbis/FuncTime.java b/java/src/client/audio/jorbis/FuncTime.java similarity index 95% rename from java/src/game/audio/jorbis/FuncTime.java rename to java/src/client/audio/jorbis/FuncTime.java index f0ea437..7ba4a6b 100644 --- a/java/src/game/audio/jorbis/FuncTime.java +++ b/java/src/client/audio/jorbis/FuncTime.java @@ -24,9 +24,9 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -package game.audio.jorbis; +package client.audio.jorbis; -import game.audio.jogg.*; +import client.audio.jogg.Buffer; abstract class FuncTime{ public static FuncTime[] time_P= {new Time0()}; diff --git a/java/src/game/audio/jorbis/Info.java b/java/src/client/audio/jorbis/Info.java similarity index 99% rename from java/src/game/audio/jorbis/Info.java rename to java/src/client/audio/jorbis/Info.java index e37fac2..077ec0e 100644 --- a/java/src/game/audio/jorbis/Info.java +++ b/java/src/client/audio/jorbis/Info.java @@ -24,9 +24,10 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -package game.audio.jorbis; +package client.audio.jorbis; -import game.audio.jogg.*; +import client.audio.jogg.Buffer; +import client.audio.jogg.Packet; public class Info{ private static final int OV_EBADPACKET=-136; diff --git a/java/src/game/audio/jorbis/InfoMode.java b/java/src/client/audio/jorbis/InfoMode.java similarity index 97% rename from java/src/game/audio/jorbis/InfoMode.java rename to java/src/client/audio/jorbis/InfoMode.java index 2125bc5..3945476 100644 --- a/java/src/game/audio/jorbis/InfoMode.java +++ b/java/src/client/audio/jorbis/InfoMode.java @@ -24,7 +24,7 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -package game.audio.jorbis; +package client.audio.jorbis; class InfoMode{ int blockflag; diff --git a/java/src/game/audio/jorbis/JOrbisException.java b/java/src/client/audio/jorbis/JOrbisException.java similarity index 97% rename from java/src/game/audio/jorbis/JOrbisException.java rename to java/src/client/audio/jorbis/JOrbisException.java index a6a2433..a58a772 100644 --- a/java/src/game/audio/jorbis/JOrbisException.java +++ b/java/src/client/audio/jorbis/JOrbisException.java @@ -24,7 +24,7 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -package game.audio.jorbis; +package client.audio.jorbis; public class JOrbisException extends Exception{ diff --git a/java/src/game/audio/jorbis/Lookup.java b/java/src/client/audio/jorbis/Lookup.java similarity index 99% rename from java/src/game/audio/jorbis/Lookup.java rename to java/src/client/audio/jorbis/Lookup.java index b539615..4838f08 100644 --- a/java/src/game/audio/jorbis/Lookup.java +++ b/java/src/client/audio/jorbis/Lookup.java @@ -24,7 +24,7 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -package game.audio.jorbis; +package client.audio.jorbis; class Lookup{ static final int COS_LOOKUP_SZ=128; diff --git a/java/src/game/audio/jorbis/Lpc.java b/java/src/client/audio/jorbis/Lpc.java similarity index 99% rename from java/src/game/audio/jorbis/Lpc.java rename to java/src/client/audio/jorbis/Lpc.java index 5a456f0..58e0e76 100644 --- a/java/src/game/audio/jorbis/Lpc.java +++ b/java/src/client/audio/jorbis/Lpc.java @@ -24,7 +24,7 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -package game.audio.jorbis; +package client.audio.jorbis; class Lpc{ // en/decode lookups diff --git a/java/src/game/audio/jorbis/Lsp.java b/java/src/client/audio/jorbis/Lsp.java similarity index 99% rename from java/src/game/audio/jorbis/Lsp.java rename to java/src/client/audio/jorbis/Lsp.java index 182e693..8a2c002 100644 --- a/java/src/game/audio/jorbis/Lsp.java +++ b/java/src/client/audio/jorbis/Lsp.java @@ -24,7 +24,7 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -package game.audio.jorbis; +package client.audio.jorbis; /* function: LSP (also called LSF) conversion routines diff --git a/java/src/game/audio/jorbis/Mapping0.java b/java/src/client/audio/jorbis/Mapping0.java similarity index 99% rename from java/src/game/audio/jorbis/Mapping0.java rename to java/src/client/audio/jorbis/Mapping0.java index b679be9..808970f 100644 --- a/java/src/game/audio/jorbis/Mapping0.java +++ b/java/src/client/audio/jorbis/Mapping0.java @@ -24,9 +24,9 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -package game.audio.jorbis; +package client.audio.jorbis; -import game.audio.jogg.*; +import client.audio.jogg.Buffer; class Mapping0 extends FuncMapping{ static int seq=0; diff --git a/java/src/game/audio/jorbis/Mdct.java b/java/src/client/audio/jorbis/Mdct.java similarity index 99% rename from java/src/game/audio/jorbis/Mdct.java rename to java/src/client/audio/jorbis/Mdct.java index 1a82a68..390fc22 100644 --- a/java/src/game/audio/jorbis/Mdct.java +++ b/java/src/client/audio/jorbis/Mdct.java @@ -24,7 +24,7 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -package game.audio.jorbis; +package client.audio.jorbis; class Mdct{ diff --git a/java/src/game/audio/jorbis/PsyInfo.java b/java/src/client/audio/jorbis/PsyInfo.java similarity index 98% rename from java/src/game/audio/jorbis/PsyInfo.java rename to java/src/client/audio/jorbis/PsyInfo.java index cedd892..f5e8665 100644 --- a/java/src/game/audio/jorbis/PsyInfo.java +++ b/java/src/client/audio/jorbis/PsyInfo.java @@ -24,7 +24,7 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -package game.audio.jorbis; +package client.audio.jorbis; // psychoacoustic setup class PsyInfo{ diff --git a/java/src/game/audio/jorbis/PsyLook.java b/java/src/client/audio/jorbis/PsyLook.java similarity index 97% rename from java/src/game/audio/jorbis/PsyLook.java rename to java/src/client/audio/jorbis/PsyLook.java index 70285ef..5fa57ad 100644 --- a/java/src/game/audio/jorbis/PsyLook.java +++ b/java/src/client/audio/jorbis/PsyLook.java @@ -24,7 +24,7 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -package game.audio.jorbis; +package client.audio.jorbis; class PsyLook{ int n; diff --git a/java/src/game/audio/jorbis/Residue0.java b/java/src/client/audio/jorbis/Residue0.java similarity index 99% rename from java/src/game/audio/jorbis/Residue0.java rename to java/src/client/audio/jorbis/Residue0.java index 6ba0e90..6af8a9c 100644 --- a/java/src/game/audio/jorbis/Residue0.java +++ b/java/src/client/audio/jorbis/Residue0.java @@ -24,9 +24,9 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -package game.audio.jorbis; +package client.audio.jorbis; -import game.audio.jogg.*; +import client.audio.jogg.Buffer; class Residue0 extends FuncResidue{ void pack(Object vr, Buffer opb){ diff --git a/java/src/game/audio/jorbis/Residue1.java b/java/src/client/audio/jorbis/Residue1.java similarity index 97% rename from java/src/game/audio/jorbis/Residue1.java rename to java/src/client/audio/jorbis/Residue1.java index d0ac707..8072ce6 100644 --- a/java/src/game/audio/jorbis/Residue1.java +++ b/java/src/client/audio/jorbis/Residue1.java @@ -24,7 +24,7 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -package game.audio.jorbis; +package client.audio.jorbis; class Residue1 extends Residue0{ diff --git a/java/src/game/audio/jorbis/Residue2.java b/java/src/client/audio/jorbis/Residue2.java similarity index 97% rename from java/src/game/audio/jorbis/Residue2.java rename to java/src/client/audio/jorbis/Residue2.java index 6c19867..b1875da 100644 --- a/java/src/game/audio/jorbis/Residue2.java +++ b/java/src/client/audio/jorbis/Residue2.java @@ -24,7 +24,7 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -package game.audio.jorbis; +package client.audio.jorbis; class Residue2 extends Residue0{ diff --git a/java/src/game/audio/jorbis/StaticCodeBook.java b/java/src/client/audio/jorbis/StaticCodeBook.java similarity index 99% rename from java/src/game/audio/jorbis/StaticCodeBook.java rename to java/src/client/audio/jorbis/StaticCodeBook.java index a32e458..9452a85 100644 --- a/java/src/game/audio/jorbis/StaticCodeBook.java +++ b/java/src/client/audio/jorbis/StaticCodeBook.java @@ -24,9 +24,9 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -package game.audio.jorbis; +package client.audio.jorbis; -import game.audio.jogg.*; +import client.audio.jogg.Buffer; class StaticCodeBook{ int dim; // codebook dimensions (elements per vector) diff --git a/java/src/game/audio/jorbis/Time0.java b/java/src/client/audio/jorbis/Time0.java similarity index 95% rename from java/src/game/audio/jorbis/Time0.java rename to java/src/client/audio/jorbis/Time0.java index 6c64b3e..af2b2fb 100644 --- a/java/src/game/audio/jorbis/Time0.java +++ b/java/src/client/audio/jorbis/Time0.java @@ -24,9 +24,9 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -package game.audio.jorbis; +package client.audio.jorbis; -import game.audio.jogg.*; +import client.audio.jogg.Buffer; class Time0 extends FuncTime{ void pack(Object i, Buffer opb){ diff --git a/java/src/game/audio/jorbis/Util.java b/java/src/client/audio/jorbis/Util.java similarity index 92% rename from java/src/game/audio/jorbis/Util.java rename to java/src/client/audio/jorbis/Util.java index ce82e07..5fd283b 100644 --- a/java/src/game/audio/jorbis/Util.java +++ b/java/src/client/audio/jorbis/Util.java @@ -1,4 +1,4 @@ -package game.audio.jorbis; +package client.audio.jorbis; class Util{ static int ilog(int v){ diff --git a/java/src/game/audio/jorbis/VorbisFile.java b/java/src/client/audio/jorbis/VorbisFile.java similarity index 99% rename from java/src/game/audio/jorbis/VorbisFile.java rename to java/src/client/audio/jorbis/VorbisFile.java index 0d5cbf7..54dade8 100644 --- a/java/src/game/audio/jorbis/VorbisFile.java +++ b/java/src/client/audio/jorbis/VorbisFile.java @@ -25,13 +25,15 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -package game.audio.jorbis; - -import java.io.InputStream; - -import game.audio.jogg.*; +package client.audio.jorbis; import java.io.IOException; +import java.io.InputStream; + +import client.audio.jogg.Packet; +import client.audio.jogg.Page; +import client.audio.jogg.StreamState; +import client.audio.jogg.SyncState; public class VorbisFile{ static final int CHUNKSIZE=8500; diff --git a/java/src/game/util/FileCallback.java b/java/src/client/gui/FileCallback.java similarity index 79% rename from java/src/game/util/FileCallback.java rename to java/src/client/gui/FileCallback.java index 0c840c7..82f57d5 100644 --- a/java/src/game/util/FileCallback.java +++ b/java/src/client/gui/FileCallback.java @@ -1,4 +1,4 @@ -package game.util; +package client.gui; import java.io.File; diff --git a/java/src/game/gui/Font.java b/java/src/client/gui/Font.java similarity index 96% rename from java/src/game/gui/Font.java rename to java/src/client/gui/Font.java index f72e210..adfe7fc 100644 --- a/java/src/game/gui/Font.java +++ b/java/src/client/gui/Font.java @@ -1,4 +1,4 @@ -package game.gui; +package client.gui; import java.awt.image.BufferedImage; import java.io.FileNotFoundException; @@ -6,9 +6,9 @@ import java.io.IOException; import org.lwjgl.opengl.GL11; +import client.renderer.GlState; +import client.renderer.texture.TextureUtil; import game.log.Log; -import game.renderer.GlState; -import game.renderer.texture.TextureUtil; import game.util.FileUtils; public class Font { diff --git a/java/src/game/gui/FontChar.java b/java/src/client/gui/FontChar.java similarity index 91% rename from java/src/game/gui/FontChar.java rename to java/src/client/gui/FontChar.java index 74a4d7e..1d39db4 100644 --- a/java/src/game/gui/FontChar.java +++ b/java/src/client/gui/FontChar.java @@ -1,4 +1,4 @@ -package game.gui; +package client.gui; public class FontChar { public final byte s; diff --git a/java/src/game/util/Formatter.java b/java/src/client/gui/Formatter.java similarity index 57% rename from java/src/game/util/Formatter.java rename to java/src/client/gui/Formatter.java index d14563e..a551198 100644 --- a/java/src/game/util/Formatter.java +++ b/java/src/client/gui/Formatter.java @@ -1,6 +1,6 @@ -package game.util; +package client.gui; -import game.gui.element.Element; +import client.gui.element.Element; public interface Formatter { String use(T elem); diff --git a/java/src/game/gui/Gui.java b/java/src/client/gui/Gui.java similarity index 97% rename from java/src/game/gui/Gui.java rename to java/src/client/gui/Gui.java index a719e0a..cb39cb5 100644 --- a/java/src/game/gui/Gui.java +++ b/java/src/client/gui/Gui.java @@ -1,21 +1,20 @@ -package game.gui; +package client.gui; import java.util.List; import org.lwjgl.opengl.GL13; +import client.Game; +import client.gui.element.Dropdown; +import client.gui.element.Dropdown.Handle; +import client.gui.element.Element; +import client.renderer.Drawing; +import client.renderer.GlState; +import client.window.Bind; +import client.window.Button; +import client.window.Keysym; import game.collect.Lists; -import game.Game; -import game.gui.element.Dropdown; -import game.gui.element.Dropdown.Handle; -import game.gui.element.Element; -import game.renderer.Drawing; -import game.renderer.GlState; -import game.window.Bind; -import game.window.Button; -import game.window.Keysym; - public abstract class Gui { public static final String DIRT_BACKGROUND = "textures/background.png"; public static final int HOVER_COLOR = 0x288080ff; diff --git a/java/src/game/gui/GuiConfirm.java b/java/src/client/gui/GuiConfirm.java similarity index 87% rename from java/src/game/gui/GuiConfirm.java rename to java/src/client/gui/GuiConfirm.java index b272826..5a4a907 100755 --- a/java/src/game/gui/GuiConfirm.java +++ b/java/src/client/gui/GuiConfirm.java @@ -1,9 +1,9 @@ -package game.gui; +package client.gui; -import game.gui.element.ActButton; -import game.gui.element.ActButton.Mode; -import game.gui.element.Label; -import game.gui.element.TransparentBox; +import client.gui.element.ActButton; +import client.gui.element.ActButton.Mode; +import client.gui.element.Label; +import client.gui.element.TransparentBox; public class GuiConfirm extends Gui implements ActButton.Callback { public static interface Callback { diff --git a/java/src/game/gui/GuiConnect.java b/java/src/client/gui/GuiConnect.java similarity index 97% rename from java/src/game/gui/GuiConnect.java rename to java/src/client/gui/GuiConnect.java index b1dabd1..05ae015 100644 --- a/java/src/game/gui/GuiConnect.java +++ b/java/src/client/gui/GuiConnect.java @@ -1,19 +1,20 @@ -package game.gui; +package client.gui; import java.io.File; import java.text.SimpleDateFormat; import java.util.Collections; import java.util.Date; + +import client.gui.element.ActButton; +import client.gui.element.ActButton.Mode; +import client.gui.element.GuiList; +import client.gui.element.ListEntry; +import client.gui.element.NavButton; +import client.renderer.Drawing; import game.color.TextColor; -import game.gui.element.ActButton; -import game.gui.element.ActButton.Mode; -import game.gui.element.GuiList; -import game.gui.element.ListEntry; -import game.gui.element.NavButton; import game.init.Config; import game.log.Log; import game.network.Player; -import game.renderer.Drawing; import game.util.FileUtils; import game.util.Tuple; import game.util.Util; diff --git a/java/src/game/gui/GuiConsole.java b/java/src/client/gui/GuiConsole.java similarity index 97% rename from java/src/game/gui/GuiConsole.java rename to java/src/client/gui/GuiConsole.java index 28e776c..a625119 100644 --- a/java/src/game/gui/GuiConsole.java +++ b/java/src/client/gui/GuiConsole.java @@ -1,22 +1,21 @@ -package game.gui; +package client.gui; import java.util.List; +import client.Game; +import client.gui.element.ActButton; +import client.gui.element.Fill; +import client.gui.element.Textbox; +import client.gui.element.Textbox.Action; +import client.gui.element.TransparentBox; +import client.window.Keysym; import game.collect.Lists; - -import game.Game; import game.color.TextColor; -import game.gui.element.ActButton; -import game.gui.element.Fill; -import game.gui.element.Textbox; -import game.gui.element.Textbox.Action; -import game.gui.element.TransparentBox; import game.network.Player; import game.packet.CPacketComplete; import game.util.ExtMath; import game.vars.BoolVar; import game.vars.CVar; -import game.window.Keysym; import game.world.BlockPos; import game.world.HitPosition; diff --git a/java/src/game/gui/GuiConvert.java b/java/src/client/gui/GuiConvert.java similarity index 95% rename from java/src/game/gui/GuiConvert.java rename to java/src/client/gui/GuiConvert.java index 1d15ac6..e4b49e8 100755 --- a/java/src/game/gui/GuiConvert.java +++ b/java/src/client/gui/GuiConvert.java @@ -1,21 +1,21 @@ -package game.gui; +package client.gui; import java.io.File; import java.io.FileFilter; import java.text.SimpleDateFormat; import java.util.Collections; import java.util.Date; -import game.Game.FileMode; + +import client.Game.FileMode; +import client.gui.element.ActButton; +import client.gui.element.ActButton.Mode; +import client.gui.element.GuiList; +import client.gui.element.ListEntry; +import client.gui.element.NavButton; +import client.renderer.Drawing; import game.color.TextColor; import game.dimension.Space; -import game.gui.element.ActButton; -import game.gui.element.ActButton.Mode; -import game.gui.element.GuiList; -import game.gui.element.ListEntry; -import game.gui.element.NavButton; import game.log.Log; -import game.renderer.Drawing; -import game.util.FileCallback; import game.world.Converter; import game.world.Converter.SaveVersion; import game.world.Region; diff --git a/java/src/game/gui/GuiInfo.java b/java/src/client/gui/GuiInfo.java similarity index 98% rename from java/src/game/gui/GuiInfo.java rename to java/src/client/gui/GuiInfo.java index 904620d..243e111 100644 --- a/java/src/game/gui/GuiInfo.java +++ b/java/src/client/gui/GuiInfo.java @@ -1,8 +1,8 @@ -package game.gui; +package client.gui; +import client.gui.element.NavButton; +import client.gui.element.TransparentBox; import game.color.TextColor; -import game.gui.element.NavButton; -import game.gui.element.TransparentBox; import game.init.Config; import game.log.Log; diff --git a/java/src/game/gui/GuiLoading.java b/java/src/client/gui/GuiLoading.java similarity index 96% rename from java/src/game/gui/GuiLoading.java rename to java/src/client/gui/GuiLoading.java index 60120f9..d1750bd 100644 --- a/java/src/game/gui/GuiLoading.java +++ b/java/src/client/gui/GuiLoading.java @@ -1,8 +1,8 @@ -package game.gui; +package client.gui; -import game.Game; -import game.gui.element.Bar; -import game.gui.element.Label; +import client.Game; +import client.gui.element.Bar; +import client.gui.element.Label; public class GuiLoading extends Gui { public static interface Callback { diff --git a/java/src/game/gui/GuiMenu.java b/java/src/client/gui/GuiMenu.java similarity index 95% rename from java/src/game/gui/GuiMenu.java rename to java/src/client/gui/GuiMenu.java index 88cd839..9037467 100644 --- a/java/src/game/gui/GuiMenu.java +++ b/java/src/client/gui/GuiMenu.java @@ -1,21 +1,20 @@ -package game.gui; +package client.gui; +import client.Timing; +import client.gui.character.GuiChar; +import client.gui.character.GuiCharacters; +import client.gui.element.ActButton; +import client.gui.element.ActButton.Mode; +import client.gui.element.Label; +import client.gui.element.NavButton; +import client.gui.element.Textbox; +import client.gui.options.GuiOptions; +import client.renderer.Drawing; +import client.window.Keysym; import game.color.TextColor; -import game.gui.character.GuiChar; -import game.gui.character.GuiCharacters; -import game.gui.element.ActButton; -import game.gui.element.ActButton.Mode; -import game.gui.element.Label; -import game.gui.element.NavButton; -import game.gui.element.Textbox; -import game.gui.options.GuiOptions; import game.init.Config; -import game.renderer.Drawing; import game.rng.Random; import game.util.ExtMath; -import game.util.Splashes; -import game.util.Timing; -import game.window.Keysym; public class GuiMenu extends Gui { public static final GuiMenu INSTANCE = new GuiMenu(); diff --git a/java/src/game/gui/GuiServer.java b/java/src/client/gui/GuiServer.java similarity index 95% rename from java/src/game/gui/GuiServer.java rename to java/src/client/gui/GuiServer.java index e0ba390..c6d256c 100644 --- a/java/src/game/gui/GuiServer.java +++ b/java/src/client/gui/GuiServer.java @@ -1,12 +1,12 @@ -package game.gui; +package client.gui; +import client.gui.GuiConnect.ServerInfo; +import client.gui.element.ActButton; +import client.gui.element.Label; +import client.gui.element.NavButton; +import client.gui.element.Textbox; +import client.gui.element.Textbox.Action; import game.color.TextColor; -import game.gui.GuiConnect.ServerInfo; -import game.gui.element.ActButton; -import game.gui.element.Label; -import game.gui.element.NavButton; -import game.gui.element.Textbox; -import game.gui.element.Textbox.Action; import game.init.Config; import game.network.Player; import game.vars.CVarCategory; diff --git a/java/src/game/util/Splashes.java b/java/src/client/gui/Splashes.java similarity index 99% rename from java/src/game/util/Splashes.java rename to java/src/client/gui/Splashes.java index 47a33c6..78711ab 100644 --- a/java/src/game/util/Splashes.java +++ b/java/src/client/gui/Splashes.java @@ -1,4 +1,4 @@ -package game.util; +package client.gui; public abstract class Splashes { public static final String[] SPLASHES = { diff --git a/java/src/game/gui/Style.java b/java/src/client/gui/Style.java similarity index 96% rename from java/src/game/gui/Style.java rename to java/src/client/gui/Style.java index cd69dd2..841b495 100644 --- a/java/src/game/gui/Style.java +++ b/java/src/client/gui/Style.java @@ -1,12 +1,12 @@ -package game.gui; +package client.gui; -import game.properties.IStringSerializable; import game.util.Displayable; +import game.util.Identifyable; import game.vars.CVarCategory; import game.vars.Variable; import game.vars.Variable.IntType; -public enum Style implements IStringSerializable, Displayable { +public enum Style implements Identifyable, Displayable { DEFAULT("default", "Standard"), SHINY("shiny", "Glänzend"), GRAY("gray", "Grau"), BLUE("blue", "Blau"), CUSTOM("custom", "Angepasst"); public final String id; diff --git a/java/src/game/gui/character/GuiChar.java b/java/src/client/gui/character/GuiChar.java similarity index 96% rename from java/src/game/gui/character/GuiChar.java rename to java/src/client/gui/character/GuiChar.java index b2d9b5a..4def730 100755 --- a/java/src/game/gui/character/GuiChar.java +++ b/java/src/client/gui/character/GuiChar.java @@ -1,4 +1,4 @@ -package game.gui.character; +package client.gui.character; import java.awt.image.BufferedImage; import java.io.File; @@ -8,13 +8,34 @@ import java.io.IOException; import java.io.InputStream; import java.nio.file.Files; import java.util.Arrays; + import javax.imageio.ImageIO; import org.lwjgl.opengl.GL11; import org.lwjgl.opengl.GL13; -import game.Game; -import game.Game.FileMode; +import client.Game; +import client.Game.FileMode; +import client.SkinConverter; +import client.gui.FileCallback; +import client.gui.GuiLoading; +import client.gui.element.ActButton; +import client.gui.element.ActButton.Mode; +import client.gui.element.Element; +import client.gui.element.GuiList; +import client.gui.element.Label; +import client.gui.element.ListEntry; +import client.gui.element.NavButton; +import client.gui.element.Slider; +import client.gui.element.Textbox; +import client.gui.element.Textbox.Action; +import client.gui.element.TransparentBox; +import client.renderer.Drawing; +import client.renderer.GlState; +import client.renderer.ItemRenderer; +import client.renderer.entity.RenderManager; +import client.renderer.texture.EntityTexManager; +import client.window.Button; import game.collect.Lists; import game.dimension.DimType; import game.dimension.Dimension; @@ -24,45 +45,25 @@ import game.entity.npc.EntityHuman; import game.entity.npc.EntityNPC; import game.entity.npc.SpeciesInfo; import game.entity.types.EntityLiving; -import game.gui.GuiLoading; -import game.gui.element.ActButton; -import game.gui.element.ActButton.Mode; -import game.gui.element.Element; -import game.gui.element.GuiList; -import game.gui.element.Label; -import game.gui.element.ListEntry; -import game.gui.element.NavButton; -import game.gui.element.Slider; -import game.gui.element.Textbox; -import game.gui.element.TransparentBox; -import game.gui.element.Textbox.Action; import game.init.EntityEggInfo; import game.init.EntityRegistry; import game.init.SpeciesRegistry; -import game.init.UniverseRegistry; import game.init.SpeciesRegistry.ModelType; +import game.init.UniverseRegistry; import game.log.Log; import game.network.Player; import game.packet.CPacketAction; import game.packet.CPacketMessage; import game.packet.CPacketSkin; -import game.properties.IStringSerializable; -import game.renderer.Drawing; -import game.renderer.GlState; -import game.renderer.ItemRenderer; -import game.renderer.entity.RenderManager; -import game.renderer.texture.EntityTexManager; import game.rng.Random; import game.util.Displayable; -import game.util.FileCallback; import game.util.FileUtils; -import game.util.SkinConverter; +import game.util.Identifyable; import game.util.Util; import game.vars.CVarCategory; import game.vars.EnumVar; import game.vars.EnumVar.EnumFunction; import game.vars.Variable; -import game.window.Button; public class GuiChar extends GuiList { @@ -206,7 +207,7 @@ public class GuiChar extends GuiList } } - public static enum FilterType implements IStringSerializable, Displayable { + public static enum FilterType implements Identifyable, Displayable { ALL("all", "Alle anzeigen"), CUSTOM("custom", "Nur eigene"), NPC("preset", "Nur vorgegebene"), SPECIES("species", "Nur Spezies"), SPECIES_CUSTOM("species_custom", "Spezies und eigene"); private final String name; diff --git a/java/src/game/gui/character/GuiCharacters.java b/java/src/client/gui/character/GuiCharacters.java similarity index 93% rename from java/src/game/gui/character/GuiCharacters.java rename to java/src/client/gui/character/GuiCharacters.java index 04f800d..f6614b4 100644 --- a/java/src/game/gui/character/GuiCharacters.java +++ b/java/src/client/gui/character/GuiCharacters.java @@ -1,17 +1,17 @@ -package game.gui.character; +package client.gui.character; +import client.gui.GuiConfirm; +import client.gui.GuiMenu; +import client.gui.element.ActButton; +import client.gui.element.ActButton.Mode; +import client.gui.element.GuiList; +import client.gui.element.ListEntry; +import client.gui.element.NavButton; +import client.gui.element.TransparentBox; +import client.renderer.Drawing; import game.color.TextColor; import game.entity.npc.PlayerCharacter; -import game.gui.GuiConfirm; -import game.gui.GuiMenu; -import game.gui.element.ActButton; -import game.gui.element.ActButton.Mode; -import game.gui.element.GuiList; -import game.gui.element.ListEntry; -import game.gui.element.NavButton; -import game.gui.element.TransparentBox; import game.packet.CPacketAction; -import game.renderer.Drawing; public class GuiCharacters extends GuiList implements ActButton.Callback { diff --git a/java/src/game/gui/character/GuiClass.java b/java/src/client/gui/character/GuiClass.java similarity index 90% rename from java/src/game/gui/character/GuiClass.java rename to java/src/client/gui/character/GuiClass.java index d82db44..f3e6559 100644 --- a/java/src/game/gui/character/GuiClass.java +++ b/java/src/client/gui/character/GuiClass.java @@ -1,12 +1,12 @@ -package game.gui.character; +package client.gui.character; -import game.gui.element.ActButton; -import game.gui.element.ActButton.Mode; -import game.gui.element.GuiList; -import game.gui.element.ListEntry; -import game.gui.element.NavButton; +import client.gui.element.ActButton; +import client.gui.element.ActButton.Mode; +import client.gui.element.GuiList; +import client.gui.element.ListEntry; +import client.gui.element.NavButton; +import client.renderer.Drawing; import game.packet.CPacketAction; -import game.renderer.Drawing; public class GuiClass extends GuiList implements ActButton.Callback { diff --git a/java/src/game/gui/character/GuiSpecies.java b/java/src/client/gui/character/GuiSpecies.java similarity index 90% rename from java/src/game/gui/character/GuiSpecies.java rename to java/src/client/gui/character/GuiSpecies.java index 33e03d6..385f5be 100644 --- a/java/src/game/gui/character/GuiSpecies.java +++ b/java/src/client/gui/character/GuiSpecies.java @@ -1,15 +1,15 @@ -package game.gui.character; +package client.gui.character; +import client.gui.element.ActButton; +import client.gui.element.ActButton.Mode; +import client.gui.element.GuiList; +import client.gui.element.ListEntry; +import client.gui.element.NavButton; +import client.renderer.Drawing; import game.entity.npc.SpeciesInfo; -import game.gui.element.ActButton; -import game.gui.element.ActButton.Mode; -import game.gui.element.GuiList; -import game.gui.element.ListEntry; -import game.gui.element.NavButton; import game.init.EntityRegistry; import game.init.SpeciesRegistry; import game.packet.CPacketAction; -import game.renderer.Drawing; public class GuiSpecies extends GuiList implements ActButton.Callback { diff --git a/java/src/game/gui/container/GuiBrewing.java b/java/src/client/gui/container/GuiBrewing.java similarity index 97% rename from java/src/game/gui/container/GuiBrewing.java rename to java/src/client/gui/container/GuiBrewing.java index 93530ba..73f2b15 100755 --- a/java/src/game/gui/container/GuiBrewing.java +++ b/java/src/client/gui/container/GuiBrewing.java @@ -1,4 +1,4 @@ -package game.gui.container; +package client.gui.container; import game.inventory.ContainerBrewingStand; import game.inventory.IInventory; diff --git a/java/src/game/gui/container/GuiChest.java b/java/src/client/gui/container/GuiChest.java similarity index 97% rename from java/src/game/gui/container/GuiChest.java rename to java/src/client/gui/container/GuiChest.java index 6adb0d9..1f7e912 100755 --- a/java/src/game/gui/container/GuiChest.java +++ b/java/src/client/gui/container/GuiChest.java @@ -1,6 +1,6 @@ -package game.gui.container; +package client.gui.container; -import game.Game; +import client.Game; import game.inventory.ContainerChest; import game.inventory.IInventory; diff --git a/java/src/game/gui/container/GuiContainer.java b/java/src/client/gui/container/GuiContainer.java similarity index 99% rename from java/src/game/gui/container/GuiContainer.java rename to java/src/client/gui/container/GuiContainer.java index d4bc825..69dc168 100755 --- a/java/src/game/gui/container/GuiContainer.java +++ b/java/src/client/gui/container/GuiContainer.java @@ -1,4 +1,4 @@ -package game.gui.container; +package client.gui.container; import java.util.List; import java.util.Set; @@ -6,24 +6,23 @@ import java.util.Set; import org.lwjgl.opengl.GL11; import org.lwjgl.opengl.GL13; +import client.gui.Gui; +import client.gui.element.InventoryButton; +import client.renderer.Drawing; +import client.renderer.GlState; +import client.renderer.ItemRenderer; +import client.renderer.entity.RenderItem; +import client.window.Button; import game.collect.Lists; import game.collect.Sets; - import game.color.TextColor; -import game.gui.Gui; -import game.gui.element.InventoryButton; import game.inventory.Container; import game.inventory.InventoryPlayer; import game.inventory.Slot; import game.item.CheatTab; import game.item.ItemStack; import game.packet.CPacketCheat; -import game.renderer.Drawing; -import game.renderer.GlState; -import game.renderer.ItemRenderer; -import game.renderer.entity.RenderItem; import game.util.ExtMath; -import game.window.Button; public abstract class GuiContainer extends Gui { diff --git a/java/src/game/gui/container/GuiCrafting.java b/java/src/client/gui/container/GuiCrafting.java similarity index 97% rename from java/src/game/gui/container/GuiCrafting.java rename to java/src/client/gui/container/GuiCrafting.java index 0dbe12c..b9fb6e2 100755 --- a/java/src/game/gui/container/GuiCrafting.java +++ b/java/src/client/gui/container/GuiCrafting.java @@ -1,4 +1,4 @@ -package game.gui.container; +package client.gui.container; import game.inventory.ContainerWorkbench; import game.inventory.InventoryPlayer; diff --git a/java/src/game/gui/container/GuiDispenser.java b/java/src/client/gui/container/GuiDispenser.java similarity index 98% rename from java/src/game/gui/container/GuiDispenser.java rename to java/src/client/gui/container/GuiDispenser.java index c65e983..8e94c00 100755 --- a/java/src/game/gui/container/GuiDispenser.java +++ b/java/src/client/gui/container/GuiDispenser.java @@ -1,4 +1,4 @@ -package game.gui.container; +package client.gui.container; import game.inventory.ContainerDispenser; import game.inventory.IInventory; diff --git a/java/src/game/gui/container/GuiEnchant.java b/java/src/client/gui/container/GuiEnchant.java similarity index 99% rename from java/src/game/gui/container/GuiEnchant.java rename to java/src/client/gui/container/GuiEnchant.java index dcf2632..31ef687 100755 --- a/java/src/game/gui/container/GuiEnchant.java +++ b/java/src/client/gui/container/GuiEnchant.java @@ -1,4 +1,4 @@ -package game.gui.container; +package client.gui.container; import game.color.TextColor; import game.enchantment.Enchantment; diff --git a/java/src/game/gui/container/GuiFurnace.java b/java/src/client/gui/container/GuiFurnace.java similarity index 98% rename from java/src/game/gui/container/GuiFurnace.java rename to java/src/client/gui/container/GuiFurnace.java index f8f31a3..3972317 100755 --- a/java/src/game/gui/container/GuiFurnace.java +++ b/java/src/client/gui/container/GuiFurnace.java @@ -1,4 +1,4 @@ -package game.gui.container; +package client.gui.container; import game.inventory.ContainerFurnace; import game.inventory.IInventory; diff --git a/java/src/game/gui/container/GuiHopper.java b/java/src/client/gui/container/GuiHopper.java similarity index 97% rename from java/src/game/gui/container/GuiHopper.java rename to java/src/client/gui/container/GuiHopper.java index 9923d08..753593e 100755 --- a/java/src/game/gui/container/GuiHopper.java +++ b/java/src/client/gui/container/GuiHopper.java @@ -1,6 +1,6 @@ -package game.gui.container; +package client.gui.container; -import game.Game; +import client.Game; import game.inventory.ContainerHopper; import game.inventory.IInventory; import game.inventory.InventoryPlayer; diff --git a/java/src/game/gui/container/GuiHorse.java b/java/src/client/gui/container/GuiHorse.java similarity index 98% rename from java/src/game/gui/container/GuiHorse.java rename to java/src/client/gui/container/GuiHorse.java index 6d620b4..bb56765 100755 --- a/java/src/game/gui/container/GuiHorse.java +++ b/java/src/client/gui/container/GuiHorse.java @@ -1,6 +1,6 @@ -package game.gui.container; +package client.gui.container; -import game.Game; +import client.Game; import game.entity.animal.EntityHorse; import game.inventory.ContainerHorseInventory; import game.inventory.IInventory; diff --git a/java/src/game/gui/container/GuiInventory.java b/java/src/client/gui/container/GuiInventory.java similarity index 98% rename from java/src/game/gui/container/GuiInventory.java rename to java/src/client/gui/container/GuiInventory.java index 71a4473..b47e81b 100755 --- a/java/src/game/gui/container/GuiInventory.java +++ b/java/src/client/gui/container/GuiInventory.java @@ -1,4 +1,4 @@ -package game.gui.container; +package client.gui.container; import game.entity.npc.EntityNPC; diff --git a/java/src/game/gui/container/GuiMachine.java b/java/src/client/gui/container/GuiMachine.java similarity index 96% rename from java/src/game/gui/container/GuiMachine.java rename to java/src/client/gui/container/GuiMachine.java index cca3fda..b61ba3d 100755 --- a/java/src/game/gui/container/GuiMachine.java +++ b/java/src/client/gui/container/GuiMachine.java @@ -1,6 +1,6 @@ -package game.gui.container; +package client.gui.container; -import game.Game; +import client.Game; import game.inventory.ContainerMachine; import game.inventory.IInventory; import game.inventory.InventoryPlayer; diff --git a/java/src/game/gui/container/GuiMerchant.java b/java/src/client/gui/container/GuiMerchant.java similarity index 99% rename from java/src/game/gui/container/GuiMerchant.java rename to java/src/client/gui/container/GuiMerchant.java index dc9e4ac..8f56250 100755 --- a/java/src/game/gui/container/GuiMerchant.java +++ b/java/src/client/gui/container/GuiMerchant.java @@ -1,13 +1,13 @@ -package game.gui.container; +package client.gui.container; import org.lwjgl.opengl.GL11; +import client.renderer.GlState; +import client.renderer.ItemRenderer; import game.inventory.ContainerMerchant; import game.inventory.InventoryPlayer; import game.item.ItemStack; import game.packet.CPacketAction; -import game.renderer.GlState; -import game.renderer.ItemRenderer; import game.village.MerchantRecipe; import game.village.MerchantRecipeList; import game.world.World; diff --git a/java/src/game/gui/container/GuiRepair.java b/java/src/client/gui/container/GuiRepair.java similarity index 99% rename from java/src/game/gui/container/GuiRepair.java rename to java/src/client/gui/container/GuiRepair.java index c8e1ba4..fec404d 100755 --- a/java/src/game/gui/container/GuiRepair.java +++ b/java/src/client/gui/container/GuiRepair.java @@ -1,8 +1,8 @@ -package game.gui.container; +package client.gui.container; import java.util.List; -import game.Game; +import client.Game; import game.inventory.Container; import game.inventory.ContainerRepair; import game.inventory.ICrafting; diff --git a/java/src/game/gui/element/ActButton.java b/java/src/client/gui/element/ActButton.java similarity index 90% rename from java/src/game/gui/element/ActButton.java rename to java/src/client/gui/element/ActButton.java index 91eb00f..72a8d88 100644 --- a/java/src/game/gui/element/ActButton.java +++ b/java/src/client/gui/element/ActButton.java @@ -1,7 +1,7 @@ -package game.gui.element; +package client.gui.element; -import game.util.Formatter; -import game.window.Button; +import client.gui.Formatter; +import client.window.Button; public class ActButton extends Element { public static enum Mode { diff --git a/java/src/game/gui/element/Bar.java b/java/src/client/gui/element/Bar.java similarity index 98% rename from java/src/game/gui/element/Bar.java rename to java/src/client/gui/element/Bar.java index b8d3f8d..bb1a457 100644 --- a/java/src/game/gui/element/Bar.java +++ b/java/src/client/gui/element/Bar.java @@ -1,6 +1,6 @@ -package game.gui.element; +package client.gui.element; -import game.renderer.Drawing; +import client.renderer.Drawing; import game.util.ExtMath; import game.util.Util; diff --git a/java/src/game/gui/element/Dropdown.java b/java/src/client/gui/element/Dropdown.java similarity index 95% rename from java/src/game/gui/element/Dropdown.java rename to java/src/client/gui/element/Dropdown.java index 33280de..010bac6 100644 --- a/java/src/game/gui/element/Dropdown.java +++ b/java/src/client/gui/element/Dropdown.java @@ -1,13 +1,13 @@ -package game.gui.element; +package client.gui.element; -import game.gui.Font; -import game.gui.Gui; -import game.renderer.Drawing; +import client.gui.Font; +import client.gui.Formatter; +import client.gui.Gui; +import client.renderer.Drawing; +import client.window.Button; import game.util.Displayable; import game.util.ExtMath; -import game.util.Formatter; import game.util.Util; -import game.window.Button; public class Dropdown extends Element { public class Handle extends Element { diff --git a/java/src/game/gui/element/Element.java b/java/src/client/gui/element/Element.java similarity index 95% rename from java/src/game/gui/element/Element.java rename to java/src/client/gui/element/Element.java index 9f7e6ce..b3dcd56 100644 --- a/java/src/game/gui/element/Element.java +++ b/java/src/client/gui/element/Element.java @@ -1,18 +1,18 @@ -package game.gui.element; +package client.gui.element; import org.lwjgl.opengl.GL11; -import game.Game; -import game.audio.PositionedSound; -import game.audio.Volume; -import game.gui.Gui; +import client.Game; +import client.gui.Formatter; +import client.gui.Gui; +import client.renderer.Drawing; +import client.renderer.Drawing.Vec2i; +import client.window.Button; +import client.window.Keysym; import game.init.SoundEvent; -import game.renderer.Drawing; -import game.renderer.Drawing.Vec2i; -import game.util.Formatter; +import game.sound.EventType; +import game.sound.PositionedSound; import game.util.Util; -import game.window.Button; -import game.window.Keysym; public abstract class Element { protected final Game gm = Game.getGame(); @@ -266,6 +266,6 @@ public abstract class Element { } public void playSound() { - this.gm.getSoundManager().playSound(new PositionedSound(SoundEvent.CLICK, Volume.GUI)); + this.gm.getSoundManager().playSound(new PositionedSound(SoundEvent.CLICK, EventType.UI_INTERFACE)); } } diff --git a/java/src/game/gui/element/Fill.java b/java/src/client/gui/element/Fill.java similarity index 92% rename from java/src/game/gui/element/Fill.java rename to java/src/client/gui/element/Fill.java index 7a9a90b..5fecb12 100644 --- a/java/src/game/gui/element/Fill.java +++ b/java/src/client/gui/element/Fill.java @@ -1,7 +1,7 @@ -package game.gui.element; +package client.gui.element; -import game.renderer.Drawing; -import game.renderer.Drawing.Vec2i; +import client.renderer.Drawing; +import client.renderer.Drawing.Vec2i; public class Fill extends Element { private final boolean left; diff --git a/java/src/game/gui/element/GuiList.java b/java/src/client/gui/element/GuiList.java similarity index 98% rename from java/src/game/gui/element/GuiList.java rename to java/src/client/gui/element/GuiList.java index 32326cd..0dd8ab6 100755 --- a/java/src/game/gui/element/GuiList.java +++ b/java/src/client/gui/element/GuiList.java @@ -1,19 +1,18 @@ -package game.gui.element; +package client.gui.element; import java.util.List; import org.lwjgl.opengl.GL11; +import client.gui.Gui; +import client.renderer.DefaultVertexFormats; +import client.renderer.Drawing; +import client.renderer.GlState; +import client.renderer.RenderBuffer; +import client.renderer.Tessellator; +import client.window.Button; import game.collect.Lists; - -import game.gui.Gui; -import game.renderer.DefaultVertexFormats; -import game.renderer.Drawing; -import game.renderer.GlState; -import game.renderer.RenderBuffer; -import game.renderer.Tessellator; import game.util.ExtMath; -import game.window.Button; public abstract class GuiList extends Gui { diff --git a/java/src/game/gui/element/InventoryButton.java b/java/src/client/gui/element/InventoryButton.java similarity index 88% rename from java/src/game/gui/element/InventoryButton.java rename to java/src/client/gui/element/InventoryButton.java index 6027422..7a71464 100644 --- a/java/src/game/gui/element/InventoryButton.java +++ b/java/src/client/gui/element/InventoryButton.java @@ -1,6 +1,6 @@ -package game.gui.element; +package client.gui.element; -import game.renderer.Drawing; +import client.renderer.Drawing; public class InventoryButton extends Element { public InventoryButton(int x, int y, int w, int h) { diff --git a/java/src/game/gui/element/Label.java b/java/src/client/gui/element/Label.java similarity index 92% rename from java/src/game/gui/element/Label.java rename to java/src/client/gui/element/Label.java index 7e2e85b..52bb201 100644 --- a/java/src/game/gui/element/Label.java +++ b/java/src/client/gui/element/Label.java @@ -1,6 +1,6 @@ -package game.gui.element; +package client.gui.element; -import game.renderer.Drawing; +import client.renderer.Drawing; import game.util.Util; public class Label extends Fill { diff --git a/java/src/game/gui/element/ListEntry.java b/java/src/client/gui/element/ListEntry.java similarity index 83% rename from java/src/game/gui/element/ListEntry.java rename to java/src/client/gui/element/ListEntry.java index 2d5d173..76236d1 100644 --- a/java/src/game/gui/element/ListEntry.java +++ b/java/src/client/gui/element/ListEntry.java @@ -1,4 +1,4 @@ -package game.gui.element; +package client.gui.element; public interface ListEntry { diff --git a/java/src/game/gui/element/NavButton.java b/java/src/client/gui/element/NavButton.java similarity index 90% rename from java/src/game/gui/element/NavButton.java rename to java/src/client/gui/element/NavButton.java index f9cc66c..224216b 100644 --- a/java/src/game/gui/element/NavButton.java +++ b/java/src/client/gui/element/NavButton.java @@ -1,8 +1,8 @@ -package game.gui.element; +package client.gui.element; -import game.Game; -import game.gui.Gui; -import game.renderer.Drawing; +import client.Game; +import client.gui.Gui; +import client.renderer.Drawing; import game.util.Util; public class NavButton extends ActButton { diff --git a/java/src/game/gui/element/SelectableButton.java b/java/src/client/gui/element/SelectableButton.java similarity index 94% rename from java/src/game/gui/element/SelectableButton.java rename to java/src/client/gui/element/SelectableButton.java index 4dc7995..0ad31d6 100644 --- a/java/src/game/gui/element/SelectableButton.java +++ b/java/src/client/gui/element/SelectableButton.java @@ -1,6 +1,6 @@ -package game.gui.element; +package client.gui.element; -import game.renderer.Drawing; +import client.renderer.Drawing; import game.util.Util; public class SelectableButton extends ActButton { diff --git a/java/src/game/gui/element/Slider.java b/java/src/client/gui/element/Slider.java similarity index 98% rename from java/src/game/gui/element/Slider.java rename to java/src/client/gui/element/Slider.java index f994c33..e6fd0d8 100644 --- a/java/src/game/gui/element/Slider.java +++ b/java/src/client/gui/element/Slider.java @@ -1,10 +1,10 @@ -package game.gui.element; +package client.gui.element; -import game.renderer.Drawing; +import client.gui.Formatter; +import client.renderer.Drawing; +import client.window.Button; import game.util.ExtMath; -import game.util.Formatter; import game.util.Util; -import game.window.Button; public class Slider extends Element { public static interface Callback { diff --git a/java/src/game/gui/element/Switch.java b/java/src/client/gui/element/Switch.java similarity index 95% rename from java/src/game/gui/element/Switch.java rename to java/src/client/gui/element/Switch.java index 77249c2..dc1e902 100644 --- a/java/src/game/gui/element/Switch.java +++ b/java/src/client/gui/element/Switch.java @@ -1,9 +1,9 @@ -package game.gui.element; +package client.gui.element; +import client.gui.Formatter; +import client.window.Button; import game.util.Displayable; -import game.util.Formatter; import game.util.Util; -import game.window.Button; public class Switch extends Element { public static interface Callback { diff --git a/java/src/game/gui/element/Textbox.java b/java/src/client/gui/element/Textbox.java similarity index 98% rename from java/src/game/gui/element/Textbox.java rename to java/src/client/gui/element/Textbox.java index ae0f452..a57e583 100644 --- a/java/src/game/gui/element/Textbox.java +++ b/java/src/client/gui/element/Textbox.java @@ -1,18 +1,18 @@ -package game.gui.element; +package client.gui.element; import org.lwjgl.opengl.GL11; -import game.gui.Font; -import game.renderer.Drawing; -import game.renderer.Drawing.Offset; -import game.renderer.Drawing.Vec2i; +import client.Timing; +import client.gui.Font; +import client.renderer.Drawing; +import client.renderer.Drawing.Offset; +import client.renderer.Drawing.Vec2i; +import client.window.Button; +import client.window.Keysym; +import client.window.Window; import game.util.CharValidator; import game.util.ExtMath; -import game.util.Timing; import game.util.Util; -import game.window.Button; -import game.window.Keysym; -import game.window.Window; public class Textbox extends Element { public static enum Action { diff --git a/java/src/game/gui/element/Toggle.java b/java/src/client/gui/element/Toggle.java similarity index 93% rename from java/src/game/gui/element/Toggle.java rename to java/src/client/gui/element/Toggle.java index 568f2b2..2c38f8b 100644 --- a/java/src/game/gui/element/Toggle.java +++ b/java/src/client/gui/element/Toggle.java @@ -1,9 +1,9 @@ -package game.gui.element; +package client.gui.element; -import game.renderer.Drawing; -import game.util.Formatter; +import client.gui.Formatter; +import client.renderer.Drawing; +import client.window.Button; import game.util.Util; -import game.window.Button; public class Toggle extends Element { public static interface Callback { diff --git a/java/src/game/gui/element/TransparentBox.java b/java/src/client/gui/element/TransparentBox.java similarity index 86% rename from java/src/game/gui/element/TransparentBox.java rename to java/src/client/gui/element/TransparentBox.java index b7f66d9..04f284d 100644 --- a/java/src/game/gui/element/TransparentBox.java +++ b/java/src/client/gui/element/TransparentBox.java @@ -1,6 +1,6 @@ -package game.gui.element; +package client.gui.element; -import game.renderer.Drawing; +import client.renderer.Drawing; public class TransparentBox extends Textbox { private final boolean background; diff --git a/java/src/game/gui/ingame/GuiGameOver.java b/java/src/client/gui/ingame/GuiGameOver.java similarity index 84% rename from java/src/game/gui/ingame/GuiGameOver.java rename to java/src/client/gui/ingame/GuiGameOver.java index 780bd41..4ed36d0 100755 --- a/java/src/game/gui/ingame/GuiGameOver.java +++ b/java/src/client/gui/ingame/GuiGameOver.java @@ -1,10 +1,10 @@ -package game.gui.ingame; +package client.gui.ingame; +import client.gui.Gui; +import client.gui.element.ActButton; +import client.gui.element.ActButton.Mode; +import client.gui.element.Label; import game.color.TextColor; -import game.gui.Gui; -import game.gui.element.ActButton; -import game.gui.element.ActButton.Mode; -import game.gui.element.Label; public class GuiGameOver extends Gui { public static final GuiGameOver INSTANCE = new GuiGameOver(); diff --git a/java/src/game/gui/ingame/GuiSign.java b/java/src/client/gui/ingame/GuiSign.java similarity index 88% rename from java/src/game/gui/ingame/GuiSign.java rename to java/src/client/gui/ingame/GuiSign.java index a04af2f..925ae91 100644 --- a/java/src/game/gui/ingame/GuiSign.java +++ b/java/src/client/gui/ingame/GuiSign.java @@ -1,9 +1,9 @@ -package game.gui.ingame; +package client.gui.ingame; -import game.gui.Gui; -import game.gui.element.NavButton; -import game.gui.element.Textbox; -import game.gui.element.Textbox.Action; +import client.gui.Gui; +import client.gui.element.NavButton; +import client.gui.element.Textbox; +import client.gui.element.Textbox.Action; import game.network.ClientPlayer; import game.packet.CPacketSign; import game.world.BlockPos; diff --git a/java/src/game/gui/options/GuiBinds.java b/java/src/client/gui/options/GuiBinds.java similarity index 90% rename from java/src/game/gui/options/GuiBinds.java rename to java/src/client/gui/options/GuiBinds.java index 5f0b7d4..01bb639 100644 --- a/java/src/game/gui/options/GuiBinds.java +++ b/java/src/client/gui/options/GuiBinds.java @@ -1,11 +1,11 @@ -package game.gui.options; +package client.gui.options; +import client.gui.Formatter; +import client.gui.element.ActButton; +import client.gui.element.ActButton.Mode; +import client.gui.element.Label; +import client.window.Bind; import game.color.TextColor; -import game.gui.element.ActButton; -import game.gui.element.ActButton.Mode; -import game.gui.element.Label; -import game.util.Formatter; -import game.window.Bind; public class GuiBinds extends GuiOptions { protected GuiBinds() { diff --git a/java/src/game/gui/options/GuiDisplay.java b/java/src/client/gui/options/GuiDisplay.java similarity index 91% rename from java/src/game/gui/options/GuiDisplay.java rename to java/src/client/gui/options/GuiDisplay.java index cfda61a..1d5d69b 100644 --- a/java/src/game/gui/options/GuiDisplay.java +++ b/java/src/client/gui/options/GuiDisplay.java @@ -1,15 +1,15 @@ -package game.gui.options; +package client.gui.options; +import client.gui.Formatter; +import client.gui.element.Dropdown; +import client.gui.element.Element; +import client.gui.element.Fill; +import client.gui.element.Slider; +import client.gui.element.Toggle; +import client.window.Button; +import client.window.DisplayMode; +import client.window.Window; import game.color.TextColor; -import game.gui.element.Dropdown; -import game.gui.element.Element; -import game.gui.element.Fill; -import game.gui.element.Slider; -import game.gui.element.Toggle; -import game.util.Formatter; -import game.window.Button; -import game.window.DisplayMode; -import game.window.Window; public class GuiDisplay extends GuiOptions { private static final String[] DISTANCES = new String[] {"Gruselig", "Winzig", "Gering", "Normal", "Weit"}; diff --git a/java/src/game/gui/options/GuiOptions.java b/java/src/client/gui/options/GuiOptions.java similarity index 86% rename from java/src/game/gui/options/GuiOptions.java rename to java/src/client/gui/options/GuiOptions.java index e50ed60..51258d8 100644 --- a/java/src/game/gui/options/GuiOptions.java +++ b/java/src/client/gui/options/GuiOptions.java @@ -1,8 +1,8 @@ -package game.gui.options; +package client.gui.options; -import game.gui.Gui; -import game.gui.GuiMenu; -import game.gui.element.NavButton; +import client.gui.Gui; +import client.gui.GuiMenu; +import client.gui.element.NavButton; public abstract class GuiOptions extends Gui { private static final GuiOptions[] PAGES = {lastPage = new GuiBinds(), new GuiStyle(), new GuiDisplay(), new GuiSound()}; diff --git a/java/src/game/gui/options/GuiSound.java b/java/src/client/gui/options/GuiSound.java similarity index 85% rename from java/src/game/gui/options/GuiSound.java rename to java/src/client/gui/options/GuiSound.java index 4fb64210..052c2ab 100644 --- a/java/src/game/gui/options/GuiSound.java +++ b/java/src/client/gui/options/GuiSound.java @@ -1,8 +1,8 @@ -package game.gui.options; +package client.gui.options; -import game.audio.Volume; -import game.gui.element.ActButton; -import game.gui.element.ActButton.Mode; +import client.audio.Volume; +import client.gui.element.ActButton; +import client.gui.element.ActButton.Mode; public class GuiSound extends GuiOptions { protected GuiSound() { diff --git a/java/src/game/gui/options/GuiStyle.java b/java/src/client/gui/options/GuiStyle.java similarity index 90% rename from java/src/game/gui/options/GuiStyle.java rename to java/src/client/gui/options/GuiStyle.java index ecba7e0..66cd703 100644 --- a/java/src/game/gui/options/GuiStyle.java +++ b/java/src/client/gui/options/GuiStyle.java @@ -1,16 +1,16 @@ -package game.gui.options; +package client.gui.options; -import game.gui.Style; -import game.gui.element.ActButton; -import game.gui.element.ActButton.Mode; -import game.gui.element.Dropdown; -import game.gui.element.Element; -import game.gui.element.SelectableButton; -import game.gui.element.Slider; -import game.gui.element.Switch; -import game.gui.element.Textbox; -import game.gui.element.Textbox.Action; -import game.gui.element.Toggle; +import client.gui.Style; +import client.gui.element.ActButton; +import client.gui.element.ActButton.Mode; +import client.gui.element.Dropdown; +import client.gui.element.Element; +import client.gui.element.SelectableButton; +import client.gui.element.Slider; +import client.gui.element.Switch; +import client.gui.element.Textbox; +import client.gui.element.Textbox.Action; +import client.gui.element.Toggle; import game.vars.CVar; import game.vars.ColorVar; diff --git a/java/src/client/init/EntityRenderRegistry.java b/java/src/client/init/EntityRenderRegistry.java new file mode 100644 index 0000000..535ff26 --- /dev/null +++ b/java/src/client/init/EntityRenderRegistry.java @@ -0,0 +1,157 @@ +package client.init; + +import java.util.Map; + +import client.renderer.entity.Render; +import client.renderer.entity.RenderArachnoid; +import client.renderer.entity.RenderArrow; +import client.renderer.entity.RenderBat; +import client.renderer.entity.RenderBlockEntity; +import client.renderer.entity.RenderBoat; +import client.renderer.entity.RenderBullet; +import client.renderer.entity.RenderChicken; +import client.renderer.entity.RenderCow; +import client.renderer.entity.RenderCrystal; +import client.renderer.entity.RenderDie; +import client.renderer.entity.RenderDragon; +import client.renderer.entity.RenderDynamite; +import client.renderer.entity.RenderEntity; +import client.renderer.entity.RenderEntityItem; +import client.renderer.entity.RenderFallingBlock; +import client.renderer.entity.RenderFireball; +import client.renderer.entity.RenderFish; +import client.renderer.entity.RenderFlyingBox; +import client.renderer.entity.RenderHorse; +import client.renderer.entity.RenderHumanoid; +import client.renderer.entity.RenderItem; +import client.renderer.entity.RenderItemEntity; +import client.renderer.entity.RenderLeashKnot; +import client.renderer.entity.RenderLightning; +import client.renderer.entity.RenderManager; +import client.renderer.entity.RenderMinecart; +import client.renderer.entity.RenderMooshroom; +import client.renderer.entity.RenderMouse; +import client.renderer.entity.RenderNpc; +import client.renderer.entity.RenderOcelot; +import client.renderer.entity.RenderPig; +import client.renderer.entity.RenderPotion; +import client.renderer.entity.RenderRabbit; +import client.renderer.entity.RenderSheep; +import client.renderer.entity.RenderSlime; +import client.renderer.entity.RenderSpaceMarine; +import client.renderer.entity.RenderSquid; +import client.renderer.entity.RenderTntMinecart; +import client.renderer.entity.RenderTntPrimed; +import client.renderer.entity.RenderWolf; +import client.renderer.entity.RenderXpOrb; +import client.renderer.model.ModelChicken; +import client.renderer.model.ModelCow; +import client.renderer.model.ModelHorse; +import client.renderer.model.ModelMouse; +import client.renderer.model.ModelOcelot; +import client.renderer.model.ModelPig; +import client.renderer.model.ModelRabbit; +import client.renderer.model.ModelSheep2; +import client.renderer.model.ModelSquid; +import client.renderer.model.ModelWolf; +import game.entity.Entity; +import game.entity.animal.EntityBat; +import game.entity.animal.EntityChicken; +import game.entity.animal.EntityCow; +import game.entity.animal.EntityDragon; +import game.entity.animal.EntityHorse; +import game.entity.animal.EntityMooshroom; +import game.entity.animal.EntityMouse; +import game.entity.animal.EntityOcelot; +import game.entity.animal.EntityPig; +import game.entity.animal.EntityRabbit; +import game.entity.animal.EntitySheep; +import game.entity.animal.EntitySquid; +import game.entity.animal.EntityWolf; +import game.entity.effect.EntityLightning; +import game.entity.item.EntityBoat; +import game.entity.item.EntityCart; +import game.entity.item.EntityCrystal; +import game.entity.item.EntityFalling; +import game.entity.item.EntityFireworks; +import game.entity.item.EntityItem; +import game.entity.item.EntityLeashKnot; +import game.entity.item.EntityNuke; +import game.entity.item.EntityOrb; +import game.entity.item.EntityTnt; +import game.entity.item.EntityTntCart; +import game.entity.item.EntityXp; +import game.entity.item.EntityXpBottle; +import game.entity.npc.SpeciesInfo; +import game.entity.projectile.EntityArrow; +import game.entity.projectile.EntityBox; +import game.entity.projectile.EntityBullet; +import game.entity.projectile.EntityDie; +import game.entity.projectile.EntityDynamite; +import game.entity.projectile.EntityEgg; +import game.entity.projectile.EntityFireCharge; +import game.entity.projectile.EntityFireball; +import game.entity.projectile.EntityHook; +import game.entity.projectile.EntityPotion; +import game.entity.projectile.EntitySnowball; +import game.init.Blocks; +import game.init.Items; +import game.init.SpeciesRegistry; +import game.init.SpeciesRegistry.ModelType; + +public class EntityRenderRegistry { + public static void registerRenderers(Map, Render> map, + Map models, RenderManager mgr, RenderItem ritem) { + map.put(EntityPig.class, new RenderPig(mgr, new ModelPig())); + map.put(EntitySheep.class, new RenderSheep(mgr, new ModelSheep2())); + map.put(EntityCow.class, new RenderCow(mgr, new ModelCow())); + map.put(EntityMooshroom.class, new RenderMooshroom(mgr, new ModelCow())); + map.put(EntityWolf.class, new RenderWolf(mgr, new ModelWolf())); + map.put(EntityChicken.class, new RenderChicken(mgr, new ModelChicken())); + map.put(EntityOcelot.class, new RenderOcelot(mgr, new ModelOcelot())); + map.put(EntityRabbit.class, new RenderRabbit(mgr, new ModelRabbit())); + map.put(EntitySquid.class, new RenderSquid(mgr, new ModelSquid())); + map.put(EntityBat.class, new RenderBat(mgr)); + map.put(EntityDragon.class, new RenderDragon(mgr)); + map.put(EntityCrystal.class, new RenderCrystal(mgr)); + map.put(Entity.class, new RenderEntity(mgr)); +// map.put(EntityPainting.class, new RenderPainting(mgr)); +// map.put(EntityFrame.class, new RenderItemFrame(mgr, ritem)); + map.put(EntityLeashKnot.class, new RenderLeashKnot(mgr)); + map.put(EntityArrow.class, new RenderArrow(mgr)); + map.put(EntitySnowball.class, new RenderItemEntity(mgr, Items.snowball, ritem)); + map.put(EntityOrb.class, new RenderItemEntity(mgr, Items.charged_orb, ritem)); + map.put(EntityEgg.class, new RenderItemEntity(mgr, Items.egg, ritem)); + map.put(EntityPotion.class, new RenderPotion(mgr, ritem)); + map.put(EntityXpBottle.class, new RenderItemEntity(mgr, Items.experience_bottle, ritem)); + map.put(EntityFireworks.class, new RenderItemEntity(mgr, Items.fireworks, ritem)); + map.put(EntityFireball.class, new RenderFireball(mgr, 0.75F)); + map.put(EntityFireCharge.class, new RenderFireball(mgr, 0.5F)); + map.put(EntityBox.class, new RenderFlyingBox(mgr)); + map.put(EntityItem.class, new RenderEntityItem(mgr, ritem)); + map.put(EntityXp.class, new RenderXpOrb(mgr)); + map.put(EntityTnt.class, new RenderTntPrimed(mgr)); + map.put(EntityFalling.class, new RenderFallingBlock(mgr)); + map.put(EntityTntCart.class, new RenderTntMinecart(mgr)); + map.put(EntityCart.class, new RenderMinecart(mgr)); + map.put(EntityBoat.class, new RenderBoat(mgr)); + map.put(EntityHook.class, new RenderFish(mgr)); + map.put(EntityHorse.class, new RenderHorse(mgr, new ModelHorse())); + map.put(EntityDynamite.class, new RenderDynamite(mgr, Items.dynamite, ritem)); + map.put(EntityNuke.class, new RenderBlockEntity(mgr, Blocks.nuke.getState())); + map.put(EntityMouse.class, new RenderMouse(mgr, new ModelMouse())); + map.put(EntityDie.class, new RenderDie(mgr)); + map.put(EntityBullet.class, new RenderBullet(mgr)); + map.put(EntityLightning.class, new RenderLightning(mgr)); + models.put(ModelType.HUMANOID, new RenderHumanoid(mgr, 12, 12, "textures/entity/char.png")); + models.put(ModelType.ARACHNOID, new RenderArachnoid(mgr)); + models.put(ModelType.SLIME, new RenderSlime(mgr)); + models.put(ModelType.DWARF, new RenderHumanoid(mgr, 10, 10, "textures/entity/dwarf.png")); + models.put(ModelType.HALFLING, new RenderHumanoid(mgr, 8, 8, "textures/entity/goblin.png")); + models.put(ModelType.SPACE_MARINE, new RenderSpaceMarine(mgr)); + for(int z = 0; z < SpeciesRegistry.SPECIMEN.size(); z++) { + SpeciesInfo info = SpeciesRegistry.SPECIMEN.get(z); + map.put(info.clazz, models.get(info.renderer)); + } + } +} diff --git a/java/src/game/renderer/ActiveRenderInfo.java b/java/src/client/renderer/ActiveRenderInfo.java similarity index 99% rename from java/src/game/renderer/ActiveRenderInfo.java rename to java/src/client/renderer/ActiveRenderInfo.java index 3987341..b9e7ecd 100755 --- a/java/src/game/renderer/ActiveRenderInfo.java +++ b/java/src/client/renderer/ActiveRenderInfo.java @@ -1,4 +1,4 @@ -package game.renderer; +package client.renderer; import java.nio.ByteBuffer; import java.nio.ByteOrder; diff --git a/java/src/game/renderer/BlockRenderer.java b/java/src/client/renderer/BlockRenderer.java similarity index 98% rename from java/src/game/renderer/BlockRenderer.java rename to java/src/client/renderer/BlockRenderer.java index 0747812..cb78895 100755 --- a/java/src/game/renderer/BlockRenderer.java +++ b/java/src/client/renderer/BlockRenderer.java @@ -1,4 +1,4 @@ -package game.renderer; +package client.renderer; import java.util.BitSet; import java.util.List; @@ -6,22 +6,21 @@ import java.util.Map; import org.lwjgl.opengl.GL11; -import game.collect.Maps; - -import game.Game; +import client.Game; +import client.renderer.blockmodel.BakedModel; +import client.renderer.blockmodel.BakedQuad; +import client.renderer.blockmodel.IBakedModel; +import client.renderer.blockmodel.ModelManager; +import client.renderer.texture.TextureAtlasSprite; +import client.renderer.texture.TextureMap; +import client.renderer.tileentity.TileEntityItemStackRenderer; import game.block.Block; import game.block.BlockLiquid; +import game.collect.Maps; import game.init.BlockRegistry; import game.init.FluidRegistry; import game.item.ItemStack; import game.material.Material; -import game.model.BakedModel; -import game.model.IBakedModel; -import game.model.ModelManager; -import game.renderer.blockmodel.BakedQuad; -import game.renderer.texture.TextureAtlasSprite; -import game.renderer.texture.TextureMap; -import game.renderer.tileentity.TileEntityItemStackRenderer; import game.util.ExtMath; import game.world.BlockPos; import game.world.Facing; diff --git a/java/src/game/renderer/DefaultVertexFormats.java b/java/src/client/renderer/DefaultVertexFormats.java similarity index 99% rename from java/src/game/renderer/DefaultVertexFormats.java rename to java/src/client/renderer/DefaultVertexFormats.java index 51416dd..ab287a5 100755 --- a/java/src/game/renderer/DefaultVertexFormats.java +++ b/java/src/client/renderer/DefaultVertexFormats.java @@ -1,4 +1,4 @@ -package game.renderer; +package client.renderer; public class DefaultVertexFormats { diff --git a/java/src/game/renderer/Drawing.java b/java/src/client/renderer/Drawing.java similarity index 99% rename from java/src/game/renderer/Drawing.java rename to java/src/client/renderer/Drawing.java index 934f5af..d4a2002 100644 --- a/java/src/game/renderer/Drawing.java +++ b/java/src/client/renderer/Drawing.java @@ -1,11 +1,11 @@ -package game.renderer; +package client.renderer; import org.lwjgl.opengl.GL11; -import game.Game; +import client.Game; +import client.gui.Font; +import client.gui.FontChar; import game.color.TextColor; -import game.gui.Font; -import game.gui.FontChar; import game.log.Log; import game.util.Util; diff --git a/java/src/game/renderer/EntityRenderer.java b/java/src/client/renderer/EntityRenderer.java similarity index 99% rename from java/src/game/renderer/EntityRenderer.java rename to java/src/client/renderer/EntityRenderer.java index 2f63441..0ca4578 100755 --- a/java/src/game/renderer/EntityRenderer.java +++ b/java/src/client/renderer/EntityRenderer.java @@ -1,16 +1,18 @@ -package game.renderer; +package client.renderer; import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.nio.FloatBuffer; import java.util.List; +import java.util.function.Predicate; import org.lwjgl.opengl.GL11; import org.lwjgl.opengl.GL13; -import java.util.function.Predicate; - -import game.Game; +import client.Game; +import client.renderer.particle.EffectRenderer; +import client.renderer.texture.DynamicTexture; +import client.renderer.texture.TextureMap; import game.biome.Biome; import game.block.Block; import game.entity.Entity; @@ -20,11 +22,9 @@ import game.entity.types.EntityLiving; import game.init.Items; import game.init.SoundEvent; import game.material.Material; +import game.model.BlockLayer; +import game.model.ParticleType; import game.potion.Potion; -import game.renderer.particle.EffectRenderer; -import game.renderer.particle.ParticleType; -import game.renderer.texture.DynamicTexture; -import game.renderer.texture.TextureMap; import game.rng.Random; import game.util.ExtMath; import game.world.BlockPos; diff --git a/java/src/game/renderer/Frustum.java b/java/src/client/renderer/Frustum.java similarity index 99% rename from java/src/game/renderer/Frustum.java rename to java/src/client/renderer/Frustum.java index d4769f1..9b3478d 100755 --- a/java/src/game/renderer/Frustum.java +++ b/java/src/client/renderer/Frustum.java @@ -1,4 +1,4 @@ -package game.renderer; +package client.renderer; import java.nio.ByteBuffer; import java.nio.ByteOrder; diff --git a/java/src/game/renderer/GlState.java b/java/src/client/renderer/GlState.java similarity index 99% rename from java/src/game/renderer/GlState.java rename to java/src/client/renderer/GlState.java index 569b0eb..d9eea4c 100755 --- a/java/src/game/renderer/GlState.java +++ b/java/src/client/renderer/GlState.java @@ -1,4 +1,4 @@ -package game.renderer; +package client.renderer; import org.lwjgl.opengl.GL11; import org.lwjgl.opengl.GL13; diff --git a/java/src/game/renderer/ItemModelMesher.java b/java/src/client/renderer/ItemModelMesher.java similarity index 95% rename from java/src/game/renderer/ItemModelMesher.java rename to java/src/client/renderer/ItemModelMesher.java index 80958f6..69fd18c 100755 --- a/java/src/game/renderer/ItemModelMesher.java +++ b/java/src/client/renderer/ItemModelMesher.java @@ -1,17 +1,17 @@ -package game.renderer; +package client.renderer; import java.util.List; import java.util.Map; +import client.renderer.blockmodel.IBakedModel; +import client.renderer.blockmodel.ModelManager; +import client.renderer.texture.TextureAtlasSprite; import game.collect.Lists; import game.collect.Maps; - import game.init.ItemRegistry; import game.item.Item; import game.item.ItemStack; -import game.model.IBakedModel; -import game.model.ModelManager; -import game.renderer.texture.TextureAtlasSprite; +import game.model.ItemMeshDefinition; public class ItemModelMesher { diff --git a/java/src/game/renderer/ItemRenderer.java b/java/src/client/renderer/ItemRenderer.java similarity index 98% rename from java/src/game/renderer/ItemRenderer.java rename to java/src/client/renderer/ItemRenderer.java index 6fdbf98..b5d7544 100755 --- a/java/src/game/renderer/ItemRenderer.java +++ b/java/src/client/renderer/ItemRenderer.java @@ -1,4 +1,4 @@ -package game.renderer; +package client.renderer; import java.nio.ByteBuffer; import java.nio.ByteOrder; @@ -7,19 +7,20 @@ import java.nio.FloatBuffer; import org.lwjgl.opengl.GL11; import org.lwjgl.opengl.GL13; -import game.Game; +import client.Game; +import client.renderer.entity.RenderItem; +import client.renderer.entity.RenderManager; +import client.renderer.entity.RenderNpc; +import client.renderer.texture.TextureAtlasSprite; +import client.renderer.texture.TextureMap; import game.block.Block; import game.entity.npc.EntityNPC; import game.entity.types.EntityLiving; import game.item.Item; import game.item.ItemAction; import game.item.ItemStack; -import game.renderer.blockmodel.Transforms; -import game.renderer.entity.RenderItem; -import game.renderer.entity.RenderManager; -import game.renderer.entity.RenderNpc; -import game.renderer.texture.TextureAtlasSprite; -import game.renderer.texture.TextureMap; +import game.model.BlockLayer; +import game.model.Transforms; import game.util.ExtMath; import game.world.BlockPos; import game.world.State; diff --git a/java/src/game/renderer/Project.java b/java/src/client/renderer/Project.java similarity index 99% rename from java/src/game/renderer/Project.java rename to java/src/client/renderer/Project.java index e6d3dd4..ce0b8a8 100644 --- a/java/src/game/renderer/Project.java +++ b/java/src/client/renderer/Project.java @@ -29,7 +29,7 @@ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package game.renderer; +package client.renderer; import java.nio.ByteBuffer; import java.nio.ByteOrder; diff --git a/java/src/game/renderer/RegionRenderCache.java b/java/src/client/renderer/RegionRenderCache.java similarity index 99% rename from java/src/game/renderer/RegionRenderCache.java rename to java/src/client/renderer/RegionRenderCache.java index cfd4050..ceeae17 100755 --- a/java/src/game/renderer/RegionRenderCache.java +++ b/java/src/client/renderer/RegionRenderCache.java @@ -1,4 +1,4 @@ -package game.renderer; +package client.renderer; import java.util.Arrays; diff --git a/java/src/game/renderer/RegionRenderCacheBuilder.java b/java/src/client/renderer/RegionRenderCacheBuilder.java similarity index 92% rename from java/src/game/renderer/RegionRenderCacheBuilder.java rename to java/src/client/renderer/RegionRenderCacheBuilder.java index e2b175a..3bdd7be 100755 --- a/java/src/game/renderer/RegionRenderCacheBuilder.java +++ b/java/src/client/renderer/RegionRenderCacheBuilder.java @@ -1,4 +1,6 @@ -package game.renderer; +package client.renderer; + +import game.model.BlockLayer; public class RegionRenderCacheBuilder { diff --git a/java/src/game/renderer/RenderBuffer.java b/java/src/client/renderer/RenderBuffer.java similarity index 99% rename from java/src/game/renderer/RenderBuffer.java rename to java/src/client/renderer/RenderBuffer.java index a0c4cb5..8889951 100755 --- a/java/src/game/renderer/RenderBuffer.java +++ b/java/src/client/renderer/RenderBuffer.java @@ -1,4 +1,4 @@ -package game.renderer; +package client.renderer; import java.nio.ByteBuffer; import java.nio.ByteOrder; diff --git a/java/src/game/renderer/RenderGlobal.java b/java/src/client/renderer/RenderGlobal.java similarity index 99% rename from java/src/game/renderer/RenderGlobal.java rename to java/src/client/renderer/RenderGlobal.java index c91daa9..2376f3c 100755 --- a/java/src/game/renderer/RenderGlobal.java +++ b/java/src/client/renderer/RenderGlobal.java @@ -1,4 +1,4 @@ -package game.renderer; +package client.renderer; import java.util.ArrayList; import java.util.Collection; @@ -15,34 +15,35 @@ import org.lwjgl.opengl.GL11; import org.lwjgl.opengl.GL13; import org.lwjgl.opengl.GL15; -import game.collect.Lists; -import game.collect.Maps; -import game.collect.Sets; - -import game.Game; -import game.audio.Sound; +import client.Game; +import client.renderer.chunk.ChunkRenderDispatcher; +import client.renderer.chunk.CompiledChunk; +import client.renderer.chunk.RenderChunk; +import client.renderer.chunk.VisGraph; +import client.renderer.entity.RenderManager; +import client.renderer.texture.TextureAtlasSprite; +import client.renderer.texture.TextureManager; +import client.renderer.texture.TextureMap; +import client.renderer.tileentity.TileEntityRendererDispatcher; import game.block.Block; import game.block.BlockChest; import game.block.BlockSign; import game.block.BlockSkull; +import game.collect.Lists; +import game.collect.Maps; +import game.collect.Sets; import game.entity.Entity; import game.entity.npc.EntityNPC; import game.entity.projectile.EntityBox; import game.entity.types.EntityLiving; import game.material.Material; -import game.renderer.chunk.ChunkRenderDispatcher; -import game.renderer.chunk.CompiledChunk; -import game.renderer.chunk.RenderChunk; -import game.renderer.chunk.VisGraph; -import game.renderer.entity.RenderManager; -import game.renderer.texture.TextureAtlasSprite; -import game.renderer.texture.TextureManager; -import game.renderer.texture.TextureMap; -import game.renderer.tileentity.TileEntityRendererDispatcher; +import game.model.BlockLayer; import game.rng.Random; +import game.sound.Sound; import game.tileentity.TileEntity; import game.tileentity.TileEntityChest; import game.util.ExtMath; +import game.util.Vector3f; import game.world.BlockPos; import game.world.BoundingBox; import game.world.Chunk; diff --git a/java/src/game/renderer/Tessellator.java b/java/src/client/renderer/Tessellator.java similarity index 99% rename from java/src/game/renderer/Tessellator.java rename to java/src/client/renderer/Tessellator.java index bc6412e..014e658 100755 --- a/java/src/game/renderer/Tessellator.java +++ b/java/src/client/renderer/Tessellator.java @@ -1,4 +1,4 @@ -package game.renderer; +package client.renderer; import java.nio.ByteBuffer; import java.util.List; diff --git a/java/src/game/renderer/VertexBuffer.java b/java/src/client/renderer/VertexBuffer.java similarity index 97% rename from java/src/game/renderer/VertexBuffer.java rename to java/src/client/renderer/VertexBuffer.java index ab21f17..ee8a33e 100755 --- a/java/src/game/renderer/VertexBuffer.java +++ b/java/src/client/renderer/VertexBuffer.java @@ -1,4 +1,4 @@ -package game.renderer; +package client.renderer; import java.nio.ByteBuffer; diff --git a/java/src/game/renderer/VertexFormat.java b/java/src/client/renderer/VertexFormat.java similarity index 99% rename from java/src/game/renderer/VertexFormat.java rename to java/src/client/renderer/VertexFormat.java index 42be6f3..8b06b07 100755 --- a/java/src/game/renderer/VertexFormat.java +++ b/java/src/client/renderer/VertexFormat.java @@ -1,9 +1,8 @@ -package game.renderer; +package client.renderer; import java.util.List; import game.collect.Lists; - import game.log.Log; public class VertexFormat diff --git a/java/src/game/renderer/VertexFormatElement.java b/java/src/client/renderer/VertexFormatElement.java similarity index 99% rename from java/src/game/renderer/VertexFormatElement.java rename to java/src/client/renderer/VertexFormatElement.java index 58804dd..3c19fca 100755 --- a/java/src/game/renderer/VertexFormatElement.java +++ b/java/src/client/renderer/VertexFormatElement.java @@ -1,4 +1,4 @@ -package game.renderer; +package client.renderer; import org.lwjgl.opengl.GL11; diff --git a/java/src/game/renderer/ViewFrustum.java b/java/src/client/renderer/ViewFrustum.java similarity index 98% rename from java/src/game/renderer/ViewFrustum.java rename to java/src/client/renderer/ViewFrustum.java index c0d460a..4b9856c 100755 --- a/java/src/game/renderer/ViewFrustum.java +++ b/java/src/client/renderer/ViewFrustum.java @@ -1,6 +1,6 @@ -package game.renderer; +package client.renderer; -import game.renderer.chunk.RenderChunk; +import client.renderer.chunk.RenderChunk; import game.util.ExtMath; import game.world.BlockPos; import game.world.World; diff --git a/java/src/game/model/BakedModel.java b/java/src/client/renderer/blockmodel/BakedModel.java similarity index 94% rename from java/src/game/model/BakedModel.java rename to java/src/client/renderer/blockmodel/BakedModel.java index 8227641..9f4ed4c 100755 --- a/java/src/game/model/BakedModel.java +++ b/java/src/client/renderer/blockmodel/BakedModel.java @@ -1,15 +1,11 @@ -package game.model; +package client.renderer.blockmodel; import java.util.ArrayList; import java.util.List; +import client.renderer.texture.TextureAtlasSprite; import game.collect.Lists; - -import game.renderer.blockmodel.BakedQuad; -import game.renderer.blockmodel.BreakingFour; -import game.renderer.blockmodel.ModelBlock; -import game.renderer.blockmodel.Transforms; -import game.renderer.texture.TextureAtlasSprite; +import game.model.Transforms; import game.world.Facing; public class BakedModel implements IBakedModel diff --git a/java/src/game/renderer/blockmodel/BakedQuad.java b/java/src/client/renderer/blockmodel/BakedQuad.java similarity index 93% rename from java/src/game/renderer/blockmodel/BakedQuad.java rename to java/src/client/renderer/blockmodel/BakedQuad.java index 8fe6886..50e1498 100755 --- a/java/src/game/renderer/blockmodel/BakedQuad.java +++ b/java/src/client/renderer/blockmodel/BakedQuad.java @@ -1,4 +1,4 @@ -package game.renderer.blockmodel; +package client.renderer.blockmodel; import game.world.Facing; diff --git a/java/src/game/renderer/blockmodel/BlockFaceUV.java b/java/src/client/renderer/blockmodel/BlockFaceUV.java similarity index 94% rename from java/src/game/renderer/blockmodel/BlockFaceUV.java rename to java/src/client/renderer/blockmodel/BlockFaceUV.java index 4eef325..6dfb737 100755 --- a/java/src/game/renderer/blockmodel/BlockFaceUV.java +++ b/java/src/client/renderer/blockmodel/BlockFaceUV.java @@ -1,4 +1,4 @@ -package game.renderer.blockmodel; +package client.renderer.blockmodel; public class BlockFaceUV { public float[] uvs; diff --git a/java/src/game/renderer/blockmodel/BlockPart.java b/java/src/client/renderer/blockmodel/BlockPart.java similarity index 92% rename from java/src/game/renderer/blockmodel/BlockPart.java rename to java/src/client/renderer/blockmodel/BlockPart.java index 92fa935..d52b5fd 100755 --- a/java/src/game/renderer/blockmodel/BlockPart.java +++ b/java/src/client/renderer/blockmodel/BlockPart.java @@ -1,8 +1,8 @@ -package game.renderer.blockmodel; +package client.renderer.blockmodel; import java.util.Map; -import game.renderer.Vector3f; +import game.util.Vector3f; import game.world.Facing; public class BlockPart @@ -22,7 +22,7 @@ public class BlockPart this.shade = shadeIn; } - protected float[] getFaceUvs(Facing face) + public float[] getFaceUvs(Facing face) { float[] afloat; diff --git a/java/src/game/renderer/blockmodel/BlockPartFace.java b/java/src/client/renderer/blockmodel/BlockPartFace.java similarity index 82% rename from java/src/game/renderer/blockmodel/BlockPartFace.java rename to java/src/client/renderer/blockmodel/BlockPartFace.java index 67dbc8d..601f36a 100755 --- a/java/src/game/renderer/blockmodel/BlockPartFace.java +++ b/java/src/client/renderer/blockmodel/BlockPartFace.java @@ -1,6 +1,6 @@ -package game.renderer.blockmodel; +package client.renderer.blockmodel; -import game.renderer.texture.TextureMap; +import client.renderer.texture.TextureMap; import game.world.Facing; public class BlockPartFace { diff --git a/java/src/game/renderer/blockmodel/BlockPartRotation.java b/java/src/client/renderer/blockmodel/BlockPartRotation.java similarity index 86% rename from java/src/game/renderer/blockmodel/BlockPartRotation.java rename to java/src/client/renderer/blockmodel/BlockPartRotation.java index ccf026e..250034f 100755 --- a/java/src/game/renderer/blockmodel/BlockPartRotation.java +++ b/java/src/client/renderer/blockmodel/BlockPartRotation.java @@ -1,6 +1,6 @@ -package game.renderer.blockmodel; +package client.renderer.blockmodel; -import game.renderer.Vector3f; +import game.util.Vector3f; import game.world.Facing; public class BlockPartRotation { diff --git a/java/src/game/renderer/blockmodel/BreakingFour.java b/java/src/client/renderer/blockmodel/BreakingFour.java similarity index 95% rename from java/src/game/renderer/blockmodel/BreakingFour.java rename to java/src/client/renderer/blockmodel/BreakingFour.java index 976d9e2..ec2cbc9 100755 --- a/java/src/game/renderer/blockmodel/BreakingFour.java +++ b/java/src/client/renderer/blockmodel/BreakingFour.java @@ -1,8 +1,8 @@ -package game.renderer.blockmodel; +package client.renderer.blockmodel; import java.util.Arrays; -import game.renderer.texture.TextureAtlasSprite; +import client.renderer.texture.TextureAtlasSprite; public class BreakingFour extends BakedQuad { diff --git a/java/src/game/model/BuiltInModel.java b/java/src/client/renderer/blockmodel/BuiltInModel.java similarity index 83% rename from java/src/game/model/BuiltInModel.java rename to java/src/client/renderer/blockmodel/BuiltInModel.java index 82611a5..4176e2c 100755 --- a/java/src/game/model/BuiltInModel.java +++ b/java/src/client/renderer/blockmodel/BuiltInModel.java @@ -1,10 +1,9 @@ -package game.model; +package client.renderer.blockmodel; import java.util.List; -import game.renderer.blockmodel.BakedQuad; -import game.renderer.blockmodel.Transforms; -import game.renderer.texture.TextureAtlasSprite; +import client.renderer.texture.TextureAtlasSprite; +import game.model.Transforms; import game.world.Facing; public class BuiltInModel implements IBakedModel diff --git a/java/src/game/renderer/blockmodel/FaceBakery.java b/java/src/client/renderer/blockmodel/FaceBakery.java similarity index 99% rename from java/src/game/renderer/blockmodel/FaceBakery.java rename to java/src/client/renderer/blockmodel/FaceBakery.java index 878669e..6576b8f 100755 --- a/java/src/game/renderer/blockmodel/FaceBakery.java +++ b/java/src/client/renderer/blockmodel/FaceBakery.java @@ -1,11 +1,11 @@ -package game.renderer.blockmodel; +package client.renderer.blockmodel; +import client.renderer.texture.TextureAtlasSprite; import game.model.ModelRotation; -import game.renderer.Matrix4f; -import game.renderer.Vector3f; -import game.renderer.Vector4f; -import game.renderer.texture.TextureAtlasSprite; import game.util.ExtMath; +import game.util.Matrix4f; +import game.util.Vector3f; +import game.util.Vector4f; import game.world.Facing; import game.world.Vec3i; diff --git a/java/src/game/model/IBakedModel.java b/java/src/client/renderer/blockmodel/IBakedModel.java similarity index 69% rename from java/src/game/model/IBakedModel.java rename to java/src/client/renderer/blockmodel/IBakedModel.java index b37bf6c..89db333 100755 --- a/java/src/game/model/IBakedModel.java +++ b/java/src/client/renderer/blockmodel/IBakedModel.java @@ -1,10 +1,9 @@ -package game.model; +package client.renderer.blockmodel; import java.util.List; -import game.renderer.blockmodel.BakedQuad; -import game.renderer.blockmodel.Transforms; -import game.renderer.texture.TextureAtlasSprite; +import client.renderer.texture.TextureAtlasSprite; +import game.model.Transforms; import game.world.Facing; public interface IBakedModel diff --git a/java/src/game/model/ModelBakery.java b/java/src/client/renderer/blockmodel/ModelBakery.java similarity index 93% rename from java/src/game/model/ModelBakery.java rename to java/src/client/renderer/blockmodel/ModelBakery.java index 4c80d7a..ea62808 100755 --- a/java/src/game/model/ModelBakery.java +++ b/java/src/client/renderer/blockmodel/ModelBakery.java @@ -1,4 +1,4 @@ -package game.model; +package client.renderer.blockmodel; import java.util.Collections; import java.util.Comparator; @@ -7,10 +7,12 @@ import java.util.Map; import java.util.Map.Entry; import java.util.Set; +import client.renderer.texture.IIconCreator; +import client.renderer.texture.TextureAtlasSprite; +import client.renderer.texture.TextureMap; import game.collect.Lists; import game.collect.Maps; import game.collect.Sets; - import game.init.BlockRegistry; import game.init.FluidRegistry; import game.init.IRegistry; @@ -18,14 +20,7 @@ import game.init.ItemRegistry; import game.init.RegistrySimple; import game.item.Item; import game.item.ItemStack; -import game.renderer.blockmodel.BlockPart; -import game.renderer.blockmodel.BlockPartFace; -import game.renderer.blockmodel.FaceBakery; -import game.renderer.blockmodel.ModelBlock; -import game.renderer.blockmodel.ModelGenerator; -import game.renderer.texture.IIconCreator; -import game.renderer.texture.TextureAtlasSprite; -import game.renderer.texture.TextureMap; +import game.model.ModelRotation; import game.world.Facing; import game.world.State; @@ -42,8 +37,8 @@ public abstract class ModelBakery "items/empty_armor_slot_helmet", "items/empty_armor_slot_chestplate", "items/empty_armor_slot_leggings", "items/empty_armor_slot_boots"); protected static final String MISSING = "builtin/missing" + '#' + "missing"; - public static final ModelBlock MODEL_GENERATED = new ModelBlock(null).add().d(""); - public static final ModelBlock MODEL_ENTITY = new ModelBlock(null).add().d(""); + public static final ModelBlock MODEL_GENERATED = (ModelBlock)new ModelBlock(null).add().d(""); + public static final ModelBlock MODEL_ENTITY = (ModelBlock)new ModelBlock(null).add().d(""); static { for(int z = 0; z < FluidRegistry.getNumFluids(); z++) { @@ -65,11 +60,11 @@ public abstract class ModelBakery // Map> variantNames = Maps.>newIdentityHashMap(); // variants.clear(); // Map map = blockModelShapes.getMap(); - models.put(MISSING, new ModelBlock(null).add().all()); + models.put(MISSING, (ModelBlock)new ModelBlock(null).add().all()); variants.add(MISSING); for(Entry entry : map.entrySet()) { - ModelBlock model = entry.getKey().getBlock().getModel(BlockRegistry.REGISTRY.getNameForObject(entry.getKey().getBlock()) - .toString(), entry.getKey()); + ModelBlock model = (ModelBlock)entry.getKey().getBlock().getModel(ModelBlock.PROVIDER, BlockRegistry.REGISTRY.getNameForObject(entry.getKey().getBlock()) + .toString(), entry.getKey()); // ResourceLocation blk = new ResourceLocation(entry.getValue().getName()); models.put(entry.getValue(), model); variants.add(entry.getValue()); @@ -150,7 +145,7 @@ public abstract class ModelBakery item.getRenderItems(item, stacks); for(ItemStack stack : stacks) { String resourcelocation = "item/" + ItemRegistry.REGISTRY.getNameForObject(item).toString() + "#" + stack.getMetadata() + '#' + "inventory"; - models.put(resourcelocation, item.getModel(ItemRegistry.REGISTRY.getNameForObject(item).toString(), stack.getMetadata())); + models.put(resourcelocation, (ModelBlock)item.getModel(ModelBlock.PROVIDER, ItemRegistry.REGISTRY.getNameForObject(item).toString(), stack.getMetadata())); itemLocations.add(resourcelocation); } stacks.clear(); diff --git a/java/src/client/renderer/blockmodel/ModelBlock.java b/java/src/client/renderer/blockmodel/ModelBlock.java new file mode 100755 index 0000000..c7e4400 --- /dev/null +++ b/java/src/client/renderer/blockmodel/ModelBlock.java @@ -0,0 +1,203 @@ +package client.renderer.blockmodel; + +import java.util.List; + +import client.renderer.texture.TextureMap; +import game.collect.Lists; +import game.collect.Maps; +import game.model.Model; +import game.model.ModelProvider; +import game.model.ModelRotation; +import game.model.Transforms; +import game.util.Vector3f; +import game.world.Facing; + +public class ModelBlock extends Model { + static final ModelProvider PROVIDER = new ModelProvider() { + public Model getModel(String primary) { + return new ModelBlock(primary); + } + + public Model getModel(Transforms transform, String... layers) { + return new ModelBlock(transform, layers); + } + + public Model getModel(Model parent, Transforms transform) { + return new ModelBlock((ModelBlock)parent, transform); + } + + public Model getEntityModel() { + return ModelBakery.MODEL_ENTITY; + } + }; + + private final List elements; + private final boolean gui3d; + private final String primary; + private final String[] layers; + private final ModelBlock parent; + + private boolean occlusion; + private ModelRotation rotation; + private boolean uvLock; + private Transforms transform; + + private BlockPart lastPart; + private BlockPartFace[] last; + + public static void setAsProvider() { + ModelProvider.setProvider(PROVIDER); + } + + public ModelBlock noOcclude() { + this.occlusion = false; + return this; + } + + public ModelBlock uvLock() { + this.uvLock = true; + return this; + } + + public ModelBlock rotate(ModelRotation rot) { + this.rotation = rot; + return this; + } + + public ModelBlock add(float x1, float y1, float z1, float x2, float y2, float z2) { + this.elements.add(this.lastPart = new BlockPart(new Vector3f(x1, y1, z1), new Vector3f(x2, y2, z2), + Maps.newEnumMap(Facing.class), null, true)); + return this; + } + + public ModelBlock noShade() { + this.lastPart.shade = false; + return this; + } + + public ModelBlock rotate(float x, float y, float z, Facing.Axis axisIn, float angleIn, boolean rescaleIn) { + this.lastPart.partRotation = new BlockPartRotation(x, y, z, axisIn, angleIn, rescaleIn); + return this; + } + + public ModelBlock face(String texture, Facing ... faces) { + texture = !texture.equals(TextureMap.LOCATION_MISSING_TEXTURE) && texture.indexOf('/') == -1 ? "blocks/" + texture : texture; + this.last = new BlockPartFace[faces.length]; + for(int z = 0; z < faces.length; z++) { + this.lastPart.mapFaces.put(faces[z], this.last[z] = + new BlockPartFace(faces[z], -1, texture, new BlockFaceUV(this.lastPart.getFaceUvs(faces[z]), 0))); + } + return this; + } + + public ModelBlock cull(Facing cull) { + for(BlockPartFace last : this.last) { + last.cull = cull; + } + return this; + } + + public ModelBlock tint() { + for(BlockPartFace last : this.last) { + last.tint = 0; + } + return this; + } + + public ModelBlock rot(int rot) { + for(BlockPartFace last : this.last) { + last.uv = new BlockFaceUV(last.uv.uvs, rot); + } + return this; + } + + public ModelBlock uv(float x1, float y1, float x2, float y2) { + for(BlockPartFace last : this.last) { + last.uv = new BlockFaceUV(new float[] {x1, y1, x2, y2}, last.uv.rotation); + } + return this; + } + + public String getPrimary() { + return this.primary; + } + + + public ModelBlock(String primary) { + this(null, Lists.newArrayList(), primary != null && primary.indexOf('/') == -1 ? "blocks/" + primary : primary, true, true, Transforms.DEFAULT, null); + } + + public ModelBlock(Transforms transform, String ... layers) { + this(ModelBakery.MODEL_GENERATED, ModelBakery.MODEL_GENERATED.elements, + layers[0].indexOf('/') == -1 ? "items/" + layers[0] : layers[0], false, false, transform, layers); + } + + public ModelBlock(ModelBlock parent, Transforms transform) { + this(parent, Lists.newArrayList(), parent.getPrimary(), false, true, transform, null); + } + + public ModelBlock(String primary, Transforms transform, String ... layers) { + this(ModelBakery.MODEL_GENERATED, ModelBakery.MODEL_GENERATED.elements, + primary.indexOf('/') == -1 ? "items/" + primary : primary, false, false, transform, layers); + } + + public ModelBlock(String primary, List elements, Transforms transform, String ... layers) { + this(null, elements, primary, false, false, transform, layers); + } + + private ModelBlock(ModelBlock parent, List elements, String primary, boolean occlude, boolean gui3d, + Transforms transform, String[] layers) { + for(int z = 0; layers != null && z < layers.length; z++) { + layers[z] = layers[z].indexOf('/') == -1 ? "items/" + layers[z] : layers[z]; + } + this.elements = parent == null ? elements : parent.getElements(); + this.occlusion = parent == null ? occlude : parent.isAmbientOcclusion(); + this.gui3d = gui3d; + this.primary = primary == null ? TextureMap.LOCATION_MISSING_TEXTURE : primary; + this.parent = parent; + this.transform = transform; + this.uvLock = false; + this.rotation = ModelRotation.X0_Y0; + this.layers = layers; + } + + public List getElements() { + return this.elements; + } + + public boolean isAmbientOcclusion() { + return this.occlusion; + } + + public boolean isGui3d() { + return this.gui3d; + } + + public String[] getTextures() { + return this.layers; + } + + public int getNumTextures() { + return this.layers == null ? 0 : this.layers.length; + } + + public String getTexture(int layer) { + return this.layers == null || this.layers[layer] == null ? TextureMap.LOCATION_MISSING_TEXTURE : this.layers[layer]; + } + + public ModelBlock getParent() { + return this.parent; + } + + public Transforms getTransform() { + return this.transform; + } + + public ModelRotation getRotation() { + return this.rotation; + } + + public boolean isUvLocked() { + return this.uvLock; + } +} diff --git a/java/src/game/renderer/blockmodel/ModelGenerator.java b/java/src/client/renderer/blockmodel/ModelGenerator.java similarity index 97% rename from java/src/game/renderer/blockmodel/ModelGenerator.java rename to java/src/client/renderer/blockmodel/ModelGenerator.java index 818db2a..60eb36b 100755 --- a/java/src/game/renderer/blockmodel/ModelGenerator.java +++ b/java/src/client/renderer/blockmodel/ModelGenerator.java @@ -1,18 +1,17 @@ -package game.renderer.blockmodel; +package client.renderer.blockmodel; import java.io.FileNotFoundException; import java.util.List; import java.util.Map; +import client.renderer.model.ModelBox; +import client.renderer.texture.TextureAtlasSprite; +import client.renderer.texture.TextureMap; +import client.renderer.texture.TextureUtil; import game.collect.Lists; import game.collect.Maps; - import game.log.Log; -import game.renderer.Vector3f; -import game.renderer.model.ModelBox; -import game.renderer.texture.TextureAtlasSprite; -import game.renderer.texture.TextureMap; -import game.renderer.texture.TextureUtil; +import game.util.Vector3f; import game.world.Facing; public abstract class ModelGenerator { diff --git a/java/src/game/model/ModelManager.java b/java/src/client/renderer/blockmodel/ModelManager.java similarity index 95% rename from java/src/game/model/ModelManager.java rename to java/src/client/renderer/blockmodel/ModelManager.java index 41e86b5..a82aa95 100755 --- a/java/src/game/model/ModelManager.java +++ b/java/src/client/renderer/blockmodel/ModelManager.java @@ -1,24 +1,20 @@ -package game.model; +package client.renderer.blockmodel; import java.util.Collections; import java.util.Map; import java.util.Map.Entry; import java.util.Set; -import game.collect.Maps; - +import client.renderer.texture.TextureAtlasSprite; +import client.renderer.texture.TextureMap; import game.block.Block; import game.block.BlockLiquid; +import game.collect.Maps; import game.init.BlockRegistry; import game.init.Blocks; import game.init.FluidRegistry; import game.init.IRegistry; import game.properties.IProperty; -import game.renderer.blockmodel.MultiStateMap; -import game.renderer.blockmodel.SingleStateMap; -import game.renderer.blockmodel.StateMap; -import game.renderer.texture.TextureAtlasSprite; -import game.renderer.texture.TextureMap; import game.world.State; public class ModelManager diff --git a/java/src/game/renderer/blockmodel/MultiStateMap.java b/java/src/client/renderer/blockmodel/MultiStateMap.java similarity index 98% rename from java/src/game/renderer/blockmodel/MultiStateMap.java rename to java/src/client/renderer/blockmodel/MultiStateMap.java index 17996e3..667d3ad 100755 --- a/java/src/game/renderer/blockmodel/MultiStateMap.java +++ b/java/src/client/renderer/blockmodel/MultiStateMap.java @@ -1,4 +1,4 @@ -package game.renderer.blockmodel; +package client.renderer.blockmodel; import java.util.Collections; import java.util.List; @@ -6,7 +6,6 @@ import java.util.Map; import game.collect.Lists; import game.collect.Maps; - import game.init.BlockRegistry; import game.properties.IProperty; import game.world.State; diff --git a/java/src/game/renderer/blockmodel/SingleStateMap.java b/java/src/client/renderer/blockmodel/SingleStateMap.java similarity index 89% rename from java/src/game/renderer/blockmodel/SingleStateMap.java rename to java/src/client/renderer/blockmodel/SingleStateMap.java index 8d236e4..69c9880 100755 --- a/java/src/game/renderer/blockmodel/SingleStateMap.java +++ b/java/src/client/renderer/blockmodel/SingleStateMap.java @@ -1,4 +1,4 @@ -package game.renderer.blockmodel; +package client.renderer.blockmodel; import game.init.BlockRegistry; import game.world.State; diff --git a/java/src/game/renderer/blockmodel/StateMap.java b/java/src/client/renderer/blockmodel/StateMap.java similarity index 97% rename from java/src/game/renderer/blockmodel/StateMap.java rename to java/src/client/renderer/blockmodel/StateMap.java index caf1a7a..ba64c28 100755 --- a/java/src/game/renderer/blockmodel/StateMap.java +++ b/java/src/client/renderer/blockmodel/StateMap.java @@ -1,11 +1,10 @@ -package game.renderer.blockmodel; +package client.renderer.blockmodel; import java.util.Map; import java.util.Map.Entry; -import game.collect.Maps; - import game.block.Block; +import game.collect.Maps; import game.properties.IProperty; import game.world.State; diff --git a/java/src/game/renderer/chunk/ChunkCompileTaskGenerator.java b/java/src/client/renderer/chunk/ChunkCompileTaskGenerator.java similarity index 97% rename from java/src/game/renderer/chunk/ChunkCompileTaskGenerator.java rename to java/src/client/renderer/chunk/ChunkCompileTaskGenerator.java index f1014f3..fb91119 100755 --- a/java/src/game/renderer/chunk/ChunkCompileTaskGenerator.java +++ b/java/src/client/renderer/chunk/ChunkCompileTaskGenerator.java @@ -1,12 +1,11 @@ -package game.renderer.chunk; +package client.renderer.chunk; import java.util.List; import java.util.concurrent.locks.ReentrantLock; +import client.renderer.RegionRenderCacheBuilder; import game.collect.Lists; -import game.renderer.RegionRenderCacheBuilder; - public class ChunkCompileTaskGenerator { private final RenderChunk renderChunk; diff --git a/java/src/game/renderer/chunk/ChunkRenderDispatcher.java b/java/src/client/renderer/chunk/ChunkRenderDispatcher.java similarity index 97% rename from java/src/game/renderer/chunk/ChunkRenderDispatcher.java rename to java/src/client/renderer/chunk/ChunkRenderDispatcher.java index ff897c0..cf5f759 100755 --- a/java/src/game/renderer/chunk/ChunkRenderDispatcher.java +++ b/java/src/client/renderer/chunk/ChunkRenderDispatcher.java @@ -1,4 +1,4 @@ -package game.renderer.chunk; +package client.renderer.chunk; import java.util.ArrayDeque; import java.util.List; @@ -7,17 +7,16 @@ import java.util.concurrent.ArrayBlockingQueue; import java.util.concurrent.BlockingQueue; import java.util.concurrent.ThreadFactory; +import client.Game; +import client.renderer.RegionRenderCacheBuilder; +import client.renderer.RenderBuffer; +import client.renderer.VertexBuffer; import game.collect.Lists; import game.future.Futures; import game.future.ListenableFuture; import game.future.ListenableFutureTask; import game.future.ThreadFactoryBuilder; - -import game.Game; -import game.renderer.BlockLayer; -import game.renderer.RegionRenderCacheBuilder; -import game.renderer.RenderBuffer; -import game.renderer.VertexBuffer; +import game.model.BlockLayer; public class ChunkRenderDispatcher { diff --git a/java/src/game/renderer/chunk/ChunkRenderWorker.java b/java/src/client/renderer/chunk/ChunkRenderWorker.java similarity index 98% rename from java/src/game/renderer/chunk/ChunkRenderWorker.java rename to java/src/client/renderer/chunk/ChunkRenderWorker.java index fecc36a..6c99786 100755 --- a/java/src/game/renderer/chunk/ChunkRenderWorker.java +++ b/java/src/client/renderer/chunk/ChunkRenderWorker.java @@ -1,19 +1,18 @@ -package game.renderer.chunk; +package client.renderer.chunk; import java.util.ArrayList; import java.util.List; import java.util.concurrent.CancellationException; +import client.Game; +import client.renderer.RegionRenderCacheBuilder; import game.collect.Lists; +import game.entity.Entity; import game.future.FutureCallback; import game.future.Futures; import game.future.ListenableFuture; - -import game.Game; -import game.entity.Entity; import game.log.Log; -import game.renderer.BlockLayer; -import game.renderer.RegionRenderCacheBuilder; +import game.model.BlockLayer; public class ChunkRenderWorker implements Runnable { diff --git a/java/src/game/renderer/chunk/CompiledChunk.java b/java/src/client/renderer/chunk/CompiledChunk.java similarity index 95% rename from java/src/game/renderer/chunk/CompiledChunk.java rename to java/src/client/renderer/chunk/CompiledChunk.java index 947eec7..a9add33 100755 --- a/java/src/game/renderer/chunk/CompiledChunk.java +++ b/java/src/client/renderer/chunk/CompiledChunk.java @@ -1,11 +1,10 @@ -package game.renderer.chunk; +package client.renderer.chunk; import java.util.List; +import client.renderer.RenderBuffer; import game.collect.Lists; - -import game.renderer.BlockLayer; -import game.renderer.RenderBuffer; +import game.model.BlockLayer; import game.tileentity.TileEntity; import game.world.Facing; diff --git a/java/src/game/renderer/chunk/RenderChunk.java b/java/src/client/renderer/chunk/RenderChunk.java similarity index 96% rename from java/src/game/renderer/chunk/RenderChunk.java rename to java/src/client/renderer/chunk/RenderChunk.java index be4673f..b2f8654 100755 --- a/java/src/game/renderer/chunk/RenderChunk.java +++ b/java/src/client/renderer/chunk/RenderChunk.java @@ -1,4 +1,4 @@ -package game.renderer.chunk; +package client.renderer.chunk; import java.nio.ByteBuffer; import java.nio.ByteOrder; @@ -10,20 +10,19 @@ import java.util.concurrent.locks.ReentrantLock; import org.lwjgl.opengl.GL11; +import client.Game; +import client.renderer.BlockRenderer; +import client.renderer.DefaultVertexFormats; +import client.renderer.RegionRenderCache; +import client.renderer.RenderBuffer; +import client.renderer.RenderGlobal; +import client.renderer.VertexBuffer; +import client.renderer.tileentity.TileEntityRendererDispatcher; +import client.renderer.tileentity.TileEntitySpecialRenderer; +import game.block.Block; import game.collect.Maps; import game.collect.Sets; - -import game.Game; -import game.block.Block; -import game.renderer.BlockLayer; -import game.renderer.BlockRenderer; -import game.renderer.DefaultVertexFormats; -import game.renderer.RegionRenderCache; -import game.renderer.RenderBuffer; -import game.renderer.RenderGlobal; -import game.renderer.VertexBuffer; -import game.renderer.tileentity.TileEntityRendererDispatcher; -import game.renderer.tileentity.TileEntitySpecialRenderer; +import game.model.BlockLayer; import game.tileentity.TileEntity; import game.world.BlockPos; import game.world.BoundingBox; diff --git a/java/src/game/renderer/chunk/SetVisibility.java b/java/src/client/renderer/chunk/SetVisibility.java similarity index 98% rename from java/src/game/renderer/chunk/SetVisibility.java rename to java/src/client/renderer/chunk/SetVisibility.java index f927525..9071bb4 100755 --- a/java/src/game/renderer/chunk/SetVisibility.java +++ b/java/src/client/renderer/chunk/SetVisibility.java @@ -1,4 +1,4 @@ -package game.renderer.chunk; +package client.renderer.chunk; import java.util.BitSet; import java.util.Set; diff --git a/java/src/game/renderer/chunk/VisGraph.java b/java/src/client/renderer/chunk/VisGraph.java similarity index 99% rename from java/src/game/renderer/chunk/VisGraph.java rename to java/src/client/renderer/chunk/VisGraph.java index 4bc1de7..8c6c300 100755 --- a/java/src/game/renderer/chunk/VisGraph.java +++ b/java/src/client/renderer/chunk/VisGraph.java @@ -1,4 +1,4 @@ -package game.renderer.chunk; +package client.renderer.chunk; import java.util.BitSet; import java.util.EnumSet; diff --git a/java/src/game/renderer/entity/Render.java b/java/src/client/renderer/entity/Render.java similarity index 98% rename from java/src/game/renderer/entity/Render.java rename to java/src/client/renderer/entity/Render.java index 2d523f0..3553c7a 100755 --- a/java/src/game/renderer/entity/Render.java +++ b/java/src/client/renderer/entity/Render.java @@ -1,18 +1,18 @@ -package game.renderer.entity; +package client.renderer.entity; import org.lwjgl.opengl.GL11; -import game.Game; +import client.Game; +import client.renderer.DefaultVertexFormats; +import client.renderer.Drawing; +import client.renderer.Frustum; +import client.renderer.GlState; +import client.renderer.RenderBuffer; +import client.renderer.Tessellator; +import client.renderer.texture.TextureAtlasSprite; +import client.renderer.texture.TextureMap; import game.block.Block; import game.entity.Entity; -import game.renderer.DefaultVertexFormats; -import game.renderer.Drawing; -import game.renderer.Frustum; -import game.renderer.GlState; -import game.renderer.RenderBuffer; -import game.renderer.Tessellator; -import game.renderer.texture.TextureAtlasSprite; -import game.renderer.texture.TextureMap; import game.world.BlockPos; import game.world.BoundingBox; import game.world.World; diff --git a/java/src/game/renderer/entity/RenderArachnoid.java b/java/src/client/renderer/entity/RenderArachnoid.java similarity index 94% rename from java/src/game/renderer/entity/RenderArachnoid.java rename to java/src/client/renderer/entity/RenderArachnoid.java index 8a59b4b..34d54a2 100755 --- a/java/src/game/renderer/entity/RenderArachnoid.java +++ b/java/src/client/renderer/entity/RenderArachnoid.java @@ -1,10 +1,10 @@ -package game.renderer.entity; +package client.renderer.entity; import org.lwjgl.opengl.GL11; +import client.renderer.layers.LayerArachnoidArmor; +import client.renderer.model.ModelArachnoid; import game.entity.npc.EntityNPC; -import game.renderer.layers.LayerArachnoidArmor; -import game.renderer.model.ModelArachnoid; public class RenderArachnoid extends RenderHumanoid diff --git a/java/src/game/renderer/entity/RenderArrow.java b/java/src/client/renderer/entity/RenderArrow.java similarity index 95% rename from java/src/game/renderer/entity/RenderArrow.java rename to java/src/client/renderer/entity/RenderArrow.java index 4b6ad8b..defe30b 100755 --- a/java/src/game/renderer/entity/RenderArrow.java +++ b/java/src/client/renderer/entity/RenderArrow.java @@ -1,12 +1,12 @@ -package game.renderer.entity; +package client.renderer.entity; import org.lwjgl.opengl.GL11; +import client.renderer.DefaultVertexFormats; +import client.renderer.GlState; +import client.renderer.RenderBuffer; +import client.renderer.Tessellator; import game.entity.projectile.EntityArrow; -import game.renderer.DefaultVertexFormats; -import game.renderer.GlState; -import game.renderer.RenderBuffer; -import game.renderer.Tessellator; import game.util.ExtMath; diff --git a/java/src/game/renderer/entity/RenderBat.java b/java/src/client/renderer/entity/RenderBat.java similarity index 94% rename from java/src/game/renderer/entity/RenderBat.java rename to java/src/client/renderer/entity/RenderBat.java index 6435569..9aebbeb 100755 --- a/java/src/game/renderer/entity/RenderBat.java +++ b/java/src/client/renderer/entity/RenderBat.java @@ -1,9 +1,9 @@ -package game.renderer.entity; +package client.renderer.entity; import org.lwjgl.opengl.GL11; +import client.renderer.model.ModelBat; import game.entity.animal.EntityBat; -import game.renderer.model.ModelBat; import game.util.ExtMath; diff --git a/java/src/game/renderer/entity/RenderBlockEntity.java b/java/src/client/renderer/entity/RenderBlockEntity.java similarity index 95% rename from java/src/game/renderer/entity/RenderBlockEntity.java rename to java/src/client/renderer/entity/RenderBlockEntity.java index 93308da..d66f02e 100755 --- a/java/src/game/renderer/entity/RenderBlockEntity.java +++ b/java/src/client/renderer/entity/RenderBlockEntity.java @@ -1,11 +1,11 @@ -package game.renderer.entity; +package client.renderer.entity; import org.lwjgl.opengl.GL11; -import game.Game; +import client.Game; +import client.renderer.BlockRenderer; +import client.renderer.texture.TextureMap; import game.entity.Entity; -import game.renderer.BlockRenderer; -import game.renderer.texture.TextureMap; import game.world.State; diff --git a/java/src/game/renderer/entity/RenderBoat.java b/java/src/client/renderer/entity/RenderBoat.java similarity index 94% rename from java/src/game/renderer/entity/RenderBoat.java rename to java/src/client/renderer/entity/RenderBoat.java index 515da63..dc07399 100755 --- a/java/src/game/renderer/entity/RenderBoat.java +++ b/java/src/client/renderer/entity/RenderBoat.java @@ -1,10 +1,10 @@ -package game.renderer.entity; +package client.renderer.entity; import org.lwjgl.opengl.GL11; +import client.renderer.model.ModelBase; +import client.renderer.model.ModelBoat; import game.entity.item.EntityBoat; -import game.renderer.model.ModelBase; -import game.renderer.model.ModelBoat; import game.util.ExtMath; diff --git a/java/src/game/renderer/entity/RenderBullet.java b/java/src/client/renderer/entity/RenderBullet.java similarity index 94% rename from java/src/game/renderer/entity/RenderBullet.java rename to java/src/client/renderer/entity/RenderBullet.java index c94042a..db19e7a 100755 --- a/java/src/game/renderer/entity/RenderBullet.java +++ b/java/src/client/renderer/entity/RenderBullet.java @@ -1,12 +1,12 @@ -package game.renderer.entity; +package client.renderer.entity; import org.lwjgl.opengl.GL11; +import client.renderer.DefaultVertexFormats; +import client.renderer.GlState; +import client.renderer.RenderBuffer; +import client.renderer.Tessellator; import game.entity.projectile.EntityBullet; -import game.renderer.DefaultVertexFormats; -import game.renderer.GlState; -import game.renderer.RenderBuffer; -import game.renderer.Tessellator; public class RenderBullet extends Render diff --git a/java/src/game/renderer/entity/RenderChicken.java b/java/src/client/renderer/entity/RenderChicken.java similarity index 93% rename from java/src/game/renderer/entity/RenderChicken.java rename to java/src/client/renderer/entity/RenderChicken.java index 6757c92..f3ca5bb 100755 --- a/java/src/game/renderer/entity/RenderChicken.java +++ b/java/src/client/renderer/entity/RenderChicken.java @@ -1,7 +1,7 @@ -package game.renderer.entity; +package client.renderer.entity; +import client.renderer.model.ModelBase; import game.entity.animal.EntityChicken; -import game.renderer.model.ModelBase; import game.util.ExtMath; diff --git a/java/src/game/renderer/entity/RenderCow.java b/java/src/client/renderer/entity/RenderCow.java similarity index 88% rename from java/src/game/renderer/entity/RenderCow.java rename to java/src/client/renderer/entity/RenderCow.java index 9fd024e..5fa89d7 100755 --- a/java/src/game/renderer/entity/RenderCow.java +++ b/java/src/client/renderer/entity/RenderCow.java @@ -1,7 +1,7 @@ -package game.renderer.entity; +package client.renderer.entity; +import client.renderer.model.ModelBase; import game.entity.animal.EntityCow; -import game.renderer.model.ModelBase; public class RenderCow extends RenderLiving diff --git a/java/src/game/renderer/entity/RenderCrystal.java b/java/src/client/renderer/entity/RenderCrystal.java similarity index 91% rename from java/src/game/renderer/entity/RenderCrystal.java rename to java/src/client/renderer/entity/RenderCrystal.java index c5bea5d..e2cafd5 100755 --- a/java/src/game/renderer/entity/RenderCrystal.java +++ b/java/src/client/renderer/entity/RenderCrystal.java @@ -1,10 +1,10 @@ -package game.renderer.entity; +package client.renderer.entity; import org.lwjgl.opengl.GL11; +import client.renderer.model.ModelBase; +import client.renderer.model.ModelCrystal; import game.entity.item.EntityCrystal; -import game.renderer.model.ModelBase; -import game.renderer.model.ModelCrystal; import game.util.ExtMath; diff --git a/java/src/game/renderer/entity/RenderDie.java b/java/src/client/renderer/entity/RenderDie.java similarity index 89% rename from java/src/game/renderer/entity/RenderDie.java rename to java/src/client/renderer/entity/RenderDie.java index 2971d80..005243d 100755 --- a/java/src/game/renderer/entity/RenderDie.java +++ b/java/src/client/renderer/entity/RenderDie.java @@ -1,12 +1,12 @@ -package game.renderer.entity; +package client.renderer.entity; import org.lwjgl.opengl.GL11; -import game.Game; +import client.Game; +import client.renderer.model.ModelDie; +import client.renderer.texture.TextureMap; import game.entity.projectile.EntityDie; -import game.renderer.blockmodel.Transforms.Camera; -import game.renderer.model.ModelDie; -import game.renderer.texture.TextureMap; +import game.model.Transforms.Camera; public class RenderDie extends Render { diff --git a/java/src/game/renderer/entity/RenderDragon.java b/java/src/client/renderer/entity/RenderDragon.java similarity index 95% rename from java/src/game/renderer/entity/RenderDragon.java rename to java/src/client/renderer/entity/RenderDragon.java index 53453fe..5195eb1 100755 --- a/java/src/game/renderer/entity/RenderDragon.java +++ b/java/src/client/renderer/entity/RenderDragon.java @@ -1,11 +1,11 @@ -package game.renderer.entity; +package client.renderer.entity; import org.lwjgl.opengl.GL11; +import client.renderer.GlState; +import client.renderer.layers.LayerEnderDragonEyes; +import client.renderer.model.ModelDragon; import game.entity.animal.EntityDragon; -import game.renderer.GlState; -import game.renderer.layers.LayerEnderDragonEyes; -import game.renderer.model.ModelDragon; import game.util.ExtMath; diff --git a/java/src/game/renderer/entity/RenderDynamite.java b/java/src/client/renderer/entity/RenderDynamite.java similarity index 93% rename from java/src/game/renderer/entity/RenderDynamite.java rename to java/src/client/renderer/entity/RenderDynamite.java index a7bdebf..095e81c 100755 --- a/java/src/game/renderer/entity/RenderDynamite.java +++ b/java/src/client/renderer/entity/RenderDynamite.java @@ -1,4 +1,4 @@ -package game.renderer.entity; +package client.renderer.entity; import game.entity.projectile.EntityDynamite; import game.item.Item; diff --git a/java/src/game/renderer/entity/RenderEntity.java b/java/src/client/renderer/entity/RenderEntity.java similarity index 96% rename from java/src/game/renderer/entity/RenderEntity.java rename to java/src/client/renderer/entity/RenderEntity.java index 5d8e2cc..35df7e4 100755 --- a/java/src/game/renderer/entity/RenderEntity.java +++ b/java/src/client/renderer/entity/RenderEntity.java @@ -1,4 +1,4 @@ -package game.renderer.entity; +package client.renderer.entity; import org.lwjgl.opengl.GL11; diff --git a/java/src/game/renderer/entity/RenderEntityItem.java b/java/src/client/renderer/entity/RenderEntityItem.java similarity index 93% rename from java/src/game/renderer/entity/RenderEntityItem.java rename to java/src/client/renderer/entity/RenderEntityItem.java index 6cb9bf3..4afd417 100755 --- a/java/src/game/renderer/entity/RenderEntityItem.java +++ b/java/src/client/renderer/entity/RenderEntityItem.java @@ -1,14 +1,14 @@ -package game.renderer.entity; +package client.renderer.entity; import org.lwjgl.opengl.GL11; +import client.renderer.GlState; +import client.renderer.blockmodel.IBakedModel; +import client.renderer.texture.TextureMap; import game.entity.item.EntityItem; import game.item.Item; import game.item.ItemStack; -import game.model.IBakedModel; -import game.renderer.GlState; -import game.renderer.blockmodel.Transforms; -import game.renderer.texture.TextureMap; +import game.model.Transforms; import game.rng.Random; import game.util.ExtMath; @@ -126,14 +126,14 @@ public class RenderEntityItem extends Render } GL11.glScalef(0.5F, 0.5F, 0.5F); - ibakedmodel.getItemCameraTransforms().apply(Transforms.Camera.GROUND); + RenderItem.apply(ibakedmodel.getItemCameraTransforms(), Transforms.Camera.GROUND); this.itemRenderer.renderItem(itemstack, ibakedmodel); GL11.glPopMatrix(); } else { GL11.glPushMatrix(); - ibakedmodel.getItemCameraTransforms().apply(Transforms.Camera.GROUND); + RenderItem.apply(ibakedmodel.getItemCameraTransforms(), Transforms.Camera.GROUND); this.itemRenderer.renderItem(itemstack, ibakedmodel); GL11.glPopMatrix(); float f3 = ibakedmodel.getItemCameraTransforms().ground.scale.x; diff --git a/java/src/game/renderer/entity/RenderFallingBlock.java b/java/src/client/renderer/entity/RenderFallingBlock.java similarity index 88% rename from java/src/game/renderer/entity/RenderFallingBlock.java rename to java/src/client/renderer/entity/RenderFallingBlock.java index 25a240f..0693bff 100755 --- a/java/src/game/renderer/entity/RenderFallingBlock.java +++ b/java/src/client/renderer/entity/RenderFallingBlock.java @@ -1,17 +1,17 @@ -package game.renderer.entity; +package client.renderer.entity; import org.lwjgl.opengl.GL11; -import game.Game; +import client.Game; +import client.renderer.BlockRenderer; +import client.renderer.DefaultVertexFormats; +import client.renderer.GlState; +import client.renderer.RenderBuffer; +import client.renderer.Tessellator; +import client.renderer.blockmodel.IBakedModel; +import client.renderer.texture.TextureMap; import game.block.Block; import game.entity.item.EntityFalling; -import game.model.IBakedModel; -import game.renderer.BlockRenderer; -import game.renderer.DefaultVertexFormats; -import game.renderer.GlState; -import game.renderer.RenderBuffer; -import game.renderer.Tessellator; -import game.renderer.texture.TextureMap; import game.world.BlockPos; import game.world.State; import game.world.World; diff --git a/java/src/game/renderer/entity/RenderFireball.java b/java/src/client/renderer/entity/RenderFireball.java similarity index 88% rename from java/src/game/renderer/entity/RenderFireball.java rename to java/src/client/renderer/entity/RenderFireball.java index d4f8768..378780c 100755 --- a/java/src/game/renderer/entity/RenderFireball.java +++ b/java/src/client/renderer/entity/RenderFireball.java @@ -1,16 +1,16 @@ -package game.renderer.entity; +package client.renderer.entity; import org.lwjgl.opengl.GL11; -import game.Game; +import client.Game; +import client.renderer.DefaultVertexFormats; +import client.renderer.GlState; +import client.renderer.RenderBuffer; +import client.renderer.Tessellator; +import client.renderer.texture.TextureAtlasSprite; +import client.renderer.texture.TextureMap; import game.entity.projectile.EntityProjectile; import game.init.Items; -import game.renderer.DefaultVertexFormats; -import game.renderer.GlState; -import game.renderer.RenderBuffer; -import game.renderer.Tessellator; -import game.renderer.texture.TextureAtlasSprite; -import game.renderer.texture.TextureMap; public class RenderFireball extends Render diff --git a/java/src/game/renderer/entity/RenderFish.java b/java/src/client/renderer/entity/RenderFish.java similarity index 95% rename from java/src/game/renderer/entity/RenderFish.java rename to java/src/client/renderer/entity/RenderFish.java index f5ce13a..e2c3b7d 100755 --- a/java/src/game/renderer/entity/RenderFish.java +++ b/java/src/client/renderer/entity/RenderFish.java @@ -1,14 +1,14 @@ -package game.renderer.entity; +package client.renderer.entity; import org.lwjgl.opengl.GL11; -import game.Game; +import client.Game; +import client.renderer.DefaultVertexFormats; +import client.renderer.GlState; +import client.renderer.RenderBuffer; +import client.renderer.Tessellator; +import client.renderer.particle.EffectRenderer; import game.entity.projectile.EntityHook; -import game.renderer.DefaultVertexFormats; -import game.renderer.GlState; -import game.renderer.RenderBuffer; -import game.renderer.Tessellator; -import game.renderer.particle.EffectRenderer; import game.util.ExtMath; import game.world.Vec3; diff --git a/java/src/game/renderer/entity/RenderFlyingBox.java b/java/src/client/renderer/entity/RenderFlyingBox.java similarity index 94% rename from java/src/game/renderer/entity/RenderFlyingBox.java rename to java/src/client/renderer/entity/RenderFlyingBox.java index 7bca700..0b974a0 100755 --- a/java/src/game/renderer/entity/RenderFlyingBox.java +++ b/java/src/client/renderer/entity/RenderFlyingBox.java @@ -1,10 +1,10 @@ -package game.renderer.entity; +package client.renderer.entity; import org.lwjgl.opengl.GL11; +import client.renderer.GlState; +import client.renderer.model.ModelHead; import game.entity.projectile.EntityBox; -import game.renderer.GlState; -import game.renderer.model.ModelHead; public class RenderFlyingBox extends Render diff --git a/java/src/game/renderer/entity/RenderHorse.java b/java/src/client/renderer/entity/RenderHorse.java similarity index 94% rename from java/src/game/renderer/entity/RenderHorse.java rename to java/src/client/renderer/entity/RenderHorse.java index 8763953..2c062fa 100755 --- a/java/src/game/renderer/entity/RenderHorse.java +++ b/java/src/client/renderer/entity/RenderHorse.java @@ -1,15 +1,14 @@ -package game.renderer.entity; +package client.renderer.entity; import java.util.Set; import org.lwjgl.opengl.GL11; +import client.Game; +import client.renderer.model.ModelHorse; +import client.renderer.texture.LayeredTexture; import game.collect.Sets; - -import game.Game; import game.entity.animal.EntityHorse; -import game.renderer.model.ModelHorse; -import game.renderer.texture.LayeredTexture; public class RenderHorse extends RenderLiving { diff --git a/java/src/game/renderer/entity/RenderHumanoid.java b/java/src/client/renderer/entity/RenderHumanoid.java similarity index 96% rename from java/src/game/renderer/entity/RenderHumanoid.java rename to java/src/client/renderer/entity/RenderHumanoid.java index e36c7d9..55748f0 100755 --- a/java/src/game/renderer/entity/RenderHumanoid.java +++ b/java/src/client/renderer/entity/RenderHumanoid.java @@ -1,20 +1,20 @@ -package game.renderer.entity; +package client.renderer.entity; import org.lwjgl.opengl.GL11; +import client.renderer.GlState; +import client.renderer.layers.LayerArmor; +import client.renderer.layers.LayerArrow; +import client.renderer.layers.LayerCape; +import client.renderer.layers.LayerCharge; +import client.renderer.layers.LayerExtra; +import client.renderer.layers.LayerHeldItem; +import client.renderer.layers.LayerPowerRods; +import client.renderer.model.ModelBiped; +import client.renderer.model.ModelHumanoid; import game.entity.npc.EntityNPC; import game.item.ItemAction; import game.item.ItemStack; -import game.renderer.GlState; -import game.renderer.layers.LayerArmor; -import game.renderer.layers.LayerArrow; -import game.renderer.layers.LayerCape; -import game.renderer.layers.LayerCharge; -import game.renderer.layers.LayerExtra; -import game.renderer.layers.LayerHeldItem; -import game.renderer.layers.LayerPowerRods; -import game.renderer.model.ModelBiped; -import game.renderer.model.ModelHumanoid; public class RenderHumanoid extends RenderNpc diff --git a/java/src/game/renderer/entity/RenderItem.java b/java/src/client/renderer/entity/RenderItem.java similarity index 90% rename from java/src/game/renderer/entity/RenderItem.java rename to java/src/client/renderer/entity/RenderItem.java index 418e2f8..336ac19 100755 --- a/java/src/game/renderer/entity/RenderItem.java +++ b/java/src/client/renderer/entity/RenderItem.java @@ -1,27 +1,27 @@ -package game.renderer.entity; +package client.renderer.entity; import java.util.List; import org.lwjgl.opengl.GL11; +import client.renderer.DefaultVertexFormats; +import client.renderer.GlState; +import client.renderer.ItemModelMesher; +import client.renderer.RenderBuffer; +import client.renderer.Tessellator; +import client.renderer.blockmodel.BakedQuad; +import client.renderer.blockmodel.IBakedModel; +import client.renderer.blockmodel.ModelManager; +import client.renderer.texture.TextureManager; +import client.renderer.texture.TextureMap; +import client.renderer.tileentity.TileEntityItemStackRenderer; import game.entity.npc.EntityNPC; import game.entity.types.EntityLiving; import game.init.Items; import game.item.Item; import game.item.ItemStack; -import game.model.IBakedModel; -import game.model.ModelManager; -import game.renderer.DefaultVertexFormats; -import game.renderer.GlState; -import game.renderer.ItemModelMesher; -import game.renderer.RenderBuffer; -import game.renderer.Tessellator; -import game.renderer.blockmodel.BakedQuad; -import game.renderer.blockmodel.Transform; -import game.renderer.blockmodel.Transforms; -import game.renderer.texture.TextureManager; -import game.renderer.texture.TextureMap; -import game.renderer.tileentity.TileEntityItemStackRenderer; +import game.model.Transform; +import game.model.Transforms; import game.world.Facing; import game.world.Vec3i; @@ -271,7 +271,7 @@ public class RenderItem GlState.tryBlendFuncSeparate(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA, GL11.GL_ONE, GL11.GL_ZERO); GL11.glPushMatrix(); Transforms itemcameratransforms = model.getItemCameraTransforms(); - itemcameratransforms.apply(cameraTransformType); + RenderItem.apply(itemcameratransforms, cameraTransformType); if (this.isThereOneNegativeScale(itemcameratransforms.get(cameraTransformType))) { @@ -310,7 +310,7 @@ public class RenderItem GlState.blendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA); GlState.color(1.0F, 1.0F, 1.0F, 1.0F); this.setupGuiTransform(x, y, ibakedmodel.isGui3d()); - ibakedmodel.getItemCameraTransforms().apply(Transforms.Camera.GUI); + RenderItem.apply(ibakedmodel.getItemCameraTransforms(), Transforms.Camera.GUI); this.renderItem(stack, ibakedmodel); GlState.disableAlpha(); GlState.disableRescaleNormal(); @@ -358,4 +358,15 @@ public class RenderItem { this.itemModelMesher.rebuildCache(); } + + public static void apply(Transforms trans, Transforms.Camera type) { + Transform vec = trans.get(type); + if(vec != Transform.IDENTITY) { + GL11.glTranslatef(vec.translation.x, vec.translation.y, vec.translation.z); + GL11.glRotatef(vec.rotation.y, 0.0F, 1.0F, 0.0F); + GL11.glRotatef(vec.rotation.x, 1.0F, 0.0F, 0.0F); + GL11.glRotatef(vec.rotation.z, 0.0F, 0.0F, 1.0F); + GL11.glScalef(vec.scale.x, vec.scale.y, vec.scale.z); + } + } } diff --git a/java/src/game/renderer/entity/RenderItemEntity.java b/java/src/client/renderer/entity/RenderItemEntity.java similarity index 90% rename from java/src/game/renderer/entity/RenderItemEntity.java rename to java/src/client/renderer/entity/RenderItemEntity.java index 1776f47..d7c1108 100755 --- a/java/src/game/renderer/entity/RenderItemEntity.java +++ b/java/src/client/renderer/entity/RenderItemEntity.java @@ -1,13 +1,13 @@ -package game.renderer.entity; +package client.renderer.entity; import org.lwjgl.opengl.GL11; +import client.renderer.GlState; +import client.renderer.texture.TextureMap; import game.entity.Entity; import game.item.Item; import game.item.ItemStack; -import game.renderer.GlState; -import game.renderer.blockmodel.Transforms; -import game.renderer.texture.TextureMap; +import game.model.Transforms; public class RenderItemEntity extends Render diff --git a/java/src/game/renderer/entity/RenderLeashKnot.java b/java/src/client/renderer/entity/RenderLeashKnot.java similarity index 92% rename from java/src/game/renderer/entity/RenderLeashKnot.java rename to java/src/client/renderer/entity/RenderLeashKnot.java index ee7afa0..cd89065 100755 --- a/java/src/game/renderer/entity/RenderLeashKnot.java +++ b/java/src/client/renderer/entity/RenderLeashKnot.java @@ -1,10 +1,10 @@ -package game.renderer.entity; +package client.renderer.entity; import org.lwjgl.opengl.GL11; +import client.renderer.GlState; +import client.renderer.model.ModelLeashKnot; import game.entity.item.EntityLeashKnot; -import game.renderer.GlState; -import game.renderer.model.ModelLeashKnot; public class RenderLeashKnot extends Render diff --git a/java/src/game/renderer/entity/RenderLightning.java b/java/src/client/renderer/entity/RenderLightning.java similarity index 96% rename from java/src/game/renderer/entity/RenderLightning.java rename to java/src/client/renderer/entity/RenderLightning.java index d520f5a..f4a77ec 100755 --- a/java/src/game/renderer/entity/RenderLightning.java +++ b/java/src/client/renderer/entity/RenderLightning.java @@ -1,12 +1,12 @@ -package game.renderer.entity; +package client.renderer.entity; import org.lwjgl.opengl.GL11; +import client.renderer.DefaultVertexFormats; +import client.renderer.GlState; +import client.renderer.RenderBuffer; +import client.renderer.Tessellator; import game.entity.effect.EntityLightning; -import game.renderer.DefaultVertexFormats; -import game.renderer.GlState; -import game.renderer.RenderBuffer; -import game.renderer.Tessellator; import game.rng.Random; diff --git a/java/src/game/renderer/entity/RenderLiving.java b/java/src/client/renderer/entity/RenderLiving.java similarity index 95% rename from java/src/game/renderer/entity/RenderLiving.java rename to java/src/client/renderer/entity/RenderLiving.java index afb8281..bb75233 100755 --- a/java/src/game/renderer/entity/RenderLiving.java +++ b/java/src/client/renderer/entity/RenderLiving.java @@ -1,17 +1,17 @@ -package game.renderer.entity; +package client.renderer.entity; import org.lwjgl.opengl.GL11; import org.lwjgl.opengl.GL13; +import client.renderer.DefaultVertexFormats; +import client.renderer.Frustum; +import client.renderer.GlState; +import client.renderer.RenderBuffer; +import client.renderer.Tessellator; +import client.renderer.model.ModelBase; import game.entity.Entity; import game.entity.item.EntityLeashKnot; import game.entity.types.EntityLiving; -import game.renderer.DefaultVertexFormats; -import game.renderer.Frustum; -import game.renderer.GlState; -import game.renderer.RenderBuffer; -import game.renderer.Tessellator; -import game.renderer.model.ModelBase; public abstract class RenderLiving extends RendererLivingEntity { public RenderLiving(RenderManager manager, ModelBase model) { diff --git a/java/src/game/renderer/entity/RenderManager.java b/java/src/client/renderer/entity/RenderManager.java similarity index 96% rename from java/src/game/renderer/entity/RenderManager.java rename to java/src/client/renderer/entity/RenderManager.java index 26cf651..3fb1186 100755 --- a/java/src/game/renderer/entity/RenderManager.java +++ b/java/src/client/renderer/entity/RenderManager.java @@ -1,23 +1,22 @@ -package game.renderer.entity; +package client.renderer.entity; import java.util.Map; import org.lwjgl.opengl.GL11; import org.lwjgl.opengl.GL13; +import client.Game; +import client.init.EntityRenderRegistry; +import client.renderer.DefaultVertexFormats; +import client.renderer.GlState; +import client.renderer.RenderBuffer; +import client.renderer.RenderGlobal; +import client.renderer.Tessellator; +import client.renderer.texture.TextureManager; import game.collect.Maps; - -import game.Game; import game.entity.Entity; import game.entity.types.EntityLiving; -import game.init.EntityRegistry; import game.init.SpeciesRegistry.ModelType; -import game.renderer.DefaultVertexFormats; -import game.renderer.GlState; -import game.renderer.RenderBuffer; -import game.renderer.RenderGlobal; -import game.renderer.Tessellator; -import game.renderer.texture.TextureManager; import game.world.BoundingBox; import game.world.Vec3; import game.world.World; @@ -69,7 +68,7 @@ public class RenderManager public RenderManager(TextureManager renderEngineIn, RenderItem itemRendererIn) { this.renderEngine = renderEngineIn; - EntityRegistry.registerRenderers(this.entityRenderMap, this.models, this, itemRendererIn); + EntityRenderRegistry.registerRenderers(this.entityRenderMap, this.models, this, itemRendererIn); for(RenderNpc render : this.models.values()) { render.initSegments(); } diff --git a/java/src/game/renderer/entity/RenderMinecart.java b/java/src/client/renderer/entity/RenderMinecart.java similarity index 95% rename from java/src/game/renderer/entity/RenderMinecart.java rename to java/src/client/renderer/entity/RenderMinecart.java index 88a70fa..c3256d1 100755 --- a/java/src/game/renderer/entity/RenderMinecart.java +++ b/java/src/client/renderer/entity/RenderMinecart.java @@ -1,13 +1,13 @@ -package game.renderer.entity; +package client.renderer.entity; import org.lwjgl.opengl.GL11; -import game.Game; +import client.Game; +import client.renderer.GlState; +import client.renderer.model.ModelBase; +import client.renderer.model.ModelMinecart; +import client.renderer.texture.TextureMap; import game.entity.item.EntityCart; -import game.renderer.GlState; -import game.renderer.model.ModelBase; -import game.renderer.model.ModelMinecart; -import game.renderer.texture.TextureMap; import game.util.ExtMath; import game.world.State; import game.world.Vec3; diff --git a/java/src/game/renderer/entity/RenderMooshroom.java b/java/src/client/renderer/entity/RenderMooshroom.java similarity index 83% rename from java/src/game/renderer/entity/RenderMooshroom.java rename to java/src/client/renderer/entity/RenderMooshroom.java index 75701b3..878c203 100755 --- a/java/src/game/renderer/entity/RenderMooshroom.java +++ b/java/src/client/renderer/entity/RenderMooshroom.java @@ -1,8 +1,8 @@ -package game.renderer.entity; +package client.renderer.entity; +import client.renderer.layers.LayerMooshroomMushroom; +import client.renderer.model.ModelBase; import game.entity.animal.EntityMooshroom; -import game.renderer.layers.LayerMooshroomMushroom; -import game.renderer.model.ModelBase; public class RenderMooshroom extends RenderLiving diff --git a/java/src/game/renderer/entity/RenderMouse.java b/java/src/client/renderer/entity/RenderMouse.java similarity index 85% rename from java/src/game/renderer/entity/RenderMouse.java rename to java/src/client/renderer/entity/RenderMouse.java index 5b07a11..3fa6ad3 100755 --- a/java/src/game/renderer/entity/RenderMouse.java +++ b/java/src/client/renderer/entity/RenderMouse.java @@ -1,7 +1,7 @@ -package game.renderer.entity; +package client.renderer.entity; +import client.renderer.model.ModelBase; import game.entity.animal.EntityMouse; -import game.renderer.model.ModelBase; public class RenderMouse extends RenderLiving diff --git a/java/src/game/renderer/entity/RenderNpc.java b/java/src/client/renderer/entity/RenderNpc.java similarity index 97% rename from java/src/game/renderer/entity/RenderNpc.java rename to java/src/client/renderer/entity/RenderNpc.java index 72c4b64..c443ef8 100755 --- a/java/src/game/renderer/entity/RenderNpc.java +++ b/java/src/client/renderer/entity/RenderNpc.java @@ -1,10 +1,10 @@ -package game.renderer.entity; +package client.renderer.entity; import java.util.ArrayList; +import client.renderer.model.ModelBase; +import client.renderer.texture.EntityTexManager; import game.entity.npc.EntityNPC; -import game.renderer.model.ModelBase; -import game.renderer.texture.EntityTexManager; public abstract class RenderNpc extends RenderLiving diff --git a/java/src/game/renderer/entity/RenderOcelot.java b/java/src/client/renderer/entity/RenderOcelot.java similarity index 95% rename from java/src/game/renderer/entity/RenderOcelot.java rename to java/src/client/renderer/entity/RenderOcelot.java index 5b9ce7c..2fd5203 100755 --- a/java/src/game/renderer/entity/RenderOcelot.java +++ b/java/src/client/renderer/entity/RenderOcelot.java @@ -1,9 +1,9 @@ -package game.renderer.entity; +package client.renderer.entity; import org.lwjgl.opengl.GL11; +import client.renderer.model.ModelBase; import game.entity.animal.EntityOcelot; -import game.renderer.model.ModelBase; public class RenderOcelot extends RenderLiving diff --git a/java/src/game/renderer/entity/RenderPig.java b/java/src/client/renderer/entity/RenderPig.java similarity index 83% rename from java/src/game/renderer/entity/RenderPig.java rename to java/src/client/renderer/entity/RenderPig.java index 73d73a6..8b821da 100755 --- a/java/src/game/renderer/entity/RenderPig.java +++ b/java/src/client/renderer/entity/RenderPig.java @@ -1,8 +1,8 @@ -package game.renderer.entity; +package client.renderer.entity; +import client.renderer.layers.LayerSaddle; +import client.renderer.model.ModelBase; import game.entity.animal.EntityPig; -import game.renderer.layers.LayerSaddle; -import game.renderer.model.ModelBase; public class RenderPig extends RenderLiving diff --git a/java/src/game/renderer/entity/RenderPotion.java b/java/src/client/renderer/entity/RenderPotion.java similarity index 93% rename from java/src/game/renderer/entity/RenderPotion.java rename to java/src/client/renderer/entity/RenderPotion.java index 06de9c3..cb574bf 100755 --- a/java/src/game/renderer/entity/RenderPotion.java +++ b/java/src/client/renderer/entity/RenderPotion.java @@ -1,4 +1,4 @@ -package game.renderer.entity; +package client.renderer.entity; import game.entity.projectile.EntityPotion; import game.init.Items; diff --git a/java/src/game/renderer/entity/RenderRabbit.java b/java/src/client/renderer/entity/RenderRabbit.java similarity index 94% rename from java/src/game/renderer/entity/RenderRabbit.java rename to java/src/client/renderer/entity/RenderRabbit.java index 3796049..fbb7c7e 100755 --- a/java/src/game/renderer/entity/RenderRabbit.java +++ b/java/src/client/renderer/entity/RenderRabbit.java @@ -1,8 +1,8 @@ -package game.renderer.entity; +package client.renderer.entity; +import client.renderer.model.ModelBase; import game.color.TextColor; import game.entity.animal.EntityRabbit; -import game.renderer.model.ModelBase; public class RenderRabbit extends RenderLiving { diff --git a/java/src/game/renderer/entity/RenderSheep.java b/java/src/client/renderer/entity/RenderSheep.java similarity index 83% rename from java/src/game/renderer/entity/RenderSheep.java rename to java/src/client/renderer/entity/RenderSheep.java index e6289a0..01cad8d 100755 --- a/java/src/game/renderer/entity/RenderSheep.java +++ b/java/src/client/renderer/entity/RenderSheep.java @@ -1,8 +1,8 @@ -package game.renderer.entity; +package client.renderer.entity; +import client.renderer.layers.LayerSheepWool; +import client.renderer.model.ModelBase; import game.entity.animal.EntitySheep; -import game.renderer.layers.LayerSheepWool; -import game.renderer.model.ModelBase; public class RenderSheep extends RenderLiving diff --git a/java/src/game/renderer/entity/RenderSlime.java b/java/src/client/renderer/entity/RenderSlime.java similarity index 96% rename from java/src/game/renderer/entity/RenderSlime.java rename to java/src/client/renderer/entity/RenderSlime.java index 4cfc046..c3ff29f 100755 --- a/java/src/game/renderer/entity/RenderSlime.java +++ b/java/src/client/renderer/entity/RenderSlime.java @@ -1,11 +1,11 @@ -package game.renderer.entity; +package client.renderer.entity; import org.lwjgl.opengl.GL11; +import client.renderer.layers.LayerSlimeGel; +import client.renderer.model.ModelSlime; import game.entity.npc.EntityNPC; import game.entity.npc.EntitySlime; -import game.renderer.layers.LayerSlimeGel; -import game.renderer.model.ModelSlime; public class RenderSlime extends RenderNpc diff --git a/java/src/game/renderer/entity/RenderSpaceMarine.java b/java/src/client/renderer/entity/RenderSpaceMarine.java similarity index 95% rename from java/src/game/renderer/entity/RenderSpaceMarine.java rename to java/src/client/renderer/entity/RenderSpaceMarine.java index 083ccd8..bad1b01 100755 --- a/java/src/game/renderer/entity/RenderSpaceMarine.java +++ b/java/src/client/renderer/entity/RenderSpaceMarine.java @@ -1,13 +1,13 @@ -package game.renderer.entity; +package client.renderer.entity; import org.lwjgl.opengl.GL11; +import client.renderer.layers.LayerArrow; +import client.renderer.layers.LayerHeldItem; +import client.renderer.model.ModelSpaceMarine; import game.entity.npc.EntityNPC; import game.item.ItemAction; import game.item.ItemStack; -import game.renderer.layers.LayerArrow; -import game.renderer.layers.LayerHeldItem; -import game.renderer.model.ModelSpaceMarine; public class RenderSpaceMarine extends RenderNpc diff --git a/java/src/game/renderer/entity/RenderSquid.java b/java/src/client/renderer/entity/RenderSquid.java similarity index 95% rename from java/src/game/renderer/entity/RenderSquid.java rename to java/src/client/renderer/entity/RenderSquid.java index d122968..c09b1cf 100755 --- a/java/src/game/renderer/entity/RenderSquid.java +++ b/java/src/client/renderer/entity/RenderSquid.java @@ -1,9 +1,9 @@ -package game.renderer.entity; +package client.renderer.entity; import org.lwjgl.opengl.GL11; +import client.renderer.model.ModelBase; import game.entity.animal.EntitySquid; -import game.renderer.model.ModelBase; public class RenderSquid extends RenderLiving diff --git a/java/src/game/renderer/entity/RenderTntMinecart.java b/java/src/client/renderer/entity/RenderTntMinecart.java similarity index 92% rename from java/src/game/renderer/entity/RenderTntMinecart.java rename to java/src/client/renderer/entity/RenderTntMinecart.java index f8ac46c..5150ccf 100755 --- a/java/src/game/renderer/entity/RenderTntMinecart.java +++ b/java/src/client/renderer/entity/RenderTntMinecart.java @@ -1,12 +1,12 @@ -package game.renderer.entity; +package client.renderer.entity; import org.lwjgl.opengl.GL11; -import game.Game; +import client.Game; +import client.renderer.BlockRenderer; +import client.renderer.GlState; import game.entity.item.EntityTntCart; import game.init.Blocks; -import game.renderer.BlockRenderer; -import game.renderer.GlState; import game.util.ExtMath; import game.world.State; diff --git a/java/src/game/renderer/entity/RenderTntPrimed.java b/java/src/client/renderer/entity/RenderTntPrimed.java similarity index 93% rename from java/src/game/renderer/entity/RenderTntPrimed.java rename to java/src/client/renderer/entity/RenderTntPrimed.java index 9ecee6e..5edf422 100755 --- a/java/src/game/renderer/entity/RenderTntPrimed.java +++ b/java/src/client/renderer/entity/RenderTntPrimed.java @@ -1,14 +1,14 @@ -package game.renderer.entity; +package client.renderer.entity; import org.lwjgl.opengl.GL11; -import game.Game; +import client.Game; +import client.renderer.BlockRenderer; +import client.renderer.GlState; +import client.renderer.texture.TextureMap; import game.block.BlockTNT; import game.entity.item.EntityTnt; import game.init.Blocks; -import game.renderer.BlockRenderer; -import game.renderer.GlState; -import game.renderer.texture.TextureMap; import game.util.ExtMath; diff --git a/java/src/game/renderer/entity/RenderWolf.java b/java/src/client/renderer/entity/RenderWolf.java similarity index 90% rename from java/src/game/renderer/entity/RenderWolf.java rename to java/src/client/renderer/entity/RenderWolf.java index f9cae80..8831285 100755 --- a/java/src/game/renderer/entity/RenderWolf.java +++ b/java/src/client/renderer/entity/RenderWolf.java @@ -1,9 +1,9 @@ -package game.renderer.entity; +package client.renderer.entity; +import client.renderer.GlState; +import client.renderer.layers.LayerWolfCollar; +import client.renderer.model.ModelBase; import game.entity.animal.EntityWolf; -import game.renderer.GlState; -import game.renderer.layers.LayerWolfCollar; -import game.renderer.model.ModelBase; public class RenderWolf extends RenderLiving diff --git a/java/src/game/renderer/entity/RenderXpOrb.java b/java/src/client/renderer/entity/RenderXpOrb.java similarity index 94% rename from java/src/game/renderer/entity/RenderXpOrb.java rename to java/src/client/renderer/entity/RenderXpOrb.java index 43252b2..c9e7d69 100755 --- a/java/src/game/renderer/entity/RenderXpOrb.java +++ b/java/src/client/renderer/entity/RenderXpOrb.java @@ -1,13 +1,13 @@ -package game.renderer.entity; +package client.renderer.entity; import org.lwjgl.opengl.GL11; import org.lwjgl.opengl.GL13; +import client.renderer.DefaultVertexFormats; +import client.renderer.GlState; +import client.renderer.RenderBuffer; +import client.renderer.Tessellator; import game.entity.item.EntityXp; -import game.renderer.DefaultVertexFormats; -import game.renderer.GlState; -import game.renderer.RenderBuffer; -import game.renderer.Tessellator; import game.util.ExtMath; diff --git a/java/src/game/renderer/entity/RendererLivingEntity.java b/java/src/client/renderer/entity/RendererLivingEntity.java similarity index 98% rename from java/src/game/renderer/entity/RendererLivingEntity.java rename to java/src/client/renderer/entity/RendererLivingEntity.java index 3034ba3..880ec72 100755 --- a/java/src/game/renderer/entity/RendererLivingEntity.java +++ b/java/src/client/renderer/entity/RendererLivingEntity.java @@ -1,4 +1,4 @@ -package game.renderer.entity; +package client.renderer.entity; import java.nio.ByteBuffer; import java.nio.ByteOrder; @@ -8,22 +8,21 @@ import java.util.List; import org.lwjgl.opengl.GL11; import org.lwjgl.opengl.GL13; +import client.renderer.DefaultVertexFormats; +import client.renderer.GlState; +import client.renderer.ItemRenderer; +import client.renderer.RenderBuffer; +import client.renderer.Tessellator; +import client.renderer.layers.LayerRenderer; +import client.renderer.model.ModelBase; +import client.renderer.texture.DynamicTexture; import game.collect.Lists; - import game.color.TextColor; import game.entity.Entity; import game.entity.item.EntityCrystal; import game.entity.types.EntityAnimal; import game.entity.types.EntityLiving; import game.log.Log; -import game.renderer.DefaultVertexFormats; -import game.renderer.GlState; -import game.renderer.ItemRenderer; -import game.renderer.RenderBuffer; -import game.renderer.Tessellator; -import game.renderer.layers.LayerRenderer; -import game.renderer.model.ModelBase; -import game.renderer.texture.DynamicTexture; import game.util.ExtMath; public abstract class RendererLivingEntity extends Render diff --git a/java/src/game/renderer/layers/LayerArachnoidArmor.java b/java/src/client/renderer/layers/LayerArachnoidArmor.java similarity index 80% rename from java/src/game/renderer/layers/LayerArachnoidArmor.java rename to java/src/client/renderer/layers/LayerArachnoidArmor.java index 9673886..52e8ef5 100755 --- a/java/src/game/renderer/layers/LayerArachnoidArmor.java +++ b/java/src/client/renderer/layers/LayerArachnoidArmor.java @@ -1,7 +1,7 @@ -package game.renderer.layers; +package client.renderer.layers; -import game.renderer.entity.RendererLivingEntity; -import game.renderer.model.ModelBiped; +import client.renderer.entity.RendererLivingEntity; +import client.renderer.model.ModelBiped; public class LayerArachnoidArmor extends LayerArmor { diff --git a/java/src/game/renderer/layers/LayerArmor.java b/java/src/client/renderer/layers/LayerArmor.java similarity index 97% rename from java/src/game/renderer/layers/LayerArmor.java rename to java/src/client/renderer/layers/LayerArmor.java index 7780453..98d402b 100755 --- a/java/src/game/renderer/layers/LayerArmor.java +++ b/java/src/client/renderer/layers/LayerArmor.java @@ -1,14 +1,14 @@ -package game.renderer.layers; +package client.renderer.layers; import org.lwjgl.opengl.GL11; +import client.renderer.GlState; +import client.renderer.entity.RendererLivingEntity; +import client.renderer.model.ModelArmor; +import client.renderer.model.ModelBiped; import game.entity.types.EntityLiving; import game.item.ItemArmor; import game.item.ItemStack; -import game.renderer.GlState; -import game.renderer.entity.RendererLivingEntity; -import game.renderer.model.ModelArmor; -import game.renderer.model.ModelBiped; public class LayerArmor implements LayerRenderer { diff --git a/java/src/game/renderer/layers/LayerArrow.java b/java/src/client/renderer/layers/LayerArrow.java similarity index 93% rename from java/src/game/renderer/layers/LayerArrow.java rename to java/src/client/renderer/layers/LayerArrow.java index 8ef39b7..a16d5a4 100755 --- a/java/src/game/renderer/layers/LayerArrow.java +++ b/java/src/client/renderer/layers/LayerArrow.java @@ -1,14 +1,14 @@ -package game.renderer.layers; +package client.renderer.layers; import org.lwjgl.opengl.GL11; +import client.renderer.ItemRenderer; +import client.renderer.entity.RendererLivingEntity; +import client.renderer.model.ModelBox; +import client.renderer.model.ModelRenderer; import game.entity.Entity; import game.entity.projectile.EntityArrow; import game.entity.types.EntityLiving; -import game.renderer.ItemRenderer; -import game.renderer.entity.RendererLivingEntity; -import game.renderer.model.ModelBox; -import game.renderer.model.ModelRenderer; import game.rng.Random; import game.util.ExtMath; diff --git a/java/src/game/renderer/layers/LayerCape.java b/java/src/client/renderer/layers/LayerCape.java similarity index 96% rename from java/src/game/renderer/layers/LayerCape.java rename to java/src/client/renderer/layers/LayerCape.java index 986284d..5191980 100755 --- a/java/src/game/renderer/layers/LayerCape.java +++ b/java/src/client/renderer/layers/LayerCape.java @@ -1,11 +1,11 @@ -package game.renderer.layers; +package client.renderer.layers; import org.lwjgl.opengl.GL11; +import client.renderer.GlState; +import client.renderer.entity.RenderHumanoid; +import client.renderer.model.ModelRenderer; import game.entity.npc.EntityNPC; -import game.renderer.GlState; -import game.renderer.entity.RenderHumanoid; -import game.renderer.model.ModelRenderer; import game.util.ExtMath; public class LayerCape implements LayerRenderer diff --git a/java/src/game/renderer/layers/LayerCharge.java b/java/src/client/renderer/layers/LayerCharge.java similarity index 92% rename from java/src/game/renderer/layers/LayerCharge.java rename to java/src/client/renderer/layers/LayerCharge.java index 80dcb6b..64aa253 100755 --- a/java/src/game/renderer/layers/LayerCharge.java +++ b/java/src/client/renderer/layers/LayerCharge.java @@ -1,11 +1,11 @@ -package game.renderer.layers; +package client.renderer.layers; import org.lwjgl.opengl.GL11; +import client.renderer.GlState; +import client.renderer.entity.RenderHumanoid; +import client.renderer.model.ModelCharge; import game.entity.npc.EntityNPC; -import game.renderer.GlState; -import game.renderer.entity.RenderHumanoid; -import game.renderer.model.ModelCharge; public class LayerCharge implements LayerRenderer diff --git a/java/src/game/renderer/layers/LayerEnderDragonEyes.java b/java/src/client/renderer/layers/LayerEnderDragonEyes.java similarity index 93% rename from java/src/game/renderer/layers/LayerEnderDragonEyes.java rename to java/src/client/renderer/layers/LayerEnderDragonEyes.java index 2b3a528..2fed9da 100755 --- a/java/src/game/renderer/layers/LayerEnderDragonEyes.java +++ b/java/src/client/renderer/layers/LayerEnderDragonEyes.java @@ -1,11 +1,11 @@ -package game.renderer.layers; +package client.renderer.layers; import org.lwjgl.opengl.GL11; import org.lwjgl.opengl.GL13; +import client.renderer.GlState; +import client.renderer.entity.RenderDragon; import game.entity.animal.EntityDragon; -import game.renderer.GlState; -import game.renderer.entity.RenderDragon; public class LayerEnderDragonEyes implements LayerRenderer diff --git a/java/src/game/renderer/layers/LayerEntityBreak.java b/java/src/client/renderer/layers/LayerEntityBreak.java similarity index 93% rename from java/src/game/renderer/layers/LayerEntityBreak.java rename to java/src/client/renderer/layers/LayerEntityBreak.java index 03aa1e1..5d64665 100755 --- a/java/src/game/renderer/layers/LayerEntityBreak.java +++ b/java/src/client/renderer/layers/LayerEntityBreak.java @@ -1,13 +1,13 @@ -package game.renderer.layers; +package client.renderer.layers; import org.lwjgl.opengl.GL11; +import client.renderer.DefaultVertexFormats; +import client.renderer.GlState; +import client.renderer.ItemRenderer; +import client.renderer.RenderBuffer; +import client.renderer.Tessellator; import game.entity.animal.EntityDragon; -import game.renderer.DefaultVertexFormats; -import game.renderer.GlState; -import game.renderer.ItemRenderer; -import game.renderer.RenderBuffer; -import game.renderer.Tessellator; import game.rng.Random; public class LayerEntityBreak implements LayerRenderer diff --git a/java/src/game/renderer/layers/LayerExtra.java b/java/src/client/renderer/layers/LayerExtra.java similarity index 96% rename from java/src/game/renderer/layers/LayerExtra.java rename to java/src/client/renderer/layers/LayerExtra.java index ff91870..d51a79c 100755 --- a/java/src/game/renderer/layers/LayerExtra.java +++ b/java/src/client/renderer/layers/LayerExtra.java @@ -1,19 +1,18 @@ -package game.renderer.layers; +package client.renderer.layers; import java.util.List; import org.lwjgl.opengl.GL11; +import client.Game; +import client.renderer.GlState; +import client.renderer.blockmodel.ModelGenerator; +import client.renderer.model.ModelBox; +import client.renderer.model.ModelHumanoid; +import client.renderer.model.ModelRenderer; import game.collect.Lists; - -import game.Game; import game.entity.npc.EntityNPC; import game.init.SpeciesRegistry.ModelType; -import game.renderer.GlState; -import game.renderer.blockmodel.ModelGenerator; -import game.renderer.model.ModelBox; -import game.renderer.model.ModelHumanoid; -import game.renderer.model.ModelRenderer; public class LayerExtra implements LayerRenderer { diff --git a/java/src/game/renderer/layers/LayerHeldItem.java b/java/src/client/renderer/layers/LayerHeldItem.java similarity index 93% rename from java/src/game/renderer/layers/LayerHeldItem.java rename to java/src/client/renderer/layers/LayerHeldItem.java index 3282fe6..0c46471 100755 --- a/java/src/game/renderer/layers/LayerHeldItem.java +++ b/java/src/client/renderer/layers/LayerHeldItem.java @@ -1,17 +1,17 @@ -package game.renderer.layers; +package client.renderer.layers; import org.lwjgl.opengl.GL11; -import game.Game; +import client.Game; +import client.renderer.entity.RendererLivingEntity; +import client.renderer.model.ModelBiped; import game.entity.npc.EntityNPC; import game.entity.types.EntityLiving; import game.init.Items; import game.item.Item; import game.item.ItemBlock; import game.item.ItemStack; -import game.renderer.blockmodel.Transforms; -import game.renderer.entity.RendererLivingEntity; -import game.renderer.model.ModelBiped; +import game.model.Transforms; public class LayerHeldItem implements LayerRenderer { diff --git a/java/src/game/renderer/layers/LayerMooshroomMushroom.java b/java/src/client/renderer/layers/LayerMooshroomMushroom.java similarity index 89% rename from java/src/game/renderer/layers/LayerMooshroomMushroom.java rename to java/src/client/renderer/layers/LayerMooshroomMushroom.java index e6e421e..dd45eab 100755 --- a/java/src/game/renderer/layers/LayerMooshroomMushroom.java +++ b/java/src/client/renderer/layers/LayerMooshroomMushroom.java @@ -1,15 +1,15 @@ -package game.renderer.layers; +package client.renderer.layers; import org.lwjgl.opengl.GL11; -import game.Game; +import client.Game; +import client.renderer.BlockRenderer; +import client.renderer.GlState; +import client.renderer.entity.RenderMooshroom; +import client.renderer.model.ModelQuadruped; +import client.renderer.texture.TextureMap; import game.entity.animal.EntityMooshroom; import game.init.Blocks; -import game.renderer.BlockRenderer; -import game.renderer.GlState; -import game.renderer.entity.RenderMooshroom; -import game.renderer.model.ModelQuadruped; -import game.renderer.texture.TextureMap; public class LayerMooshroomMushroom implements LayerRenderer { diff --git a/java/src/game/renderer/layers/LayerPowerRods.java b/java/src/client/renderer/layers/LayerPowerRods.java similarity index 94% rename from java/src/game/renderer/layers/LayerPowerRods.java rename to java/src/client/renderer/layers/LayerPowerRods.java index 6e641df..dae23aa 100755 --- a/java/src/game/renderer/layers/LayerPowerRods.java +++ b/java/src/client/renderer/layers/LayerPowerRods.java @@ -1,9 +1,9 @@ -package game.renderer.layers; +package client.renderer.layers; +import client.renderer.GlState; +import client.renderer.entity.RenderHumanoid; +import client.renderer.model.ModelRenderer; import game.entity.npc.EntityNPC; -import game.renderer.GlState; -import game.renderer.entity.RenderHumanoid; -import game.renderer.model.ModelRenderer; import game.util.ExtMath; public class LayerPowerRods implements LayerRenderer diff --git a/java/src/game/renderer/layers/LayerRenderer.java b/java/src/client/renderer/layers/LayerRenderer.java similarity index 90% rename from java/src/game/renderer/layers/LayerRenderer.java rename to java/src/client/renderer/layers/LayerRenderer.java index 2ae4c8e..6a5c439 100755 --- a/java/src/game/renderer/layers/LayerRenderer.java +++ b/java/src/client/renderer/layers/LayerRenderer.java @@ -1,4 +1,4 @@ -package game.renderer.layers; +package client.renderer.layers; import game.entity.types.EntityLiving; diff --git a/java/src/game/renderer/layers/LayerSaddle.java b/java/src/client/renderer/layers/LayerSaddle.java similarity index 89% rename from java/src/game/renderer/layers/LayerSaddle.java rename to java/src/client/renderer/layers/LayerSaddle.java index 20893ac..4432dc8 100755 --- a/java/src/game/renderer/layers/LayerSaddle.java +++ b/java/src/client/renderer/layers/LayerSaddle.java @@ -1,8 +1,8 @@ -package game.renderer.layers; +package client.renderer.layers; +import client.renderer.entity.RenderPig; +import client.renderer.model.ModelPig; import game.entity.animal.EntityPig; -import game.renderer.entity.RenderPig; -import game.renderer.model.ModelPig; public class LayerSaddle implements LayerRenderer diff --git a/java/src/game/renderer/layers/LayerSheepWool.java b/java/src/client/renderer/layers/LayerSheepWool.java similarity index 93% rename from java/src/game/renderer/layers/LayerSheepWool.java rename to java/src/client/renderer/layers/LayerSheepWool.java index 1dd3f87..5f2efeb 100755 --- a/java/src/game/renderer/layers/LayerSheepWool.java +++ b/java/src/client/renderer/layers/LayerSheepWool.java @@ -1,9 +1,9 @@ -package game.renderer.layers; +package client.renderer.layers; +import client.renderer.GlState; +import client.renderer.entity.RenderSheep; +import client.renderer.model.ModelSheep1; import game.entity.animal.EntitySheep; -import game.renderer.GlState; -import game.renderer.entity.RenderSheep; -import game.renderer.model.ModelSheep1; public class LayerSheepWool implements LayerRenderer diff --git a/java/src/game/renderer/layers/LayerSlimeGel.java b/java/src/client/renderer/layers/LayerSlimeGel.java similarity index 86% rename from java/src/game/renderer/layers/LayerSlimeGel.java rename to java/src/client/renderer/layers/LayerSlimeGel.java index aceaaf3..9e16e9f 100755 --- a/java/src/game/renderer/layers/LayerSlimeGel.java +++ b/java/src/client/renderer/layers/LayerSlimeGel.java @@ -1,12 +1,12 @@ -package game.renderer.layers; +package client.renderer.layers; import org.lwjgl.opengl.GL11; +import client.renderer.GlState; +import client.renderer.entity.RenderSlime; +import client.renderer.model.ModelBase; +import client.renderer.model.ModelSlime; import game.entity.npc.EntityNPC; -import game.renderer.GlState; -import game.renderer.entity.RenderSlime; -import game.renderer.model.ModelBase; -import game.renderer.model.ModelSlime; public class LayerSlimeGel implements LayerRenderer { diff --git a/java/src/game/renderer/layers/LayerWolfCollar.java b/java/src/client/renderer/layers/LayerWolfCollar.java similarity index 92% rename from java/src/game/renderer/layers/LayerWolfCollar.java rename to java/src/client/renderer/layers/LayerWolfCollar.java index 2777896..42301f8 100755 --- a/java/src/game/renderer/layers/LayerWolfCollar.java +++ b/java/src/client/renderer/layers/LayerWolfCollar.java @@ -1,10 +1,10 @@ -package game.renderer.layers; +package client.renderer.layers; +import client.renderer.GlState; +import client.renderer.entity.RenderWolf; import game.color.DyeColor; import game.entity.animal.EntitySheep; import game.entity.animal.EntityWolf; -import game.renderer.GlState; -import game.renderer.entity.RenderWolf; public class LayerWolfCollar implements LayerRenderer diff --git a/java/src/game/renderer/model/ModelArachnoid.java b/java/src/client/renderer/model/ModelArachnoid.java similarity index 99% rename from java/src/game/renderer/model/ModelArachnoid.java rename to java/src/client/renderer/model/ModelArachnoid.java index 27b8c24..609be74 100755 --- a/java/src/game/renderer/model/ModelArachnoid.java +++ b/java/src/client/renderer/model/ModelArachnoid.java @@ -1,4 +1,4 @@ -package game.renderer.model; +package client.renderer.model; import org.lwjgl.opengl.GL11; diff --git a/java/src/game/renderer/model/ModelArmor.java b/java/src/client/renderer/model/ModelArmor.java similarity index 98% rename from java/src/game/renderer/model/ModelArmor.java rename to java/src/client/renderer/model/ModelArmor.java index edc71cc..69c970a 100755 --- a/java/src/game/renderer/model/ModelArmor.java +++ b/java/src/client/renderer/model/ModelArmor.java @@ -1,4 +1,4 @@ -package game.renderer.model; +package client.renderer.model; public class ModelArmor extends ModelBiped { public ModelArmor(float size, int arms, int legs) diff --git a/java/src/game/renderer/model/ModelBanner.java b/java/src/client/renderer/model/ModelBanner.java similarity index 96% rename from java/src/game/renderer/model/ModelBanner.java rename to java/src/client/renderer/model/ModelBanner.java index 7e9bc2b..bd7157e 100755 --- a/java/src/game/renderer/model/ModelBanner.java +++ b/java/src/client/renderer/model/ModelBanner.java @@ -1,4 +1,4 @@ -package game.renderer.model; +package client.renderer.model; public class ModelBanner extends ModelBase { diff --git a/java/src/game/renderer/model/ModelBase.java b/java/src/client/renderer/model/ModelBase.java similarity index 98% rename from java/src/game/renderer/model/ModelBase.java rename to java/src/client/renderer/model/ModelBase.java index 0793e10..bb98213 100755 --- a/java/src/game/renderer/model/ModelBase.java +++ b/java/src/client/renderer/model/ModelBase.java @@ -1,11 +1,10 @@ -package game.renderer.model; +package client.renderer.model; import java.util.List; import java.util.Map; import game.collect.Lists; import game.collect.Maps; - import game.entity.Entity; import game.entity.types.EntityLiving; import game.rng.Random; diff --git a/java/src/game/renderer/model/ModelBat.java b/java/src/client/renderer/model/ModelBat.java similarity index 99% rename from java/src/game/renderer/model/ModelBat.java rename to java/src/client/renderer/model/ModelBat.java index 69a398c..43edc45 100755 --- a/java/src/game/renderer/model/ModelBat.java +++ b/java/src/client/renderer/model/ModelBat.java @@ -1,4 +1,4 @@ -package game.renderer.model; +package client.renderer.model; import game.entity.Entity; import game.entity.animal.EntityBat; diff --git a/java/src/game/renderer/model/ModelBiped.java b/java/src/client/renderer/model/ModelBiped.java similarity index 99% rename from java/src/game/renderer/model/ModelBiped.java rename to java/src/client/renderer/model/ModelBiped.java index ca9876d..fc2e8ee 100755 --- a/java/src/game/renderer/model/ModelBiped.java +++ b/java/src/client/renderer/model/ModelBiped.java @@ -1,4 +1,4 @@ -package game.renderer.model; +package client.renderer.model; import org.lwjgl.opengl.GL11; diff --git a/java/src/game/renderer/model/ModelBoat.java b/java/src/client/renderer/model/ModelBoat.java similarity index 98% rename from java/src/game/renderer/model/ModelBoat.java rename to java/src/client/renderer/model/ModelBoat.java index 7d5ff91..0d18951 100755 --- a/java/src/game/renderer/model/ModelBoat.java +++ b/java/src/client/renderer/model/ModelBoat.java @@ -1,4 +1,4 @@ -package game.renderer.model; +package client.renderer.model; import game.entity.Entity; diff --git a/java/src/game/renderer/model/ModelBox.java b/java/src/client/renderer/model/ModelBox.java similarity index 99% rename from java/src/game/renderer/model/ModelBox.java rename to java/src/client/renderer/model/ModelBox.java index 22d2846..5e3c4c5 100755 --- a/java/src/game/renderer/model/ModelBox.java +++ b/java/src/client/renderer/model/ModelBox.java @@ -1,6 +1,6 @@ -package game.renderer.model; +package client.renderer.model; -import game.renderer.RenderBuffer; +import client.renderer.RenderBuffer; import game.world.Facing; import game.world.Vec3; diff --git a/java/src/game/renderer/model/ModelCharge.java b/java/src/client/renderer/model/ModelCharge.java similarity index 94% rename from java/src/game/renderer/model/ModelCharge.java rename to java/src/client/renderer/model/ModelCharge.java index 77c507c..c0bf14d 100755 --- a/java/src/game/renderer/model/ModelCharge.java +++ b/java/src/client/renderer/model/ModelCharge.java @@ -1,4 +1,4 @@ -package game.renderer.model; +package client.renderer.model; import game.entity.Entity; diff --git a/java/src/game/renderer/model/ModelChest.java b/java/src/client/renderer/model/ModelChest.java similarity index 97% rename from java/src/game/renderer/model/ModelChest.java rename to java/src/client/renderer/model/ModelChest.java index b3aafa0..bfb5ffe 100755 --- a/java/src/game/renderer/model/ModelChest.java +++ b/java/src/client/renderer/model/ModelChest.java @@ -1,4 +1,4 @@ -package game.renderer.model; +package client.renderer.model; public class ModelChest extends ModelBase { diff --git a/java/src/game/renderer/model/ModelChicken.java b/java/src/client/renderer/model/ModelChicken.java similarity index 99% rename from java/src/game/renderer/model/ModelChicken.java rename to java/src/client/renderer/model/ModelChicken.java index 7fce604..736fe95 100755 --- a/java/src/game/renderer/model/ModelChicken.java +++ b/java/src/client/renderer/model/ModelChicken.java @@ -1,4 +1,4 @@ -package game.renderer.model; +package client.renderer.model; import org.lwjgl.opengl.GL11; diff --git a/java/src/game/renderer/model/ModelCow.java b/java/src/client/renderer/model/ModelCow.java similarity index 97% rename from java/src/game/renderer/model/ModelCow.java rename to java/src/client/renderer/model/ModelCow.java index ac19109..3c1f360 100755 --- a/java/src/game/renderer/model/ModelCow.java +++ b/java/src/client/renderer/model/ModelCow.java @@ -1,4 +1,4 @@ -package game.renderer.model; +package client.renderer.model; public class ModelCow extends ModelQuadruped { diff --git a/java/src/game/renderer/model/ModelCrystal.java b/java/src/client/renderer/model/ModelCrystal.java similarity index 98% rename from java/src/game/renderer/model/ModelCrystal.java rename to java/src/client/renderer/model/ModelCrystal.java index 6688da6..3dc7814 100755 --- a/java/src/game/renderer/model/ModelCrystal.java +++ b/java/src/client/renderer/model/ModelCrystal.java @@ -1,4 +1,4 @@ -package game.renderer.model; +package client.renderer.model; import org.lwjgl.opengl.GL11; diff --git a/java/src/game/renderer/model/ModelDie.java b/java/src/client/renderer/model/ModelDie.java similarity index 96% rename from java/src/game/renderer/model/ModelDie.java rename to java/src/client/renderer/model/ModelDie.java index d8f3d03..32c8838 100755 --- a/java/src/game/renderer/model/ModelDie.java +++ b/java/src/client/renderer/model/ModelDie.java @@ -1,4 +1,4 @@ -package game.renderer.model; +package client.renderer.model; import org.lwjgl.opengl.GL11; diff --git a/java/src/game/renderer/model/ModelDragon.java b/java/src/client/renderer/model/ModelDragon.java similarity index 99% rename from java/src/game/renderer/model/ModelDragon.java rename to java/src/client/renderer/model/ModelDragon.java index 45fb3b0..6da7183 100755 --- a/java/src/game/renderer/model/ModelDragon.java +++ b/java/src/client/renderer/model/ModelDragon.java @@ -1,11 +1,11 @@ -package game.renderer.model; +package client.renderer.model; import org.lwjgl.opengl.GL11; +import client.renderer.GlState; import game.entity.Entity; import game.entity.animal.EntityDragon; import game.entity.types.EntityLiving; -import game.renderer.GlState; public class ModelDragon extends ModelBase { diff --git a/java/src/game/renderer/model/ModelHead.java b/java/src/client/renderer/model/ModelHead.java similarity index 98% rename from java/src/game/renderer/model/ModelHead.java rename to java/src/client/renderer/model/ModelHead.java index 3a48d0f..457e44c 100755 --- a/java/src/game/renderer/model/ModelHead.java +++ b/java/src/client/renderer/model/ModelHead.java @@ -1,4 +1,4 @@ -package game.renderer.model; +package client.renderer.model; import game.entity.Entity; diff --git a/java/src/game/renderer/model/ModelHorse.java b/java/src/client/renderer/model/ModelHorse.java similarity index 99% rename from java/src/game/renderer/model/ModelHorse.java rename to java/src/client/renderer/model/ModelHorse.java index af28039..36035bb 100755 --- a/java/src/game/renderer/model/ModelHorse.java +++ b/java/src/client/renderer/model/ModelHorse.java @@ -1,4 +1,4 @@ -package game.renderer.model; +package client.renderer.model; import org.lwjgl.opengl.GL11; diff --git a/java/src/game/renderer/model/ModelHumanoid.java b/java/src/client/renderer/model/ModelHumanoid.java similarity index 99% rename from java/src/game/renderer/model/ModelHumanoid.java rename to java/src/client/renderer/model/ModelHumanoid.java index d7333d0..73a6c39 100755 --- a/java/src/game/renderer/model/ModelHumanoid.java +++ b/java/src/client/renderer/model/ModelHumanoid.java @@ -1,4 +1,4 @@ -package game.renderer.model; +package client.renderer.model; import org.lwjgl.opengl.GL11; diff --git a/java/src/game/renderer/model/ModelHumanoidHead.java b/java/src/client/renderer/model/ModelHumanoidHead.java similarity index 97% rename from java/src/game/renderer/model/ModelHumanoidHead.java rename to java/src/client/renderer/model/ModelHumanoidHead.java index 4950f71..e7ae14e 100755 --- a/java/src/game/renderer/model/ModelHumanoidHead.java +++ b/java/src/client/renderer/model/ModelHumanoidHead.java @@ -1,4 +1,4 @@ -package game.renderer.model; +package client.renderer.model; import game.entity.Entity; diff --git a/java/src/game/renderer/model/ModelLargeChest.java b/java/src/client/renderer/model/ModelLargeChest.java similarity index 96% rename from java/src/game/renderer/model/ModelLargeChest.java rename to java/src/client/renderer/model/ModelLargeChest.java index a037d0c..0c585ac 100755 --- a/java/src/game/renderer/model/ModelLargeChest.java +++ b/java/src/client/renderer/model/ModelLargeChest.java @@ -1,4 +1,4 @@ -package game.renderer.model; +package client.renderer.model; public class ModelLargeChest extends ModelChest { diff --git a/java/src/game/renderer/model/ModelLeashKnot.java b/java/src/client/renderer/model/ModelLeashKnot.java similarity index 98% rename from java/src/game/renderer/model/ModelLeashKnot.java rename to java/src/client/renderer/model/ModelLeashKnot.java index 583988e..3a9e4bb 100755 --- a/java/src/game/renderer/model/ModelLeashKnot.java +++ b/java/src/client/renderer/model/ModelLeashKnot.java @@ -1,4 +1,4 @@ -package game.renderer.model; +package client.renderer.model; import game.entity.Entity; diff --git a/java/src/game/renderer/model/ModelMinecart.java b/java/src/client/renderer/model/ModelMinecart.java similarity index 98% rename from java/src/game/renderer/model/ModelMinecart.java rename to java/src/client/renderer/model/ModelMinecart.java index 13aced3..ffef2fd 100755 --- a/java/src/game/renderer/model/ModelMinecart.java +++ b/java/src/client/renderer/model/ModelMinecart.java @@ -1,4 +1,4 @@ -package game.renderer.model; +package client.renderer.model; import game.entity.Entity; diff --git a/java/src/game/renderer/model/ModelMouse.java b/java/src/client/renderer/model/ModelMouse.java similarity index 99% rename from java/src/game/renderer/model/ModelMouse.java rename to java/src/client/renderer/model/ModelMouse.java index 0693896..0671240 100755 --- a/java/src/game/renderer/model/ModelMouse.java +++ b/java/src/client/renderer/model/ModelMouse.java @@ -1,4 +1,4 @@ -package game.renderer.model; +package client.renderer.model; import org.lwjgl.opengl.GL11; diff --git a/java/src/game/renderer/model/ModelOcelot.java b/java/src/client/renderer/model/ModelOcelot.java similarity index 99% rename from java/src/game/renderer/model/ModelOcelot.java rename to java/src/client/renderer/model/ModelOcelot.java index 3f289c1..82f27aa 100755 --- a/java/src/game/renderer/model/ModelOcelot.java +++ b/java/src/client/renderer/model/ModelOcelot.java @@ -1,4 +1,4 @@ -package game.renderer.model; +package client.renderer.model; import org.lwjgl.opengl.GL11; diff --git a/java/src/game/renderer/model/ModelPig.java b/java/src/client/renderer/model/ModelPig.java similarity index 90% rename from java/src/game/renderer/model/ModelPig.java rename to java/src/client/renderer/model/ModelPig.java index 476512b..7bf7a8e 100755 --- a/java/src/game/renderer/model/ModelPig.java +++ b/java/src/client/renderer/model/ModelPig.java @@ -1,4 +1,4 @@ -package game.renderer.model; +package client.renderer.model; public class ModelPig extends ModelQuadruped { diff --git a/java/src/game/renderer/model/ModelQuadruped.java b/java/src/client/renderer/model/ModelQuadruped.java similarity index 99% rename from java/src/game/renderer/model/ModelQuadruped.java rename to java/src/client/renderer/model/ModelQuadruped.java index c287c1e..e8be36c 100755 --- a/java/src/game/renderer/model/ModelQuadruped.java +++ b/java/src/client/renderer/model/ModelQuadruped.java @@ -1,4 +1,4 @@ -package game.renderer.model; +package client.renderer.model; import org.lwjgl.opengl.GL11; diff --git a/java/src/game/renderer/model/ModelRabbit.java b/java/src/client/renderer/model/ModelRabbit.java similarity index 99% rename from java/src/game/renderer/model/ModelRabbit.java rename to java/src/client/renderer/model/ModelRabbit.java index f4efe68..3b383c0 100755 --- a/java/src/game/renderer/model/ModelRabbit.java +++ b/java/src/client/renderer/model/ModelRabbit.java @@ -1,4 +1,4 @@ -package game.renderer.model; +package client.renderer.model; import org.lwjgl.opengl.GL11; diff --git a/java/src/game/renderer/model/ModelRenderer.java b/java/src/client/renderer/model/ModelRenderer.java similarity index 99% rename from java/src/game/renderer/model/ModelRenderer.java rename to java/src/client/renderer/model/ModelRenderer.java index 0c0123b..3931a59 100755 --- a/java/src/game/renderer/model/ModelRenderer.java +++ b/java/src/client/renderer/model/ModelRenderer.java @@ -1,14 +1,13 @@ -package game.renderer.model; +package client.renderer.model; import java.util.List; import org.lwjgl.opengl.GL11; +import client.renderer.RenderBuffer; +import client.renderer.Tessellator; import game.collect.Lists; -import game.renderer.RenderBuffer; -import game.renderer.Tessellator; - public class ModelRenderer { /** The size of the texture file's width in pixels. */ diff --git a/java/src/game/renderer/model/ModelSheep1.java b/java/src/client/renderer/model/ModelSheep1.java similarity index 98% rename from java/src/game/renderer/model/ModelSheep1.java rename to java/src/client/renderer/model/ModelSheep1.java index b6b2075..fda7fb9 100755 --- a/java/src/game/renderer/model/ModelSheep1.java +++ b/java/src/client/renderer/model/ModelSheep1.java @@ -1,4 +1,4 @@ -package game.renderer.model; +package client.renderer.model; import game.entity.Entity; import game.entity.animal.EntitySheep; diff --git a/java/src/game/renderer/model/ModelSheep2.java b/java/src/client/renderer/model/ModelSheep2.java similarity index 98% rename from java/src/game/renderer/model/ModelSheep2.java rename to java/src/client/renderer/model/ModelSheep2.java index 4db5e7a..3ac1c98 100755 --- a/java/src/game/renderer/model/ModelSheep2.java +++ b/java/src/client/renderer/model/ModelSheep2.java @@ -1,4 +1,4 @@ -package game.renderer.model; +package client.renderer.model; import game.entity.Entity; import game.entity.animal.EntitySheep; diff --git a/java/src/game/renderer/model/ModelSign.java b/java/src/client/renderer/model/ModelSign.java similarity index 95% rename from java/src/game/renderer/model/ModelSign.java rename to java/src/client/renderer/model/ModelSign.java index 85fc809..3685860 100755 --- a/java/src/game/renderer/model/ModelSign.java +++ b/java/src/client/renderer/model/ModelSign.java @@ -1,4 +1,4 @@ -package game.renderer.model; +package client.renderer.model; public class ModelSign extends ModelBase { diff --git a/java/src/game/renderer/model/ModelSlime.java b/java/src/client/renderer/model/ModelSlime.java similarity index 98% rename from java/src/game/renderer/model/ModelSlime.java rename to java/src/client/renderer/model/ModelSlime.java index 51165cc..8994594 100755 --- a/java/src/game/renderer/model/ModelSlime.java +++ b/java/src/client/renderer/model/ModelSlime.java @@ -1,4 +1,4 @@ -package game.renderer.model; +package client.renderer.model; import game.entity.Entity; diff --git a/java/src/game/renderer/model/ModelSpaceMarine.java b/java/src/client/renderer/model/ModelSpaceMarine.java similarity index 99% rename from java/src/game/renderer/model/ModelSpaceMarine.java rename to java/src/client/renderer/model/ModelSpaceMarine.java index 1464753..7fb4c55 100755 --- a/java/src/game/renderer/model/ModelSpaceMarine.java +++ b/java/src/client/renderer/model/ModelSpaceMarine.java @@ -1,4 +1,4 @@ -package game.renderer.model; +package client.renderer.model; public class ModelSpaceMarine extends ModelBiped { public ModelSpaceMarine() diff --git a/java/src/game/renderer/model/ModelSquid.java b/java/src/client/renderer/model/ModelSquid.java similarity index 98% rename from java/src/game/renderer/model/ModelSquid.java rename to java/src/client/renderer/model/ModelSquid.java index ccc0841..22242f9 100755 --- a/java/src/game/renderer/model/ModelSquid.java +++ b/java/src/client/renderer/model/ModelSquid.java @@ -1,4 +1,4 @@ -package game.renderer.model; +package client.renderer.model; import game.entity.Entity; diff --git a/java/src/game/renderer/model/ModelWolf.java b/java/src/client/renderer/model/ModelWolf.java similarity index 99% rename from java/src/game/renderer/model/ModelWolf.java rename to java/src/client/renderer/model/ModelWolf.java index adde16b..efa86d1 100755 --- a/java/src/game/renderer/model/ModelWolf.java +++ b/java/src/client/renderer/model/ModelWolf.java @@ -1,4 +1,4 @@ -package game.renderer.model; +package client.renderer.model; import org.lwjgl.opengl.GL11; diff --git a/java/src/game/renderer/model/PositionTextureVertex.java b/java/src/client/renderer/model/PositionTextureVertex.java similarity index 90% rename from java/src/game/renderer/model/PositionTextureVertex.java rename to java/src/client/renderer/model/PositionTextureVertex.java index df29489..f18ca99 100755 --- a/java/src/game/renderer/model/PositionTextureVertex.java +++ b/java/src/client/renderer/model/PositionTextureVertex.java @@ -1,4 +1,4 @@ -package game.renderer.model; +package client.renderer.model; import game.world.Vec3; diff --git a/java/src/game/renderer/model/TextureOffset.java b/java/src/client/renderer/model/TextureOffset.java similarity index 92% rename from java/src/game/renderer/model/TextureOffset.java rename to java/src/client/renderer/model/TextureOffset.java index 8668dfa..535d70b 100755 --- a/java/src/game/renderer/model/TextureOffset.java +++ b/java/src/client/renderer/model/TextureOffset.java @@ -1,4 +1,4 @@ -package game.renderer.model; +package client.renderer.model; public class TextureOffset { diff --git a/java/src/game/renderer/model/TexturedQuad.java b/java/src/client/renderer/model/TexturedQuad.java similarity index 84% rename from java/src/game/renderer/model/TexturedQuad.java rename to java/src/client/renderer/model/TexturedQuad.java index d72d146..b3b012d 100755 --- a/java/src/game/renderer/model/TexturedQuad.java +++ b/java/src/client/renderer/model/TexturedQuad.java @@ -1,10 +1,10 @@ -package game.renderer.model; +package client.renderer.model; import org.lwjgl.opengl.GL11; -import game.renderer.DefaultVertexFormats; -import game.renderer.RenderBuffer; -import game.renderer.Tessellator; +import client.renderer.DefaultVertexFormats; +import client.renderer.RenderBuffer; +import client.renderer.Tessellator; import game.world.Vec3; public class TexturedQuad @@ -19,10 +19,10 @@ public class TexturedQuad // this.vertices[1] = u1v1.toTextureVertex(u1 / tw + ax, v1 / th + ay); // this.vertices[2] = u1v2.toTextureVertex(u1 / tw + ax, v2 / th - ay); // this.vertices[3] = u2v2.toTextureVertex(u2 / tw - ax, v2 / th - ay); - this.vertices[0] = u2v1.toTextureVertex(u2 / tw, v1 / th); - this.vertices[1] = u1v1.toTextureVertex(u1 / tw, v1 / th); - this.vertices[2] = u1v2.toTextureVertex(u1 / tw, v2 / th); - this.vertices[3] = u2v2.toTextureVertex(u2 / tw, v2 / th); + this.vertices[0] = new PositionTextureVertex(u2v1, u2 / tw, v1 / th); + this.vertices[1] = new PositionTextureVertex(u1v1, u1 / tw, v1 / th); + this.vertices[2] = new PositionTextureVertex(u1v2, u1 / tw, v2 / th); + this.vertices[3] = new PositionTextureVertex(u2v2, u2 / tw, v2 / th); } public TexturedQuad(Vec3[] verts, int[] uvs, float tw, float th) diff --git a/java/src/game/renderer/particle/EffectRenderer.java b/java/src/client/renderer/particle/EffectRenderer.java similarity index 97% rename from java/src/game/renderer/particle/EffectRenderer.java rename to java/src/client/renderer/particle/EffectRenderer.java index 0431ab0..ac369e3 100755 --- a/java/src/game/renderer/particle/EffectRenderer.java +++ b/java/src/client/renderer/particle/EffectRenderer.java @@ -1,23 +1,23 @@ -package game.renderer.particle; +package client.renderer.particle; import java.util.List; import java.util.Map; import org.lwjgl.opengl.GL11; +import client.renderer.ActiveRenderInfo; +import client.renderer.DefaultVertexFormats; +import client.renderer.GlState; +import client.renderer.RenderBuffer; +import client.renderer.Tessellator; +import client.renderer.texture.TextureManager; +import client.renderer.texture.TextureMap; +import game.block.Block; import game.collect.Lists; import game.collect.Maps; - -import game.block.Block; import game.entity.Entity; import game.material.Material; -import game.renderer.ActiveRenderInfo; -import game.renderer.DefaultVertexFormats; -import game.renderer.GlState; -import game.renderer.RenderBuffer; -import game.renderer.Tessellator; -import game.renderer.texture.TextureManager; -import game.renderer.texture.TextureMap; +import game.model.ParticleType; import game.rng.Random; import game.util.ExtMath; import game.world.BlockPos; diff --git a/java/src/game/renderer/particle/EntityAuraFX.java b/java/src/client/renderer/particle/EntityAuraFX.java similarity index 98% rename from java/src/game/renderer/particle/EntityAuraFX.java rename to java/src/client/renderer/particle/EntityAuraFX.java index 183a805..d69be96 100755 --- a/java/src/game/renderer/particle/EntityAuraFX.java +++ b/java/src/client/renderer/particle/EntityAuraFX.java @@ -1,4 +1,4 @@ -package game.renderer.particle; +package client.renderer.particle; import game.world.World; diff --git a/java/src/game/renderer/particle/EntityBlockDustFX.java b/java/src/client/renderer/particle/EntityBlockDustFX.java similarity index 96% rename from java/src/game/renderer/particle/EntityBlockDustFX.java rename to java/src/client/renderer/particle/EntityBlockDustFX.java index 963aee9..f1fdce7 100755 --- a/java/src/game/renderer/particle/EntityBlockDustFX.java +++ b/java/src/client/renderer/particle/EntityBlockDustFX.java @@ -1,4 +1,4 @@ -package game.renderer.particle; +package client.renderer.particle; import game.init.BlockRegistry; import game.world.State; diff --git a/java/src/game/renderer/particle/EntityBreakingFX.java b/java/src/client/renderer/particle/EntityBreakingFX.java similarity index 98% rename from java/src/game/renderer/particle/EntityBreakingFX.java rename to java/src/client/renderer/particle/EntityBreakingFX.java index c27924a..1982a28 100755 --- a/java/src/game/renderer/particle/EntityBreakingFX.java +++ b/java/src/client/renderer/particle/EntityBreakingFX.java @@ -1,11 +1,11 @@ -package game.renderer.particle; +package client.renderer.particle; -import game.Game; +import client.Game; +import client.renderer.RenderBuffer; import game.entity.Entity; import game.init.ItemRegistry; import game.init.Items; import game.item.Item; -import game.renderer.RenderBuffer; import game.world.World; public class EntityBreakingFX extends EntityFX diff --git a/java/src/game/renderer/particle/EntityBubbleFX.java b/java/src/client/renderer/particle/EntityBubbleFX.java similarity index 98% rename from java/src/game/renderer/particle/EntityBubbleFX.java rename to java/src/client/renderer/particle/EntityBubbleFX.java index 2ace7d8..072304b 100755 --- a/java/src/game/renderer/particle/EntityBubbleFX.java +++ b/java/src/client/renderer/particle/EntityBubbleFX.java @@ -1,4 +1,4 @@ -package game.renderer.particle; +package client.renderer.particle; import game.material.Material; import game.world.BlockPos; diff --git a/java/src/game/renderer/particle/EntityCloudFX.java b/java/src/client/renderer/particle/EntityCloudFX.java similarity index 97% rename from java/src/game/renderer/particle/EntityCloudFX.java rename to java/src/client/renderer/particle/EntityCloudFX.java index f76aed3..39baf00 100755 --- a/java/src/game/renderer/particle/EntityCloudFX.java +++ b/java/src/client/renderer/particle/EntityCloudFX.java @@ -1,8 +1,8 @@ -package game.renderer.particle; +package client.renderer.particle; +import client.renderer.RenderBuffer; import game.entity.Entity; import game.entity.npc.EntityNPC; -import game.renderer.RenderBuffer; import game.util.ExtMath; import game.world.World; diff --git a/java/src/game/renderer/particle/EntityCrit2FX.java b/java/src/client/renderer/particle/EntityCrit2FX.java similarity index 98% rename from java/src/game/renderer/particle/EntityCrit2FX.java rename to java/src/client/renderer/particle/EntityCrit2FX.java index 644fb2c..49a03c0 100755 --- a/java/src/game/renderer/particle/EntityCrit2FX.java +++ b/java/src/client/renderer/particle/EntityCrit2FX.java @@ -1,7 +1,7 @@ -package game.renderer.particle; +package client.renderer.particle; +import client.renderer.RenderBuffer; import game.entity.Entity; -import game.renderer.RenderBuffer; import game.util.ExtMath; import game.world.World; diff --git a/java/src/game/renderer/particle/EntityCritFX.java b/java/src/client/renderer/particle/EntityCritFX.java similarity index 95% rename from java/src/game/renderer/particle/EntityCritFX.java rename to java/src/client/renderer/particle/EntityCritFX.java index 4c039a8..743c0b3 100755 --- a/java/src/game/renderer/particle/EntityCritFX.java +++ b/java/src/client/renderer/particle/EntityCritFX.java @@ -1,4 +1,4 @@ -package game.renderer.particle; +package client.renderer.particle; import game.world.World; diff --git a/java/src/game/renderer/particle/EntityDiggingFX.java b/java/src/client/renderer/particle/EntityDiggingFX.java similarity index 98% rename from java/src/game/renderer/particle/EntityDiggingFX.java rename to java/src/client/renderer/particle/EntityDiggingFX.java index 291692e..ace9f1b 100755 --- a/java/src/game/renderer/particle/EntityDiggingFX.java +++ b/java/src/client/renderer/particle/EntityDiggingFX.java @@ -1,11 +1,11 @@ -package game.renderer.particle; +package client.renderer.particle; -import game.Game; +import client.Game; +import client.renderer.RenderBuffer; import game.block.Block; import game.entity.Entity; import game.init.BlockRegistry; import game.init.Blocks; -import game.renderer.RenderBuffer; import game.world.BlockPos; import game.world.State; import game.world.World; diff --git a/java/src/game/renderer/particle/EntityDownfallFX.java b/java/src/client/renderer/particle/EntityDownfallFX.java similarity index 99% rename from java/src/game/renderer/particle/EntityDownfallFX.java rename to java/src/client/renderer/particle/EntityDownfallFX.java index 9a66aaa..8da5ea6 100755 --- a/java/src/game/renderer/particle/EntityDownfallFX.java +++ b/java/src/client/renderer/particle/EntityDownfallFX.java @@ -1,4 +1,4 @@ -package game.renderer.particle; +package client.renderer.particle; import game.block.Block; import game.block.BlockLiquid; diff --git a/java/src/game/renderer/particle/EntityDropParticleFX.java b/java/src/client/renderer/particle/EntityDropParticleFX.java similarity index 98% rename from java/src/game/renderer/particle/EntityDropParticleFX.java rename to java/src/client/renderer/particle/EntityDropParticleFX.java index 3c49a61..0b47971 100755 --- a/java/src/game/renderer/particle/EntityDropParticleFX.java +++ b/java/src/client/renderer/particle/EntityDropParticleFX.java @@ -1,7 +1,8 @@ -package game.renderer.particle; +package client.renderer.particle; import game.block.BlockLiquid; import game.material.Material; +import game.model.ParticleType; import game.util.ExtMath; import game.world.BlockPos; import game.world.State; diff --git a/java/src/game/renderer/particle/EntityEnchantmentTableParticleFX.java b/java/src/client/renderer/particle/EntityEnchantmentTableParticleFX.java similarity index 98% rename from java/src/game/renderer/particle/EntityEnchantmentTableParticleFX.java rename to java/src/client/renderer/particle/EntityEnchantmentTableParticleFX.java index 7fd3b52..b50ae80 100755 --- a/java/src/game/renderer/particle/EntityEnchantmentTableParticleFX.java +++ b/java/src/client/renderer/particle/EntityEnchantmentTableParticleFX.java @@ -1,4 +1,4 @@ -package game.renderer.particle; +package client.renderer.particle; import game.world.World; diff --git a/java/src/game/renderer/particle/EntityExplodeFX.java b/java/src/client/renderer/particle/EntityExplodeFX.java similarity index 98% rename from java/src/game/renderer/particle/EntityExplodeFX.java rename to java/src/client/renderer/particle/EntityExplodeFX.java index dbac18e..d12c6cf 100755 --- a/java/src/game/renderer/particle/EntityExplodeFX.java +++ b/java/src/client/renderer/particle/EntityExplodeFX.java @@ -1,4 +1,4 @@ -package game.renderer.particle; +package client.renderer.particle; import game.world.World; diff --git a/java/src/game/renderer/particle/EntityFX.java b/java/src/client/renderer/particle/EntityFX.java similarity index 98% rename from java/src/game/renderer/particle/EntityFX.java rename to java/src/client/renderer/particle/EntityFX.java index 963a872..c9a61f2 100755 --- a/java/src/game/renderer/particle/EntityFX.java +++ b/java/src/client/renderer/particle/EntityFX.java @@ -1,11 +1,11 @@ -package game.renderer.particle; +package client.renderer.particle; -import game.Game; +import client.Game; +import client.renderer.RenderBuffer; +import client.renderer.texture.TextureAtlasSprite; import game.entity.Entity; import game.entity.EntityType; import game.nbt.NBTTagCompound; -import game.renderer.RenderBuffer; -import game.renderer.texture.TextureAtlasSprite; import game.util.ExtMath; import game.world.World; diff --git a/java/src/game/renderer/particle/EntityFirework.java b/java/src/client/renderer/particle/EntityFirework.java similarity index 99% rename from java/src/game/renderer/particle/EntityFirework.java rename to java/src/client/renderer/particle/EntityFirework.java index 24f483b..042242e 100755 --- a/java/src/game/renderer/particle/EntityFirework.java +++ b/java/src/client/renderer/particle/EntityFirework.java @@ -1,12 +1,12 @@ -package game.renderer.particle; +package client.renderer.particle; -import game.Game; +import client.Game; +import client.renderer.RenderBuffer; import game.entity.Entity; import game.init.SoundEvent; import game.item.ItemDye; import game.nbt.NBTTagCompound; import game.nbt.NBTTagList; -import game.renderer.RenderBuffer; import game.util.ExtMath; import game.world.BoundingBox; import game.world.World; diff --git a/java/src/game/renderer/particle/EntityFishWakeFX.java b/java/src/client/renderer/particle/EntityFishWakeFX.java similarity index 98% rename from java/src/game/renderer/particle/EntityFishWakeFX.java rename to java/src/client/renderer/particle/EntityFishWakeFX.java index 93ea151..35207c5 100755 --- a/java/src/game/renderer/particle/EntityFishWakeFX.java +++ b/java/src/client/renderer/particle/EntityFishWakeFX.java @@ -1,4 +1,4 @@ -package game.renderer.particle; +package client.renderer.particle; import game.world.World; diff --git a/java/src/game/renderer/particle/EntityFlameFX.java b/java/src/client/renderer/particle/EntityFlameFX.java similarity index 98% rename from java/src/game/renderer/particle/EntityFlameFX.java rename to java/src/client/renderer/particle/EntityFlameFX.java index 0f72184..6ad5901 100755 --- a/java/src/game/renderer/particle/EntityFlameFX.java +++ b/java/src/client/renderer/particle/EntityFlameFX.java @@ -1,7 +1,7 @@ -package game.renderer.particle; +package client.renderer.particle; +import client.renderer.RenderBuffer; import game.entity.Entity; -import game.renderer.RenderBuffer; import game.util.ExtMath; import game.world.World; diff --git a/java/src/game/renderer/particle/EntityFootStepFX.java b/java/src/client/renderer/particle/EntityFootStepFX.java similarity index 92% rename from java/src/game/renderer/particle/EntityFootStepFX.java rename to java/src/client/renderer/particle/EntityFootStepFX.java index 887fdf7..9fc77a5 100755 --- a/java/src/game/renderer/particle/EntityFootStepFX.java +++ b/java/src/client/renderer/particle/EntityFootStepFX.java @@ -1,14 +1,14 @@ -package game.renderer.particle; +package client.renderer.particle; import org.lwjgl.opengl.GL11; -import game.Game; +import client.Game; +import client.renderer.DefaultVertexFormats; +import client.renderer.GlState; +import client.renderer.RenderBuffer; +import client.renderer.Tessellator; +import client.renderer.texture.TextureManager; import game.entity.Entity; -import game.renderer.DefaultVertexFormats; -import game.renderer.GlState; -import game.renderer.RenderBuffer; -import game.renderer.Tessellator; -import game.renderer.texture.TextureManager; import game.world.BlockPos; import game.world.World; diff --git a/java/src/game/renderer/particle/EntityHeartFX.java b/java/src/client/renderer/particle/EntityHeartFX.java similarity index 97% rename from java/src/game/renderer/particle/EntityHeartFX.java rename to java/src/client/renderer/particle/EntityHeartFX.java index c9d14be..45effe6 100755 --- a/java/src/game/renderer/particle/EntityHeartFX.java +++ b/java/src/client/renderer/particle/EntityHeartFX.java @@ -1,7 +1,7 @@ -package game.renderer.particle; +package client.renderer.particle; +import client.renderer.RenderBuffer; import game.entity.Entity; -import game.renderer.RenderBuffer; import game.util.ExtMath; import game.world.World; diff --git a/java/src/game/renderer/particle/EntityHugeExplodeFX.java b/java/src/client/renderer/particle/EntityHugeExplodeFX.java similarity index 94% rename from java/src/game/renderer/particle/EntityHugeExplodeFX.java rename to java/src/client/renderer/particle/EntityHugeExplodeFX.java index 2956853..42cd4a8 100755 --- a/java/src/game/renderer/particle/EntityHugeExplodeFX.java +++ b/java/src/client/renderer/particle/EntityHugeExplodeFX.java @@ -1,7 +1,8 @@ -package game.renderer.particle; +package client.renderer.particle; +import client.renderer.RenderBuffer; import game.entity.Entity; -import game.renderer.RenderBuffer; +import game.model.ParticleType; import game.world.World; public class EntityHugeExplodeFX extends EntityFX diff --git a/java/src/game/renderer/particle/EntityLargeExplodeFX.java b/java/src/client/renderer/particle/EntityLargeExplodeFX.java similarity index 93% rename from java/src/game/renderer/particle/EntityLargeExplodeFX.java rename to java/src/client/renderer/particle/EntityLargeExplodeFX.java index 21020a8..04a509a 100755 --- a/java/src/game/renderer/particle/EntityLargeExplodeFX.java +++ b/java/src/client/renderer/particle/EntityLargeExplodeFX.java @@ -1,16 +1,16 @@ -package game.renderer.particle; +package client.renderer.particle; import org.lwjgl.opengl.GL11; -import game.Game; +import client.Game; +import client.renderer.DefaultVertexFormats; +import client.renderer.GlState; +import client.renderer.ItemRenderer; +import client.renderer.RenderBuffer; +import client.renderer.Tessellator; +import client.renderer.VertexFormat; +import client.renderer.texture.TextureManager; import game.entity.Entity; -import game.renderer.DefaultVertexFormats; -import game.renderer.GlState; -import game.renderer.ItemRenderer; -import game.renderer.RenderBuffer; -import game.renderer.Tessellator; -import game.renderer.VertexFormat; -import game.renderer.texture.TextureManager; import game.world.World; public class EntityLargeExplodeFX extends EntityFX diff --git a/java/src/game/renderer/particle/EntityLavaFX.java b/java/src/client/renderer/particle/EntityLavaFX.java similarity index 96% rename from java/src/game/renderer/particle/EntityLavaFX.java rename to java/src/client/renderer/particle/EntityLavaFX.java index b187423..869b753 100755 --- a/java/src/game/renderer/particle/EntityLavaFX.java +++ b/java/src/client/renderer/particle/EntityLavaFX.java @@ -1,7 +1,8 @@ -package game.renderer.particle; +package client.renderer.particle; +import client.renderer.RenderBuffer; import game.entity.Entity; -import game.renderer.RenderBuffer; +import game.model.ParticleType; import game.util.ExtMath; import game.world.World; diff --git a/java/src/game/renderer/particle/EntityNoteFX.java b/java/src/client/renderer/particle/EntityNoteFX.java similarity index 97% rename from java/src/game/renderer/particle/EntityNoteFX.java rename to java/src/client/renderer/particle/EntityNoteFX.java index 0517d0c..cdb1373 100755 --- a/java/src/game/renderer/particle/EntityNoteFX.java +++ b/java/src/client/renderer/particle/EntityNoteFX.java @@ -1,7 +1,7 @@ -package game.renderer.particle; +package client.renderer.particle; +import client.renderer.RenderBuffer; import game.entity.Entity; -import game.renderer.RenderBuffer; import game.util.ExtMath; import game.world.World; diff --git a/java/src/game/renderer/particle/EntityParticleEmitter.java b/java/src/client/renderer/particle/EntityParticleEmitter.java similarity index 95% rename from java/src/game/renderer/particle/EntityParticleEmitter.java rename to java/src/client/renderer/particle/EntityParticleEmitter.java index 3f7e957..8a19ef4 100755 --- a/java/src/game/renderer/particle/EntityParticleEmitter.java +++ b/java/src/client/renderer/particle/EntityParticleEmitter.java @@ -1,7 +1,8 @@ -package game.renderer.particle; +package client.renderer.particle; +import client.renderer.RenderBuffer; import game.entity.Entity; -import game.renderer.RenderBuffer; +import game.model.ParticleType; import game.world.World; import game.world.WorldClient; diff --git a/java/src/game/renderer/particle/EntityPickupFX.java b/java/src/client/renderer/particle/EntityPickupFX.java similarity index 93% rename from java/src/game/renderer/particle/EntityPickupFX.java rename to java/src/client/renderer/particle/EntityPickupFX.java index 05f5153..9ff6b8b 100755 --- a/java/src/game/renderer/particle/EntityPickupFX.java +++ b/java/src/client/renderer/particle/EntityPickupFX.java @@ -1,12 +1,12 @@ -package game.renderer.particle; +package client.renderer.particle; import org.lwjgl.opengl.GL13; -import game.Game; +import client.Game; +import client.renderer.GlState; +import client.renderer.RenderBuffer; +import client.renderer.entity.RenderManager; import game.entity.Entity; -import game.renderer.GlState; -import game.renderer.RenderBuffer; -import game.renderer.entity.RenderManager; import game.world.World; public class EntityPickupFX extends EntityFX diff --git a/java/src/game/renderer/particle/EntityPortalFX.java b/java/src/client/renderer/particle/EntityPortalFX.java similarity index 98% rename from java/src/game/renderer/particle/EntityPortalFX.java rename to java/src/client/renderer/particle/EntityPortalFX.java index 5b07ac2..712f4d9 100755 --- a/java/src/game/renderer/particle/EntityPortalFX.java +++ b/java/src/client/renderer/particle/EntityPortalFX.java @@ -1,7 +1,7 @@ -package game.renderer.particle; +package client.renderer.particle; +import client.renderer.RenderBuffer; import game.entity.Entity; -import game.renderer.RenderBuffer; import game.world.World; public class EntityPortalFX extends EntityFX diff --git a/java/src/game/renderer/particle/EntityReddustFX.java b/java/src/client/renderer/particle/EntityReddustFX.java similarity index 97% rename from java/src/game/renderer/particle/EntityReddustFX.java rename to java/src/client/renderer/particle/EntityReddustFX.java index 8a0e278..c88dece 100755 --- a/java/src/game/renderer/particle/EntityReddustFX.java +++ b/java/src/client/renderer/particle/EntityReddustFX.java @@ -1,7 +1,7 @@ -package game.renderer.particle; +package client.renderer.particle; +import client.renderer.RenderBuffer; import game.entity.Entity; -import game.renderer.RenderBuffer; import game.util.ExtMath; import game.world.World; diff --git a/java/src/game/renderer/particle/EntitySmokeFX.java b/java/src/client/renderer/particle/EntitySmokeFX.java similarity index 97% rename from java/src/game/renderer/particle/EntitySmokeFX.java rename to java/src/client/renderer/particle/EntitySmokeFX.java index ed2acaf..63f85dd 100755 --- a/java/src/game/renderer/particle/EntitySmokeFX.java +++ b/java/src/client/renderer/particle/EntitySmokeFX.java @@ -1,7 +1,7 @@ -package game.renderer.particle; +package client.renderer.particle; +import client.renderer.RenderBuffer; import game.entity.Entity; -import game.renderer.RenderBuffer; import game.util.ExtMath; import game.world.World; diff --git a/java/src/game/renderer/particle/EntitySnowShovelFX.java b/java/src/client/renderer/particle/EntitySnowShovelFX.java similarity index 97% rename from java/src/game/renderer/particle/EntitySnowShovelFX.java rename to java/src/client/renderer/particle/EntitySnowShovelFX.java index 31acfdf..5d83213 100755 --- a/java/src/game/renderer/particle/EntitySnowShovelFX.java +++ b/java/src/client/renderer/particle/EntitySnowShovelFX.java @@ -1,7 +1,7 @@ -package game.renderer.particle; +package client.renderer.particle; +import client.renderer.RenderBuffer; import game.entity.Entity; -import game.renderer.RenderBuffer; import game.util.ExtMath; import game.world.World; diff --git a/java/src/game/renderer/particle/EntitySpellParticleFX.java b/java/src/client/renderer/particle/EntitySpellParticleFX.java similarity index 98% rename from java/src/game/renderer/particle/EntitySpellParticleFX.java rename to java/src/client/renderer/particle/EntitySpellParticleFX.java index 55b7a9a..bdc8765 100755 --- a/java/src/game/renderer/particle/EntitySpellParticleFX.java +++ b/java/src/client/renderer/particle/EntitySpellParticleFX.java @@ -1,7 +1,7 @@ -package game.renderer.particle; +package client.renderer.particle; +import client.renderer.RenderBuffer; import game.entity.Entity; -import game.renderer.RenderBuffer; import game.rng.Random; import game.util.ExtMath; import game.world.World; diff --git a/java/src/game/renderer/particle/EntitySplashFX.java b/java/src/client/renderer/particle/EntitySplashFX.java similarity index 96% rename from java/src/game/renderer/particle/EntitySplashFX.java rename to java/src/client/renderer/particle/EntitySplashFX.java index 7a18588..411b5ba 100755 --- a/java/src/game/renderer/particle/EntitySplashFX.java +++ b/java/src/client/renderer/particle/EntitySplashFX.java @@ -1,4 +1,4 @@ -package game.renderer.particle; +package client.renderer.particle; import game.world.World; diff --git a/java/src/game/renderer/particle/EntitySuspendFX.java b/java/src/client/renderer/particle/EntitySuspendFX.java similarity index 98% rename from java/src/game/renderer/particle/EntitySuspendFX.java rename to java/src/client/renderer/particle/EntitySuspendFX.java index ae02469..18c0d9e 100755 --- a/java/src/game/renderer/particle/EntitySuspendFX.java +++ b/java/src/client/renderer/particle/EntitySuspendFX.java @@ -1,4 +1,4 @@ -package game.renderer.particle; +package client.renderer.particle; import game.material.Material; import game.world.BlockPos; diff --git a/java/src/game/renderer/particle/IParticleFactory.java b/java/src/client/renderer/particle/IParticleFactory.java similarity index 87% rename from java/src/game/renderer/particle/IParticleFactory.java rename to java/src/client/renderer/particle/IParticleFactory.java index dfef805..06a5b62 100755 --- a/java/src/game/renderer/particle/IParticleFactory.java +++ b/java/src/client/renderer/particle/IParticleFactory.java @@ -1,4 +1,4 @@ -package game.renderer.particle; +package client.renderer.particle; import game.world.World; diff --git a/java/src/game/renderer/texture/DynamicTexture.java b/java/src/client/renderer/texture/DynamicTexture.java similarity index 95% rename from java/src/game/renderer/texture/DynamicTexture.java rename to java/src/client/renderer/texture/DynamicTexture.java index 8067614..1d82fcd 100755 --- a/java/src/game/renderer/texture/DynamicTexture.java +++ b/java/src/client/renderer/texture/DynamicTexture.java @@ -1,9 +1,9 @@ -package game.renderer.texture; +package client.renderer.texture; import java.awt.image.BufferedImage; import java.io.IOException; -import game.renderer.GlState; +import client.renderer.GlState; public class DynamicTexture extends Texture { diff --git a/java/src/game/renderer/texture/EntityTexManager.java b/java/src/client/renderer/texture/EntityTexManager.java similarity index 98% rename from java/src/game/renderer/texture/EntityTexManager.java rename to java/src/client/renderer/texture/EntityTexManager.java index bc52a92..d2f0146 100755 --- a/java/src/game/renderer/texture/EntityTexManager.java +++ b/java/src/client/renderer/texture/EntityTexManager.java @@ -1,4 +1,4 @@ -package game.renderer.texture; +package client.renderer.texture; import java.awt.Color; import java.awt.Graphics2D; @@ -10,17 +10,16 @@ import java.util.Map; import java.util.Map.Entry; import java.util.Set; +import client.Game; +import client.renderer.entity.RenderNpc; +import client.renderer.layers.LayerExtra; import game.collect.Lists; import game.collect.Maps; import game.collect.Sets; - -import game.Game; import game.entity.npc.EntityNPC; import game.init.SpeciesRegistry; import game.init.SpeciesRegistry.ModelType; import game.log.Log; -import game.renderer.entity.RenderNpc; -import game.renderer.layers.LayerExtra; import game.util.FileUtils; public abstract class EntityTexManager diff --git a/java/src/game/renderer/texture/IIconCreator.java b/java/src/client/renderer/texture/IIconCreator.java similarity index 72% rename from java/src/game/renderer/texture/IIconCreator.java rename to java/src/client/renderer/texture/IIconCreator.java index 3b6c142..ed1f0aa 100755 --- a/java/src/game/renderer/texture/IIconCreator.java +++ b/java/src/client/renderer/texture/IIconCreator.java @@ -1,4 +1,4 @@ -package game.renderer.texture; +package client.renderer.texture; public interface IIconCreator { diff --git a/java/src/game/renderer/texture/LayeredColorMaskTexture.java b/java/src/client/renderer/texture/LayeredColorMaskTexture.java similarity index 99% rename from java/src/game/renderer/texture/LayeredColorMaskTexture.java rename to java/src/client/renderer/texture/LayeredColorMaskTexture.java index 14aff6b..5920829 100755 --- a/java/src/game/renderer/texture/LayeredColorMaskTexture.java +++ b/java/src/client/renderer/texture/LayeredColorMaskTexture.java @@ -1,4 +1,4 @@ -package game.renderer.texture; +package client.renderer.texture; import java.awt.Graphics; import java.awt.image.BufferedImage; diff --git a/java/src/game/renderer/texture/LayeredTexture.java b/java/src/client/renderer/texture/LayeredTexture.java similarity index 97% rename from java/src/game/renderer/texture/LayeredTexture.java rename to java/src/client/renderer/texture/LayeredTexture.java index cda67c9..6f9102f 100755 --- a/java/src/game/renderer/texture/LayeredTexture.java +++ b/java/src/client/renderer/texture/LayeredTexture.java @@ -1,4 +1,4 @@ -package game.renderer.texture; +package client.renderer.texture; import java.awt.image.BufferedImage; import java.awt.image.ImageObserver; @@ -7,7 +7,6 @@ import java.io.InputStream; import java.util.List; import game.collect.Lists; - import game.log.Log; import game.util.FileUtils; diff --git a/java/src/game/renderer/texture/SimpleTexture.java b/java/src/client/renderer/texture/SimpleTexture.java similarity index 95% rename from java/src/game/renderer/texture/SimpleTexture.java rename to java/src/client/renderer/texture/SimpleTexture.java index 0af92ec..8a142b6 100755 --- a/java/src/game/renderer/texture/SimpleTexture.java +++ b/java/src/client/renderer/texture/SimpleTexture.java @@ -1,4 +1,4 @@ -package game.renderer.texture; +package client.renderer.texture; import java.awt.image.BufferedImage; import java.io.IOException; diff --git a/java/src/game/renderer/texture/Stitcher.java b/java/src/client/renderer/texture/Stitcher.java similarity index 99% rename from java/src/game/renderer/texture/Stitcher.java rename to java/src/client/renderer/texture/Stitcher.java index e2b827d..008e615 100755 --- a/java/src/game/renderer/texture/Stitcher.java +++ b/java/src/client/renderer/texture/Stitcher.java @@ -1,4 +1,4 @@ -package game.renderer.texture; +package client.renderer.texture; import java.util.ArrayList; import java.util.Arrays; diff --git a/java/src/game/renderer/texture/Texture.java b/java/src/client/renderer/texture/Texture.java similarity index 90% rename from java/src/game/renderer/texture/Texture.java rename to java/src/client/renderer/texture/Texture.java index b98cdfd..4c0ab84 100755 --- a/java/src/game/renderer/texture/Texture.java +++ b/java/src/client/renderer/texture/Texture.java @@ -1,10 +1,10 @@ -package game.renderer.texture; +package client.renderer.texture; import java.io.IOException; import org.lwjgl.opengl.GL11; -import game.renderer.GlState; +import client.renderer.GlState; public abstract class Texture { diff --git a/java/src/game/renderer/texture/TextureAtlasSprite.java b/java/src/client/renderer/texture/TextureAtlasSprite.java similarity index 99% rename from java/src/game/renderer/texture/TextureAtlasSprite.java rename to java/src/client/renderer/texture/TextureAtlasSprite.java index d7ac2d9..d75b3fa 100755 --- a/java/src/game/renderer/texture/TextureAtlasSprite.java +++ b/java/src/client/renderer/texture/TextureAtlasSprite.java @@ -1,4 +1,4 @@ -package game.renderer.texture; +package client.renderer.texture; import java.awt.image.BufferedImage; import java.io.IOException; diff --git a/java/src/game/renderer/texture/TextureManager.java b/java/src/client/renderer/texture/TextureManager.java similarity index 95% rename from java/src/game/renderer/texture/TextureManager.java rename to java/src/client/renderer/texture/TextureManager.java index 313f5cc..06de1dd 100755 --- a/java/src/game/renderer/texture/TextureManager.java +++ b/java/src/client/renderer/texture/TextureManager.java @@ -1,14 +1,13 @@ -package game.renderer.texture; +package client.renderer.texture; import java.io.FileNotFoundException; import java.io.IOException; import java.util.Map; import java.util.Map.Entry; +import client.renderer.GlState; import game.collect.Maps; - import game.log.Log; -import game.renderer.GlState; public class TextureManager { private final Map textures = Maps.newHashMap(); diff --git a/java/src/game/renderer/texture/TextureMap.java b/java/src/client/renderer/texture/TextureMap.java similarity index 99% rename from java/src/game/renderer/texture/TextureMap.java rename to java/src/client/renderer/texture/TextureMap.java index d0a89b6..51a6936 100755 --- a/java/src/game/renderer/texture/TextureMap.java +++ b/java/src/client/renderer/texture/TextureMap.java @@ -1,4 +1,4 @@ -package game.renderer.texture; +package client.renderer.texture; import java.awt.image.BufferedImage; import java.io.FileNotFoundException; @@ -7,14 +7,13 @@ import java.util.List; import java.util.Map; import java.util.Map.Entry; +import client.renderer.GlState; +import game.block.Block; import game.collect.Lists; import game.collect.Maps; - -import game.block.Block; import game.init.BlockRegistry; import game.init.FluidRegistry; import game.log.Log; -import game.renderer.GlState; import game.util.FileUtils; public class TextureMap extends Texture diff --git a/java/src/game/renderer/texture/TextureTicked.java b/java/src/client/renderer/texture/TextureTicked.java similarity index 79% rename from java/src/game/renderer/texture/TextureTicked.java rename to java/src/client/renderer/texture/TextureTicked.java index 5520aed..b2f0fa6 100755 --- a/java/src/game/renderer/texture/TextureTicked.java +++ b/java/src/client/renderer/texture/TextureTicked.java @@ -1,4 +1,4 @@ -package game.renderer.texture; +package client.renderer.texture; public abstract class TextureTicked { public abstract void renderStep(int[] data); diff --git a/java/src/game/renderer/texture/TextureUtil.java b/java/src/client/renderer/texture/TextureUtil.java similarity index 98% rename from java/src/game/renderer/texture/TextureUtil.java rename to java/src/client/renderer/texture/TextureUtil.java index 2baadf3..61f517d 100755 --- a/java/src/game/renderer/texture/TextureUtil.java +++ b/java/src/client/renderer/texture/TextureUtil.java @@ -1,4 +1,4 @@ -package game.renderer.texture; +package client.renderer.texture; import static org.lwjgl.system.MemoryUtil.NULL; @@ -14,7 +14,7 @@ import javax.imageio.ImageIO; import org.lwjgl.opengl.GL11; import org.lwjgl.opengl.GL12; -import game.renderer.GlState; +import client.renderer.GlState; import game.util.FileUtils; public class TextureUtil diff --git a/java/src/game/renderer/ticked/TextureFlamesFX1.java b/java/src/client/renderer/ticked/TextureFlamesFX1.java similarity index 93% rename from java/src/game/renderer/ticked/TextureFlamesFX1.java rename to java/src/client/renderer/ticked/TextureFlamesFX1.java index adac8b8..6b07093 100755 --- a/java/src/game/renderer/ticked/TextureFlamesFX1.java +++ b/java/src/client/renderer/ticked/TextureFlamesFX1.java @@ -1,6 +1,6 @@ -package game.renderer.ticked; +package client.renderer.ticked; -import game.renderer.texture.TextureTicked; +import client.renderer.texture.TextureTicked; public class TextureFlamesFX1 extends TextureTicked diff --git a/java/src/game/renderer/ticked/TextureFlamesFX2.java b/java/src/client/renderer/ticked/TextureFlamesFX2.java similarity index 85% rename from java/src/game/renderer/ticked/TextureFlamesFX2.java rename to java/src/client/renderer/ticked/TextureFlamesFX2.java index 2328e07..615af67 100755 --- a/java/src/game/renderer/ticked/TextureFlamesFX2.java +++ b/java/src/client/renderer/ticked/TextureFlamesFX2.java @@ -1,4 +1,4 @@ -package game.renderer.ticked; +package client.renderer.ticked; public class TextureFlamesFX2 extends TextureFlamesFX1 { public TextureFlamesFX2() diff --git a/java/src/game/renderer/ticked/TextureLavaFX.java b/java/src/client/renderer/ticked/TextureLavaFX.java similarity index 94% rename from java/src/game/renderer/ticked/TextureLavaFX.java rename to java/src/client/renderer/ticked/TextureLavaFX.java index d7a95eb..b862970 100755 --- a/java/src/game/renderer/ticked/TextureLavaFX.java +++ b/java/src/client/renderer/ticked/TextureLavaFX.java @@ -1,6 +1,6 @@ -package game.renderer.ticked; +package client.renderer.ticked; -import game.renderer.texture.TextureTicked; +import client.renderer.texture.TextureTicked; import game.util.ExtMath; public class TextureLavaFX extends TextureTicked diff --git a/java/src/game/renderer/ticked/TextureLavaFlowFX.java b/java/src/client/renderer/ticked/TextureLavaFlowFX.java similarity index 95% rename from java/src/game/renderer/ticked/TextureLavaFlowFX.java rename to java/src/client/renderer/ticked/TextureLavaFlowFX.java index e9028af..d6494a9 100755 --- a/java/src/game/renderer/ticked/TextureLavaFlowFX.java +++ b/java/src/client/renderer/ticked/TextureLavaFlowFX.java @@ -1,6 +1,6 @@ -package game.renderer.ticked; +package client.renderer.ticked; -import game.renderer.texture.TextureTicked; +import client.renderer.texture.TextureTicked; import game.util.ExtMath; public class TextureLavaFlowFX extends TextureTicked diff --git a/java/src/game/renderer/ticked/TextureWaterFX.java b/java/src/client/renderer/ticked/TextureWaterFX.java similarity index 93% rename from java/src/game/renderer/ticked/TextureWaterFX.java rename to java/src/client/renderer/ticked/TextureWaterFX.java index 0493dd1..be5a276 100755 --- a/java/src/game/renderer/ticked/TextureWaterFX.java +++ b/java/src/client/renderer/ticked/TextureWaterFX.java @@ -1,6 +1,6 @@ -package game.renderer.ticked; +package client.renderer.ticked; -import game.renderer.texture.TextureTicked; +import client.renderer.texture.TextureTicked; public class TextureWaterFX extends TextureTicked diff --git a/java/src/game/renderer/ticked/TextureWaterFlowFX.java b/java/src/client/renderer/ticked/TextureWaterFlowFX.java similarity index 94% rename from java/src/game/renderer/ticked/TextureWaterFlowFX.java rename to java/src/client/renderer/ticked/TextureWaterFlowFX.java index bdbe153..ebf64ef 100755 --- a/java/src/game/renderer/ticked/TextureWaterFlowFX.java +++ b/java/src/client/renderer/ticked/TextureWaterFlowFX.java @@ -1,6 +1,6 @@ -package game.renderer.ticked; +package client.renderer.ticked; -import game.renderer.texture.TextureTicked; +import client.renderer.texture.TextureTicked; public class TextureWaterFlowFX extends TextureTicked diff --git a/java/src/game/renderer/tileentity/TileEntityBannerRenderer.java b/java/src/client/renderer/tileentity/TileEntityBannerRenderer.java similarity index 96% rename from java/src/game/renderer/tileentity/TileEntityBannerRenderer.java rename to java/src/client/renderer/tileentity/TileEntityBannerRenderer.java index 939bd81..d968685 100755 --- a/java/src/game/renderer/tileentity/TileEntityBannerRenderer.java +++ b/java/src/client/renderer/tileentity/TileEntityBannerRenderer.java @@ -1,4 +1,4 @@ -package game.renderer.tileentity; +package client.renderer.tileentity; import java.util.Iterator; import java.util.List; @@ -6,15 +6,14 @@ import java.util.Map; import org.lwjgl.opengl.GL11; +import client.Game; +import client.renderer.GlState; +import client.renderer.model.ModelBanner; +import client.renderer.texture.LayeredColorMaskTexture; import game.collect.Lists; import game.collect.Maps; - -import game.Game; import game.color.DyeColor; import game.init.Blocks; -import game.renderer.GlState; -import game.renderer.model.ModelBanner; -import game.renderer.texture.LayeredColorMaskTexture; import game.tileentity.TileEntityBanner; import game.util.ExtMath; import game.world.BlockPos; diff --git a/java/src/game/renderer/tileentity/TileEntityChestRenderer.java b/java/src/client/renderer/tileentity/TileEntityChestRenderer.java similarity index 97% rename from java/src/game/renderer/tileentity/TileEntityChestRenderer.java rename to java/src/client/renderer/tileentity/TileEntityChestRenderer.java index 0e1ca98..9d83257 100755 --- a/java/src/game/renderer/tileentity/TileEntityChestRenderer.java +++ b/java/src/client/renderer/tileentity/TileEntityChestRenderer.java @@ -1,12 +1,12 @@ -package game.renderer.tileentity; +package client.renderer.tileentity; import org.lwjgl.opengl.GL11; +import client.renderer.GlState; +import client.renderer.model.ModelChest; +import client.renderer.model.ModelLargeChest; import game.block.Block; import game.block.BlockChest; -import game.renderer.GlState; -import game.renderer.model.ModelChest; -import game.renderer.model.ModelLargeChest; import game.tileentity.TileEntityChest; diff --git a/java/src/game/renderer/tileentity/TileEntityItemStackRenderer.java b/java/src/client/renderer/tileentity/TileEntityItemStackRenderer.java similarity index 97% rename from java/src/game/renderer/tileentity/TileEntityItemStackRenderer.java rename to java/src/client/renderer/tileentity/TileEntityItemStackRenderer.java index 08829fb..72702f5 100755 --- a/java/src/game/renderer/tileentity/TileEntityItemStackRenderer.java +++ b/java/src/client/renderer/tileentity/TileEntityItemStackRenderer.java @@ -1,12 +1,12 @@ -package game.renderer.tileentity; +package client.renderer.tileentity; import org.lwjgl.opengl.GL11; +import client.renderer.GlState; import game.block.Block; import game.init.Blocks; import game.init.Items; import game.item.ItemStack; -import game.renderer.GlState; import game.tileentity.TileEntityBanner; import game.tileentity.TileEntityChest; import game.tileentity.TileEntitySkull; diff --git a/java/src/game/renderer/tileentity/TileEntityMobSpawnerRenderer.java b/java/src/client/renderer/tileentity/TileEntityMobSpawnerRenderer.java similarity index 96% rename from java/src/game/renderer/tileentity/TileEntityMobSpawnerRenderer.java rename to java/src/client/renderer/tileentity/TileEntityMobSpawnerRenderer.java index 96aa199..e31dca2 100755 --- a/java/src/game/renderer/tileentity/TileEntityMobSpawnerRenderer.java +++ b/java/src/client/renderer/tileentity/TileEntityMobSpawnerRenderer.java @@ -1,8 +1,8 @@ -package game.renderer.tileentity; +package client.renderer.tileentity; import org.lwjgl.opengl.GL11; -import game.Game; +import client.Game; import game.entity.Entity; import game.tileentity.TileEntityMobSpawner; diff --git a/java/src/game/renderer/tileentity/TileEntityPistonRenderer.java b/java/src/client/renderer/tileentity/TileEntityPistonRenderer.java similarity index 92% rename from java/src/game/renderer/tileentity/TileEntityPistonRenderer.java rename to java/src/client/renderer/tileentity/TileEntityPistonRenderer.java index 201fbad..651f015 100755 --- a/java/src/game/renderer/tileentity/TileEntityPistonRenderer.java +++ b/java/src/client/renderer/tileentity/TileEntityPistonRenderer.java @@ -1,20 +1,20 @@ -package game.renderer.tileentity; +package client.renderer.tileentity; import org.lwjgl.opengl.GL11; -import game.Game; +import client.Game; +import client.renderer.BlockRenderer; +import client.renderer.DefaultVertexFormats; +import client.renderer.GlState; +import client.renderer.ItemRenderer; +import client.renderer.RenderBuffer; +import client.renderer.Tessellator; +import client.renderer.texture.TextureMap; import game.block.Block; import game.block.BlockPistonBase; import game.block.BlockPistonHead; import game.init.Blocks; import game.material.Material; -import game.renderer.BlockRenderer; -import game.renderer.DefaultVertexFormats; -import game.renderer.GlState; -import game.renderer.ItemRenderer; -import game.renderer.RenderBuffer; -import game.renderer.Tessellator; -import game.renderer.texture.TextureMap; import game.tileentity.TileEntityPiston; import game.world.BlockPos; import game.world.State; diff --git a/java/src/game/renderer/tileentity/TileEntityRendererDispatcher.java b/java/src/client/renderer/tileentity/TileEntityRendererDispatcher.java similarity index 98% rename from java/src/game/renderer/tileentity/TileEntityRendererDispatcher.java rename to java/src/client/renderer/tileentity/TileEntityRendererDispatcher.java index a28a185..3fb7166 100755 --- a/java/src/game/renderer/tileentity/TileEntityRendererDispatcher.java +++ b/java/src/client/renderer/tileentity/TileEntityRendererDispatcher.java @@ -1,14 +1,13 @@ -package game.renderer.tileentity; +package client.renderer.tileentity; import java.util.Map; import org.lwjgl.opengl.GL13; +import client.renderer.GlState; +import client.renderer.texture.TextureManager; import game.collect.Maps; - import game.entity.Entity; -import game.renderer.GlState; -import game.renderer.texture.TextureManager; import game.tileentity.TileEntity; import game.tileentity.TileEntityBanner; import game.tileentity.TileEntityChest; diff --git a/java/src/game/renderer/tileentity/TileEntitySignRenderer.java b/java/src/client/renderer/tileentity/TileEntitySignRenderer.java similarity index 96% rename from java/src/game/renderer/tileentity/TileEntitySignRenderer.java rename to java/src/client/renderer/tileentity/TileEntitySignRenderer.java index 0d20bab..b5d3117 100755 --- a/java/src/game/renderer/tileentity/TileEntitySignRenderer.java +++ b/java/src/client/renderer/tileentity/TileEntitySignRenderer.java @@ -1,13 +1,13 @@ -package game.renderer.tileentity; +package client.renderer.tileentity; import org.lwjgl.opengl.GL11; +import client.gui.Font; +import client.renderer.Drawing; +import client.renderer.GlState; +import client.renderer.model.ModelSign; import game.block.Block; -import game.gui.Font; import game.init.Blocks; -import game.renderer.Drawing; -import game.renderer.GlState; -import game.renderer.model.ModelSign; import game.tileentity.TileEntitySign; diff --git a/java/src/game/renderer/tileentity/TileEntitySkullRenderer.java b/java/src/client/renderer/tileentity/TileEntitySkullRenderer.java similarity index 96% rename from java/src/game/renderer/tileentity/TileEntitySkullRenderer.java rename to java/src/client/renderer/tileentity/TileEntitySkullRenderer.java index 7a6ef45..577b18a 100755 --- a/java/src/game/renderer/tileentity/TileEntitySkullRenderer.java +++ b/java/src/client/renderer/tileentity/TileEntitySkullRenderer.java @@ -1,9 +1,9 @@ -package game.renderer.tileentity; +package client.renderer.tileentity; import org.lwjgl.opengl.GL11; -import game.renderer.GlState; -import game.renderer.model.ModelHumanoidHead; +import client.renderer.GlState; +import client.renderer.model.ModelHumanoidHead; import game.tileentity.TileEntitySkull; import game.world.Facing; diff --git a/java/src/game/renderer/tileentity/TileEntitySpecialRenderer.java b/java/src/client/renderer/tileentity/TileEntitySpecialRenderer.java similarity index 95% rename from java/src/game/renderer/tileentity/TileEntitySpecialRenderer.java rename to java/src/client/renderer/tileentity/TileEntitySpecialRenderer.java index 68bd7c3..8903943 100755 --- a/java/src/game/renderer/tileentity/TileEntitySpecialRenderer.java +++ b/java/src/client/renderer/tileentity/TileEntitySpecialRenderer.java @@ -1,6 +1,6 @@ -package game.renderer.tileentity; +package client.renderer.tileentity; -import game.renderer.texture.TextureManager; +import client.renderer.texture.TextureManager; import game.tileentity.TileEntity; import game.world.World; diff --git a/java/src/game/window/Bind.java b/java/src/client/window/Bind.java similarity index 96% rename from java/src/game/window/Bind.java rename to java/src/client/window/Bind.java index 5cf89db..040ea95 100644 --- a/java/src/game/window/Bind.java +++ b/java/src/client/window/Bind.java @@ -1,14 +1,14 @@ -package game.window; +package client.window; -import game.Game; +import client.Game; +import client.gui.element.Element; import game.color.TextColor; -import game.gui.element.Element; -import game.properties.IStringSerializable; +import game.util.Identifyable; import game.util.Util; import game.vars.CVar; import game.vars.CVarCategory; -public enum Bind implements IStringSerializable, CVar { +public enum Bind implements Identifyable, CVar { FORWARD("forward", "Vorwärts", Keysym.W), LEFT("left", "Nach links", Keysym.A), BACKWARD("backward", "Rückwärts", Keysym.S), diff --git a/java/src/game/window/Button.java b/java/src/client/window/Button.java similarity index 95% rename from java/src/game/window/Button.java rename to java/src/client/window/Button.java index 89cd8f8..c5809e2 100644 --- a/java/src/game/window/Button.java +++ b/java/src/client/window/Button.java @@ -1,6 +1,6 @@ -package game.window; +package client.window; -import game.Game; +import client.Game; public enum Button implements Input { MOUSE_LEFT("lmb", "Linke Maustaste"), diff --git a/java/src/game/window/DisplayMode.java b/java/src/client/window/DisplayMode.java similarity index 96% rename from java/src/game/window/DisplayMode.java rename to java/src/client/window/DisplayMode.java index c734e4d..9ab016f 100644 --- a/java/src/game/window/DisplayMode.java +++ b/java/src/client/window/DisplayMode.java @@ -1,4 +1,4 @@ -package game.window; +package client.window; public class DisplayMode { public static final int VID_MODES = 28; diff --git a/java/src/client/window/Input.java b/java/src/client/window/Input.java new file mode 100644 index 0000000..b4700a4 --- /dev/null +++ b/java/src/client/window/Input.java @@ -0,0 +1,8 @@ +package client.window; + +import game.util.Displayable; +import game.util.Identifyable; + +public interface Input extends Identifyable, Displayable { + public boolean read(); +} diff --git a/java/src/game/window/KeyEvent.java b/java/src/client/window/KeyEvent.java similarity index 69% rename from java/src/game/window/KeyEvent.java rename to java/src/client/window/KeyEvent.java index d4101ae..87ed04d 100644 --- a/java/src/game/window/KeyEvent.java +++ b/java/src/client/window/KeyEvent.java @@ -1,4 +1,4 @@ -package game.window; +package client.window; public enum KeyEvent { RELEASE, diff --git a/java/src/game/window/Keysym.java b/java/src/client/window/Keysym.java similarity index 99% rename from java/src/game/window/Keysym.java rename to java/src/client/window/Keysym.java index 0e9ffe8..0660f91 100644 --- a/java/src/game/window/Keysym.java +++ b/java/src/client/window/Keysym.java @@ -1,4 +1,4 @@ -package game.window; +package client.window; import static org.lwjgl.glfw.GLFW.*; diff --git a/java/src/game/window/Wheel.java b/java/src/client/window/Wheel.java similarity index 93% rename from java/src/game/window/Wheel.java rename to java/src/client/window/Wheel.java index fff8d68..50cd5c3 100644 --- a/java/src/game/window/Wheel.java +++ b/java/src/client/window/Wheel.java @@ -1,6 +1,6 @@ -package game.window; +package client.window; -import game.Game; +import client.Game; public enum Wheel implements Input { SCROLL_UP("scrup", "Mausrad aufwärts"), diff --git a/java/src/game/window/Window.java b/java/src/client/window/Window.java similarity index 77% rename from java/src/game/window/Window.java rename to java/src/client/window/Window.java index a3e8d30..5356abe 100644 --- a/java/src/game/window/Window.java +++ b/java/src/client/window/Window.java @@ -1,7 +1,54 @@ -package game.window; +package client.window; import static org.lwjgl.glfw.Callbacks.glfwFreeCallbacks; -import static org.lwjgl.glfw.GLFW.*; +import static org.lwjgl.glfw.GLFW.GLFW_CONTEXT_DEBUG; +import static org.lwjgl.glfw.GLFW.GLFW_CURSOR; +import static org.lwjgl.glfw.GLFW.GLFW_CURSOR_DISABLED; +import static org.lwjgl.glfw.GLFW.GLFW_CURSOR_NORMAL; +import static org.lwjgl.glfw.GLFW.GLFW_DONT_CARE; +import static org.lwjgl.glfw.GLFW.GLFW_FALSE; +import static org.lwjgl.glfw.GLFW.GLFW_PRESS; +import static org.lwjgl.glfw.GLFW.GLFW_RELEASE; +import static org.lwjgl.glfw.GLFW.GLFW_REPEAT; +import static org.lwjgl.glfw.GLFW.GLFW_RESIZABLE; +import static org.lwjgl.glfw.GLFW.GLFW_TRUE; +import static org.lwjgl.glfw.GLFW.GLFW_VISIBLE; +import static org.lwjgl.glfw.GLFW.glfwCreateWindow; +import static org.lwjgl.glfw.GLFW.glfwDefaultWindowHints; +import static org.lwjgl.glfw.GLFW.glfwDestroyWindow; +import static org.lwjgl.glfw.GLFW.glfwGetClipboardString; +import static org.lwjgl.glfw.GLFW.glfwGetKey; +import static org.lwjgl.glfw.GLFW.glfwGetMonitorPos; +import static org.lwjgl.glfw.GLFW.glfwGetPrimaryMonitor; +import static org.lwjgl.glfw.GLFW.glfwGetTimerFrequency; +import static org.lwjgl.glfw.GLFW.glfwGetVideoMode; +import static org.lwjgl.glfw.GLFW.glfwGetVideoModes; +import static org.lwjgl.glfw.GLFW.glfwInit; +import static org.lwjgl.glfw.GLFW.glfwMakeContextCurrent; +import static org.lwjgl.glfw.GLFW.glfwPollEvents; +import static org.lwjgl.glfw.GLFW.glfwSetCharCallback; +import static org.lwjgl.glfw.GLFW.glfwSetClipboardString; +import static org.lwjgl.glfw.GLFW.glfwSetCursorPosCallback; +import static org.lwjgl.glfw.GLFW.glfwSetErrorCallback; +import static org.lwjgl.glfw.GLFW.glfwSetFramebufferSizeCallback; +import static org.lwjgl.glfw.GLFW.glfwSetInputMode; +import static org.lwjgl.glfw.GLFW.glfwSetKeyCallback; +import static org.lwjgl.glfw.GLFW.glfwSetMouseButtonCallback; +import static org.lwjgl.glfw.GLFW.glfwSetScrollCallback; +import static org.lwjgl.glfw.GLFW.glfwSetWindowCloseCallback; +import static org.lwjgl.glfw.GLFW.glfwSetWindowFocusCallback; +import static org.lwjgl.glfw.GLFW.glfwSetWindowIcon; +import static org.lwjgl.glfw.GLFW.glfwSetWindowMonitor; +import static org.lwjgl.glfw.GLFW.glfwSetWindowPos; +import static org.lwjgl.glfw.GLFW.glfwSetWindowPosCallback; +import static org.lwjgl.glfw.GLFW.glfwSetWindowRefreshCallback; +import static org.lwjgl.glfw.GLFW.glfwSetWindowSize; +import static org.lwjgl.glfw.GLFW.glfwSetWindowTitle; +import static org.lwjgl.glfw.GLFW.glfwShowWindow; +import static org.lwjgl.glfw.GLFW.glfwSwapBuffers; +import static org.lwjgl.glfw.GLFW.glfwSwapInterval; +import static org.lwjgl.glfw.GLFW.glfwTerminate; +import static org.lwjgl.glfw.GLFW.glfwWindowHint; import static org.lwjgl.system.MemoryUtil.NULL; import java.util.ArrayList; diff --git a/java/src/game/window/WindowAction.java b/java/src/client/window/WindowAction.java similarity index 84% rename from java/src/game/window/WindowAction.java rename to java/src/client/window/WindowAction.java index e775b65..cdba867 100644 --- a/java/src/game/window/WindowAction.java +++ b/java/src/client/window/WindowAction.java @@ -1,4 +1,4 @@ -package game.window; +package client.window; public enum WindowAction { RESIZE, diff --git a/java/src/game/window/WindowEvent.java b/java/src/client/window/WindowEvent.java similarity index 91% rename from java/src/game/window/WindowEvent.java rename to java/src/client/window/WindowEvent.java index d370a06..294b005 100644 --- a/java/src/game/window/WindowEvent.java +++ b/java/src/client/window/WindowEvent.java @@ -1,4 +1,4 @@ -package game.window; +package client.window; public class WindowEvent { public final WindowAction action; diff --git a/java/src/game/ai/EntityAIAvoidEntity.java b/java/src/game/ai/EntityAIAvoidEntity.java index 79e15c4..8fe4468 100755 --- a/java/src/game/ai/EntityAIAvoidEntity.java +++ b/java/src/game/ai/EntityAIAvoidEntity.java @@ -1,14 +1,13 @@ package game.ai; import java.util.List; - import java.util.function.Predicate; -import game.util.Predicates; import game.entity.Entity; import game.entity.types.EntityLiving; import game.pathfinding.PathEntity; import game.pathfinding.PathNavigate; +import game.util.Predicates; import game.world.Vec3; public class EntityAIAvoidEntity extends EntityAIBase diff --git a/java/src/game/ai/EntityAIEatGrass.java b/java/src/game/ai/EntityAIEatGrass.java index 9886e91..4996966 100755 --- a/java/src/game/ai/EntityAIEatGrass.java +++ b/java/src/game/ai/EntityAIEatGrass.java @@ -1,7 +1,6 @@ package game.ai; import java.util.function.Predicate; -import game.util.Predicates; import game.block.BlockTallGrass; import game.entity.animal.EntitySheep; @@ -9,6 +8,7 @@ import game.init.BlockRegistry; import game.init.Blocks; import game.init.Config; import game.pattern.BlockStateHelper; +import game.util.Predicates; import game.world.BlockPos; import game.world.State; import game.world.World; diff --git a/java/src/game/ai/EntityAIFindEntityNearest.java b/java/src/game/ai/EntityAIFindEntityNearest.java index 99ee83e..5d9af13 100755 --- a/java/src/game/ai/EntityAIFindEntityNearest.java +++ b/java/src/game/ai/EntityAIFindEntityNearest.java @@ -2,7 +2,6 @@ package game.ai; import java.util.Collections; import java.util.List; - import java.util.function.Predicate; import game.entity.attributes.AttributeInstance; diff --git a/java/src/game/ai/EntityAIMate.java b/java/src/game/ai/EntityAIMate.java index cbe3146..ec0c071 100755 --- a/java/src/game/ai/EntityAIMate.java +++ b/java/src/game/ai/EntityAIMate.java @@ -7,7 +7,7 @@ import game.entity.npc.EntityNPC; import game.entity.types.EntityAnimal; import game.entity.types.EntityLiving; import game.init.Config; -import game.renderer.particle.ParticleType; +import game.model.ParticleType; import game.rng.Random; import game.world.World; diff --git a/java/src/game/ai/EntityAIMoveThroughVillage.java b/java/src/game/ai/EntityAIMoveThroughVillage.java index 2085b57..fa7b075 100755 --- a/java/src/game/ai/EntityAIMoveThroughVillage.java +++ b/java/src/game/ai/EntityAIMoveThroughVillage.java @@ -3,7 +3,6 @@ package game.ai; import java.util.List; import game.collect.Lists; - import game.entity.types.EntityLiving; import game.pathfinding.PathEntity; import game.pathfinding.PathNavigateGround; diff --git a/java/src/game/ai/EntityAINearestAttackableTarget.java b/java/src/game/ai/EntityAINearestAttackableTarget.java index 1ffbcf6..3e7ed3b 100755 --- a/java/src/game/ai/EntityAINearestAttackableTarget.java +++ b/java/src/game/ai/EntityAINearestAttackableTarget.java @@ -3,7 +3,6 @@ package game.ai; import java.util.Collections; import java.util.Comparator; import java.util.List; - import java.util.function.Predicate; import game.entity.Entity; diff --git a/java/src/game/ai/EntityAITakePlace.java b/java/src/game/ai/EntityAITakePlace.java index 564c713..597bf01 100755 --- a/java/src/game/ai/EntityAITakePlace.java +++ b/java/src/game/ai/EntityAITakePlace.java @@ -2,9 +2,8 @@ package game.ai; import java.util.Map; -import game.collect.Maps; - import game.block.Block; +import game.collect.Maps; import game.entity.npc.EntityNPC; import game.init.Blocks; import game.init.Config; diff --git a/java/src/game/ai/EntitySenses.java b/java/src/game/ai/EntitySenses.java index e9c257d..245cafb 100755 --- a/java/src/game/ai/EntitySenses.java +++ b/java/src/game/ai/EntitySenses.java @@ -3,7 +3,6 @@ package game.ai; import java.util.List; import game.collect.Lists; - import game.entity.Entity; import game.entity.types.EntityLiving; diff --git a/java/src/game/biome/Biome.java b/java/src/game/biome/Biome.java index b5269e3..b7a60d3 100755 --- a/java/src/game/biome/Biome.java +++ b/java/src/game/biome/Biome.java @@ -3,14 +3,13 @@ package game.biome; import java.util.List; import java.util.Map; -import game.collect.Lists; -import game.collect.Maps; - import game.block.Block; import game.block.BlockColored; import game.block.BlockFlower; import game.block.BlockSand; import game.block.BlockTallGrass; +import game.collect.Lists; +import game.collect.Maps; import game.color.Colorizer; import game.color.DyeColor; import game.entity.animal.EntityBat; diff --git a/java/src/game/block/Block.java b/java/src/game/block/Block.java index 78aab88..16e974a 100755 --- a/java/src/game/block/Block.java +++ b/java/src/game/block/Block.java @@ -9,16 +9,14 @@ import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.NoSuchElementException; - import java.util.function.Function; + import game.collect.ImmutableList; import game.collect.ImmutableMap; import game.collect.Iterables; import game.collect.Lists; import game.collect.Maps; import game.collect.UnmodifiableIterator; - -import game.audio.SoundType; import game.enchantment.EnchantmentHelper; import game.entity.Entity; import game.entity.item.EntityItem; @@ -31,10 +29,11 @@ import game.item.CheatTab; import game.item.Item; import game.item.ItemStack; import game.material.Material; +import game.model.BlockLayer; +import game.model.Model; +import game.model.ModelProvider; +import game.model.Transforms; import game.properties.IProperty; -import game.renderer.BlockLayer; -import game.renderer.blockmodel.ModelBlock; -import game.renderer.blockmodel.Transforms; import game.rng.Random; import game.tileentity.TileEntity; import game.util.ExtMath; @@ -1427,8 +1426,8 @@ public class Block return Transforms.BLOCK; } - public ModelBlock getModel(String name, State state) { - return new ModelBlock(name).add().all(); + public Model getModel(ModelProvider provider, String name, State state) { + return provider.getModel(name).add().all(); } public IProperty[] getIgnoredProperties() { diff --git a/java/src/game/block/BlockAnvil.java b/java/src/game/block/BlockAnvil.java index ef79ee3..cfca9f7 100755 --- a/java/src/game/block/BlockAnvil.java +++ b/java/src/game/block/BlockAnvil.java @@ -12,12 +12,13 @@ import game.item.CheatTab; import game.item.Item; import game.item.ItemStack; import game.material.Material; +import game.model.Model; +import game.model.ModelProvider; import game.model.ModelRotation; +import game.model.Transforms; import game.properties.IProperty; import game.properties.PropertyDirection; import game.properties.PropertyInteger; -import game.renderer.blockmodel.ModelBlock; -import game.renderer.blockmodel.Transforms; import game.tileentity.IInteractionObject; import game.world.BlockPos; import game.world.Facing; @@ -155,8 +156,8 @@ public class BlockAnvil extends BlockFalling return Transforms.ANVIL; } - public ModelBlock getModel(String name, State state) { - return new ModelBlock("anvil_base") + public Model getModel(ModelProvider provider, String name, State state) { + return provider.getModel("anvil_base") .add(2, 0, 2, 14, 4, 14).d().uv(2, 2, 14, 14).rot(180).u().uv(2, 2, 14, 14).rot(180).noCull() .ns().uv(2, 12, 14, 16).noCull().w().uv(0, 2, 4, 14).rot(90).noCull().e().uv(4, 2, 0, 14).rot(270).noCull() .add(4, 4, 3, 12, 5, 13).du().uv(4, 3, 12, 13).rot(180).noCull() diff --git a/java/src/game/block/BlockBanner.java b/java/src/game/block/BlockBanner.java index 4136f50..889a8f0 100755 --- a/java/src/game/block/BlockBanner.java +++ b/java/src/game/block/BlockBanner.java @@ -5,11 +5,11 @@ import game.init.Items; import game.item.Item; import game.item.ItemStack; import game.material.Material; +import game.model.Transforms; import game.nbt.NBTTagCompound; import game.properties.IProperty; import game.properties.PropertyDirection; import game.properties.PropertyInteger; -import game.renderer.blockmodel.Transforms; import game.rng.Random; import game.tileentity.TileEntity; import game.tileentity.TileEntityBanner; diff --git a/java/src/game/block/BlockBasePressurePlate.java b/java/src/game/block/BlockBasePressurePlate.java index 38057fd..1e60e30 100755 --- a/java/src/game/block/BlockBasePressurePlate.java +++ b/java/src/game/block/BlockBasePressurePlate.java @@ -4,7 +4,8 @@ import game.entity.Entity; import game.init.SoundEvent; import game.item.CheatTab; import game.material.Material; -import game.renderer.blockmodel.ModelBlock; +import game.model.Model; +import game.model.ModelProvider; import game.rng.Random; import game.world.BlockPos; import game.world.BoundingBox; @@ -235,9 +236,9 @@ public abstract class BlockBasePressurePlate extends Block return 1; } - public ModelBlock getModel(String name, State state) { + public Model getModel(ModelProvider provider, String name, State state) { if(this.getRedstoneStrength(state) > 0) - return new ModelBlock(this.getTexture()) + return provider.getModel(this.getTexture()) .add(1, 0, 1, 15, 0.5f, 15) .d().uv(1, 1, 15, 15) .u().uv(1, 1, 15, 15).noCull() @@ -246,7 +247,7 @@ public abstract class BlockBasePressurePlate extends Block .w().uv(1, 15.5f, 15, 16).noCull() .e().uv(1, 15.5f, 15, 16).noCull(); else - return new ModelBlock(this.getTexture()) + return provider.getModel(this.getTexture()) .add(1, 0, 1, 15, 1, 15) .d().uv(1, 1, 15, 15) .u().uv(1, 1, 15, 15).noCull() diff --git a/java/src/game/block/BlockBeacon.java b/java/src/game/block/BlockBeacon.java index 000cd97..48bf1a1 100755 --- a/java/src/game/block/BlockBeacon.java +++ b/java/src/game/block/BlockBeacon.java @@ -3,8 +3,9 @@ package game.block; import game.entity.npc.EntityNPC; import game.item.CheatTab; import game.material.Material; -import game.renderer.BlockLayer; -import game.renderer.blockmodel.ModelBlock; +import game.model.BlockLayer; +import game.model.Model; +import game.model.ModelProvider; import game.tileentity.TileEntity; import game.tileentity.TileEntityBeacon; import game.world.BlockPos; @@ -14,7 +15,7 @@ import game.world.World; public class BlockBeacon extends BlockContainer { - private static final ModelBlock beacon = new ModelBlock("glass").noOcclude() + private static final Model beacon = ModelProvider.getModelProvider().getModel("glass").noOcclude() .add(0, 0, 0, 16, 16, 16) .d().uv(0, 0, 16, 16).noCull() .u().uv(0, 0, 16, 16).noCull() @@ -131,7 +132,7 @@ public class BlockBeacon extends BlockContainer return BlockLayer.CUTOUT; } - public ModelBlock getModel(String name, State state) { + public Model getModel(ModelProvider provider, String name, State state) { return beacon; } } diff --git a/java/src/game/block/BlockBed.java b/java/src/game/block/BlockBed.java index bfb2ac0..9ed32a2 100755 --- a/java/src/game/block/BlockBed.java +++ b/java/src/game/block/BlockBed.java @@ -6,13 +6,14 @@ import game.entity.npc.EntityNPC; import game.init.ItemRegistry; import game.item.Item; import game.material.Material; +import game.model.BlockLayer; +import game.model.Model; +import game.model.ModelProvider; import game.model.ModelRotation; import game.properties.IProperty; -import game.properties.IStringSerializable; import game.properties.PropertyEnum; -import game.renderer.BlockLayer; -import game.renderer.blockmodel.ModelBlock; import game.rng.Random; +import game.util.Identifyable; import game.world.BlockPos; import game.world.Facing; import game.world.IWorldAccess; @@ -21,7 +22,7 @@ import game.world.World; import game.world.WorldPos; public class BlockBed extends BlockDirectional { - public static enum EnumPartType implements IStringSerializable { + public static enum EnumPartType implements Identifyable { HEAD("head"), FOOT("foot"); private final String name; @@ -189,15 +190,15 @@ public class BlockBed extends BlockDirectional { return new IProperty[] {FACING, PART}; } - public ModelBlock getModel(String name, State state) { + public Model getModel(ModelProvider provider, String name, State state) { if(state.getValue(PART) == EnumPartType.HEAD) - return new ModelBlock(this.color + "_bed_head_top").add(0, 0, 0, 16, 9, 16) + return provider.getModel(this.color + "_bed_head_top").add(0, 0, 0, 16, 9, 16) .u().rot(90).noCull().s(this.color + "_bed_head_end").noCull() .w(this.color + "_bed_head_side").uv(0, 7, 16, 16).noCull().e(this.color + "_bed_head_side").uv(16, 7, 0, 16).noCull() .add(0, 3, 0, 16, 3, 16) .d("oak_planks").noCull().rotate(ModelRotation.getNorthRot(state.getValue(FACING).getOpposite())); else - return new ModelBlock(this.color + "_bed_foot_top").add(0, 0, 0, 16, 9, 16) + return provider.getModel(this.color + "_bed_foot_top").add(0, 0, 0, 16, 9, 16) .u().rot(90).noCull().n(this.color + "_bed_foot_end").noCull() .w(this.color + "_bed_foot_side").uv(0, 7, 16, 16).noCull().e(this.color + "_bed_foot_side").uv(16, 7, 0, 16).noCull() .add(0, 3, 0, 16, 3, 16) diff --git a/java/src/game/block/BlockBedrock.java b/java/src/game/block/BlockBedrock.java index c5abe11..42c60eb 100755 --- a/java/src/game/block/BlockBedrock.java +++ b/java/src/game/block/BlockBedrock.java @@ -1,7 +1,7 @@ package game.block; import game.material.Material; -import game.renderer.particle.ParticleType; +import game.model.ParticleType; import game.rng.Random; import game.world.BlockPos; import game.world.State; diff --git a/java/src/game/block/BlockBlackenedSoil.java b/java/src/game/block/BlockBlackenedSoil.java index 7b3026a..d1427ba 100644 --- a/java/src/game/block/BlockBlackenedSoil.java +++ b/java/src/game/block/BlockBlackenedSoil.java @@ -5,7 +5,8 @@ import game.init.Config; import game.item.CheatTab; import game.item.Item; import game.material.Material; -import game.renderer.blockmodel.ModelBlock; +import game.model.Model; +import game.model.ModelProvider; import game.rng.Random; import game.world.BlockPos; import game.world.State; @@ -48,7 +49,7 @@ public class BlockBlackenedSoil extends Block return Blocks.blackened_dirt.getItemDropped(Blocks.blackened_dirt.getState(), rand, fortune); } - public ModelBlock getModel(String name, State state) { - return new ModelBlock("blackened_dirt").add().d().u("blackened_soil_top").nswe("blackened_soil_side"); + public Model getModel(ModelProvider provider, String name, State state) { + return provider.getModel("blackened_dirt").add().d().u("blackened_soil_top").nswe("blackened_soil_side"); } } diff --git a/java/src/game/block/BlockBlueShroom.java b/java/src/game/block/BlockBlueShroom.java index ff95349..d8b7ffe 100755 --- a/java/src/game/block/BlockBlueShroom.java +++ b/java/src/game/block/BlockBlueShroom.java @@ -2,7 +2,8 @@ package game.block; import game.init.Blocks; import game.init.Config; -import game.renderer.blockmodel.ModelBlock; +import game.model.Model; +import game.model.ModelProvider; import game.rng.Random; import game.world.BlockPos; import game.world.State; @@ -80,7 +81,7 @@ public class BlockBlueShroom extends BlockBush } } - public ModelBlock getModel(String name, State state) { - return new ModelBlock("blue_mushroom").cross(); + public Model getModel(ModelProvider provider, String name, State state) { + return provider.getModel("blue_mushroom").cross(); } } diff --git a/java/src/game/block/BlockBookshelf.java b/java/src/game/block/BlockBookshelf.java index bd4761a..7d871f4 100755 --- a/java/src/game/block/BlockBookshelf.java +++ b/java/src/game/block/BlockBookshelf.java @@ -4,7 +4,8 @@ import game.init.Items; import game.item.CheatTab; import game.item.Item; import game.material.Material; -import game.renderer.blockmodel.ModelBlock; +import game.model.Model; +import game.model.ModelProvider; import game.rng.Random; import game.world.State; @@ -32,7 +33,7 @@ public class BlockBookshelf extends Block return Items.book; } - public ModelBlock getModel(String name, State state) { - return new ModelBlock("bookshelf").add().nswe().du("oak_planks"); + public Model getModel(ModelProvider provider, String name, State state) { + return provider.getModel("bookshelf").add().nswe().du("oak_planks"); } } diff --git a/java/src/game/block/BlockBrewingStand.java b/java/src/game/block/BlockBrewingStand.java index 7fafe33..5a51b4b 100755 --- a/java/src/game/block/BlockBrewingStand.java +++ b/java/src/game/block/BlockBrewingStand.java @@ -11,11 +11,12 @@ import game.inventory.InventoryHelper; import game.item.Item; import game.item.ItemStack; import game.material.Material; +import game.model.BlockLayer; +import game.model.Model; +import game.model.ModelProvider; +import game.model.ParticleType; import game.properties.IProperty; import game.properties.PropertyBool; -import game.renderer.BlockLayer; -import game.renderer.blockmodel.ModelBlock; -import game.renderer.particle.ParticleType; import game.rng.Random; import game.tileentity.TileEntity; import game.tileentity.TileEntityBrewingStand; @@ -29,7 +30,7 @@ import game.world.WorldServer; public class BlockBrewingStand extends BlockContainer { - private static final ModelBlock brewing_stand_bottles_2 = new ModelBlock("brewing_stand") + private static final Model brewing_stand_bottles_2 = ModelProvider.getModelProvider().getModel("brewing_stand") .add(7, 0, 7, 9, 14, 9) .d().uv(7, 7, 9, 9).noCull() .u().uv(7, 7, 9, 9).noCull() @@ -68,7 +69,7 @@ public class BlockBrewingStand extends BlockContainer .n().uv(8, 0, 0, 16).noCull() .s().uv(0, 0, 8, 16).noCull() ; - private static final ModelBlock brewing_stand_bottles_123 = new ModelBlock("brewing_stand") + private static final Model brewing_stand_bottles_123 = ModelProvider.getModelProvider().getModel("brewing_stand") .add(7, 0, 7, 9, 14, 9) .d().uv(7, 7, 9, 9).noCull() .u().uv(7, 7, 9, 9).noCull() @@ -107,7 +108,7 @@ public class BlockBrewingStand extends BlockContainer .n().uv(8, 0, 0, 16).noCull() .s().uv(0, 0, 8, 16).noCull() ; - private static final ModelBlock brewing_stand_empty = new ModelBlock("brewing_stand") + private static final Model brewing_stand_empty = ModelProvider.getModelProvider().getModel("brewing_stand") .add(7, 0, 7, 9, 14, 9) .d().uv(7, 7, 9, 9).noCull() .u().uv(7, 7, 9, 9).noCull() @@ -146,7 +147,7 @@ public class BlockBrewingStand extends BlockContainer .n().uv(8, 0, 16, 16).noCull() .s().uv(16, 0, 8, 16).noCull() ; - private static final ModelBlock brewing_stand_bottles_3 = new ModelBlock("brewing_stand") + private static final Model brewing_stand_bottles_3 = ModelProvider.getModelProvider().getModel("brewing_stand") .add(7, 0, 7, 9, 14, 9) .d().uv(7, 7, 9, 9).noCull() .u().uv(7, 7, 9, 9).noCull() @@ -185,7 +186,7 @@ public class BlockBrewingStand extends BlockContainer .n().uv(8, 0, 16, 16).noCull() .s().uv(16, 0, 8, 16).noCull() ; - private static final ModelBlock brewing_stand_bottles_13 = new ModelBlock("brewing_stand") + private static final Model brewing_stand_bottles_13 = ModelProvider.getModelProvider().getModel("brewing_stand") .add(7, 0, 7, 9, 14, 9) .d().uv(7, 7, 9, 9).noCull() .u().uv(7, 7, 9, 9).noCull() @@ -224,7 +225,7 @@ public class BlockBrewingStand extends BlockContainer .n().uv(8, 0, 16, 16).noCull() .s().uv(16, 0, 8, 16).noCull() ; - private static final ModelBlock brewing_stand_bottles_12 = new ModelBlock("brewing_stand") + private static final Model brewing_stand_bottles_12 = ModelProvider.getModelProvider().getModel("brewing_stand") .add(7, 0, 7, 9, 14, 9) .d().uv(7, 7, 9, 9).noCull() .u().uv(7, 7, 9, 9).noCull() @@ -263,7 +264,7 @@ public class BlockBrewingStand extends BlockContainer .n().uv(8, 0, 0, 16).noCull() .s().uv(0, 0, 8, 16).noCull() ; - private static final ModelBlock brewing_stand_bottles_23 = new ModelBlock("brewing_stand") + private static final Model brewing_stand_bottles_23 = ModelProvider.getModelProvider().getModel("brewing_stand") .add(7, 0, 7, 9, 14, 9) .d().uv(7, 7, 9, 9).noCull() .u().uv(7, 7, 9, 9).noCull() @@ -302,7 +303,7 @@ public class BlockBrewingStand extends BlockContainer .n().uv(8, 0, 0, 16).noCull() .s().uv(0, 0, 8, 16).noCull() ; - private static final ModelBlock brewing_stand_bottles_1 = new ModelBlock("brewing_stand") + private static final Model brewing_stand_bottles_1 = ModelProvider.getModelProvider().getModel("brewing_stand") .add(7, 0, 7, 9, 14, 9) .d().uv(7, 7, 9, 9).noCull() .u().uv(7, 7, 9, 9).noCull() @@ -341,7 +342,7 @@ public class BlockBrewingStand extends BlockContainer .n().uv(8, 0, 16, 16).noCull() .s().uv(16, 0, 8, 16).noCull() ; - private static final ModelBlock[] brewing_stand_bottles = new ModelBlock[] { + private static final Model[] brewing_stand_bottles = new Model[] { brewing_stand_empty, brewing_stand_bottles_1, brewing_stand_bottles_2, brewing_stand_bottles_12, brewing_stand_bottles_3, brewing_stand_bottles_13, brewing_stand_bottles_23, brewing_stand_bottles_123 }; @@ -536,7 +537,7 @@ public class BlockBrewingStand extends BlockContainer return true; } - public ModelBlock getModel(String name, State state) { + public Model getModel(ModelProvider provider, String name, State state) { return brewing_stand_bottles[(state.getValue(HAS_BOTTLE[0]) ? 1 : 0) | (state.getValue(HAS_BOTTLE[1]) ? 2 : 0) | (state.getValue(HAS_BOTTLE[2]) ? 4 : 0)]; } diff --git a/java/src/game/block/BlockBush.java b/java/src/game/block/BlockBush.java index a24495d..efc7592 100755 --- a/java/src/game/block/BlockBush.java +++ b/java/src/game/block/BlockBush.java @@ -3,7 +3,7 @@ package game.block; import game.init.Blocks; import game.item.CheatTab; import game.material.Material; -import game.renderer.BlockLayer; +import game.model.BlockLayer; import game.rng.Random; import game.world.BlockPos; import game.world.BoundingBox; diff --git a/java/src/game/block/BlockButton.java b/java/src/game/block/BlockButton.java index f98c869..982d1a6 100755 --- a/java/src/game/block/BlockButton.java +++ b/java/src/game/block/BlockButton.java @@ -3,7 +3,6 @@ package game.block; import java.util.List; import game.collect.Lists; - import game.entity.Entity; import game.entity.npc.EntityNPC; import game.entity.projectile.EntityArrow; @@ -11,12 +10,13 @@ import game.entity.types.EntityLiving; import game.init.SoundEvent; import game.item.CheatTab; import game.material.Material; +import game.model.Model; +import game.model.ModelProvider; import game.model.ModelRotation; +import game.model.Transforms; import game.properties.IProperty; import game.properties.PropertyBool; import game.properties.PropertyDirection; -import game.renderer.blockmodel.ModelBlock; -import game.renderer.blockmodel.Transforms; import game.rng.Random; import game.world.BlockPos; import game.world.BoundingBox; @@ -428,9 +428,9 @@ public class BlockButton extends Block return this.texture; } - public ModelBlock getModel(String name, State state) { + public Model getModel(ModelProvider provider, String name, State state) { boolean pressed = state.getValue(POWERED); - return new ModelBlock(this.texture).add(5, 0, 6, 11, pressed ? 1 : 2, 10) + return provider.getModel(this.texture).add(5, 0, 6, 11, pressed ? 1 : 2, 10) .d().uv(5, 6, 11, 10).u().uv(5, 10, 11, 6).noCull() .ns().uv(5, pressed ? 15 : 14, 11, 16).noCull().we().uv(6, pressed ? 15 : 14, 10, 16).noCull() .rotate(getRotation(state.getValue(FACING))); diff --git a/java/src/game/block/BlockCactus.java b/java/src/game/block/BlockCactus.java index 1ab1259..fa0cf2a 100755 --- a/java/src/game/block/BlockCactus.java +++ b/java/src/game/block/BlockCactus.java @@ -6,10 +6,11 @@ import game.init.Blocks; import game.init.Config; import game.item.CheatTab; import game.material.Material; +import game.model.BlockLayer; +import game.model.Model; +import game.model.ModelProvider; import game.properties.IProperty; import game.properties.PropertyInteger; -import game.renderer.BlockLayer; -import game.renderer.blockmodel.ModelBlock; import game.rng.Random; import game.world.BlockPos; import game.world.BoundingBox; @@ -20,7 +21,7 @@ import game.world.WorldServer; public class BlockCactus extends Block { - private static final ModelBlock cactus = new ModelBlock("cactus_side").noOcclude() + private static final Model cactus = ModelProvider.getModelProvider().getModel("cactus_side").noOcclude() .add(0, 0, 0, 16, 16, 16) .d("cactus_bottom").uv(0, 0, 16, 16) .u("cactus_top").uv(0, 0, 16, 16) @@ -164,7 +165,7 @@ public class BlockCactus extends Block return new IProperty[] {AGE}; } - public ModelBlock getModel(String name, State state) { + public Model getModel(ModelProvider provider, String name, State state) { return cactus; } diff --git a/java/src/game/block/BlockCake.java b/java/src/game/block/BlockCake.java index c71cee1..bf8995d 100755 --- a/java/src/game/block/BlockCake.java +++ b/java/src/game/block/BlockCake.java @@ -4,10 +4,11 @@ import game.entity.npc.EntityNPC; import game.init.Items; import game.item.Item; import game.material.Material; +import game.model.BlockLayer; +import game.model.Model; +import game.model.ModelProvider; import game.properties.IProperty; import game.properties.PropertyInteger; -import game.renderer.BlockLayer; -import game.renderer.blockmodel.ModelBlock; import game.rng.Random; import game.world.BlockPos; import game.world.BoundingBox; @@ -18,7 +19,7 @@ import game.world.World; public class BlockCake extends Block { - private static final ModelBlock cake_slice3 = new ModelBlock("cake_side") + private static final Model cake_slice3 = ModelProvider.getModelProvider().getModel("cake_side") .add(7, 0, 1, 15, 8, 15) .d("cake_bottom").uv(7, 1, 15, 15) .u("cake_top").uv(7, 1, 15, 15).noCull() @@ -27,7 +28,7 @@ public class BlockCake extends Block .w("cake_inner").uv(1, 8, 15, 16).noCull() .e().uv(1, 8, 15, 16).noCull() ; - private static final ModelBlock cake_slice1 = new ModelBlock("cake_side") + private static final Model cake_slice1 = ModelProvider.getModelProvider().getModel("cake_side") .add(3, 0, 1, 15, 8, 15) .d("cake_bottom").uv(3, 1, 15, 15) .u("cake_top").uv(3, 1, 15, 15).noCull() @@ -36,7 +37,7 @@ public class BlockCake extends Block .w("cake_inner").uv(1, 8, 15, 16).noCull() .e().uv(1, 8, 15, 16).noCull() ; - private static final ModelBlock cake_slice2 = new ModelBlock("cake_side") + private static final Model cake_slice2 = ModelProvider.getModelProvider().getModel("cake_side") .add(5, 0, 1, 15, 8, 15) .d("cake_bottom").uv(5, 1, 15, 15) .u("cake_top").uv(5, 1, 15, 15).noCull() @@ -45,7 +46,7 @@ public class BlockCake extends Block .w("cake_inner").uv(1, 8, 15, 16).noCull() .e().uv(1, 8, 15, 16).noCull() ; - private static final ModelBlock cake_slice5 = new ModelBlock("cake_side") + private static final Model cake_slice5 = ModelProvider.getModelProvider().getModel("cake_side") .add(11, 0, 1, 15, 8, 15) .d("cake_bottom").uv(11, 1, 15, 15) .u("cake_top").uv(11, 1, 15, 15).noCull() @@ -54,7 +55,7 @@ public class BlockCake extends Block .w("cake_inner").uv(1, 8, 15, 16).noCull() .e().uv(1, 8, 15, 16).noCull() ; - private static final ModelBlock cake_slice4 = new ModelBlock("cake_side") + private static final Model cake_slice4 = ModelProvider.getModelProvider().getModel("cake_side") .add(9, 0, 1, 15, 8, 15) .d("cake_bottom").uv(9, 1, 15, 15) .u("cake_top").uv(9, 1, 15, 15).noCull() @@ -63,7 +64,7 @@ public class BlockCake extends Block .w("cake_inner").uv(1, 8, 15, 16).noCull() .e().uv(1, 8, 15, 16).noCull() ; - private static final ModelBlock cake_uneaten = new ModelBlock("cake_side") + private static final Model cake_uneaten = ModelProvider.getModelProvider().getModel("cake_side") .add(1, 0, 1, 15, 8, 15) .d("cake_bottom").uv(1, 1, 15, 15) .u("cake_top").uv(1, 1, 15, 15).noCull() @@ -72,7 +73,7 @@ public class BlockCake extends Block .w().uv(1, 8, 15, 16).noCull() .e().uv(1, 8, 15, 16).noCull() ; - private static final ModelBlock cake_slice6 = new ModelBlock("cake_side") + private static final Model cake_slice6 = ModelProvider.getModelProvider().getModel("cake_side") .add(13, 0, 1, 15, 8, 15) .d("cake_bottom").uv(13, 1, 15, 15) .u("cake_top").uv(13, 1, 15, 15).noCull() @@ -81,8 +82,8 @@ public class BlockCake extends Block .w("cake_inner").uv(1, 8, 15, 16).noCull() .e().uv(1, 8, 15, 16).noCull() ; - private static final ModelBlock[] cake_slices = - new ModelBlock[] {cake_uneaten, cake_slice1, cake_slice2, cake_slice3, cake_slice4, cake_slice5, cake_slice6}; + private static final Model[] cake_slices = + new Model[] {cake_uneaten, cake_slice1, cake_slice2, cake_slice3, cake_slice4, cake_slice5, cake_slice6}; public static final PropertyInteger BITES = PropertyInteger.create("bites", 0, 6); @@ -241,7 +242,7 @@ public class BlockCake extends Block return true; } - public ModelBlock getModel(String name, State state) { + public Model getModel(ModelProvider provider, String name, State state) { return cake_slices[state.getValue(BITES)]; } } diff --git a/java/src/game/block/BlockCarpet.java b/java/src/game/block/BlockCarpet.java index a5a7c00..a54cc4d 100755 --- a/java/src/game/block/BlockCarpet.java +++ b/java/src/game/block/BlockCarpet.java @@ -7,10 +7,11 @@ import game.item.CheatTab; import game.item.Item; import game.item.ItemStack; import game.material.Material; +import game.model.Model; +import game.model.ModelProvider; +import game.model.Transforms; import game.properties.IProperty; import game.properties.PropertyEnum; -import game.renderer.blockmodel.ModelBlock; -import game.renderer.blockmodel.Transforms; import game.world.BlockPos; import game.world.Facing; import game.world.IWorldAccess; @@ -154,7 +155,7 @@ public class BlockCarpet extends Block return Transforms.LAYER; } - public ModelBlock getModel(String name, State state) { - return new ModelBlock(state.getValue(COLOR).getName() + "_wool").add(0, 0, 0, 16, 1, 16).nswe().uv(0, 15, 16, 16).d().u().noCull(); + public Model getModel(ModelProvider provider, String name, State state) { + return provider.getModel(state.getValue(COLOR).getName() + "_wool").add(0, 0, 0, 16, 1, 16).nswe().uv(0, 15, 16, 16).d().u().noCull(); } } diff --git a/java/src/game/block/BlockCarrot.java b/java/src/game/block/BlockCarrot.java index 0339480..54088e8 100755 --- a/java/src/game/block/BlockCarrot.java +++ b/java/src/game/block/BlockCarrot.java @@ -2,7 +2,8 @@ package game.block; import game.init.Items; import game.item.Item; -import game.renderer.blockmodel.ModelBlock; +import game.model.Model; +import game.model.ModelProvider; import game.world.State; public class BlockCarrot extends BlockCrops @@ -17,8 +18,8 @@ public class BlockCarrot extends BlockCrops return Items.carrot; } - public ModelBlock getModel(String name, State state) { + public Model getModel(ModelProvider provider, String name, State state) { int age = state.getValue(AGE); - return crop(name + "_" + (age == 6 ? 2 : (age / 2))); + return crop(provider, name + "_" + (age == 6 ? 2 : (age / 2))); } } diff --git a/java/src/game/block/BlockCauldron.java b/java/src/game/block/BlockCauldron.java index aa8d2c6..37296d8 100755 --- a/java/src/game/block/BlockCauldron.java +++ b/java/src/game/block/BlockCauldron.java @@ -13,9 +13,10 @@ import game.item.ItemArmor; import game.item.ItemBanner; import game.item.ItemStack; import game.material.Material; +import game.model.Model; +import game.model.ModelProvider; import game.properties.IProperty; import game.properties.PropertyInteger; -import game.renderer.blockmodel.ModelBlock; import game.rng.Random; import game.tileentity.TileEntityBanner; import game.util.ExtMath; @@ -27,7 +28,7 @@ import game.world.World; public class BlockCauldron extends Block { - private static final ModelBlock cauldron_empty = new ModelBlock("cauldron_side").noOcclude() + private static final Model cauldron_empty = ModelProvider.getModelProvider().getModel("cauldron_side").noOcclude() .add(0, 3, 0, 2, 16, 16) .d("cauldron_inner").uv(0, 0, 2, 16) .u("cauldron_top").uv(0, 0, 2, 16) @@ -120,7 +121,7 @@ public class BlockCauldron extends Block .w().uv(14, 13, 12, 16).noCull() .e().uv(14, 13, 12, 16).noCull() ; - private static final ModelBlock cauldron_level1 = new ModelBlock("cauldron_side").noOcclude() + private static final Model cauldron_level1 = ModelProvider.getModelProvider().getModel("cauldron_side").noOcclude() .add(0, 3, 0, 2, 16, 16) .d("cauldron_inner").uv(0, 0, 2, 16) .u("cauldron_top").uv(0, 0, 2, 16) @@ -215,7 +216,7 @@ public class BlockCauldron extends Block .add(2, 9, 2, 14, 9, 14) .u("water_still").uv(2, 2, 14, 14).noCull() ; - private static final ModelBlock cauldron_level2 = new ModelBlock("cauldron_side").noOcclude() + private static final Model cauldron_level2 = ModelProvider.getModelProvider().getModel("cauldron_side").noOcclude() .add(0, 3, 0, 2, 16, 16) .d("cauldron_inner").uv(0, 0, 2, 16) .u("cauldron_top").uv(0, 0, 2, 16) @@ -310,7 +311,7 @@ public class BlockCauldron extends Block .add(2, 12, 2, 14, 12, 14) .u("water_still").uv(2, 2, 14, 14).noCull() ; - private static final ModelBlock cauldron_level3 = new ModelBlock("cauldron_side").noOcclude() + private static final Model cauldron_level3 = ModelProvider.getModelProvider().getModel("cauldron_side").noOcclude() .add(0, 3, 0, 2, 16, 16) .d("cauldron_inner").uv(0, 0, 2, 16) .u("cauldron_top").uv(0, 0, 2, 16) @@ -405,8 +406,8 @@ public class BlockCauldron extends Block .add(2, 15, 2, 14, 15, 14) .u("water_still").uv(2, 2, 14, 14).noCull() ; - private static final ModelBlock[] cauldron_levels = - new ModelBlock[] {cauldron_empty, cauldron_level1, cauldron_level2, cauldron_level3}; + private static final Model[] cauldron_levels = + new Model[] {cauldron_empty, cauldron_level1, cauldron_level2, cauldron_level3}; public static final PropertyInteger LEVEL = PropertyInteger.create("level", 0, 3); @@ -666,7 +667,7 @@ public class BlockCauldron extends Block return true; } - public ModelBlock getModel(String name, State state) { + public Model getModel(ModelProvider provider, String name, State state) { return cauldron_levels[state.getValue(LEVEL)]; } } diff --git a/java/src/game/block/BlockCocoa.java b/java/src/game/block/BlockCocoa.java index d24cbe3..0f24db0 100755 --- a/java/src/game/block/BlockCocoa.java +++ b/java/src/game/block/BlockCocoa.java @@ -8,11 +8,12 @@ import game.init.Items; import game.item.Item; import game.item.ItemStack; import game.material.Material; +import game.model.BlockLayer; +import game.model.Model; +import game.model.ModelProvider; import game.model.ModelRotation; import game.properties.IProperty; import game.properties.PropertyInteger; -import game.renderer.BlockLayer; -import game.renderer.blockmodel.ModelBlock; import game.rng.Random; import game.world.BlockPos; import game.world.BoundingBox; @@ -230,11 +231,11 @@ public class BlockCocoa extends BlockDirectional implements IGrowable return new IProperty[] {FACING, AGE}; } - public ModelBlock getModel(String name, State state) { - ModelBlock model; + public Model getModel(ModelProvider provider, String name, State state) { + Model model; switch(state.getValue(AGE)) { case 0: - model = new ModelBlock("cocoa_0").noOcclude() + model = provider.getModel("cocoa_0").noOcclude() .add(6, 7, 11, 10, 12, 15) .d().uv(0, 0, 4, 4).noCull() .u().uv(0, 0, 4, 4).noCull() @@ -247,7 +248,7 @@ public class BlockCocoa extends BlockDirectional implements IGrowable .e().uv(16, 0, 12, 4).noCull(); break; case 1: - model = new ModelBlock("cocoa_1").noOcclude() + model = provider.getModel("cocoa_1").noOcclude() .add(5, 5, 9, 11, 12, 15) .d().uv(0, 0, 6, 6).noCull() .u().uv(0, 0, 6, 6).noCull() @@ -261,7 +262,7 @@ public class BlockCocoa extends BlockDirectional implements IGrowable break; case 2: default: - model = new ModelBlock("cocoa_2").noOcclude() + model = provider.getModel("cocoa_2").noOcclude() .add(4, 3, 7, 12, 12, 15) .d().uv(0, 0, 7, 7).noCull() .u().uv(0, 0, 7, 7).noCull() diff --git a/java/src/game/block/BlockColored.java b/java/src/game/block/BlockColored.java index 3b3aafc..9aee9e4 100755 --- a/java/src/game/block/BlockColored.java +++ b/java/src/game/block/BlockColored.java @@ -7,9 +7,10 @@ import game.item.CheatTab; import game.item.Item; import game.item.ItemStack; import game.material.Material; +import game.model.Model; +import game.model.ModelProvider; import game.properties.IProperty; import game.properties.PropertyEnum; -import game.renderer.blockmodel.ModelBlock; import game.world.State; public class BlockColored extends Block @@ -72,7 +73,7 @@ public class BlockColored extends Block return new IProperty[] {COLOR}; } - public ModelBlock getModel(String name, State state) { - return new ModelBlock(state.getValue(COLOR).getName() + "_" + name).add().all(); + public Model getModel(ModelProvider provider, String name, State state) { + return provider.getModel(state.getValue(COLOR).getName() + "_" + name).add().all(); } } diff --git a/java/src/game/block/BlockCrops.java b/java/src/game/block/BlockCrops.java index 9b5d17a..cb052a9 100755 --- a/java/src/game/block/BlockCrops.java +++ b/java/src/game/block/BlockCrops.java @@ -1,15 +1,15 @@ package game.block; -import game.audio.SoundType; import game.init.Blocks; import game.init.Config; import game.init.Items; import game.item.CheatTab; import game.item.Item; import game.item.ItemStack; +import game.model.Model; +import game.model.ModelProvider; import game.properties.IProperty; import game.properties.PropertyInteger; -import game.renderer.blockmodel.ModelBlock; import game.rng.Random; import game.world.BlockPos; import game.world.State; @@ -220,12 +220,12 @@ public class BlockCrops extends BlockBush implements IGrowable return new IProperty[] {AGE}; } - public ModelBlock getModel(String name, State state) { - return crop(name + "_" + state.getValue(AGE)); + public Model getModel(ModelProvider provider, String name, State state) { + return crop(provider, name + "_" + state.getValue(AGE)); } - public static ModelBlock crop(String crop) { - return new ModelBlock(crop).noOcclude() + public static Model crop(ModelProvider provider, String crop) { + return provider.getModel(crop).noOcclude() .add(4, -1, 0, 4, 15, 16).noShade() .w().uv(0, 0, 16, 16).noCull() .e().uv(0, 0, 16, 16).noCull() diff --git a/java/src/game/block/BlockDaylightDetector.java b/java/src/game/block/BlockDaylightDetector.java index ca7d156..5ce1ee7 100755 --- a/java/src/game/block/BlockDaylightDetector.java +++ b/java/src/game/block/BlockDaylightDetector.java @@ -2,7 +2,6 @@ package game.block; import java.util.List; -import game.audio.SoundType; import game.entity.npc.EntityNPC; import game.init.Blocks; import game.init.ItemRegistry; @@ -10,10 +9,11 @@ import game.item.CheatTab; import game.item.Item; import game.item.ItemStack; import game.material.Material; +import game.model.Model; +import game.model.ModelProvider; +import game.model.Transforms; import game.properties.IProperty; import game.properties.PropertyInteger; -import game.renderer.blockmodel.ModelBlock; -import game.renderer.blockmodel.Transforms; import game.rng.Random; import game.tileentity.TileEntity; import game.tileentity.TileEntityDaylightDetector; @@ -193,8 +193,8 @@ public class BlockDaylightDetector extends BlockContainer return Transforms.FLAT; } - public ModelBlock getModel(String name, State state) { - return new ModelBlock(this.inverted ? "daylight_detector_inverted_top" : "daylight_detector_top") + public Model getModel(ModelProvider provider, String name, State state) { + return provider.getModel(this.inverted ? "daylight_detector_inverted_top" : "daylight_detector_top") .add(0, 0, 0, 16, 6, 16) .d("daylight_detector_side").uv(0, 0, 16, 16) .u().uv(0, 0, 16, 16).noCull() diff --git a/java/src/game/block/BlockDeadBush.java b/java/src/game/block/BlockDeadBush.java index 1cfc441..0badc17 100755 --- a/java/src/game/block/BlockDeadBush.java +++ b/java/src/game/block/BlockDeadBush.java @@ -7,7 +7,8 @@ import game.item.Item; import game.item.ItemShears; import game.item.ItemStack; import game.material.Material; -import game.renderer.blockmodel.ModelBlock; +import game.model.Model; +import game.model.ModelProvider; import game.rng.Random; import game.tileentity.TileEntity; import game.world.BlockPos; @@ -68,7 +69,7 @@ public class BlockDeadBush extends BlockBush } } - public ModelBlock getModel(String name, State state) { - return new ModelBlock("deadbush").cross(); + public Model getModel(ModelProvider provider, String name, State state) { + return provider.getModel("deadbush").cross(); } } diff --git a/java/src/game/block/BlockDirt.java b/java/src/game/block/BlockDirt.java index f77e481..159bbda 100755 --- a/java/src/game/block/BlockDirt.java +++ b/java/src/game/block/BlockDirt.java @@ -7,11 +7,12 @@ import game.item.CheatTab; import game.item.Item; import game.item.ItemStack; import game.material.Material; +import game.model.Model; +import game.model.ModelProvider; import game.properties.IProperty; -import game.properties.IStringSerializable; import game.properties.PropertyBool; import game.properties.PropertyEnum; -import game.renderer.blockmodel.ModelBlock; +import game.util.Identifyable; import game.world.BlockPos; import game.world.IWorldAccess; import game.world.State; @@ -108,20 +109,20 @@ public class BlockDirt extends Block return blockdirt$dirttype.getMetadata(); } - public ModelBlock getModel(String name, State state) { + public Model getModel(ModelProvider provider, String name, State state) { switch(state.getValue(VARIANT)) { case DIRT: default: - return new ModelBlock("dirt").add().all(); + return provider.getModel("dirt").add().all(); case COARSE_DIRT: - return new ModelBlock("coarse_dirt").add().all(); + return provider.getModel("coarse_dirt").add().all(); case PODZOL: - return state.getValue(SNOWY) ? new ModelBlock("grass_side_snowed").add().nswe().d("dirt").u("grass_top") : - new ModelBlock("dirt_podzol_side").add().nswe().d("dirt").u("dirt_podzol_top"); + return state.getValue(SNOWY) ? provider.getModel("grass_side_snowed").add().nswe().d("dirt").u("grass_top") : + provider.getModel("dirt_podzol_side").add().nswe().d("dirt").u("dirt_podzol_top"); } } - public static enum DirtType implements IStringSerializable + public static enum DirtType implements Identifyable { DIRT(0, "dirt", "Erde"), COARSE_DIRT(1, "coarse_dirt", "Grobe Erde"), diff --git a/java/src/game/block/BlockDispenser.java b/java/src/game/block/BlockDispenser.java index 2cce3ee..f4f6e51 100755 --- a/java/src/game/block/BlockDispenser.java +++ b/java/src/game/block/BlockDispenser.java @@ -15,11 +15,12 @@ import game.item.CheatTab; import game.item.Item; import game.item.ItemStack; import game.material.Material; +import game.model.Model; +import game.model.ModelProvider; import game.model.ModelRotation; import game.properties.IProperty; import game.properties.PropertyBool; import game.properties.PropertyDirection; -import game.renderer.blockmodel.ModelBlock; import game.rng.Random; import game.tileentity.TileEntity; import game.tileentity.TileEntityDispenser; @@ -306,12 +307,12 @@ public class BlockDispenser extends BlockContainer return true; } - public ModelBlock getModel(String name, State state) { + public Model getModel(ModelProvider provider, String name, State state) { if(state.getValue(FACING) == Facing.DOWN || state.getValue(FACING) == Facing.UP) - return new ModelBlock("furnace_top").add().dnswe().u(name + "_front_vertical") + return provider.getModel("furnace_top").add().dnswe().u(name + "_front_vertical") .rotate(state.getValue(FACING) == Facing.DOWN ? ModelRotation.X180_Y0 : ModelRotation.X0_Y0); else - return new ModelBlock(name + "_front_horizontal").add().du("furnace_top").n() + return provider.getModel(name + "_front_horizontal").add().du("furnace_top").n() .s("furnace_side").we("furnace_side").rotate(ModelRotation.getNorthRot(state.getValue(FACING))); } diff --git a/java/src/game/block/BlockDoor.java b/java/src/game/block/BlockDoor.java index 64f33c7..8addee0 100755 --- a/java/src/game/block/BlockDoor.java +++ b/java/src/game/block/BlockDoor.java @@ -3,21 +3,21 @@ package game.block; import java.util.List; import game.collect.Lists; - import game.entity.npc.EntityNPC; import game.init.Blocks; import game.init.Items; import game.item.Item; import game.material.Material; +import game.model.BlockLayer; +import game.model.Model; +import game.model.ModelProvider; import game.model.ModelRotation; import game.properties.IProperty; -import game.properties.IStringSerializable; import game.properties.PropertyBool; import game.properties.PropertyDirection; import game.properties.PropertyEnum; -import game.renderer.BlockLayer; -import game.renderer.blockmodel.ModelBlock; import game.rng.Random; +import game.util.Identifyable; import game.world.BlockPos; import game.world.BoundingBox; import game.world.Facing; @@ -454,12 +454,12 @@ public class BlockDoor extends Block return ModelRotation.getEastRot(Facing.getHorizontal(rot.getHorizontalIndex() + offset), false); } - public ModelBlock getModel(String name, State state) { + public Model getModel(ModelProvider provider, String name, State state) { String bottom = name + "_bottom"; String top = name + "_top"; if(state.getValue(HALF) == EnumDoorHalf.LOWER) { if(state.getValue(HINGE) == EnumHingePosition.LEFT == state.getValue(OPEN)) - return new ModelBlock(bottom).noOcclude() + return provider.getModel(bottom).noOcclude() .add(0, 0, 0, 3, 16, 16) .d().uv(13, 0, 16, 16) .n().uv(3, 0, 0, 16) @@ -468,7 +468,7 @@ public class BlockDoor extends Block .e().uv(0, 0, 16, 16).noCull() .rotate(getRotation(state.getValue(FACING), state.getValue(OPEN) ? 1 : 0)); else - return new ModelBlock(bottom).noOcclude() + return provider.getModel(bottom).noOcclude() .add(0, 0, 0, 3, 16, 16) .d().uv(13, 0, 16, 16) .n().uv(3, 0, 0, 16) @@ -479,7 +479,7 @@ public class BlockDoor extends Block } else { if(state.getValue(HINGE) == EnumHingePosition.LEFT == state.getValue(OPEN)) - return new ModelBlock(top).noOcclude() + return provider.getModel(top).noOcclude() .add(0, 0, 0, 3, 16, 16) .u(bottom).uv(13, 0, 16, 16) .n().uv(3, 0, 0, 16) @@ -488,7 +488,7 @@ public class BlockDoor extends Block .e().uv(0, 0, 16, 16).noCull() .rotate(getRotation(state.getValue(FACING), state.getValue(OPEN) ? 1 : 0)); else - return new ModelBlock(top).noOcclude() + return provider.getModel(top).noOcclude() .add(0, 0, 0, 3, 16, 16) .u(bottom).uv(13, 0, 16, 16) .n().uv(3, 0, 0, 16) @@ -503,7 +503,7 @@ public class BlockDoor extends Block return new IProperty[] {POWERED}; } - public static enum EnumDoorHalf implements IStringSerializable + public static enum EnumDoorHalf implements Identifyable { UPPER, LOWER; @@ -519,7 +519,7 @@ public class BlockDoor extends Block } } - public static enum EnumHingePosition implements IStringSerializable + public static enum EnumHingePosition implements Identifyable { LEFT, RIGHT; diff --git a/java/src/game/block/BlockDoublePlant.java b/java/src/game/block/BlockDoublePlant.java index a54fe1f..ce68511 100755 --- a/java/src/game/block/BlockDoublePlant.java +++ b/java/src/game/block/BlockDoublePlant.java @@ -2,7 +2,6 @@ package game.block; import java.util.List; -import game.audio.SoundType; import game.color.Colorizer; import game.entity.npc.EntityNPC; import game.entity.types.EntityLiving; @@ -15,12 +14,13 @@ import game.item.Item; import game.item.ItemShears; import game.item.ItemStack; import game.material.Material; +import game.model.Model; +import game.model.ModelProvider; import game.properties.IProperty; -import game.properties.IStringSerializable; import game.properties.PropertyEnum; -import game.renderer.blockmodel.ModelBlock; import game.rng.Random; import game.tileentity.TileEntity; +import game.util.Identifyable; import game.world.BlockPos; import game.world.Facing; import game.world.Facing.Axis; @@ -345,9 +345,9 @@ public class BlockDoublePlant extends BlockBush implements IGrowable // return EnumOffsetType.XZ; // } - public ModelBlock getModel(String name, State state) { + public Model getModel(ModelProvider provider, String name, State state) { if(state.getValue(VARIANT) == EnumPlantType.SUNFLOWER && state.getValue(HALF) == EnumBlockHalf.UPPER) - return new ModelBlock("sunflower_front").noOcclude() + return provider.getModel("sunflower_front").noOcclude() .add(0.8f, 0f, 8f, 15.2f, 8f, 8f).noShade().rotate(8, 8, 8, Axis.Y, 45, true).ns("sunflower_top") .uv(0, 8, 16, 16).noCull() .add(8f, 0f, 0.8f, 8f, 8f, 15.2f).noShade().rotate(8, 8, 8, Axis.Y, 45, true).we("sunflower_top") @@ -355,10 +355,10 @@ public class BlockDoublePlant extends BlockBush implements IGrowable .add(9.6f, -1f, 1f, 9.6f, 15f, 15f).noShade().rotate(8, 8, 8, Axis.Z, 22.5f, true).w("sunflower_back") .uv(0, 0, 16, 16).noCull().e().uv(0, 0, 16, 16).noCull(); else if(state.getValue(VARIANT) == EnumPlantType.FERN || state.getValue(VARIANT) == EnumPlantType.GRASS) - return new ModelBlock(state.getValue(VARIANT).getName() + "_" + (state.getValue(HALF) == EnumBlockHalf.UPPER + return provider.getModel(state.getValue(VARIANT).getName() + "_" + (state.getValue(HALF) == EnumBlockHalf.UPPER ? "top" : "bottom")).crossTint(); else - return new ModelBlock(state.getValue(VARIANT).getName() + "_" + (state.getValue(HALF) == EnumBlockHalf.UPPER + return provider.getModel(state.getValue(VARIANT).getName() + "_" + (state.getValue(HALF) == EnumBlockHalf.UPPER ? "top" : "bottom")).cross(); } @@ -366,7 +366,7 @@ public class BlockDoublePlant extends BlockBush implements IGrowable return new IProperty[] {FACING}; } - public static enum EnumBlockHalf implements IStringSerializable + public static enum EnumBlockHalf implements Identifyable { UPPER, LOWER; @@ -382,7 +382,7 @@ public class BlockDoublePlant extends BlockBush implements IGrowable } } - public static enum EnumPlantType implements IStringSerializable + public static enum EnumPlantType implements Identifyable { SUNFLOWER(0, "sunflower", "Sonnenblume"), SYRINGA(1, "syringa", "Flieder"), diff --git a/java/src/game/block/BlockDragonEgg.java b/java/src/game/block/BlockDragonEgg.java index 057e2b6..e343fa7 100755 --- a/java/src/game/block/BlockDragonEgg.java +++ b/java/src/game/block/BlockDragonEgg.java @@ -4,8 +4,9 @@ import game.entity.item.EntityFalling; import game.entity.npc.EntityNPC; import game.init.Config; import game.material.Material; -import game.renderer.blockmodel.ModelBlock; -import game.renderer.particle.ParticleType; +import game.model.Model; +import game.model.ModelProvider; +import game.model.ParticleType; import game.rng.Random; import game.world.BlockPos; import game.world.Facing; @@ -16,7 +17,7 @@ import game.world.WorldServer; public class BlockDragonEgg extends Block { - private static final ModelBlock dragon_egg = new ModelBlock("dragon_egg").noOcclude() + private static final Model dragon_egg = ModelProvider.getModelProvider().getModel("dragon_egg").noOcclude() .add(6, 15, 6, 10, 16, 10) .d().uv(6, 6, 10, 10).noCull() .u().uv(6, 6, 10, 10).noCull() @@ -211,7 +212,7 @@ public class BlockDragonEgg extends Block // return null; // } - public ModelBlock getModel(String name, State state) { + public Model getModel(ModelProvider provider, String name, State state) { return dragon_egg; } } diff --git a/java/src/game/block/BlockDryLeaves.java b/java/src/game/block/BlockDryLeaves.java index 532086e..2cfd685 100755 --- a/java/src/game/block/BlockDryLeaves.java +++ b/java/src/game/block/BlockDryLeaves.java @@ -1,6 +1,5 @@ package game.block; -import game.audio.SoundType; import game.init.Items; import game.item.CheatTab; import game.item.Item; diff --git a/java/src/game/block/BlockEnchantmentTable.java b/java/src/game/block/BlockEnchantmentTable.java index 161c254..1f0bd32 100755 --- a/java/src/game/block/BlockEnchantmentTable.java +++ b/java/src/game/block/BlockEnchantmentTable.java @@ -6,8 +6,9 @@ import game.init.Blocks; import game.item.CheatTab; import game.item.ItemStack; import game.material.Material; -import game.renderer.blockmodel.ModelBlock; -import game.renderer.particle.ParticleType; +import game.model.Model; +import game.model.ModelProvider; +import game.model.ParticleType; import game.rng.Random; import game.tileentity.TileEntity; import game.tileentity.TileEntityEnchantmentTable; @@ -19,7 +20,7 @@ import game.world.WorldClient; public class BlockEnchantmentTable extends BlockContainer { - private static final ModelBlock enchanting_table_base = new ModelBlock("enchanting_table_bottom") + private static final Model enchanting_table_base = ModelProvider.getModelProvider().getModel("enchanting_table_bottom") .add(0, 0, 0, 16, 12, 16) .d().uv(0, 0, 16, 16) .u("enchanting_table_top").uv(0, 0, 16, 16).noCull() @@ -137,7 +138,7 @@ public class BlockEnchantmentTable extends BlockContainer } } - public ModelBlock getModel(String name, State state) { + public Model getModel(ModelProvider provider, String name, State state) { return enchanting_table_base; } } diff --git a/java/src/game/block/BlockFarmland.java b/java/src/game/block/BlockFarmland.java index a3c476c..1885e73 100755 --- a/java/src/game/block/BlockFarmland.java +++ b/java/src/game/block/BlockFarmland.java @@ -7,9 +7,10 @@ import game.init.Config; import game.init.ItemRegistry; import game.item.Item; import game.material.Material; +import game.model.Model; +import game.model.ModelProvider; import game.properties.IProperty; import game.properties.PropertyInteger; -import game.renderer.blockmodel.ModelBlock; import game.rng.Random; import game.world.BlockPos; import game.world.BoundingBox; @@ -175,7 +176,7 @@ public class BlockFarmland extends Block return new IProperty[] {MOISTURE}; } - public ModelBlock getModel(String name, State state) { - return new ModelBlock("dirt").add(0, 0, 0, 16, 15, 16).dnswe().u("farmland_" + state.getValue(MOISTURE)).noCull(); + public Model getModel(ModelProvider provider, String name, State state) { + return provider.getModel("dirt").add(0, 0, 0, 16, 15, 16).dnswe().u("farmland_" + state.getValue(MOISTURE)).noCull(); } } diff --git a/java/src/game/block/BlockFence.java b/java/src/game/block/BlockFence.java index 8b8530a..715bfcc 100755 --- a/java/src/game/block/BlockFence.java +++ b/java/src/game/block/BlockFence.java @@ -3,17 +3,17 @@ package game.block; import java.util.List; import game.collect.Lists; - import game.entity.Entity; import game.entity.npc.EntityNPC; import game.item.CheatTab; import game.item.ItemLead; import game.material.Material; +import game.model.Model; +import game.model.ModelProvider; import game.model.ModelRotation; +import game.model.Transforms; import game.properties.IProperty; import game.properties.PropertyBool; -import game.renderer.blockmodel.ModelBlock; -import game.renderer.blockmodel.Transforms; import game.world.BlockPos; import game.world.BoundingBox; import game.world.Facing; @@ -208,14 +208,14 @@ public class BlockFence extends Block return this.texture; } - public ModelBlock getModel(String name, State state) { + public Model getModel(ModelProvider provider, String name, State state) { boolean n = state.getValue(NORTH); boolean s = state.getValue(SOUTH); boolean w = state.getValue(WEST); boolean e = state.getValue(EAST); int sides = (n ? 1 : 0) + (s ? 1 : 0) + (w ? 1 : 0) + (e ? 1 : 0); if(sides == 0) - return new ModelBlock(this.texture) + return provider.getModel(this.texture) .add(6, 0, 6, 10, 16, 10) .d().uv(6, 6, 10, 10) .u().uv(6, 6, 10, 10) @@ -224,7 +224,7 @@ public class BlockFence extends Block .w().uv(6, 0, 10, 16).noCull() .e().uv(6, 0, 10, 16).noCull(); else if(sides == 4) - return new ModelBlock(this.texture).uvLock() + return provider.getModel(this.texture).uvLock() .add(6, 0, 6, 10, 16, 10) .d().uv(6, 6, 10, 10) .u().uv(6, 6, 10, 10) @@ -261,7 +261,7 @@ public class BlockFence extends Block .w().uv(7, 7, 9, 10) .e().uv(7, 7, 9, 10); else if(sides == 1) - return new ModelBlock(this.texture).uvLock() + return provider.getModel(this.texture).uvLock() .add(6, 0, 6, 10, 16, 10) .d().uv(6, 6, 10, 10) .u().uv(6, 6, 10, 10) @@ -283,7 +283,7 @@ public class BlockFence extends Block .e().uv(0, 7, 9, 10).noCull() .rotate(n ? ModelRotation.X0_Y0 : (s ? ModelRotation.X0_Y180 : (w ? ModelRotation.X0_Y270 : ModelRotation.X0_Y90))); else if(sides == 2 && ((e != w) || (n != s))) - return new ModelBlock(this.texture).uvLock() + return provider.getModel(this.texture).uvLock() .add(6, 0, 6, 10, 16, 10) .d().uv(6, 6, 10, 10) .u().uv(6, 6, 10, 10) @@ -318,7 +318,7 @@ public class BlockFence extends Block .rotate(n && e ? ModelRotation.X0_Y0 : (s && w ? ModelRotation.X0_Y180 : (n && w ? ModelRotation.X0_Y270 : ModelRotation.X0_Y90))); else if(sides == 2) - return new ModelBlock(this.texture).uvLock() + return provider.getModel(this.texture).uvLock() .add(6, 0, 6, 10, 16, 10) .d().uv(6, 6, 10, 10) .u().uv(6, 6, 10, 10) @@ -342,7 +342,7 @@ public class BlockFence extends Block .e().uv(0, 7, 16, 10).noCull() .rotate(n ? ModelRotation.X0_Y0 : ModelRotation.X0_Y90); else - return new ModelBlock(this.texture).uvLock() + return provider.getModel(this.texture).uvLock() .add(6, 0, 6, 10, 16, 10) .d().uv(6, 6, 10, 10) .u().uv(6, 6, 10, 10) diff --git a/java/src/game/block/BlockFenceGate.java b/java/src/game/block/BlockFenceGate.java index ffc78cb..1d5d2a1 100755 --- a/java/src/game/block/BlockFenceGate.java +++ b/java/src/game/block/BlockFenceGate.java @@ -6,11 +6,12 @@ import game.init.Blocks; import game.init.WoodType; import game.item.CheatTab; import game.material.Material; +import game.model.Model; +import game.model.ModelProvider; import game.model.ModelRotation; +import game.model.Transforms; import game.properties.IProperty; import game.properties.PropertyBool; -import game.renderer.blockmodel.ModelBlock; -import game.renderer.blockmodel.Transforms; import game.world.BlockPos; import game.world.BoundingBox; import game.world.Facing; @@ -206,8 +207,8 @@ public class BlockFenceGate extends BlockDirectional return Transforms.GATE; } - public ModelBlock getModel(String name, State state) { - return (state.getValue(IN_WALL) ? (state.getValue(OPEN) ? new ModelBlock(this.texture).noOcclude().uvLock() + public Model getModel(ModelProvider provider, String name, State state) { + return (state.getValue(IN_WALL) ? (state.getValue(OPEN) ? provider.getModel(this.texture).noOcclude().uvLock() .add(0, 2, 7, 2, 13, 9) .d().uv(0, 7, 2, 9).noCull() .u().uv(0, 7, 2, 9).noCull() @@ -255,7 +256,7 @@ public class BlockFenceGate extends BlockDirectional .d().uv(14, 9, 16, 13).noCull() .u().uv(14, 9, 16, 13).noCull() .w().uv(13, 1, 15, 4).noCull() - .e().uv(13, 1, 15, 4).noCull() : new ModelBlock(this.texture).noOcclude().uvLock() + .e().uv(13, 1, 15, 4).noCull() : provider.getModel(this.texture).noOcclude().uvLock() .add(0, 2, 7, 2, 13, 9) .d().uv(0, 7, 2, 9).noCull() .u().uv(0, 7, 2, 9).noCull() @@ -303,7 +304,7 @@ public class BlockFenceGate extends BlockDirectional .d().uv(10, 7, 14, 9).noCull() .u().uv(10, 7, 14, 9).noCull() .n().uv(10, 1, 14, 4).noCull() - .s().uv(10, 1, 14, 4).noCull()) : (state.getValue(OPEN) ? new ModelBlock(this.texture).uvLock() + .s().uv(10, 1, 14, 4).noCull()) : (state.getValue(OPEN) ? provider.getModel(this.texture).uvLock() .add(0, 5, 7, 2, 16, 9) .d().uv(0, 7, 2, 9).noCull() .u().uv(0, 7, 2, 9).noCull() @@ -351,7 +352,7 @@ public class BlockFenceGate extends BlockDirectional .d().uv(14, 9, 16, 13).noCull() .u().uv(14, 9, 16, 13).noCull() .w().uv(13, 1, 15, 4).noCull() - .e().uv(13, 1, 15, 4).noCull() : new ModelBlock(this.texture).uvLock() + .e().uv(13, 1, 15, 4).noCull() : provider.getModel(this.texture).uvLock() .add(0, 5, 7, 2, 16, 9) .d().uv(0, 7, 2, 9).noCull() .u().uv(0, 7, 2, 9).noCull() diff --git a/java/src/game/block/BlockFire.java b/java/src/game/block/BlockFire.java index f517e84..da5f8ed 100755 --- a/java/src/game/block/BlockFire.java +++ b/java/src/game/block/BlockFire.java @@ -2,21 +2,21 @@ package game.block; import java.util.Map; +import client.renderer.ticked.TextureFlamesFX1; +import client.renderer.ticked.TextureFlamesFX2; import game.collect.Maps; - import game.init.Blocks; import game.init.Config; import game.init.SoundEvent; import game.material.Material; +import game.model.BlockLayer; +import game.model.Model; +import game.model.ModelProvider; import game.model.ModelRotation; +import game.model.ParticleType; import game.properties.IProperty; import game.properties.PropertyBool; import game.properties.PropertyInteger; -import game.renderer.BlockLayer; -import game.renderer.blockmodel.ModelBlock; -import game.renderer.particle.ParticleType; -import game.renderer.ticked.TextureFlamesFX1; -import game.renderer.ticked.TextureFlamesFX2; import game.rng.Random; import game.world.BlockPos; import game.world.BoundingBox; @@ -478,8 +478,8 @@ public class BlockFire extends Block return new IProperty[] {AGE, NORTH, EAST, SOUTH, WEST, UPPER, FLIP, ALT}; } - private static ModelBlock fire_nsu2_flip(String fire) { - return new ModelBlock(fire).noOcclude() + private static Model fire_nsu2_flip(String fire) { + return ModelProvider.getModelProvider().getModel(fire).noOcclude() .add(0, 1, 0.01f, 16, 23.4f, 0.01f).noShade() .s().uv(16, 0, 0, 16).noCull() .add(0, 1, 0.01f, 16, 23.4f, 0.01f).noShade() @@ -493,8 +493,8 @@ public class BlockFire extends Block .add(0, 16, 0, 16, 16, 16).noShade().rotate(8, 16, 0, Facing.Axis.X, 22.5f, true) .d().uv(0, 0, 16, 16).noCull(); } - private static ModelBlock fire_nu1(String fire) { - return new ModelBlock(fire).noOcclude() + private static Model fire_nu1(String fire) { + return ModelProvider.getModelProvider().getModel(fire).noOcclude() .add(0, 1, 0.01f, 16, 23.4f, 0.01f).noShade() .s().uv(0, 0, 16, 16).noCull() .add(0, 1, 0.01f, 16, 23.4f, 0.01f).noShade() @@ -504,8 +504,8 @@ public class BlockFire extends Block .add(0, 16, 0, 16, 16, 16).noShade().rotate(0, 16, 8, Facing.Axis.Z, -22.5f, true) .d().uv(0, 0, 16, 16).rot(90).noCull(); } - private static ModelBlock fire_nseu2_flip(String fire) { - return new ModelBlock(fire).noOcclude() + private static Model fire_nseu2_flip(String fire) { + return ModelProvider.getModelProvider().getModel(fire).noOcclude() .add(0, 1, 0.01f, 16, 23.4f, 0.01f).noShade() .s().uv(16, 0, 0, 16).noCull() .add(0, 1, 0.01f, 16, 23.4f, 0.01f).noShade() @@ -523,8 +523,8 @@ public class BlockFire extends Block .add(0, 16, 0, 16, 16, 16).noShade().rotate(8, 16, 0, Facing.Axis.X, 22.5f, true) .d().uv(0, 0, 16, 16).noCull(); } - private static ModelBlock fire_neu1_flip(String fire) { - return new ModelBlock(fire).noOcclude() + private static Model fire_neu1_flip(String fire) { + return ModelProvider.getModelProvider().getModel(fire).noOcclude() .add(0, 1, 0.01f, 16, 23.4f, 0.01f).noShade() .s().uv(16, 0, 0, 16).noCull() .add(0, 1, 0.01f, 16, 23.4f, 0.01f).noShade() @@ -538,8 +538,8 @@ public class BlockFire extends Block .add(0, 16, 0, 16, 16, 16).noShade().rotate(0, 16, 8, Facing.Axis.Z, -22.5f, true) .d().uv(0, 0, 16, 16).rot(90).noCull(); } - private static ModelBlock fire_nsu2(String fire) { - return new ModelBlock(fire).noOcclude() + private static Model fire_nsu2(String fire) { + return ModelProvider.getModelProvider().getModel(fire).noOcclude() .add(0, 1, 0.01f, 16, 23.4f, 0.01f).noShade() .s().uv(0, 0, 16, 16).noCull() .add(0, 1, 0.01f, 16, 23.4f, 0.01f).noShade() @@ -553,8 +553,8 @@ public class BlockFire extends Block .add(0, 16, 0, 16, 16, 16).noShade().rotate(8, 16, 0, Facing.Axis.X, 22.5f, true) .d().uv(0, 0, 16, 16).noCull(); } - private static ModelBlock fire_nu2_flip(String fire) { - return new ModelBlock(fire).noOcclude() + private static Model fire_nu2_flip(String fire) { + return ModelProvider.getModelProvider().getModel(fire).noOcclude() .add(0, 1, 0.01f, 16, 23.4f, 0.01f).noShade() .s().uv(16, 0, 0, 16).noCull() .add(0, 1, 0.01f, 16, 23.4f, 0.01f).noShade() @@ -564,8 +564,8 @@ public class BlockFire extends Block .add(0, 16, 0, 16, 16, 16).noShade().rotate(8, 16, 0, Facing.Axis.X, 22.5f, true) .d().uv(0, 0, 16, 16).noCull(); } - private static ModelBlock fire_neu2_flip(String fire) { - return new ModelBlock(fire).noOcclude() + private static Model fire_neu2_flip(String fire) { + return ModelProvider.getModelProvider().getModel(fire).noOcclude() .add(0, 1, 0.01f, 16, 23.4f, 0.01f).noShade() .s().uv(16, 0, 0, 16).noCull() .add(0, 1, 0.01f, 16, 23.4f, 0.01f).noShade() @@ -579,8 +579,8 @@ public class BlockFire extends Block .add(0, 16, 0, 16, 16, 16).noShade().rotate(8, 16, 0, Facing.Axis.X, 22.5f, true) .d().uv(0, 0, 16, 16).noCull(); } - private static ModelBlock fire_nsewu2_flip(String fire) { - return new ModelBlock(fire).noOcclude() + private static Model fire_nsewu2_flip(String fire) { + return ModelProvider.getModelProvider().getModel(fire).noOcclude() .add(0, 1, 0.01f, 16, 23.4f, 0.01f).noShade() .s().uv(16, 0, 0, 16).noCull() .add(0, 1, 0.01f, 16, 23.4f, 0.01f).noShade() @@ -602,8 +602,8 @@ public class BlockFire extends Block .add(0, 16, 0, 16, 16, 16).noShade().rotate(8, 16, 0, Facing.Axis.X, 22.5f, true) .d().uv(0, 0, 16, 16).noCull(); } - private static ModelBlock fire_nsewu2(String fire) { - return new ModelBlock(fire).noOcclude() + private static Model fire_nsewu2(String fire) { + return ModelProvider.getModelProvider().getModel(fire).noOcclude() .add(0, 1, 0.01f, 16, 23.4f, 0.01f).noShade() .s().uv(0, 0, 16, 16).noCull() .add(0, 1, 0.01f, 16, 23.4f, 0.01f).noShade() @@ -625,8 +625,8 @@ public class BlockFire extends Block .add(0, 16, 0, 16, 16, 16).noShade().rotate(8, 16, 0, Facing.Axis.X, 22.5f, true) .d().uv(0, 0, 16, 16).noCull(); } - private static ModelBlock fire_nsew(String fire) { - return new ModelBlock(fire).noOcclude() + private static Model fire_nsew(String fire) { + return ModelProvider.getModelProvider().getModel(fire).noOcclude() .add(0, 1, 0.01f, 16, 23.4f, 0.01f).noShade() .s().uv(0, 0, 16, 16).noCull() .add(0, 1, 0.01f, 16, 23.4f, 0.01f).noShade() @@ -644,8 +644,8 @@ public class BlockFire extends Block .add(15.99f, 1, 0, 0.01f, 23.4f, 16).noShade() .w().uv(0, 0, 16, 16).noCull(); } - private static ModelBlock fire_floor(String fire) { - return new ModelBlock(fire).noOcclude() + private static Model fire_floor(String fire) { + return ModelProvider.getModelProvider().getModel(fire).noOcclude() .add(0, 0, 8.8f, 16, 22.4f, 8.8f).noShade().rotate(8, 8, 8, Facing.Axis.X, -22.5f, true) .s().uv(0, 0, 16, 16).noCull() .add(0, 0, 7.2f, 16, 22.4f, 7.2f).noShade().rotate(8, 8, 8, Facing.Axis.X, 22.5f, true) @@ -663,22 +663,22 @@ public class BlockFire extends Block .add(15.99f, 0, 0, 15.99f, 22.4f, 16).noShade() .e().uv(0, 0, 16, 16).noCull(); } - private static ModelBlock fire_u1(String fire) { - return new ModelBlock(fire).noOcclude() + private static Model fire_u1(String fire) { + return ModelProvider.getModelProvider().getModel(fire).noOcclude() .add(0, 16, 0, 16, 16, 16).noShade().rotate(16, 16, 8, Facing.Axis.Z, 22.5f, true) .d().uv(0, 0, 16, 16).rot(270).noCull() .add(0, 16, 0, 16, 16, 16).noShade().rotate(0, 16, 8, Facing.Axis.Z, -22.5f, true) .d().uv(0, 0, 16, 16).rot(90).noCull(); } - private static ModelBlock fire_n_flip(String fire) { - return new ModelBlock(fire).noOcclude() + private static Model fire_n_flip(String fire) { + return ModelProvider.getModelProvider().getModel(fire).noOcclude() .add(0, 1, 0.01f, 16, 23.4f, 0.01f).noShade() .s().uv(16, 0, 0, 16).noCull() .add(0, 1, 0.01f, 16, 23.4f, 0.01f).noShade() .n().uv(16, 0, 0, 16).noCull(); } - private static ModelBlock fire_ne(String fire) { - return new ModelBlock(fire).noOcclude() + private static Model fire_ne(String fire) { + return ModelProvider.getModelProvider().getModel(fire).noOcclude() .add(0, 1, 0.01f, 16, 23.4f, 0.01f).noShade() .s().uv(0, 0, 16, 16).noCull() .add(0, 1, 0.01f, 16, 23.4f, 0.01f).noShade() @@ -688,8 +688,8 @@ public class BlockFire extends Block .add(15.99f, 1, 0, 15.99f, 23.4f, 16).noShade() .w().uv(0, 0, 16, 16).noCull(); } - private static ModelBlock fire_nsew_flip(String fire) { - return new ModelBlock(fire).noOcclude() + private static Model fire_nsew_flip(String fire) { + return ModelProvider.getModelProvider().getModel(fire).noOcclude() .add(0, 1, 0.01f, 16, 23.4f, 0.01f).noShade() .s().uv(16, 0, 0, 16).noCull() .add(0, 1, 0.01f, 16, 23.4f, 0.01f).noShade() @@ -707,8 +707,8 @@ public class BlockFire extends Block .add(15.99f, 1, 0, 0.01f, 23.4f, 16).noShade() .w().uv(16, 0, 0, 16).noCull(); } - private static ModelBlock fire_nse(String fire) { - return new ModelBlock(fire).noOcclude() + private static Model fire_nse(String fire) { + return ModelProvider.getModelProvider().getModel(fire).noOcclude() .add(0, 1, 0.01f, 16, 23.4f, 0.01f).noShade() .s().uv(0, 0, 16, 16).noCull() .add(0, 1, 0.01f, 16, 23.4f, 0.01f).noShade() @@ -722,8 +722,8 @@ public class BlockFire extends Block .add(15.99f, 1, 0, 15.99f, 23.4f, 16).noShade() .w().uv(0, 0, 16, 16).noCull(); } - private static ModelBlock fire_nse_flip(String fire) { - return new ModelBlock(fire).noOcclude() + private static Model fire_nse_flip(String fire) { + return ModelProvider.getModelProvider().getModel(fire).noOcclude() .add(0, 1, 0.01f, 16, 23.4f, 0.01f).noShade() .s().uv(16, 0, 0, 16).noCull() .add(0, 1, 0.01f, 16, 23.4f, 0.01f).noShade() @@ -737,8 +737,8 @@ public class BlockFire extends Block .add(15.99f, 1, 0, 15.99f, 23.4f, 16).noShade() .w().uv(16, 0, 0, 16).noCull(); } - private static ModelBlock fire_nsu1_flip(String fire) { - return new ModelBlock(fire).noOcclude() + private static Model fire_nsu1_flip(String fire) { + return ModelProvider.getModelProvider().getModel(fire).noOcclude() .add(0, 1, 0.01f, 16, 23.4f, 0.01f).noShade() .s().uv(16, 0, 0, 16).noCull() .add(0, 1, 0.01f, 16, 23.4f, 0.01f).noShade() @@ -752,15 +752,15 @@ public class BlockFire extends Block .add(0, 16, 0, 16, 16, 16).noShade().rotate(0, 16, 8, Facing.Axis.Z, -22.5f, true) .d().uv(0, 0, 16, 16).rot(90).noCull(); } - private static ModelBlock fire_n(String fire) { - return new ModelBlock(fire).noOcclude() + private static Model fire_n(String fire) { + return ModelProvider.getModelProvider().getModel(fire).noOcclude() .add(0, 1, 0.01f, 16, 23.4f, 0.01f).noShade() .s().uv(0, 0, 16, 16).noCull() .add(0, 1, 0.01f, 16, 23.4f, 0.01f).noShade() .n().uv(0, 0, 16, 16).noCull(); } - private static ModelBlock fire_ns(String fire) { - return new ModelBlock(fire).noOcclude() + private static Model fire_ns(String fire) { + return ModelProvider.getModelProvider().getModel(fire).noOcclude() .add(0, 1, 0.01f, 16, 23.4f, 0.01f).noShade() .s().uv(0, 0, 16, 16).noCull() .add(0, 1, 0.01f, 16, 23.4f, 0.01f).noShade() @@ -770,8 +770,8 @@ public class BlockFire extends Block .add(0, 1, 15.99f, 16, 23.4f, 15.99f).noShade() .n().uv(0, 0, 16, 16).noCull(); } - private static ModelBlock fire_neu1(String fire) { - return new ModelBlock(fire).noOcclude() + private static Model fire_neu1(String fire) { + return ModelProvider.getModelProvider().getModel(fire).noOcclude() .add(0, 1, 0.01f, 16, 23.4f, 0.01f).noShade() .s().uv(0, 0, 16, 16).noCull() .add(0, 1, 0.01f, 16, 23.4f, 0.01f).noShade() @@ -785,15 +785,15 @@ public class BlockFire extends Block .add(0, 16, 0, 16, 16, 16).noShade().rotate(0, 16, 8, Facing.Axis.Z, -22.5f, true) .d().uv(0, 0, 16, 16).rot(90).noCull(); } - private static ModelBlock fire_u2(String fire) { - return new ModelBlock(fire).noOcclude() + private static Model fire_u2(String fire) { + return ModelProvider.getModelProvider().getModel(fire).noOcclude() .add(0, 16, 0, 16, 16, 16).noShade().rotate(8, 16, 16, Facing.Axis.X, -22.5f, true) .d().uv(0, 0, 16, 16).rot(180).noCull() .add(0, 16, 0, 16, 16, 16).noShade().rotate(8, 16, 0, Facing.Axis.X, 22.5f, true) .d().uv(0, 0, 16, 16).noCull(); } - private static ModelBlock fire_nseu2(String fire) { - return new ModelBlock(fire).noOcclude() + private static Model fire_nseu2(String fire) { + return ModelProvider.getModelProvider().getModel(fire).noOcclude() .add(0, 1, 0.01f, 16, 23.4f, 0.01f).noShade() .s().uv(0, 0, 16, 16).noCull() .add(0, 1, 0.01f, 16, 23.4f, 0.01f).noShade() @@ -811,8 +811,8 @@ public class BlockFire extends Block .add(0, 16, 0, 16, 16, 16).noShade().rotate(8, 16, 0, Facing.Axis.X, 22.5f, true) .d().uv(0, 0, 16, 16).noCull(); } - private static ModelBlock fire_neu2(String fire) { - return new ModelBlock(fire).noOcclude() + private static Model fire_neu2(String fire) { + return ModelProvider.getModelProvider().getModel(fire).noOcclude() .add(0, 1, 0.01f, 16, 23.4f, 0.01f).noShade() .s().uv(0, 0, 16, 16).noCull() .add(0, 1, 0.01f, 16, 23.4f, 0.01f).noShade() @@ -826,8 +826,8 @@ public class BlockFire extends Block .add(0, 16, 0, 16, 16, 16).noShade().rotate(8, 16, 0, Facing.Axis.X, 22.5f, true) .d().uv(0, 0, 16, 16).noCull(); } - private static ModelBlock fire_nu2(String fire) { - return new ModelBlock(fire).noOcclude() + private static Model fire_nu2(String fire) { + return ModelProvider.getModelProvider().getModel(fire).noOcclude() .add(0, 1, 0.01f, 16, 23.4f, 0.01f).noShade() .s().uv(0, 0, 16, 16).noCull() .add(0, 1, 0.01f, 16, 23.4f, 0.01f).noShade() @@ -837,8 +837,8 @@ public class BlockFire extends Block .add(0, 16, 0, 16, 16, 16).noShade().rotate(8, 16, 0, Facing.Axis.X, 22.5f, true) .d().uv(0, 0, 16, 16).noCull(); } - private static ModelBlock fire_nseu1(String fire) { - return new ModelBlock(fire).noOcclude() + private static Model fire_nseu1(String fire) { + return ModelProvider.getModelProvider().getModel(fire).noOcclude() .add(0, 1, 0.01f, 16, 23.4f, 0.01f).noShade() .s().uv(0, 0, 16, 16).noCull() .add(0, 1, 0.01f, 16, 23.4f, 0.01f).noShade() @@ -856,8 +856,8 @@ public class BlockFire extends Block .add(0, 16, 0, 16, 16, 16).noShade().rotate(0, 16, 8, Facing.Axis.Z, -22.5f, true) .d().uv(0, 0, 16, 16).rot(90).noCull(); } - private static ModelBlock fire_ns_flip(String fire) { - return new ModelBlock(fire).noOcclude() + private static Model fire_ns_flip(String fire) { + return ModelProvider.getModelProvider().getModel(fire).noOcclude() .add(0, 1, 0.01f, 16, 23.4f, 0.01f).noShade() .s().uv(16, 0, 0, 16).noCull() .add(0, 1, 0.01f, 16, 23.4f, 0.01f).noShade() @@ -867,8 +867,8 @@ public class BlockFire extends Block .add(0, 1, 15.99f, 16, 23.4f, 15.99f).noShade() .n().uv(16, 0, 0, 16).noCull(); } - private static ModelBlock fire_nsewu1(String fire) { - return new ModelBlock(fire).noOcclude() + private static Model fire_nsewu1(String fire) { + return ModelProvider.getModelProvider().getModel(fire).noOcclude() .add(0, 1, 0.01f, 16, 23.4f, 0.01f).noShade() .s().uv(0, 0, 16, 16).noCull() .add(0, 1, 0.01f, 16, 23.4f, 0.01f).noShade() @@ -890,8 +890,8 @@ public class BlockFire extends Block .add(0, 16, 0, 16, 16, 16).noShade().rotate(0, 16, 8, Facing.Axis.Z, -22.5f, true) .d().uv(0, 0, 16, 16).rot(90).noCull(); } - private static ModelBlock fire_nsu1(String fire) { - return new ModelBlock(fire).noOcclude() + private static Model fire_nsu1(String fire) { + return ModelProvider.getModelProvider().getModel(fire).noOcclude() .add(0, 1, 0.01f, 16, 23.4f, 0.01f).noShade() .s().uv(0, 0, 16, 16).noCull() .add(0, 1, 0.01f, 16, 23.4f, 0.01f).noShade() @@ -905,8 +905,8 @@ public class BlockFire extends Block .add(0, 16, 0, 16, 16, 16).noShade().rotate(0, 16, 8, Facing.Axis.Z, -22.5f, true) .d().uv(0, 0, 16, 16).rot(90).noCull(); } - private static ModelBlock fire_nsewu1_flip(String fire) { - return new ModelBlock(fire).noOcclude() + private static Model fire_nsewu1_flip(String fire) { + return ModelProvider.getModelProvider().getModel(fire).noOcclude() .add(0, 1, 0.01f, 16, 23.4f, 0.01f).noShade() .s().uv(16, 0, 0, 16).noCull() .add(0, 1, 0.01f, 16, 23.4f, 0.01f).noShade() @@ -928,8 +928,8 @@ public class BlockFire extends Block .add(0, 16, 0, 16, 16, 16).noShade().rotate(0, 16, 8, Facing.Axis.Z, -22.5f, true) .d().uv(0, 0, 16, 16).rot(90).noCull(); } - private static ModelBlock fire_ne_flip(String fire) { - return new ModelBlock(fire).noOcclude() + private static Model fire_ne_flip(String fire) { + return ModelProvider.getModelProvider().getModel(fire).noOcclude() .add(0, 1, 0.01f, 16, 23.4f, 0.01f).noShade() .s().uv(16, 0, 0, 16).noCull() .add(0, 1, 0.01f, 16, 23.4f, 0.01f).noShade() @@ -939,8 +939,8 @@ public class BlockFire extends Block .add(15.99f, 1, 0, 15.99f, 23.4f, 16).noShade() .w().uv(16, 0, 0, 16).noCull(); } - private static ModelBlock fire_nseu1_flip(String fire) { - return new ModelBlock(fire).noOcclude() + private static Model fire_nseu1_flip(String fire) { + return ModelProvider.getModelProvider().getModel(fire).noOcclude() .add(0, 1, 0.01f, 16, 23.4f, 0.01f).noShade() .s().uv(16, 0, 0, 16).noCull() .add(0, 1, 0.01f, 16, 23.4f, 0.01f).noShade() @@ -958,7 +958,7 @@ public class BlockFire extends Block .add(0, 16, 0, 16, 16, 16).noShade().rotate(0, 16, 8, Facing.Axis.Z, -22.5f, true) .d().uv(0, 0, 16, 16).rot(90).noCull(); } - private static ModelBlock getFireModel(boolean alt, boolean flip, int upper, boolean n, boolean s, boolean w, boolean e) { + private static Model getFireModel(boolean alt, boolean flip, int upper, boolean n, boolean s, boolean w, boolean e) { String tex = alt ? "fire_layer_1" : "fire_layer_0"; if(!e && !flip && !n && !s && upper == 0 && !w) return fire_floor(tex); @@ -1156,7 +1156,7 @@ public class BlockFire extends Block return fire_floor(tex); } - public ModelBlock getModel(String name, State state) { + public Model getModel(ModelProvider provider, String name, State state) { return getFireModel(state.getValue(ALT), state.getValue(FLIP), state.getValue(UPPER), state.getValue(NORTH), state.getValue(SOUTH), state.getValue(WEST), state.getValue(EAST)); } diff --git a/java/src/game/block/BlockFloorPortal.java b/java/src/game/block/BlockFloorPortal.java index 4eb4c3f..acc7dfb 100755 --- a/java/src/game/block/BlockFloorPortal.java +++ b/java/src/game/block/BlockFloorPortal.java @@ -5,12 +5,12 @@ import java.util.Map; import java.util.Set; import game.collect.Sets; - import game.entity.Entity; import game.item.Item; import game.material.Material; -import game.renderer.blockmodel.ModelBlock; -import game.renderer.particle.ParticleType; +import game.model.Model; +import game.model.ModelProvider; +import game.model.ParticleType; import game.rng.Random; import game.world.BlockPos; import game.world.BoundingBox; @@ -22,7 +22,7 @@ import game.world.WorldClient; public class BlockFloorPortal extends Block { - private static final ModelBlock floor_portal = new ModelBlock("floor_portal") + private static final Model floor_portal = ModelProvider.getModelProvider().getModel("floor_portal") .add(0, 11, 0, 16, 12, 16).du().uv(0, 0, 16, 16).noCull().nswe().uv(0, 0, 16, 1); public BlockFloorPortal(Material materialIn) @@ -146,7 +146,7 @@ public class BlockFloorPortal extends Block return true; } - public ModelBlock getModel(String name, State state) { + public Model getModel(ModelProvider provider, String name, State state) { return floor_portal; } diff --git a/java/src/game/block/BlockFlower.java b/java/src/game/block/BlockFlower.java index 7479965..fff920c 100755 --- a/java/src/game/block/BlockFlower.java +++ b/java/src/game/block/BlockFlower.java @@ -2,21 +2,21 @@ package game.block; import java.util.Collection; import java.util.List; - import java.util.function.Predicate; + import game.collect.Filter; import game.collect.Lists; - import game.init.Blocks; import game.init.Config; import game.item.CheatTab; import game.item.Item; import game.item.ItemStack; +import game.model.Model; +import game.model.ModelProvider; import game.properties.IProperty; -import game.properties.IStringSerializable; import game.properties.PropertyEnum; -import game.renderer.blockmodel.ModelBlock; import game.rng.Random; +import game.util.Identifyable; import game.world.BlockPos; import game.world.State; import game.world.WorldServer; @@ -119,11 +119,11 @@ public abstract class BlockFlower extends BlockBush } } - public ModelBlock getModel(String name, State state) { - return new ModelBlock(state.getValue(this.type).getName()).cross(); + public Model getModel(ModelProvider provider, String name, State state) { + return provider.getModel(state.getValue(this.type).getName()).cross(); } - public static enum EnumFlowerType implements IStringSerializable + public static enum EnumFlowerType implements Identifyable { DANDELION(BlockFlower.EnumFlowerColor.BASE, 0, "dandelion", "Löwenzahn"), ROSE(BlockFlower.EnumFlowerColor.BASE, 1, "rose", "Rose"), diff --git a/java/src/game/block/BlockFlowerPot.java b/java/src/game/block/BlockFlowerPot.java index 46dfb09..852df5b 100755 --- a/java/src/game/block/BlockFlowerPot.java +++ b/java/src/game/block/BlockFlowerPot.java @@ -8,10 +8,11 @@ import game.item.Item; import game.item.ItemBlock; import game.item.ItemStack; import game.material.Material; +import game.model.BlockLayer; +import game.model.Model; +import game.model.ModelProvider; import game.properties.IProperty; import game.properties.PropertyInteger; -import game.renderer.BlockLayer; -import game.renderer.blockmodel.ModelBlock; import game.rng.Random; import game.world.BlockPos; import game.world.Facing; @@ -21,7 +22,7 @@ import game.world.WorldServer; public class BlockFlowerPot extends Block // Container { - private static final ModelBlock flower_pot_cactus = new ModelBlock("flower_pot").noOcclude() + private static final Model flower_pot_cactus = ModelProvider.getModelProvider().getModel("flower_pot").noOcclude() .add(5, 0, 5, 6, 6, 11) .d().uv(5, 5, 6, 11) .u().uv(5, 5, 6, 11).noCull() @@ -66,7 +67,7 @@ public class BlockFlowerPot extends Block // Container .w("cactus_side").uv(6, 0, 10, 4).noCull() .e("cactus_side").uv(6, 0, 10, 4).noCull() ; - private static final ModelBlock flower_pot = new ModelBlock("flower_pot").noOcclude() + private static final Model flower_pot = ModelProvider.getModelProvider().getModel("flower_pot").noOcclude() .add(5, 0, 5, 6, 6, 11) .d().uv(5, 5, 6, 11) .u().uv(5, 5, 6, 11).noCull() @@ -344,7 +345,7 @@ public class BlockFlowerPot extends Block // Container return BlockLayer.CUTOUT; } - public ModelBlock getModel(String name, State state) { + public Model getModel(ModelProvider provider, String name, State state) { switch(state.getValue(CONTENTS)) { case 0: return flower_pot; @@ -354,7 +355,7 @@ public class BlockFlowerPot extends Block // Container // return flower_pot_fern; default: String plant = BlockFlower.EnumFlowerType.getType(BlockFlower.EnumFlowerColor.BASE, state.getValue(CONTENTS) - 2).getName().toLowerCase(); - return new ModelBlock("flower_pot").noOcclude() + return provider.getModel("flower_pot").noOcclude() .add(5, 0, 5, 6, 6, 11) .d().uv(5, 5, 6, 11) .u().uv(5, 5, 6, 11).noCull() diff --git a/java/src/game/block/BlockFurnace.java b/java/src/game/block/BlockFurnace.java index 5dfdb9b..1e89482 100755 --- a/java/src/game/block/BlockFurnace.java +++ b/java/src/game/block/BlockFurnace.java @@ -9,11 +9,12 @@ import game.inventory.InventoryHelper; import game.item.Item; import game.item.ItemStack; import game.material.Material; +import game.model.Model; +import game.model.ModelProvider; import game.model.ModelRotation; +import game.model.ParticleType; import game.properties.IProperty; import game.properties.PropertyDirection; -import game.renderer.blockmodel.ModelBlock; -import game.renderer.particle.ParticleType; import game.rng.Random; import game.tileentity.TileEntity; import game.tileentity.TileEntityFurnace; @@ -273,8 +274,8 @@ public class BlockFurnace extends BlockContainer return new IProperty[] {FACING}; } - public ModelBlock getModel(String name, State state) { - return new ModelBlock("furnace_side").add().du("furnace_top").n("furnace_front_" + (this.isBurning ? "on" : "off")) + public Model getModel(ModelProvider provider, String name, State state) { + return provider.getModel("furnace_side").add().du("furnace_top").n("furnace_front_" + (this.isBurning ? "on" : "off")) .s().we().rotate(ModelRotation.getNorthRot(state.getValue(FACING))); } } diff --git a/java/src/game/block/BlockGlass.java b/java/src/game/block/BlockGlass.java index 2d0a22a..4445d66 100755 --- a/java/src/game/block/BlockGlass.java +++ b/java/src/game/block/BlockGlass.java @@ -2,7 +2,7 @@ package game.block; import game.item.CheatTab; import game.material.Material; -import game.renderer.BlockLayer; +import game.model.BlockLayer; import game.rng.Random; public class BlockGlass extends BlockBreakable diff --git a/java/src/game/block/BlockGrass.java b/java/src/game/block/BlockGrass.java index f360442..39cd89c 100755 --- a/java/src/game/block/BlockGrass.java +++ b/java/src/game/block/BlockGrass.java @@ -6,10 +6,11 @@ import game.init.Config; import game.item.CheatTab; import game.item.Item; import game.material.Material; +import game.model.BlockLayer; +import game.model.Model; +import game.model.ModelProvider; import game.properties.IProperty; import game.properties.PropertyBool; -import game.renderer.BlockLayer; -import game.renderer.blockmodel.ModelBlock; import game.rng.Random; import game.world.BlockPos; import game.world.IWorldAccess; @@ -180,11 +181,11 @@ public class BlockGrass extends Block implements IGrowable return new IProperty[] {SNOWY}; } - public ModelBlock getModel(String name, State state) { + public Model getModel(ModelProvider provider, String name, State state) { if(state.getValue(SNOWY)) - return new ModelBlock("grass_side_snowed").add().nswe().d("dirt").u("grass_top"); + return provider.getModel("grass_side_snowed").add().nswe().d("dirt").u("grass_top"); else - return new ModelBlock("dirt").add().d().u("grass_top").tint().nswe("grass_side") + return provider.getModel("dirt").add().d().u("grass_top").tint().nswe("grass_side") .add().nswe("grass_side_overlay").tint(); } } diff --git a/java/src/game/block/BlockHopper.java b/java/src/game/block/BlockHopper.java index 6b3c0f7..6d4fd33 100755 --- a/java/src/game/block/BlockHopper.java +++ b/java/src/game/block/BlockHopper.java @@ -1,7 +1,6 @@ package game.block; import java.util.List; - import java.util.function.Predicate; import game.entity.Entity; @@ -12,12 +11,13 @@ import game.inventory.InventoryHelper; import game.item.CheatTab; import game.item.ItemStack; import game.material.Material; +import game.model.BlockLayer; +import game.model.Model; +import game.model.ModelProvider; import game.model.ModelRotation; import game.properties.IProperty; import game.properties.PropertyBool; import game.properties.PropertyDirection; -import game.renderer.BlockLayer; -import game.renderer.blockmodel.ModelBlock; import game.tileentity.TileEntity; import game.tileentity.TileEntityHopper; import game.world.BlockPos; @@ -30,7 +30,7 @@ import game.world.WorldServer; public class BlockHopper extends BlockContainer { - private static final ModelBlock hopper_down = new ModelBlock("hopper_outside").noOcclude() + private static final Model hopper_down = ModelProvider.getModelProvider().getModel("hopper_outside").noOcclude() .add(0, 10, 0, 16, 11, 16) .d().uv(0, 0, 16, 16).noCull() .u("hopper_inside").uv(0, 0, 16, 16).noCull() @@ -309,8 +309,8 @@ public class BlockHopper extends BlockContainer return true; } - public ModelBlock getModel(String name, State state) { - return state.getValue(FACING) == Facing.DOWN ? hopper_down : new ModelBlock("hopper_outside").noOcclude() + public Model getModel(ModelProvider provider, String name, State state) { + return state.getValue(FACING) == Facing.DOWN ? hopper_down : provider.getModel("hopper_outside").noOcclude() .add(0, 10, 0, 16, 11, 16) .d().uv(0, 0, 16, 16).noCull() .u("hopper_inside").uv(0, 0, 16, 16).noCull() diff --git a/java/src/game/block/BlockHugeMushroom.java b/java/src/game/block/BlockHugeMushroom.java index 6926cf6..ba36f71 100755 --- a/java/src/game/block/BlockHugeMushroom.java +++ b/java/src/game/block/BlockHugeMushroom.java @@ -4,11 +4,12 @@ import game.entity.types.EntityLiving; import game.init.ItemRegistry; import game.item.Item; import game.material.Material; +import game.model.Model; +import game.model.ModelProvider; import game.properties.IProperty; -import game.properties.IStringSerializable; import game.properties.PropertyEnum; -import game.renderer.blockmodel.ModelBlock; import game.rng.Random; +import game.util.Identifyable; import game.world.BlockPos; import game.world.Facing; import game.world.State; @@ -98,48 +99,48 @@ public class BlockHugeMushroom extends Block return new IProperty[] {VARIANT}; } - public ModelBlock getModel(String name, State state) { + public Model getModel(ModelProvider provider, String name, State state) { switch(state.getValue(VARIANT)) { case ALL_INSIDE: - return new ModelBlock(name + "_inside").add().all(); + return provider.getModel(name + "_inside").add().all(); case ALL_OUTSIDE: default: - return new ModelBlock(name + "_cap").add().all(); + return provider.getModel(name + "_cap").add().all(); case ALL_STEM: - return new ModelBlock(name + "_stem").add().all(); + return provider.getModel(name + "_stem").add().all(); case STEM: - return new ModelBlock(name + "_stem").add().nswe().du(name + "_inside"); + return provider.getModel(name + "_stem").add().nswe().du(name + "_inside"); case CENTER: - return new ModelBlock(name + "_inside").add().d(name + "_inside").u(name + "_cap").n(name + "_inside").s(name + "_inside") + return provider.getModel(name + "_inside").add().d(name + "_inside").u(name + "_cap").n(name + "_inside").s(name + "_inside") .w(name + "_inside").e(name + "_inside"); case EAST: - return new ModelBlock(name + "_inside").add().d(name + "_inside").u(name + "_cap").n(name + "_inside").s(name + "_inside") + return provider.getModel(name + "_inside").add().d(name + "_inside").u(name + "_cap").n(name + "_inside").s(name + "_inside") .w(name + "_inside").e(name + "_cap"); case NORTH_EAST: - return new ModelBlock(name + "_inside").add().d(name + "_inside").u(name + "_cap").n(name + "_cap").s(name + "_inside") + return provider.getModel(name + "_inside").add().d(name + "_inside").u(name + "_cap").n(name + "_cap").s(name + "_inside") .w(name + "_inside").e(name + "_cap"); case NORTH: - return new ModelBlock(name + "_inside").add().d(name + "_inside").u(name + "_cap").n(name + "_cap").s(name + "_inside") + return provider.getModel(name + "_inside").add().d(name + "_inside").u(name + "_cap").n(name + "_cap").s(name + "_inside") .w(name + "_inside").e(name + "_inside"); case NORTH_WEST: - return new ModelBlock(name + "_inside").add().d(name + "_inside").u(name + "_cap").n(name + "_cap").s(name + "_inside") + return provider.getModel(name + "_inside").add().d(name + "_inside").u(name + "_cap").n(name + "_cap").s(name + "_inside") .w(name + "_cap").e(name + "_inside"); case SOUTH_EAST: - return new ModelBlock(name + "_inside").add().d(name + "_inside").u(name + "_cap").n(name + "_inside").s(name + "_cap") + return provider.getModel(name + "_inside").add().d(name + "_inside").u(name + "_cap").n(name + "_inside").s(name + "_cap") .w(name + "_inside").e(name + "_cap"); case SOUTH: - return new ModelBlock(name + "_inside").add().d(name + "_inside").u(name + "_cap").n(name + "_inside").s(name + "_cap") + return provider.getModel(name + "_inside").add().d(name + "_inside").u(name + "_cap").n(name + "_inside").s(name + "_cap") .w(name + "_inside").e(name + "_inside"); case SOUTH_WEST: - return new ModelBlock(name + "_inside").add().d(name + "_inside").u(name + "_cap").n(name + "_inside").s(name + "_cap") + return provider.getModel(name + "_inside").add().d(name + "_inside").u(name + "_cap").n(name + "_inside").s(name + "_cap") .w(name + "_cap").e(name + "_inside"); case WEST: - return new ModelBlock(name + "_inside").add().d(name + "_inside").u(name + "_cap").n(name + "_inside").s(name + "_inside") + return provider.getModel(name + "_inside").add().d(name + "_inside").u(name + "_cap").n(name + "_inside").s(name + "_inside") .w(name + "_cap").e(name + "_inside"); } } - public static enum EnumType implements IStringSerializable + public static enum EnumType implements Identifyable { NORTH_WEST(1, "north_west"), NORTH(2, "north"), diff --git a/java/src/game/block/BlockIce.java b/java/src/game/block/BlockIce.java index 805124d..565104a 100755 --- a/java/src/game/block/BlockIce.java +++ b/java/src/game/block/BlockIce.java @@ -7,7 +7,7 @@ import game.init.Config; import game.item.CheatTab; import game.item.ItemStack; import game.material.Material; -import game.renderer.BlockLayer; +import game.model.BlockLayer; import game.rng.Random; import game.tileentity.TileEntity; import game.world.BlockPos; diff --git a/java/src/game/block/BlockJukebox.java b/java/src/game/block/BlockJukebox.java index ae45af8..839ae8e 100755 --- a/java/src/game/block/BlockJukebox.java +++ b/java/src/game/block/BlockJukebox.java @@ -4,7 +4,8 @@ import game.entity.npc.EntityNPC; import game.init.SoundEvent; import game.item.CheatTab; import game.material.Material; -import game.renderer.blockmodel.ModelBlock; +import game.model.Model; +import game.model.ModelProvider; import game.world.BlockPos; import game.world.Facing; import game.world.State; @@ -22,7 +23,7 @@ public class BlockJukebox extends Block { return true; } - public ModelBlock getModel(String name, State state) { - return new ModelBlock("jukebox_side").add().dnswe().u("jukebox_top"); + public Model getModel(ModelProvider provider, String name, State state) { + return provider.getModel("jukebox_side").add().dnswe().u("jukebox_top"); } } diff --git a/java/src/game/block/BlockLadder.java b/java/src/game/block/BlockLadder.java index b29c387..3c8df92 100755 --- a/java/src/game/block/BlockLadder.java +++ b/java/src/game/block/BlockLadder.java @@ -3,11 +3,12 @@ package game.block; import game.entity.types.EntityLiving; import game.item.CheatTab; import game.material.Material; +import game.model.BlockLayer; +import game.model.Model; +import game.model.ModelProvider; import game.model.ModelRotation; import game.properties.IProperty; import game.properties.PropertyDirection; -import game.renderer.BlockLayer; -import game.renderer.blockmodel.ModelBlock; import game.world.BlockPos; import game.world.BoundingBox; import game.world.Facing; @@ -163,8 +164,8 @@ public class BlockLadder extends Block return new IProperty[] {FACING}; } - public ModelBlock getModel(String name, State state) { - return new ModelBlock("ladder").noOcclude() + public Model getModel(ModelProvider provider, String name, State state) { + return provider.getModel("ladder").noOcclude() .add(0, 0, 15.2f, 16, 16, 15.2f).noShade() .n().uv(0, 0, 16, 16).noCull() .s().uv(0, 0, 16, 16).noCull() diff --git a/java/src/game/block/BlockLeaves.java b/java/src/game/block/BlockLeaves.java index 96a20bf..d37c901 100755 --- a/java/src/game/block/BlockLeaves.java +++ b/java/src/game/block/BlockLeaves.java @@ -3,8 +3,6 @@ package game.block; import java.util.List; import game.collect.Lists; - -import game.audio.SoundType; import game.color.Colorizer; import game.entity.npc.EntityNPC; import game.init.Blocks; @@ -16,11 +14,12 @@ import game.item.Item; import game.item.ItemShears; import game.item.ItemStack; import game.material.Material; +import game.model.Model; +import game.model.ModelProvider; +import game.model.ParticleType; import game.properties.IProperty; import game.properties.PropertyBool; import game.properties.PropertyEnum; -import game.renderer.blockmodel.ModelBlock; -import game.renderer.particle.ParticleType; import game.rng.Random; import game.tileentity.TileEntity; import game.world.BlockPos; @@ -349,9 +348,9 @@ public class BlockLeaves extends BlockLeavesBase } } - public ModelBlock getModel(String name, State state) { - return state.getValue(TYPE).isTinted() ? new ModelBlock(name + "_" + state.getValue(TYPE).getName()).add().all().tint() : - new ModelBlock(name + "_" + state.getValue(TYPE).getName()).add().all(); + public Model getModel(ModelProvider provider, String name, State state) { + return state.getValue(TYPE).isTinted() ? provider.getModel(name + "_" + state.getValue(TYPE).getName()).add().all().tint() : + provider.getModel(name + "_" + state.getValue(TYPE).getName()).add().all(); } public IProperty[] getIgnoredProperties() { diff --git a/java/src/game/block/BlockLeavesBase.java b/java/src/game/block/BlockLeavesBase.java index 6dfe938..e9b871d 100755 --- a/java/src/game/block/BlockLeavesBase.java +++ b/java/src/game/block/BlockLeavesBase.java @@ -1,7 +1,7 @@ package game.block; import game.material.Material; -import game.renderer.BlockLayer; +import game.model.BlockLayer; public class BlockLeavesBase extends Block { diff --git a/java/src/game/block/BlockLever.java b/java/src/game/block/BlockLever.java index 369457c..0592a0d 100755 --- a/java/src/game/block/BlockLever.java +++ b/java/src/game/block/BlockLever.java @@ -5,12 +5,13 @@ import game.entity.types.EntityLiving; import game.init.SoundEvent; import game.item.CheatTab; import game.material.Material; +import game.model.Model; +import game.model.ModelProvider; import game.model.ModelRotation; import game.properties.IProperty; -import game.properties.IStringSerializable; import game.properties.PropertyBool; import game.properties.PropertyEnum; -import game.renderer.blockmodel.ModelBlock; +import game.util.Identifyable; import game.world.BlockPos; import game.world.BoundingBox; import game.world.Facing; @@ -295,8 +296,8 @@ public class BlockLever extends Block } } - public ModelBlock getModel(String name, State state) { - return new ModelBlock("cobblestone").noOcclude() + public Model getModel(ModelProvider provider, String name, State state) { + return provider.getModel("cobblestone").noOcclude() .add(5, 0, 4, 11, 3, 12) .d().uv(5, 4, 11, 12).noCull() .u().uv(5, 4, 11, 12).noCull() @@ -314,7 +315,7 @@ public class BlockLever extends Block .rotate(getRotation(state.getValue(FACING))); } - public static enum EnumOrientation implements IStringSerializable + public static enum EnumOrientation implements Identifyable { DOWN_X(0, "down_x", Facing.DOWN), EAST(1, "east", Facing.EAST), diff --git a/java/src/game/block/BlockLilyPad.java b/java/src/game/block/BlockLilyPad.java index d7d04d9..1e67c54 100755 --- a/java/src/game/block/BlockLilyPad.java +++ b/java/src/game/block/BlockLilyPad.java @@ -7,9 +7,10 @@ import game.entity.item.EntityBoat; import game.entity.types.EntityLiving; import game.init.Blocks; import game.item.CheatTab; +import game.model.Model; +import game.model.ModelProvider; import game.model.ModelRotation; import game.properties.IProperty; -import game.renderer.blockmodel.ModelBlock; import game.world.BlockPos; import game.world.BoundingBox; import game.world.Facing; @@ -100,8 +101,8 @@ public class BlockLilyPad extends BlockBush return this.getState().withProperty(BlockDirectional.FACING, placer.getHorizontalFacing().getOpposite()); } - public ModelBlock getModel(String name, State state) { - return new ModelBlock("waterlily").noOcclude() + public Model getModel(ModelProvider provider, String name, State state) { + return provider.getModel("waterlily").noOcclude() .add(0, 0.25f, 0, 16, 0.25f, 16) .d().uv(16, 16, 0, 0).tint().noCull() .u().uv(16, 0, 0, 16).tint().noCull() diff --git a/java/src/game/block/BlockLiquid.java b/java/src/game/block/BlockLiquid.java index 6a2b1e7..940ffd7 100755 --- a/java/src/game/block/BlockLiquid.java +++ b/java/src/game/block/BlockLiquid.java @@ -8,10 +8,10 @@ import game.init.FluidRegistry; import game.init.SoundEvent; import game.item.Item; import game.material.Material; +import game.model.BlockLayer; +import game.model.ParticleType; import game.properties.IProperty; import game.properties.PropertyInteger; -import game.renderer.BlockLayer; -import game.renderer.particle.ParticleType; import game.rng.Random; import game.util.ExtMath; import game.world.BlockPos; diff --git a/java/src/game/block/BlockLog.java b/java/src/game/block/BlockLog.java index 8a1ee73..c3de107 100755 --- a/java/src/game/block/BlockLog.java +++ b/java/src/game/block/BlockLog.java @@ -1,14 +1,14 @@ package game.block; -import game.audio.SoundType; import game.entity.types.EntityLiving; import game.item.CheatTab; import game.material.Material; +import game.model.Model; +import game.model.ModelProvider; import game.model.ModelRotation; import game.properties.IProperty; -import game.properties.IStringSerializable; import game.properties.PropertyEnum; -import game.renderer.blockmodel.ModelBlock; +import game.util.Identifyable; import game.world.BlockPos; import game.world.Facing; import game.world.State; @@ -56,21 +56,21 @@ public class BlockLog extends BlockRotatedPillar return super.onBlockPlaced(worldIn, pos, facing, hitX, hitY, hitZ, meta, placer).withProperty(LOG_AXIS, BlockLog.EnumAxis.fromFacingAxis(facing.getAxis())); } - public ModelBlock getModel(String name, State state) { + public Model getModel(ModelProvider provider, String name, State state) { switch(state.getValue(LOG_AXIS)) { case X: - return new ModelBlock(name + "_bark").add().d().rot(180).u() + return provider.getModel(name + "_bark").add().d().rot(180).u() .n(name + "_top").rot(180).s(name + "_top").w().rot(270) .e().rot(90).rotate(ModelRotation.X0_Y90); case Y: default: - return new ModelBlock(name + "_bark").add().nswe().du(name + "_top"); + return provider.getModel(name + "_bark").add().nswe().du(name + "_top"); case Z: - return new ModelBlock(name + "_bark").add().d().rot(180).u() + return provider.getModel(name + "_bark").add().d().rot(180).u() .n(name + "_top").rot(180).s(name + "_top").w().rot(270) .e().rot(90); case NONE: - return new ModelBlock(name + "_bark").add().all(); + return provider.getModel(name + "_bark").add().all(); } } @@ -131,7 +131,7 @@ public class BlockLog extends BlockRotatedPillar return new IProperty[] {LOG_AXIS}; } - public static enum EnumAxis implements IStringSerializable + public static enum EnumAxis implements Identifyable { X("x", Facing.Axis.X), Y("y", Facing.Axis.Y), diff --git a/java/src/game/block/BlockMelon.java b/java/src/game/block/BlockMelon.java index 1095cba..6ce8e2d 100755 --- a/java/src/game/block/BlockMelon.java +++ b/java/src/game/block/BlockMelon.java @@ -4,7 +4,8 @@ import game.init.Items; import game.item.CheatTab; import game.item.Item; import game.material.Material; -import game.renderer.blockmodel.ModelBlock; +import game.model.Model; +import game.model.ModelProvider; import game.rng.Random; import game.world.State; @@ -40,7 +41,7 @@ public class BlockMelon extends Block return Math.min(9, this.quantityDropped(random) + random.zrange(1 + fortune)); } - public ModelBlock getModel(String name, State state) { - return new ModelBlock("melon_side").add().nswe().du("melon_top"); + public Model getModel(ModelProvider provider, String name, State state) { + return provider.getModel("melon_side").add().nswe().du("melon_top"); } } diff --git a/java/src/game/block/BlockMobSpawner.java b/java/src/game/block/BlockMobSpawner.java index 6559c80..3e79503 100755 --- a/java/src/game/block/BlockMobSpawner.java +++ b/java/src/game/block/BlockMobSpawner.java @@ -3,7 +3,7 @@ package game.block; import game.item.CheatTab; import game.item.Item; import game.material.Material; -import game.renderer.BlockLayer; +import game.model.BlockLayer; import game.rng.Random; import game.tileentity.TileEntity; import game.tileentity.TileEntityMobSpawner; diff --git a/java/src/game/block/BlockMushroom.java b/java/src/game/block/BlockMushroom.java index ab19610..9fb2154 100755 --- a/java/src/game/block/BlockMushroom.java +++ b/java/src/game/block/BlockMushroom.java @@ -2,7 +2,8 @@ package game.block; import game.init.Blocks; import game.init.Config; -import game.renderer.blockmodel.ModelBlock; +import game.model.Model; +import game.model.ModelProvider; import game.rng.Random; import game.world.BlockPos; import game.world.State; @@ -128,7 +129,7 @@ public class BlockMushroom extends BlockBush implements IGrowable this.generateBigMushroom(worldIn, pos, state, rand); } - public ModelBlock getModel(String name, State state) { - return new ModelBlock(name).cross(); + public Model getModel(ModelProvider provider, String name, State state) { + return provider.getModel(name).cross(); } } diff --git a/java/src/game/block/BlockMycelium.java b/java/src/game/block/BlockMycelium.java index 9ee62fb..d014d87 100755 --- a/java/src/game/block/BlockMycelium.java +++ b/java/src/game/block/BlockMycelium.java @@ -5,10 +5,11 @@ import game.init.Config; import game.item.CheatTab; import game.item.Item; import game.material.Material; +import game.model.Model; +import game.model.ModelProvider; +import game.model.ParticleType; import game.properties.IProperty; import game.properties.PropertyBool; -import game.renderer.blockmodel.ModelBlock; -import game.renderer.particle.ParticleType; import game.rng.Random; import game.world.BlockPos; import game.world.IWorldAccess; @@ -98,10 +99,10 @@ public class BlockMycelium extends Block return new IProperty[] {SNOWY}; } - public ModelBlock getModel(String name, State state) { + public Model getModel(ModelProvider provider, String name, State state) { if(state.getValue(SNOWY)) - return new ModelBlock("grass_side_snowed").add().nswe().d("dirt").u("grass_top"); + return provider.getModel("grass_side_snowed").add().nswe().d("dirt").u("grass_top"); else - return new ModelBlock("mycelium_side").add().nswe().d("dirt").u("mycelium_top"); + return provider.getModel("mycelium_side").add().nswe().d("dirt").u("mycelium_top"); } } diff --git a/java/src/game/block/BlockNote.java b/java/src/game/block/BlockNote.java index 5e01ddb..1413107 100755 --- a/java/src/game/block/BlockNote.java +++ b/java/src/game/block/BlockNote.java @@ -4,7 +4,7 @@ import game.entity.npc.EntityNPC; import game.init.SoundEvent; import game.item.CheatTab; import game.material.Material; -import game.renderer.particle.ParticleType; +import game.model.ParticleType; import game.tileentity.TileEntity; import game.tileentity.TileEntityNote; import game.world.BlockPos; diff --git a/java/src/game/block/BlockNuke.java b/java/src/game/block/BlockNuke.java index ce5e470..f666ba6 100755 --- a/java/src/game/block/BlockNuke.java +++ b/java/src/game/block/BlockNuke.java @@ -5,7 +5,8 @@ import game.init.Blocks; import game.init.SoundEvent; import game.item.CheatTab; import game.material.Material; -import game.renderer.blockmodel.ModelBlock; +import game.model.Model; +import game.model.ModelProvider; import game.world.BlockPos; import game.world.Explosion; import game.world.State; @@ -68,7 +69,7 @@ public class BlockNuke extends Block return true; } - public ModelBlock getModel(String name, State state) { - return new ModelBlock("nuke_side").add().nswe().d("nuke_bottom").u("nuke_top"); + public Model getModel(ModelProvider provider, String name, State state) { + return provider.getModel("nuke_side").add().nswe().d("nuke_bottom").u("nuke_top"); } } diff --git a/java/src/game/block/BlockPane.java b/java/src/game/block/BlockPane.java index d911c82..7b01c70 100755 --- a/java/src/game/block/BlockPane.java +++ b/java/src/game/block/BlockPane.java @@ -7,11 +7,12 @@ import game.init.Blocks; import game.item.CheatTab; import game.item.Item; import game.material.Material; +import game.model.BlockLayer; +import game.model.Model; +import game.model.ModelProvider; import game.model.ModelRotation; import game.properties.IProperty; import game.properties.PropertyBool; -import game.renderer.BlockLayer; -import game.renderer.blockmodel.ModelBlock; import game.rng.Random; import game.world.BlockPos; import game.world.BoundingBox; @@ -216,7 +217,7 @@ public class BlockPane extends Block return "glass_pane"; } - public ModelBlock getModel(String name, State state) { + public Model getModel(ModelProvider provider, String name, State state) { boolean n = state.getValue(NORTH); boolean s = state.getValue(SOUTH); boolean w = state.getValue(WEST); @@ -224,7 +225,7 @@ public class BlockPane extends Block int sides = (n ? 1 : 0) + (s ? 1 : 0) + (w ? 1 : 0) + (e ? 1 : 0); if(this.canDrop) { if(sides == 0 || sides == 4) - return new ModelBlock(name).noOcclude() + return provider.getModel(name).noOcclude() .add(8, 0, 0, 8, 16, 16) .w().uv(0, 0, 16, 16).noCull() .e().uv(0, 0, 16, 16).noCull() @@ -247,7 +248,7 @@ public class BlockPane extends Block .d().uv(9, 0, 7, 7).rot(90).noCull() .u().uv(7, 0, 9, 7).rot(90).noCull(); else if(sides == 1) - return new ModelBlock(name).noOcclude() + return provider.getModel(name).noOcclude() .add(8, 0, 0, 8, 16, 8) .w().uv(8, 0, 16, 16).noCull() .e().uv(8, 0, 16, 16).noCull() @@ -259,7 +260,7 @@ public class BlockPane extends Block .u().uv(7, 0, 9, 9).noCull() .rotate(n ? ModelRotation.X0_Y0 : (s ? ModelRotation.X0_Y180 : (w ? ModelRotation.X0_Y270 : ModelRotation.X0_Y90))); else if(sides == 2 && ((e != w) || (n != s))) - return new ModelBlock(name).noOcclude() + return provider.getModel(name).noOcclude() .add(8, 0, 0, 8, 16, 8) .w().uv(0, 0, 8, 16).noCull() .e().uv(8, 0, 16, 16).noCull() @@ -279,7 +280,7 @@ public class BlockPane extends Block .rotate(n && e ? ModelRotation.X0_Y0 : (s && w ? ModelRotation.X0_Y180 : (n && w ? ModelRotation.X0_Y270 : ModelRotation.X0_Y90))); else if(sides == 2) - return new ModelBlock(name).noOcclude() + return provider.getModel(name).noOcclude() .add(8, 0, 0, 8, 16, 16) .w().uv(0, 0, 16, 16).noCull() .e().uv(0, 0, 16, 16).noCull() @@ -291,7 +292,7 @@ public class BlockPane extends Block .u().uv(9, 0, 7, 16).noCull() .rotate(n ? ModelRotation.X0_Y0 : ModelRotation.X0_Y90); else - return new ModelBlock(name).noOcclude() + return provider.getModel(name).noOcclude() .add(8, 0, 0, 8, 16, 16) .w().uv(0, 0, 16, 16).noCull() .e().uv(0, 0, 16, 16).noCull() @@ -315,7 +316,7 @@ public class BlockPane extends Block String pane = this.getPaneBase(state); String edge = this.getPaneEdge(state); if(sides == 0 || sides == 4) - return new ModelBlock(pane).noOcclude() + return provider.getModel(pane).noOcclude() .add(7, 0, 0, 9, 16, 16).noShade() .d(edge).uv(7, 0, 9, 16).noCull() .u(edge).uv(7, 0, 9, 16).noCull() @@ -331,7 +332,7 @@ public class BlockPane extends Block .w(edge).uv(7, 0, 9, 16) .e(edge).uv(7, 0, 9, 16); else if(sides == 1 && (n || e)) - return new ModelBlock(pane).noOcclude() + return provider.getModel(pane).noOcclude() .add(7, 0, 0, 9, 16, 9).noShade() .d(edge).uv(7, 0, 9, 9).noCull() .u(edge).uv(7, 0, 9, 9).noCull() @@ -341,7 +342,7 @@ public class BlockPane extends Block .e().uv(7, 0, 16, 16).noCull() .rotate(n ? ModelRotation.X0_Y0 : ModelRotation.X0_Y90); else if(sides == 1) - return new ModelBlock(pane).noOcclude() + return provider.getModel(pane).noOcclude() .add(7, 0, 7, 9, 16, 16).noShade() .d(edge).uv(7, 7, 9, 16).noCull() .u(edge).uv(7, 7, 9, 16).noCull() @@ -351,7 +352,7 @@ public class BlockPane extends Block .e().uv(0, 0, 9, 16).noCull() .rotate(s ? ModelRotation.X0_Y0 : ModelRotation.X0_Y90); else if(e && n && !s && !w) - return new ModelBlock(pane).noOcclude() + return provider.getModel(pane).noOcclude() .add(7, 0, 0, 9, 16, 9).noShade() .d(edge).uv(7, 0, 9, 9).noCull() .u(edge).uv(7, 0, 9, 9).noCull() @@ -367,7 +368,7 @@ public class BlockPane extends Block .w().uv(7, 0, 9, 16).noCull() .e(edge).uv(7, 0, 9, 16); else if(e && !n && s && !w) - return new ModelBlock(pane).noOcclude() + return provider.getModel(pane).noOcclude() .add(7, 0, 7, 9, 16, 16).noShade() .d(edge).uv(7, 7, 9, 16).noCull() .u(edge).uv(7, 7, 9, 16).noCull() @@ -383,7 +384,7 @@ public class BlockPane extends Block .w().uv(7, 0, 9, 16).noCull() .e(edge).uv(7, 0, 9, 16); else if(!e && !n && s && w) - return new ModelBlock(pane).noOcclude() + return provider.getModel(pane).noOcclude() .add(7, 0, 7, 9, 16, 16).noShade() .d(edge).uv(7, 7, 9, 16).noCull() .u(edge).uv(7, 7, 9, 16).noCull() @@ -399,7 +400,7 @@ public class BlockPane extends Block .w(edge).uv(7, 0, 9, 16) .e().uv(7, 0, 9, 16).noCull(); else if(!e && n && !s && w) - return new ModelBlock(pane).noOcclude() + return provider.getModel(pane).noOcclude() .add(7, 0, 0, 9, 16, 9).noShade() .d(edge).uv(7, 0, 9, 9).noCull() .u(edge).uv(7, 0, 9, 9).noCull() @@ -415,7 +416,7 @@ public class BlockPane extends Block .w(edge).uv(7, 0, 9, 16) .e().uv(7, 0, 9, 16).noCull(); else if((!e && n && s && !w) || (e && !n && !s && w)) - return new ModelBlock(pane).noOcclude() + return provider.getModel(pane).noOcclude() .add(7, 0, 0, 9, 16, 16).noShade() .d(edge).uv(7, 0, 9, 16).noCull() .u(edge).uv(7, 0, 9, 16).noCull() @@ -425,7 +426,7 @@ public class BlockPane extends Block .e().uv(0, 0, 16, 16).noCull() .rotate(s ? ModelRotation.X0_Y0 : ModelRotation.X0_Y90); else if(!w) - return new ModelBlock(pane).noOcclude() + return provider.getModel(pane).noOcclude() .add(7, 0, 0, 9, 16, 16).noShade() .d(edge).uv(7, 0, 9, 16).noCull() .u(edge).uv(7, 0, 9, 16).noCull() @@ -441,7 +442,7 @@ public class BlockPane extends Block .w(edge).uv(7, 0, 9, 16).noCull() .e(edge).uv(7, 0, 9, 16); else if(!n) - return new ModelBlock(pane).noOcclude() + return provider.getModel(pane).noOcclude() .add(7, 0, 9, 9, 16, 16).noShade() .d(edge).uv(7, 9, 9, 16).noCull() .u(edge).uv(7, 9, 9, 16).noCull() @@ -457,7 +458,7 @@ public class BlockPane extends Block .w(edge).uv(7, 0, 9, 16) .e(edge).uv(7, 0, 9, 16); else if(!e) - return new ModelBlock(pane).noOcclude() + return provider.getModel(pane).noOcclude() .add(7, 0, 0, 9, 16, 16).noShade() .d(edge).uv(7, 0, 9, 16).noCull() .u(edge).uv(7, 0, 9, 16).noCull() @@ -473,7 +474,7 @@ public class BlockPane extends Block .w(edge).uv(7, 0, 9, 16).cull(Facing.EAST) .e(edge).uv(7, 0, 9, 16).noCull(); else - return new ModelBlock(pane).noOcclude() + return provider.getModel(pane).noOcclude() .add(7, 0, 0, 9, 16, 7).noShade() .d(edge).uv(7, 0, 9, 7).noCull() .u(edge).uv(7, 0, 9, 7).noCull() diff --git a/java/src/game/block/BlockPistonBase.java b/java/src/game/block/BlockPistonBase.java index 04c6fd6..03a2622 100755 --- a/java/src/game/block/BlockPistonBase.java +++ b/java/src/game/block/BlockPistonBase.java @@ -3,8 +3,6 @@ package game.block; import java.util.List; import game.collect.Lists; - -import game.audio.SoundType; import game.entity.Entity; import game.entity.types.EntityLiving; import game.init.Blocks; @@ -13,11 +11,12 @@ import game.init.SoundEvent; import game.item.CheatTab; import game.item.ItemStack; import game.material.Material; +import game.model.Model; +import game.model.ModelProvider; import game.model.ModelRotation; import game.properties.IProperty; import game.properties.PropertyBool; import game.properties.PropertyDirection; -import game.renderer.blockmodel.ModelBlock; import game.tileentity.TileEntity; import game.tileentity.TileEntityPiston; import game.util.ExtMath; @@ -706,15 +705,15 @@ public class BlockPistonBase extends Block return new IProperty[] {FACING, EXTENDED}; } - public ModelBlock getModel(String name, State state) { - return (state.getValue(EXTENDED) ? new ModelBlock("piston_side") + public Model getModel(ModelProvider provider, String name, State state) { + return (state.getValue(EXTENDED) ? provider.getModel("piston_side") .add(0, 0, 4, 16, 16, 16) .d().uv(0, 4, 16, 16).rot(180) .u().uv(0, 4, 16, 16) .n("piston_inner").uv(0, 0, 16, 16).noCull() .s("piston_bottom").uv(0, 0, 16, 16) .w().uv(0, 4, 16, 16).rot(270) - .e().uv(0, 4, 16, 16).rot(90) : new ModelBlock("piston_side") + .e().uv(0, 4, 16, 16).rot(90) : provider.getModel("piston_side") .add(0, 0, 0, 16, 16, 16) .d().uv(0, 0, 16, 16).rot(180) .u().uv(0, 0, 16, 16) diff --git a/java/src/game/block/BlockPistonHead.java b/java/src/game/block/BlockPistonHead.java index a77af50..911638d 100755 --- a/java/src/game/block/BlockPistonHead.java +++ b/java/src/game/block/BlockPistonHead.java @@ -2,20 +2,20 @@ package game.block; import java.util.List; -import game.audio.SoundType; import game.entity.Entity; import game.init.Blocks; import game.init.ItemRegistry; import game.item.Item; import game.material.Material; +import game.model.Model; +import game.model.ModelProvider; import game.model.ModelRotation; import game.properties.IProperty; -import game.properties.IStringSerializable; import game.properties.PropertyBool; import game.properties.PropertyDirection; import game.properties.PropertyEnum; -import game.renderer.blockmodel.ModelBlock; import game.rng.Random; +import game.util.Identifyable; import game.world.BlockPos; import game.world.BoundingBox; import game.world.Facing; @@ -258,9 +258,9 @@ public class BlockPistonHead extends Block return new IProperty[] {FACING, TYPE, SHORT}; } - public ModelBlock getModel(String name, State state) { + public Model getModel(ModelProvider provider, String name, State state) { String side = "piston_side"; - return (state.getValue(SHORT) ? new ModelBlock(state.getValue(TYPE) == EnumPistonType.STICKY ? "piston_top_sticky" : "piston_top") + return (state.getValue(SHORT) ? provider.getModel(state.getValue(TYPE) == EnumPistonType.STICKY ? "piston_top_sticky" : "piston_top") .add(0, 0, 0, 16, 16, 4) .d(side).uv(0, 0, 16, 4).rot(180) .u(side).uv(0, 0, 16, 4) @@ -273,7 +273,7 @@ public class BlockPistonHead extends Block .u(side).uv(4, 0, 16, 4).rot(270).noCull() .w(side).uv(16, 4, 4, 0).noCull() .e(side).uv(4, 0, 16, 4).noCull() - : new ModelBlock(state.getValue(TYPE) == EnumPistonType.STICKY ? "piston_top_sticky" : "piston_top") + : provider.getModel(state.getValue(TYPE) == EnumPistonType.STICKY ? "piston_top_sticky" : "piston_top") .add(0, 0, 0, 16, 16, 4) .d(side).uv(0, 0, 16, 4).rot(180) .u(side).uv(0, 0, 16, 4) @@ -295,7 +295,7 @@ public class BlockPistonHead extends Block ? state.getValue(FACING).getOpposite() : state.getValue(FACING))); } - public static enum EnumPistonType implements IStringSerializable + public static enum EnumPistonType implements Identifyable { DEFAULT("normal"), STICKY("sticky"); diff --git a/java/src/game/block/BlockPortal.java b/java/src/game/block/BlockPortal.java index e715a8a..33cd0ab 100755 --- a/java/src/game/block/BlockPortal.java +++ b/java/src/game/block/BlockPortal.java @@ -6,12 +6,13 @@ import game.entity.Entity; import game.init.Blocks; import game.item.Item; import game.material.Material; +import game.model.BlockLayer; +import game.model.Model; +import game.model.ModelProvider; +import game.model.ParticleType; import game.properties.IProperty; import game.properties.PropertyEnum; import game.properties.PropertyInteger; -import game.renderer.BlockLayer; -import game.renderer.blockmodel.ModelBlock; -import game.renderer.particle.ParticleType; import game.rng.Random; import game.world.BlockPos; import game.world.BoundingBox; @@ -276,11 +277,11 @@ public class BlockPortal extends BlockBreakable return new IProperty[] {AXIS, DIM}; } - public ModelBlock getModel(String name, State state) { - return state.getValue(AXIS) == Facing.Axis.X ? new ModelBlock(name) + public Model getModel(ModelProvider provider, String name, State state) { + return state.getValue(AXIS) == Facing.Axis.X ? provider.getModel(name) .add(0, 0, 6, 16, 16, 10) .n().uv(0, 0, 16, 16).noCull().tint() - .s().uv(0, 0, 16, 16).noCull().tint() : new ModelBlock(name) + .s().uv(0, 0, 16, 16).noCull().tint() : provider.getModel(name) .add(6, 0, 0, 10, 16, 16) .w().uv(0, 0, 16, 16).noCull().tint() .e().uv(0, 0, 16, 16).noCull().tint(); diff --git a/java/src/game/block/BlockPortalFrame.java b/java/src/game/block/BlockPortalFrame.java index 6ec55a2..aefda08 100755 --- a/java/src/game/block/BlockPortalFrame.java +++ b/java/src/game/block/BlockPortalFrame.java @@ -11,11 +11,12 @@ import game.init.Items; import game.item.Item; import game.item.ItemStack; import game.material.Material; +import game.model.Model; +import game.model.ModelProvider; import game.model.ModelRotation; import game.properties.IProperty; import game.properties.PropertyBool; import game.properties.PropertyDirection; -import game.renderer.blockmodel.ModelBlock; import game.rng.Random; import game.tileentity.TileEntity; import game.world.BlockPos; @@ -151,8 +152,8 @@ public class BlockPortalFrame extends Block return true; } - public ModelBlock getModel(String name, State state) { - return (state.getValue(ORB) ? new ModelBlock("portal_frame_side") + public Model getModel(ModelProvider provider, String name, State state) { + return (state.getValue(ORB) ? provider.getModel("portal_frame_side") .add(0, 0, 0, 16, 13, 16) .d("portal_frame_bottom").uv(0, 0, 16, 16).noCull() .u("portal_frame_top").uv(0, 0, 16, 16).noCull() @@ -166,7 +167,7 @@ public class BlockPortalFrame extends Block .n("portal_frame_orb").uv(4, 0, 12, 3).noCull() .s("portal_frame_orb").uv(4, 0, 12, 3).noCull() .w("portal_frame_orb").uv(4, 0, 12, 3).noCull() - .e("portal_frame_orb").uv(4, 0, 12, 3).noCull() : new ModelBlock("portal_frame_side") + .e("portal_frame_orb").uv(4, 0, 12, 3).noCull() : provider.getModel("portal_frame_side") .add(0, 0, 0, 16, 13, 16) .d("portal_frame_bottom").uv(0, 0, 16, 16).noCull() .u("portal_frame_top").uv(0, 0, 16, 16).noCull() diff --git a/java/src/game/block/BlockPotato.java b/java/src/game/block/BlockPotato.java index 8795566..68d5c30 100755 --- a/java/src/game/block/BlockPotato.java +++ b/java/src/game/block/BlockPotato.java @@ -3,7 +3,8 @@ package game.block; import game.init.Items; import game.item.Item; import game.item.ItemStack; -import game.renderer.blockmodel.ModelBlock; +import game.model.Model; +import game.model.ModelProvider; import game.world.BlockPos; import game.world.State; import game.world.World; @@ -36,8 +37,8 @@ public class BlockPotato extends BlockCrops } } - public ModelBlock getModel(String name, State state) { + public Model getModel(ModelProvider provider, String name, State state) { int age = state.getValue(AGE); - return crop(name + "_" + (age == 6 ? 2 : (age / 2))); + return crop(provider, name + "_" + (age == 6 ? 2 : (age / 2))); } } diff --git a/java/src/game/block/BlockPumpkin.java b/java/src/game/block/BlockPumpkin.java index c955c33..e3a6fa8 100755 --- a/java/src/game/block/BlockPumpkin.java +++ b/java/src/game/block/BlockPumpkin.java @@ -3,9 +3,10 @@ package game.block; import game.entity.types.EntityLiving; import game.item.CheatTab; import game.material.Material; +import game.model.Model; +import game.model.ModelProvider; import game.model.ModelRotation; import game.properties.IProperty; -import game.renderer.blockmodel.ModelBlock; import game.world.BlockPos; import game.world.Facing; import game.world.State; @@ -183,8 +184,8 @@ public class BlockPumpkin extends BlockDirectional // return this.golemPattern; // } - public ModelBlock getModel(String name, State state) { - return new ModelBlock("pumpkin_side").add().du("pumpkin_top").n("pumpkin_face_" + (this.getLightValue() == 0 ? "off" : "on")) + public Model getModel(ModelProvider provider, String name, State state) { + return provider.getModel("pumpkin_side").add().du("pumpkin_top").n("pumpkin_face_" + (this.getLightValue() == 0 ? "off" : "on")) .s().we().rotate(ModelRotation.getNorthRot(state.getValue(FACING))); } } diff --git a/java/src/game/block/BlockQuartz.java b/java/src/game/block/BlockQuartz.java index ce2bc47..dafd6c6 100755 --- a/java/src/game/block/BlockQuartz.java +++ b/java/src/game/block/BlockQuartz.java @@ -8,11 +8,12 @@ import game.item.CheatTab; import game.item.Item; import game.item.ItemStack; import game.material.Material; +import game.model.Model; +import game.model.ModelProvider; import game.model.ModelRotation; import game.properties.IProperty; -import game.properties.IStringSerializable; import game.properties.PropertyEnum; -import game.renderer.blockmodel.ModelBlock; +import game.util.Identifyable; import game.world.BlockPos; import game.world.Facing; import game.world.State; @@ -114,23 +115,23 @@ public class BlockQuartz extends Block return new IProperty[] {VARIANT}; } - public ModelBlock getModel(String name, State state) { + public Model getModel(ModelProvider provider, String name, State state) { switch(state.getValue(VARIANT)) { case DEFAULT: default: - return new ModelBlock(this.prefix + "quartz_block_side").add().nswe().d(this.prefix + "quartz_block_bottom").u(this.prefix + "quartz_top"); + return provider.getModel(this.prefix + "quartz_block_side").add().nswe().d(this.prefix + "quartz_block_bottom").u(this.prefix + "quartz_top"); case CHISELED: - return new ModelBlock(this.prefix + "quartz_block_chiseled").add().nswe().du(this.prefix + "quartz_block_chiseled_top"); + return provider.getModel(this.prefix + "quartz_block_chiseled").add().nswe().du(this.prefix + "quartz_block_chiseled_top"); case LINES_X: - return new ModelBlock(this.prefix + "quartz_block_lines").add().nswe().du(this.prefix + "quartz_block_lines_top").rotate(ModelRotation.X90_Y90); + return provider.getModel(this.prefix + "quartz_block_lines").add().nswe().du(this.prefix + "quartz_block_lines_top").rotate(ModelRotation.X90_Y90); case LINES_Y: - return new ModelBlock(this.prefix + "quartz_block_lines").add().nswe().du(this.prefix + "quartz_block_lines_top"); + return provider.getModel(this.prefix + "quartz_block_lines").add().nswe().du(this.prefix + "quartz_block_lines_top"); case LINES_Z: - return new ModelBlock(this.prefix + "quartz_block_lines").add().nswe().du(this.prefix + "quartz_block_lines_top").rotate(ModelRotation.X90_Y0); + return provider.getModel(this.prefix + "quartz_block_lines").add().nswe().du(this.prefix + "quartz_block_lines_top").rotate(ModelRotation.X90_Y0); } } - public static enum EnumType implements IStringSerializable + public static enum EnumType implements Identifyable { DEFAULT(0, "default", "default", null), CHISELED(1, "chiseled", "chiseled", null), diff --git a/java/src/game/block/BlockRailBase.java b/java/src/game/block/BlockRailBase.java index 44c9cee..a64c897 100755 --- a/java/src/game/block/BlockRailBase.java +++ b/java/src/game/block/BlockRailBase.java @@ -3,15 +3,15 @@ package game.block; import java.util.List; import game.collect.Lists; - import game.init.Blocks; import game.item.CheatTab; import game.material.Material; +import game.model.BlockLayer; +import game.model.Model; +import game.model.ModelProvider; import game.model.ModelRotation; import game.properties.IProperty; -import game.properties.IStringSerializable; -import game.renderer.BlockLayer; -import game.renderer.blockmodel.ModelBlock; +import game.util.Identifyable; import game.world.BlockPos; import game.world.BoundingBox; import game.world.Facing; @@ -188,13 +188,13 @@ public abstract class BlockRailBase extends Block return true; } - public ModelBlock getModel(String name, State state) { + public Model getModel(ModelProvider provider, String name, State state) { EnumRailDirection dir = state.getValue(this.getShapeProperty()); switch(dir) { case NORTH_SOUTH: case EAST_WEST: default: - return new ModelBlock(name).noOcclude() + return provider.getModel(name).noOcclude() .add(0, 1, 0, 16, 1, 16) .d().uv(0, 16, 16, 0).noCull() .u().uv(0, 0, 16, 16).noCull() @@ -203,7 +203,7 @@ public abstract class BlockRailBase extends Block case NORTH_WEST: case SOUTH_EAST: case SOUTH_WEST: - return new ModelBlock(name + "_turned").noOcclude() + return provider.getModel(name + "_turned").noOcclude() .add(0, 1, 0, 16, 1, 16) .d().uv(0, 16, 16, 0).noCull() .u().uv(0, 0, 16, 16).noCull() @@ -211,14 +211,14 @@ public abstract class BlockRailBase extends Block ModelRotation.X0_Y180 : (dir == EnumRailDirection.NORTH_EAST ? ModelRotation.X0_Y270 : ModelRotation.X0_Y0))); case ASCENDING_NORTH: case ASCENDING_EAST: - return new ModelBlock(name).noOcclude() + return provider.getModel(name).noOcclude() .add(0, 9, 0, 16, 9, 16).rotate(8, 9, 8, Facing.Axis.X, 45, true) .d().uv(0, 16, 16, 0).noCull() .u().uv(0, 0, 16, 16).noCull() .rotate(dir == EnumRailDirection.ASCENDING_EAST ? ModelRotation.X0_Y90 : ModelRotation.X0_Y0); case ASCENDING_SOUTH: case ASCENDING_WEST: - return new ModelBlock(name).noOcclude() + return provider.getModel(name).noOcclude() .add(0, 9, 0, 16, 9, 16).rotate(8, 9, 8, Facing.Axis.X, -45, true) .d().uv(0, 16, 16, 0).noCull() .u().uv(0, 0, 16, 16).noCull() @@ -228,7 +228,7 @@ public abstract class BlockRailBase extends Block public abstract IProperty getShapeProperty(); - public static enum EnumRailDirection implements IStringSerializable + public static enum EnumRailDirection implements Identifyable { NORTH_SOUTH(0, "north_south", Facing.SOUTH), EAST_WEST(1, "east_west", Facing.EAST), diff --git a/java/src/game/block/BlockRailDetector.java b/java/src/game/block/BlockRailDetector.java index 976b079..7070c82 100755 --- a/java/src/game/block/BlockRailDetector.java +++ b/java/src/game/block/BlockRailDetector.java @@ -1,17 +1,17 @@ package game.block; import java.util.List; - import java.util.function.Predicate; import game.entity.Entity; import game.entity.item.EntityCart; import game.inventory.Container; import game.inventory.IInventory; +import game.model.Model; +import game.model.ModelProvider; import game.properties.IProperty; import game.properties.PropertyBool; import game.properties.PropertyEnum; -import game.renderer.blockmodel.ModelBlock; import game.rng.Random; import game.world.BlockPos; import game.world.BoundingBox; @@ -212,7 +212,7 @@ public class BlockRailDetector extends BlockRailBase return new IProperty[] {SHAPE, POWERED}; } - public ModelBlock getModel(String name, State state) { - return super.getModel(name + (state.getValue(POWERED) ? "_powered" : ""), state); + public Model getModel(ModelProvider provider, String name, State state) { + return super.getModel(provider, name + (state.getValue(POWERED) ? "_powered" : ""), state); } } diff --git a/java/src/game/block/BlockRailPowered.java b/java/src/game/block/BlockRailPowered.java index 7782ed8..f7b6181 100755 --- a/java/src/game/block/BlockRailPowered.java +++ b/java/src/game/block/BlockRailPowered.java @@ -2,10 +2,11 @@ package game.block; import java.util.function.Predicate; +import game.model.Model; +import game.model.ModelProvider; import game.properties.IProperty; import game.properties.PropertyBool; import game.properties.PropertyEnum; -import game.renderer.blockmodel.ModelBlock; import game.world.BlockPos; import game.world.State; import game.world.World; @@ -198,7 +199,7 @@ public class BlockRailPowered extends BlockRailBase return new IProperty[] {SHAPE, POWERED}; } - public ModelBlock getModel(String name, State state) { - return super.getModel(name + (state.getValue(POWERED) ? "_powered" : ""), state); + public Model getModel(ModelProvider provider, String name, State state) { + return super.getModel(provider, name + (state.getValue(POWERED) ? "_powered" : ""), state); } } diff --git a/java/src/game/block/BlockRedstoneComparator.java b/java/src/game/block/BlockRedstoneComparator.java index 1e79399..5d61b94 100755 --- a/java/src/game/block/BlockRedstoneComparator.java +++ b/java/src/game/block/BlockRedstoneComparator.java @@ -6,15 +6,16 @@ import game.init.Blocks; import game.init.Items; import game.init.SoundEvent; import game.item.Item; +import game.model.Model; +import game.model.ModelProvider; import game.model.ModelRotation; import game.properties.IProperty; -import game.properties.IStringSerializable; import game.properties.PropertyBool; import game.properties.PropertyEnum; -import game.renderer.blockmodel.ModelBlock; import game.rng.Random; import game.tileentity.TileEntity; import game.tileentity.TileEntityComparator; +import game.util.Identifyable; import game.world.BlockPos; import game.world.Facing; import game.world.IWorldAccess; @@ -312,8 +313,8 @@ public class BlockRedstoneComparator extends BlockRedstoneDiode implements ITile return this.getState().withProperty(FACING, placer.getHorizontalFacing().getOpposite()).withProperty(POWERED, Boolean.valueOf(false)).withProperty(MODE, BlockRedstoneComparator.Mode.COMPARE); } - public ModelBlock getModel(String name, State state) { - return (state.getValue(POWERED) ? (state.getValue(MODE) == Mode.SUBTRACT ? new ModelBlock("comparator_on").noOcclude() + public Model getModel(ModelProvider provider, String name, State state) { + return (state.getValue(POWERED) ? (state.getValue(MODE) == Mode.SUBTRACT ? provider.getModel("comparator_on").noOcclude() .add(0, 0, 0, 16, 2, 16) .d("double_stone_top").uv(0, 0, 16, 16) .u().uv(0, 0, 16, 16).noCull() @@ -344,7 +345,7 @@ public class BlockRedstoneComparator extends BlockRedstoneDiode implements ITile .e("redstone_torch").uv(6, 5, 10, 9).noCull() .add(6, 2, 2, 10, 6, 4) .n("redstone_torch").uv(6, 5, 10, 9).noCull() - .s("redstone_torch").uv(6, 5, 10, 9).noCull() : new ModelBlock("comparator_on").noOcclude() + .s("redstone_torch").uv(6, 5, 10, 9).noCull() : provider.getModel("comparator_on").noOcclude() .add(0, 0, 0, 16, 2, 16) .d("double_stone_top").uv(0, 0, 16, 16) .u().uv(0, 0, 16, 16).noCull() @@ -375,7 +376,7 @@ public class BlockRedstoneComparator extends BlockRedstoneDiode implements ITile .s("unlit_redstone_torch").uv(7, 6, 9, 8).noCull() .w("unlit_redstone_torch").uv(7, 6, 9, 8).noCull() .e("unlit_redstone_torch").uv(7, 6, 9, 8).noCull()) - : (state.getValue(MODE) == Mode.SUBTRACT ? new ModelBlock("comparator_off").noOcclude() + : (state.getValue(MODE) == Mode.SUBTRACT ? provider.getModel("comparator_off").noOcclude() .add(0, 0, 0, 16, 2, 16) .d("double_stone_top").uv(0, 0, 16, 16) .u().uv(0, 0, 16, 16).noCull() @@ -404,7 +405,7 @@ public class BlockRedstoneComparator extends BlockRedstoneDiode implements ITile .e("redstone_torch").uv(6, 5, 10, 9).noCull() .add(6, 2, 2, 10, 6, 4) .n("redstone_torch").uv(6, 5, 10, 9).noCull() - .s("redstone_torch").uv(6, 5, 10, 9).noCull() : new ModelBlock("comparator_off").noOcclude() + .s("redstone_torch").uv(6, 5, 10, 9).noCull() : provider.getModel("comparator_off").noOcclude() .add(0, 0, 0, 16, 2, 16) .d("double_stone_top").uv(0, 0, 16, 16) .u().uv(0, 0, 16, 16).noCull() @@ -436,7 +437,7 @@ public class BlockRedstoneComparator extends BlockRedstoneDiode implements ITile .rotate(ModelRotation.getNorthRot(state.getValue(FACING).getOpposite())); } - public static enum Mode implements IStringSerializable + public static enum Mode implements Identifyable { COMPARE("compare"), SUBTRACT("subtract"); diff --git a/java/src/game/block/BlockRedstoneDiode.java b/java/src/game/block/BlockRedstoneDiode.java index 766c5d9..a510f6e 100755 --- a/java/src/game/block/BlockRedstoneDiode.java +++ b/java/src/game/block/BlockRedstoneDiode.java @@ -4,7 +4,7 @@ import game.entity.types.EntityLiving; import game.init.Blocks; import game.item.ItemStack; import game.material.Material; -import game.renderer.BlockLayer; +import game.model.BlockLayer; import game.rng.Random; import game.world.BlockPos; import game.world.Facing; diff --git a/java/src/game/block/BlockRedstoneOre.java b/java/src/game/block/BlockRedstoneOre.java index b590557..f5736f1 100755 --- a/java/src/game/block/BlockRedstoneOre.java +++ b/java/src/game/block/BlockRedstoneOre.java @@ -8,8 +8,9 @@ import game.init.Items; import game.item.Item; import game.item.ItemStack; import game.material.Material; -import game.renderer.blockmodel.ModelBlock; -import game.renderer.particle.ParticleType; +import game.model.Model; +import game.model.ModelProvider; +import game.model.ParticleType; import game.rng.Random; import game.world.BlockPos; import game.world.Facing; @@ -189,7 +190,7 @@ public class BlockRedstoneOre extends Block return true; } - public ModelBlock getModel(String name, State state) { - return new ModelBlock("redstone_ore").add().all(); + public Model getModel(ModelProvider provider, String name, State state) { + return provider.getModel("redstone_ore").add().all(); } } diff --git a/java/src/game/block/BlockRedstoneRepeater.java b/java/src/game/block/BlockRedstoneRepeater.java index 4c1283f..a43adfd 100755 --- a/java/src/game/block/BlockRedstoneRepeater.java +++ b/java/src/game/block/BlockRedstoneRepeater.java @@ -4,12 +4,13 @@ import game.entity.npc.EntityNPC; import game.init.Blocks; import game.init.Items; import game.item.Item; +import game.model.Model; +import game.model.ModelProvider; import game.model.ModelRotation; +import game.model.ParticleType; import game.properties.IProperty; import game.properties.PropertyBool; import game.properties.PropertyInteger; -import game.renderer.blockmodel.ModelBlock; -import game.renderer.particle.ParticleType; import game.rng.Random; import game.world.BlockPos; import game.world.Facing; @@ -156,11 +157,11 @@ public class BlockRedstoneRepeater extends BlockRedstoneDiode return new IProperty[] {FACING, DELAY, LOCKED}; } - private static ModelBlock getModelOff(int delay) { + private static Model getModelOff(int delay) { switch(delay) { case 1: default: - return new ModelBlock("repeater_off").noOcclude() + return ModelProvider.getModelProvider().getModel("repeater_off").noOcclude() .add(0, 0, 0, 16, 2, 16) .d("double_stone_top").uv(0, 0, 16, 16) .u().uv(0, 0, 16, 16).noCull() @@ -183,7 +184,7 @@ public class BlockRedstoneRepeater extends BlockRedstoneDiode .w("unlit_redstone_torch").uv(7, 6, 9, 11).noCull() .e("unlit_redstone_torch").uv(7, 6, 9, 11).noCull(); case 2: - return new ModelBlock("repeater_off").noOcclude() + return ModelProvider.getModelProvider().getModel("repeater_off").noOcclude() .add(0, 0, 0, 16, 2, 16) .d("double_stone_top").uv(0, 0, 16, 16) .u().uv(0, 0, 16, 16).noCull() @@ -206,7 +207,7 @@ public class BlockRedstoneRepeater extends BlockRedstoneDiode .w("unlit_redstone_torch").uv(7, 6, 9, 11).noCull() .e("unlit_redstone_torch").uv(7, 6, 9, 11).noCull(); case 3: - return new ModelBlock("repeater_off").noOcclude() + return ModelProvider.getModelProvider().getModel("repeater_off").noOcclude() .add(0, 0, 0, 16, 2, 16) .d("double_stone_top").uv(0, 0, 16, 16) .u().uv(0, 0, 16, 16).noCull() @@ -229,7 +230,7 @@ public class BlockRedstoneRepeater extends BlockRedstoneDiode .w("unlit_redstone_torch").uv(7, 6, 9, 11).noCull() .e("unlit_redstone_torch").uv(7, 6, 9, 11).noCull(); case 4: - return new ModelBlock("repeater_off").noOcclude() + return ModelProvider.getModelProvider().getModel("repeater_off").noOcclude() .add(0, 0, 0, 16, 2, 16) .d("double_stone_top").uv(0, 0, 16, 16) .u().uv(0, 0, 16, 16).noCull() @@ -254,11 +255,11 @@ public class BlockRedstoneRepeater extends BlockRedstoneDiode } } - private static ModelBlock getModelOn(int delay) { + private static Model getModelOn(int delay) { switch(delay) { case 1: default: - return new ModelBlock("repeater_on").noOcclude() + return ModelProvider.getModelProvider().getModel("repeater_on").noOcclude() .add(0, 0, 0, 16, 2, 16) .d("double_stone_top").uv(0, 0, 16, 16) .u().uv(0, 0, 16, 16).noCull() @@ -283,7 +284,7 @@ public class BlockRedstoneRepeater extends BlockRedstoneDiode .n("redstone_torch").uv(6, 5, 10, 11).noCull() .s("redstone_torch").uv(6, 5, 10, 11).noCull(); case 2: - return new ModelBlock("repeater_on").noOcclude() + return ModelProvider.getModelProvider().getModel("repeater_on").noOcclude() .add(0, 0, 0, 16, 2, 16) .d("double_stone_top").uv(0, 0, 16, 16) .u().uv(0, 0, 16, 16).noCull() @@ -308,7 +309,7 @@ public class BlockRedstoneRepeater extends BlockRedstoneDiode .n("redstone_torch").uv(6, 5, 10, 11).noCull() .s("redstone_torch").uv(6, 5, 10, 11).noCull(); case 3: - return new ModelBlock("repeater_on").noOcclude() + return ModelProvider.getModelProvider().getModel("repeater_on").noOcclude() .add(0, 0, 0, 16, 2, 16) .d("double_stone_top").uv(0, 0, 16, 16) .u().uv(0, 0, 16, 16).noCull() @@ -333,7 +334,7 @@ public class BlockRedstoneRepeater extends BlockRedstoneDiode .n("redstone_torch").uv(6, 5, 10, 11).noCull() .s("redstone_torch").uv(6, 5, 10, 11).noCull(); case 4: - return new ModelBlock("repeater_on").noOcclude() + return ModelProvider.getModelProvider().getModel("repeater_on").noOcclude() .add(0, 0, 0, 16, 2, 16) .d("double_stone_top").uv(0, 0, 16, 16) .u().uv(0, 0, 16, 16).noCull() @@ -360,11 +361,11 @@ public class BlockRedstoneRepeater extends BlockRedstoneDiode } } - private static ModelBlock getModelOffLocked(int delay) { + private static Model getModelOffLocked(int delay) { switch(delay) { case 1: default: - return new ModelBlock("repeater_off").noOcclude() + return ModelProvider.getModelProvider().getModel("repeater_off").noOcclude() .add(0, 0, 0, 16, 2, 16) .d("double_stone_top").uv(0, 0, 16, 16) .u().uv(0, 0, 16, 16).noCull() @@ -387,7 +388,7 @@ public class BlockRedstoneRepeater extends BlockRedstoneDiode .w("unlit_redstone_torch").uv(7, 6, 9, 11).noCull() .e("unlit_redstone_torch").uv(7, 6, 9, 11).noCull(); case 2: - return new ModelBlock("repeater_off").noOcclude() + return ModelProvider.getModelProvider().getModel("repeater_off").noOcclude() .add(0, 0, 0, 16, 2, 16) .d("double_stone_top").uv(0, 0, 16, 16) .u().uv(0, 0, 16, 16).noCull() @@ -410,7 +411,7 @@ public class BlockRedstoneRepeater extends BlockRedstoneDiode .w("unlit_redstone_torch").uv(7, 6, 9, 11).noCull() .e("unlit_redstone_torch").uv(7, 6, 9, 11).noCull(); case 3: - return new ModelBlock("repeater_off").noOcclude() + return ModelProvider.getModelProvider().getModel("repeater_off").noOcclude() .add(0, 0, 0, 16, 2, 16) .d("double_stone_top").uv(0, 0, 16, 16) .u().uv(0, 0, 16, 16).noCull() @@ -433,7 +434,7 @@ public class BlockRedstoneRepeater extends BlockRedstoneDiode .w("unlit_redstone_torch").uv(7, 6, 9, 11).noCull() .e("unlit_redstone_torch").uv(7, 6, 9, 11).noCull(); case 4: - return new ModelBlock("repeater_off").noOcclude() + return ModelProvider.getModelProvider().getModel("repeater_off").noOcclude() .add(0, 0, 0, 16, 2, 16) .d("double_stone_top").uv(0, 0, 16, 16) .u().uv(0, 0, 16, 16).noCull() @@ -458,11 +459,11 @@ public class BlockRedstoneRepeater extends BlockRedstoneDiode } } - private static ModelBlock getModelOnLocked(int delay) { + private static Model getModelOnLocked(int delay) { switch(delay) { case 1: default: - return new ModelBlock("repeater_on").noOcclude() + return ModelProvider.getModelProvider().getModel("repeater_on").noOcclude() .add(0, 0, 0, 16, 2, 16) .d("double_stone_top").uv(0, 0, 16, 16) .u().uv(0, 0, 16, 16).noCull() @@ -486,7 +487,7 @@ public class BlockRedstoneRepeater extends BlockRedstoneDiode .n("redstone_torch").uv(6, 5, 10, 11).noCull() .s("redstone_torch").uv(6, 5, 10, 11).noCull(); case 2: - return new ModelBlock("repeater_on").noOcclude() + return ModelProvider.getModelProvider().getModel("repeater_on").noOcclude() .add(0, 0, 0, 16, 2, 16) .d("double_stone_top").uv(0, 0, 16, 16) .u().uv(0, 0, 16, 16).noCull() @@ -510,7 +511,7 @@ public class BlockRedstoneRepeater extends BlockRedstoneDiode .n("redstone_torch").uv(6, 5, 10, 11).noCull() .s("redstone_torch").uv(6, 5, 10, 11).noCull(); case 3: - return new ModelBlock("repeater_on").noOcclude() + return ModelProvider.getModelProvider().getModel("repeater_on").noOcclude() .add(0, 0, 0, 16, 2, 16) .d("double_stone_top").uv(0, 0, 16, 16) .u().uv(0, 0, 16, 16).noCull() @@ -534,7 +535,7 @@ public class BlockRedstoneRepeater extends BlockRedstoneDiode .n("redstone_torch").uv(6, 5, 10, 11).noCull() .s("redstone_torch").uv(6, 5, 10, 11).noCull(); case 4: - return new ModelBlock("repeater_on").noOcclude() + return ModelProvider.getModelProvider().getModel("repeater_on").noOcclude() .add(0, 0, 0, 16, 2, 16) .d("double_stone_top").uv(0, 0, 16, 16) .u().uv(0, 0, 16, 16).noCull() @@ -560,7 +561,7 @@ public class BlockRedstoneRepeater extends BlockRedstoneDiode } } - public ModelBlock getModel(String name, State state) { + public Model getModel(ModelProvider provider, String name, State state) { return (this.isRepeaterPowered ? (state.getValue(LOCKED) ? getModelOnLocked(state.getValue(DELAY)) : getModelOn(state.getValue(DELAY))) : (state.getValue(LOCKED) ? getModelOffLocked(state.getValue(DELAY)) : getModelOff(state.getValue(DELAY)))) diff --git a/java/src/game/block/BlockRedstoneTorch.java b/java/src/game/block/BlockRedstoneTorch.java index 1ad83e1..2590c67 100755 --- a/java/src/game/block/BlockRedstoneTorch.java +++ b/java/src/game/block/BlockRedstoneTorch.java @@ -5,13 +5,12 @@ import java.util.Map; import game.collect.Lists; import game.collect.Maps; - import game.init.Blocks; import game.init.ItemRegistry; import game.init.SoundEvent; import game.item.CheatTab; import game.item.Item; -import game.renderer.particle.ParticleType; +import game.model.ParticleType; import game.rng.Random; import game.world.BlockPos; import game.world.Facing; diff --git a/java/src/game/block/BlockRedstoneWire.java b/java/src/game/block/BlockRedstoneWire.java index ef33571..3b119ab 100755 --- a/java/src/game/block/BlockRedstoneWire.java +++ b/java/src/game/block/BlockRedstoneWire.java @@ -6,21 +6,21 @@ import java.util.Set; import game.collect.Lists; import game.collect.Sets; - import game.init.Blocks; import game.init.Items; import game.item.Item; import game.material.Material; +import game.model.BlockLayer; +import game.model.Model; +import game.model.ModelProvider; import game.model.ModelRotation; +import game.model.ParticleType; import game.properties.IProperty; -import game.properties.IStringSerializable; import game.properties.PropertyEnum; import game.properties.PropertyInteger; -import game.renderer.BlockLayer; -import game.renderer.blockmodel.ModelBlock; -import game.renderer.particle.ParticleType; import game.rng.Random; import game.util.ExtMath; +import game.util.Identifyable; import game.world.BlockPos; import game.world.BoundingBox; import game.world.Facing; @@ -33,19 +33,19 @@ import game.world.WorldServer; public class BlockRedstoneWire extends Block { - private static final ModelBlock redstone_none = new ModelBlock("redstone_dust_cross").noOcclude() + private static final Model redstone_none = ModelProvider.getModelProvider().getModel("redstone_dust_cross").noOcclude() .add(5, 0.25f, 5, 11, 0.25f, 11).noShade() .u().uv(5, 5, 11, 11).tint().noCull() .add(5, 0.25f, 5, 11, 0.25f, 11).noShade() .u("redstone_dust_cross_overlay").uv(5, 5, 11, 11).noCull() ; - private static final ModelBlock redstone_nsew = new ModelBlock("redstone_dust_cross").noOcclude().uvLock() + private static final Model redstone_nsew = ModelProvider.getModelProvider().getModel("redstone_dust_cross").noOcclude().uvLock() .add(0, 0.25f, 0, 16, 0.25f, 16).noShade() .u().uv(0, 0, 16, 16).tint().noCull() .add(0, 0.25f, 0, 16, 0.25f, 16).noShade() .u("redstone_dust_cross_overlay").uv(0, 0, 16, 16).noCull() ; - private static final ModelBlock redstone_unusueuw = new ModelBlock("redstone_dust_cross").noOcclude().uvLock() + private static final Model redstone_unusueuw = ModelProvider.getModelProvider().getModel("redstone_dust_cross").noOcclude().uvLock() .add(0, 0.25f, 0, 16, 0.25f, 16).noShade() .u().uv(0, 0, 16, 16).tint().noCull() .add(0, 0.25f, 0, 16, 0.25f, 16).noShade() @@ -67,7 +67,7 @@ public class BlockRedstoneWire extends Block .add(0.25f, 0, 0, 0.25f, 16, 16).noShade() .e("redstone_dust_line_overlay").uv(0, 0, 16, 16).rot(90).noCull() ; - private static final ModelBlock redstone_unus = new ModelBlock("redstone_dust_cross").noOcclude() + private static final Model redstone_unus = ModelProvider.getModelProvider().getModel("redstone_dust_cross").noOcclude() .add(0, 0.25f, 0, 16, 0.25f, 16).noShade() .u("redstone_dust_line").uv(0, 0, 16, 16).rot(90).tint().noCull() .add(0, 0.25f, 0, 16, 0.25f, 16).noShade() @@ -81,7 +81,7 @@ public class BlockRedstoneWire extends Block .add(0, 0, 15.75f, 16, 16, 15.75f).noShade() .n("redstone_dust_line_overlay").uv(0, 0, 16, 16).rot(90).noCull() ; - private static final ModelBlock redstone_ueuw = new ModelBlock("redstone_dust_cross").noOcclude() + private static final Model redstone_ueuw = ModelProvider.getModelProvider().getModel("redstone_dust_cross").noOcclude() .add(0, 0.25f, 0, 16, 0.25f, 16).noShade() .u("redstone_dust_line").uv(0, 0, 16, 16).tint().noCull() .add(0, 0.25f, 0, 16, 0.25f, 16).noShade() @@ -96,8 +96,8 @@ public class BlockRedstoneWire extends Block .w("redstone_dust_line_overlay").uv(0, 0, 16, 16).rot(90).noCull() ; - private static ModelBlock redstone_n(boolean rot) { - return new ModelBlock("redstone_dust_cross").noOcclude() + private static Model redstone_n(boolean rot) { + return ModelProvider.getModelProvider().getModel("redstone_dust_cross").noOcclude() .add(0, 0.25f, 0, 16, 0.25f, 16).noShade() .u("redstone_dust_line").uv(0, 0, 16, 16).rot(90).tint().noCull() .add(0, 0.25f, 0, 16, 0.25f, 16).noShade() @@ -105,8 +105,8 @@ public class BlockRedstoneWire extends Block .rotate(rot ? ModelRotation.X0_Y90 : ModelRotation.X0_Y0); } - private static ModelBlock redstone_ne(ModelRotation rot) { - return new ModelBlock("redstone_dust_cross").noOcclude().uvLock() + private static Model redstone_ne(ModelRotation rot) { + return ModelProvider.getModelProvider().getModel("redstone_dust_cross").noOcclude().uvLock() .add(5, 0.25f, 0, 16, 0.25f, 11).noShade() .u().uv(5, 0, 16, 11).tint().noCull() .add(5, 0.25f, 0, 16, 0.25f, 11).noShade() @@ -114,8 +114,8 @@ public class BlockRedstoneWire extends Block .rotate(rot); } - private static ModelBlock redstone_uew(boolean rot) { - ModelBlock model = new ModelBlock("redstone_dust_cross").noOcclude() + private static Model redstone_uew(boolean rot) { + Model model = ModelProvider.getModelProvider().getModel("redstone_dust_cross").noOcclude() .add(0, 0.25f, 0, 16, 0.25f, 16).noShade() .u("redstone_dust_line").uv(0, 0, 16, 16).tint().noCull() .add(0, 0.25f, 0, 16, 0.25f, 16).noShade() @@ -126,8 +126,8 @@ public class BlockRedstoneWire extends Block .w("redstone_dust_line_overlay").uv(0, 0, 16, 16).rot(90).noCull(); return rot ? model.uvLock().rotate(ModelRotation.X0_Y180) : model; } - private static ModelBlock redstone_nue(ModelRotation rot) { - return new ModelBlock("redstone_dust_cross").noOcclude().uvLock() + private static Model redstone_nue(ModelRotation rot) { + return ModelProvider.getModelProvider().getModel("redstone_dust_cross").noOcclude().uvLock() .add(5, 0.25f, 0, 16, 0.25f, 11).noShade() .u().uv(5, 0, 16, 11).tint().noCull() .add(5, 0.25f, 0, 16, 0.25f, 11).noShade() @@ -138,8 +138,8 @@ public class BlockRedstoneWire extends Block .w("redstone_dust_line_overlay").uv(0, 0, 16, 16).rot(270).noCull() .rotate(rot); } - private static ModelBlock redstone_une(ModelRotation rot) { - return new ModelBlock("redstone_dust_cross").noOcclude().uvLock() + private static Model redstone_une(ModelRotation rot) { + return ModelProvider.getModelProvider().getModel("redstone_dust_cross").noOcclude().uvLock() .add(5, 0.25f, 0, 16, 0.25f, 11).noShade() .u().uv(5, 0, 16, 11).tint().noCull() .add(5, 0.25f, 0, 16, 0.25f, 11).noShade() @@ -150,16 +150,16 @@ public class BlockRedstoneWire extends Block .s("redstone_dust_line_overlay").uv(0, 0, 16, 16).rot(90).noCull() .rotate(rot); } - private static ModelBlock redstone_nse(ModelRotation rot) { - return new ModelBlock("redstone_dust_cross").noOcclude().uvLock() + private static Model redstone_nse(ModelRotation rot) { + return ModelProvider.getModelProvider().getModel("redstone_dust_cross").noOcclude().uvLock() .add(5, 0.25f, 0, 16, 0.25f, 16).noShade() .u().uv(5, 0, 16, 16).tint().noCull() .add(5, 0.25f, 0, 16, 0.25f, 16).noShade() .u("redstone_dust_cross_overlay").uv(5, 0, 16, 16).noCull() .rotate(rot); } - private static ModelBlock redstone_uns(boolean lock, ModelRotation rot) { - ModelBlock model = new ModelBlock("redstone_dust_cross").noOcclude() + private static Model redstone_uns(boolean lock, ModelRotation rot) { + Model model = ModelProvider.getModelProvider().getModel("redstone_dust_cross").noOcclude() .add(0, 0.25f, 0, 16, 0.25f, 16).noShade() .u("redstone_dust_line").uv(0, 0, 16, 16).rot(90).tint().noCull() .add(0, 0.25f, 0, 16, 0.25f, 16).noShade() @@ -172,8 +172,8 @@ public class BlockRedstoneWire extends Block return lock ? model.uvLock() : model; } - private static ModelBlock redstone_nsue(ModelRotation rot) { - return new ModelBlock("redstone_dust_cross").noOcclude().uvLock() + private static Model redstone_nsue(ModelRotation rot) { + return ModelProvider.getModelProvider().getModel("redstone_dust_cross").noOcclude().uvLock() .add(5, 0.25f, 0, 16, 0.25f, 16).noShade() .u().uv(5, 0, 16, 16).tint().noCull() .add(5, 0.25f, 0, 16, 0.25f, 16).noShade() @@ -184,8 +184,8 @@ public class BlockRedstoneWire extends Block .w("redstone_dust_line_overlay").uv(0, 0, 16, 16).rot(270).noCull() .rotate(rot); } - private static ModelBlock redstone_unse(ModelRotation rot) { - return new ModelBlock("redstone_dust_cross").noOcclude().uvLock() + private static Model redstone_unse(ModelRotation rot) { + return ModelProvider.getModelProvider().getModel("redstone_dust_cross").noOcclude().uvLock() .add(5, 0.25f, 0, 16, 0.25f, 16).noShade() .u().uv(5, 0, 16, 16).tint().noCull() .add(5, 0.25f, 0, 16, 0.25f, 16).noShade() @@ -196,8 +196,8 @@ public class BlockRedstoneWire extends Block .s("redstone_dust_line_overlay").uv(0, 0, 16, 16).rot(90).noCull() .rotate(rot); } - private static ModelBlock redstone_nuse(ModelRotation rot) { - return new ModelBlock("redstone_dust_cross").noOcclude().uvLock() + private static Model redstone_nuse(ModelRotation rot) { + return ModelProvider.getModelProvider().getModel("redstone_dust_cross").noOcclude().uvLock() .add(5, 0.25f, 0, 16, 0.25f, 16).noShade() .u().uv(5, 0, 16, 16).tint().noCull() .add(5, 0.25f, 0, 16, 0.25f, 16).noShade() @@ -208,8 +208,8 @@ public class BlockRedstoneWire extends Block .n("redstone_dust_line_overlay").uv(0, 0, 16, 16).rot(90).noCull() .rotate(rot); } - private static ModelBlock redstone_unue(ModelRotation rot) { - return new ModelBlock("redstone_dust_cross").noOcclude().uvLock() + private static Model redstone_unue(ModelRotation rot) { + return ModelProvider.getModelProvider().getModel("redstone_dust_cross").noOcclude().uvLock() .add(5, 0.25f, 0, 16, 0.25f, 11).noShade() .u().uv(5, 0, 16, 11).tint().noCull() .add(5, 0.25f, 0, 16, 0.25f, 11).noShade() @@ -225,8 +225,8 @@ public class BlockRedstoneWire extends Block .rotate(rot); } - private static ModelBlock redstone_unusue(ModelRotation rot) { - return new ModelBlock("redstone_dust_cross").noOcclude().uvLock() + private static Model redstone_unusue(ModelRotation rot) { + return ModelProvider.getModelProvider().getModel("redstone_dust_cross").noOcclude().uvLock() .add(5, 0.25f, 0, 16, 0.25f, 16).noShade() .u().uv(5, 0, 16, 16).tint().noCull() .add(5, 0.25f, 0, 16, 0.25f, 16).noShade() @@ -245,8 +245,8 @@ public class BlockRedstoneWire extends Block .w("redstone_dust_line_overlay").uv(0, 0, 16, 16).rot(90).noCull() .rotate(rot); } - private static ModelBlock redstone_unusew(boolean rot) { - return new ModelBlock("redstone_dust_cross").noOcclude().uvLock() + private static Model redstone_unusew(boolean rot) { + return ModelProvider.getModelProvider().getModel("redstone_dust_cross").noOcclude().uvLock() .add(0, 0.25f, 0, 16, 0.25f, 16).noShade() .u().uv(0, 0, 16, 16).tint().noCull() .add(0, 0.25f, 0, 16, 0.25f, 16).noShade() @@ -261,8 +261,8 @@ public class BlockRedstoneWire extends Block .n("redstone_dust_line_overlay").uv(0, 0, 16, 16).rot(90).noCull() .rotate(rot ? ModelRotation.X0_Y90 : ModelRotation.X0_Y0); } - private static ModelBlock redstone_unusuew(ModelRotation rot) { - return new ModelBlock("redstone_dust_cross").noOcclude().uvLock() + private static Model redstone_unusuew(ModelRotation rot) { + return ModelProvider.getModelProvider().getModel("redstone_dust_cross").noOcclude().uvLock() .add(0, 0.25f, 0, 16, 0.25f, 16).noShade() .u().uv(0, 0, 16, 16).tint().noCull() .add(0, 0.25f, 0, 16, 0.25f, 16).noShade() @@ -281,8 +281,8 @@ public class BlockRedstoneWire extends Block .w("redstone_dust_line_overlay").uv(0, 0, 16, 16).rot(90).noCull() .rotate(rot); } - private static ModelBlock redstone_unuse(ModelRotation rot) { - return new ModelBlock("redstone_dust_cross").noOcclude().uvLock() + private static Model redstone_unuse(ModelRotation rot) { + return ModelProvider.getModelProvider().getModel("redstone_dust_cross").noOcclude().uvLock() .add(5, 0.25f, 0, 16, 0.25f, 16).noShade() .u().uv(5, 0, 16, 16).tint().noCull() .add(5, 0.25f, 0, 16, 0.25f, 16).noShade() @@ -297,8 +297,8 @@ public class BlockRedstoneWire extends Block .n("redstone_dust_line_overlay").uv(0, 0, 16, 16).rot(90).noCull() .rotate(rot); } - private static ModelBlock redstone_nusue(ModelRotation rot) { - return new ModelBlock("redstone_dust_cross").noOcclude().uvLock() + private static Model redstone_nusue(ModelRotation rot) { + return ModelProvider.getModelProvider().getModel("redstone_dust_cross").noOcclude().uvLock() .add(5, 0.25f, 0, 16, 0.25f, 16).noShade() .u().uv(5, 0, 16, 16).tint().noCull() .add(5, 0.25f, 0, 16, 0.25f, 16).noShade() @@ -313,8 +313,8 @@ public class BlockRedstoneWire extends Block .w("redstone_dust_line_overlay").uv(0, 0, 16, 16).rot(90).noCull() .rotate(rot); } - private static ModelBlock redstone_unsew(ModelRotation rot) { - return new ModelBlock("redstone_dust_cross").noOcclude().uvLock() + private static Model redstone_unsew(ModelRotation rot) { + return ModelProvider.getModelProvider().getModel("redstone_dust_cross").noOcclude().uvLock() .add(0, 0.25f, 0, 16, 0.25f, 16).noShade() .u().uv(0, 0, 16, 16).tint().noCull() .add(0, 0.25f, 0, 16, 0.25f, 16).noShade() @@ -325,8 +325,8 @@ public class BlockRedstoneWire extends Block .s("redstone_dust_line_overlay").uv(0, 0, 16, 16).rot(90).noCull() .rotate(rot); } - private static ModelBlock redstone_unsuew(ModelRotation rot) { - return new ModelBlock("redstone_dust_cross").noOcclude().uvLock() + private static Model redstone_unsuew(ModelRotation rot) { + return ModelProvider.getModelProvider().getModel("redstone_dust_cross").noOcclude().uvLock() .add(0, 0.25f, 0, 16, 0.25f, 16).noShade() .u().uv(0, 0, 16, 16).tint().noCull() .add(0, 0.25f, 0, 16, 0.25f, 16).noShade() @@ -341,8 +341,8 @@ public class BlockRedstoneWire extends Block .w("redstone_dust_line_overlay").uv(0, 0, 16, 16).rot(90).noCull() .rotate(rot); } - private static ModelBlock redstone_unsue(ModelRotation rot) { - return new ModelBlock("redstone_dust_cross").noOcclude().uvLock() + private static Model redstone_unsue(ModelRotation rot) { + return ModelProvider.getModelProvider().getModel("redstone_dust_cross").noOcclude().uvLock() .add(5, 0.25f, 0, 16, 0.25f, 16).noShade() .u().uv(5, 0, 16, 16).tint().noCull() .add(5, 0.25f, 0, 16, 0.25f, 16).noShade() @@ -825,7 +825,7 @@ public class BlockRedstoneWire extends Block return true; } - public ModelBlock getModel(String name, State state) { + public Model getModel(ModelProvider provider, String name, State state) { boolean na = state.getValue(NORTH) == EnumAttachPosition.NONE; boolean sa = state.getValue(SOUTH) == EnumAttachPosition.NONE; boolean wa = state.getValue(WEST) == EnumAttachPosition.NONE; @@ -1026,7 +1026,7 @@ public class BlockRedstoneWire extends Block return new IProperty[] {POWER}; } - static enum EnumAttachPosition implements IStringSerializable + static enum EnumAttachPosition implements Identifyable { UP("up"), SIDE("side"), diff --git a/java/src/game/block/BlockReed.java b/java/src/game/block/BlockReed.java index 6cae792..a60106d 100755 --- a/java/src/game/block/BlockReed.java +++ b/java/src/game/block/BlockReed.java @@ -5,10 +5,11 @@ import game.init.Config; import game.init.Items; import game.item.Item; import game.material.Material; +import game.model.BlockLayer; +import game.model.Model; +import game.model.ModelProvider; import game.properties.IProperty; import game.properties.PropertyInteger; -import game.renderer.BlockLayer; -import game.renderer.blockmodel.ModelBlock; import game.rng.Random; import game.world.BlockPos; import game.world.BoundingBox; @@ -182,8 +183,8 @@ public class BlockReed extends Block return new IProperty[] {AGE}; } - public ModelBlock getModel(String name, State state) { - return new ModelBlock("reeds").crossTint(); + public Model getModel(ModelProvider provider, String name, State state) { + return provider.getModel("reeds").crossTint(); } public IProperty[] getIgnoredProperties() { diff --git a/java/src/game/block/BlockRock.java b/java/src/game/block/BlockRock.java index a457ece..607027f 100755 --- a/java/src/game/block/BlockRock.java +++ b/java/src/game/block/BlockRock.java @@ -6,9 +6,10 @@ import game.item.CheatTab; import game.item.Item; import game.item.ItemStack; import game.material.Material; +import game.model.Model; +import game.model.ModelProvider; import game.properties.IProperty; import game.properties.PropertyBool; -import game.renderer.blockmodel.ModelBlock; import game.world.State; public class BlockRock extends Block { @@ -41,7 +42,7 @@ public class BlockRock extends Block { return new IProperty[] {SMOOTH}; } - public ModelBlock getModel(String name, State state) { - return new ModelBlock(state.getValue(SMOOTH) ? "smooth_rock" : "rock").add().all(); + public Model getModel(ModelProvider provider, String name, State state) { + return provider.getModel(state.getValue(SMOOTH) ? "smooth_rock" : "rock").add().all(); } } diff --git a/java/src/game/block/BlockRotatedPillar.java b/java/src/game/block/BlockRotatedPillar.java index a1c42ba..1bcc08f 100755 --- a/java/src/game/block/BlockRotatedPillar.java +++ b/java/src/game/block/BlockRotatedPillar.java @@ -1,9 +1,10 @@ package game.block; import game.material.Material; +import game.model.Model; +import game.model.ModelProvider; import game.model.ModelRotation; import game.properties.PropertyEnum; -import game.renderer.blockmodel.ModelBlock; import game.world.Facing; import game.world.State; @@ -16,17 +17,17 @@ public abstract class BlockRotatedPillar extends Block super(materialIn); } - public ModelBlock getModel(String name, State state) { + public Model getModel(ModelProvider provider, String name, State state) { switch(state.getValue(AXIS)) { case X: - return new ModelBlock(name + "_side").add().d().rot(180).u() + return provider.getModel(name + "_side").add().d().rot(180).u() .n(name + "_top").rot(180).s(name + "_top").w().rot(270) .e().rot(90).rotate(ModelRotation.X0_Y90); case Y: default: - return new ModelBlock(name + "_side").add().nswe().du(name + "_top"); + return provider.getModel(name + "_side").add().nswe().du(name + "_top"); case Z: - return new ModelBlock(name + "_side").add().d().rot(180).u() + return provider.getModel(name + "_side").add().d().rot(180).u() .n(name + "_top").rot(180).s(name + "_top").w().rot(270) .e().rot(90); } diff --git a/java/src/game/block/BlockSand.java b/java/src/game/block/BlockSand.java index 2739809..37e93c6 100755 --- a/java/src/game/block/BlockSand.java +++ b/java/src/game/block/BlockSand.java @@ -5,10 +5,11 @@ import java.util.List; import game.item.CheatTab; import game.item.Item; import game.item.ItemStack; +import game.model.Model; +import game.model.ModelProvider; import game.properties.IProperty; -import game.properties.IStringSerializable; import game.properties.PropertyEnum; -import game.renderer.blockmodel.ModelBlock; +import game.util.Identifyable; import game.world.State; public class BlockSand extends BlockFalling @@ -69,11 +70,11 @@ public class BlockSand extends BlockFalling return new IProperty[] {VARIANT}; } - public ModelBlock getModel(String name, State state) { - return new ModelBlock(state.getValue(VARIANT).getName()).add().all(); + public Model getModel(ModelProvider provider, String name, State state) { + return provider.getModel(state.getValue(VARIANT).getName()).add().all(); } - public static enum EnumType implements IStringSerializable + public static enum EnumType implements Identifyable { SAND(0, "sand", "Sand"), RED_SAND(1, "red_sand", "Roter Sand"); diff --git a/java/src/game/block/BlockSandStone.java b/java/src/game/block/BlockSandStone.java index 5bbba58..b92213c 100755 --- a/java/src/game/block/BlockSandStone.java +++ b/java/src/game/block/BlockSandStone.java @@ -6,10 +6,11 @@ import game.item.CheatTab; import game.item.Item; import game.item.ItemStack; import game.material.Material; +import game.model.Model; +import game.model.ModelProvider; import game.properties.IProperty; -import game.properties.IStringSerializable; import game.properties.PropertyEnum; -import game.renderer.blockmodel.ModelBlock; +import game.util.Identifyable; import game.world.State; public class BlockSandStone extends Block @@ -72,19 +73,19 @@ public class BlockSandStone extends Block return new IProperty[] {TYPE}; } - public ModelBlock getModel(String name, State state) { + public Model getModel(ModelProvider provider, String name, State state) { switch(state.getValue(TYPE)) { case DEFAULT: default: - return new ModelBlock("sandstone_normal").add().nswe().d("sandstone_bottom").u("sandstone_all"); + return provider.getModel("sandstone_normal").add().nswe().d("sandstone_bottom").u("sandstone_all"); case CHISELED: - return new ModelBlock("sandstone_carved").add().nswe().d("sandstone_bottom").u("sandstone_all"); + return provider.getModel("sandstone_carved").add().nswe().d("sandstone_bottom").u("sandstone_all"); case SMOOTH: - return new ModelBlock("sandstone_smooth").add().nswe().d("sandstone_bottom").u("sandstone_all"); + return provider.getModel("sandstone_smooth").add().nswe().d("sandstone_bottom").u("sandstone_all"); } } - public static enum EnumType implements IStringSerializable + public static enum EnumType implements Identifyable { DEFAULT(0, "sandstone", "Sandstein"), CHISELED(1, "chiseled_sandstone", "Gemeißelter Sandstein"), diff --git a/java/src/game/block/BlockSapling.java b/java/src/game/block/BlockSapling.java index e829bc7..5f2eddf 100755 --- a/java/src/game/block/BlockSapling.java +++ b/java/src/game/block/BlockSapling.java @@ -3,14 +3,14 @@ package game.block; import java.util.List; import game.collect.Lists; - import game.init.Blocks; import game.init.Config; import game.init.WoodType; import game.item.CheatTab; +import game.model.Model; +import game.model.ModelProvider; import game.properties.IProperty; import game.properties.PropertyInteger; -import game.renderer.blockmodel.ModelBlock; import game.rng.Random; import game.world.BlockPos; import game.world.State; @@ -293,7 +293,7 @@ public class BlockSapling extends BlockBush implements IGrowable return new IProperty[] {STAGE}; } - public ModelBlock getModel(String name, State state) { - return new ModelBlock(name).cross(); + public Model getModel(ModelProvider provider, String name, State state) { + return provider.getModel(name).cross(); } } diff --git a/java/src/game/block/BlockSkull.java b/java/src/game/block/BlockSkull.java index 5c88d17..b3575c6 100755 --- a/java/src/game/block/BlockSkull.java +++ b/java/src/game/block/BlockSkull.java @@ -5,9 +5,9 @@ import game.init.Items; import game.item.Item; import game.item.ItemStack; import game.material.Material; +import game.model.Transforms; import game.properties.IProperty; import game.properties.PropertyDirection; -import game.renderer.blockmodel.Transforms; import game.rng.Random; import game.tileentity.TileEntity; import game.tileentity.TileEntitySkull; diff --git a/java/src/game/block/BlockSlab.java b/java/src/game/block/BlockSlab.java index caebe48..222d216 100755 --- a/java/src/game/block/BlockSlab.java +++ b/java/src/game/block/BlockSlab.java @@ -3,17 +3,17 @@ package game.block; import java.util.List; import game.collect.Lists; - import game.entity.Entity; import game.entity.types.EntityLiving; import game.item.CheatTab; import game.item.Item; import game.item.ItemStack; import game.material.Material; +import game.model.Model; +import game.model.ModelProvider; import game.properties.IProperty; import game.properties.PropertyBool; import game.properties.PropertyDirection; -import game.renderer.blockmodel.ModelBlock; import game.world.BlockPos; import game.world.BoundingBox; import game.world.Facing; @@ -251,52 +251,52 @@ public class BlockSlab extends Block // // public abstract Object getVariant(ItemStack stack); - public ModelBlock getModel(String name, State state) { + public Model getModel(ModelProvider provider, String name, State state) { if(state.getValue(DOUBLE)) { - return new ModelBlock(state.getValue(SEAMLESS) ? this.textureTop : this.textureSide) + return provider.getModel(state.getValue(SEAMLESS) ? this.textureTop : this.textureSide) .add().nswe().d(state.getValue(SEAMLESS) ? this.textureTop : this.textureBottom).u(this.textureTop); } else { if(state.getValue(FACING).getAxis() != Axis.Y) - return new ModelBlock(this.textureSide).vslab(state.getValue(FACING), this.textureBottom, this.textureTop); + return provider.getModel(this.textureSide).vslab(state.getValue(FACING), this.textureBottom, this.textureTop); else - return new ModelBlock(this.textureSide).slab(state.getValue(FACING) == Facing.UP, this.textureBottom, + return provider.getModel(this.textureSide).slab(state.getValue(FACING) == Facing.UP, this.textureBottom, this.textureTop); } } /* - public ModelBlock getModel(String name, IBlockState state) { + public Model getModel(String name, IBlockState state) { if(state.getValue(VARIANT) == EnumType.STONE) - return state.getValue(SEAMLESS) ? new ModelBlock("double_stone_top").add().all() : - new ModelBlock("stone_slab_side").add().nswe().du("double_stone_top"); + return state.getValue(SEAMLESS) ? provider.getModel("double_stone_top").add().all() : + provider.getModel("stone_slab_side").add().nswe().du("double_stone_top"); else if(state.getValue(VARIANT) == EnumType.QUARTZ) - return new ModelBlock("quartz_block_side").add().nswe().d("quartz_block_bottom").u("quartz_top"); + return provider.getModel("quartz_block_side").add().nswe().d("quartz_block_bottom").u("quartz_top"); else if(state.getValue(VARIANT) == EnumType.SAND) - return new ModelBlock("sandstone_normal").add().nswe().d("sandstone_bottom").u("sandstone_all"); + return provider.getModel("sandstone_normal").add().nswe().d("sandstone_bottom").u("sandstone_all"); else - return new ModelBlock(getTexture(state.getValue(VARIANT))).add().all(); + return provider.getModel(getTexture(state.getValue(VARIANT))).add().all(); } - public ModelBlock getModel(String name, IBlockState state) { + public Model getModel(String name, IBlockState state) { if(state.getValue(VARIANT) == EnumType.STONE) - return new ModelBlock("stone_slab_side").slab(state.getValue(HALF) == EnumBlockHalf.TOP, "double_stone_top"); + return provider.getModel("stone_slab_side").slab(state.getValue(HALF) == EnumBlockHalf.TOP, "double_stone_top"); else if(state.getValue(VARIANT) == EnumType.QUARTZ) - return new ModelBlock("quartz_block_side").slab(state.getValue(HALF) == EnumBlockHalf.TOP, "quartz_block_bottom", + return provider.getModel("quartz_block_side").slab(state.getValue(HALF) == EnumBlockHalf.TOP, "quartz_block_bottom", "quartz_top"); else if(state.getValue(VARIANT) == EnumType.SAND) - return new ModelBlock("sandstone_normal").slab(state.getValue(HALF) == EnumBlockHalf.TOP, "sandstone_bottom", + return provider.getModel("sandstone_normal").slab(state.getValue(HALF) == EnumBlockHalf.TOP, "sandstone_bottom", "sandstone_all"); else - return new ModelBlock(getTexture(state.getValue(VARIANT))).slab(state.getValue(HALF) == EnumBlockHalf.TOP); + return provider.getModel(getTexture(state.getValue(VARIANT))).slab(state.getValue(HALF) == EnumBlockHalf.TOP); } - public ModelBlock getModel(String name, IBlockState state) { - return new ModelBlock(state.getValue(VARIANT).getName() + "_planks").slab(state.getValue(HALF) == EnumBlockHalf.TOP); + public Model getModel(String name, IBlockState state) { + return provider.getModel(state.getValue(VARIANT).getName() + "_planks").slab(state.getValue(HALF) == EnumBlockHalf.TOP); } - public ModelBlock getModel(String name, IBlockState state) { - return new ModelBlock(state.getValue(VARIANT).getName() + "_planks").add().all(); + public Model getModel(String name, IBlockState state) { + return provider.getModel(state.getValue(VARIANT).getName() + "_planks").add().all(); } protected static String getTexture(BlockStoneSlab.EnumType type) { @@ -321,14 +321,14 @@ public class BlockSlab extends Block } } - public ModelBlock getModel(String name, IBlockState state) { + public Model getModel(String name, IBlockState state) { if(state.getValue(VARIANT) == EnumType.STONE) - return new ModelBlock("stone_slab_side").vslab(state.getValue(FACING), "double_stone_top"); + return provider.getModel("stone_slab_side").vslab(state.getValue(FACING), "double_stone_top"); else if(state.getValue(VARIANT) == EnumType.SAND) - return new ModelBlock("sandstone_normal").vslab(state.getValue(FACING), "sandstone_bottom", + return provider.getModel("sandstone_normal").vslab(state.getValue(FACING), "sandstone_bottom", "sandstone_all"); else - return new ModelBlock(getTexture(state.getValue(VARIANT))).vslab(state.getValue(FACING)); + return provider.getModel(getTexture(state.getValue(VARIANT))).vslab(state.getValue(FACING)); } private static String getTexture(BlockVertStoneSlab2.EnumType type) { @@ -342,20 +342,20 @@ public class BlockSlab extends Block } } - public ModelBlock getModel(String name, IBlockState state) { + public Model getModel(String name, IBlockState state) { if(state.getValue(VARIANT) == EnumType.QUARTZ) - return new ModelBlock("quartz_block_side").vslab(state.getValue(FACING), "quartz_block_bottom", + return provider.getModel("quartz_block_side").vslab(state.getValue(FACING), "quartz_block_bottom", "quartz_top"); else - return new ModelBlock(getTexture(state.getValue(VARIANT))).vslab(state.getValue(FACING)); + return provider.getModel(getTexture(state.getValue(VARIANT))).vslab(state.getValue(FACING)); } - public ModelBlock getModel(String name, IBlockState state) { - return new ModelBlock(state.getValue(VARIANT).getName() + "_planks").vslab(state.getValue(FACING)); + public Model getModel(String name, IBlockState state) { + return provider.getModel(state.getValue(VARIANT).getName() + "_planks").vslab(state.getValue(FACING)); } - public ModelBlock getModel(String name, IBlockState state) { - return new ModelBlock(state.getValue(VARIANT).getName() + "_planks").vslab(state.getValue(FACING)); + public Model getModel(String name, IBlockState state) { + return provider.getModel(state.getValue(VARIANT).getName() + "_planks").vslab(state.getValue(FACING)); } */ } diff --git a/java/src/game/block/BlockSlime.java b/java/src/game/block/BlockSlime.java index 27bdee5..81f0625 100755 --- a/java/src/game/block/BlockSlime.java +++ b/java/src/game/block/BlockSlime.java @@ -3,15 +3,16 @@ package game.block; import game.entity.Entity; import game.item.CheatTab; import game.material.Material; -import game.renderer.BlockLayer; -import game.renderer.blockmodel.ModelBlock; +import game.model.BlockLayer; +import game.model.Model; +import game.model.ModelProvider; import game.world.BlockPos; import game.world.State; import game.world.World; public class BlockSlime extends BlockBreakable { - private static final ModelBlock slime = new ModelBlock("slime") + private static final Model slime = ModelProvider.getModelProvider().getModel("slime") .add(0, 0, 0, 16, 16, 16) .d().uv(0, 0, 16, 16).noCull() .u().uv(0, 0, 16, 16).noCull() @@ -86,7 +87,7 @@ public class BlockSlime extends BlockBreakable super.onEntityCollidedWithBlock(worldIn, pos, entityIn); } - public ModelBlock getModel(String name, State state) { + public Model getModel(ModelProvider provider, String name, State state) { return slime; } } diff --git a/java/src/game/block/BlockSnow.java b/java/src/game/block/BlockSnow.java index bff067b..f8b68fd 100755 --- a/java/src/game/block/BlockSnow.java +++ b/java/src/game/block/BlockSnow.java @@ -8,10 +8,11 @@ import game.item.CheatTab; import game.item.Item; import game.item.ItemStack; import game.material.Material; +import game.model.Model; +import game.model.ModelProvider; +import game.model.Transforms; import game.properties.IProperty; import game.properties.PropertyInteger; -import game.renderer.blockmodel.ModelBlock; -import game.renderer.blockmodel.Transforms; import game.rng.Random; import game.tileentity.TileEntity; import game.world.BlockPos; @@ -181,9 +182,9 @@ public class BlockSnow extends Block return Transforms.LAYER; } - public ModelBlock getModel(String name, State state) { + public Model getModel(ModelProvider provider, String name, State state) { int height = state.getValue(LAYERS) * 2; - return height == 16 ? new ModelBlock("snow").add().all() : - new ModelBlock("snow").add(0, 0, 0, 16, height, 16).u().noCull().d().nswe().uv(0, 16 - height, 16, 16); + return height == 16 ? provider.getModel("snow").add().all() : + provider.getModel("snow").add(0, 0, 0, 16, height, 16).u().noCull().d().nswe().uv(0, 16 - height, 16, 16); } } diff --git a/java/src/game/block/BlockStainedGlass.java b/java/src/game/block/BlockStainedGlass.java index 6277a9a..8cd1807 100755 --- a/java/src/game/block/BlockStainedGlass.java +++ b/java/src/game/block/BlockStainedGlass.java @@ -7,10 +7,11 @@ import game.item.CheatTab; import game.item.Item; import game.item.ItemStack; import game.material.Material; +import game.model.BlockLayer; +import game.model.Model; +import game.model.ModelProvider; import game.properties.IProperty; import game.properties.PropertyEnum; -import game.renderer.BlockLayer; -import game.renderer.blockmodel.ModelBlock; import game.rng.Random; import game.world.State; @@ -113,7 +114,7 @@ public class BlockStainedGlass extends BlockBreakable return new IProperty[] {COLOR}; } - public ModelBlock getModel(String name, State state) { - return new ModelBlock(state.getValue(COLOR).getName() + "_glass").add().all(); + public Model getModel(ModelProvider provider, String name, State state) { + return provider.getModel(state.getValue(COLOR).getName() + "_glass").add().all(); } } diff --git a/java/src/game/block/BlockStainedGlassPane.java b/java/src/game/block/BlockStainedGlassPane.java index 7642973..405b2b1 100755 --- a/java/src/game/block/BlockStainedGlassPane.java +++ b/java/src/game/block/BlockStainedGlassPane.java @@ -7,9 +7,9 @@ import game.item.CheatTab; import game.item.Item; import game.item.ItemStack; import game.material.Material; +import game.model.BlockLayer; import game.properties.IProperty; import game.properties.PropertyEnum; -import game.renderer.BlockLayer; import game.world.State; public class BlockStainedGlassPane extends BlockPane diff --git a/java/src/game/block/BlockStairs.java b/java/src/game/block/BlockStairs.java index 6b035eb..ed7fb59 100755 --- a/java/src/game/block/BlockStairs.java +++ b/java/src/game/block/BlockStairs.java @@ -10,14 +10,15 @@ import game.init.BlockRegistry; import game.init.Blocks; import game.item.CheatTab; import game.material.Material; +import game.model.BlockLayer; +import game.model.Model; +import game.model.ModelProvider; +import game.model.Transforms; import game.properties.IProperty; -import game.properties.IStringSerializable; import game.properties.PropertyDirection; import game.properties.PropertyEnum; -import game.renderer.BlockLayer; -import game.renderer.blockmodel.ModelBlock; -import game.renderer.blockmodel.Transforms; import game.rng.Random; +import game.util.Identifyable; import game.world.BlockPos; import game.world.BoundingBox; import game.world.Explosion; @@ -812,10 +813,10 @@ public class BlockStairs extends Block return Transforms.STAIRS; } - public ModelBlock getModel(String name, State state) { - String primary = this.modelBlock.getModel(BlockRegistry.REGISTRY.getNameForObject(this.modelBlock).toString(), this.modelState) + public Model getModel(ModelProvider provider, String name, State state) { + String primary = this.modelBlock.getModel(provider, BlockRegistry.REGISTRY.getNameForObject(this.modelBlock).toString(), this.modelState) .getPrimary(); - return new ModelBlock(primary) + return provider.getModel(primary) .stairs(state.getValue(HALF) == EnumHalf.TOP, state.getValue(SHAPE) == EnumShape.INNER_RIGHT || state.getValue(SHAPE) == EnumShape.INNER_LEFT, state.getValue(SHAPE) == EnumShape.OUTER_RIGHT || state.getValue(SHAPE) == EnumShape.OUTER_LEFT, state.getValue(SHAPE) == EnumShape.INNER_LEFT || @@ -828,7 +829,7 @@ public class BlockStairs extends Block ); } - public static enum EnumHalf implements IStringSerializable + public static enum EnumHalf implements Identifyable { TOP("top"), BOTTOM("bottom"); @@ -851,7 +852,7 @@ public class BlockStairs extends Block } } - public static enum EnumShape implements IStringSerializable + public static enum EnumShape implements Identifyable { STRAIGHT("straight"), INNER_LEFT("inner_left"), diff --git a/java/src/game/block/BlockStem.java b/java/src/game/block/BlockStem.java index f8b3364..5b715de 100755 --- a/java/src/game/block/BlockStem.java +++ b/java/src/game/block/BlockStem.java @@ -9,11 +9,12 @@ import game.item.CheatTab; import game.item.Item; import game.item.ItemStack; import game.material.Material; +import game.model.Model; +import game.model.ModelProvider; import game.model.ModelRotation; import game.properties.IProperty; import game.properties.PropertyDirection; import game.properties.PropertyInteger; -import game.renderer.blockmodel.ModelBlock; import game.rng.Random; import game.world.BlockPos; import game.world.Facing; @@ -238,13 +239,13 @@ public class BlockStem extends BlockBush implements IGrowable return new IProperty[] {AGE, FACING}; } - public ModelBlock getModel(String name, State state) { + public Model getModel(ModelProvider provider, String name, State state) { String stem = name; String upperstem = name + "_connected"; if(state.getValue(FACING) == Facing.UP) { switch(state.getValue(AGE)) { case 0: - return new ModelBlock(stem).noOcclude() + return provider.getModel(stem).noOcclude() .add(0, -1, 8, 16, 1, 8).rotate(8, 8, 8, Facing.Axis.Y, 45, true) .n().uv(0, 0, 16, 2).tint().noCull() .s().uv(16, 0, 0, 2).tint().noCull() @@ -252,7 +253,7 @@ public class BlockStem extends BlockBush implements IGrowable .w().uv(0, 0, 16, 2).tint().noCull() .e().uv(16, 0, 0, 2).tint().noCull(); case 1: - return new ModelBlock(stem).noOcclude() + return provider.getModel(stem).noOcclude() .add(0, -1, 8, 16, 3, 8).rotate(8, 8, 8, Facing.Axis.Y, 45, true) .n().uv(0, 0, 16, 4).tint().noCull() .s().uv(16, 0, 0, 4).tint().noCull() @@ -260,7 +261,7 @@ public class BlockStem extends BlockBush implements IGrowable .w().uv(0, 0, 16, 4).tint().noCull() .e().uv(16, 0, 0, 4).tint().noCull(); case 2: - return new ModelBlock(stem).noOcclude() + return provider.getModel(stem).noOcclude() .add(0, -1, 8, 16, 5, 8).rotate(8, 8, 8, Facing.Axis.Y, 45, true) .n().uv(0, 0, 16, 6).tint().noCull() .s().uv(16, 0, 0, 6).tint().noCull() @@ -268,7 +269,7 @@ public class BlockStem extends BlockBush implements IGrowable .w().uv(0, 0, 16, 6).tint().noCull() .e().uv(16, 0, 0, 6).tint().noCull(); case 3: - return new ModelBlock(stem).noOcclude() + return provider.getModel(stem).noOcclude() .add(0, -1, 8, 16, 7, 8).rotate(8, 8, 8, Facing.Axis.Y, 45, true) .n().uv(0, 0, 16, 8).tint().noCull() .s().uv(16, 0, 0, 8).tint().noCull() @@ -276,7 +277,7 @@ public class BlockStem extends BlockBush implements IGrowable .w().uv(0, 0, 16, 8).tint().noCull() .e().uv(16, 0, 0, 8).tint().noCull(); case 4: - return new ModelBlock(stem).noOcclude() + return provider.getModel(stem).noOcclude() .add(0, -1, 8, 16, 9, 8).rotate(8, 8, 8, Facing.Axis.Y, 45, true) .n().uv(0, 0, 16, 10).tint().noCull() .s().uv(16, 0, 0, 10).tint().noCull() @@ -284,7 +285,7 @@ public class BlockStem extends BlockBush implements IGrowable .w().uv(0, 0, 16, 10).tint().noCull() .e().uv(16, 0, 0, 10).tint().noCull(); case 5: - return new ModelBlock(stem).noOcclude() + return provider.getModel(stem).noOcclude() .add(0, -1, 8, 16, 11, 8).rotate(8, 8, 8, Facing.Axis.Y, 45, true) .n().uv(0, 0, 16, 12).tint().noCull() .s().uv(16, 0, 0, 12).tint().noCull() @@ -292,7 +293,7 @@ public class BlockStem extends BlockBush implements IGrowable .w().uv(0, 0, 16, 12).tint().noCull() .e().uv(16, 0, 0, 12).tint().noCull(); case 6: - return new ModelBlock(stem).noOcclude() + return provider.getModel(stem).noOcclude() .add(0, -1, 8, 16, 13, 8).rotate(8, 8, 8, Facing.Axis.Y, 45, true) .n().uv(0, 0, 16, 14).tint().noCull() .s().uv(16, 0, 0, 14).tint().noCull() @@ -301,7 +302,7 @@ public class BlockStem extends BlockBush implements IGrowable .e().uv(16, 0, 0, 14).tint().noCull(); case 7: default: - return new ModelBlock(stem).noOcclude() + return provider.getModel(stem).noOcclude() .add(0, -1, 8, 16, 15, 8).rotate(8, 8, 8, Facing.Axis.Y, 45, true) .n().uv(0, 0, 16, 16).tint().noCull() .s().uv(16, 0, 0, 16).tint().noCull() @@ -311,7 +312,7 @@ public class BlockStem extends BlockBush implements IGrowable } } else { - return new ModelBlock(stem).noOcclude() + return provider.getModel(stem).noOcclude() .add(0, -1, 8, 16, 7, 8).rotate(8, 8, 8, Facing.Axis.Y, 45, true) .n().uv(0, 0, 16, 8).tint().noCull() .s().uv(16, 0, 0, 8).tint().noCull() diff --git a/java/src/game/block/BlockStoneBrick.java b/java/src/game/block/BlockStoneBrick.java index 3b0389d..5300cf5 100755 --- a/java/src/game/block/BlockStoneBrick.java +++ b/java/src/game/block/BlockStoneBrick.java @@ -6,10 +6,11 @@ import game.item.CheatTab; import game.item.Item; import game.item.ItemStack; import game.material.Material; +import game.model.Model; +import game.model.ModelProvider; import game.properties.IProperty; -import game.properties.IStringSerializable; import game.properties.PropertyEnum; -import game.renderer.blockmodel.ModelBlock; +import game.util.Identifyable; import game.world.State; public class BlockStoneBrick extends Block @@ -68,11 +69,11 @@ public class BlockStoneBrick extends Block return new IProperty[] {VARIANT}; } - public ModelBlock getModel(String name, State state) { - return new ModelBlock("stonebrick_" + state.getValue(VARIANT).getTexture()).add().all(); + public Model getModel(ModelProvider provider, String name, State state) { + return provider.getModel("stonebrick_" + state.getValue(VARIANT).getTexture()).add().all(); } - public static enum EnumType implements IStringSerializable + public static enum EnumType implements Identifyable { DEFAULT("default", 0, "stonebrick", "Steinziegel"), MOSSY("mossy", 1, "mossy_stonebrick", "Bemooste Steinziegel"), diff --git a/java/src/game/block/BlockTNT.java b/java/src/game/block/BlockTNT.java index 843a60b..17e4550 100755 --- a/java/src/game/block/BlockTNT.java +++ b/java/src/game/block/BlockTNT.java @@ -13,10 +13,11 @@ import game.item.CheatTab; import game.item.Item; import game.item.ItemStack; import game.material.Material; +import game.model.Model; +import game.model.ModelProvider; import game.properties.IProperty; import game.properties.PropertyBool; import game.properties.PropertyInteger; -import game.renderer.blockmodel.ModelBlock; import game.world.BlockPos; import game.world.Explosion; import game.world.Facing; @@ -183,9 +184,9 @@ public class BlockTNT extends Block return true; } - public ModelBlock getModel(String name, State state) { + public Model getModel(ModelProvider provider, String name, State state) { String power = state.getValue(POWER) == 0 ? "" : ("_" + state.getValue(POWER)); - return new ModelBlock("tnt_side" + power).add().nswe().d("tnt_bottom" + power).u("tnt_top" + power); + return provider.getModel("tnt_side" + power).add().nswe().d("tnt_bottom" + power).u("tnt_top" + power); } public IProperty[] getIgnoredProperties() { diff --git a/java/src/game/block/BlockTallGrass.java b/java/src/game/block/BlockTallGrass.java index 0ac4605..bcf86a7 100755 --- a/java/src/game/block/BlockTallGrass.java +++ b/java/src/game/block/BlockTallGrass.java @@ -12,12 +12,13 @@ import game.item.Item; import game.item.ItemShears; import game.item.ItemStack; import game.material.Material; +import game.model.Model; +import game.model.ModelProvider; import game.properties.IProperty; -import game.properties.IStringSerializable; import game.properties.PropertyEnum; -import game.renderer.blockmodel.ModelBlock; import game.rng.Random; import game.tileentity.TileEntity; +import game.util.Identifyable; import game.world.BlockPos; import game.world.IWorldAccess; import game.world.State; @@ -187,14 +188,14 @@ public class BlockTallGrass extends BlockBush implements IGrowable // return EnumOffsetType.XYZ; // } - public ModelBlock getModel(String name, State state) { + public Model getModel(ModelProvider provider, String name, State state) { if(state.getValue(TYPE) != EnumType.DEAD_BUSH) - return new ModelBlock(state.getValue(TYPE).getName()).crossTint(); + return provider.getModel(state.getValue(TYPE).getName()).crossTint(); else - return new ModelBlock("deadbush").cross(); + return provider.getModel("deadbush").cross(); } - public static enum EnumType implements IStringSerializable + public static enum EnumType implements Identifyable { DEAD_BUSH(0, "dead_bush"), GRASS(1, "tall_grass"), diff --git a/java/src/game/block/BlockTianReactor.java b/java/src/game/block/BlockTianReactor.java index f480c46..f1b7ca0 100755 --- a/java/src/game/block/BlockTianReactor.java +++ b/java/src/game/block/BlockTianReactor.java @@ -2,8 +2,9 @@ package game.block; import java.util.Map; +import game.model.Model; +import game.model.ModelProvider; import game.model.ModelRotation; -import game.renderer.blockmodel.ModelBlock; import game.tileentity.TileEntity; import game.tileentity.TileEntityTianReactor; import game.world.State; @@ -14,8 +15,8 @@ public class BlockTianReactor extends BlockMachine { return new TileEntityTianReactor(); } - public ModelBlock getModel(String name, State state) { - return new ModelBlock("tian_reactor_front").add().d("tian_reactor_bottom").u("tian_reactor_top").n().s("tian_reactor_side") + public Model getModel(ModelProvider provider, String name, State state) { + return provider.getModel("tian_reactor_front").add().d("tian_reactor_bottom").u("tian_reactor_top").n().s("tian_reactor_side") .we("tian_reactor_side").rotate(ModelRotation.getNorthRot(state.getValue(FACING))); } diff --git a/java/src/game/block/BlockTianSoil.java b/java/src/game/block/BlockTianSoil.java index fbfea0f..e898bae 100755 --- a/java/src/game/block/BlockTianSoil.java +++ b/java/src/game/block/BlockTianSoil.java @@ -4,9 +4,10 @@ import game.init.Blocks; import game.item.CheatTab; import game.item.Item; import game.material.Material; +import game.model.Model; +import game.model.ModelProvider; import game.properties.IProperty; import game.properties.PropertyBool; -import game.renderer.blockmodel.ModelBlock; import game.rng.Random; import game.world.BlockPos; import game.world.IWorldAccess; @@ -44,10 +45,10 @@ public class BlockTianSoil extends Block return new IProperty[] {SNOWY}; } - public ModelBlock getModel(String name, State state) { + public Model getModel(ModelProvider provider, String name, State state) { if(state.getValue(SNOWY)) - return new ModelBlock("tian_soil_side_snowed").add().nswe().d("tian").u("grass_top"); + return provider.getModel("tian_soil_side_snowed").add().nswe().d("tian").u("grass_top"); else - return new ModelBlock("tian_soil_side").add().nswe().d("tian").u("tian_soil_top"); + return provider.getModel("tian_soil_side").add().nswe().d("tian").u("tian_soil_top"); } } diff --git a/java/src/game/block/BlockTorch.java b/java/src/game/block/BlockTorch.java index 5aff3b1..717009c 100755 --- a/java/src/game/block/BlockTorch.java +++ b/java/src/game/block/BlockTorch.java @@ -6,12 +6,13 @@ import game.entity.types.EntityLiving; import game.init.Blocks; import game.item.CheatTab; import game.material.Material; +import game.model.BlockLayer; +import game.model.Model; +import game.model.ModelProvider; import game.model.ModelRotation; +import game.model.ParticleType; import game.properties.IProperty; import game.properties.PropertyDirection; -import game.renderer.BlockLayer; -import game.renderer.blockmodel.ModelBlock; -import game.renderer.particle.ParticleType; import game.rng.Random; import game.world.BlockPos; import game.world.BoundingBox; @@ -332,9 +333,9 @@ public class BlockTorch extends Block return new IProperty[] {FACING}; } - public ModelBlock getModel(String name, State state) { + public Model getModel(ModelProvider provider, String name, State state) { if(state.getValue(FACING) == Facing.UP) - return new ModelBlock(name).noOcclude() + return provider.getModel(name).noOcclude() .add(7, 0, 7, 9, 10, 9).noShade() .d().uv(7, 13, 9, 15).noCull() .u().uv(7, 6, 9, 8).noCull() @@ -345,7 +346,7 @@ public class BlockTorch extends Block .n().uv(0, 0, 16, 16).noCull() .s().uv(0, 0, 16, 16).noCull(); else - return new ModelBlock(name).noOcclude() + return provider.getModel(name).noOcclude() .add(-1, 3.5f, 7, 1, 13.5f, 9).noShade().rotate(0, 3.5f, 8, Facing.Axis.Z, -22.5f, false) .d().uv(7, 13, 9, 15).noCull() .u().uv(7, 6, 9, 8).noCull() diff --git a/java/src/game/block/BlockTrapDoor.java b/java/src/game/block/BlockTrapDoor.java index edc6932..55ffc46 100755 --- a/java/src/game/block/BlockTrapDoor.java +++ b/java/src/game/block/BlockTrapDoor.java @@ -5,15 +5,16 @@ import game.entity.types.EntityLiving; import game.init.Blocks; import game.item.CheatTab; import game.material.Material; +import game.model.BlockLayer; +import game.model.Model; +import game.model.ModelProvider; import game.model.ModelRotation; +import game.model.Transforms; import game.properties.IProperty; -import game.properties.IStringSerializable; import game.properties.PropertyBool; import game.properties.PropertyDirection; import game.properties.PropertyEnum; -import game.renderer.BlockLayer; -import game.renderer.blockmodel.ModelBlock; -import game.renderer.blockmodel.Transforms; +import game.util.Identifyable; import game.world.BlockPos; import game.world.BoundingBox; import game.world.Facing; @@ -298,10 +299,10 @@ public class BlockTrapDoor extends Block return Transforms.FLAT; } - public ModelBlock getModel(String name, State state) { - ModelBlock model; + public Model getModel(ModelProvider provider, String name, State state) { + Model model; if(state.getValue(OPEN)) { - model = new ModelBlock(name) + model = provider.getModel(name) .add(0, 0, 13, 16, 16, 16) .d().uv(0, 13, 16, 16) .u().uv(0, 16, 16, 13) @@ -311,7 +312,7 @@ public class BlockTrapDoor extends Block .e().uv(13, 0, 16, 16); } else if(state.getValue(HALF) == DoorHalf.TOP) { - model = new ModelBlock(name) + model = provider.getModel(name) .add(0, 13, 0, 16, 16, 16) .d().uv(0, 0, 16, 16).noCull() .u().uv(0, 0, 16, 16) @@ -321,7 +322,7 @@ public class BlockTrapDoor extends Block .e().uv(0, 16, 16, 13); } else { - model = new ModelBlock(name) + model = provider.getModel(name) .add(0, 0, 0, 16, 3, 16) .d().uv(0, 0, 16, 16) .u().uv(0, 0, 16, 16).noCull() @@ -333,7 +334,7 @@ public class BlockTrapDoor extends Block return model.rotate(ModelRotation.getNorthRot(state.getValue(FACING))); } - public static enum DoorHalf implements IStringSerializable + public static enum DoorHalf implements Identifyable { TOP("top"), BOTTOM("bottom"); diff --git a/java/src/game/block/BlockTripWire.java b/java/src/game/block/BlockTripWire.java index 7252904..11e1a08 100755 --- a/java/src/game/block/BlockTripWire.java +++ b/java/src/game/block/BlockTripWire.java @@ -9,11 +9,12 @@ import game.init.Items; import game.item.Item; import game.item.ItemShears; import game.material.Material; +import game.model.BlockLayer; +import game.model.Model; +import game.model.ModelProvider; import game.model.ModelRotation; import game.properties.IProperty; import game.properties.PropertyBool; -import game.renderer.BlockLayer; -import game.renderer.blockmodel.ModelBlock; import game.rng.Random; import game.world.BlockPos; import game.world.BoundingBox; @@ -303,9 +304,9 @@ public class BlockTripWire extends Block return new IProperty[] {POWERED, SUSPENDED, ATTACHED, DISARMED, NORTH, EAST, WEST, SOUTH}; } - private static ModelBlock getModelDetached(boolean n, boolean s, boolean w, boolean e, int sides) { + private static Model getModelDetached(boolean n, boolean s, boolean w, boolean e, int sides) { if(sides == 1) - return new ModelBlock("trip_wire").noOcclude() + return ModelProvider.getModelProvider().getModel("trip_wire").noOcclude() .add(7.75f, 1.5f, 0, 8.25f, 1.5f, 4).noShade() .d().uv(0, 2, 16, 0).rot(90).noCull() .u().uv(0, 0, 16, 2).rot(90).noCull() @@ -317,7 +318,7 @@ public class BlockTripWire extends Block .u().uv(0, 0, 16, 2).rot(90).noCull() .rotate(n ? ModelRotation.X0_Y0 : (s ? ModelRotation.X0_Y180 : (w ? ModelRotation.X0_Y270 : ModelRotation.X0_Y90))); else if(sides == 2 && ((e != w) || (n != s))) - return new ModelBlock("trip_wire").noOcclude() + return ModelProvider.getModelProvider().getModel("trip_wire").noOcclude() .add(7.75f, 1.5f, 0, 8.25f, 1.5f, 4).noShade() .d().uv(0, 2, 16, 0).rot(90).noCull() .u().uv(0, 0, 16, 2).rot(90).noCull() @@ -333,7 +334,7 @@ public class BlockTripWire extends Block .rotate(n && e ? ModelRotation.X0_Y0 : (s && w ? ModelRotation.X0_Y180 : (n && w ? ModelRotation.X0_Y270 : ModelRotation.X0_Y90))); else if(sides == 2) - return new ModelBlock("trip_wire").noOcclude() + return ModelProvider.getModelProvider().getModel("trip_wire").noOcclude() .add(7.75f, 1.5f, 0, 8.25f, 1.5f, 4).noShade() .d().uv(0, 2, 16, 0).rot(90).noCull() .u().uv(0, 0, 16, 2).rot(90).noCull() @@ -348,7 +349,7 @@ public class BlockTripWire extends Block .u().uv(0, 0, 16, 2).rot(90).noCull() .rotate(n ? ModelRotation.X0_Y0 : ModelRotation.X0_Y90); else if(sides == 3) - return new ModelBlock("trip_wire").noOcclude() + return ModelProvider.getModelProvider().getModel("trip_wire").noOcclude() .add(7.75f, 1.5f, 0, 8.25f, 1.5f, 4).noShade() .d().uv(0, 2, 16, 0).rot(90).noCull() .u().uv(0, 0, 16, 2).rot(90).noCull() @@ -369,7 +370,7 @@ public class BlockTripWire extends Block .u().uv(0, 0, 16, 2).noCull() .rotate(!w ? ModelRotation.X0_Y0 : (!e ? ModelRotation.X0_Y180 : (!s ? ModelRotation.X0_Y270 : ModelRotation.X0_Y90))); else - return new ModelBlock("trip_wire").noOcclude() + return ModelProvider.getModelProvider().getModel("trip_wire").noOcclude() .add(7.75f, 1.5f, 0, 8.25f, 1.5f, 4).noShade() .d().uv(0, 2, 16, 0).rot(90).noCull() .u().uv(0, 0, 16, 2).rot(90).noCull() @@ -396,9 +397,9 @@ public class BlockTripWire extends Block .u().uv(0, 0, 16, 2).noCull(); } - private static ModelBlock getModelAttached(boolean n, boolean s, boolean w, boolean e, int sides) { + private static Model getModelAttached(boolean n, boolean s, boolean w, boolean e, int sides) { if(sides == 1) - return new ModelBlock("trip_wire").noOcclude() + return ModelProvider.getModelProvider().getModel("trip_wire").noOcclude() .add(7.75f, 1.5f, 0, 8.25f, 1.5f, 4).noShade() .d().uv(0, 4, 16, 2).rot(90).noCull() .u().uv(0, 2, 16, 4).rot(90).noCull() @@ -410,7 +411,7 @@ public class BlockTripWire extends Block .u().uv(0, 2, 16, 4).rot(90).noCull() .rotate(n ? ModelRotation.X0_Y0 : (s ? ModelRotation.X0_Y180 : (w ? ModelRotation.X0_Y270 : ModelRotation.X0_Y90))); else if(sides == 2 && ((e != w) || (n != s))) - return new ModelBlock("trip_wire").noOcclude() + return ModelProvider.getModelProvider().getModel("trip_wire").noOcclude() .add(7.75f, 1.5f, 0, 8.25f, 1.5f, 4).noShade() .d().uv(0, 4, 16, 2).rot(90).noCull() .u().uv(0, 2, 16, 4).rot(90).noCull() @@ -426,7 +427,7 @@ public class BlockTripWire extends Block .rotate(n && e ? ModelRotation.X0_Y0 : (s && w ? ModelRotation.X0_Y180 : (n && w ? ModelRotation.X0_Y270 : ModelRotation.X0_Y90))); else if(sides == 2) - return new ModelBlock("trip_wire").noOcclude() + return ModelProvider.getModelProvider().getModel("trip_wire").noOcclude() .add(7.75f, 1.5f, 0, 8.25f, 1.5f, 4).noShade() .d().uv(0, 4, 16, 2).rot(90).noCull() .u().uv(0, 2, 16, 4).rot(90).noCull() @@ -441,7 +442,7 @@ public class BlockTripWire extends Block .u().uv(0, 2, 16, 4).rot(90).noCull() .rotate(n ? ModelRotation.X0_Y0 : ModelRotation.X0_Y90); else if(sides == 3) - return new ModelBlock("trip_wire").noOcclude() + return ModelProvider.getModelProvider().getModel("trip_wire").noOcclude() .add(7.75f, 1.5f, 0, 8.25f, 1.5f, 4).noShade() .d().uv(0, 4, 16, 2).rot(90).noCull() .u().uv(0, 2, 16, 4).rot(90).noCull() @@ -462,7 +463,7 @@ public class BlockTripWire extends Block .u().uv(0, 2, 16, 4).noCull() .rotate(!w ? ModelRotation.X0_Y0 : (!e ? ModelRotation.X0_Y180 : (!s ? ModelRotation.X0_Y270 : ModelRotation.X0_Y90))); else - return new ModelBlock("trip_wire").noOcclude() + return ModelProvider.getModelProvider().getModel("trip_wire").noOcclude() .add(7.75f, 1.5f, 0, 8.25f, 1.5f, 4).noShade() .d().uv(0, 4, 16, 2).rot(90).noCull() .u().uv(0, 2, 16, 4).rot(90).noCull() @@ -489,9 +490,9 @@ public class BlockTripWire extends Block .u().uv(0, 2, 16, 4).noCull(); } - private static ModelBlock getModelDetSuspend(boolean n, boolean s, boolean w, boolean e, int sides) { + private static Model getModelDetSuspend(boolean n, boolean s, boolean w, boolean e, int sides) { if(sides == 1) - return new ModelBlock("trip_wire").noOcclude() + return ModelProvider.getModelProvider().getModel("trip_wire").noOcclude() .add(7.75f, 3.5f, 0, 8.25f, 3.5f, 4).noShade() .d().uv(0, 2, 16, 0).rot(90).noCull() .u().uv(0, 0, 16, 2).rot(90).noCull() @@ -503,7 +504,7 @@ public class BlockTripWire extends Block .u().uv(0, 0, 16, 2).rot(90).noCull() .rotate(n ? ModelRotation.X0_Y0 : (s ? ModelRotation.X0_Y180 : (w ? ModelRotation.X0_Y270 : ModelRotation.X0_Y90))); else if(sides == 2 && ((e != w) || (n != s))) - return new ModelBlock("trip_wire").noOcclude() + return ModelProvider.getModelProvider().getModel("trip_wire").noOcclude() .add(7.75f, 3.5f, 0, 8.25f, 3.5f, 4).noShade() .d().uv(0, 2, 16, 0).rot(90).noCull() .u().uv(0, 0, 16, 2).rot(90).noCull() @@ -519,7 +520,7 @@ public class BlockTripWire extends Block .rotate(n && e ? ModelRotation.X0_Y0 : (s && w ? ModelRotation.X0_Y180 : (n && w ? ModelRotation.X0_Y270 : ModelRotation.X0_Y90))); else if(sides == 2) - return new ModelBlock("trip_wire").noOcclude() + return ModelProvider.getModelProvider().getModel("trip_wire").noOcclude() .add(7.75f, 3.5f, 0, 8.25f, 3.5f, 4).noShade() .d().uv(0, 2, 16, 0).rot(90).noCull() .u().uv(0, 0, 16, 2).rot(90).noCull() @@ -534,7 +535,7 @@ public class BlockTripWire extends Block .u().uv(0, 0, 16, 2).rot(90).noCull() .rotate(n ? ModelRotation.X0_Y0 : ModelRotation.X0_Y90); else if(sides == 3) - return new ModelBlock("trip_wire").noOcclude() + return ModelProvider.getModelProvider().getModel("trip_wire").noOcclude() .add(7.75f, 3.5f, 0, 8.25f, 3.5f, 4).noShade() .d().uv(0, 2, 16, 0).rot(90).noCull() .u().uv(0, 0, 16, 2).rot(90).noCull() @@ -555,7 +556,7 @@ public class BlockTripWire extends Block .u().uv(0, 0, 16, 2).noCull() .rotate(!w ? ModelRotation.X0_Y0 : (!e ? ModelRotation.X0_Y180 : (!s ? ModelRotation.X0_Y270 : ModelRotation.X0_Y90))); else - return new ModelBlock("trip_wire").noOcclude() + return ModelProvider.getModelProvider().getModel("trip_wire").noOcclude() .add(7.75f, 3.5f, 0, 8.25f, 3.5f, 4).noShade() .d().uv(0, 2, 16, 0).rot(90).noCull() .u().uv(0, 0, 16, 2).rot(90).noCull() @@ -582,9 +583,9 @@ public class BlockTripWire extends Block .u().uv(0, 0, 16, 2).noCull(); } - private static ModelBlock getModelAttSuspend(boolean n, boolean s, boolean w, boolean e, int sides) { + private static Model getModelAttSuspend(boolean n, boolean s, boolean w, boolean e, int sides) { if(sides == 1) - return new ModelBlock("trip_wire").noOcclude() + return ModelProvider.getModelProvider().getModel("trip_wire").noOcclude() .add(7.75f, 3.5f, 0, 8.25f, 3.5f, 4).noShade() .d().uv(0, 4, 16, 2).rot(90).noCull() .u().uv(0, 2, 16, 4).rot(90).noCull() @@ -596,7 +597,7 @@ public class BlockTripWire extends Block .u().uv(0, 2, 16, 4).rot(90).noCull() .rotate(n ? ModelRotation.X0_Y0 : (s ? ModelRotation.X0_Y180 : (w ? ModelRotation.X0_Y270 : ModelRotation.X0_Y90))); else if(sides == 2 && ((e != w) || (n != s))) - return new ModelBlock("trip_wire").noOcclude() + return ModelProvider.getModelProvider().getModel("trip_wire").noOcclude() .add(7.75f, 3.5f, 0, 8.25f, 3.5f, 4).noShade() .d().uv(0, 4, 16, 2).rot(90).noCull() .u().uv(0, 2, 16, 4).rot(90).noCull() @@ -612,7 +613,7 @@ public class BlockTripWire extends Block .rotate(n && e ? ModelRotation.X0_Y0 : (s && w ? ModelRotation.X0_Y180 : (n && w ? ModelRotation.X0_Y270 : ModelRotation.X0_Y90))); else if(sides == 2) - return new ModelBlock("trip_wire").noOcclude() + return ModelProvider.getModelProvider().getModel("trip_wire").noOcclude() .add(7.75f, 3.5f, 0, 8.25f, 3.5f, 4).noShade() .d().uv(0, 4, 16, 2).rot(90).noCull() .u().uv(0, 2, 16, 4).rot(90).noCull() @@ -627,7 +628,7 @@ public class BlockTripWire extends Block .u().uv(0, 2, 16, 4).rot(90).noCull() .rotate(n ? ModelRotation.X0_Y0 : ModelRotation.X0_Y90); else if(sides == 3) - return new ModelBlock("trip_wire").noOcclude() + return ModelProvider.getModelProvider().getModel("trip_wire").noOcclude() .add(7.75f, 3.5f, 0, 8.25f, 3.5f, 4).noShade() .d().uv(0, 4, 16, 2).rot(90).noCull() .u().uv(0, 2, 16, 4).rot(90).noCull() @@ -648,7 +649,7 @@ public class BlockTripWire extends Block .u().uv(0, 2, 16, 4).noCull() .rotate(!w ? ModelRotation.X0_Y0 : (!e ? ModelRotation.X0_Y180 : (!s ? ModelRotation.X0_Y270 : ModelRotation.X0_Y90))); else - return new ModelBlock("trip_wire").noOcclude() + return ModelProvider.getModelProvider().getModel("trip_wire").noOcclude() .add(7.75f, 3.5f, 0, 8.25f, 3.5f, 4).noShade() .d().uv(0, 4, 16, 2).rot(90).noCull() .u().uv(0, 2, 16, 4).rot(90).noCull() @@ -675,7 +676,7 @@ public class BlockTripWire extends Block .u().uv(0, 2, 16, 4).noCull(); } - public ModelBlock getModel(String name, State state) { + public Model getModel(ModelProvider provider, String name, State state) { boolean n = state.getValue(NORTH); boolean s = state.getValue(SOUTH); boolean w = state.getValue(WEST); diff --git a/java/src/game/block/BlockTripWireHook.java b/java/src/game/block/BlockTripWireHook.java index c1cfb43..5dc6835 100755 --- a/java/src/game/block/BlockTripWireHook.java +++ b/java/src/game/block/BlockTripWireHook.java @@ -6,12 +6,13 @@ import game.init.SoundEvent; import game.item.CheatTab; import game.item.ItemStack; import game.material.Material; +import game.model.BlockLayer; +import game.model.Model; +import game.model.ModelProvider; import game.model.ModelRotation; import game.properties.IProperty; import game.properties.PropertyBool; import game.properties.PropertyDirection; -import game.renderer.BlockLayer; -import game.renderer.blockmodel.ModelBlock; import game.rng.Random; import game.world.BlockPos; import game.world.BoundingBox; @@ -377,12 +378,12 @@ public class BlockTripWireHook extends Block return true; } - public ModelBlock getModel(String name, State state) { - ModelBlock model; + public Model getModel(ModelProvider provider, String name, State state) { + Model model; if(state.getValue(ATTACHED)) { if(state.getValue(SUSPENDED)) { if(state.getValue(POWERED)) - model = new ModelBlock("oak_planks") + model = provider.getModel("oak_planks") .add(7.75f, 2.5f, 0, 8.25f, 2.5f, 6.7f).rotate(8, 0, 0, Facing.Axis.X, -22.5f, true) .d("trip_wire").uv(0, 8, 16, 6).rot(90).noCull() .u("trip_wire").uv(0, 6, 16, 8).rot(90).noCull() @@ -416,7 +417,7 @@ public class BlockTripWireHook extends Block .w().uv(0, 7, 2, 15).noCull() .e().uv(14, 7, 16, 15).noCull(); else - model = new ModelBlock("oak_planks") + model = provider.getModel("oak_planks") .add(7.75f, 3.5f, 0, 8.25f, 3.5f, 6.7f).rotate(8, 0, 0, Facing.Axis.X, -22.5f, true) .d("trip_wire").uv(0, 8, 16, 6).rot(90).noCull() .u("trip_wire").uv(0, 6, 16, 8).rot(90).noCull() @@ -452,7 +453,7 @@ public class BlockTripWireHook extends Block } else { if(state.getValue(POWERED)) - model = new ModelBlock("oak_planks") + model = provider.getModel("oak_planks") .add(7.75f, 0.5f, 0, 8.25f, 0.5f, 6.7f).rotate(8, 0, 0, Facing.Axis.X, -22.5f, true) .d("trip_wire").uv(0, 8, 16, 6).rot(90).noCull() .u("trip_wire").uv(0, 6, 16, 8).rot(90).noCull() @@ -486,7 +487,7 @@ public class BlockTripWireHook extends Block .w().uv(0, 7, 2, 15).noCull() .e().uv(14, 7, 16, 15).noCull(); else - model = new ModelBlock("oak_planks") + model = provider.getModel("oak_planks") .add(7.75f, 1.5f, 0, 8.25f, 1.5f, 6.7f).rotate(8, 0, 0, Facing.Axis.X, -22.5f, true) .d("trip_wire").uv(0, 8, 16, 6).rot(90).noCull() .u("trip_wire").uv(0, 6, 16, 8).rot(90).noCull() @@ -523,7 +524,7 @@ public class BlockTripWireHook extends Block } else { if(state.getValue(POWERED)) - model = new ModelBlock("oak_planks") + model = provider.getModel("oak_planks") .add(6.2f, 4.2f, 6.7f, 9.8f, 5, 10.3f) .d("tripwire_hook").uv(5, 3, 11, 9).noCull() .u("tripwire_hook").uv(5, 3, 11, 9).noCull() @@ -554,7 +555,7 @@ public class BlockTripWireHook extends Block .w().uv(0, 7, 2, 15).noCull() .e().uv(14, 7, 16, 15).noCull(); else - model = new ModelBlock("oak_planks") + model = provider.getModel("oak_planks") .add(6.2f, 3.8f, 7.9f, 9.8f, 4.6f, 11.5f).rotate(8, 6, 5.2f, Facing.Axis.X, -45, false) .d("tripwire_hook").uv(5, 3, 11, 9).noCull() .u("tripwire_hook").uv(5, 3, 11, 9).noCull() diff --git a/java/src/game/block/BlockVine.java b/java/src/game/block/BlockVine.java index 779cd88..b7d516e 100755 --- a/java/src/game/block/BlockVine.java +++ b/java/src/game/block/BlockVine.java @@ -10,11 +10,12 @@ import game.item.Item; import game.item.ItemShears; import game.item.ItemStack; import game.material.Material; +import game.model.BlockLayer; +import game.model.Model; +import game.model.ModelProvider; import game.model.ModelRotation; import game.properties.IProperty; import game.properties.PropertyBool; -import game.renderer.BlockLayer; -import game.renderer.blockmodel.ModelBlock; import game.rng.Random; import game.tileentity.TileEntity; import game.world.BlockPos; @@ -518,8 +519,8 @@ public class BlockVine extends Block return i; } - public ModelBlock getModel(String name, State state) { - ModelBlock model = new ModelBlock("vine").noOcclude(); + public Model getModel(ModelProvider provider, String name, State state) { + Model model = provider.getModel("vine").noOcclude(); if(state.getValue(UP)) model.add(0, 15.2f, 0, 16, 15.2f, 16).noShade() .d().uv(0, 0, 16, 16).tint().noCull() diff --git a/java/src/game/block/BlockWall.java b/java/src/game/block/BlockWall.java index 38383f3..c49c0ca 100755 --- a/java/src/game/block/BlockWall.java +++ b/java/src/game/block/BlockWall.java @@ -6,12 +6,13 @@ import game.item.CheatTab; import game.item.Item; import game.item.ItemStack; import game.material.Material; +import game.model.Model; +import game.model.ModelProvider; import game.model.ModelRotation; import game.properties.IProperty; -import game.properties.IStringSerializable; import game.properties.PropertyBool; import game.properties.PropertyEnum; -import game.renderer.blockmodel.ModelBlock; +import game.util.Identifyable; import game.world.BlockPos; import game.world.BoundingBox; import game.world.Facing; @@ -181,7 +182,7 @@ public class BlockWall extends Block return new IProperty[] {UP, NORTH, EAST, WEST, SOUTH, VARIANT}; } - public ModelBlock getModel(String name, State state) { + public Model getModel(ModelProvider provider, String name, State state) { String wall = state.getValue(VARIANT).getName(); boolean n = state.getValue(NORTH); boolean s = state.getValue(SOUTH); @@ -189,7 +190,7 @@ public class BlockWall extends Block boolean e = state.getValue(EAST); int sides = (n ? 1 : 0) + (s ? 1 : 0) + (w ? 1 : 0) + (e ? 1 : 0); if(sides == 0) - return new ModelBlock(wall) + return provider.getModel(wall) .add(4, 0, 4, 12, 16, 12) .d().uv(4, 4, 12, 12) .u().uv(4, 4, 12, 12) @@ -198,7 +199,7 @@ public class BlockWall extends Block .w().uv(4, 0, 12, 16).noCull() .e().uv(4, 0, 12, 16).noCull(); else if(sides == 4) - return new ModelBlock(wall) + return provider.getModel(wall) .add(4, 0, 4, 12, 16, 12) .d().uv(4, 4, 12, 12) .u().uv(4, 4, 12, 12) @@ -231,7 +232,7 @@ public class BlockWall extends Block .s().uv(0, 3, 4, 16).noCull() .w().uv(5, 3, 11, 16); else if(sides == 1) - return new ModelBlock(wall).uvLock() + return provider.getModel(wall).uvLock() .add(4, 0, 4, 12, 16, 12) .d().uv(4, 4, 12, 12) .u().uv(4, 4, 12, 12) @@ -247,7 +248,7 @@ public class BlockWall extends Block .e().uv(0, 3, 4, 16).noCull() .rotate(n ? ModelRotation.X0_Y0 : (s ? ModelRotation.X0_Y180 : (w ? ModelRotation.X0_Y270 : ModelRotation.X0_Y90))); else if(sides == 2 && ((e != w) || (n != s))) - return new ModelBlock(wall).uvLock() + return provider.getModel(wall).uvLock() .add(4, 0, 4, 12, 16, 12) .d().uv(4, 4, 12, 12) .u().uv(4, 4, 12, 12) @@ -270,7 +271,7 @@ public class BlockWall extends Block .rotate(n && e ? ModelRotation.X0_Y0 : (s && w ? ModelRotation.X0_Y180 : (n && w ? ModelRotation.X0_Y270 : ModelRotation.X0_Y90))); else if(sides == 2 && state.getValue(UP)) - return new ModelBlock(wall).uvLock() + return provider.getModel(wall).uvLock() .add(4, 0, 4, 12, 16, 12) .d().uv(4, 4, 12, 12) .u().uv(4, 4, 12, 12) @@ -287,7 +288,7 @@ public class BlockWall extends Block .e().uv(0, 3, 16, 16).noCull() .rotate(n ? ModelRotation.X0_Y0 : ModelRotation.X0_Y90); else if(sides == 2) - return new ModelBlock(wall).uvLock() + return provider.getModel(wall).uvLock() .add(5, 0, 0, 11, 13, 16) .d().uv(5, 0, 11, 16) .u().uv(5, 0, 11, 16).noCull() @@ -297,7 +298,7 @@ public class BlockWall extends Block .e().uv(0, 3, 16, 16).noCull() .rotate(n ? ModelRotation.X0_Y0 : ModelRotation.X0_Y90); else - return new ModelBlock(wall).uvLock() + return provider.getModel(wall).uvLock() .add(4, 0, 4, 12, 16, 12) .d().uv(4, 4, 12, 12) .u().uv(4, 4, 12, 12) @@ -326,7 +327,7 @@ public class BlockWall extends Block .rotate(!w ? ModelRotation.X0_Y0 : (!e ? ModelRotation.X0_Y180 : (!s ? ModelRotation.X0_Y270 : ModelRotation.X0_Y90))); } - public static enum EnumType implements IStringSerializable + public static enum EnumType implements Identifyable { NORMAL(0, "cobblestone", "Bruchsteinmauer"), MOSSY(1, "mossy_cobblestone", "Bemooste Bruchsteinmauer"); diff --git a/java/src/game/block/BlockWarpChest.java b/java/src/game/block/BlockWarpChest.java index 423ad01..a8776d2 100755 --- a/java/src/game/block/BlockWarpChest.java +++ b/java/src/game/block/BlockWarpChest.java @@ -9,11 +9,12 @@ import game.item.CheatTab; import game.item.Item; import game.item.ItemStack; import game.material.Material; +import game.model.Model; +import game.model.ModelProvider; import game.model.ModelRotation; +import game.model.ParticleType; import game.properties.IProperty; import game.properties.PropertyDirection; -import game.renderer.blockmodel.ModelBlock; -import game.renderer.particle.ParticleType; import game.rng.Random; import game.world.BlockPos; import game.world.Facing; @@ -54,8 +55,8 @@ public class BlockWarpChest extends Block // return 2; // } - public ModelBlock getModel(String name, State state) { - return new ModelBlock("warp_chest_side").add(1, 0, 1, 15, 14, 15).d("warp_chest_top").u("warp_chest_top").noCull() + public Model getModel(ModelProvider provider, String name, State state) { + return provider.getModel("warp_chest_side").add(1, 0, 1, 15, 14, 15).d("warp_chest_top").u("warp_chest_top").noCull() .n("warp_chest_front").noCull().s().noCull().we().noCull().rotate(ModelRotation.getNorthRot(state.getValue(FACING))); } diff --git a/java/src/game/block/BlockWart.java b/java/src/game/block/BlockWart.java index ee31c6a..c77813c 100755 --- a/java/src/game/block/BlockWart.java +++ b/java/src/game/block/BlockWart.java @@ -7,9 +7,10 @@ import game.item.CheatTab; import game.item.Item; import game.item.ItemStack; import game.material.Material; +import game.model.Model; +import game.model.ModelProvider; import game.properties.IProperty; import game.properties.PropertyInteger; -import game.renderer.blockmodel.ModelBlock; import game.rng.Random; import game.world.BlockPos; import game.world.State; @@ -126,8 +127,8 @@ public class BlockWart extends BlockBush return new IProperty[] {AGE}; } - public ModelBlock getModel(String name, State state) { + public Model getModel(ModelProvider provider, String name, State state) { int age = state.getValue(AGE); - return BlockCrops.crop(name + "_" + (age >= 2 ? age - 1 : age)); + return BlockCrops.crop(provider, name + "_" + (age >= 2 ? age - 1 : age)); } } diff --git a/java/src/game/block/BlockWeb.java b/java/src/game/block/BlockWeb.java index e7cf5c4..261b092 100755 --- a/java/src/game/block/BlockWeb.java +++ b/java/src/game/block/BlockWeb.java @@ -5,8 +5,9 @@ import game.init.Items; import game.item.CheatTab; import game.item.Item; import game.material.Material; -import game.renderer.BlockLayer; -import game.renderer.blockmodel.ModelBlock; +import game.model.BlockLayer; +import game.model.Model; +import game.model.ModelProvider; import game.rng.Random; import game.world.BlockPos; import game.world.BoundingBox; @@ -65,7 +66,7 @@ public class BlockWeb extends Block return BlockLayer.CUTOUT; } - public ModelBlock getModel(String name, State state) { - return new ModelBlock("web").cross(); + public Model getModel(ModelProvider provider, String name, State state) { + return provider.getModel("web").cross(); } } diff --git a/java/src/game/block/BlockWorkbench.java b/java/src/game/block/BlockWorkbench.java index 453d852..a970372 100755 --- a/java/src/game/block/BlockWorkbench.java +++ b/java/src/game/block/BlockWorkbench.java @@ -6,7 +6,8 @@ import game.inventory.ContainerWorkbench; import game.inventory.InventoryPlayer; import game.item.CheatTab; import game.material.Material; -import game.renderer.blockmodel.ModelBlock; +import game.model.Model; +import game.model.ModelProvider; import game.tileentity.IInteractionObject; import game.world.BlockPos; import game.world.Facing; @@ -35,8 +36,8 @@ public class BlockWorkbench extends Block } } - public ModelBlock getModel(String name, State state) { - return new ModelBlock("crafting_table_front").add().d("oak_planks").u("crafting_table_top").n().s("crafting_table_side") + public Model getModel(ModelProvider provider, String name, State state) { + return provider.getModel("crafting_table_front").add().d("oak_planks").u("crafting_table_top").n().s("crafting_table_side") .w().e("crafting_table_side"); } diff --git a/java/src/game/block/LeavesType.java b/java/src/game/block/LeavesType.java index 22bc1cb..faa13f1 100755 --- a/java/src/game/block/LeavesType.java +++ b/java/src/game/block/LeavesType.java @@ -1,8 +1,8 @@ package game.block; -import game.properties.IStringSerializable; +import game.util.Identifyable; -public enum LeavesType implements IStringSerializable { +public enum LeavesType implements Identifyable { SPRING(0, "spring", true, "Frühling"), SUMMER(1, "summer", true, "Sommer"), AUTUMN(2, "autumn", false, "Herbst"), diff --git a/java/src/game/audio/SoundType.java b/java/src/game/block/SoundType.java similarity index 94% rename from java/src/game/audio/SoundType.java rename to java/src/game/block/SoundType.java index 74c6519..9dfc4ec 100755 --- a/java/src/game/audio/SoundType.java +++ b/java/src/game/block/SoundType.java @@ -1,4 +1,4 @@ -package game.audio; +package game.block; import game.init.SoundEvent; diff --git a/java/src/game/clipboard/ClipboardPlacer.java b/java/src/game/clipboard/ClipboardPlacer.java index 02dd51b..5a94c52 100755 --- a/java/src/game/clipboard/ClipboardPlacer.java +++ b/java/src/game/clipboard/ClipboardPlacer.java @@ -8,12 +8,11 @@ import java.util.List; import java.util.Map; import java.util.Set; -import game.collect.Lists; - import game.block.Block; import game.block.BlockDoor; import game.block.BlockRailBase; import game.block.ITileEntityProvider; +import game.collect.Lists; import game.init.Blocks; import game.init.ReorderRegistry; import game.inventory.IInventory; diff --git a/java/src/game/color/Colorizer.java b/java/src/game/color/Colorizer.java index 2b42b87..0e45326 100755 --- a/java/src/game/color/Colorizer.java +++ b/java/src/game/color/Colorizer.java @@ -2,8 +2,8 @@ package game.color; import java.awt.image.BufferedImage; +import client.renderer.texture.TextureUtil; import game.biome.Biome; -import game.renderer.texture.TextureUtil; import game.util.FileUtils; import game.world.BlockPos; import game.world.IWorldAccess; diff --git a/java/src/game/color/DyeColor.java b/java/src/game/color/DyeColor.java index 8681ee5..497f6b5 100755 --- a/java/src/game/color/DyeColor.java +++ b/java/src/game/color/DyeColor.java @@ -3,10 +3,9 @@ package game.color; import java.util.Map; import game.collect.Maps; +import game.util.Identifyable; -import game.properties.IStringSerializable; - -public enum DyeColor implements IStringSerializable +public enum DyeColor implements Identifyable { WHITE(0, 15, "white", "Weiß", "Weißes", "Weißer", "Weiße", "Knochenmehl", 16777215, TextColor.WHITE), ORANGE(1, 14, "orange", "Orange", "Oranges", "Oranger", "Orange", "Oranger Farbstoff", 14188339, TextColor.ORANGE), diff --git a/java/src/game/command/Command.java b/java/src/game/command/Command.java index cfb029e..42f8e5e 100644 --- a/java/src/game/command/Command.java +++ b/java/src/game/command/Command.java @@ -7,7 +7,6 @@ import java.util.Map; import game.collect.Lists; import game.collect.Maps; - import game.command.DoubleParser.DefType; import game.world.Vec3; import game.world.World; diff --git a/java/src/game/command/CommandEnvironment.java b/java/src/game/command/CommandEnvironment.java index 458a2c2..5b4b243 100644 --- a/java/src/game/command/CommandEnvironment.java +++ b/java/src/game/command/CommandEnvironment.java @@ -10,10 +10,25 @@ import java.util.function.Function; import game.collect.Lists; import game.collect.Maps; import game.collect.Sets; -import game.Server; import game.color.TextColor; -import game.command.commands.*; +import game.command.commands.CommandAdmin; +import game.command.commands.CommandHelp; +import game.command.commands.CommandKick; +import game.command.commands.CommandMessage; +import game.command.commands.CommandMilk; +import game.command.commands.CommandOfflinetp; +import game.command.commands.CommandPotion; +import game.command.commands.CommandRemove; +import game.command.commands.CommandRevoke; +import game.command.commands.CommandSpawn; +import game.command.commands.CommandTele; +import game.command.commands.CommandTime; +import game.command.commands.CommandTp; +import game.command.commands.CommandWarp; +import game.command.commands.CommandWeather; +import game.command.commands.CommandWorld; import game.log.Log; +import server.Server; public class CommandEnvironment { private final Server server; diff --git a/java/src/game/command/FixedExecutor.java b/java/src/game/command/FixedExecutor.java index 04b5d43..465b298 100644 --- a/java/src/game/command/FixedExecutor.java +++ b/java/src/game/command/FixedExecutor.java @@ -1,9 +1,9 @@ package game.command; -import game.Server; import game.entity.Entity; import game.world.BlockPos; import game.world.Position; +import server.Server; public class FixedExecutor implements Executor { private final Server server; diff --git a/java/src/game/command/PlayerParser.java b/java/src/game/command/PlayerParser.java index 0c5d7c8..b9fc191 100644 --- a/java/src/game/command/PlayerParser.java +++ b/java/src/game/command/PlayerParser.java @@ -1,6 +1,7 @@ package game.command; import java.util.Collection; + import game.network.Player; public class PlayerParser extends CompletingParser { diff --git a/java/src/game/command/WorldParser.java b/java/src/game/command/WorldParser.java index c2df3bf..2c32352 100644 --- a/java/src/game/command/WorldParser.java +++ b/java/src/game/command/WorldParser.java @@ -4,7 +4,6 @@ import java.util.Collection; import java.util.List; import game.collect.Lists; - import game.dimension.Dimension; import game.world.WorldServer; diff --git a/java/src/game/command/commands/CommandAdmin.java b/java/src/game/command/commands/CommandAdmin.java index eb58a51..813948b 100644 --- a/java/src/game/command/commands/CommandAdmin.java +++ b/java/src/game/command/commands/CommandAdmin.java @@ -1,9 +1,9 @@ package game.command.commands; -import game.command.CommandEnvironment; -import game.command.RunException; import game.command.Command; +import game.command.CommandEnvironment; import game.command.Executor; +import game.command.RunException; import game.network.Player; public class CommandAdmin extends Command { diff --git a/java/src/game/command/commands/CommandHelp.java b/java/src/game/command/commands/CommandHelp.java index 3d2b988..5803721 100644 --- a/java/src/game/command/commands/CommandHelp.java +++ b/java/src/game/command/commands/CommandHelp.java @@ -5,13 +5,12 @@ import java.util.Map.Entry; import java.util.function.Function; import game.collect.Lists; - import game.command.ArgumentParser; import game.command.CachedExecutable; -import game.command.Parameter; -import game.command.CommandEnvironment; import game.command.Command; +import game.command.CommandEnvironment; import game.command.Executor; +import game.command.Parameter; import game.util.Util; public class CommandHelp extends Command { diff --git a/java/src/game/command/commands/CommandKick.java b/java/src/game/command/commands/CommandKick.java index 5f93b33..26f054a 100644 --- a/java/src/game/command/commands/CommandKick.java +++ b/java/src/game/command/commands/CommandKick.java @@ -1,9 +1,9 @@ package game.command.commands; -import game.command.CommandEnvironment; -import game.command.RunException; import game.command.Command; +import game.command.CommandEnvironment; import game.command.Executor; +import game.command.RunException; import game.network.Player; public class CommandKick extends Command { diff --git a/java/src/game/command/commands/CommandMessage.java b/java/src/game/command/commands/CommandMessage.java index ecd6702..997258f 100644 --- a/java/src/game/command/commands/CommandMessage.java +++ b/java/src/game/command/commands/CommandMessage.java @@ -1,7 +1,7 @@ package game.command.commands; -import game.command.CommandEnvironment; import game.command.Command; +import game.command.CommandEnvironment; import game.command.Executor; import game.packet.SPacketMessage; diff --git a/java/src/game/command/commands/CommandMilk.java b/java/src/game/command/commands/CommandMilk.java index 66c6769..a016afa 100644 --- a/java/src/game/command/commands/CommandMilk.java +++ b/java/src/game/command/commands/CommandMilk.java @@ -1,9 +1,10 @@ package game.command.commands; import java.util.List; + import game.collect.Lists; -import game.command.CommandEnvironment; import game.command.Command; +import game.command.CommandEnvironment; import game.command.Executor; import game.entity.types.EntityLiving; import game.potion.Potion; diff --git a/java/src/game/command/commands/CommandOfflinetp.java b/java/src/game/command/commands/CommandOfflinetp.java index a7340b7..f4b7591 100644 --- a/java/src/game/command/commands/CommandOfflinetp.java +++ b/java/src/game/command/commands/CommandOfflinetp.java @@ -2,9 +2,10 @@ package game.command.commands; import java.util.Collection; import java.util.List; -import game.command.CommandEnvironment; + import game.collect.Lists; import game.command.Command; +import game.command.CommandEnvironment; import game.command.Executor; import game.command.RunException; import game.command.StringCompleter; diff --git a/java/src/game/command/commands/CommandPotion.java b/java/src/game/command/commands/CommandPotion.java index edf0d5a..e5500e9 100644 --- a/java/src/game/command/commands/CommandPotion.java +++ b/java/src/game/command/commands/CommandPotion.java @@ -1,8 +1,9 @@ package game.command.commands; import java.util.List; -import game.command.CommandEnvironment; + import game.command.Command; +import game.command.CommandEnvironment; import game.command.Executor; import game.entity.types.EntityLiving; import game.potion.Potion; diff --git a/java/src/game/command/commands/CommandRemove.java b/java/src/game/command/commands/CommandRemove.java index 314dcc6..fa43608 100644 --- a/java/src/game/command/commands/CommandRemove.java +++ b/java/src/game/command/commands/CommandRemove.java @@ -1,8 +1,9 @@ package game.command.commands; import java.util.List; -import game.command.CommandEnvironment; + import game.command.Command; +import game.command.CommandEnvironment; import game.command.Executor; import game.entity.Entity; diff --git a/java/src/game/command/commands/CommandRevoke.java b/java/src/game/command/commands/CommandRevoke.java index 25ceb93..5269241 100644 --- a/java/src/game/command/commands/CommandRevoke.java +++ b/java/src/game/command/commands/CommandRevoke.java @@ -1,9 +1,9 @@ package game.command.commands; -import game.command.CommandEnvironment; -import game.command.RunException; import game.command.Command; +import game.command.CommandEnvironment; import game.command.Executor; +import game.command.RunException; import game.network.Player; public class CommandRevoke extends Command { diff --git a/java/src/game/command/commands/CommandSpawn.java b/java/src/game/command/commands/CommandSpawn.java index aff6b20..0236021 100644 --- a/java/src/game/command/commands/CommandSpawn.java +++ b/java/src/game/command/commands/CommandSpawn.java @@ -5,11 +5,10 @@ import java.util.Set; import game.collect.Lists; import game.collect.Sets; - -import game.command.CommandEnvironment; -import game.command.RunException; import game.command.Command; +import game.command.CommandEnvironment; import game.command.Executor; +import game.command.RunException; import game.entity.Entity; import game.entity.types.EntityLiving; import game.init.EntityRegistry; diff --git a/java/src/game/command/commands/CommandTele.java b/java/src/game/command/commands/CommandTele.java index 5b918c1..82dbace 100644 --- a/java/src/game/command/commands/CommandTele.java +++ b/java/src/game/command/commands/CommandTele.java @@ -1,10 +1,11 @@ package game.command.commands; import java.util.List; -import game.command.CommandEnvironment; -import game.dimension.Dimension; + import game.command.Command; +import game.command.CommandEnvironment; import game.command.Executor; +import game.dimension.Dimension; import game.entity.Entity; import game.world.Vec3; diff --git a/java/src/game/command/commands/CommandTime.java b/java/src/game/command/commands/CommandTime.java index 0f31c8b..2df30de 100644 --- a/java/src/game/command/commands/CommandTime.java +++ b/java/src/game/command/commands/CommandTime.java @@ -1,10 +1,10 @@ package game.command.commands; +import game.command.Command; import game.command.CommandEnvironment; +import game.command.Executor; import game.command.RunException; import game.dimension.Dimension; -import game.command.Command; -import game.command.Executor; import game.item.ItemSpaceNavigator; import game.world.Position; import game.world.WorldServer; diff --git a/java/src/game/command/commands/CommandTp.java b/java/src/game/command/commands/CommandTp.java index 56a1443..0fbf23e 100644 --- a/java/src/game/command/commands/CommandTp.java +++ b/java/src/game/command/commands/CommandTp.java @@ -1,8 +1,9 @@ package game.command.commands; import java.util.List; -import game.command.CommandEnvironment; + import game.command.Command; +import game.command.CommandEnvironment; import game.command.Executor; import game.entity.Entity; import game.init.UniverseRegistry; diff --git a/java/src/game/command/commands/CommandWarp.java b/java/src/game/command/commands/CommandWarp.java index 8f102ef..4cd5897 100644 --- a/java/src/game/command/commands/CommandWarp.java +++ b/java/src/game/command/commands/CommandWarp.java @@ -2,8 +2,9 @@ package game.command.commands; import java.util.Collection; import java.util.List; -import game.command.CommandEnvironment; + import game.command.Command; +import game.command.CommandEnvironment; import game.command.Executor; import game.command.RunException; import game.command.StringCompleter; diff --git a/java/src/game/command/commands/CommandWeather.java b/java/src/game/command/commands/CommandWeather.java index 30b7ab8..b8c1e45 100644 --- a/java/src/game/command/commands/CommandWeather.java +++ b/java/src/game/command/commands/CommandWeather.java @@ -1,9 +1,9 @@ package game.command.commands; -import game.command.CommandEnvironment; -import game.command.RunException; import game.command.Command; +import game.command.CommandEnvironment; import game.command.Executor; +import game.command.RunException; import game.world.Weather; import game.world.WorldServer; diff --git a/java/src/game/command/commands/CommandWorld.java b/java/src/game/command/commands/CommandWorld.java index a673dca..325c5f9 100644 --- a/java/src/game/command/commands/CommandWorld.java +++ b/java/src/game/command/commands/CommandWorld.java @@ -1,8 +1,9 @@ package game.command.commands; import java.util.List; -import game.command.CommandEnvironment; + import game.command.Command; +import game.command.CommandEnvironment; import game.command.Executor; import game.entity.Entity; import game.world.BlockPos; diff --git a/java/src/game/dimension/Dimension.java b/java/src/game/dimension/Dimension.java index 3cad8cf..7c330a9 100755 --- a/java/src/game/dimension/Dimension.java +++ b/java/src/game/dimension/Dimension.java @@ -4,12 +4,11 @@ import java.util.List; import java.util.Map; import java.util.Set; +import game.biome.Biome; +import game.block.LeavesType; import game.collect.Lists; import game.collect.Maps; import game.collect.Sets; - -import game.biome.Biome; -import game.block.LeavesType; import game.init.BlockRegistry; import game.init.Blocks; import game.init.MetalType; diff --git a/java/src/game/dimension/Star.java b/java/src/game/dimension/Star.java index 6cfa58d..4a2452b 100755 --- a/java/src/game/dimension/Star.java +++ b/java/src/game/dimension/Star.java @@ -3,7 +3,6 @@ package game.dimension; import java.util.Set; import game.collect.Sets; - import game.world.State; public final class Star extends Dimension { diff --git a/java/src/game/enchantment/Enchantment.java b/java/src/game/enchantment/Enchantment.java index b212fd0..2241101 100755 --- a/java/src/game/enchantment/Enchantment.java +++ b/java/src/game/enchantment/Enchantment.java @@ -6,7 +6,6 @@ import java.util.Set; import game.collect.Lists; import game.collect.Maps; - import game.entity.DamageSource; import game.entity.Entity; import game.entity.types.EntityLiving; diff --git a/java/src/game/enchantment/EnchantmentHelper.java b/java/src/game/enchantment/EnchantmentHelper.java index 364d437..6a74e6e 100755 --- a/java/src/game/enchantment/EnchantmentHelper.java +++ b/java/src/game/enchantment/EnchantmentHelper.java @@ -6,7 +6,6 @@ import java.util.Map; import game.collect.Lists; import game.collect.Maps; - import game.entity.DamageSource; import game.entity.Entity; import game.entity.types.EntityLiving; diff --git a/java/src/game/entity/DataWatcher.java b/java/src/game/entity/DataWatcher.java index 5b95477..bc7f2a7 100755 --- a/java/src/game/entity/DataWatcher.java +++ b/java/src/game/entity/DataWatcher.java @@ -8,7 +8,6 @@ import java.util.concurrent.locks.ReentrantReadWriteLock; import game.collect.Lists; import game.collect.Maps; - import game.item.ItemStack; import game.network.PacketBuffer; import game.world.BlockPos; diff --git a/java/src/game/entity/Entity.java b/java/src/game/entity/Entity.java index e972e30..331864e 100755 --- a/java/src/game/entity/Entity.java +++ b/java/src/game/entity/Entity.java @@ -2,12 +2,12 @@ package game.entity; import java.util.List; -import game.audio.SoundType; import game.block.Block; import game.block.BlockFence; import game.block.BlockFenceGate; import game.block.BlockLiquid; import game.block.BlockWall; +import game.block.SoundType; import game.color.TextColor; import game.dimension.DimType; import game.enchantment.EnchantmentHelper; @@ -26,11 +26,11 @@ import game.init.UniverseRegistry; import game.item.Item; import game.item.ItemStack; import game.material.Material; +import game.model.ParticleType; import game.nbt.NBTTagCompound; import game.nbt.NBTTagDouble; import game.nbt.NBTTagFloat; import game.nbt.NBTTagList; -import game.renderer.particle.ParticleType; import game.rng.Random; import game.util.ExtMath; import game.world.BlockPos; diff --git a/java/src/game/entity/EntityTrackerEntry.java b/java/src/game/entity/EntityTrackerEntry.java index b560415..e661a3d 100755 --- a/java/src/game/entity/EntityTrackerEntry.java +++ b/java/src/game/entity/EntityTrackerEntry.java @@ -5,7 +5,6 @@ import java.util.List; import java.util.Set; import game.collect.Sets; - import game.entity.attributes.AttributeInstance; import game.entity.attributes.AttributeMap; import game.entity.npc.EntityNPC; diff --git a/java/src/game/entity/animal/EntityDragon.java b/java/src/game/entity/animal/EntityDragon.java index 52653bc..4084f10 100755 --- a/java/src/game/entity/animal/EntityDragon.java +++ b/java/src/game/entity/animal/EntityDragon.java @@ -3,7 +3,6 @@ package game.entity.animal; import java.util.List; import game.collect.Lists; - import game.entity.DamageSource; import game.entity.Entity; import game.entity.EntityType; @@ -13,7 +12,7 @@ import game.entity.types.EntityLiving; import game.entity.types.IEntityMultiPart; import game.init.Config; import game.init.SoundEvent; -import game.renderer.particle.ParticleType; +import game.model.ParticleType; import game.util.ExtMath; import game.world.Vec3; import game.world.World; diff --git a/java/src/game/entity/animal/EntityHorse.java b/java/src/game/entity/animal/EntityHorse.java index b9ed9b2..515a0e5 100755 --- a/java/src/game/entity/animal/EntityHorse.java +++ b/java/src/game/entity/animal/EntityHorse.java @@ -10,8 +10,8 @@ import game.ai.EntityAIRunAroundLikeCrazy; import game.ai.EntityAISwimming; import game.ai.EntityAIWander; import game.ai.EntityAIWatchClosest; -import game.audio.SoundType; import game.block.Block; +import game.block.SoundType; import game.entity.DamageSource; import game.entity.Entity; import game.entity.attributes.AttributeInstance; @@ -31,11 +31,11 @@ import game.item.Item; import game.item.ItemMonsterPlacer; import game.item.ItemStack; import game.material.Material; +import game.model.ParticleType; import game.nbt.NBTTagCompound; import game.nbt.NBTTagList; import game.pathfinding.PathNavigateGround; import game.potion.Potion; -import game.renderer.particle.ParticleType; import game.util.ExtMath; import game.world.BlockPos; import game.world.World; diff --git a/java/src/game/entity/animal/EntityMooshroom.java b/java/src/game/entity/animal/EntityMooshroom.java index 610c8bb..3b57c9b 100755 --- a/java/src/game/entity/animal/EntityMooshroom.java +++ b/java/src/game/entity/animal/EntityMooshroom.java @@ -8,7 +8,7 @@ import game.init.Items; import game.init.SoundEvent; import game.item.ItemShears; import game.item.ItemStack; -import game.renderer.particle.ParticleType; +import game.model.ParticleType; import game.world.World; public class EntityMooshroom extends EntityCow diff --git a/java/src/game/entity/animal/EntityRabbit.java b/java/src/game/entity/animal/EntityRabbit.java index 7878ba3..1a58e41 100755 --- a/java/src/game/entity/animal/EntityRabbit.java +++ b/java/src/game/entity/animal/EntityRabbit.java @@ -32,12 +32,12 @@ import game.init.Items; import game.init.SoundEvent; import game.item.Item; import game.item.ItemStack; +import game.model.ParticleType; import game.nbt.NBTTagCompound; import game.pathfinding.PathEntity; import game.pathfinding.PathNavigateGround; import game.potion.Potion; import game.potion.PotionEffect; -import game.renderer.particle.ParticleType; import game.util.ExtMath; import game.world.BlockPos; import game.world.State; diff --git a/java/src/game/entity/animal/EntitySheep.java b/java/src/game/entity/animal/EntitySheep.java index 2410159..71f19b8 100755 --- a/java/src/game/entity/animal/EntitySheep.java +++ b/java/src/game/entity/animal/EntitySheep.java @@ -2,8 +2,6 @@ package game.entity.animal; import java.util.Map; -import game.collect.Maps; - import game.ai.EntityAIEatGrass; import game.ai.EntityAIFollowParent; import game.ai.EntityAILookIdle; @@ -14,6 +12,7 @@ import game.ai.EntityAITempt; import game.ai.EntityAIWander; import game.ai.EntityAIWatchClosest; import game.biome.Biome; +import game.collect.Maps; import game.color.DyeColor; import game.entity.attributes.Attributes; import game.entity.item.EntityItem; diff --git a/java/src/game/entity/animal/EntityWolf.java b/java/src/game/entity/animal/EntityWolf.java index 33c7ee3..5f2ddd7 100755 --- a/java/src/game/entity/animal/EntityWolf.java +++ b/java/src/game/entity/animal/EntityWolf.java @@ -30,9 +30,9 @@ import game.init.SoundEvent; import game.item.Item; import game.item.ItemFood; import game.item.ItemStack; +import game.model.ParticleType; import game.nbt.NBTTagCompound; import game.pathfinding.PathNavigateGround; -import game.renderer.particle.ParticleType; import game.util.ExtMath; import game.world.World; diff --git a/java/src/game/entity/attributes/Attribute.java b/java/src/game/entity/attributes/Attribute.java index 25804a4..81ea3b4 100755 --- a/java/src/game/entity/attributes/Attribute.java +++ b/java/src/game/entity/attributes/Attribute.java @@ -3,7 +3,6 @@ package game.entity.attributes; import java.util.Map; import game.collect.Maps; - import game.util.ExtMath; public class Attribute diff --git a/java/src/game/entity/item/EntityBoat.java b/java/src/game/entity/item/EntityBoat.java index 77f22d2..ca7e129 100755 --- a/java/src/game/entity/item/EntityBoat.java +++ b/java/src/game/entity/item/EntityBoat.java @@ -14,8 +14,8 @@ import game.init.Config; import game.init.ItemRegistry; import game.init.Items; import game.item.Item; +import game.model.ParticleType; import game.nbt.NBTTagCompound; -import game.renderer.particle.ParticleType; import game.util.ExtMath; import game.world.BlockPos; import game.world.BoundingBox; diff --git a/java/src/game/entity/item/EntityFalling.java b/java/src/game/entity/item/EntityFalling.java index b5e633f..8196747 100755 --- a/java/src/game/entity/item/EntityFalling.java +++ b/java/src/game/entity/item/EntityFalling.java @@ -2,12 +2,11 @@ package game.entity.item; import java.util.List; -import game.collect.Lists; - import game.block.Block; import game.block.BlockAnvil; import game.block.BlockFalling; import game.block.ITileEntityProvider; +import game.collect.Lists; import game.entity.DamageSource; import game.entity.Entity; import game.entity.EntityType; diff --git a/java/src/game/entity/item/EntityFireworks.java b/java/src/game/entity/item/EntityFireworks.java index a58c58b..dc20a18 100755 --- a/java/src/game/entity/item/EntityFireworks.java +++ b/java/src/game/entity/item/EntityFireworks.java @@ -4,8 +4,8 @@ import game.entity.Entity; import game.entity.EntityType; import game.init.SoundEvent; import game.item.ItemStack; +import game.model.ParticleType; import game.nbt.NBTTagCompound; -import game.renderer.particle.ParticleType; import game.util.ExtMath; import game.world.World; import game.world.WorldClient; diff --git a/java/src/game/entity/item/EntityHopperCart.java b/java/src/game/entity/item/EntityHopperCart.java index d21856d..9441c6a 100755 --- a/java/src/game/entity/item/EntityHopperCart.java +++ b/java/src/game/entity/item/EntityHopperCart.java @@ -1,7 +1,6 @@ package game.entity.item; import java.util.List; - import java.util.function.Predicate; import game.entity.DamageSource; diff --git a/java/src/game/entity/item/EntityItem.java b/java/src/game/entity/item/EntityItem.java index 01c751b..fb04bbd 100755 --- a/java/src/game/entity/item/EntityItem.java +++ b/java/src/game/entity/item/EntityItem.java @@ -13,8 +13,8 @@ import game.init.SoundEvent; import game.item.ItemStack; import game.log.Log; import game.material.Material; +import game.model.ParticleType; import game.nbt.NBTTagCompound; -import game.renderer.particle.ParticleType; import game.util.ExtMath; import game.world.BlockPos; import game.world.PortalType; diff --git a/java/src/game/entity/item/EntityNuke.java b/java/src/game/entity/item/EntityNuke.java index abca66f..9828a96 100755 --- a/java/src/game/entity/item/EntityNuke.java +++ b/java/src/game/entity/item/EntityNuke.java @@ -2,8 +2,8 @@ package game.entity.item; import game.entity.Entity; import game.entity.EntityType; +import game.model.ParticleType; import game.nbt.NBTTagCompound; -import game.renderer.particle.ParticleType; import game.world.World; public class EntityNuke extends Entity diff --git a/java/src/game/entity/item/EntityOrb.java b/java/src/game/entity/item/EntityOrb.java index ec9743b..bd1f534 100755 --- a/java/src/game/entity/item/EntityOrb.java +++ b/java/src/game/entity/item/EntityOrb.java @@ -5,7 +5,7 @@ import game.entity.Entity; import game.entity.types.EntityLiving; import game.entity.types.EntityThrowable; import game.init.Config; -import game.renderer.particle.ParticleType; +import game.model.ParticleType; import game.world.HitPosition; import game.world.World; diff --git a/java/src/game/entity/item/EntityTnt.java b/java/src/game/entity/item/EntityTnt.java index f140c85..e306bf9 100755 --- a/java/src/game/entity/item/EntityTnt.java +++ b/java/src/game/entity/item/EntityTnt.java @@ -4,8 +4,8 @@ import game.entity.Entity; import game.entity.EntityType; import game.entity.types.EntityLiving; import game.entity.types.IObjectData; +import game.model.ParticleType; import game.nbt.NBTTagCompound; -import game.renderer.particle.ParticleType; import game.world.World; public class EntityTnt extends Entity implements IObjectData diff --git a/java/src/game/entity/item/EntityTntCart.java b/java/src/game/entity/item/EntityTntCart.java index f318b98..16fa7c7 100755 --- a/java/src/game/entity/item/EntityTntCart.java +++ b/java/src/game/entity/item/EntityTntCart.java @@ -8,8 +8,8 @@ import game.init.Blocks; import game.init.Config; import game.init.SoundEvent; import game.item.ItemStack; +import game.model.ParticleType; import game.nbt.NBTTagCompound; -import game.renderer.particle.ParticleType; import game.world.BlockPos; import game.world.Explosion; import game.world.State; diff --git a/java/src/game/entity/item/EntityXp.java b/java/src/game/entity/item/EntityXp.java index e8cae54..3ab09b2 100755 --- a/java/src/game/entity/item/EntityXp.java +++ b/java/src/game/entity/item/EntityXp.java @@ -9,8 +9,8 @@ import game.entity.types.IObjectData; import game.init.Config; import game.init.SoundEvent; import game.material.Material; +import game.model.ParticleType; import game.nbt.NBTTagCompound; -import game.renderer.particle.ParticleType; import game.util.ExtMath; import game.world.BlockPos; import game.world.PortalType; diff --git a/java/src/game/entity/npc/Alignment.java b/java/src/game/entity/npc/Alignment.java index f38481c..8e96033 100755 --- a/java/src/game/entity/npc/Alignment.java +++ b/java/src/game/entity/npc/Alignment.java @@ -3,7 +3,6 @@ package game.entity.npc; import java.util.Map; import game.collect.Maps; - import game.color.TextColor; public enum Alignment { diff --git a/java/src/game/entity/npc/EntityChaosMarine.java b/java/src/game/entity/npc/EntityChaosMarine.java index 51ade10..a988ac3 100755 --- a/java/src/game/entity/npc/EntityChaosMarine.java +++ b/java/src/game/entity/npc/EntityChaosMarine.java @@ -3,17 +3,16 @@ package game.entity.npc; import java.util.List; import game.collect.Lists; - import game.entity.attributes.Attributes; import game.init.Items; import game.init.SpeciesRegistry; import game.item.ItemStack; -import game.properties.IStringSerializable; import game.rng.Random; +import game.util.Identifyable; import game.world.World; public class EntityChaosMarine extends EntityNPC { - public static enum Legion implements IStringSerializable { + public static enum Legion implements Identifyable { OTHER("other", null, 0x000000, 0x000000, 2.15f, 200), EMPERORS_CHILDREN("emperorchild", "Emperors Children", 0xa224cc, 0xccb963, 2.43f, 300, "emperors_child"); diff --git a/java/src/game/entity/npc/EntityDarkMage.java b/java/src/game/entity/npc/EntityDarkMage.java index cec4c6f..790cc12 100755 --- a/java/src/game/entity/npc/EntityDarkMage.java +++ b/java/src/game/entity/npc/EntityDarkMage.java @@ -2,7 +2,7 @@ package game.entity.npc; import game.ai.AISmallFireballAttack; import game.init.SoundEvent; -import game.renderer.particle.ParticleType; +import game.model.ParticleType; import game.rng.Random; import game.world.World; import game.world.WorldClient; diff --git a/java/src/game/entity/npc/EntityGargoyle.java b/java/src/game/entity/npc/EntityGargoyle.java index 8291424..9443e01 100755 --- a/java/src/game/entity/npc/EntityGargoyle.java +++ b/java/src/game/entity/npc/EntityGargoyle.java @@ -5,8 +5,8 @@ import game.entity.DamageSource; import game.entity.attributes.Attributes; import game.init.Config; import game.item.ItemStack; +import game.model.ParticleType; import game.nbt.NBTTagCompound; -import game.renderer.particle.ParticleType; import game.rng.Random; import game.world.World; diff --git a/java/src/game/entity/npc/EntityHuman.java b/java/src/game/entity/npc/EntityHuman.java index 18af6a7..aa68011 100755 --- a/java/src/game/entity/npc/EntityHuman.java +++ b/java/src/game/entity/npc/EntityHuman.java @@ -3,15 +3,15 @@ package game.entity.npc; import game.entity.types.EntityLiving; import game.init.Items; import game.item.ItemStack; -import game.properties.IStringSerializable; import game.rng.Random; +import game.util.Identifyable; import game.village.Village; import game.world.BlockPos; import game.world.World; import game.world.WorldServer; public class EntityHuman extends EntityNPC { - public static enum ClassType implements IStringSerializable { + public static enum ClassType implements Identifyable { NONE("none", ""), KNIGHT("knight", "Krieger"), PEASANT("peasant", "Bauer"), diff --git a/java/src/game/entity/npc/EntityMagma.java b/java/src/game/entity/npc/EntityMagma.java index 8d6e679..049852c 100755 --- a/java/src/game/entity/npc/EntityMagma.java +++ b/java/src/game/entity/npc/EntityMagma.java @@ -1,6 +1,6 @@ package game.entity.npc; -import game.renderer.particle.ParticleType; +import game.model.ParticleType; import game.world.World; public class EntityMagma extends EntitySlime diff --git a/java/src/game/entity/npc/EntityNPC.java b/java/src/game/entity/npc/EntityNPC.java index 5d53a6a..dc4aa1a 100755 --- a/java/src/game/entity/npc/EntityNPC.java +++ b/java/src/game/entity/npc/EntityNPC.java @@ -2,10 +2,22 @@ package game.entity.npc; import java.lang.reflect.InvocationTargetException; import java.util.List; - import java.util.function.Predicate; -import game.Game; +import client.Game; +import client.gui.container.GuiBrewing; +import client.gui.container.GuiChest; +import client.gui.container.GuiCrafting; +import client.gui.container.GuiDispenser; +import client.gui.container.GuiEnchant; +import client.gui.container.GuiFurnace; +import client.gui.container.GuiHopper; +import client.gui.container.GuiHorse; +import client.gui.container.GuiMerchant; +import client.gui.container.GuiRepair; +import client.gui.ingame.GuiSign; +import client.renderer.layers.LayerExtra; +import client.renderer.texture.EntityTexManager; import game.ai.AIRangedAttack; import game.ai.EntityAIAttackOnCollide; import game.ai.EntityAIAvoidEntity; @@ -21,7 +33,6 @@ import game.ai.EntityAISwimming; import game.ai.EntityAIWander; import game.ai.EntityAIWatchClosest; import game.ai.EntityAIWatchClosest2; -import game.audio.MovingSoundMinecartRiding; import game.block.Block; import game.block.BlockBed; import game.dimension.Space; @@ -45,17 +56,6 @@ import game.entity.projectile.EntityPotion; import game.entity.projectile.EntitySnowball; import game.entity.types.EntityLiving; import game.entity.types.IEntityMultiPart; -import game.gui.container.GuiBrewing; -import game.gui.container.GuiChest; -import game.gui.container.GuiCrafting; -import game.gui.container.GuiDispenser; -import game.gui.container.GuiEnchant; -import game.gui.container.GuiFurnace; -import game.gui.container.GuiHopper; -import game.gui.container.GuiHorse; -import game.gui.container.GuiMerchant; -import game.gui.container.GuiRepair; -import game.gui.ingame.GuiSign; import game.init.Config; import game.init.ItemRegistry; import game.init.Items; @@ -80,6 +80,7 @@ import game.item.ItemShears; import game.item.ItemStack; import game.item.ItemSword; import game.item.ItemTool; +import game.model.ParticleType; import game.nbt.NBTTagCompound; import game.nbt.NBTTagList; import game.network.ClientPlayer; @@ -93,10 +94,8 @@ import game.packet.SPacketEntityVelocity; import game.pathfinding.PathNavigateGround; import game.potion.Potion; import game.potion.PotionEffect; -import game.renderer.layers.LayerExtra; -import game.renderer.particle.ParticleType; -import game.renderer.texture.EntityTexManager; import game.rng.Random; +import game.sound.MovingSoundMinecartRiding; import game.tileentity.IInteractionObject; import game.tileentity.LockCode; import game.tileentity.TileEntitySign; diff --git a/java/src/game/entity/npc/EntityPrimarch.java b/java/src/game/entity/npc/EntityPrimarch.java index a09e4ec..9edcf12 100755 --- a/java/src/game/entity/npc/EntityPrimarch.java +++ b/java/src/game/entity/npc/EntityPrimarch.java @@ -3,14 +3,13 @@ package game.entity.npc; import java.util.List; import game.collect.Lists; - import game.entity.attributes.Attributes; -import game.properties.IStringSerializable; import game.rng.Random; +import game.util.Identifyable; import game.world.World; public class EntityPrimarch extends EntityMobNPC { - public static enum Founding implements IStringSerializable { + public static enum Founding implements Identifyable { OTHER("other", "", 0, 0x000000, 0x000000), DARK_ANGELS("darkangel", "Dark Angels", 1, 0xaf0000, 0x400000, "Lion El'Jonson:lion_el_jonson", 2.65f, 850, Alignment.GOOD), UNKNOWN_A("unkna", "[Legion 2]", 2, 0xaf0000, 0x400000), diff --git a/java/src/game/entity/npc/EntitySlime.java b/java/src/game/entity/npc/EntitySlime.java index e853c79..578b1b9 100755 --- a/java/src/game/entity/npc/EntitySlime.java +++ b/java/src/game/entity/npc/EntitySlime.java @@ -9,9 +9,9 @@ import game.entity.attributes.Attributes; import game.entity.types.EntityLiving; import game.init.Config; import game.init.SoundEvent; +import game.model.ParticleType; import game.nbt.NBTTagCompound; import game.pathfinding.PathNavigateGround; -import game.renderer.particle.ParticleType; import game.rng.Random; import game.util.ExtMath; import game.world.BlockPos; diff --git a/java/src/game/entity/npc/EntitySpaceMarine.java b/java/src/game/entity/npc/EntitySpaceMarine.java index 7d48b33..18cbf31 100755 --- a/java/src/game/entity/npc/EntitySpaceMarine.java +++ b/java/src/game/entity/npc/EntitySpaceMarine.java @@ -3,17 +3,16 @@ package game.entity.npc; import java.util.List; import game.collect.Lists; - import game.entity.attributes.Attributes; import game.init.Items; import game.init.SpeciesRegistry; import game.item.ItemStack; -import game.properties.IStringSerializable; import game.rng.Random; +import game.util.Identifyable; import game.world.World; public class EntitySpaceMarine extends EntityNPC { - public static enum Legion implements IStringSerializable { + public static enum Legion implements Identifyable { OTHER("other", null, 0x000000, 0x000000, 2.15f, 200), BLACK_TEMPLARS("blacktemplar", "Black Templars", 0x101010, 0xc0c0c0, 2.43f, 300, "black_templar"); diff --git a/java/src/game/entity/npc/EntityZombie.java b/java/src/game/entity/npc/EntityZombie.java index d61bec4..8ca32f5 100755 --- a/java/src/game/entity/npc/EntityZombie.java +++ b/java/src/game/entity/npc/EntityZombie.java @@ -1,7 +1,6 @@ package game.entity.npc; import java.util.List; - import java.util.function.Predicate; import game.ai.EntityAIMoveThroughVillage; diff --git a/java/src/game/entity/npc/SpeciesInfo.java b/java/src/game/entity/npc/SpeciesInfo.java index 33f341f..9e8242f 100755 --- a/java/src/game/entity/npc/SpeciesInfo.java +++ b/java/src/game/entity/npc/SpeciesInfo.java @@ -1,13 +1,14 @@ package game.entity.npc; import java.util.List; + import game.collect.BiMap; import game.collect.HashBiMap; import game.collect.Lists; import game.init.SpeciesRegistry; import game.init.SpeciesRegistry.ModelType; -import game.properties.IStringSerializable; import game.rng.Random; +import game.util.Identifyable; public class SpeciesInfo { public final BiMap classnames; @@ -76,7 +77,7 @@ public class SpeciesInfo { SpeciesRegistry.CLASSES.put(this.clazz, this); if(this.classEnum != null) { for(Enum type : this.classEnum.getEnumConstants()) { - this.classnames.put(((IStringSerializable)type).getName(), type); + this.classnames.put(((Identifyable)type).getName(), type); } } } diff --git a/java/src/game/entity/projectile/EntityArrow.java b/java/src/game/entity/projectile/EntityArrow.java index 911c1bf..59180f1 100755 --- a/java/src/game/entity/projectile/EntityArrow.java +++ b/java/src/game/entity/projectile/EntityArrow.java @@ -17,8 +17,8 @@ import game.init.Items; import game.init.SoundEvent; import game.item.ItemStack; import game.material.Material; +import game.model.ParticleType; import game.nbt.NBTTagCompound; -import game.renderer.particle.ParticleType; import game.util.ExtMath; import game.world.BlockPos; import game.world.BoundingBox; diff --git a/java/src/game/entity/projectile/EntityDynamite.java b/java/src/game/entity/projectile/EntityDynamite.java index 0ca9029..abe2a29 100755 --- a/java/src/game/entity/projectile/EntityDynamite.java +++ b/java/src/game/entity/projectile/EntityDynamite.java @@ -8,8 +8,8 @@ import game.entity.types.IObjectData; import game.init.Config; import game.init.ItemRegistry; import game.init.Items; +import game.model.ParticleType; import game.nbt.NBTTagCompound; -import game.renderer.particle.ParticleType; import game.world.HitPosition; import game.world.World; diff --git a/java/src/game/entity/projectile/EntityEgg.java b/java/src/game/entity/projectile/EntityEgg.java index c693d74..2b5f183 100755 --- a/java/src/game/entity/projectile/EntityEgg.java +++ b/java/src/game/entity/projectile/EntityEgg.java @@ -7,7 +7,7 @@ import game.entity.types.EntityThrowable; import game.init.Config; import game.init.ItemRegistry; import game.init.Items; -import game.renderer.particle.ParticleType; +import game.model.ParticleType; import game.world.HitPosition; import game.world.World; diff --git a/java/src/game/entity/projectile/EntityHook.java b/java/src/game/entity/projectile/EntityHook.java index 15fc77f..d5ef76a 100755 --- a/java/src/game/entity/projectile/EntityHook.java +++ b/java/src/game/entity/projectile/EntityHook.java @@ -17,8 +17,8 @@ import game.init.Config; import game.init.Items; import game.init.SoundEvent; import game.item.ItemStack; +import game.model.ParticleType; import game.nbt.NBTTagCompound; -import game.renderer.particle.ParticleType; import game.util.ExtMath; import game.world.BlockPos; import game.world.BoundingBox; diff --git a/java/src/game/entity/projectile/EntityProjectile.java b/java/src/game/entity/projectile/EntityProjectile.java index cde6ff9..97d0578 100755 --- a/java/src/game/entity/projectile/EntityProjectile.java +++ b/java/src/game/entity/projectile/EntityProjectile.java @@ -8,9 +8,9 @@ import game.entity.Entity; import game.entity.EntityType; import game.entity.types.EntityLiving; import game.init.BlockRegistry; +import game.model.ParticleType; import game.nbt.NBTTagCompound; import game.nbt.NBTTagList; -import game.renderer.particle.ParticleType; import game.util.ExtMath; import game.world.BlockPos; import game.world.BoundingBox; diff --git a/java/src/game/entity/projectile/EntitySnowball.java b/java/src/game/entity/projectile/EntitySnowball.java index 883d290..9c0ee15 100755 --- a/java/src/game/entity/projectile/EntitySnowball.java +++ b/java/src/game/entity/projectile/EntitySnowball.java @@ -4,7 +4,7 @@ import game.entity.DamageSource; import game.entity.types.EntityLiving; import game.entity.types.EntityThrowable; import game.init.Config; -import game.renderer.particle.ParticleType; +import game.model.ParticleType; import game.world.HitPosition; import game.world.World; diff --git a/java/src/game/entity/types/EntityAnimal.java b/java/src/game/entity/types/EntityAnimal.java index e9f995d..85c8944 100755 --- a/java/src/game/entity/types/EntityAnimal.java +++ b/java/src/game/entity/types/EntityAnimal.java @@ -2,9 +2,8 @@ package game.entity.types; import java.util.Set; -import game.collect.Sets; - import game.block.Block; +import game.collect.Sets; import game.entity.DamageSource; import game.entity.EntityType; import game.entity.npc.Alignment; @@ -12,8 +11,8 @@ import game.entity.npc.EntityNPC; import game.init.Blocks; import game.init.Items; import game.item.ItemStack; +import game.model.ParticleType; import game.nbt.NBTTagCompound; -import game.renderer.particle.ParticleType; import game.util.ExtMath; import game.world.BlockPos; import game.world.World; diff --git a/java/src/game/entity/types/EntityLiving.java b/java/src/game/entity/types/EntityLiving.java index 560d5b7..7089c2b 100755 --- a/java/src/game/entity/types/EntityLiving.java +++ b/java/src/game/entity/types/EntityLiving.java @@ -4,10 +4,7 @@ import java.util.Collection; import java.util.Iterator; import java.util.List; import java.util.Map; - import java.util.function.Predicate; -import game.collect.Lists; -import game.collect.Maps; import game.ai.EntityAIBase; import game.ai.EntityAIMoveTowardsRestriction; @@ -16,8 +13,10 @@ import game.ai.EntityJumpHelper; import game.ai.EntityLookHelper; import game.ai.EntityMoveHelper; import game.ai.EntitySenses; -import game.audio.SoundType; import game.block.Block; +import game.block.SoundType; +import game.collect.Lists; +import game.collect.Maps; import game.color.TextColor; import game.enchantment.EnchantmentHelper; import game.entity.DamageSource; @@ -48,6 +47,7 @@ import game.item.ItemArmor; import game.item.ItemMonsterPlacer; import game.item.ItemStack; import game.material.Material; +import game.model.ParticleType; import game.nbt.NBTTagCompound; import game.nbt.NBTTagList; import game.network.Player; @@ -59,7 +59,6 @@ import game.pathfinding.PathNavigateGround; import game.potion.Potion; import game.potion.PotionEffect; import game.potion.PotionHelper; -import game.renderer.particle.ParticleType; import game.rng.Random; import game.util.ExtMath; import game.world.BlockPos; diff --git a/java/src/game/entity/types/EntityTameable.java b/java/src/game/entity/types/EntityTameable.java index 3563575..ab00c53 100755 --- a/java/src/game/entity/types/EntityTameable.java +++ b/java/src/game/entity/types/EntityTameable.java @@ -1,8 +1,8 @@ package game.entity.types; import game.ai.EntityAISit; +import game.model.ParticleType; import game.nbt.NBTTagCompound; -import game.renderer.particle.ParticleType; import game.world.World; public abstract class EntityTameable extends EntityAnimal implements IEntityOwnable diff --git a/java/src/game/entity/types/EntityThrowable.java b/java/src/game/entity/types/EntityThrowable.java index c781e42..79395d4 100755 --- a/java/src/game/entity/types/EntityThrowable.java +++ b/java/src/game/entity/types/EntityThrowable.java @@ -8,8 +8,8 @@ import game.entity.Entity; import game.entity.EntityType; import game.init.BlockRegistry; import game.init.Blocks; +import game.model.ParticleType; import game.nbt.NBTTagCompound; -import game.renderer.particle.ParticleType; import game.util.ExtMath; import game.world.BlockPos; import game.world.BoundingBox; diff --git a/java/src/game/init/BlockRegistry.java b/java/src/game/init/BlockRegistry.java index 699ee3b..4536a76 100755 --- a/java/src/game/init/BlockRegistry.java +++ b/java/src/game/init/BlockRegistry.java @@ -1,15 +1,14 @@ package game.init; -import game.audio.SoundType; +import client.renderer.ticked.TextureLavaFX; +import client.renderer.ticked.TextureLavaFlowFX; +import client.renderer.ticked.TextureWaterFX; +import client.renderer.ticked.TextureWaterFlowFX; import game.block.*; import game.color.DyeColor; import game.init.FluidRegistry.LiquidType; import game.item.CheatTab; import game.material.Material; -import game.renderer.ticked.TextureLavaFX; -import game.renderer.ticked.TextureLavaFlowFX; -import game.renderer.ticked.TextureWaterFX; -import game.renderer.ticked.TextureWaterFlowFX; import game.world.State; public abstract class BlockRegistry { diff --git a/java/src/game/init/Config.java b/java/src/game/init/Config.java index 6ac62fb..3210f9f 100755 --- a/java/src/game/init/Config.java +++ b/java/src/game/init/Config.java @@ -11,10 +11,10 @@ import java.lang.reflect.Modifier; import java.util.Map; import java.util.TreeMap; -import game.Server; import game.packet.SPacketWorld; import game.util.ExtMath; import game.world.WorldServer; +import server.Server; public abstract class Config { public static enum ValueType { diff --git a/java/src/game/init/CraftingRegistry.java b/java/src/game/init/CraftingRegistry.java index 930d644..58f80df 100755 --- a/java/src/game/init/CraftingRegistry.java +++ b/java/src/game/init/CraftingRegistry.java @@ -6,9 +6,6 @@ import java.util.List; import java.util.Map; import java.util.Set; -import game.collect.Lists; -import game.collect.Maps; - import game.block.Block; import game.block.BlockBed; import game.block.BlockDirt; @@ -19,6 +16,8 @@ import game.block.BlockSand; import game.block.BlockSandStone; import game.block.BlockStoneBrick; import game.block.BlockWall; +import game.collect.Lists; +import game.collect.Maps; import game.color.DyeColor; import game.entity.animal.EntitySheep; import game.inventory.InventoryCrafting; diff --git a/java/src/game/init/EntityRegistry.java b/java/src/game/init/EntityRegistry.java index d43d4d4..86d8e97 100755 --- a/java/src/game/init/EntityRegistry.java +++ b/java/src/game/init/EntityRegistry.java @@ -4,7 +4,6 @@ import java.util.Map; import java.util.Set; import game.collect.Maps; - import game.entity.Entity; import game.entity.animal.EntityBat; import game.entity.animal.EntityChicken; @@ -19,9 +18,7 @@ import game.entity.animal.EntityRabbit; import game.entity.animal.EntitySheep; import game.entity.animal.EntitySquid; import game.entity.animal.EntityWolf; -import game.entity.effect.EntityLightning; import game.entity.item.EntityBoat; -import game.entity.item.EntityCart; import game.entity.item.EntityChestCart; import game.entity.item.EntityCrystal; import game.entity.item.EntityExplosion; @@ -51,61 +48,8 @@ import game.entity.projectile.EntityPotion; import game.entity.projectile.EntitySnowball; import game.entity.types.EntityLiving; import game.entity.types.IObjectData; -import game.init.SpeciesRegistry.ModelType; import game.log.Log; import game.nbt.NBTTagCompound; -import game.renderer.entity.Render; -import game.renderer.entity.RenderArachnoid; -import game.renderer.entity.RenderArrow; -import game.renderer.entity.RenderBat; -import game.renderer.entity.RenderBlockEntity; -import game.renderer.entity.RenderBoat; -import game.renderer.entity.RenderBullet; -import game.renderer.entity.RenderChicken; -import game.renderer.entity.RenderCow; -import game.renderer.entity.RenderCrystal; -import game.renderer.entity.RenderDie; -import game.renderer.entity.RenderDragon; -import game.renderer.entity.RenderDynamite; -import game.renderer.entity.RenderEntity; -import game.renderer.entity.RenderEntityItem; -import game.renderer.entity.RenderFallingBlock; -import game.renderer.entity.RenderFireball; -import game.renderer.entity.RenderFish; -import game.renderer.entity.RenderFlyingBox; -import game.renderer.entity.RenderHorse; -import game.renderer.entity.RenderHumanoid; -import game.renderer.entity.RenderItem; -import game.renderer.entity.RenderItemEntity; -import game.renderer.entity.RenderLeashKnot; -import game.renderer.entity.RenderLightning; -import game.renderer.entity.RenderManager; -import game.renderer.entity.RenderMinecart; -import game.renderer.entity.RenderMooshroom; -import game.renderer.entity.RenderMouse; -import game.renderer.entity.RenderNpc; -import game.renderer.entity.RenderOcelot; -import game.renderer.entity.RenderPig; -import game.renderer.entity.RenderPotion; -import game.renderer.entity.RenderRabbit; -import game.renderer.entity.RenderSheep; -import game.renderer.entity.RenderSlime; -import game.renderer.entity.RenderSpaceMarine; -import game.renderer.entity.RenderSquid; -import game.renderer.entity.RenderTntMinecart; -import game.renderer.entity.RenderTntPrimed; -import game.renderer.entity.RenderWolf; -import game.renderer.entity.RenderXpOrb; -import game.renderer.model.ModelChicken; -import game.renderer.model.ModelCow; -import game.renderer.model.ModelHorse; -import game.renderer.model.ModelMouse; -import game.renderer.model.ModelOcelot; -import game.renderer.model.ModelPig; -import game.renderer.model.ModelRabbit; -import game.renderer.model.ModelSheep2; -import game.renderer.model.ModelSquid; -import game.renderer.model.ModelWolf; import game.world.World; public abstract class EntityRegistry { @@ -385,59 +329,4 @@ public abstract class EntityRegistry { // } registerEggs(); } - - public static void registerRenderers(Map, Render> map, - Map models, RenderManager mgr, RenderItem ritem) { - map.put(EntityPig.class, new RenderPig(mgr, new ModelPig())); - map.put(EntitySheep.class, new RenderSheep(mgr, new ModelSheep2())); - map.put(EntityCow.class, new RenderCow(mgr, new ModelCow())); - map.put(EntityMooshroom.class, new RenderMooshroom(mgr, new ModelCow())); - map.put(EntityWolf.class, new RenderWolf(mgr, new ModelWolf())); - map.put(EntityChicken.class, new RenderChicken(mgr, new ModelChicken())); - map.put(EntityOcelot.class, new RenderOcelot(mgr, new ModelOcelot())); - map.put(EntityRabbit.class, new RenderRabbit(mgr, new ModelRabbit())); - map.put(EntitySquid.class, new RenderSquid(mgr, new ModelSquid())); - map.put(EntityBat.class, new RenderBat(mgr)); - map.put(EntityDragon.class, new RenderDragon(mgr)); - map.put(EntityCrystal.class, new RenderCrystal(mgr)); - map.put(Entity.class, new RenderEntity(mgr)); -// map.put(EntityPainting.class, new RenderPainting(mgr)); -// map.put(EntityFrame.class, new RenderItemFrame(mgr, ritem)); - map.put(EntityLeashKnot.class, new RenderLeashKnot(mgr)); - map.put(EntityArrow.class, new RenderArrow(mgr)); - map.put(EntitySnowball.class, new RenderItemEntity(mgr, Items.snowball, ritem)); - map.put(EntityOrb.class, new RenderItemEntity(mgr, Items.charged_orb, ritem)); - map.put(EntityEgg.class, new RenderItemEntity(mgr, Items.egg, ritem)); - map.put(EntityPotion.class, new RenderPotion(mgr, ritem)); - map.put(EntityXpBottle.class, new RenderItemEntity(mgr, Items.experience_bottle, ritem)); - map.put(EntityFireworks.class, new RenderItemEntity(mgr, Items.fireworks, ritem)); - map.put(EntityFireball.class, new RenderFireball(mgr, 0.75F)); - map.put(EntityFireCharge.class, new RenderFireball(mgr, 0.5F)); - map.put(EntityBox.class, new RenderFlyingBox(mgr)); - map.put(EntityItem.class, new RenderEntityItem(mgr, ritem)); - map.put(EntityXp.class, new RenderXpOrb(mgr)); - map.put(EntityTnt.class, new RenderTntPrimed(mgr)); - map.put(EntityFalling.class, new RenderFallingBlock(mgr)); - map.put(EntityTntCart.class, new RenderTntMinecart(mgr)); - map.put(EntityCart.class, new RenderMinecart(mgr)); - map.put(EntityBoat.class, new RenderBoat(mgr)); - map.put(EntityHook.class, new RenderFish(mgr)); - map.put(EntityHorse.class, new RenderHorse(mgr, new ModelHorse())); - map.put(EntityDynamite.class, new RenderDynamite(mgr, Items.dynamite, ritem)); - map.put(EntityNuke.class, new RenderBlockEntity(mgr, Blocks.nuke.getState())); - map.put(EntityMouse.class, new RenderMouse(mgr, new ModelMouse())); - map.put(EntityDie.class, new RenderDie(mgr)); - map.put(EntityBullet.class, new RenderBullet(mgr)); - map.put(EntityLightning.class, new RenderLightning(mgr)); - models.put(ModelType.HUMANOID, new RenderHumanoid(mgr, 12, 12, "textures/entity/char.png")); - models.put(ModelType.ARACHNOID, new RenderArachnoid(mgr)); - models.put(ModelType.SLIME, new RenderSlime(mgr)); - models.put(ModelType.DWARF, new RenderHumanoid(mgr, 10, 10, "textures/entity/dwarf.png")); - models.put(ModelType.HALFLING, new RenderHumanoid(mgr, 8, 8, "textures/entity/goblin.png")); - models.put(ModelType.SPACE_MARINE, new RenderSpaceMarine(mgr)); - for(int z = 0; z < SpeciesRegistry.SPECIMEN.size(); z++) { - SpeciesInfo info = SpeciesRegistry.SPECIMEN.get(z); - map.put(info.clazz, models.get(info.renderer)); - } - } } diff --git a/java/src/game/init/FluidRegistry.java b/java/src/game/init/FluidRegistry.java index 429adcf..88545a9 100755 --- a/java/src/game/init/FluidRegistry.java +++ b/java/src/game/init/FluidRegistry.java @@ -3,13 +3,12 @@ package game.init; import java.util.List; import java.util.Map; -import game.collect.Lists; -import game.collect.Maps; - import game.block.Block; import game.block.BlockDynamicLiquid; import game.block.BlockLiquid; import game.block.BlockStaticLiquid; +import game.collect.Lists; +import game.collect.Maps; import game.material.Material; public abstract class FluidRegistry { diff --git a/java/src/game/init/ItemRegistry.java b/java/src/game/init/ItemRegistry.java index 27b52e3..161ba68 100755 --- a/java/src/game/init/ItemRegistry.java +++ b/java/src/game/init/ItemRegistry.java @@ -4,9 +4,6 @@ import java.util.Map; import java.util.Set; import java.util.function.Function; -import game.collect.Maps; -import game.collect.Sets; - import game.block.Block; import game.block.BlockBed; import game.block.BlockButton; @@ -23,6 +20,8 @@ import game.block.BlockSapling; import game.block.BlockSlab; import game.block.BlockStoneBrick; import game.block.BlockWall; +import game.collect.Maps; +import game.collect.Sets; import game.color.DyeColor; import game.color.TextColor; import game.entity.item.EntityCart; diff --git a/java/src/game/init/ObjectIntIdentityMap.java b/java/src/game/init/ObjectIntIdentityMap.java index ea81b20..42b0642 100755 --- a/java/src/game/init/ObjectIntIdentityMap.java +++ b/java/src/game/init/ObjectIntIdentityMap.java @@ -4,9 +4,9 @@ import java.util.IdentityHashMap; import java.util.Iterator; import java.util.List; -import game.util.Predicates; import game.collect.Iterators; import game.collect.Lists; +import game.util.Predicates; public class ObjectIntIdentityMap implements IObjectIntIterable { diff --git a/java/src/game/init/RotationRegistry.java b/java/src/game/init/RotationRegistry.java index 52c8bc2..e8b38ff 100755 --- a/java/src/game/init/RotationRegistry.java +++ b/java/src/game/init/RotationRegistry.java @@ -3,10 +3,7 @@ package game.init; import java.util.HashMap; import java.util.List; import java.util.Map; - import java.util.function.Predicate; -import game.collect.Lists; -import game.collect.Maps; import game.block.Block; import game.block.BlockDoor; @@ -22,6 +19,8 @@ import game.block.BlockRotatedPillar; import game.clipboard.Rotation; import game.clipboard.RotationValue; import game.clipboard.Vector; +import game.collect.Lists; +import game.collect.Maps; import game.properties.IProperty; import game.properties.PropertyDirection; import game.world.Facing; diff --git a/java/src/game/init/SmeltingRegistry.java b/java/src/game/init/SmeltingRegistry.java index b8e3e6f..1d2e404 100755 --- a/java/src/game/init/SmeltingRegistry.java +++ b/java/src/game/init/SmeltingRegistry.java @@ -4,10 +4,9 @@ import java.util.Map; import java.util.Map.Entry; import java.util.Set; -import game.collect.Maps; - import game.block.Block; import game.block.BlockStoneBrick; +import game.collect.Maps; import game.color.DyeColor; import game.item.Item; import game.item.ItemFishFood; diff --git a/java/src/game/init/SoundEvent.java b/java/src/game/init/SoundEvent.java index 716f5d2..ddeb5b2 100755 --- a/java/src/game/init/SoundEvent.java +++ b/java/src/game/init/SoundEvent.java @@ -1,14 +1,5 @@ package game.init; -import java.io.BufferedInputStream; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.io.InputStream; -import game.audio.CodecJOrbis; -import game.log.Log; -import game.rng.Random; -import game.util.FileUtils; - public enum SoundEvent { CLOTH("cloth1", "cloth2", "cloth3", "cloth4"), GRASS("grass1", "grass2", "grass3", "grass4"), @@ -122,53 +113,14 @@ public enum SoundEvent { SLIME_ATTACK("slime_attack1", "slime_attack2"), SLIME_BIG("slime_big1", "slime_big2", "slime_big3", "slime_big4"), SLIME_SMALL("slime_small1", "slime_small2", "slime_small3", "slime_small4", "slime_small5"); - - private static final Random RANDOM = new Random(); private final String[] sounds; - private final short[][] buffers; - - public static void loadSounds() { - int n = 0; - for(SoundEvent entry : SoundEvent.values()) { - for(int z = 0; z < entry.sounds.length; z++) { - String sound = entry.sounds[z]; - Log.SOUND.trace("Lade Sound %s", sound); - entry.buffers[z] = readOgg("sounds/" + sound + ".ogg"); - } - } - } - - private static short[] readOgg(String filename) { - InputStream in = null; - try { - in = new BufferedInputStream(FileUtils.getResource(filename)); - return CodecJOrbis.readAll(in); - } - catch(FileNotFoundException e) { - Log.IO.error("Fehler beim Lesen von OPUS-Datei '%s': Datei nicht gefunden", filename); - return null; - } - catch(Exception e) { - Log.IO.error("Fehler beim Lesen von OPUS-Datei '%s': %s", filename, e.getMessage()); - return null; - } - finally { - try { - if(in != null) - in.close(); - } - catch(IOException e) { - } - } - } private SoundEvent(String ... sounds) { this.sounds = sounds; - this.buffers = new short[sounds.length][]; } - public short[] getBuffer() { - return RANDOM.pick(this.buffers); + public String[] getSounds() { + return this.sounds; } } diff --git a/java/src/game/init/SpeciesRegistry.java b/java/src/game/init/SpeciesRegistry.java index e6df5e4..5afa09e 100755 --- a/java/src/game/init/SpeciesRegistry.java +++ b/java/src/game/init/SpeciesRegistry.java @@ -7,7 +7,6 @@ import java.util.Set; import game.collect.Lists; import game.collect.Maps; import game.collect.Sets; - import game.entity.npc.EntityArachnoid; import game.entity.npc.EntityBloodElf; import game.entity.npc.EntityChaosMarine; diff --git a/java/src/game/init/TileRegistry.java b/java/src/game/init/TileRegistry.java index d8d4147..8da4f9d 100755 --- a/java/src/game/init/TileRegistry.java +++ b/java/src/game/init/TileRegistry.java @@ -3,7 +3,6 @@ package game.init; import java.util.Map; import game.collect.Maps; - import game.tileentity.TileEntity; import game.tileentity.TileEntityBanner; import game.tileentity.TileEntityBeacon; diff --git a/java/src/game/init/ToolMaterial.java b/java/src/game/init/ToolMaterial.java index bff7669..85fade6 100755 --- a/java/src/game/init/ToolMaterial.java +++ b/java/src/game/init/ToolMaterial.java @@ -3,7 +3,6 @@ package game.init; import java.util.Set; import game.collect.Sets; - import game.item.Item; public class ToolMaterial diff --git a/java/src/game/init/UniverseRegistry.java b/java/src/game/init/UniverseRegistry.java index e42c48c..396de6c 100755 --- a/java/src/game/init/UniverseRegistry.java +++ b/java/src/game/init/UniverseRegistry.java @@ -5,14 +5,13 @@ import java.util.Map; import java.util.Map.Entry; import java.util.Set; -import game.collect.Lists; -import game.collect.Maps; -import game.collect.Sets; - import game.biome.Biome; import game.block.BlockColored; import game.block.BlockSand; import game.block.LeavesType; +import game.collect.Lists; +import game.collect.Maps; +import game.collect.Sets; import game.color.DyeColor; import game.dimension.Area; import game.dimension.DimType; diff --git a/java/src/game/inventory/Container.java b/java/src/game/inventory/Container.java index 34fa6fb..8472563 100755 --- a/java/src/game/inventory/Container.java +++ b/java/src/game/inventory/Container.java @@ -5,7 +5,6 @@ import java.util.Set; import game.collect.Lists; import game.collect.Sets; - import game.entity.npc.EntityNPC; import game.item.Item; import game.item.ItemStack; diff --git a/java/src/game/inventory/ContainerLocalMenu.java b/java/src/game/inventory/ContainerLocalMenu.java index 9b2fa72..08d7992 100755 --- a/java/src/game/inventory/ContainerLocalMenu.java +++ b/java/src/game/inventory/ContainerLocalMenu.java @@ -3,7 +3,6 @@ package game.inventory; import java.util.Map; import game.collect.Maps; - import game.entity.npc.EntityNPC; import game.tileentity.ILockableContainer; import game.tileentity.LockCode; diff --git a/java/src/game/inventory/ContainerPlayer.java b/java/src/game/inventory/ContainerPlayer.java index 24f9857..c5ce694 100755 --- a/java/src/game/inventory/ContainerPlayer.java +++ b/java/src/game/inventory/ContainerPlayer.java @@ -3,7 +3,6 @@ package game.inventory; import java.util.List; import game.collect.Lists; - import game.entity.attributes.AttributeMap; import game.entity.npc.EntityNPC; import game.init.CraftingRegistry; diff --git a/java/src/game/inventory/InventoryBasic.java b/java/src/game/inventory/InventoryBasic.java index 38db51e..c7667da 100755 --- a/java/src/game/inventory/InventoryBasic.java +++ b/java/src/game/inventory/InventoryBasic.java @@ -3,7 +3,6 @@ package game.inventory; import java.util.List; import game.collect.Lists; - import game.entity.npc.EntityNPC; import game.item.ItemStack; diff --git a/java/src/game/item/Item.java b/java/src/game/item/Item.java index 7a7f408..7f68355 100755 --- a/java/src/game/item/Item.java +++ b/java/src/game/item/Item.java @@ -4,19 +4,19 @@ import java.util.List; import java.util.Map; import java.util.Set; +import game.block.Block; import game.collect.Maps; import game.collect.Sets; - -import game.block.Block; import game.color.TextColor; import game.entity.attributes.Attribute; import game.entity.attributes.AttributeModifier; import game.entity.npc.EntityNPC; import game.entity.types.EntityLiving; +import game.model.ItemMeshDefinition; +import game.model.Model; +import game.model.ModelProvider; +import game.model.Transforms; import game.nbt.NBTTagCompound; -import game.renderer.ItemMeshDefinition; -import game.renderer.blockmodel.ModelBlock; -import game.renderer.blockmodel.Transforms; import game.rng.Random; import game.util.ExtMath; import game.world.BlockPos; @@ -660,8 +660,8 @@ public class Item return Transforms.ITEM; } - public ModelBlock getModel(String name, int meta) { - return new ModelBlock(this.getTransform(), name); + public Model getModel(ModelProvider provider, String name, int meta) { + return provider.getModel(this.getTransform(), name); } public ItemMeshDefinition getMesher() { diff --git a/java/src/game/item/ItemArmor.java b/java/src/game/item/ItemArmor.java index 74cedb3..cc0f01b 100755 --- a/java/src/game/item/ItemArmor.java +++ b/java/src/game/item/ItemArmor.java @@ -3,11 +3,10 @@ package game.item; import java.util.List; import java.util.Map; import java.util.Set; - import java.util.function.Predicate; -import game.collect.Sets; import game.block.BlockDispenser; +import game.collect.Sets; import game.dispenser.BehaviorDefaultDispenseItem; import game.dispenser.IBehaviorDispenseItem; import game.dispenser.IBlockSource; @@ -18,9 +17,10 @@ import game.entity.npc.EntityNPC; import game.entity.types.EntityLiving; import game.init.DispenserRegistry; import game.init.ToolMaterial; +import game.model.Model; +import game.model.ModelProvider; +import game.model.Transforms; import game.nbt.NBTTagCompound; -import game.renderer.blockmodel.ModelBlock; -import game.renderer.blockmodel.Transforms; import game.world.BlockPos; import game.world.BoundingBox; import game.world.World; @@ -279,11 +279,11 @@ public class ItemArmor extends Item super.getTransform()); } - public ModelBlock getModel(String name, int meta) { + public Model getModel(ModelProvider provider, String name, int meta) { if(this.material.canBeDyed()) - return new ModelBlock(this.getTransform(), name, name + "_overlay"); + return provider.getModel(this.getTransform(), name, name + "_overlay"); else - return super.getModel(name, meta); + return super.getModel(provider, name, meta); } public void addInformation(ItemStack stack, EntityNPC playerIn, List tooltip) { diff --git a/java/src/game/item/ItemBanner.java b/java/src/game/item/ItemBanner.java index 4885146..46f28bf 100755 --- a/java/src/game/item/ItemBanner.java +++ b/java/src/game/item/ItemBanner.java @@ -7,11 +7,11 @@ import game.block.BlockWallSign; import game.color.DyeColor; import game.entity.npc.EntityNPC; import game.init.Blocks; -import game.model.ModelBakery; +import game.model.ItemMeshDefinition; +import game.model.Model; +import game.model.ModelProvider; import game.nbt.NBTTagCompound; import game.nbt.NBTTagList; -import game.renderer.ItemMeshDefinition; -import game.renderer.blockmodel.ModelBlock; import game.tileentity.TileEntity; import game.tileentity.TileEntityBanner; import game.util.ExtMath; @@ -214,7 +214,7 @@ public class ItemBanner extends ItemBlock subItems.add(new ItemStack(itemIn, 1, 0)); } - public ModelBlock getModel(String name, int meta) { - return new ModelBlock(ModelBakery.MODEL_ENTITY, this.getTransform()); + public Model getModel(ModelProvider provider, String name, int meta) { + return provider.getModel(provider.getEntityModel(), this.getTransform()); } } diff --git a/java/src/game/item/ItemBlock.java b/java/src/game/item/ItemBlock.java index 85c373f..b619ade 100755 --- a/java/src/game/item/ItemBlock.java +++ b/java/src/game/item/ItemBlock.java @@ -8,9 +8,10 @@ import game.entity.Entity; import game.entity.npc.EntityNPC; import game.init.BlockRegistry; import game.init.Blocks; +import game.model.Model; +import game.model.ModelProvider; +import game.model.Transforms; import game.nbt.NBTTagCompound; -import game.renderer.blockmodel.ModelBlock; -import game.renderer.blockmodel.Transforms; import game.tileentity.TileEntity; import game.world.BlockPos; import game.world.Facing; @@ -214,11 +215,11 @@ public class ItemBlock extends Item return this.flatTexture != null ? super.getTransform() : this.block.getTransform(); } - public ModelBlock getModel(String name, int meta) { - return this.flatTexture != null ? new ModelBlock(this.getTransform(), !this.flatTexture.isEmpty() ? this.flatTexture : - this.block.getModel(BlockRegistry.REGISTRY.getNameForObject(this.block).toString(), - this.block.getStateFromMeta(this.getMetadata(meta))).getPrimary() /* "blocks/" + name */) : - new ModelBlock(this.block.getModel(BlockRegistry.REGISTRY.getNameForObject(this.block).toString(), - this.block.getStateFromMeta(this.getMetadata(meta))), this.getTransform()); + public Model getModel(ModelProvider provider, String name, int meta) { + return this.flatTexture != null ? provider.getModel(this.getTransform(), !this.flatTexture.isEmpty() ? this.flatTexture : + this.block.getModel(provider, + BlockRegistry.REGISTRY.getNameForObject(this.block).toString(), this.block.getStateFromMeta(this.getMetadata(meta))).getPrimary() /* "blocks/" + name */) : + provider.getModel(this.block.getModel(provider, + BlockRegistry.REGISTRY.getNameForObject(this.block).toString(), this.block.getStateFromMeta(this.getMetadata(meta))), this.getTransform()); } } diff --git a/java/src/game/item/ItemBow.java b/java/src/game/item/ItemBow.java index 8147936..4670914 100755 --- a/java/src/game/item/ItemBow.java +++ b/java/src/game/item/ItemBow.java @@ -8,8 +8,9 @@ import game.entity.npc.EntityNPC; import game.entity.projectile.EntityArrow; import game.init.Items; import game.init.SoundEvent; -import game.renderer.blockmodel.ModelBlock; -import game.renderer.blockmodel.Transforms; +import game.model.Model; +import game.model.ModelProvider; +import game.model.Transforms; import game.world.World; public class ItemBow extends Item @@ -148,8 +149,8 @@ public class ItemBow extends Item return Transforms.RANGED; } - public ModelBlock getModel(String name, int meta) { - return new ModelBlock(this.getTransform(), meta == 0 ? "bow" : ("bow_pulling_" + (meta - 1))); + public Model getModel(ModelProvider provider, String name, int meta) { + return provider.getModel(this.getTransform(), meta == 0 ? "bow" : ("bow_pulling_" + (meta - 1))); } public boolean canBeWielded() { diff --git a/java/src/game/item/ItemBucket.java b/java/src/game/item/ItemBucket.java index 65ef496..ee2f4de 100755 --- a/java/src/game/item/ItemBucket.java +++ b/java/src/game/item/ItemBucket.java @@ -7,12 +7,11 @@ import java.util.List; import java.util.Queue; import java.util.Set; -import game.collect.Sets; - import game.block.Block; import game.block.BlockDynamicLiquid; import game.block.BlockLiquid; import game.block.BlockStaticLiquid; +import game.collect.Sets; import game.entity.npc.EntityNPC; import game.init.BlockRegistry; import game.init.Blocks; @@ -21,8 +20,9 @@ import game.init.ItemRegistry; import game.init.Items; import game.init.SoundEvent; import game.material.Material; -import game.renderer.blockmodel.ModelBlock; -import game.renderer.particle.ParticleType; +import game.model.Model; +import game.model.ModelProvider; +import game.model.ParticleType; import game.world.BlockPos; import game.world.HitPosition; import game.world.State; @@ -316,8 +316,8 @@ public class ItemBucket extends Item return true; } - public ModelBlock getModel(String name, int meta) { - return this.recursive ? new ModelBlock(this.getTransform(), name.substring("recursive_".length())) : super.getModel(name, meta); + public Model getModel(ModelProvider provider, String name, int meta) { + return this.recursive ? provider.getModel(this.getTransform(), name.substring("recursive_".length())) : super.getModel(provider, name, meta); } // public ItemMeshDefinition getMesher() { @@ -337,11 +337,11 @@ public class ItemBucket extends Item // subItems.add(new ItemStack(itemIn, 1, 0)); // } -// public ModelBlock getModel(String name, int meta) { +// public Model getModel(String name, int meta) { // if(this.empty) // return super.getModel(name, meta); // else -// return new ModelBlock(this.getTransform(), meta < 0 || meta >= FluidRegistry.getNumFluids() ? "bucket" : +// return provider.getModel(this.getTransform(), meta < 0 || meta >= FluidRegistry.getNumFluids() ? "bucket" : // (BlockRegistry.REGISTRY.getNameForObject(FluidRegistry.getStaticBlock(meta)) + "_bucket")); // } } diff --git a/java/src/game/item/ItemBucketMilk.java b/java/src/game/item/ItemBucketMilk.java index 5ffdc20..d6aea49 100755 --- a/java/src/game/item/ItemBucketMilk.java +++ b/java/src/game/item/ItemBucketMilk.java @@ -4,7 +4,6 @@ import java.util.Map; import java.util.Set; import game.collect.Sets; - import game.entity.attributes.Attribute; import game.entity.attributes.AttributeModifier; import game.entity.attributes.Attributes; diff --git a/java/src/game/item/ItemButton.java b/java/src/game/item/ItemButton.java index 52a25e8..7645145 100755 --- a/java/src/game/item/ItemButton.java +++ b/java/src/game/item/ItemButton.java @@ -1,7 +1,8 @@ package game.item; import game.block.BlockButton; -import game.renderer.blockmodel.ModelBlock; +import game.model.Model; +import game.model.ModelProvider; public class ItemButton extends ItemBlock { private final BlockButton button; @@ -11,8 +12,8 @@ public class ItemButton extends ItemBlock { this.button = block; } - public ModelBlock getModel(String name, int meta) { - return new ModelBlock(new ModelBlock(this.button.getTexture()).add(5, 6, 6, 11, 10, 10) + public Model getModel(ModelProvider provider, String name, int meta) { + return provider.getModel(provider.getModel(this.button.getTexture()).add(5, 6, 6, 11, 10, 10) .d().uv(5, 6, 11, 10).noCull().u().uv(5, 10, 11, 6).noCull() .ns().uv(5, 12, 11, 16).noCull().we().uv(6, 12, 10, 16).noCull(), this.getTransform()); } diff --git a/java/src/game/item/ItemCarrotOnAStick.java b/java/src/game/item/ItemCarrotOnAStick.java index 33a15a4..6eb5c1d 100755 --- a/java/src/game/item/ItemCarrotOnAStick.java +++ b/java/src/game/item/ItemCarrotOnAStick.java @@ -3,7 +3,7 @@ package game.item; import game.entity.animal.EntityPig; import game.entity.npc.EntityNPC; import game.init.Items; -import game.renderer.blockmodel.Transforms; +import game.model.Transforms; import game.world.World; public class ItemCarrotOnAStick extends Item diff --git a/java/src/game/item/ItemChargedOrb.java b/java/src/game/item/ItemChargedOrb.java index 928e51e..7cd9990 100755 --- a/java/src/game/item/ItemChargedOrb.java +++ b/java/src/game/item/ItemChargedOrb.java @@ -7,7 +7,7 @@ import game.entity.npc.EntityNPC; import game.init.Blocks; import game.init.Items; import game.init.SoundEvent; -import game.renderer.particle.ParticleType; +import game.model.ParticleType; import game.world.BlockPos; import game.world.Facing; import game.world.State; diff --git a/java/src/game/item/ItemChest.java b/java/src/game/item/ItemChest.java index 4974a74..50c11e7 100755 --- a/java/src/game/item/ItemChest.java +++ b/java/src/game/item/ItemChest.java @@ -1,17 +1,17 @@ package game.item; import game.block.Block; -import game.model.ModelBakery; -import game.renderer.blockmodel.ModelBlock; -import game.renderer.blockmodel.Transforms; +import game.model.Model; +import game.model.ModelProvider; +import game.model.Transforms; public class ItemChest extends ItemBlock { public ItemChest(Block block) { super(block); } - public ModelBlock getModel(String name, int meta) { - return new ModelBlock(ModelBakery.MODEL_ENTITY, this.getTransform()); + public Model getModel(ModelProvider provider, String name, int meta) { + return provider.getModel(provider.getEntityModel(), this.getTransform()); } public Transforms getTransform() { diff --git a/java/src/game/item/ItemCloth.java b/java/src/game/item/ItemCloth.java index 5892e22..791a8cd 100755 --- a/java/src/game/item/ItemCloth.java +++ b/java/src/game/item/ItemCloth.java @@ -2,7 +2,8 @@ package game.item; import game.block.Block; import game.color.DyeColor; -import game.renderer.blockmodel.ModelBlock; +import game.model.Model; +import game.model.ModelProvider; public class ItemCloth extends ItemBlock { @@ -39,8 +40,8 @@ public class ItemCloth extends ItemBlock return DyeColor.byMetadata(stack.getMetadata()).getSubject(this.display) + " " + super.getDisplay(stack); } - public ModelBlock getModel(String name, int meta) { - return this.flatTexture != null ? new ModelBlock(this.getTransform(), "blocks/" + DyeColor.byMetadata(meta).getName() + "_" + - this.flatTexture) : super.getModel(name, meta); + public Model getModel(ModelProvider provider, String name, int meta) { + return this.flatTexture != null ? provider.getModel(this.getTransform(), "blocks/" + DyeColor.byMetadata(meta).getName() + "_" + + this.flatTexture) : super.getModel(provider, name, meta); } } diff --git a/java/src/game/item/ItemCoal.java b/java/src/game/item/ItemCoal.java index 4943f64..637ddaa 100755 --- a/java/src/game/item/ItemCoal.java +++ b/java/src/game/item/ItemCoal.java @@ -2,7 +2,8 @@ package game.item; import java.util.List; -import game.renderer.blockmodel.ModelBlock; +import game.model.Model; +import game.model.ModelProvider; public class ItemCoal extends Item { @@ -31,7 +32,7 @@ public class ItemCoal extends Item subItems.add(new ItemStack(itemIn, 1, 1)); } - public ModelBlock getModel(String name, int meta) { - return new ModelBlock(this.getTransform(), meta == 1 ? "charcoal" : "coal"); + public Model getModel(ModelProvider provider, String name, int meta) { + return provider.getModel(this.getTransform(), meta == 1 ? "charcoal" : "coal"); } } diff --git a/java/src/game/item/ItemDie.java b/java/src/game/item/ItemDie.java index c2f29ca..86c7b86 100755 --- a/java/src/game/item/ItemDie.java +++ b/java/src/game/item/ItemDie.java @@ -6,8 +6,9 @@ import game.color.TextColor; import game.entity.npc.EntityNPC; import game.entity.projectile.EntityDie; import game.init.SoundEvent; -import game.renderer.blockmodel.ModelBlock; -import game.renderer.blockmodel.Transforms; +import game.model.Model; +import game.model.ModelProvider; +import game.model.Transforms; import game.util.ExtMath; import game.world.World; @@ -59,8 +60,8 @@ public class ItemDie extends Item return Transforms.DICE; } - public ModelBlock getModel(String name, int meta) { - return new ModelBlock(new ModelBlock("items/die_d" + DIE_SIDES[meta] + "_side").add().nswe() + public Model getModel(ModelProvider provider, String name, int meta) { + return provider.getModel(provider.getModel("items/die_d" + DIE_SIDES[meta] + "_side").add().nswe() .du("items/die_d" + DIE_SIDES[meta] + "_top"), this.getTransform()); } } diff --git a/java/src/game/item/ItemDoublePlant.java b/java/src/game/item/ItemDoublePlant.java index e326216..3ac9222 100755 --- a/java/src/game/item/ItemDoublePlant.java +++ b/java/src/game/item/ItemDoublePlant.java @@ -6,7 +6,8 @@ import game.block.Block; import game.block.BlockDoublePlant; import game.block.BlockDoublePlant.EnumPlantType; import game.color.Colorizer; -import game.renderer.blockmodel.ModelBlock; +import game.model.Model; +import game.model.ModelProvider; public class ItemDoublePlant extends ItemMultiTexture { @@ -21,8 +22,8 @@ public class ItemDoublePlant extends ItemMultiTexture return blockdoubleplant$enumplanttype != BlockDoublePlant.EnumPlantType.GRASS && blockdoubleplant$enumplanttype != BlockDoublePlant.EnumPlantType.FERN ? super.getColorFromItemStack(stack, renderPass) : Colorizer.getGrassColor(0.5D, 1.0D); } - public ModelBlock getModel(String name, int meta) { - return new ModelBlock(this.getTransform(), "blocks/" + ( + public Model getModel(ModelProvider provider, String name, int meta) { + return provider.getModel(this.getTransform(), "blocks/" + ( BlockDoublePlant.EnumPlantType.byMetadata(meta) == EnumPlantType.SUNFLOWER ? "sunflower_front" : BlockDoublePlant.EnumPlantType.byMetadata(meta).getName() + "_top")); } diff --git a/java/src/game/item/ItemDye.java b/java/src/game/item/ItemDye.java index 46ca085..b74ef3e 100755 --- a/java/src/game/item/ItemDye.java +++ b/java/src/game/item/ItemDye.java @@ -12,8 +12,9 @@ import game.entity.types.EntityLiving; import game.init.BlockRegistry; import game.init.Blocks; import game.material.Material; -import game.renderer.blockmodel.ModelBlock; -import game.renderer.particle.ParticleType; +import game.model.Model; +import game.model.ModelProvider; +import game.model.ParticleType; import game.tileentity.TileEntity; import game.tileentity.TileEntityBeacon; import game.world.BlockPos; @@ -229,7 +230,7 @@ public class ItemDye extends Item } } - public ModelBlock getModel(String name, int meta) { - return new ModelBlock(this.getTransform(), "dye_" + DyeColor.byDyeDamage(meta).getName()); + public Model getModel(ModelProvider provider, String name, int meta) { + return provider.getModel(this.getTransform(), "dye_" + DyeColor.byDyeDamage(meta).getName()); } } diff --git a/java/src/game/item/ItemDynamite.java b/java/src/game/item/ItemDynamite.java index ffd637d..d6b695a 100755 --- a/java/src/game/item/ItemDynamite.java +++ b/java/src/game/item/ItemDynamite.java @@ -5,7 +5,8 @@ import java.util.List; import game.entity.npc.EntityNPC; import game.entity.projectile.EntityDynamite; import game.init.SoundEvent; -import game.renderer.blockmodel.ModelBlock; +import game.model.Model; +import game.model.ModelProvider; import game.world.World; public class ItemDynamite extends Item @@ -54,7 +55,7 @@ public class ItemDynamite extends Item return super.getDisplay(stack) + (exp == 0 ? "" : " " + TIERS[exp-1]); } - public ModelBlock getModel(String name, int meta) { - return new ModelBlock(this.getTransform(), "dynamite" + (meta == 0 ? "" : ("_" + meta))); + public Model getModel(ModelProvider provider, String name, int meta) { + return provider.getModel(this.getTransform(), "dynamite" + (meta == 0 ? "" : ("_" + meta))); } } diff --git a/java/src/game/item/ItemEditWand.java b/java/src/game/item/ItemEditWand.java index 057a0f5..e5248f7 100755 --- a/java/src/game/item/ItemEditWand.java +++ b/java/src/game/item/ItemEditWand.java @@ -1,7 +1,7 @@ package game.item; import game.entity.npc.EntityNPC; -import game.renderer.blockmodel.Transforms; +import game.model.Transforms; import game.world.BlockPos; import game.world.World; diff --git a/java/src/game/item/ItemEnchantedBook.java b/java/src/game/item/ItemEnchantedBook.java index bd1834f..ebdf3e9 100755 --- a/java/src/game/item/ItemEnchantedBook.java +++ b/java/src/game/item/ItemEnchantedBook.java @@ -8,9 +8,9 @@ import game.enchantment.EnchantmentHelper; import game.enchantment.RngEnchantment; import game.entity.npc.EntityNPC; import game.init.Items; +import game.model.ItemMeshDefinition; import game.nbt.NBTTagCompound; import game.nbt.NBTTagList; -import game.renderer.ItemMeshDefinition; import game.rng.Random; public class ItemEnchantedBook extends Item diff --git a/java/src/game/item/ItemFence.java b/java/src/game/item/ItemFence.java index a36455d..846c9dc 100755 --- a/java/src/game/item/ItemFence.java +++ b/java/src/game/item/ItemFence.java @@ -2,15 +2,16 @@ package game.item; import game.block.Block; import game.block.BlockFence; -import game.renderer.blockmodel.ModelBlock; +import game.model.Model; +import game.model.ModelProvider; public class ItemFence extends ItemBlock { public ItemFence(Block block) { super(block); } - public ModelBlock getModel(String name, int meta) { - return new ModelBlock(new ModelBlock(((BlockFence)this.block).getTexture()).noOcclude() + public Model getModel(ModelProvider provider, String name, int meta) { + return provider.getModel(provider.getModel(((BlockFence)this.block).getTexture()).noOcclude() .add(6, 0, 0, 10, 16, 4) .d().uv(6, 0, 10, 4) .u().uv(6, 0, 10, 4).noCull() diff --git a/java/src/game/item/ItemFirework.java b/java/src/game/item/ItemFirework.java index 3e867cc..5f606c9 100755 --- a/java/src/game/item/ItemFirework.java +++ b/java/src/game/item/ItemFirework.java @@ -3,7 +3,6 @@ package game.item; import java.util.List; import game.collect.Lists; - import game.entity.item.EntityFireworks; import game.entity.npc.EntityNPC; import game.nbt.NBTTagCompound; diff --git a/java/src/game/item/ItemFireworkCharge.java b/java/src/game/item/ItemFireworkCharge.java index 458a26b..e239551 100755 --- a/java/src/game/item/ItemFireworkCharge.java +++ b/java/src/game/item/ItemFireworkCharge.java @@ -4,10 +4,11 @@ import java.util.List; import game.color.DyeColor; import game.entity.npc.EntityNPC; +import game.model.Model; +import game.model.ModelProvider; import game.nbt.NBTBase; import game.nbt.NBTTagCompound; import game.nbt.NBTTagIntArray; -import game.renderer.blockmodel.ModelBlock; public class ItemFireworkCharge extends Item { @@ -193,7 +194,7 @@ public class ItemFireworkCharge extends Item // return Sets.newHashSet("Explosion"); // } - public ModelBlock getModel(String name, int meta) { - return new ModelBlock(this.getTransform(), "firework_charge", "firework_charge_overlay"); + public Model getModel(ModelProvider provider, String name, int meta) { + return provider.getModel(this.getTransform(), "firework_charge", "firework_charge_overlay"); } } diff --git a/java/src/game/item/ItemFishFood.java b/java/src/game/item/ItemFishFood.java index 93b554e..c5464fa 100755 --- a/java/src/game/item/ItemFishFood.java +++ b/java/src/game/item/ItemFishFood.java @@ -4,12 +4,12 @@ import java.util.List; import java.util.Map; import game.collect.Maps; - import game.entity.npc.EntityNPC; +import game.model.Model; +import game.model.ModelProvider; import game.potion.Potion; import game.potion.PotionEffect; import game.potion.PotionHelper; -import game.renderer.blockmodel.ModelBlock; import game.world.World; public class ItemFishFood extends ItemFood @@ -71,8 +71,8 @@ public class ItemFishFood extends ItemFood return (type.canCook() ? (this.cooked ? "Gebratener " : "Roher ") : "") + type.getName(); } - public ModelBlock getModel(String name, int meta) { - return new ModelBlock(this.getTransform(), (this.cooked ? "cooked_" : "") + FishType.byMetadata(meta).getTexture()); + public Model getModel(ModelProvider provider, String name, int meta) { + return provider.getModel(this.getTransform(), (this.cooked ? "cooked_" : "") + FishType.byMetadata(meta).getTexture()); } public static enum FishType diff --git a/java/src/game/item/ItemFishingRod.java b/java/src/game/item/ItemFishingRod.java index ca91cc9..da31478 100755 --- a/java/src/game/item/ItemFishingRod.java +++ b/java/src/game/item/ItemFishingRod.java @@ -5,8 +5,9 @@ import java.util.List; import game.entity.npc.EntityNPC; import game.entity.projectile.EntityHook; import game.init.SoundEvent; -import game.renderer.blockmodel.ModelBlock; -import game.renderer.blockmodel.Transforms; +import game.model.Model; +import game.model.ModelProvider; +import game.model.Transforms; import game.world.World; public class ItemFishingRod extends Item @@ -87,7 +88,7 @@ public class ItemFishingRod extends Item return Transforms.TOOL_FLIP; } - public ModelBlock getModel(String name, int meta) { - return new ModelBlock(this.getTransform(), meta == 1 ? "fishing_rod_cast" : "fishing_rod"); + public Model getModel(ModelProvider provider, String name, int meta) { + return provider.getModel(this.getTransform(), meta == 1 ? "fishing_rod_cast" : "fishing_rod"); } } diff --git a/java/src/game/item/ItemGlassBottle.java b/java/src/game/item/ItemGlassBottle.java index 448a435..5d765c6 100755 --- a/java/src/game/item/ItemGlassBottle.java +++ b/java/src/game/item/ItemGlassBottle.java @@ -3,7 +3,8 @@ package game.item; import game.entity.npc.EntityNPC; import game.init.Items; import game.material.Material; -import game.renderer.blockmodel.ModelBlock; +import game.model.Model; +import game.model.ModelProvider; import game.world.BlockPos; import game.world.HitPosition; import game.world.World; @@ -63,7 +64,7 @@ public class ItemGlassBottle extends Item } } - public ModelBlock getModel(String name, int meta) { - return new ModelBlock(this.getTransform(), "potion_bottle_empty"); + public Model getModel(ModelProvider provider, String name, int meta) { + return provider.getModel(this.getTransform(), "potion_bottle_empty"); } } diff --git a/java/src/game/item/ItemGunBase.java b/java/src/game/item/ItemGunBase.java index 77ca3f8..437bb77 100755 --- a/java/src/game/item/ItemGunBase.java +++ b/java/src/game/item/ItemGunBase.java @@ -5,7 +5,7 @@ import game.enchantment.EnchantmentHelper; import game.entity.npc.EntityNPC; import game.entity.projectile.EntityBullet; import game.init.SoundEvent; -import game.renderer.blockmodel.Transforms; +import game.model.Transforms; import game.world.World; public abstract class ItemGunBase extends Item diff --git a/java/src/game/item/ItemHoe.java b/java/src/game/item/ItemHoe.java index 3e94c2c..30ab087 100755 --- a/java/src/game/item/ItemHoe.java +++ b/java/src/game/item/ItemHoe.java @@ -6,7 +6,7 @@ import game.entity.npc.EntityNPC; import game.init.Blocks; import game.init.ToolMaterial; import game.material.Material; -import game.renderer.blockmodel.Transforms; +import game.model.Transforms; import game.world.BlockPos; import game.world.Facing; import game.world.State; diff --git a/java/src/game/item/ItemKey.java b/java/src/game/item/ItemKey.java index af70514..27438c7 100755 --- a/java/src/game/item/ItemKey.java +++ b/java/src/game/item/ItemKey.java @@ -1,6 +1,6 @@ package game.item; -import game.renderer.blockmodel.Transforms; +import game.model.Transforms; public class ItemKey extends ItemMagnetic { public Transforms getTransform() { diff --git a/java/src/game/item/ItemMagnet.java b/java/src/game/item/ItemMagnet.java index efa05c9..2a03a84 100755 --- a/java/src/game/item/ItemMagnet.java +++ b/java/src/game/item/ItemMagnet.java @@ -1,13 +1,12 @@ package game.item; import java.util.List; - import java.util.function.Predicate; import game.entity.Entity; import game.entity.animal.EntityChicken; import game.entity.npc.EntityNPC; -import game.renderer.blockmodel.Transforms; +import game.model.Transforms; import game.world.BoundingBox; import game.world.Vec3; import game.world.World; diff --git a/java/src/game/item/ItemMetal.java b/java/src/game/item/ItemMetal.java index 26a8f8a..428ac93 100755 --- a/java/src/game/item/ItemMetal.java +++ b/java/src/game/item/ItemMetal.java @@ -5,7 +5,6 @@ import java.util.Map; import java.util.Set; import game.collect.Sets; - import game.color.TextColor; import game.entity.attributes.Attribute; import game.entity.attributes.AttributeModifier; diff --git a/java/src/game/item/ItemMetalBlock.java b/java/src/game/item/ItemMetalBlock.java index b1ab01c..68a09cb 100755 --- a/java/src/game/item/ItemMetalBlock.java +++ b/java/src/game/item/ItemMetalBlock.java @@ -4,9 +4,8 @@ import java.util.List; import java.util.Map; import java.util.Set; -import game.collect.Sets; - import game.block.Block; +import game.collect.Sets; import game.color.TextColor; import game.entity.attributes.Attribute; import game.entity.attributes.AttributeModifier; diff --git a/java/src/game/item/ItemMonsterPlacer.java b/java/src/game/item/ItemMonsterPlacer.java index cc69eb4..a1768de 100755 --- a/java/src/game/item/ItemMonsterPlacer.java +++ b/java/src/game/item/ItemMonsterPlacer.java @@ -13,7 +13,8 @@ import game.init.Blocks; import game.init.EntityEggInfo; import game.init.EntityRegistry; import game.init.UniverseRegistry; -import game.renderer.blockmodel.ModelBlock; +import game.model.Model; +import game.model.ModelProvider; import game.tileentity.TileEntity; import game.tileentity.TileEntityMobSpawner; import game.util.ExtMath; @@ -265,7 +266,7 @@ public class ItemMonsterPlacer extends Item // subItems.add(new ItemStack(itemIn, 1, 0)); // } - public ModelBlock getModel(String name, int meta) { - return new ModelBlock(this.getTransform(), "spawn_egg", "spawn_egg_overlay"); + public Model getModel(ModelProvider provider, String name, int meta) { + return provider.getModel(this.getTransform(), "spawn_egg", "spawn_egg_overlay"); } } diff --git a/java/src/game/item/ItemNpcSpawner.java b/java/src/game/item/ItemNpcSpawner.java index e215853..5758549 100755 --- a/java/src/game/item/ItemNpcSpawner.java +++ b/java/src/game/item/ItemNpcSpawner.java @@ -14,7 +14,8 @@ import game.entity.npc.EntityNPC.CharacterTypeData; import game.entity.types.EntityLiving; import game.init.EntityRegistry; import game.init.UniverseRegistry; -import game.renderer.blockmodel.ModelBlock; +import game.model.Model; +import game.model.ModelProvider; import game.util.ExtMath; import game.world.BlockPos; import game.world.Facing; @@ -201,7 +202,7 @@ public class ItemNpcSpawner extends Item // subItems.add(new ItemStack(itemIn, 1, 0)); // } - public ModelBlock getModel(String name, int meta) { - return new ModelBlock(this.getTransform(), "npc_spawner", "npc_spawner_overlay"); + public Model getModel(ModelProvider provider, String name, int meta) { + return provider.getModel(this.getTransform(), "npc_spawner", "npc_spawner_overlay"); } } diff --git a/java/src/game/item/ItemNugget.java b/java/src/game/item/ItemNugget.java index 563df21..ad2f783 100755 --- a/java/src/game/item/ItemNugget.java +++ b/java/src/game/item/ItemNugget.java @@ -1,6 +1,6 @@ package game.item; -import game.renderer.blockmodel.Transforms; +import game.model.Transforms; public class ItemNugget extends Item { public Transforms getTransform() { diff --git a/java/src/game/item/ItemPiston.java b/java/src/game/item/ItemPiston.java index 1a874da..e5b6723 100755 --- a/java/src/game/item/ItemPiston.java +++ b/java/src/game/item/ItemPiston.java @@ -2,7 +2,8 @@ package game.item; import game.block.Block; import game.init.Blocks; -import game.renderer.blockmodel.ModelBlock; +import game.model.Model; +import game.model.ModelProvider; public class ItemPiston extends ItemBlock { @@ -24,8 +25,8 @@ public class ItemPiston extends ItemBlock return true; } - public ModelBlock getModel(String name, int meta) { - return new ModelBlock(new ModelBlock("piston_side").add().nswe().d("piston_bottom").u("piston_top" + (this.block == + public Model getModel(ModelProvider provider, String name, int meta) { + return provider.getModel(provider.getModel("piston_side").add().nswe().d("piston_bottom").u("piston_top" + (this.block == Blocks.sticky_piston ? "_sticky" : "")), this.getTransform()); } } diff --git a/java/src/game/item/ItemPotion.java b/java/src/game/item/ItemPotion.java index 43d5c93..556090e 100755 --- a/java/src/game/item/ItemPotion.java +++ b/java/src/game/item/ItemPotion.java @@ -8,7 +8,6 @@ import java.util.Set; import game.collect.Maps; import game.collect.Sets; - import game.color.TextColor; import game.entity.attributes.Attribute; import game.entity.attributes.AttributeModifier; @@ -16,11 +15,12 @@ import game.entity.npc.EntityNPC; import game.entity.projectile.EntityPotion; import game.init.Items; import game.init.SoundEvent; +import game.model.ItemMeshDefinition; +import game.model.Model; +import game.model.ModelProvider; import game.potion.Potion; import game.potion.PotionEffect; import game.potion.PotionHelper; -import game.renderer.ItemMeshDefinition; -import game.renderer.blockmodel.ModelBlock; import game.world.World; public class ItemPotion extends Item @@ -439,8 +439,8 @@ public class ItemPotion extends Item subItems.add(new ItemStack(itemIn, 1, 16384)); } - public ModelBlock getModel(String name, int meta) { - return new ModelBlock(this.getTransform(), "potion_overlay", + public Model getModel(ModelProvider provider, String name, int meta) { + return provider.getModel(this.getTransform(), "potion_overlay", isSplash(meta) ? "potion_bottle_splash" : "potion_bottle_drinkable"); } } diff --git a/java/src/game/item/ItemPressurePlate.java b/java/src/game/item/ItemPressurePlate.java index 23095e4..0488c5b 100755 --- a/java/src/game/item/ItemPressurePlate.java +++ b/java/src/game/item/ItemPressurePlate.java @@ -2,15 +2,16 @@ package game.item; import game.block.Block; import game.block.BlockBasePressurePlate; -import game.renderer.blockmodel.ModelBlock; +import game.model.Model; +import game.model.ModelProvider; public class ItemPressurePlate extends ItemBlock { public ItemPressurePlate(Block block) { super(block); } - public ModelBlock getModel(String name, int meta) { - return new ModelBlock(new ModelBlock(((BlockBasePressurePlate)this.block).getTexture()) + public Model getModel(ModelProvider provider, String name, int meta) { + return provider.getModel(provider.getModel(((BlockBasePressurePlate)this.block).getTexture()) .add(1, 6, 1, 15, 10, 15) .d().uv(1, 1, 15, 15).noCull() .u().uv(1, 1, 15, 15).noCull() diff --git a/java/src/game/item/ItemRecord.java b/java/src/game/item/ItemRecord.java index 736a92c..1cd10dd 100755 --- a/java/src/game/item/ItemRecord.java +++ b/java/src/game/item/ItemRecord.java @@ -1,13 +1,14 @@ package game.item; -import game.renderer.blockmodel.ModelBlock; +import game.model.Model; +import game.model.ModelProvider; public class ItemRecord extends Item { public ItemRecord() { this.setTab(CheatTab.tabMisc); } - public ModelBlock getModel(String name, int meta) { - return new ModelBlock(this.getTransform(), "record_old"); + public Model getModel(ModelProvider provider, String name, int meta) { + return provider.getModel(this.getTransform(), "record_old"); } } diff --git a/java/src/game/item/ItemRod.java b/java/src/game/item/ItemRod.java index 5fa50e6..8e5934f 100755 --- a/java/src/game/item/ItemRod.java +++ b/java/src/game/item/ItemRod.java @@ -1,6 +1,6 @@ package game.item; -import game.renderer.blockmodel.Transforms; +import game.model.Transforms; public class ItemRod extends Item { public Transforms getTransform() { diff --git a/java/src/game/item/ItemSeeds.java b/java/src/game/item/ItemSeeds.java index 07472fe..c9e243c 100755 --- a/java/src/game/item/ItemSeeds.java +++ b/java/src/game/item/ItemSeeds.java @@ -2,7 +2,7 @@ package game.item; import game.block.Block; import game.entity.npc.EntityNPC; -import game.renderer.blockmodel.Transforms; +import game.model.Transforms; import game.world.BlockPos; import game.world.Facing; import game.world.World; diff --git a/java/src/game/item/ItemSkull.java b/java/src/game/item/ItemSkull.java index 2e6f50f..0def762 100755 --- a/java/src/game/item/ItemSkull.java +++ b/java/src/game/item/ItemSkull.java @@ -4,9 +4,9 @@ import game.block.Block; import game.block.BlockSkull; import game.entity.npc.EntityNPC; import game.init.Blocks; -import game.model.ModelBakery; -import game.renderer.blockmodel.ModelBlock; -import game.renderer.blockmodel.Transforms; +import game.model.Model; +import game.model.ModelProvider; +import game.model.Transforms; import game.tileentity.TileEntity; import game.tileentity.TileEntitySkull; import game.util.ExtMath; @@ -182,7 +182,7 @@ public class ItemSkull extends Item return Transforms.SKULL; } - public ModelBlock getModel(String name, int meta) { - return new ModelBlock(ModelBakery.MODEL_ENTITY, this.getTransform()); + public Model getModel(ModelProvider provider, String name, int meta) { + return provider.getModel(provider.getEntityModel(), this.getTransform()); } } diff --git a/java/src/game/item/ItemSmall.java b/java/src/game/item/ItemSmall.java index 93f598d..0278dbc 100755 --- a/java/src/game/item/ItemSmall.java +++ b/java/src/game/item/ItemSmall.java @@ -1,6 +1,6 @@ package game.item; -import game.renderer.blockmodel.Transforms; +import game.model.Transforms; public class ItemSmall extends Item { public Transforms getTransform() { diff --git a/java/src/game/item/ItemSoup.java b/java/src/game/item/ItemSoup.java index 9ea2ace..0cd6946 100755 --- a/java/src/game/item/ItemSoup.java +++ b/java/src/game/item/ItemSoup.java @@ -2,7 +2,7 @@ package game.item; import game.entity.npc.EntityNPC; import game.init.Items; -import game.renderer.blockmodel.Transforms; +import game.model.Transforms; import game.world.World; public class ItemSoup extends ItemFood diff --git a/java/src/game/item/ItemStack.java b/java/src/game/item/ItemStack.java index c6fcc06..11c034a 100755 --- a/java/src/game/item/ItemStack.java +++ b/java/src/game/item/ItemStack.java @@ -6,10 +6,9 @@ import java.util.Map; import java.util.Map.Entry; import java.util.Set; +import game.block.Block; import game.collect.Lists; import game.collect.Maps; - -import game.block.Block; import game.color.TextColor; import game.enchantment.Enchantment; import game.enchantment.EnchantmentDurability; diff --git a/java/src/game/item/ItemStick.java b/java/src/game/item/ItemStick.java index 1810890..fe18c93 100755 --- a/java/src/game/item/ItemStick.java +++ b/java/src/game/item/ItemStick.java @@ -1,6 +1,6 @@ package game.item; -import game.renderer.blockmodel.Transforms; +import game.model.Transforms; public class ItemStick extends Item { public Transforms getTransform() { diff --git a/java/src/game/item/ItemSword.java b/java/src/game/item/ItemSword.java index f3511d9..a3e942b 100755 --- a/java/src/game/item/ItemSword.java +++ b/java/src/game/item/ItemSword.java @@ -3,9 +3,8 @@ package game.item; import java.util.Map; import java.util.Set; -import game.collect.Sets; - import game.block.Block; +import game.collect.Sets; import game.entity.attributes.Attribute; import game.entity.attributes.AttributeModifier; import game.entity.attributes.Attributes; @@ -14,7 +13,7 @@ import game.entity.types.EntityLiving; import game.init.Blocks; import game.init.ToolMaterial; import game.material.Material; -import game.renderer.blockmodel.Transforms; +import game.model.Transforms; import game.world.BlockPos; import game.world.World; diff --git a/java/src/game/item/ItemTiny.java b/java/src/game/item/ItemTiny.java index d51b8fd..5afe04c 100755 --- a/java/src/game/item/ItemTiny.java +++ b/java/src/game/item/ItemTiny.java @@ -1,6 +1,6 @@ package game.item; -import game.renderer.blockmodel.Transforms; +import game.model.Transforms; public class ItemTiny extends Item { public Transforms getTransform() { diff --git a/java/src/game/item/ItemTool.java b/java/src/game/item/ItemTool.java index 7c24492..ae32886 100755 --- a/java/src/game/item/ItemTool.java +++ b/java/src/game/item/ItemTool.java @@ -3,15 +3,14 @@ package game.item; import java.util.Map; import java.util.Set; -import game.collect.Sets; - import game.block.Block; +import game.collect.Sets; import game.entity.attributes.Attribute; import game.entity.attributes.AttributeModifier; import game.entity.attributes.Attributes; import game.entity.types.EntityLiving; import game.init.ToolMaterial; -import game.renderer.blockmodel.Transforms; +import game.model.Transforms; import game.world.BlockPos; import game.world.World; diff --git a/java/src/game/item/ItemWall.java b/java/src/game/item/ItemWall.java index 6b6be4c..af0d374 100755 --- a/java/src/game/item/ItemWall.java +++ b/java/src/game/item/ItemWall.java @@ -4,16 +4,17 @@ import java.util.function.Function; import game.block.Block; import game.block.BlockWall; -import game.renderer.blockmodel.ModelBlock; +import game.model.Model; +import game.model.ModelProvider; public class ItemWall extends ItemMultiTexture { public ItemWall(Block block, Block block2, Function nameFunction) { super(block, block2, nameFunction); } - public ModelBlock getModel(String name, int meta) { - return new ModelBlock( - new ModelBlock(this.block.getStateFromMeta(this.getMetadata(meta)).getValue(BlockWall.VARIANT).getName()).noOcclude() + public Model getModel(ModelProvider provider, String name, int meta) { + return provider.getModel( + provider.getModel(this.block.getStateFromMeta(this.getMetadata(meta)).getValue(BlockWall.VARIANT).getName()).noOcclude() .add(4, 0, 4, 12, 16, 12) .d().uv(4, 4, 12, 12) .u().uv(4, 4, 12, 12).noCull() diff --git a/java/src/game/item/ItemWand.java b/java/src/game/item/ItemWand.java index 172198d..1e0b191 100755 --- a/java/src/game/item/ItemWand.java +++ b/java/src/game/item/ItemWand.java @@ -4,7 +4,7 @@ import java.util.List; import game.color.TextColor; import game.entity.npc.EntityNPC; -import game.renderer.blockmodel.Transforms; +import game.model.Transforms; import game.util.ExtMath; import game.world.BlockPos; import game.world.Facing; diff --git a/java/src/game/log/Log.java b/java/src/game/log/Log.java index e328a1c..099f10b 100644 --- a/java/src/game/log/Log.java +++ b/java/src/game/log/Log.java @@ -5,7 +5,6 @@ import java.io.StringWriter; import java.util.List; import game.collect.Lists; - import game.color.TextColor; import game.future.ListenableFuture; import game.network.IThreadListener; diff --git a/java/src/game/log/LogLevel.java b/java/src/game/log/LogLevel.java index 2af9bb6..c299bf0 100644 --- a/java/src/game/log/LogLevel.java +++ b/java/src/game/log/LogLevel.java @@ -1,10 +1,10 @@ package game.log; import game.color.TextColor; -import game.properties.IStringSerializable; import game.util.Displayable; +import game.util.Identifyable; -public enum LogLevel implements Displayable, IStringSerializable { +public enum LogLevel implements Displayable, Identifyable { SILENT("silent", "Nichts", "UNK?", TextColor.BLACK), USER("user", "Benutzer", "USER", TextColor.WHITE), ERROR("error", "Fehler", "ERR!", TextColor.RED), diff --git a/java/src/game/renderer/BlockLayer.java b/java/src/game/model/BlockLayer.java similarity index 93% rename from java/src/game/renderer/BlockLayer.java rename to java/src/game/model/BlockLayer.java index c57b910..3be6166 100755 --- a/java/src/game/renderer/BlockLayer.java +++ b/java/src/game/model/BlockLayer.java @@ -1,4 +1,4 @@ -package game.renderer; +package game.model; public enum BlockLayer { diff --git a/java/src/game/renderer/ItemMeshDefinition.java b/java/src/game/model/ItemMeshDefinition.java similarity index 83% rename from java/src/game/renderer/ItemMeshDefinition.java rename to java/src/game/model/ItemMeshDefinition.java index 827f812..91b59e2 100755 --- a/java/src/game/renderer/ItemMeshDefinition.java +++ b/java/src/game/model/ItemMeshDefinition.java @@ -1,4 +1,4 @@ -package game.renderer; +package game.model; import game.item.ItemStack; diff --git a/java/src/game/model/Model.java b/java/src/game/model/Model.java new file mode 100644 index 0000000..c0c78a8 --- /dev/null +++ b/java/src/game/model/Model.java @@ -0,0 +1,177 @@ +package game.model; + +import game.world.Facing; + +public abstract class Model { + public abstract Model noOcclude(); + public abstract Model uvLock(); + public abstract Model rotate(ModelRotation rot); + public abstract Model add(float x1, float y1, float z1, float x2, float y2, float z2); + public abstract Model noShade(); + public abstract Model rotate(float x, float y, float z, Facing.Axis axisIn, float angleIn, boolean rescaleIn); + public abstract Model face(String texture, Facing... faces); + public abstract Model cull(Facing cull); + public abstract Model tint(); + public abstract Model rot(int rot); + public abstract Model uv(float x1, float y1, float x2, float y2); + public abstract String getPrimary(); + + public Model slab(boolean upper) { + return this.slab(upper, this.getPrimary(), this.getPrimary()); + } + + public Model slab(boolean upper, String du) { + return this.slab(upper, du, du); + } + + public Model slab(boolean upper, String down, String up) { + return this.add(0, upper ? 8 : 0, 0, 16, upper ? 16 : 8, 16).nswe().uv(0, upper ? 0 : 8, 16, upper ? 8 : 16) + .d(down).cull(upper ? null : Facing.DOWN).u(up).cull(upper ? Facing.UP : null); + } + + public Model vslab(Facing dir) { + return this.vslab(dir, this.getPrimary(), this.getPrimary()); + } + + public Model vslab(Facing dir, String du) { + return this.vslab(dir, du, du); + } + + public Model vslab(Facing dir, String down, String up) { + return this.add(0, 0, 0, 16, 16, 8).du().uv(0, 8, 16, 16).we().uv(0, 8, 16, 16).rot(90).n(down).s(up).noCull().rotate(ModelRotation.getNorthRot(dir)); + } + + public Model cross() { + return this.noOcclude() + .add(0.8f, 0f, 8f, 15.2f, 16f, 8f).noShade().rotate(8, 8, 8, Facing.Axis.Y, 45, true) + .ns().uv(0, 0, 16, 16).noCull() + .add(8f, 0f, 0.8f, 8f, 16f, 15.2f).noShade().rotate(8, 8, 8, Facing.Axis.Y, 45, true) + .we().uv(0, 0, 16, 16).noCull(); + } + + public Model crossTint() { + return this.noOcclude() + .add(0.8f, 0f, 8f, 15.2f, 16f, 8f).noShade().rotate(8, 8, 8, Facing.Axis.Y, 45, true) + .ns().uv(0, 0, 16, 16).noCull().tint() + .add(8f, 0f, 0.8f, 8f, 16f, 15.2f).noShade().rotate(8, 8, 8, Facing.Axis.Y, 45, true) + .we().uv(0, 0, 16, 16).noCull().tint(); + } + + public Model stairs(boolean upper, boolean inner, boolean outer, boolean left, Facing dir, String down, String up) { + this.add(0, 0, 0, 16, 8, 16).d(down).uv(0, 0, 16, 16).u(up).noCull().uv(0, 0, 16, 16).nswe().uv(0, 8, 16, 16); + if(outer) + this.add(8, 8, 8, 16, 16, 16).d(down).uv(8, 0, 16, 8).u(up).uv(8, 8, 16, 16).n().noCull().uv(0, 0, 8, 8).s().uv(8, 0, 16, 8) + .w().noCull().uv(8, 0, 16, 8).e().uv(0, 0, 8, 8); + else + this.add(8, 8, 0, 16, 16, 16).d(down).uv(inner ? 8 : 0, 0, 16, 16).u(up).uv(inner ? 8 : 0, 0, 16, 16).n().uv(0, 0, 8, 8) + .s().uv(8, 0, 16, 8).w().noCull().uv(0, 0, 16, 8).e().uv(0, 0, 16, 8); + if(inner) + this.add(0, 8, 8, 8, 16, 16).d(down).uv(0, 0, 8, 8).u(up).uv(0, 8, 8, 16).n().noCull().uv(8, 0, 16, 8).s().uv(0, 0, 8, 8) + .w().uv(8, 0, 16, 8).e().uv(0, 0, 8, 8); + return this.rotate(ModelRotation.getEastRot(left ? Facing.getHorizontal(dir.getHorizontalIndex() + 3) : dir, upper)).uvLock(); + } + + public Model add() { + return this.add(0, 0, 0, 16, 16, 16); + } + + public Model d(String textureIn) { + return this.face(textureIn, Facing.DOWN); + } + + public Model u(String textureIn) { + return this.face(textureIn, Facing.UP); + } + + public Model n(String textureIn) { + return this.face(textureIn, Facing.NORTH); + } + + public Model s(String textureIn) { + return this.face(textureIn, Facing.SOUTH); + } + + public Model w(String textureIn) { + return this.face(textureIn, Facing.WEST); + } + + public Model e(String textureIn) { + return this.face(textureIn, Facing.EAST); + } + + public Model nswe(String textureIn) { + return this.face(textureIn, Facing.NORTH, Facing.SOUTH, Facing.WEST, Facing.EAST); + } + + public Model dnswe(String textureIn) { + return this.face(textureIn, Facing.DOWN, Facing.NORTH, Facing.SOUTH, Facing.WEST, Facing.EAST); + } + + public Model du(String textureIn) { + return this.face(textureIn, Facing.DOWN, Facing.UP); + } + + public Model ns(String textureIn) { + return this.face(textureIn, Facing.NORTH, Facing.SOUTH); + } + + public Model we(String textureIn) { + return this.face(textureIn, Facing.WEST, Facing.EAST); + } + + public Model all(String textureIn) { + return this.face(textureIn, Facing.DOWN, Facing.UP, Facing.NORTH, Facing.SOUTH, Facing.WEST, Facing.EAST); + } + + public Model d() { + return this.d(this.getPrimary()); + } + + public Model u() { + return this.u(this.getPrimary()); + } + + public Model n() { + return this.n(this.getPrimary()); + } + + public Model s() { + return this.s(this.getPrimary()); + } + + public Model w() { + return this.w(this.getPrimary()); + } + + public Model e() { + return this.e(this.getPrimary()); + } + + public Model nswe() { + return this.nswe(this.getPrimary()); + } + + public Model dnswe() { + return this.dnswe(this.getPrimary()); + } + + public Model du() { + return this.du(this.getPrimary()); + } + + public Model ns() { + return this.ns(this.getPrimary()); + } + + public Model we() { + return this.we(this.getPrimary()); + } + + public Model all() { + return this.all(this.getPrimary()); + } + + public Model noCull() { + return this.cull(null); + } +} \ No newline at end of file diff --git a/java/src/game/model/ModelProvider.java b/java/src/game/model/ModelProvider.java new file mode 100644 index 0000000..d08c37f --- /dev/null +++ b/java/src/game/model/ModelProvider.java @@ -0,0 +1,90 @@ +package game.model; + +import game.world.Facing; +import game.world.Facing.Axis; + +public interface ModelProvider { + Model getModel(String primary); + Model getModel(Transforms transform, String ... layers); + Model getModel(Model parent, Transforms transform); + Model getEntityModel(); + + public static class DummyModel extends Model { + public Model noOcclude() { + return this; + } + + public Model uvLock() { + return this; + } + + public Model rotate(ModelRotation rot) { + return this; + } + + public Model add(float x1, float y1, float z1, float x2, float y2, float z2) { + return this; + } + + public Model noShade() { + return this; + } + + public Model rotate(float x, float y, float z, Axis axisIn, float angleIn, boolean rescaleIn) { + return this; + } + + public Model face(String texture, Facing... faces) { + return this; + } + + public Model cull(Facing cull) { + return this; + } + + public Model tint() { + return this; + } + + public Model rot(int rot) { + return this; + } + + public Model uv(float x1, float y1, float x2, float y2) { + return this; + } + + public String getPrimary() { + return ""; + } + + } + + public static class BlockModelProvider { + private static ModelProvider provider = new ModelProvider() { + public Model getModel(Model parent, Transforms transform) { + return new DummyModel(); + } + + public Model getModel(Transforms transform, String... layers) { + return new DummyModel(); + } + + public Model getModel(String primary) { + return new DummyModel(); + } + + public Model getEntityModel() { + return new DummyModel(); + } + }; + } + + public static void setProvider(ModelProvider provider) { + BlockModelProvider.provider = provider; + } + + public static ModelProvider getModelProvider() { + return BlockModelProvider.provider; + } +} diff --git a/java/src/game/model/ModelRotation.java b/java/src/game/model/ModelRotation.java index 5eae937..4551b8a 100755 --- a/java/src/game/model/ModelRotation.java +++ b/java/src/game/model/ModelRotation.java @@ -3,10 +3,9 @@ package game.model; import java.util.Map; import game.collect.Maps; - -import game.renderer.Matrix4f; -import game.renderer.Vector3f; import game.util.ExtMath; +import game.util.Matrix4f; +import game.util.Vector3f; import game.world.Facing; public enum ModelRotation diff --git a/java/src/game/renderer/particle/ParticleType.java b/java/src/game/model/ParticleType.java similarity index 99% rename from java/src/game/renderer/particle/ParticleType.java rename to java/src/game/model/ParticleType.java index 4e3911e..792b8e1 100755 --- a/java/src/game/renderer/particle/ParticleType.java +++ b/java/src/game/model/ParticleType.java @@ -1,4 +1,4 @@ -package game.renderer.particle; +package game.model; import java.util.List; import java.util.Map; diff --git a/java/src/game/renderer/blockmodel/Transform.java b/java/src/game/model/Transform.java similarity index 83% rename from java/src/game/renderer/blockmodel/Transform.java rename to java/src/game/model/Transform.java index ea6f47f..e546145 100755 --- a/java/src/game/renderer/blockmodel/Transform.java +++ b/java/src/game/model/Transform.java @@ -1,9 +1,9 @@ -package game.renderer.blockmodel; +package game.model; -import game.renderer.Vector3f; +import game.util.Vector3f; public class Transform { - static final Transform IDENTITY = new Transform(0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f); + public static final Transform IDENTITY = new Transform(0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f); public final Vector3f rotation; public final Vector3f translation; diff --git a/java/src/game/renderer/blockmodel/Transforms.java b/java/src/game/model/Transforms.java similarity index 91% rename from java/src/game/renderer/blockmodel/Transforms.java rename to java/src/game/model/Transforms.java index 09a2e34..60c722c 100755 --- a/java/src/game/renderer/blockmodel/Transforms.java +++ b/java/src/game/model/Transforms.java @@ -1,6 +1,4 @@ -package game.renderer.blockmodel; - -import org.lwjgl.opengl.GL11; +package game.model; public enum Transforms { DEFAULT( @@ -150,17 +148,6 @@ public enum Transforms { this.ground = ground; } - public void apply(Camera type) { - Transform vec = this.get(type); - if(vec != Transform.IDENTITY) { - GL11.glTranslatef(vec.translation.x, vec.translation.y, vec.translation.z); - GL11.glRotatef(vec.rotation.y, 0.0F, 1.0F, 0.0F); - GL11.glRotatef(vec.rotation.x, 1.0F, 0.0F, 0.0F); - GL11.glRotatef(vec.rotation.z, 0.0F, 0.0F, 1.0F); - GL11.glScalef(vec.scale.x, vec.scale.y, vec.scale.z); - } - } - public Transform get(Camera type) { switch(type) { case THIRD_PERSON: diff --git a/java/src/game/nbt/NBTTagList.java b/java/src/game/nbt/NBTTagList.java index 51c1e17..2ce7cfa 100755 --- a/java/src/game/nbt/NBTTagList.java +++ b/java/src/game/nbt/NBTTagList.java @@ -7,7 +7,6 @@ import java.util.ArrayList; import java.util.List; import game.collect.Lists; - import game.log.Log; public class NBTTagList extends NBTBase diff --git a/java/src/game/network/ClientLoginHandler.java b/java/src/game/network/ClientLoginHandler.java index 4122100..6620101 100755 --- a/java/src/game/network/ClientLoginHandler.java +++ b/java/src/game/network/ClientLoginHandler.java @@ -1,6 +1,6 @@ package game.network; -import game.Game; +import client.Game; import game.packet.RPacketDisconnect; import game.packet.RPacketEnableCompression; import game.packet.RPacketLoginSuccess; diff --git a/java/src/game/network/ClientPlayer.java b/java/src/game/network/ClientPlayer.java index 8bc4e24..8cd036e 100755 --- a/java/src/game/network/ClientPlayer.java +++ b/java/src/game/network/ClientPlayer.java @@ -6,10 +6,19 @@ import java.util.Map; import java.util.Map.Entry; import java.util.Set; +import client.Game; +import client.PlayerController; +import client.gui.Gui; +import client.gui.GuiConsole; +import client.gui.GuiLoading; +import client.gui.character.GuiChar; +import client.gui.character.GuiCharacters; +import client.gui.container.GuiMachine; +import client.gui.container.GuiMerchant; +import client.renderer.particle.EntityPickupFX; +import client.renderer.texture.EntityTexManager; import game.collect.Lists; import game.collect.Maps; - -import game.Game; import game.dimension.Dimension; import game.entity.DataWatcher; import game.entity.Entity; @@ -25,13 +34,6 @@ import game.entity.npc.EntityNPC; import game.entity.npc.PlayerCharacter; import game.entity.projectile.EntityProjectile; import game.entity.types.EntityLiving; -import game.gui.Gui; -import game.gui.GuiConsole; -import game.gui.GuiLoading; -import game.gui.character.GuiChar; -import game.gui.character.GuiCharacters; -import game.gui.container.GuiMachine; -import game.gui.container.GuiMerchant; import game.init.EntityRegistry; import game.init.ItemRegistry; import game.init.SoundEvent; @@ -42,6 +44,7 @@ import game.inventory.InventoryBasic; import game.inventory.InventoryPlayer; import game.item.ItemStack; import game.log.Log; +import game.model.ParticleType; import game.packet.CPacketAction; import game.packet.CPacketKeepAlive; import game.packet.CPacketPlayer; @@ -107,9 +110,6 @@ import game.packet.SPacketTrades; import game.packet.SPacketUpdateHealth; import game.packet.SPacketWorld; import game.potion.PotionEffect; -import game.renderer.particle.EntityPickupFX; -import game.renderer.particle.ParticleType; -import game.renderer.texture.EntityTexManager; import game.rng.Random; import game.tileentity.LocalBlockIntercommunication; import game.tileentity.TileEntity; diff --git a/java/src/game/network/HandshakeHandler.java b/java/src/game/network/HandshakeHandler.java index dee4f5b..51dd361 100755 --- a/java/src/game/network/HandshakeHandler.java +++ b/java/src/game/network/HandshakeHandler.java @@ -1,9 +1,9 @@ package game.network; -import game.Server; import game.init.Config; import game.packet.HPacketHandshake; import game.packet.RPacketDisconnect; +import server.Server; public class HandshakeHandler extends NetHandler { diff --git a/java/src/game/network/LoginHandler.java b/java/src/game/network/LoginHandler.java index 061af2a..9aa117d 100755 --- a/java/src/game/network/LoginHandler.java +++ b/java/src/game/network/LoginHandler.java @@ -1,11 +1,11 @@ package game.network; -import game.Server; import game.color.TextColor; import game.init.Config; import game.log.Log; import game.packet.LPacketPasswordResponse; import game.packet.RPacketDisconnect; +import server.Server; public class LoginHandler extends NetHandler { diff --git a/java/src/game/network/NetConnection.java b/java/src/game/network/NetConnection.java index b975e47..2ce2493 100755 --- a/java/src/game/network/NetConnection.java +++ b/java/src/game/network/NetConnection.java @@ -8,7 +8,6 @@ import java.util.concurrent.locks.ReentrantReadWriteLock; import java.util.regex.Pattern; import game.future.ThreadFactoryBuilder; - import game.log.Log; import game.network.NetHandler.ThreadQuickExitException; import io.netty.bootstrap.Bootstrap; diff --git a/java/src/game/network/PacketRegistry.java b/java/src/game/network/PacketRegistry.java index cbfaffc..28ae74b 100755 --- a/java/src/game/network/PacketRegistry.java +++ b/java/src/game/network/PacketRegistry.java @@ -5,7 +5,6 @@ import java.util.Map; import game.collect.BiMap; import game.collect.HashBiMap; import game.collect.Maps; - import game.packet.CPacketAction; import game.packet.CPacketBook; import game.packet.CPacketBreak; diff --git a/java/src/game/network/Player.java b/java/src/game/network/Player.java index 8a19a68..eca1b80 100755 --- a/java/src/game/network/Player.java +++ b/java/src/game/network/Player.java @@ -6,12 +6,8 @@ import java.util.LinkedList; import java.util.List; import java.util.Map.Entry; import java.util.Set; - import java.util.function.Predicate; -import game.collect.Lists; -import game.future.Futures; -import game.Server; import game.block.Block; import game.block.BlockFence; import game.block.BlockFenceGate; @@ -22,6 +18,7 @@ import game.clipboard.ClipboardPlacer; import game.clipboard.Rotation; import game.clipboard.RotationValue; import game.clipboard.Vector; +import game.collect.Lists; import game.color.TextColor; import game.command.Executor; import game.dimension.Dimension; @@ -35,6 +32,7 @@ import game.entity.npc.EntityNPC; import game.entity.npc.PlayerCharacter; import game.entity.projectile.EntityArrow; import game.entity.types.EntityLiving; +import game.future.Futures; import game.init.BlockRegistry; import game.init.Config; import game.init.Config.ValueType; @@ -132,6 +130,7 @@ import game.world.WorldPos; import game.world.WorldServer; import io.netty.util.concurrent.Future; import io.netty.util.concurrent.GenericFutureListener; +import server.Server; public class Player extends NetHandler implements ICrafting, Executor { diff --git a/java/src/game/packet/CPacketAction.java b/java/src/game/packet/CPacketAction.java index 5a93ea9..171e7b1 100755 --- a/java/src/game/packet/CPacketAction.java +++ b/java/src/game/packet/CPacketAction.java @@ -2,9 +2,9 @@ package game.packet; import java.io.IOException; -import game.network.Player; import game.network.Packet; import game.network.PacketBuffer; +import game.network.Player; public class CPacketAction implements Packet { diff --git a/java/src/game/packet/CPacketBook.java b/java/src/game/packet/CPacketBook.java index 271924e..3dd0e62 100755 --- a/java/src/game/packet/CPacketBook.java +++ b/java/src/game/packet/CPacketBook.java @@ -2,9 +2,9 @@ package game.packet; import java.io.IOException; -import game.network.Player; import game.network.Packet; import game.network.PacketBuffer; +import game.network.Player; public class CPacketBook implements Packet { diff --git a/java/src/game/packet/CPacketBreak.java b/java/src/game/packet/CPacketBreak.java index 07e67d8..18c95fb 100755 --- a/java/src/game/packet/CPacketBreak.java +++ b/java/src/game/packet/CPacketBreak.java @@ -2,9 +2,9 @@ package game.packet; import java.io.IOException; -import game.network.Player; import game.network.Packet; import game.network.PacketBuffer; +import game.network.Player; import game.world.BlockPos; import game.world.Facing; diff --git a/java/src/game/packet/CPacketCheat.java b/java/src/game/packet/CPacketCheat.java index 7faa62d..136f332 100755 --- a/java/src/game/packet/CPacketCheat.java +++ b/java/src/game/packet/CPacketCheat.java @@ -3,9 +3,9 @@ package game.packet; import java.io.IOException; import game.item.ItemStack; -import game.network.Player; import game.network.Packet; import game.network.PacketBuffer; +import game.network.Player; public class CPacketCheat implements Packet { diff --git a/java/src/game/packet/CPacketClick.java b/java/src/game/packet/CPacketClick.java index ae6078d..e622458 100755 --- a/java/src/game/packet/CPacketClick.java +++ b/java/src/game/packet/CPacketClick.java @@ -3,9 +3,9 @@ package game.packet; import java.io.IOException; import game.item.ItemStack; -import game.network.Player; import game.network.Packet; import game.network.PacketBuffer; +import game.network.Player; public class CPacketClick implements Packet { diff --git a/java/src/game/packet/CPacketComplete.java b/java/src/game/packet/CPacketComplete.java index d160d13..4b110ae 100755 --- a/java/src/game/packet/CPacketComplete.java +++ b/java/src/game/packet/CPacketComplete.java @@ -2,9 +2,9 @@ package game.packet; import java.io.IOException; -import game.network.Player; import game.network.Packet; import game.network.PacketBuffer; +import game.network.Player; import game.world.BlockPos; public class CPacketComplete implements Packet diff --git a/java/src/game/packet/CPacketInput.java b/java/src/game/packet/CPacketInput.java index 975a66a..413a311 100755 --- a/java/src/game/packet/CPacketInput.java +++ b/java/src/game/packet/CPacketInput.java @@ -2,9 +2,9 @@ package game.packet; import java.io.IOException; -import game.network.Player; import game.network.Packet; import game.network.PacketBuffer; +import game.network.Player; public class CPacketInput implements Packet { diff --git a/java/src/game/packet/CPacketMessage.java b/java/src/game/packet/CPacketMessage.java index 037f27e..0bbcd8a 100755 --- a/java/src/game/packet/CPacketMessage.java +++ b/java/src/game/packet/CPacketMessage.java @@ -2,9 +2,9 @@ package game.packet; import java.io.IOException; -import game.network.Player; import game.network.Packet; import game.network.PacketBuffer; +import game.network.Player; public class CPacketMessage implements Packet { diff --git a/java/src/game/packet/CPacketPlace.java b/java/src/game/packet/CPacketPlace.java index 4b5aeaf..a17a8f1 100755 --- a/java/src/game/packet/CPacketPlace.java +++ b/java/src/game/packet/CPacketPlace.java @@ -3,9 +3,9 @@ package game.packet; import java.io.IOException; import game.item.ItemStack; -import game.network.Player; import game.network.Packet; import game.network.PacketBuffer; +import game.network.Player; import game.world.BlockPos; public class CPacketPlace implements Packet diff --git a/java/src/game/packet/CPacketPlayer.java b/java/src/game/packet/CPacketPlayer.java index 11fc2f0..dfa6fd7 100755 --- a/java/src/game/packet/CPacketPlayer.java +++ b/java/src/game/packet/CPacketPlayer.java @@ -2,9 +2,9 @@ package game.packet; import java.io.IOException; -import game.network.Player; import game.network.Packet; import game.network.PacketBuffer; +import game.network.Player; public class CPacketPlayer implements Packet { diff --git a/java/src/game/packet/CPacketSign.java b/java/src/game/packet/CPacketSign.java index c8df819..e905fba 100755 --- a/java/src/game/packet/CPacketSign.java +++ b/java/src/game/packet/CPacketSign.java @@ -2,9 +2,9 @@ package game.packet; import java.io.IOException; -import game.network.Player; import game.network.Packet; import game.network.PacketBuffer; +import game.network.Player; import game.world.BlockPos; public class CPacketSign implements Packet diff --git a/java/src/game/packet/CPacketSkin.java b/java/src/game/packet/CPacketSkin.java index b039eae..25f69c5 100755 --- a/java/src/game/packet/CPacketSkin.java +++ b/java/src/game/packet/CPacketSkin.java @@ -3,11 +3,11 @@ package game.packet; import java.awt.image.BufferedImage; import java.io.IOException; +import client.renderer.texture.EntityTexManager; import game.init.SpeciesRegistry.ModelType; -import game.network.Player; import game.network.Packet; import game.network.PacketBuffer; -import game.renderer.texture.EntityTexManager; +import game.network.Player; public class CPacketSkin implements Packet { private byte[] texture; diff --git a/java/src/game/packet/LPacketPasswordResponse.java b/java/src/game/packet/LPacketPasswordResponse.java index 4d445df..be6eaae 100755 --- a/java/src/game/packet/LPacketPasswordResponse.java +++ b/java/src/game/packet/LPacketPasswordResponse.java @@ -3,9 +3,9 @@ package game.packet; import java.io.IOException; import game.network.LoginHandler; -import game.network.Player; import game.network.Packet; import game.network.PacketBuffer; +import game.network.Player; public class LPacketPasswordResponse implements Packet { diff --git a/java/src/game/packet/S20PacketEntityProperties.java b/java/src/game/packet/S20PacketEntityProperties.java index ad22227..5d6e690 100755 --- a/java/src/game/packet/S20PacketEntityProperties.java +++ b/java/src/game/packet/S20PacketEntityProperties.java @@ -5,7 +5,6 @@ import java.util.Collection; import java.util.List; import game.collect.Lists; - import game.entity.attributes.AttributeInstance; import game.entity.attributes.AttributeModifier; import game.network.ClientPlayer; diff --git a/java/src/game/packet/S27PacketExplosion.java b/java/src/game/packet/S27PacketExplosion.java index 1124ab6..740400a 100755 --- a/java/src/game/packet/S27PacketExplosion.java +++ b/java/src/game/packet/S27PacketExplosion.java @@ -5,7 +5,6 @@ import java.util.ArrayList; import java.util.List; import game.collect.Lists; - import game.network.ClientPlayer; import game.network.Packet; import game.network.PacketBuffer; diff --git a/java/src/game/packet/S2APacketParticles.java b/java/src/game/packet/S2APacketParticles.java index d1bb616..b2692fd 100755 --- a/java/src/game/packet/S2APacketParticles.java +++ b/java/src/game/packet/S2APacketParticles.java @@ -2,10 +2,10 @@ package game.packet; import java.io.IOException; +import game.model.ParticleType; import game.network.ClientPlayer; import game.network.Packet; import game.network.PacketBuffer; -import game.renderer.particle.ParticleType; public class S2APacketParticles implements Packet { diff --git a/java/src/game/packet/S38PacketPlayerListItem.java b/java/src/game/packet/S38PacketPlayerListItem.java index b3309d2..f05f4ba 100755 --- a/java/src/game/packet/S38PacketPlayerListItem.java +++ b/java/src/game/packet/S38PacketPlayerListItem.java @@ -6,11 +6,10 @@ import java.util.Map; import java.util.Map.Entry; import game.collect.Maps; - import game.network.ClientPlayer; -import game.network.Player; import game.network.Packet; import game.network.PacketBuffer; +import game.network.Player; public class S38PacketPlayerListItem implements Packet { private final Map players = Maps.newHashMap(); diff --git a/java/src/game/packet/SPacketCharacterList.java b/java/src/game/packet/SPacketCharacterList.java index f375a4b..58fb869 100644 --- a/java/src/game/packet/SPacketCharacterList.java +++ b/java/src/game/packet/SPacketCharacterList.java @@ -9,10 +9,10 @@ import game.collect.Maps; import game.entity.npc.Alignment; import game.entity.npc.PlayerCharacter; import game.network.ClientPlayer; -import game.network.Player; -import game.world.BlockPos; import game.network.Packet; import game.network.PacketBuffer; +import game.network.Player; +import game.world.BlockPos; public class SPacketCharacterList implements Packet { private final Map players = Maps.newHashMap(); diff --git a/java/src/game/packet/SPacketChunkData.java b/java/src/game/packet/SPacketChunkData.java index 7e62e3a..6f45ac3 100755 --- a/java/src/game/packet/SPacketChunkData.java +++ b/java/src/game/packet/SPacketChunkData.java @@ -4,7 +4,6 @@ import java.io.IOException; import java.util.List; import game.collect.Lists; - import game.network.ClientPlayer; import game.network.Packet; import game.network.PacketBuffer; diff --git a/java/src/game/packet/SPacketSkin.java b/java/src/game/packet/SPacketSkin.java index 546b913..429bc0f 100755 --- a/java/src/game/packet/SPacketSkin.java +++ b/java/src/game/packet/SPacketSkin.java @@ -2,11 +2,11 @@ package game.packet; import java.io.IOException; +import client.renderer.texture.EntityTexManager; import game.entity.Entity; import game.network.ClientPlayer; import game.network.Packet; import game.network.PacketBuffer; -import game.renderer.texture.EntityTexManager; import game.world.World; public class SPacketSkin implements Packet diff --git a/java/src/game/packet/SPacketSpawnPlayer.java b/java/src/game/packet/SPacketSpawnPlayer.java index 2f989f3..9f9dec5 100755 --- a/java/src/game/packet/SPacketSpawnPlayer.java +++ b/java/src/game/packet/SPacketSpawnPlayer.java @@ -3,6 +3,7 @@ package game.packet; import java.io.IOException; import java.util.List; +import client.renderer.texture.EntityTexManager; import game.entity.DataWatcher; import game.entity.npc.EntityNPC; import game.init.EntityRegistry; @@ -11,7 +12,6 @@ import game.item.ItemStack; import game.network.ClientPlayer; import game.network.Packet; import game.network.PacketBuffer; -import game.renderer.texture.EntityTexManager; import game.util.ExtMath; public class SPacketSpawnPlayer implements Packet diff --git a/java/src/game/pattern/BlockStateHelper.java b/java/src/game/pattern/BlockStateHelper.java index 2bbb7ae..2e3972e 100755 --- a/java/src/game/pattern/BlockStateHelper.java +++ b/java/src/game/pattern/BlockStateHelper.java @@ -2,11 +2,10 @@ package game.pattern; import java.util.Map; import java.util.Map.Entry; - import java.util.function.Predicate; -import game.collect.Maps; import game.block.Block; +import game.collect.Maps; import game.properties.IProperty; import game.world.State; diff --git a/java/src/game/potion/Potion.java b/java/src/game/potion/Potion.java index f1a413d..b298f83 100755 --- a/java/src/game/potion/Potion.java +++ b/java/src/game/potion/Potion.java @@ -2,8 +2,8 @@ package game.potion; import java.util.Map; import java.util.Map.Entry; -import game.collect.Maps; +import game.collect.Maps; import game.entity.DamageSource; import game.entity.attributes.Attribute; import game.entity.attributes.AttributeInstance; diff --git a/java/src/game/properties/IStringSerializable.java b/java/src/game/properties/IStringSerializable.java deleted file mode 100755 index b98fa26..0000000 --- a/java/src/game/properties/IStringSerializable.java +++ /dev/null @@ -1,6 +0,0 @@ -package game.properties; - -public interface IStringSerializable -{ - String getName(); -} diff --git a/java/src/game/properties/PropertyDirection.java b/java/src/game/properties/PropertyDirection.java index 52b3ff5..fbcb34a 100755 --- a/java/src/game/properties/PropertyDirection.java +++ b/java/src/game/properties/PropertyDirection.java @@ -1,12 +1,11 @@ package game.properties; import java.util.Collection; - import java.util.function.Predicate; -import game.util.Predicates; + import game.collect.Filter; import game.collect.Lists; - +import game.util.Predicates; import game.world.Facing; public class PropertyDirection extends PropertyEnum diff --git a/java/src/game/properties/PropertyEnum.java b/java/src/game/properties/PropertyEnum.java index 9fe4fec..6501431 100755 --- a/java/src/game/properties/PropertyEnum.java +++ b/java/src/game/properties/PropertyEnum.java @@ -2,15 +2,16 @@ package game.properties; import java.util.Collection; import java.util.Map; - import java.util.function.Predicate; -import game.util.Predicates; + import game.collect.Filter; import game.collect.ImmutableSet; import game.collect.Lists; import game.collect.Maps; +import game.util.Identifyable; +import game.util.Predicates; -public class PropertyEnum & IStringSerializable> extends PropertyHelper +public class PropertyEnum & Identifyable> extends PropertyHelper { private final ImmutableSet allowedValues; private final Map nameToValue = Maps.newHashMap(); @@ -22,7 +23,7 @@ public class PropertyEnum & IStringSerializable> extends Prope for (T t : allowedValues) { - String s = ((IStringSerializable)t).getName(); + String s = ((Identifyable)t).getName(); if (this.nameToValue.containsKey(s)) { @@ -43,25 +44,25 @@ public class PropertyEnum & IStringSerializable> extends Prope */ public String getName(T value) { - return ((IStringSerializable)value).getName(); + return ((Identifyable)value).getName(); } - public static & IStringSerializable> PropertyEnum create(String name, Class clazz) + public static & Identifyable> PropertyEnum create(String name, Class clazz) { return create(name, clazz, Predicates.alwaysTrue()); } - public static & IStringSerializable> PropertyEnum create(String name, Class clazz, Predicate filter) + public static & Identifyable> PropertyEnum create(String name, Class clazz, Predicate filter) { return create(name, clazz, Filter.filter(Lists.newArrayList(clazz.getEnumConstants()), filter)); } - public static & IStringSerializable> PropertyEnum create(String name, Class clazz, T... values) + public static & Identifyable> PropertyEnum create(String name, Class clazz, T... values) { return create(name, clazz, Lists.newArrayList(values)); } - public static & IStringSerializable> PropertyEnum create(String name, Class clazz, Collection values) + public static & Identifyable> PropertyEnum create(String name, Class clazz, Collection values) { return new PropertyEnum(name, clazz, values); } diff --git a/java/src/game/renderer/blockmodel/ModelBlock.java b/java/src/game/renderer/blockmodel/ModelBlock.java deleted file mode 100755 index 3fc27ac..0000000 --- a/java/src/game/renderer/blockmodel/ModelBlock.java +++ /dev/null @@ -1,342 +0,0 @@ -package game.renderer.blockmodel; - -import java.util.List; - -import game.collect.Lists; -import game.collect.Maps; - -import game.model.ModelBakery; -import game.model.ModelRotation; -import game.renderer.Vector3f; -import game.renderer.texture.TextureMap; -import game.world.Facing; - -public class ModelBlock { - private final List elements; - private final boolean gui3d; - private final String primary; - private final String[] layers; - private final ModelBlock parent; - - private boolean occlusion; - private ModelRotation rotation; - private boolean uvLock; - private Transforms transform; - - private BlockPart lastPart; - private BlockPartFace[] last; - - - public ModelBlock slab(boolean upper) { - return this.slab(upper, this.primary, this.primary); - } - - public ModelBlock slab(boolean upper, String du) { - return this.slab(upper, du, du); - } - - public ModelBlock slab(boolean upper, String down, String up) { - return this.add(0, upper ? 8 : 0, 0, 16, upper ? 16 : 8, 16).nswe().uv(0, upper ? 0 : 8, 16, upper ? 8 : 16) - .d(down).cull(upper ? null : Facing.DOWN).u(up).cull(upper ? Facing.UP : null); - } - - public ModelBlock vslab(Facing dir) { - return this.vslab(dir, this.primary, this.primary); - } - - public ModelBlock vslab(Facing dir, String du) { - return this.vslab(dir, du, du); - } - - public ModelBlock vslab(Facing dir, String down, String up) { - return this.add(0, 0, 0, 16, 16, 8).du().uv(0, 8, 16, 16).we().uv(0, 8, 16, 16).rot(90).n(down).s(up).noCull().rotate(ModelRotation.getNorthRot(dir)); - } - - public ModelBlock cross() { - return this.noOcclude() - .add(0.8f, 0f, 8f, 15.2f, 16f, 8f).noShade().rotate(8, 8, 8, Facing.Axis.Y, 45, true) - .ns().uv(0, 0, 16, 16).noCull() - .add(8f, 0f, 0.8f, 8f, 16f, 15.2f).noShade().rotate(8, 8, 8, Facing.Axis.Y, 45, true) - .we().uv(0, 0, 16, 16).noCull(); - } - - public ModelBlock crossTint() { - return this.noOcclude() - .add(0.8f, 0f, 8f, 15.2f, 16f, 8f).noShade().rotate(8, 8, 8, Facing.Axis.Y, 45, true) - .ns().uv(0, 0, 16, 16).noCull().tint() - .add(8f, 0f, 0.8f, 8f, 16f, 15.2f).noShade().rotate(8, 8, 8, Facing.Axis.Y, 45, true) - .we().uv(0, 0, 16, 16).noCull().tint(); - } - - public ModelBlock stairs(boolean upper, boolean inner, boolean outer, boolean left, Facing dir, String down, String up) { - this.add(0, 0, 0, 16, 8, 16).d(down).uv(0, 0, 16, 16).u(up).noCull().uv(0, 0, 16, 16).nswe().uv(0, 8, 16, 16); - if(outer) - this.add(8, 8, 8, 16, 16, 16).d(down).uv(8, 0, 16, 8).u(up).uv(8, 8, 16, 16).n().noCull().uv(0, 0, 8, 8).s().uv(8, 0, 16, 8) - .w().noCull().uv(8, 0, 16, 8).e().uv(0, 0, 8, 8); - else - this.add(8, 8, 0, 16, 16, 16).d(down).uv(inner ? 8 : 0, 0, 16, 16).u(up).uv(inner ? 8 : 0, 0, 16, 16).n().uv(0, 0, 8, 8) - .s().uv(8, 0, 16, 8).w().noCull().uv(0, 0, 16, 8).e().uv(0, 0, 16, 8); - if(inner) - this.add(0, 8, 8, 8, 16, 16).d(down).uv(0, 0, 8, 8).u(up).uv(0, 8, 8, 16).n().noCull().uv(8, 0, 16, 8).s().uv(0, 0, 8, 8) - .w().uv(8, 0, 16, 8).e().uv(0, 0, 8, 8); - return this.rotate(ModelRotation.getEastRot(left ? Facing.getHorizontal(dir.getHorizontalIndex() + 3) : dir, upper)).uvLock(); - } - - - - public ModelBlock noOcclude() { - this.occlusion = false; - return this; - } - - public ModelBlock uvLock() { - this.uvLock = true; - return this; - } - - public ModelBlock rotate(ModelRotation rot) { - this.rotation = rot; - return this; - } - - public ModelBlock add(float x1, float y1, float z1, float x2, float y2, float z2) { - this.elements.add(this.lastPart = new BlockPart(new Vector3f(x1, y1, z1), new Vector3f(x2, y2, z2), - Maps.newEnumMap(Facing.class), null, true)); - return this; - } - - public ModelBlock add() { - return this.add(0, 0, 0, 16, 16, 16); - } - - public ModelBlock noShade() { - this.lastPart.shade = false; - return this; - } - - public ModelBlock rotate(float x, float y, float z, Facing.Axis axisIn, float angleIn, boolean rescaleIn) { - this.lastPart.partRotation = new BlockPartRotation(x, y, z, axisIn, angleIn, rescaleIn); - return this; - } - - public ModelBlock face(String texture, Facing ... faces) { - texture = !texture.equals(TextureMap.LOCATION_MISSING_TEXTURE) && texture.indexOf('/') == -1 ? "blocks/" + texture : texture; - this.last = new BlockPartFace[faces.length]; - for(int z = 0; z < faces.length; z++) { - this.lastPart.mapFaces.put(faces[z], this.last[z] = - new BlockPartFace(faces[z], -1, texture, new BlockFaceUV(this.lastPart.getFaceUvs(faces[z]), 0))); - } - return this; - } - - public ModelBlock d(String textureIn) { - return this.face(textureIn, Facing.DOWN); - } - - public ModelBlock u(String textureIn) { - return this.face(textureIn, Facing.UP); - } - - public ModelBlock n(String textureIn) { - return this.face(textureIn, Facing.NORTH); - } - - public ModelBlock s(String textureIn) { - return this.face(textureIn, Facing.SOUTH); - } - - public ModelBlock w(String textureIn) { - return this.face(textureIn, Facing.WEST); - } - - public ModelBlock e(String textureIn) { - return this.face(textureIn, Facing.EAST); - } - - public ModelBlock nswe(String textureIn) { - return this.face(textureIn, Facing.NORTH, Facing.SOUTH, Facing.WEST, Facing.EAST); - } - - public ModelBlock dnswe(String textureIn) { - return this.face(textureIn, Facing.DOWN, Facing.NORTH, Facing.SOUTH, Facing.WEST, Facing.EAST); - } - - public ModelBlock du(String textureIn) { - return this.face(textureIn, Facing.DOWN, Facing.UP); - } - - public ModelBlock ns(String textureIn) { - return this.face(textureIn, Facing.NORTH, Facing.SOUTH); - } - - public ModelBlock we(String textureIn) { - return this.face(textureIn, Facing.WEST, Facing.EAST); - } - - public ModelBlock all(String textureIn) { - return this.face(textureIn, Facing.DOWN, Facing.UP, Facing.NORTH, Facing.SOUTH, Facing.WEST, Facing.EAST); - } - - public ModelBlock d() { - return this.d(this.primary); - } - - public ModelBlock u() { - return this.u(this.primary); - } - - public ModelBlock n() { - return this.n(this.primary); - } - - public ModelBlock s() { - return this.s(this.primary); - } - - public ModelBlock w() { - return this.w(this.primary); - } - - public ModelBlock e() { - return this.e(this.primary); - } - - public ModelBlock nswe() { - return this.nswe(this.primary); - } - - public ModelBlock dnswe() { - return this.dnswe(this.primary); - } - - public ModelBlock du() { - return this.du(this.primary); - } - - public ModelBlock ns() { - return this.ns(this.primary); - } - - public ModelBlock we() { - return this.we(this.primary); - } - - public ModelBlock all() { - return this.all(this.primary); - } - - public ModelBlock cull(Facing cull) { - for(BlockPartFace last : this.last) { - last.cull = cull; - } - return this; - } - - public ModelBlock noCull() { - return this.cull(null); - } - - public ModelBlock tint() { - for(BlockPartFace last : this.last) { - last.tint = 0; - } - return this; - } - - public ModelBlock rot(int rot) { - for(BlockPartFace last : this.last) { - last.uv = new BlockFaceUV(last.uv.uvs, rot); - } - return this; - } - - public ModelBlock uv(float x1, float y1, float x2, float y2) { - for(BlockPartFace last : this.last) { - last.uv = new BlockFaceUV(new float[] {x1, y1, x2, y2}, last.uv.rotation); - } - return this; - } - - - public ModelBlock(String primary) { - this(null, Lists.newArrayList(), primary != null && primary.indexOf('/') == -1 ? "blocks/" + primary : primary, true, true, Transforms.DEFAULT, null); - } - - public ModelBlock(String primary, Transforms transform, String ... layers) { - this(ModelBakery.MODEL_GENERATED, ModelBakery.MODEL_GENERATED.elements, - primary.indexOf('/') == -1 ? "items/" + primary : primary, false, false, transform, layers); - } - - public ModelBlock(Transforms transform, String ... layers) { - this(ModelBakery.MODEL_GENERATED, ModelBakery.MODEL_GENERATED.elements, - layers[0].indexOf('/') == -1 ? "items/" + layers[0] : layers[0], false, false, transform, layers); - } - - protected ModelBlock(String primary, List elements, Transforms transform, String ... layers) { - this(null, elements, primary, false, false, transform, layers); - } - - public ModelBlock(ModelBlock parent, Transforms transform) { - this(parent, Lists.newArrayList(), parent.getPrimary(), false, true, transform, null); - } - - private ModelBlock(ModelBlock parent, List elements, String primary, boolean occlude, boolean gui3d, - Transforms transform, String[] layers) { - for(int z = 0; layers != null && z < layers.length; z++) { - layers[z] = layers[z].indexOf('/') == -1 ? "items/" + layers[z] : layers[z]; - } - this.elements = parent == null ? elements : parent.getElements(); - this.occlusion = parent == null ? occlude : parent.isAmbientOcclusion(); - this.gui3d = gui3d; - this.primary = primary == null ? TextureMap.LOCATION_MISSING_TEXTURE : primary; - this.parent = parent; - this.transform = transform; - this.uvLock = false; - this.rotation = ModelRotation.X0_Y0; - this.layers = layers; - } - - public List getElements() { - return this.elements; - } - - public boolean isAmbientOcclusion() { - return this.occlusion; - } - - public boolean isGui3d() { - return this.gui3d; - } - - public String getPrimary() { - return this.primary; - } - - public String[] getTextures() { - return this.layers; - } - - public int getNumTextures() { - return this.layers == null ? 0 : this.layers.length; - } - - public String getTexture(int layer) { - return this.layers == null || this.layers[layer] == null ? TextureMap.LOCATION_MISSING_TEXTURE : this.layers[layer]; - } - - public ModelBlock getParent() { - return this.parent; - } - - public Transforms getTransform() { - return this.transform; - } - - public ModelRotation getRotation() { - return this.rotation; - } - - public boolean isUvLocked() { - return this.uvLock; - } -} diff --git a/java/src/game/rng/WeightedList.java b/java/src/game/rng/WeightedList.java index f08fd42..575c324 100755 --- a/java/src/game/rng/WeightedList.java +++ b/java/src/game/rng/WeightedList.java @@ -3,9 +3,8 @@ package game.rng; import java.util.ArrayList; import java.util.Collection; import java.util.Comparator; -import java.util.function.UnaryOperator; - import java.util.function.Predicate; +import java.util.function.UnaryOperator; public class WeightedList extends ArrayList { protected boolean modified; diff --git a/java/src/game/sound/EventType.java b/java/src/game/sound/EventType.java new file mode 100644 index 0000000..e234d21 --- /dev/null +++ b/java/src/game/sound/EventType.java @@ -0,0 +1,5 @@ +package game.sound; + +public enum EventType { + SOUND_EFFECT, UI_INTERFACE; +} diff --git a/java/src/game/audio/MovingSound.java b/java/src/game/sound/MovingSound.java similarity index 94% rename from java/src/game/audio/MovingSound.java rename to java/src/game/sound/MovingSound.java index f2a18b2..c3f5fc9 100755 --- a/java/src/game/audio/MovingSound.java +++ b/java/src/game/sound/MovingSound.java @@ -1,4 +1,4 @@ -package game.audio; +package game.sound; import game.init.SoundEvent; diff --git a/java/src/game/audio/MovingSoundMinecart.java b/java/src/game/sound/MovingSoundMinecart.java similarity index 98% rename from java/src/game/audio/MovingSoundMinecart.java rename to java/src/game/sound/MovingSoundMinecart.java index fc95eb3..aa4f110 100755 --- a/java/src/game/audio/MovingSoundMinecart.java +++ b/java/src/game/sound/MovingSoundMinecart.java @@ -1,4 +1,4 @@ -package game.audio; +package game.sound; import game.entity.item.EntityCart; import game.init.SoundEvent; diff --git a/java/src/game/audio/MovingSoundMinecartRiding.java b/java/src/game/sound/MovingSoundMinecartRiding.java similarity index 98% rename from java/src/game/audio/MovingSoundMinecartRiding.java rename to java/src/game/sound/MovingSoundMinecartRiding.java index 12521b1..42ba8be 100755 --- a/java/src/game/audio/MovingSoundMinecartRiding.java +++ b/java/src/game/sound/MovingSoundMinecartRiding.java @@ -1,4 +1,4 @@ -package game.audio; +package game.sound; import game.entity.item.EntityCart; import game.entity.npc.EntityNPC; diff --git a/java/src/game/audio/PositionedSound.java b/java/src/game/sound/PositionedSound.java similarity index 88% rename from java/src/game/audio/PositionedSound.java rename to java/src/game/sound/PositionedSound.java index 53f03c2..ff4a221 100755 --- a/java/src/game/audio/PositionedSound.java +++ b/java/src/game/sound/PositionedSound.java @@ -1,9 +1,9 @@ -package game.audio; +package game.sound; import game.init.SoundEvent; public class PositionedSound extends Sound { - public PositionedSound(SoundEvent event, Volume type) { + public PositionedSound(SoundEvent event, EventType type) { this(event, 1.0F, false, 0.0F, 0.0F, 0.0F); this.type = type; } diff --git a/java/src/game/audio/Sound.java b/java/src/game/sound/Sound.java similarity index 89% rename from java/src/game/audio/Sound.java rename to java/src/game/sound/Sound.java index 72b5ac9..fb4247f 100755 --- a/java/src/game/audio/Sound.java +++ b/java/src/game/sound/Sound.java @@ -1,11 +1,11 @@ -package game.audio; +package game.sound; import game.init.SoundEvent; public abstract class Sound { protected final SoundEvent event; - protected Volume type = Volume.SFX; + protected EventType type = EventType.SOUND_EFFECT; protected float volume = 1.0F; protected float xPosF; protected float yPosF; @@ -53,7 +53,7 @@ public abstract class Sound return this.attenuationType; } - public Volume getChannelType() + public EventType getChannelType() { return this.type; } diff --git a/java/src/game/tileentity/TileEntityBanner.java b/java/src/game/tileentity/TileEntityBanner.java index 03a20a5..24b8210 100755 --- a/java/src/game/tileentity/TileEntityBanner.java +++ b/java/src/game/tileentity/TileEntityBanner.java @@ -2,9 +2,8 @@ package game.tileentity; import java.util.List; -import game.collect.Lists; - import game.block.BlockFlower; +import game.collect.Lists; import game.color.DyeColor; import game.init.Blocks; import game.init.Items; diff --git a/java/src/game/tileentity/TileEntityHopper.java b/java/src/game/tileentity/TileEntityHopper.java index 96a4189..80d75de 100755 --- a/java/src/game/tileentity/TileEntityHopper.java +++ b/java/src/game/tileentity/TileEntityHopper.java @@ -1,7 +1,6 @@ package game.tileentity; import java.util.List; - import java.util.function.Predicate; import game.block.Block; diff --git a/java/src/game/tileentity/TileEntityMobSpawner.java b/java/src/game/tileentity/TileEntityMobSpawner.java index 0b99b0d..e8a8765 100755 --- a/java/src/game/tileentity/TileEntityMobSpawner.java +++ b/java/src/game/tileentity/TileEntityMobSpawner.java @@ -5,10 +5,10 @@ import game.entity.types.EntityLiving; import game.init.Blocks; import game.init.Config; import game.init.EntityRegistry; +import game.model.ParticleType; import game.nbt.NBTTagCompound; import game.network.Packet; import game.packet.S35PacketUpdateTileEntity; -import game.renderer.particle.ParticleType; import game.world.BlockPos; import game.world.BoundingBox; import game.world.World; diff --git a/java/src/game/tileentity/TileEntityPiston.java b/java/src/game/tileentity/TileEntityPiston.java index 1baff97..98fdb26 100755 --- a/java/src/game/tileentity/TileEntityPiston.java +++ b/java/src/game/tileentity/TileEntityPiston.java @@ -3,7 +3,6 @@ package game.tileentity; import java.util.List; import game.collect.Lists; - import game.entity.Entity; import game.init.BlockRegistry; import game.init.Blocks; diff --git a/java/src/game/util/Identifyable.java b/java/src/game/util/Identifyable.java new file mode 100755 index 0000000..03fa092 --- /dev/null +++ b/java/src/game/util/Identifyable.java @@ -0,0 +1,6 @@ +package game.util; + +public interface Identifyable +{ + String getName(); +} diff --git a/java/src/game/renderer/Matrix4f.java b/java/src/game/util/Matrix4f.java similarity index 99% rename from java/src/game/renderer/Matrix4f.java rename to java/src/game/util/Matrix4f.java index f14cd8e..813d579 100644 --- a/java/src/game/renderer/Matrix4f.java +++ b/java/src/game/util/Matrix4f.java @@ -29,7 +29,7 @@ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package game.renderer; +package game.util; import java.io.Serializable; import java.nio.FloatBuffer; diff --git a/java/src/game/util/Util.java b/java/src/game/util/Util.java index 4e12a61..92704a1 100644 --- a/java/src/game/util/Util.java +++ b/java/src/game/util/Util.java @@ -10,7 +10,6 @@ import javax.swing.JOptionPane; import game.collect.Lists; import game.collect.Maps; import game.log.Log; -import game.properties.IStringSerializable; public abstract class Util { private static long start = getTime(); @@ -179,7 +178,7 @@ int utf_len(const char *str) { } public static T parseEnum(Class clazz, String str) { - boolean name = IStringSerializable.class.isAssignableFrom(clazz); + boolean name = Identifyable.class.isAssignableFrom(clazz); T[] values = clazz.getEnumConstants(); Integer value; if((value = parseInt(str, 0)) != null && (value >= 0) && (value < values.length)) { @@ -189,7 +188,7 @@ int utf_len(const char *str) { int max = 0; T best = null; for(int z = 0; z < values.length; z++) { - if((comp = compareLower(name ? ((IStringSerializable)values[z]).getName() : values[z].toString(), str)) > max) { + if((comp = compareLower(name ? ((Identifyable)values[z]).getName() : values[z].toString(), str)) > max) { max = comp; best = values[z]; } @@ -204,10 +203,10 @@ int utf_len(const char *str) { for(Class clazz : enums) { if(!base.isAssignableFrom(clazz)) throw new IllegalArgumentException("Klasse " + clazz.getSimpleName() + " ist nicht " + base.getSimpleName() + " untergeordnet"); - boolean name = IStringSerializable.class.isAssignableFrom(clazz); + boolean name = Identifyable.class.isAssignableFrom(clazz); Enum[] values = clazz.getEnumConstants(); for(int z = 0; z < values.length; z++) { - if((comp = compareLower(name ? ((IStringSerializable)values[z]).getName() : values[z].toString(), str)) > max) { + if((comp = compareLower(name ? ((Identifyable)values[z]).getName() : values[z].toString(), str)) > max) { max = comp; best = (T)values[z]; } diff --git a/java/src/game/renderer/Vector.java b/java/src/game/util/Vector.java similarity index 99% rename from java/src/game/renderer/Vector.java rename to java/src/game/util/Vector.java index c877b86..4e2385a 100644 --- a/java/src/game/renderer/Vector.java +++ b/java/src/game/util/Vector.java @@ -29,7 +29,7 @@ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package game.renderer; +package game.util; import java.io.Serializable; import java.nio.FloatBuffer; diff --git a/java/src/game/renderer/Vector3f.java b/java/src/game/util/Vector3f.java similarity index 99% rename from java/src/game/renderer/Vector3f.java rename to java/src/game/util/Vector3f.java index 777b6bc..e9f56db 100644 --- a/java/src/game/renderer/Vector3f.java +++ b/java/src/game/util/Vector3f.java @@ -29,7 +29,7 @@ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package game.renderer; +package game.util; import java.io.Serializable; import java.nio.FloatBuffer; diff --git a/java/src/game/renderer/Vector4f.java b/java/src/game/util/Vector4f.java similarity index 99% rename from java/src/game/renderer/Vector4f.java rename to java/src/game/util/Vector4f.java index 58b8831..bfd95fc 100644 --- a/java/src/game/renderer/Vector4f.java +++ b/java/src/game/util/Vector4f.java @@ -29,7 +29,7 @@ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package game.renderer; +package game.util; import java.io.Serializable; import java.nio.FloatBuffer; diff --git a/java/src/game/vars/BoolVar.java b/java/src/game/vars/BoolVar.java index fb3b9aa..388ccc8 100644 --- a/java/src/game/vars/BoolVar.java +++ b/java/src/game/vars/BoolVar.java @@ -2,8 +2,8 @@ package game.vars; import java.lang.reflect.Field; +import client.gui.element.Toggle; import game.color.TextColor; -import game.gui.element.Toggle; import game.util.Util; public class BoolVar extends BaseVar { diff --git a/java/src/game/vars/CVar.java b/java/src/game/vars/CVar.java index bddcd04..26649cb 100644 --- a/java/src/game/vars/CVar.java +++ b/java/src/game/vars/CVar.java @@ -1,6 +1,6 @@ package game.vars; -import game.gui.element.Element; +import client.gui.element.Element; import game.util.Displayable; public interface CVar extends Displayable { diff --git a/java/src/game/vars/ColorVar.java b/java/src/game/vars/ColorVar.java index 0651922..e361a08 100644 --- a/java/src/game/vars/ColorVar.java +++ b/java/src/game/vars/ColorVar.java @@ -2,12 +2,12 @@ package game.vars; import java.lang.reflect.Field; +import client.gui.Style; +import client.gui.element.Label; +import client.gui.element.Slider; +import client.gui.element.Textbox; +import client.gui.element.Textbox.Action; import game.color.TextColor; -import game.gui.Style; -import game.gui.element.Label; -import game.gui.element.Slider; -import game.gui.element.Textbox; -import game.gui.element.Textbox.Action; import game.util.Util; public class ColorVar extends IntVar { diff --git a/java/src/game/vars/EnumVar.java b/java/src/game/vars/EnumVar.java index 68900f1..def5478 100644 --- a/java/src/game/vars/EnumVar.java +++ b/java/src/game/vars/EnumVar.java @@ -2,11 +2,11 @@ package game.vars; import java.lang.reflect.Field; +import client.gui.element.Dropdown; +import client.gui.element.Element; +import client.gui.element.Switch; import game.color.TextColor; -import game.gui.element.Dropdown; -import game.gui.element.Element; -import game.gui.element.Switch; -import game.properties.IStringSerializable; +import game.util.Identifyable; import game.util.Util; public class EnumVar extends BaseVar { @@ -27,7 +27,7 @@ public class EnumVar extends BaseVar { for(T value : (T[])field.getType().getEnumConstants()) { if(sb.length() > 0) sb.append(','); - sb.append(value instanceof IStringSerializable ? ((IStringSerializable)value).getName() : value.toString()); + sb.append(value instanceof Identifyable ? ((Identifyable)value).getName() : value.toString()); } this.values = sb.toString(); try { @@ -60,7 +60,7 @@ public class EnumVar extends BaseVar { public String format() { try { T value = (T)this.field.get(this.object); - return value instanceof IStringSerializable ? ((IStringSerializable)value).getName() : value.toString(); + return value instanceof Identifyable ? ((Identifyable)value).getName() : value.toString(); } catch(IllegalArgumentException | IllegalAccessException e) { throw new RuntimeException(e); @@ -68,7 +68,7 @@ public class EnumVar extends BaseVar { } public String getDefault() { - return this.def instanceof IStringSerializable ? ((IStringSerializable)this.def).getName() : this.def.toString(); + return this.def instanceof Identifyable ? ((Identifyable)this.def).getName() : this.def.toString(); } public String getValues() { @@ -81,7 +81,7 @@ public class EnumVar extends BaseVar { try { return new Dropdown(x, y, w, h, false, (T[])this.field.getType().getEnumConstants(), this.def, (T)this.field.get(this.object), new Dropdown.Callback() { public void use(Dropdown elem, T value) { - EnumVar.this.parse(value instanceof IStringSerializable ? ((IStringSerializable)value).getName() : value.toString()); + EnumVar.this.parse(value instanceof Identifyable ? ((Identifyable)value).getName() : value.toString()); } }, this.display); } @@ -94,7 +94,7 @@ public class EnumVar extends BaseVar { try { return new Switch(x, y, w, h, (T[])this.field.getType().getEnumConstants(), this.def, (T)this.field.get(this.object), new Switch.Callback() { public void use(Switch elem, T value) { - EnumVar.this.parse(value instanceof IStringSerializable ? ((IStringSerializable)value).getName() : value.toString()); + EnumVar.this.parse(value instanceof Identifyable ? ((Identifyable)value).getName() : value.toString()); } }, this.display); } diff --git a/java/src/game/vars/FloatVar.java b/java/src/game/vars/FloatVar.java index cbac18e..734ca49 100644 --- a/java/src/game/vars/FloatVar.java +++ b/java/src/game/vars/FloatVar.java @@ -2,8 +2,8 @@ package game.vars; import java.lang.reflect.Field; +import client.gui.element.Slider; import game.color.TextColor; -import game.gui.element.Slider; import game.util.ExtMath; public class FloatVar extends BaseVar { diff --git a/java/src/game/vars/IntVar.java b/java/src/game/vars/IntVar.java index 95f791d..3d87ef5 100644 --- a/java/src/game/vars/IntVar.java +++ b/java/src/game/vars/IntVar.java @@ -2,8 +2,8 @@ package game.vars; import java.lang.reflect.Field; +import client.gui.element.Slider; import game.color.TextColor; -import game.gui.element.Slider; import game.util.ExtMath; import game.util.Util; diff --git a/java/src/game/vars/StringVar.java b/java/src/game/vars/StringVar.java index 7c52469..c761585 100644 --- a/java/src/game/vars/StringVar.java +++ b/java/src/game/vars/StringVar.java @@ -2,9 +2,9 @@ package game.vars; import java.lang.reflect.Field; +import client.gui.element.Textbox; +import client.gui.element.Textbox.Action; import game.color.TextColor; -import game.gui.element.Textbox; -import game.gui.element.Textbox.Action; import game.util.CharValidator; public class StringVar extends BaseVar { diff --git a/java/src/game/village/Village.java b/java/src/game/village/Village.java index 7cde6fe..5c80e39 100755 --- a/java/src/game/village/Village.java +++ b/java/src/game/village/Village.java @@ -3,10 +3,9 @@ package game.village; import java.util.Iterator; import java.util.List; -import game.collect.Lists; - import game.block.Block; import game.block.BlockDoor; +import game.collect.Lists; import game.material.Material; import game.nbt.NBTTagCompound; import game.nbt.NBTTagList; diff --git a/java/src/game/village/VillageCollection.java b/java/src/game/village/VillageCollection.java index e00e7b0..74b0a9e 100755 --- a/java/src/game/village/VillageCollection.java +++ b/java/src/game/village/VillageCollection.java @@ -3,10 +3,9 @@ package game.village; import java.util.Iterator; import java.util.List; -import game.collect.Lists; - import game.block.Block; import game.block.BlockDoor; +import game.collect.Lists; import game.material.Material; import game.nbt.NBTTagCompound; import game.nbt.NBTTagList; diff --git a/java/src/game/window/Input.java b/java/src/game/window/Input.java deleted file mode 100644 index 848f2b6..0000000 --- a/java/src/game/window/Input.java +++ /dev/null @@ -1,8 +0,0 @@ -package game.window; - -import game.properties.IStringSerializable; -import game.util.Displayable; - -public interface Input extends IStringSerializable, Displayable { - public boolean read(); -} diff --git a/java/src/game/world/BlockPos.java b/java/src/game/world/BlockPos.java index 9638c4c..9a8abf2 100755 --- a/java/src/game/world/BlockPos.java +++ b/java/src/game/world/BlockPos.java @@ -3,7 +3,6 @@ package game.world; import java.util.Iterator; import game.collect.AbstractIterator; - import game.entity.Entity; public class BlockPos extends Vec3i diff --git a/java/src/game/world/Chunk.java b/java/src/game/world/Chunk.java index 51791fb..336e6fb 100755 --- a/java/src/game/world/Chunk.java +++ b/java/src/game/world/Chunk.java @@ -4,13 +4,12 @@ import java.util.Arrays; import java.util.List; import java.util.Map; import java.util.concurrent.ConcurrentLinkedQueue; - import java.util.function.Predicate; -import game.collect.Maps; import game.biome.Biome; import game.block.Block; import game.block.ITileEntityProvider; +import game.collect.Maps; import game.entity.Entity; import game.init.Blocks; import game.log.Log; diff --git a/java/src/game/world/Converter.java b/java/src/game/world/Converter.java index b7ff953..279412e 100644 --- a/java/src/game/world/Converter.java +++ b/java/src/game/world/Converter.java @@ -13,9 +13,10 @@ import java.util.Map.Entry; import java.util.zip.GZIPInputStream; import java.util.zip.InflaterInputStream; -import game.collect.Maps; - -import game.Game; +import client.Game; +import client.gui.GuiConvert; +import client.gui.GuiLoading; +import client.gui.GuiLoading.Callback; import game.biome.Biome; import game.block.Block; import game.block.BlockCactus; @@ -42,6 +43,7 @@ import game.block.BlockTNT; import game.block.BlockTallGrass; import game.block.BlockWall; import game.block.LeavesType; +import game.collect.Maps; import game.color.DyeColor; import game.entity.Entity; import game.entity.animal.EntityBat; @@ -57,9 +59,6 @@ import game.entity.animal.EntitySquid; import game.entity.animal.EntityWolf; import game.entity.item.EntityBoat; import game.entity.item.EntityMinecart; -import game.gui.GuiConvert; -import game.gui.GuiLoading; -import game.gui.GuiLoading.Callback; import game.init.BlockRegistry; import game.init.Blocks; import game.init.Config; diff --git a/java/src/game/world/EmptyChunk.java b/java/src/game/world/EmptyChunk.java index 14e327f..00392cd 100755 --- a/java/src/game/world/EmptyChunk.java +++ b/java/src/game/world/EmptyChunk.java @@ -1,7 +1,6 @@ package game.world; import java.util.List; - import java.util.function.Predicate; import game.block.Block; diff --git a/java/src/game/world/Explosion.java b/java/src/game/world/Explosion.java index 9a111cd..ac9438f 100755 --- a/java/src/game/world/Explosion.java +++ b/java/src/game/world/Explosion.java @@ -4,11 +4,10 @@ import java.util.List; import java.util.Map; import java.util.Set; +import game.block.Block; import game.collect.Lists; import game.collect.Maps; import game.collect.Sets; - -import game.block.Block; import game.enchantment.EnchantmentProtection; import game.entity.DamageSource; import game.entity.Entity; @@ -19,7 +18,7 @@ import game.init.Blocks; import game.init.Config; import game.init.SoundEvent; import game.material.Material; -import game.renderer.particle.ParticleType; +import game.model.ParticleType; import game.rng.Random; import game.util.ExtMath; diff --git a/java/src/game/world/Facing.java b/java/src/game/world/Facing.java index 67ab478..c94d154 100755 --- a/java/src/game/world/Facing.java +++ b/java/src/game/world/Facing.java @@ -2,16 +2,15 @@ package game.world; import java.util.Iterator; import java.util.Map; - import java.util.function.Predicate; + import game.collect.Iterators; import game.collect.Maps; - -import game.properties.IStringSerializable; import game.rng.Random; import game.util.ExtMath; +import game.util.Identifyable; -public enum Facing implements IStringSerializable +public enum Facing implements Identifyable { DOWN(0, 2, 1, -1, "down", Facing.AxisDirection.NEGATIVE, Facing.Axis.Y, new Vec3i(0, -1, 0)), UP(1, 3, 0, -1, "up", Facing.AxisDirection.POSITIVE, Facing.Axis.Y, new Vec3i(0, 1, 0)), @@ -371,7 +370,7 @@ public enum Facing implements IStringSerializable } } - public static enum Axis implements Predicate, IStringSerializable { + public static enum Axis implements Predicate, Identifyable { X("x", Facing.Plane.HORIZONTAL), Y("y", Facing.Plane.VERTICAL), Z("z", Facing.Plane.HORIZONTAL); diff --git a/java/src/game/world/Region.java b/java/src/game/world/Region.java index bd7c25c..a3a5a28 100755 --- a/java/src/game/world/Region.java +++ b/java/src/game/world/Region.java @@ -17,10 +17,9 @@ import java.util.Map; import java.util.zip.DeflaterOutputStream; import java.util.zip.InflaterInputStream; +import game.block.Block; import game.collect.Lists; import game.collect.Maps; - -import game.block.Block; import game.entity.Entity; import game.init.BlockRegistry; import game.init.Config; diff --git a/java/src/game/world/Spawner.java b/java/src/game/world/Spawner.java index 739cdd4..05a830c 100755 --- a/java/src/game/world/Spawner.java +++ b/java/src/game/world/Spawner.java @@ -2,11 +2,10 @@ package game.world; import java.util.Set; -import game.collect.Sets; - import game.biome.Biome; import game.biome.RngSpawn; import game.block.Block; +import game.collect.Sets; import game.entity.npc.EntityNPC; import game.entity.types.EntityLiving; import game.entity.types.EntityWaterMob; diff --git a/java/src/game/world/State.java b/java/src/game/world/State.java index 53cbd2a..8e05fc8 100755 --- a/java/src/game/world/State.java +++ b/java/src/game/world/State.java @@ -5,16 +5,15 @@ import java.util.Collections; import java.util.Iterator; import java.util.Map; import java.util.Map.Entry; - import java.util.function.Function; + +import game.block.Block; import game.collect.ImmutableMap; import game.collect.ImmutableTable; import game.collect.Iterables; import game.collect.Maps; import game.collect.StandardTable; import game.collect.Table; - -import game.block.Block; import game.init.BlockRegistry; import game.properties.IProperty; diff --git a/java/src/game/world/Vec3.java b/java/src/game/world/Vec3.java index 8392614..460787f 100755 --- a/java/src/game/world/Vec3.java +++ b/java/src/game/world/Vec3.java @@ -1,6 +1,5 @@ package game.world; -import game.renderer.model.PositionTextureVertex; import game.util.ExtMath; public class Vec3 @@ -211,9 +210,4 @@ public class Vec3 double d2 = this.zCoord * (double)f - this.xCoord * (double)f1; return new Vec3(d0, d1, d2); } - - public PositionTextureVertex toTextureVertex(float tx, float ty) - { - return new PositionTextureVertex(this, tx, ty); - } } diff --git a/java/src/game/world/Weather.java b/java/src/game/world/Weather.java index 9df13f4..d5b52f3 100755 --- a/java/src/game/world/Weather.java +++ b/java/src/game/world/Weather.java @@ -3,7 +3,6 @@ package game.world; import java.util.Map; import game.collect.Maps; - import game.rng.Random; import game.rng.RngItem; import game.rng.WeightedList; diff --git a/java/src/game/world/World.java b/java/src/game/world/World.java index 5c0e471..76ad069 100755 --- a/java/src/game/world/World.java +++ b/java/src/game/world/World.java @@ -4,10 +4,7 @@ import java.util.Collection; import java.util.Iterator; import java.util.List; import java.util.Set; - import java.util.function.Predicate; -import game.collect.Lists; -import game.collect.Sets; import game.biome.Biome; import game.block.Block; @@ -17,6 +14,8 @@ import game.block.BlockSlab; import game.block.BlockSnow; import game.block.BlockStairs; import game.block.LeavesType; +import game.collect.Lists; +import game.collect.Sets; import game.dimension.Dimension; import game.entity.Entity; import game.entity.item.EntityExplosion; @@ -26,7 +25,7 @@ import game.init.Blocks; import game.init.SoundEvent; import game.item.ItemStack; import game.material.Material; -import game.renderer.particle.ParticleType; +import game.model.ParticleType; import game.rng.Random; import game.tileentity.ITickable; import game.tileentity.TileEntity; diff --git a/java/src/game/world/WorldClient.java b/java/src/game/world/WorldClient.java index 0e01f13..6378f1f 100755 --- a/java/src/game/world/WorldClient.java +++ b/java/src/game/world/WorldClient.java @@ -3,14 +3,13 @@ package game.world; import java.util.List; import java.util.Set; -import game.collect.Lists; -import game.collect.Sets; - -import game.Game; -import game.audio.MovingSoundMinecart; -import game.audio.PositionedSound; +import client.Game; +import client.renderer.particle.EntityFX; +import client.renderer.particle.EntityFirework; import game.biome.Biome; import game.block.Block; +import game.collect.Lists; +import game.collect.Sets; import game.dimension.Dimension; import game.entity.Entity; import game.entity.item.EntityCart; @@ -22,11 +21,11 @@ import game.init.SoundEvent; import game.item.ItemDye; import game.log.Log; import game.material.Material; +import game.model.ParticleType; import game.nbt.NBTTagCompound; -import game.renderer.particle.EntityFX; -import game.renderer.particle.EntityFirework; -import game.renderer.particle.ParticleType; import game.rng.Random; +import game.sound.MovingSoundMinecart; +import game.sound.PositionedSound; import game.tileentity.TileEntity; import game.util.ExtMath; import game.world.BlockPos.MutableBlockPos; diff --git a/java/src/game/world/WorldServer.java b/java/src/game/world/WorldServer.java index 150ba5b..9b97b07 100755 --- a/java/src/game/world/WorldServer.java +++ b/java/src/game/world/WorldServer.java @@ -11,13 +11,8 @@ import java.util.Map.Entry; import java.util.Set; import java.util.TreeSet; import java.util.concurrent.ConcurrentHashMap; - import java.util.function.Predicate; -import game.collect.Lists; -import game.collect.Maps; -import game.collect.Sets; -import game.Server; import game.biome.Biome; import game.biome.RngSpawn; import game.block.Block; @@ -27,6 +22,9 @@ import game.block.BlockFalling; import game.block.BlockLiquid; import game.block.BlockSnow; import game.clipboard.ClipboardBlock; +import game.collect.Lists; +import game.collect.Maps; +import game.collect.Sets; import game.dimension.Dimension; import game.entity.DamageSource; import game.entity.Entity; @@ -41,12 +39,13 @@ import game.init.UniverseRegistry; import game.item.ItemDoor; import game.log.Log; import game.material.Material; +import game.model.ParticleType; import game.nbt.NBTLoader; import game.nbt.NBTTagCompound; import game.nbt.NBTTagInt; import game.nbt.NBTTagList; -import game.network.Player; import game.network.Packet; +import game.network.Player; import game.packet.S1APacketEntityStatus; import game.packet.S27PacketExplosion; import game.packet.S28PacketEffect; @@ -60,7 +59,6 @@ import game.packet.SPacketBlockBreakAnim; import game.packet.SPacketBlockChange; import game.packet.SPacketChunkData; import game.packet.SPacketMultiBlockChange; -import game.renderer.particle.ParticleType; import game.rng.Random; import game.rng.WeightedList; import game.tileentity.TileEntity; @@ -88,6 +86,7 @@ import game.worldgen.structure.MapGenMineshaft; import game.worldgen.structure.MapGenScatteredFeature; import game.worldgen.structure.MapGenStronghold; import game.worldgen.structure.MapGenVillage; +import server.Server; public final class WorldServer extends World { private static final int[][] XZ_DIRS = new int[][] {{1, 0}, {0, 1}, {-1, 0}, {0, -1}}; diff --git a/java/src/game/worldgen/BiomeGenLayered.java b/java/src/game/worldgen/BiomeGenLayered.java index 74f666d..f78abbc 100755 --- a/java/src/game/worldgen/BiomeGenLayered.java +++ b/java/src/game/worldgen/BiomeGenLayered.java @@ -3,9 +3,8 @@ package game.worldgen; import java.util.List; import java.util.Set; -import game.collect.Lists; - import game.biome.Biome; +import game.collect.Lists; import game.world.BlockPos; import game.world.LongHashMap; import game.worldgen.layer.GenLayer; diff --git a/java/src/game/worldgen/GeneratorDebug.java b/java/src/game/worldgen/GeneratorDebug.java index 4168d4f..b945e86 100755 --- a/java/src/game/worldgen/GeneratorDebug.java +++ b/java/src/game/worldgen/GeneratorDebug.java @@ -2,9 +2,8 @@ package game.worldgen; import java.util.List; -import game.collect.Lists; - import game.block.Block; +import game.collect.Lists; import game.init.BlockRegistry; import game.util.ExtMath; import game.world.State; diff --git a/java/src/game/worldgen/feature/WorldGenDesertWells.java b/java/src/game/worldgen/feature/WorldGenDesertWells.java index 7dd67f9..b0e233d 100755 --- a/java/src/game/worldgen/feature/WorldGenDesertWells.java +++ b/java/src/game/worldgen/feature/WorldGenDesertWells.java @@ -1,12 +1,11 @@ package game.worldgen.feature; -import game.util.Predicates; - import game.block.BlockSand; import game.block.BlockSlab; import game.init.Blocks; import game.pattern.BlockStateHelper; import game.rng.Random; +import game.util.Predicates; import game.world.BlockPos; import game.world.Facing; import game.world.State; diff --git a/java/src/game/worldgen/structure/MapGenStructure.java b/java/src/game/worldgen/structure/MapGenStructure.java index 7712648..360f058 100755 --- a/java/src/game/worldgen/structure/MapGenStructure.java +++ b/java/src/game/worldgen/structure/MapGenStructure.java @@ -4,7 +4,6 @@ import java.util.Iterator; import java.util.Map; import game.collect.Maps; - import game.nbt.NBTBase; import game.nbt.NBTTagCompound; import game.rng.Random; diff --git a/java/src/game/worldgen/structure/MapGenStructureIO.java b/java/src/game/worldgen/structure/MapGenStructureIO.java index 06a3f4e..94c185c 100755 --- a/java/src/game/worldgen/structure/MapGenStructureIO.java +++ b/java/src/game/worldgen/structure/MapGenStructureIO.java @@ -3,7 +3,6 @@ package game.worldgen.structure; import java.util.Map; import game.collect.Maps; - import game.log.Log; import game.nbt.NBTTagCompound; import game.world.WorldServer; diff --git a/java/src/game/worldgen/structure/MapGenVillage.java b/java/src/game/worldgen/structure/MapGenVillage.java index fef7738..9a81a77 100755 --- a/java/src/game/worldgen/structure/MapGenVillage.java +++ b/java/src/game/worldgen/structure/MapGenVillage.java @@ -3,9 +3,8 @@ package game.worldgen.structure; import java.util.List; import java.util.Set; -import game.collect.Sets; - import game.biome.Biome; +import game.collect.Sets; import game.nbt.NBTTagCompound; import game.rng.Random; import game.world.WorldServer; diff --git a/java/src/game/worldgen/structure/StructureBridge.java b/java/src/game/worldgen/structure/StructureBridge.java index 1dcba01..a04e30a 100755 --- a/java/src/game/worldgen/structure/StructureBridge.java +++ b/java/src/game/worldgen/structure/StructureBridge.java @@ -3,7 +3,6 @@ package game.worldgen.structure; import java.util.List; import game.collect.Lists; - import game.init.Blocks; import game.nbt.NBTTagCompound; import game.rng.Random; diff --git a/java/src/game/worldgen/structure/StructureStronghold.java b/java/src/game/worldgen/structure/StructureStronghold.java index e76b7ac..6d4f792 100755 --- a/java/src/game/worldgen/structure/StructureStronghold.java +++ b/java/src/game/worldgen/structure/StructureStronghold.java @@ -3,11 +3,10 @@ package game.worldgen.structure; import java.util.List; import java.util.Map; -import game.collect.Lists; -import game.collect.Maps; - import game.block.BlockSlab; import game.block.BlockStoneBrick; +import game.collect.Lists; +import game.collect.Maps; import game.init.Blocks; import game.init.Items; import game.item.RngLoot; diff --git a/java/src/game/worldgen/structure/StructureVillage.java b/java/src/game/worldgen/structure/StructureVillage.java index 1188590..79b793d 100755 --- a/java/src/game/worldgen/structure/StructureVillage.java +++ b/java/src/game/worldgen/structure/StructureVillage.java @@ -3,8 +3,6 @@ package game.worldgen.structure; import java.util.Iterator; import java.util.List; -import game.collect.Lists; - import game.biome.Biome; import game.block.Block; import game.block.BlockLog; @@ -12,6 +10,7 @@ import game.block.BlockSandStone; import game.block.BlockSlab; import game.block.BlockStairs; import game.block.BlockTorch; +import game.collect.Lists; import game.color.DyeColor; import game.entity.npc.EntityHuman; import game.init.BlockRegistry; diff --git a/java/src/game/worldgen/tree/WorldGenBigTree.java b/java/src/game/worldgen/tree/WorldGenBigTree.java index fba563a..9655450 100755 --- a/java/src/game/worldgen/tree/WorldGenBigTree.java +++ b/java/src/game/worldgen/tree/WorldGenBigTree.java @@ -2,11 +2,10 @@ package game.worldgen.tree; import java.util.List; -import game.collect.Lists; - import game.block.Block; import game.block.BlockLeaves; import game.block.BlockLog; +import game.collect.Lists; import game.init.Blocks; import game.material.Material; import game.rng.Random; diff --git a/java/src/game/Server.java b/java/src/server/Server.java similarity index 99% rename from java/src/game/Server.java rename to java/src/server/Server.java index 4c0c661..03e23ba 100755 --- a/java/src/game/Server.java +++ b/java/src/server/Server.java @@ -1,4 +1,4 @@ -package game; +package server; import java.io.BufferedInputStream; import java.io.BufferedReader; @@ -20,11 +20,6 @@ import java.util.concurrent.FutureTask; import game.collect.Lists; import game.collect.Maps; -import game.future.Futures; -import game.future.ListenableFuture; -import game.future.ListenableFutureTask; -import game.future.ThreadFactoryBuilder; - import game.color.TextColor; import game.command.CommandEnvironment; import game.command.FixedExecutor; @@ -33,6 +28,10 @@ import game.dimension.Space; import game.entity.Entity; import game.entity.npc.EntityHuman; import game.entity.npc.EntityNPC; +import game.future.Futures; +import game.future.ListenableFuture; +import game.future.ListenableFutureTask; +import game.future.ThreadFactoryBuilder; import game.init.Config; import game.init.EntityRegistry; import game.init.Registry; @@ -41,17 +40,17 @@ import game.log.Log; import game.nbt.NBTLoader; import game.nbt.NBTTagCompound; import game.nbt.NBTTagList; +import game.network.HandshakeHandler; import game.network.IThreadListener; import game.network.LazyLoadBase; import game.network.NetConnection; import game.network.NetHandler.ThreadQuickExitException; -import game.network.HandshakeHandler; -import game.network.Player; import game.network.Packet; import game.network.PacketDecoder; import game.network.PacketEncoder; import game.network.PacketPrepender; import game.network.PacketSplitter; +import game.network.Player; import game.packet.RPacketEnableCompression; import game.packet.RPacketLoginSuccess; import game.packet.S1DPacketEntityEffect; From b17efb5b07a87b81c2c71bf2826dd1f6642abf84 Mon Sep 17 00:00:00 2001 From: Sen Date: Mon, 5 May 2025 18:27:06 +0200 Subject: [PATCH 002/200] split client and server 2 --- java/src/client/Game.java | 6 +- java/src/client/PlayerController.java | 2 +- java/src/client/gui/GuiConnect.java | 4 +- java/src/client/gui/GuiConsole.java | 7 +- java/src/client/gui/GuiServer.java | 14 +- java/src/client/gui/character/GuiChar.java | 8 +- java/src/client/gui/ingame/GuiSign.java | 2 +- .../network/ClientLoginHandler.java | 8 +- .../network/ClientPlayer.java | 8 +- java/src/game/IServer.java | 33 ++ java/src/game/entity/npc/EntityNPC.java | 12 +- java/src/game/entity/types/EntityLiving.java | 6 +- .../src/game/network/IClientLoginHandler.java | 15 + java/src/game/network/IClientPlayer.java | 315 ++++++++++++++++++ java/src/game/network/IHandshakeHandler.java | 9 + java/src/game/network/ILoginHandler.java | 9 + java/src/game/network/IPlayer.java | 173 ++++++++++ java/src/game/network/NetConnection.java | 1 + java/src/game/network/NetHandler.java | 4 +- java/src/game/network/Packet.java | 2 +- java/src/game/packet/APacketEmpty.java | 3 +- java/src/game/packet/APacketVarInt.java | 3 +- java/src/game/packet/CPacketAction.java | 6 +- java/src/game/packet/CPacketBook.java | 6 +- java/src/game/packet/CPacketBreak.java | 6 +- java/src/game/packet/CPacketCheat.java | 6 +- java/src/game/packet/CPacketClick.java | 6 +- java/src/game/packet/CPacketComplete.java | 6 +- java/src/game/packet/CPacketInput.java | 6 +- java/src/game/packet/CPacketKeepAlive.java | 6 +- java/src/game/packet/CPacketMessage.java | 14 +- java/src/game/packet/CPacketPlace.java | 6 +- java/src/game/packet/CPacketPlayer.java | 6 +- java/src/game/packet/CPacketSign.java | 6 +- java/src/game/packet/CPacketSkin.java | 6 +- java/src/game/packet/HPacketHandshake.java | 6 +- .../game/packet/LPacketPasswordResponse.java | 14 +- java/src/game/packet/RPacketDisconnect.java | 6 +- .../game/packet/RPacketEnableCompression.java | 6 +- java/src/game/packet/RPacketLoginSuccess.java | 6 +- java/src/game/packet/S14PacketEntity.java | 6 +- .../game/packet/S18PacketEntityTeleport.java | 6 +- .../game/packet/S19PacketEntityHeadLook.java | 6 +- .../game/packet/S1APacketEntityStatus.java | 6 +- .../game/packet/S1BPacketEntityAttach.java | 6 +- .../game/packet/S1CPacketEntityMetadata.java | 6 +- .../game/packet/S1DPacketEntityEffect.java | 6 +- .../packet/S1EPacketRemoveEntityEffect.java | 6 +- .../packet/S20PacketEntityProperties.java | 6 +- java/src/game/packet/S27PacketExplosion.java | 6 +- java/src/game/packet/S28PacketEffect.java | 6 +- .../src/game/packet/S29PacketSoundEffect.java | 6 +- java/src/game/packet/S2APacketParticles.java | 6 +- .../game/packet/S2BPacketChangeGameState.java | 6 +- .../packet/S2CPacketSpawnGlobalEntity.java | 6 +- java/src/game/packet/S2DPacketOpenWindow.java | 6 +- .../src/game/packet/S2EPacketCloseWindow.java | 6 +- java/src/game/packet/S2FPacketSetSlot.java | 6 +- .../src/game/packet/S30PacketWindowItems.java | 6 +- .../game/packet/S31PacketWindowProperty.java | 6 +- .../packet/S32PacketConfirmTransaction.java | 6 +- java/src/game/packet/S33PacketUpdateSign.java | 6 +- .../packet/S35PacketUpdateTileEntity.java | 6 +- .../game/packet/S36PacketSignEditorOpen.java | 6 +- .../game/packet/S38PacketPlayerListItem.java | 18 +- .../game/packet/S39PacketPlayerAbilities.java | 6 +- .../src/game/packet/S3APacketTabComplete.java | 6 +- .../game/packet/S43PacketUpdateEntityNBT.java | 6 +- java/src/game/packet/SPacketAnimation.java | 6 +- java/src/game/packet/SPacketBiomes.java | 6 +- java/src/game/packet/SPacketBlockAction.java | 6 +- .../game/packet/SPacketBlockBreakAnim.java | 6 +- java/src/game/packet/SPacketBlockChange.java | 6 +- java/src/game/packet/SPacketCamera.java | 6 +- .../src/game/packet/SPacketCharacterList.java | 12 +- java/src/game/packet/SPacketChunkData.java | 6 +- java/src/game/packet/SPacketCollectItem.java | 6 +- .../game/packet/SPacketDestroyEntities.java | 6 +- .../src/game/packet/SPacketDimensionName.java | 6 +- java/src/game/packet/SPacketDisconnect.java | 6 +- .../game/packet/SPacketEntityEquipment.java | 6 +- .../game/packet/SPacketEntityVelocity.java | 6 +- .../game/packet/SPacketHeldItemChange.java | 6 +- java/src/game/packet/SPacketJoinGame.java | 6 +- java/src/game/packet/SPacketKeepAlive.java | 6 +- java/src/game/packet/SPacketLoading.java | 6 +- java/src/game/packet/SPacketMapChunkBulk.java | 6 +- java/src/game/packet/SPacketMessage.java | 6 +- .../game/packet/SPacketMultiBlockChange.java | 6 +- .../src/game/packet/SPacketPlayerPosLook.java | 6 +- java/src/game/packet/SPacketRespawn.java | 6 +- java/src/game/packet/SPacketServerTick.java | 6 +- .../src/game/packet/SPacketSetExperience.java | 6 +- java/src/game/packet/SPacketSkin.java | 6 +- java/src/game/packet/SPacketSpawnMob.java | 6 +- java/src/game/packet/SPacketSpawnObject.java | 6 +- java/src/game/packet/SPacketSpawnPlayer.java | 6 +- java/src/game/packet/SPacketTimeUpdate.java | 6 +- java/src/game/packet/SPacketTrades.java | 6 +- java/src/game/packet/SPacketUpdateHealth.java | 6 +- java/src/game/packet/SPacketWorld.java | 6 +- .../game/{network => util}/LazyLoadBase.java | 2 +- java/src/game/world/WorldServer.java | 50 ++- java/src/server/Server.java | 24 +- .../{game => server}/command/ArgCombiner.java | 2 +- .../{game => server}/command/Argument.java | 2 +- .../command/ArgumentParser.java | 2 +- .../command/ArgumentSplitter.java | 2 +- .../command/BooleanParser.java | 2 +- .../command/CachedExecutable.java | 2 +- .../{game => server}/command/ColorParser.java | 2 +- .../src/{game => server}/command/Command.java | 4 +- .../command/CommandEnvironment.java | 34 +- .../{game => server}/command/Completer.java | 2 +- .../command/CompletingParser.java | 2 +- .../command/DefaultingParser.java | 2 +- .../command/DimensionParser.java | 2 +- .../command/DoubleParser.java | 2 +- .../command/EntityListParser.java | 4 +- .../command/EntityParser.java | 2 +- .../{game => server}/command/EnumParser.java | 2 +- .../{game => server}/command/Executable.java | 2 +- .../{game => server}/command/Executor.java | 2 +- .../command/FixedExecutor.java | 2 +- .../{game => server}/command/IntParser.java | 2 +- .../{game => server}/command/LongParser.java | 2 +- .../command/NonDefaultingParser.java | 2 +- .../{game => server}/command/Parameter.java | 2 +- .../command/PatternReplacer.java | 2 +- .../command/PlayerEntityListParser.java | 4 +- .../command/PlayerEntityParser.java | 4 +- .../command/PlayerListParser.java | 4 +- .../command/PlayerParser.java | 4 +- .../command/RunException.java | 2 +- .../command/StringCompleter.java | 2 +- .../command/StringParser.java | 2 +- .../{game => server}/command/TagParser.java | 2 +- .../{game => server}/command/Variable.java | 2 +- .../{game => server}/command/WorldParser.java | 2 +- .../command/commands/CommandAdmin.java | 12 +- .../command/commands/CommandHelp.java | 14 +- .../command/commands/CommandKick.java | 12 +- .../command/commands/CommandMessage.java | 8 +- .../command/commands/CommandMilk.java | 8 +- .../command/commands/CommandOfflinetp.java | 14 +- .../command/commands/CommandPotion.java | 8 +- .../command/commands/CommandRemove.java | 8 +- .../command/commands/CommandRevoke.java | 12 +- .../command/commands/CommandSpawn.java | 12 +- .../command/commands/CommandTele.java | 8 +- .../command/commands/CommandTime.java | 10 +- .../command/commands/CommandTp.java | 8 +- .../command/commands/CommandWarp.java | 12 +- .../command/commands/CommandWeather.java | 10 +- .../command/commands/CommandWorld.java | 8 +- .../network/HandshakeHandler.java | 8 +- .../network/LoginHandler.java | 10 +- java/src/{game => server}/network/Player.java | 71 ++-- 158 files changed, 1080 insertions(+), 515 deletions(-) rename java/src/{game => client}/network/ClientLoginHandler.java (87%) rename java/src/{game => client}/network/ClientPlayer.java (99%) create mode 100644 java/src/game/IServer.java create mode 100644 java/src/game/network/IClientLoginHandler.java create mode 100644 java/src/game/network/IClientPlayer.java create mode 100644 java/src/game/network/IHandshakeHandler.java create mode 100644 java/src/game/network/ILoginHandler.java create mode 100644 java/src/game/network/IPlayer.java rename java/src/game/{network => util}/LazyLoadBase.java (93%) rename java/src/{game => server}/command/ArgCombiner.java (83%) rename java/src/{game => server}/command/Argument.java (96%) rename java/src/{game => server}/command/ArgumentParser.java (98%) rename java/src/{game => server}/command/ArgumentSplitter.java (99%) rename java/src/{game => server}/command/BooleanParser.java (91%) rename java/src/{game => server}/command/CachedExecutable.java (99%) rename java/src/{game => server}/command/ColorParser.java (96%) rename java/src/{game => server}/command/Command.java (99%) rename java/src/{game => server}/command/CommandEnvironment.java (91%) rename java/src/{game => server}/command/Completer.java (86%) rename java/src/{game => server}/command/CompletingParser.java (95%) rename java/src/{game => server}/command/DefaultingParser.java (93%) rename java/src/{game => server}/command/DimensionParser.java (98%) rename java/src/{game => server}/command/DoubleParser.java (99%) rename java/src/{game => server}/command/EntityListParser.java (98%) rename java/src/{game => server}/command/EntityParser.java (98%) rename java/src/{game => server}/command/EnumParser.java (98%) rename java/src/{game => server}/command/Executable.java (90%) rename java/src/{game => server}/command/Executor.java (94%) rename java/src/{game => server}/command/FixedExecutor.java (97%) rename java/src/{game => server}/command/IntParser.java (98%) rename java/src/{game => server}/command/LongParser.java (97%) rename java/src/{game => server}/command/NonDefaultingParser.java (90%) rename java/src/{game => server}/command/Parameter.java (97%) rename java/src/{game => server}/command/PatternReplacer.java (98%) rename java/src/{game => server}/command/PlayerEntityListParser.java (96%) rename java/src/{game => server}/command/PlayerEntityParser.java (92%) rename java/src/{game => server}/command/PlayerListParser.java (95%) rename java/src/{game => server}/command/PlayerParser.java (93%) rename java/src/{game => server}/command/RunException.java (96%) rename java/src/{game => server}/command/StringCompleter.java (83%) rename java/src/{game => server}/command/StringParser.java (99%) rename java/src/{game => server}/command/TagParser.java (96%) rename java/src/{game => server}/command/Variable.java (68%) rename java/src/{game => server}/command/WorldParser.java (98%) rename java/src/{game => server}/command/commands/CommandAdmin.java (74%) rename java/src/{game => server}/command/commands/CommandHelp.java (88%) rename java/src/{game => server}/command/commands/CommandKick.java (75%) rename java/src/{game => server}/command/commands/CommandMessage.java (76%) rename java/src/{game => server}/command/commands/CommandMilk.java (89%) rename java/src/{game => server}/command/commands/CommandOfflinetp.java (83%) rename java/src/{game => server}/command/commands/CommandPotion.java (91%) rename java/src/{game => server}/command/commands/CommandRemove.java (83%) rename java/src/{game => server}/command/commands/CommandRevoke.java (77%) rename java/src/{game => server}/command/commands/CommandSpawn.java (93%) rename java/src/{game => server}/command/commands/CommandTele.java (88%) rename java/src/{game => server}/command/commands/CommandTime.java (93%) rename java/src/{game => server}/command/commands/CommandTp.java (83%) rename java/src/{game => server}/command/commands/CommandWarp.java (89%) rename java/src/{game => server}/command/commands/CommandWeather.java (83%) rename java/src/{game => server}/command/commands/CommandWorld.java (90%) rename java/src/{game => server}/network/HandshakeHandler.java (84%) rename java/src/{game => server}/network/LoginHandler.java (92%) rename java/src/{game => server}/network/Player.java (98%) diff --git a/java/src/client/Game.java b/java/src/client/Game.java index be13f94..2dc5fe7 100755 --- a/java/src/client/Game.java +++ b/java/src/client/Game.java @@ -51,6 +51,8 @@ import client.gui.container.GuiContainer; import client.gui.container.GuiInventory; import client.gui.element.Textbox; import client.gui.ingame.GuiGameOver; +import client.network.ClientLoginHandler; +import client.network.ClientPlayer; import client.renderer.BlockRenderer; import client.renderer.Drawing; import client.renderer.EntityRenderer; @@ -104,8 +106,6 @@ import game.log.Log; import game.log.LogLevel; import game.log.Message; import game.material.Material; -import game.network.ClientLoginHandler; -import game.network.ClientPlayer; import game.network.IThreadListener; import game.network.NetConnection; import game.network.NetHandler.ThreadQuickExitException; @@ -1476,7 +1476,7 @@ public class Game implements IThreadListener { public ClientPlayer getNetHandler() { - return this.thePlayer != null ? this.thePlayer.sendQueue : null; + return this.thePlayer != null ? (ClientPlayer)this.thePlayer.sendQueue : null; } // public void setSkin(BufferedImage skin, String id, ModelType model, boolean slim) diff --git a/java/src/client/PlayerController.java b/java/src/client/PlayerController.java index 1b6d07b..d12dd90 100755 --- a/java/src/client/PlayerController.java +++ b/java/src/client/PlayerController.java @@ -1,5 +1,6 @@ package client; +import client.network.ClientPlayer; import game.block.Block; import game.entity.Entity; import game.entity.npc.EntityNPC; @@ -9,7 +10,6 @@ import game.item.ItemBlock; import game.item.ItemControl; import game.item.ItemStack; import game.material.Material; -import game.network.ClientPlayer; import game.packet.CPacketAction; import game.packet.CPacketBreak; import game.packet.CPacketClick; diff --git a/java/src/client/gui/GuiConnect.java b/java/src/client/gui/GuiConnect.java index 05ae015..568343f 100644 --- a/java/src/client/gui/GuiConnect.java +++ b/java/src/client/gui/GuiConnect.java @@ -14,7 +14,7 @@ import client.renderer.Drawing; import game.color.TextColor; import game.init.Config; import game.log.Log; -import game.network.Player; +import game.network.IPlayer; import game.util.FileUtils; import game.util.Tuple; import game.util.Util; @@ -132,7 +132,7 @@ public class GuiConnect extends GuiList implements ActBut for(int z = 0; z <= lines.length; z++) { String line = z == lines.length ? null : lines[z]; if(line == null || (line.startsWith("[") && line.endsWith("]"))) { - if(!name.isEmpty() && !address.isEmpty() && !user.isEmpty() && user.length() < Player.MAX_USER_LENGTH && Player.isValidUser(user) && password.length() < Player.MAX_PASS_LENGTH && access.length() < Player.MAX_PASS_LENGTH && address.length() < 128 && name.length() < 128 && port >= 0 && port < 65536) + if(!name.isEmpty() && !address.isEmpty() && !user.isEmpty() && user.length() < IPlayer.MAX_USER_LENGTH && IPlayer.isValidUser(user) && password.length() < IPlayer.MAX_PASS_LENGTH && access.length() < IPlayer.MAX_PASS_LENGTH && address.length() < 128 && name.length() < 128 && port >= 0 && port < 65536) this.elements.add(new ServerInfo(name, address, port, user, password, access, time)); if(line != null) { address = ""; diff --git a/java/src/client/gui/GuiConsole.java b/java/src/client/gui/GuiConsole.java index a625119..d4023e7 100644 --- a/java/src/client/gui/GuiConsole.java +++ b/java/src/client/gui/GuiConsole.java @@ -7,11 +7,12 @@ import client.gui.element.ActButton; import client.gui.element.Fill; import client.gui.element.Textbox; import client.gui.element.Textbox.Action; +import client.network.ClientPlayer; import client.gui.element.TransparentBox; import client.window.Keysym; import game.collect.Lists; import game.color.TextColor; -import game.network.Player; +import game.network.IPlayer; import game.packet.CPacketComplete; import game.util.ExtMath; import game.vars.BoolVar; @@ -57,7 +58,7 @@ public class GuiConsole extends Gui implements Textbox.Callback { this.logBox = this.add(new TransparentBox(0, this.full ? 24 : 0, width, height - (this.full ? 48 : 24), this.gm.getBuffer(), this.gm.theWorld != null && !this.gm.charEditor)); if(this.full) this.add(new Fill(640, 0, width - 640, 24)); - this.inputField = this.add(new Textbox(0, height - 24, width, 24, Player.MAX_CMD_LENGTH, true, this, "")); + this.inputField = this.add(new Textbox(0, height - 24, width, 24, IPlayer.MAX_CMD_LENGTH, true, this, "")); this.inputField.setSelected(); this.sentHistoryCursor = this.sentMessages.size(); } @@ -214,7 +215,7 @@ public class GuiConsole extends Gui implements Textbox.Callback { s = argv[argv.length - 1]; Iterable res = pre.startsWith("#") ? (argv.length == 1 ? this.gm.getVars() : (argv.length == 2 ? getVarCompletion(argv[0].substring(1)) : Lists.newArrayList())) : - (this.gm.thePlayer == null ? Lists.newArrayList() : this.gm.thePlayer.sendQueue.getPlayerNames()); + (this.gm.thePlayer == null ? Lists.newArrayList() : ((ClientPlayer)this.gm.thePlayer.sendQueue).getPlayerNames()); if(argv.length == 1 && pre.startsWith("#")) s = s.substring(1); for(String s1 : res) { diff --git a/java/src/client/gui/GuiServer.java b/java/src/client/gui/GuiServer.java index c6d256c..45833a1 100644 --- a/java/src/client/gui/GuiServer.java +++ b/java/src/client/gui/GuiServer.java @@ -8,7 +8,7 @@ import client.gui.element.Textbox; import client.gui.element.Textbox.Action; import game.color.TextColor; import game.init.Config; -import game.network.Player; +import game.network.IPlayer; import game.vars.CVarCategory; import game.vars.Variable; @@ -38,11 +38,11 @@ public class GuiServer extends Gui implements Textbox.Callback { private String lastAddr = ""; @Variable(name = "srv_last_port", category = CVarCategory.SYSTEM, min = 0, max = 65535, display = "Letzter Server-Port") private int lastPort = Config.PORT; - @Variable(name = "srv_last_user", category = CVarCategory.SYSTEM, max = Player.MAX_USER_LENGTH, display = "Letzter Server-Nutzer", validator = Player.UserValidator.class) + @Variable(name = "srv_last_user", category = CVarCategory.SYSTEM, max = IPlayer.MAX_USER_LENGTH, display = "Letzter Server-Nutzer", validator = IPlayer.UserValidator.class) private String lastUser = ""; - @Variable(name = "srv_last_password", category = CVarCategory.SYSTEM, max = Player.MAX_PASS_LENGTH, display = "Letztes Server-Passwort") + @Variable(name = "srv_last_password", category = CVarCategory.SYSTEM, max = IPlayer.MAX_PASS_LENGTH, display = "Letztes Server-Passwort") private String lastPass = ""; - @Variable(name = "srv_last_access", category = CVarCategory.SYSTEM, max = Player.MAX_PASS_LENGTH, display = "Letzter Server-Zugang") + @Variable(name = "srv_last_access", category = CVarCategory.SYSTEM, max = IPlayer.MAX_PASS_LENGTH, display = "Letzter Server-Zugang") private String lastAcc = ""; public void init(int width, int height) { @@ -50,9 +50,9 @@ public class GuiServer extends Gui implements Textbox.Callback { this.nameBox = this.add(new Textbox(0, -50, 400, 24, 128, true, this, this.server.getName())); this.addrBox = this.add(new Textbox(0, 20, 400, 24, 128, true, this, this.server == null ? this.lastAddr : this.server.getAddress())); this.portBox = this.add(new Textbox(404, 20, 76, 24, 5, true, this, "" + (this.server == null ? this.lastPort : this.server.getPort()))); - this.userBox = this.add(new Textbox(0, 70, 220, 24, Player.MAX_USER_LENGTH, true, this, Player.VALID_USER, this.server == null ? this.lastUser : this.server.getUser())); - this.passBox = this.add(new Textbox(0, 120, 480, 24, Player.MAX_PASS_LENGTH, true, this, this.server == null ? this.lastPass : this.server.getPassword())); - this.accBox = this.add(new Textbox(0, 170, 480, 24, Player.MAX_PASS_LENGTH, true, this, this.server == null ? this.lastAcc : this.server.getAccess())); + this.userBox = this.add(new Textbox(0, 70, 220, 24, IPlayer.MAX_USER_LENGTH, true, this, IPlayer.VALID_USER, this.server == null ? this.lastUser : this.server.getUser())); + this.passBox = this.add(new Textbox(0, 120, 480, 24, IPlayer.MAX_PASS_LENGTH, true, this, this.server == null ? this.lastPass : this.server.getPassword())); + this.accBox = this.add(new Textbox(0, 170, 480, 24, IPlayer.MAX_PASS_LENGTH, true, this, this.server == null ? this.lastAcc : this.server.getAccess())); this.add(new ActButton(0, 220, 480, 24, new ActButton.Callback() { public void use(ActButton elem, ActButton.Mode action) { GuiServer.this.connect(); diff --git a/java/src/client/gui/character/GuiChar.java b/java/src/client/gui/character/GuiChar.java index 4def730..4ffc119 100755 --- a/java/src/client/gui/character/GuiChar.java +++ b/java/src/client/gui/character/GuiChar.java @@ -51,7 +51,7 @@ import game.init.SpeciesRegistry; import game.init.SpeciesRegistry.ModelType; import game.init.UniverseRegistry; import game.log.Log; -import game.network.Player; +import game.network.IPlayer; import game.packet.CPacketAction; import game.packet.CPacketMessage; import game.packet.CPacketSkin; @@ -361,7 +361,7 @@ public class GuiChar extends GuiList }, "Spieler-Größe", "cm")).enabled = this.gm.thePlayer == null || this.gm.thePlayer.getMinSize() != this.gm.thePlayer.getMaxSize(); this.add(new Label(width / 2 - 200, 36, 400, 20, "Name", true)); this.add(new Label(width - 396, height - 384, 392, 20, "Beschreibung", true)); - final Textbox descField = this.add(new Textbox(width - 396, height - 364, 392, 130, Player.MAX_INFO_LENGTH, new Textbox.Callback() { + final Textbox descField = this.add(new Textbox(width - 396, height - 364, 392, 130, IPlayer.MAX_INFO_LENGTH, new Textbox.Callback() { public void use(Textbox elem, Action value) { } }, "")); @@ -375,7 +375,7 @@ public class GuiChar extends GuiList } } }, "Charakter erstellen")); - this.add(new Textbox(width / 2 - 200, 36 + 20, 400, 24, Player.MAX_NICK_LENGTH, true, new Textbox.Callback() { + this.add(new Textbox(width / 2 - 200, 36 + 20, 400, 24, IPlayer.MAX_NICK_LENGTH, true, new Textbox.Callback() { public void use(Textbox elem, Action value) { if(value == Action.SEND || value == Action.UNFOCUS) { String name = elem.getText(); @@ -387,7 +387,7 @@ public class GuiChar extends GuiList } } } - }, Player.VALID_NICK, this.gm.thePlayer == null ? "" : this.gm.thePlayer.getCustomNameTag())); + }, IPlayer.VALID_NICK, this.gm.thePlayer == null ? "" : this.gm.thePlayer.getCustomNameTag())); this.templateButton.enabled = false; this.dimension = new Random().zrange(UniverseRegistry.getBaseDimensions().size()); EntityEggInfo egg = EntityRegistry.SPAWN_EGGS.get(this.gm.thePlayer == null ? EntityRegistry.getEntityString(EntityHuman.class) : EntityRegistry.getEntityString(this.gm.thePlayer)); diff --git a/java/src/client/gui/ingame/GuiSign.java b/java/src/client/gui/ingame/GuiSign.java index 925ae91..4678e86 100644 --- a/java/src/client/gui/ingame/GuiSign.java +++ b/java/src/client/gui/ingame/GuiSign.java @@ -4,7 +4,7 @@ import client.gui.Gui; import client.gui.element.NavButton; import client.gui.element.Textbox; import client.gui.element.Textbox.Action; -import game.network.ClientPlayer; +import client.network.ClientPlayer; import game.packet.CPacketSign; import game.world.BlockPos; diff --git a/java/src/game/network/ClientLoginHandler.java b/java/src/client/network/ClientLoginHandler.java similarity index 87% rename from java/src/game/network/ClientLoginHandler.java rename to java/src/client/network/ClientLoginHandler.java index 6620101..b699978 100755 --- a/java/src/game/network/ClientLoginHandler.java +++ b/java/src/client/network/ClientLoginHandler.java @@ -1,11 +1,15 @@ -package game.network; +package client.network; import client.Game; +import game.network.IClientLoginHandler; +import game.network.NetConnection; +import game.network.NetHandler; +import game.network.PacketRegistry; import game.packet.RPacketDisconnect; import game.packet.RPacketEnableCompression; import game.packet.RPacketLoginSuccess; -public class ClientLoginHandler extends NetHandler { +public class ClientLoginHandler extends NetHandler implements IClientLoginHandler { private final Game gm; private final NetConnection networkManager; diff --git a/java/src/game/network/ClientPlayer.java b/java/src/client/network/ClientPlayer.java similarity index 99% rename from java/src/game/network/ClientPlayer.java rename to java/src/client/network/ClientPlayer.java index 8cd036e..a94a2b3 100755 --- a/java/src/game/network/ClientPlayer.java +++ b/java/src/client/network/ClientPlayer.java @@ -1,4 +1,4 @@ -package game.network; +package client.network; import java.util.Collection; import java.util.List; @@ -45,6 +45,10 @@ import game.inventory.InventoryPlayer; import game.item.ItemStack; import game.log.Log; import game.model.ParticleType; +import game.network.IClientPlayer; +import game.network.NetConnection; +import game.network.NetHandler; +import game.network.Packet; import game.packet.CPacketAction; import game.packet.CPacketKeepAlive; import game.packet.CPacketPlayer; @@ -121,7 +125,7 @@ import game.world.Explosion; import game.world.Weather; import game.world.WorldClient; -public class ClientPlayer extends NetHandler +public class ClientPlayer extends NetHandler implements IClientPlayer { /** * The NetworkManager instance used to communicate with the server (used only by handlePlayerPosLook to update diff --git a/java/src/game/IServer.java b/java/src/game/IServer.java new file mode 100644 index 0000000..27dd5dd --- /dev/null +++ b/java/src/game/IServer.java @@ -0,0 +1,33 @@ +package game; + +import java.util.List; +import java.util.Map; + +import game.entity.Entity; +import game.entity.npc.EntityNPC; +import game.network.IPlayer; +import game.network.Packet; +import game.world.BlockPos; +import game.world.PortalType; +import game.world.Position; +import game.world.WorldServer; + +public interface IServer { + List getIPlayers(); + + void sendPacket(Packet packet); + + void sendPacket(Packet packet, int dimension); + + void sendNear(double x, double y, double z, double radius, int dimension, Packet packet); + + void sendNearExcept(EntityNPC except, double x, double y, double z, double radius, int dimension, Packet packet); + + Map getWarps(); + + List getWorlds(); + + WorldServer getWorld(int dimension); + + void placeInDimension(Entity entity, WorldServer oldWorld, WorldServer world, BlockPos pos, PortalType portal); +} \ No newline at end of file diff --git a/java/src/game/entity/npc/EntityNPC.java b/java/src/game/entity/npc/EntityNPC.java index dc4aa1a..8ec1d52 100755 --- a/java/src/game/entity/npc/EntityNPC.java +++ b/java/src/game/entity/npc/EntityNPC.java @@ -83,8 +83,8 @@ import game.item.ItemTool; import game.model.ParticleType; import game.nbt.NBTTagCompound; import game.nbt.NBTTagList; -import game.network.ClientPlayer; -import game.network.Player; +import game.network.IClientPlayer; +import game.network.IPlayer; import game.packet.CPacketAction; import game.packet.CPacketBreak; import game.packet.CPacketInput; @@ -198,8 +198,8 @@ public abstract class EntityNPC extends EntityLiving private int healTimer; private byte[] skin; - public Player connection; - public ClientPlayer sendQueue; + public IPlayer connection; + public IClientPlayer sendQueue; protected Game gm; public InventoryPlayer inventory; @@ -399,13 +399,13 @@ public abstract class EntityNPC extends EntityLiving this.getEntityAttribute(Attributes.MOVEMENT_SPEED).setBaseValue(this.getEntityAttribute(Attributes.MOVEMENT_SPEED).getBaseValue() / 3.0); // 0.10000000149011612D); } - public final void setServerPlayer(Player connection) { + public final void setServerPlayer(IPlayer connection) { this.initPlayer(); this.connection = connection; this.stepHeight = 0.0F; } - public final void setClientPlayer(Game gm, ClientPlayer connection) { + public final void setClientPlayer(Game gm, IClientPlayer connection) { this.initPlayer(); this.gm = gm; this.sendQueue = connection; diff --git a/java/src/game/entity/types/EntityLiving.java b/java/src/game/entity/types/EntityLiving.java index 7089c2b..baa92d7 100755 --- a/java/src/game/entity/types/EntityLiving.java +++ b/java/src/game/entity/types/EntityLiving.java @@ -50,7 +50,7 @@ import game.material.Material; import game.model.ParticleType; import game.nbt.NBTTagCompound; import game.nbt.NBTTagList; -import game.network.Player; +import game.network.IPlayer; import game.packet.S1BPacketEntityAttach; import game.packet.SPacketAnimation; import game.packet.SPacketCollectItem; @@ -2462,7 +2462,7 @@ public abstract class EntityLiving extends Entity return; String msg; String kill; - Player receiver = null; + IPlayer receiver = null; if(this.combat.size() == 0) { msg = kill = natural ? String.format("%s starb", this.getColoredName(TextColor.LGRAY)) : null; } @@ -2551,7 +2551,7 @@ public abstract class EntityLiving extends Entity if(receiver != null) receiver.addFeed(kill); if(forAll) - for(Player player : ((WorldServer)this.worldObj).getServer().getPlayers()) { + for(IPlayer player : ((WorldServer)this.worldObj).getServer().getIPlayers()) { if(player != receiver) player.addFeed(msg); } diff --git a/java/src/game/network/IClientLoginHandler.java b/java/src/game/network/IClientLoginHandler.java new file mode 100644 index 0000000..b06b99e --- /dev/null +++ b/java/src/game/network/IClientLoginHandler.java @@ -0,0 +1,15 @@ +package game.network; + +import game.packet.RPacketDisconnect; +import game.packet.RPacketEnableCompression; +import game.packet.RPacketLoginSuccess; + +public interface IClientLoginHandler { + + void handleDisconnect(RPacketDisconnect packetIn); + + void handleLoginSuccess(RPacketLoginSuccess packetIn); + + void handleEnableCompression(RPacketEnableCompression packetIn); + +} \ No newline at end of file diff --git a/java/src/game/network/IClientPlayer.java b/java/src/game/network/IClientPlayer.java new file mode 100644 index 0000000..4ac9f51 --- /dev/null +++ b/java/src/game/network/IClientPlayer.java @@ -0,0 +1,315 @@ +package game.network; + +import game.packet.S14PacketEntity; +import game.packet.S18PacketEntityTeleport; +import game.packet.S19PacketEntityHeadLook; +import game.packet.S1APacketEntityStatus; +import game.packet.S1BPacketEntityAttach; +import game.packet.S1CPacketEntityMetadata; +import game.packet.S1DPacketEntityEffect; +import game.packet.S1EPacketRemoveEntityEffect; +import game.packet.S20PacketEntityProperties; +import game.packet.S27PacketExplosion; +import game.packet.S28PacketEffect; +import game.packet.S29PacketSoundEffect; +import game.packet.S2APacketParticles; +import game.packet.S2BPacketChangeGameState; +import game.packet.S2CPacketSpawnGlobalEntity; +import game.packet.S2DPacketOpenWindow; +import game.packet.S2EPacketCloseWindow; +import game.packet.S2FPacketSetSlot; +import game.packet.S30PacketWindowItems; +import game.packet.S31PacketWindowProperty; +import game.packet.S32PacketConfirmTransaction; +import game.packet.S33PacketUpdateSign; +import game.packet.S35PacketUpdateTileEntity; +import game.packet.S36PacketSignEditorOpen; +import game.packet.S38PacketPlayerListItem; +import game.packet.S39PacketPlayerAbilities; +import game.packet.S3APacketTabComplete; +import game.packet.S43PacketUpdateEntityNBT; +import game.packet.SPacketAnimation; +import game.packet.SPacketBiomes; +import game.packet.SPacketBlockAction; +import game.packet.SPacketBlockBreakAnim; +import game.packet.SPacketBlockChange; +import game.packet.SPacketCamera; +import game.packet.SPacketCharacterList; +import game.packet.SPacketChunkData; +import game.packet.SPacketCollectItem; +import game.packet.SPacketDestroyEntities; +import game.packet.SPacketDimensionName; +import game.packet.SPacketDisconnect; +import game.packet.SPacketEntityEquipment; +import game.packet.SPacketEntityVelocity; +import game.packet.SPacketHeldItemChange; +import game.packet.SPacketJoinGame; +import game.packet.SPacketKeepAlive; +import game.packet.SPacketLoading; +import game.packet.SPacketMapChunkBulk; +import game.packet.SPacketMessage; +import game.packet.SPacketMultiBlockChange; +import game.packet.SPacketPlayerPosLook; +import game.packet.SPacketRespawn; +import game.packet.SPacketServerTick; +import game.packet.SPacketSetExperience; +import game.packet.SPacketSkin; +import game.packet.SPacketSpawnMob; +import game.packet.SPacketSpawnObject; +import game.packet.SPacketSpawnPlayer; +import game.packet.SPacketTimeUpdate; +import game.packet.SPacketTrades; +import game.packet.SPacketUpdateHealth; +import game.packet.SPacketWorld; + +public interface IClientPlayer { + void addToSendQueue(Packet packet); + + void handleJoinGame(SPacketJoinGame packetIn); + + /** + * Spawns an instance of the objecttype indicated by the packet and sets its position and momentum + */ + void handleSpawnObject(SPacketSpawnObject packetIn); + + /** + * Handles globally visible entities. Used in vanilla for lightning bolts + */ + void handleSpawnGlobalEntity(S2CPacketSpawnGlobalEntity packetIn); + + /** + * Sets the velocity of the specified entity to the specified value + */ + void handleEntityVelocity(SPacketEntityVelocity packetIn); + + /** + * Invoked when the server registers new proximate objects in your watchlist or when objects in your watchlist have + * changed -> Registers any changes locally + */ + void handleEntityMetadata(S1CPacketEntityMetadata packetIn); + + /** + * Handles the creation of a nearby player entity, sets the position and held item + */ + void handleSpawnPlayer(SPacketSpawnPlayer packetIn); + + /** + * Updates an entity's position and rotation as specified by the packet + */ + void handleEntityTeleport(S18PacketEntityTeleport packetIn); + + /** + * Updates which hotbar slot of the player is currently selected + */ + void handleHeldItemChange(SPacketHeldItemChange packetIn); + + /** + * Updates the specified entity's position by the specified relative moment and absolute rotation. Note that + * subclassing of the packet allows for the specification of a subset of this data (e.g. only rel. position, abs. + * rotation or both). + */ + void handleEntityMovement(S14PacketEntity packetIn); + + /** + * Updates the direction in which the specified entity is looking, normally this head rotation is independent of the + * rotation of the entity itself + */ + void handleEntityHeadLook(S19PacketEntityHeadLook packetIn); + + /** + * Locally eliminates the entities. Invoked by the server when the items are in fact destroyed, or the player is no + * longer registered as required to monitor them. The latter happens when distance between the player and item + * increases beyond a certain treshold (typically the viewing distance) + */ + void handleDestroyEntities(SPacketDestroyEntities packetIn); + + /** + * Handles changes in player positioning and rotation such as when travelling to a new dimension, (re)spawning, + * mounting horses etc. Seems to immediately reply to the server with the clients post-processing perspective on the + * player positioning + */ + void handlePlayerPosLook(SPacketPlayerPosLook packetIn); + + /** + * Received from the servers PlayerManager if between 1 and 64 blocks in a chunk are changed. If only one block + * requires an update, the server sends S23PacketBlockChange and if 64 or more blocks are changed, the server sends + * S21PacketChunkData + */ + void handleMultiBlockChange(SPacketMultiBlockChange packetIn); + + /** + * Updates the specified chunk with the supplied data, marks it for re-rendering and lighting recalculation + */ + void handleChunkData(SPacketChunkData packetIn); + + void handleBiomes(SPacketBiomes packetIn); + + /** + * Updates the block and metadata and generates a blockupdate (and notify the clients) + */ + void handleBlockChange(SPacketBlockChange packetIn); + + /** + * Closes the network channel + */ + void handleDisconnect(SPacketDisconnect packetIn); + + void handleCollectItem(SPacketCollectItem packetIn); + + /** + * Prints a chatmessage in the chat GUI + */ + void handleMessage(SPacketMessage packetIn); + + void handleLoading(SPacketLoading packet); + + /** + * Renders a specified animation: Waking up a player, a living entity swinging its currently held item, being hurt + * or receiving a critical hit by normal or magical means + */ + void handleAnimation(SPacketAnimation packetIn); + + /** + * Spawns the mob entity at the specified location, with the specified rotation, momentum and type. Updates the + * entities Datawatchers with the entity metadata specified in the packet + */ + void handleSpawnMob(SPacketSpawnMob packetIn); + + void handleTimeUpdate(SPacketTimeUpdate packetIn); + + void handleServerTick(SPacketServerTick packet); + + void handleEntityAttach(S1BPacketEntityAttach packetIn); + + /** + * Invokes the entities' handleUpdateHealth method which is implemented in LivingBase (hurt/death), + * MinecartMobSpawner (spawn delay), FireworkRocket & MinecartTNT (explosion), IronGolem (throwing,...), Witch + * (spawn particles), Zombie (villager transformation), Animal (breeding mode particles), Horse (breeding/smoke + * particles), Sheep (...), Tameable (...), Villager (particles for breeding mode, angry and happy), Wolf (...) + */ + void handleEntityStatus(S1APacketEntityStatus packetIn); + + void handleUpdateHealth(SPacketUpdateHealth packetIn); + + void handleSetExperience(SPacketSetExperience packetIn); + + void handleRespawn(SPacketRespawn packetIn); + + /** + * Initiates a new explosion (sound, particles, drop spawn) for the affected blocks indicated by the packet. + */ + void handleExplosion(S27PacketExplosion packetIn); + + /** + * Displays a GUI by ID. In order starting from id 0: Chest, Workbench, Furnace, Dispenser, Enchanting table, + * Brewing stand, Villager merchant, Beacon, Anvil, Hopper, Dropper, Horse + */ + void handleOpenWindow(S2DPacketOpenWindow packetIn); + + /** + * Handles pickin up an ItemStack or dropping one in your inventory or an open container + */ + void handleSetSlot(S2FPacketSetSlot packetIn); + + /** + * Verifies that the server and client are synchronized with respect to the inventory/container opened by the player + * and confirms if it is the case. + */ + void handleConfirmTransaction(S32PacketConfirmTransaction packetIn); + + /** + * Handles the placement of a specified ItemStack in a specified container/inventory slot + */ + void handleWindowItems(S30PacketWindowItems packetIn); + + /** + * Creates a sign in the specified location if it didn't exist and opens the GUI to edit its text + */ + void handleSignEditorOpen(S36PacketSignEditorOpen packetIn); + + /** + * Updates a specified sign with the specified text lines + */ + void handleUpdateSign(S33PacketUpdateSign packetIn); + + /** + * Updates the NBTTagCompound metadata of instances of the following entitytypes: Mob spawners, command blocks, + * beacons, skulls, flowerpot + */ + void handleUpdateTileEntity(S35PacketUpdateTileEntity packetIn); + + /** + * Sets the progressbar of the opened window to the specified value + */ + void handleWindowProperty(S31PacketWindowProperty packetIn); + + void handleEntityEquipment(SPacketEntityEquipment packetIn); + + /** + * Resets the ItemStack held in hand and closes the window that is opened + */ + void handleCloseWindow(S2EPacketCloseWindow packetIn); + + /** + * Triggers Block.onBlockEventReceived, which is implemented in BlockPistonBase for extension/retraction, BlockNote + * for setting the instrument (including audiovisual feedback) and in BlockContainer to set the number of players + * accessing a (Ender)Chest + */ + void handleBlockAction(SPacketBlockAction packetIn); + + /** + * Updates all registered IWorldAccess instances with destroyBlockInWorldPartially + */ + void handleBlockBreakAnim(SPacketBlockBreakAnim packetIn); + + void handleMapChunkBulk(SPacketMapChunkBulk packetIn); + + void handleChangeGameState(S2BPacketChangeGameState packetIn); + + void handleEffect(S28PacketEffect packetIn); + + void handleEntityEffect(S1DPacketEntityEffect packetIn); + + void handleCamera(SPacketCamera packetIn); + + void handleRemoveEntityEffect(S1EPacketRemoveEntityEffect packetIn); + + void handlePlayerListItem(S38PacketPlayerListItem packetIn); + + void handleCharacterList(SPacketCharacterList packet); + + void handleKeepAlive(SPacketKeepAlive packetIn); + + void handlePlayerAbilities(S39PacketPlayerAbilities packetIn); + + /** + * Displays the available command-completion options the server knows of + */ + void handleTabComplete(S3APacketTabComplete packetIn); + + void handleSoundEffect(S29PacketSoundEffect packetIn); + + void handleEntityNBT(S43PacketUpdateEntityNBT packetIn); + + /** + * Spawns a specified number of particles at the specified location with a randomized displacement according to + * specified bounds + */ + void handleParticles(S2APacketParticles packetIn); + + /** + * Updates en entity's attributes and their respective modifiers, which are used for speed bonusses (player + * sprinting, animals fleeing, baby speed), weapon/tool attackDamage, hostiles followRange randomization, zombie + * maxHealth and knockback resistance as well as reinforcement spawning chance. + */ + void handleEntityProperties(S20PacketEntityProperties packetIn); + + void handleSkin(SPacketSkin packetIn); + + void handleTrades(SPacketTrades packetIn); + + void handleWorld(SPacketWorld packetIn); + + void handleDimName(SPacketDimensionName packetIn); + +} \ No newline at end of file diff --git a/java/src/game/network/IHandshakeHandler.java b/java/src/game/network/IHandshakeHandler.java new file mode 100644 index 0000000..73af36d --- /dev/null +++ b/java/src/game/network/IHandshakeHandler.java @@ -0,0 +1,9 @@ +package game.network; + +import game.packet.HPacketHandshake; + +public interface IHandshakeHandler { + + void processHandshake(HPacketHandshake packetIn); + +} \ No newline at end of file diff --git a/java/src/game/network/ILoginHandler.java b/java/src/game/network/ILoginHandler.java new file mode 100644 index 0000000..45f6ff3 --- /dev/null +++ b/java/src/game/network/ILoginHandler.java @@ -0,0 +1,9 @@ +package game.network; + +import game.packet.LPacketPasswordResponse; + +public interface ILoginHandler { + + void processPasswordResponse(LPacketPasswordResponse packetIn); + +} \ No newline at end of file diff --git a/java/src/game/network/IPlayer.java b/java/src/game/network/IPlayer.java new file mode 100644 index 0000000..6d06d57 --- /dev/null +++ b/java/src/game/network/IPlayer.java @@ -0,0 +1,173 @@ +package game.network; + +import java.util.List; + +import game.entity.Entity; +import game.entity.animal.EntityHorse; +import game.entity.npc.EntityNPC; +import game.entity.types.EntityLiving; +import game.init.SoundEvent; +import game.inventory.Container; +import game.inventory.IInventory; +import game.item.ItemStack; +import game.packet.CPacketAction; +import game.packet.CPacketBook; +import game.packet.CPacketBreak; +import game.packet.CPacketCheat; +import game.packet.CPacketClick; +import game.packet.CPacketComplete; +import game.packet.CPacketInput; +import game.packet.CPacketKeepAlive; +import game.packet.CPacketMessage; +import game.packet.CPacketPlace; +import game.packet.CPacketPlayer; +import game.packet.CPacketSign; +import game.packet.CPacketSkin; +import game.potion.PotionEffect; +import game.tileentity.IInteractionObject; +import game.tileentity.TileEntitySign; +import game.util.CharValidator; +import game.world.BlockPos; +import game.world.ChunkPos; +import game.world.PortalType; + +public interface IPlayer { + public static class UserValidator implements CharValidator { + public boolean valid(char ch) { + return (ch >= 'a' && ch <= 'z') || (ch >= '0' && ch <= '9') || ch == '_' || ch == '-'; + } + } + + public static class NickValidator implements CharValidator { + public boolean valid(char ch) { + return (ch <= 0xff && Character.isLetterOrDigit(ch)) || (ch >= 32 && ch < 126); + } + } + + public static int MAX_USER_LENGTH = 16; + public static int MAX_NICK_LENGTH = 32; + public static int MAX_PASS_LENGTH = 64; + public static int MAX_CMD_LENGTH = 1024; + public static int MAX_INFO_LENGTH = 4096; + public static CharValidator VALID_USER = new IPlayer.UserValidator(); + public static CharValidator VALID_NICK = new IPlayer.NickValidator(); + + public static boolean isValidNick(String user) { + return VALID_NICK.valid(user); + } + + public static boolean isValidUser(String user) { + return VALID_USER.valid(user); + } + + void onEntityDeath(); + + boolean isInEditor(); + + EntityNPC getPresentEntity(); + + String getUser(); + + int getLatency(); + + boolean isAdmin(); + + void addToPlayerScore(EntityLiving entity); + + void displayTradeGui(EntityNPC npc); + + void setPlayerHealthUpdated(); + + void removeEntity(Entity p_152339_1_); + + void sendPlayerAbilities(); + + void addFeed(String msg); + + void addHotbar(String msg); + + void addHotbar(String format, Object... args); + + void sendThrowMessage(ItemStack stack); + + void resetLastExperience(); + + void travelToDimension(int dimensionId, BlockPos pos, float yaw, float pitch, PortalType portal); + + void teleport(double x, double y, double z, float yaw, float pitch, int dimension); + + void onItemPickup(Entity entity, int amount); + + void mountEntity(Entity entityIn); + + void openEditSign(TileEntitySign signTile); + + void displayGui(IInteractionObject guiOwner); + + void displayGUIChest(IInventory chestInventory); + + void displayGUIHorse(EntityHorse horse, IInventory horseInventory); + + void closeScreen(); + + void onItemUseFinish(); + + void onNewEffect(PotionEffect id); + + void onChangedEffect(PotionEffect id, boolean added); + + void onFinishedEffect(PotionEffect effect); + + void setPositionAndUpdate(double x, double y, double z); + + void onCriticalHit(Entity entityHit); + + void onEnchantmentCritical(Entity entityHit); + + void updateEffectMeta(); + + void playSound(SoundEvent name, float volume); + + void sendContainerToPlayer(Container container); + + void updateEntity(); + + void setSelection(boolean primary, BlockPos pos); + + void setSelectMode(); + + void sendPacket(Packet packet); + + void setPlayerLocation(double x, double y, double z, float yaw, float pitch); + + void processKeepAlive(CPacketKeepAlive packetIn); + + void processMessage(CPacketMessage packetIn); + + void processComplete(CPacketComplete packetIn); + + void processPlayer(CPacketPlayer packetIn); + + void processBreak(CPacketBreak packetIn); + + void processPlace(CPacketPlace packetIn); + + void processAction(CPacketAction packetIn); + + void processInput(CPacketInput packetIn); + + void processClick(CPacketClick packetIn); + + void processCheat(CPacketCheat packetIn); + + void processSign(CPacketSign packetIn); + + void processSkin(CPacketSkin packetIn); + + void processBook(CPacketBook packetIn); + + List getLoadedChunkList(); + double getManagedX(); + double getManagedZ(); + void setManagedPos(double x, double z); +} \ No newline at end of file diff --git a/java/src/game/network/NetConnection.java b/java/src/game/network/NetConnection.java index 2ce2493..3941f3f 100755 --- a/java/src/game/network/NetConnection.java +++ b/java/src/game/network/NetConnection.java @@ -10,6 +10,7 @@ import java.util.regex.Pattern; import game.future.ThreadFactoryBuilder; import game.log.Log; import game.network.NetHandler.ThreadQuickExitException; +import game.util.LazyLoadBase; import io.netty.bootstrap.Bootstrap; import io.netty.channel.Channel; import io.netty.channel.ChannelException; diff --git a/java/src/game/network/NetHandler.java b/java/src/game/network/NetHandler.java index db1d6c2..0d47cb4 100755 --- a/java/src/game/network/NetHandler.java +++ b/java/src/game/network/NetHandler.java @@ -19,7 +19,7 @@ public abstract class NetHandler { public void update() { } - public static void checkThread(final Packet packet, final T handler, IThreadListener listener) + public static void checkThread(final Packet packet, final T handler, IThreadListener listener) throws ThreadQuickExitException { if(!listener.isMainThread()) { listener.schedule(new Runnable() { @@ -31,7 +31,7 @@ public abstract class NetHandler { } } - public static void checkThread(final Packet packet, final T handler, IThreadListener listener, Object check) + public static void checkThread(final Packet packet, final T handler, IThreadListener listener, Object check) throws ThreadQuickExitException { if(check == null && listener.isMainThread()) { throw EXIT; diff --git a/java/src/game/network/Packet.java b/java/src/game/network/Packet.java index 2adea92..ced4621 100755 --- a/java/src/game/network/Packet.java +++ b/java/src/game/network/Packet.java @@ -2,7 +2,7 @@ package game.network; import java.io.IOException; -public interface Packet +public interface Packet { void readPacketData(PacketBuffer buf) throws IOException; void writePacketData(PacketBuffer buf) throws IOException; diff --git a/java/src/game/packet/APacketEmpty.java b/java/src/game/packet/APacketEmpty.java index f6dbe4c..8fede40 100755 --- a/java/src/game/packet/APacketEmpty.java +++ b/java/src/game/packet/APacketEmpty.java @@ -2,11 +2,10 @@ package game.packet; import java.io.IOException; -import game.network.NetHandler; import game.network.Packet; import game.network.PacketBuffer; -public abstract class APacketEmpty implements Packet { +public abstract class APacketEmpty implements Packet { public final void readPacketData(PacketBuffer buf) throws IOException { } diff --git a/java/src/game/packet/APacketVarInt.java b/java/src/game/packet/APacketVarInt.java index 44f58a2..87d9b79 100755 --- a/java/src/game/packet/APacketVarInt.java +++ b/java/src/game/packet/APacketVarInt.java @@ -2,11 +2,10 @@ package game.packet; import java.io.IOException; -import game.network.NetHandler; import game.network.Packet; import game.network.PacketBuffer; -public abstract class APacketVarInt implements Packet { +public abstract class APacketVarInt implements Packet { private int value; public APacketVarInt() { diff --git a/java/src/game/packet/CPacketAction.java b/java/src/game/packet/CPacketAction.java index 171e7b1..34b6229 100755 --- a/java/src/game/packet/CPacketAction.java +++ b/java/src/game/packet/CPacketAction.java @@ -4,9 +4,9 @@ import java.io.IOException; import game.network.Packet; import game.network.PacketBuffer; -import game.network.Player; +import game.network.IPlayer; -public class CPacketAction implements Packet +public class CPacketAction implements Packet { private Action action; private int auxData; @@ -38,7 +38,7 @@ public class CPacketAction implements Packet buf.writeVarIntToBuffer(this.auxData); } - public void processPacket(Player handler) + public void processPacket(IPlayer handler) { handler.processAction(this); } diff --git a/java/src/game/packet/CPacketBook.java b/java/src/game/packet/CPacketBook.java index 3dd0e62..1bd02f4 100755 --- a/java/src/game/packet/CPacketBook.java +++ b/java/src/game/packet/CPacketBook.java @@ -4,9 +4,9 @@ import java.io.IOException; import game.network.Packet; import game.network.PacketBuffer; -import game.network.Player; +import game.network.IPlayer; -public class CPacketBook implements Packet +public class CPacketBook implements Packet { private String[] pages; @@ -40,7 +40,7 @@ public class CPacketBook implements Packet } } - public void processPacket(Player handler) + public void processPacket(IPlayer handler) { handler.processBook(this); } diff --git a/java/src/game/packet/CPacketBreak.java b/java/src/game/packet/CPacketBreak.java index 18c95fb..bb4b869 100755 --- a/java/src/game/packet/CPacketBreak.java +++ b/java/src/game/packet/CPacketBreak.java @@ -4,11 +4,11 @@ import java.io.IOException; import game.network.Packet; import game.network.PacketBuffer; -import game.network.Player; +import game.network.IPlayer; import game.world.BlockPos; import game.world.Facing; -public class CPacketBreak implements Packet +public class CPacketBreak implements Packet { private BlockPos position; private Facing facing; @@ -39,7 +39,7 @@ public class CPacketBreak implements Packet buf.writeByte(this.facing.getIndex()); } - public void processPacket(Player handler) + public void processPacket(IPlayer handler) { handler.processBreak(this); } diff --git a/java/src/game/packet/CPacketCheat.java b/java/src/game/packet/CPacketCheat.java index 136f332..3ce4a6e 100755 --- a/java/src/game/packet/CPacketCheat.java +++ b/java/src/game/packet/CPacketCheat.java @@ -5,9 +5,9 @@ import java.io.IOException; import game.item.ItemStack; import game.network.Packet; import game.network.PacketBuffer; -import game.network.Player; +import game.network.IPlayer; -public class CPacketCheat implements Packet +public class CPacketCheat implements Packet { private ItemStack stack; private int slot; @@ -23,7 +23,7 @@ public class CPacketCheat implements Packet this.stack.stackSize = full ? this.stack.getMaxStackSize() : 1; } - public void processPacket(Player handler) + public void processPacket(IPlayer handler) { handler.processCheat(this); } diff --git a/java/src/game/packet/CPacketClick.java b/java/src/game/packet/CPacketClick.java index e622458..8d03eb6 100755 --- a/java/src/game/packet/CPacketClick.java +++ b/java/src/game/packet/CPacketClick.java @@ -5,9 +5,9 @@ import java.io.IOException; import game.item.ItemStack; import game.network.Packet; import game.network.PacketBuffer; -import game.network.Player; +import game.network.IPlayer; -public class CPacketClick implements Packet +public class CPacketClick implements Packet { /** The id of the window which was clicked. 0 for player inventory. */ private int windowId; @@ -41,7 +41,7 @@ public class CPacketClick implements Packet this.mode = mode; } - public void processPacket(Player handler) + public void processPacket(IPlayer handler) { handler.processClick(this); } diff --git a/java/src/game/packet/CPacketComplete.java b/java/src/game/packet/CPacketComplete.java index 4b110ae..f4bcd82 100755 --- a/java/src/game/packet/CPacketComplete.java +++ b/java/src/game/packet/CPacketComplete.java @@ -4,10 +4,10 @@ import java.io.IOException; import game.network.Packet; import game.network.PacketBuffer; -import game.network.Player; +import game.network.IPlayer; import game.world.BlockPos; -public class CPacketComplete implements Packet +public class CPacketComplete implements Packet { private String message; private int entityId; @@ -41,7 +41,7 @@ public class CPacketComplete implements Packet buf.writeBlockPos(this.position); } - public void processPacket(Player handler) + public void processPacket(IPlayer handler) { handler.processComplete(this); } diff --git a/java/src/game/packet/CPacketInput.java b/java/src/game/packet/CPacketInput.java index 413a311..5618427 100755 --- a/java/src/game/packet/CPacketInput.java +++ b/java/src/game/packet/CPacketInput.java @@ -4,9 +4,9 @@ import java.io.IOException; import game.network.Packet; import game.network.PacketBuffer; -import game.network.Player; +import game.network.IPlayer; -public class CPacketInput implements Packet +public class CPacketInput implements Packet { private float strafeSpeed; private float forwardSpeed; @@ -53,7 +53,7 @@ public class CPacketInput implements Packet buf.writeByte(b0); } - public void processPacket(Player handler) + public void processPacket(IPlayer handler) { handler.processInput(this); } diff --git a/java/src/game/packet/CPacketKeepAlive.java b/java/src/game/packet/CPacketKeepAlive.java index 096f558..6cbf08d 100755 --- a/java/src/game/packet/CPacketKeepAlive.java +++ b/java/src/game/packet/CPacketKeepAlive.java @@ -1,8 +1,8 @@ package game.packet; -import game.network.Player; +import game.network.IPlayer; -public class CPacketKeepAlive extends APacketVarInt +public class CPacketKeepAlive extends APacketVarInt { public CPacketKeepAlive() { @@ -13,7 +13,7 @@ public class CPacketKeepAlive extends APacketVarInt super(key); } - public void processPacket(Player handler) + public void processPacket(IPlayer handler) { handler.processKeepAlive(this); } diff --git a/java/src/game/packet/CPacketMessage.java b/java/src/game/packet/CPacketMessage.java index 0bbcd8a..427b22e 100755 --- a/java/src/game/packet/CPacketMessage.java +++ b/java/src/game/packet/CPacketMessage.java @@ -4,9 +4,9 @@ import java.io.IOException; import game.network.Packet; import game.network.PacketBuffer; -import game.network.Player; +import game.network.IPlayer; -public class CPacketMessage implements Packet +public class CPacketMessage implements Packet { private Type type; private String message; @@ -33,7 +33,7 @@ public class CPacketMessage implements Packet buf.writeString(this.message); } - public void processPacket(Player handler) + public void processPacket(IPlayer handler) { handler.processMessage(this); } @@ -49,10 +49,10 @@ public class CPacketMessage implements Packet } public static enum Type { - COMMAND(Player.MAX_CMD_LENGTH), - CHAT(Player.MAX_CMD_LENGTH), - DISPLAY(Player.MAX_NICK_LENGTH), - INFO(Player.MAX_INFO_LENGTH); + COMMAND(IPlayer.MAX_CMD_LENGTH), + CHAT(IPlayer.MAX_CMD_LENGTH), + DISPLAY(IPlayer.MAX_NICK_LENGTH), + INFO(IPlayer.MAX_INFO_LENGTH); // , ITEM(30); private final int length; diff --git a/java/src/game/packet/CPacketPlace.java b/java/src/game/packet/CPacketPlace.java index a17a8f1..8dd4e11 100755 --- a/java/src/game/packet/CPacketPlace.java +++ b/java/src/game/packet/CPacketPlace.java @@ -5,10 +5,10 @@ import java.io.IOException; import game.item.ItemStack; import game.network.Packet; import game.network.PacketBuffer; -import game.network.Player; +import game.network.IPlayer; import game.world.BlockPos; -public class CPacketPlace implements Packet +public class CPacketPlace implements Packet { private static final BlockPos DUMMY_POS = new BlockPos(-1, -1, -1); @@ -58,7 +58,7 @@ public class CPacketPlace implements Packet buf.writeByte((int)(this.facingZ * 16.0F)); } - public void processPacket(Player handler) + public void processPacket(IPlayer handler) { handler.processPlace(this); } diff --git a/java/src/game/packet/CPacketPlayer.java b/java/src/game/packet/CPacketPlayer.java index dfa6fd7..6298845 100755 --- a/java/src/game/packet/CPacketPlayer.java +++ b/java/src/game/packet/CPacketPlayer.java @@ -4,9 +4,9 @@ import java.io.IOException; import game.network.Packet; import game.network.PacketBuffer; -import game.network.Player; +import game.network.IPlayer; -public class CPacketPlayer implements Packet +public class CPacketPlayer implements Packet { protected double x; protected double y; @@ -26,7 +26,7 @@ public class CPacketPlayer implements Packet this.onGround = isOnGround; } - public void processPacket(Player handler) + public void processPacket(IPlayer handler) { handler.processPlayer(this); } diff --git a/java/src/game/packet/CPacketSign.java b/java/src/game/packet/CPacketSign.java index e905fba..dd60ed6 100755 --- a/java/src/game/packet/CPacketSign.java +++ b/java/src/game/packet/CPacketSign.java @@ -4,10 +4,10 @@ import java.io.IOException; import game.network.Packet; import game.network.PacketBuffer; -import game.network.Player; +import game.network.IPlayer; import game.world.BlockPos; -public class CPacketSign implements Packet +public class CPacketSign implements Packet { private BlockPos pos; private String[] lines; @@ -48,7 +48,7 @@ public class CPacketSign implements Packet } } - public void processPacket(Player handler) + public void processPacket(IPlayer handler) { handler.processSign(this); } diff --git a/java/src/game/packet/CPacketSkin.java b/java/src/game/packet/CPacketSkin.java index 25f69c5..b20c00e 100755 --- a/java/src/game/packet/CPacketSkin.java +++ b/java/src/game/packet/CPacketSkin.java @@ -7,9 +7,9 @@ import client.renderer.texture.EntityTexManager; import game.init.SpeciesRegistry.ModelType; import game.network.Packet; import game.network.PacketBuffer; -import game.network.Player; +import game.network.IPlayer; -public class CPacketSkin implements Packet { +public class CPacketSkin implements Packet { private byte[] texture; private String character; @@ -58,7 +58,7 @@ public class CPacketSkin implements Packet { buf.writeByteArray(this.texture); } - public void processPacket(Player handler) { + public void processPacket(IPlayer handler) { handler.processSkin(this); } } diff --git a/java/src/game/packet/HPacketHandshake.java b/java/src/game/packet/HPacketHandshake.java index 1d4fb5b..36a3994 100755 --- a/java/src/game/packet/HPacketHandshake.java +++ b/java/src/game/packet/HPacketHandshake.java @@ -2,11 +2,11 @@ package game.packet; import java.io.IOException; -import game.network.HandshakeHandler; +import game.network.IHandshakeHandler; import game.network.Packet; import game.network.PacketBuffer; -public class HPacketHandshake implements Packet { +public class HPacketHandshake implements Packet { private int protocol; public HPacketHandshake() { @@ -30,7 +30,7 @@ public class HPacketHandshake implements Packet { buf.writeVarIntToBuffer(this.protocol); } - public void processPacket(HandshakeHandler handler) { + public void processPacket(IHandshakeHandler handler) { handler.processHandshake(this); } diff --git a/java/src/game/packet/LPacketPasswordResponse.java b/java/src/game/packet/LPacketPasswordResponse.java index be6eaae..f2735b4 100755 --- a/java/src/game/packet/LPacketPasswordResponse.java +++ b/java/src/game/packet/LPacketPasswordResponse.java @@ -2,12 +2,12 @@ package game.packet; import java.io.IOException; -import game.network.LoginHandler; +import game.network.IPlayer; +import game.network.ILoginHandler; import game.network.Packet; import game.network.PacketBuffer; -import game.network.Player; -public class LPacketPasswordResponse implements Packet +public class LPacketPasswordResponse implements Packet { private String user; private String access; @@ -29,9 +29,9 @@ public class LPacketPasswordResponse implements Packet */ public void readPacketData(PacketBuffer buf) throws IOException { - this.user = buf.readStringFromBuffer(Player.MAX_USER_LENGTH); - this.access = buf.readStringFromBuffer(Player.MAX_PASS_LENGTH); - this.password = buf.readStringFromBuffer(Player.MAX_PASS_LENGTH); + this.user = buf.readStringFromBuffer(IPlayer.MAX_USER_LENGTH); + this.access = buf.readStringFromBuffer(IPlayer.MAX_PASS_LENGTH); + this.password = buf.readStringFromBuffer(IPlayer.MAX_PASS_LENGTH); } /** @@ -47,7 +47,7 @@ public class LPacketPasswordResponse implements Packet /** * Passes this Packet on to the NetHandler for processing. */ - public void processPacket(LoginHandler handler) + public void processPacket(ILoginHandler handler) { handler.processPasswordResponse(this); } diff --git a/java/src/game/packet/RPacketDisconnect.java b/java/src/game/packet/RPacketDisconnect.java index 1aee0bd..a81019b 100755 --- a/java/src/game/packet/RPacketDisconnect.java +++ b/java/src/game/packet/RPacketDisconnect.java @@ -2,11 +2,11 @@ package game.packet; import java.io.IOException; -import game.network.ClientLoginHandler; +import game.network.IClientLoginHandler; import game.network.Packet; import game.network.PacketBuffer; -public class RPacketDisconnect implements Packet +public class RPacketDisconnect implements Packet { private String reason; @@ -38,7 +38,7 @@ public class RPacketDisconnect implements Packet /** * Passes this Packet on to the NetHandler for processing. */ - public void processPacket(ClientLoginHandler handler) + public void processPacket(IClientLoginHandler handler) { handler.handleDisconnect(this); } diff --git a/java/src/game/packet/RPacketEnableCompression.java b/java/src/game/packet/RPacketEnableCompression.java index f338992..4fed689 100755 --- a/java/src/game/packet/RPacketEnableCompression.java +++ b/java/src/game/packet/RPacketEnableCompression.java @@ -1,8 +1,8 @@ package game.packet; -import game.network.ClientLoginHandler; +import game.network.IClientLoginHandler; -public class RPacketEnableCompression extends APacketVarInt +public class RPacketEnableCompression extends APacketVarInt { public RPacketEnableCompression() { @@ -13,7 +13,7 @@ public class RPacketEnableCompression extends APacketVarInt super(comp); } - public void processPacket(ClientLoginHandler handler) + public void processPacket(IClientLoginHandler handler) { handler.handleEnableCompression(this); } diff --git a/java/src/game/packet/RPacketLoginSuccess.java b/java/src/game/packet/RPacketLoginSuccess.java index 047cffc..4bff216 100755 --- a/java/src/game/packet/RPacketLoginSuccess.java +++ b/java/src/game/packet/RPacketLoginSuccess.java @@ -1,10 +1,10 @@ package game.packet; -import game.network.ClientLoginHandler; +import game.network.IClientLoginHandler; -public class RPacketLoginSuccess extends APacketEmpty +public class RPacketLoginSuccess extends APacketEmpty { - public void processPacket(ClientLoginHandler handler) + public void processPacket(IClientLoginHandler handler) { handler.handleLoginSuccess(this); } diff --git a/java/src/game/packet/S14PacketEntity.java b/java/src/game/packet/S14PacketEntity.java index 9c42bc2..e720185 100755 --- a/java/src/game/packet/S14PacketEntity.java +++ b/java/src/game/packet/S14PacketEntity.java @@ -3,12 +3,12 @@ package game.packet; import java.io.IOException; import game.entity.Entity; -import game.network.ClientPlayer; +import game.network.IClientPlayer; import game.network.Packet; import game.network.PacketBuffer; import game.world.World; -public class S14PacketEntity implements Packet +public class S14PacketEntity implements Packet { protected int entityId; protected byte posX; @@ -47,7 +47,7 @@ public class S14PacketEntity implements Packet /** * Passes this Packet on to the NetHandler for processing. */ - public void processPacket(ClientPlayer handler) + public void processPacket(IClientPlayer handler) { handler.handleEntityMovement(this); } diff --git a/java/src/game/packet/S18PacketEntityTeleport.java b/java/src/game/packet/S18PacketEntityTeleport.java index d5e26f0..955fd66 100755 --- a/java/src/game/packet/S18PacketEntityTeleport.java +++ b/java/src/game/packet/S18PacketEntityTeleport.java @@ -3,12 +3,12 @@ package game.packet; import java.io.IOException; import game.entity.Entity; -import game.network.ClientPlayer; +import game.network.IClientPlayer; import game.network.Packet; import game.network.PacketBuffer; import game.util.ExtMath; -public class S18PacketEntityTeleport implements Packet +public class S18PacketEntityTeleport implements Packet { private int entityId; private int posX; @@ -75,7 +75,7 @@ public class S18PacketEntityTeleport implements Packet /** * Passes this Packet on to the NetHandler for processing. */ - public void processPacket(ClientPlayer handler) + public void processPacket(IClientPlayer handler) { handler.handleEntityTeleport(this); } diff --git a/java/src/game/packet/S19PacketEntityHeadLook.java b/java/src/game/packet/S19PacketEntityHeadLook.java index d4c012e..97f4853 100755 --- a/java/src/game/packet/S19PacketEntityHeadLook.java +++ b/java/src/game/packet/S19PacketEntityHeadLook.java @@ -3,12 +3,12 @@ package game.packet; import java.io.IOException; import game.entity.Entity; -import game.network.ClientPlayer; +import game.network.IClientPlayer; import game.network.Packet; import game.network.PacketBuffer; import game.world.World; -public class S19PacketEntityHeadLook implements Packet +public class S19PacketEntityHeadLook implements Packet { private int entityId; private byte yaw; @@ -44,7 +44,7 @@ public class S19PacketEntityHeadLook implements Packet /** * Passes this Packet on to the NetHandler for processing. */ - public void processPacket(ClientPlayer handler) + public void processPacket(IClientPlayer handler) { handler.handleEntityHeadLook(this); } diff --git a/java/src/game/packet/S1APacketEntityStatus.java b/java/src/game/packet/S1APacketEntityStatus.java index 2771749..4fd3017 100755 --- a/java/src/game/packet/S1APacketEntityStatus.java +++ b/java/src/game/packet/S1APacketEntityStatus.java @@ -3,12 +3,12 @@ package game.packet; import java.io.IOException; import game.entity.Entity; -import game.network.ClientPlayer; +import game.network.IClientPlayer; import game.network.Packet; import game.network.PacketBuffer; import game.world.World; -public class S1APacketEntityStatus implements Packet +public class S1APacketEntityStatus implements Packet { private int entityId; private byte logicOpcode; @@ -44,7 +44,7 @@ public class S1APacketEntityStatus implements Packet /** * Passes this Packet on to the NetHandler for processing. */ - public void processPacket(ClientPlayer handler) + public void processPacket(IClientPlayer handler) { handler.handleEntityStatus(this); } diff --git a/java/src/game/packet/S1BPacketEntityAttach.java b/java/src/game/packet/S1BPacketEntityAttach.java index 7b30497..a0e6c6b 100755 --- a/java/src/game/packet/S1BPacketEntityAttach.java +++ b/java/src/game/packet/S1BPacketEntityAttach.java @@ -3,11 +3,11 @@ package game.packet; import java.io.IOException; import game.entity.Entity; -import game.network.ClientPlayer; +import game.network.IClientPlayer; import game.network.Packet; import game.network.PacketBuffer; -public class S1BPacketEntityAttach implements Packet +public class S1BPacketEntityAttach implements Packet { private int leash; private int entityId; @@ -47,7 +47,7 @@ public class S1BPacketEntityAttach implements Packet /** * Passes this Packet on to the NetHandler for processing. */ - public void processPacket(ClientPlayer handler) + public void processPacket(IClientPlayer handler) { handler.handleEntityAttach(this); } diff --git a/java/src/game/packet/S1CPacketEntityMetadata.java b/java/src/game/packet/S1CPacketEntityMetadata.java index 9662fca..3eda517 100755 --- a/java/src/game/packet/S1CPacketEntityMetadata.java +++ b/java/src/game/packet/S1CPacketEntityMetadata.java @@ -4,11 +4,11 @@ import java.io.IOException; import java.util.List; import game.entity.DataWatcher; -import game.network.ClientPlayer; +import game.network.IClientPlayer; import game.network.Packet; import game.network.PacketBuffer; -public class S1CPacketEntityMetadata implements Packet +public class S1CPacketEntityMetadata implements Packet { private int entityId; private List field_149378_b; @@ -52,7 +52,7 @@ public class S1CPacketEntityMetadata implements Packet /** * Passes this Packet on to the NetHandler for processing. */ - public void processPacket(ClientPlayer handler) + public void processPacket(IClientPlayer handler) { handler.handleEntityMetadata(this); } diff --git a/java/src/game/packet/S1DPacketEntityEffect.java b/java/src/game/packet/S1DPacketEntityEffect.java index 418d84b..661aa94 100755 --- a/java/src/game/packet/S1DPacketEntityEffect.java +++ b/java/src/game/packet/S1DPacketEntityEffect.java @@ -2,13 +2,13 @@ package game.packet; import java.io.IOException; -import game.network.ClientPlayer; +import game.network.IClientPlayer; import game.network.Packet; import game.network.PacketBuffer; import game.potion.Potion; import game.potion.PotionEffect; -public class S1DPacketEntityEffect implements Packet +public class S1DPacketEntityEffect implements Packet { private int entityId; private Potion effectId; @@ -69,7 +69,7 @@ public class S1DPacketEntityEffect implements Packet /** * Passes this Packet on to the NetHandler for processing. */ - public void processPacket(ClientPlayer handler) + public void processPacket(IClientPlayer handler) { handler.handleEntityEffect(this); } diff --git a/java/src/game/packet/S1EPacketRemoveEntityEffect.java b/java/src/game/packet/S1EPacketRemoveEntityEffect.java index 76af411..a7872cf 100755 --- a/java/src/game/packet/S1EPacketRemoveEntityEffect.java +++ b/java/src/game/packet/S1EPacketRemoveEntityEffect.java @@ -2,13 +2,13 @@ package game.packet; import java.io.IOException; -import game.network.ClientPlayer; +import game.network.IClientPlayer; import game.network.Packet; import game.network.PacketBuffer; import game.potion.Potion; import game.potion.PotionEffect; -public class S1EPacketRemoveEntityEffect implements Packet +public class S1EPacketRemoveEntityEffect implements Packet { private int entityId; private Potion effectId; @@ -44,7 +44,7 @@ public class S1EPacketRemoveEntityEffect implements Packet /** * Passes this Packet on to the NetHandler for processing. */ - public void processPacket(ClientPlayer handler) + public void processPacket(IClientPlayer handler) { handler.handleRemoveEntityEffect(this); } diff --git a/java/src/game/packet/S20PacketEntityProperties.java b/java/src/game/packet/S20PacketEntityProperties.java index 5d6e690..6fa51f3 100755 --- a/java/src/game/packet/S20PacketEntityProperties.java +++ b/java/src/game/packet/S20PacketEntityProperties.java @@ -7,11 +7,11 @@ import java.util.List; import game.collect.Lists; import game.entity.attributes.AttributeInstance; import game.entity.attributes.AttributeModifier; -import game.network.ClientPlayer; +import game.network.IClientPlayer; import game.network.Packet; import game.network.PacketBuffer; -public class S20PacketEntityProperties implements Packet +public class S20PacketEntityProperties implements Packet { private int entityId; private final List field_149444_b = Lists.newArrayList(); @@ -81,7 +81,7 @@ public class S20PacketEntityProperties implements Packet /** * Passes this Packet on to the NetHandler for processing. */ - public void processPacket(ClientPlayer handler) + public void processPacket(IClientPlayer handler) { handler.handleEntityProperties(this); } diff --git a/java/src/game/packet/S27PacketExplosion.java b/java/src/game/packet/S27PacketExplosion.java index 740400a..24aa5ee 100755 --- a/java/src/game/packet/S27PacketExplosion.java +++ b/java/src/game/packet/S27PacketExplosion.java @@ -5,13 +5,13 @@ import java.util.ArrayList; import java.util.List; import game.collect.Lists; -import game.network.ClientPlayer; +import game.network.IClientPlayer; import game.network.Packet; import game.network.PacketBuffer; import game.world.BlockPos; import game.world.Vec3; -public class S27PacketExplosion implements Packet +public class S27PacketExplosion implements Packet { private double posX; private double posY; @@ -106,7 +106,7 @@ public class S27PacketExplosion implements Packet /** * Passes this Packet on to the NetHandler for processing. */ - public void processPacket(ClientPlayer handler) + public void processPacket(IClientPlayer handler) { handler.handleExplosion(this); } diff --git a/java/src/game/packet/S28PacketEffect.java b/java/src/game/packet/S28PacketEffect.java index 263e148..a64be06 100755 --- a/java/src/game/packet/S28PacketEffect.java +++ b/java/src/game/packet/S28PacketEffect.java @@ -2,12 +2,12 @@ package game.packet; import java.io.IOException; -import game.network.ClientPlayer; +import game.network.IClientPlayer; import game.network.Packet; import game.network.PacketBuffer; import game.world.BlockPos; -public class S28PacketEffect implements Packet { +public class S28PacketEffect implements Packet { private int soundType; private BlockPos soundPos; private int soundData; @@ -33,7 +33,7 @@ public class S28PacketEffect implements Packet { buf.writeInt(this.soundData); } - public void processPacket(ClientPlayer handler) { + public void processPacket(IClientPlayer handler) { handler.handleEffect(this); } diff --git a/java/src/game/packet/S29PacketSoundEffect.java b/java/src/game/packet/S29PacketSoundEffect.java index e80a9af..e0581b6 100755 --- a/java/src/game/packet/S29PacketSoundEffect.java +++ b/java/src/game/packet/S29PacketSoundEffect.java @@ -3,11 +3,11 @@ package game.packet; import java.io.IOException; import game.init.SoundEvent; -import game.network.ClientPlayer; +import game.network.IClientPlayer; import game.network.Packet; import game.network.PacketBuffer; -public class S29PacketSoundEffect implements Packet +public class S29PacketSoundEffect implements Packet { private SoundEvent sound; private int posX; @@ -86,7 +86,7 @@ public class S29PacketSoundEffect implements Packet return this.soundVolume; } - public void processPacket(ClientPlayer handler) + public void processPacket(IClientPlayer handler) { handler.handleSoundEffect(this); } diff --git a/java/src/game/packet/S2APacketParticles.java b/java/src/game/packet/S2APacketParticles.java index b2692fd..198ecf8 100755 --- a/java/src/game/packet/S2APacketParticles.java +++ b/java/src/game/packet/S2APacketParticles.java @@ -3,11 +3,11 @@ package game.packet; import java.io.IOException; import game.model.ParticleType; -import game.network.ClientPlayer; +import game.network.IClientPlayer; import game.network.Packet; import game.network.PacketBuffer; -public class S2APacketParticles implements Packet +public class S2APacketParticles implements Packet { private ParticleType particleType; private float xCoord; @@ -183,7 +183,7 @@ public class S2APacketParticles implements Packet /** * Passes this Packet on to the NetHandler for processing. */ - public void processPacket(ClientPlayer handler) + public void processPacket(IClientPlayer handler) { handler.handleParticles(this); } diff --git a/java/src/game/packet/S2BPacketChangeGameState.java b/java/src/game/packet/S2BPacketChangeGameState.java index 3a29de1..4c9272c 100755 --- a/java/src/game/packet/S2BPacketChangeGameState.java +++ b/java/src/game/packet/S2BPacketChangeGameState.java @@ -2,12 +2,12 @@ package game.packet; import java.io.IOException; -import game.network.ClientPlayer; +import game.network.IClientPlayer; import game.network.Packet; import game.network.PacketBuffer; import game.util.ExtMath; -public class S2BPacketChangeGameState implements Packet +public class S2BPacketChangeGameState implements Packet { private Action action; private int param; @@ -44,7 +44,7 @@ public class S2BPacketChangeGameState implements Packet buf.writeVarIntToBuffer(this.param); } - public void processPacket(ClientPlayer handler) + public void processPacket(IClientPlayer handler) { handler.handleChangeGameState(this); } diff --git a/java/src/game/packet/S2CPacketSpawnGlobalEntity.java b/java/src/game/packet/S2CPacketSpawnGlobalEntity.java index 74bdb84..df86f15 100755 --- a/java/src/game/packet/S2CPacketSpawnGlobalEntity.java +++ b/java/src/game/packet/S2CPacketSpawnGlobalEntity.java @@ -3,12 +3,12 @@ package game.packet; import java.io.IOException; import game.entity.Entity; -import game.network.ClientPlayer; +import game.network.IClientPlayer; import game.network.Packet; import game.network.PacketBuffer; import game.util.ExtMath; -public class S2CPacketSpawnGlobalEntity implements Packet +public class S2CPacketSpawnGlobalEntity implements Packet { private int entityId; private int x; @@ -60,7 +60,7 @@ public class S2CPacketSpawnGlobalEntity implements Packet /** * Passes this Packet on to the NetHandler for processing. */ - public void processPacket(ClientPlayer handler) + public void processPacket(IClientPlayer handler) { handler.handleSpawnGlobalEntity(this); } diff --git a/java/src/game/packet/S2DPacketOpenWindow.java b/java/src/game/packet/S2DPacketOpenWindow.java index 7ac73fc..c1f7c70 100755 --- a/java/src/game/packet/S2DPacketOpenWindow.java +++ b/java/src/game/packet/S2DPacketOpenWindow.java @@ -2,12 +2,12 @@ package game.packet; import java.io.IOException; -import game.network.ClientPlayer; +import game.network.IClientPlayer; import game.network.Packet; import game.network.PacketBuffer; import game.world.BlockPos; -public class S2DPacketOpenWindow implements Packet +public class S2DPacketOpenWindow implements Packet { private int windowId; private String inventoryType; @@ -48,7 +48,7 @@ public class S2DPacketOpenWindow implements Packet /** * Passes this Packet on to the NetHandler for processing. */ - public void processPacket(ClientPlayer handler) + public void processPacket(IClientPlayer handler) { handler.handleOpenWindow(this); } diff --git a/java/src/game/packet/S2EPacketCloseWindow.java b/java/src/game/packet/S2EPacketCloseWindow.java index fedeedd..a6652cc 100755 --- a/java/src/game/packet/S2EPacketCloseWindow.java +++ b/java/src/game/packet/S2EPacketCloseWindow.java @@ -2,11 +2,11 @@ package game.packet; import java.io.IOException; -import game.network.ClientPlayer; +import game.network.IClientPlayer; import game.network.Packet; import game.network.PacketBuffer; -public class S2EPacketCloseWindow implements Packet +public class S2EPacketCloseWindow implements Packet { private int windowId; @@ -22,7 +22,7 @@ public class S2EPacketCloseWindow implements Packet /** * Passes this Packet on to the NetHandler for processing. */ - public void processPacket(ClientPlayer handler) + public void processPacket(IClientPlayer handler) { handler.handleCloseWindow(this); } diff --git a/java/src/game/packet/S2FPacketSetSlot.java b/java/src/game/packet/S2FPacketSetSlot.java index ca30800..6b307f1 100755 --- a/java/src/game/packet/S2FPacketSetSlot.java +++ b/java/src/game/packet/S2FPacketSetSlot.java @@ -3,11 +3,11 @@ package game.packet; import java.io.IOException; import game.item.ItemStack; -import game.network.ClientPlayer; +import game.network.IClientPlayer; import game.network.Packet; import game.network.PacketBuffer; -public class S2FPacketSetSlot implements Packet +public class S2FPacketSetSlot implements Packet { private int windowId; private int slot; @@ -27,7 +27,7 @@ public class S2FPacketSetSlot implements Packet /** * Passes this Packet on to the NetHandler for processing. */ - public void processPacket(ClientPlayer handler) + public void processPacket(IClientPlayer handler) { handler.handleSetSlot(this); } diff --git a/java/src/game/packet/S30PacketWindowItems.java b/java/src/game/packet/S30PacketWindowItems.java index a0aca09..a7dc2c1 100755 --- a/java/src/game/packet/S30PacketWindowItems.java +++ b/java/src/game/packet/S30PacketWindowItems.java @@ -4,11 +4,11 @@ import java.io.IOException; import java.util.List; import game.item.ItemStack; -import game.network.ClientPlayer; +import game.network.IClientPlayer; import game.network.Packet; import game.network.PacketBuffer; -public class S30PacketWindowItems implements Packet +public class S30PacketWindowItems implements Packet { private int windowId; private ItemStack[] itemStacks; @@ -61,7 +61,7 @@ public class S30PacketWindowItems implements Packet /** * Passes this Packet on to the NetHandler for processing. */ - public void processPacket(ClientPlayer handler) + public void processPacket(IClientPlayer handler) { handler.handleWindowItems(this); } diff --git a/java/src/game/packet/S31PacketWindowProperty.java b/java/src/game/packet/S31PacketWindowProperty.java index 5d0d0a1..50b5ed1 100755 --- a/java/src/game/packet/S31PacketWindowProperty.java +++ b/java/src/game/packet/S31PacketWindowProperty.java @@ -2,11 +2,11 @@ package game.packet; import java.io.IOException; -import game.network.ClientPlayer; +import game.network.IClientPlayer; import game.network.Packet; import game.network.PacketBuffer; -public class S31PacketWindowProperty implements Packet +public class S31PacketWindowProperty implements Packet { private int windowId; private int varIndex; @@ -26,7 +26,7 @@ public class S31PacketWindowProperty implements Packet /** * Passes this Packet on to the NetHandler for processing. */ - public void processPacket(ClientPlayer handler) + public void processPacket(IClientPlayer handler) { handler.handleWindowProperty(this); } diff --git a/java/src/game/packet/S32PacketConfirmTransaction.java b/java/src/game/packet/S32PacketConfirmTransaction.java index a639e29..f323a67 100755 --- a/java/src/game/packet/S32PacketConfirmTransaction.java +++ b/java/src/game/packet/S32PacketConfirmTransaction.java @@ -2,11 +2,11 @@ package game.packet; import java.io.IOException; -import game.network.ClientPlayer; +import game.network.IClientPlayer; import game.network.Packet; import game.network.PacketBuffer; -public class S32PacketConfirmTransaction implements Packet +public class S32PacketConfirmTransaction implements Packet { private int windowId; private short actionNumber; @@ -26,7 +26,7 @@ public class S32PacketConfirmTransaction implements Packet /** * Passes this Packet on to the NetHandler for processing. */ - public void processPacket(ClientPlayer handler) + public void processPacket(IClientPlayer handler) { handler.handleConfirmTransaction(this); } diff --git a/java/src/game/packet/S33PacketUpdateSign.java b/java/src/game/packet/S33PacketUpdateSign.java index cd49fb9..798140b 100755 --- a/java/src/game/packet/S33PacketUpdateSign.java +++ b/java/src/game/packet/S33PacketUpdateSign.java @@ -2,13 +2,13 @@ package game.packet; import java.io.IOException; -import game.network.ClientPlayer; +import game.network.IClientPlayer; import game.network.Packet; import game.network.PacketBuffer; import game.world.BlockPos; import game.world.World; -public class S33PacketUpdateSign implements Packet +public class S33PacketUpdateSign implements Packet { private World world; private BlockPos blockPos; @@ -62,7 +62,7 @@ public class S33PacketUpdateSign implements Packet /** * Passes this Packet on to the NetHandler for processing. */ - public void processPacket(ClientPlayer handler) + public void processPacket(IClientPlayer handler) { handler.handleUpdateSign(this); } diff --git a/java/src/game/packet/S35PacketUpdateTileEntity.java b/java/src/game/packet/S35PacketUpdateTileEntity.java index f0237ad..eb8e079 100755 --- a/java/src/game/packet/S35PacketUpdateTileEntity.java +++ b/java/src/game/packet/S35PacketUpdateTileEntity.java @@ -4,13 +4,13 @@ import java.io.IOException; import game.init.TileRegistry; import game.nbt.NBTTagCompound; -import game.network.ClientPlayer; +import game.network.IClientPlayer; import game.network.Packet; import game.network.PacketBuffer; import game.tileentity.TileEntity; import game.world.BlockPos; -public class S35PacketUpdateTileEntity implements Packet +public class S35PacketUpdateTileEntity implements Packet { private BlockPos blockPos; private int type; @@ -50,7 +50,7 @@ public class S35PacketUpdateTileEntity implements Packet /** * Passes this Packet on to the NetHandler for processing. */ - public void processPacket(ClientPlayer handler) + public void processPacket(IClientPlayer handler) { handler.handleUpdateTileEntity(this); } diff --git a/java/src/game/packet/S36PacketSignEditorOpen.java b/java/src/game/packet/S36PacketSignEditorOpen.java index 70d0560..6d5b2d4 100755 --- a/java/src/game/packet/S36PacketSignEditorOpen.java +++ b/java/src/game/packet/S36PacketSignEditorOpen.java @@ -2,12 +2,12 @@ package game.packet; import java.io.IOException; -import game.network.ClientPlayer; +import game.network.IClientPlayer; import game.network.Packet; import game.network.PacketBuffer; import game.world.BlockPos; -public class S36PacketSignEditorOpen implements Packet +public class S36PacketSignEditorOpen implements Packet { private BlockPos signPosition; @@ -23,7 +23,7 @@ public class S36PacketSignEditorOpen implements Packet /** * Passes this Packet on to the NetHandler for processing. */ - public void processPacket(ClientPlayer handler) + public void processPacket(IClientPlayer handler) { handler.handleSignEditorOpen(this); } diff --git a/java/src/game/packet/S38PacketPlayerListItem.java b/java/src/game/packet/S38PacketPlayerListItem.java index f05f4ba..afcde9f 100755 --- a/java/src/game/packet/S38PacketPlayerListItem.java +++ b/java/src/game/packet/S38PacketPlayerListItem.java @@ -6,26 +6,26 @@ import java.util.Map; import java.util.Map.Entry; import game.collect.Maps; -import game.network.ClientPlayer; +import game.network.IClientPlayer; import game.network.Packet; import game.network.PacketBuffer; -import game.network.Player; +import game.network.IPlayer; -public class S38PacketPlayerListItem implements Packet { +public class S38PacketPlayerListItem implements Packet { private final Map players = Maps.newHashMap(); public S38PacketPlayerListItem() { } - public S38PacketPlayerListItem(boolean remove, Player... conns) { - for(Player conn : conns) { + public S38PacketPlayerListItem(boolean remove, IPlayer... conns) { + for(IPlayer conn : conns) { this.players.put(conn.getUser(), remove ? -1 : conn.getLatency()); } } - public S38PacketPlayerListItem(Iterable conns) { - for(Player conn : conns) { - this.players.put(conn.getUser(), conn.getLatency()); + public S38PacketPlayerListItem(Iterable conns) { + for(IPlayer conn : conns) { + this.players.put(((IPlayer)conn).getUser(), ((IPlayer)conn).getLatency()); } } @@ -44,7 +44,7 @@ public class S38PacketPlayerListItem implements Packet { } } - public void processPacket(ClientPlayer handler) { + public void processPacket(IClientPlayer handler) { handler.handlePlayerListItem(this); } diff --git a/java/src/game/packet/S39PacketPlayerAbilities.java b/java/src/game/packet/S39PacketPlayerAbilities.java index 1dae15f..740aa08 100755 --- a/java/src/game/packet/S39PacketPlayerAbilities.java +++ b/java/src/game/packet/S39PacketPlayerAbilities.java @@ -3,11 +3,11 @@ package game.packet; import java.io.IOException; import game.entity.npc.EntityNPC; -import game.network.ClientPlayer; +import game.network.IClientPlayer; import game.network.Packet; import game.network.PacketBuffer; -public class S39PacketPlayerAbilities implements Packet { +public class S39PacketPlayerAbilities implements Packet { private boolean flying; private boolean noClip; @@ -39,7 +39,7 @@ public class S39PacketPlayerAbilities implements Packet { buf.writeByte(bt); } - public void processPacket(ClientPlayer handler) { + public void processPacket(IClientPlayer handler) { handler.handlePlayerAbilities(this); } diff --git a/java/src/game/packet/S3APacketTabComplete.java b/java/src/game/packet/S3APacketTabComplete.java index 09a7ebc..680df6a 100755 --- a/java/src/game/packet/S3APacketTabComplete.java +++ b/java/src/game/packet/S3APacketTabComplete.java @@ -2,11 +2,11 @@ package game.packet; import java.io.IOException; -import game.network.ClientPlayer; +import game.network.IClientPlayer; import game.network.Packet; import game.network.PacketBuffer; -public class S3APacketTabComplete implements Packet +public class S3APacketTabComplete implements Packet { private String[] matches; @@ -48,7 +48,7 @@ public class S3APacketTabComplete implements Packet /** * Passes this Packet on to the NetHandler for processing. */ - public void processPacket(ClientPlayer handler) + public void processPacket(IClientPlayer handler) { handler.handleTabComplete(this); } diff --git a/java/src/game/packet/S43PacketUpdateEntityNBT.java b/java/src/game/packet/S43PacketUpdateEntityNBT.java index d069803..1982acc 100755 --- a/java/src/game/packet/S43PacketUpdateEntityNBT.java +++ b/java/src/game/packet/S43PacketUpdateEntityNBT.java @@ -4,12 +4,12 @@ import java.io.IOException; import game.entity.Entity; import game.nbt.NBTTagCompound; -import game.network.ClientPlayer; +import game.network.IClientPlayer; import game.network.Packet; import game.network.PacketBuffer; import game.world.World; -public class S43PacketUpdateEntityNBT implements Packet +public class S43PacketUpdateEntityNBT implements Packet { private int entityId; private NBTTagCompound tagCompound; @@ -45,7 +45,7 @@ public class S43PacketUpdateEntityNBT implements Packet /** * Passes this Packet on to the NetHandler for processing. */ - public void processPacket(ClientPlayer handler) + public void processPacket(IClientPlayer handler) { handler.handleEntityNBT(this); } diff --git a/java/src/game/packet/SPacketAnimation.java b/java/src/game/packet/SPacketAnimation.java index 0593b16..f04fa3f 100755 --- a/java/src/game/packet/SPacketAnimation.java +++ b/java/src/game/packet/SPacketAnimation.java @@ -3,11 +3,11 @@ package game.packet; import java.io.IOException; import game.entity.Entity; -import game.network.ClientPlayer; +import game.network.IClientPlayer; import game.network.Packet; import game.network.PacketBuffer; -public class SPacketAnimation implements Packet +public class SPacketAnimation implements Packet { private int entityId; private int type; @@ -45,7 +45,7 @@ public class SPacketAnimation implements Packet // buf.writeVarIntToBuffer(this.par); } - public void processPacket(ClientPlayer handler) + public void processPacket(IClientPlayer handler) { handler.handleAnimation(this); } diff --git a/java/src/game/packet/SPacketBiomes.java b/java/src/game/packet/SPacketBiomes.java index 5edc5d6..9af8bdf 100755 --- a/java/src/game/packet/SPacketBiomes.java +++ b/java/src/game/packet/SPacketBiomes.java @@ -2,11 +2,11 @@ package game.packet; import java.io.IOException; -import game.network.ClientPlayer; +import game.network.IClientPlayer; import game.network.Packet; import game.network.PacketBuffer; -public class SPacketBiomes implements Packet { +public class SPacketBiomes implements Packet { private int chunkX; private int chunkZ; private byte[] biomes; @@ -32,7 +32,7 @@ public class SPacketBiomes implements Packet { buf.writeBytes(this.biomes); } - public void processPacket(ClientPlayer handler) { + public void processPacket(IClientPlayer handler) { handler.handleBiomes(this); } diff --git a/java/src/game/packet/SPacketBlockAction.java b/java/src/game/packet/SPacketBlockAction.java index 3a5bfb8..b20f782 100755 --- a/java/src/game/packet/SPacketBlockAction.java +++ b/java/src/game/packet/SPacketBlockAction.java @@ -4,12 +4,12 @@ import java.io.IOException; import game.block.Block; import game.init.BlockRegistry; -import game.network.ClientPlayer; +import game.network.IClientPlayer; import game.network.Packet; import game.network.PacketBuffer; import game.world.BlockPos; -public class SPacketBlockAction implements Packet +public class SPacketBlockAction implements Packet { private BlockPos blockPosition; private int instrument; @@ -53,7 +53,7 @@ public class SPacketBlockAction implements Packet /** * Passes this Packet on to the NetHandler for processing. */ - public void processPacket(ClientPlayer handler) + public void processPacket(IClientPlayer handler) { handler.handleBlockAction(this); } diff --git a/java/src/game/packet/SPacketBlockBreakAnim.java b/java/src/game/packet/SPacketBlockBreakAnim.java index 13c487f..8621320 100755 --- a/java/src/game/packet/SPacketBlockBreakAnim.java +++ b/java/src/game/packet/SPacketBlockBreakAnim.java @@ -2,12 +2,12 @@ package game.packet; import java.io.IOException; -import game.network.ClientPlayer; +import game.network.IClientPlayer; import game.network.Packet; import game.network.PacketBuffer; import game.world.BlockPos; -public class SPacketBlockBreakAnim implements Packet +public class SPacketBlockBreakAnim implements Packet { private int breakerId; private BlockPos position; @@ -47,7 +47,7 @@ public class SPacketBlockBreakAnim implements Packet /** * Passes this Packet on to the NetHandler for processing. */ - public void processPacket(ClientPlayer handler) + public void processPacket(IClientPlayer handler) { handler.handleBlockBreakAnim(this); } diff --git a/java/src/game/packet/SPacketBlockChange.java b/java/src/game/packet/SPacketBlockChange.java index 3924844..801050a 100755 --- a/java/src/game/packet/SPacketBlockChange.java +++ b/java/src/game/packet/SPacketBlockChange.java @@ -3,14 +3,14 @@ package game.packet; import java.io.IOException; import game.init.BlockRegistry; -import game.network.ClientPlayer; +import game.network.IClientPlayer; import game.network.Packet; import game.network.PacketBuffer; import game.world.BlockPos; import game.world.State; import game.world.World; -public class SPacketBlockChange implements Packet +public class SPacketBlockChange implements Packet { private BlockPos blockPosition; private State blockState; @@ -46,7 +46,7 @@ public class SPacketBlockChange implements Packet /** * Passes this Packet on to the NetHandler for processing. */ - public void processPacket(ClientPlayer handler) + public void processPacket(IClientPlayer handler) { handler.handleBlockChange(this); } diff --git a/java/src/game/packet/SPacketCamera.java b/java/src/game/packet/SPacketCamera.java index 8b8c932..a22f016 100755 --- a/java/src/game/packet/SPacketCamera.java +++ b/java/src/game/packet/SPacketCamera.java @@ -3,12 +3,12 @@ package game.packet; import java.io.IOException; import game.entity.Entity; -import game.network.ClientPlayer; +import game.network.IClientPlayer; import game.network.Packet; import game.network.PacketBuffer; import game.world.World; -public class SPacketCamera implements Packet +public class SPacketCamera implements Packet { public int entityId; @@ -31,7 +31,7 @@ public class SPacketCamera implements Packet buf.writeVarIntToBuffer(this.entityId); } - public void processPacket(ClientPlayer handler) + public void processPacket(IClientPlayer handler) { handler.handleCamera(this); } diff --git a/java/src/game/packet/SPacketCharacterList.java b/java/src/game/packet/SPacketCharacterList.java index 58fb869..e9f3c74 100644 --- a/java/src/game/packet/SPacketCharacterList.java +++ b/java/src/game/packet/SPacketCharacterList.java @@ -8,13 +8,13 @@ import java.util.Map.Entry; import game.collect.Maps; import game.entity.npc.Alignment; import game.entity.npc.PlayerCharacter; -import game.network.ClientPlayer; +import game.network.IClientPlayer; +import game.network.IPlayer; import game.network.Packet; import game.network.PacketBuffer; -import game.network.Player; import game.world.BlockPos; -public class SPacketCharacterList implements Packet { +public class SPacketCharacterList implements Packet { private final Map players = Maps.newHashMap(); private int selected; @@ -43,12 +43,12 @@ public class SPacketCharacterList implements Packet { int n = buf.readVarIntFromBuffer(); for(int z = 0; z < n; z++) { int id = buf.readVarIntFromBuffer(); - String name = buf.readStringFromBuffer(Player.MAX_NICK_LENGTH); + String name = buf.readStringFromBuffer(IPlayer.MAX_NICK_LENGTH); if(name.isEmpty()) { this.players.put(id, null); continue; } - String info = buf.readStringFromBuffer(Player.MAX_INFO_LENGTH); + String info = buf.readStringFromBuffer(IPlayer.MAX_INFO_LENGTH); info = info.isEmpty() ? null : info; Alignment align = buf.readEnumValue(Alignment.class); String dim = buf.readStringFromBuffer(256); @@ -80,7 +80,7 @@ public class SPacketCharacterList implements Packet { buf.writeVarIntToBuffer(this.selected); } - public void processPacket(ClientPlayer handler) { + public void processPacket(IClientPlayer handler) { handler.handleCharacterList(this); } diff --git a/java/src/game/packet/SPacketChunkData.java b/java/src/game/packet/SPacketChunkData.java index 6f45ac3..c0122d8 100755 --- a/java/src/game/packet/SPacketChunkData.java +++ b/java/src/game/packet/SPacketChunkData.java @@ -4,13 +4,13 @@ import java.io.IOException; import java.util.List; import game.collect.Lists; -import game.network.ClientPlayer; +import game.network.IClientPlayer; import game.network.Packet; import game.network.PacketBuffer; import game.world.BlockArray; import game.world.Chunk; -public class SPacketChunkData implements Packet +public class SPacketChunkData implements Packet { private int chunkX; private int chunkZ; @@ -57,7 +57,7 @@ public class SPacketChunkData implements Packet /** * Passes this Packet on to the NetHandler for processing. */ - public void processPacket(ClientPlayer handler) + public void processPacket(IClientPlayer handler) { handler.handleChunkData(this); } diff --git a/java/src/game/packet/SPacketCollectItem.java b/java/src/game/packet/SPacketCollectItem.java index b6103e9..3763c56 100755 --- a/java/src/game/packet/SPacketCollectItem.java +++ b/java/src/game/packet/SPacketCollectItem.java @@ -2,11 +2,11 @@ package game.packet; import java.io.IOException; -import game.network.ClientPlayer; +import game.network.IClientPlayer; import game.network.Packet; import game.network.PacketBuffer; -public class SPacketCollectItem implements Packet +public class SPacketCollectItem implements Packet { private int collectedItemEntityId; private int entityId; @@ -42,7 +42,7 @@ public class SPacketCollectItem implements Packet /** * Passes this Packet on to the NetHandler for processing. */ - public void processPacket(ClientPlayer handler) + public void processPacket(IClientPlayer handler) { handler.handleCollectItem(this); } diff --git a/java/src/game/packet/SPacketDestroyEntities.java b/java/src/game/packet/SPacketDestroyEntities.java index 2124150..4afc384 100755 --- a/java/src/game/packet/SPacketDestroyEntities.java +++ b/java/src/game/packet/SPacketDestroyEntities.java @@ -2,11 +2,11 @@ package game.packet; import java.io.IOException; -import game.network.ClientPlayer; +import game.network.IClientPlayer; import game.network.Packet; import game.network.PacketBuffer; -public class SPacketDestroyEntities implements Packet +public class SPacketDestroyEntities implements Packet { private int[] entityIDs; @@ -48,7 +48,7 @@ public class SPacketDestroyEntities implements Packet /** * Passes this Packet on to the NetHandler for processing. */ - public void processPacket(ClientPlayer handler) + public void processPacket(IClientPlayer handler) { handler.handleDestroyEntities(this); } diff --git a/java/src/game/packet/SPacketDimensionName.java b/java/src/game/packet/SPacketDimensionName.java index 6f9110b..e0160a2 100755 --- a/java/src/game/packet/SPacketDimensionName.java +++ b/java/src/game/packet/SPacketDimensionName.java @@ -3,11 +3,11 @@ package game.packet; import java.io.IOException; import game.dimension.Dimension; -import game.network.ClientPlayer; +import game.network.IClientPlayer; import game.network.Packet; import game.network.PacketBuffer; -public class SPacketDimensionName implements Packet { +public class SPacketDimensionName implements Packet { private String fullName; private String customName; @@ -20,7 +20,7 @@ public class SPacketDimensionName implements Packet { dim.getCustomName(); } - public void processPacket(ClientPlayer handler) { + public void processPacket(IClientPlayer handler) { handler.handleDimName(this); } diff --git a/java/src/game/packet/SPacketDisconnect.java b/java/src/game/packet/SPacketDisconnect.java index 640a002..1ff1234 100755 --- a/java/src/game/packet/SPacketDisconnect.java +++ b/java/src/game/packet/SPacketDisconnect.java @@ -2,11 +2,11 @@ package game.packet; import java.io.IOException; -import game.network.ClientPlayer; +import game.network.IClientPlayer; import game.network.Packet; import game.network.PacketBuffer; -public class SPacketDisconnect implements Packet +public class SPacketDisconnect implements Packet { public SPacketDisconnect() { @@ -20,7 +20,7 @@ public class SPacketDisconnect implements Packet { } - public void processPacket(ClientPlayer handler) + public void processPacket(IClientPlayer handler) { handler.handleDisconnect(this); } diff --git a/java/src/game/packet/SPacketEntityEquipment.java b/java/src/game/packet/SPacketEntityEquipment.java index 07425c7..d90e86d 100755 --- a/java/src/game/packet/SPacketEntityEquipment.java +++ b/java/src/game/packet/SPacketEntityEquipment.java @@ -3,11 +3,11 @@ package game.packet; import java.io.IOException; import game.item.ItemStack; -import game.network.ClientPlayer; +import game.network.IClientPlayer; import game.network.Packet; import game.network.PacketBuffer; -public class SPacketEntityEquipment implements Packet +public class SPacketEntityEquipment implements Packet { private int entityID; private int equipmentSlot; @@ -47,7 +47,7 @@ public class SPacketEntityEquipment implements Packet /** * Passes this Packet on to the NetHandler for processing. */ - public void processPacket(ClientPlayer handler) + public void processPacket(IClientPlayer handler) { handler.handleEntityEquipment(this); } diff --git a/java/src/game/packet/SPacketEntityVelocity.java b/java/src/game/packet/SPacketEntityVelocity.java index 5cb59bb..ccca607 100755 --- a/java/src/game/packet/SPacketEntityVelocity.java +++ b/java/src/game/packet/SPacketEntityVelocity.java @@ -3,11 +3,11 @@ package game.packet; import java.io.IOException; import game.entity.Entity; -import game.network.ClientPlayer; +import game.network.IClientPlayer; import game.network.Packet; import game.network.PacketBuffer; -public class SPacketEntityVelocity implements Packet +public class SPacketEntityVelocity implements Packet { private int entityID; private int motionX; @@ -88,7 +88,7 @@ public class SPacketEntityVelocity implements Packet /** * Passes this Packet on to the NetHandler for processing. */ - public void processPacket(ClientPlayer handler) + public void processPacket(IClientPlayer handler) { handler.handleEntityVelocity(this); } diff --git a/java/src/game/packet/SPacketHeldItemChange.java b/java/src/game/packet/SPacketHeldItemChange.java index b0b8e37..8c36e08 100755 --- a/java/src/game/packet/SPacketHeldItemChange.java +++ b/java/src/game/packet/SPacketHeldItemChange.java @@ -2,11 +2,11 @@ package game.packet; import java.io.IOException; -import game.network.ClientPlayer; +import game.network.IClientPlayer; import game.network.Packet; import game.network.PacketBuffer; -public class SPacketHeldItemChange implements Packet +public class SPacketHeldItemChange implements Packet { private int heldItemHotbarIndex; @@ -38,7 +38,7 @@ public class SPacketHeldItemChange implements Packet /** * Passes this Packet on to the NetHandler for processing. */ - public void processPacket(ClientPlayer handler) + public void processPacket(IClientPlayer handler) { handler.handleHeldItemChange(this); } diff --git a/java/src/game/packet/SPacketJoinGame.java b/java/src/game/packet/SPacketJoinGame.java index 59568d8..6c9e0ac 100755 --- a/java/src/game/packet/SPacketJoinGame.java +++ b/java/src/game/packet/SPacketJoinGame.java @@ -4,11 +4,11 @@ import java.io.IOException; import game.dimension.Dimension; import game.nbt.NBTTagCompound; -import game.network.ClientPlayer; +import game.network.IClientPlayer; import game.network.Packet; import game.network.PacketBuffer; -public class SPacketJoinGame implements Packet { +public class SPacketJoinGame implements Packet { private int entityId; private NBTTagCompound dimension; private int type; @@ -38,7 +38,7 @@ public class SPacketJoinGame implements Packet { buf.writeBoolean(this.editor); } - public void processPacket(ClientPlayer handler) { + public void processPacket(IClientPlayer handler) { handler.handleJoinGame(this); } diff --git a/java/src/game/packet/SPacketKeepAlive.java b/java/src/game/packet/SPacketKeepAlive.java index 9fb15cd..9c5cbb9 100755 --- a/java/src/game/packet/SPacketKeepAlive.java +++ b/java/src/game/packet/SPacketKeepAlive.java @@ -1,8 +1,8 @@ package game.packet; -import game.network.ClientPlayer; +import game.network.IClientPlayer; -public class SPacketKeepAlive extends APacketVarInt +public class SPacketKeepAlive extends APacketVarInt { public SPacketKeepAlive() { @@ -13,7 +13,7 @@ public class SPacketKeepAlive extends APacketVarInt super(key); } - public void processPacket(ClientPlayer handler) + public void processPacket(IClientPlayer handler) { handler.handleKeepAlive(this); } diff --git a/java/src/game/packet/SPacketLoading.java b/java/src/game/packet/SPacketLoading.java index 827c67e..ae2214c 100644 --- a/java/src/game/packet/SPacketLoading.java +++ b/java/src/game/packet/SPacketLoading.java @@ -2,11 +2,11 @@ package game.packet; import java.io.IOException; -import game.network.ClientPlayer; +import game.network.IClientPlayer; import game.network.Packet; import game.network.PacketBuffer; -public class SPacketLoading implements Packet { +public class SPacketLoading implements Packet { private String message; private String task; private int total = -1; @@ -48,7 +48,7 @@ public class SPacketLoading implements Packet { } } - public void processPacket(ClientPlayer handler) { + public void processPacket(IClientPlayer handler) { handler.handleLoading(this); } diff --git a/java/src/game/packet/SPacketMapChunkBulk.java b/java/src/game/packet/SPacketMapChunkBulk.java index e8948ab..4b119fe 100755 --- a/java/src/game/packet/SPacketMapChunkBulk.java +++ b/java/src/game/packet/SPacketMapChunkBulk.java @@ -3,12 +3,12 @@ package game.packet; import java.io.IOException; import java.util.List; -import game.network.ClientPlayer; +import game.network.IClientPlayer; import game.network.Packet; import game.network.PacketBuffer; import game.world.Chunk; -public class SPacketMapChunkBulk implements Packet +public class SPacketMapChunkBulk implements Packet { private int[] xPositions; private int[] zPositions; @@ -87,7 +87,7 @@ public class SPacketMapChunkBulk implements Packet /** * Passes this Packet on to the NetHandler for processing. */ - public void processPacket(ClientPlayer handler) + public void processPacket(IClientPlayer handler) { handler.handleMapChunkBulk(this); } diff --git a/java/src/game/packet/SPacketMessage.java b/java/src/game/packet/SPacketMessage.java index 52bfa0f..d73032e 100755 --- a/java/src/game/packet/SPacketMessage.java +++ b/java/src/game/packet/SPacketMessage.java @@ -2,11 +2,11 @@ package game.packet; import java.io.IOException; -import game.network.ClientPlayer; +import game.network.IClientPlayer; import game.network.Packet; import game.network.PacketBuffer; -public class SPacketMessage implements Packet { +public class SPacketMessage implements Packet { public static enum Type { CONSOLE, CHAT, FEED, HOTBAR; } @@ -32,7 +32,7 @@ public class SPacketMessage implements Packet { buf.writeEnumValue(this.type); } - public void processPacket(ClientPlayer handler) { + public void processPacket(IClientPlayer handler) { handler.handleMessage(this); } diff --git a/java/src/game/packet/SPacketMultiBlockChange.java b/java/src/game/packet/SPacketMultiBlockChange.java index 47f8622..1fcf7fd 100755 --- a/java/src/game/packet/SPacketMultiBlockChange.java +++ b/java/src/game/packet/SPacketMultiBlockChange.java @@ -3,7 +3,7 @@ package game.packet; import java.io.IOException; import game.init.BlockRegistry; -import game.network.ClientPlayer; +import game.network.IClientPlayer; import game.network.Packet; import game.network.PacketBuffer; import game.world.BlockPos; @@ -11,7 +11,7 @@ import game.world.Chunk; import game.world.ChunkPos; import game.world.State; -public class SPacketMultiBlockChange implements Packet +public class SPacketMultiBlockChange implements Packet { private ChunkPos chunkPosCoord; private SPacketMultiBlockChange.BlockUpdateData[] changedBlocks; @@ -64,7 +64,7 @@ public class SPacketMultiBlockChange implements Packet /** * Passes this Packet on to the NetHandler for processing. */ - public void processPacket(ClientPlayer handler) + public void processPacket(IClientPlayer handler) { handler.handleMultiBlockChange(this); } diff --git a/java/src/game/packet/SPacketPlayerPosLook.java b/java/src/game/packet/SPacketPlayerPosLook.java index 1458e9d..74b4b2d 100755 --- a/java/src/game/packet/SPacketPlayerPosLook.java +++ b/java/src/game/packet/SPacketPlayerPosLook.java @@ -4,11 +4,11 @@ import java.io.IOException; import java.util.EnumSet; import java.util.Set; -import game.network.ClientPlayer; +import game.network.IClientPlayer; import game.network.Packet; import game.network.PacketBuffer; -public class SPacketPlayerPosLook implements Packet +public class SPacketPlayerPosLook implements Packet { private double x; private double y; @@ -60,7 +60,7 @@ public class SPacketPlayerPosLook implements Packet /** * Passes this Packet on to the NetHandler for processing. */ - public void processPacket(ClientPlayer handler) + public void processPacket(IClientPlayer handler) { handler.handlePlayerPosLook(this); } diff --git a/java/src/game/packet/SPacketRespawn.java b/java/src/game/packet/SPacketRespawn.java index 4366f0f..d577276 100755 --- a/java/src/game/packet/SPacketRespawn.java +++ b/java/src/game/packet/SPacketRespawn.java @@ -4,11 +4,11 @@ import java.io.IOException; import game.dimension.Dimension; import game.nbt.NBTTagCompound; -import game.network.ClientPlayer; +import game.network.IClientPlayer; import game.network.Packet; import game.network.PacketBuffer; -public class SPacketRespawn implements Packet +public class SPacketRespawn implements Packet { private NBTTagCompound dimension; private int type; @@ -25,7 +25,7 @@ public class SPacketRespawn implements Packet this.editor = editor; } - public void processPacket(ClientPlayer handler) + public void processPacket(IClientPlayer handler) { handler.handleRespawn(this); } diff --git a/java/src/game/packet/SPacketServerTick.java b/java/src/game/packet/SPacketServerTick.java index 14dcaea..03ad7ec 100644 --- a/java/src/game/packet/SPacketServerTick.java +++ b/java/src/game/packet/SPacketServerTick.java @@ -2,11 +2,11 @@ package game.packet; import java.io.IOException; -import game.network.ClientPlayer; +import game.network.IClientPlayer; import game.network.Packet; import game.network.PacketBuffer; -public class SPacketServerTick implements Packet { +public class SPacketServerTick implements Packet { private int time; public SPacketServerTick() { @@ -24,7 +24,7 @@ public class SPacketServerTick implements Packet { buf.writeInt(this.time); } - public void processPacket(ClientPlayer handler) { + public void processPacket(IClientPlayer handler) { handler.handleServerTick(this); } diff --git a/java/src/game/packet/SPacketSetExperience.java b/java/src/game/packet/SPacketSetExperience.java index de31d5f..b317b66 100755 --- a/java/src/game/packet/SPacketSetExperience.java +++ b/java/src/game/packet/SPacketSetExperience.java @@ -2,11 +2,11 @@ package game.packet; import java.io.IOException; -import game.network.ClientPlayer; +import game.network.IClientPlayer; import game.network.Packet; import game.network.PacketBuffer; -public class SPacketSetExperience implements Packet +public class SPacketSetExperience implements Packet { private float progress; private int totalExperience; @@ -46,7 +46,7 @@ public class SPacketSetExperience implements Packet /** * Passes this Packet on to the NetHandler for processing. */ - public void processPacket(ClientPlayer handler) + public void processPacket(IClientPlayer handler) { handler.handleSetExperience(this); } diff --git a/java/src/game/packet/SPacketSkin.java b/java/src/game/packet/SPacketSkin.java index 429bc0f..512d09b 100755 --- a/java/src/game/packet/SPacketSkin.java +++ b/java/src/game/packet/SPacketSkin.java @@ -4,12 +4,12 @@ import java.io.IOException; import client.renderer.texture.EntityTexManager; import game.entity.Entity; -import game.network.ClientPlayer; +import game.network.IClientPlayer; import game.network.Packet; import game.network.PacketBuffer; import game.world.World; -public class SPacketSkin implements Packet +public class SPacketSkin implements Packet { private int id; // private ModelType model; @@ -58,7 +58,7 @@ public class SPacketSkin implements Packet buf.writeByteArray(this.texture == null ? new byte[0] : this.texture); } - public void processPacket(ClientPlayer handler) + public void processPacket(IClientPlayer handler) { handler.handleSkin(this); } diff --git a/java/src/game/packet/SPacketSpawnMob.java b/java/src/game/packet/SPacketSpawnMob.java index 2fa62b3..2bd5afe 100755 --- a/java/src/game/packet/SPacketSpawnMob.java +++ b/java/src/game/packet/SPacketSpawnMob.java @@ -6,12 +6,12 @@ import java.util.List; import game.entity.DataWatcher; import game.entity.types.EntityLiving; import game.init.EntityRegistry; -import game.network.ClientPlayer; +import game.network.IClientPlayer; import game.network.Packet; import game.network.PacketBuffer; import game.util.ExtMath; -public class SPacketSpawnMob implements Packet +public class SPacketSpawnMob implements Packet { private int entityId; private int type; @@ -114,7 +114,7 @@ public class SPacketSpawnMob implements Packet this.writeWatcher.writeTo(buf); } - public void processPacket(ClientPlayer handler) + public void processPacket(IClientPlayer handler) { handler.handleSpawnMob(this); } diff --git a/java/src/game/packet/SPacketSpawnObject.java b/java/src/game/packet/SPacketSpawnObject.java index aa697dd..238e1ef 100755 --- a/java/src/game/packet/SPacketSpawnObject.java +++ b/java/src/game/packet/SPacketSpawnObject.java @@ -7,14 +7,14 @@ import game.entity.item.EntityLeashKnot; import game.entity.projectile.EntityProjectile; import game.entity.types.IObjectData; import game.init.EntityRegistry; -import game.network.ClientPlayer; +import game.network.IClientPlayer; import game.network.Packet; import game.network.PacketBuffer; import game.util.ExtMath; import game.world.BlockPos; import game.world.Vec3; -public class SPacketSpawnObject implements Packet +public class SPacketSpawnObject implements Packet { private int entityId; private int x; @@ -139,7 +139,7 @@ public class SPacketSpawnObject implements Packet } } - public void processPacket(ClientPlayer handler) + public void processPacket(IClientPlayer handler) { handler.handleSpawnObject(this); } diff --git a/java/src/game/packet/SPacketSpawnPlayer.java b/java/src/game/packet/SPacketSpawnPlayer.java index 9f9dec5..c0a9f3b 100755 --- a/java/src/game/packet/SPacketSpawnPlayer.java +++ b/java/src/game/packet/SPacketSpawnPlayer.java @@ -9,12 +9,12 @@ import game.entity.npc.EntityNPC; import game.init.EntityRegistry; import game.init.ItemRegistry; import game.item.ItemStack; -import game.network.ClientPlayer; +import game.network.IClientPlayer; import game.network.Packet; import game.network.PacketBuffer; import game.util.ExtMath; -public class SPacketSpawnPlayer implements Packet +public class SPacketSpawnPlayer implements Packet { private int entityId; private int type; @@ -90,7 +90,7 @@ public class SPacketSpawnPlayer implements Packet /** * Passes this Packet on to the NetHandler for processing. */ - public void processPacket(ClientPlayer handler) + public void processPacket(IClientPlayer handler) { handler.handleSpawnPlayer(this); } diff --git a/java/src/game/packet/SPacketTimeUpdate.java b/java/src/game/packet/SPacketTimeUpdate.java index 47ec0ae..f8b28fa 100755 --- a/java/src/game/packet/SPacketTimeUpdate.java +++ b/java/src/game/packet/SPacketTimeUpdate.java @@ -2,11 +2,11 @@ package game.packet; import java.io.IOException; -import game.network.ClientPlayer; +import game.network.IClientPlayer; import game.network.Packet; import game.network.PacketBuffer; -public class SPacketTimeUpdate implements Packet { +public class SPacketTimeUpdate implements Packet { private long worldTime; private String serverInfo; @@ -28,7 +28,7 @@ public class SPacketTimeUpdate implements Packet { buf.writeString(this.serverInfo); } - public void processPacket(ClientPlayer handler) { + public void processPacket(IClientPlayer handler) { handler.handleTimeUpdate(this); } diff --git a/java/src/game/packet/SPacketTrades.java b/java/src/game/packet/SPacketTrades.java index 98ea171..4c64a65 100755 --- a/java/src/game/packet/SPacketTrades.java +++ b/java/src/game/packet/SPacketTrades.java @@ -3,13 +3,13 @@ package game.packet; import java.io.IOException; import game.item.ItemStack; -import game.network.ClientPlayer; +import game.network.IClientPlayer; import game.network.Packet; import game.network.PacketBuffer; import game.village.MerchantRecipe; import game.village.MerchantRecipeList; -public class SPacketTrades implements Packet +public class SPacketTrades implements Packet { private MerchantRecipeList recipes; private int windowId; @@ -88,7 +88,7 @@ public class SPacketTrades implements Packet /** * Passes this Packet on to the NetHandler for processing. */ - public void processPacket(ClientPlayer handler) + public void processPacket(IClientPlayer handler) { handler.handleTrades(this); } diff --git a/java/src/game/packet/SPacketUpdateHealth.java b/java/src/game/packet/SPacketUpdateHealth.java index 059c8a1..cda549b 100755 --- a/java/src/game/packet/SPacketUpdateHealth.java +++ b/java/src/game/packet/SPacketUpdateHealth.java @@ -2,11 +2,11 @@ package game.packet; import java.io.IOException; -import game.network.ClientPlayer; +import game.network.IClientPlayer; import game.network.Packet; import game.network.PacketBuffer; -public class SPacketUpdateHealth implements Packet { +public class SPacketUpdateHealth implements Packet { private int health; public SPacketUpdateHealth() { @@ -24,7 +24,7 @@ public class SPacketUpdateHealth implements Packet { buf.writeInt(this.health); } - public void processPacket(ClientPlayer handler) { + public void processPacket(IClientPlayer handler) { handler.handleUpdateHealth(this); } diff --git a/java/src/game/packet/SPacketWorld.java b/java/src/game/packet/SPacketWorld.java index 0f8ff25..3c68f29 100755 --- a/java/src/game/packet/SPacketWorld.java +++ b/java/src/game/packet/SPacketWorld.java @@ -2,11 +2,11 @@ package game.packet; import java.io.IOException; -import game.network.ClientPlayer; +import game.network.IClientPlayer; import game.network.Packet; import game.network.PacketBuffer; -public class SPacketWorld implements Packet { +public class SPacketWorld implements Packet { private float gravity; private int timeFactor; private boolean dayCycle; @@ -20,7 +20,7 @@ public class SPacketWorld implements Packet { this.dayCycle = dayCycle; } - public void processPacket(ClientPlayer handler) { + public void processPacket(IClientPlayer handler) { handler.handleWorld(this); } diff --git a/java/src/game/network/LazyLoadBase.java b/java/src/game/util/LazyLoadBase.java similarity index 93% rename from java/src/game/network/LazyLoadBase.java rename to java/src/game/util/LazyLoadBase.java index 05d41b0..d40c4e7 100755 --- a/java/src/game/network/LazyLoadBase.java +++ b/java/src/game/util/LazyLoadBase.java @@ -1,4 +1,4 @@ -package game.network; +package game.util; public abstract class LazyLoadBase { diff --git a/java/src/game/world/WorldServer.java b/java/src/game/world/WorldServer.java index 9b97b07..69fa871 100755 --- a/java/src/game/world/WorldServer.java +++ b/java/src/game/world/WorldServer.java @@ -13,6 +13,7 @@ import java.util.TreeSet; import java.util.concurrent.ConcurrentHashMap; import java.util.function.Predicate; +import game.IServer; import game.biome.Biome; import game.biome.RngSpawn; import game.block.Block; @@ -44,8 +45,8 @@ import game.nbt.NBTLoader; import game.nbt.NBTTagCompound; import game.nbt.NBTTagInt; import game.nbt.NBTTagList; +import game.network.IPlayer; import game.network.Packet; -import game.network.Player; import game.packet.S1APacketEntityStatus; import game.packet.S27PacketExplosion; import game.packet.S28PacketEffect; @@ -86,12 +87,11 @@ import game.worldgen.structure.MapGenMineshaft; import game.worldgen.structure.MapGenScatteredFeature; import game.worldgen.structure.MapGenStronghold; import game.worldgen.structure.MapGenVillage; -import server.Server; public final class WorldServer extends World { private static final int[][] XZ_DIRS = new int[][] {{1, 0}, {0, 1}, {-1, 0}, {0, -1}}; - private final Server server; + private final IServer server; private final File chunkDir; private final Random grng; private final Set ticks = Sets.newHashSet(); @@ -154,7 +154,7 @@ public final class WorldServer extends World { private long prevUpdate; private long time; - public WorldServer(Server server, long dtime, Dimension dim, boolean debug) { + public WorldServer(IServer server, long dtime, Dimension dim, boolean debug) { super(dim, false, debug); this.server = server; // this.time = time; @@ -361,7 +361,7 @@ public final class WorldServer extends World { return ExtMath.clampf(Config.gravity, -10.0f, 10.0f); } - public Server getServer() { + public IServer getServer() { return this.server; } @@ -1623,7 +1623,7 @@ public final class WorldServer extends World { this.dungeons = null; } - public static String getLoadedInfo(Server server) { + public static String getLoadedInfo(IServer server) { int chunks = 0; int entities = 0; int tiles = 0; @@ -1689,7 +1689,7 @@ public final class WorldServer extends World { public void sendBlockBreakProgress(int breakerId, BlockPos pos, int progress) { - for (Player conn : this.server.getPlayers()) + for (IPlayer conn : this.server.getIPlayers()) { EntityNPC player = conn.getPresentEntity(); if (player != null && player.worldObj == this && player.getId() != breakerId) @@ -1774,8 +1774,7 @@ public final class WorldServer extends World { public void addPlayer(EntityNPC player) { int x = (int)player.posX >> 4; int z = (int)player.posZ >> 4; - player.connection.managedPosX = player.posX; - player.connection.managedPosZ = player.posZ; + player.connection.setManagedPos(player.posX, player.posZ); for(int cx = x - this.viewRadius; cx <= x + this.viewRadius; ++cx) { for(int cz = z - this.viewRadius; cz <= z + this.viewRadius; ++cz) { @@ -1788,7 +1787,7 @@ public final class WorldServer extends World { } private void filterChunkLoadQueue(EntityNPC player) { - List list = Lists.newArrayList(player.connection.loadedChunks); + List list = Lists.newArrayList(player.connection.getLoadedChunkList()); int p = 0; int r = this.viewRadius; int x = (int)player.posX >> 4; @@ -1796,10 +1795,10 @@ public final class WorldServer extends World { int cx = 0; int cz = 0; ChunkPos pos = this.getPlayerInstance(x, z, true).position; - player.connection.loadedChunks.clear(); + player.connection.getLoadedChunkList().clear(); if(list.contains(pos)) { - player.connection.loadedChunks.add(pos); + player.connection.getLoadedChunkList().add(pos); } for(int n = 1; n <= r * 2; ++n) { @@ -1812,7 +1811,7 @@ public final class WorldServer extends World { pos = this.getPlayerInstance(x + cx, z + cz, true).position; if(list.contains(pos)) { - player.connection.loadedChunks.add(pos); + player.connection.getLoadedChunkList().add(pos); } } } @@ -1826,14 +1825,14 @@ public final class WorldServer extends World { pos = this.getPlayerInstance(x + cx, z + cz, true).position; if(list.contains(pos)) { - player.connection.loadedChunks.add(pos); + player.connection.getLoadedChunkList().add(pos); } } } public void removePlayer(EntityNPC player) { - int x = (int)player.connection.managedPosX >> 4; - int z = (int)player.connection.managedPosZ >> 4; + int x = (int)player.connection.getManagedX() >> 4; + int z = (int)player.connection.getManagedZ() >> 4; for(int cx = x - this.viewRadius; cx <= x + this.viewRadius; ++cx) { for(int cz = z - this.viewRadius; cz <= z + this.viewRadius; ++cz) { @@ -1857,13 +1856,13 @@ public final class WorldServer extends World { public void updateMountedMovingPlayer(EntityNPC player) { int x = (int)player.posX >> 4; int z = (int)player.posZ >> 4; - double dx = player.connection.managedPosX - player.posX; - double dz = player.connection.managedPosZ - player.posZ; + double dx = player.connection.getManagedX() - player.posX; + double dz = player.connection.getManagedZ() - player.posZ; double dist = dx * dx + dz * dz; if(dist >= 64.0D) { - int px = (int)player.connection.managedPosX >> 4; - int pz = (int)player.connection.managedPosZ >> 4; + int px = (int)player.connection.getManagedX() >> 4; + int pz = (int)player.connection.getManagedZ() >> 4; int r = this.viewRadius; int mx = x - px; int mz = z - pz; @@ -1886,15 +1885,14 @@ public final class WorldServer extends World { } this.filterChunkLoadQueue(player); - player.connection.managedPosX = player.posX; - player.connection.managedPosZ = player.posZ; + player.connection.setManagedPos(player.posX, player.posZ); } } } public boolean isPlayerWatchingChunk(EntityNPC player, int chunkX, int chunkZ) { PlayerInstance inst = this.getPlayerInstance(chunkX, chunkZ, false); - return inst != null && inst.watching.contains(player) && !player.connection.loadedChunks.contains(inst.position); + return inst != null && inst.watching.contains(player) && !player.connection.getLoadedChunkList().contains(inst.position); } public void updateViewRadius() { @@ -2678,7 +2676,7 @@ public final class WorldServer extends World { } this.watching.add(player); - player.connection.loadedChunks.add(this.position); + player.connection.getLoadedChunkList().add(this.position); } } @@ -2691,7 +2689,7 @@ public final class WorldServer extends World { } this.watching.remove(player); - player.connection.loadedChunks.remove(this.position); + player.connection.getLoadedChunkList().remove(this.position); if(this.watching.isEmpty()) { long v = (long)this.position.x + 2147483647L | (long)this.position.z + 2147483647L << 32; @@ -2749,7 +2747,7 @@ public final class WorldServer extends World { for(int z = 0; z < this.watching.size(); ++z) { EntityNPC player = this.watching.get(z); - if(!player.connection.loadedChunks.contains(this.position)) { + if(!player.connection.getLoadedChunkList().contains(this.position)) { player.connection.sendPacket(packet); } } diff --git a/java/src/server/Server.java b/java/src/server/Server.java index 03e23ba..1419a7d 100755 --- a/java/src/server/Server.java +++ b/java/src/server/Server.java @@ -18,11 +18,10 @@ import java.util.concurrent.ExecutionException; import java.util.concurrent.Executors; import java.util.concurrent.FutureTask; +import game.IServer; import game.collect.Lists; import game.collect.Maps; import game.color.TextColor; -import game.command.CommandEnvironment; -import game.command.FixedExecutor; import game.dimension.Dimension; import game.dimension.Space; import game.entity.Entity; @@ -40,9 +39,8 @@ import game.log.Log; import game.nbt.NBTLoader; import game.nbt.NBTTagCompound; import game.nbt.NBTTagList; -import game.network.HandshakeHandler; +import game.network.IPlayer; import game.network.IThreadListener; -import game.network.LazyLoadBase; import game.network.NetConnection; import game.network.NetHandler.ThreadQuickExitException; import game.network.Packet; @@ -50,7 +48,6 @@ import game.network.PacketDecoder; import game.network.PacketEncoder; import game.network.PacketPrepender; import game.network.PacketSplitter; -import game.network.Player; import game.packet.RPacketEnableCompression; import game.packet.RPacketLoginSuccess; import game.packet.S1DPacketEntityEffect; @@ -67,6 +64,7 @@ import game.packet.SPacketTimeUpdate; import game.packet.SPacketWorld; import game.potion.PotionEffect; import game.util.ExtMath; +import game.util.LazyLoadBase; import game.util.Tuple; import game.util.Util; import game.world.BlockPos; @@ -90,8 +88,12 @@ import io.netty.channel.socket.nio.NioServerSocketChannel; import io.netty.handler.timeout.ReadTimeoutHandler; import io.netty.util.concurrent.Future; import io.netty.util.concurrent.GenericFutureListener; +import server.command.CommandEnvironment; +import server.command.FixedExecutor; +import server.network.HandshakeHandler; +import server.network.Player; -public final class Server implements IThreadListener { +public final class Server implements IThreadListener, IServer { private static final LazyLoadBase SERVER_NIO_EVENTLOOP = new LazyLoadBase() { protected NioEventLoopGroup load() { return new NioEventLoopGroup(0, (new ThreadFactoryBuilder()).setNameFormat("Netty Server IO #%d").setDaemon(true).build()); @@ -186,7 +188,7 @@ public final class Server implements IThreadListener { } public Position getOfflinePosition(String user) { - if(this.debug || !Player.isValidUser(user)) + if(this.debug || !IPlayer.isValidUser(user)) return null; NBTTagCompound tag = null; try { @@ -503,7 +505,7 @@ public final class Server implements IThreadListener { } this.networkTick(); if(++this.pingTimer > 600) { - this.sendPacket(new S38PacketPlayerListItem(this.players)); + this.sendPacket(new S38PacketPlayerListItem(this.getIPlayers())); this.pingTimer = 0; } if(Config.saveInterval > 0 && ++this.saveTimer >= Config.saveInterval) { @@ -591,6 +593,10 @@ public final class Server implements IThreadListener { return this.players; } + public List getIPlayers() { + return (List)this.players; + } + public Player getPlayer(String user) { return this.usermap.get(user); } @@ -951,7 +957,7 @@ public final class Server implements IThreadListener { if(pos != null) player.setRotationYawHead(yaw); // player.interactManager.setWorld(newWorld); - this.updateTimeAndWeatherForPlayer(player.connection, newWorld); + this.updateTimeAndWeatherForPlayer((Player)player.connection, newWorld); this.syncPlayerInventory(player); for(PotionEffect effect : player.getEffects()) { player.connection.sendPacket(new S1DPacketEntityEffect(player.getId(), effect)); diff --git a/java/src/game/command/ArgCombiner.java b/java/src/server/command/ArgCombiner.java similarity index 83% rename from java/src/game/command/ArgCombiner.java rename to java/src/server/command/ArgCombiner.java index b893697..166c11b 100644 --- a/java/src/game/command/ArgCombiner.java +++ b/java/src/server/command/ArgCombiner.java @@ -1,4 +1,4 @@ -package game.command; +package server.command; public interface ArgCombiner { Object combine(T[] values); diff --git a/java/src/game/command/Argument.java b/java/src/server/command/Argument.java similarity index 96% rename from java/src/game/command/Argument.java rename to java/src/server/command/Argument.java index fb1307e..9863e7c 100644 --- a/java/src/game/command/Argument.java +++ b/java/src/server/command/Argument.java @@ -1,4 +1,4 @@ -package game.command; +package server.command; import java.util.Map; diff --git a/java/src/game/command/ArgumentParser.java b/java/src/server/command/ArgumentParser.java similarity index 98% rename from java/src/game/command/ArgumentParser.java rename to java/src/server/command/ArgumentParser.java index d961f69..e6a90d7 100644 --- a/java/src/game/command/ArgumentParser.java +++ b/java/src/server/command/ArgumentParser.java @@ -1,4 +1,4 @@ -package game.command; +package server.command; import java.util.Collection; import java.util.List; diff --git a/java/src/game/command/ArgumentSplitter.java b/java/src/server/command/ArgumentSplitter.java similarity index 99% rename from java/src/game/command/ArgumentSplitter.java rename to java/src/server/command/ArgumentSplitter.java index 6d229e5..6e746a9 100644 --- a/java/src/game/command/ArgumentSplitter.java +++ b/java/src/server/command/ArgumentSplitter.java @@ -1,4 +1,4 @@ -package game.command; +package server.command; import java.util.List; import java.util.Map; diff --git a/java/src/game/command/BooleanParser.java b/java/src/server/command/BooleanParser.java similarity index 91% rename from java/src/game/command/BooleanParser.java rename to java/src/server/command/BooleanParser.java index 600435c..e821832 100644 --- a/java/src/game/command/BooleanParser.java +++ b/java/src/server/command/BooleanParser.java @@ -1,4 +1,4 @@ -package game.command; +package server.command; public class BooleanParser extends EnumParser { public BooleanParser(String name, Boolean def) { diff --git a/java/src/game/command/CachedExecutable.java b/java/src/server/command/CachedExecutable.java similarity index 99% rename from java/src/game/command/CachedExecutable.java rename to java/src/server/command/CachedExecutable.java index af728d2..d3e97c4 100644 --- a/java/src/game/command/CachedExecutable.java +++ b/java/src/server/command/CachedExecutable.java @@ -1,4 +1,4 @@ -package game.command; +package server.command; import java.lang.reflect.Method; import java.util.List; diff --git a/java/src/game/command/ColorParser.java b/java/src/server/command/ColorParser.java similarity index 96% rename from java/src/game/command/ColorParser.java rename to java/src/server/command/ColorParser.java index d8db5ff..191568b 100644 --- a/java/src/game/command/ColorParser.java +++ b/java/src/server/command/ColorParser.java @@ -1,4 +1,4 @@ -package game.command; +package server.command; import game.color.DyeColor; diff --git a/java/src/game/command/Command.java b/java/src/server/command/Command.java similarity index 99% rename from java/src/game/command/Command.java rename to java/src/server/command/Command.java index 42f8e5e..1a7074f 100644 --- a/java/src/game/command/Command.java +++ b/java/src/server/command/Command.java @@ -1,4 +1,4 @@ -package game.command; +package server.command; import java.lang.reflect.Array; import java.util.Collection; @@ -7,9 +7,9 @@ import java.util.Map; import game.collect.Lists; import game.collect.Maps; -import game.command.DoubleParser.DefType; import game.world.Vec3; import game.world.World; +import server.command.DoubleParser.DefType; public abstract class Command implements Executable { private final String name; diff --git a/java/src/game/command/CommandEnvironment.java b/java/src/server/command/CommandEnvironment.java similarity index 91% rename from java/src/game/command/CommandEnvironment.java rename to java/src/server/command/CommandEnvironment.java index 5b4b243..d416d93 100644 --- a/java/src/game/command/CommandEnvironment.java +++ b/java/src/server/command/CommandEnvironment.java @@ -1,4 +1,4 @@ -package game.command; +package server.command; import java.lang.reflect.Array; import java.lang.reflect.InvocationTargetException; @@ -11,24 +11,24 @@ import game.collect.Lists; import game.collect.Maps; import game.collect.Sets; import game.color.TextColor; -import game.command.commands.CommandAdmin; -import game.command.commands.CommandHelp; -import game.command.commands.CommandKick; -import game.command.commands.CommandMessage; -import game.command.commands.CommandMilk; -import game.command.commands.CommandOfflinetp; -import game.command.commands.CommandPotion; -import game.command.commands.CommandRemove; -import game.command.commands.CommandRevoke; -import game.command.commands.CommandSpawn; -import game.command.commands.CommandTele; -import game.command.commands.CommandTime; -import game.command.commands.CommandTp; -import game.command.commands.CommandWarp; -import game.command.commands.CommandWeather; -import game.command.commands.CommandWorld; import game.log.Log; import server.Server; +import server.command.commands.CommandAdmin; +import server.command.commands.CommandHelp; +import server.command.commands.CommandKick; +import server.command.commands.CommandMessage; +import server.command.commands.CommandMilk; +import server.command.commands.CommandOfflinetp; +import server.command.commands.CommandPotion; +import server.command.commands.CommandRemove; +import server.command.commands.CommandRevoke; +import server.command.commands.CommandSpawn; +import server.command.commands.CommandTele; +import server.command.commands.CommandTime; +import server.command.commands.CommandTp; +import server.command.commands.CommandWarp; +import server.command.commands.CommandWeather; +import server.command.commands.CommandWorld; public class CommandEnvironment { private final Server server; diff --git a/java/src/game/command/Completer.java b/java/src/server/command/Completer.java similarity index 86% rename from java/src/game/command/Completer.java rename to java/src/server/command/Completer.java index e09a484..3ec7b5c 100644 --- a/java/src/game/command/Completer.java +++ b/java/src/server/command/Completer.java @@ -1,4 +1,4 @@ -package game.command; +package server.command; import java.util.List; diff --git a/java/src/game/command/CompletingParser.java b/java/src/server/command/CompletingParser.java similarity index 95% rename from java/src/game/command/CompletingParser.java rename to java/src/server/command/CompletingParser.java index 247c740..21c7de1 100644 --- a/java/src/game/command/CompletingParser.java +++ b/java/src/server/command/CompletingParser.java @@ -1,4 +1,4 @@ -package game.command; +package server.command; import java.util.ArrayList; import java.util.Collection; diff --git a/java/src/game/command/DefaultingParser.java b/java/src/server/command/DefaultingParser.java similarity index 93% rename from java/src/game/command/DefaultingParser.java rename to java/src/server/command/DefaultingParser.java index 9accdaf..0b392c1 100644 --- a/java/src/game/command/DefaultingParser.java +++ b/java/src/server/command/DefaultingParser.java @@ -1,4 +1,4 @@ -package game.command; +package server.command; public abstract class DefaultingParser extends CompletingParser { private final Object def; diff --git a/java/src/game/command/DimensionParser.java b/java/src/server/command/DimensionParser.java similarity index 98% rename from java/src/game/command/DimensionParser.java rename to java/src/server/command/DimensionParser.java index f66ebf3..268702f 100644 --- a/java/src/game/command/DimensionParser.java +++ b/java/src/server/command/DimensionParser.java @@ -1,4 +1,4 @@ -package game.command; +package server.command; import java.util.Collection; diff --git a/java/src/game/command/DoubleParser.java b/java/src/server/command/DoubleParser.java similarity index 99% rename from java/src/game/command/DoubleParser.java rename to java/src/server/command/DoubleParser.java index a629fa9..9401ae5 100644 --- a/java/src/game/command/DoubleParser.java +++ b/java/src/server/command/DoubleParser.java @@ -1,4 +1,4 @@ -package game.command; +package server.command; import java.util.Collection; diff --git a/java/src/game/command/EntityListParser.java b/java/src/server/command/EntityListParser.java similarity index 98% rename from java/src/game/command/EntityListParser.java rename to java/src/server/command/EntityListParser.java index b21f17b..c221a28 100644 --- a/java/src/game/command/EntityListParser.java +++ b/java/src/server/command/EntityListParser.java @@ -1,4 +1,4 @@ -package game.command; +package server.command; import java.util.Collection; import java.util.Collections; @@ -11,8 +11,8 @@ import game.entity.Entity; import game.entity.EntityType; import game.entity.types.EntityLiving; import game.init.EntityRegistry; -import game.network.Player; import game.world.WorldServer; +import server.network.Player; public class EntityListParser extends EntityParser { public EntityListParser(String name, boolean useSender, boolean livingOnly) { diff --git a/java/src/game/command/EntityParser.java b/java/src/server/command/EntityParser.java similarity index 98% rename from java/src/game/command/EntityParser.java rename to java/src/server/command/EntityParser.java index ef53831..93a1934 100644 --- a/java/src/game/command/EntityParser.java +++ b/java/src/server/command/EntityParser.java @@ -1,4 +1,4 @@ -package game.command; +package server.command; import java.util.Collection; import java.util.List; diff --git a/java/src/game/command/EnumParser.java b/java/src/server/command/EnumParser.java similarity index 98% rename from java/src/game/command/EnumParser.java rename to java/src/server/command/EnumParser.java index 356348d..b39653b 100644 --- a/java/src/game/command/EnumParser.java +++ b/java/src/server/command/EnumParser.java @@ -1,4 +1,4 @@ -package game.command; +package server.command; import java.util.Map; diff --git a/java/src/game/command/Executable.java b/java/src/server/command/Executable.java similarity index 90% rename from java/src/game/command/Executable.java rename to java/src/server/command/Executable.java index 8761873..1912915 100644 --- a/java/src/game/command/Executable.java +++ b/java/src/server/command/Executable.java @@ -1,4 +1,4 @@ -package game.command; +package server.command; import java.util.List; import java.util.Map; diff --git a/java/src/game/command/Executor.java b/java/src/server/command/Executor.java similarity index 94% rename from java/src/game/command/Executor.java rename to java/src/server/command/Executor.java index 85f7b93..cde825c 100644 --- a/java/src/game/command/Executor.java +++ b/java/src/server/command/Executor.java @@ -1,4 +1,4 @@ -package game.command; +package server.command; import game.entity.Entity; import game.world.BlockPos; diff --git a/java/src/game/command/FixedExecutor.java b/java/src/server/command/FixedExecutor.java similarity index 97% rename from java/src/game/command/FixedExecutor.java rename to java/src/server/command/FixedExecutor.java index 465b298..c609f8c 100644 --- a/java/src/game/command/FixedExecutor.java +++ b/java/src/server/command/FixedExecutor.java @@ -1,4 +1,4 @@ -package game.command; +package server.command; import game.entity.Entity; import game.world.BlockPos; diff --git a/java/src/game/command/IntParser.java b/java/src/server/command/IntParser.java similarity index 98% rename from java/src/game/command/IntParser.java rename to java/src/server/command/IntParser.java index 56dc52d..a1673b0 100644 --- a/java/src/game/command/IntParser.java +++ b/java/src/server/command/IntParser.java @@ -1,4 +1,4 @@ -package game.command; +package server.command; public class IntParser extends DefaultingParser { private final Integer min; diff --git a/java/src/game/command/LongParser.java b/java/src/server/command/LongParser.java similarity index 97% rename from java/src/game/command/LongParser.java rename to java/src/server/command/LongParser.java index e2452f2..c072ac2 100644 --- a/java/src/game/command/LongParser.java +++ b/java/src/server/command/LongParser.java @@ -1,4 +1,4 @@ -package game.command; +package server.command; public class LongParser extends DefaultingParser { private final Long min; diff --git a/java/src/game/command/NonDefaultingParser.java b/java/src/server/command/NonDefaultingParser.java similarity index 90% rename from java/src/game/command/NonDefaultingParser.java rename to java/src/server/command/NonDefaultingParser.java index af97377..c06b105 100644 --- a/java/src/game/command/NonDefaultingParser.java +++ b/java/src/server/command/NonDefaultingParser.java @@ -1,4 +1,4 @@ -package game.command; +package server.command; public abstract class NonDefaultingParser extends CompletingParser { public NonDefaultingParser(String name, Object ... completions) { diff --git a/java/src/game/command/Parameter.java b/java/src/server/command/Parameter.java similarity index 97% rename from java/src/game/command/Parameter.java rename to java/src/server/command/Parameter.java index 8aef298..a61a828 100644 --- a/java/src/game/command/Parameter.java +++ b/java/src/server/command/Parameter.java @@ -1,4 +1,4 @@ -package game.command; +package server.command; import java.util.List; diff --git a/java/src/game/command/PatternReplacer.java b/java/src/server/command/PatternReplacer.java similarity index 98% rename from java/src/game/command/PatternReplacer.java rename to java/src/server/command/PatternReplacer.java index 0f064b8..685c94f 100644 --- a/java/src/game/command/PatternReplacer.java +++ b/java/src/server/command/PatternReplacer.java @@ -1,4 +1,4 @@ -package game.command; +package server.command; import java.util.function.Function; import java.util.regex.Matcher; diff --git a/java/src/game/command/PlayerEntityListParser.java b/java/src/server/command/PlayerEntityListParser.java similarity index 96% rename from java/src/game/command/PlayerEntityListParser.java rename to java/src/server/command/PlayerEntityListParser.java index 06335f6..45adab1 100644 --- a/java/src/game/command/PlayerEntityListParser.java +++ b/java/src/server/command/PlayerEntityListParser.java @@ -1,4 +1,4 @@ -package game.command; +package server.command; import java.util.Collection; import java.util.List; @@ -8,7 +8,7 @@ import game.collect.Lists; import game.collect.Sets; import game.entity.Entity; import game.entity.npc.EntityNPC; -import game.network.Player; +import server.network.Player; public class PlayerEntityListParser extends PlayerEntityParser { public PlayerEntityListParser(String name, boolean useSender) { diff --git a/java/src/game/command/PlayerEntityParser.java b/java/src/server/command/PlayerEntityParser.java similarity index 92% rename from java/src/game/command/PlayerEntityParser.java rename to java/src/server/command/PlayerEntityParser.java index 1239f06..f202478 100644 --- a/java/src/game/command/PlayerEntityParser.java +++ b/java/src/server/command/PlayerEntityParser.java @@ -1,7 +1,7 @@ -package game.command; +package server.command; import game.entity.npc.EntityNPC; -import game.network.Player; +import server.network.Player; public class PlayerEntityParser extends PlayerParser { public PlayerEntityParser(String name, boolean useSender) { diff --git a/java/src/game/command/PlayerListParser.java b/java/src/server/command/PlayerListParser.java similarity index 95% rename from java/src/game/command/PlayerListParser.java rename to java/src/server/command/PlayerListParser.java index a9a888f..3bc9d57 100644 --- a/java/src/game/command/PlayerListParser.java +++ b/java/src/server/command/PlayerListParser.java @@ -1,4 +1,4 @@ -package game.command; +package server.command; import java.util.Collection; import java.util.List; @@ -6,7 +6,7 @@ import java.util.Set; import game.collect.Lists; import game.collect.Sets; -import game.network.Player; +import server.network.Player; public class PlayerListParser extends PlayerParser { public PlayerListParser(String name, boolean useSender) { diff --git a/java/src/game/command/PlayerParser.java b/java/src/server/command/PlayerParser.java similarity index 93% rename from java/src/game/command/PlayerParser.java rename to java/src/server/command/PlayerParser.java index b9fc191..6e2cc07 100644 --- a/java/src/game/command/PlayerParser.java +++ b/java/src/server/command/PlayerParser.java @@ -1,8 +1,8 @@ -package game.command; +package server.command; import java.util.Collection; -import game.network.Player; +import server.network.Player; public class PlayerParser extends CompletingParser { protected final boolean useSender; diff --git a/java/src/game/command/RunException.java b/java/src/server/command/RunException.java similarity index 96% rename from java/src/game/command/RunException.java rename to java/src/server/command/RunException.java index ca97655..212af1c 100644 --- a/java/src/game/command/RunException.java +++ b/java/src/server/command/RunException.java @@ -1,4 +1,4 @@ -package game.command; +package server.command; public class RunException extends RuntimeException { public RunException(String desc) { diff --git a/java/src/game/command/StringCompleter.java b/java/src/server/command/StringCompleter.java similarity index 83% rename from java/src/game/command/StringCompleter.java rename to java/src/server/command/StringCompleter.java index 374bbb1..71cf5ce 100644 --- a/java/src/game/command/StringCompleter.java +++ b/java/src/server/command/StringCompleter.java @@ -1,4 +1,4 @@ -package game.command; +package server.command; import java.util.Collection; diff --git a/java/src/game/command/StringParser.java b/java/src/server/command/StringParser.java similarity index 99% rename from java/src/game/command/StringParser.java rename to java/src/server/command/StringParser.java index 1b3d636..b676e21 100644 --- a/java/src/game/command/StringParser.java +++ b/java/src/server/command/StringParser.java @@ -1,4 +1,4 @@ -package game.command; +package server.command; import java.util.Collection; diff --git a/java/src/game/command/TagParser.java b/java/src/server/command/TagParser.java similarity index 96% rename from java/src/game/command/TagParser.java rename to java/src/server/command/TagParser.java index 44327ff..ffef156 100644 --- a/java/src/game/command/TagParser.java +++ b/java/src/server/command/TagParser.java @@ -1,4 +1,4 @@ -package game.command; +package server.command; import game.nbt.NBTException; import game.nbt.NBTParser; diff --git a/java/src/game/command/Variable.java b/java/src/server/command/Variable.java similarity index 68% rename from java/src/game/command/Variable.java rename to java/src/server/command/Variable.java index 625aa39..46362ca 100644 --- a/java/src/game/command/Variable.java +++ b/java/src/server/command/Variable.java @@ -1,4 +1,4 @@ -package game.command; +package server.command; public interface Variable { public String get(); diff --git a/java/src/game/command/WorldParser.java b/java/src/server/command/WorldParser.java similarity index 98% rename from java/src/game/command/WorldParser.java rename to java/src/server/command/WorldParser.java index 2c32352..8659362 100644 --- a/java/src/game/command/WorldParser.java +++ b/java/src/server/command/WorldParser.java @@ -1,4 +1,4 @@ -package game.command; +package server.command; import java.util.Collection; import java.util.List; diff --git a/java/src/game/command/commands/CommandAdmin.java b/java/src/server/command/commands/CommandAdmin.java similarity index 74% rename from java/src/game/command/commands/CommandAdmin.java rename to java/src/server/command/commands/CommandAdmin.java index 813948b..49c155e 100644 --- a/java/src/game/command/commands/CommandAdmin.java +++ b/java/src/server/command/commands/CommandAdmin.java @@ -1,10 +1,10 @@ -package game.command.commands; +package server.command.commands; -import game.command.Command; -import game.command.CommandEnvironment; -import game.command.Executor; -import game.command.RunException; -import game.network.Player; +import server.command.Command; +import server.command.CommandEnvironment; +import server.command.Executor; +import server.command.RunException; +import server.network.Player; public class CommandAdmin extends Command { public CommandAdmin() { diff --git a/java/src/game/command/commands/CommandHelp.java b/java/src/server/command/commands/CommandHelp.java similarity index 88% rename from java/src/game/command/commands/CommandHelp.java rename to java/src/server/command/commands/CommandHelp.java index 5803721..2ec6e9d 100644 --- a/java/src/game/command/commands/CommandHelp.java +++ b/java/src/server/command/commands/CommandHelp.java @@ -1,17 +1,17 @@ -package game.command.commands; +package server.command.commands; import java.util.List; import java.util.Map.Entry; import java.util.function.Function; import game.collect.Lists; -import game.command.ArgumentParser; -import game.command.CachedExecutable; -import game.command.Command; -import game.command.CommandEnvironment; -import game.command.Executor; -import game.command.Parameter; import game.util.Util; +import server.command.ArgumentParser; +import server.command.CachedExecutable; +import server.command.Command; +import server.command.CommandEnvironment; +import server.command.Executor; +import server.command.Parameter; public class CommandHelp extends Command { public CommandHelp(CommandEnvironment env) { diff --git a/java/src/game/command/commands/CommandKick.java b/java/src/server/command/commands/CommandKick.java similarity index 75% rename from java/src/game/command/commands/CommandKick.java rename to java/src/server/command/commands/CommandKick.java index 26f054a..6785b09 100644 --- a/java/src/game/command/commands/CommandKick.java +++ b/java/src/server/command/commands/CommandKick.java @@ -1,10 +1,10 @@ -package game.command.commands; +package server.command.commands; -import game.command.Command; -import game.command.CommandEnvironment; -import game.command.Executor; -import game.command.RunException; -import game.network.Player; +import server.command.Command; +import server.command.CommandEnvironment; +import server.command.Executor; +import server.command.RunException; +import server.network.Player; public class CommandKick extends Command { public CommandKick() { diff --git a/java/src/game/command/commands/CommandMessage.java b/java/src/server/command/commands/CommandMessage.java similarity index 76% rename from java/src/game/command/commands/CommandMessage.java rename to java/src/server/command/commands/CommandMessage.java index 997258f..ba0fd94 100644 --- a/java/src/game/command/commands/CommandMessage.java +++ b/java/src/server/command/commands/CommandMessage.java @@ -1,9 +1,9 @@ -package game.command.commands; +package server.command.commands; -import game.command.Command; -import game.command.CommandEnvironment; -import game.command.Executor; import game.packet.SPacketMessage; +import server.command.Command; +import server.command.CommandEnvironment; +import server.command.Executor; public class CommandMessage extends Command { public CommandMessage() { diff --git a/java/src/game/command/commands/CommandMilk.java b/java/src/server/command/commands/CommandMilk.java similarity index 89% rename from java/src/game/command/commands/CommandMilk.java rename to java/src/server/command/commands/CommandMilk.java index a016afa..c858882 100644 --- a/java/src/game/command/commands/CommandMilk.java +++ b/java/src/server/command/commands/CommandMilk.java @@ -1,13 +1,13 @@ -package game.command.commands; +package server.command.commands; import java.util.List; import game.collect.Lists; -import game.command.Command; -import game.command.CommandEnvironment; -import game.command.Executor; import game.entity.types.EntityLiving; import game.potion.Potion; +import server.command.Command; +import server.command.CommandEnvironment; +import server.command.Executor; public class CommandMilk extends Command { public CommandMilk() { diff --git a/java/src/game/command/commands/CommandOfflinetp.java b/java/src/server/command/commands/CommandOfflinetp.java similarity index 83% rename from java/src/game/command/commands/CommandOfflinetp.java rename to java/src/server/command/commands/CommandOfflinetp.java index f4b7591..892bbb9 100644 --- a/java/src/game/command/commands/CommandOfflinetp.java +++ b/java/src/server/command/commands/CommandOfflinetp.java @@ -1,18 +1,18 @@ -package game.command.commands; +package server.command.commands; import java.util.Collection; import java.util.List; import game.collect.Lists; -import game.command.Command; -import game.command.CommandEnvironment; -import game.command.Executor; -import game.command.RunException; -import game.command.StringCompleter; import game.entity.Entity; import game.init.UniverseRegistry; -import game.network.Player; import game.world.Position; +import server.command.Command; +import server.command.CommandEnvironment; +import server.command.Executor; +import server.command.RunException; +import server.command.StringCompleter; +import server.network.Player; public class CommandOfflinetp extends Command { public CommandOfflinetp() { diff --git a/java/src/game/command/commands/CommandPotion.java b/java/src/server/command/commands/CommandPotion.java similarity index 91% rename from java/src/game/command/commands/CommandPotion.java rename to java/src/server/command/commands/CommandPotion.java index e5500e9..d3262ec 100644 --- a/java/src/game/command/commands/CommandPotion.java +++ b/java/src/server/command/commands/CommandPotion.java @@ -1,13 +1,13 @@ -package game.command.commands; +package server.command.commands; import java.util.List; -import game.command.Command; -import game.command.CommandEnvironment; -import game.command.Executor; import game.entity.types.EntityLiving; import game.potion.Potion; import game.potion.PotionEffect; +import server.command.Command; +import server.command.CommandEnvironment; +import server.command.Executor; public class CommandPotion extends Command { public CommandPotion() { diff --git a/java/src/game/command/commands/CommandRemove.java b/java/src/server/command/commands/CommandRemove.java similarity index 83% rename from java/src/game/command/commands/CommandRemove.java rename to java/src/server/command/commands/CommandRemove.java index fa43608..e3265f4 100644 --- a/java/src/game/command/commands/CommandRemove.java +++ b/java/src/server/command/commands/CommandRemove.java @@ -1,11 +1,11 @@ -package game.command.commands; +package server.command.commands; import java.util.List; -import game.command.Command; -import game.command.CommandEnvironment; -import game.command.Executor; import game.entity.Entity; +import server.command.Command; +import server.command.CommandEnvironment; +import server.command.Executor; public class CommandRemove extends Command { public CommandRemove() { diff --git a/java/src/game/command/commands/CommandRevoke.java b/java/src/server/command/commands/CommandRevoke.java similarity index 77% rename from java/src/game/command/commands/CommandRevoke.java rename to java/src/server/command/commands/CommandRevoke.java index 5269241..10c88d2 100644 --- a/java/src/game/command/commands/CommandRevoke.java +++ b/java/src/server/command/commands/CommandRevoke.java @@ -1,10 +1,10 @@ -package game.command.commands; +package server.command.commands; -import game.command.Command; -import game.command.CommandEnvironment; -import game.command.Executor; -import game.command.RunException; -import game.network.Player; +import server.command.Command; +import server.command.CommandEnvironment; +import server.command.Executor; +import server.command.RunException; +import server.network.Player; public class CommandRevoke extends Command { public CommandRevoke() { diff --git a/java/src/game/command/commands/CommandSpawn.java b/java/src/server/command/commands/CommandSpawn.java similarity index 93% rename from java/src/game/command/commands/CommandSpawn.java rename to java/src/server/command/commands/CommandSpawn.java index 0236021..74f3ffb 100644 --- a/java/src/game/command/commands/CommandSpawn.java +++ b/java/src/server/command/commands/CommandSpawn.java @@ -1,22 +1,22 @@ -package game.command.commands; +package server.command.commands; import java.util.List; import java.util.Set; import game.collect.Lists; import game.collect.Sets; -import game.command.Command; -import game.command.CommandEnvironment; -import game.command.Executor; -import game.command.RunException; import game.entity.Entity; import game.entity.types.EntityLiving; import game.init.EntityRegistry; import game.nbt.NBTTagCompound; -import game.network.Player; import game.util.Util; import game.world.Vec3; import game.world.WorldServer; +import server.command.Command; +import server.command.CommandEnvironment; +import server.command.Executor; +import server.command.RunException; +import server.network.Player; public class CommandSpawn extends Command { public CommandSpawn() { diff --git a/java/src/game/command/commands/CommandTele.java b/java/src/server/command/commands/CommandTele.java similarity index 88% rename from java/src/game/command/commands/CommandTele.java rename to java/src/server/command/commands/CommandTele.java index 82dbace..427111f 100644 --- a/java/src/game/command/commands/CommandTele.java +++ b/java/src/server/command/commands/CommandTele.java @@ -1,13 +1,13 @@ -package game.command.commands; +package server.command.commands; import java.util.List; -import game.command.Command; -import game.command.CommandEnvironment; -import game.command.Executor; import game.dimension.Dimension; import game.entity.Entity; import game.world.Vec3; +import server.command.Command; +import server.command.CommandEnvironment; +import server.command.Executor; public class CommandTele extends Command { public CommandTele() { diff --git a/java/src/game/command/commands/CommandTime.java b/java/src/server/command/commands/CommandTime.java similarity index 93% rename from java/src/game/command/commands/CommandTime.java rename to java/src/server/command/commands/CommandTime.java index 2df30de..2cedd0a 100644 --- a/java/src/game/command/commands/CommandTime.java +++ b/java/src/server/command/commands/CommandTime.java @@ -1,13 +1,13 @@ -package game.command.commands; +package server.command.commands; -import game.command.Command; -import game.command.CommandEnvironment; -import game.command.Executor; -import game.command.RunException; import game.dimension.Dimension; import game.item.ItemSpaceNavigator; import game.world.Position; import game.world.WorldServer; +import server.command.Command; +import server.command.CommandEnvironment; +import server.command.Executor; +import server.command.RunException; public class CommandTime extends Command { public CommandTime() { diff --git a/java/src/game/command/commands/CommandTp.java b/java/src/server/command/commands/CommandTp.java similarity index 83% rename from java/src/game/command/commands/CommandTp.java rename to java/src/server/command/commands/CommandTp.java index 0fbf23e..9011787 100644 --- a/java/src/game/command/commands/CommandTp.java +++ b/java/src/server/command/commands/CommandTp.java @@ -1,13 +1,13 @@ -package game.command.commands; +package server.command.commands; import java.util.List; -import game.command.Command; -import game.command.CommandEnvironment; -import game.command.Executor; import game.entity.Entity; import game.init.UniverseRegistry; import game.world.Position; +import server.command.Command; +import server.command.CommandEnvironment; +import server.command.Executor; public class CommandTp extends Command { public CommandTp() { diff --git a/java/src/game/command/commands/CommandWarp.java b/java/src/server/command/commands/CommandWarp.java similarity index 89% rename from java/src/game/command/commands/CommandWarp.java rename to java/src/server/command/commands/CommandWarp.java index 4cd5897..0e4802e 100644 --- a/java/src/game/command/commands/CommandWarp.java +++ b/java/src/server/command/commands/CommandWarp.java @@ -1,16 +1,16 @@ -package game.command.commands; +package server.command.commands; import java.util.Collection; import java.util.List; -import game.command.Command; -import game.command.CommandEnvironment; -import game.command.Executor; -import game.command.RunException; -import game.command.StringCompleter; import game.entity.Entity; import game.init.UniverseRegistry; import game.world.Position; +import server.command.Command; +import server.command.CommandEnvironment; +import server.command.Executor; +import server.command.RunException; +import server.command.StringCompleter; public class CommandWarp extends Command { public CommandWarp() { diff --git a/java/src/game/command/commands/CommandWeather.java b/java/src/server/command/commands/CommandWeather.java similarity index 83% rename from java/src/game/command/commands/CommandWeather.java rename to java/src/server/command/commands/CommandWeather.java index b8c1e45..2e8b8bd 100644 --- a/java/src/game/command/commands/CommandWeather.java +++ b/java/src/server/command/commands/CommandWeather.java @@ -1,11 +1,11 @@ -package game.command.commands; +package server.command.commands; -import game.command.Command; -import game.command.CommandEnvironment; -import game.command.Executor; -import game.command.RunException; import game.world.Weather; import game.world.WorldServer; +import server.command.Command; +import server.command.CommandEnvironment; +import server.command.Executor; +import server.command.RunException; public class CommandWeather extends Command { public CommandWeather() { diff --git a/java/src/game/command/commands/CommandWorld.java b/java/src/server/command/commands/CommandWorld.java similarity index 90% rename from java/src/game/command/commands/CommandWorld.java rename to java/src/server/command/commands/CommandWorld.java index 325c5f9..0fba0c4 100644 --- a/java/src/game/command/commands/CommandWorld.java +++ b/java/src/server/command/commands/CommandWorld.java @@ -1,13 +1,13 @@ -package game.command.commands; +package server.command.commands; import java.util.List; -import game.command.Command; -import game.command.CommandEnvironment; -import game.command.Executor; import game.entity.Entity; import game.world.BlockPos; import game.world.WorldServer; +import server.command.Command; +import server.command.CommandEnvironment; +import server.command.Executor; public class CommandWorld extends Command { public CommandWorld() { diff --git a/java/src/game/network/HandshakeHandler.java b/java/src/server/network/HandshakeHandler.java similarity index 84% rename from java/src/game/network/HandshakeHandler.java rename to java/src/server/network/HandshakeHandler.java index 51dd361..4d79d09 100755 --- a/java/src/game/network/HandshakeHandler.java +++ b/java/src/server/network/HandshakeHandler.java @@ -1,11 +1,15 @@ -package game.network; +package server.network; import game.init.Config; +import game.network.IHandshakeHandler; +import game.network.NetConnection; +import game.network.NetHandler; +import game.network.PacketRegistry; import game.packet.HPacketHandshake; import game.packet.RPacketDisconnect; import server.Server; -public class HandshakeHandler extends NetHandler +public class HandshakeHandler extends NetHandler implements IHandshakeHandler { private final Server server; private final NetConnection networkManager; diff --git a/java/src/game/network/LoginHandler.java b/java/src/server/network/LoginHandler.java similarity index 92% rename from java/src/game/network/LoginHandler.java rename to java/src/server/network/LoginHandler.java index 9aa117d..51d9e22 100755 --- a/java/src/game/network/LoginHandler.java +++ b/java/src/server/network/LoginHandler.java @@ -1,13 +1,17 @@ -package game.network; +package server.network; import game.color.TextColor; import game.init.Config; import game.log.Log; +import game.network.ILoginHandler; +import game.network.IPlayer; +import game.network.NetConnection; +import game.network.NetHandler; import game.packet.LPacketPasswordResponse; import game.packet.RPacketDisconnect; import server.Server; -public class LoginHandler extends NetHandler +public class LoginHandler extends NetHandler implements ILoginHandler { private static enum LoginState { PASSWORD, READY_TO_ACCEPT, ACCEPTED; @@ -104,7 +108,7 @@ public class LoginHandler extends NetHandler throw new IllegalStateException("Unerwartetes Passwort-Paket"); this.loginUser = packetIn.getUser(); this.loginPass = packetIn.getPassword(); - if(this.loginUser.isEmpty() || !Player.isValidUser(this.loginUser)) + if(this.loginUser.isEmpty() || !IPlayer.isValidUser(this.loginUser)) throw new IllegalStateException("Ungültiger Nutzername!"); // if(!this.checkConnect(packetIn.getAccess())) // return; diff --git a/java/src/game/network/Player.java b/java/src/server/network/Player.java similarity index 98% rename from java/src/game/network/Player.java rename to java/src/server/network/Player.java index eca1b80..97fab53 100755 --- a/java/src/game/network/Player.java +++ b/java/src/server/network/Player.java @@ -1,4 +1,4 @@ -package game.network; +package server.network; import java.util.Collections; import java.util.Iterator; @@ -20,7 +20,6 @@ import game.clipboard.RotationValue; import game.clipboard.Vector; import game.collect.Lists; import game.color.TextColor; -import game.command.Executor; import game.dimension.Dimension; import game.entity.Entity; import game.entity.animal.EntityHorse; @@ -58,6 +57,10 @@ import game.material.Material; import game.nbt.NBTTagCompound; import game.nbt.NBTTagList; import game.nbt.NBTTagString; +import game.network.IPlayer; +import game.network.NetConnection; +import game.network.NetHandler; +import game.network.Packet; import game.packet.CPacketAction; import game.packet.CPacketAction.Action; import game.packet.CPacketBook; @@ -111,7 +114,6 @@ import game.tileentity.ILockableContainer; import game.tileentity.TileEntity; import game.tileentity.TileEntityMachine; import game.tileentity.TileEntitySign; -import game.util.CharValidator; import game.util.ExtMath; import game.village.MerchantRecipeList; import game.world.BlockPos; @@ -131,8 +133,9 @@ import game.world.WorldServer; import io.netty.util.concurrent.Future; import io.netty.util.concurrent.GenericFutureListener; import server.Server; +import server.command.Executor; -public class Player extends NetHandler implements ICrafting, Executor +public class Player extends NetHandler implements ICrafting, Executor, IPlayer { private static enum EditAction { SELECT("Auswahlmodus"), COPYPASTE("Kopiermodus"), TRANSFORM("Drehmodus"); @@ -144,27 +147,6 @@ public class Player extends NetHandler implements ICrafting, Executor } } - public static class UserValidator implements CharValidator { - public boolean valid(char ch) { - return (ch >= 'a' && ch <= 'z') || (ch >= '0' && ch <= '9') || ch == '_' || ch == '-'; - } - } - - public static class NickValidator implements CharValidator { - public boolean valid(char ch) { - return (ch <= 0xff && Character.isLetterOrDigit(ch)) || (ch >= 32 && ch < 126); - } - } - - public static final int MAX_USER_LENGTH = 16; - public static final int MAX_NICK_LENGTH = 32; - public static final int MAX_PASS_LENGTH = 64; - public static final int MAX_CMD_LENGTH = 1024; - public static final int MAX_INFO_LENGTH = 4096; - - public static final CharValidator VALID_USER = new UserValidator(); - public static final CharValidator VALID_NICK = new NickValidator(); - private final NetConnection connection; private final Server server; private final String user; @@ -209,11 +191,11 @@ public class Player extends NetHandler implements ICrafting, Executor private int initialBlockDamage; private int durabilityRemainingOnBlock = -1; - public boolean isChangingQuantityOnly; + private boolean isChangingQuantityOnly; private int respawnTimer; - public double managedPosX; - public double managedPosZ; + private double managedPosX; + private double managedPosZ; private float combinedHealth = Float.MIN_VALUE; private float lastHealth = -1.0E8F; private int lastExperience = -99999999; @@ -222,20 +204,12 @@ public class Player extends NetHandler implements ICrafting, Executor private int pointedEntity; private BlockPos pointedPosition; - public final List loadedChunks = new LinkedList(); + private final List loadedChunks = new LinkedList(); private final List destroyedItemsNetCache = new LinkedList(); // private final Set statsQueue = Sets.newHashSet(); // private final Map stats = Maps.newConcurrentMap(); - public static boolean isValidUser(String user) { - return VALID_USER.valid(user); - } - - public static boolean isValidNick(String user) { - return VALID_NICK.valid(user); - } - - public Player(Server server, NetConnection connection, String user) + public Player(Server server, NetConnection connection, String user) { this.user = user; this.server = server; @@ -1997,13 +1971,13 @@ public class Player extends NetHandler implements ICrafting, Executor break; case DISPLAY: - if(msg.isEmpty() || !isValidNick(msg) || msg.length() > MAX_NICK_LENGTH) + if(msg.isEmpty() || !IPlayer.isValidNick(msg) || msg.length() > IPlayer.MAX_NICK_LENGTH) throw new IllegalArgumentException("Ungültiger Anzeigename"); this.entity.setCustomNameTag(msg); break; case INFO: - if(msg.length() > MAX_INFO_LENGTH) + if(msg.length() > IPlayer.MAX_INFO_LENGTH) throw new IllegalArgumentException("Ungültige Beschreibung"); this.entity.setDescription(msg.isEmpty() ? null : msg); break; @@ -3177,6 +3151,23 @@ public class Player extends NetHandler implements ICrafting, Executor public BlockPos getPointedPosition() { return this.pointedPosition; } + + public List getLoadedChunkList() { + return this.loadedChunks; + } + + public double getManagedX() { + return this.managedPosX; + } + + public double getManagedZ() { + return this.managedPosZ; + } + + public void setManagedPos(double x, double z) { + this.managedPosX = x; + this.managedPosZ = z; + } // public void processCmdBlock(CPacketCmdBlock packetIn) { // NetHandler.checkThread(packetIn, this, this.serverController); From d37bb7f6ccb9c0f1097ec16399a94048235a85f4 Mon Sep 17 00:00:00 2001 From: Sen Date: Mon, 5 May 2025 18:51:52 +0200 Subject: [PATCH 003/200] split client and server 3 --- java/src/client/Game.java | 53 +++++++++++++++++- java/src/client/network/ClientPlayer.java | 4 +- .../client/renderer/particle/EntityFX.java | 3 +- java/src/game/IClient.java | 24 ++++++++ java/src/game/IServer.java | 8 --- java/src/game/entity/types/IEntityFX.java | 11 ++++ java/src/game/world/WorldClient.java | 56 +++++++++---------- 7 files changed, 118 insertions(+), 41 deletions(-) create mode 100644 java/src/game/IClient.java create mode 100644 java/src/game/entity/types/IEntityFX.java diff --git a/java/src/client/Game.java b/java/src/client/Game.java index 2dc5fe7..f528cb0 100755 --- a/java/src/client/Game.java +++ b/java/src/client/Game.java @@ -65,6 +65,7 @@ import client.renderer.chunk.RenderChunk; import client.renderer.entity.RenderItem; import client.renderer.entity.RenderManager; import client.renderer.particle.EffectRenderer; +import client.renderer.particle.EntityFirework; import client.renderer.texture.EntityTexManager; import client.renderer.texture.TextureManager; import client.renderer.texture.TextureMap; @@ -76,6 +77,7 @@ import client.window.Keysym; import client.window.Wheel; import client.window.Window; import client.window.WindowEvent; +import game.IClient; import game.biome.Biome; import game.block.Block; import game.collect.Lists; @@ -87,6 +89,7 @@ import game.entity.animal.EntityHorse; import game.entity.npc.Energy; import game.entity.npc.EntityNPC; import game.entity.types.EntityLiving; +import game.entity.types.IEntityFX; import game.future.Futures; import game.future.ListenableFuture; import game.future.ListenableFutureTask; @@ -106,6 +109,7 @@ import game.log.Log; import game.log.LogLevel; import game.log.Message; import game.material.Material; +import game.nbt.NBTTagCompound; import game.network.IThreadListener; import game.network.NetConnection; import game.network.NetHandler.ThreadQuickExitException; @@ -122,6 +126,7 @@ import game.properties.IProperty; import game.rng.Random; import game.sound.EventType; import game.sound.PositionedSound; +import game.sound.Sound; import game.util.CharValidator; import game.util.ExtMath; import game.util.FileUtils; @@ -175,7 +180,7 @@ import game.world.WorldClient; [[oder einfach einen Toaster mit nem LCD und Maus]] */ -public class Game implements IThreadListener { +public class Game implements IThreadListener, IClient { public static class SyncFunction implements IntFunction { public void apply(IntVar cv, int value) { Game.getGame().sync(value); @@ -3275,4 +3280,50 @@ public class Game implements IThreadListener { } }, "Zenity listener").start(); } + + public void makeFireworks(double x, double y, double z, double motionX, double motionY, double motionZ, NBTTagCompound compund) + { + this.effectRenderer.addEffect(new EntityFirework.StarterFX(this.theWorld, x, y, z, motionX, motionY, motionZ, this.effectRenderer, compund)); + } + + public int getRenderDistance() { + return this.renderDistance; + } + + public float getGravity() { + return this.gravity; + } + + public int getTimeFactor() { + return this.timeFactor; + } + + public boolean hasDayCycle() { + return this.dayCycle; + } + + public void playSound(Sound sound) { + this.soundManager.playSound(sound); + } + + public EntityNPC getPlayer() { + return this.thePlayer; + } + + public IEntityFX spawnEffectParticle(int particleId, double xCoord, double yCoord, double zCoord, double xSpeed, double ySpeed, double zSpeed, + int[] parameters) { + return this.effectRenderer.spawnEffectParticle(particleId, xCoord, yCoord, zCoord, xSpeed, ySpeed, zSpeed, parameters); + } + + public void addBlockDestroyEffects(BlockPos pos, State state) { + this.effectRenderer.addBlockDestroyEffects(pos, state); + } + + public void sendBlockBreakProgress(int breakerId, BlockPos pos, int progress) { + this.renderGlobal.sendBlockBreakProgress(breakerId, pos, progress); + } + + public void markBlocksForUpdate(int x1, int y1, int z1, int x2, int y2, int z2) { + this.renderGlobal.markBlocksForUpdate(x1, y1, z1, x2, y2, z2); + } } diff --git a/java/src/client/network/ClientPlayer.java b/java/src/client/network/ClientPlayer.java index a94a2b3..78cc391 100755 --- a/java/src/client/network/ClientPlayer.java +++ b/java/src/client/network/ClientPlayer.java @@ -184,7 +184,7 @@ public class ClientPlayer extends NetHandler implements IClientPlayer NetHandler.checkThread(packetIn, this, this.gameController); this.gameController.charEditor = packetIn.isInEditor(); this.gameController.controller = new PlayerController(this.gameController, this); - this.clientWorldController = new WorldClient(this.gameController.debugWorld, packetIn.getDimension()); + this.clientWorldController = new WorldClient(this.gameController, this.gameController.debugWorld, packetIn.getDimension()); // this.gameController.gameSettings.difficulty = packetIn.getDifficulty(); this.gameController.loadWorld(this.clientWorldController, packetIn.getEntityType()); // this.gameController.thePlayer.dimension = this.clientWorldController.dimension.getDimensionId(); @@ -1046,7 +1046,7 @@ public class ClientPlayer extends NetHandler implements IClientPlayer // this.travelSound = "portal.travel"; // } // Scoreboard scoreboard = this.clientWorldController.getScoreboard(); - this.clientWorldController = new WorldClient(this.gameController.debugWorld, dim); + this.clientWorldController = new WorldClient(this.gameController, this.gameController.debugWorld, dim); // this.clientWorldController.setWorldScoreboard(scoreboard); this.gameController.loadWorld(this.clientWorldController, packetIn.getEntityType()); // this.gameController.thePlayer.dimension = dim.getDimensionId(); diff --git a/java/src/client/renderer/particle/EntityFX.java b/java/src/client/renderer/particle/EntityFX.java index c9a61f2..78f154d 100755 --- a/java/src/client/renderer/particle/EntityFX.java +++ b/java/src/client/renderer/particle/EntityFX.java @@ -5,11 +5,12 @@ import client.renderer.RenderBuffer; import client.renderer.texture.TextureAtlasSprite; import game.entity.Entity; import game.entity.EntityType; +import game.entity.types.IEntityFX; import game.nbt.NBTTagCompound; import game.util.ExtMath; import game.world.World; -public class EntityFX extends Entity +public class EntityFX extends Entity implements IEntityFX { protected int particleTextureIndexX; protected int particleTextureIndexY; diff --git a/java/src/game/IClient.java b/java/src/game/IClient.java new file mode 100644 index 0000000..9bec92c --- /dev/null +++ b/java/src/game/IClient.java @@ -0,0 +1,24 @@ +package game; + +import game.entity.Entity; +import game.entity.npc.EntityNPC; +import game.entity.types.IEntityFX; +import game.nbt.NBTTagCompound; +import game.sound.Sound; +import game.world.BlockPos; +import game.world.State; + +public interface IClient { + int getRenderDistance(); + float getGravity(); + int getTimeFactor(); + boolean hasDayCycle(); + void playSound(Sound sound); + EntityNPC getPlayer(); + Entity getRenderViewEntity(); + void makeFireworks(double x, double y, double z, double motionX, double motionY, double motionZ, NBTTagCompound compund); + IEntityFX spawnEffectParticle(int particleId, double xCoord, double yCoord, double zCoord, double xSpeed, double ySpeed, double zSpeed, int[] parameters); + void addBlockDestroyEffects(BlockPos pos, State state); + void sendBlockBreakProgress(int breakerId, BlockPos pos, int progress); + void markBlocksForUpdate(int x1, int y1, int z1, int x2, int y2, int z2); +} diff --git a/java/src/game/IServer.java b/java/src/game/IServer.java index 27dd5dd..bae8d70 100644 --- a/java/src/game/IServer.java +++ b/java/src/game/IServer.java @@ -14,20 +14,12 @@ import game.world.WorldServer; public interface IServer { List getIPlayers(); - void sendPacket(Packet packet); - void sendPacket(Packet packet, int dimension); - void sendNear(double x, double y, double z, double radius, int dimension, Packet packet); - void sendNearExcept(EntityNPC except, double x, double y, double z, double radius, int dimension, Packet packet); - Map getWarps(); - List getWorlds(); - WorldServer getWorld(int dimension); - void placeInDimension(Entity entity, WorldServer oldWorld, WorldServer world, BlockPos pos, PortalType portal); } \ No newline at end of file diff --git a/java/src/game/entity/types/IEntityFX.java b/java/src/game/entity/types/IEntityFX.java new file mode 100644 index 0000000..26b274f --- /dev/null +++ b/java/src/game/entity/types/IEntityFX.java @@ -0,0 +1,11 @@ +package game.entity.types; + +import client.renderer.particle.EntityFX; + +public interface IEntityFX { + + EntityFX multiplyVelocity(float multiplier); + + void setRBGColorF(float particleRedIn, float particleGreenIn, float particleBlueIn); + +} \ No newline at end of file diff --git a/java/src/game/world/WorldClient.java b/java/src/game/world/WorldClient.java index 6378f1f..e03a9cd 100755 --- a/java/src/game/world/WorldClient.java +++ b/java/src/game/world/WorldClient.java @@ -3,9 +3,7 @@ package game.world; import java.util.List; import java.util.Set; -import client.Game; -import client.renderer.particle.EntityFX; -import client.renderer.particle.EntityFirework; +import game.IClient; import game.biome.Biome; import game.block.Block; import game.collect.Lists; @@ -14,6 +12,7 @@ import game.dimension.Dimension; import game.entity.Entity; import game.entity.item.EntityCart; import game.entity.npc.EntityNPC; +import game.entity.types.IEntityFX; import game.init.BlockRegistry; import game.init.ItemRegistry; import game.init.Items; @@ -34,7 +33,7 @@ public class WorldClient extends World { private static final int DISPLAY_RANGE = 16; - private final Game gm = Game.getGame(); + private final IClient gm; private final Set entityList = Sets.newHashSet(); private final Set spawnQueue = Sets.newHashSet(); private final Set previousActive = Sets.newHashSet(); @@ -45,14 +44,14 @@ public class WorldClient extends World protected int lastLightning; protected Vec3 lightColor = new Vec3(0xffffff); - public WorldClient(boolean debug, Dimension dim) + public WorldClient(IClient gm, boolean debug, Dimension dim) { super(dim, true, debug); -// this.gm = profiler; + this.gm = gm; this.calculateInitialSkylight(); this.calculateInitialWeather(); - this.setGravity(this.gm.gravity); - this.setTimeFactor(this.gm.timeFactor); + this.setGravity(this.gm.getGravity()); + this.setTimeFactor(this.gm.getTimeFactor()); // this.setDifficulty(this.gm.difficulty); } @@ -60,7 +59,7 @@ public class WorldClient extends World { // this.info.tick(); - if (this.gm.dayCycle) + if (this.gm.hasDayCycle()) { this.daytime += this.timeFactor; } @@ -89,7 +88,7 @@ public class WorldClient extends World protected void updateBlocks() { - this.setActivePlayerChunksAndCheckLight(this.gm.renderDistance); + this.setActivePlayerChunksAndCheckLight(this.gm.getRenderDistance()); this.previousActive.retainAll(this.active); if (this.previousActive.size() == this.active.size()) @@ -157,7 +156,7 @@ public class WorldClient extends World } else if (entityIn instanceof EntityCart) { - this.gm.getSoundManager().playSound(new MovingSoundMinecart((EntityCart)entityIn)); + this.gm.playSound(new MovingSoundMinecart((EntityCart)entityIn)); } return flag; @@ -217,7 +216,7 @@ public class WorldClient extends World public Entity getEntityByID(int id) { - return (Entity)(id == this.gm.thePlayer.getId() ? this.gm.thePlayer : super.getEntityByID(id)); + return (Entity)(id == this.gm.getPlayer().getId() ? this.gm.getPlayer() : super.getEntityByID(id)); } public Entity removeEntityFromWorld(int entityID) @@ -335,13 +334,13 @@ public class WorldClient extends World // } // else // { - this.gm.getSoundManager().playSound(positionedsoundrecord); + this.gm.playSound(positionedsoundrecord); // } } public void makeFireworks(double x, double y, double z, double motionX, double motionY, double motionZ, NBTTagCompound compund) { - this.gm.effectRenderer.addEffect(new EntityFirework.StarterFX(this, x, y, z, motionX, motionY, motionZ, this.gm.effectRenderer, compund)); + this.gm.makeFireworks(x, y, z, motionX, motionY, motionZ, compund); } public Chunk getChunk(int x, int z) @@ -370,9 +369,9 @@ public class WorldClient extends World this.spawnEntityFX(particleType, particleType.getShouldIgnoreRange(), xCoord, yCoord, zCoord, xOffset, yOffset, zOffset, data); } - public EntityFX spawnEntityFX(ParticleType particle, boolean ignoreRange, double xCoord, double yCoord, double zCoord, double xOffset, double yOffset, double zOffset, int[] parameters) + public IEntityFX spawnEntityFX(ParticleType particle, boolean ignoreRange, double xCoord, double yCoord, double zCoord, double xOffset, double yOffset, double zOffset, int[] parameters) { - if (this.gm != null && this.gm.getRenderViewEntity() != null && this.gm.effectRenderer != null) + if (this.gm.getRenderViewEntity() != null) { int particleID = particle.getParticleID(); // int i = this.gm.particleSetting; @@ -388,18 +387,17 @@ public class WorldClient extends World if (ignoreRange) { - return this.gm.effectRenderer.spawnEffectParticle(particleID, xCoord, yCoord, zCoord, xOffset, yOffset, zOffset, parameters); + return this.gm.spawnEffectParticle(particleID, xCoord, yCoord, zCoord, xOffset, yOffset, zOffset, parameters); } else { double d3 = 16.0D; - return d0 * d0 + d1 * d1 + d2 * d2 > 256.0D ? null : (/* i > 1 ? null : */ this.gm.effectRenderer.spawnEffectParticle(particleID, xCoord, yCoord, zCoord, xOffset, yOffset, zOffset, parameters)); + if(d0 * d0 + d1 * d1 + d2 * d2 > 256.0D) + return null; + return this.gm.spawnEffectParticle(particleID, xCoord, yCoord, zCoord, xOffset, yOffset, zOffset, parameters); } } - else - { - return null; - } + return null; } // public void broadcastSound(int soundID, BlockPos pos, int data) @@ -583,10 +581,10 @@ public class WorldClient extends World if (block.getMaterial() != Material.air) { - this.gm.getSoundManager().playSound(new PositionedSound(block.sound.getBreakSound(), 1.0F, /* block.sound.getFrequency() * 0.8F, */ (float)blockPosIn.getX() + 0.5F, (float)blockPosIn.getY() + 0.5F, (float)blockPosIn.getZ() + 0.5F)); + this.gm.playSound(new PositionedSound(block.sound.getBreakSound(), 1.0F, /* block.sound.getFrequency() * 0.8F, */ (float)blockPosIn.getX() + 0.5F, (float)blockPosIn.getY() + 0.5F, (float)blockPosIn.getZ() + 0.5F)); } - this.gm.effectRenderer.addBlockDestroyEffects(blockPosIn, block.getStateFromMeta(data >> 12 & 255)); + this.gm.addBlockDestroyEffects(blockPosIn, block.getStateFromMeta(data >> 12 & 255)); break; case 2002: @@ -623,7 +621,7 @@ public class WorldClient extends World double d24 = Math.cos(d23) * d22; double d9 = 0.01D + this.rand.doublev() * 0.5D; double d11 = Math.sin(d23) * d22; - EntityFX entityfx = this.spawnEntityFX(enumparticletypes, enumparticletypes.getShouldIgnoreRange(), d13 + d24 * 0.1D, d14 + 0.3D, d16 + d11 * 0.1D, d24, d9, d11, new int[0]); + IEntityFX entityfx = this.spawnEntityFX(enumparticletypes, enumparticletypes.getShouldIgnoreRange(), d13 + d24 * 0.1D, d14 + 0.3D, d16 + d11 * 0.1D, d24, d9, d11, new int[0]); if (entityfx != null) { @@ -660,7 +658,7 @@ public class WorldClient extends World int i = pos.getX(); int j = pos.getY(); int k = pos.getZ(); - this.gm.renderGlobal.markBlocksForUpdate(i - 1, j - 1, k - 1, i + 1, j + 1, k + 1); + this.gm.markBlocksForUpdate(i - 1, j - 1, k - 1, i + 1, j + 1, k + 1); } public void notifyLightSet(BlockPos pos) @@ -668,17 +666,17 @@ public class WorldClient extends World int i = pos.getX(); int j = pos.getY(); int k = pos.getZ(); - this.gm.renderGlobal.markBlocksForUpdate(i - 1, j - 1, k - 1, i + 1, j + 1, k + 1); + this.gm.markBlocksForUpdate(i - 1, j - 1, k - 1, i + 1, j + 1, k + 1); } public void markBlockRangeForRenderUpdate(int x1, int y1, int z1, int x2, int y2, int z2) { - this.gm.renderGlobal.markBlocksForUpdate(x1 - 1, y1 - 1, z1 - 1, x2 + 1, y2 + 1, z2 + 1); + this.gm.markBlocksForUpdate(x1 - 1, y1 - 1, z1 - 1, x2 + 1, y2 + 1, z2 + 1); } public void sendBlockBreakProgress(int breakerId, BlockPos pos, int progress) { - this.gm.renderGlobal.sendBlockBreakProgress(breakerId, pos, progress); + this.gm.sendBlockBreakProgress(breakerId, pos, progress); } public float getSunBrightness(float p_72971_1_) { From a6b0f110b1fdce5142257ffa773b83b86772a9b4 Mon Sep 17 00:00:00 2001 From: Sen Date: Tue, 6 May 2025 13:32:30 +0200 Subject: [PATCH 004/200] split client and server 5 --- {java => client}/src/client/Game.java | 0 {java => client}/src/client/PerfSection.java | 0 .../src/client/PlayerController.java | 0 {java => client}/src/client/SkinConverter.java | 0 {java => client}/src/client/Timing.java | 0 .../src/client/audio/AudioInterface.java | 0 .../src/client/audio/CodecJOrbis.java | 0 .../src/client/audio/SoundManager.java | 0 {java => client}/src/client/audio/Volume.java | 0 .../src/client/audio/jogg/Buffer.java | 0 .../src/client/audio/jogg/Packet.java | 0 .../src/client/audio/jogg/Page.java | 0 .../src/client/audio/jogg/StreamState.java | 0 .../src/client/audio/jogg/SyncState.java | 0 .../src/client/audio/jorbis/Block.java | 0 .../client/audio/jorbis/ChainingExample.java | 0 .../src/client/audio/jorbis/CodeBook.java | 0 .../src/client/audio/jorbis/Comment.java | 0 .../src/client/audio/jorbis/DecodeExample.java | 0 .../src/client/audio/jorbis/Drft.java | 0 .../src/client/audio/jorbis/DspState.java | 0 .../src/client/audio/jorbis/Floor0.java | 0 .../src/client/audio/jorbis/Floor1.java | 0 .../src/client/audio/jorbis/FuncFloor.java | 0 .../src/client/audio/jorbis/FuncMapping.java | 0 .../src/client/audio/jorbis/FuncResidue.java | 0 .../src/client/audio/jorbis/FuncTime.java | 0 .../src/client/audio/jorbis/Info.java | 0 .../src/client/audio/jorbis/InfoMode.java | 0 .../client/audio/jorbis/JOrbisException.java | 0 .../src/client/audio/jorbis/Lookup.java | 0 .../src/client/audio/jorbis/Lpc.java | 0 .../src/client/audio/jorbis/Lsp.java | 0 .../src/client/audio/jorbis/Mapping0.java | 0 .../src/client/audio/jorbis/Mdct.java | 0 .../src/client/audio/jorbis/PsyInfo.java | 0 .../src/client/audio/jorbis/PsyLook.java | 0 .../src/client/audio/jorbis/Residue0.java | 0 .../src/client/audio/jorbis/Residue1.java | 0 .../src/client/audio/jorbis/Residue2.java | 0 .../client/audio/jorbis/StaticCodeBook.java | 0 .../src/client/audio/jorbis/Time0.java | 0 .../src/client/audio/jorbis/Util.java | 0 .../src/client/audio/jorbis/VorbisFile.java | 0 .../src/client/gui/FileCallback.java | 0 {java => client}/src/client/gui/Font.java | 0 {java => client}/src/client/gui/FontChar.java | 0 {java => client}/src/client/gui/Formatter.java | 0 {java => client}/src/client/gui/Gui.java | 0 .../src/client/gui/GuiConfirm.java | 0 .../src/client/gui/GuiConnect.java | 0 .../src/client/gui/GuiConsole.java | 0 .../src/client/gui/GuiConvert.java | 0 {java => client}/src/client/gui/GuiInfo.java | 0 .../src/client/gui/GuiLoading.java | 0 {java => client}/src/client/gui/GuiMenu.java | 0 {java => client}/src/client/gui/GuiServer.java | 0 {java => client}/src/client/gui/Splashes.java | 0 {java => client}/src/client/gui/Style.java | 0 .../src/client/gui/character/GuiChar.java | 0 .../client/gui/character/GuiCharacters.java | 0 .../src/client/gui/character/GuiClass.java | 0 .../src/client/gui/character/GuiSpecies.java | 0 .../src/client/gui/container/GuiBrewing.java | 0 .../src/client/gui/container/GuiChest.java | 0 .../src/client/gui/container/GuiContainer.java | 0 .../src/client/gui/container/GuiCrafting.java | 0 .../src/client/gui/container/GuiDispenser.java | 0 .../src/client/gui/container/GuiEnchant.java | 0 .../src/client/gui/container/GuiFurnace.java | 0 .../src/client/gui/container/GuiHopper.java | 0 .../src/client/gui/container/GuiHorse.java | 0 .../src/client/gui/container/GuiInventory.java | 0 .../src/client/gui/container/GuiMachine.java | 0 .../src/client/gui/container/GuiMerchant.java | 0 .../src/client/gui/container/GuiRepair.java | 0 .../src/client/gui/element/ActButton.java | 0 .../src/client/gui/element/Bar.java | 0 .../src/client/gui/element/Dropdown.java | 0 .../src/client/gui/element/Element.java | 0 .../src/client/gui/element/Fill.java | 0 .../src/client/gui/element/GuiList.java | 0 .../client/gui/element/InventoryButton.java | 0 .../src/client/gui/element/Label.java | 0 .../src/client/gui/element/ListEntry.java | 0 .../src/client/gui/element/NavButton.java | 0 .../client/gui/element/SelectableButton.java | 0 .../src/client/gui/element/Slider.java | 0 .../src/client/gui/element/Switch.java | 0 .../src/client/gui/element/Textbox.java | 0 .../src/client/gui/element/Toggle.java | 0 .../src/client/gui/element/TransparentBox.java | 0 .../src/client/gui/ingame/GuiGameOver.java | 0 .../src/client/gui/ingame/GuiSign.java | 0 .../src/client/gui/options/GuiBinds.java | 0 .../src/client/gui/options/GuiDisplay.java | 0 .../src/client/gui/options/GuiOptions.java | 0 .../src/client/gui/options/GuiSound.java | 0 .../src/client/gui/options/GuiStyle.java | 0 .../src/client/init/EntityRenderRegistry.java | 0 .../src/client/network/ClientLoginHandler.java | 0 .../src/client/network/ClientPlayer.java | 0 .../src/client/renderer/ActiveRenderInfo.java | 0 .../src/client/renderer/BlockRenderer.java | 0 .../client/renderer/DefaultVertexFormats.java | 0 .../src/client/renderer/Drawing.java | 0 .../src/client/renderer/EntityRenderer.java | 0 .../src/client/renderer/Frustum.java | 0 .../src/client/renderer/GlState.java | 0 .../src/client/renderer/ItemModelMesher.java | 0 .../src/client/renderer/ItemRenderer.java | 0 .../src/client/renderer/Project.java | 0 .../src/client/renderer/RegionRenderCache.java | 0 .../renderer/RegionRenderCacheBuilder.java | 0 .../src/client/renderer/RenderBuffer.java | 0 .../src/client/renderer/RenderGlobal.java | 0 .../src/client/renderer/Tessellator.java | 0 .../src/client/renderer/VertexBuffer.java | 0 .../src/client/renderer/VertexFormat.java | 0 .../client/renderer/VertexFormatElement.java | 0 .../src/client/renderer/ViewFrustum.java | 0 .../client/renderer/blockmodel/BakedModel.java | 0 .../client/renderer/blockmodel/BakedQuad.java | 0 .../renderer/blockmodel/BlockFaceUV.java | 0 .../client/renderer/blockmodel/BlockPart.java | 0 .../renderer/blockmodel/BlockPartFace.java | 0 .../renderer/blockmodel/BlockPartRotation.java | 0 .../renderer/blockmodel/BreakingFour.java | 0 .../renderer/blockmodel/BuiltInModel.java | 0 .../client/renderer/blockmodel/FaceBakery.java | 0 .../renderer/blockmodel/IBakedModel.java | 0 .../renderer/blockmodel/ModelBakery.java | 0 .../client/renderer/blockmodel/ModelBlock.java | 0 .../renderer/blockmodel/ModelGenerator.java | 0 .../renderer/blockmodel/ModelManager.java | 0 .../renderer/blockmodel/MultiStateMap.java | 0 .../renderer/blockmodel/SingleStateMap.java | 0 .../client/renderer/blockmodel/StateMap.java | 0 .../chunk/ChunkCompileTaskGenerator.java | 0 .../renderer/chunk/ChunkRenderDispatcher.java | 0 .../renderer/chunk/ChunkRenderWorker.java | 0 .../client/renderer/chunk/CompiledChunk.java | 0 .../src/client/renderer/chunk/RenderChunk.java | 0 .../client/renderer/chunk/SetVisibility.java | 0 .../src/client/renderer/chunk/VisGraph.java | 0 .../src/client/renderer/entity/Render.java | 0 .../renderer/entity/RenderArachnoid.java | 0 .../client/renderer/entity/RenderArrow.java | 0 .../src/client/renderer/entity/RenderBat.java | 0 .../renderer/entity/RenderBlockEntity.java | 0 .../src/client/renderer/entity/RenderBoat.java | 0 .../client/renderer/entity/RenderBullet.java | 0 .../client/renderer/entity/RenderChicken.java | 0 .../src/client/renderer/entity/RenderCow.java | 0 .../client/renderer/entity/RenderCrystal.java | 0 .../src/client/renderer/entity/RenderDie.java | 0 .../client/renderer/entity/RenderDragon.java | 0 .../client/renderer/entity/RenderDynamite.java | 0 .../client/renderer/entity/RenderEntity.java | 0 .../renderer/entity/RenderEntityItem.java | 0 .../renderer/entity/RenderFallingBlock.java | 0 .../client/renderer/entity/RenderFireball.java | 0 .../src/client/renderer/entity/RenderFish.java | 0 .../renderer/entity/RenderFlyingBox.java | 0 .../client/renderer/entity/RenderHorse.java | 0 .../client/renderer/entity/RenderHumanoid.java | 0 .../src/client/renderer/entity/RenderItem.java | 0 .../renderer/entity/RenderItemEntity.java | 0 .../renderer/entity/RenderLeashKnot.java | 0 .../renderer/entity/RenderLightning.java | 0 .../client/renderer/entity/RenderLiving.java | 0 .../client/renderer/entity/RenderManager.java | 0 .../client/renderer/entity/RenderMinecart.java | 0 .../renderer/entity/RenderMooshroom.java | 0 .../client/renderer/entity/RenderMouse.java | 0 .../src/client/renderer/entity/RenderNpc.java | 0 .../client/renderer/entity/RenderOcelot.java | 0 .../src/client/renderer/entity/RenderPig.java | 0 .../client/renderer/entity/RenderPotion.java | 0 .../client/renderer/entity/RenderRabbit.java | 0 .../client/renderer/entity/RenderSheep.java | 0 .../client/renderer/entity/RenderSlime.java | 0 .../renderer/entity/RenderSpaceMarine.java | 0 .../client/renderer/entity/RenderSquid.java | 0 .../renderer/entity/RenderTntMinecart.java | 0 .../renderer/entity/RenderTntPrimed.java | 0 .../src/client/renderer/entity/RenderWolf.java | 0 .../client/renderer/entity/RenderXpOrb.java | 0 .../renderer/entity/RendererLivingEntity.java | 0 .../renderer/layers/LayerArachnoidArmor.java | 0 .../src/client/renderer/layers/LayerArmor.java | 0 .../src/client/renderer/layers/LayerArrow.java | 0 .../src/client/renderer/layers/LayerCape.java | 0 .../client/renderer/layers/LayerCharge.java | 0 .../renderer/layers/LayerEnderDragonEyes.java | 0 .../renderer/layers/LayerEntityBreak.java | 0 .../src/client/renderer/layers/LayerExtra.java | 0 .../client/renderer/layers/LayerHeldItem.java | 0 .../layers/LayerMooshroomMushroom.java | 0 .../client/renderer/layers/LayerPowerRods.java | 0 .../client/renderer/layers/LayerRenderer.java | 0 .../client/renderer/layers/LayerSaddle.java | 0 .../client/renderer/layers/LayerSheepWool.java | 0 .../client/renderer/layers/LayerSlimeGel.java | 0 .../renderer/layers/LayerWolfCollar.java | 0 .../client/renderer/model/ModelArachnoid.java | 0 .../src/client/renderer/model/ModelArmor.java | 0 .../src/client/renderer/model/ModelBanner.java | 0 .../src/client/renderer/model/ModelBase.java | 0 .../src/client/renderer/model/ModelBat.java | 0 .../src/client/renderer/model/ModelBiped.java | 0 .../src/client/renderer/model/ModelBoat.java | 0 .../src/client/renderer/model/ModelBox.java | 0 .../src/client/renderer/model/ModelCharge.java | 0 .../src/client/renderer/model/ModelChest.java | 0 .../client/renderer/model/ModelChicken.java | 0 .../src/client/renderer/model/ModelCow.java | 0 .../client/renderer/model/ModelCrystal.java | 0 .../src/client/renderer/model/ModelDie.java | 0 .../src/client/renderer/model/ModelDragon.java | 0 .../src/client/renderer/model/ModelHead.java | 0 .../src/client/renderer/model/ModelHorse.java | 0 .../client/renderer/model/ModelHumanoid.java | 0 .../renderer/model/ModelHumanoidHead.java | 0 .../client/renderer/model/ModelLargeChest.java | 0 .../client/renderer/model/ModelLeashKnot.java | 0 .../client/renderer/model/ModelMinecart.java | 0 .../src/client/renderer/model/ModelMouse.java | 0 .../src/client/renderer/model/ModelOcelot.java | 0 .../src/client/renderer/model/ModelPig.java | 0 .../client/renderer/model/ModelQuadruped.java | 0 .../src/client/renderer/model/ModelRabbit.java | 0 .../client/renderer/model/ModelRenderer.java | 0 .../src/client/renderer/model/ModelSheep1.java | 0 .../src/client/renderer/model/ModelSheep2.java | 0 .../src/client/renderer/model/ModelSign.java | 0 .../src/client/renderer/model/ModelSlime.java | 0 .../renderer/model/ModelSpaceMarine.java | 0 .../src/client/renderer/model/ModelSquid.java | 0 .../src/client/renderer/model/ModelWolf.java | 0 .../renderer/model/PositionTextureVertex.java | 0 .../client/renderer/model/TextureOffset.java | 0 .../client/renderer/model/TexturedQuad.java | 0 .../renderer/particle/EffectRenderer.java | 0 .../client/renderer/particle/EntityAuraFX.java | 0 .../renderer/particle/EntityBlockDustFX.java | 0 .../renderer/particle/EntityBreakingFX.java | 0 .../renderer/particle/EntityBubbleFX.java | 0 .../renderer/particle/EntityCloudFX.java | 0 .../renderer/particle/EntityCrit2FX.java | 0 .../client/renderer/particle/EntityCritFX.java | 0 .../renderer/particle/EntityDiggingFX.java | 0 .../renderer/particle/EntityDownfallFX.java | 0 .../particle/EntityDropParticleFX.java | 0 .../EntityEnchantmentTableParticleFX.java | 0 .../renderer/particle/EntityExplodeFX.java | 0 .../src/client/renderer/particle/EntityFX.java | 0 .../renderer/particle/EntityFirework.java | 0 .../renderer/particle/EntityFishWakeFX.java | 0 .../renderer/particle/EntityFlameFX.java | 0 .../renderer/particle/EntityFootStepFX.java | 0 .../renderer/particle/EntityHeartFX.java | 0 .../renderer/particle/EntityHugeExplodeFX.java | 0 .../particle/EntityLargeExplodeFX.java | 0 .../client/renderer/particle/EntityLavaFX.java | 0 .../client/renderer/particle/EntityNoteFX.java | 0 .../particle/EntityParticleEmitter.java | 0 .../renderer/particle/EntityPickupFX.java | 0 .../renderer/particle/EntityPortalFX.java | 0 .../renderer/particle/EntityReddustFX.java | 0 .../renderer/particle/EntitySmokeFX.java | 0 .../renderer/particle/EntitySnowShovelFX.java | 0 .../particle/EntitySpellParticleFX.java | 0 .../renderer/particle/EntitySplashFX.java | 0 .../renderer/particle/EntitySuspendFX.java | 0 .../renderer/particle/IParticleFactory.java | 0 .../renderer/texture/DynamicTexture.java | 0 .../renderer/texture/EntityTexManager.java | 0 .../client/renderer/texture/IIconCreator.java | 0 .../texture/LayeredColorMaskTexture.java | 0 .../renderer/texture/LayeredTexture.java | 0 .../client/renderer/texture/SimpleTexture.java | 0 .../src/client/renderer/texture/Stitcher.java | 0 .../src/client/renderer/texture/Texture.java | 0 .../renderer/texture/TextureAtlasSprite.java | 0 .../renderer/texture/TextureManager.java | 0 .../client/renderer/texture/TextureMap.java | 0 .../client/renderer/texture/TextureTicked.java | 0 .../client/renderer/texture/TextureUtil.java | 0 .../renderer/ticked/TextureFlamesFX1.java | 0 .../renderer/ticked/TextureFlamesFX2.java | 0 .../client/renderer/ticked/TextureLavaFX.java | 0 .../renderer/ticked/TextureLavaFlowFX.java | 0 .../client/renderer/ticked/TextureWaterFX.java | 0 .../renderer/ticked/TextureWaterFlowFX.java | 0 .../tileentity/TileEntityBannerRenderer.java | 0 .../tileentity/TileEntityChestRenderer.java | 0 .../TileEntityItemStackRenderer.java | 0 .../TileEntityMobSpawnerRenderer.java | 0 .../tileentity/TileEntityPistonRenderer.java | 0 .../TileEntityRendererDispatcher.java | 0 .../tileentity/TileEntitySignRenderer.java | 0 .../tileentity/TileEntitySkullRenderer.java | 0 .../tileentity/TileEntitySpecialRenderer.java | 0 {java => client}/src/client/window/Bind.java | 0 {java => client}/src/client/window/Button.java | 0 .../src/client/window/DisplayMode.java | 0 {java => client}/src/client/window/Input.java | 0 .../src/client/window/KeyEvent.java | 0 {java => client}/src/client/window/Keysym.java | 0 {java => client}/src/client/window/Wheel.java | 0 {java => client}/src/client/window/Window.java | 0 .../src/client/window/WindowAction.java | 0 .../src/client/window/WindowEvent.java | 0 {java => client}/src/game/vars/BaseVar.java | 0 {java => client}/src/game/vars/BoolVar.java | 0 {java => client}/src/game/vars/CVar.java | 0 .../src/game/vars/CVarCategory.java | 0 {java => client}/src/game/vars/ColorVar.java | 0 {java => client}/src/game/vars/EnumVar.java | 0 {java => client}/src/game/vars/FloatVar.java | 0 {java => client}/src/game/vars/IntVar.java | 0 {java => client}/src/game/vars/StringVar.java | 0 {java => client}/src/game/vars/Variable.java | 0 {java => client}/src/game/world/Converter.java | 18 +----------------- java/src/game/init/Config.java | 10 +++++----- java/src/game/world/Region.java | 18 +++++++++++++++++- {java => server}/src/server/Server.java | 0 .../src/server/command/ArgCombiner.java | 0 .../src/server/command/Argument.java | 0 .../src/server/command/ArgumentParser.java | 0 .../src/server/command/ArgumentSplitter.java | 0 .../src/server/command/BooleanParser.java | 0 .../src/server/command/CachedExecutable.java | 0 .../src/server/command/ColorParser.java | 0 .../src/server/command/Command.java | 0 .../src/server/command/CommandEnvironment.java | 0 .../src/server/command/Completer.java | 0 .../src/server/command/CompletingParser.java | 0 .../src/server/command/DefaultingParser.java | 0 .../src/server/command/DimensionParser.java | 0 .../src/server/command/DoubleParser.java | 0 .../src/server/command/EntityListParser.java | 0 .../src/server/command/EntityParser.java | 0 .../src/server/command/EnumParser.java | 0 .../src/server/command/Executable.java | 0 .../src/server/command/Executor.java | 0 .../src/server/command/FixedExecutor.java | 0 .../src/server/command/IntParser.java | 0 .../src/server/command/LongParser.java | 0 .../server/command/NonDefaultingParser.java | 0 .../src/server/command/Parameter.java | 0 .../src/server/command/PatternReplacer.java | 0 .../server/command/PlayerEntityListParser.java | 0 .../src/server/command/PlayerEntityParser.java | 0 .../src/server/command/PlayerListParser.java | 0 .../src/server/command/PlayerParser.java | 0 .../src/server/command/RunException.java | 0 .../src/server/command/StringCompleter.java | 0 .../src/server/command/StringParser.java | 0 .../src/server/command/TagParser.java | 0 .../src/server/command/Variable.java | 0 .../src/server/command/WorldParser.java | 0 .../server/command/commands/CommandAdmin.java | 0 .../server/command/commands/CommandHelp.java | 0 .../server/command/commands/CommandKick.java | 0 .../command/commands/CommandMessage.java | 0 .../server/command/commands/CommandMilk.java | 0 .../command/commands/CommandOfflinetp.java | 0 .../server/command/commands/CommandPotion.java | 0 .../server/command/commands/CommandRemove.java | 0 .../server/command/commands/CommandRevoke.java | 0 .../server/command/commands/CommandSpawn.java | 0 .../server/command/commands/CommandTele.java | 0 .../server/command/commands/CommandTime.java | 0 .../src/server/command/commands/CommandTp.java | 0 .../server/command/commands/CommandWarp.java | 0 .../command/commands/CommandWeather.java | 0 .../server/command/commands/CommandWorld.java | 0 .../src/server/network/HandshakeHandler.java | 0 .../src/server/network/LoginHandler.java | 0 .../src/server/network/Player.java | 0 382 files changed, 23 insertions(+), 23 deletions(-) rename {java => client}/src/client/Game.java (100%) rename {java => client}/src/client/PerfSection.java (100%) rename {java => client}/src/client/PlayerController.java (100%) rename {java => client}/src/client/SkinConverter.java (100%) rename {java => client}/src/client/Timing.java (100%) rename {java => client}/src/client/audio/AudioInterface.java (100%) rename {java => client}/src/client/audio/CodecJOrbis.java (100%) rename {java => client}/src/client/audio/SoundManager.java (100%) rename {java => client}/src/client/audio/Volume.java (100%) rename {java => client}/src/client/audio/jogg/Buffer.java (100%) rename {java => client}/src/client/audio/jogg/Packet.java (100%) rename {java => client}/src/client/audio/jogg/Page.java (100%) rename {java => client}/src/client/audio/jogg/StreamState.java (100%) rename {java => client}/src/client/audio/jogg/SyncState.java (100%) rename {java => client}/src/client/audio/jorbis/Block.java (100%) rename {java => client}/src/client/audio/jorbis/ChainingExample.java (100%) rename {java => client}/src/client/audio/jorbis/CodeBook.java (100%) rename {java => client}/src/client/audio/jorbis/Comment.java (100%) rename {java => client}/src/client/audio/jorbis/DecodeExample.java (100%) rename {java => client}/src/client/audio/jorbis/Drft.java (100%) rename {java => client}/src/client/audio/jorbis/DspState.java (100%) rename {java => client}/src/client/audio/jorbis/Floor0.java (100%) rename {java => client}/src/client/audio/jorbis/Floor1.java (100%) rename {java => client}/src/client/audio/jorbis/FuncFloor.java (100%) rename {java => client}/src/client/audio/jorbis/FuncMapping.java (100%) rename {java => client}/src/client/audio/jorbis/FuncResidue.java (100%) rename {java => client}/src/client/audio/jorbis/FuncTime.java (100%) rename {java => client}/src/client/audio/jorbis/Info.java (100%) rename {java => client}/src/client/audio/jorbis/InfoMode.java (100%) rename {java => client}/src/client/audio/jorbis/JOrbisException.java (100%) rename {java => client}/src/client/audio/jorbis/Lookup.java (100%) rename {java => client}/src/client/audio/jorbis/Lpc.java (100%) rename {java => client}/src/client/audio/jorbis/Lsp.java (100%) rename {java => client}/src/client/audio/jorbis/Mapping0.java (100%) rename {java => client}/src/client/audio/jorbis/Mdct.java (100%) rename {java => client}/src/client/audio/jorbis/PsyInfo.java (100%) rename {java => client}/src/client/audio/jorbis/PsyLook.java (100%) rename {java => client}/src/client/audio/jorbis/Residue0.java (100%) rename {java => client}/src/client/audio/jorbis/Residue1.java (100%) rename {java => client}/src/client/audio/jorbis/Residue2.java (100%) rename {java => client}/src/client/audio/jorbis/StaticCodeBook.java (100%) rename {java => client}/src/client/audio/jorbis/Time0.java (100%) rename {java => client}/src/client/audio/jorbis/Util.java (100%) rename {java => client}/src/client/audio/jorbis/VorbisFile.java (100%) rename {java => client}/src/client/gui/FileCallback.java (100%) rename {java => client}/src/client/gui/Font.java (100%) rename {java => client}/src/client/gui/FontChar.java (100%) rename {java => client}/src/client/gui/Formatter.java (100%) rename {java => client}/src/client/gui/Gui.java (100%) rename {java => client}/src/client/gui/GuiConfirm.java (100%) rename {java => client}/src/client/gui/GuiConnect.java (100%) rename {java => client}/src/client/gui/GuiConsole.java (100%) rename {java => client}/src/client/gui/GuiConvert.java (100%) rename {java => client}/src/client/gui/GuiInfo.java (100%) rename {java => client}/src/client/gui/GuiLoading.java (100%) rename {java => client}/src/client/gui/GuiMenu.java (100%) rename {java => client}/src/client/gui/GuiServer.java (100%) rename {java => client}/src/client/gui/Splashes.java (100%) rename {java => client}/src/client/gui/Style.java (100%) rename {java => client}/src/client/gui/character/GuiChar.java (100%) rename {java => client}/src/client/gui/character/GuiCharacters.java (100%) rename {java => client}/src/client/gui/character/GuiClass.java (100%) rename {java => client}/src/client/gui/character/GuiSpecies.java (100%) rename {java => client}/src/client/gui/container/GuiBrewing.java (100%) rename {java => client}/src/client/gui/container/GuiChest.java (100%) rename {java => client}/src/client/gui/container/GuiContainer.java (100%) rename {java => client}/src/client/gui/container/GuiCrafting.java (100%) rename {java => client}/src/client/gui/container/GuiDispenser.java (100%) rename {java => client}/src/client/gui/container/GuiEnchant.java (100%) rename {java => client}/src/client/gui/container/GuiFurnace.java (100%) rename {java => client}/src/client/gui/container/GuiHopper.java (100%) rename {java => client}/src/client/gui/container/GuiHorse.java (100%) rename {java => client}/src/client/gui/container/GuiInventory.java (100%) rename {java => client}/src/client/gui/container/GuiMachine.java (100%) rename {java => client}/src/client/gui/container/GuiMerchant.java (100%) rename {java => client}/src/client/gui/container/GuiRepair.java (100%) rename {java => client}/src/client/gui/element/ActButton.java (100%) rename {java => client}/src/client/gui/element/Bar.java (100%) rename {java => client}/src/client/gui/element/Dropdown.java (100%) rename {java => client}/src/client/gui/element/Element.java (100%) rename {java => client}/src/client/gui/element/Fill.java (100%) rename {java => client}/src/client/gui/element/GuiList.java (100%) rename {java => client}/src/client/gui/element/InventoryButton.java (100%) rename {java => client}/src/client/gui/element/Label.java (100%) rename {java => client}/src/client/gui/element/ListEntry.java (100%) rename {java => client}/src/client/gui/element/NavButton.java (100%) rename {java => client}/src/client/gui/element/SelectableButton.java (100%) rename {java => client}/src/client/gui/element/Slider.java (100%) rename {java => client}/src/client/gui/element/Switch.java (100%) rename {java => client}/src/client/gui/element/Textbox.java (100%) rename {java => client}/src/client/gui/element/Toggle.java (100%) rename {java => client}/src/client/gui/element/TransparentBox.java (100%) rename {java => client}/src/client/gui/ingame/GuiGameOver.java (100%) rename {java => client}/src/client/gui/ingame/GuiSign.java (100%) rename {java => client}/src/client/gui/options/GuiBinds.java (100%) rename {java => client}/src/client/gui/options/GuiDisplay.java (100%) rename {java => client}/src/client/gui/options/GuiOptions.java (100%) rename {java => client}/src/client/gui/options/GuiSound.java (100%) rename {java => client}/src/client/gui/options/GuiStyle.java (100%) rename {java => client}/src/client/init/EntityRenderRegistry.java (100%) rename {java => client}/src/client/network/ClientLoginHandler.java (100%) rename {java => client}/src/client/network/ClientPlayer.java (100%) rename {java => client}/src/client/renderer/ActiveRenderInfo.java (100%) rename {java => client}/src/client/renderer/BlockRenderer.java (100%) rename {java => client}/src/client/renderer/DefaultVertexFormats.java (100%) rename {java => client}/src/client/renderer/Drawing.java (100%) rename {java => client}/src/client/renderer/EntityRenderer.java (100%) rename {java => client}/src/client/renderer/Frustum.java (100%) rename {java => client}/src/client/renderer/GlState.java (100%) rename {java => client}/src/client/renderer/ItemModelMesher.java (100%) rename {java => client}/src/client/renderer/ItemRenderer.java (100%) rename {java => client}/src/client/renderer/Project.java (100%) rename {java => client}/src/client/renderer/RegionRenderCache.java (100%) rename {java => client}/src/client/renderer/RegionRenderCacheBuilder.java (100%) rename {java => client}/src/client/renderer/RenderBuffer.java (100%) rename {java => client}/src/client/renderer/RenderGlobal.java (100%) rename {java => client}/src/client/renderer/Tessellator.java (100%) rename {java => client}/src/client/renderer/VertexBuffer.java (100%) rename {java => client}/src/client/renderer/VertexFormat.java (100%) rename {java => client}/src/client/renderer/VertexFormatElement.java (100%) rename {java => client}/src/client/renderer/ViewFrustum.java (100%) rename {java => client}/src/client/renderer/blockmodel/BakedModel.java (100%) rename {java => client}/src/client/renderer/blockmodel/BakedQuad.java (100%) rename {java => client}/src/client/renderer/blockmodel/BlockFaceUV.java (100%) rename {java => client}/src/client/renderer/blockmodel/BlockPart.java (100%) rename {java => client}/src/client/renderer/blockmodel/BlockPartFace.java (100%) rename {java => client}/src/client/renderer/blockmodel/BlockPartRotation.java (100%) rename {java => client}/src/client/renderer/blockmodel/BreakingFour.java (100%) rename {java => client}/src/client/renderer/blockmodel/BuiltInModel.java (100%) rename {java => client}/src/client/renderer/blockmodel/FaceBakery.java (100%) rename {java => client}/src/client/renderer/blockmodel/IBakedModel.java (100%) rename {java => client}/src/client/renderer/blockmodel/ModelBakery.java (100%) rename {java => client}/src/client/renderer/blockmodel/ModelBlock.java (100%) rename {java => client}/src/client/renderer/blockmodel/ModelGenerator.java (100%) rename {java => client}/src/client/renderer/blockmodel/ModelManager.java (100%) rename {java => client}/src/client/renderer/blockmodel/MultiStateMap.java (100%) rename {java => client}/src/client/renderer/blockmodel/SingleStateMap.java (100%) rename {java => client}/src/client/renderer/blockmodel/StateMap.java (100%) rename {java => client}/src/client/renderer/chunk/ChunkCompileTaskGenerator.java (100%) rename {java => client}/src/client/renderer/chunk/ChunkRenderDispatcher.java (100%) rename {java => client}/src/client/renderer/chunk/ChunkRenderWorker.java (100%) rename {java => client}/src/client/renderer/chunk/CompiledChunk.java (100%) rename {java => client}/src/client/renderer/chunk/RenderChunk.java (100%) rename {java => client}/src/client/renderer/chunk/SetVisibility.java (100%) rename {java => client}/src/client/renderer/chunk/VisGraph.java (100%) rename {java => client}/src/client/renderer/entity/Render.java (100%) rename {java => client}/src/client/renderer/entity/RenderArachnoid.java (100%) rename {java => client}/src/client/renderer/entity/RenderArrow.java (100%) rename {java => client}/src/client/renderer/entity/RenderBat.java (100%) rename {java => client}/src/client/renderer/entity/RenderBlockEntity.java (100%) rename {java => client}/src/client/renderer/entity/RenderBoat.java (100%) rename {java => client}/src/client/renderer/entity/RenderBullet.java (100%) rename {java => client}/src/client/renderer/entity/RenderChicken.java (100%) rename {java => client}/src/client/renderer/entity/RenderCow.java (100%) rename {java => client}/src/client/renderer/entity/RenderCrystal.java (100%) rename {java => client}/src/client/renderer/entity/RenderDie.java (100%) rename {java => client}/src/client/renderer/entity/RenderDragon.java (100%) rename {java => client}/src/client/renderer/entity/RenderDynamite.java (100%) rename {java => client}/src/client/renderer/entity/RenderEntity.java (100%) rename {java => client}/src/client/renderer/entity/RenderEntityItem.java (100%) rename {java => client}/src/client/renderer/entity/RenderFallingBlock.java (100%) rename {java => client}/src/client/renderer/entity/RenderFireball.java (100%) rename {java => client}/src/client/renderer/entity/RenderFish.java (100%) rename {java => client}/src/client/renderer/entity/RenderFlyingBox.java (100%) rename {java => client}/src/client/renderer/entity/RenderHorse.java (100%) rename {java => client}/src/client/renderer/entity/RenderHumanoid.java (100%) rename {java => client}/src/client/renderer/entity/RenderItem.java (100%) rename {java => client}/src/client/renderer/entity/RenderItemEntity.java (100%) rename {java => client}/src/client/renderer/entity/RenderLeashKnot.java (100%) rename {java => client}/src/client/renderer/entity/RenderLightning.java (100%) rename {java => client}/src/client/renderer/entity/RenderLiving.java (100%) rename {java => client}/src/client/renderer/entity/RenderManager.java (100%) rename {java => client}/src/client/renderer/entity/RenderMinecart.java (100%) rename {java => client}/src/client/renderer/entity/RenderMooshroom.java (100%) rename {java => client}/src/client/renderer/entity/RenderMouse.java (100%) rename {java => client}/src/client/renderer/entity/RenderNpc.java (100%) rename {java => client}/src/client/renderer/entity/RenderOcelot.java (100%) rename {java => client}/src/client/renderer/entity/RenderPig.java (100%) rename {java => client}/src/client/renderer/entity/RenderPotion.java (100%) rename {java => client}/src/client/renderer/entity/RenderRabbit.java (100%) rename {java => client}/src/client/renderer/entity/RenderSheep.java (100%) rename {java => client}/src/client/renderer/entity/RenderSlime.java (100%) rename {java => client}/src/client/renderer/entity/RenderSpaceMarine.java (100%) rename {java => client}/src/client/renderer/entity/RenderSquid.java (100%) rename {java => client}/src/client/renderer/entity/RenderTntMinecart.java (100%) rename {java => client}/src/client/renderer/entity/RenderTntPrimed.java (100%) rename {java => client}/src/client/renderer/entity/RenderWolf.java (100%) rename {java => client}/src/client/renderer/entity/RenderXpOrb.java (100%) rename {java => client}/src/client/renderer/entity/RendererLivingEntity.java (100%) rename {java => client}/src/client/renderer/layers/LayerArachnoidArmor.java (100%) rename {java => client}/src/client/renderer/layers/LayerArmor.java (100%) rename {java => client}/src/client/renderer/layers/LayerArrow.java (100%) rename {java => client}/src/client/renderer/layers/LayerCape.java (100%) rename {java => client}/src/client/renderer/layers/LayerCharge.java (100%) rename {java => client}/src/client/renderer/layers/LayerEnderDragonEyes.java (100%) rename {java => client}/src/client/renderer/layers/LayerEntityBreak.java (100%) rename {java => client}/src/client/renderer/layers/LayerExtra.java (100%) rename {java => client}/src/client/renderer/layers/LayerHeldItem.java (100%) rename {java => client}/src/client/renderer/layers/LayerMooshroomMushroom.java (100%) rename {java => client}/src/client/renderer/layers/LayerPowerRods.java (100%) rename {java => client}/src/client/renderer/layers/LayerRenderer.java (100%) rename {java => client}/src/client/renderer/layers/LayerSaddle.java (100%) rename {java => client}/src/client/renderer/layers/LayerSheepWool.java (100%) rename {java => client}/src/client/renderer/layers/LayerSlimeGel.java (100%) rename {java => client}/src/client/renderer/layers/LayerWolfCollar.java (100%) rename {java => client}/src/client/renderer/model/ModelArachnoid.java (100%) rename {java => client}/src/client/renderer/model/ModelArmor.java (100%) rename {java => client}/src/client/renderer/model/ModelBanner.java (100%) rename {java => client}/src/client/renderer/model/ModelBase.java (100%) rename {java => client}/src/client/renderer/model/ModelBat.java (100%) rename {java => client}/src/client/renderer/model/ModelBiped.java (100%) rename {java => client}/src/client/renderer/model/ModelBoat.java (100%) rename {java => client}/src/client/renderer/model/ModelBox.java (100%) rename {java => client}/src/client/renderer/model/ModelCharge.java (100%) rename {java => client}/src/client/renderer/model/ModelChest.java (100%) rename {java => client}/src/client/renderer/model/ModelChicken.java (100%) rename {java => client}/src/client/renderer/model/ModelCow.java (100%) rename {java => client}/src/client/renderer/model/ModelCrystal.java (100%) rename {java => client}/src/client/renderer/model/ModelDie.java (100%) rename {java => client}/src/client/renderer/model/ModelDragon.java (100%) rename {java => client}/src/client/renderer/model/ModelHead.java (100%) rename {java => client}/src/client/renderer/model/ModelHorse.java (100%) rename {java => client}/src/client/renderer/model/ModelHumanoid.java (100%) rename {java => client}/src/client/renderer/model/ModelHumanoidHead.java (100%) rename {java => client}/src/client/renderer/model/ModelLargeChest.java (100%) rename {java => client}/src/client/renderer/model/ModelLeashKnot.java (100%) rename {java => client}/src/client/renderer/model/ModelMinecart.java (100%) rename {java => client}/src/client/renderer/model/ModelMouse.java (100%) rename {java => client}/src/client/renderer/model/ModelOcelot.java (100%) rename {java => client}/src/client/renderer/model/ModelPig.java (100%) rename {java => client}/src/client/renderer/model/ModelQuadruped.java (100%) rename {java => client}/src/client/renderer/model/ModelRabbit.java (100%) rename {java => client}/src/client/renderer/model/ModelRenderer.java (100%) rename {java => client}/src/client/renderer/model/ModelSheep1.java (100%) rename {java => client}/src/client/renderer/model/ModelSheep2.java (100%) rename {java => client}/src/client/renderer/model/ModelSign.java (100%) rename {java => client}/src/client/renderer/model/ModelSlime.java (100%) rename {java => client}/src/client/renderer/model/ModelSpaceMarine.java (100%) rename {java => client}/src/client/renderer/model/ModelSquid.java (100%) rename {java => client}/src/client/renderer/model/ModelWolf.java (100%) rename {java => client}/src/client/renderer/model/PositionTextureVertex.java (100%) rename {java => client}/src/client/renderer/model/TextureOffset.java (100%) rename {java => client}/src/client/renderer/model/TexturedQuad.java (100%) rename {java => client}/src/client/renderer/particle/EffectRenderer.java (100%) rename {java => client}/src/client/renderer/particle/EntityAuraFX.java (100%) rename {java => client}/src/client/renderer/particle/EntityBlockDustFX.java (100%) rename {java => client}/src/client/renderer/particle/EntityBreakingFX.java (100%) rename {java => client}/src/client/renderer/particle/EntityBubbleFX.java (100%) rename {java => client}/src/client/renderer/particle/EntityCloudFX.java (100%) rename {java => client}/src/client/renderer/particle/EntityCrit2FX.java (100%) rename {java => client}/src/client/renderer/particle/EntityCritFX.java (100%) rename {java => client}/src/client/renderer/particle/EntityDiggingFX.java (100%) rename {java => client}/src/client/renderer/particle/EntityDownfallFX.java (100%) rename {java => client}/src/client/renderer/particle/EntityDropParticleFX.java (100%) rename {java => client}/src/client/renderer/particle/EntityEnchantmentTableParticleFX.java (100%) rename {java => client}/src/client/renderer/particle/EntityExplodeFX.java (100%) rename {java => client}/src/client/renderer/particle/EntityFX.java (100%) rename {java => client}/src/client/renderer/particle/EntityFirework.java (100%) rename {java => client}/src/client/renderer/particle/EntityFishWakeFX.java (100%) rename {java => client}/src/client/renderer/particle/EntityFlameFX.java (100%) rename {java => client}/src/client/renderer/particle/EntityFootStepFX.java (100%) rename {java => client}/src/client/renderer/particle/EntityHeartFX.java (100%) rename {java => client}/src/client/renderer/particle/EntityHugeExplodeFX.java (100%) rename {java => client}/src/client/renderer/particle/EntityLargeExplodeFX.java (100%) rename {java => client}/src/client/renderer/particle/EntityLavaFX.java (100%) rename {java => client}/src/client/renderer/particle/EntityNoteFX.java (100%) rename {java => client}/src/client/renderer/particle/EntityParticleEmitter.java (100%) rename {java => client}/src/client/renderer/particle/EntityPickupFX.java (100%) rename {java => client}/src/client/renderer/particle/EntityPortalFX.java (100%) rename {java => client}/src/client/renderer/particle/EntityReddustFX.java (100%) rename {java => client}/src/client/renderer/particle/EntitySmokeFX.java (100%) rename {java => client}/src/client/renderer/particle/EntitySnowShovelFX.java (100%) rename {java => client}/src/client/renderer/particle/EntitySpellParticleFX.java (100%) rename {java => client}/src/client/renderer/particle/EntitySplashFX.java (100%) rename {java => client}/src/client/renderer/particle/EntitySuspendFX.java (100%) rename {java => client}/src/client/renderer/particle/IParticleFactory.java (100%) rename {java => client}/src/client/renderer/texture/DynamicTexture.java (100%) rename {java => client}/src/client/renderer/texture/EntityTexManager.java (100%) rename {java => client}/src/client/renderer/texture/IIconCreator.java (100%) rename {java => client}/src/client/renderer/texture/LayeredColorMaskTexture.java (100%) rename {java => client}/src/client/renderer/texture/LayeredTexture.java (100%) rename {java => client}/src/client/renderer/texture/SimpleTexture.java (100%) rename {java => client}/src/client/renderer/texture/Stitcher.java (100%) rename {java => client}/src/client/renderer/texture/Texture.java (100%) rename {java => client}/src/client/renderer/texture/TextureAtlasSprite.java (100%) rename {java => client}/src/client/renderer/texture/TextureManager.java (100%) rename {java => client}/src/client/renderer/texture/TextureMap.java (100%) rename {java => client}/src/client/renderer/texture/TextureTicked.java (100%) rename {java => client}/src/client/renderer/texture/TextureUtil.java (100%) rename {java => client}/src/client/renderer/ticked/TextureFlamesFX1.java (100%) rename {java => client}/src/client/renderer/ticked/TextureFlamesFX2.java (100%) rename {java => client}/src/client/renderer/ticked/TextureLavaFX.java (100%) rename {java => client}/src/client/renderer/ticked/TextureLavaFlowFX.java (100%) rename {java => client}/src/client/renderer/ticked/TextureWaterFX.java (100%) rename {java => client}/src/client/renderer/ticked/TextureWaterFlowFX.java (100%) rename {java => client}/src/client/renderer/tileentity/TileEntityBannerRenderer.java (100%) rename {java => client}/src/client/renderer/tileentity/TileEntityChestRenderer.java (100%) rename {java => client}/src/client/renderer/tileentity/TileEntityItemStackRenderer.java (100%) rename {java => client}/src/client/renderer/tileentity/TileEntityMobSpawnerRenderer.java (100%) rename {java => client}/src/client/renderer/tileentity/TileEntityPistonRenderer.java (100%) rename {java => client}/src/client/renderer/tileentity/TileEntityRendererDispatcher.java (100%) rename {java => client}/src/client/renderer/tileentity/TileEntitySignRenderer.java (100%) rename {java => client}/src/client/renderer/tileentity/TileEntitySkullRenderer.java (100%) rename {java => client}/src/client/renderer/tileentity/TileEntitySpecialRenderer.java (100%) rename {java => client}/src/client/window/Bind.java (100%) rename {java => client}/src/client/window/Button.java (100%) rename {java => client}/src/client/window/DisplayMode.java (100%) rename {java => client}/src/client/window/Input.java (100%) rename {java => client}/src/client/window/KeyEvent.java (100%) rename {java => client}/src/client/window/Keysym.java (100%) rename {java => client}/src/client/window/Wheel.java (100%) rename {java => client}/src/client/window/Window.java (100%) rename {java => client}/src/client/window/WindowAction.java (100%) rename {java => client}/src/client/window/WindowEvent.java (100%) rename {java => client}/src/game/vars/BaseVar.java (100%) rename {java => client}/src/game/vars/BoolVar.java (100%) rename {java => client}/src/game/vars/CVar.java (100%) rename {java => client}/src/game/vars/CVarCategory.java (100%) rename {java => client}/src/game/vars/ColorVar.java (100%) rename {java => client}/src/game/vars/EnumVar.java (100%) rename {java => client}/src/game/vars/FloatVar.java (100%) rename {java => client}/src/game/vars/IntVar.java (100%) rename {java => client}/src/game/vars/StringVar.java (100%) rename {java => client}/src/game/vars/Variable.java (100%) rename {java => client}/src/game/world/Converter.java (99%) rename {java => server}/src/server/Server.java (100%) rename {java => server}/src/server/command/ArgCombiner.java (100%) rename {java => server}/src/server/command/Argument.java (100%) rename {java => server}/src/server/command/ArgumentParser.java (100%) rename {java => server}/src/server/command/ArgumentSplitter.java (100%) rename {java => server}/src/server/command/BooleanParser.java (100%) rename {java => server}/src/server/command/CachedExecutable.java (100%) rename {java => server}/src/server/command/ColorParser.java (100%) rename {java => server}/src/server/command/Command.java (100%) rename {java => server}/src/server/command/CommandEnvironment.java (100%) rename {java => server}/src/server/command/Completer.java (100%) rename {java => server}/src/server/command/CompletingParser.java (100%) rename {java => server}/src/server/command/DefaultingParser.java (100%) rename {java => server}/src/server/command/DimensionParser.java (100%) rename {java => server}/src/server/command/DoubleParser.java (100%) rename {java => server}/src/server/command/EntityListParser.java (100%) rename {java => server}/src/server/command/EntityParser.java (100%) rename {java => server}/src/server/command/EnumParser.java (100%) rename {java => server}/src/server/command/Executable.java (100%) rename {java => server}/src/server/command/Executor.java (100%) rename {java => server}/src/server/command/FixedExecutor.java (100%) rename {java => server}/src/server/command/IntParser.java (100%) rename {java => server}/src/server/command/LongParser.java (100%) rename {java => server}/src/server/command/NonDefaultingParser.java (100%) rename {java => server}/src/server/command/Parameter.java (100%) rename {java => server}/src/server/command/PatternReplacer.java (100%) rename {java => server}/src/server/command/PlayerEntityListParser.java (100%) rename {java => server}/src/server/command/PlayerEntityParser.java (100%) rename {java => server}/src/server/command/PlayerListParser.java (100%) rename {java => server}/src/server/command/PlayerParser.java (100%) rename {java => server}/src/server/command/RunException.java (100%) rename {java => server}/src/server/command/StringCompleter.java (100%) rename {java => server}/src/server/command/StringParser.java (100%) rename {java => server}/src/server/command/TagParser.java (100%) rename {java => server}/src/server/command/Variable.java (100%) rename {java => server}/src/server/command/WorldParser.java (100%) rename {java => server}/src/server/command/commands/CommandAdmin.java (100%) rename {java => server}/src/server/command/commands/CommandHelp.java (100%) rename {java => server}/src/server/command/commands/CommandKick.java (100%) rename {java => server}/src/server/command/commands/CommandMessage.java (100%) rename {java => server}/src/server/command/commands/CommandMilk.java (100%) rename {java => server}/src/server/command/commands/CommandOfflinetp.java (100%) rename {java => server}/src/server/command/commands/CommandPotion.java (100%) rename {java => server}/src/server/command/commands/CommandRemove.java (100%) rename {java => server}/src/server/command/commands/CommandRevoke.java (100%) rename {java => server}/src/server/command/commands/CommandSpawn.java (100%) rename {java => server}/src/server/command/commands/CommandTele.java (100%) rename {java => server}/src/server/command/commands/CommandTime.java (100%) rename {java => server}/src/server/command/commands/CommandTp.java (100%) rename {java => server}/src/server/command/commands/CommandWarp.java (100%) rename {java => server}/src/server/command/commands/CommandWeather.java (100%) rename {java => server}/src/server/command/commands/CommandWorld.java (100%) rename {java => server}/src/server/network/HandshakeHandler.java (100%) rename {java => server}/src/server/network/LoginHandler.java (100%) rename {java => server}/src/server/network/Player.java (100%) diff --git a/java/src/client/Game.java b/client/src/client/Game.java similarity index 100% rename from java/src/client/Game.java rename to client/src/client/Game.java diff --git a/java/src/client/PerfSection.java b/client/src/client/PerfSection.java similarity index 100% rename from java/src/client/PerfSection.java rename to client/src/client/PerfSection.java diff --git a/java/src/client/PlayerController.java b/client/src/client/PlayerController.java similarity index 100% rename from java/src/client/PlayerController.java rename to client/src/client/PlayerController.java diff --git a/java/src/client/SkinConverter.java b/client/src/client/SkinConverter.java similarity index 100% rename from java/src/client/SkinConverter.java rename to client/src/client/SkinConverter.java diff --git a/java/src/client/Timing.java b/client/src/client/Timing.java similarity index 100% rename from java/src/client/Timing.java rename to client/src/client/Timing.java diff --git a/java/src/client/audio/AudioInterface.java b/client/src/client/audio/AudioInterface.java similarity index 100% rename from java/src/client/audio/AudioInterface.java rename to client/src/client/audio/AudioInterface.java diff --git a/java/src/client/audio/CodecJOrbis.java b/client/src/client/audio/CodecJOrbis.java similarity index 100% rename from java/src/client/audio/CodecJOrbis.java rename to client/src/client/audio/CodecJOrbis.java diff --git a/java/src/client/audio/SoundManager.java b/client/src/client/audio/SoundManager.java similarity index 100% rename from java/src/client/audio/SoundManager.java rename to client/src/client/audio/SoundManager.java diff --git a/java/src/client/audio/Volume.java b/client/src/client/audio/Volume.java similarity index 100% rename from java/src/client/audio/Volume.java rename to client/src/client/audio/Volume.java diff --git a/java/src/client/audio/jogg/Buffer.java b/client/src/client/audio/jogg/Buffer.java similarity index 100% rename from java/src/client/audio/jogg/Buffer.java rename to client/src/client/audio/jogg/Buffer.java diff --git a/java/src/client/audio/jogg/Packet.java b/client/src/client/audio/jogg/Packet.java similarity index 100% rename from java/src/client/audio/jogg/Packet.java rename to client/src/client/audio/jogg/Packet.java diff --git a/java/src/client/audio/jogg/Page.java b/client/src/client/audio/jogg/Page.java similarity index 100% rename from java/src/client/audio/jogg/Page.java rename to client/src/client/audio/jogg/Page.java diff --git a/java/src/client/audio/jogg/StreamState.java b/client/src/client/audio/jogg/StreamState.java similarity index 100% rename from java/src/client/audio/jogg/StreamState.java rename to client/src/client/audio/jogg/StreamState.java diff --git a/java/src/client/audio/jogg/SyncState.java b/client/src/client/audio/jogg/SyncState.java similarity index 100% rename from java/src/client/audio/jogg/SyncState.java rename to client/src/client/audio/jogg/SyncState.java diff --git a/java/src/client/audio/jorbis/Block.java b/client/src/client/audio/jorbis/Block.java similarity index 100% rename from java/src/client/audio/jorbis/Block.java rename to client/src/client/audio/jorbis/Block.java diff --git a/java/src/client/audio/jorbis/ChainingExample.java b/client/src/client/audio/jorbis/ChainingExample.java similarity index 100% rename from java/src/client/audio/jorbis/ChainingExample.java rename to client/src/client/audio/jorbis/ChainingExample.java diff --git a/java/src/client/audio/jorbis/CodeBook.java b/client/src/client/audio/jorbis/CodeBook.java similarity index 100% rename from java/src/client/audio/jorbis/CodeBook.java rename to client/src/client/audio/jorbis/CodeBook.java diff --git a/java/src/client/audio/jorbis/Comment.java b/client/src/client/audio/jorbis/Comment.java similarity index 100% rename from java/src/client/audio/jorbis/Comment.java rename to client/src/client/audio/jorbis/Comment.java diff --git a/java/src/client/audio/jorbis/DecodeExample.java b/client/src/client/audio/jorbis/DecodeExample.java similarity index 100% rename from java/src/client/audio/jorbis/DecodeExample.java rename to client/src/client/audio/jorbis/DecodeExample.java diff --git a/java/src/client/audio/jorbis/Drft.java b/client/src/client/audio/jorbis/Drft.java similarity index 100% rename from java/src/client/audio/jorbis/Drft.java rename to client/src/client/audio/jorbis/Drft.java diff --git a/java/src/client/audio/jorbis/DspState.java b/client/src/client/audio/jorbis/DspState.java similarity index 100% rename from java/src/client/audio/jorbis/DspState.java rename to client/src/client/audio/jorbis/DspState.java diff --git a/java/src/client/audio/jorbis/Floor0.java b/client/src/client/audio/jorbis/Floor0.java similarity index 100% rename from java/src/client/audio/jorbis/Floor0.java rename to client/src/client/audio/jorbis/Floor0.java diff --git a/java/src/client/audio/jorbis/Floor1.java b/client/src/client/audio/jorbis/Floor1.java similarity index 100% rename from java/src/client/audio/jorbis/Floor1.java rename to client/src/client/audio/jorbis/Floor1.java diff --git a/java/src/client/audio/jorbis/FuncFloor.java b/client/src/client/audio/jorbis/FuncFloor.java similarity index 100% rename from java/src/client/audio/jorbis/FuncFloor.java rename to client/src/client/audio/jorbis/FuncFloor.java diff --git a/java/src/client/audio/jorbis/FuncMapping.java b/client/src/client/audio/jorbis/FuncMapping.java similarity index 100% rename from java/src/client/audio/jorbis/FuncMapping.java rename to client/src/client/audio/jorbis/FuncMapping.java diff --git a/java/src/client/audio/jorbis/FuncResidue.java b/client/src/client/audio/jorbis/FuncResidue.java similarity index 100% rename from java/src/client/audio/jorbis/FuncResidue.java rename to client/src/client/audio/jorbis/FuncResidue.java diff --git a/java/src/client/audio/jorbis/FuncTime.java b/client/src/client/audio/jorbis/FuncTime.java similarity index 100% rename from java/src/client/audio/jorbis/FuncTime.java rename to client/src/client/audio/jorbis/FuncTime.java diff --git a/java/src/client/audio/jorbis/Info.java b/client/src/client/audio/jorbis/Info.java similarity index 100% rename from java/src/client/audio/jorbis/Info.java rename to client/src/client/audio/jorbis/Info.java diff --git a/java/src/client/audio/jorbis/InfoMode.java b/client/src/client/audio/jorbis/InfoMode.java similarity index 100% rename from java/src/client/audio/jorbis/InfoMode.java rename to client/src/client/audio/jorbis/InfoMode.java diff --git a/java/src/client/audio/jorbis/JOrbisException.java b/client/src/client/audio/jorbis/JOrbisException.java similarity index 100% rename from java/src/client/audio/jorbis/JOrbisException.java rename to client/src/client/audio/jorbis/JOrbisException.java diff --git a/java/src/client/audio/jorbis/Lookup.java b/client/src/client/audio/jorbis/Lookup.java similarity index 100% rename from java/src/client/audio/jorbis/Lookup.java rename to client/src/client/audio/jorbis/Lookup.java diff --git a/java/src/client/audio/jorbis/Lpc.java b/client/src/client/audio/jorbis/Lpc.java similarity index 100% rename from java/src/client/audio/jorbis/Lpc.java rename to client/src/client/audio/jorbis/Lpc.java diff --git a/java/src/client/audio/jorbis/Lsp.java b/client/src/client/audio/jorbis/Lsp.java similarity index 100% rename from java/src/client/audio/jorbis/Lsp.java rename to client/src/client/audio/jorbis/Lsp.java diff --git a/java/src/client/audio/jorbis/Mapping0.java b/client/src/client/audio/jorbis/Mapping0.java similarity index 100% rename from java/src/client/audio/jorbis/Mapping0.java rename to client/src/client/audio/jorbis/Mapping0.java diff --git a/java/src/client/audio/jorbis/Mdct.java b/client/src/client/audio/jorbis/Mdct.java similarity index 100% rename from java/src/client/audio/jorbis/Mdct.java rename to client/src/client/audio/jorbis/Mdct.java diff --git a/java/src/client/audio/jorbis/PsyInfo.java b/client/src/client/audio/jorbis/PsyInfo.java similarity index 100% rename from java/src/client/audio/jorbis/PsyInfo.java rename to client/src/client/audio/jorbis/PsyInfo.java diff --git a/java/src/client/audio/jorbis/PsyLook.java b/client/src/client/audio/jorbis/PsyLook.java similarity index 100% rename from java/src/client/audio/jorbis/PsyLook.java rename to client/src/client/audio/jorbis/PsyLook.java diff --git a/java/src/client/audio/jorbis/Residue0.java b/client/src/client/audio/jorbis/Residue0.java similarity index 100% rename from java/src/client/audio/jorbis/Residue0.java rename to client/src/client/audio/jorbis/Residue0.java diff --git a/java/src/client/audio/jorbis/Residue1.java b/client/src/client/audio/jorbis/Residue1.java similarity index 100% rename from java/src/client/audio/jorbis/Residue1.java rename to client/src/client/audio/jorbis/Residue1.java diff --git a/java/src/client/audio/jorbis/Residue2.java b/client/src/client/audio/jorbis/Residue2.java similarity index 100% rename from java/src/client/audio/jorbis/Residue2.java rename to client/src/client/audio/jorbis/Residue2.java diff --git a/java/src/client/audio/jorbis/StaticCodeBook.java b/client/src/client/audio/jorbis/StaticCodeBook.java similarity index 100% rename from java/src/client/audio/jorbis/StaticCodeBook.java rename to client/src/client/audio/jorbis/StaticCodeBook.java diff --git a/java/src/client/audio/jorbis/Time0.java b/client/src/client/audio/jorbis/Time0.java similarity index 100% rename from java/src/client/audio/jorbis/Time0.java rename to client/src/client/audio/jorbis/Time0.java diff --git a/java/src/client/audio/jorbis/Util.java b/client/src/client/audio/jorbis/Util.java similarity index 100% rename from java/src/client/audio/jorbis/Util.java rename to client/src/client/audio/jorbis/Util.java diff --git a/java/src/client/audio/jorbis/VorbisFile.java b/client/src/client/audio/jorbis/VorbisFile.java similarity index 100% rename from java/src/client/audio/jorbis/VorbisFile.java rename to client/src/client/audio/jorbis/VorbisFile.java diff --git a/java/src/client/gui/FileCallback.java b/client/src/client/gui/FileCallback.java similarity index 100% rename from java/src/client/gui/FileCallback.java rename to client/src/client/gui/FileCallback.java diff --git a/java/src/client/gui/Font.java b/client/src/client/gui/Font.java similarity index 100% rename from java/src/client/gui/Font.java rename to client/src/client/gui/Font.java diff --git a/java/src/client/gui/FontChar.java b/client/src/client/gui/FontChar.java similarity index 100% rename from java/src/client/gui/FontChar.java rename to client/src/client/gui/FontChar.java diff --git a/java/src/client/gui/Formatter.java b/client/src/client/gui/Formatter.java similarity index 100% rename from java/src/client/gui/Formatter.java rename to client/src/client/gui/Formatter.java diff --git a/java/src/client/gui/Gui.java b/client/src/client/gui/Gui.java similarity index 100% rename from java/src/client/gui/Gui.java rename to client/src/client/gui/Gui.java diff --git a/java/src/client/gui/GuiConfirm.java b/client/src/client/gui/GuiConfirm.java similarity index 100% rename from java/src/client/gui/GuiConfirm.java rename to client/src/client/gui/GuiConfirm.java diff --git a/java/src/client/gui/GuiConnect.java b/client/src/client/gui/GuiConnect.java similarity index 100% rename from java/src/client/gui/GuiConnect.java rename to client/src/client/gui/GuiConnect.java diff --git a/java/src/client/gui/GuiConsole.java b/client/src/client/gui/GuiConsole.java similarity index 100% rename from java/src/client/gui/GuiConsole.java rename to client/src/client/gui/GuiConsole.java diff --git a/java/src/client/gui/GuiConvert.java b/client/src/client/gui/GuiConvert.java similarity index 100% rename from java/src/client/gui/GuiConvert.java rename to client/src/client/gui/GuiConvert.java diff --git a/java/src/client/gui/GuiInfo.java b/client/src/client/gui/GuiInfo.java similarity index 100% rename from java/src/client/gui/GuiInfo.java rename to client/src/client/gui/GuiInfo.java diff --git a/java/src/client/gui/GuiLoading.java b/client/src/client/gui/GuiLoading.java similarity index 100% rename from java/src/client/gui/GuiLoading.java rename to client/src/client/gui/GuiLoading.java diff --git a/java/src/client/gui/GuiMenu.java b/client/src/client/gui/GuiMenu.java similarity index 100% rename from java/src/client/gui/GuiMenu.java rename to client/src/client/gui/GuiMenu.java diff --git a/java/src/client/gui/GuiServer.java b/client/src/client/gui/GuiServer.java similarity index 100% rename from java/src/client/gui/GuiServer.java rename to client/src/client/gui/GuiServer.java diff --git a/java/src/client/gui/Splashes.java b/client/src/client/gui/Splashes.java similarity index 100% rename from java/src/client/gui/Splashes.java rename to client/src/client/gui/Splashes.java diff --git a/java/src/client/gui/Style.java b/client/src/client/gui/Style.java similarity index 100% rename from java/src/client/gui/Style.java rename to client/src/client/gui/Style.java diff --git a/java/src/client/gui/character/GuiChar.java b/client/src/client/gui/character/GuiChar.java similarity index 100% rename from java/src/client/gui/character/GuiChar.java rename to client/src/client/gui/character/GuiChar.java diff --git a/java/src/client/gui/character/GuiCharacters.java b/client/src/client/gui/character/GuiCharacters.java similarity index 100% rename from java/src/client/gui/character/GuiCharacters.java rename to client/src/client/gui/character/GuiCharacters.java diff --git a/java/src/client/gui/character/GuiClass.java b/client/src/client/gui/character/GuiClass.java similarity index 100% rename from java/src/client/gui/character/GuiClass.java rename to client/src/client/gui/character/GuiClass.java diff --git a/java/src/client/gui/character/GuiSpecies.java b/client/src/client/gui/character/GuiSpecies.java similarity index 100% rename from java/src/client/gui/character/GuiSpecies.java rename to client/src/client/gui/character/GuiSpecies.java diff --git a/java/src/client/gui/container/GuiBrewing.java b/client/src/client/gui/container/GuiBrewing.java similarity index 100% rename from java/src/client/gui/container/GuiBrewing.java rename to client/src/client/gui/container/GuiBrewing.java diff --git a/java/src/client/gui/container/GuiChest.java b/client/src/client/gui/container/GuiChest.java similarity index 100% rename from java/src/client/gui/container/GuiChest.java rename to client/src/client/gui/container/GuiChest.java diff --git a/java/src/client/gui/container/GuiContainer.java b/client/src/client/gui/container/GuiContainer.java similarity index 100% rename from java/src/client/gui/container/GuiContainer.java rename to client/src/client/gui/container/GuiContainer.java diff --git a/java/src/client/gui/container/GuiCrafting.java b/client/src/client/gui/container/GuiCrafting.java similarity index 100% rename from java/src/client/gui/container/GuiCrafting.java rename to client/src/client/gui/container/GuiCrafting.java diff --git a/java/src/client/gui/container/GuiDispenser.java b/client/src/client/gui/container/GuiDispenser.java similarity index 100% rename from java/src/client/gui/container/GuiDispenser.java rename to client/src/client/gui/container/GuiDispenser.java diff --git a/java/src/client/gui/container/GuiEnchant.java b/client/src/client/gui/container/GuiEnchant.java similarity index 100% rename from java/src/client/gui/container/GuiEnchant.java rename to client/src/client/gui/container/GuiEnchant.java diff --git a/java/src/client/gui/container/GuiFurnace.java b/client/src/client/gui/container/GuiFurnace.java similarity index 100% rename from java/src/client/gui/container/GuiFurnace.java rename to client/src/client/gui/container/GuiFurnace.java diff --git a/java/src/client/gui/container/GuiHopper.java b/client/src/client/gui/container/GuiHopper.java similarity index 100% rename from java/src/client/gui/container/GuiHopper.java rename to client/src/client/gui/container/GuiHopper.java diff --git a/java/src/client/gui/container/GuiHorse.java b/client/src/client/gui/container/GuiHorse.java similarity index 100% rename from java/src/client/gui/container/GuiHorse.java rename to client/src/client/gui/container/GuiHorse.java diff --git a/java/src/client/gui/container/GuiInventory.java b/client/src/client/gui/container/GuiInventory.java similarity index 100% rename from java/src/client/gui/container/GuiInventory.java rename to client/src/client/gui/container/GuiInventory.java diff --git a/java/src/client/gui/container/GuiMachine.java b/client/src/client/gui/container/GuiMachine.java similarity index 100% rename from java/src/client/gui/container/GuiMachine.java rename to client/src/client/gui/container/GuiMachine.java diff --git a/java/src/client/gui/container/GuiMerchant.java b/client/src/client/gui/container/GuiMerchant.java similarity index 100% rename from java/src/client/gui/container/GuiMerchant.java rename to client/src/client/gui/container/GuiMerchant.java diff --git a/java/src/client/gui/container/GuiRepair.java b/client/src/client/gui/container/GuiRepair.java similarity index 100% rename from java/src/client/gui/container/GuiRepair.java rename to client/src/client/gui/container/GuiRepair.java diff --git a/java/src/client/gui/element/ActButton.java b/client/src/client/gui/element/ActButton.java similarity index 100% rename from java/src/client/gui/element/ActButton.java rename to client/src/client/gui/element/ActButton.java diff --git a/java/src/client/gui/element/Bar.java b/client/src/client/gui/element/Bar.java similarity index 100% rename from java/src/client/gui/element/Bar.java rename to client/src/client/gui/element/Bar.java diff --git a/java/src/client/gui/element/Dropdown.java b/client/src/client/gui/element/Dropdown.java similarity index 100% rename from java/src/client/gui/element/Dropdown.java rename to client/src/client/gui/element/Dropdown.java diff --git a/java/src/client/gui/element/Element.java b/client/src/client/gui/element/Element.java similarity index 100% rename from java/src/client/gui/element/Element.java rename to client/src/client/gui/element/Element.java diff --git a/java/src/client/gui/element/Fill.java b/client/src/client/gui/element/Fill.java similarity index 100% rename from java/src/client/gui/element/Fill.java rename to client/src/client/gui/element/Fill.java diff --git a/java/src/client/gui/element/GuiList.java b/client/src/client/gui/element/GuiList.java similarity index 100% rename from java/src/client/gui/element/GuiList.java rename to client/src/client/gui/element/GuiList.java diff --git a/java/src/client/gui/element/InventoryButton.java b/client/src/client/gui/element/InventoryButton.java similarity index 100% rename from java/src/client/gui/element/InventoryButton.java rename to client/src/client/gui/element/InventoryButton.java diff --git a/java/src/client/gui/element/Label.java b/client/src/client/gui/element/Label.java similarity index 100% rename from java/src/client/gui/element/Label.java rename to client/src/client/gui/element/Label.java diff --git a/java/src/client/gui/element/ListEntry.java b/client/src/client/gui/element/ListEntry.java similarity index 100% rename from java/src/client/gui/element/ListEntry.java rename to client/src/client/gui/element/ListEntry.java diff --git a/java/src/client/gui/element/NavButton.java b/client/src/client/gui/element/NavButton.java similarity index 100% rename from java/src/client/gui/element/NavButton.java rename to client/src/client/gui/element/NavButton.java diff --git a/java/src/client/gui/element/SelectableButton.java b/client/src/client/gui/element/SelectableButton.java similarity index 100% rename from java/src/client/gui/element/SelectableButton.java rename to client/src/client/gui/element/SelectableButton.java diff --git a/java/src/client/gui/element/Slider.java b/client/src/client/gui/element/Slider.java similarity index 100% rename from java/src/client/gui/element/Slider.java rename to client/src/client/gui/element/Slider.java diff --git a/java/src/client/gui/element/Switch.java b/client/src/client/gui/element/Switch.java similarity index 100% rename from java/src/client/gui/element/Switch.java rename to client/src/client/gui/element/Switch.java diff --git a/java/src/client/gui/element/Textbox.java b/client/src/client/gui/element/Textbox.java similarity index 100% rename from java/src/client/gui/element/Textbox.java rename to client/src/client/gui/element/Textbox.java diff --git a/java/src/client/gui/element/Toggle.java b/client/src/client/gui/element/Toggle.java similarity index 100% rename from java/src/client/gui/element/Toggle.java rename to client/src/client/gui/element/Toggle.java diff --git a/java/src/client/gui/element/TransparentBox.java b/client/src/client/gui/element/TransparentBox.java similarity index 100% rename from java/src/client/gui/element/TransparentBox.java rename to client/src/client/gui/element/TransparentBox.java diff --git a/java/src/client/gui/ingame/GuiGameOver.java b/client/src/client/gui/ingame/GuiGameOver.java similarity index 100% rename from java/src/client/gui/ingame/GuiGameOver.java rename to client/src/client/gui/ingame/GuiGameOver.java diff --git a/java/src/client/gui/ingame/GuiSign.java b/client/src/client/gui/ingame/GuiSign.java similarity index 100% rename from java/src/client/gui/ingame/GuiSign.java rename to client/src/client/gui/ingame/GuiSign.java diff --git a/java/src/client/gui/options/GuiBinds.java b/client/src/client/gui/options/GuiBinds.java similarity index 100% rename from java/src/client/gui/options/GuiBinds.java rename to client/src/client/gui/options/GuiBinds.java diff --git a/java/src/client/gui/options/GuiDisplay.java b/client/src/client/gui/options/GuiDisplay.java similarity index 100% rename from java/src/client/gui/options/GuiDisplay.java rename to client/src/client/gui/options/GuiDisplay.java diff --git a/java/src/client/gui/options/GuiOptions.java b/client/src/client/gui/options/GuiOptions.java similarity index 100% rename from java/src/client/gui/options/GuiOptions.java rename to client/src/client/gui/options/GuiOptions.java diff --git a/java/src/client/gui/options/GuiSound.java b/client/src/client/gui/options/GuiSound.java similarity index 100% rename from java/src/client/gui/options/GuiSound.java rename to client/src/client/gui/options/GuiSound.java diff --git a/java/src/client/gui/options/GuiStyle.java b/client/src/client/gui/options/GuiStyle.java similarity index 100% rename from java/src/client/gui/options/GuiStyle.java rename to client/src/client/gui/options/GuiStyle.java diff --git a/java/src/client/init/EntityRenderRegistry.java b/client/src/client/init/EntityRenderRegistry.java similarity index 100% rename from java/src/client/init/EntityRenderRegistry.java rename to client/src/client/init/EntityRenderRegistry.java diff --git a/java/src/client/network/ClientLoginHandler.java b/client/src/client/network/ClientLoginHandler.java similarity index 100% rename from java/src/client/network/ClientLoginHandler.java rename to client/src/client/network/ClientLoginHandler.java diff --git a/java/src/client/network/ClientPlayer.java b/client/src/client/network/ClientPlayer.java similarity index 100% rename from java/src/client/network/ClientPlayer.java rename to client/src/client/network/ClientPlayer.java diff --git a/java/src/client/renderer/ActiveRenderInfo.java b/client/src/client/renderer/ActiveRenderInfo.java similarity index 100% rename from java/src/client/renderer/ActiveRenderInfo.java rename to client/src/client/renderer/ActiveRenderInfo.java diff --git a/java/src/client/renderer/BlockRenderer.java b/client/src/client/renderer/BlockRenderer.java similarity index 100% rename from java/src/client/renderer/BlockRenderer.java rename to client/src/client/renderer/BlockRenderer.java diff --git a/java/src/client/renderer/DefaultVertexFormats.java b/client/src/client/renderer/DefaultVertexFormats.java similarity index 100% rename from java/src/client/renderer/DefaultVertexFormats.java rename to client/src/client/renderer/DefaultVertexFormats.java diff --git a/java/src/client/renderer/Drawing.java b/client/src/client/renderer/Drawing.java similarity index 100% rename from java/src/client/renderer/Drawing.java rename to client/src/client/renderer/Drawing.java diff --git a/java/src/client/renderer/EntityRenderer.java b/client/src/client/renderer/EntityRenderer.java similarity index 100% rename from java/src/client/renderer/EntityRenderer.java rename to client/src/client/renderer/EntityRenderer.java diff --git a/java/src/client/renderer/Frustum.java b/client/src/client/renderer/Frustum.java similarity index 100% rename from java/src/client/renderer/Frustum.java rename to client/src/client/renderer/Frustum.java diff --git a/java/src/client/renderer/GlState.java b/client/src/client/renderer/GlState.java similarity index 100% rename from java/src/client/renderer/GlState.java rename to client/src/client/renderer/GlState.java diff --git a/java/src/client/renderer/ItemModelMesher.java b/client/src/client/renderer/ItemModelMesher.java similarity index 100% rename from java/src/client/renderer/ItemModelMesher.java rename to client/src/client/renderer/ItemModelMesher.java diff --git a/java/src/client/renderer/ItemRenderer.java b/client/src/client/renderer/ItemRenderer.java similarity index 100% rename from java/src/client/renderer/ItemRenderer.java rename to client/src/client/renderer/ItemRenderer.java diff --git a/java/src/client/renderer/Project.java b/client/src/client/renderer/Project.java similarity index 100% rename from java/src/client/renderer/Project.java rename to client/src/client/renderer/Project.java diff --git a/java/src/client/renderer/RegionRenderCache.java b/client/src/client/renderer/RegionRenderCache.java similarity index 100% rename from java/src/client/renderer/RegionRenderCache.java rename to client/src/client/renderer/RegionRenderCache.java diff --git a/java/src/client/renderer/RegionRenderCacheBuilder.java b/client/src/client/renderer/RegionRenderCacheBuilder.java similarity index 100% rename from java/src/client/renderer/RegionRenderCacheBuilder.java rename to client/src/client/renderer/RegionRenderCacheBuilder.java diff --git a/java/src/client/renderer/RenderBuffer.java b/client/src/client/renderer/RenderBuffer.java similarity index 100% rename from java/src/client/renderer/RenderBuffer.java rename to client/src/client/renderer/RenderBuffer.java diff --git a/java/src/client/renderer/RenderGlobal.java b/client/src/client/renderer/RenderGlobal.java similarity index 100% rename from java/src/client/renderer/RenderGlobal.java rename to client/src/client/renderer/RenderGlobal.java diff --git a/java/src/client/renderer/Tessellator.java b/client/src/client/renderer/Tessellator.java similarity index 100% rename from java/src/client/renderer/Tessellator.java rename to client/src/client/renderer/Tessellator.java diff --git a/java/src/client/renderer/VertexBuffer.java b/client/src/client/renderer/VertexBuffer.java similarity index 100% rename from java/src/client/renderer/VertexBuffer.java rename to client/src/client/renderer/VertexBuffer.java diff --git a/java/src/client/renderer/VertexFormat.java b/client/src/client/renderer/VertexFormat.java similarity index 100% rename from java/src/client/renderer/VertexFormat.java rename to client/src/client/renderer/VertexFormat.java diff --git a/java/src/client/renderer/VertexFormatElement.java b/client/src/client/renderer/VertexFormatElement.java similarity index 100% rename from java/src/client/renderer/VertexFormatElement.java rename to client/src/client/renderer/VertexFormatElement.java diff --git a/java/src/client/renderer/ViewFrustum.java b/client/src/client/renderer/ViewFrustum.java similarity index 100% rename from java/src/client/renderer/ViewFrustum.java rename to client/src/client/renderer/ViewFrustum.java diff --git a/java/src/client/renderer/blockmodel/BakedModel.java b/client/src/client/renderer/blockmodel/BakedModel.java similarity index 100% rename from java/src/client/renderer/blockmodel/BakedModel.java rename to client/src/client/renderer/blockmodel/BakedModel.java diff --git a/java/src/client/renderer/blockmodel/BakedQuad.java b/client/src/client/renderer/blockmodel/BakedQuad.java similarity index 100% rename from java/src/client/renderer/blockmodel/BakedQuad.java rename to client/src/client/renderer/blockmodel/BakedQuad.java diff --git a/java/src/client/renderer/blockmodel/BlockFaceUV.java b/client/src/client/renderer/blockmodel/BlockFaceUV.java similarity index 100% rename from java/src/client/renderer/blockmodel/BlockFaceUV.java rename to client/src/client/renderer/blockmodel/BlockFaceUV.java diff --git a/java/src/client/renderer/blockmodel/BlockPart.java b/client/src/client/renderer/blockmodel/BlockPart.java similarity index 100% rename from java/src/client/renderer/blockmodel/BlockPart.java rename to client/src/client/renderer/blockmodel/BlockPart.java diff --git a/java/src/client/renderer/blockmodel/BlockPartFace.java b/client/src/client/renderer/blockmodel/BlockPartFace.java similarity index 100% rename from java/src/client/renderer/blockmodel/BlockPartFace.java rename to client/src/client/renderer/blockmodel/BlockPartFace.java diff --git a/java/src/client/renderer/blockmodel/BlockPartRotation.java b/client/src/client/renderer/blockmodel/BlockPartRotation.java similarity index 100% rename from java/src/client/renderer/blockmodel/BlockPartRotation.java rename to client/src/client/renderer/blockmodel/BlockPartRotation.java diff --git a/java/src/client/renderer/blockmodel/BreakingFour.java b/client/src/client/renderer/blockmodel/BreakingFour.java similarity index 100% rename from java/src/client/renderer/blockmodel/BreakingFour.java rename to client/src/client/renderer/blockmodel/BreakingFour.java diff --git a/java/src/client/renderer/blockmodel/BuiltInModel.java b/client/src/client/renderer/blockmodel/BuiltInModel.java similarity index 100% rename from java/src/client/renderer/blockmodel/BuiltInModel.java rename to client/src/client/renderer/blockmodel/BuiltInModel.java diff --git a/java/src/client/renderer/blockmodel/FaceBakery.java b/client/src/client/renderer/blockmodel/FaceBakery.java similarity index 100% rename from java/src/client/renderer/blockmodel/FaceBakery.java rename to client/src/client/renderer/blockmodel/FaceBakery.java diff --git a/java/src/client/renderer/blockmodel/IBakedModel.java b/client/src/client/renderer/blockmodel/IBakedModel.java similarity index 100% rename from java/src/client/renderer/blockmodel/IBakedModel.java rename to client/src/client/renderer/blockmodel/IBakedModel.java diff --git a/java/src/client/renderer/blockmodel/ModelBakery.java b/client/src/client/renderer/blockmodel/ModelBakery.java similarity index 100% rename from java/src/client/renderer/blockmodel/ModelBakery.java rename to client/src/client/renderer/blockmodel/ModelBakery.java diff --git a/java/src/client/renderer/blockmodel/ModelBlock.java b/client/src/client/renderer/blockmodel/ModelBlock.java similarity index 100% rename from java/src/client/renderer/blockmodel/ModelBlock.java rename to client/src/client/renderer/blockmodel/ModelBlock.java diff --git a/java/src/client/renderer/blockmodel/ModelGenerator.java b/client/src/client/renderer/blockmodel/ModelGenerator.java similarity index 100% rename from java/src/client/renderer/blockmodel/ModelGenerator.java rename to client/src/client/renderer/blockmodel/ModelGenerator.java diff --git a/java/src/client/renderer/blockmodel/ModelManager.java b/client/src/client/renderer/blockmodel/ModelManager.java similarity index 100% rename from java/src/client/renderer/blockmodel/ModelManager.java rename to client/src/client/renderer/blockmodel/ModelManager.java diff --git a/java/src/client/renderer/blockmodel/MultiStateMap.java b/client/src/client/renderer/blockmodel/MultiStateMap.java similarity index 100% rename from java/src/client/renderer/blockmodel/MultiStateMap.java rename to client/src/client/renderer/blockmodel/MultiStateMap.java diff --git a/java/src/client/renderer/blockmodel/SingleStateMap.java b/client/src/client/renderer/blockmodel/SingleStateMap.java similarity index 100% rename from java/src/client/renderer/blockmodel/SingleStateMap.java rename to client/src/client/renderer/blockmodel/SingleStateMap.java diff --git a/java/src/client/renderer/blockmodel/StateMap.java b/client/src/client/renderer/blockmodel/StateMap.java similarity index 100% rename from java/src/client/renderer/blockmodel/StateMap.java rename to client/src/client/renderer/blockmodel/StateMap.java diff --git a/java/src/client/renderer/chunk/ChunkCompileTaskGenerator.java b/client/src/client/renderer/chunk/ChunkCompileTaskGenerator.java similarity index 100% rename from java/src/client/renderer/chunk/ChunkCompileTaskGenerator.java rename to client/src/client/renderer/chunk/ChunkCompileTaskGenerator.java diff --git a/java/src/client/renderer/chunk/ChunkRenderDispatcher.java b/client/src/client/renderer/chunk/ChunkRenderDispatcher.java similarity index 100% rename from java/src/client/renderer/chunk/ChunkRenderDispatcher.java rename to client/src/client/renderer/chunk/ChunkRenderDispatcher.java diff --git a/java/src/client/renderer/chunk/ChunkRenderWorker.java b/client/src/client/renderer/chunk/ChunkRenderWorker.java similarity index 100% rename from java/src/client/renderer/chunk/ChunkRenderWorker.java rename to client/src/client/renderer/chunk/ChunkRenderWorker.java diff --git a/java/src/client/renderer/chunk/CompiledChunk.java b/client/src/client/renderer/chunk/CompiledChunk.java similarity index 100% rename from java/src/client/renderer/chunk/CompiledChunk.java rename to client/src/client/renderer/chunk/CompiledChunk.java diff --git a/java/src/client/renderer/chunk/RenderChunk.java b/client/src/client/renderer/chunk/RenderChunk.java similarity index 100% rename from java/src/client/renderer/chunk/RenderChunk.java rename to client/src/client/renderer/chunk/RenderChunk.java diff --git a/java/src/client/renderer/chunk/SetVisibility.java b/client/src/client/renderer/chunk/SetVisibility.java similarity index 100% rename from java/src/client/renderer/chunk/SetVisibility.java rename to client/src/client/renderer/chunk/SetVisibility.java diff --git a/java/src/client/renderer/chunk/VisGraph.java b/client/src/client/renderer/chunk/VisGraph.java similarity index 100% rename from java/src/client/renderer/chunk/VisGraph.java rename to client/src/client/renderer/chunk/VisGraph.java diff --git a/java/src/client/renderer/entity/Render.java b/client/src/client/renderer/entity/Render.java similarity index 100% rename from java/src/client/renderer/entity/Render.java rename to client/src/client/renderer/entity/Render.java diff --git a/java/src/client/renderer/entity/RenderArachnoid.java b/client/src/client/renderer/entity/RenderArachnoid.java similarity index 100% rename from java/src/client/renderer/entity/RenderArachnoid.java rename to client/src/client/renderer/entity/RenderArachnoid.java diff --git a/java/src/client/renderer/entity/RenderArrow.java b/client/src/client/renderer/entity/RenderArrow.java similarity index 100% rename from java/src/client/renderer/entity/RenderArrow.java rename to client/src/client/renderer/entity/RenderArrow.java diff --git a/java/src/client/renderer/entity/RenderBat.java b/client/src/client/renderer/entity/RenderBat.java similarity index 100% rename from java/src/client/renderer/entity/RenderBat.java rename to client/src/client/renderer/entity/RenderBat.java diff --git a/java/src/client/renderer/entity/RenderBlockEntity.java b/client/src/client/renderer/entity/RenderBlockEntity.java similarity index 100% rename from java/src/client/renderer/entity/RenderBlockEntity.java rename to client/src/client/renderer/entity/RenderBlockEntity.java diff --git a/java/src/client/renderer/entity/RenderBoat.java b/client/src/client/renderer/entity/RenderBoat.java similarity index 100% rename from java/src/client/renderer/entity/RenderBoat.java rename to client/src/client/renderer/entity/RenderBoat.java diff --git a/java/src/client/renderer/entity/RenderBullet.java b/client/src/client/renderer/entity/RenderBullet.java similarity index 100% rename from java/src/client/renderer/entity/RenderBullet.java rename to client/src/client/renderer/entity/RenderBullet.java diff --git a/java/src/client/renderer/entity/RenderChicken.java b/client/src/client/renderer/entity/RenderChicken.java similarity index 100% rename from java/src/client/renderer/entity/RenderChicken.java rename to client/src/client/renderer/entity/RenderChicken.java diff --git a/java/src/client/renderer/entity/RenderCow.java b/client/src/client/renderer/entity/RenderCow.java similarity index 100% rename from java/src/client/renderer/entity/RenderCow.java rename to client/src/client/renderer/entity/RenderCow.java diff --git a/java/src/client/renderer/entity/RenderCrystal.java b/client/src/client/renderer/entity/RenderCrystal.java similarity index 100% rename from java/src/client/renderer/entity/RenderCrystal.java rename to client/src/client/renderer/entity/RenderCrystal.java diff --git a/java/src/client/renderer/entity/RenderDie.java b/client/src/client/renderer/entity/RenderDie.java similarity index 100% rename from java/src/client/renderer/entity/RenderDie.java rename to client/src/client/renderer/entity/RenderDie.java diff --git a/java/src/client/renderer/entity/RenderDragon.java b/client/src/client/renderer/entity/RenderDragon.java similarity index 100% rename from java/src/client/renderer/entity/RenderDragon.java rename to client/src/client/renderer/entity/RenderDragon.java diff --git a/java/src/client/renderer/entity/RenderDynamite.java b/client/src/client/renderer/entity/RenderDynamite.java similarity index 100% rename from java/src/client/renderer/entity/RenderDynamite.java rename to client/src/client/renderer/entity/RenderDynamite.java diff --git a/java/src/client/renderer/entity/RenderEntity.java b/client/src/client/renderer/entity/RenderEntity.java similarity index 100% rename from java/src/client/renderer/entity/RenderEntity.java rename to client/src/client/renderer/entity/RenderEntity.java diff --git a/java/src/client/renderer/entity/RenderEntityItem.java b/client/src/client/renderer/entity/RenderEntityItem.java similarity index 100% rename from java/src/client/renderer/entity/RenderEntityItem.java rename to client/src/client/renderer/entity/RenderEntityItem.java diff --git a/java/src/client/renderer/entity/RenderFallingBlock.java b/client/src/client/renderer/entity/RenderFallingBlock.java similarity index 100% rename from java/src/client/renderer/entity/RenderFallingBlock.java rename to client/src/client/renderer/entity/RenderFallingBlock.java diff --git a/java/src/client/renderer/entity/RenderFireball.java b/client/src/client/renderer/entity/RenderFireball.java similarity index 100% rename from java/src/client/renderer/entity/RenderFireball.java rename to client/src/client/renderer/entity/RenderFireball.java diff --git a/java/src/client/renderer/entity/RenderFish.java b/client/src/client/renderer/entity/RenderFish.java similarity index 100% rename from java/src/client/renderer/entity/RenderFish.java rename to client/src/client/renderer/entity/RenderFish.java diff --git a/java/src/client/renderer/entity/RenderFlyingBox.java b/client/src/client/renderer/entity/RenderFlyingBox.java similarity index 100% rename from java/src/client/renderer/entity/RenderFlyingBox.java rename to client/src/client/renderer/entity/RenderFlyingBox.java diff --git a/java/src/client/renderer/entity/RenderHorse.java b/client/src/client/renderer/entity/RenderHorse.java similarity index 100% rename from java/src/client/renderer/entity/RenderHorse.java rename to client/src/client/renderer/entity/RenderHorse.java diff --git a/java/src/client/renderer/entity/RenderHumanoid.java b/client/src/client/renderer/entity/RenderHumanoid.java similarity index 100% rename from java/src/client/renderer/entity/RenderHumanoid.java rename to client/src/client/renderer/entity/RenderHumanoid.java diff --git a/java/src/client/renderer/entity/RenderItem.java b/client/src/client/renderer/entity/RenderItem.java similarity index 100% rename from java/src/client/renderer/entity/RenderItem.java rename to client/src/client/renderer/entity/RenderItem.java diff --git a/java/src/client/renderer/entity/RenderItemEntity.java b/client/src/client/renderer/entity/RenderItemEntity.java similarity index 100% rename from java/src/client/renderer/entity/RenderItemEntity.java rename to client/src/client/renderer/entity/RenderItemEntity.java diff --git a/java/src/client/renderer/entity/RenderLeashKnot.java b/client/src/client/renderer/entity/RenderLeashKnot.java similarity index 100% rename from java/src/client/renderer/entity/RenderLeashKnot.java rename to client/src/client/renderer/entity/RenderLeashKnot.java diff --git a/java/src/client/renderer/entity/RenderLightning.java b/client/src/client/renderer/entity/RenderLightning.java similarity index 100% rename from java/src/client/renderer/entity/RenderLightning.java rename to client/src/client/renderer/entity/RenderLightning.java diff --git a/java/src/client/renderer/entity/RenderLiving.java b/client/src/client/renderer/entity/RenderLiving.java similarity index 100% rename from java/src/client/renderer/entity/RenderLiving.java rename to client/src/client/renderer/entity/RenderLiving.java diff --git a/java/src/client/renderer/entity/RenderManager.java b/client/src/client/renderer/entity/RenderManager.java similarity index 100% rename from java/src/client/renderer/entity/RenderManager.java rename to client/src/client/renderer/entity/RenderManager.java diff --git a/java/src/client/renderer/entity/RenderMinecart.java b/client/src/client/renderer/entity/RenderMinecart.java similarity index 100% rename from java/src/client/renderer/entity/RenderMinecart.java rename to client/src/client/renderer/entity/RenderMinecart.java diff --git a/java/src/client/renderer/entity/RenderMooshroom.java b/client/src/client/renderer/entity/RenderMooshroom.java similarity index 100% rename from java/src/client/renderer/entity/RenderMooshroom.java rename to client/src/client/renderer/entity/RenderMooshroom.java diff --git a/java/src/client/renderer/entity/RenderMouse.java b/client/src/client/renderer/entity/RenderMouse.java similarity index 100% rename from java/src/client/renderer/entity/RenderMouse.java rename to client/src/client/renderer/entity/RenderMouse.java diff --git a/java/src/client/renderer/entity/RenderNpc.java b/client/src/client/renderer/entity/RenderNpc.java similarity index 100% rename from java/src/client/renderer/entity/RenderNpc.java rename to client/src/client/renderer/entity/RenderNpc.java diff --git a/java/src/client/renderer/entity/RenderOcelot.java b/client/src/client/renderer/entity/RenderOcelot.java similarity index 100% rename from java/src/client/renderer/entity/RenderOcelot.java rename to client/src/client/renderer/entity/RenderOcelot.java diff --git a/java/src/client/renderer/entity/RenderPig.java b/client/src/client/renderer/entity/RenderPig.java similarity index 100% rename from java/src/client/renderer/entity/RenderPig.java rename to client/src/client/renderer/entity/RenderPig.java diff --git a/java/src/client/renderer/entity/RenderPotion.java b/client/src/client/renderer/entity/RenderPotion.java similarity index 100% rename from java/src/client/renderer/entity/RenderPotion.java rename to client/src/client/renderer/entity/RenderPotion.java diff --git a/java/src/client/renderer/entity/RenderRabbit.java b/client/src/client/renderer/entity/RenderRabbit.java similarity index 100% rename from java/src/client/renderer/entity/RenderRabbit.java rename to client/src/client/renderer/entity/RenderRabbit.java diff --git a/java/src/client/renderer/entity/RenderSheep.java b/client/src/client/renderer/entity/RenderSheep.java similarity index 100% rename from java/src/client/renderer/entity/RenderSheep.java rename to client/src/client/renderer/entity/RenderSheep.java diff --git a/java/src/client/renderer/entity/RenderSlime.java b/client/src/client/renderer/entity/RenderSlime.java similarity index 100% rename from java/src/client/renderer/entity/RenderSlime.java rename to client/src/client/renderer/entity/RenderSlime.java diff --git a/java/src/client/renderer/entity/RenderSpaceMarine.java b/client/src/client/renderer/entity/RenderSpaceMarine.java similarity index 100% rename from java/src/client/renderer/entity/RenderSpaceMarine.java rename to client/src/client/renderer/entity/RenderSpaceMarine.java diff --git a/java/src/client/renderer/entity/RenderSquid.java b/client/src/client/renderer/entity/RenderSquid.java similarity index 100% rename from java/src/client/renderer/entity/RenderSquid.java rename to client/src/client/renderer/entity/RenderSquid.java diff --git a/java/src/client/renderer/entity/RenderTntMinecart.java b/client/src/client/renderer/entity/RenderTntMinecart.java similarity index 100% rename from java/src/client/renderer/entity/RenderTntMinecart.java rename to client/src/client/renderer/entity/RenderTntMinecart.java diff --git a/java/src/client/renderer/entity/RenderTntPrimed.java b/client/src/client/renderer/entity/RenderTntPrimed.java similarity index 100% rename from java/src/client/renderer/entity/RenderTntPrimed.java rename to client/src/client/renderer/entity/RenderTntPrimed.java diff --git a/java/src/client/renderer/entity/RenderWolf.java b/client/src/client/renderer/entity/RenderWolf.java similarity index 100% rename from java/src/client/renderer/entity/RenderWolf.java rename to client/src/client/renderer/entity/RenderWolf.java diff --git a/java/src/client/renderer/entity/RenderXpOrb.java b/client/src/client/renderer/entity/RenderXpOrb.java similarity index 100% rename from java/src/client/renderer/entity/RenderXpOrb.java rename to client/src/client/renderer/entity/RenderXpOrb.java diff --git a/java/src/client/renderer/entity/RendererLivingEntity.java b/client/src/client/renderer/entity/RendererLivingEntity.java similarity index 100% rename from java/src/client/renderer/entity/RendererLivingEntity.java rename to client/src/client/renderer/entity/RendererLivingEntity.java diff --git a/java/src/client/renderer/layers/LayerArachnoidArmor.java b/client/src/client/renderer/layers/LayerArachnoidArmor.java similarity index 100% rename from java/src/client/renderer/layers/LayerArachnoidArmor.java rename to client/src/client/renderer/layers/LayerArachnoidArmor.java diff --git a/java/src/client/renderer/layers/LayerArmor.java b/client/src/client/renderer/layers/LayerArmor.java similarity index 100% rename from java/src/client/renderer/layers/LayerArmor.java rename to client/src/client/renderer/layers/LayerArmor.java diff --git a/java/src/client/renderer/layers/LayerArrow.java b/client/src/client/renderer/layers/LayerArrow.java similarity index 100% rename from java/src/client/renderer/layers/LayerArrow.java rename to client/src/client/renderer/layers/LayerArrow.java diff --git a/java/src/client/renderer/layers/LayerCape.java b/client/src/client/renderer/layers/LayerCape.java similarity index 100% rename from java/src/client/renderer/layers/LayerCape.java rename to client/src/client/renderer/layers/LayerCape.java diff --git a/java/src/client/renderer/layers/LayerCharge.java b/client/src/client/renderer/layers/LayerCharge.java similarity index 100% rename from java/src/client/renderer/layers/LayerCharge.java rename to client/src/client/renderer/layers/LayerCharge.java diff --git a/java/src/client/renderer/layers/LayerEnderDragonEyes.java b/client/src/client/renderer/layers/LayerEnderDragonEyes.java similarity index 100% rename from java/src/client/renderer/layers/LayerEnderDragonEyes.java rename to client/src/client/renderer/layers/LayerEnderDragonEyes.java diff --git a/java/src/client/renderer/layers/LayerEntityBreak.java b/client/src/client/renderer/layers/LayerEntityBreak.java similarity index 100% rename from java/src/client/renderer/layers/LayerEntityBreak.java rename to client/src/client/renderer/layers/LayerEntityBreak.java diff --git a/java/src/client/renderer/layers/LayerExtra.java b/client/src/client/renderer/layers/LayerExtra.java similarity index 100% rename from java/src/client/renderer/layers/LayerExtra.java rename to client/src/client/renderer/layers/LayerExtra.java diff --git a/java/src/client/renderer/layers/LayerHeldItem.java b/client/src/client/renderer/layers/LayerHeldItem.java similarity index 100% rename from java/src/client/renderer/layers/LayerHeldItem.java rename to client/src/client/renderer/layers/LayerHeldItem.java diff --git a/java/src/client/renderer/layers/LayerMooshroomMushroom.java b/client/src/client/renderer/layers/LayerMooshroomMushroom.java similarity index 100% rename from java/src/client/renderer/layers/LayerMooshroomMushroom.java rename to client/src/client/renderer/layers/LayerMooshroomMushroom.java diff --git a/java/src/client/renderer/layers/LayerPowerRods.java b/client/src/client/renderer/layers/LayerPowerRods.java similarity index 100% rename from java/src/client/renderer/layers/LayerPowerRods.java rename to client/src/client/renderer/layers/LayerPowerRods.java diff --git a/java/src/client/renderer/layers/LayerRenderer.java b/client/src/client/renderer/layers/LayerRenderer.java similarity index 100% rename from java/src/client/renderer/layers/LayerRenderer.java rename to client/src/client/renderer/layers/LayerRenderer.java diff --git a/java/src/client/renderer/layers/LayerSaddle.java b/client/src/client/renderer/layers/LayerSaddle.java similarity index 100% rename from java/src/client/renderer/layers/LayerSaddle.java rename to client/src/client/renderer/layers/LayerSaddle.java diff --git a/java/src/client/renderer/layers/LayerSheepWool.java b/client/src/client/renderer/layers/LayerSheepWool.java similarity index 100% rename from java/src/client/renderer/layers/LayerSheepWool.java rename to client/src/client/renderer/layers/LayerSheepWool.java diff --git a/java/src/client/renderer/layers/LayerSlimeGel.java b/client/src/client/renderer/layers/LayerSlimeGel.java similarity index 100% rename from java/src/client/renderer/layers/LayerSlimeGel.java rename to client/src/client/renderer/layers/LayerSlimeGel.java diff --git a/java/src/client/renderer/layers/LayerWolfCollar.java b/client/src/client/renderer/layers/LayerWolfCollar.java similarity index 100% rename from java/src/client/renderer/layers/LayerWolfCollar.java rename to client/src/client/renderer/layers/LayerWolfCollar.java diff --git a/java/src/client/renderer/model/ModelArachnoid.java b/client/src/client/renderer/model/ModelArachnoid.java similarity index 100% rename from java/src/client/renderer/model/ModelArachnoid.java rename to client/src/client/renderer/model/ModelArachnoid.java diff --git a/java/src/client/renderer/model/ModelArmor.java b/client/src/client/renderer/model/ModelArmor.java similarity index 100% rename from java/src/client/renderer/model/ModelArmor.java rename to client/src/client/renderer/model/ModelArmor.java diff --git a/java/src/client/renderer/model/ModelBanner.java b/client/src/client/renderer/model/ModelBanner.java similarity index 100% rename from java/src/client/renderer/model/ModelBanner.java rename to client/src/client/renderer/model/ModelBanner.java diff --git a/java/src/client/renderer/model/ModelBase.java b/client/src/client/renderer/model/ModelBase.java similarity index 100% rename from java/src/client/renderer/model/ModelBase.java rename to client/src/client/renderer/model/ModelBase.java diff --git a/java/src/client/renderer/model/ModelBat.java b/client/src/client/renderer/model/ModelBat.java similarity index 100% rename from java/src/client/renderer/model/ModelBat.java rename to client/src/client/renderer/model/ModelBat.java diff --git a/java/src/client/renderer/model/ModelBiped.java b/client/src/client/renderer/model/ModelBiped.java similarity index 100% rename from java/src/client/renderer/model/ModelBiped.java rename to client/src/client/renderer/model/ModelBiped.java diff --git a/java/src/client/renderer/model/ModelBoat.java b/client/src/client/renderer/model/ModelBoat.java similarity index 100% rename from java/src/client/renderer/model/ModelBoat.java rename to client/src/client/renderer/model/ModelBoat.java diff --git a/java/src/client/renderer/model/ModelBox.java b/client/src/client/renderer/model/ModelBox.java similarity index 100% rename from java/src/client/renderer/model/ModelBox.java rename to client/src/client/renderer/model/ModelBox.java diff --git a/java/src/client/renderer/model/ModelCharge.java b/client/src/client/renderer/model/ModelCharge.java similarity index 100% rename from java/src/client/renderer/model/ModelCharge.java rename to client/src/client/renderer/model/ModelCharge.java diff --git a/java/src/client/renderer/model/ModelChest.java b/client/src/client/renderer/model/ModelChest.java similarity index 100% rename from java/src/client/renderer/model/ModelChest.java rename to client/src/client/renderer/model/ModelChest.java diff --git a/java/src/client/renderer/model/ModelChicken.java b/client/src/client/renderer/model/ModelChicken.java similarity index 100% rename from java/src/client/renderer/model/ModelChicken.java rename to client/src/client/renderer/model/ModelChicken.java diff --git a/java/src/client/renderer/model/ModelCow.java b/client/src/client/renderer/model/ModelCow.java similarity index 100% rename from java/src/client/renderer/model/ModelCow.java rename to client/src/client/renderer/model/ModelCow.java diff --git a/java/src/client/renderer/model/ModelCrystal.java b/client/src/client/renderer/model/ModelCrystal.java similarity index 100% rename from java/src/client/renderer/model/ModelCrystal.java rename to client/src/client/renderer/model/ModelCrystal.java diff --git a/java/src/client/renderer/model/ModelDie.java b/client/src/client/renderer/model/ModelDie.java similarity index 100% rename from java/src/client/renderer/model/ModelDie.java rename to client/src/client/renderer/model/ModelDie.java diff --git a/java/src/client/renderer/model/ModelDragon.java b/client/src/client/renderer/model/ModelDragon.java similarity index 100% rename from java/src/client/renderer/model/ModelDragon.java rename to client/src/client/renderer/model/ModelDragon.java diff --git a/java/src/client/renderer/model/ModelHead.java b/client/src/client/renderer/model/ModelHead.java similarity index 100% rename from java/src/client/renderer/model/ModelHead.java rename to client/src/client/renderer/model/ModelHead.java diff --git a/java/src/client/renderer/model/ModelHorse.java b/client/src/client/renderer/model/ModelHorse.java similarity index 100% rename from java/src/client/renderer/model/ModelHorse.java rename to client/src/client/renderer/model/ModelHorse.java diff --git a/java/src/client/renderer/model/ModelHumanoid.java b/client/src/client/renderer/model/ModelHumanoid.java similarity index 100% rename from java/src/client/renderer/model/ModelHumanoid.java rename to client/src/client/renderer/model/ModelHumanoid.java diff --git a/java/src/client/renderer/model/ModelHumanoidHead.java b/client/src/client/renderer/model/ModelHumanoidHead.java similarity index 100% rename from java/src/client/renderer/model/ModelHumanoidHead.java rename to client/src/client/renderer/model/ModelHumanoidHead.java diff --git a/java/src/client/renderer/model/ModelLargeChest.java b/client/src/client/renderer/model/ModelLargeChest.java similarity index 100% rename from java/src/client/renderer/model/ModelLargeChest.java rename to client/src/client/renderer/model/ModelLargeChest.java diff --git a/java/src/client/renderer/model/ModelLeashKnot.java b/client/src/client/renderer/model/ModelLeashKnot.java similarity index 100% rename from java/src/client/renderer/model/ModelLeashKnot.java rename to client/src/client/renderer/model/ModelLeashKnot.java diff --git a/java/src/client/renderer/model/ModelMinecart.java b/client/src/client/renderer/model/ModelMinecart.java similarity index 100% rename from java/src/client/renderer/model/ModelMinecart.java rename to client/src/client/renderer/model/ModelMinecart.java diff --git a/java/src/client/renderer/model/ModelMouse.java b/client/src/client/renderer/model/ModelMouse.java similarity index 100% rename from java/src/client/renderer/model/ModelMouse.java rename to client/src/client/renderer/model/ModelMouse.java diff --git a/java/src/client/renderer/model/ModelOcelot.java b/client/src/client/renderer/model/ModelOcelot.java similarity index 100% rename from java/src/client/renderer/model/ModelOcelot.java rename to client/src/client/renderer/model/ModelOcelot.java diff --git a/java/src/client/renderer/model/ModelPig.java b/client/src/client/renderer/model/ModelPig.java similarity index 100% rename from java/src/client/renderer/model/ModelPig.java rename to client/src/client/renderer/model/ModelPig.java diff --git a/java/src/client/renderer/model/ModelQuadruped.java b/client/src/client/renderer/model/ModelQuadruped.java similarity index 100% rename from java/src/client/renderer/model/ModelQuadruped.java rename to client/src/client/renderer/model/ModelQuadruped.java diff --git a/java/src/client/renderer/model/ModelRabbit.java b/client/src/client/renderer/model/ModelRabbit.java similarity index 100% rename from java/src/client/renderer/model/ModelRabbit.java rename to client/src/client/renderer/model/ModelRabbit.java diff --git a/java/src/client/renderer/model/ModelRenderer.java b/client/src/client/renderer/model/ModelRenderer.java similarity index 100% rename from java/src/client/renderer/model/ModelRenderer.java rename to client/src/client/renderer/model/ModelRenderer.java diff --git a/java/src/client/renderer/model/ModelSheep1.java b/client/src/client/renderer/model/ModelSheep1.java similarity index 100% rename from java/src/client/renderer/model/ModelSheep1.java rename to client/src/client/renderer/model/ModelSheep1.java diff --git a/java/src/client/renderer/model/ModelSheep2.java b/client/src/client/renderer/model/ModelSheep2.java similarity index 100% rename from java/src/client/renderer/model/ModelSheep2.java rename to client/src/client/renderer/model/ModelSheep2.java diff --git a/java/src/client/renderer/model/ModelSign.java b/client/src/client/renderer/model/ModelSign.java similarity index 100% rename from java/src/client/renderer/model/ModelSign.java rename to client/src/client/renderer/model/ModelSign.java diff --git a/java/src/client/renderer/model/ModelSlime.java b/client/src/client/renderer/model/ModelSlime.java similarity index 100% rename from java/src/client/renderer/model/ModelSlime.java rename to client/src/client/renderer/model/ModelSlime.java diff --git a/java/src/client/renderer/model/ModelSpaceMarine.java b/client/src/client/renderer/model/ModelSpaceMarine.java similarity index 100% rename from java/src/client/renderer/model/ModelSpaceMarine.java rename to client/src/client/renderer/model/ModelSpaceMarine.java diff --git a/java/src/client/renderer/model/ModelSquid.java b/client/src/client/renderer/model/ModelSquid.java similarity index 100% rename from java/src/client/renderer/model/ModelSquid.java rename to client/src/client/renderer/model/ModelSquid.java diff --git a/java/src/client/renderer/model/ModelWolf.java b/client/src/client/renderer/model/ModelWolf.java similarity index 100% rename from java/src/client/renderer/model/ModelWolf.java rename to client/src/client/renderer/model/ModelWolf.java diff --git a/java/src/client/renderer/model/PositionTextureVertex.java b/client/src/client/renderer/model/PositionTextureVertex.java similarity index 100% rename from java/src/client/renderer/model/PositionTextureVertex.java rename to client/src/client/renderer/model/PositionTextureVertex.java diff --git a/java/src/client/renderer/model/TextureOffset.java b/client/src/client/renderer/model/TextureOffset.java similarity index 100% rename from java/src/client/renderer/model/TextureOffset.java rename to client/src/client/renderer/model/TextureOffset.java diff --git a/java/src/client/renderer/model/TexturedQuad.java b/client/src/client/renderer/model/TexturedQuad.java similarity index 100% rename from java/src/client/renderer/model/TexturedQuad.java rename to client/src/client/renderer/model/TexturedQuad.java diff --git a/java/src/client/renderer/particle/EffectRenderer.java b/client/src/client/renderer/particle/EffectRenderer.java similarity index 100% rename from java/src/client/renderer/particle/EffectRenderer.java rename to client/src/client/renderer/particle/EffectRenderer.java diff --git a/java/src/client/renderer/particle/EntityAuraFX.java b/client/src/client/renderer/particle/EntityAuraFX.java similarity index 100% rename from java/src/client/renderer/particle/EntityAuraFX.java rename to client/src/client/renderer/particle/EntityAuraFX.java diff --git a/java/src/client/renderer/particle/EntityBlockDustFX.java b/client/src/client/renderer/particle/EntityBlockDustFX.java similarity index 100% rename from java/src/client/renderer/particle/EntityBlockDustFX.java rename to client/src/client/renderer/particle/EntityBlockDustFX.java diff --git a/java/src/client/renderer/particle/EntityBreakingFX.java b/client/src/client/renderer/particle/EntityBreakingFX.java similarity index 100% rename from java/src/client/renderer/particle/EntityBreakingFX.java rename to client/src/client/renderer/particle/EntityBreakingFX.java diff --git a/java/src/client/renderer/particle/EntityBubbleFX.java b/client/src/client/renderer/particle/EntityBubbleFX.java similarity index 100% rename from java/src/client/renderer/particle/EntityBubbleFX.java rename to client/src/client/renderer/particle/EntityBubbleFX.java diff --git a/java/src/client/renderer/particle/EntityCloudFX.java b/client/src/client/renderer/particle/EntityCloudFX.java similarity index 100% rename from java/src/client/renderer/particle/EntityCloudFX.java rename to client/src/client/renderer/particle/EntityCloudFX.java diff --git a/java/src/client/renderer/particle/EntityCrit2FX.java b/client/src/client/renderer/particle/EntityCrit2FX.java similarity index 100% rename from java/src/client/renderer/particle/EntityCrit2FX.java rename to client/src/client/renderer/particle/EntityCrit2FX.java diff --git a/java/src/client/renderer/particle/EntityCritFX.java b/client/src/client/renderer/particle/EntityCritFX.java similarity index 100% rename from java/src/client/renderer/particle/EntityCritFX.java rename to client/src/client/renderer/particle/EntityCritFX.java diff --git a/java/src/client/renderer/particle/EntityDiggingFX.java b/client/src/client/renderer/particle/EntityDiggingFX.java similarity index 100% rename from java/src/client/renderer/particle/EntityDiggingFX.java rename to client/src/client/renderer/particle/EntityDiggingFX.java diff --git a/java/src/client/renderer/particle/EntityDownfallFX.java b/client/src/client/renderer/particle/EntityDownfallFX.java similarity index 100% rename from java/src/client/renderer/particle/EntityDownfallFX.java rename to client/src/client/renderer/particle/EntityDownfallFX.java diff --git a/java/src/client/renderer/particle/EntityDropParticleFX.java b/client/src/client/renderer/particle/EntityDropParticleFX.java similarity index 100% rename from java/src/client/renderer/particle/EntityDropParticleFX.java rename to client/src/client/renderer/particle/EntityDropParticleFX.java diff --git a/java/src/client/renderer/particle/EntityEnchantmentTableParticleFX.java b/client/src/client/renderer/particle/EntityEnchantmentTableParticleFX.java similarity index 100% rename from java/src/client/renderer/particle/EntityEnchantmentTableParticleFX.java rename to client/src/client/renderer/particle/EntityEnchantmentTableParticleFX.java diff --git a/java/src/client/renderer/particle/EntityExplodeFX.java b/client/src/client/renderer/particle/EntityExplodeFX.java similarity index 100% rename from java/src/client/renderer/particle/EntityExplodeFX.java rename to client/src/client/renderer/particle/EntityExplodeFX.java diff --git a/java/src/client/renderer/particle/EntityFX.java b/client/src/client/renderer/particle/EntityFX.java similarity index 100% rename from java/src/client/renderer/particle/EntityFX.java rename to client/src/client/renderer/particle/EntityFX.java diff --git a/java/src/client/renderer/particle/EntityFirework.java b/client/src/client/renderer/particle/EntityFirework.java similarity index 100% rename from java/src/client/renderer/particle/EntityFirework.java rename to client/src/client/renderer/particle/EntityFirework.java diff --git a/java/src/client/renderer/particle/EntityFishWakeFX.java b/client/src/client/renderer/particle/EntityFishWakeFX.java similarity index 100% rename from java/src/client/renderer/particle/EntityFishWakeFX.java rename to client/src/client/renderer/particle/EntityFishWakeFX.java diff --git a/java/src/client/renderer/particle/EntityFlameFX.java b/client/src/client/renderer/particle/EntityFlameFX.java similarity index 100% rename from java/src/client/renderer/particle/EntityFlameFX.java rename to client/src/client/renderer/particle/EntityFlameFX.java diff --git a/java/src/client/renderer/particle/EntityFootStepFX.java b/client/src/client/renderer/particle/EntityFootStepFX.java similarity index 100% rename from java/src/client/renderer/particle/EntityFootStepFX.java rename to client/src/client/renderer/particle/EntityFootStepFX.java diff --git a/java/src/client/renderer/particle/EntityHeartFX.java b/client/src/client/renderer/particle/EntityHeartFX.java similarity index 100% rename from java/src/client/renderer/particle/EntityHeartFX.java rename to client/src/client/renderer/particle/EntityHeartFX.java diff --git a/java/src/client/renderer/particle/EntityHugeExplodeFX.java b/client/src/client/renderer/particle/EntityHugeExplodeFX.java similarity index 100% rename from java/src/client/renderer/particle/EntityHugeExplodeFX.java rename to client/src/client/renderer/particle/EntityHugeExplodeFX.java diff --git a/java/src/client/renderer/particle/EntityLargeExplodeFX.java b/client/src/client/renderer/particle/EntityLargeExplodeFX.java similarity index 100% rename from java/src/client/renderer/particle/EntityLargeExplodeFX.java rename to client/src/client/renderer/particle/EntityLargeExplodeFX.java diff --git a/java/src/client/renderer/particle/EntityLavaFX.java b/client/src/client/renderer/particle/EntityLavaFX.java similarity index 100% rename from java/src/client/renderer/particle/EntityLavaFX.java rename to client/src/client/renderer/particle/EntityLavaFX.java diff --git a/java/src/client/renderer/particle/EntityNoteFX.java b/client/src/client/renderer/particle/EntityNoteFX.java similarity index 100% rename from java/src/client/renderer/particle/EntityNoteFX.java rename to client/src/client/renderer/particle/EntityNoteFX.java diff --git a/java/src/client/renderer/particle/EntityParticleEmitter.java b/client/src/client/renderer/particle/EntityParticleEmitter.java similarity index 100% rename from java/src/client/renderer/particle/EntityParticleEmitter.java rename to client/src/client/renderer/particle/EntityParticleEmitter.java diff --git a/java/src/client/renderer/particle/EntityPickupFX.java b/client/src/client/renderer/particle/EntityPickupFX.java similarity index 100% rename from java/src/client/renderer/particle/EntityPickupFX.java rename to client/src/client/renderer/particle/EntityPickupFX.java diff --git a/java/src/client/renderer/particle/EntityPortalFX.java b/client/src/client/renderer/particle/EntityPortalFX.java similarity index 100% rename from java/src/client/renderer/particle/EntityPortalFX.java rename to client/src/client/renderer/particle/EntityPortalFX.java diff --git a/java/src/client/renderer/particle/EntityReddustFX.java b/client/src/client/renderer/particle/EntityReddustFX.java similarity index 100% rename from java/src/client/renderer/particle/EntityReddustFX.java rename to client/src/client/renderer/particle/EntityReddustFX.java diff --git a/java/src/client/renderer/particle/EntitySmokeFX.java b/client/src/client/renderer/particle/EntitySmokeFX.java similarity index 100% rename from java/src/client/renderer/particle/EntitySmokeFX.java rename to client/src/client/renderer/particle/EntitySmokeFX.java diff --git a/java/src/client/renderer/particle/EntitySnowShovelFX.java b/client/src/client/renderer/particle/EntitySnowShovelFX.java similarity index 100% rename from java/src/client/renderer/particle/EntitySnowShovelFX.java rename to client/src/client/renderer/particle/EntitySnowShovelFX.java diff --git a/java/src/client/renderer/particle/EntitySpellParticleFX.java b/client/src/client/renderer/particle/EntitySpellParticleFX.java similarity index 100% rename from java/src/client/renderer/particle/EntitySpellParticleFX.java rename to client/src/client/renderer/particle/EntitySpellParticleFX.java diff --git a/java/src/client/renderer/particle/EntitySplashFX.java b/client/src/client/renderer/particle/EntitySplashFX.java similarity index 100% rename from java/src/client/renderer/particle/EntitySplashFX.java rename to client/src/client/renderer/particle/EntitySplashFX.java diff --git a/java/src/client/renderer/particle/EntitySuspendFX.java b/client/src/client/renderer/particle/EntitySuspendFX.java similarity index 100% rename from java/src/client/renderer/particle/EntitySuspendFX.java rename to client/src/client/renderer/particle/EntitySuspendFX.java diff --git a/java/src/client/renderer/particle/IParticleFactory.java b/client/src/client/renderer/particle/IParticleFactory.java similarity index 100% rename from java/src/client/renderer/particle/IParticleFactory.java rename to client/src/client/renderer/particle/IParticleFactory.java diff --git a/java/src/client/renderer/texture/DynamicTexture.java b/client/src/client/renderer/texture/DynamicTexture.java similarity index 100% rename from java/src/client/renderer/texture/DynamicTexture.java rename to client/src/client/renderer/texture/DynamicTexture.java diff --git a/java/src/client/renderer/texture/EntityTexManager.java b/client/src/client/renderer/texture/EntityTexManager.java similarity index 100% rename from java/src/client/renderer/texture/EntityTexManager.java rename to client/src/client/renderer/texture/EntityTexManager.java diff --git a/java/src/client/renderer/texture/IIconCreator.java b/client/src/client/renderer/texture/IIconCreator.java similarity index 100% rename from java/src/client/renderer/texture/IIconCreator.java rename to client/src/client/renderer/texture/IIconCreator.java diff --git a/java/src/client/renderer/texture/LayeredColorMaskTexture.java b/client/src/client/renderer/texture/LayeredColorMaskTexture.java similarity index 100% rename from java/src/client/renderer/texture/LayeredColorMaskTexture.java rename to client/src/client/renderer/texture/LayeredColorMaskTexture.java diff --git a/java/src/client/renderer/texture/LayeredTexture.java b/client/src/client/renderer/texture/LayeredTexture.java similarity index 100% rename from java/src/client/renderer/texture/LayeredTexture.java rename to client/src/client/renderer/texture/LayeredTexture.java diff --git a/java/src/client/renderer/texture/SimpleTexture.java b/client/src/client/renderer/texture/SimpleTexture.java similarity index 100% rename from java/src/client/renderer/texture/SimpleTexture.java rename to client/src/client/renderer/texture/SimpleTexture.java diff --git a/java/src/client/renderer/texture/Stitcher.java b/client/src/client/renderer/texture/Stitcher.java similarity index 100% rename from java/src/client/renderer/texture/Stitcher.java rename to client/src/client/renderer/texture/Stitcher.java diff --git a/java/src/client/renderer/texture/Texture.java b/client/src/client/renderer/texture/Texture.java similarity index 100% rename from java/src/client/renderer/texture/Texture.java rename to client/src/client/renderer/texture/Texture.java diff --git a/java/src/client/renderer/texture/TextureAtlasSprite.java b/client/src/client/renderer/texture/TextureAtlasSprite.java similarity index 100% rename from java/src/client/renderer/texture/TextureAtlasSprite.java rename to client/src/client/renderer/texture/TextureAtlasSprite.java diff --git a/java/src/client/renderer/texture/TextureManager.java b/client/src/client/renderer/texture/TextureManager.java similarity index 100% rename from java/src/client/renderer/texture/TextureManager.java rename to client/src/client/renderer/texture/TextureManager.java diff --git a/java/src/client/renderer/texture/TextureMap.java b/client/src/client/renderer/texture/TextureMap.java similarity index 100% rename from java/src/client/renderer/texture/TextureMap.java rename to client/src/client/renderer/texture/TextureMap.java diff --git a/java/src/client/renderer/texture/TextureTicked.java b/client/src/client/renderer/texture/TextureTicked.java similarity index 100% rename from java/src/client/renderer/texture/TextureTicked.java rename to client/src/client/renderer/texture/TextureTicked.java diff --git a/java/src/client/renderer/texture/TextureUtil.java b/client/src/client/renderer/texture/TextureUtil.java similarity index 100% rename from java/src/client/renderer/texture/TextureUtil.java rename to client/src/client/renderer/texture/TextureUtil.java diff --git a/java/src/client/renderer/ticked/TextureFlamesFX1.java b/client/src/client/renderer/ticked/TextureFlamesFX1.java similarity index 100% rename from java/src/client/renderer/ticked/TextureFlamesFX1.java rename to client/src/client/renderer/ticked/TextureFlamesFX1.java diff --git a/java/src/client/renderer/ticked/TextureFlamesFX2.java b/client/src/client/renderer/ticked/TextureFlamesFX2.java similarity index 100% rename from java/src/client/renderer/ticked/TextureFlamesFX2.java rename to client/src/client/renderer/ticked/TextureFlamesFX2.java diff --git a/java/src/client/renderer/ticked/TextureLavaFX.java b/client/src/client/renderer/ticked/TextureLavaFX.java similarity index 100% rename from java/src/client/renderer/ticked/TextureLavaFX.java rename to client/src/client/renderer/ticked/TextureLavaFX.java diff --git a/java/src/client/renderer/ticked/TextureLavaFlowFX.java b/client/src/client/renderer/ticked/TextureLavaFlowFX.java similarity index 100% rename from java/src/client/renderer/ticked/TextureLavaFlowFX.java rename to client/src/client/renderer/ticked/TextureLavaFlowFX.java diff --git a/java/src/client/renderer/ticked/TextureWaterFX.java b/client/src/client/renderer/ticked/TextureWaterFX.java similarity index 100% rename from java/src/client/renderer/ticked/TextureWaterFX.java rename to client/src/client/renderer/ticked/TextureWaterFX.java diff --git a/java/src/client/renderer/ticked/TextureWaterFlowFX.java b/client/src/client/renderer/ticked/TextureWaterFlowFX.java similarity index 100% rename from java/src/client/renderer/ticked/TextureWaterFlowFX.java rename to client/src/client/renderer/ticked/TextureWaterFlowFX.java diff --git a/java/src/client/renderer/tileentity/TileEntityBannerRenderer.java b/client/src/client/renderer/tileentity/TileEntityBannerRenderer.java similarity index 100% rename from java/src/client/renderer/tileentity/TileEntityBannerRenderer.java rename to client/src/client/renderer/tileentity/TileEntityBannerRenderer.java diff --git a/java/src/client/renderer/tileentity/TileEntityChestRenderer.java b/client/src/client/renderer/tileentity/TileEntityChestRenderer.java similarity index 100% rename from java/src/client/renderer/tileentity/TileEntityChestRenderer.java rename to client/src/client/renderer/tileentity/TileEntityChestRenderer.java diff --git a/java/src/client/renderer/tileentity/TileEntityItemStackRenderer.java b/client/src/client/renderer/tileentity/TileEntityItemStackRenderer.java similarity index 100% rename from java/src/client/renderer/tileentity/TileEntityItemStackRenderer.java rename to client/src/client/renderer/tileentity/TileEntityItemStackRenderer.java diff --git a/java/src/client/renderer/tileentity/TileEntityMobSpawnerRenderer.java b/client/src/client/renderer/tileentity/TileEntityMobSpawnerRenderer.java similarity index 100% rename from java/src/client/renderer/tileentity/TileEntityMobSpawnerRenderer.java rename to client/src/client/renderer/tileentity/TileEntityMobSpawnerRenderer.java diff --git a/java/src/client/renderer/tileentity/TileEntityPistonRenderer.java b/client/src/client/renderer/tileentity/TileEntityPistonRenderer.java similarity index 100% rename from java/src/client/renderer/tileentity/TileEntityPistonRenderer.java rename to client/src/client/renderer/tileentity/TileEntityPistonRenderer.java diff --git a/java/src/client/renderer/tileentity/TileEntityRendererDispatcher.java b/client/src/client/renderer/tileentity/TileEntityRendererDispatcher.java similarity index 100% rename from java/src/client/renderer/tileentity/TileEntityRendererDispatcher.java rename to client/src/client/renderer/tileentity/TileEntityRendererDispatcher.java diff --git a/java/src/client/renderer/tileentity/TileEntitySignRenderer.java b/client/src/client/renderer/tileentity/TileEntitySignRenderer.java similarity index 100% rename from java/src/client/renderer/tileentity/TileEntitySignRenderer.java rename to client/src/client/renderer/tileentity/TileEntitySignRenderer.java diff --git a/java/src/client/renderer/tileentity/TileEntitySkullRenderer.java b/client/src/client/renderer/tileentity/TileEntitySkullRenderer.java similarity index 100% rename from java/src/client/renderer/tileentity/TileEntitySkullRenderer.java rename to client/src/client/renderer/tileentity/TileEntitySkullRenderer.java diff --git a/java/src/client/renderer/tileentity/TileEntitySpecialRenderer.java b/client/src/client/renderer/tileentity/TileEntitySpecialRenderer.java similarity index 100% rename from java/src/client/renderer/tileentity/TileEntitySpecialRenderer.java rename to client/src/client/renderer/tileentity/TileEntitySpecialRenderer.java diff --git a/java/src/client/window/Bind.java b/client/src/client/window/Bind.java similarity index 100% rename from java/src/client/window/Bind.java rename to client/src/client/window/Bind.java diff --git a/java/src/client/window/Button.java b/client/src/client/window/Button.java similarity index 100% rename from java/src/client/window/Button.java rename to client/src/client/window/Button.java diff --git a/java/src/client/window/DisplayMode.java b/client/src/client/window/DisplayMode.java similarity index 100% rename from java/src/client/window/DisplayMode.java rename to client/src/client/window/DisplayMode.java diff --git a/java/src/client/window/Input.java b/client/src/client/window/Input.java similarity index 100% rename from java/src/client/window/Input.java rename to client/src/client/window/Input.java diff --git a/java/src/client/window/KeyEvent.java b/client/src/client/window/KeyEvent.java similarity index 100% rename from java/src/client/window/KeyEvent.java rename to client/src/client/window/KeyEvent.java diff --git a/java/src/client/window/Keysym.java b/client/src/client/window/Keysym.java similarity index 100% rename from java/src/client/window/Keysym.java rename to client/src/client/window/Keysym.java diff --git a/java/src/client/window/Wheel.java b/client/src/client/window/Wheel.java similarity index 100% rename from java/src/client/window/Wheel.java rename to client/src/client/window/Wheel.java diff --git a/java/src/client/window/Window.java b/client/src/client/window/Window.java similarity index 100% rename from java/src/client/window/Window.java rename to client/src/client/window/Window.java diff --git a/java/src/client/window/WindowAction.java b/client/src/client/window/WindowAction.java similarity index 100% rename from java/src/client/window/WindowAction.java rename to client/src/client/window/WindowAction.java diff --git a/java/src/client/window/WindowEvent.java b/client/src/client/window/WindowEvent.java similarity index 100% rename from java/src/client/window/WindowEvent.java rename to client/src/client/window/WindowEvent.java diff --git a/java/src/game/vars/BaseVar.java b/client/src/game/vars/BaseVar.java similarity index 100% rename from java/src/game/vars/BaseVar.java rename to client/src/game/vars/BaseVar.java diff --git a/java/src/game/vars/BoolVar.java b/client/src/game/vars/BoolVar.java similarity index 100% rename from java/src/game/vars/BoolVar.java rename to client/src/game/vars/BoolVar.java diff --git a/java/src/game/vars/CVar.java b/client/src/game/vars/CVar.java similarity index 100% rename from java/src/game/vars/CVar.java rename to client/src/game/vars/CVar.java diff --git a/java/src/game/vars/CVarCategory.java b/client/src/game/vars/CVarCategory.java similarity index 100% rename from java/src/game/vars/CVarCategory.java rename to client/src/game/vars/CVarCategory.java diff --git a/java/src/game/vars/ColorVar.java b/client/src/game/vars/ColorVar.java similarity index 100% rename from java/src/game/vars/ColorVar.java rename to client/src/game/vars/ColorVar.java diff --git a/java/src/game/vars/EnumVar.java b/client/src/game/vars/EnumVar.java similarity index 100% rename from java/src/game/vars/EnumVar.java rename to client/src/game/vars/EnumVar.java diff --git a/java/src/game/vars/FloatVar.java b/client/src/game/vars/FloatVar.java similarity index 100% rename from java/src/game/vars/FloatVar.java rename to client/src/game/vars/FloatVar.java diff --git a/java/src/game/vars/IntVar.java b/client/src/game/vars/IntVar.java similarity index 100% rename from java/src/game/vars/IntVar.java rename to client/src/game/vars/IntVar.java diff --git a/java/src/game/vars/StringVar.java b/client/src/game/vars/StringVar.java similarity index 100% rename from java/src/game/vars/StringVar.java rename to client/src/game/vars/StringVar.java diff --git a/java/src/game/vars/Variable.java b/client/src/game/vars/Variable.java similarity index 100% rename from java/src/game/vars/Variable.java rename to client/src/game/vars/Variable.java diff --git a/java/src/game/world/Converter.java b/client/src/game/world/Converter.java similarity index 99% rename from java/src/game/world/Converter.java rename to client/src/game/world/Converter.java index 279412e..c50ebe0 100644 --- a/java/src/game/world/Converter.java +++ b/client/src/game/world/Converter.java @@ -87,25 +87,9 @@ import game.tileentity.TileEntityPiston; import game.tileentity.TileEntitySign; import game.tileentity.TileEntitySkull; import game.world.Region.FolderInfo; +import game.world.Region.SaveVersion; public final class Converter { - public static enum SaveVersion { - ALPHA_1_0("Alpha 1.0 - Beta 1.2"), - BETA_1_3("Beta 1.3 - Release 1.8.9"), - RELEASE_1_9("Release 1.9 - Release 1.12.2"), - RELEASE_1_13("Release 1.13 +"); - - private final String name; - - private SaveVersion(String name) { - this.name = name; - } - - public String toString() { - return this.name; - } - } - // public static interface Callback { // void postMessage(String msg); // void postProgress(int progress); diff --git a/java/src/game/init/Config.java b/java/src/game/init/Config.java index 3210f9f..e59968e 100755 --- a/java/src/game/init/Config.java +++ b/java/src/game/init/Config.java @@ -14,7 +14,7 @@ import java.util.TreeMap; import game.packet.SPacketWorld; import game.util.ExtMath; import game.world.WorldServer; -import server.Server; +import game.IServer; public abstract class Config { public static enum ValueType { @@ -22,7 +22,7 @@ public abstract class Config { } private static interface Callback { - void run(Server server); + void run(IServer server); } @Target(FIELD) @@ -504,7 +504,7 @@ public abstract class Config { } } - public static void set(String key, String value, Server server) { + public static void set(String key, String value, IServer server) { Config.Value vl = VARS.get(key); if(vl != null) { vl.setValue(value); @@ -514,7 +514,7 @@ public abstract class Config { } public static class WorldCallback implements Callback { - public void run(Server server) { + public void run(IServer server) { for(WorldServer world : server.getWorlds()) { world.updatePhysics(); } @@ -522,7 +522,7 @@ public abstract class Config { } } public static class DistanceCallback implements Callback { - public void run(Server server) { + public void run(IServer server) { for(WorldServer world : server.getWorlds()) { world.updateViewRadius(); } diff --git a/java/src/game/world/Region.java b/java/src/game/world/Region.java index a3a5a28..a3df508 100755 --- a/java/src/game/world/Region.java +++ b/java/src/game/world/Region.java @@ -30,9 +30,25 @@ import game.nbt.NBTLoader; import game.nbt.NBTTagCompound; import game.nbt.NBTTagList; import game.tileentity.TileEntity; -import game.world.Converter.SaveVersion; public class Region { + public static enum SaveVersion { + ALPHA_1_0("Alpha 1.0 - Beta 1.2"), + BETA_1_3("Beta 1.3 - Release 1.8.9"), + RELEASE_1_9("Release 1.9 - Release 1.12.2"), + RELEASE_1_13("Release 1.13 +"); + + private final String name; + + private SaveVersion(String name) { + this.name = name; + } + + public String toString() { + return this.name; + } + } + public static class FolderInfo { public final long time; public final long lastPlayed; diff --git a/java/src/server/Server.java b/server/src/server/Server.java similarity index 100% rename from java/src/server/Server.java rename to server/src/server/Server.java diff --git a/java/src/server/command/ArgCombiner.java b/server/src/server/command/ArgCombiner.java similarity index 100% rename from java/src/server/command/ArgCombiner.java rename to server/src/server/command/ArgCombiner.java diff --git a/java/src/server/command/Argument.java b/server/src/server/command/Argument.java similarity index 100% rename from java/src/server/command/Argument.java rename to server/src/server/command/Argument.java diff --git a/java/src/server/command/ArgumentParser.java b/server/src/server/command/ArgumentParser.java similarity index 100% rename from java/src/server/command/ArgumentParser.java rename to server/src/server/command/ArgumentParser.java diff --git a/java/src/server/command/ArgumentSplitter.java b/server/src/server/command/ArgumentSplitter.java similarity index 100% rename from java/src/server/command/ArgumentSplitter.java rename to server/src/server/command/ArgumentSplitter.java diff --git a/java/src/server/command/BooleanParser.java b/server/src/server/command/BooleanParser.java similarity index 100% rename from java/src/server/command/BooleanParser.java rename to server/src/server/command/BooleanParser.java diff --git a/java/src/server/command/CachedExecutable.java b/server/src/server/command/CachedExecutable.java similarity index 100% rename from java/src/server/command/CachedExecutable.java rename to server/src/server/command/CachedExecutable.java diff --git a/java/src/server/command/ColorParser.java b/server/src/server/command/ColorParser.java similarity index 100% rename from java/src/server/command/ColorParser.java rename to server/src/server/command/ColorParser.java diff --git a/java/src/server/command/Command.java b/server/src/server/command/Command.java similarity index 100% rename from java/src/server/command/Command.java rename to server/src/server/command/Command.java diff --git a/java/src/server/command/CommandEnvironment.java b/server/src/server/command/CommandEnvironment.java similarity index 100% rename from java/src/server/command/CommandEnvironment.java rename to server/src/server/command/CommandEnvironment.java diff --git a/java/src/server/command/Completer.java b/server/src/server/command/Completer.java similarity index 100% rename from java/src/server/command/Completer.java rename to server/src/server/command/Completer.java diff --git a/java/src/server/command/CompletingParser.java b/server/src/server/command/CompletingParser.java similarity index 100% rename from java/src/server/command/CompletingParser.java rename to server/src/server/command/CompletingParser.java diff --git a/java/src/server/command/DefaultingParser.java b/server/src/server/command/DefaultingParser.java similarity index 100% rename from java/src/server/command/DefaultingParser.java rename to server/src/server/command/DefaultingParser.java diff --git a/java/src/server/command/DimensionParser.java b/server/src/server/command/DimensionParser.java similarity index 100% rename from java/src/server/command/DimensionParser.java rename to server/src/server/command/DimensionParser.java diff --git a/java/src/server/command/DoubleParser.java b/server/src/server/command/DoubleParser.java similarity index 100% rename from java/src/server/command/DoubleParser.java rename to server/src/server/command/DoubleParser.java diff --git a/java/src/server/command/EntityListParser.java b/server/src/server/command/EntityListParser.java similarity index 100% rename from java/src/server/command/EntityListParser.java rename to server/src/server/command/EntityListParser.java diff --git a/java/src/server/command/EntityParser.java b/server/src/server/command/EntityParser.java similarity index 100% rename from java/src/server/command/EntityParser.java rename to server/src/server/command/EntityParser.java diff --git a/java/src/server/command/EnumParser.java b/server/src/server/command/EnumParser.java similarity index 100% rename from java/src/server/command/EnumParser.java rename to server/src/server/command/EnumParser.java diff --git a/java/src/server/command/Executable.java b/server/src/server/command/Executable.java similarity index 100% rename from java/src/server/command/Executable.java rename to server/src/server/command/Executable.java diff --git a/java/src/server/command/Executor.java b/server/src/server/command/Executor.java similarity index 100% rename from java/src/server/command/Executor.java rename to server/src/server/command/Executor.java diff --git a/java/src/server/command/FixedExecutor.java b/server/src/server/command/FixedExecutor.java similarity index 100% rename from java/src/server/command/FixedExecutor.java rename to server/src/server/command/FixedExecutor.java diff --git a/java/src/server/command/IntParser.java b/server/src/server/command/IntParser.java similarity index 100% rename from java/src/server/command/IntParser.java rename to server/src/server/command/IntParser.java diff --git a/java/src/server/command/LongParser.java b/server/src/server/command/LongParser.java similarity index 100% rename from java/src/server/command/LongParser.java rename to server/src/server/command/LongParser.java diff --git a/java/src/server/command/NonDefaultingParser.java b/server/src/server/command/NonDefaultingParser.java similarity index 100% rename from java/src/server/command/NonDefaultingParser.java rename to server/src/server/command/NonDefaultingParser.java diff --git a/java/src/server/command/Parameter.java b/server/src/server/command/Parameter.java similarity index 100% rename from java/src/server/command/Parameter.java rename to server/src/server/command/Parameter.java diff --git a/java/src/server/command/PatternReplacer.java b/server/src/server/command/PatternReplacer.java similarity index 100% rename from java/src/server/command/PatternReplacer.java rename to server/src/server/command/PatternReplacer.java diff --git a/java/src/server/command/PlayerEntityListParser.java b/server/src/server/command/PlayerEntityListParser.java similarity index 100% rename from java/src/server/command/PlayerEntityListParser.java rename to server/src/server/command/PlayerEntityListParser.java diff --git a/java/src/server/command/PlayerEntityParser.java b/server/src/server/command/PlayerEntityParser.java similarity index 100% rename from java/src/server/command/PlayerEntityParser.java rename to server/src/server/command/PlayerEntityParser.java diff --git a/java/src/server/command/PlayerListParser.java b/server/src/server/command/PlayerListParser.java similarity index 100% rename from java/src/server/command/PlayerListParser.java rename to server/src/server/command/PlayerListParser.java diff --git a/java/src/server/command/PlayerParser.java b/server/src/server/command/PlayerParser.java similarity index 100% rename from java/src/server/command/PlayerParser.java rename to server/src/server/command/PlayerParser.java diff --git a/java/src/server/command/RunException.java b/server/src/server/command/RunException.java similarity index 100% rename from java/src/server/command/RunException.java rename to server/src/server/command/RunException.java diff --git a/java/src/server/command/StringCompleter.java b/server/src/server/command/StringCompleter.java similarity index 100% rename from java/src/server/command/StringCompleter.java rename to server/src/server/command/StringCompleter.java diff --git a/java/src/server/command/StringParser.java b/server/src/server/command/StringParser.java similarity index 100% rename from java/src/server/command/StringParser.java rename to server/src/server/command/StringParser.java diff --git a/java/src/server/command/TagParser.java b/server/src/server/command/TagParser.java similarity index 100% rename from java/src/server/command/TagParser.java rename to server/src/server/command/TagParser.java diff --git a/java/src/server/command/Variable.java b/server/src/server/command/Variable.java similarity index 100% rename from java/src/server/command/Variable.java rename to server/src/server/command/Variable.java diff --git a/java/src/server/command/WorldParser.java b/server/src/server/command/WorldParser.java similarity index 100% rename from java/src/server/command/WorldParser.java rename to server/src/server/command/WorldParser.java diff --git a/java/src/server/command/commands/CommandAdmin.java b/server/src/server/command/commands/CommandAdmin.java similarity index 100% rename from java/src/server/command/commands/CommandAdmin.java rename to server/src/server/command/commands/CommandAdmin.java diff --git a/java/src/server/command/commands/CommandHelp.java b/server/src/server/command/commands/CommandHelp.java similarity index 100% rename from java/src/server/command/commands/CommandHelp.java rename to server/src/server/command/commands/CommandHelp.java diff --git a/java/src/server/command/commands/CommandKick.java b/server/src/server/command/commands/CommandKick.java similarity index 100% rename from java/src/server/command/commands/CommandKick.java rename to server/src/server/command/commands/CommandKick.java diff --git a/java/src/server/command/commands/CommandMessage.java b/server/src/server/command/commands/CommandMessage.java similarity index 100% rename from java/src/server/command/commands/CommandMessage.java rename to server/src/server/command/commands/CommandMessage.java diff --git a/java/src/server/command/commands/CommandMilk.java b/server/src/server/command/commands/CommandMilk.java similarity index 100% rename from java/src/server/command/commands/CommandMilk.java rename to server/src/server/command/commands/CommandMilk.java diff --git a/java/src/server/command/commands/CommandOfflinetp.java b/server/src/server/command/commands/CommandOfflinetp.java similarity index 100% rename from java/src/server/command/commands/CommandOfflinetp.java rename to server/src/server/command/commands/CommandOfflinetp.java diff --git a/java/src/server/command/commands/CommandPotion.java b/server/src/server/command/commands/CommandPotion.java similarity index 100% rename from java/src/server/command/commands/CommandPotion.java rename to server/src/server/command/commands/CommandPotion.java diff --git a/java/src/server/command/commands/CommandRemove.java b/server/src/server/command/commands/CommandRemove.java similarity index 100% rename from java/src/server/command/commands/CommandRemove.java rename to server/src/server/command/commands/CommandRemove.java diff --git a/java/src/server/command/commands/CommandRevoke.java b/server/src/server/command/commands/CommandRevoke.java similarity index 100% rename from java/src/server/command/commands/CommandRevoke.java rename to server/src/server/command/commands/CommandRevoke.java diff --git a/java/src/server/command/commands/CommandSpawn.java b/server/src/server/command/commands/CommandSpawn.java similarity index 100% rename from java/src/server/command/commands/CommandSpawn.java rename to server/src/server/command/commands/CommandSpawn.java diff --git a/java/src/server/command/commands/CommandTele.java b/server/src/server/command/commands/CommandTele.java similarity index 100% rename from java/src/server/command/commands/CommandTele.java rename to server/src/server/command/commands/CommandTele.java diff --git a/java/src/server/command/commands/CommandTime.java b/server/src/server/command/commands/CommandTime.java similarity index 100% rename from java/src/server/command/commands/CommandTime.java rename to server/src/server/command/commands/CommandTime.java diff --git a/java/src/server/command/commands/CommandTp.java b/server/src/server/command/commands/CommandTp.java similarity index 100% rename from java/src/server/command/commands/CommandTp.java rename to server/src/server/command/commands/CommandTp.java diff --git a/java/src/server/command/commands/CommandWarp.java b/server/src/server/command/commands/CommandWarp.java similarity index 100% rename from java/src/server/command/commands/CommandWarp.java rename to server/src/server/command/commands/CommandWarp.java diff --git a/java/src/server/command/commands/CommandWeather.java b/server/src/server/command/commands/CommandWeather.java similarity index 100% rename from java/src/server/command/commands/CommandWeather.java rename to server/src/server/command/commands/CommandWeather.java diff --git a/java/src/server/command/commands/CommandWorld.java b/server/src/server/command/commands/CommandWorld.java similarity index 100% rename from java/src/server/command/commands/CommandWorld.java rename to server/src/server/command/commands/CommandWorld.java diff --git a/java/src/server/network/HandshakeHandler.java b/server/src/server/network/HandshakeHandler.java similarity index 100% rename from java/src/server/network/HandshakeHandler.java rename to server/src/server/network/HandshakeHandler.java diff --git a/java/src/server/network/LoginHandler.java b/server/src/server/network/LoginHandler.java similarity index 100% rename from java/src/server/network/LoginHandler.java rename to server/src/server/network/LoginHandler.java diff --git a/java/src/server/network/Player.java b/server/src/server/network/Player.java similarity index 100% rename from java/src/server/network/Player.java rename to server/src/server/network/Player.java From 3e70accb76b11b28259cf276515a9b767426bbf0 Mon Sep 17 00:00:00 2001 From: Sen Date: Wed, 7 May 2025 17:40:28 +0200 Subject: [PATCH 005/200] split client and server 6 --- client/src/client/Game.java | 39 ++++- client/src/client/gui/GuiConvert.java | 2 +- client/src/client/gui/character/GuiChar.java | 10 +- client/src/client/init/AnimationRegistry.java | 22 +++ .../src/client/init/EntityRenderRegistry.java | 2 +- client/src/client/network/ClientPlayer.java | 80 +++++++++++ client/src/client/renderer/ItemRenderer.java | 3 +- .../renderer/entity/RenderHumanoid.java | 3 +- .../src/client/renderer/entity/RenderNpc.java | 5 +- .../src/client/renderer/layers/LayerCape.java | 5 +- .../client/renderer/layers/LayerExtra.java | 3 +- .../renderer/texture/ColormapLoader.java | 27 ++++ .../renderer/texture/EntityTexManager.java | 14 +- .../client/renderer/texture/TextureMap.java | 15 +- java/src/game/IClient.java | 10 ++ java/src/game/block/BlockFire.java | 6 +- java/src/game/color/Colorizer.java | 30 ++-- .../game/entity/npc/EntityHoveringNPC.java | 4 +- java/src/game/entity/npc/EntityNPC.java | 136 +++++------------- java/src/game/entity/types/IEntityFX.java | 4 +- java/src/game/init/BlockRegistry.java | 8 +- java/src/game/network/IClientPlayer.java | 12 ++ java/src/game/network/IPlayer.java | 15 +- java/src/game/packet/CPacketSkin.java | 21 +-- java/src/game/packet/SPacketSkin.java | 6 +- java/src/game/packet/SPacketSpawnPlayer.java | 6 +- 26 files changed, 301 insertions(+), 187 deletions(-) create mode 100644 client/src/client/init/AnimationRegistry.java create mode 100644 client/src/client/renderer/texture/ColormapLoader.java diff --git a/client/src/client/Game.java b/client/src/client/Game.java index f528cb0..48ac915 100755 --- a/client/src/client/Game.java +++ b/client/src/client/Game.java @@ -66,6 +66,7 @@ import client.renderer.entity.RenderItem; import client.renderer.entity.RenderManager; import client.renderer.particle.EffectRenderer; import client.renderer.particle.EntityFirework; +import client.renderer.texture.ColormapLoader; import client.renderer.texture.EntityTexManager; import client.renderer.texture.TextureManager; import client.renderer.texture.TextureMap; @@ -82,7 +83,6 @@ import game.biome.Biome; import game.block.Block; import game.collect.Lists; import game.collect.Maps; -import game.color.Colorizer; import game.color.TextColor; import game.entity.Entity; import game.entity.animal.EntityHorse; @@ -109,6 +109,7 @@ import game.log.Log; import game.log.LogLevel; import game.log.Message; import game.material.Material; +import game.model.ParticleType; import game.nbt.NBTTagCompound; import game.network.IThreadListener; import game.network.NetConnection; @@ -489,7 +490,7 @@ public class Game implements IThreadListener, IClient { public void refreshResources() { this.textureManager.onReload(); - Colorizer.reload(); + ColormapLoader.reload(); this.modelManager.onReload(); this.renderItem.onReload(); this.blockRenderer.onReload(); @@ -503,7 +504,7 @@ public class Game implements IThreadListener, IClient { this.textureManager = new TextureManager(); this.textureManager.onReload(); this.soundManager = new SoundManager(this); - Colorizer.reload(); + ColormapLoader.reload(); GlState.enableTexture2D(); GlState.shadeModel(GL11.GL_SMOOTH); GL11.glClearDepth(1.0D); @@ -3326,4 +3327,36 @@ public class Game implements IThreadListener, IClient { public void markBlocksForUpdate(int x1, int y1, int z1, int x2, int y2, int z2) { this.renderGlobal.markBlocksForUpdate(x1, y1, z1, x2, y2, z2); } + + public void emitParticleAtEntity(Entity entityIn, ParticleType particleTypes) { + this.effectRenderer.emitParticleAtEntity(entityIn, particleTypes); + } + + public boolean isJumping() { + return this.jump; + } + + public boolean isSprinting() { + return this.sprint; + } + + public boolean isSneaking() { + return this.sneak; + } + + public float getMoveForward() { + return this.moveForward; + } + + public float getMoveStrafe() { + return this.moveStrafe; + } + + public void setMoveForward(float value) { + this.moveForward = value; + } + + public void setMoveStrafe(float value) { + this.moveStrafe = value; + } } diff --git a/client/src/client/gui/GuiConvert.java b/client/src/client/gui/GuiConvert.java index e4b49e8..4097025 100755 --- a/client/src/client/gui/GuiConvert.java +++ b/client/src/client/gui/GuiConvert.java @@ -17,9 +17,9 @@ import game.color.TextColor; import game.dimension.Space; import game.log.Log; import game.world.Converter; -import game.world.Converter.SaveVersion; import game.world.Region; import game.world.Region.FolderInfo; +import game.world.Region.SaveVersion; import game.world.World; public class GuiConvert extends GuiList implements ActButton.Callback diff --git a/client/src/client/gui/character/GuiChar.java b/client/src/client/gui/character/GuiChar.java index 4ffc119..7fc0645 100755 --- a/client/src/client/gui/character/GuiChar.java +++ b/client/src/client/gui/character/GuiChar.java @@ -162,7 +162,15 @@ public class GuiChar extends GuiList // } // } GuiChar.this.templateButton.enabled = this.charinfo != null; - GuiChar.this.gm.getNetHandler().addToSendQueue(new CPacketSkin(this.skinImage, this.skinImage != null ? null : this.charinfo.skin, this.model)); + if(this.skinImage == null) { + GuiChar.this.gm.getNetHandler().addToSendQueue(new CPacketSkin(null, this.charinfo.skin)); + } + else { + int[] img = new int[this.model.texWidth * this.model.texHeight]; + this.skinImage.getRGB(0, 0, this.skinImage.getWidth(), this.skinImage.getHeight(), img, 0, this.skinImage.getWidth()); + GuiChar.this.gm.getNetHandler().addToSendQueue(new CPacketSkin(EntityTexManager.imageToComp(img, this.model), null)); + } +// GuiChar.this.gm.getNetHandler().addToSendQueue(new CPacketSkin(this.skinImage, this.skinImage != null ? null : this.charinfo.skin, this.model)); GuiChar.this.currentSkin = this.skinFile != null ? this.skinFile.getName() : this.charinfo.skin; GuiChar.this.waiting = false; } diff --git a/client/src/client/init/AnimationRegistry.java b/client/src/client/init/AnimationRegistry.java new file mode 100644 index 0000000..4120fbb --- /dev/null +++ b/client/src/client/init/AnimationRegistry.java @@ -0,0 +1,22 @@ +package client.init; + +import java.util.Map; + +import client.renderer.texture.TextureTicked; +import client.renderer.ticked.TextureFlamesFX1; +import client.renderer.ticked.TextureFlamesFX2; +import client.renderer.ticked.TextureLavaFX; +import client.renderer.ticked.TextureLavaFlowFX; +import client.renderer.ticked.TextureWaterFX; +import client.renderer.ticked.TextureWaterFlowFX; + +public abstract class AnimationRegistry { + public static void registerAnimations(Map> anim) { + anim.put("fire1", TextureFlamesFX1.class); + anim.put("fire2", TextureFlamesFX2.class); + anim.put("lavaflow", TextureLavaFlowFX.class); + anim.put("lava", TextureLavaFX.class); + anim.put("waterflow", TextureWaterFlowFX.class); + anim.put("water", TextureWaterFX.class); + } +} diff --git a/client/src/client/init/EntityRenderRegistry.java b/client/src/client/init/EntityRenderRegistry.java index 535ff26..b8df0a0 100644 --- a/client/src/client/init/EntityRenderRegistry.java +++ b/client/src/client/init/EntityRenderRegistry.java @@ -99,7 +99,7 @@ import game.init.Items; import game.init.SpeciesRegistry; import game.init.SpeciesRegistry.ModelType; -public class EntityRenderRegistry { +public abstract class EntityRenderRegistry { public static void registerRenderers(Map, Render> map, Map models, RenderManager mgr, RenderItem ritem) { map.put(EntityPig.class, new RenderPig(mgr, new ModelPig())); diff --git a/client/src/client/network/ClientPlayer.java b/client/src/client/network/ClientPlayer.java index 78cc391..dff2c2f 100755 --- a/client/src/client/network/ClientPlayer.java +++ b/client/src/client/network/ClientPlayer.java @@ -13,8 +13,18 @@ import client.gui.GuiConsole; import client.gui.GuiLoading; import client.gui.character.GuiChar; import client.gui.character.GuiCharacters; +import client.gui.container.GuiBrewing; +import client.gui.container.GuiChest; +import client.gui.container.GuiCrafting; +import client.gui.container.GuiDispenser; +import client.gui.container.GuiEnchant; +import client.gui.container.GuiFurnace; +import client.gui.container.GuiHopper; +import client.gui.container.GuiHorse; import client.gui.container.GuiMachine; import client.gui.container.GuiMerchant; +import client.gui.container.GuiRepair; +import client.gui.ingame.GuiSign; import client.renderer.particle.EntityPickupFX; import client.renderer.texture.EntityTexManager; import game.collect.Lists; @@ -40,6 +50,7 @@ import game.init.SoundEvent; import game.inventory.AnimalChest; import game.inventory.Container; import game.inventory.ContainerLocalMenu; +import game.inventory.IInventory; import game.inventory.InventoryBasic; import game.inventory.InventoryPlayer; import game.item.ItemStack; @@ -115,14 +126,17 @@ import game.packet.SPacketUpdateHealth; import game.packet.SPacketWorld; import game.potion.PotionEffect; import game.rng.Random; +import game.tileentity.IInteractionObject; import game.tileentity.LocalBlockIntercommunication; import game.tileentity.TileEntity; import game.tileentity.TileEntityMachine; import game.tileentity.TileEntitySign; import game.village.MerchantRecipeList; +import game.world.BlockPos; import game.world.Chunk; import game.world.Explosion; import game.world.Weather; +import game.world.World; import game.world.WorldClient; public class ClientPlayer extends NetHandler implements IClientPlayer @@ -1941,4 +1955,70 @@ public class ClientPlayer extends NetHandler implements IClientPlayer { return this.playerList.keySet(); } + + public void displayGUIChest(IInventory chestInventory, InventoryPlayer inventory) { + String s = chestInventory instanceof IInteractionObject ? ((IInteractionObject)chestInventory).getGuiID() : "container"; + + if ("chest".equals(s)) + { + this.gameController.displayGuiScreen(new GuiChest(inventory, chestInventory)); + } + else if ("hopper".equals(s)) + { + this.gameController.displayGuiScreen(new GuiHopper(inventory, chestInventory)); + } + else if ("furnace".equals(s)) + { + this.gameController.displayGuiScreen(new GuiFurnace(inventory, chestInventory)); + } + else if ("brewing_stand".equals(s)) + { + this.gameController.displayGuiScreen(new GuiBrewing(inventory, chestInventory)); + } +// else if ("beacon".equals(s)) +// { +// this.gm.displayGuiScreen(new GuiBeacon(this.inventory, chestInventory)); +// } + else if (!"dispenser".equals(s) && !"dropper".equals(s)) + { + this.gameController.displayGuiScreen(new GuiChest(inventory, chestInventory)); + } + else + { + this.gameController.displayGuiScreen(new GuiDispenser(inventory, chestInventory)); + } + } + + public void displayGui(IInteractionObject guiOwner, InventoryPlayer inventory, World worldObj) { + String s = guiOwner.getGuiID(); + + if ("crafting_table".equals(s)) + { + this.gameController.displayGuiScreen(new GuiCrafting(inventory, worldObj)); + } + else if ("enchanting_table".equals(s)) + { + this.gameController.displayGuiScreen(new GuiEnchant(inventory, worldObj, guiOwner)); + } + else if ("anvil".equals(s)) + { + this.gameController.displayGuiScreen(new GuiRepair(inventory, worldObj)); + } + } + + public void displayGuiHorse(EntityHorse horse, InventoryPlayer inventory, IInventory horseInventory) { + this.gameController.displayGuiScreen(new GuiHorse(inventory, horseInventory, horse)); + } + + public void displayGuiMerchant(String title, InventoryPlayer inventory, World worldObj) { + this.gameController.displayGuiScreen(new GuiMerchant(inventory, title, worldObj)); + } + + public void displayGuiSign(BlockPos pos, String[] signText) { + this.gameController.displayGuiScreen(new GuiSign(pos, signText)); + } + + public void closeGui() { + this.gameController.displayGuiScreen(null); + } } diff --git a/client/src/client/renderer/ItemRenderer.java b/client/src/client/renderer/ItemRenderer.java index b5d7544..c3ac2e1 100755 --- a/client/src/client/renderer/ItemRenderer.java +++ b/client/src/client/renderer/ItemRenderer.java @@ -11,6 +11,7 @@ import client.Game; import client.renderer.entity.RenderItem; import client.renderer.entity.RenderManager; import client.renderer.entity.RenderNpc; +import client.renderer.texture.EntityTexManager; import client.renderer.texture.TextureAtlasSprite; import client.renderer.texture.TextureMap; import game.block.Block; @@ -291,7 +292,7 @@ public class ItemRenderer float f4 = ExtMath.sin(ExtMath.sqrtf(swingProgress) * (float)Math.PI); GL11.glRotatef(f4 * 70.0F, 0.0F, 1.0F, 0.0F); GL11.glRotatef(f3 * -20.0F, 0.0F, 0.0F, 1.0F); - this.gm.getTextureManager().bindTexture(clientPlayer.getLocationSkin()); + this.gm.getTextureManager().bindTexture(EntityTexManager.getSkin(clientPlayer)); GL11.glTranslatef(-1.0F, 3.6F, 3.5F); GL11.glRotatef(120.0F, 0.0F, 0.0F, 1.0F); GL11.glRotatef(200.0F, 1.0F, 0.0F, 0.0F); diff --git a/client/src/client/renderer/entity/RenderHumanoid.java b/client/src/client/renderer/entity/RenderHumanoid.java index 55748f0..6815f32 100755 --- a/client/src/client/renderer/entity/RenderHumanoid.java +++ b/client/src/client/renderer/entity/RenderHumanoid.java @@ -12,6 +12,7 @@ import client.renderer.layers.LayerHeldItem; import client.renderer.layers.LayerPowerRods; import client.renderer.model.ModelBiped; import client.renderer.model.ModelHumanoid; +import client.renderer.texture.EntityTexManager; import game.entity.npc.EntityNPC; import game.item.ItemAction; import game.item.ItemStack; @@ -82,7 +83,7 @@ public class RenderHumanoid extends RenderNpc protected void renderLayers(EntityNPC entity, float swing, float amount, float partial, float time, float dYaw, float dPitch, float scale) { super.renderLayers(entity, swing, amount, partial, time, dYaw, dPitch, scale); - LayerExtra extra = entity.getExtrasLayer(); + LayerExtra extra = EntityTexManager.getLayer(entity); if(extra != null) { extra.setModel(this.getMainModel()); // boolean bright = this.setBrightness(entity, partial, extra.shouldCombineTextures()); diff --git a/client/src/client/renderer/entity/RenderNpc.java b/client/src/client/renderer/entity/RenderNpc.java index c443ef8..8fee9dc 100755 --- a/client/src/client/renderer/entity/RenderNpc.java +++ b/client/src/client/renderer/entity/RenderNpc.java @@ -5,6 +5,7 @@ import java.util.ArrayList; import client.renderer.model.ModelBase; import client.renderer.texture.EntityTexManager; import game.entity.npc.EntityNPC; +import game.network.IPlayer; public abstract class RenderNpc extends RenderLiving @@ -64,7 +65,7 @@ public abstract class RenderNpc extends RenderLiving TexList alpha = new TexList(); this.getSegments(opaque, alpha); this.compressedSize = alpha.getSize() * 4 + opaque.getSize() * 3; - if(this.compressedSize > EntityTexManager.MAX_SKIN_SIZE) + if(this.compressedSize > IPlayer.MAX_SKIN_SIZE) throw new IllegalArgumentException("Renderer " + this.getClass() + ": Textur zu Groß (" + this.compressedSize + " Bytes)"); this.opaqueSegments = opaque.compile(); this.alphaSegments = alpha.compile(); @@ -91,7 +92,7 @@ public abstract class RenderNpc extends RenderLiving protected String getEntityTexture(EntityNPC entity) { - return entity.getLocationSkin(); + return EntityTexManager.getSkin(entity); } public void renderPlayerArm(EntityNPC entity) diff --git a/client/src/client/renderer/layers/LayerCape.java b/client/src/client/renderer/layers/LayerCape.java index 5191980..ba3bbb9 100755 --- a/client/src/client/renderer/layers/LayerCape.java +++ b/client/src/client/renderer/layers/LayerCape.java @@ -5,6 +5,7 @@ import org.lwjgl.opengl.GL11; import client.renderer.GlState; import client.renderer.entity.RenderHumanoid; import client.renderer.model.ModelRenderer; +import client.renderer.texture.EntityTexManager; import game.entity.npc.EntityNPC; import game.util.ExtMath; @@ -28,9 +29,9 @@ public class LayerCape implements LayerRenderer { if(/* !entitylivingbaseIn.isInvisible() && */ // entitylivingbaseIn.isWearing(ModelPart.CAPE) // && - entitylivingbaseIn.getLocationCape() != null) { + EntityTexManager.getCape(entitylivingbaseIn) != null) { GlState.color(1.0F, 1.0F, 1.0F, 1.0F); - this.renderer.bindTexture(entitylivingbaseIn.getLocationCape()); + this.renderer.bindTexture(EntityTexManager.getCape(entitylivingbaseIn)); GL11.glPushMatrix(); GL11.glTranslatef(0.0F, 0.0F, 0.125F); if(entitylivingbaseIn.isPlayer()) { diff --git a/client/src/client/renderer/layers/LayerExtra.java b/client/src/client/renderer/layers/LayerExtra.java index d51a79c..75c168b 100755 --- a/client/src/client/renderer/layers/LayerExtra.java +++ b/client/src/client/renderer/layers/LayerExtra.java @@ -10,6 +10,7 @@ import client.renderer.blockmodel.ModelGenerator; import client.renderer.model.ModelBox; import client.renderer.model.ModelHumanoid; import client.renderer.model.ModelRenderer; +import client.renderer.texture.EntityTexManager; import game.collect.Lists; import game.entity.npc.EntityNPC; import game.init.SpeciesRegistry.ModelType; @@ -61,7 +62,7 @@ public class LayerExtra implements LayerRenderer // if (!entity.isInvisible()) // { GlState.color(1.0F, 1.0F, 1.0F, 1.0F); - Game.getGame().getTextureManager().bindTexture(extended.getLocationSkin()); + Game.getGame().getTextureManager().bindTexture(EntityTexManager.getSkin(extended)); GL11.glPushMatrix(); if (entity.isSneakingVisually()) diff --git a/client/src/client/renderer/texture/ColormapLoader.java b/client/src/client/renderer/texture/ColormapLoader.java new file mode 100644 index 0000000..38c257d --- /dev/null +++ b/client/src/client/renderer/texture/ColormapLoader.java @@ -0,0 +1,27 @@ +package client.renderer.texture; + +import java.awt.image.BufferedImage; + +import game.color.Colorizer; +import game.util.FileUtils; + +public abstract class ColormapLoader { + private static final String GRASS_TEX = "textures/world/grass.png"; + private static final String FOLIAGE_TEX = "textures/world/foliage.png"; + + public static void reload() { + BufferedImage img; + try { + img = TextureUtil.readImage(FileUtils.getResource(GRASS_TEX)); + img.getRGB(0, 0, 256, 256, Colorizer.getGrassMap(), 0, 256); + } + catch(Exception e) { + } + try { + img = TextureUtil.readImage(FileUtils.getResource(FOLIAGE_TEX)); + img.getRGB(0, 0, 256, 256, Colorizer.getFoliageMap(), 0, 256); + } + catch(Exception e) { + } + } +} diff --git a/client/src/client/renderer/texture/EntityTexManager.java b/client/src/client/renderer/texture/EntityTexManager.java index d2f0146..444163c 100755 --- a/client/src/client/renderer/texture/EntityTexManager.java +++ b/client/src/client/renderer/texture/EntityTexManager.java @@ -27,8 +27,6 @@ public abstract class EntityTexManager public static String altTexture = null; public static int altLayer = -1; public static String altNpcLayer = null; - - public static final int MAX_SKIN_SIZE = 65536; private static final Set USER_TEXTURES = Sets.newHashSet(); private static final Map USER_LAYERS = Maps.newHashMap(); @@ -233,4 +231,16 @@ public abstract class EntityTexManager render.imageToComp(comp, img, model.texWidth); return comp; } + + public static String getSkin(EntityNPC entity) { + return getSkin(entity.isPlayer() ? entity.getId() : -1, entity.getChar(), entity.getSpecies().renderer); + } + + public static LayerExtra getLayer(EntityNPC entity) { + return getLayer(entity.isPlayer() ? entity.getId() : -1, entity.getChar(), entity.getSpecies().renderer); + } + + public static String getCape(EntityNPC entity) { + return !entity.getCape().isEmpty() ? EntityTexManager.getCape(entity.getCape()) : null; + } } diff --git a/client/src/client/renderer/texture/TextureMap.java b/client/src/client/renderer/texture/TextureMap.java index 51a6936..50af03f 100755 --- a/client/src/client/renderer/texture/TextureMap.java +++ b/client/src/client/renderer/texture/TextureMap.java @@ -7,6 +7,7 @@ import java.util.List; import java.util.Map; import java.util.Map.Entry; +import client.init.AnimationRegistry; import client.renderer.GlState; import game.block.Block; import game.collect.Lists; @@ -38,6 +39,8 @@ public class TextureMap extends Texture this.missingImage = new TextureAtlasSprite(LOCATION_MISSING_TEXTURE); // RenderRegistry.registerAnimations(this); Map map = Maps.newHashMap(); + Map> anim = Maps.newHashMap(); + AnimationRegistry.registerAnimations(anim); for(Block block : BlockRegistry.REGISTRY) { block.getAnimatedTextures(map); } @@ -48,12 +51,18 @@ public class TextureMap extends Texture FluidRegistry.getFluidAnim(z)); } for(Entry entry : map.entrySet()) { - if(entry.getValue() instanceof Integer) + if(entry.getValue() instanceof Integer) { this.animTextures.put(entry.getKey(), (Integer)entry.getValue()); - else - this.tickedTextures.put(entry.getKey(), (Class)entry.getValue()); + } + else { + Class clazz = anim.get((String)entry.getValue()); + if(clazz == null) + throw new RuntimeException("Animation '" + (String)entry.getValue() + "' existiert nicht"); + this.tickedTextures.put(entry.getKey(), clazz); + } } map.clear(); + anim.clear(); } private void initMissingImage() diff --git a/java/src/game/IClient.java b/java/src/game/IClient.java index 9bec92c..3049938 100644 --- a/java/src/game/IClient.java +++ b/java/src/game/IClient.java @@ -3,6 +3,7 @@ package game; import game.entity.Entity; import game.entity.npc.EntityNPC; import game.entity.types.IEntityFX; +import game.model.ParticleType; import game.nbt.NBTTagCompound; import game.sound.Sound; import game.world.BlockPos; @@ -21,4 +22,13 @@ public interface IClient { void addBlockDestroyEffects(BlockPos pos, State state); void sendBlockBreakProgress(int breakerId, BlockPos pos, int progress); void markBlocksForUpdate(int x1, int y1, int z1, int x2, int y2, int z2); + void updatePlayerMoveState(); + void emitParticleAtEntity(Entity entityIn, ParticleType particleTypes); + boolean isJumping(); + boolean isSprinting(); + boolean isSneaking(); + float getMoveForward(); + float getMoveStrafe(); + void setMoveForward(float value); + void setMoveStrafe(float value); } diff --git a/java/src/game/block/BlockFire.java b/java/src/game/block/BlockFire.java index da5f8ed..3374010 100755 --- a/java/src/game/block/BlockFire.java +++ b/java/src/game/block/BlockFire.java @@ -2,8 +2,6 @@ package game.block; import java.util.Map; -import client.renderer.ticked.TextureFlamesFX1; -import client.renderer.ticked.TextureFlamesFX2; import game.collect.Maps; import game.init.Blocks; import game.init.Config; @@ -1166,7 +1164,7 @@ public class BlockFire extends Block } public void getAnimatedTextures(Map map) { - map.put("blocks/fire_layer_0", TextureFlamesFX1.class); - map.put("blocks/fire_layer_1", TextureFlamesFX2.class); + map.put("blocks/fire_layer_0", "fire1"); + map.put("blocks/fire_layer_1", "fire2"); } } diff --git a/java/src/game/color/Colorizer.java b/java/src/game/color/Colorizer.java index 0e45326..daba4cb 100755 --- a/java/src/game/color/Colorizer.java +++ b/java/src/game/color/Colorizer.java @@ -1,10 +1,6 @@ package game.color; -import java.awt.image.BufferedImage; - -import client.renderer.texture.TextureUtil; import game.biome.Biome; -import game.util.FileUtils; import game.world.BlockPos; import game.world.IWorldAccess; @@ -30,12 +26,18 @@ public enum Colorizer { return biome.waterColor; } }; - private static final String GRASS_TEX = "textures/world/grass.png"; - private static final String FOLIAGE_TEX = "textures/world/foliage.png"; private static final int[] GRASS = new int[65536]; private static final int[] FOLIAGE = new int[65536]; private final int color; + + public static int[] getGrassMap() { + return GRASS; + } + + public static int[] getFoliageMap() { + return FOLIAGE; + } public static int getGrassColor(double temp, double rain) { rain = rain * temp; @@ -52,22 +54,6 @@ public enum Colorizer { return FOLIAGE[j << 8 | i]; } - public static void reload() { - BufferedImage img; - try { - img = TextureUtil.readImage(FileUtils.getResource(GRASS_TEX)); - img.getRGB(0, 0, 256, 256, GRASS, 0, 256); - } - catch(Exception e) { - } - try { - img = TextureUtil.readImage(FileUtils.getResource(FOLIAGE_TEX)); - img.getRGB(0, 0, 256, 256, FOLIAGE, 0, 256); - } - catch(Exception e) { - } - } - private static int getColor(IWorldAccess access, BlockPos pos, ColorResolver resolver) { int r = 0; int g = 0; diff --git a/java/src/game/entity/npc/EntityHoveringNPC.java b/java/src/game/entity/npc/EntityHoveringNPC.java index 6a09843..c413458 100755 --- a/java/src/game/entity/npc/EntityHoveringNPC.java +++ b/java/src/game/entity/npc/EntityHoveringNPC.java @@ -114,9 +114,9 @@ public abstract class EntityHoveringNPC extends EntityNPC public void onLivingUpdate() { if(this.sendQueue != null) { - if(this.gm.jump && this.gm.sprint && this.gm.moveForward == 0.0f && this.gm.moveStrafe == 0.0f) + if(this.gm.isJumping() && this.gm.isSprinting() && this.gm.getMoveForward() == 0.0f && this.gm.getMoveStrafe() == 0.0f) this.setHovering(true); - if(this.isFlying() || (!this.gm.jump && this.gm.sneak && this.onGround)) + if(this.isFlying() || (!this.gm.isJumping() && this.gm.isSneaking() && this.onGround)) this.setHovering(false); } if (!this.onGround && this.motionY < 0.0D && (!this.isPlayer() || (!this.isFlying() && this.isHovering() && !this.jumping))) diff --git a/java/src/game/entity/npc/EntityNPC.java b/java/src/game/entity/npc/EntityNPC.java index 8ec1d52..196893c 100755 --- a/java/src/game/entity/npc/EntityNPC.java +++ b/java/src/game/entity/npc/EntityNPC.java @@ -4,20 +4,7 @@ import java.lang.reflect.InvocationTargetException; import java.util.List; import java.util.function.Predicate; -import client.Game; -import client.gui.container.GuiBrewing; -import client.gui.container.GuiChest; -import client.gui.container.GuiCrafting; -import client.gui.container.GuiDispenser; -import client.gui.container.GuiEnchant; -import client.gui.container.GuiFurnace; -import client.gui.container.GuiHopper; -import client.gui.container.GuiHorse; -import client.gui.container.GuiMerchant; -import client.gui.container.GuiRepair; -import client.gui.ingame.GuiSign; -import client.renderer.layers.LayerExtra; -import client.renderer.texture.EntityTexManager; +import game.IClient; import game.ai.AIRangedAttack; import game.ai.EntityAIAttackOnCollide; import game.ai.EntityAIAvoidEntity; @@ -200,7 +187,7 @@ public abstract class EntityNPC extends EntityLiving public IPlayer connection; public IClientPlayer sendQueue; - protected Game gm; + protected IClient gm; public InventoryPlayer inventory; protected InventoryWarpChest warpChest; @@ -405,13 +392,13 @@ public abstract class EntityNPC extends EntityLiving this.stepHeight = 0.0F; } - public final void setClientPlayer(Game gm, IClientPlayer connection) { + public final void setClientPlayer(IClient gm, IClientPlayer connection) { this.initPlayer(); this.gm = gm; this.sendQueue = connection; } - public final void setOtherPlayer(Game gm) { + public final void setOtherPlayer(IClient gm) { this.initPlayer(); this.gm = gm; this.stepHeight = 0.0F; @@ -1071,11 +1058,6 @@ public abstract class EntityNPC extends EntityLiving // { // return this.getChar().startsWith("~"); // } - - public String getLocationCape() - { - return !this.getCape().isEmpty() ? EntityTexManager.getCape(this.getCape()) : null; - } // public boolean canRenderExtras() // { @@ -1801,7 +1783,7 @@ public abstract class EntityNPC extends EntityLiving if (this.sendQueue != null && entityIn instanceof EntityCart) { - this.gm.getSoundManager().playSound(new MovingSoundMinecartRiding(this, (EntityCart)entityIn)); + this.gm.playSound(new MovingSoundMinecartRiding(this, (EntityCart)entityIn)); } } @@ -1819,7 +1801,7 @@ public abstract class EntityNPC extends EntityLiving if (this.isRiding()) { this.sendQueue.addToSendQueue(new CPacketPlayer.C05PacketPlayerLook(this.rotYaw, this.rotPitch, this.onGround)); - this.sendQueue.addToSendQueue(new CPacketInput(this.moveStrafe, this.moveForward, this.gm.jump, this.gm.sneak)); + this.sendQueue.addToSendQueue(new CPacketInput(this.moveStrafe, this.moveForward, this.gm.isJumping(), this.gm.isSneaking())); } else { @@ -2072,7 +2054,7 @@ public abstract class EntityNPC extends EntityLiving // this.setScreenClosed(); // this.sendQueue.addToSendQueue(new CPacketAction(CPacketAction.Action.CLOSE_CONTAINER)); // , this.openContainer.windowId)); // this.closeScreenAndDropStack(); - this.gm.displayGuiScreen(null); + this.sendQueue.closeGui(); } else this.openContainer = this.inventoryContainer; @@ -2186,7 +2168,7 @@ public abstract class EntityNPC extends EntityLiving if(this.connection != null) this.connection.openEditSign(signTile); else if(this.sendQueue != null) - this.gm.displayGuiScreen(new GuiSign(signTile.getPos(), signTile.signText)); + this.sendQueue.displayGuiSign(signTile.getPos(), signTile.signText); } /** @@ -2214,36 +2196,7 @@ public abstract class EntityNPC extends EntityLiving if(this.connection != null) this.connection.displayGUIChest(chestInventory); else if(this.sendQueue != null) { - String s = chestInventory instanceof IInteractionObject ? ((IInteractionObject)chestInventory).getGuiID() : "container"; - - if ("chest".equals(s)) - { - this.gm.displayGuiScreen(new GuiChest(this.inventory, chestInventory)); - } - else if ("hopper".equals(s)) - { - this.gm.displayGuiScreen(new GuiHopper(this.inventory, chestInventory)); - } - else if ("furnace".equals(s)) - { - this.gm.displayGuiScreen(new GuiFurnace(this.inventory, chestInventory)); - } - else if ("brewing_stand".equals(s)) - { - this.gm.displayGuiScreen(new GuiBrewing(this.inventory, chestInventory)); - } -// else if ("beacon".equals(s)) -// { -// this.gm.displayGuiScreen(new GuiBeacon(this.inventory, chestInventory)); -// } - else if (!"dispenser".equals(s) && !"dropper".equals(s)) - { - this.gm.displayGuiScreen(new GuiChest(this.inventory, chestInventory)); - } - else - { - this.gm.displayGuiScreen(new GuiDispenser(this.inventory, chestInventory)); - } + this.sendQueue.displayGUIChest(chestInventory, this.inventory); } } @@ -2252,7 +2205,7 @@ public abstract class EntityNPC extends EntityLiving if(this.connection != null) this.connection.displayGUIHorse(horse, horseInventory); else if(this.sendQueue != null) - this.gm.displayGuiScreen(new GuiHorse(this.inventory, horseInventory, horse)); + this.sendQueue.displayGuiHorse(horse, this.inventory, horseInventory); } public void displayGui(IInteractionObject guiOwner) @@ -2260,20 +2213,7 @@ public abstract class EntityNPC extends EntityLiving if(this.connection != null) this.connection.displayGui(guiOwner); else if(this.sendQueue != null) { - String s = guiOwner.getGuiID(); - - if ("crafting_table".equals(s)) - { - this.gm.displayGuiScreen(new GuiCrafting(this.inventory, this.worldObj)); - } - else if ("enchanting_table".equals(s)) - { - this.gm.displayGuiScreen(new GuiEnchant(this.inventory, this.worldObj, guiOwner)); - } - else if ("anvil".equals(s)) - { - this.gm.displayGuiScreen(new GuiRepair(this.inventory, this.worldObj)); - } + this.sendQueue.displayGui(guiOwner, this.inventory, this.worldObj); } } @@ -2285,7 +2225,7 @@ public abstract class EntityNPC extends EntityLiving if(this.connection != null) this.connection.onCriticalHit(entityHit); else if(this.sendQueue != null) - this.gm.effectRenderer.emitParticleAtEntity(entityHit, ParticleType.CRIT); + this.gm.emitParticleAtEntity(entityHit, ParticleType.CRIT); } public void onEnchantmentCritical(Entity entityHit) @@ -2293,7 +2233,7 @@ public abstract class EntityNPC extends EntityLiving if(this.connection != null) this.connection.onEnchantmentCritical(entityHit); else if(this.sendQueue != null) - this.gm.effectRenderer.emitParticleAtEntity(entityHit, ParticleType.CRIT_MAGIC); + this.gm.emitParticleAtEntity(entityHit, ParticleType.CRIT_MAGIC); } /** @@ -2301,7 +2241,7 @@ public abstract class EntityNPC extends EntityLiving */ public boolean isSneaking() { - return this.sendQueue != null ? this.gm.sneak : super.isSneaking(); + return this.sendQueue != null ? this.gm.isSneaking() : super.isSneaking(); } public void updateEntityActionState() @@ -2316,9 +2256,9 @@ public abstract class EntityNPC extends EntityLiving if (this.sendQueue != null && this.isCurrentViewEntity()) { - this.moveStrafe = this.gm.moveStrafe; - this.moveForward = this.gm.moveForward; - this.jumping = this.gm.jump; + this.moveStrafe = this.gm.getMoveStrafe(); + this.moveForward = this.gm.getMoveForward(); + this.jumping = this.gm.isJumping(); this.prevRenderArmYaw = this.renderArmYaw; this.prevRenderArmPitch = this.renderArmPitch; this.renderArmPitch = (float)((double)this.renderArmPitch + (double)(this.rotPitch - this.renderArmPitch) * 0.5D); @@ -2398,16 +2338,16 @@ public abstract class EntityNPC extends EntityLiving // --this.portalTimer; // } - boolean flag = this.gm.jump; - boolean flag1 = this.gm.sneak; + boolean flag = this.gm.isJumping(); + boolean flag1 = this.gm.isSneaking(); float f = 0.8F; - boolean flag2 = this.gm.moveForward >= f; + boolean flag2 = this.gm.getMoveForward() >= f; this.gm.updatePlayerMoveState(); if (this.isUsingItem() && !this.isRiding()) { - this.gm.moveStrafe *= 0.2F; - this.gm.moveForward *= 0.2F; + this.gm.setMoveStrafe(this.gm.getMoveStrafe() * 0.2F); + this.gm.setMoveForward(this.gm.getMoveForward() * 0.2F); this.sprintToggleTimer = 0; } @@ -2417,9 +2357,9 @@ public abstract class EntityNPC extends EntityLiving this.pushOutOfBlocks(this.posX + (double)this.width * 0.35D, this.getEntityBoundingBox().minY + 0.5D, this.posZ + (double)this.width * 0.35D); boolean canSprint = true; // (float)this.getFoodStats().getFoodLevel() > 6.0F || this.allowFlying; - if (this.onGround && !flag1 && !flag2 && this.gm.moveForward >= f && !this.isSprinting() && canSprint && !this.isUsingItem() && !this.hasEffect(Potion.BLINDNESS)) + if (this.onGround && !flag1 && !flag2 && this.gm.getMoveForward() >= f && !this.isSprinting() && canSprint && !this.isUsingItem() && !this.hasEffect(Potion.BLINDNESS)) { - if (this.sprintToggleTimer <= 0 && !this.gm.sprint) + if (this.sprintToggleTimer <= 0 && !this.gm.isSprinting()) { this.sprintToggleTimer = 7; } @@ -2429,12 +2369,12 @@ public abstract class EntityNPC extends EntityLiving } } - if (!this.isSprinting() && this.gm.moveForward >= f && canSprint && !this.isUsingItem() && !this.hasEffect(Potion.BLINDNESS) && this.gm.sprint) + if (!this.isSprinting() && this.gm.getMoveForward() >= f && canSprint && !this.isUsingItem() && !this.hasEffect(Potion.BLINDNESS) && this.gm.isSprinting()) { this.setSprinting(true); } - if (this.isSprinting() && (this.gm.moveForward < f || this.collidedHorizontally || !canSprint)) + if (this.isSprinting() && (this.gm.getMoveForward() < f || this.collidedHorizontally || !canSprint)) { this.setSprinting(false); } @@ -2449,7 +2389,7 @@ public abstract class EntityNPC extends EntityLiving this.sendQueue.addToSendQueue(new CPacketAction(CPacketAction.Action.START_FLYING)); } } - else if (!flag && this.gm.jump) + else if (!flag && this.gm.isJumping()) { if (this.flyToggleTimer == 0) { @@ -2471,13 +2411,13 @@ public abstract class EntityNPC extends EntityLiving if (this.isFlying() && this.isCurrentViewEntity()) { - if (this.gm.sneak) + if (this.gm.isSneaking()) { this.motionY -= (double)( this.landMovement * 0.5f * (this.canFlyFullSpeed() ? 3.0F : 1.0F)); } - if (this.gm.jump) + if (this.gm.isJumping()) { this.motionY += (double)( this.landMovement * 0.5f * (this.canFlyFullSpeed() ? 3.0F : 1.0F)); @@ -2496,12 +2436,12 @@ public abstract class EntityNPC extends EntityLiving } } - if (flag && !this.gm.jump) + if (flag && !this.gm.isJumping()) { this.horseJumpPowerCounter = -10; this.sendHorseJump(); } - else if (!flag && this.gm.jump) + else if (!flag && this.gm.isJumping()) { this.horseJumpPowerCounter = 0; this.horseJumpPower = 0.0F; @@ -2854,7 +2794,7 @@ public abstract class EntityNPC extends EntityLiving public void displayTradeGui(String title) { - this.gm.displayGuiScreen(new GuiMerchant(this.inventory, title, this.worldObj)); + this.sendQueue.displayGuiMerchant(title, this.inventory, this.worldObj); } protected boolean isCurrentViewEntity() @@ -4709,17 +4649,7 @@ public abstract class EntityNPC extends EntityLiving public int getColor() { return this.isPlayer() ? 0xff00ff : 0x5000ad; } - - public LayerExtra getExtrasLayer() - { - return EntityTexManager.getLayer(this.isPlayer() ? this.getId() : -1, this.getChar(), this.species.renderer); - } - - public String getLocationSkin() - { - return EntityTexManager.getSkin(this.isPlayer() ? this.getId() : -1, this.getChar(), this.species.renderer); - } - + public void sendDeathMessage() { this.sendDeathMessage(this.isPlayer(), true); } diff --git a/java/src/game/entity/types/IEntityFX.java b/java/src/game/entity/types/IEntityFX.java index 26b274f..cf4aece 100644 --- a/java/src/game/entity/types/IEntityFX.java +++ b/java/src/game/entity/types/IEntityFX.java @@ -1,10 +1,8 @@ package game.entity.types; -import client.renderer.particle.EntityFX; - public interface IEntityFX { - EntityFX multiplyVelocity(float multiplier); + IEntityFX multiplyVelocity(float multiplier); void setRBGColorF(float particleRedIn, float particleGreenIn, float particleBlueIn); diff --git a/java/src/game/init/BlockRegistry.java b/java/src/game/init/BlockRegistry.java index 4536a76..1008a5f 100755 --- a/java/src/game/init/BlockRegistry.java +++ b/java/src/game/init/BlockRegistry.java @@ -1,9 +1,5 @@ package game.init; -import client.renderer.ticked.TextureLavaFX; -import client.renderer.ticked.TextureLavaFlowFX; -import client.renderer.ticked.TextureWaterFX; -import client.renderer.ticked.TextureWaterFlowFX; import game.block.*; import game.color.DyeColor; import game.init.FluidRegistry.LiquidType; @@ -199,9 +195,9 @@ public abstract class BlockRegistry { .setDisplay("Schwarzbruchstein").setTab(CheatTab.tabNature)); - registerFluid(32, 33, "water", "Wasser", true, LiquidType.WATER, false, 0, 5, 0.0f, TextureWaterFX.class, TextureWaterFlowFX.class); + registerFluid(32, 33, "water", "Wasser", true, LiquidType.WATER, false, 0, 5, 0.0f, "water", "waterflow"); registerFluid(34, 35, "lava", "Lava", false, LiquidType.LAVA, true, 15, -30, 0.0f, 2, 3); - registerFluid(36, 37, "magma", "Magma", false, LiquidType.HOT, true, 15, 40, 0.0f, TextureLavaFX.class, TextureLavaFlowFX.class); + registerFluid(36, 37, "magma", "Magma", false, LiquidType.HOT, true, 15, 40, 0.0f, "lava", "lavaflow"); registerFluid(38, 39, "mercury", "Quecksilber", false, LiquidType.COLD, true, 0, 40, 0.0f, 8, 4); registerFluid(40, 41, "hydrogen", "Wasserstoff", false, LiquidType.COLD, true, 0, 50, 0.0f, 8, 4); registerFluid(42, 43, "acid", "Säure", false, LiquidType.HOT, false, 0, 5, 0.0f, 1, 1); diff --git a/java/src/game/network/IClientPlayer.java b/java/src/game/network/IClientPlayer.java index 4ac9f51..4fb6331 100644 --- a/java/src/game/network/IClientPlayer.java +++ b/java/src/game/network/IClientPlayer.java @@ -1,5 +1,8 @@ package game.network; +import game.entity.animal.EntityHorse; +import game.inventory.IInventory; +import game.inventory.InventoryPlayer; import game.packet.S14PacketEntity; import game.packet.S18PacketEntityTeleport; import game.packet.S19PacketEntityHeadLook; @@ -61,6 +64,9 @@ import game.packet.SPacketTimeUpdate; import game.packet.SPacketTrades; import game.packet.SPacketUpdateHealth; import game.packet.SPacketWorld; +import game.tileentity.IInteractionObject; +import game.world.BlockPos; +import game.world.World; public interface IClientPlayer { void addToSendQueue(Packet packet); @@ -312,4 +318,10 @@ public interface IClientPlayer { void handleDimName(SPacketDimensionName packetIn); + void displayGUIChest(IInventory chestInventory, InventoryPlayer inventory); + void displayGui(IInteractionObject guiOwner, InventoryPlayer inventory, World worldObj); + void displayGuiHorse(EntityHorse horse, InventoryPlayer inventory, IInventory horseInventory); + void displayGuiMerchant(String title, InventoryPlayer inventory, World worldObj); + void displayGuiSign(BlockPos pos, String[] signText); + void closeGui(); } \ No newline at end of file diff --git a/java/src/game/network/IPlayer.java b/java/src/game/network/IPlayer.java index 6d06d57..2ec04ba 100644 --- a/java/src/game/network/IPlayer.java +++ b/java/src/game/network/IPlayer.java @@ -44,13 +44,14 @@ public interface IPlayer { } } - public static int MAX_USER_LENGTH = 16; - public static int MAX_NICK_LENGTH = 32; - public static int MAX_PASS_LENGTH = 64; - public static int MAX_CMD_LENGTH = 1024; - public static int MAX_INFO_LENGTH = 4096; - public static CharValidator VALID_USER = new IPlayer.UserValidator(); - public static CharValidator VALID_NICK = new IPlayer.NickValidator(); + public static final int MAX_USER_LENGTH = 16; + public static final int MAX_NICK_LENGTH = 32; + public static final int MAX_PASS_LENGTH = 64; + public static final int MAX_CMD_LENGTH = 1024; + public static final int MAX_INFO_LENGTH = 4096; + public static final int MAX_SKIN_SIZE = 65536; + public static final CharValidator VALID_USER = new IPlayer.UserValidator(); + public static final CharValidator VALID_NICK = new IPlayer.NickValidator(); public static boolean isValidNick(String user) { return VALID_NICK.valid(user); diff --git a/java/src/game/packet/CPacketSkin.java b/java/src/game/packet/CPacketSkin.java index b20c00e..180c49b 100755 --- a/java/src/game/packet/CPacketSkin.java +++ b/java/src/game/packet/CPacketSkin.java @@ -1,10 +1,7 @@ package game.packet; -import java.awt.image.BufferedImage; import java.io.IOException; -import client.renderer.texture.EntityTexManager; -import game.init.SpeciesRegistry.ModelType; import game.network.Packet; import game.network.PacketBuffer; import game.network.IPlayer; @@ -16,17 +13,9 @@ public class CPacketSkin implements Packet { public CPacketSkin() { } - public CPacketSkin(BufferedImage image, String character, ModelType model) { - if(image == null) { - this.texture = null; - this.character = character; - } - else { - int[] img = new int[model.texWidth * model.texHeight]; - image.getRGB(0, 0, image.getWidth(), image.getHeight(), img, 0, image.getWidth()); - this.texture = EntityTexManager.imageToComp(img, model); - this.character = null; - } + public CPacketSkin(byte[] texture, String character) { + this.texture = texture; + this.character = character; } public byte[] getCompressed() { @@ -45,8 +34,8 @@ public class CPacketSkin implements Packet { else { this.texture = buf.readByteArray(); this.character = null; - if(this.texture.length == 0 || this.texture.length > EntityTexManager.MAX_SKIN_SIZE) - this.texture = new byte[EntityTexManager.MAX_SKIN_SIZE]; + if(this.texture.length == 0 || this.texture.length > IPlayer.MAX_SKIN_SIZE) + this.texture = new byte[IPlayer.MAX_SKIN_SIZE]; } } diff --git a/java/src/game/packet/SPacketSkin.java b/java/src/game/packet/SPacketSkin.java index 512d09b..23b619f 100755 --- a/java/src/game/packet/SPacketSkin.java +++ b/java/src/game/packet/SPacketSkin.java @@ -2,9 +2,9 @@ package game.packet; import java.io.IOException; -import client.renderer.texture.EntityTexManager; import game.entity.Entity; import game.network.IClientPlayer; +import game.network.IPlayer; import game.network.Packet; import game.network.PacketBuffer; import game.world.World; @@ -46,8 +46,8 @@ public class SPacketSkin implements Packet if(this.texture.length == 0) { this.texture = null; } - else if(this.texture.length > EntityTexManager.MAX_SKIN_SIZE) { - this.texture = new byte[EntityTexManager.MAX_SKIN_SIZE]; + else if(this.texture.length > IPlayer.MAX_SKIN_SIZE) { + this.texture = new byte[IPlayer.MAX_SKIN_SIZE]; } } diff --git a/java/src/game/packet/SPacketSpawnPlayer.java b/java/src/game/packet/SPacketSpawnPlayer.java index c0a9f3b..89702e6 100755 --- a/java/src/game/packet/SPacketSpawnPlayer.java +++ b/java/src/game/packet/SPacketSpawnPlayer.java @@ -3,13 +3,13 @@ package game.packet; import java.io.IOException; import java.util.List; -import client.renderer.texture.EntityTexManager; import game.entity.DataWatcher; import game.entity.npc.EntityNPC; import game.init.EntityRegistry; import game.init.ItemRegistry; import game.item.ItemStack; import game.network.IClientPlayer; +import game.network.IPlayer; import game.network.Packet; import game.network.PacketBuffer; import game.util.ExtMath; @@ -65,8 +65,8 @@ public class SPacketSpawnPlayer implements Packet if(this.texture.length == 0) { this.texture = null; } - else if(this.texture.length > EntityTexManager.MAX_SKIN_SIZE) { - this.texture = new byte[EntityTexManager.MAX_SKIN_SIZE]; + else if(this.texture.length > IPlayer.MAX_SKIN_SIZE) { + this.texture = new byte[IPlayer.MAX_SKIN_SIZE]; } } From d08d0e11fcb4bd724cebf2bc9a42d0ed2a6cf67d Mon Sep 17 00:00:00 2001 From: Sen Date: Wed, 7 May 2025 18:19:24 +0200 Subject: [PATCH 006/200] change package names --- client/src/client/Game.java | 162 ++++++------ client/src/client/PerfSection.java | 2 +- client/src/client/PlayerController.java | 40 +-- client/src/client/SkinConverter.java | 2 +- client/src/client/audio/AudioInterface.java | 7 +- client/src/client/audio/SoundManager.java | 24 +- client/src/client/audio/Volume.java | 8 +- client/src/client/gui/Font.java | 4 +- client/src/client/gui/Gui.java | 2 +- client/src/client/gui/GuiConnect.java | 14 +- client/src/client/gui/GuiConsole.java | 18 +- client/src/client/gui/GuiConvert.java | 16 +- client/src/client/gui/GuiInfo.java | 6 +- client/src/client/gui/GuiMenu.java | 8 +- client/src/client/gui/GuiServer.java | 10 +- client/src/client/gui/Style.java | 10 +- client/src/client/gui/character/GuiChar.java | 56 ++-- .../client/gui/character/GuiCharacters.java | 6 +- client/src/client/gui/character/GuiClass.java | 2 +- .../src/client/gui/character/GuiSpecies.java | 8 +- .../src/client/gui/container/GuiBrewing.java | 6 +- client/src/client/gui/container/GuiChest.java | 4 +- .../client/gui/container/GuiContainer.java | 20 +- .../src/client/gui/container/GuiCrafting.java | 8 +- .../client/gui/container/GuiDispenser.java | 6 +- .../src/client/gui/container/GuiEnchant.java | 14 +- .../src/client/gui/container/GuiFurnace.java | 8 +- .../src/client/gui/container/GuiHopper.java | 6 +- client/src/client/gui/container/GuiHorse.java | 6 +- .../client/gui/container/GuiInventory.java | 2 +- .../src/client/gui/container/GuiMachine.java | 8 +- .../src/client/gui/container/GuiMerchant.java | 14 +- .../src/client/gui/container/GuiRepair.java | 14 +- client/src/client/gui/element/Bar.java | 4 +- client/src/client/gui/element/Dropdown.java | 6 +- client/src/client/gui/element/Element.java | 8 +- client/src/client/gui/element/GuiList.java | 4 +- client/src/client/gui/element/Label.java | 2 +- client/src/client/gui/element/NavButton.java | 2 +- .../client/gui/element/SelectableButton.java | 2 +- client/src/client/gui/element/Slider.java | 4 +- client/src/client/gui/element/Switch.java | 4 +- client/src/client/gui/element/Textbox.java | 6 +- client/src/client/gui/element/Toggle.java | 2 +- client/src/client/gui/ingame/GuiGameOver.java | 2 +- client/src/client/gui/ingame/GuiSign.java | 4 +- client/src/client/gui/options/GuiBinds.java | 2 +- client/src/client/gui/options/GuiDisplay.java | 2 +- client/src/client/gui/options/GuiStyle.java | 4 +- .../src/client/init/EntityRenderRegistry.java | 88 +++---- .../client/network/ClientLoginHandler.java | 14 +- client/src/client/network/ClientPlayer.java | 222 ++++++++-------- .../src/client/renderer/ActiveRenderInfo.java | 18 +- client/src/client/renderer/BlockRenderer.java | 28 +- client/src/client/renderer/Drawing.java | 6 +- .../src/client/renderer/EntityRenderer.java | 40 +-- client/src/client/renderer/Frustum.java | 4 +- .../src/client/renderer/ItemModelMesher.java | 12 +- client/src/client/renderer/ItemRenderer.java | 24 +- .../client/renderer/RegionRenderCache.java | 24 +- .../renderer/RegionRenderCacheBuilder.java | 2 +- client/src/client/renderer/RenderBuffer.java | 4 +- client/src/client/renderer/RenderGlobal.java | 56 ++-- client/src/client/renderer/VertexFormat.java | 4 +- .../client/renderer/VertexFormatElement.java | 2 +- client/src/client/renderer/ViewFrustum.java | 6 +- .../renderer/blockmodel/BakedModel.java | 6 +- .../client/renderer/blockmodel/BakedQuad.java | 2 +- .../client/renderer/blockmodel/BlockPart.java | 4 +- .../renderer/blockmodel/BlockPartFace.java | 2 +- .../blockmodel/BlockPartRotation.java | 4 +- .../renderer/blockmodel/BuiltInModel.java | 4 +- .../renderer/blockmodel/FaceBakery.java | 14 +- .../renderer/blockmodel/IBakedModel.java | 4 +- .../renderer/blockmodel/ModelBakery.java | 26 +- .../renderer/blockmodel/ModelBlock.java | 16 +- .../renderer/blockmodel/ModelGenerator.java | 10 +- .../renderer/blockmodel/ModelManager.java | 18 +- .../renderer/blockmodel/MultiStateMap.java | 10 +- .../renderer/blockmodel/SingleStateMap.java | 4 +- .../client/renderer/blockmodel/StateMap.java | 8 +- .../chunk/ChunkCompileTaskGenerator.java | 2 +- .../renderer/chunk/ChunkRenderDispatcher.java | 12 +- .../renderer/chunk/ChunkRenderWorker.java | 14 +- .../client/renderer/chunk/CompiledChunk.java | 8 +- .../client/renderer/chunk/RenderChunk.java | 20 +- .../client/renderer/chunk/SetVisibility.java | 2 +- .../src/client/renderer/chunk/VisGraph.java | 4 +- client/src/client/renderer/entity/Render.java | 10 +- .../renderer/entity/RenderArachnoid.java | 2 +- .../client/renderer/entity/RenderArrow.java | 4 +- .../src/client/renderer/entity/RenderBat.java | 4 +- .../renderer/entity/RenderBlockEntity.java | 4 +- .../client/renderer/entity/RenderBoat.java | 4 +- .../client/renderer/entity/RenderBullet.java | 2 +- .../client/renderer/entity/RenderChicken.java | 4 +- .../src/client/renderer/entity/RenderCow.java | 2 +- .../client/renderer/entity/RenderCrystal.java | 4 +- .../src/client/renderer/entity/RenderDie.java | 4 +- .../client/renderer/entity/RenderDragon.java | 4 +- .../renderer/entity/RenderDynamite.java | 6 +- .../client/renderer/entity/RenderEntity.java | 2 +- .../renderer/entity/RenderEntityItem.java | 12 +- .../renderer/entity/RenderFallingBlock.java | 10 +- .../renderer/entity/RenderFireball.java | 4 +- .../client/renderer/entity/RenderFish.java | 6 +- .../renderer/entity/RenderFlyingBox.java | 2 +- .../client/renderer/entity/RenderHorse.java | 4 +- .../renderer/entity/RenderHumanoid.java | 6 +- .../client/renderer/entity/RenderItem.java | 18 +- .../renderer/entity/RenderItemEntity.java | 8 +- .../renderer/entity/RenderLeashKnot.java | 2 +- .../renderer/entity/RenderLightning.java | 4 +- .../client/renderer/entity/RenderLiving.java | 6 +- .../client/renderer/entity/RenderManager.java | 14 +- .../renderer/entity/RenderMinecart.java | 8 +- .../renderer/entity/RenderMooshroom.java | 2 +- .../client/renderer/entity/RenderMouse.java | 2 +- .../src/client/renderer/entity/RenderNpc.java | 4 +- .../client/renderer/entity/RenderOcelot.java | 2 +- .../src/client/renderer/entity/RenderPig.java | 2 +- .../client/renderer/entity/RenderPotion.java | 6 +- .../client/renderer/entity/RenderRabbit.java | 4 +- .../client/renderer/entity/RenderSheep.java | 2 +- .../client/renderer/entity/RenderSlime.java | 4 +- .../renderer/entity/RenderSpaceMarine.java | 6 +- .../client/renderer/entity/RenderSquid.java | 2 +- .../renderer/entity/RenderTntMinecart.java | 8 +- .../renderer/entity/RenderTntPrimed.java | 8 +- .../client/renderer/entity/RenderWolf.java | 2 +- .../client/renderer/entity/RenderXpOrb.java | 4 +- .../renderer/entity/RendererLivingEntity.java | 16 +- .../client/renderer/layers/LayerArmor.java | 6 +- .../client/renderer/layers/LayerArrow.java | 10 +- .../src/client/renderer/layers/LayerCape.java | 4 +- .../client/renderer/layers/LayerCharge.java | 2 +- .../renderer/layers/LayerEnderDragonEyes.java | 2 +- .../renderer/layers/LayerEntityBreak.java | 4 +- .../client/renderer/layers/LayerExtra.java | 6 +- .../client/renderer/layers/LayerHeldItem.java | 14 +- .../layers/LayerMooshroomMushroom.java | 4 +- .../renderer/layers/LayerPowerRods.java | 4 +- .../client/renderer/layers/LayerRenderer.java | 2 +- .../client/renderer/layers/LayerSaddle.java | 2 +- .../renderer/layers/LayerSheepWool.java | 2 +- .../client/renderer/layers/LayerSlimeGel.java | 2 +- .../renderer/layers/LayerWolfCollar.java | 6 +- .../client/renderer/model/ModelArachnoid.java | 4 +- .../src/client/renderer/model/ModelBase.java | 10 +- .../src/client/renderer/model/ModelBat.java | 6 +- .../src/client/renderer/model/ModelBiped.java | 6 +- .../src/client/renderer/model/ModelBoat.java | 2 +- .../src/client/renderer/model/ModelBox.java | 4 +- .../client/renderer/model/ModelCharge.java | 2 +- .../client/renderer/model/ModelChicken.java | 4 +- .../client/renderer/model/ModelCrystal.java | 2 +- .../src/client/renderer/model/ModelDie.java | 2 +- .../client/renderer/model/ModelDragon.java | 6 +- .../src/client/renderer/model/ModelHead.java | 2 +- .../src/client/renderer/model/ModelHorse.java | 8 +- .../client/renderer/model/ModelHumanoid.java | 4 +- .../renderer/model/ModelHumanoidHead.java | 2 +- .../client/renderer/model/ModelLeashKnot.java | 2 +- .../client/renderer/model/ModelMinecart.java | 2 +- .../src/client/renderer/model/ModelMouse.java | 6 +- .../client/renderer/model/ModelOcelot.java | 8 +- .../client/renderer/model/ModelQuadruped.java | 4 +- .../client/renderer/model/ModelRabbit.java | 8 +- .../client/renderer/model/ModelRenderer.java | 2 +- .../client/renderer/model/ModelSheep1.java | 6 +- .../client/renderer/model/ModelSheep2.java | 6 +- .../src/client/renderer/model/ModelSlime.java | 2 +- .../src/client/renderer/model/ModelSquid.java | 2 +- .../src/client/renderer/model/ModelWolf.java | 8 +- .../renderer/model/PositionTextureVertex.java | 2 +- .../client/renderer/model/TexturedQuad.java | 2 +- .../renderer/particle/EffectRenderer.java | 24 +- .../renderer/particle/EntityAuraFX.java | 2 +- .../renderer/particle/EntityBlockDustFX.java | 6 +- .../renderer/particle/EntityBreakingFX.java | 10 +- .../renderer/particle/EntityBubbleFX.java | 6 +- .../renderer/particle/EntityCloudFX.java | 8 +- .../renderer/particle/EntityCrit2FX.java | 6 +- .../renderer/particle/EntityCritFX.java | 2 +- .../renderer/particle/EntityDiggingFX.java | 14 +- .../renderer/particle/EntityDownfallFX.java | 14 +- .../particle/EntityDropParticleFX.java | 14 +- .../EntityEnchantmentTableParticleFX.java | 2 +- .../renderer/particle/EntityExplodeFX.java | 2 +- .../client/renderer/particle/EntityFX.java | 12 +- .../renderer/particle/EntityFirework.java | 18 +- .../renderer/particle/EntityFishWakeFX.java | 2 +- .../renderer/particle/EntityFlameFX.java | 6 +- .../renderer/particle/EntityFootStepFX.java | 6 +- .../renderer/particle/EntityHeartFX.java | 6 +- .../particle/EntityHugeExplodeFX.java | 6 +- .../particle/EntityLargeExplodeFX.java | 4 +- .../renderer/particle/EntityLavaFX.java | 8 +- .../renderer/particle/EntityNoteFX.java | 6 +- .../particle/EntityParticleEmitter.java | 8 +- .../renderer/particle/EntityPickupFX.java | 4 +- .../renderer/particle/EntityPortalFX.java | 4 +- .../renderer/particle/EntityReddustFX.java | 6 +- .../renderer/particle/EntitySmokeFX.java | 6 +- .../renderer/particle/EntitySnowShovelFX.java | 6 +- .../particle/EntitySpellParticleFX.java | 8 +- .../renderer/particle/EntitySplashFX.java | 2 +- .../renderer/particle/EntitySuspendFX.java | 6 +- .../renderer/particle/IParticleFactory.java | 2 +- .../renderer/texture/ColormapLoader.java | 4 +- .../renderer/texture/EntityTexManager.java | 16 +- .../texture/LayeredColorMaskTexture.java | 6 +- .../renderer/texture/LayeredTexture.java | 6 +- .../renderer/texture/SimpleTexture.java | 2 +- .../src/client/renderer/texture/Stitcher.java | 4 +- .../renderer/texture/TextureAtlasSprite.java | 2 +- .../renderer/texture/TextureManager.java | 4 +- .../client/renderer/texture/TextureMap.java | 14 +- .../client/renderer/texture/TextureUtil.java | 2 +- .../client/renderer/ticked/TextureLavaFX.java | 2 +- .../renderer/ticked/TextureLavaFlowFX.java | 2 +- .../tileentity/TileEntityBannerRenderer.java | 14 +- .../tileentity/TileEntityChestRenderer.java | 6 +- .../TileEntityItemStackRenderer.java | 16 +- .../TileEntityMobSpawnerRenderer.java | 4 +- .../tileentity/TileEntityPistonRenderer.java | 18 +- .../TileEntityRendererDispatcher.java | 22 +- .../tileentity/TileEntitySignRenderer.java | 6 +- .../tileentity/TileEntitySkullRenderer.java | 4 +- .../tileentity/TileEntitySpecialRenderer.java | 4 +- client/src/{game => client}/vars/BaseVar.java | 2 +- client/src/{game => client}/vars/BoolVar.java | 6 +- client/src/{game => client}/vars/CVar.java | 4 +- .../{game => client}/vars/CVarCategory.java | 4 +- .../src/{game => client}/vars/ColorVar.java | 6 +- client/src/{game => client}/vars/EnumVar.java | 8 +- .../src/{game => client}/vars/FloatVar.java | 6 +- client/src/{game => client}/vars/IntVar.java | 8 +- .../src/{game => client}/vars/StringVar.java | 6 +- .../src/{game => client}/vars/Variable.java | 6 +- client/src/client/window/Bind.java | 10 +- client/src/client/window/Input.java | 4 +- client/src/client/window/Window.java | 2 +- .../src/{game => client}/world/Converter.java | 150 +++++------ java/src/{game => common}/IClient.java | 18 +- java/src/{game => common}/IServer.java | 18 +- .../{game => common}/ai/AIFireballAttack.java | 18 +- .../ai/AIFlyingBoxAttack.java | 10 +- .../{game => common}/ai/AIRangedAttack.java | 8 +- .../ai/AISmallFireballAttack.java | 10 +- .../ai/EntityAIAttackOnCollide.java | 12 +- .../ai/EntityAIAvoidEntity.java | 14 +- .../src/{game => common}/ai/EntityAIBase.java | 2 +- java/src/{game => common}/ai/EntityAIBeg.java | 12 +- .../ai/EntityAIControlledByPlayer.java | 24 +- .../ai/EntityAIDoorInteract.java | 18 +- .../{game => common}/ai/EntityAIEatGrass.java | 22 +- .../{game => common}/ai/EntityAIExplode.java | 6 +- .../ai/EntityAIFindEntityNearest.java | 8 +- .../{game => common}/ai/EntityAIFleeSun.java | 14 +- .../ai/EntityAIFollowOwner.java | 12 +- .../ai/EntityAIFollowParent.java | 4 +- .../ai/EntityAIHarvestFarmland.java | 8 +- .../ai/EntityAIHurtByTarget.java | 6 +- .../ai/EntityAILeapAtTarget.java | 6 +- .../ai/EntityAILookAtTalkingPlayer.java | 4 +- .../{game => common}/ai/EntityAILookIdle.java | 4 +- .../src/{game => common}/ai/EntityAIMate.java | 18 +- .../ai/EntityAIMoveIndoors.java | 14 +- .../ai/EntityAIMoveThroughVillage.java | 22 +- .../ai/EntityAIMoveToBlock.java | 8 +- .../ai/EntityAIMoveTowardsRestriction.java | 8 +- .../ai/EntityAIMoveTowardsTarget.java | 6 +- .../ai/EntityAINagPlayer.java | 6 +- .../ai/EntityAINearestAttackableTarget.java | 6 +- .../ai/EntityAINpcInteract.java | 4 +- .../{game => common}/ai/EntityAINpcMate.java | 10 +- .../ai/EntityAIOcelotAttack.java | 6 +- .../ai/EntityAIOcelotSit.java | 20 +- .../{game => common}/ai/EntityAIOpenDoor.java | 4 +- .../ai/EntityAIOwnerHurtByTarget.java | 6 +- .../ai/EntityAIOwnerHurtTarget.java | 6 +- .../{game => common}/ai/EntityAIPanic.java | 6 +- .../src/{game => common}/ai/EntityAIPlay.java | 8 +- .../ai/EntityAIRestrictOpenDoor.java | 14 +- .../ai/EntityAIRestrictSun.java | 8 +- .../ai/EntityAIRunAroundLikeCrazy.java | 10 +- .../ai/EntityAIShareItems.java | 16 +- java/src/{game => common}/ai/EntityAISit.java | 6 +- .../{game => common}/ai/EntityAISwimming.java | 6 +- .../ai/EntityAITakePlace.java | 28 +- .../{game => common}/ai/EntityAITarget.java | 20 +- .../ai/EntityAITargetNonTamed.java | 6 +- .../{game => common}/ai/EntityAITasks.java | 4 +- .../{game => common}/ai/EntityAITempt.java | 12 +- .../{game => common}/ai/EntityAIWander.java | 6 +- .../ai/EntityAIWatchClosest.java | 8 +- .../ai/EntityAIWatchClosest2.java | 6 +- .../{game => common}/ai/EntityJumpHelper.java | 4 +- .../{game => common}/ai/EntityLookHelper.java | 8 +- .../{game => common}/ai/EntityMoveHelper.java | 8 +- .../src/{game => common}/ai/EntitySenses.java | 8 +- .../ai/RandomPositionGenerator.java | 12 +- java/src/{game => common}/biome/Biome.java | 108 ++++---- .../{game => common}/biome/BiomeBeach.java | 6 +- .../biome/BiomeBlackened.java | 18 +- .../{game => common}/biome/BiomeChaos.java | 22 +- .../{game => common}/biome/BiomeDesert.java | 14 +- .../biome/BiomeExterminated.java | 12 +- .../{game => common}/biome/BiomeForest.java | 36 +-- .../src/{game => common}/biome/BiomeHell.java | 34 +-- .../{game => common}/biome/BiomeHills.java | 18 +- .../{game => common}/biome/BiomeJungle.java | 34 +-- .../src/{game => common}/biome/BiomeMesa.java | 32 +-- .../src/{game => common}/biome/BiomeMoon.java | 14 +- .../{game => common}/biome/BiomeMushroom.java | 8 +- .../{game => common}/biome/BiomeMutated.java | 14 +- .../src/{game => common}/biome/BiomeNone.java | 14 +- .../{game => common}/biome/BiomePlains.java | 14 +- .../{game => common}/biome/BiomeSavanna.java | 22 +- .../src/{game => common}/biome/BiomeSnow.java | 20 +- .../{game => common}/biome/BiomeSnowLand.java | 10 +- .../{game => common}/biome/BiomeSpace.java | 18 +- .../biome/BiomeStoneBeach.java | 6 +- .../{game => common}/biome/BiomeSwamp.java | 24 +- .../{game => common}/biome/BiomeTaiga.java | 34 +-- .../src/{game => common}/biome/BiomeTian.java | 34 +-- .../{game => common}/biome/BiomeWater.java | 6 +- java/src/{game => common}/biome/RngSpawn.java | 6 +- java/src/{game => common}/biome/Scaling.java | 2 +- .../{game => common}/biome/Temperature.java | 2 +- java/src/{game => common}/block/Block.java | 80 +++--- java/src/{game => common}/block/BlockAir.java | 12 +- .../{game => common}/block/BlockAnvil.java | 48 ++-- .../{game => common}/block/BlockBanner.java | 42 +-- .../block/BlockBaseFlower.java | 2 +- .../block/BlockBasePressurePlate.java | 32 +-- .../{game => common}/block/BlockBeacon.java | 26 +- java/src/{game => common}/block/BlockBed.java | 42 +-- .../{game => common}/block/BlockBedrock.java | 14 +- .../block/BlockBlackenedDirt.java | 18 +- .../block/BlockBlackenedSoil.java | 24 +- .../block/BlockBlackenedStone.java | 16 +- .../block/BlockBlueShroom.java | 20 +- .../block/BlockBookshelf.java | 18 +- .../block/BlockBreakable.java | 14 +- .../block/BlockBrewingStand.java | 52 ++-- .../src/{game => common}/block/BlockBush.java | 22 +- .../{game => common}/block/BlockButton.java | 48 ++-- .../{game => common}/block/BlockCactus.java | 38 +-- .../src/{game => common}/block/BlockCake.java | 34 +-- .../{game => common}/block/BlockCarpet.java | 32 +-- .../{game => common}/block/BlockCarrot.java | 12 +- .../{game => common}/block/BlockCauldron.java | 48 ++-- .../{game => common}/block/BlockChest.java | 62 ++--- .../src/{game => common}/block/BlockClay.java | 14 +- .../{game => common}/block/BlockCocoa.java | 46 ++-- .../{game => common}/block/BlockColored.java | 22 +- .../block/BlockCompressedPowered.java | 12 +- .../block/BlockContainer.java | 16 +- .../src/{game => common}/block/BlockCore.java | 14 +- .../{game => common}/block/BlockCrops.java | 32 +-- .../block/BlockDaylightDetector.java | 48 ++-- .../{game => common}/block/BlockDeadBush.java | 30 +-- .../block/BlockDirectional.java | 8 +- .../src/{game => common}/block/BlockDirt.java | 32 +-- .../block/BlockDispenser.java | 60 ++--- .../src/{game => common}/block/BlockDoor.java | 52 ++-- .../block/BlockDoublePlant.java | 54 ++-- .../block/BlockDragonEgg.java | 30 +-- .../{game => common}/block/BlockDropper.java | 24 +- .../block/BlockDryLeaves.java | 14 +- .../block/BlockDynamicLiquid.java | 20 +- .../block/BlockEnchantmentTable.java | 36 +-- .../block/BlockEventData.java | 4 +- .../{game => common}/block/BlockFalling.java | 22 +- .../{game => common}/block/BlockFarmland.java | 40 +-- .../{game => common}/block/BlockFence.java | 40 +-- .../block/BlockFenceGate.java | 40 +-- .../src/{game => common}/block/BlockFire.java | 48 ++-- .../block/BlockFloorPortal.java | 32 +-- .../{game => common}/block/BlockFlower.java | 34 +-- .../block/BlockFlowerPot.java | 40 +-- .../{game => common}/block/BlockFurnace.java | 50 ++-- .../{game => common}/block/BlockGlass.java | 10 +- .../block/BlockGlowstone.java | 16 +- .../{game => common}/block/BlockGrass.java | 36 +-- .../{game => common}/block/BlockGravel.java | 14 +- .../block/BlockHardenedClay.java | 6 +- java/src/{game => common}/block/BlockHay.java | 22 +- .../{game => common}/block/BlockHellRock.java | 6 +- .../{game => common}/block/BlockHopper.java | 50 ++-- .../block/BlockHugeMushroom.java | 30 +-- java/src/{game => common}/block/BlockIce.java | 32 +-- .../{game => common}/block/BlockJukebox.java | 22 +- .../{game => common}/block/BlockLadder.java | 32 +-- .../{game => common}/block/BlockLeaves.java | 54 ++-- .../block/BlockLeavesBase.java | 6 +- .../{game => common}/block/BlockLever.java | 40 +-- .../{game => common}/block/BlockLilyPad.java | 32 +-- .../{game => common}/block/BlockLiquid.java | 50 ++-- java/src/{game => common}/block/BlockLog.java | 30 +-- .../{game => common}/block/BlockMachine.java | 30 +-- .../{game => common}/block/BlockMelon.java | 18 +- .../block/BlockMobSpawner.java | 22 +- .../{game => common}/block/BlockMushroom.java | 24 +- .../{game => common}/block/BlockMycelium.java | 34 +-- .../src/{game => common}/block/BlockNote.java | 24 +- .../src/{game => common}/block/BlockNuke.java | 26 +- .../{game => common}/block/BlockObsidian.java | 16 +- java/src/{game => common}/block/BlockOre.java | 22 +- .../block/BlockPackedIce.java | 8 +- .../src/{game => common}/block/BlockPane.java | 38 +-- .../block/BlockPistonBase.java | 52 ++-- .../block/BlockPistonHead.java | 44 ++-- .../block/BlockPistonMoving.java | 40 +-- .../{game => common}/block/BlockPortal.java | 42 +-- .../block/BlockPortalFrame.java | 46 ++-- .../{game => common}/block/BlockPotato.java | 18 +- .../block/BlockPressurePlate.java | 20 +- .../block/BlockPressurePlateWeighted.java | 18 +- .../{game => common}/block/BlockPumpkin.java | 24 +- .../{game => common}/block/BlockQuartz.java | 34 +-- .../src/{game => common}/block/BlockRail.java | 12 +- .../{game => common}/block/BlockRailBase.java | 40 +-- .../block/BlockRailDetector.java | 36 +-- .../block/BlockRailPowered.java | 18 +- .../block/BlockRedstoneComparator.java | 46 ++-- .../block/BlockRedstoneDiode.java | 26 +- .../block/BlockRedstoneLight.java | 22 +- .../block/BlockRedstoneOre.java | 38 +-- .../block/BlockRedstoneRepeater.java | 40 +-- .../block/BlockRedstoneTorch.java | 34 +-- .../block/BlockRedstoneWire.java | 54 ++-- .../src/{game => common}/block/BlockReed.java | 38 +-- .../src/{game => common}/block/BlockRock.java | 20 +- .../block/BlockRotatedPillar.java | 16 +- .../src/{game => common}/block/BlockSand.java | 20 +- .../block/BlockSandStone.java | 22 +- .../{game => common}/block/BlockSapling.java | 48 ++-- .../src/{game => common}/block/BlockSign.java | 24 +- .../{game => common}/block/BlockSkull.java | 38 +-- .../src/{game => common}/block/BlockSlab.java | 40 +-- .../{game => common}/block/BlockSlime.java | 20 +- .../src/{game => common}/block/BlockSnow.java | 50 ++-- .../block/BlockSnowBlock.java | 22 +- .../{game => common}/block/BlockSoulSand.java | 16 +- .../block/BlockSourceImpl.java | 12 +- .../block/BlockStainedGlass.java | 26 +- .../block/BlockStainedGlassPane.java | 20 +- .../{game => common}/block/BlockStairs.java | 58 ++--- .../block/BlockStandingSign.java | 12 +- .../block/BlockStaticLiquid.java | 20 +- .../src/{game => common}/block/BlockStem.java | 42 +-- .../{game => common}/block/BlockStone.java | 16 +- .../block/BlockStoneBrick.java | 22 +- java/src/{game => common}/block/BlockTNT.java | 46 ++-- .../block/BlockTallGrass.java | 46 ++-- .../block/BlockTianReactor.java | 16 +- .../{game => common}/block/BlockTianSoil.java | 26 +- .../{game => common}/block/BlockTorch.java | 46 ++-- .../{game => common}/block/BlockTrapDoor.java | 50 ++-- .../{game => common}/block/BlockTreasure.java | 4 +- .../{game => common}/block/BlockTripWire.java | 46 ++-- .../block/BlockTripWireHook.java | 44 ++-- .../src/{game => common}/block/BlockVine.java | 52 ++-- .../src/{game => common}/block/BlockWall.java | 38 +-- .../{game => common}/block/BlockWallSign.java | 16 +- .../block/BlockWarpChest.java | 44 ++-- .../src/{game => common}/block/BlockWart.java | 34 +-- java/src/{game => common}/block/BlockWeb.java | 28 +- .../block/BlockWorkbench.java | 28 +- .../src/{game => common}/block/IGrowable.java | 12 +- .../block/ITileEntityProvider.java | 6 +- .../{game => common}/block/LeavesType.java | 4 +- .../src/{game => common}/block/SoundType.java | 4 +- .../clipboard/BlockTransform.java | 2 +- .../clipboard/ClipboardBlock.java | 8 +- .../clipboard/ClipboardPlacer.java | 26 +- .../{game => common}/clipboard/Rotation.java | 2 +- .../clipboard/RotationValue.java | 2 +- .../{game => common}/clipboard/Vector.java | 2 +- .../collect/AbstractBiMap.java | 8 +- .../collect/AbstractIndexedListIterator.java | 4 +- .../collect/AbstractIterator.java | 4 +- .../collect/AbstractMapEntry.java | 2 +- .../collect/AbstractTable.java | 2 +- java/src/{game => common}/collect/BiMap.java | 2 +- .../collect/CollectPreconditions.java | 4 +- .../collect/DenseImmutableTable.java | 4 +- .../collect/EmptyImmutableMap.java | 2 +- .../collect/EmptyImmutableSet.java | 2 +- java/src/{game => common}/collect/Filter.java | 14 +- .../collect/ForwardingCollection.java | 2 +- .../collect/ForwardingMap.java | 2 +- .../collect/ForwardingMapEntry.java | 2 +- .../collect/ForwardingObject.java | 2 +- .../collect/ForwardingSet.java | 4 +- .../{game => common}/collect/HashBiMap.java | 8 +- .../src/{game => common}/collect/Hashing.java | 2 +- .../collect/ImmutableAsList.java | 2 +- .../collect/ImmutableCollection.java | 8 +- .../collect/ImmutableEntry.java | 2 +- .../collect/ImmutableEnumMap.java | 4 +- .../collect/ImmutableEnumSet.java | 2 +- .../collect/ImmutableList.java | 12 +- .../collect/ImmutableMap.java | 6 +- .../collect/ImmutableMapEntry.java | 4 +- .../collect/ImmutableMapEntrySet.java | 2 +- .../collect/ImmutableMapKeySet.java | 2 +- .../collect/ImmutableMapValues.java | 2 +- .../collect/ImmutableSet.java | 6 +- .../collect/ImmutableTable.java | 4 +- .../{game => common}/collect/Iterables.java | 4 +- .../{game => common}/collect/Iterators.java | 16 +- java/src/{game => common}/collect/Lists.java | 2 +- java/src/{game => common}/collect/Maps.java | 8 +- .../collect/ObjectArrays.java | 2 +- .../collect/Preconditions.java | 2 +- .../collect/RegularImmutableAsList.java | 2 +- .../collect/RegularImmutableList.java | 2 +- .../collect/RegularImmutableMap.java | 6 +- .../collect/RegularImmutableSet.java | 2 +- .../collect/RegularImmutableTable.java | 4 +- java/src/{game => common}/collect/Sets.java | 4 +- .../collect/SparseImmutableTable.java | 2 +- .../collect/StandardTable.java | 20 +- java/src/{game => common}/collect/Table.java | 2 +- .../collect/TransformedIterator.java | 4 +- .../collect/UnmodifiableIterator.java | 2 +- .../collect/UnmodifiableListIterator.java | 2 +- .../src/{game => common}/color/Colorizer.java | 8 +- java/src/{game => common}/color/DyeColor.java | 6 +- .../src/{game => common}/color/TextColor.java | 4 +- java/src/{game => common}/dimension/Area.java | 2 +- .../{game => common}/dimension/DimType.java | 4 +- .../{game => common}/dimension/Dimension.java | 82 +++--- .../{game => common}/dimension/Domain.java | 4 +- .../{game => common}/dimension/Galaxy.java | 4 +- java/src/{game => common}/dimension/Moon.java | 2 +- .../{game => common}/dimension/Nameable.java | 4 +- .../{game => common}/dimension/Planet.java | 4 +- .../{game => common}/dimension/Sector.java | 4 +- java/src/{game => common}/dimension/Semi.java | 2 +- .../src/{game => common}/dimension/Space.java | 4 +- java/src/{game => common}/dimension/Star.java | 6 +- .../BehaviorDefaultDispenseItem.java | 12 +- .../dispenser/BehaviorProjectileDispense.java | 14 +- .../dispenser/IBehaviorDispenseItem.java | 4 +- .../dispenser/IBlockSource.java | 6 +- .../dispenser/ILocatableSource.java | 2 +- .../{game => common}/dispenser/ILocation.java | 4 +- .../{game => common}/dispenser/IPosition.java | 2 +- .../dispenser/PositionImpl.java | 2 +- .../enchantment/Enchantment.java | 14 +- .../enchantment/EnchantmentArrowDamage.java | 2 +- .../enchantment/EnchantmentArrowFire.java | 2 +- .../enchantment/EnchantmentArrowInfinite.java | 2 +- .../EnchantmentArrowKnockback.java | 2 +- .../enchantment/EnchantmentDamage.java | 6 +- .../enchantment/EnchantmentDigging.java | 6 +- .../enchantment/EnchantmentDraining.java | 12 +- .../enchantment/EnchantmentDurability.java | 8 +- .../enchantment/EnchantmentFireAspect.java | 2 +- .../enchantment/EnchantmentFishingSpeed.java | 2 +- .../enchantment/EnchantmentHelper.java | 26 +- .../enchantment/EnchantmentKnockback.java | 2 +- .../enchantment/EnchantmentLootBonus.java | 2 +- .../enchantment/EnchantmentProtection.java | 8 +- .../enchantment/EnchantmentThorns.java | 16 +- .../enchantment/EnchantmentUntouching.java | 6 +- .../enchantment/EnumEnchantmentType.java | 14 +- .../enchantment/RngEnchantment.java | 4 +- .../{game => common}/entity/DamageSource.java | 10 +- .../{game => common}/entity/DataWatcher.java | 12 +- java/src/{game => common}/entity/Entity.java | 86 +++--- .../entity/EntityDamageSource.java | 8 +- .../entity/EntityDamageSourceIndirect.java | 8 +- .../entity/EntityTrackerEntry.java | 52 ++-- .../{game => common}/entity/EntityType.java | 4 +- .../entity/animal/EntityBat.java | 26 +- .../entity/animal/EntityChicken.java | 42 +-- .../entity/animal/EntityCow.java | 38 +-- .../entity/animal/EntityDragon.java | 32 +-- .../entity/animal/EntityDragonPart.java | 12 +- .../entity/animal/EntityHorse.java | 76 +++--- .../entity/animal/EntityMooshroom.java | 22 +- .../entity/animal/EntityMouse.java | 42 +-- .../entity/animal/EntityOcelot.java | 56 ++-- .../entity/animal/EntityPig.java | 42 +-- .../entity/animal/EntityRabbit.java | 84 +++--- .../entity/animal/EntitySheep.java | 66 ++--- .../entity/animal/EntitySquid.java | 22 +- .../entity/animal/EntityWolf.java | 68 ++--- .../entity/attributes/Attribute.java | 6 +- .../entity/attributes/AttributeInstance.java | 8 +- .../entity/attributes/AttributeMap.java | 9 +- .../entity/attributes/AttributeModifier.java | 4 +- .../entity/attributes/Attributes.java | 8 +- .../entity/attributes/LowerStringMap.java | 4 +- .../entity/effect/EntityLightning.java | 24 +- .../entity/item/EntityBoat.java | 38 +-- .../entity/item/EntityCart.java | 44 ++-- .../entity/item/EntityCartContainer.java | 30 +-- .../entity/item/EntityChestCart.java | 26 +- .../entity/item/EntityCrystal.java | 12 +- .../entity/item/EntityExplosion.java | 12 +- .../entity/item/EntityFalling.java | 46 ++-- .../entity/item/EntityFireworks.java | 20 +- .../entity/item/EntityHopperCart.java | 30 +-- .../entity/item/EntityItem.java | 42 +-- .../entity/item/EntityLeashKnot.java | 30 +-- .../entity/item/EntityMinecart.java | 8 +- .../entity/item/EntityNuke.java | 12 +- .../entity/item/EntityOrb.java | 18 +- .../entity/item/EntityTnt.java | 16 +- .../entity/item/EntityTntCart.java | 30 +-- .../entity/item/EntityXp.java | 32 +-- .../entity/item/EntityXpBottle.java | 12 +- .../entity/npc/Alignment.java | 6 +- .../entity/npc/CharacterInfo.java | 6 +- .../entity/npc/ClassInfo.java | 2 +- .../{game => common}/entity/npc/Energy.java | 2 +- .../entity/npc/EntityArachnoid.java | 24 +- .../entity/npc/EntityBloodElf.java | 12 +- .../entity/npc/EntityChaosMarine.java | 18 +- .../entity/npc/EntityCpu.java | 10 +- .../entity/npc/EntityCultivator.java | 20 +- .../entity/npc/EntityDarkMage.java | 14 +- .../entity/npc/EntityDwarf.java | 8 +- .../entity/npc/EntityElf.java | 14 +- .../entity/npc/EntityFireDemon.java | 12 +- .../entity/npc/EntityFlyingNPC.java | 24 +- .../entity/npc/EntityGargoyle.java | 20 +- .../entity/npc/EntityGoblin.java | 10 +- .../entity/npc/EntityHaunter.java | 28 +- .../entity/npc/EntityHoveringNPC.java | 10 +- .../entity/npc/EntityHuman.java | 20 +- .../entity/npc/EntityMage.java | 22 +- .../entity/npc/EntityMagma.java | 6 +- .../entity/npc/EntityMetalhead.java | 14 +- .../entity/npc/EntityMobNPC.java | 18 +- .../entity/npc/EntityNPC.java | 188 +++++++------- .../entity/npc/EntityOrc.java | 8 +- .../entity/npc/EntityPrimarch.java | 12 +- .../entity/npc/EntitySlime.java | 38 +-- .../entity/npc/EntitySpaceMarine.java | 18 +- .../entity/npc/EntitySpirit.java | 10 +- .../entity/npc/EntityTiefling.java | 8 +- .../entity/npc/EntityUndead.java | 20 +- .../entity/npc/EntityVampire.java | 10 +- .../entity/npc/EntityWoodElf.java | 14 +- .../entity/npc/EntityZombie.java | 26 +- .../{game => common}/entity/npc/NpcInfo.java | 4 +- .../entity/npc/PlayerCharacter.java | 4 +- .../entity/npc/SpeciesInfo.java | 16 +- .../entity/projectile/EntityArrow.java | 50 ++-- .../entity/projectile/EntityBox.java | 18 +- .../entity/projectile/EntityBullet.java | 32 +-- .../entity/projectile/EntityDie.java | 26 +- .../entity/projectile/EntityDynamite.java | 26 +- .../entity/projectile/EntityEgg.java | 22 +- .../entity/projectile/EntityFireCharge.java | 16 +- .../entity/projectile/EntityFireball.java | 14 +- .../entity/projectile/EntityHook.java | 52 ++-- .../entity/projectile/EntityPotion.java | 26 +- .../entity/projectile/EntityProjectile.java | 32 +-- .../entity/projectile/EntitySnowball.java | 16 +- .../entity/projectile/RngFishable.java | 10 +- .../entity/types/CombatEntry.java | 4 +- .../entity/types/EntityAnimal.java | 30 +-- .../entity/types/EntityBodyHelper.java | 4 +- .../entity/types/EntityLiving.java | 124 ++++----- .../entity/types/EntityTameable.java | 10 +- .../entity/types/EntityThrowable.java | 32 +-- .../entity/types/EntityWaterMob.java | 12 +- .../entity/types/EntityWeatherEffect.java | 10 +- .../entity/types/IEntityFX.java | 2 +- .../entity/types/IEntityMultiPart.java | 8 +- .../entity/types/IEntityOwnable.java | 4 +- .../entity/types/IObjectData.java | 2 +- .../entity/types/IProjectile.java | 2 +- .../future/AbstractFuture.java | 2 +- .../future/ExecutionError.java | 2 +- .../future/ExecutionList.java | 2 +- .../future/FutureCallback.java | 2 +- java/src/{game => common}/future/Futures.java | 6 +- .../future/ListenableFuture.java | 2 +- .../future/ListenableFutureTask.java | 2 +- .../future/MoreExecutors.java | 2 +- .../future/ThreadFactoryBuilder.java | 2 +- .../future/UncheckedExecutionException.java | 2 +- .../{game => common}/init/BlockRegistry.java | 14 +- java/src/{game => common}/init/Blocks.java | 76 +++--- java/src/{game => common}/init/Config.java | 10 +- .../init/CraftingRegistry.java | 48 ++-- java/src/{game => common}/init/DecoType.java | 2 +- .../init/DispenserRegistry.java | 82 +++--- .../{game => common}/init/EntityEggInfo.java | 2 +- .../{game => common}/init/EntityRegistry.java | 98 +++---- .../init/FlammabilityRegistry.java | 4 +- .../{game => common}/init/FluidRegistry.java | 16 +- .../init/IObjectIntIterable.java | 2 +- java/src/{game => common}/init/IRegistry.java | 2 +- .../{game => common}/init/ItemRegistry.java | 242 ++++++++--------- java/src/{game => common}/init/Items.java | 18 +- java/src/{game => common}/init/MetalType.java | 4 +- .../{game => common}/init/NameRegistry.java | 4 +- .../init/ObjectIntIdentityMap.java | 8 +- java/src/{game => common}/init/OreType.java | 2 +- java/src/{game => common}/init/Registry.java | 4 +- .../init/RegistryDefaulted.java | 2 +- .../init/RegistryNamespaced.java | 6 +- .../RegistryNamespacedDefaultedByKey.java | 2 +- .../{game => common}/init/RegistrySimple.java | 4 +- .../init/ReorderRegistry.java | 16 +- .../init/RotationRegistry.java | 48 ++-- .../init/SmeltingRegistry.java | 19 +- .../src/{game => common}/init/SoundEvent.java | 2 +- .../init/SpeciesRegistry.java | 64 ++--- .../{game => common}/init/TileRegistry.java | 40 +-- .../{game => common}/init/ToolMaterial.java | 6 +- java/src/{game => common}/init/ToolType.java | 2 +- .../{game => common}/init/TradeRegistry.java | 20 +- .../init/UniverseRegistry.java | 65 ++--- java/src/{game => common}/init/WoodType.java | 4 +- .../inventory/AnimalChest.java | 2 +- .../{game => common}/inventory/Container.java | 16 +- .../inventory/ContainerBrewingStand.java | 8 +- .../inventory/ContainerChest.java | 6 +- .../inventory/ContainerDispenser.java | 6 +- .../inventory/ContainerEnchantment.java | 20 +- .../inventory/ContainerFurnace.java | 10 +- .../inventory/ContainerHopper.java | 6 +- .../inventory/ContainerHorseInventory.java | 10 +- .../inventory/ContainerLocalMenu.java | 10 +- .../inventory/ContainerMachine.java | 10 +- .../inventory/ContainerMerchant.java | 8 +- .../inventory/ContainerPlayer.java | 14 +- .../inventory/ContainerRepair.java | 24 +- .../inventory/ContainerWorkbench.java | 14 +- .../{game => common}/inventory/ICrafting.java | 4 +- .../{game => common}/inventory/IInvBasic.java | 2 +- .../inventory/IInventory.java | 8 +- .../inventory/ISidedInventory.java | 6 +- .../inventory/InventoryBasic.java | 8 +- .../inventory/InventoryCraftResult.java | 6 +- .../inventory/InventoryCrafting.java | 6 +- .../inventory/InventoryHelper.java | 16 +- .../inventory/InventoryLargeChest.java | 12 +- .../inventory/InventoryMerchant.java | 10 +- .../inventory/InventoryPlayer.java | 16 +- .../inventory/InventoryWarpChest.java | 14 +- java/src/{game => common}/inventory/Slot.java | 6 +- .../inventory/SlotCrafting.java | 8 +- .../inventory/SlotFurnaceFuel.java | 8 +- .../inventory/SlotFurnaceOutput.java | 14 +- .../inventory/SlotMerchantResult.java | 8 +- java/src/{game => common}/item/CheatTab.java | 8 +- java/src/{game => common}/item/Item.java | 42 +-- .../src/{game => common}/item/ItemAction.java | 2 +- java/src/{game => common}/item/ItemAmmo.java | 2 +- .../{game => common}/item/ItemAnvilBlock.java | 4 +- .../{game => common}/item/ItemAppleGold.java | 12 +- java/src/{game => common}/item/ItemArmor.java | 40 +-- java/src/{game => common}/item/ItemAxe.java | 6 +- .../{game => common}/item/ItemBanHammer.java | 16 +- .../src/{game => common}/item/ItemBanner.java | 34 +-- java/src/{game => common}/item/ItemBed.java | 18 +- java/src/{game => common}/item/ItemBlock.java | 32 +-- java/src/{game => common}/item/ItemBoat.java | 22 +- .../{game => common}/item/ItemBoltgun.java | 4 +- java/src/{game => common}/item/ItemBook.java | 2 +- java/src/{game => common}/item/ItemBow.java | 22 +- .../src/{game => common}/item/ItemBucket.java | 46 ++-- .../{game => common}/item/ItemBucketMilk.java | 16 +- .../src/{game => common}/item/ItemButton.java | 8 +- .../src/{game => common}/item/ItemCamera.java | 8 +- .../item/ItemCarrotOnAStick.java | 12 +- .../{game => common}/item/ItemChargedOrb.java | 26 +- java/src/{game => common}/item/ItemChest.java | 10 +- java/src/{game => common}/item/ItemCloth.java | 10 +- java/src/{game => common}/item/ItemCoal.java | 6 +- .../{game => common}/item/ItemColored.java | 4 +- .../{game => common}/item/ItemControl.java | 2 +- java/src/{game => common}/item/ItemDie.java | 20 +- .../{game => common}/item/ItemDispenser.java | 4 +- java/src/{game => common}/item/ItemDoor.java | 20 +- .../item/ItemDoublePlant.java | 14 +- java/src/{game => common}/item/ItemDye.java | 42 +-- .../{game => common}/item/ItemDynamite.java | 14 +- .../{game => common}/item/ItemEditWand.java | 10 +- .../src/{game => common}/item/ItemEffect.java | 2 +- java/src/{game => common}/item/ItemEgg.java | 10 +- .../item/ItemEnchantedBook.java | 22 +- .../{game => common}/item/ItemExpBottle.java | 10 +- .../item/ItemExterminator.java | 14 +- java/src/{game => common}/item/ItemFence.java | 10 +- .../{game => common}/item/ItemFireball.java | 16 +- .../{game => common}/item/ItemFirework.java | 18 +- .../item/ItemFireworkCharge.java | 16 +- .../{game => common}/item/ItemFishFood.java | 18 +- .../{game => common}/item/ItemFishingRod.java | 16 +- .../item/ItemFlintAndSteel.java | 16 +- java/src/{game => common}/item/ItemFood.java | 12 +- .../{game => common}/item/ItemFragile.java | 2 +- .../item/ItemGlassBottle.java | 18 +- .../{game => common}/item/ItemGunBase.java | 16 +- java/src/{game => common}/item/ItemHoe.java | 24 +- .../{game => common}/item/ItemHorseArmor.java | 4 +- .../item/ItemHugeMushroom.java | 4 +- .../{game => common}/item/ItemInfoWand.java | 14 +- java/src/{game => common}/item/ItemKey.java | 4 +- java/src/{game => common}/item/ItemLead.java | 20 +- .../src/{game => common}/item/ItemLeaves.java | 6 +- .../{game => common}/item/ItemLightning.java | 10 +- .../{game => common}/item/ItemLilyPad.java | 20 +- .../src/{game => common}/item/ItemMagnet.java | 16 +- .../{game => common}/item/ItemMagnetic.java | 2 +- java/src/{game => common}/item/ItemMetal.java | 16 +- .../{game => common}/item/ItemMetalBlock.java | 18 +- .../{game => common}/item/ItemMinecart.java | 28 +- .../item/ItemMonsterPlacer.java | 44 ++-- .../item/ItemMultiTexture.java | 4 +- .../{game => common}/item/ItemNameTag.java | 6 +- .../{game => common}/item/ItemNpcSpawner.java | 40 +-- .../src/{game => common}/item/ItemNugget.java | 4 +- .../{game => common}/item/ItemPickaxe.java | 6 +- .../src/{game => common}/item/ItemPiston.java | 10 +- .../src/{game => common}/item/ItemPotion.java | 37 +-- .../item/ItemPressurePlate.java | 10 +- .../src/{game => common}/item/ItemRecord.java | 6 +- .../{game => common}/item/ItemRedstone.java | 16 +- java/src/{game => common}/item/ItemReed.java | 20 +- java/src/{game => common}/item/ItemRod.java | 4 +- .../src/{game => common}/item/ItemSaddle.java | 8 +- .../{game => common}/item/ItemSeedFood.java | 12 +- java/src/{game => common}/item/ItemSeeds.java | 14 +- .../src/{game => common}/item/ItemShears.java | 16 +- java/src/{game => common}/item/ItemSign.java | 24 +- java/src/{game => common}/item/ItemSkull.java | 30 +-- java/src/{game => common}/item/ItemSlab.java | 16 +- java/src/{game => common}/item/ItemSmall.java | 4 +- java/src/{game => common}/item/ItemSnow.java | 18 +- .../{game => common}/item/ItemSnowball.java | 10 +- java/src/{game => common}/item/ItemSoup.java | 10 +- .../item/ItemSpaceNavigator.java | 12 +- java/src/{game => common}/item/ItemSpade.java | 8 +- java/src/{game => common}/item/ItemStack.java | 47 ++-- java/src/{game => common}/item/ItemStick.java | 4 +- java/src/{game => common}/item/ItemSword.java | 28 +- java/src/{game => common}/item/ItemTNT.java | 6 +- java/src/{game => common}/item/ItemTiny.java | 4 +- java/src/{game => common}/item/ItemTool.java | 22 +- java/src/{game => common}/item/ItemWall.java | 10 +- java/src/{game => common}/item/ItemWand.java | 20 +- .../item/ItemWeatherToken.java | 14 +- java/src/{game => common}/item/RngLoot.java | 12 +- java/src/{game => common}/log/Log.java | 12 +- java/src/{game => common}/log/LogLevel.java | 8 +- java/src/{game => common}/log/Message.java | 2 +- .../src/{game => common}/log/NettyLogger.java | 2 +- .../{game => common}/material/Material.java | 2 +- .../material/MaterialColdFluid.java | 2 +- .../material/MaterialHotFluid.java | 2 +- .../material/MaterialLogic.java | 2 +- .../material/MaterialPortal.java | 2 +- .../material/MaterialTransparent.java | 2 +- .../{game => common}/model/BlockLayer.java | 2 +- .../model/ItemMeshDefinition.java | 4 +- java/src/{game => common}/model/Model.java | 4 +- .../{game => common}/model/ModelProvider.java | 6 +- .../{game => common}/model/ModelRotation.java | 12 +- .../{game => common}/model/ParticleType.java | 6 +- .../src/{game => common}/model/Transform.java | 4 +- .../{game => common}/model/Transforms.java | 2 +- java/src/{game => common}/nbt/NBTBase.java | 2 +- .../{game => common}/nbt/NBTException.java | 2 +- java/src/{game => common}/nbt/NBTLoader.java | 2 +- java/src/{game => common}/nbt/NBTParser.java | 4 +- .../{game => common}/nbt/NBTSizeTracker.java | 2 +- java/src/{game => common}/nbt/NBTTagByte.java | 2 +- .../{game => common}/nbt/NBTTagByteArray.java | 2 +- .../{game => common}/nbt/NBTTagCompound.java | 7 +- .../{game => common}/nbt/NBTTagDouble.java | 4 +- java/src/{game => common}/nbt/NBTTagEnd.java | 2 +- .../src/{game => common}/nbt/NBTTagFloat.java | 4 +- java/src/{game => common}/nbt/NBTTagInt.java | 2 +- .../{game => common}/nbt/NBTTagIntArray.java | 2 +- java/src/{game => common}/nbt/NBTTagList.java | 6 +- java/src/{game => common}/nbt/NBTTagLong.java | 2 +- .../src/{game => common}/nbt/NBTTagShort.java | 2 +- .../{game => common}/nbt/NBTTagString.java | 2 +- java/src/{game => common}/nbt/NBTUtil.java | 2 +- .../network/IClientLoginHandler.java | 8 +- .../network/IClientPlayer.java | 136 +++++----- .../network/IHandshakeHandler.java | 4 +- .../network/ILoginHandler.java | 4 +- .../src/{game => common}/network/IPlayer.java | 58 ++--- .../network/IThreadListener.java | 4 +- .../network/NetConnection.java | 10 +- .../{game => common}/network/NetHandler.java | 2 +- .../network/NettyCompressionDecoder.java | 2 +- .../network/NettyCompressionEncoder.java | 2 +- java/src/{game => common}/network/Packet.java | 2 +- .../network/PacketBuffer.java | 14 +- .../network/PacketDecoder.java | 2 +- .../network/PacketEncoder.java | 4 +- .../network/PacketPrepender.java | 2 +- .../network/PacketRegistry.java | 166 ++++++------ .../network/PacketSplitter.java | 2 +- .../{game => common}/packet/APacketEmpty.java | 6 +- .../packet/APacketVarInt.java | 6 +- .../packet/CPacketAction.java | 8 +- .../{game => common}/packet/CPacketBook.java | 8 +- .../{game => common}/packet/CPacketBreak.java | 12 +- .../{game => common}/packet/CPacketCheat.java | 10 +- .../{game => common}/packet/CPacketClick.java | 10 +- .../packet/CPacketComplete.java | 10 +- .../{game => common}/packet/CPacketInput.java | 8 +- .../packet/CPacketKeepAlive.java | 4 +- .../packet/CPacketMessage.java | 8 +- .../{game => common}/packet/CPacketPlace.java | 12 +- .../packet/CPacketPlayer.java | 8 +- .../{game => common}/packet/CPacketSign.java | 10 +- .../{game => common}/packet/CPacketSkin.java | 8 +- .../packet/HPacketHandshake.java | 8 +- .../packet/LPacketPasswordResponse.java | 10 +- .../packet/RPacketDisconnect.java | 8 +- .../packet/RPacketEnableCompression.java | 4 +- .../packet/RPacketLoginSuccess.java | 4 +- .../packet/S14PacketEntity.java | 12 +- .../packet/S18PacketEntityTeleport.java | 12 +- .../packet/S19PacketEntityHeadLook.java | 12 +- .../packet/S1APacketEntityStatus.java | 12 +- .../packet/S1BPacketEntityAttach.java | 10 +- .../packet/S1CPacketEntityMetadata.java | 10 +- .../packet/S1DPacketEntityEffect.java | 12 +- .../packet/S1EPacketRemoveEntityEffect.java | 12 +- .../packet/S20PacketEntityProperties.java | 14 +- .../packet/S27PacketExplosion.java | 14 +- .../packet/S28PacketEffect.java | 10 +- .../packet/S29PacketSoundEffect.java | 10 +- .../packet/S2APacketParticles.java | 10 +- .../packet/S2BPacketChangeGameState.java | 10 +- .../packet/S2CPacketSpawnGlobalEntity.java | 12 +- .../packet/S2DPacketOpenWindow.java | 10 +- .../packet/S2EPacketCloseWindow.java | 8 +- .../packet/S2FPacketSetSlot.java | 10 +- .../packet/S30PacketWindowItems.java | 10 +- .../packet/S31PacketWindowProperty.java | 8 +- .../packet/S32PacketConfirmTransaction.java | 8 +- .../packet/S33PacketUpdateSign.java | 12 +- .../packet/S35PacketUpdateTileEntity.java | 16 +- .../packet/S36PacketSignEditorOpen.java | 10 +- .../packet/S38PacketPlayerListItem.java | 12 +- .../packet/S39PacketPlayerAbilities.java | 10 +- .../packet/S3APacketTabComplete.java | 8 +- .../packet/S43PacketUpdateEntityNBT.java | 14 +- .../packet/SPacketAnimation.java | 10 +- .../packet/SPacketBiomes.java | 8 +- .../packet/SPacketBlockAction.java | 14 +- .../packet/SPacketBlockBreakAnim.java | 10 +- .../packet/SPacketBlockChange.java | 16 +- .../packet/SPacketCamera.java | 12 +- .../packet/SPacketCharacterList.java | 18 +- .../packet/SPacketChunkData.java | 14 +- .../packet/SPacketCollectItem.java | 8 +- .../packet/SPacketDestroyEntities.java | 8 +- .../packet/SPacketDimensionName.java | 10 +- .../packet/SPacketDisconnect.java | 8 +- .../packet/SPacketEntityEquipment.java | 10 +- .../packet/SPacketEntityVelocity.java | 10 +- .../packet/SPacketHeldItemChange.java | 8 +- .../packet/SPacketJoinGame.java | 12 +- .../packet/SPacketKeepAlive.java | 4 +- .../packet/SPacketLoading.java | 8 +- .../packet/SPacketMapChunkBulk.java | 10 +- .../packet/SPacketMessage.java | 8 +- .../packet/SPacketMultiBlockChange.java | 18 +- .../packet/SPacketPlayerPosLook.java | 8 +- .../packet/SPacketRespawn.java | 12 +- .../packet/SPacketServerTick.java | 8 +- .../packet/SPacketSetExperience.java | 8 +- .../{game => common}/packet/SPacketSkin.java | 14 +- .../packet/SPacketSpawnMob.java | 16 +- .../packet/SPacketSpawnObject.java | 24 +- .../packet/SPacketSpawnPlayer.java | 22 +- .../packet/SPacketTimeUpdate.java | 8 +- .../packet/SPacketTrades.java | 14 +- .../packet/SPacketUpdateHealth.java | 8 +- .../{game => common}/packet/SPacketWorld.java | 8 +- .../pathfinding/NodeProcessor.java | 8 +- .../{game => common}/pathfinding/Path.java | 2 +- .../pathfinding/PathCache.java | 16 +- .../pathfinding/PathEntity.java | 6 +- .../pathfinding/PathFinder.java | 6 +- .../pathfinding/PathNavigate.java | 20 +- .../pathfinding/PathNavigateClimber.java | 12 +- .../pathfinding/PathNavigateGround.java | 20 +- .../pathfinding/PathPoint.java | 4 +- .../pathfinding/SwimNodeProcessor.java | 12 +- .../pathfinding/WalkNodeProcessor.java | 26 +- .../pattern/BlockStateHelper.java | 10 +- java/src/{game => common}/potion/Potion.java | 22 +- .../{game => common}/potion/PotionEffect.java | 8 +- .../{game => common}/potion/PotionHelper.java | 6 +- .../properties/IProperty.java | 2 +- .../properties/PropertyBool.java | 4 +- .../properties/PropertyDirection.java | 10 +- .../properties/PropertyEnum.java | 14 +- .../properties/PropertyHelper.java | 2 +- .../properties/PropertyInteger.java | 6 +- .../src/{game => common}/rng/ImprovedGen.java | 2 +- .../{game => common}/rng/ImprovedGenOld.java | 2 +- java/src/{game => common}/rng/NoiseGen.java | 2 +- java/src/{game => common}/rng/OctaveGen.java | 2 +- .../{game => common}/rng/OctaveGenOld.java | 2 +- java/src/{game => common}/rng/PerlinGen.java | 2 +- .../{game => common}/rng/PerlinGenOld.java | 2 +- java/src/{game => common}/rng/Random.java | 2 +- java/src/{game => common}/rng/RngItem.java | 2 +- java/src/{game => common}/rng/SimplexGen.java | 2 +- .../{game => common}/rng/SimplexGenOld.java | 2 +- .../{game => common}/rng/WeightedList.java | 2 +- .../src/{game => common}/sound/EventType.java | 2 +- .../{game => common}/sound/MovingSound.java | 4 +- .../sound/MovingSoundMinecart.java | 8 +- .../sound/MovingSoundMinecartRiding.java | 10 +- .../sound/PositionedSound.java | 4 +- java/src/{game => common}/sound/Sound.java | 4 +- .../{game => common}/tileentity/IHopper.java | 6 +- .../tileentity/IInteractionObject.java | 8 +- .../tileentity/ILockableContainer.java | 4 +- .../tileentity/ITickable.java | 2 +- .../tileentity/IWorldNameable.java | 2 +- .../LocalBlockIntercommunication.java | 8 +- .../{game => common}/tileentity/LockCode.java | 4 +- .../tileentity/MachineResource.java | 4 +- .../tileentity/TileEntity.java | 20 +- .../tileentity/TileEntityBanner.java | 22 +- .../tileentity/TileEntityBeacon.java | 30 +-- .../tileentity/TileEntityBrewingStand.java | 34 +-- .../tileentity/TileEntityChest.java | 32 +-- .../tileentity/TileEntityComparator.java | 4 +- .../TileEntityDaylightDetector.java | 6 +- .../tileentity/TileEntityDispenser.java | 20 +- .../tileentity/TileEntityDropper.java | 2 +- .../TileEntityEnchantmentTable.java | 16 +- .../tileentity/TileEntityFurnace.java | 56 ++-- .../tileentity/TileEntityHopper.java | 42 +-- .../tileentity/TileEntityLockable.java | 4 +- .../tileentity/TileEntityMachine.java | 26 +- .../tileentity/TileEntityMobSpawner.java | 26 +- .../tileentity/TileEntityNote.java | 14 +- .../tileentity/TileEntityPiston.java | 18 +- .../tileentity/TileEntitySign.java | 10 +- .../tileentity/TileEntitySkull.java | 8 +- .../tileentity/TileEntityTianReactor.java | 12 +- .../{game => common}/util/CharValidator.java | 2 +- java/src/{game => common}/util/DC32.java | 2 +- .../{game => common}/util/Displayable.java | 2 +- java/src/{game => common}/util/ExtMath.java | 2 +- java/src/{game => common}/util/FileUtils.java | 4 +- .../{game => common}/util/Identifyable.java | 2 +- .../{game => common}/util/LazyLoadBase.java | 2 +- java/src/{game => common}/util/Matrix4f.java | 2 +- .../src/{game => common}/util/Predicates.java | 2 +- java/src/{game => common}/util/Tuple.java | 2 +- java/src/{game => common}/util/Util.java | 8 +- java/src/{game => common}/util/Vector.java | 2 +- java/src/{game => common}/util/Vector3f.java | 2 +- java/src/{game => common}/util/Vector4f.java | 2 +- .../village/MerchantRecipe.java | 8 +- .../village/MerchantRecipeList.java | 10 +- .../src/{game => common}/village/Village.java | 18 +- .../village/VillageCollection.java | 20 +- .../village/VillageDoorInfo.java | 6 +- .../{game => common}/world/BlockArray.java | 8 +- java/src/{game => common}/world/BlockPos.java | 6 +- .../{game => common}/world/BoundingBox.java | 4 +- java/src/{game => common}/world/Chunk.java | 30 +-- .../{game => common}/world/ChunkCache.java | 2 +- java/src/{game => common}/world/ChunkPos.java | 2 +- .../world/ClassInheritanceMultiMap.java | 8 +- .../{game => common}/world/EmptyChunk.java | 10 +- .../src/{game => common}/world/Explosion.java | 36 +-- java/src/{game => common}/world/Facing.java | 12 +- .../{game => common}/world/HitPosition.java | 4 +- .../{game => common}/world/IBlockAccess.java | 2 +- .../{game => common}/world/IWorldAccess.java | 6 +- .../{game => common}/world/IntHashMap.java | 2 +- .../src/{game => common}/world/LightType.java | 2 +- .../{game => common}/world/LongHashMap.java | 2 +- .../world/NextTickListEntry.java | 6 +- .../{game => common}/world/NibbleArray.java | 2 +- .../{game => common}/world/PortalType.java | 2 +- java/src/{game => common}/world/Position.java | 2 +- java/src/{game => common}/world/Region.java | 28 +- java/src/{game => common}/world/Spawner.java | 26 +- java/src/{game => common}/world/State.java | 20 +- java/src/{game => common}/world/Vec3.java | 4 +- java/src/{game => common}/world/Vec3i.java | 4 +- java/src/{game => common}/world/Weather.java | 10 +- java/src/{game => common}/world/World.java | 50 ++-- .../{game => common}/world/WorldClient.java | 52 ++-- java/src/{game => common}/world/WorldPos.java | 2 +- .../{game => common}/world/WorldServer.java | 150 +++++------ .../worldgen/BiomeGenLayered.java | 50 ++-- .../worldgen/BiomeGenPerlin.java | 6 +- .../worldgen/BiomeGenSingle.java | 6 +- .../worldgen/BiomeGenerator.java | 6 +- .../worldgen/BlockReplacer.java | 8 +- .../worldgen/ChunkGenerator.java | 4 +- .../worldgen/ChunkPrimer.java | 8 +- .../worldgen/FeatureDungeons.java | 28 +- .../worldgen/FeatureGenerator.java | 10 +- .../worldgen/FeatureLakes.java | 20 +- .../worldgen/FeatureLiquids.java | 14 +- .../worldgen/FeatureOres.java | 14 +- .../worldgen/GeneratorCavern.java | 12 +- .../worldgen/GeneratorDebug.java | 14 +- .../worldgen/GeneratorDestroyed.java | 10 +- .../worldgen/GeneratorFlat.java | 6 +- .../worldgen/GeneratorIsland.java | 12 +- .../worldgen/GeneratorPerlin.java | 18 +- .../worldgen/GeneratorSimple.java | 12 +- .../worldgen/LootConstants.java | 32 +-- .../worldgen/ReplacerAltBiome.java | 18 +- .../worldgen/ReplacerAltSurface.java | 16 +- .../worldgen/ReplacerBiome.java | 10 +- .../worldgen/ReplacerTopLayer.java | 16 +- .../worldgen/caves/MapGenBase.java | 8 +- .../worldgen/caves/MapGenBigCaves.java | 16 +- .../worldgen/caves/MapGenCaves.java | 24 +- .../worldgen/caves/MapGenRavine.java | 18 +- .../feature/WorldGenAbandonedChest.java | 26 +- .../worldgen/feature/WorldGenAsteroid.java | 12 +- .../worldgen/feature/WorldGenBlockBlob.java | 14 +- .../worldgen/feature/WorldGenClay.java | 14 +- .../worldgen/feature/WorldGenClayExt.java | 14 +- .../worldgen/feature/WorldGenDesertWells.java | 24 +- .../worldgen/feature/WorldGenFire.java | 12 +- .../worldgen/feature/WorldGenGlowStone.java | 16 +- .../worldgen/feature/WorldGenHellLava.java | 16 +- .../worldgen/feature/WorldGenIcePath.java | 14 +- .../worldgen/feature/WorldGenIceSpike.java | 18 +- .../worldgen/feature/WorldGenSand.java | 14 +- .../worldgen/feature/WorldGenSpikes.java | 18 +- .../worldgen/foliage/FeatureDoublePlant.java | 12 +- .../worldgen/foliage/WorldGenBigMushroom.java | 18 +- .../worldgen/foliage/WorldGenCactus.java | 12 +- .../worldgen/foliage/WorldGenDeadBush.java | 16 +- .../worldgen/foliage/WorldGenFlowers.java | 14 +- .../worldgen/foliage/WorldGenMelon.java | 12 +- .../worldgen/foliage/WorldGenMushroom.java | 12 +- .../worldgen/foliage/WorldGenPumpkin.java | 16 +- .../worldgen/foliage/WorldGenReed.java | 14 +- .../worldgen/foliage/WorldGenShrub.java | 20 +- .../worldgen/foliage/WorldGenTallGrass.java | 20 +- .../worldgen/foliage/WorldGenVines.java | 18 +- .../worldgen/foliage/WorldGenWaterlily.java | 16 +- .../worldgen/layer/GenLayer.java | 4 +- .../worldgen/layer/GenLayerAddAreas.java | 2 +- .../worldgen/layer/GenLayerAddExtra.java | 4 +- .../worldgen/layer/GenLayerAddSea.java | 4 +- .../worldgen/layer/GenLayerAddSnow.java | 2 +- .../worldgen/layer/GenLayerBase.java | 2 +- .../worldgen/layer/GenLayerBiome.java | 4 +- .../worldgen/layer/GenLayerBiomeEdge.java | 6 +- .../worldgen/layer/GenLayerEdge.java | 2 +- .../worldgen/layer/GenLayerFuzzyZoom.java | 2 +- .../worldgen/layer/GenLayerHills.java | 6 +- .../worldgen/layer/GenLayerRemoveEmpty.java | 2 +- .../worldgen/layer/GenLayerRiver.java | 4 +- .../worldgen/layer/GenLayerRiverInit.java | 2 +- .../worldgen/layer/GenLayerRiverMix.java | 4 +- .../worldgen/layer/GenLayerShore.java | 6 +- .../worldgen/layer/GenLayerSmooth.java | 2 +- .../worldgen/layer/GenLayerVoronoiZoom.java | 2 +- .../worldgen/layer/GenLayerZoom.java | 2 +- .../worldgen/layer/IntCache.java | 4 +- .../worldgen/structure/MapGenBridge.java | 6 +- .../worldgen/structure/MapGenMineshaft.java | 2 +- .../structure/MapGenScatteredFeature.java | 10 +- .../worldgen/structure/MapGenStronghold.java | 6 +- .../worldgen/structure/MapGenStructure.java | 26 +- .../worldgen/structure/MapGenStructureIO.java | 10 +- .../worldgen/structure/MapGenVillage.java | 12 +- .../structure/StructureBoundingBox.java | 10 +- .../worldgen/structure/StructureBridge.java | 22 +- .../structure/StructureComponent.java | 36 +-- .../structure/StructureMineshaft.java | 34 +-- .../structure/StructureMineshaftStart.java | 6 +- .../structure/StructureScattered.java | 40 +-- .../worldgen/structure/StructureStart.java | 12 +- .../structure/StructureStronghold.java | 32 +-- .../worldgen/structure/StructureVillage.java | 46 ++-- .../worldgen/tree/WorldGenBaseTree.java | 26 +- .../worldgen/tree/WorldGenBigTree.java | 24 +- .../worldgen/tree/WorldGenBirch.java | 18 +- .../worldgen/tree/WorldGenDarkOak.java | 20 +- .../worldgen/tree/WorldGenHugeTree.java | 18 +- .../worldgen/tree/WorldGenJungle.java | 18 +- .../worldgen/tree/WorldGenPine.java | 20 +- .../worldgen/tree/WorldGenSavanna.java | 20 +- .../worldgen/tree/WorldGenSwamp.java | 22 +- .../worldgen/tree/WorldGenTaiga1.java | 18 +- .../worldgen/tree/WorldGenTaiga2.java | 18 +- .../worldgen/tree/WorldGenTree.java | 20 +- server/src/server/Server.java | 114 ++++---- server/src/server/command/ArgumentParser.java | 2 +- .../src/server/command/ArgumentSplitter.java | 6 +- .../src/server/command/CachedExecutable.java | 4 +- server/src/server/command/ColorParser.java | 2 +- server/src/server/command/Command.java | 8 +- .../server/command/CommandEnvironment.java | 10 +- .../src/server/command/DimensionParser.java | 6 +- server/src/server/command/DoubleParser.java | 6 +- .../src/server/command/EntityListParser.java | 14 +- server/src/server/command/EntityParser.java | 8 +- server/src/server/command/EnumParser.java | 2 +- server/src/server/command/Executor.java | 6 +- server/src/server/command/FixedExecutor.java | 6 +- .../command/PlayerEntityListParser.java | 8 +- .../server/command/PlayerEntityParser.java | 2 +- .../src/server/command/PlayerListParser.java | 4 +- server/src/server/command/StringParser.java | 2 +- server/src/server/command/TagParser.java | 6 +- server/src/server/command/WorldParser.java | 6 +- .../server/command/commands/CommandHelp.java | 4 +- .../command/commands/CommandMessage.java | 2 +- .../server/command/commands/CommandMilk.java | 6 +- .../command/commands/CommandOfflinetp.java | 8 +- .../command/commands/CommandPotion.java | 6 +- .../command/commands/CommandRemove.java | 2 +- .../server/command/commands/CommandSpawn.java | 18 +- .../server/command/commands/CommandTele.java | 6 +- .../server/command/commands/CommandTime.java | 8 +- .../server/command/commands/CommandTp.java | 6 +- .../server/command/commands/CommandWarp.java | 6 +- .../command/commands/CommandWeather.java | 4 +- .../server/command/commands/CommandWorld.java | 6 +- .../src/server/network/HandshakeHandler.java | 14 +- server/src/server/network/LoginHandler.java | 18 +- server/src/server/network/Player.java | 244 +++++++++--------- 1246 files changed, 9285 insertions(+), 9272 deletions(-) rename client/src/{game => client}/vars/BaseVar.java (97%) rename client/src/{game => client}/vars/BoolVar.java (95%) rename client/src/{game => client}/vars/CVar.java (86%) rename client/src/{game => client}/vars/CVarCategory.java (89%) rename client/src/{game => client}/vars/ColorVar.java (95%) rename client/src/{game => client}/vars/EnumVar.java (96%) rename client/src/{game => client}/vars/FloatVar.java (97%) rename client/src/{game => client}/vars/IntVar.java (95%) rename client/src/{game => client}/vars/StringVar.java (96%) rename client/src/{game => client}/vars/Variable.java (88%) rename client/src/{game => client}/world/Converter.java (95%) rename java/src/{game => common}/IClient.java (78%) rename java/src/{game => common}/IServer.java (69%) rename java/src/{game => common}/ai/AIFireballAttack.java (92%) rename java/src/{game => common}/ai/AIFlyingBoxAttack.java (94%) rename java/src/{game => common}/ai/AIRangedAttack.java (96%) rename java/src/{game => common}/ai/AISmallFireballAttack.java (94%) rename java/src/{game => common}/ai/EntityAIAttackOnCollide.java (96%) rename java/src/{game => common}/ai/EntityAIAvoidEntity.java (94%) rename java/src/{game => common}/ai/EntityAIBase.java (98%) rename java/src/{game => common}/ai/EntityAIBeg.java (92%) rename java/src/{game => common}/ai/EntityAIControlledByPlayer.java (94%) rename java/src/{game => common}/ai/EntityAIDoorInteract.java (92%) rename java/src/{game => common}/ai/EntityAIEatGrass.java (90%) rename java/src/{game => common}/ai/EntityAIExplode.java (93%) rename java/src/{game => common}/ai/EntityAIFindEntityNearest.java (95%) rename java/src/{game => common}/ai/EntityAIFleeSun.java (92%) rename java/src/{game => common}/ai/EntityAIFollowOwner.java (93%) rename java/src/{game => common}/ai/EntityAIFollowParent.java (97%) rename java/src/{game => common}/ai/EntityAIHarvestFarmland.java (97%) rename java/src/{game => common}/ai/EntityAIHurtByTarget.java (96%) rename java/src/{game => common}/ai/EntityAILeapAtTarget.java (95%) rename java/src/{game => common}/ai/EntityAILookAtTalkingPlayer.java (90%) rename java/src/{game => common}/ai/EntityAILookIdle.java (96%) rename java/src/{game => common}/ai/EntityAIMate.java (94%) rename java/src/{game => common}/ai/EntityAIMoveIndoors.java (93%) rename java/src/{game => common}/ai/EntityAIMoveThroughVillage.java (93%) rename java/src/{game => common}/ai/EntityAIMoveToBlock.java (97%) rename java/src/{game => common}/ai/EntityAIMoveTowardsRestriction.java (93%) rename java/src/{game => common}/ai/EntityAIMoveTowardsTarget.java (96%) rename java/src/{game => common}/ai/EntityAINagPlayer.java (91%) rename java/src/{game => common}/ai/EntityAINearestAttackableTarget.java (98%) rename java/src/{game => common}/ai/EntityAINpcInteract.java (95%) rename java/src/{game => common}/ai/EntityAINpcMate.java (95%) rename java/src/{game => common}/ai/EntityAIOcelotAttack.java (96%) rename java/src/{game => common}/ai/EntityAIOcelotSit.java (88%) rename java/src/{game => common}/ai/EntityAIOpenDoor.java (95%) rename java/src/{game => common}/ai/EntityAIOwnerHurtByTarget.java (94%) rename java/src/{game => common}/ai/EntityAIOwnerHurtTarget.java (93%) rename java/src/{game => common}/ai/EntityAIPanic.java (94%) rename java/src/{game => common}/ai/EntityAIPlay.java (93%) rename java/src/{game => common}/ai/EntityAIRestrictOpenDoor.java (90%) rename java/src/{game => common}/ai/EntityAIRestrictSun.java (84%) rename java/src/{game => common}/ai/EntityAIRunAroundLikeCrazy.java (94%) rename java/src/{game => common}/ai/EntityAIShareItems.java (93%) rename java/src/{game => common}/ai/EntityAISit.java (93%) rename java/src/{game => common}/ai/EntityAISwimming.java (87%) rename java/src/{game => common}/ai/EntityAITakePlace.java (93%) rename java/src/{game => common}/ai/EntityAITarget.java (95%) rename java/src/{game => common}/ai/EntityAITargetNonTamed.java (86%) rename java/src/{game => common}/ai/EntityAITasks.java (99%) rename java/src/{game => common}/ai/EntityAITempt.java (96%) rename java/src/{game => common}/ai/EntityAIWander.java (96%) rename java/src/{game => common}/ai/EntityAIWatchClosest.java (96%) rename java/src/{game => common}/ai/EntityAIWatchClosest2.java (78%) rename java/src/{game => common}/ai/EntityJumpHelper.java (88%) rename java/src/{game => common}/ai/EntityLookHelper.java (96%) rename java/src/{game => common}/ai/EntityMoveHelper.java (95%) rename java/src/{game => common}/ai/EntitySenses.java (91%) rename java/src/{game => common}/ai/RandomPositionGenerator.java (96%) rename java/src/{game => common}/biome/Biome.java (93%) rename java/src/{game => common}/biome/BiomeBeach.java (83%) rename java/src/{game => common}/biome/BiomeBlackened.java (70%) rename java/src/{game => common}/biome/BiomeChaos.java (73%) rename java/src/{game => common}/biome/BiomeDesert.java (79%) rename java/src/{game => common}/biome/BiomeExterminated.java (73%) rename java/src/{game => common}/biome/BiomeForest.java (93%) rename java/src/{game => common}/biome/BiomeHell.java (87%) rename java/src/{game => common}/biome/BiomeHills.java (91%) rename java/src/{game => common}/biome/BiomeJungle.java (78%) rename java/src/{game => common}/biome/BiomeMesa.java (95%) rename java/src/{game => common}/biome/BiomeMoon.java (70%) rename java/src/{game => common}/biome/BiomeMushroom.java (79%) rename java/src/{game => common}/biome/BiomeMutated.java (92%) rename java/src/{game => common}/biome/BiomeNone.java (71%) rename java/src/{game => common}/biome/BiomePlains.java (94%) rename java/src/{game => common}/biome/BiomeSavanna.java (87%) rename java/src/{game => common}/biome/BiomeSnow.java (82%) rename java/src/{game => common}/biome/BiomeSnowLand.java (73%) rename java/src/{game => common}/biome/BiomeSpace.java (74%) rename java/src/{game => common}/biome/BiomeStoneBeach.java (84%) rename java/src/{game => common}/biome/BiomeSwamp.java (85%) rename java/src/{game => common}/biome/BiomeTaiga.java (85%) rename java/src/{game => common}/biome/BiomeTian.java (80%) rename java/src/{game => common}/biome/BiomeWater.java (80%) rename java/src/{game => common}/biome/RngSpawn.java (77%) rename java/src/{game => common}/biome/Scaling.java (96%) rename java/src/{game => common}/biome/Temperature.java (71%) rename java/src/{game => common}/block/Block.java (96%) rename java/src/{game => common}/block/BlockAir.java (86%) rename java/src/{game => common}/block/BlockAnvil.java (88%) rename java/src/{game => common}/block/BlockBanner.java (91%) rename java/src/{game => common}/block/BlockBaseFlower.java (88%) rename java/src/{game => common}/block/BlockBasePressurePlate.java (93%) rename java/src/{game => common}/block/BlockBeacon.java (89%) rename java/src/{game => common}/block/BlockBed.java (91%) rename java/src/{game => common}/block/BlockBedrock.java (68%) rename java/src/{game => common}/block/BlockBlackenedDirt.java (83%) rename java/src/{game => common}/block/BlockBlackenedSoil.java (83%) rename java/src/{game => common}/block/BlockBlackenedStone.java (56%) rename java/src/{game => common}/block/BlockBlueShroom.java (89%) rename java/src/{game => common}/block/BlockBookshelf.java (72%) rename java/src/{game => common}/block/BlockBreakable.java (83%) rename java/src/{game => common}/block/BlockBrewingStand.java (96%) rename java/src/{game => common}/block/BlockBush.java (87%) rename java/src/{game => common}/block/BlockButton.java (94%) rename java/src/{game => common}/block/BlockCactus.java (89%) rename java/src/{game => common}/block/BlockCake.java (93%) rename java/src/{game => common}/block/BlockCarpet.java (89%) rename java/src/{game => common}/block/BlockCarrot.java (70%) rename java/src/{game => common}/block/BlockCauldron.java (96%) rename java/src/{game => common}/block/BlockChest.java (94%) rename java/src/{game => common}/block/BlockClay.java (72%) rename java/src/{game => common}/block/BlockCocoa.java (92%) rename java/src/{game => common}/block/BlockColored.java (85%) rename java/src/{game => common}/block/BlockCompressedPowered.java (75%) rename java/src/{game => common}/block/BlockContainer.java (87%) rename java/src/{game => common}/block/BlockCore.java (66%) rename java/src/{game => common}/block/BlockCrops.java (93%) rename java/src/{game => common}/block/BlockDaylightDetector.java (87%) rename java/src/{game => common}/block/BlockDeadBush.java (80%) rename java/src/{game => common}/block/BlockDirectional.java (67%) rename java/src/{game => common}/block/BlockDirt.java (91%) rename java/src/{game => common}/block/BlockDispenser.java (90%) rename java/src/{game => common}/block/BlockDoor.java (95%) rename java/src/{game => common}/block/BlockDoublePlant.java (95%) rename java/src/{game => common}/block/BlockDragonEgg.java (93%) rename java/src/{game => common}/block/BlockDropper.java (85%) rename java/src/{game => common}/block/BlockDryLeaves.java (88%) rename java/src/{game => common}/block/BlockDynamicLiquid.java (96%) rename java/src/{game => common}/block/BlockEnchantmentTable.java (87%) rename java/src/{game => common}/block/BlockEventData.java (96%) rename java/src/{game => common}/block/BlockFalling.java (88%) rename java/src/{game => common}/block/BlockFarmland.java (89%) rename java/src/{game => common}/block/BlockFence.java (95%) rename java/src/{game => common}/block/BlockFenceGate.java (95%) rename java/src/{game => common}/block/BlockFire.java (98%) rename java/src/{game => common}/block/BlockFloorPortal.java (90%) rename java/src/{game => common}/block/BlockFlower.java (93%) rename java/src/{game => common}/block/BlockFlowerPot.java (95%) rename java/src/{game => common}/block/BlockFurnace.java (91%) rename java/src/{game => common}/block/BlockGlass.java (80%) rename java/src/{game => common}/block/BlockGlowstone.java (82%) rename java/src/{game => common}/block/BlockGrass.java (91%) rename java/src/{game => common}/block/BlockGravel.java (74%) rename java/src/{game => common}/block/BlockHardenedClay.java (80%) rename java/src/{game => common}/block/BlockHay.java (84%) rename java/src/{game => common}/block/BlockHellRock.java (83%) rename java/src/{game => common}/block/BlockHopper.java (92%) rename java/src/{game => common}/block/BlockHugeMushroom.java (93%) rename java/src/{game => common}/block/BlockIce.java (81%) rename java/src/{game => common}/block/BlockJukebox.java (64%) rename java/src/{game => common}/block/BlockLadder.java (90%) rename java/src/{game => common}/block/BlockLeaves.java (93%) rename java/src/{game => common}/block/BlockLeavesBase.java (91%) rename java/src/{game => common}/block/BlockLever.java (94%) rename java/src/{game => common}/block/BlockLilyPad.java (86%) rename java/src/{game => common}/block/BlockLiquid.java (94%) rename java/src/{game => common}/block/BlockLog.java (90%) rename java/src/{game => common}/block/BlockMachine.java (85%) rename java/src/{game => common}/block/BlockMelon.java (78%) rename java/src/{game => common}/block/BlockMobSpawner.java (84%) rename java/src/{game => common}/block/BlockMushroom.java (90%) rename java/src/{game => common}/block/BlockMycelium.java (86%) rename java/src/{game => common}/block/BlockNote.java (90%) rename java/src/{game => common}/block/BlockNuke.java (81%) rename java/src/{game => common}/block/BlockObsidian.java (72%) rename java/src/{game => common}/block/BlockOre.java (93%) rename java/src/{game => common}/block/BlockPackedIce.java (76%) rename java/src/{game => common}/block/BlockPane.java (96%) rename java/src/{game => common}/block/BlockPistonBase.java (96%) rename java/src/{game => common}/block/BlockPistonHead.java (93%) rename java/src/{game => common}/block/BlockPistonMoving.java (93%) rename java/src/{game => common}/block/BlockPortal.java (96%) rename java/src/{game => common}/block/BlockPortalFrame.java (87%) rename java/src/{game => common}/block/BlockPotato.java (78%) rename java/src/{game => common}/block/BlockPressurePlate.java (88%) rename java/src/{game => common}/block/BlockPressurePlateWeighted.java (88%) rename java/src/{game => common}/block/BlockPumpkin.java (95%) rename java/src/{game => common}/block/BlockQuartz.java (92%) rename java/src/{game => common}/block/BlockRail.java (88%) rename java/src/{game => common}/block/BlockRailBase.java (97%) rename java/src/{game => common}/block/BlockRailDetector.java (92%) rename java/src/{game => common}/block/BlockRailPowered.java (96%) rename java/src/{game => common}/block/BlockRedstoneComparator.java (95%) rename java/src/{game => common}/block/BlockRedstoneDiode.java (95%) rename java/src/{game => common}/block/BlockRedstoneLight.java (87%) rename java/src/{game => common}/block/BlockRedstoneOre.java (90%) rename java/src/{game => common}/block/BlockRedstoneRepeater.java (97%) rename java/src/{game => common}/block/BlockRedstoneTorch.java (93%) rename java/src/{game => common}/block/BlockRedstoneWire.java (97%) rename java/src/{game => common}/block/BlockReed.java (89%) rename java/src/{game => common}/block/BlockRock.java (76%) rename java/src/{game => common}/block/BlockRotatedPillar.java (78%) rename java/src/{game => common}/block/BlockSand.java (91%) rename java/src/{game => common}/block/BlockSandStone.java (92%) rename java/src/{game => common}/block/BlockSapling.java (92%) rename java/src/{game => common}/block/BlockSign.java (88%) rename java/src/{game => common}/block/BlockSkull.java (86%) rename java/src/{game => common}/block/BlockSlab.java (95%) rename java/src/{game => common}/block/BlockSlime.java (88%) rename java/src/{game => common}/block/BlockSnow.java (87%) rename java/src/{game => common}/block/BlockSnowBlock.java (73%) rename java/src/{game => common}/block/BlockSoulSand.java (75%) rename java/src/{game => common}/block/BlockSourceImpl.java (84%) rename java/src/{game => common}/block/BlockStainedGlass.java (87%) rename java/src/{game => common}/block/BlockStainedGlassPane.java (90%) rename java/src/{game => common}/block/BlockStairs.java (96%) rename java/src/{game => common}/block/BlockStandingSign.java (87%) rename java/src/{game => common}/block/BlockStaticLiquid.java (91%) rename java/src/{game => common}/block/BlockStem.java (94%) rename java/src/{game => common}/block/BlockStone.java (54%) rename java/src/{game => common}/block/BlockStoneBrick.java (92%) rename java/src/{game => common}/block/BlockTNT.java (89%) rename java/src/{game => common}/block/BlockTallGrass.java (90%) rename java/src/{game => common}/block/BlockTianReactor.java (70%) rename java/src/{game => common}/block/BlockTianSoil.java (76%) rename java/src/{game => common}/block/BlockTorch.java (93%) rename java/src/{game => common}/block/BlockTrapDoor.java (92%) rename java/src/{game => common}/block/BlockTreasure.java (75%) rename java/src/{game => common}/block/BlockTripWire.java (97%) rename java/src/{game => common}/block/BlockTripWireHook.java (97%) rename java/src/{game => common}/block/BlockVine.java (96%) rename java/src/{game => common}/block/BlockWall.java (95%) rename java/src/{game => common}/block/BlockWallSign.java (90%) rename java/src/{game => common}/block/BlockWarpChest.java (86%) rename java/src/{game => common}/block/BlockWart.java (86%) rename java/src/{game => common}/block/BlockWeb.java (74%) rename java/src/{game => common}/block/BlockWorkbench.java (79%) rename java/src/{game => common}/block/IGrowable.java (62%) rename java/src/{game => common}/block/ITileEntityProvider.java (71%) rename java/src/{game => common}/block/LeavesType.java (91%) rename java/src/{game => common}/block/SoundType.java (91%) rename java/src/{game => common}/clipboard/BlockTransform.java (99%) rename java/src/{game => common}/clipboard/ClipboardBlock.java (82%) rename java/src/{game => common}/clipboard/ClipboardPlacer.java (93%) rename java/src/{game => common}/clipboard/Rotation.java (97%) rename java/src/{game => common}/clipboard/RotationValue.java (95%) rename java/src/{game => common}/clipboard/Vector.java (99%) rename java/src/{game => common}/collect/AbstractBiMap.java (98%) rename java/src/{game => common}/collect/AbstractIndexedListIterator.java (97%) rename java/src/{game => common}/collect/AbstractIterator.java (98%) rename java/src/{game => common}/collect/AbstractMapEntry.java (98%) rename java/src/{game => common}/collect/AbstractTable.java (99%) rename java/src/{game => common}/collect/BiMap.java (99%) rename java/src/{game => common}/collect/CollectPreconditions.java (94%) rename java/src/{game => common}/collect/DenseImmutableTable.java (98%) rename java/src/{game => common}/collect/EmptyImmutableMap.java (99%) rename java/src/{game => common}/collect/EmptyImmutableSet.java (98%) rename java/src/{game => common}/collect/Filter.java (98%) rename java/src/{game => common}/collect/ForwardingCollection.java (99%) rename java/src/{game => common}/collect/ForwardingMap.java (99%) rename java/src/{game => common}/collect/ForwardingMapEntry.java (99%) rename java/src/{game => common}/collect/ForwardingObject.java (99%) rename java/src/{game => common}/collect/ForwardingSet.java (97%) rename java/src/{game => common}/collect/HashBiMap.java (98%) rename java/src/{game => common}/collect/Hashing.java (98%) rename java/src/{game => common}/collect/ImmutableAsList.java (98%) rename java/src/{game => common}/collect/ImmutableCollection.java (97%) rename java/src/{game => common}/collect/ImmutableEntry.java (98%) rename java/src/{game => common}/collect/ImmutableEnumMap.java (97%) rename java/src/{game => common}/collect/ImmutableEnumSet.java (99%) rename java/src/{game => common}/collect/ImmutableList.java (98%) rename java/src/{game => common}/collect/ImmutableMap.java (99%) rename java/src/{game => common}/collect/ImmutableMapEntry.java (95%) rename java/src/{game => common}/collect/ImmutableMapEntrySet.java (98%) rename java/src/{game => common}/collect/ImmutableMapKeySet.java (98%) rename java/src/{game => common}/collect/ImmutableMapValues.java (98%) rename java/src/{game => common}/collect/ImmutableSet.java (99%) rename java/src/{game => common}/collect/ImmutableTable.java (99%) rename java/src/{game => common}/collect/Iterables.java (99%) rename java/src/{game => common}/collect/Iterators.java (99%) rename java/src/{game => common}/collect/Lists.java (98%) rename java/src/{game => common}/collect/Maps.java (99%) rename java/src/{game => common}/collect/ObjectArrays.java (99%) rename java/src/{game => common}/collect/Preconditions.java (99%) rename java/src/{game => common}/collect/RegularImmutableAsList.java (98%) rename java/src/{game => common}/collect/RegularImmutableList.java (99%) rename java/src/{game => common}/collect/RegularImmutableMap.java (97%) rename java/src/{game => common}/collect/RegularImmutableSet.java (98%) rename java/src/{game => common}/collect/RegularImmutableTable.java (98%) rename java/src/{game => common}/collect/Sets.java (99%) rename java/src/{game => common}/collect/SparseImmutableTable.java (99%) rename java/src/{game => common}/collect/StandardTable.java (98%) rename java/src/{game => common}/collect/Table.java (99%) rename java/src/{game => common}/collect/TransformedIterator.java (94%) rename java/src/{game => common}/collect/UnmodifiableIterator.java (98%) rename java/src/{game => common}/collect/UnmodifiableListIterator.java (98%) rename java/src/{game => common}/color/Colorizer.java (95%) rename java/src/{game => common}/color/DyeColor.java (98%) rename java/src/{game => common}/color/TextColor.java (97%) rename java/src/{game => common}/dimension/Area.java (93%) rename java/src/{game => common}/dimension/DimType.java (96%) rename java/src/{game => common}/dimension/Dimension.java (97%) rename java/src/{game => common}/dimension/Domain.java (90%) rename java/src/{game => common}/dimension/Galaxy.java (90%) rename java/src/{game => common}/dimension/Moon.java (95%) rename java/src/{game => common}/dimension/Nameable.java (95%) rename java/src/{game => common}/dimension/Planet.java (96%) rename java/src/{game => common}/dimension/Sector.java (90%) rename java/src/{game => common}/dimension/Semi.java (95%) rename java/src/{game => common}/dimension/Space.java (98%) rename java/src/{game => common}/dimension/Star.java (96%) rename java/src/{game => common}/dispenser/BehaviorDefaultDispenseItem.java (93%) rename java/src/{game => common}/dispenser/BehaviorProjectileDispense.java (86%) rename java/src/{game => common}/dispenser/IBehaviorDispenseItem.java (87%) rename java/src/{game => common}/dispenser/IBlockSource.java (71%) rename java/src/{game => common}/dispenser/ILocatableSource.java (68%) rename java/src/{game => common}/dispenser/ILocation.java (57%) rename java/src/{game => common}/dispenser/IPosition.java (77%) rename java/src/{game => common}/dispenser/PositionImpl.java (94%) rename java/src/{game => common}/enchantment/Enchantment.java (97%) rename java/src/{game => common}/enchantment/EnchantmentArrowDamage.java (96%) rename java/src/{game => common}/enchantment/EnchantmentArrowFire.java (96%) rename java/src/{game => common}/enchantment/EnchantmentArrowInfinite.java (96%) rename java/src/{game => common}/enchantment/EnchantmentArrowKnockback.java (96%) rename java/src/{game => common}/enchantment/EnchantmentDamage.java (96%) rename java/src/{game => common}/enchantment/EnchantmentDigging.java (92%) rename java/src/{game => common}/enchantment/EnchantmentDraining.java (85%) rename java/src/{game => common}/enchantment/EnchantmentDurability.java (93%) rename java/src/{game => common}/enchantment/EnchantmentFireAspect.java (96%) rename java/src/{game => common}/enchantment/EnchantmentFishingSpeed.java (96%) rename java/src/{game => common}/enchantment/EnchantmentHelper.java (97%) rename java/src/{game => common}/enchantment/EnchantmentKnockback.java (96%) rename java/src/{game => common}/enchantment/EnchantmentLootBonus.java (98%) rename java/src/{game => common}/enchantment/EnchantmentProtection.java (97%) rename java/src/{game => common}/enchantment/EnchantmentThorns.java (90%) rename java/src/{game => common}/enchantment/EnchantmentUntouching.java (93%) rename java/src/{game => common}/enchantment/EnumEnchantmentType.java (86%) rename java/src/{game => common}/enchantment/RngEnchantment.java (89%) rename java/src/{game => common}/entity/DamageSource.java (98%) rename java/src/{game => common}/entity/DataWatcher.java (98%) rename java/src/{game => common}/entity/Entity.java (98%) rename java/src/{game => common}/entity/EntityDamageSource.java (94%) rename java/src/{game => common}/entity/EntityDamageSourceIndirect.java (92%) rename java/src/{game => common}/entity/EntityTrackerEntry.java (93%) rename java/src/{game => common}/entity/EntityType.java (93%) rename java/src/{game => common}/entity/animal/EntityBat.java (95%) rename java/src/{game => common}/entity/animal/EntityChicken.java (90%) rename java/src/{game => common}/entity/animal/EntityCow.java (85%) rename java/src/{game => common}/entity/animal/EntityDragon.java (97%) rename java/src/{game => common}/entity/animal/EntityDragonPart.java (89%) rename java/src/{game => common}/entity/animal/EntityHorse.java (97%) rename java/src/{game => common}/entity/animal/EntityMooshroom.java (88%) rename java/src/{game => common}/entity/animal/EntityMouse.java (80%) rename java/src/{game => common}/entity/animal/EntityOcelot.java (92%) rename java/src/{game => common}/entity/animal/EntityPig.java (90%) rename java/src/{game => common}/entity/animal/EntityRabbit.java (92%) rename java/src/{game => common}/entity/animal/EntitySheep.java (91%) rename java/src/{game => common}/entity/animal/EntitySquid.java (96%) rename java/src/{game => common}/entity/animal/EntityWolf.java (94%) rename java/src/{game => common}/entity/attributes/Attribute.java (95%) rename java/src/{game => common}/entity/attributes/AttributeInstance.java (97%) rename java/src/{game => common}/entity/attributes/AttributeMap.java (98%) rename java/src/{game => common}/entity/attributes/AttributeModifier.java (98%) rename java/src/{game => common}/entity/attributes/Attributes.java (98%) rename java/src/{game => common}/entity/attributes/LowerStringMap.java (96%) rename java/src/{game => common}/entity/effect/EntityLightning.java (87%) rename java/src/{game => common}/entity/item/EntityBoat.java (97%) rename java/src/{game => common}/entity/item/EntityCart.java (98%) rename java/src/{game => common}/entity/item/EntityCartContainer.java (93%) rename java/src/{game => common}/entity/item/EntityChestCart.java (74%) rename java/src/{game => common}/entity/item/EntityCrystal.java (94%) rename java/src/{game => common}/entity/item/EntityExplosion.java (91%) rename java/src/{game => common}/entity/item/EntityFalling.java (93%) rename java/src/{game => common}/entity/item/EntityFireworks.java (95%) rename java/src/{game => common}/entity/item/EntityHopperCart.java (91%) rename java/src/{game => common}/entity/item/EntityItem.java (96%) rename java/src/{game => common}/entity/item/EntityLeashKnot.java (96%) rename java/src/{game => common}/entity/item/EntityMinecart.java (93%) rename java/src/{game => common}/entity/item/EntityNuke.java (94%) rename java/src/{game => common}/entity/item/EntityOrb.java (93%) rename java/src/{game => common}/entity/item/EntityTnt.java (93%) rename java/src/{game => common}/entity/item/EntityTntCart.java (92%) rename java/src/{game => common}/entity/item/EntityXp.java (95%) rename java/src/{game => common}/entity/item/EntityXpBottle.java (86%) rename java/src/{game => common}/entity/npc/Alignment.java (95%) rename java/src/{game => common}/entity/npc/CharacterInfo.java (86%) rename java/src/{game => common}/entity/npc/ClassInfo.java (80%) rename java/src/{game => common}/entity/npc/Energy.java (96%) rename java/src/{game => common}/entity/npc/EntityArachnoid.java (94%) rename java/src/{game => common}/entity/npc/EntityBloodElf.java (91%) rename java/src/{game => common}/entity/npc/EntityChaosMarine.java (91%) rename java/src/{game => common}/entity/npc/EntityCpu.java (89%) rename java/src/{game => common}/entity/npc/EntityCultivator.java (91%) rename java/src/{game => common}/entity/npc/EntityDarkMage.java (90%) rename java/src/{game => common}/entity/npc/EntityDwarf.java (92%) rename java/src/{game => common}/entity/npc/EntityElf.java (89%) rename java/src/{game => common}/entity/npc/EntityFireDemon.java (89%) rename java/src/{game => common}/entity/npc/EntityFlyingNPC.java (95%) rename java/src/{game => common}/entity/npc/EntityGargoyle.java (95%) rename java/src/{game => common}/entity/npc/EntityGoblin.java (87%) rename java/src/{game => common}/entity/npc/EntityHaunter.java (95%) rename java/src/{game => common}/entity/npc/EntityHoveringNPC.java (97%) rename java/src/{game => common}/entity/npc/EntityHuman.java (91%) rename java/src/{game => common}/entity/npc/EntityMage.java (92%) rename java/src/{game => common}/entity/npc/EntityMagma.java (97%) rename java/src/{game => common}/entity/npc/EntityMetalhead.java (89%) rename java/src/{game => common}/entity/npc/EntityMobNPC.java (96%) rename java/src/{game => common}/entity/npc/EntityNPC.java (97%) rename java/src/{game => common}/entity/npc/EntityOrc.java (92%) rename java/src/{game => common}/entity/npc/EntityPrimarch.java (96%) rename java/src/{game => common}/entity/npc/EntitySlime.java (97%) rename java/src/{game => common}/entity/npc/EntitySpaceMarine.java (91%) rename java/src/{game => common}/entity/npc/EntitySpirit.java (92%) rename java/src/{game => common}/entity/npc/EntityTiefling.java (92%) rename java/src/{game => common}/entity/npc/EntityUndead.java (87%) rename java/src/{game => common}/entity/npc/EntityVampire.java (90%) rename java/src/{game => common}/entity/npc/EntityWoodElf.java (88%) rename java/src/{game => common}/entity/npc/EntityZombie.java (96%) rename java/src/{game => common}/entity/npc/NpcInfo.java (89%) rename java/src/{game => common}/entity/npc/PlayerCharacter.java (89%) rename java/src/{game => common}/entity/npc/SpeciesInfo.java (92%) rename java/src/{game => common}/entity/projectile/EntityArrow.java (96%) rename java/src/{game => common}/entity/projectile/EntityBox.java (94%) rename java/src/{game => common}/entity/projectile/EntityBullet.java (96%) rename java/src/{game => common}/entity/projectile/EntityDie.java (89%) rename java/src/{game => common}/entity/projectile/EntityDynamite.java (82%) rename java/src/{game => common}/entity/projectile/EntityEgg.java (82%) rename java/src/{game => common}/entity/projectile/EntityFireCharge.java (91%) rename java/src/{game => common}/entity/projectile/EntityFireball.java (89%) rename java/src/{game => common}/entity/projectile/EntityHook.java (96%) rename java/src/{game => common}/entity/projectile/EntityPotion.java (92%) rename java/src/{game => common}/entity/projectile/EntityProjectile.java (96%) rename java/src/{game => common}/entity/projectile/EntitySnowball.java (80%) rename java/src/{game => common}/entity/projectile/RngFishable.java (88%) rename java/src/{game => common}/entity/types/CombatEntry.java (91%) rename java/src/{game => common}/entity/types/EntityAnimal.java (94%) rename java/src/{game => common}/entity/types/EntityBodyHelper.java (97%) rename java/src/{game => common}/entity/types/EntityLiving.java (97%) rename java/src/{game => common}/entity/types/EntityTameable.java (97%) rename java/src/{game => common}/entity/types/EntityThrowable.java (96%) rename java/src/{game => common}/entity/types/EntityWaterMob.java (92%) rename java/src/{game => common}/entity/types/EntityWeatherEffect.java (81%) rename java/src/{game => common}/entity/types/IEntityFX.java (84%) rename java/src/{game => common}/entity/types/IEntityMultiPart.java (54%) rename java/src/{game => common}/entity/types/IEntityOwnable.java (60%) rename java/src/{game => common}/entity/types/IObjectData.java (65%) rename java/src/{game => common}/entity/types/IProjectile.java (81%) rename java/src/{game => common}/future/AbstractFuture.java (99%) rename java/src/{game => common}/future/ExecutionError.java (98%) rename java/src/{game => common}/future/ExecutionList.java (99%) rename java/src/{game => common}/future/FutureCallback.java (98%) rename java/src/{game => common}/future/Futures.java (99%) rename java/src/{game => common}/future/ListenableFuture.java (99%) rename java/src/{game => common}/future/ListenableFutureTask.java (99%) rename java/src/{game => common}/future/MoreExecutors.java (99%) rename java/src/{game => common}/future/ThreadFactoryBuilder.java (99%) rename java/src/{game => common}/future/UncheckedExecutionException.java (98%) rename java/src/{game => common}/init/BlockRegistry.java (97%) rename java/src/{game => common}/init/Blocks.java (94%) rename java/src/{game => common}/init/Config.java (99%) rename java/src/{game => common}/init/CraftingRegistry.java (99%) rename java/src/{game => common}/init/DecoType.java (95%) rename java/src/{game => common}/init/DispenserRegistry.java (91%) rename java/src/{game => common}/init/EntityEggInfo.java (94%) rename java/src/{game => common}/init/EntityRegistry.java (84%) rename java/src/{game => common}/init/FlammabilityRegistry.java (96%) rename java/src/{game => common}/init/FluidRegistry.java (89%) rename java/src/{game => common}/init/IObjectIntIterable.java (75%) rename java/src/{game => common}/init/IRegistry.java (89%) rename java/src/{game => common}/init/ItemRegistry.java (88%) rename java/src/{game => common}/init/Items.java (98%) rename java/src/{game => common}/init/MetalType.java (98%) rename java/src/{game => common}/init/NameRegistry.java (99%) rename java/src/{game => common}/init/ObjectIntIdentityMap.java (89%) rename java/src/{game => common}/init/OreType.java (98%) rename java/src/{game => common}/init/Registry.java (98%) rename java/src/{game => common}/init/RegistryDefaulted.java (95%) rename java/src/{game => common}/init/RegistryNamespaced.java (96%) rename java/src/{game => common}/init/RegistryNamespacedDefaultedByKey.java (98%) rename java/src/{game => common}/init/RegistrySimple.java (96%) rename java/src/{game => common}/init/ReorderRegistry.java (97%) rename java/src/{game => common}/init/RotationRegistry.java (81%) rename java/src/{game => common}/init/SmeltingRegistry.java (95%) rename java/src/{game => common}/init/SoundEvent.java (99%) rename java/src/{game => common}/init/SpeciesRegistry.java (85%) rename java/src/{game => common}/init/TileRegistry.java (69%) rename java/src/{game => common}/init/ToolMaterial.java (98%) rename java/src/{game => common}/init/ToolType.java (97%) rename java/src/{game => common}/init/TradeRegistry.java (96%) rename java/src/{game => common}/init/UniverseRegistry.java (97%) rename java/src/{game => common}/init/WoodType.java (96%) rename java/src/{game => common}/inventory/AnimalChest.java (92%) rename java/src/{game => common}/inventory/Container.java (99%) rename java/src/{game => common}/inventory/ContainerBrewingStand.java (98%) rename java/src/{game => common}/inventory/ContainerChest.java (96%) rename java/src/{game => common}/inventory/ContainerDispenser.java (95%) rename java/src/{game => common}/inventory/ContainerEnchantment.java (97%) rename java/src/{game => common}/inventory/ContainerFurnace.java (96%) rename java/src/{game => common}/inventory/ContainerHopper.java (96%) rename java/src/{game => common}/inventory/ContainerHorseInventory.java (96%) rename java/src/{game => common}/inventory/ContainerLocalMenu.java (87%) rename java/src/{game => common}/inventory/ContainerMachine.java (95%) rename java/src/{game => common}/inventory/ContainerMerchant.java (97%) rename java/src/{game => common}/inventory/ContainerPlayer.java (96%) rename java/src/{game => common}/inventory/ContainerRepair.java (97%) rename java/src/{game => common}/inventory/ContainerWorkbench.java (95%) rename java/src/{game => common}/inventory/ICrafting.java (87%) rename java/src/{game => common}/inventory/IInvBasic.java (87%) rename java/src/{game => common}/inventory/IInventory.java (92%) rename java/src/{game => common}/inventory/ISidedInventory.java (86%) rename java/src/{game => common}/inventory/InventoryBasic.java (98%) rename java/src/{game => common}/inventory/InventoryCraftResult.java (97%) rename java/src/{game => common}/inventory/InventoryCrafting.java (98%) rename java/src/{game => common}/inventory/InventoryHelper.java (89%) rename java/src/{game => common}/inventory/InventoryLargeChest.java (96%) rename java/src/{game => common}/inventory/InventoryMerchant.java (97%) rename java/src/{game => common}/inventory/InventoryPlayer.java (98%) rename java/src/{game => common}/inventory/InventoryWarpChest.java (91%) rename java/src/{game => common}/inventory/Slot.java (97%) rename java/src/{game => common}/inventory/SlotCrafting.java (97%) rename java/src/{game => common}/inventory/SlotFurnaceFuel.java (85%) rename java/src/{game => common}/inventory/SlotFurnaceOutput.java (93%) rename java/src/{game => common}/inventory/SlotMerchantResult.java (96%) rename java/src/{game => common}/item/CheatTab.java (96%) rename java/src/{game => common}/item/Item.java (96%) rename java/src/{game => common}/item/ItemAction.java (74%) rename java/src/{game => common}/item/ItemAmmo.java (95%) rename java/src/{game => common}/item/ItemAnvilBlock.java (92%) rename java/src/{game => common}/item/ItemAppleGold.java (89%) rename java/src/{game => common}/item/ItemArmor.java (93%) rename java/src/{game => common}/item/ItemAxe.java (88%) rename java/src/{game => common}/item/ItemBanHammer.java (78%) rename java/src/{game => common}/item/ItemBanner.java (92%) rename java/src/{game => common}/item/ItemBed.java (90%) rename java/src/{game => common}/item/ItemBlock.java (93%) rename java/src/{game => common}/item/ItemBoat.java (92%) rename java/src/{game => common}/item/ItemBoltgun.java (80%) rename java/src/{game => common}/item/ItemBook.java (94%) rename java/src/{game => common}/item/ItemBow.java (91%) rename java/src/{game => common}/item/ItemBucket.java (94%) rename java/src/{game => common}/item/ItemBucketMilk.java (87%) rename java/src/{game => common}/item/ItemButton.java (81%) rename java/src/{game => common}/item/ItemCamera.java (85%) rename java/src/{game => common}/item/ItemCarrotOnAStick.java (90%) rename java/src/{game => common}/item/ItemChargedOrb.java (93%) rename java/src/{game => common}/item/ItemChest.java (70%) rename java/src/{game => common}/item/ItemCloth.java (90%) rename java/src/{game => common}/item/ItemCoal.java (92%) rename java/src/{game => common}/item/ItemColored.java (97%) rename java/src/{game => common}/item/ItemControl.java (77%) rename java/src/{game => common}/item/ItemDie.java (85%) rename java/src/{game => common}/item/ItemDispenser.java (78%) rename java/src/{game => common}/item/ItemDoor.java (91%) rename java/src/{game => common}/item/ItemDoublePlant.java (81%) rename java/src/{game => common}/item/ItemDye.java (91%) rename java/src/{game => common}/item/ItemDynamite.java (87%) rename java/src/{game => common}/item/ItemEditWand.java (88%) rename java/src/{game => common}/item/ItemEffect.java (85%) rename java/src/{game => common}/item/ItemEgg.java (83%) rename java/src/{game => common}/item/ItemEnchantedBook.java (94%) rename java/src/{game => common}/item/ItemExpBottle.java (84%) rename java/src/{game => common}/item/ItemExterminator.java (84%) rename java/src/{game => common}/item/ItemFence.java (90%) rename java/src/{game => common}/item/ItemFireball.java (83%) rename java/src/{game => common}/item/ItemFirework.java (89%) rename java/src/{game => common}/item/ItemFireworkCharge.java (95%) rename java/src/{game => common}/item/ItemFishFood.java (94%) rename java/src/{game => common}/item/ItemFishingRod.java (90%) rename java/src/{game => common}/item/ItemFlintAndSteel.java (81%) rename java/src/{game => common}/item/ItemFood.java (94%) rename java/src/{game => common}/item/ItemFragile.java (82%) rename java/src/{game => common}/item/ItemGlassBottle.java (88%) rename java/src/{game => common}/item/ItemGunBase.java (88%) rename java/src/{game => common}/item/ItemHoe.java (89%) rename java/src/{game => common}/item/ItemHorseArmor.java (87%) rename java/src/{game => common}/item/ItemHugeMushroom.java (79%) rename java/src/{game => common}/item/ItemInfoWand.java (76%) rename java/src/{game => common}/item/ItemKey.java (69%) rename java/src/{game => common}/item/ItemLead.java (84%) rename java/src/{game => common}/item/ItemLeaves.java (93%) rename java/src/{game => common}/item/ItemLightning.java (77%) rename java/src/{game => common}/item/ItemLilyPad.java (86%) rename java/src/{game => common}/item/ItemMagnet.java (88%) rename java/src/{game => common}/item/ItemMagnetic.java (82%) rename java/src/{game => common}/item/ItemMetal.java (82%) rename java/src/{game => common}/item/ItemMetalBlock.java (83%) rename java/src/{game => common}/item/ItemMinecart.java (91%) rename java/src/{game => common}/item/ItemMonsterPlacer.java (92%) rename java/src/{game => common}/item/ItemMultiTexture.java (97%) rename java/src/{game => common}/item/ItemNameTag.java (89%) rename java/src/{game => common}/item/ItemNpcSpawner.java (90%) rename java/src/{game => common}/item/ItemNugget.java (69%) rename java/src/{game => common}/item/ItemPickaxe.java (96%) rename java/src/{game => common}/item/ItemPiston.java (84%) rename java/src/{game => common}/item/ItemPotion.java (96%) rename java/src/{game => common}/item/ItemPressurePlate.java (78%) rename java/src/{game => common}/item/ItemRecord.java (75%) rename java/src/{game => common}/item/ItemRedstone.java (85%) rename java/src/{game => common}/item/ItemReed.java (88%) rename java/src/{game => common}/item/ItemRod.java (68%) rename java/src/{game => common}/item/ItemSaddle.java (89%) rename java/src/{game => common}/item/ItemSeedFood.java (87%) rename java/src/{game => common}/item/ItemSeeds.java (85%) rename java/src/{game => common}/item/ItemShears.java (88%) rename java/src/{game => common}/item/ItemSign.java (85%) rename java/src/{game => common}/item/ItemSkull.java (91%) rename java/src/{game => common}/item/ItemSlab.java (96%) rename java/src/{game => common}/item/ItemSmall.java (68%) rename java/src/{game => common}/item/ItemSnow.java (89%) rename java/src/{game => common}/item/ItemSnowball.java (82%) rename java/src/{game => common}/item/ItemSoup.java (81%) rename java/src/{game => common}/item/ItemSpaceNavigator.java (91%) rename java/src/{game => common}/item/ItemSpade.java (86%) rename java/src/{game => common}/item/ItemStack.java (98%) rename java/src/{game => common}/item/ItemStick.java (68%) rename java/src/{game => common}/item/ItemSword.java (90%) rename java/src/{game => common}/item/ItemTNT.java (88%) rename java/src/{game => common}/item/ItemTiny.java (68%) rename java/src/{game => common}/item/ItemTool.java (89%) rename java/src/{game => common}/item/ItemWall.java (86%) rename java/src/{game => common}/item/ItemWand.java (89%) rename java/src/{game => common}/item/ItemWeatherToken.java (83%) rename java/src/{game => common}/item/RngLoot.java (94%) rename java/src/{game => common}/log/Log.java (97%) rename java/src/{game => common}/log/LogLevel.java (87%) rename java/src/{game => common}/log/Message.java (89%) rename java/src/{game => common}/log/NettyLogger.java (99%) rename java/src/{game => common}/material/Material.java (99%) rename java/src/{game => common}/material/MaterialColdFluid.java (93%) rename java/src/{game => common}/material/MaterialHotFluid.java (93%) rename java/src/{game => common}/material/MaterialLogic.java (95%) rename java/src/{game => common}/material/MaterialPortal.java (95%) rename java/src/{game => common}/material/MaterialTransparent.java (96%) rename java/src/{game => common}/model/BlockLayer.java (93%) rename java/src/{game => common}/model/ItemMeshDefinition.java (62%) rename java/src/{game => common}/model/Model.java (99%) rename java/src/{game => common}/model/ModelProvider.java (95%) rename java/src/{game => common}/model/ModelRotation.java (95%) rename java/src/{game => common}/model/ParticleType.java (97%) rename java/src/{game => common}/model/Transform.java (95%) rename java/src/{game => common}/model/Transforms.java (99%) rename java/src/{game => common}/nbt/NBTBase.java (99%) rename java/src/{game => common}/nbt/NBTException.java (86%) rename java/src/{game => common}/nbt/NBTLoader.java (99%) rename java/src/{game => common}/nbt/NBTParser.java (99%) rename java/src/{game => common}/nbt/NBTSizeTracker.java (97%) rename java/src/{game => common}/nbt/NBTTagByte.java (98%) rename java/src/{game => common}/nbt/NBTTagByteArray.java (98%) rename java/src/{game => common}/nbt/NBTTagCompound.java (99%) rename java/src/{game => common}/nbt/NBTTagDouble.java (97%) rename java/src/{game => common}/nbt/NBTTagEnd.java (97%) rename java/src/{game => common}/nbt/NBTTagFloat.java (97%) rename java/src/{game => common}/nbt/NBTTagInt.java (98%) rename java/src/{game => common}/nbt/NBTTagIntArray.java (98%) rename java/src/{game => common}/nbt/NBTTagList.java (99%) rename java/src/{game => common}/nbt/NBTTagLong.java (98%) rename java/src/{game => common}/nbt/NBTTagShort.java (98%) rename java/src/{game => common}/nbt/NBTTagString.java (98%) rename java/src/{game => common}/nbt/NBTUtil.java (99%) rename java/src/{game => common}/network/IClientLoginHandler.java (58%) rename java/src/{game => common}/network/IClientPlayer.java (76%) rename java/src/{game => common}/network/IHandshakeHandler.java (58%) rename java/src/{game => common}/network/ILoginHandler.java (58%) rename java/src/{game => common}/network/IPlayer.java (77%) rename java/src/{game => common}/network/IThreadListener.java (73%) rename java/src/{game => common}/network/NetConnection.java (98%) rename java/src/{game => common}/network/NetHandler.java (97%) rename java/src/{game => common}/network/NettyCompressionDecoder.java (98%) rename java/src/{game => common}/network/NettyCompressionEncoder.java (98%) rename java/src/{game => common}/network/Packet.java (90%) rename java/src/{game => common}/network/PacketBuffer.java (98%) rename java/src/{game => common}/network/PacketDecoder.java (98%) rename java/src/{game => common}/network/PacketEncoder.java (96%) rename java/src/{game => common}/network/PacketPrepender.java (97%) rename java/src/{game => common}/network/PacketRegistry.java (69%) rename java/src/{game => common}/network/PacketSplitter.java (98%) rename java/src/{game => common}/packet/APacketEmpty.java (73%) rename java/src/{game => common}/packet/APacketVarInt.java (84%) rename java/src/{game => common}/packet/CPacketAction.java (94%) rename java/src/{game => common}/packet/CPacketBook.java (89%) rename java/src/{game => common}/packet/CPacketBreak.java (89%) rename java/src/{game => common}/packet/CPacketCheat.java (86%) rename java/src/{game => common}/packet/CPacketClick.java (93%) rename java/src/{game => common}/packet/CPacketComplete.java (89%) rename java/src/{game => common}/packet/CPacketInput.java (92%) rename java/src/{game => common}/packet/CPacketKeepAlive.java (83%) rename java/src/{game => common}/packet/CPacketMessage.java (91%) rename java/src/{game => common}/packet/CPacketPlace.java (92%) rename java/src/{game => common}/packet/CPacketPlayer.java (97%) rename java/src/{game => common}/packet/CPacketSign.java (90%) rename java/src/{game => common}/packet/CPacketSkin.java (90%) rename java/src/{game => common}/packet/HPacketHandshake.java (85%) rename java/src/{game => common}/packet/LPacketPasswordResponse.java (90%) rename java/src/{game => common}/packet/RPacketDisconnect.java (87%) rename java/src/{game => common}/packet/RPacketEnableCompression.java (83%) rename java/src/{game => common}/packet/RPacketLoginSuccess.java (74%) rename java/src/{game => common}/packet/S14PacketEntity.java (96%) rename java/src/{game => common}/packet/S18PacketEntityTeleport.java (93%) rename java/src/{game => common}/packet/S19PacketEntityHeadLook.java (86%) rename java/src/{game => common}/packet/S1APacketEntityStatus.java (86%) rename java/src/{game => common}/packet/S1BPacketEntityAttach.java (90%) rename java/src/{game => common}/packet/S1CPacketEntityMetadata.java (90%) rename java/src/{game => common}/packet/S1DPacketEntityEffect.java (92%) rename java/src/{game => common}/packet/S1EPacketRemoveEntityEffect.java (86%) rename java/src/{game => common}/packet/S20PacketEntityProperties.java (93%) rename java/src/{game => common}/packet/S27PacketExplosion.java (94%) rename java/src/{game => common}/packet/S28PacketEffect.java (86%) rename java/src/{game => common}/packet/S29PacketSoundEffect.java (92%) rename java/src/{game => common}/packet/S2APacketParticles.java (96%) rename java/src/{game => common}/packet/S2BPacketChangeGameState.java (90%) rename java/src/{game => common}/packet/S2CPacketSpawnGlobalEntity.java (91%) rename java/src/{game => common}/packet/S2DPacketOpenWindow.java (95%) rename java/src/{game => common}/packet/S2EPacketCloseWindow.java (87%) rename java/src/{game => common}/packet/S2FPacketSetSlot.java (89%) rename java/src/{game => common}/packet/S30PacketWindowItems.java (91%) rename java/src/{game => common}/packet/S31PacketWindowProperty.java (91%) rename java/src/{game => common}/packet/S32PacketConfirmTransaction.java (92%) rename java/src/{game => common}/packet/S33PacketUpdateSign.java (91%) rename java/src/{game => common}/packet/S35PacketUpdateTileEntity.java (85%) rename java/src/{game => common}/packet/S36PacketSignEditorOpen.java (86%) rename java/src/{game => common}/packet/S38PacketPlayerListItem.java (87%) rename java/src/{game => common}/packet/S39PacketPlayerAbilities.java (84%) rename java/src/{game => common}/packet/S3APacketTabComplete.java (90%) rename java/src/{game => common}/packet/S43PacketUpdateEntityNBT.java (85%) rename java/src/{game => common}/packet/SPacketAnimation.java (89%) rename java/src/{game => common}/packet/SPacketBiomes.java (87%) rename java/src/{game => common}/packet/SPacketBlockAction.java (89%) rename java/src/{game => common}/packet/SPacketBlockBreakAnim.java (90%) rename java/src/{game => common}/packet/SPacketBlockChange.java (84%) rename java/src/{game => common}/packet/SPacketCamera.java (80%) rename java/src/{game => common}/packet/SPacketCharacterList.java (89%) rename java/src/{game => common}/packet/SPacketChunkData.java (95%) rename java/src/{game => common}/packet/SPacketCollectItem.java (91%) rename java/src/{game => common}/packet/SPacketDestroyEntities.java (90%) rename java/src/{game => common}/packet/SPacketDimensionName.java (86%) rename java/src/{game => common}/packet/SPacketDisconnect.java (77%) rename java/src/{game => common}/packet/SPacketEntityEquipment.java (90%) rename java/src/{game => common}/packet/SPacketEntityVelocity.java (93%) rename java/src/{game => common}/packet/SPacketHeldItemChange.java (88%) rename java/src/{game => common}/packet/SPacketJoinGame.java (86%) rename java/src/{game => common}/packet/SPacketKeepAlive.java (83%) rename java/src/{game => common}/packet/SPacketLoading.java (92%) rename java/src/{game => common}/packet/SPacketMapChunkBulk.java (95%) rename java/src/{game => common}/packet/SPacketMessage.java (86%) rename java/src/{game => common}/packet/SPacketMultiBlockChange.java (91%) rename java/src/{game => common}/packet/SPacketPlayerPosLook.java (96%) rename java/src/{game => common}/packet/SPacketRespawn.java (86%) rename java/src/{game => common}/packet/SPacketServerTick.java (81%) rename java/src/{game => common}/packet/SPacketSetExperience.java (92%) rename java/src/{game => common}/packet/SPacketSkin.java (86%) rename java/src/{game => common}/packet/SPacketSpawnMob.java (93%) rename java/src/{game => common}/packet/SPacketSpawnObject.java (91%) rename java/src/{game => common}/packet/SPacketSpawnPlayer.java (90%) rename java/src/{game => common}/packet/SPacketTimeUpdate.java (86%) rename java/src/{game => common}/packet/SPacketTrades.java (91%) rename java/src/{game => common}/packet/SPacketUpdateHealth.java (82%) rename java/src/{game => common}/packet/SPacketWorld.java (89%) rename java/src/{game => common}/pathfinding/NodeProcessor.java (93%) rename java/src/{game => common}/pathfinding/Path.java (99%) rename java/src/{game => common}/pathfinding/PathCache.java (76%) rename java/src/{game => common}/pathfinding/PathEntity.java (97%) rename java/src/{game => common}/pathfinding/PathFinder.java (98%) rename java/src/{game => common}/pathfinding/PathNavigate.java (96%) rename java/src/{game => common}/pathfinding/PathNavigateClimber.java (92%) rename java/src/{game => common}/pathfinding/PathNavigateGround.java (96%) rename java/src/{game => common}/pathfinding/PathPoint.java (97%) rename java/src/{game => common}/pathfinding/SwimNodeProcessor.java (94%) rename java/src/{game => common}/pathfinding/WalkNodeProcessor.java (96%) rename java/src/{game => common}/pattern/BlockStateHelper.java (91%) rename java/src/{game => common}/potion/Potion.java (95%) rename java/src/{game => common}/potion/PotionEffect.java (97%) rename java/src/{game => common}/potion/PotionHelper.java (99%) rename java/src/{game => common}/properties/IProperty.java (90%) rename java/src/{game => common}/properties/PropertyBool.java (91%) rename java/src/{game => common}/properties/PropertyDirection.java (87%) rename java/src/{game => common}/properties/PropertyEnum.java (89%) rename java/src/{game => common}/properties/PropertyHelper.java (97%) rename java/src/{game => common}/properties/PropertyInteger.java (95%) rename java/src/{game => common}/rng/ImprovedGen.java (99%) rename java/src/{game => common}/rng/ImprovedGenOld.java (96%) rename java/src/{game => common}/rng/NoiseGen.java (95%) rename java/src/{game => common}/rng/OctaveGen.java (98%) rename java/src/{game => common}/rng/OctaveGenOld.java (94%) rename java/src/{game => common}/rng/PerlinGen.java (98%) rename java/src/{game => common}/rng/PerlinGenOld.java (94%) rename java/src/{game => common}/rng/Random.java (99%) rename java/src/{game => common}/rng/RngItem.java (84%) rename java/src/{game => common}/rng/SimplexGen.java (99%) rename java/src/{game => common}/rng/SimplexGenOld.java (95%) rename java/src/{game => common}/rng/WeightedList.java (99%) rename java/src/{game => common}/sound/EventType.java (71%) rename java/src/{game => common}/sound/MovingSound.java (84%) rename java/src/{game => common}/sound/MovingSoundMinecart.java (90%) rename java/src/{game => common}/sound/MovingSoundMinecartRiding.java (87%) rename java/src/{game => common}/sound/PositionedSound.java (92%) rename java/src/{game => common}/sound/Sound.java (94%) rename java/src/{game => common}/tileentity/IHopper.java (82%) rename java/src/{game => common}/tileentity/IInteractionObject.java (55%) rename java/src/{game => common}/tileentity/ILockableContainer.java (73%) rename java/src/{game => common}/tileentity/ITickable.java (65%) rename java/src/{game => common}/tileentity/IWorldNameable.java (70%) rename java/src/{game => common}/tileentity/LocalBlockIntercommunication.java (87%) rename java/src/{game => common}/tileentity/LockCode.java (92%) rename java/src/{game => common}/tileentity/MachineResource.java (97%) rename java/src/{game => common}/tileentity/TileEntity.java (94%) rename java/src/{game => common}/tileentity/TileEntityBanner.java (97%) rename java/src/{game => common}/tileentity/TileEntityBeacon.java (97%) rename java/src/{game => common}/tileentity/TileEntityBrewingStand.java (95%) rename java/src/{game => common}/tileentity/TileEntityChest.java (96%) rename java/src/{game => common}/tileentity/TileEntityComparator.java (91%) rename java/src/{game => common}/tileentity/TileEntityDaylightDetector.java (86%) rename java/src/{game => common}/tileentity/TileEntityDispenser.java (94%) rename java/src/{game => common}/tileentity/TileEntityDropper.java (92%) rename java/src/{game => common}/tileentity/TileEntityEnchantmentTable.java (94%) rename java/src/{game => common}/tileentity/TileEntityFurnace.java (94%) rename java/src/{game => common}/tileentity/TileEntityHopper.java (96%) rename java/src/{game => common}/tileentity/TileEntityLockable.java (94%) rename java/src/{game => common}/tileentity/TileEntityMachine.java (94%) rename java/src/{game => common}/tileentity/TileEntityMobSpawner.java (94%) rename java/src/{game => common}/tileentity/TileEntityNote.java (88%) rename java/src/{game => common}/tileentity/TileEntityPiston.java (96%) rename java/src/{game => common}/tileentity/TileEntitySign.java (95%) rename java/src/{game => common}/tileentity/TileEntitySkull.java (91%) rename java/src/{game => common}/tileentity/TileEntityTianReactor.java (88%) rename java/src/{game => common}/util/CharValidator.java (95%) rename java/src/{game => common}/util/DC32.java (99%) rename java/src/{game => common}/util/Displayable.java (75%) rename java/src/{game => common}/util/ExtMath.java (99%) rename java/src/{game => common}/util/FileUtils.java (97%) rename java/src/{game => common}/util/Identifyable.java (73%) rename java/src/{game => common}/util/LazyLoadBase.java (93%) rename java/src/{game => common}/util/Matrix4f.java (99%) rename java/src/{game => common}/util/Predicates.java (99%) rename java/src/{game => common}/util/Tuple.java (88%) rename java/src/{game => common}/util/Util.java (99%) rename java/src/{game => common}/util/Vector.java (99%) rename java/src/{game => common}/util/Vector3f.java (99%) rename java/src/{game => common}/util/Vector4f.java (99%) rename java/src/{game => common}/village/MerchantRecipe.java (94%) rename java/src/{game => common}/village/MerchantRecipeList.java (97%) rename java/src/{game => common}/village/Village.java (96%) rename java/src/{game => common}/village/VillageCollection.java (96%) rename java/src/{game => common}/village/VillageDoorInfo.java (97%) rename java/src/{game => common}/world/BlockArray.java (95%) rename java/src/{game => common}/world/BlockPos.java (99%) rename java/src/{game => common}/world/BoundingBox.java (99%) rename java/src/{game => common}/world/Chunk.java (98%) rename java/src/{game => common}/world/ChunkCache.java (97%) rename java/src/{game => common}/world/ChunkPos.java (96%) rename java/src/{game => common}/world/ClassInheritanceMultiMap.java (97%) rename java/src/{game => common}/world/EmptyChunk.java (91%) rename java/src/{game => common}/world/Explosion.java (96%) rename java/src/{game => common}/world/Facing.java (98%) rename java/src/{game => common}/world/HitPosition.java (93%) rename java/src/{game => common}/world/IBlockAccess.java (75%) rename java/src/{game => common}/world/IWorldAccess.java (70%) rename java/src/{game => common}/world/IntHashMap.java (99%) rename java/src/{game => common}/world/LightType.java (85%) rename java/src/{game => common}/world/LongHashMap.java (99%) rename java/src/{game => common}/world/NextTickListEntry.java (96%) rename java/src/{game => common}/world/NibbleArray.java (97%) rename java/src/{game => common}/world/PortalType.java (86%) rename java/src/{game => common}/world/Position.java (94%) rename java/src/{game => common}/world/Region.java (98%) rename java/src/{game => common}/world/Spawner.java (94%) rename java/src/{game => common}/world/State.java (92%) rename java/src/{game => common}/world/Vec3.java (99%) rename java/src/{game => common}/world/Vec3i.java (98%) rename java/src/{game => common}/world/Weather.java (96%) rename java/src/{game => common}/world/World.java (98%) rename java/src/{game => common}/world/WorldClient.java (97%) rename java/src/{game => common}/world/WorldPos.java (97%) rename java/src/{game => common}/world/WorldServer.java (97%) rename java/src/{game => common}/worldgen/BiomeGenLayered.java (89%) rename java/src/{game => common}/worldgen/BiomeGenPerlin.java (93%) rename java/src/{game => common}/worldgen/BiomeGenSingle.java (94%) rename java/src/{game => common}/worldgen/BiomeGenerator.java (87%) rename java/src/{game => common}/worldgen/BlockReplacer.java (55%) rename java/src/{game => common}/worldgen/ChunkGenerator.java (69%) rename java/src/{game => common}/worldgen/ChunkPrimer.java (82%) rename java/src/{game => common}/worldgen/FeatureDungeons.java (93%) rename java/src/{game => common}/worldgen/FeatureGenerator.java (81%) rename java/src/{game => common}/worldgen/FeatureLakes.java (96%) rename java/src/{game => common}/worldgen/FeatureLiquids.java (94%) rename java/src/{game => common}/worldgen/FeatureOres.java (97%) rename java/src/{game => common}/worldgen/GeneratorCavern.java (97%) rename java/src/{game => common}/worldgen/GeneratorDebug.java (82%) rename java/src/{game => common}/worldgen/GeneratorDestroyed.java (86%) rename java/src/{game => common}/worldgen/GeneratorFlat.java (90%) rename java/src/{game => common}/worldgen/GeneratorIsland.java (97%) rename java/src/{game => common}/worldgen/GeneratorPerlin.java (97%) rename java/src/{game => common}/worldgen/GeneratorSimple.java (95%) rename java/src/{game => common}/worldgen/LootConstants.java (94%) rename java/src/{game => common}/worldgen/ReplacerAltBiome.java (93%) rename java/src/{game => common}/worldgen/ReplacerAltSurface.java (95%) rename java/src/{game => common}/worldgen/ReplacerBiome.java (84%) rename java/src/{game => common}/worldgen/ReplacerTopLayer.java (90%) rename java/src/{game => common}/worldgen/caves/MapGenBase.java (90%) rename java/src/{game => common}/worldgen/caves/MapGenBigCaves.java (97%) rename java/src/{game => common}/worldgen/caves/MapGenCaves.java (97%) rename java/src/{game => common}/worldgen/caves/MapGenRavine.java (97%) rename java/src/{game => common}/worldgen/feature/WorldGenAbandonedChest.java (79%) rename java/src/{game => common}/worldgen/feature/WorldGenAsteroid.java (91%) rename java/src/{game => common}/worldgen/feature/WorldGenBlockBlob.java (90%) rename java/src/{game => common}/worldgen/feature/WorldGenClay.java (87%) rename java/src/{game => common}/worldgen/feature/WorldGenClayExt.java (90%) rename java/src/{game => common}/worldgen/feature/WorldGenDesertWells.java (89%) rename java/src/{game => common}/worldgen/feature/WorldGenFire.java (75%) rename java/src/{game => common}/worldgen/feature/WorldGenGlowStone.java (85%) rename java/src/{game => common}/worldgen/feature/WorldGenHellLava.java (90%) rename java/src/{game => common}/worldgen/feature/WorldGenIcePath.java (88%) rename java/src/{game => common}/worldgen/feature/WorldGenIceSpike.java (93%) rename java/src/{game => common}/worldgen/feature/WorldGenSand.java (88%) rename java/src/{game => common}/worldgen/feature/WorldGenSpikes.java (90%) rename java/src/{game => common}/worldgen/foliage/FeatureDoublePlant.java (81%) rename java/src/{game => common}/worldgen/foliage/WorldGenBigMushroom.java (96%) rename java/src/{game => common}/worldgen/foliage/WorldGenCactus.java (80%) rename java/src/{game => common}/worldgen/foliage/WorldGenDeadBush.java (77%) rename java/src/{game => common}/worldgen/foliage/WorldGenFlowers.java (83%) rename java/src/{game => common}/worldgen/foliage/WorldGenMelon.java (76%) rename java/src/{game => common}/worldgen/foliage/WorldGenMushroom.java (80%) rename java/src/{game => common}/worldgen/foliage/WorldGenPumpkin.java (73%) rename java/src/{game => common}/worldgen/foliage/WorldGenReed.java (84%) rename java/src/{game => common}/worldgen/foliage/WorldGenShrub.java (86%) rename java/src/{game => common}/worldgen/foliage/WorldGenTallGrass.java (77%) rename java/src/{game => common}/worldgen/foliage/WorldGenVines.java (81%) rename java/src/{game => common}/worldgen/foliage/WorldGenWaterlily.java (74%) rename java/src/{game => common}/worldgen/layer/GenLayer.java (98%) rename java/src/{game => common}/worldgen/layer/GenLayerAddAreas.java (99%) rename java/src/{game => common}/worldgen/layer/GenLayerAddExtra.java (96%) rename java/src/{game => common}/worldgen/layer/GenLayerAddSea.java (97%) rename java/src/{game => common}/worldgen/layer/GenLayerAddSnow.java (98%) rename java/src/{game => common}/worldgen/layer/GenLayerBase.java (95%) rename java/src/{game => common}/worldgen/layer/GenLayerBiome.java (97%) rename java/src/{game => common}/worldgen/layer/GenLayerBiomeEdge.java (98%) rename java/src/{game => common}/worldgen/layer/GenLayerEdge.java (99%) rename java/src/{game => common}/worldgen/layer/GenLayerFuzzyZoom.java (94%) rename java/src/{game => common}/worldgen/layer/GenLayerHills.java (98%) rename java/src/{game => common}/worldgen/layer/GenLayerRemoveEmpty.java (98%) rename java/src/{game => common}/worldgen/layer/GenLayerRiver.java (96%) rename java/src/{game => common}/worldgen/layer/GenLayerRiverInit.java (96%) rename java/src/{game => common}/worldgen/layer/GenLayerRiverMix.java (97%) rename java/src/{game => common}/worldgen/layer/GenLayerShore.java (98%) rename java/src/{game => common}/worldgen/layer/GenLayerSmooth.java (98%) rename java/src/{game => common}/worldgen/layer/GenLayerVoronoiZoom.java (99%) rename java/src/{game => common}/worldgen/layer/GenLayerZoom.java (98%) rename java/src/{game => common}/worldgen/layer/IntCache.java (97%) rename java/src/{game => common}/worldgen/structure/MapGenBridge.java (94%) rename java/src/{game => common}/worldgen/structure/MapGenMineshaft.java (96%) rename java/src/{game => common}/worldgen/structure/MapGenScatteredFeature.java (96%) rename java/src/{game => common}/worldgen/structure/MapGenStronghold.java (98%) rename java/src/{game => common}/worldgen/structure/MapGenStructure.java (94%) rename java/src/{game => common}/worldgen/structure/MapGenStructureIO.java (96%) rename java/src/{game => common}/worldgen/structure/MapGenVillage.java (96%) rename java/src/{game => common}/worldgen/structure/StructureBoundingBox.java (98%) rename java/src/{game => common}/worldgen/structure/StructureBridge.java (99%) rename java/src/{game => common}/worldgen/structure/StructureComponent.java (97%) rename java/src/{game => common}/worldgen/structure/StructureMineshaft.java (98%) rename java/src/{game => common}/worldgen/structure/StructureMineshaftStart.java (87%) rename java/src/{game => common}/worldgen/structure/StructureScattered.java (98%) rename java/src/{game => common}/worldgen/structure/StructureStart.java (96%) rename java/src/{game => common}/worldgen/structure/StructureStronghold.java (99%) rename java/src/{game => common}/worldgen/structure/StructureVillage.java (99%) rename java/src/{game => common}/worldgen/tree/WorldGenBaseTree.java (96%) rename java/src/{game => common}/worldgen/tree/WorldGenBigTree.java (97%) rename java/src/{game => common}/worldgen/tree/WorldGenBirch.java (94%) rename java/src/{game => common}/worldgen/tree/WorldGenDarkOak.java (96%) rename java/src/{game => common}/worldgen/tree/WorldGenHugeTree.java (94%) rename java/src/{game => common}/worldgen/tree/WorldGenJungle.java (94%) rename java/src/{game => common}/worldgen/tree/WorldGenPine.java (94%) rename java/src/{game => common}/worldgen/tree/WorldGenSavanna.java (96%) rename java/src/{game => common}/worldgen/tree/WorldGenSwamp.java (95%) rename java/src/{game => common}/worldgen/tree/WorldGenTaiga1.java (94%) rename java/src/{game => common}/worldgen/tree/WorldGenTaiga2.java (94%) rename java/src/{game => common}/worldgen/tree/WorldGenTree.java (73%) diff --git a/client/src/client/Game.java b/client/src/client/Game.java index 48ac915..f36f055 100755 --- a/client/src/client/Game.java +++ b/client/src/client/Game.java @@ -70,6 +70,22 @@ import client.renderer.texture.ColormapLoader; import client.renderer.texture.EntityTexManager; import client.renderer.texture.TextureManager; import client.renderer.texture.TextureMap; +import client.vars.BoolVar; +import client.vars.CVar; +import client.vars.CVarCategory; +import client.vars.ColorVar; +import client.vars.EnumVar; +import client.vars.FloatVar; +import client.vars.IntVar; +import client.vars.StringVar; +import client.vars.Variable; +import client.vars.BaseVar.VarFunction; +import client.vars.BoolVar.BoolFunction; +import client.vars.EnumVar.EnumFunction; +import client.vars.FloatVar.FloatFunction; +import client.vars.IntVar.IntFunction; +import client.vars.StringVar.StringFunction; +import client.vars.Variable.IntType; import client.window.Bind; import client.window.Button; import client.window.DisplayMode; @@ -78,87 +94,71 @@ import client.window.Keysym; import client.window.Wheel; import client.window.Window; import client.window.WindowEvent; -import game.IClient; -import game.biome.Biome; -import game.block.Block; -import game.collect.Lists; -import game.collect.Maps; -import game.color.TextColor; -import game.entity.Entity; -import game.entity.animal.EntityHorse; -import game.entity.npc.Energy; -import game.entity.npc.EntityNPC; -import game.entity.types.EntityLiving; -import game.entity.types.IEntityFX; -import game.future.Futures; -import game.future.ListenableFuture; -import game.future.ListenableFutureTask; -import game.init.BlockRegistry; -import game.init.Config; -import game.init.EntityRegistry; -import game.init.ItemRegistry; -import game.init.Items; -import game.init.Registry; -import game.init.SoundEvent; -import game.inventory.InventoryPlayer; -import game.item.Item; -import game.item.ItemBlock; -import game.item.ItemControl; -import game.item.ItemStack; -import game.log.Log; -import game.log.LogLevel; -import game.log.Message; -import game.material.Material; -import game.model.ParticleType; -import game.nbt.NBTTagCompound; -import game.network.IThreadListener; -import game.network.NetConnection; -import game.network.NetHandler.ThreadQuickExitException; -import game.packet.CPacketAction; -import game.packet.CPacketAction.Action; -import game.packet.CPacketCheat; -import game.packet.CPacketMessage; -import game.packet.HPacketHandshake; -import game.packet.LPacketPasswordResponse; -import game.potion.Potion; -import game.potion.PotionEffect; -import game.potion.PotionHelper; -import game.properties.IProperty; -import game.rng.Random; -import game.sound.EventType; -import game.sound.PositionedSound; -import game.sound.Sound; -import game.util.CharValidator; -import game.util.ExtMath; -import game.util.FileUtils; -import game.util.Util; -import game.vars.BaseVar.VarFunction; -import game.vars.BoolVar; -import game.vars.BoolVar.BoolFunction; -import game.vars.CVar; -import game.vars.CVarCategory; -import game.vars.ColorVar; -import game.vars.EnumVar; -import game.vars.EnumVar.EnumFunction; -import game.vars.FloatVar; -import game.vars.FloatVar.FloatFunction; -import game.vars.IntVar; -import game.vars.IntVar.IntFunction; -import game.vars.StringVar; -import game.vars.StringVar.StringFunction; -import game.vars.Variable; -import game.vars.Variable.IntType; -import game.world.BlockPos; -import game.world.BoundingBox; -import game.world.Chunk; -import game.world.Facing; -import game.world.HitPosition; -import game.world.HitPosition.ObjectType; -import game.world.LightType; -import game.world.Region; -import game.world.State; -import game.world.World; -import game.world.WorldClient; +import common.IClient; +import common.biome.Biome; +import common.block.Block; +import common.collect.Lists; +import common.collect.Maps; +import common.color.TextColor; +import common.entity.Entity; +import common.entity.animal.EntityHorse; +import common.entity.npc.Energy; +import common.entity.npc.EntityNPC; +import common.entity.types.EntityLiving; +import common.entity.types.IEntityFX; +import common.future.Futures; +import common.future.ListenableFuture; +import common.future.ListenableFutureTask; +import common.init.BlockRegistry; +import common.init.Config; +import common.init.EntityRegistry; +import common.init.ItemRegistry; +import common.init.Items; +import common.init.Registry; +import common.init.SoundEvent; +import common.inventory.InventoryPlayer; +import common.item.Item; +import common.item.ItemBlock; +import common.item.ItemControl; +import common.item.ItemStack; +import common.log.Log; +import common.log.LogLevel; +import common.log.Message; +import common.material.Material; +import common.model.ParticleType; +import common.nbt.NBTTagCompound; +import common.network.IThreadListener; +import common.network.NetConnection; +import common.network.NetHandler.ThreadQuickExitException; +import common.packet.CPacketAction; +import common.packet.CPacketCheat; +import common.packet.CPacketMessage; +import common.packet.HPacketHandshake; +import common.packet.LPacketPasswordResponse; +import common.packet.CPacketAction.Action; +import common.potion.Potion; +import common.potion.PotionEffect; +import common.potion.PotionHelper; +import common.properties.IProperty; +import common.rng.Random; +import common.sound.EventType; +import common.sound.PositionedSound; +import common.sound.Sound; +import common.util.CharValidator; +import common.util.ExtMath; +import common.util.FileUtils; +import common.util.Util; +import common.world.BlockPos; +import common.world.BoundingBox; +import common.world.Chunk; +import common.world.Facing; +import common.world.HitPosition; +import common.world.LightType; +import common.world.Region; +import common.world.State; +import common.world.World; +import common.world.WorldClient; +import common.world.HitPosition.ObjectType; /* Een net ganz funktionierndes Programm ... diff --git a/client/src/client/PerfSection.java b/client/src/client/PerfSection.java index f1f9bf5..ba9599f 100644 --- a/client/src/client/PerfSection.java +++ b/client/src/client/PerfSection.java @@ -1,6 +1,6 @@ package client; -import game.util.Util; +import common.util.Util; public enum PerfSection { TIMING("Timing"), diff --git a/client/src/client/PlayerController.java b/client/src/client/PlayerController.java index d12dd90..579c38a 100755 --- a/client/src/client/PlayerController.java +++ b/client/src/client/PlayerController.java @@ -1,26 +1,26 @@ package client; import client.network.ClientPlayer; -import game.block.Block; -import game.entity.Entity; -import game.entity.npc.EntityNPC; -import game.init.BlockRegistry; -import game.init.EntityRegistry; -import game.item.ItemBlock; -import game.item.ItemControl; -import game.item.ItemStack; -import game.material.Material; -import game.packet.CPacketAction; -import game.packet.CPacketBreak; -import game.packet.CPacketClick; -import game.packet.CPacketPlace; -import game.sound.PositionedSound; -import game.world.BlockPos; -import game.world.Facing; -import game.world.State; -import game.world.Vec3; -import game.world.World; -import game.world.WorldClient; +import common.block.Block; +import common.entity.Entity; +import common.entity.npc.EntityNPC; +import common.init.BlockRegistry; +import common.init.EntityRegistry; +import common.item.ItemBlock; +import common.item.ItemControl; +import common.item.ItemStack; +import common.material.Material; +import common.packet.CPacketAction; +import common.packet.CPacketBreak; +import common.packet.CPacketClick; +import common.packet.CPacketPlace; +import common.sound.PositionedSound; +import common.world.BlockPos; +import common.world.Facing; +import common.world.State; +import common.world.Vec3; +import common.world.World; +import common.world.WorldClient; public class PlayerController { diff --git a/client/src/client/SkinConverter.java b/client/src/client/SkinConverter.java index c787066..6c7695e 100755 --- a/client/src/client/SkinConverter.java +++ b/client/src/client/SkinConverter.java @@ -9,7 +9,7 @@ import java.io.IOException; import javax.imageio.ImageIO; -import game.log.Log; +import common.log.Log; public abstract class SkinConverter { private static BufferedImage convertSkin(BufferedImage image) { diff --git a/client/src/client/audio/AudioInterface.java b/client/src/client/audio/AudioInterface.java index a1f8654..2e7c105 100644 --- a/client/src/client/audio/AudioInterface.java +++ b/client/src/client/audio/AudioInterface.java @@ -7,12 +7,13 @@ import javax.sound.sampled.AudioFormat; import javax.sound.sampled.AudioFormat.Encoding; import javax.sound.sampled.AudioSystem; import javax.sound.sampled.DataLine.Info; + +import common.collect.Lists; +import common.log.Log; + import javax.sound.sampled.LineUnavailableException; import javax.sound.sampled.SourceDataLine; -import game.collect.Lists; -import game.log.Log; - public class AudioInterface implements Runnable { private static class Channel { short[] buffer; diff --git a/client/src/client/audio/SoundManager.java b/client/src/client/audio/SoundManager.java index dfd1474..062682c 100755 --- a/client/src/client/audio/SoundManager.java +++ b/client/src/client/audio/SoundManager.java @@ -11,18 +11,18 @@ import java.util.Map; import java.util.Map.Entry; import client.Game; -import game.collect.BiMap; -import game.collect.HashBiMap; -import game.collect.Lists; -import game.collect.Maps; -import game.entity.npc.EntityNPC; -import game.init.SoundEvent; -import game.log.Log; -import game.rng.Random; -import game.sound.MovingSound; -import game.sound.Sound; -import game.util.ExtMath; -import game.util.FileUtils; +import common.collect.BiMap; +import common.collect.HashBiMap; +import common.collect.Lists; +import common.collect.Maps; +import common.entity.npc.EntityNPC; +import common.init.SoundEvent; +import common.log.Log; +import common.rng.Random; +import common.sound.MovingSound; +import common.sound.Sound; +import common.util.ExtMath; +import common.util.FileUtils; public class SoundManager { private class Source { diff --git a/client/src/client/audio/Volume.java b/client/src/client/audio/Volume.java index d41e319..a879b91 100644 --- a/client/src/client/audio/Volume.java +++ b/client/src/client/audio/Volume.java @@ -2,10 +2,10 @@ package client.audio; import client.Game; import client.gui.element.Slider; -import game.color.TextColor; -import game.sound.EventType; -import game.vars.CVar; -import game.vars.CVarCategory; +import client.vars.CVar; +import client.vars.CVarCategory; +import common.color.TextColor; +import common.sound.EventType; public enum Volume implements CVar { MASTER("master", "Gesamt"), diff --git a/client/src/client/gui/Font.java b/client/src/client/gui/Font.java index adfe7fc..51fa18b 100644 --- a/client/src/client/gui/Font.java +++ b/client/src/client/gui/Font.java @@ -8,8 +8,8 @@ import org.lwjgl.opengl.GL11; import client.renderer.GlState; import client.renderer.texture.TextureUtil; -import game.log.Log; -import game.util.FileUtils; +import common.log.Log; +import common.util.FileUtils; public class Font { public static final FontChar[] SIZES = new FontChar[256]; diff --git a/client/src/client/gui/Gui.java b/client/src/client/gui/Gui.java index cb39cb5..36c7810 100644 --- a/client/src/client/gui/Gui.java +++ b/client/src/client/gui/Gui.java @@ -13,7 +13,7 @@ import client.renderer.GlState; import client.window.Bind; import client.window.Button; import client.window.Keysym; -import game.collect.Lists; +import common.collect.Lists; public abstract class Gui { public static final String DIRT_BACKGROUND = "textures/background.png"; diff --git a/client/src/client/gui/GuiConnect.java b/client/src/client/gui/GuiConnect.java index 568343f..339a92e 100644 --- a/client/src/client/gui/GuiConnect.java +++ b/client/src/client/gui/GuiConnect.java @@ -11,13 +11,13 @@ import client.gui.element.GuiList; import client.gui.element.ListEntry; import client.gui.element.NavButton; import client.renderer.Drawing; -import game.color.TextColor; -import game.init.Config; -import game.log.Log; -import game.network.IPlayer; -import game.util.FileUtils; -import game.util.Tuple; -import game.util.Util; +import common.color.TextColor; +import common.init.Config; +import common.log.Log; +import common.network.IPlayer; +import common.util.FileUtils; +import common.util.Tuple; +import common.util.Util; public class GuiConnect extends GuiList implements ActButton.Callback { public class ServerInfo implements Comparable, ListEntry { diff --git a/client/src/client/gui/GuiConsole.java b/client/src/client/gui/GuiConsole.java index d4023e7..2bd506f 100644 --- a/client/src/client/gui/GuiConsole.java +++ b/client/src/client/gui/GuiConsole.java @@ -8,17 +8,17 @@ import client.gui.element.Fill; import client.gui.element.Textbox; import client.gui.element.Textbox.Action; import client.network.ClientPlayer; +import client.vars.BoolVar; +import client.vars.CVar; import client.gui.element.TransparentBox; import client.window.Keysym; -import game.collect.Lists; -import game.color.TextColor; -import game.network.IPlayer; -import game.packet.CPacketComplete; -import game.util.ExtMath; -import game.vars.BoolVar; -import game.vars.CVar; -import game.world.BlockPos; -import game.world.HitPosition; +import common.collect.Lists; +import common.color.TextColor; +import common.network.IPlayer; +import common.packet.CPacketComplete; +import common.util.ExtMath; +import common.world.BlockPos; +import common.world.HitPosition; public class GuiConsole extends Gui implements Textbox.Callback { public static final GuiConsole INSTANCE = new GuiConsole(); diff --git a/client/src/client/gui/GuiConvert.java b/client/src/client/gui/GuiConvert.java index 4097025..8799b51 100755 --- a/client/src/client/gui/GuiConvert.java +++ b/client/src/client/gui/GuiConvert.java @@ -13,14 +13,14 @@ import client.gui.element.GuiList; import client.gui.element.ListEntry; import client.gui.element.NavButton; import client.renderer.Drawing; -import game.color.TextColor; -import game.dimension.Space; -import game.log.Log; -import game.world.Converter; -import game.world.Region; -import game.world.Region.FolderInfo; -import game.world.Region.SaveVersion; -import game.world.World; +import client.world.Converter; +import common.color.TextColor; +import common.dimension.Space; +import common.log.Log; +import common.world.Region; +import common.world.World; +import common.world.Region.FolderInfo; +import common.world.Region.SaveVersion; public class GuiConvert extends GuiList implements ActButton.Callback { diff --git a/client/src/client/gui/GuiInfo.java b/client/src/client/gui/GuiInfo.java index 243e111..eadf6dd 100644 --- a/client/src/client/gui/GuiInfo.java +++ b/client/src/client/gui/GuiInfo.java @@ -2,9 +2,9 @@ package client.gui; import client.gui.element.NavButton; import client.gui.element.TransparentBox; -import game.color.TextColor; -import game.init.Config; -import game.log.Log; +import common.color.TextColor; +import common.init.Config; +import common.log.Log; public class GuiInfo extends Gui { private static final String VER = diff --git a/client/src/client/gui/GuiMenu.java b/client/src/client/gui/GuiMenu.java index 9037467..40002ad 100644 --- a/client/src/client/gui/GuiMenu.java +++ b/client/src/client/gui/GuiMenu.java @@ -11,10 +11,10 @@ import client.gui.element.Textbox; import client.gui.options.GuiOptions; import client.renderer.Drawing; import client.window.Keysym; -import game.color.TextColor; -import game.init.Config; -import game.rng.Random; -import game.util.ExtMath; +import common.color.TextColor; +import common.init.Config; +import common.rng.Random; +import common.util.ExtMath; public class GuiMenu extends Gui { public static final GuiMenu INSTANCE = new GuiMenu(); diff --git a/client/src/client/gui/GuiServer.java b/client/src/client/gui/GuiServer.java index 45833a1..ca80fa0 100644 --- a/client/src/client/gui/GuiServer.java +++ b/client/src/client/gui/GuiServer.java @@ -6,11 +6,11 @@ import client.gui.element.Label; import client.gui.element.NavButton; import client.gui.element.Textbox; import client.gui.element.Textbox.Action; -import game.color.TextColor; -import game.init.Config; -import game.network.IPlayer; -import game.vars.CVarCategory; -import game.vars.Variable; +import client.vars.CVarCategory; +import client.vars.Variable; +import common.color.TextColor; +import common.init.Config; +import common.network.IPlayer; public class GuiServer extends Gui implements Textbox.Callback { public static final GuiServer INSTANCE = new GuiServer(null); diff --git a/client/src/client/gui/Style.java b/client/src/client/gui/Style.java index 841b495..db7435f 100644 --- a/client/src/client/gui/Style.java +++ b/client/src/client/gui/Style.java @@ -1,10 +1,10 @@ package client.gui; -import game.util.Displayable; -import game.util.Identifyable; -import game.vars.CVarCategory; -import game.vars.Variable; -import game.vars.Variable.IntType; +import client.vars.CVarCategory; +import client.vars.Variable; +import client.vars.Variable.IntType; +import common.util.Displayable; +import common.util.Identifyable; public enum Style implements Identifyable, Displayable { DEFAULT("default", "Standard"), SHINY("shiny", "Glänzend"), GRAY("gray", "Grau"), BLUE("blue", "Blau"), CUSTOM("custom", "Angepasst"); diff --git a/client/src/client/gui/character/GuiChar.java b/client/src/client/gui/character/GuiChar.java index 7fc0645..806ec6e 100755 --- a/client/src/client/gui/character/GuiChar.java +++ b/client/src/client/gui/character/GuiChar.java @@ -35,35 +35,35 @@ import client.renderer.GlState; import client.renderer.ItemRenderer; import client.renderer.entity.RenderManager; import client.renderer.texture.EntityTexManager; +import client.vars.CVarCategory; +import client.vars.EnumVar; +import client.vars.Variable; +import client.vars.EnumVar.EnumFunction; import client.window.Button; -import game.collect.Lists; -import game.dimension.DimType; -import game.dimension.Dimension; -import game.entity.npc.Alignment; -import game.entity.npc.CharacterInfo; -import game.entity.npc.EntityHuman; -import game.entity.npc.EntityNPC; -import game.entity.npc.SpeciesInfo; -import game.entity.types.EntityLiving; -import game.init.EntityEggInfo; -import game.init.EntityRegistry; -import game.init.SpeciesRegistry; -import game.init.SpeciesRegistry.ModelType; -import game.init.UniverseRegistry; -import game.log.Log; -import game.network.IPlayer; -import game.packet.CPacketAction; -import game.packet.CPacketMessage; -import game.packet.CPacketSkin; -import game.rng.Random; -import game.util.Displayable; -import game.util.FileUtils; -import game.util.Identifyable; -import game.util.Util; -import game.vars.CVarCategory; -import game.vars.EnumVar; -import game.vars.EnumVar.EnumFunction; -import game.vars.Variable; +import common.collect.Lists; +import common.dimension.DimType; +import common.dimension.Dimension; +import common.entity.npc.Alignment; +import common.entity.npc.CharacterInfo; +import common.entity.npc.EntityHuman; +import common.entity.npc.EntityNPC; +import common.entity.npc.SpeciesInfo; +import common.entity.types.EntityLiving; +import common.init.EntityEggInfo; +import common.init.EntityRegistry; +import common.init.SpeciesRegistry; +import common.init.UniverseRegistry; +import common.init.SpeciesRegistry.ModelType; +import common.log.Log; +import common.network.IPlayer; +import common.packet.CPacketAction; +import common.packet.CPacketMessage; +import common.packet.CPacketSkin; +import common.rng.Random; +import common.util.Displayable; +import common.util.FileUtils; +import common.util.Identifyable; +import common.util.Util; public class GuiChar extends GuiList { diff --git a/client/src/client/gui/character/GuiCharacters.java b/client/src/client/gui/character/GuiCharacters.java index f6614b4..cd94394 100644 --- a/client/src/client/gui/character/GuiCharacters.java +++ b/client/src/client/gui/character/GuiCharacters.java @@ -9,9 +9,9 @@ import client.gui.element.ListEntry; import client.gui.element.NavButton; import client.gui.element.TransparentBox; import client.renderer.Drawing; -import game.color.TextColor; -import game.entity.npc.PlayerCharacter; -import game.packet.CPacketAction; +import common.color.TextColor; +import common.entity.npc.PlayerCharacter; +import common.packet.CPacketAction; public class GuiCharacters extends GuiList implements ActButton.Callback { diff --git a/client/src/client/gui/character/GuiClass.java b/client/src/client/gui/character/GuiClass.java index f3e6559..c1ca519 100644 --- a/client/src/client/gui/character/GuiClass.java +++ b/client/src/client/gui/character/GuiClass.java @@ -6,7 +6,7 @@ import client.gui.element.GuiList; import client.gui.element.ListEntry; import client.gui.element.NavButton; import client.renderer.Drawing; -import game.packet.CPacketAction; +import common.packet.CPacketAction; public class GuiClass extends GuiList implements ActButton.Callback { diff --git a/client/src/client/gui/character/GuiSpecies.java b/client/src/client/gui/character/GuiSpecies.java index 385f5be..af9b9bd 100644 --- a/client/src/client/gui/character/GuiSpecies.java +++ b/client/src/client/gui/character/GuiSpecies.java @@ -6,10 +6,10 @@ import client.gui.element.GuiList; import client.gui.element.ListEntry; import client.gui.element.NavButton; import client.renderer.Drawing; -import game.entity.npc.SpeciesInfo; -import game.init.EntityRegistry; -import game.init.SpeciesRegistry; -import game.packet.CPacketAction; +import common.entity.npc.SpeciesInfo; +import common.init.EntityRegistry; +import common.init.SpeciesRegistry; +import common.packet.CPacketAction; public class GuiSpecies extends GuiList implements ActButton.Callback { diff --git a/client/src/client/gui/container/GuiBrewing.java b/client/src/client/gui/container/GuiBrewing.java index 73f2b15..45690d6 100755 --- a/client/src/client/gui/container/GuiBrewing.java +++ b/client/src/client/gui/container/GuiBrewing.java @@ -1,8 +1,8 @@ package client.gui.container; -import game.inventory.ContainerBrewingStand; -import game.inventory.IInventory; -import game.inventory.InventoryPlayer; +import common.inventory.ContainerBrewingStand; +import common.inventory.IInventory; +import common.inventory.InventoryPlayer; public class GuiBrewing extends GuiContainer diff --git a/client/src/client/gui/container/GuiChest.java b/client/src/client/gui/container/GuiChest.java index 1f7e912..e2bea30 100755 --- a/client/src/client/gui/container/GuiChest.java +++ b/client/src/client/gui/container/GuiChest.java @@ -1,8 +1,8 @@ package client.gui.container; import client.Game; -import game.inventory.ContainerChest; -import game.inventory.IInventory; +import common.inventory.ContainerChest; +import common.inventory.IInventory; public class GuiChest extends GuiContainer diff --git a/client/src/client/gui/container/GuiContainer.java b/client/src/client/gui/container/GuiContainer.java index 69dc168..7f5051d 100755 --- a/client/src/client/gui/container/GuiContainer.java +++ b/client/src/client/gui/container/GuiContainer.java @@ -13,16 +13,16 @@ import client.renderer.GlState; import client.renderer.ItemRenderer; import client.renderer.entity.RenderItem; import client.window.Button; -import game.collect.Lists; -import game.collect.Sets; -import game.color.TextColor; -import game.inventory.Container; -import game.inventory.InventoryPlayer; -import game.inventory.Slot; -import game.item.CheatTab; -import game.item.ItemStack; -import game.packet.CPacketCheat; -import game.util.ExtMath; +import common.collect.Lists; +import common.collect.Sets; +import common.color.TextColor; +import common.inventory.Container; +import common.inventory.InventoryPlayer; +import common.inventory.Slot; +import common.item.CheatTab; +import common.item.ItemStack; +import common.packet.CPacketCheat; +import common.util.ExtMath; public abstract class GuiContainer extends Gui { diff --git a/client/src/client/gui/container/GuiCrafting.java b/client/src/client/gui/container/GuiCrafting.java index b9fb6e2..e206188 100755 --- a/client/src/client/gui/container/GuiCrafting.java +++ b/client/src/client/gui/container/GuiCrafting.java @@ -1,9 +1,9 @@ package client.gui.container; -import game.inventory.ContainerWorkbench; -import game.inventory.InventoryPlayer; -import game.world.BlockPos; -import game.world.World; +import common.inventory.ContainerWorkbench; +import common.inventory.InventoryPlayer; +import common.world.BlockPos; +import common.world.World; public class GuiCrafting extends GuiContainer { diff --git a/client/src/client/gui/container/GuiDispenser.java b/client/src/client/gui/container/GuiDispenser.java index 8e94c00..00184b5 100755 --- a/client/src/client/gui/container/GuiDispenser.java +++ b/client/src/client/gui/container/GuiDispenser.java @@ -1,8 +1,8 @@ package client.gui.container; -import game.inventory.ContainerDispenser; -import game.inventory.IInventory; -import game.inventory.InventoryPlayer; +import common.inventory.ContainerDispenser; +import common.inventory.IInventory; +import common.inventory.InventoryPlayer; public class GuiDispenser extends GuiContainer diff --git a/client/src/client/gui/container/GuiEnchant.java b/client/src/client/gui/container/GuiEnchant.java index 31ef687..5dce728 100755 --- a/client/src/client/gui/container/GuiEnchant.java +++ b/client/src/client/gui/container/GuiEnchant.java @@ -1,12 +1,12 @@ package client.gui.container; -import game.color.TextColor; -import game.enchantment.Enchantment; -import game.inventory.ContainerEnchantment; -import game.inventory.InventoryPlayer; -import game.rng.Random; -import game.tileentity.IWorldNameable; -import game.world.World; +import common.color.TextColor; +import common.enchantment.Enchantment; +import common.inventory.ContainerEnchantment; +import common.inventory.InventoryPlayer; +import common.rng.Random; +import common.tileentity.IWorldNameable; +import common.world.World; public class GuiEnchant extends GuiContainer { diff --git a/client/src/client/gui/container/GuiFurnace.java b/client/src/client/gui/container/GuiFurnace.java index 3972317..c3aad9a 100755 --- a/client/src/client/gui/container/GuiFurnace.java +++ b/client/src/client/gui/container/GuiFurnace.java @@ -1,9 +1,9 @@ package client.gui.container; -import game.inventory.ContainerFurnace; -import game.inventory.IInventory; -import game.inventory.InventoryPlayer; -import game.tileentity.TileEntityFurnace; +import common.inventory.ContainerFurnace; +import common.inventory.IInventory; +import common.inventory.InventoryPlayer; +import common.tileentity.TileEntityFurnace; public class GuiFurnace extends GuiContainer diff --git a/client/src/client/gui/container/GuiHopper.java b/client/src/client/gui/container/GuiHopper.java index 753593e..400105a 100755 --- a/client/src/client/gui/container/GuiHopper.java +++ b/client/src/client/gui/container/GuiHopper.java @@ -1,9 +1,9 @@ package client.gui.container; import client.Game; -import game.inventory.ContainerHopper; -import game.inventory.IInventory; -import game.inventory.InventoryPlayer; +import common.inventory.ContainerHopper; +import common.inventory.IInventory; +import common.inventory.InventoryPlayer; public class GuiHopper extends GuiContainer diff --git a/client/src/client/gui/container/GuiHorse.java b/client/src/client/gui/container/GuiHorse.java index bb56765..966bf1e 100755 --- a/client/src/client/gui/container/GuiHorse.java +++ b/client/src/client/gui/container/GuiHorse.java @@ -1,9 +1,9 @@ package client.gui.container; import client.Game; -import game.entity.animal.EntityHorse; -import game.inventory.ContainerHorseInventory; -import game.inventory.IInventory; +import common.entity.animal.EntityHorse; +import common.inventory.ContainerHorseInventory; +import common.inventory.IInventory; public class GuiHorse extends GuiContainer diff --git a/client/src/client/gui/container/GuiInventory.java b/client/src/client/gui/container/GuiInventory.java index b47e81b..3dd33f0 100755 --- a/client/src/client/gui/container/GuiInventory.java +++ b/client/src/client/gui/container/GuiInventory.java @@ -1,6 +1,6 @@ package client.gui.container; -import game.entity.npc.EntityNPC; +import common.entity.npc.EntityNPC; public class GuiInventory extends GuiContainer { diff --git a/client/src/client/gui/container/GuiMachine.java b/client/src/client/gui/container/GuiMachine.java index b61ba3d..679131a 100755 --- a/client/src/client/gui/container/GuiMachine.java +++ b/client/src/client/gui/container/GuiMachine.java @@ -1,10 +1,10 @@ package client.gui.container; import client.Game; -import game.inventory.ContainerMachine; -import game.inventory.IInventory; -import game.inventory.InventoryPlayer; -import game.tileentity.TileEntityMachine; +import common.inventory.ContainerMachine; +import common.inventory.IInventory; +import common.inventory.InventoryPlayer; +import common.tileentity.TileEntityMachine; public class GuiMachine extends GuiContainer diff --git a/client/src/client/gui/container/GuiMerchant.java b/client/src/client/gui/container/GuiMerchant.java index 8f56250..0b1543e 100755 --- a/client/src/client/gui/container/GuiMerchant.java +++ b/client/src/client/gui/container/GuiMerchant.java @@ -4,13 +4,13 @@ import org.lwjgl.opengl.GL11; import client.renderer.GlState; import client.renderer.ItemRenderer; -import game.inventory.ContainerMerchant; -import game.inventory.InventoryPlayer; -import game.item.ItemStack; -import game.packet.CPacketAction; -import game.village.MerchantRecipe; -import game.village.MerchantRecipeList; -import game.world.World; +import common.inventory.ContainerMerchant; +import common.inventory.InventoryPlayer; +import common.item.ItemStack; +import common.packet.CPacketAction; +import common.village.MerchantRecipe; +import common.village.MerchantRecipeList; +import common.world.World; public class GuiMerchant extends GuiContainer { diff --git a/client/src/client/gui/container/GuiRepair.java b/client/src/client/gui/container/GuiRepair.java index fec404d..85e4099 100755 --- a/client/src/client/gui/container/GuiRepair.java +++ b/client/src/client/gui/container/GuiRepair.java @@ -3,13 +3,13 @@ package client.gui.container; import java.util.List; import client.Game; -import game.inventory.Container; -import game.inventory.ContainerRepair; -import game.inventory.ICrafting; -import game.inventory.IInventory; -import game.inventory.InventoryPlayer; -import game.item.ItemStack; -import game.world.World; +import common.inventory.Container; +import common.inventory.ContainerRepair; +import common.inventory.ICrafting; +import common.inventory.IInventory; +import common.inventory.InventoryPlayer; +import common.item.ItemStack; +import common.world.World; public class GuiRepair extends GuiContainer implements ICrafting { diff --git a/client/src/client/gui/element/Bar.java b/client/src/client/gui/element/Bar.java index bb1a457..649fb21 100644 --- a/client/src/client/gui/element/Bar.java +++ b/client/src/client/gui/element/Bar.java @@ -1,8 +1,8 @@ package client.gui.element; import client.renderer.Drawing; -import game.util.ExtMath; -import game.util.Util; +import common.util.ExtMath; +import common.util.Util; public class Bar extends Fill { private int color = 0x00ff00; diff --git a/client/src/client/gui/element/Dropdown.java b/client/src/client/gui/element/Dropdown.java index 010bac6..6ba417f 100644 --- a/client/src/client/gui/element/Dropdown.java +++ b/client/src/client/gui/element/Dropdown.java @@ -5,9 +5,9 @@ import client.gui.Formatter; import client.gui.Gui; import client.renderer.Drawing; import client.window.Button; -import game.util.Displayable; -import game.util.ExtMath; -import game.util.Util; +import common.util.Displayable; +import common.util.ExtMath; +import common.util.Util; public class Dropdown extends Element { public class Handle extends Element { diff --git a/client/src/client/gui/element/Element.java b/client/src/client/gui/element/Element.java index b3dcd56..86acf19 100644 --- a/client/src/client/gui/element/Element.java +++ b/client/src/client/gui/element/Element.java @@ -9,10 +9,10 @@ import client.renderer.Drawing; import client.renderer.Drawing.Vec2i; import client.window.Button; import client.window.Keysym; -import game.init.SoundEvent; -import game.sound.EventType; -import game.sound.PositionedSound; -import game.util.Util; +import common.init.SoundEvent; +import common.sound.EventType; +import common.sound.PositionedSound; +import common.util.Util; public abstract class Element { protected final Game gm = Game.getGame(); diff --git a/client/src/client/gui/element/GuiList.java b/client/src/client/gui/element/GuiList.java index 0dd8ab6..1f4ac01 100755 --- a/client/src/client/gui/element/GuiList.java +++ b/client/src/client/gui/element/GuiList.java @@ -11,8 +11,8 @@ import client.renderer.GlState; import client.renderer.RenderBuffer; import client.renderer.Tessellator; import client.window.Button; -import game.collect.Lists; -import game.util.ExtMath; +import common.collect.Lists; +import common.util.ExtMath; public abstract class GuiList extends Gui { diff --git a/client/src/client/gui/element/Label.java b/client/src/client/gui/element/Label.java index 52bb201..7420a1d 100644 --- a/client/src/client/gui/element/Label.java +++ b/client/src/client/gui/element/Label.java @@ -1,7 +1,7 @@ package client.gui.element; import client.renderer.Drawing; -import game.util.Util; +import common.util.Util; public class Label extends Fill { public Label(int x, int y, int w, int h, String text, boolean top, boolean left) { diff --git a/client/src/client/gui/element/NavButton.java b/client/src/client/gui/element/NavButton.java index 224216b..2b16df9 100644 --- a/client/src/client/gui/element/NavButton.java +++ b/client/src/client/gui/element/NavButton.java @@ -3,7 +3,7 @@ package client.gui.element; import client.Game; import client.gui.Gui; import client.renderer.Drawing; -import game.util.Util; +import common.util.Util; public class NavButton extends ActButton { private final Gui navGui; diff --git a/client/src/client/gui/element/SelectableButton.java b/client/src/client/gui/element/SelectableButton.java index 0ad31d6..699121d 100644 --- a/client/src/client/gui/element/SelectableButton.java +++ b/client/src/client/gui/element/SelectableButton.java @@ -1,7 +1,7 @@ package client.gui.element; import client.renderer.Drawing; -import game.util.Util; +import common.util.Util; public class SelectableButton extends ActButton { private boolean selected; diff --git a/client/src/client/gui/element/Slider.java b/client/src/client/gui/element/Slider.java index e6fd0d8..45bb1e7 100644 --- a/client/src/client/gui/element/Slider.java +++ b/client/src/client/gui/element/Slider.java @@ -3,8 +3,8 @@ package client.gui.element; import client.gui.Formatter; import client.renderer.Drawing; import client.window.Button; -import game.util.ExtMath; -import game.util.Util; +import common.util.ExtMath; +import common.util.Util; public class Slider extends Element { public static interface Callback { diff --git a/client/src/client/gui/element/Switch.java b/client/src/client/gui/element/Switch.java index dc1e902..6053cd2 100644 --- a/client/src/client/gui/element/Switch.java +++ b/client/src/client/gui/element/Switch.java @@ -2,8 +2,8 @@ package client.gui.element; import client.gui.Formatter; import client.window.Button; -import game.util.Displayable; -import game.util.Util; +import common.util.Displayable; +import common.util.Util; public class Switch extends Element { public static interface Callback { diff --git a/client/src/client/gui/element/Textbox.java b/client/src/client/gui/element/Textbox.java index a57e583..533e160 100644 --- a/client/src/client/gui/element/Textbox.java +++ b/client/src/client/gui/element/Textbox.java @@ -10,9 +10,9 @@ import client.renderer.Drawing.Vec2i; import client.window.Button; import client.window.Keysym; import client.window.Window; -import game.util.CharValidator; -import game.util.ExtMath; -import game.util.Util; +import common.util.CharValidator; +import common.util.ExtMath; +import common.util.Util; public class Textbox extends Element { public static enum Action { diff --git a/client/src/client/gui/element/Toggle.java b/client/src/client/gui/element/Toggle.java index 2c38f8b..5c4be8b 100644 --- a/client/src/client/gui/element/Toggle.java +++ b/client/src/client/gui/element/Toggle.java @@ -3,7 +3,7 @@ package client.gui.element; import client.gui.Formatter; import client.renderer.Drawing; import client.window.Button; -import game.util.Util; +import common.util.Util; public class Toggle extends Element { public static interface Callback { diff --git a/client/src/client/gui/ingame/GuiGameOver.java b/client/src/client/gui/ingame/GuiGameOver.java index 4ed36d0..8b79563 100755 --- a/client/src/client/gui/ingame/GuiGameOver.java +++ b/client/src/client/gui/ingame/GuiGameOver.java @@ -3,8 +3,8 @@ package client.gui.ingame; import client.gui.Gui; import client.gui.element.ActButton; import client.gui.element.ActButton.Mode; +import common.color.TextColor; import client.gui.element.Label; -import game.color.TextColor; public class GuiGameOver extends Gui { public static final GuiGameOver INSTANCE = new GuiGameOver(); diff --git a/client/src/client/gui/ingame/GuiSign.java b/client/src/client/gui/ingame/GuiSign.java index 4678e86..fbdfb60 100644 --- a/client/src/client/gui/ingame/GuiSign.java +++ b/client/src/client/gui/ingame/GuiSign.java @@ -5,8 +5,8 @@ import client.gui.element.NavButton; import client.gui.element.Textbox; import client.gui.element.Textbox.Action; import client.network.ClientPlayer; -import game.packet.CPacketSign; -import game.world.BlockPos; +import common.packet.CPacketSign; +import common.world.BlockPos; public class GuiSign extends Gui implements Textbox.Callback { private final BlockPos position; diff --git a/client/src/client/gui/options/GuiBinds.java b/client/src/client/gui/options/GuiBinds.java index 01bb639..1c1ab7a 100644 --- a/client/src/client/gui/options/GuiBinds.java +++ b/client/src/client/gui/options/GuiBinds.java @@ -5,7 +5,7 @@ import client.gui.element.ActButton; import client.gui.element.ActButton.Mode; import client.gui.element.Label; import client.window.Bind; -import game.color.TextColor; +import common.color.TextColor; public class GuiBinds extends GuiOptions { protected GuiBinds() { diff --git a/client/src/client/gui/options/GuiDisplay.java b/client/src/client/gui/options/GuiDisplay.java index 1d5d69b..68febe0 100644 --- a/client/src/client/gui/options/GuiDisplay.java +++ b/client/src/client/gui/options/GuiDisplay.java @@ -9,7 +9,7 @@ import client.gui.element.Toggle; import client.window.Button; import client.window.DisplayMode; import client.window.Window; -import game.color.TextColor; +import common.color.TextColor; public class GuiDisplay extends GuiOptions { private static final String[] DISTANCES = new String[] {"Gruselig", "Winzig", "Gering", "Normal", "Weit"}; diff --git a/client/src/client/gui/options/GuiStyle.java b/client/src/client/gui/options/GuiStyle.java index 66cd703..6d374ee 100644 --- a/client/src/client/gui/options/GuiStyle.java +++ b/client/src/client/gui/options/GuiStyle.java @@ -10,9 +10,9 @@ import client.gui.element.Slider; import client.gui.element.Switch; import client.gui.element.Textbox; import client.gui.element.Textbox.Action; +import client.vars.CVar; +import client.vars.ColorVar; import client.gui.element.Toggle; -import game.vars.CVar; -import game.vars.ColorVar; public class GuiStyle extends GuiOptions implements Dropdown.Callback, ActButton.Callback, Toggle.Callback, Switch.Callback, Slider.Callback, Textbox.Callback { private static final String[] STYLE_CVARS = { diff --git a/client/src/client/init/EntityRenderRegistry.java b/client/src/client/init/EntityRenderRegistry.java index b8df0a0..2abdd41 100644 --- a/client/src/client/init/EntityRenderRegistry.java +++ b/client/src/client/init/EntityRenderRegistry.java @@ -54,50 +54,50 @@ import client.renderer.model.ModelRabbit; import client.renderer.model.ModelSheep2; import client.renderer.model.ModelSquid; import client.renderer.model.ModelWolf; -import game.entity.Entity; -import game.entity.animal.EntityBat; -import game.entity.animal.EntityChicken; -import game.entity.animal.EntityCow; -import game.entity.animal.EntityDragon; -import game.entity.animal.EntityHorse; -import game.entity.animal.EntityMooshroom; -import game.entity.animal.EntityMouse; -import game.entity.animal.EntityOcelot; -import game.entity.animal.EntityPig; -import game.entity.animal.EntityRabbit; -import game.entity.animal.EntitySheep; -import game.entity.animal.EntitySquid; -import game.entity.animal.EntityWolf; -import game.entity.effect.EntityLightning; -import game.entity.item.EntityBoat; -import game.entity.item.EntityCart; -import game.entity.item.EntityCrystal; -import game.entity.item.EntityFalling; -import game.entity.item.EntityFireworks; -import game.entity.item.EntityItem; -import game.entity.item.EntityLeashKnot; -import game.entity.item.EntityNuke; -import game.entity.item.EntityOrb; -import game.entity.item.EntityTnt; -import game.entity.item.EntityTntCart; -import game.entity.item.EntityXp; -import game.entity.item.EntityXpBottle; -import game.entity.npc.SpeciesInfo; -import game.entity.projectile.EntityArrow; -import game.entity.projectile.EntityBox; -import game.entity.projectile.EntityBullet; -import game.entity.projectile.EntityDie; -import game.entity.projectile.EntityDynamite; -import game.entity.projectile.EntityEgg; -import game.entity.projectile.EntityFireCharge; -import game.entity.projectile.EntityFireball; -import game.entity.projectile.EntityHook; -import game.entity.projectile.EntityPotion; -import game.entity.projectile.EntitySnowball; -import game.init.Blocks; -import game.init.Items; -import game.init.SpeciesRegistry; -import game.init.SpeciesRegistry.ModelType; +import common.entity.Entity; +import common.entity.animal.EntityBat; +import common.entity.animal.EntityChicken; +import common.entity.animal.EntityCow; +import common.entity.animal.EntityDragon; +import common.entity.animal.EntityHorse; +import common.entity.animal.EntityMooshroom; +import common.entity.animal.EntityMouse; +import common.entity.animal.EntityOcelot; +import common.entity.animal.EntityPig; +import common.entity.animal.EntityRabbit; +import common.entity.animal.EntitySheep; +import common.entity.animal.EntitySquid; +import common.entity.animal.EntityWolf; +import common.entity.effect.EntityLightning; +import common.entity.item.EntityBoat; +import common.entity.item.EntityCart; +import common.entity.item.EntityCrystal; +import common.entity.item.EntityFalling; +import common.entity.item.EntityFireworks; +import common.entity.item.EntityItem; +import common.entity.item.EntityLeashKnot; +import common.entity.item.EntityNuke; +import common.entity.item.EntityOrb; +import common.entity.item.EntityTnt; +import common.entity.item.EntityTntCart; +import common.entity.item.EntityXp; +import common.entity.item.EntityXpBottle; +import common.entity.npc.SpeciesInfo; +import common.entity.projectile.EntityArrow; +import common.entity.projectile.EntityBox; +import common.entity.projectile.EntityBullet; +import common.entity.projectile.EntityDie; +import common.entity.projectile.EntityDynamite; +import common.entity.projectile.EntityEgg; +import common.entity.projectile.EntityFireCharge; +import common.entity.projectile.EntityFireball; +import common.entity.projectile.EntityHook; +import common.entity.projectile.EntityPotion; +import common.entity.projectile.EntitySnowball; +import common.init.Blocks; +import common.init.Items; +import common.init.SpeciesRegistry; +import common.init.SpeciesRegistry.ModelType; public abstract class EntityRenderRegistry { public static void registerRenderers(Map, Render> map, diff --git a/client/src/client/network/ClientLoginHandler.java b/client/src/client/network/ClientLoginHandler.java index b699978..c7b66e8 100755 --- a/client/src/client/network/ClientLoginHandler.java +++ b/client/src/client/network/ClientLoginHandler.java @@ -1,13 +1,13 @@ package client.network; import client.Game; -import game.network.IClientLoginHandler; -import game.network.NetConnection; -import game.network.NetHandler; -import game.network.PacketRegistry; -import game.packet.RPacketDisconnect; -import game.packet.RPacketEnableCompression; -import game.packet.RPacketLoginSuccess; +import common.network.IClientLoginHandler; +import common.network.NetConnection; +import common.network.NetHandler; +import common.network.PacketRegistry; +import common.packet.RPacketDisconnect; +import common.packet.RPacketEnableCompression; +import common.packet.RPacketLoginSuccess; public class ClientLoginHandler extends NetHandler implements IClientLoginHandler { private final Game gm; diff --git a/client/src/client/network/ClientPlayer.java b/client/src/client/network/ClientPlayer.java index dff2c2f..76fbc35 100755 --- a/client/src/client/network/ClientPlayer.java +++ b/client/src/client/network/ClientPlayer.java @@ -27,117 +27,117 @@ import client.gui.container.GuiRepair; import client.gui.ingame.GuiSign; import client.renderer.particle.EntityPickupFX; import client.renderer.texture.EntityTexManager; -import game.collect.Lists; -import game.collect.Maps; -import game.dimension.Dimension; -import game.entity.DataWatcher; -import game.entity.Entity; -import game.entity.animal.EntityHorse; -import game.entity.attributes.Attribute; -import game.entity.attributes.AttributeInstance; -import game.entity.attributes.AttributeMap; -import game.entity.attributes.AttributeModifier; -import game.entity.effect.EntityLightning; -import game.entity.item.EntityBoat; -import game.entity.item.EntityXp; -import game.entity.npc.EntityNPC; -import game.entity.npc.PlayerCharacter; -import game.entity.projectile.EntityProjectile; -import game.entity.types.EntityLiving; -import game.init.EntityRegistry; -import game.init.ItemRegistry; -import game.init.SoundEvent; -import game.inventory.AnimalChest; -import game.inventory.Container; -import game.inventory.ContainerLocalMenu; -import game.inventory.IInventory; -import game.inventory.InventoryBasic; -import game.inventory.InventoryPlayer; -import game.item.ItemStack; -import game.log.Log; -import game.model.ParticleType; -import game.network.IClientPlayer; -import game.network.NetConnection; -import game.network.NetHandler; -import game.network.Packet; -import game.packet.CPacketAction; -import game.packet.CPacketKeepAlive; -import game.packet.CPacketPlayer; -import game.packet.S14PacketEntity; -import game.packet.S18PacketEntityTeleport; -import game.packet.S19PacketEntityHeadLook; -import game.packet.S1APacketEntityStatus; -import game.packet.S1BPacketEntityAttach; -import game.packet.S1CPacketEntityMetadata; -import game.packet.S1DPacketEntityEffect; -import game.packet.S1EPacketRemoveEntityEffect; -import game.packet.S20PacketEntityProperties; -import game.packet.S27PacketExplosion; -import game.packet.S28PacketEffect; -import game.packet.S29PacketSoundEffect; -import game.packet.S2APacketParticles; -import game.packet.S2BPacketChangeGameState; -import game.packet.S2CPacketSpawnGlobalEntity; -import game.packet.S2DPacketOpenWindow; -import game.packet.S2EPacketCloseWindow; -import game.packet.S2FPacketSetSlot; -import game.packet.S30PacketWindowItems; -import game.packet.S31PacketWindowProperty; -import game.packet.S32PacketConfirmTransaction; -import game.packet.S33PacketUpdateSign; -import game.packet.S35PacketUpdateTileEntity; -import game.packet.S36PacketSignEditorOpen; -import game.packet.S38PacketPlayerListItem; -import game.packet.S39PacketPlayerAbilities; -import game.packet.S3APacketTabComplete; -import game.packet.S43PacketUpdateEntityNBT; -import game.packet.SPacketAnimation; -import game.packet.SPacketBiomes; -import game.packet.SPacketBlockAction; -import game.packet.SPacketBlockBreakAnim; -import game.packet.SPacketBlockChange; -import game.packet.SPacketCamera; -import game.packet.SPacketCharacterList; -import game.packet.SPacketChunkData; -import game.packet.SPacketCollectItem; -import game.packet.SPacketDestroyEntities; -import game.packet.SPacketDimensionName; -import game.packet.SPacketDisconnect; -import game.packet.SPacketEntityEquipment; -import game.packet.SPacketEntityVelocity; -import game.packet.SPacketHeldItemChange; -import game.packet.SPacketJoinGame; -import game.packet.SPacketKeepAlive; -import game.packet.SPacketLoading; -import game.packet.SPacketMapChunkBulk; -import game.packet.SPacketMessage; -import game.packet.SPacketMultiBlockChange; -import game.packet.SPacketPlayerPosLook; -import game.packet.SPacketRespawn; -import game.packet.SPacketServerTick; -import game.packet.SPacketSetExperience; -import game.packet.SPacketSkin; -import game.packet.SPacketSpawnMob; -import game.packet.SPacketSpawnObject; -import game.packet.SPacketSpawnPlayer; -import game.packet.SPacketTimeUpdate; -import game.packet.SPacketTrades; -import game.packet.SPacketUpdateHealth; -import game.packet.SPacketWorld; -import game.potion.PotionEffect; -import game.rng.Random; -import game.tileentity.IInteractionObject; -import game.tileentity.LocalBlockIntercommunication; -import game.tileentity.TileEntity; -import game.tileentity.TileEntityMachine; -import game.tileentity.TileEntitySign; -import game.village.MerchantRecipeList; -import game.world.BlockPos; -import game.world.Chunk; -import game.world.Explosion; -import game.world.Weather; -import game.world.World; -import game.world.WorldClient; +import common.collect.Lists; +import common.collect.Maps; +import common.dimension.Dimension; +import common.entity.DataWatcher; +import common.entity.Entity; +import common.entity.animal.EntityHorse; +import common.entity.attributes.Attribute; +import common.entity.attributes.AttributeInstance; +import common.entity.attributes.AttributeMap; +import common.entity.attributes.AttributeModifier; +import common.entity.effect.EntityLightning; +import common.entity.item.EntityBoat; +import common.entity.item.EntityXp; +import common.entity.npc.EntityNPC; +import common.entity.npc.PlayerCharacter; +import common.entity.projectile.EntityProjectile; +import common.entity.types.EntityLiving; +import common.init.EntityRegistry; +import common.init.ItemRegistry; +import common.init.SoundEvent; +import common.inventory.AnimalChest; +import common.inventory.Container; +import common.inventory.ContainerLocalMenu; +import common.inventory.IInventory; +import common.inventory.InventoryBasic; +import common.inventory.InventoryPlayer; +import common.item.ItemStack; +import common.log.Log; +import common.model.ParticleType; +import common.network.IClientPlayer; +import common.network.NetConnection; +import common.network.NetHandler; +import common.network.Packet; +import common.packet.CPacketAction; +import common.packet.CPacketKeepAlive; +import common.packet.CPacketPlayer; +import common.packet.S14PacketEntity; +import common.packet.S18PacketEntityTeleport; +import common.packet.S19PacketEntityHeadLook; +import common.packet.S1APacketEntityStatus; +import common.packet.S1BPacketEntityAttach; +import common.packet.S1CPacketEntityMetadata; +import common.packet.S1DPacketEntityEffect; +import common.packet.S1EPacketRemoveEntityEffect; +import common.packet.S20PacketEntityProperties; +import common.packet.S27PacketExplosion; +import common.packet.S28PacketEffect; +import common.packet.S29PacketSoundEffect; +import common.packet.S2APacketParticles; +import common.packet.S2BPacketChangeGameState; +import common.packet.S2CPacketSpawnGlobalEntity; +import common.packet.S2DPacketOpenWindow; +import common.packet.S2EPacketCloseWindow; +import common.packet.S2FPacketSetSlot; +import common.packet.S30PacketWindowItems; +import common.packet.S31PacketWindowProperty; +import common.packet.S32PacketConfirmTransaction; +import common.packet.S33PacketUpdateSign; +import common.packet.S35PacketUpdateTileEntity; +import common.packet.S36PacketSignEditorOpen; +import common.packet.S38PacketPlayerListItem; +import common.packet.S39PacketPlayerAbilities; +import common.packet.S3APacketTabComplete; +import common.packet.S43PacketUpdateEntityNBT; +import common.packet.SPacketAnimation; +import common.packet.SPacketBiomes; +import common.packet.SPacketBlockAction; +import common.packet.SPacketBlockBreakAnim; +import common.packet.SPacketBlockChange; +import common.packet.SPacketCamera; +import common.packet.SPacketCharacterList; +import common.packet.SPacketChunkData; +import common.packet.SPacketCollectItem; +import common.packet.SPacketDestroyEntities; +import common.packet.SPacketDimensionName; +import common.packet.SPacketDisconnect; +import common.packet.SPacketEntityEquipment; +import common.packet.SPacketEntityVelocity; +import common.packet.SPacketHeldItemChange; +import common.packet.SPacketJoinGame; +import common.packet.SPacketKeepAlive; +import common.packet.SPacketLoading; +import common.packet.SPacketMapChunkBulk; +import common.packet.SPacketMessage; +import common.packet.SPacketMultiBlockChange; +import common.packet.SPacketPlayerPosLook; +import common.packet.SPacketRespawn; +import common.packet.SPacketServerTick; +import common.packet.SPacketSetExperience; +import common.packet.SPacketSkin; +import common.packet.SPacketSpawnMob; +import common.packet.SPacketSpawnObject; +import common.packet.SPacketSpawnPlayer; +import common.packet.SPacketTimeUpdate; +import common.packet.SPacketTrades; +import common.packet.SPacketUpdateHealth; +import common.packet.SPacketWorld; +import common.potion.PotionEffect; +import common.rng.Random; +import common.tileentity.IInteractionObject; +import common.tileentity.LocalBlockIntercommunication; +import common.tileentity.TileEntity; +import common.tileentity.TileEntityMachine; +import common.tileentity.TileEntitySign; +import common.village.MerchantRecipeList; +import common.world.BlockPos; +import common.world.Chunk; +import common.world.Explosion; +import common.world.Weather; +import common.world.World; +import common.world.WorldClient; public class ClientPlayer extends NetHandler implements IClientPlayer { diff --git a/client/src/client/renderer/ActiveRenderInfo.java b/client/src/client/renderer/ActiveRenderInfo.java index b9e7ecd..fc8a9ef 100755 --- a/client/src/client/renderer/ActiveRenderInfo.java +++ b/client/src/client/renderer/ActiveRenderInfo.java @@ -7,15 +7,15 @@ import java.nio.IntBuffer; import org.lwjgl.opengl.GL11; -import game.block.Block; -import game.block.BlockLiquid; -import game.entity.Entity; -import game.entity.npc.EntityNPC; -import game.util.ExtMath; -import game.world.BlockPos; -import game.world.State; -import game.world.Vec3; -import game.world.World; +import common.block.Block; +import common.block.BlockLiquid; +import common.entity.Entity; +import common.entity.npc.EntityNPC; +import common.util.ExtMath; +import common.world.BlockPos; +import common.world.State; +import common.world.Vec3; +import common.world.World; public class ActiveRenderInfo { diff --git a/client/src/client/renderer/BlockRenderer.java b/client/src/client/renderer/BlockRenderer.java index cb78895..ba4e8d1 100755 --- a/client/src/client/renderer/BlockRenderer.java +++ b/client/src/client/renderer/BlockRenderer.java @@ -14,20 +14,20 @@ import client.renderer.blockmodel.ModelManager; import client.renderer.texture.TextureAtlasSprite; import client.renderer.texture.TextureMap; import client.renderer.tileentity.TileEntityItemStackRenderer; -import game.block.Block; -import game.block.BlockLiquid; -import game.collect.Maps; -import game.init.BlockRegistry; -import game.init.FluidRegistry; -import game.item.ItemStack; -import game.material.Material; -import game.util.ExtMath; -import game.world.BlockPos; -import game.world.Facing; -import game.world.IBlockAccess; -import game.world.IWorldAccess; -import game.world.State; -import game.world.Vec3i; +import common.block.Block; +import common.block.BlockLiquid; +import common.collect.Maps; +import common.init.BlockRegistry; +import common.init.FluidRegistry; +import common.item.ItemStack; +import common.material.Material; +import common.util.ExtMath; +import common.world.BlockPos; +import common.world.Facing; +import common.world.IBlockAccess; +import common.world.IWorldAccess; +import common.world.State; +import common.world.Vec3i; public class BlockRenderer { diff --git a/client/src/client/renderer/Drawing.java b/client/src/client/renderer/Drawing.java index d4a2002..d4056c4 100644 --- a/client/src/client/renderer/Drawing.java +++ b/client/src/client/renderer/Drawing.java @@ -5,9 +5,9 @@ import org.lwjgl.opengl.GL11; import client.Game; import client.gui.Font; import client.gui.FontChar; -import game.color.TextColor; -import game.log.Log; -import game.util.Util; +import common.color.TextColor; +import common.log.Log; +import common.util.Util; public abstract class Drawing { public static class Vec2i { diff --git a/client/src/client/renderer/EntityRenderer.java b/client/src/client/renderer/EntityRenderer.java index 0ca4578..94152e2 100755 --- a/client/src/client/renderer/EntityRenderer.java +++ b/client/src/client/renderer/EntityRenderer.java @@ -13,26 +13,26 @@ import client.Game; import client.renderer.particle.EffectRenderer; import client.renderer.texture.DynamicTexture; import client.renderer.texture.TextureMap; -import game.biome.Biome; -import game.block.Block; -import game.entity.Entity; -import game.entity.npc.EntityNPC; -import game.entity.types.EntityAnimal; -import game.entity.types.EntityLiving; -import game.init.Items; -import game.init.SoundEvent; -import game.material.Material; -import game.model.BlockLayer; -import game.model.ParticleType; -import game.potion.Potion; -import game.rng.Random; -import game.util.ExtMath; -import game.world.BlockPos; -import game.world.BoundingBox; -import game.world.HitPosition; -import game.world.Vec3; -import game.world.World; -import game.world.WorldClient; +import common.biome.Biome; +import common.block.Block; +import common.entity.Entity; +import common.entity.npc.EntityNPC; +import common.entity.types.EntityAnimal; +import common.entity.types.EntityLiving; +import common.init.Items; +import common.init.SoundEvent; +import common.material.Material; +import common.model.BlockLayer; +import common.model.ParticleType; +import common.potion.Potion; +import common.rng.Random; +import common.util.ExtMath; +import common.world.BlockPos; +import common.world.BoundingBox; +import common.world.HitPosition; +import common.world.Vec3; +import common.world.World; +import common.world.WorldClient; public class EntityRenderer { private static final String locationMoltenPng = "textures/world/molten.png"; diff --git a/client/src/client/renderer/Frustum.java b/client/src/client/renderer/Frustum.java index 9b3478d..ba0a6f5 100755 --- a/client/src/client/renderer/Frustum.java +++ b/client/src/client/renderer/Frustum.java @@ -6,8 +6,8 @@ import java.nio.FloatBuffer; import org.lwjgl.opengl.GL11; -import game.util.ExtMath; -import game.world.BoundingBox; +import common.util.ExtMath; +import common.world.BoundingBox; public class Frustum { private static class ClippingHelper { diff --git a/client/src/client/renderer/ItemModelMesher.java b/client/src/client/renderer/ItemModelMesher.java index 69fd18c..b242df1 100755 --- a/client/src/client/renderer/ItemModelMesher.java +++ b/client/src/client/renderer/ItemModelMesher.java @@ -6,12 +6,12 @@ import java.util.Map; import client.renderer.blockmodel.IBakedModel; import client.renderer.blockmodel.ModelManager; import client.renderer.texture.TextureAtlasSprite; -import game.collect.Lists; -import game.collect.Maps; -import game.init.ItemRegistry; -import game.item.Item; -import game.item.ItemStack; -import game.model.ItemMeshDefinition; +import common.collect.Lists; +import common.collect.Maps; +import common.init.ItemRegistry; +import common.item.Item; +import common.item.ItemStack; +import common.model.ItemMeshDefinition; public class ItemModelMesher { diff --git a/client/src/client/renderer/ItemRenderer.java b/client/src/client/renderer/ItemRenderer.java index c3ac2e1..559e6a0 100755 --- a/client/src/client/renderer/ItemRenderer.java +++ b/client/src/client/renderer/ItemRenderer.java @@ -14,18 +14,18 @@ import client.renderer.entity.RenderNpc; import client.renderer.texture.EntityTexManager; import client.renderer.texture.TextureAtlasSprite; import client.renderer.texture.TextureMap; -import game.block.Block; -import game.entity.npc.EntityNPC; -import game.entity.types.EntityLiving; -import game.item.Item; -import game.item.ItemAction; -import game.item.ItemStack; -import game.model.BlockLayer; -import game.model.Transforms; -import game.util.ExtMath; -import game.world.BlockPos; -import game.world.State; -import game.world.Vec3; +import common.block.Block; +import common.entity.npc.EntityNPC; +import common.entity.types.EntityLiving; +import common.item.Item; +import common.item.ItemAction; +import common.item.ItemStack; +import common.model.BlockLayer; +import common.model.Transforms; +import common.util.ExtMath; +import common.world.BlockPos; +import common.world.State; +import common.world.Vec3; public class ItemRenderer diff --git a/client/src/client/renderer/RegionRenderCache.java b/client/src/client/renderer/RegionRenderCache.java index ceeae17..91c66d6 100755 --- a/client/src/client/renderer/RegionRenderCache.java +++ b/client/src/client/renderer/RegionRenderCache.java @@ -2,18 +2,18 @@ package client.renderer; import java.util.Arrays; -import game.biome.Biome; -import game.init.Blocks; -import game.tileentity.TileEntity; -import game.world.BlockPos; -import game.world.Chunk; -import game.world.ChunkCache; -import game.world.Facing; -import game.world.IWorldAccess; -import game.world.LightType; -import game.world.State; -import game.world.Vec3i; -import game.world.World; +import common.biome.Biome; +import common.init.Blocks; +import common.tileentity.TileEntity; +import common.world.BlockPos; +import common.world.Chunk; +import common.world.ChunkCache; +import common.world.Facing; +import common.world.IWorldAccess; +import common.world.LightType; +import common.world.State; +import common.world.Vec3i; +import common.world.World; public class RegionRenderCache extends ChunkCache implements IWorldAccess { diff --git a/client/src/client/renderer/RegionRenderCacheBuilder.java b/client/src/client/renderer/RegionRenderCacheBuilder.java index 3bdd7be..7318dc3 100755 --- a/client/src/client/renderer/RegionRenderCacheBuilder.java +++ b/client/src/client/renderer/RegionRenderCacheBuilder.java @@ -1,6 +1,6 @@ package client.renderer; -import game.model.BlockLayer; +import common.model.BlockLayer; public class RegionRenderCacheBuilder { diff --git a/client/src/client/renderer/RenderBuffer.java b/client/src/client/renderer/RenderBuffer.java index 8889951..b5cb077 100755 --- a/client/src/client/renderer/RenderBuffer.java +++ b/client/src/client/renderer/RenderBuffer.java @@ -9,8 +9,8 @@ import java.util.Arrays; import java.util.BitSet; import java.util.Comparator; -import game.log.Log; -import game.util.ExtMath; +import common.log.Log; +import common.util.ExtMath; public class RenderBuffer { diff --git a/client/src/client/renderer/RenderGlobal.java b/client/src/client/renderer/RenderGlobal.java index 2376f3c..c1a1d9d 100755 --- a/client/src/client/renderer/RenderGlobal.java +++ b/client/src/client/renderer/RenderGlobal.java @@ -25,34 +25,34 @@ import client.renderer.texture.TextureAtlasSprite; import client.renderer.texture.TextureManager; import client.renderer.texture.TextureMap; import client.renderer.tileentity.TileEntityRendererDispatcher; -import game.block.Block; -import game.block.BlockChest; -import game.block.BlockSign; -import game.block.BlockSkull; -import game.collect.Lists; -import game.collect.Maps; -import game.collect.Sets; -import game.entity.Entity; -import game.entity.npc.EntityNPC; -import game.entity.projectile.EntityBox; -import game.entity.types.EntityLiving; -import game.material.Material; -import game.model.BlockLayer; -import game.rng.Random; -import game.sound.Sound; -import game.tileentity.TileEntity; -import game.tileentity.TileEntityChest; -import game.util.ExtMath; -import game.util.Vector3f; -import game.world.BlockPos; -import game.world.BoundingBox; -import game.world.Chunk; -import game.world.ClassInheritanceMultiMap; -import game.world.Facing; -import game.world.HitPosition; -import game.world.State; -import game.world.Vec3; -import game.world.WorldClient; +import common.block.Block; +import common.block.BlockChest; +import common.block.BlockSign; +import common.block.BlockSkull; +import common.collect.Lists; +import common.collect.Maps; +import common.collect.Sets; +import common.entity.Entity; +import common.entity.npc.EntityNPC; +import common.entity.projectile.EntityBox; +import common.entity.types.EntityLiving; +import common.material.Material; +import common.model.BlockLayer; +import common.rng.Random; +import common.sound.Sound; +import common.tileentity.TileEntity; +import common.tileentity.TileEntityChest; +import common.util.ExtMath; +import common.util.Vector3f; +import common.world.BlockPos; +import common.world.BoundingBox; +import common.world.Chunk; +import common.world.ClassInheritanceMultiMap; +import common.world.Facing; +import common.world.HitPosition; +import common.world.State; +import common.world.Vec3; +import common.world.WorldClient; public class RenderGlobal { diff --git a/client/src/client/renderer/VertexFormat.java b/client/src/client/renderer/VertexFormat.java index 8b06b07..d8c6e93 100755 --- a/client/src/client/renderer/VertexFormat.java +++ b/client/src/client/renderer/VertexFormat.java @@ -2,8 +2,8 @@ package client.renderer; import java.util.List; -import game.collect.Lists; -import game.log.Log; +import common.collect.Lists; +import common.log.Log; public class VertexFormat { diff --git a/client/src/client/renderer/VertexFormatElement.java b/client/src/client/renderer/VertexFormatElement.java index 3c19fca..4ff2116 100755 --- a/client/src/client/renderer/VertexFormatElement.java +++ b/client/src/client/renderer/VertexFormatElement.java @@ -2,7 +2,7 @@ package client.renderer; import org.lwjgl.opengl.GL11; -import game.log.Log; +import common.log.Log; public class VertexFormatElement { diff --git a/client/src/client/renderer/ViewFrustum.java b/client/src/client/renderer/ViewFrustum.java index 4b9856c..e4d4980 100755 --- a/client/src/client/renderer/ViewFrustum.java +++ b/client/src/client/renderer/ViewFrustum.java @@ -1,9 +1,9 @@ package client.renderer; import client.renderer.chunk.RenderChunk; -import game.util.ExtMath; -import game.world.BlockPos; -import game.world.World; +import common.util.ExtMath; +import common.world.BlockPos; +import common.world.World; public class ViewFrustum { diff --git a/client/src/client/renderer/blockmodel/BakedModel.java b/client/src/client/renderer/blockmodel/BakedModel.java index 9f4ed4c..5a25ef0 100755 --- a/client/src/client/renderer/blockmodel/BakedModel.java +++ b/client/src/client/renderer/blockmodel/BakedModel.java @@ -4,9 +4,9 @@ import java.util.ArrayList; import java.util.List; import client.renderer.texture.TextureAtlasSprite; -import game.collect.Lists; -import game.model.Transforms; -import game.world.Facing; +import common.collect.Lists; +import common.model.Transforms; +import common.world.Facing; public class BakedModel implements IBakedModel { diff --git a/client/src/client/renderer/blockmodel/BakedQuad.java b/client/src/client/renderer/blockmodel/BakedQuad.java index 50e1498..faefddb 100755 --- a/client/src/client/renderer/blockmodel/BakedQuad.java +++ b/client/src/client/renderer/blockmodel/BakedQuad.java @@ -1,6 +1,6 @@ package client.renderer.blockmodel; -import game.world.Facing; +import common.world.Facing; public class BakedQuad { protected final int[] data; diff --git a/client/src/client/renderer/blockmodel/BlockPart.java b/client/src/client/renderer/blockmodel/BlockPart.java index d52b5fd..f3a03e7 100755 --- a/client/src/client/renderer/blockmodel/BlockPart.java +++ b/client/src/client/renderer/blockmodel/BlockPart.java @@ -2,8 +2,8 @@ package client.renderer.blockmodel; import java.util.Map; -import game.util.Vector3f; -import game.world.Facing; +import common.util.Vector3f; +import common.world.Facing; public class BlockPart { diff --git a/client/src/client/renderer/blockmodel/BlockPartFace.java b/client/src/client/renderer/blockmodel/BlockPartFace.java index 601f36a..9d7e0fd 100755 --- a/client/src/client/renderer/blockmodel/BlockPartFace.java +++ b/client/src/client/renderer/blockmodel/BlockPartFace.java @@ -1,7 +1,7 @@ package client.renderer.blockmodel; import client.renderer.texture.TextureMap; -import game.world.Facing; +import common.world.Facing; public class BlockPartFace { public Facing cull; diff --git a/client/src/client/renderer/blockmodel/BlockPartRotation.java b/client/src/client/renderer/blockmodel/BlockPartRotation.java index 250034f..b3cfbea 100755 --- a/client/src/client/renderer/blockmodel/BlockPartRotation.java +++ b/client/src/client/renderer/blockmodel/BlockPartRotation.java @@ -1,7 +1,7 @@ package client.renderer.blockmodel; -import game.util.Vector3f; -import game.world.Facing; +import common.util.Vector3f; +import common.world.Facing; public class BlockPartRotation { public final Vector3f origin; diff --git a/client/src/client/renderer/blockmodel/BuiltInModel.java b/client/src/client/renderer/blockmodel/BuiltInModel.java index 4176e2c..7c9c306 100755 --- a/client/src/client/renderer/blockmodel/BuiltInModel.java +++ b/client/src/client/renderer/blockmodel/BuiltInModel.java @@ -3,8 +3,8 @@ package client.renderer.blockmodel; import java.util.List; import client.renderer.texture.TextureAtlasSprite; -import game.model.Transforms; -import game.world.Facing; +import common.model.Transforms; +import common.world.Facing; public class BuiltInModel implements IBakedModel { diff --git a/client/src/client/renderer/blockmodel/FaceBakery.java b/client/src/client/renderer/blockmodel/FaceBakery.java index 6576b8f..09fd515 100755 --- a/client/src/client/renderer/blockmodel/FaceBakery.java +++ b/client/src/client/renderer/blockmodel/FaceBakery.java @@ -1,13 +1,13 @@ package client.renderer.blockmodel; import client.renderer.texture.TextureAtlasSprite; -import game.model.ModelRotation; -import game.util.ExtMath; -import game.util.Matrix4f; -import game.util.Vector3f; -import game.util.Vector4f; -import game.world.Facing; -import game.world.Vec3i; +import common.model.ModelRotation; +import common.util.ExtMath; +import common.util.Matrix4f; +import common.util.Vector3f; +import common.util.Vector4f; +import common.world.Facing; +import common.world.Vec3i; public class FaceBakery { diff --git a/client/src/client/renderer/blockmodel/IBakedModel.java b/client/src/client/renderer/blockmodel/IBakedModel.java index 89db333..7e5b482 100755 --- a/client/src/client/renderer/blockmodel/IBakedModel.java +++ b/client/src/client/renderer/blockmodel/IBakedModel.java @@ -3,8 +3,8 @@ package client.renderer.blockmodel; import java.util.List; import client.renderer.texture.TextureAtlasSprite; -import game.model.Transforms; -import game.world.Facing; +import common.model.Transforms; +import common.world.Facing; public interface IBakedModel { diff --git a/client/src/client/renderer/blockmodel/ModelBakery.java b/client/src/client/renderer/blockmodel/ModelBakery.java index ea62808..ef9e54c 100755 --- a/client/src/client/renderer/blockmodel/ModelBakery.java +++ b/client/src/client/renderer/blockmodel/ModelBakery.java @@ -10,19 +10,19 @@ import java.util.Set; import client.renderer.texture.IIconCreator; import client.renderer.texture.TextureAtlasSprite; import client.renderer.texture.TextureMap; -import game.collect.Lists; -import game.collect.Maps; -import game.collect.Sets; -import game.init.BlockRegistry; -import game.init.FluidRegistry; -import game.init.IRegistry; -import game.init.ItemRegistry; -import game.init.RegistrySimple; -import game.item.Item; -import game.item.ItemStack; -import game.model.ModelRotation; -import game.world.Facing; -import game.world.State; +import common.collect.Lists; +import common.collect.Maps; +import common.collect.Sets; +import common.init.BlockRegistry; +import common.init.FluidRegistry; +import common.init.IRegistry; +import common.init.ItemRegistry; +import common.init.RegistrySimple; +import common.item.Item; +import common.item.ItemStack; +import common.model.ModelRotation; +import common.world.Facing; +import common.world.State; public abstract class ModelBakery { diff --git a/client/src/client/renderer/blockmodel/ModelBlock.java b/client/src/client/renderer/blockmodel/ModelBlock.java index c7e4400..c54e391 100755 --- a/client/src/client/renderer/blockmodel/ModelBlock.java +++ b/client/src/client/renderer/blockmodel/ModelBlock.java @@ -3,14 +3,14 @@ package client.renderer.blockmodel; import java.util.List; import client.renderer.texture.TextureMap; -import game.collect.Lists; -import game.collect.Maps; -import game.model.Model; -import game.model.ModelProvider; -import game.model.ModelRotation; -import game.model.Transforms; -import game.util.Vector3f; -import game.world.Facing; +import common.collect.Lists; +import common.collect.Maps; +import common.model.Model; +import common.model.ModelProvider; +import common.model.ModelRotation; +import common.model.Transforms; +import common.util.Vector3f; +import common.world.Facing; public class ModelBlock extends Model { static final ModelProvider PROVIDER = new ModelProvider() { diff --git a/client/src/client/renderer/blockmodel/ModelGenerator.java b/client/src/client/renderer/blockmodel/ModelGenerator.java index 60eb36b..178a13a 100755 --- a/client/src/client/renderer/blockmodel/ModelGenerator.java +++ b/client/src/client/renderer/blockmodel/ModelGenerator.java @@ -8,11 +8,11 @@ import client.renderer.model.ModelBox; import client.renderer.texture.TextureAtlasSprite; import client.renderer.texture.TextureMap; import client.renderer.texture.TextureUtil; -import game.collect.Lists; -import game.collect.Maps; -import game.log.Log; -import game.util.Vector3f; -import game.world.Facing; +import common.collect.Lists; +import common.collect.Maps; +import common.log.Log; +import common.util.Vector3f; +import common.world.Facing; public abstract class ModelGenerator { // public static final List LAYERS = Lists.newArrayList("layer0", "layer1", "layer2", "layer3", "layer4"); diff --git a/client/src/client/renderer/blockmodel/ModelManager.java b/client/src/client/renderer/blockmodel/ModelManager.java index a82aa95..810b25d 100755 --- a/client/src/client/renderer/blockmodel/ModelManager.java +++ b/client/src/client/renderer/blockmodel/ModelManager.java @@ -7,15 +7,15 @@ import java.util.Set; import client.renderer.texture.TextureAtlasSprite; import client.renderer.texture.TextureMap; -import game.block.Block; -import game.block.BlockLiquid; -import game.collect.Maps; -import game.init.BlockRegistry; -import game.init.Blocks; -import game.init.FluidRegistry; -import game.init.IRegistry; -import game.properties.IProperty; -import game.world.State; +import common.block.Block; +import common.block.BlockLiquid; +import common.collect.Maps; +import common.init.BlockRegistry; +import common.init.Blocks; +import common.init.FluidRegistry; +import common.init.IRegistry; +import common.properties.IProperty; +import common.world.State; public class ModelManager { diff --git a/client/src/client/renderer/blockmodel/MultiStateMap.java b/client/src/client/renderer/blockmodel/MultiStateMap.java index 667d3ad..1461f83 100755 --- a/client/src/client/renderer/blockmodel/MultiStateMap.java +++ b/client/src/client/renderer/blockmodel/MultiStateMap.java @@ -4,11 +4,11 @@ import java.util.Collections; import java.util.List; import java.util.Map; -import game.collect.Lists; -import game.collect.Maps; -import game.init.BlockRegistry; -import game.properties.IProperty; -import game.world.State; +import common.collect.Lists; +import common.collect.Maps; +import common.init.BlockRegistry; +import common.properties.IProperty; +import common.world.State; public class MultiStateMap extends StateMap { diff --git a/client/src/client/renderer/blockmodel/SingleStateMap.java b/client/src/client/renderer/blockmodel/SingleStateMap.java index 69c9880..6ad21d9 100755 --- a/client/src/client/renderer/blockmodel/SingleStateMap.java +++ b/client/src/client/renderer/blockmodel/SingleStateMap.java @@ -1,7 +1,7 @@ package client.renderer.blockmodel; -import game.init.BlockRegistry; -import game.world.State; +import common.init.BlockRegistry; +import common.world.State; public class SingleStateMap extends StateMap diff --git a/client/src/client/renderer/blockmodel/StateMap.java b/client/src/client/renderer/blockmodel/StateMap.java index ba64c28..d85f8a1 100755 --- a/client/src/client/renderer/blockmodel/StateMap.java +++ b/client/src/client/renderer/blockmodel/StateMap.java @@ -3,10 +3,10 @@ package client.renderer.blockmodel; import java.util.Map; import java.util.Map.Entry; -import game.block.Block; -import game.collect.Maps; -import game.properties.IProperty; -import game.world.State; +import common.block.Block; +import common.collect.Maps; +import common.properties.IProperty; +import common.world.State; public abstract class StateMap { diff --git a/client/src/client/renderer/chunk/ChunkCompileTaskGenerator.java b/client/src/client/renderer/chunk/ChunkCompileTaskGenerator.java index fb91119..d8244ea 100755 --- a/client/src/client/renderer/chunk/ChunkCompileTaskGenerator.java +++ b/client/src/client/renderer/chunk/ChunkCompileTaskGenerator.java @@ -4,7 +4,7 @@ import java.util.List; import java.util.concurrent.locks.ReentrantLock; import client.renderer.RegionRenderCacheBuilder; -import game.collect.Lists; +import common.collect.Lists; public class ChunkCompileTaskGenerator { diff --git a/client/src/client/renderer/chunk/ChunkRenderDispatcher.java b/client/src/client/renderer/chunk/ChunkRenderDispatcher.java index cf5f759..0258888 100755 --- a/client/src/client/renderer/chunk/ChunkRenderDispatcher.java +++ b/client/src/client/renderer/chunk/ChunkRenderDispatcher.java @@ -11,12 +11,12 @@ import client.Game; import client.renderer.RegionRenderCacheBuilder; import client.renderer.RenderBuffer; import client.renderer.VertexBuffer; -import game.collect.Lists; -import game.future.Futures; -import game.future.ListenableFuture; -import game.future.ListenableFutureTask; -import game.future.ThreadFactoryBuilder; -import game.model.BlockLayer; +import common.collect.Lists; +import common.future.Futures; +import common.future.ListenableFuture; +import common.future.ListenableFutureTask; +import common.future.ThreadFactoryBuilder; +import common.model.BlockLayer; public class ChunkRenderDispatcher { diff --git a/client/src/client/renderer/chunk/ChunkRenderWorker.java b/client/src/client/renderer/chunk/ChunkRenderWorker.java index 6c99786..c140f7d 100755 --- a/client/src/client/renderer/chunk/ChunkRenderWorker.java +++ b/client/src/client/renderer/chunk/ChunkRenderWorker.java @@ -6,13 +6,13 @@ import java.util.concurrent.CancellationException; import client.Game; import client.renderer.RegionRenderCacheBuilder; -import game.collect.Lists; -import game.entity.Entity; -import game.future.FutureCallback; -import game.future.Futures; -import game.future.ListenableFuture; -import game.log.Log; -import game.model.BlockLayer; +import common.collect.Lists; +import common.entity.Entity; +import common.future.FutureCallback; +import common.future.Futures; +import common.future.ListenableFuture; +import common.log.Log; +import common.model.BlockLayer; public class ChunkRenderWorker implements Runnable { diff --git a/client/src/client/renderer/chunk/CompiledChunk.java b/client/src/client/renderer/chunk/CompiledChunk.java index a9add33..bdd2a33 100755 --- a/client/src/client/renderer/chunk/CompiledChunk.java +++ b/client/src/client/renderer/chunk/CompiledChunk.java @@ -3,10 +3,10 @@ package client.renderer.chunk; import java.util.List; import client.renderer.RenderBuffer; -import game.collect.Lists; -import game.model.BlockLayer; -import game.tileentity.TileEntity; -import game.world.Facing; +import common.collect.Lists; +import common.model.BlockLayer; +import common.tileentity.TileEntity; +import common.world.Facing; public class CompiledChunk { diff --git a/client/src/client/renderer/chunk/RenderChunk.java b/client/src/client/renderer/chunk/RenderChunk.java index b2f8654..c014e18 100755 --- a/client/src/client/renderer/chunk/RenderChunk.java +++ b/client/src/client/renderer/chunk/RenderChunk.java @@ -19,16 +19,16 @@ import client.renderer.RenderGlobal; import client.renderer.VertexBuffer; import client.renderer.tileentity.TileEntityRendererDispatcher; import client.renderer.tileentity.TileEntitySpecialRenderer; -import game.block.Block; -import game.collect.Maps; -import game.collect.Sets; -import game.model.BlockLayer; -import game.tileentity.TileEntity; -import game.world.BlockPos; -import game.world.BoundingBox; -import game.world.Facing; -import game.world.State; -import game.world.World; +import common.block.Block; +import common.collect.Maps; +import common.collect.Sets; +import common.model.BlockLayer; +import common.tileentity.TileEntity; +import common.world.BlockPos; +import common.world.BoundingBox; +import common.world.Facing; +import common.world.State; +import common.world.World; public class RenderChunk { diff --git a/client/src/client/renderer/chunk/SetVisibility.java b/client/src/client/renderer/chunk/SetVisibility.java index 9071bb4..edbb073 100755 --- a/client/src/client/renderer/chunk/SetVisibility.java +++ b/client/src/client/renderer/chunk/SetVisibility.java @@ -3,7 +3,7 @@ package client.renderer.chunk; import java.util.BitSet; import java.util.Set; -import game.world.Facing; +import common.world.Facing; public class SetVisibility { diff --git a/client/src/client/renderer/chunk/VisGraph.java b/client/src/client/renderer/chunk/VisGraph.java index 8c6c300..2294ec1 100755 --- a/client/src/client/renderer/chunk/VisGraph.java +++ b/client/src/client/renderer/chunk/VisGraph.java @@ -6,8 +6,8 @@ import java.util.LinkedList; import java.util.Queue; import java.util.Set; -import game.world.BlockPos; -import game.world.Facing; +import common.world.BlockPos; +import common.world.Facing; public class VisGraph { diff --git a/client/src/client/renderer/entity/Render.java b/client/src/client/renderer/entity/Render.java index 3553c7a..74f181f 100755 --- a/client/src/client/renderer/entity/Render.java +++ b/client/src/client/renderer/entity/Render.java @@ -11,11 +11,11 @@ import client.renderer.RenderBuffer; import client.renderer.Tessellator; import client.renderer.texture.TextureAtlasSprite; import client.renderer.texture.TextureMap; -import game.block.Block; -import game.entity.Entity; -import game.world.BlockPos; -import game.world.BoundingBox; -import game.world.World; +import common.block.Block; +import common.entity.Entity; +import common.world.BlockPos; +import common.world.BoundingBox; +import common.world.World; public abstract class Render { diff --git a/client/src/client/renderer/entity/RenderArachnoid.java b/client/src/client/renderer/entity/RenderArachnoid.java index 34d54a2..1a35652 100755 --- a/client/src/client/renderer/entity/RenderArachnoid.java +++ b/client/src/client/renderer/entity/RenderArachnoid.java @@ -4,7 +4,7 @@ import org.lwjgl.opengl.GL11; import client.renderer.layers.LayerArachnoidArmor; import client.renderer.model.ModelArachnoid; -import game.entity.npc.EntityNPC; +import common.entity.npc.EntityNPC; public class RenderArachnoid extends RenderHumanoid diff --git a/client/src/client/renderer/entity/RenderArrow.java b/client/src/client/renderer/entity/RenderArrow.java index defe30b..59b26ab 100755 --- a/client/src/client/renderer/entity/RenderArrow.java +++ b/client/src/client/renderer/entity/RenderArrow.java @@ -6,8 +6,8 @@ import client.renderer.DefaultVertexFormats; import client.renderer.GlState; import client.renderer.RenderBuffer; import client.renderer.Tessellator; -import game.entity.projectile.EntityArrow; -import game.util.ExtMath; +import common.entity.projectile.EntityArrow; +import common.util.ExtMath; public class RenderArrow extends Render diff --git a/client/src/client/renderer/entity/RenderBat.java b/client/src/client/renderer/entity/RenderBat.java index 9aebbeb..0aa6c4a 100755 --- a/client/src/client/renderer/entity/RenderBat.java +++ b/client/src/client/renderer/entity/RenderBat.java @@ -3,8 +3,8 @@ package client.renderer.entity; import org.lwjgl.opengl.GL11; import client.renderer.model.ModelBat; -import game.entity.animal.EntityBat; -import game.util.ExtMath; +import common.entity.animal.EntityBat; +import common.util.ExtMath; public class RenderBat extends RenderLiving diff --git a/client/src/client/renderer/entity/RenderBlockEntity.java b/client/src/client/renderer/entity/RenderBlockEntity.java index d66f02e..1adf24c 100755 --- a/client/src/client/renderer/entity/RenderBlockEntity.java +++ b/client/src/client/renderer/entity/RenderBlockEntity.java @@ -5,8 +5,8 @@ import org.lwjgl.opengl.GL11; import client.Game; import client.renderer.BlockRenderer; import client.renderer.texture.TextureMap; -import game.entity.Entity; -import game.world.State; +import common.entity.Entity; +import common.world.State; public class RenderBlockEntity extends Render diff --git a/client/src/client/renderer/entity/RenderBoat.java b/client/src/client/renderer/entity/RenderBoat.java index dc07399..a9fafca 100755 --- a/client/src/client/renderer/entity/RenderBoat.java +++ b/client/src/client/renderer/entity/RenderBoat.java @@ -4,8 +4,8 @@ import org.lwjgl.opengl.GL11; import client.renderer.model.ModelBase; import client.renderer.model.ModelBoat; -import game.entity.item.EntityBoat; -import game.util.ExtMath; +import common.entity.item.EntityBoat; +import common.util.ExtMath; public class RenderBoat extends Render diff --git a/client/src/client/renderer/entity/RenderBullet.java b/client/src/client/renderer/entity/RenderBullet.java index db19e7a..c143312 100755 --- a/client/src/client/renderer/entity/RenderBullet.java +++ b/client/src/client/renderer/entity/RenderBullet.java @@ -6,7 +6,7 @@ import client.renderer.DefaultVertexFormats; import client.renderer.GlState; import client.renderer.RenderBuffer; import client.renderer.Tessellator; -import game.entity.projectile.EntityBullet; +import common.entity.projectile.EntityBullet; public class RenderBullet extends Render diff --git a/client/src/client/renderer/entity/RenderChicken.java b/client/src/client/renderer/entity/RenderChicken.java index f3ca5bb..9afeff9 100755 --- a/client/src/client/renderer/entity/RenderChicken.java +++ b/client/src/client/renderer/entity/RenderChicken.java @@ -1,8 +1,8 @@ package client.renderer.entity; import client.renderer.model.ModelBase; -import game.entity.animal.EntityChicken; -import game.util.ExtMath; +import common.entity.animal.EntityChicken; +import common.util.ExtMath; public class RenderChicken extends RenderLiving diff --git a/client/src/client/renderer/entity/RenderCow.java b/client/src/client/renderer/entity/RenderCow.java index 5fa89d7..b6280ab 100755 --- a/client/src/client/renderer/entity/RenderCow.java +++ b/client/src/client/renderer/entity/RenderCow.java @@ -1,7 +1,7 @@ package client.renderer.entity; import client.renderer.model.ModelBase; -import game.entity.animal.EntityCow; +import common.entity.animal.EntityCow; public class RenderCow extends RenderLiving diff --git a/client/src/client/renderer/entity/RenderCrystal.java b/client/src/client/renderer/entity/RenderCrystal.java index e2cafd5..d5642b1 100755 --- a/client/src/client/renderer/entity/RenderCrystal.java +++ b/client/src/client/renderer/entity/RenderCrystal.java @@ -4,8 +4,8 @@ import org.lwjgl.opengl.GL11; import client.renderer.model.ModelBase; import client.renderer.model.ModelCrystal; -import game.entity.item.EntityCrystal; -import game.util.ExtMath; +import common.entity.item.EntityCrystal; +import common.util.ExtMath; public class RenderCrystal extends Render diff --git a/client/src/client/renderer/entity/RenderDie.java b/client/src/client/renderer/entity/RenderDie.java index 005243d..51a6cf1 100755 --- a/client/src/client/renderer/entity/RenderDie.java +++ b/client/src/client/renderer/entity/RenderDie.java @@ -5,8 +5,8 @@ import org.lwjgl.opengl.GL11; import client.Game; import client.renderer.model.ModelDie; import client.renderer.texture.TextureMap; -import game.entity.projectile.EntityDie; -import game.model.Transforms.Camera; +import common.entity.projectile.EntityDie; +import common.model.Transforms.Camera; public class RenderDie extends Render { diff --git a/client/src/client/renderer/entity/RenderDragon.java b/client/src/client/renderer/entity/RenderDragon.java index 5195eb1..e76f636 100755 --- a/client/src/client/renderer/entity/RenderDragon.java +++ b/client/src/client/renderer/entity/RenderDragon.java @@ -5,8 +5,8 @@ import org.lwjgl.opengl.GL11; import client.renderer.GlState; import client.renderer.layers.LayerEnderDragonEyes; import client.renderer.model.ModelDragon; -import game.entity.animal.EntityDragon; -import game.util.ExtMath; +import common.entity.animal.EntityDragon; +import common.util.ExtMath; public class RenderDragon extends RenderLiving diff --git a/client/src/client/renderer/entity/RenderDynamite.java b/client/src/client/renderer/entity/RenderDynamite.java index 095e81c..376e2ae 100755 --- a/client/src/client/renderer/entity/RenderDynamite.java +++ b/client/src/client/renderer/entity/RenderDynamite.java @@ -1,8 +1,8 @@ package client.renderer.entity; -import game.entity.projectile.EntityDynamite; -import game.item.Item; -import game.item.ItemStack; +import common.entity.projectile.EntityDynamite; +import common.item.Item; +import common.item.ItemStack; public class RenderDynamite extends RenderItemEntity { public RenderDynamite(RenderManager renderManagerIn, Item itemIn, RenderItem renderItemIn) { diff --git a/client/src/client/renderer/entity/RenderEntity.java b/client/src/client/renderer/entity/RenderEntity.java index 35df7e4..40f7baa 100755 --- a/client/src/client/renderer/entity/RenderEntity.java +++ b/client/src/client/renderer/entity/RenderEntity.java @@ -2,7 +2,7 @@ package client.renderer.entity; import org.lwjgl.opengl.GL11; -import game.entity.Entity; +import common.entity.Entity; public class RenderEntity extends Render diff --git a/client/src/client/renderer/entity/RenderEntityItem.java b/client/src/client/renderer/entity/RenderEntityItem.java index 4afd417..21e8fd5 100755 --- a/client/src/client/renderer/entity/RenderEntityItem.java +++ b/client/src/client/renderer/entity/RenderEntityItem.java @@ -5,12 +5,12 @@ import org.lwjgl.opengl.GL11; import client.renderer.GlState; import client.renderer.blockmodel.IBakedModel; import client.renderer.texture.TextureMap; -import game.entity.item.EntityItem; -import game.item.Item; -import game.item.ItemStack; -import game.model.Transforms; -import game.rng.Random; -import game.util.ExtMath; +import common.entity.item.EntityItem; +import common.item.Item; +import common.item.ItemStack; +import common.model.Transforms; +import common.rng.Random; +import common.util.ExtMath; public class RenderEntityItem extends Render { diff --git a/client/src/client/renderer/entity/RenderFallingBlock.java b/client/src/client/renderer/entity/RenderFallingBlock.java index 0693bff..5f12f22 100755 --- a/client/src/client/renderer/entity/RenderFallingBlock.java +++ b/client/src/client/renderer/entity/RenderFallingBlock.java @@ -10,11 +10,11 @@ import client.renderer.RenderBuffer; import client.renderer.Tessellator; import client.renderer.blockmodel.IBakedModel; import client.renderer.texture.TextureMap; -import game.block.Block; -import game.entity.item.EntityFalling; -import game.world.BlockPos; -import game.world.State; -import game.world.World; +import common.block.Block; +import common.entity.item.EntityFalling; +import common.world.BlockPos; +import common.world.State; +import common.world.World; public class RenderFallingBlock extends Render { diff --git a/client/src/client/renderer/entity/RenderFireball.java b/client/src/client/renderer/entity/RenderFireball.java index 378780c..4431da3 100755 --- a/client/src/client/renderer/entity/RenderFireball.java +++ b/client/src/client/renderer/entity/RenderFireball.java @@ -9,8 +9,8 @@ import client.renderer.RenderBuffer; import client.renderer.Tessellator; import client.renderer.texture.TextureAtlasSprite; import client.renderer.texture.TextureMap; -import game.entity.projectile.EntityProjectile; -import game.init.Items; +import common.entity.projectile.EntityProjectile; +import common.init.Items; public class RenderFireball extends Render diff --git a/client/src/client/renderer/entity/RenderFish.java b/client/src/client/renderer/entity/RenderFish.java index e2c3b7d..c9537ab 100755 --- a/client/src/client/renderer/entity/RenderFish.java +++ b/client/src/client/renderer/entity/RenderFish.java @@ -8,9 +8,9 @@ import client.renderer.GlState; import client.renderer.RenderBuffer; import client.renderer.Tessellator; import client.renderer.particle.EffectRenderer; -import game.entity.projectile.EntityHook; -import game.util.ExtMath; -import game.world.Vec3; +import common.entity.projectile.EntityHook; +import common.util.ExtMath; +import common.world.Vec3; public class RenderFish extends Render { diff --git a/client/src/client/renderer/entity/RenderFlyingBox.java b/client/src/client/renderer/entity/RenderFlyingBox.java index 0b974a0..a8518c5 100755 --- a/client/src/client/renderer/entity/RenderFlyingBox.java +++ b/client/src/client/renderer/entity/RenderFlyingBox.java @@ -4,7 +4,7 @@ import org.lwjgl.opengl.GL11; import client.renderer.GlState; import client.renderer.model.ModelHead; -import game.entity.projectile.EntityBox; +import common.entity.projectile.EntityBox; public class RenderFlyingBox extends Render diff --git a/client/src/client/renderer/entity/RenderHorse.java b/client/src/client/renderer/entity/RenderHorse.java index 2c062fa..46a3ff9 100755 --- a/client/src/client/renderer/entity/RenderHorse.java +++ b/client/src/client/renderer/entity/RenderHorse.java @@ -7,8 +7,8 @@ import org.lwjgl.opengl.GL11; import client.Game; import client.renderer.model.ModelHorse; import client.renderer.texture.LayeredTexture; -import game.collect.Sets; -import game.entity.animal.EntityHorse; +import common.collect.Sets; +import common.entity.animal.EntityHorse; public class RenderHorse extends RenderLiving { diff --git a/client/src/client/renderer/entity/RenderHumanoid.java b/client/src/client/renderer/entity/RenderHumanoid.java index 6815f32..04e767e 100755 --- a/client/src/client/renderer/entity/RenderHumanoid.java +++ b/client/src/client/renderer/entity/RenderHumanoid.java @@ -13,9 +13,9 @@ import client.renderer.layers.LayerPowerRods; import client.renderer.model.ModelBiped; import client.renderer.model.ModelHumanoid; import client.renderer.texture.EntityTexManager; -import game.entity.npc.EntityNPC; -import game.item.ItemAction; -import game.item.ItemStack; +import common.entity.npc.EntityNPC; +import common.item.ItemAction; +import common.item.ItemStack; public class RenderHumanoid extends RenderNpc diff --git a/client/src/client/renderer/entity/RenderItem.java b/client/src/client/renderer/entity/RenderItem.java index 336ac19..b881350 100755 --- a/client/src/client/renderer/entity/RenderItem.java +++ b/client/src/client/renderer/entity/RenderItem.java @@ -15,15 +15,15 @@ import client.renderer.blockmodel.ModelManager; import client.renderer.texture.TextureManager; import client.renderer.texture.TextureMap; import client.renderer.tileentity.TileEntityItemStackRenderer; -import game.entity.npc.EntityNPC; -import game.entity.types.EntityLiving; -import game.init.Items; -import game.item.Item; -import game.item.ItemStack; -import game.model.Transform; -import game.model.Transforms; -import game.world.Facing; -import game.world.Vec3i; +import common.entity.npc.EntityNPC; +import common.entity.types.EntityLiving; +import common.init.Items; +import common.item.Item; +import common.item.ItemStack; +import common.model.Transform; +import common.model.Transforms; +import common.world.Facing; +import common.world.Vec3i; public class RenderItem { diff --git a/client/src/client/renderer/entity/RenderItemEntity.java b/client/src/client/renderer/entity/RenderItemEntity.java index d7c1108..41da344 100755 --- a/client/src/client/renderer/entity/RenderItemEntity.java +++ b/client/src/client/renderer/entity/RenderItemEntity.java @@ -4,10 +4,10 @@ import org.lwjgl.opengl.GL11; import client.renderer.GlState; import client.renderer.texture.TextureMap; -import game.entity.Entity; -import game.item.Item; -import game.item.ItemStack; -import game.model.Transforms; +import common.entity.Entity; +import common.item.Item; +import common.item.ItemStack; +import common.model.Transforms; public class RenderItemEntity extends Render diff --git a/client/src/client/renderer/entity/RenderLeashKnot.java b/client/src/client/renderer/entity/RenderLeashKnot.java index cd89065..9a03683 100755 --- a/client/src/client/renderer/entity/RenderLeashKnot.java +++ b/client/src/client/renderer/entity/RenderLeashKnot.java @@ -4,7 +4,7 @@ import org.lwjgl.opengl.GL11; import client.renderer.GlState; import client.renderer.model.ModelLeashKnot; -import game.entity.item.EntityLeashKnot; +import common.entity.item.EntityLeashKnot; public class RenderLeashKnot extends Render diff --git a/client/src/client/renderer/entity/RenderLightning.java b/client/src/client/renderer/entity/RenderLightning.java index f4a77ec..3cf3319 100755 --- a/client/src/client/renderer/entity/RenderLightning.java +++ b/client/src/client/renderer/entity/RenderLightning.java @@ -6,8 +6,8 @@ import client.renderer.DefaultVertexFormats; import client.renderer.GlState; import client.renderer.RenderBuffer; import client.renderer.Tessellator; -import game.entity.effect.EntityLightning; -import game.rng.Random; +import common.entity.effect.EntityLightning; +import common.rng.Random; public class RenderLightning extends Render diff --git a/client/src/client/renderer/entity/RenderLiving.java b/client/src/client/renderer/entity/RenderLiving.java index bb75233..4e308dd 100755 --- a/client/src/client/renderer/entity/RenderLiving.java +++ b/client/src/client/renderer/entity/RenderLiving.java @@ -9,9 +9,9 @@ import client.renderer.GlState; import client.renderer.RenderBuffer; import client.renderer.Tessellator; import client.renderer.model.ModelBase; -import game.entity.Entity; -import game.entity.item.EntityLeashKnot; -import game.entity.types.EntityLiving; +import common.entity.Entity; +import common.entity.item.EntityLeashKnot; +import common.entity.types.EntityLiving; public abstract class RenderLiving extends RendererLivingEntity { public RenderLiving(RenderManager manager, ModelBase model) { diff --git a/client/src/client/renderer/entity/RenderManager.java b/client/src/client/renderer/entity/RenderManager.java index 3fb1186..f88738d 100755 --- a/client/src/client/renderer/entity/RenderManager.java +++ b/client/src/client/renderer/entity/RenderManager.java @@ -13,13 +13,13 @@ import client.renderer.RenderBuffer; import client.renderer.RenderGlobal; import client.renderer.Tessellator; import client.renderer.texture.TextureManager; -import game.collect.Maps; -import game.entity.Entity; -import game.entity.types.EntityLiving; -import game.init.SpeciesRegistry.ModelType; -import game.world.BoundingBox; -import game.world.Vec3; -import game.world.World; +import common.collect.Maps; +import common.entity.Entity; +import common.entity.types.EntityLiving; +import common.init.SpeciesRegistry.ModelType; +import common.world.BoundingBox; +import common.world.Vec3; +import common.world.World; public class RenderManager { diff --git a/client/src/client/renderer/entity/RenderMinecart.java b/client/src/client/renderer/entity/RenderMinecart.java index c3256d1..24255f9 100755 --- a/client/src/client/renderer/entity/RenderMinecart.java +++ b/client/src/client/renderer/entity/RenderMinecart.java @@ -7,10 +7,10 @@ import client.renderer.GlState; import client.renderer.model.ModelBase; import client.renderer.model.ModelMinecart; import client.renderer.texture.TextureMap; -import game.entity.item.EntityCart; -import game.util.ExtMath; -import game.world.State; -import game.world.Vec3; +import common.entity.item.EntityCart; +import common.util.ExtMath; +import common.world.State; +import common.world.Vec3; public class RenderMinecart extends Render { diff --git a/client/src/client/renderer/entity/RenderMooshroom.java b/client/src/client/renderer/entity/RenderMooshroom.java index 878c203..28793f3 100755 --- a/client/src/client/renderer/entity/RenderMooshroom.java +++ b/client/src/client/renderer/entity/RenderMooshroom.java @@ -2,7 +2,7 @@ package client.renderer.entity; import client.renderer.layers.LayerMooshroomMushroom; import client.renderer.model.ModelBase; -import game.entity.animal.EntityMooshroom; +import common.entity.animal.EntityMooshroom; public class RenderMooshroom extends RenderLiving diff --git a/client/src/client/renderer/entity/RenderMouse.java b/client/src/client/renderer/entity/RenderMouse.java index 3fa6ad3..5c266dd 100755 --- a/client/src/client/renderer/entity/RenderMouse.java +++ b/client/src/client/renderer/entity/RenderMouse.java @@ -1,7 +1,7 @@ package client.renderer.entity; import client.renderer.model.ModelBase; -import game.entity.animal.EntityMouse; +import common.entity.animal.EntityMouse; public class RenderMouse extends RenderLiving diff --git a/client/src/client/renderer/entity/RenderNpc.java b/client/src/client/renderer/entity/RenderNpc.java index 8fee9dc..7462455 100755 --- a/client/src/client/renderer/entity/RenderNpc.java +++ b/client/src/client/renderer/entity/RenderNpc.java @@ -4,8 +4,8 @@ import java.util.ArrayList; import client.renderer.model.ModelBase; import client.renderer.texture.EntityTexManager; -import game.entity.npc.EntityNPC; -import game.network.IPlayer; +import common.entity.npc.EntityNPC; +import common.network.IPlayer; public abstract class RenderNpc extends RenderLiving diff --git a/client/src/client/renderer/entity/RenderOcelot.java b/client/src/client/renderer/entity/RenderOcelot.java index 2fd5203..09edb56 100755 --- a/client/src/client/renderer/entity/RenderOcelot.java +++ b/client/src/client/renderer/entity/RenderOcelot.java @@ -3,7 +3,7 @@ package client.renderer.entity; import org.lwjgl.opengl.GL11; import client.renderer.model.ModelBase; -import game.entity.animal.EntityOcelot; +import common.entity.animal.EntityOcelot; public class RenderOcelot extends RenderLiving diff --git a/client/src/client/renderer/entity/RenderPig.java b/client/src/client/renderer/entity/RenderPig.java index 8b821da..be614ee 100755 --- a/client/src/client/renderer/entity/RenderPig.java +++ b/client/src/client/renderer/entity/RenderPig.java @@ -2,7 +2,7 @@ package client.renderer.entity; import client.renderer.layers.LayerSaddle; import client.renderer.model.ModelBase; -import game.entity.animal.EntityPig; +import common.entity.animal.EntityPig; public class RenderPig extends RenderLiving diff --git a/client/src/client/renderer/entity/RenderPotion.java b/client/src/client/renderer/entity/RenderPotion.java index cb574bf..4256783 100755 --- a/client/src/client/renderer/entity/RenderPotion.java +++ b/client/src/client/renderer/entity/RenderPotion.java @@ -1,8 +1,8 @@ package client.renderer.entity; -import game.entity.projectile.EntityPotion; -import game.init.Items; -import game.item.ItemStack; +import common.entity.projectile.EntityPotion; +import common.init.Items; +import common.item.ItemStack; public class RenderPotion extends RenderItemEntity { diff --git a/client/src/client/renderer/entity/RenderRabbit.java b/client/src/client/renderer/entity/RenderRabbit.java index fbb7c7e..7527e5a 100755 --- a/client/src/client/renderer/entity/RenderRabbit.java +++ b/client/src/client/renderer/entity/RenderRabbit.java @@ -1,8 +1,8 @@ package client.renderer.entity; import client.renderer.model.ModelBase; -import game.color.TextColor; -import game.entity.animal.EntityRabbit; +import common.color.TextColor; +import common.entity.animal.EntityRabbit; public class RenderRabbit extends RenderLiving { diff --git a/client/src/client/renderer/entity/RenderSheep.java b/client/src/client/renderer/entity/RenderSheep.java index 01cad8d..c9277db 100755 --- a/client/src/client/renderer/entity/RenderSheep.java +++ b/client/src/client/renderer/entity/RenderSheep.java @@ -2,7 +2,7 @@ package client.renderer.entity; import client.renderer.layers.LayerSheepWool; import client.renderer.model.ModelBase; -import game.entity.animal.EntitySheep; +import common.entity.animal.EntitySheep; public class RenderSheep extends RenderLiving diff --git a/client/src/client/renderer/entity/RenderSlime.java b/client/src/client/renderer/entity/RenderSlime.java index c3ff29f..e76df43 100755 --- a/client/src/client/renderer/entity/RenderSlime.java +++ b/client/src/client/renderer/entity/RenderSlime.java @@ -4,8 +4,8 @@ import org.lwjgl.opengl.GL11; import client.renderer.layers.LayerSlimeGel; import client.renderer.model.ModelSlime; -import game.entity.npc.EntityNPC; -import game.entity.npc.EntitySlime; +import common.entity.npc.EntityNPC; +import common.entity.npc.EntitySlime; public class RenderSlime extends RenderNpc diff --git a/client/src/client/renderer/entity/RenderSpaceMarine.java b/client/src/client/renderer/entity/RenderSpaceMarine.java index bad1b01..864b24c 100755 --- a/client/src/client/renderer/entity/RenderSpaceMarine.java +++ b/client/src/client/renderer/entity/RenderSpaceMarine.java @@ -5,9 +5,9 @@ import org.lwjgl.opengl.GL11; import client.renderer.layers.LayerArrow; import client.renderer.layers.LayerHeldItem; import client.renderer.model.ModelSpaceMarine; -import game.entity.npc.EntityNPC; -import game.item.ItemAction; -import game.item.ItemStack; +import common.entity.npc.EntityNPC; +import common.item.ItemAction; +import common.item.ItemStack; public class RenderSpaceMarine extends RenderNpc diff --git a/client/src/client/renderer/entity/RenderSquid.java b/client/src/client/renderer/entity/RenderSquid.java index c09b1cf..15f3c96 100755 --- a/client/src/client/renderer/entity/RenderSquid.java +++ b/client/src/client/renderer/entity/RenderSquid.java @@ -3,7 +3,7 @@ package client.renderer.entity; import org.lwjgl.opengl.GL11; import client.renderer.model.ModelBase; -import game.entity.animal.EntitySquid; +import common.entity.animal.EntitySquid; public class RenderSquid extends RenderLiving diff --git a/client/src/client/renderer/entity/RenderTntMinecart.java b/client/src/client/renderer/entity/RenderTntMinecart.java index 5150ccf..2a9413e 100755 --- a/client/src/client/renderer/entity/RenderTntMinecart.java +++ b/client/src/client/renderer/entity/RenderTntMinecart.java @@ -5,10 +5,10 @@ import org.lwjgl.opengl.GL11; import client.Game; import client.renderer.BlockRenderer; import client.renderer.GlState; -import game.entity.item.EntityTntCart; -import game.init.Blocks; -import game.util.ExtMath; -import game.world.State; +import common.entity.item.EntityTntCart; +import common.init.Blocks; +import common.util.ExtMath; +import common.world.State; public class RenderTntMinecart extends RenderMinecart { diff --git a/client/src/client/renderer/entity/RenderTntPrimed.java b/client/src/client/renderer/entity/RenderTntPrimed.java index 5edf422..0c339de 100755 --- a/client/src/client/renderer/entity/RenderTntPrimed.java +++ b/client/src/client/renderer/entity/RenderTntPrimed.java @@ -6,10 +6,10 @@ import client.Game; import client.renderer.BlockRenderer; import client.renderer.GlState; import client.renderer.texture.TextureMap; -import game.block.BlockTNT; -import game.entity.item.EntityTnt; -import game.init.Blocks; -import game.util.ExtMath; +import common.block.BlockTNT; +import common.entity.item.EntityTnt; +import common.init.Blocks; +import common.util.ExtMath; public class RenderTntPrimed extends Render diff --git a/client/src/client/renderer/entity/RenderWolf.java b/client/src/client/renderer/entity/RenderWolf.java index 8831285..3fb1bf1 100755 --- a/client/src/client/renderer/entity/RenderWolf.java +++ b/client/src/client/renderer/entity/RenderWolf.java @@ -3,7 +3,7 @@ package client.renderer.entity; import client.renderer.GlState; import client.renderer.layers.LayerWolfCollar; import client.renderer.model.ModelBase; -import game.entity.animal.EntityWolf; +import common.entity.animal.EntityWolf; public class RenderWolf extends RenderLiving diff --git a/client/src/client/renderer/entity/RenderXpOrb.java b/client/src/client/renderer/entity/RenderXpOrb.java index c9e7d69..815456d 100755 --- a/client/src/client/renderer/entity/RenderXpOrb.java +++ b/client/src/client/renderer/entity/RenderXpOrb.java @@ -7,8 +7,8 @@ import client.renderer.DefaultVertexFormats; import client.renderer.GlState; import client.renderer.RenderBuffer; import client.renderer.Tessellator; -import game.entity.item.EntityXp; -import game.util.ExtMath; +import common.entity.item.EntityXp; +import common.util.ExtMath; public class RenderXpOrb extends Render diff --git a/client/src/client/renderer/entity/RendererLivingEntity.java b/client/src/client/renderer/entity/RendererLivingEntity.java index 880ec72..e8df489 100755 --- a/client/src/client/renderer/entity/RendererLivingEntity.java +++ b/client/src/client/renderer/entity/RendererLivingEntity.java @@ -16,14 +16,14 @@ import client.renderer.Tessellator; import client.renderer.layers.LayerRenderer; import client.renderer.model.ModelBase; import client.renderer.texture.DynamicTexture; -import game.collect.Lists; -import game.color.TextColor; -import game.entity.Entity; -import game.entity.item.EntityCrystal; -import game.entity.types.EntityAnimal; -import game.entity.types.EntityLiving; -import game.log.Log; -import game.util.ExtMath; +import common.collect.Lists; +import common.color.TextColor; +import common.entity.Entity; +import common.entity.item.EntityCrystal; +import common.entity.types.EntityAnimal; +import common.entity.types.EntityLiving; +import common.log.Log; +import common.util.ExtMath; public abstract class RendererLivingEntity extends Render { diff --git a/client/src/client/renderer/layers/LayerArmor.java b/client/src/client/renderer/layers/LayerArmor.java index 98d402b..35f1280 100755 --- a/client/src/client/renderer/layers/LayerArmor.java +++ b/client/src/client/renderer/layers/LayerArmor.java @@ -6,9 +6,9 @@ import client.renderer.GlState; import client.renderer.entity.RendererLivingEntity; import client.renderer.model.ModelArmor; import client.renderer.model.ModelBiped; -import game.entity.types.EntityLiving; -import game.item.ItemArmor; -import game.item.ItemStack; +import common.entity.types.EntityLiving; +import common.item.ItemArmor; +import common.item.ItemStack; public class LayerArmor implements LayerRenderer { diff --git a/client/src/client/renderer/layers/LayerArrow.java b/client/src/client/renderer/layers/LayerArrow.java index a16d5a4..6fa6589 100755 --- a/client/src/client/renderer/layers/LayerArrow.java +++ b/client/src/client/renderer/layers/LayerArrow.java @@ -6,11 +6,11 @@ import client.renderer.ItemRenderer; import client.renderer.entity.RendererLivingEntity; import client.renderer.model.ModelBox; import client.renderer.model.ModelRenderer; -import game.entity.Entity; -import game.entity.projectile.EntityArrow; -import game.entity.types.EntityLiving; -import game.rng.Random; -import game.util.ExtMath; +import common.entity.Entity; +import common.entity.projectile.EntityArrow; +import common.entity.types.EntityLiving; +import common.rng.Random; +import common.util.ExtMath; public class LayerArrow implements LayerRenderer { diff --git a/client/src/client/renderer/layers/LayerCape.java b/client/src/client/renderer/layers/LayerCape.java index ba3bbb9..495e678 100755 --- a/client/src/client/renderer/layers/LayerCape.java +++ b/client/src/client/renderer/layers/LayerCape.java @@ -6,8 +6,8 @@ import client.renderer.GlState; import client.renderer.entity.RenderHumanoid; import client.renderer.model.ModelRenderer; import client.renderer.texture.EntityTexManager; -import game.entity.npc.EntityNPC; -import game.util.ExtMath; +import common.entity.npc.EntityNPC; +import common.util.ExtMath; public class LayerCape implements LayerRenderer { diff --git a/client/src/client/renderer/layers/LayerCharge.java b/client/src/client/renderer/layers/LayerCharge.java index 64aa253..2bc6578 100755 --- a/client/src/client/renderer/layers/LayerCharge.java +++ b/client/src/client/renderer/layers/LayerCharge.java @@ -5,7 +5,7 @@ import org.lwjgl.opengl.GL11; import client.renderer.GlState; import client.renderer.entity.RenderHumanoid; import client.renderer.model.ModelCharge; -import game.entity.npc.EntityNPC; +import common.entity.npc.EntityNPC; public class LayerCharge implements LayerRenderer diff --git a/client/src/client/renderer/layers/LayerEnderDragonEyes.java b/client/src/client/renderer/layers/LayerEnderDragonEyes.java index 2fed9da..7fb6b27 100755 --- a/client/src/client/renderer/layers/LayerEnderDragonEyes.java +++ b/client/src/client/renderer/layers/LayerEnderDragonEyes.java @@ -5,7 +5,7 @@ import org.lwjgl.opengl.GL13; import client.renderer.GlState; import client.renderer.entity.RenderDragon; -import game.entity.animal.EntityDragon; +import common.entity.animal.EntityDragon; public class LayerEnderDragonEyes implements LayerRenderer diff --git a/client/src/client/renderer/layers/LayerEntityBreak.java b/client/src/client/renderer/layers/LayerEntityBreak.java index 5d64665..a705c6d 100755 --- a/client/src/client/renderer/layers/LayerEntityBreak.java +++ b/client/src/client/renderer/layers/LayerEntityBreak.java @@ -7,8 +7,8 @@ import client.renderer.GlState; import client.renderer.ItemRenderer; import client.renderer.RenderBuffer; import client.renderer.Tessellator; -import game.entity.animal.EntityDragon; -import game.rng.Random; +import common.entity.animal.EntityDragon; +import common.rng.Random; public class LayerEntityBreak implements LayerRenderer { diff --git a/client/src/client/renderer/layers/LayerExtra.java b/client/src/client/renderer/layers/LayerExtra.java index 75c168b..0364213 100755 --- a/client/src/client/renderer/layers/LayerExtra.java +++ b/client/src/client/renderer/layers/LayerExtra.java @@ -11,9 +11,9 @@ import client.renderer.model.ModelBox; import client.renderer.model.ModelHumanoid; import client.renderer.model.ModelRenderer; import client.renderer.texture.EntityTexManager; -import game.collect.Lists; -import game.entity.npc.EntityNPC; -import game.init.SpeciesRegistry.ModelType; +import common.collect.Lists; +import common.entity.npc.EntityNPC; +import common.init.SpeciesRegistry.ModelType; public class LayerExtra implements LayerRenderer { diff --git a/client/src/client/renderer/layers/LayerHeldItem.java b/client/src/client/renderer/layers/LayerHeldItem.java index 0c46471..97dc2ad 100755 --- a/client/src/client/renderer/layers/LayerHeldItem.java +++ b/client/src/client/renderer/layers/LayerHeldItem.java @@ -5,13 +5,13 @@ import org.lwjgl.opengl.GL11; import client.Game; import client.renderer.entity.RendererLivingEntity; import client.renderer.model.ModelBiped; -import game.entity.npc.EntityNPC; -import game.entity.types.EntityLiving; -import game.init.Items; -import game.item.Item; -import game.item.ItemBlock; -import game.item.ItemStack; -import game.model.Transforms; +import common.entity.npc.EntityNPC; +import common.entity.types.EntityLiving; +import common.init.Items; +import common.item.Item; +import common.item.ItemBlock; +import common.item.ItemStack; +import common.model.Transforms; public class LayerHeldItem implements LayerRenderer { diff --git a/client/src/client/renderer/layers/LayerMooshroomMushroom.java b/client/src/client/renderer/layers/LayerMooshroomMushroom.java index dd45eab..cc5291f 100755 --- a/client/src/client/renderer/layers/LayerMooshroomMushroom.java +++ b/client/src/client/renderer/layers/LayerMooshroomMushroom.java @@ -8,8 +8,8 @@ import client.renderer.GlState; import client.renderer.entity.RenderMooshroom; import client.renderer.model.ModelQuadruped; import client.renderer.texture.TextureMap; -import game.entity.animal.EntityMooshroom; -import game.init.Blocks; +import common.entity.animal.EntityMooshroom; +import common.init.Blocks; public class LayerMooshroomMushroom implements LayerRenderer { diff --git a/client/src/client/renderer/layers/LayerPowerRods.java b/client/src/client/renderer/layers/LayerPowerRods.java index dae23aa..54b45a4 100755 --- a/client/src/client/renderer/layers/LayerPowerRods.java +++ b/client/src/client/renderer/layers/LayerPowerRods.java @@ -3,8 +3,8 @@ package client.renderer.layers; import client.renderer.GlState; import client.renderer.entity.RenderHumanoid; import client.renderer.model.ModelRenderer; -import game.entity.npc.EntityNPC; -import game.util.ExtMath; +import common.entity.npc.EntityNPC; +import common.util.ExtMath; public class LayerPowerRods implements LayerRenderer { diff --git a/client/src/client/renderer/layers/LayerRenderer.java b/client/src/client/renderer/layers/LayerRenderer.java index 6a5c439..dd5905e 100755 --- a/client/src/client/renderer/layers/LayerRenderer.java +++ b/client/src/client/renderer/layers/LayerRenderer.java @@ -1,6 +1,6 @@ package client.renderer.layers; -import game.entity.types.EntityLiving; +import common.entity.types.EntityLiving; public interface LayerRenderer { diff --git a/client/src/client/renderer/layers/LayerSaddle.java b/client/src/client/renderer/layers/LayerSaddle.java index 4432dc8..ce30c6b 100755 --- a/client/src/client/renderer/layers/LayerSaddle.java +++ b/client/src/client/renderer/layers/LayerSaddle.java @@ -2,7 +2,7 @@ package client.renderer.layers; import client.renderer.entity.RenderPig; import client.renderer.model.ModelPig; -import game.entity.animal.EntityPig; +import common.entity.animal.EntityPig; public class LayerSaddle implements LayerRenderer diff --git a/client/src/client/renderer/layers/LayerSheepWool.java b/client/src/client/renderer/layers/LayerSheepWool.java index 5f2efeb..dd1022c 100755 --- a/client/src/client/renderer/layers/LayerSheepWool.java +++ b/client/src/client/renderer/layers/LayerSheepWool.java @@ -3,7 +3,7 @@ package client.renderer.layers; import client.renderer.GlState; import client.renderer.entity.RenderSheep; import client.renderer.model.ModelSheep1; -import game.entity.animal.EntitySheep; +import common.entity.animal.EntitySheep; public class LayerSheepWool implements LayerRenderer diff --git a/client/src/client/renderer/layers/LayerSlimeGel.java b/client/src/client/renderer/layers/LayerSlimeGel.java index 9e16e9f..7cf892a 100755 --- a/client/src/client/renderer/layers/LayerSlimeGel.java +++ b/client/src/client/renderer/layers/LayerSlimeGel.java @@ -6,7 +6,7 @@ import client.renderer.GlState; import client.renderer.entity.RenderSlime; import client.renderer.model.ModelBase; import client.renderer.model.ModelSlime; -import game.entity.npc.EntityNPC; +import common.entity.npc.EntityNPC; public class LayerSlimeGel implements LayerRenderer { diff --git a/client/src/client/renderer/layers/LayerWolfCollar.java b/client/src/client/renderer/layers/LayerWolfCollar.java index 42301f8..7d07d87 100755 --- a/client/src/client/renderer/layers/LayerWolfCollar.java +++ b/client/src/client/renderer/layers/LayerWolfCollar.java @@ -2,9 +2,9 @@ package client.renderer.layers; import client.renderer.GlState; import client.renderer.entity.RenderWolf; -import game.color.DyeColor; -import game.entity.animal.EntitySheep; -import game.entity.animal.EntityWolf; +import common.color.DyeColor; +import common.entity.animal.EntitySheep; +import common.entity.animal.EntityWolf; public class LayerWolfCollar implements LayerRenderer diff --git a/client/src/client/renderer/model/ModelArachnoid.java b/client/src/client/renderer/model/ModelArachnoid.java index 609be74..e828555 100755 --- a/client/src/client/renderer/model/ModelArachnoid.java +++ b/client/src/client/renderer/model/ModelArachnoid.java @@ -2,8 +2,8 @@ package client.renderer.model; import org.lwjgl.opengl.GL11; -import game.entity.Entity; -import game.util.ExtMath; +import common.entity.Entity; +import common.util.ExtMath; public class ModelArachnoid extends ModelHumanoid { diff --git a/client/src/client/renderer/model/ModelBase.java b/client/src/client/renderer/model/ModelBase.java index bb98213..f8f65af 100755 --- a/client/src/client/renderer/model/ModelBase.java +++ b/client/src/client/renderer/model/ModelBase.java @@ -3,11 +3,11 @@ package client.renderer.model; import java.util.List; import java.util.Map; -import game.collect.Lists; -import game.collect.Maps; -import game.entity.Entity; -import game.entity.types.EntityLiving; -import game.rng.Random; +import common.collect.Lists; +import common.collect.Maps; +import common.entity.Entity; +import common.entity.types.EntityLiving; +import common.rng.Random; public abstract class ModelBase { diff --git a/client/src/client/renderer/model/ModelBat.java b/client/src/client/renderer/model/ModelBat.java index 43edc45..80a5c31 100755 --- a/client/src/client/renderer/model/ModelBat.java +++ b/client/src/client/renderer/model/ModelBat.java @@ -1,8 +1,8 @@ package client.renderer.model; -import game.entity.Entity; -import game.entity.animal.EntityBat; -import game.util.ExtMath; +import common.entity.Entity; +import common.entity.animal.EntityBat; +import common.util.ExtMath; public class ModelBat extends ModelBase { diff --git a/client/src/client/renderer/model/ModelBiped.java b/client/src/client/renderer/model/ModelBiped.java index fc2e8ee..32801ca 100755 --- a/client/src/client/renderer/model/ModelBiped.java +++ b/client/src/client/renderer/model/ModelBiped.java @@ -2,9 +2,9 @@ package client.renderer.model; import org.lwjgl.opengl.GL11; -import game.entity.Entity; -import game.entity.types.EntityLiving; -import game.util.ExtMath; +import common.entity.Entity; +import common.entity.types.EntityLiving; +import common.util.ExtMath; public abstract class ModelBiped extends ModelBase { diff --git a/client/src/client/renderer/model/ModelBoat.java b/client/src/client/renderer/model/ModelBoat.java index 0d18951..34a15e4 100755 --- a/client/src/client/renderer/model/ModelBoat.java +++ b/client/src/client/renderer/model/ModelBoat.java @@ -1,6 +1,6 @@ package client.renderer.model; -import game.entity.Entity; +import common.entity.Entity; public class ModelBoat extends ModelBase { diff --git a/client/src/client/renderer/model/ModelBox.java b/client/src/client/renderer/model/ModelBox.java index 5e3c4c5..091e341 100755 --- a/client/src/client/renderer/model/ModelBox.java +++ b/client/src/client/renderer/model/ModelBox.java @@ -1,8 +1,8 @@ package client.renderer.model; import client.renderer.RenderBuffer; -import game.world.Facing; -import game.world.Vec3; +import common.world.Facing; +import common.world.Vec3; public class ModelBox { private static Vec3[] getPoints(float x1, float y1, float z1, float x2, float y2, float z2, int dir) { diff --git a/client/src/client/renderer/model/ModelCharge.java b/client/src/client/renderer/model/ModelCharge.java index c0bf14d..3f5def9 100755 --- a/client/src/client/renderer/model/ModelCharge.java +++ b/client/src/client/renderer/model/ModelCharge.java @@ -1,6 +1,6 @@ package client.renderer.model; -import game.entity.Entity; +import common.entity.Entity; public class ModelCharge extends ModelBase { diff --git a/client/src/client/renderer/model/ModelChicken.java b/client/src/client/renderer/model/ModelChicken.java index 736fe95..57e7a9f 100755 --- a/client/src/client/renderer/model/ModelChicken.java +++ b/client/src/client/renderer/model/ModelChicken.java @@ -2,8 +2,8 @@ package client.renderer.model; import org.lwjgl.opengl.GL11; -import game.entity.Entity; -import game.util.ExtMath; +import common.entity.Entity; +import common.util.ExtMath; public class ModelChicken extends ModelBase { diff --git a/client/src/client/renderer/model/ModelCrystal.java b/client/src/client/renderer/model/ModelCrystal.java index 3dc7814..9074211 100755 --- a/client/src/client/renderer/model/ModelCrystal.java +++ b/client/src/client/renderer/model/ModelCrystal.java @@ -2,7 +2,7 @@ package client.renderer.model; import org.lwjgl.opengl.GL11; -import game.entity.Entity; +import common.entity.Entity; public class ModelCrystal extends ModelBase { diff --git a/client/src/client/renderer/model/ModelDie.java b/client/src/client/renderer/model/ModelDie.java index 32c8838..0f99092 100755 --- a/client/src/client/renderer/model/ModelDie.java +++ b/client/src/client/renderer/model/ModelDie.java @@ -2,7 +2,7 @@ package client.renderer.model; import org.lwjgl.opengl.GL11; -import game.entity.Entity; +import common.entity.Entity; public class ModelDie extends ModelBase { diff --git a/client/src/client/renderer/model/ModelDragon.java b/client/src/client/renderer/model/ModelDragon.java index 6da7183..a4d0f76 100755 --- a/client/src/client/renderer/model/ModelDragon.java +++ b/client/src/client/renderer/model/ModelDragon.java @@ -3,9 +3,9 @@ package client.renderer.model; import org.lwjgl.opengl.GL11; import client.renderer.GlState; -import game.entity.Entity; -import game.entity.animal.EntityDragon; -import game.entity.types.EntityLiving; +import common.entity.Entity; +import common.entity.animal.EntityDragon; +import common.entity.types.EntityLiving; public class ModelDragon extends ModelBase { diff --git a/client/src/client/renderer/model/ModelHead.java b/client/src/client/renderer/model/ModelHead.java index 457e44c..7f0c6f5 100755 --- a/client/src/client/renderer/model/ModelHead.java +++ b/client/src/client/renderer/model/ModelHead.java @@ -1,6 +1,6 @@ package client.renderer.model; -import game.entity.Entity; +import common.entity.Entity; public class ModelHead extends ModelBase { diff --git a/client/src/client/renderer/model/ModelHorse.java b/client/src/client/renderer/model/ModelHorse.java index 36035bb..9dc1003 100755 --- a/client/src/client/renderer/model/ModelHorse.java +++ b/client/src/client/renderer/model/ModelHorse.java @@ -2,10 +2,10 @@ package client.renderer.model; import org.lwjgl.opengl.GL11; -import game.entity.Entity; -import game.entity.animal.EntityHorse; -import game.entity.types.EntityLiving; -import game.util.ExtMath; +import common.entity.Entity; +import common.entity.animal.EntityHorse; +import common.entity.types.EntityLiving; +import common.util.ExtMath; public class ModelHorse extends ModelBase { diff --git a/client/src/client/renderer/model/ModelHumanoid.java b/client/src/client/renderer/model/ModelHumanoid.java index 73a6c39..df8f4fb 100755 --- a/client/src/client/renderer/model/ModelHumanoid.java +++ b/client/src/client/renderer/model/ModelHumanoid.java @@ -2,8 +2,8 @@ package client.renderer.model; import org.lwjgl.opengl.GL11; -import game.entity.Entity; -import game.util.ExtMath; +import common.entity.Entity; +import common.util.ExtMath; public class ModelHumanoid extends ModelBiped { diff --git a/client/src/client/renderer/model/ModelHumanoidHead.java b/client/src/client/renderer/model/ModelHumanoidHead.java index e7ae14e..6e787e5 100755 --- a/client/src/client/renderer/model/ModelHumanoidHead.java +++ b/client/src/client/renderer/model/ModelHumanoidHead.java @@ -1,6 +1,6 @@ package client.renderer.model; -import game.entity.Entity; +import common.entity.Entity; public class ModelHumanoidHead extends ModelHead { diff --git a/client/src/client/renderer/model/ModelLeashKnot.java b/client/src/client/renderer/model/ModelLeashKnot.java index 3a9e4bb..c2a413c 100755 --- a/client/src/client/renderer/model/ModelLeashKnot.java +++ b/client/src/client/renderer/model/ModelLeashKnot.java @@ -1,6 +1,6 @@ package client.renderer.model; -import game.entity.Entity; +import common.entity.Entity; public class ModelLeashKnot extends ModelBase { diff --git a/client/src/client/renderer/model/ModelMinecart.java b/client/src/client/renderer/model/ModelMinecart.java index ffef2fd..cba48c6 100755 --- a/client/src/client/renderer/model/ModelMinecart.java +++ b/client/src/client/renderer/model/ModelMinecart.java @@ -1,6 +1,6 @@ package client.renderer.model; -import game.entity.Entity; +import common.entity.Entity; public class ModelMinecart extends ModelBase { diff --git a/client/src/client/renderer/model/ModelMouse.java b/client/src/client/renderer/model/ModelMouse.java index 0671240..5cc4e06 100755 --- a/client/src/client/renderer/model/ModelMouse.java +++ b/client/src/client/renderer/model/ModelMouse.java @@ -2,9 +2,9 @@ package client.renderer.model; import org.lwjgl.opengl.GL11; -import game.entity.Entity; -import game.entity.types.EntityLiving; -import game.util.ExtMath; +import common.entity.Entity; +import common.entity.types.EntityLiving; +import common.util.ExtMath; public class ModelMouse extends ModelBase { diff --git a/client/src/client/renderer/model/ModelOcelot.java b/client/src/client/renderer/model/ModelOcelot.java index 82f27aa..e7765ca 100755 --- a/client/src/client/renderer/model/ModelOcelot.java +++ b/client/src/client/renderer/model/ModelOcelot.java @@ -2,10 +2,10 @@ package client.renderer.model; import org.lwjgl.opengl.GL11; -import game.entity.Entity; -import game.entity.animal.EntityOcelot; -import game.entity.types.EntityLiving; -import game.util.ExtMath; +import common.entity.Entity; +import common.entity.animal.EntityOcelot; +import common.entity.types.EntityLiving; +import common.util.ExtMath; public class ModelOcelot extends ModelBase { diff --git a/client/src/client/renderer/model/ModelQuadruped.java b/client/src/client/renderer/model/ModelQuadruped.java index e8be36c..c608f36 100755 --- a/client/src/client/renderer/model/ModelQuadruped.java +++ b/client/src/client/renderer/model/ModelQuadruped.java @@ -2,8 +2,8 @@ package client.renderer.model; import org.lwjgl.opengl.GL11; -import game.entity.Entity; -import game.util.ExtMath; +import common.entity.Entity; +import common.util.ExtMath; public class ModelQuadruped extends ModelBase { diff --git a/client/src/client/renderer/model/ModelRabbit.java b/client/src/client/renderer/model/ModelRabbit.java index 3b383c0..71e7fff 100755 --- a/client/src/client/renderer/model/ModelRabbit.java +++ b/client/src/client/renderer/model/ModelRabbit.java @@ -2,10 +2,10 @@ package client.renderer.model; import org.lwjgl.opengl.GL11; -import game.entity.Entity; -import game.entity.animal.EntityRabbit; -import game.entity.types.EntityLiving; -import game.util.ExtMath; +import common.entity.Entity; +import common.entity.animal.EntityRabbit; +import common.entity.types.EntityLiving; +import common.util.ExtMath; public class ModelRabbit extends ModelBase { private final ModelRenderer rabbitLeftFoot; diff --git a/client/src/client/renderer/model/ModelRenderer.java b/client/src/client/renderer/model/ModelRenderer.java index 3931a59..330ff92 100755 --- a/client/src/client/renderer/model/ModelRenderer.java +++ b/client/src/client/renderer/model/ModelRenderer.java @@ -6,7 +6,7 @@ import org.lwjgl.opengl.GL11; import client.renderer.RenderBuffer; import client.renderer.Tessellator; -import game.collect.Lists; +import common.collect.Lists; public class ModelRenderer { diff --git a/client/src/client/renderer/model/ModelSheep1.java b/client/src/client/renderer/model/ModelSheep1.java index fda7fb9..e25a89c 100755 --- a/client/src/client/renderer/model/ModelSheep1.java +++ b/client/src/client/renderer/model/ModelSheep1.java @@ -1,8 +1,8 @@ package client.renderer.model; -import game.entity.Entity; -import game.entity.animal.EntitySheep; -import game.entity.types.EntityLiving; +import common.entity.Entity; +import common.entity.animal.EntitySheep; +import common.entity.types.EntityLiving; public class ModelSheep1 extends ModelQuadruped { diff --git a/client/src/client/renderer/model/ModelSheep2.java b/client/src/client/renderer/model/ModelSheep2.java index 3ac1c98..510f948 100755 --- a/client/src/client/renderer/model/ModelSheep2.java +++ b/client/src/client/renderer/model/ModelSheep2.java @@ -1,8 +1,8 @@ package client.renderer.model; -import game.entity.Entity; -import game.entity.animal.EntitySheep; -import game.entity.types.EntityLiving; +import common.entity.Entity; +import common.entity.animal.EntitySheep; +import common.entity.types.EntityLiving; public class ModelSheep2 extends ModelQuadruped { diff --git a/client/src/client/renderer/model/ModelSlime.java b/client/src/client/renderer/model/ModelSlime.java index 8994594..2363426 100755 --- a/client/src/client/renderer/model/ModelSlime.java +++ b/client/src/client/renderer/model/ModelSlime.java @@ -1,6 +1,6 @@ package client.renderer.model; -import game.entity.Entity; +import common.entity.Entity; public class ModelSlime extends ModelBase { diff --git a/client/src/client/renderer/model/ModelSquid.java b/client/src/client/renderer/model/ModelSquid.java index 22242f9..5db6680 100755 --- a/client/src/client/renderer/model/ModelSquid.java +++ b/client/src/client/renderer/model/ModelSquid.java @@ -1,6 +1,6 @@ package client.renderer.model; -import game.entity.Entity; +import common.entity.Entity; public class ModelSquid extends ModelBase { diff --git a/client/src/client/renderer/model/ModelWolf.java b/client/src/client/renderer/model/ModelWolf.java index efa86d1..7bb6909 100755 --- a/client/src/client/renderer/model/ModelWolf.java +++ b/client/src/client/renderer/model/ModelWolf.java @@ -2,10 +2,10 @@ package client.renderer.model; import org.lwjgl.opengl.GL11; -import game.entity.Entity; -import game.entity.animal.EntityWolf; -import game.entity.types.EntityLiving; -import game.util.ExtMath; +import common.entity.Entity; +import common.entity.animal.EntityWolf; +import common.entity.types.EntityLiving; +import common.util.ExtMath; public class ModelWolf extends ModelBase { diff --git a/client/src/client/renderer/model/PositionTextureVertex.java b/client/src/client/renderer/model/PositionTextureVertex.java index f18ca99..8346105 100755 --- a/client/src/client/renderer/model/PositionTextureVertex.java +++ b/client/src/client/renderer/model/PositionTextureVertex.java @@ -1,6 +1,6 @@ package client.renderer.model; -import game.world.Vec3; +import common.world.Vec3; public class PositionTextureVertex { diff --git a/client/src/client/renderer/model/TexturedQuad.java b/client/src/client/renderer/model/TexturedQuad.java index b3b012d..53ec9a5 100755 --- a/client/src/client/renderer/model/TexturedQuad.java +++ b/client/src/client/renderer/model/TexturedQuad.java @@ -5,7 +5,7 @@ import org.lwjgl.opengl.GL11; import client.renderer.DefaultVertexFormats; import client.renderer.RenderBuffer; import client.renderer.Tessellator; -import game.world.Vec3; +import common.world.Vec3; public class TexturedQuad { diff --git a/client/src/client/renderer/particle/EffectRenderer.java b/client/src/client/renderer/particle/EffectRenderer.java index ac369e3..c1624c4 100755 --- a/client/src/client/renderer/particle/EffectRenderer.java +++ b/client/src/client/renderer/particle/EffectRenderer.java @@ -12,18 +12,18 @@ import client.renderer.RenderBuffer; import client.renderer.Tessellator; import client.renderer.texture.TextureManager; import client.renderer.texture.TextureMap; -import game.block.Block; -import game.collect.Lists; -import game.collect.Maps; -import game.entity.Entity; -import game.material.Material; -import game.model.ParticleType; -import game.rng.Random; -import game.util.ExtMath; -import game.world.BlockPos; -import game.world.Facing; -import game.world.State; -import game.world.World; +import common.block.Block; +import common.collect.Lists; +import common.collect.Maps; +import common.entity.Entity; +import common.material.Material; +import common.model.ParticleType; +import common.rng.Random; +import common.util.ExtMath; +import common.world.BlockPos; +import common.world.Facing; +import common.world.State; +import common.world.World; public class EffectRenderer { diff --git a/client/src/client/renderer/particle/EntityAuraFX.java b/client/src/client/renderer/particle/EntityAuraFX.java index d69be96..1240fb8 100755 --- a/client/src/client/renderer/particle/EntityAuraFX.java +++ b/client/src/client/renderer/particle/EntityAuraFX.java @@ -1,6 +1,6 @@ package client.renderer.particle; -import game.world.World; +import common.world.World; public class EntityAuraFX extends EntityFX { diff --git a/client/src/client/renderer/particle/EntityBlockDustFX.java b/client/src/client/renderer/particle/EntityBlockDustFX.java index f1fdce7..cc6f805 100755 --- a/client/src/client/renderer/particle/EntityBlockDustFX.java +++ b/client/src/client/renderer/particle/EntityBlockDustFX.java @@ -1,8 +1,8 @@ package client.renderer.particle; -import game.init.BlockRegistry; -import game.world.State; -import game.world.World; +import common.init.BlockRegistry; +import common.world.State; +import common.world.World; public class EntityBlockDustFX extends EntityDiggingFX { diff --git a/client/src/client/renderer/particle/EntityBreakingFX.java b/client/src/client/renderer/particle/EntityBreakingFX.java index 1982a28..dbd35f0 100755 --- a/client/src/client/renderer/particle/EntityBreakingFX.java +++ b/client/src/client/renderer/particle/EntityBreakingFX.java @@ -2,11 +2,11 @@ package client.renderer.particle; import client.Game; import client.renderer.RenderBuffer; -import game.entity.Entity; -import game.init.ItemRegistry; -import game.init.Items; -import game.item.Item; -import game.world.World; +import common.entity.Entity; +import common.init.ItemRegistry; +import common.init.Items; +import common.item.Item; +import common.world.World; public class EntityBreakingFX extends EntityFX { diff --git a/client/src/client/renderer/particle/EntityBubbleFX.java b/client/src/client/renderer/particle/EntityBubbleFX.java index 072304b..c21ba62 100755 --- a/client/src/client/renderer/particle/EntityBubbleFX.java +++ b/client/src/client/renderer/particle/EntityBubbleFX.java @@ -1,8 +1,8 @@ package client.renderer.particle; -import game.material.Material; -import game.world.BlockPos; -import game.world.World; +import common.material.Material; +import common.world.BlockPos; +import common.world.World; public class EntityBubbleFX extends EntityFX { diff --git a/client/src/client/renderer/particle/EntityCloudFX.java b/client/src/client/renderer/particle/EntityCloudFX.java index 39baf00..4b46bf9 100755 --- a/client/src/client/renderer/particle/EntityCloudFX.java +++ b/client/src/client/renderer/particle/EntityCloudFX.java @@ -1,10 +1,10 @@ package client.renderer.particle; import client.renderer.RenderBuffer; -import game.entity.Entity; -import game.entity.npc.EntityNPC; -import game.util.ExtMath; -import game.world.World; +import common.entity.Entity; +import common.entity.npc.EntityNPC; +import common.util.ExtMath; +import common.world.World; public class EntityCloudFX extends EntityFX { diff --git a/client/src/client/renderer/particle/EntityCrit2FX.java b/client/src/client/renderer/particle/EntityCrit2FX.java index 49a03c0..e021842 100755 --- a/client/src/client/renderer/particle/EntityCrit2FX.java +++ b/client/src/client/renderer/particle/EntityCrit2FX.java @@ -1,9 +1,9 @@ package client.renderer.particle; import client.renderer.RenderBuffer; -import game.entity.Entity; -import game.util.ExtMath; -import game.world.World; +import common.entity.Entity; +import common.util.ExtMath; +import common.world.World; public class EntityCrit2FX extends EntityFX { diff --git a/client/src/client/renderer/particle/EntityCritFX.java b/client/src/client/renderer/particle/EntityCritFX.java index 743c0b3..2e224cc 100755 --- a/client/src/client/renderer/particle/EntityCritFX.java +++ b/client/src/client/renderer/particle/EntityCritFX.java @@ -1,6 +1,6 @@ package client.renderer.particle; -import game.world.World; +import common.world.World; public class EntityCritFX extends EntitySmokeFX { diff --git a/client/src/client/renderer/particle/EntityDiggingFX.java b/client/src/client/renderer/particle/EntityDiggingFX.java index ace9f1b..8e3e89d 100755 --- a/client/src/client/renderer/particle/EntityDiggingFX.java +++ b/client/src/client/renderer/particle/EntityDiggingFX.java @@ -2,13 +2,13 @@ package client.renderer.particle; import client.Game; import client.renderer.RenderBuffer; -import game.block.Block; -import game.entity.Entity; -import game.init.BlockRegistry; -import game.init.Blocks; -import game.world.BlockPos; -import game.world.State; -import game.world.World; +import common.block.Block; +import common.entity.Entity; +import common.init.BlockRegistry; +import common.init.Blocks; +import common.world.BlockPos; +import common.world.State; +import common.world.World; public class EntityDiggingFX extends EntityFX { diff --git a/client/src/client/renderer/particle/EntityDownfallFX.java b/client/src/client/renderer/particle/EntityDownfallFX.java index 8da5ea6..c321d6b 100755 --- a/client/src/client/renderer/particle/EntityDownfallFX.java +++ b/client/src/client/renderer/particle/EntityDownfallFX.java @@ -1,12 +1,12 @@ package client.renderer.particle; -import game.block.Block; -import game.block.BlockLiquid; -import game.material.Material; -import game.util.ExtMath; -import game.world.BlockPos; -import game.world.State; -import game.world.World; +import common.block.Block; +import common.block.BlockLiquid; +import common.material.Material; +import common.util.ExtMath; +import common.world.BlockPos; +import common.world.State; +import common.world.World; public class EntityDownfallFX extends EntityFX { diff --git a/client/src/client/renderer/particle/EntityDropParticleFX.java b/client/src/client/renderer/particle/EntityDropParticleFX.java index 0b47971..8409e31 100755 --- a/client/src/client/renderer/particle/EntityDropParticleFX.java +++ b/client/src/client/renderer/particle/EntityDropParticleFX.java @@ -1,12 +1,12 @@ package client.renderer.particle; -import game.block.BlockLiquid; -import game.material.Material; -import game.model.ParticleType; -import game.util.ExtMath; -import game.world.BlockPos; -import game.world.State; -import game.world.World; +import common.block.BlockLiquid; +import common.material.Material; +import common.model.ParticleType; +import common.util.ExtMath; +import common.world.BlockPos; +import common.world.State; +import common.world.World; public class EntityDropParticleFX extends EntityFX { diff --git a/client/src/client/renderer/particle/EntityEnchantmentTableParticleFX.java b/client/src/client/renderer/particle/EntityEnchantmentTableParticleFX.java index b50ae80..b337bc0 100755 --- a/client/src/client/renderer/particle/EntityEnchantmentTableParticleFX.java +++ b/client/src/client/renderer/particle/EntityEnchantmentTableParticleFX.java @@ -1,6 +1,6 @@ package client.renderer.particle; -import game.world.World; +import common.world.World; public class EntityEnchantmentTableParticleFX extends EntityFX { diff --git a/client/src/client/renderer/particle/EntityExplodeFX.java b/client/src/client/renderer/particle/EntityExplodeFX.java index d12c6cf..fcf1d11 100755 --- a/client/src/client/renderer/particle/EntityExplodeFX.java +++ b/client/src/client/renderer/particle/EntityExplodeFX.java @@ -1,6 +1,6 @@ package client.renderer.particle; -import game.world.World; +import common.world.World; public class EntityExplodeFX extends EntityFX { diff --git a/client/src/client/renderer/particle/EntityFX.java b/client/src/client/renderer/particle/EntityFX.java index 78f154d..c3066fe 100755 --- a/client/src/client/renderer/particle/EntityFX.java +++ b/client/src/client/renderer/particle/EntityFX.java @@ -3,12 +3,12 @@ package client.renderer.particle; import client.Game; import client.renderer.RenderBuffer; import client.renderer.texture.TextureAtlasSprite; -import game.entity.Entity; -import game.entity.EntityType; -import game.entity.types.IEntityFX; -import game.nbt.NBTTagCompound; -import game.util.ExtMath; -import game.world.World; +import common.entity.Entity; +import common.entity.EntityType; +import common.entity.types.IEntityFX; +import common.nbt.NBTTagCompound; +import common.util.ExtMath; +import common.world.World; public class EntityFX extends Entity implements IEntityFX { diff --git a/client/src/client/renderer/particle/EntityFirework.java b/client/src/client/renderer/particle/EntityFirework.java index 042242e..078c6fc 100755 --- a/client/src/client/renderer/particle/EntityFirework.java +++ b/client/src/client/renderer/particle/EntityFirework.java @@ -2,15 +2,15 @@ package client.renderer.particle; import client.Game; import client.renderer.RenderBuffer; -import game.entity.Entity; -import game.init.SoundEvent; -import game.item.ItemDye; -import game.nbt.NBTTagCompound; -import game.nbt.NBTTagList; -import game.util.ExtMath; -import game.world.BoundingBox; -import game.world.World; -import game.world.WorldClient; +import common.entity.Entity; +import common.init.SoundEvent; +import common.item.ItemDye; +import common.nbt.NBTTagCompound; +import common.nbt.NBTTagList; +import common.util.ExtMath; +import common.world.BoundingBox; +import common.world.World; +import common.world.WorldClient; public class EntityFirework { diff --git a/client/src/client/renderer/particle/EntityFishWakeFX.java b/client/src/client/renderer/particle/EntityFishWakeFX.java index 35207c5..c120d5e 100755 --- a/client/src/client/renderer/particle/EntityFishWakeFX.java +++ b/client/src/client/renderer/particle/EntityFishWakeFX.java @@ -1,6 +1,6 @@ package client.renderer.particle; -import game.world.World; +import common.world.World; public class EntityFishWakeFX extends EntityFX { diff --git a/client/src/client/renderer/particle/EntityFlameFX.java b/client/src/client/renderer/particle/EntityFlameFX.java index 6ad5901..462370d 100755 --- a/client/src/client/renderer/particle/EntityFlameFX.java +++ b/client/src/client/renderer/particle/EntityFlameFX.java @@ -1,9 +1,9 @@ package client.renderer.particle; import client.renderer.RenderBuffer; -import game.entity.Entity; -import game.util.ExtMath; -import game.world.World; +import common.entity.Entity; +import common.util.ExtMath; +import common.world.World; public class EntityFlameFX extends EntityFX { diff --git a/client/src/client/renderer/particle/EntityFootStepFX.java b/client/src/client/renderer/particle/EntityFootStepFX.java index 9fc77a5..d8d47e9 100755 --- a/client/src/client/renderer/particle/EntityFootStepFX.java +++ b/client/src/client/renderer/particle/EntityFootStepFX.java @@ -8,9 +8,9 @@ import client.renderer.GlState; import client.renderer.RenderBuffer; import client.renderer.Tessellator; import client.renderer.texture.TextureManager; -import game.entity.Entity; -import game.world.BlockPos; -import game.world.World; +import common.entity.Entity; +import common.world.BlockPos; +import common.world.World; public class EntityFootStepFX extends EntityFX { diff --git a/client/src/client/renderer/particle/EntityHeartFX.java b/client/src/client/renderer/particle/EntityHeartFX.java index 45effe6..f048950 100755 --- a/client/src/client/renderer/particle/EntityHeartFX.java +++ b/client/src/client/renderer/particle/EntityHeartFX.java @@ -1,9 +1,9 @@ package client.renderer.particle; import client.renderer.RenderBuffer; -import game.entity.Entity; -import game.util.ExtMath; -import game.world.World; +import common.entity.Entity; +import common.util.ExtMath; +import common.world.World; public class EntityHeartFX extends EntityFX { diff --git a/client/src/client/renderer/particle/EntityHugeExplodeFX.java b/client/src/client/renderer/particle/EntityHugeExplodeFX.java index 42cd4a8..7f287b9 100755 --- a/client/src/client/renderer/particle/EntityHugeExplodeFX.java +++ b/client/src/client/renderer/particle/EntityHugeExplodeFX.java @@ -1,9 +1,9 @@ package client.renderer.particle; import client.renderer.RenderBuffer; -import game.entity.Entity; -import game.model.ParticleType; -import game.world.World; +import common.entity.Entity; +import common.model.ParticleType; +import common.world.World; public class EntityHugeExplodeFX extends EntityFX { diff --git a/client/src/client/renderer/particle/EntityLargeExplodeFX.java b/client/src/client/renderer/particle/EntityLargeExplodeFX.java index 04a509a..e4bdfd5 100755 --- a/client/src/client/renderer/particle/EntityLargeExplodeFX.java +++ b/client/src/client/renderer/particle/EntityLargeExplodeFX.java @@ -10,8 +10,8 @@ import client.renderer.RenderBuffer; import client.renderer.Tessellator; import client.renderer.VertexFormat; import client.renderer.texture.TextureManager; -import game.entity.Entity; -import game.world.World; +import common.entity.Entity; +import common.world.World; public class EntityLargeExplodeFX extends EntityFX { diff --git a/client/src/client/renderer/particle/EntityLavaFX.java b/client/src/client/renderer/particle/EntityLavaFX.java index 869b753..bd823f0 100755 --- a/client/src/client/renderer/particle/EntityLavaFX.java +++ b/client/src/client/renderer/particle/EntityLavaFX.java @@ -1,10 +1,10 @@ package client.renderer.particle; import client.renderer.RenderBuffer; -import game.entity.Entity; -import game.model.ParticleType; -import game.util.ExtMath; -import game.world.World; +import common.entity.Entity; +import common.model.ParticleType; +import common.util.ExtMath; +import common.world.World; public class EntityLavaFX extends EntityFX { diff --git a/client/src/client/renderer/particle/EntityNoteFX.java b/client/src/client/renderer/particle/EntityNoteFX.java index cdb1373..2bfa850 100755 --- a/client/src/client/renderer/particle/EntityNoteFX.java +++ b/client/src/client/renderer/particle/EntityNoteFX.java @@ -1,9 +1,9 @@ package client.renderer.particle; import client.renderer.RenderBuffer; -import game.entity.Entity; -import game.util.ExtMath; -import game.world.World; +import common.entity.Entity; +import common.util.ExtMath; +import common.world.World; public class EntityNoteFX extends EntityFX { diff --git a/client/src/client/renderer/particle/EntityParticleEmitter.java b/client/src/client/renderer/particle/EntityParticleEmitter.java index 8a19ef4..262871b 100755 --- a/client/src/client/renderer/particle/EntityParticleEmitter.java +++ b/client/src/client/renderer/particle/EntityParticleEmitter.java @@ -1,10 +1,10 @@ package client.renderer.particle; import client.renderer.RenderBuffer; -import game.entity.Entity; -import game.model.ParticleType; -import game.world.World; -import game.world.WorldClient; +import common.entity.Entity; +import common.model.ParticleType; +import common.world.World; +import common.world.WorldClient; public class EntityParticleEmitter extends EntityFX { diff --git a/client/src/client/renderer/particle/EntityPickupFX.java b/client/src/client/renderer/particle/EntityPickupFX.java index 9ff6b8b..a9b68b5 100755 --- a/client/src/client/renderer/particle/EntityPickupFX.java +++ b/client/src/client/renderer/particle/EntityPickupFX.java @@ -6,8 +6,8 @@ import client.Game; import client.renderer.GlState; import client.renderer.RenderBuffer; import client.renderer.entity.RenderManager; -import game.entity.Entity; -import game.world.World; +import common.entity.Entity; +import common.world.World; public class EntityPickupFX extends EntityFX { diff --git a/client/src/client/renderer/particle/EntityPortalFX.java b/client/src/client/renderer/particle/EntityPortalFX.java index 712f4d9..3c5dd59 100755 --- a/client/src/client/renderer/particle/EntityPortalFX.java +++ b/client/src/client/renderer/particle/EntityPortalFX.java @@ -1,8 +1,8 @@ package client.renderer.particle; import client.renderer.RenderBuffer; -import game.entity.Entity; -import game.world.World; +import common.entity.Entity; +import common.world.World; public class EntityPortalFX extends EntityFX { diff --git a/client/src/client/renderer/particle/EntityReddustFX.java b/client/src/client/renderer/particle/EntityReddustFX.java index c88dece..f89e164 100755 --- a/client/src/client/renderer/particle/EntityReddustFX.java +++ b/client/src/client/renderer/particle/EntityReddustFX.java @@ -1,9 +1,9 @@ package client.renderer.particle; import client.renderer.RenderBuffer; -import game.entity.Entity; -import game.util.ExtMath; -import game.world.World; +import common.entity.Entity; +import common.util.ExtMath; +import common.world.World; public class EntityReddustFX extends EntityFX { diff --git a/client/src/client/renderer/particle/EntitySmokeFX.java b/client/src/client/renderer/particle/EntitySmokeFX.java index 63f85dd..5566bf2 100755 --- a/client/src/client/renderer/particle/EntitySmokeFX.java +++ b/client/src/client/renderer/particle/EntitySmokeFX.java @@ -1,9 +1,9 @@ package client.renderer.particle; import client.renderer.RenderBuffer; -import game.entity.Entity; -import game.util.ExtMath; -import game.world.World; +import common.entity.Entity; +import common.util.ExtMath; +import common.world.World; public class EntitySmokeFX extends EntityFX { diff --git a/client/src/client/renderer/particle/EntitySnowShovelFX.java b/client/src/client/renderer/particle/EntitySnowShovelFX.java index 5d83213..ff9e9fa 100755 --- a/client/src/client/renderer/particle/EntitySnowShovelFX.java +++ b/client/src/client/renderer/particle/EntitySnowShovelFX.java @@ -1,9 +1,9 @@ package client.renderer.particle; import client.renderer.RenderBuffer; -import game.entity.Entity; -import game.util.ExtMath; -import game.world.World; +import common.entity.Entity; +import common.util.ExtMath; +import common.world.World; public class EntitySnowShovelFX extends EntityFX { diff --git a/client/src/client/renderer/particle/EntitySpellParticleFX.java b/client/src/client/renderer/particle/EntitySpellParticleFX.java index bdc8765..4aaa047 100755 --- a/client/src/client/renderer/particle/EntitySpellParticleFX.java +++ b/client/src/client/renderer/particle/EntitySpellParticleFX.java @@ -1,10 +1,10 @@ package client.renderer.particle; import client.renderer.RenderBuffer; -import game.entity.Entity; -import game.rng.Random; -import game.util.ExtMath; -import game.world.World; +import common.entity.Entity; +import common.rng.Random; +import common.util.ExtMath; +import common.world.World; public class EntitySpellParticleFX extends EntityFX { diff --git a/client/src/client/renderer/particle/EntitySplashFX.java b/client/src/client/renderer/particle/EntitySplashFX.java index 411b5ba..8c1f93a 100755 --- a/client/src/client/renderer/particle/EntitySplashFX.java +++ b/client/src/client/renderer/particle/EntitySplashFX.java @@ -1,6 +1,6 @@ package client.renderer.particle; -import game.world.World; +import common.world.World; public class EntitySplashFX extends EntityDownfallFX { diff --git a/client/src/client/renderer/particle/EntitySuspendFX.java b/client/src/client/renderer/particle/EntitySuspendFX.java index 18c0d9e..aae9b5e 100755 --- a/client/src/client/renderer/particle/EntitySuspendFX.java +++ b/client/src/client/renderer/particle/EntitySuspendFX.java @@ -1,8 +1,8 @@ package client.renderer.particle; -import game.material.Material; -import game.world.BlockPos; -import game.world.World; +import common.material.Material; +import common.world.BlockPos; +import common.world.World; public class EntitySuspendFX extends EntityFX { diff --git a/client/src/client/renderer/particle/IParticleFactory.java b/client/src/client/renderer/particle/IParticleFactory.java index 06a5b62..f018fda 100755 --- a/client/src/client/renderer/particle/IParticleFactory.java +++ b/client/src/client/renderer/particle/IParticleFactory.java @@ -1,6 +1,6 @@ package client.renderer.particle; -import game.world.World; +import common.world.World; public interface IParticleFactory { diff --git a/client/src/client/renderer/texture/ColormapLoader.java b/client/src/client/renderer/texture/ColormapLoader.java index 38c257d..7566500 100644 --- a/client/src/client/renderer/texture/ColormapLoader.java +++ b/client/src/client/renderer/texture/ColormapLoader.java @@ -2,8 +2,8 @@ package client.renderer.texture; import java.awt.image.BufferedImage; -import game.color.Colorizer; -import game.util.FileUtils; +import common.color.Colorizer; +import common.util.FileUtils; public abstract class ColormapLoader { private static final String GRASS_TEX = "textures/world/grass.png"; diff --git a/client/src/client/renderer/texture/EntityTexManager.java b/client/src/client/renderer/texture/EntityTexManager.java index 444163c..91e1658 100755 --- a/client/src/client/renderer/texture/EntityTexManager.java +++ b/client/src/client/renderer/texture/EntityTexManager.java @@ -13,14 +13,14 @@ import java.util.Set; import client.Game; import client.renderer.entity.RenderNpc; import client.renderer.layers.LayerExtra; -import game.collect.Lists; -import game.collect.Maps; -import game.collect.Sets; -import game.entity.npc.EntityNPC; -import game.init.SpeciesRegistry; -import game.init.SpeciesRegistry.ModelType; -import game.log.Log; -import game.util.FileUtils; +import common.collect.Lists; +import common.collect.Maps; +import common.collect.Sets; +import common.entity.npc.EntityNPC; +import common.init.SpeciesRegistry; +import common.init.SpeciesRegistry.ModelType; +import common.log.Log; +import common.util.FileUtils; public abstract class EntityTexManager { diff --git a/client/src/client/renderer/texture/LayeredColorMaskTexture.java b/client/src/client/renderer/texture/LayeredColorMaskTexture.java index 5920829..654e960 100755 --- a/client/src/client/renderer/texture/LayeredColorMaskTexture.java +++ b/client/src/client/renderer/texture/LayeredColorMaskTexture.java @@ -7,9 +7,9 @@ import java.io.IOException; import java.io.InputStream; import java.util.List; -import game.color.DyeColor; -import game.log.Log; -import game.util.FileUtils; +import common.color.DyeColor; +import common.log.Log; +import common.util.FileUtils; public class LayeredColorMaskTexture extends Texture { diff --git a/client/src/client/renderer/texture/LayeredTexture.java b/client/src/client/renderer/texture/LayeredTexture.java index 6f9102f..5339db5 100755 --- a/client/src/client/renderer/texture/LayeredTexture.java +++ b/client/src/client/renderer/texture/LayeredTexture.java @@ -6,9 +6,9 @@ import java.io.IOException; import java.io.InputStream; import java.util.List; -import game.collect.Lists; -import game.log.Log; -import game.util.FileUtils; +import common.collect.Lists; +import common.log.Log; +import common.util.FileUtils; public class LayeredTexture extends Texture { diff --git a/client/src/client/renderer/texture/SimpleTexture.java b/client/src/client/renderer/texture/SimpleTexture.java index 8a142b6..43c4629 100755 --- a/client/src/client/renderer/texture/SimpleTexture.java +++ b/client/src/client/renderer/texture/SimpleTexture.java @@ -4,7 +4,7 @@ import java.awt.image.BufferedImage; import java.io.IOException; import java.io.InputStream; -import game.util.FileUtils; +import common.util.FileUtils; public class SimpleTexture extends Texture { private final String location; diff --git a/client/src/client/renderer/texture/Stitcher.java b/client/src/client/renderer/texture/Stitcher.java index 008e615..f9cff3b 100755 --- a/client/src/client/renderer/texture/Stitcher.java +++ b/client/src/client/renderer/texture/Stitcher.java @@ -5,8 +5,8 @@ import java.util.Arrays; import java.util.List; import java.util.Set; -import game.collect.Lists; -import game.collect.Sets; +import common.collect.Lists; +import common.collect.Sets; public class Stitcher { diff --git a/client/src/client/renderer/texture/TextureAtlasSprite.java b/client/src/client/renderer/texture/TextureAtlasSprite.java index d75b3fa..4226a06 100755 --- a/client/src/client/renderer/texture/TextureAtlasSprite.java +++ b/client/src/client/renderer/texture/TextureAtlasSprite.java @@ -4,7 +4,7 @@ import java.awt.image.BufferedImage; import java.io.IOException; import java.util.List; -import game.collect.Lists; +import common.collect.Lists; public class TextureAtlasSprite { diff --git a/client/src/client/renderer/texture/TextureManager.java b/client/src/client/renderer/texture/TextureManager.java index 06de1dd..4bd6328 100755 --- a/client/src/client/renderer/texture/TextureManager.java +++ b/client/src/client/renderer/texture/TextureManager.java @@ -6,8 +6,8 @@ import java.util.Map; import java.util.Map.Entry; import client.renderer.GlState; -import game.collect.Maps; -import game.log.Log; +import common.collect.Maps; +import common.log.Log; public class TextureManager { private final Map textures = Maps.newHashMap(); diff --git a/client/src/client/renderer/texture/TextureMap.java b/client/src/client/renderer/texture/TextureMap.java index 50af03f..afe4afd 100755 --- a/client/src/client/renderer/texture/TextureMap.java +++ b/client/src/client/renderer/texture/TextureMap.java @@ -9,13 +9,13 @@ import java.util.Map.Entry; import client.init.AnimationRegistry; import client.renderer.GlState; -import game.block.Block; -import game.collect.Lists; -import game.collect.Maps; -import game.init.BlockRegistry; -import game.init.FluidRegistry; -import game.log.Log; -import game.util.FileUtils; +import common.block.Block; +import common.collect.Lists; +import common.collect.Maps; +import common.init.BlockRegistry; +import common.init.FluidRegistry; +import common.log.Log; +import common.util.FileUtils; public class TextureMap extends Texture { diff --git a/client/src/client/renderer/texture/TextureUtil.java b/client/src/client/renderer/texture/TextureUtil.java index 61f517d..71bced9 100755 --- a/client/src/client/renderer/texture/TextureUtil.java +++ b/client/src/client/renderer/texture/TextureUtil.java @@ -15,7 +15,7 @@ import org.lwjgl.opengl.GL11; import org.lwjgl.opengl.GL12; import client.renderer.GlState; -import game.util.FileUtils; +import common.util.FileUtils; public class TextureUtil { diff --git a/client/src/client/renderer/ticked/TextureLavaFX.java b/client/src/client/renderer/ticked/TextureLavaFX.java index b862970..af7811d 100755 --- a/client/src/client/renderer/ticked/TextureLavaFX.java +++ b/client/src/client/renderer/ticked/TextureLavaFX.java @@ -1,7 +1,7 @@ package client.renderer.ticked; import client.renderer.texture.TextureTicked; -import game.util.ExtMath; +import common.util.ExtMath; public class TextureLavaFX extends TextureTicked { diff --git a/client/src/client/renderer/ticked/TextureLavaFlowFX.java b/client/src/client/renderer/ticked/TextureLavaFlowFX.java index d6494a9..2948f93 100755 --- a/client/src/client/renderer/ticked/TextureLavaFlowFX.java +++ b/client/src/client/renderer/ticked/TextureLavaFlowFX.java @@ -1,7 +1,7 @@ package client.renderer.ticked; import client.renderer.texture.TextureTicked; -import game.util.ExtMath; +import common.util.ExtMath; public class TextureLavaFlowFX extends TextureTicked { diff --git a/client/src/client/renderer/tileentity/TileEntityBannerRenderer.java b/client/src/client/renderer/tileentity/TileEntityBannerRenderer.java index d968685..3e38162 100755 --- a/client/src/client/renderer/tileentity/TileEntityBannerRenderer.java +++ b/client/src/client/renderer/tileentity/TileEntityBannerRenderer.java @@ -10,13 +10,13 @@ import client.Game; import client.renderer.GlState; import client.renderer.model.ModelBanner; import client.renderer.texture.LayeredColorMaskTexture; -import game.collect.Lists; -import game.collect.Maps; -import game.color.DyeColor; -import game.init.Blocks; -import game.tileentity.TileEntityBanner; -import game.util.ExtMath; -import game.world.BlockPos; +import common.collect.Lists; +import common.collect.Maps; +import common.color.DyeColor; +import common.init.Blocks; +import common.tileentity.TileEntityBanner; +import common.util.ExtMath; +import common.world.BlockPos; public class TileEntityBannerRenderer extends TileEntitySpecialRenderer { diff --git a/client/src/client/renderer/tileentity/TileEntityChestRenderer.java b/client/src/client/renderer/tileentity/TileEntityChestRenderer.java index 9d83257..4fbb70f 100755 --- a/client/src/client/renderer/tileentity/TileEntityChestRenderer.java +++ b/client/src/client/renderer/tileentity/TileEntityChestRenderer.java @@ -5,9 +5,9 @@ import org.lwjgl.opengl.GL11; import client.renderer.GlState; import client.renderer.model.ModelChest; import client.renderer.model.ModelLargeChest; -import game.block.Block; -import game.block.BlockChest; -import game.tileentity.TileEntityChest; +import common.block.Block; +import common.block.BlockChest; +import common.tileentity.TileEntityChest; public class TileEntityChestRenderer extends TileEntitySpecialRenderer diff --git a/client/src/client/renderer/tileentity/TileEntityItemStackRenderer.java b/client/src/client/renderer/tileentity/TileEntityItemStackRenderer.java index 72702f5..ed89a94 100755 --- a/client/src/client/renderer/tileentity/TileEntityItemStackRenderer.java +++ b/client/src/client/renderer/tileentity/TileEntityItemStackRenderer.java @@ -3,14 +3,14 @@ package client.renderer.tileentity; import org.lwjgl.opengl.GL11; import client.renderer.GlState; -import game.block.Block; -import game.init.Blocks; -import game.init.Items; -import game.item.ItemStack; -import game.tileentity.TileEntityBanner; -import game.tileentity.TileEntityChest; -import game.tileentity.TileEntitySkull; -import game.world.Facing; +import common.block.Block; +import common.init.Blocks; +import common.init.Items; +import common.item.ItemStack; +import common.tileentity.TileEntityBanner; +import common.tileentity.TileEntityChest; +import common.tileentity.TileEntitySkull; +import common.world.Facing; public class TileEntityItemStackRenderer { diff --git a/client/src/client/renderer/tileentity/TileEntityMobSpawnerRenderer.java b/client/src/client/renderer/tileentity/TileEntityMobSpawnerRenderer.java index e31dca2..8a9f501 100755 --- a/client/src/client/renderer/tileentity/TileEntityMobSpawnerRenderer.java +++ b/client/src/client/renderer/tileentity/TileEntityMobSpawnerRenderer.java @@ -3,8 +3,8 @@ package client.renderer.tileentity; import org.lwjgl.opengl.GL11; import client.Game; -import game.entity.Entity; -import game.tileentity.TileEntityMobSpawner; +import common.entity.Entity; +import common.tileentity.TileEntityMobSpawner; public class TileEntityMobSpawnerRenderer extends TileEntitySpecialRenderer { diff --git a/client/src/client/renderer/tileentity/TileEntityPistonRenderer.java b/client/src/client/renderer/tileentity/TileEntityPistonRenderer.java index 651f015..9d0bfe7 100755 --- a/client/src/client/renderer/tileentity/TileEntityPistonRenderer.java +++ b/client/src/client/renderer/tileentity/TileEntityPistonRenderer.java @@ -10,15 +10,15 @@ import client.renderer.ItemRenderer; import client.renderer.RenderBuffer; import client.renderer.Tessellator; import client.renderer.texture.TextureMap; -import game.block.Block; -import game.block.BlockPistonBase; -import game.block.BlockPistonHead; -import game.init.Blocks; -import game.material.Material; -import game.tileentity.TileEntityPiston; -import game.world.BlockPos; -import game.world.State; -import game.world.World; +import common.block.Block; +import common.block.BlockPistonBase; +import common.block.BlockPistonHead; +import common.init.Blocks; +import common.material.Material; +import common.tileentity.TileEntityPiston; +import common.world.BlockPos; +import common.world.State; +import common.world.World; public class TileEntityPistonRenderer extends TileEntitySpecialRenderer { diff --git a/client/src/client/renderer/tileentity/TileEntityRendererDispatcher.java b/client/src/client/renderer/tileentity/TileEntityRendererDispatcher.java index 3fb7166..1bf7bdc 100755 --- a/client/src/client/renderer/tileentity/TileEntityRendererDispatcher.java +++ b/client/src/client/renderer/tileentity/TileEntityRendererDispatcher.java @@ -6,17 +6,17 @@ import org.lwjgl.opengl.GL13; import client.renderer.GlState; import client.renderer.texture.TextureManager; -import game.collect.Maps; -import game.entity.Entity; -import game.tileentity.TileEntity; -import game.tileentity.TileEntityBanner; -import game.tileentity.TileEntityChest; -import game.tileentity.TileEntityMobSpawner; -import game.tileentity.TileEntityPiston; -import game.tileentity.TileEntitySign; -import game.tileentity.TileEntitySkull; -import game.world.BlockPos; -import game.world.World; +import common.collect.Maps; +import common.entity.Entity; +import common.tileentity.TileEntity; +import common.tileentity.TileEntityBanner; +import common.tileentity.TileEntityChest; +import common.tileentity.TileEntityMobSpawner; +import common.tileentity.TileEntityPiston; +import common.tileentity.TileEntitySign; +import common.tileentity.TileEntitySkull; +import common.world.BlockPos; +import common.world.World; public class TileEntityRendererDispatcher { diff --git a/client/src/client/renderer/tileentity/TileEntitySignRenderer.java b/client/src/client/renderer/tileentity/TileEntitySignRenderer.java index b5d3117..22d543c 100755 --- a/client/src/client/renderer/tileentity/TileEntitySignRenderer.java +++ b/client/src/client/renderer/tileentity/TileEntitySignRenderer.java @@ -6,9 +6,9 @@ import client.gui.Font; import client.renderer.Drawing; import client.renderer.GlState; import client.renderer.model.ModelSign; -import game.block.Block; -import game.init.Blocks; -import game.tileentity.TileEntitySign; +import common.block.Block; +import common.init.Blocks; +import common.tileentity.TileEntitySign; public class TileEntitySignRenderer extends TileEntitySpecialRenderer diff --git a/client/src/client/renderer/tileentity/TileEntitySkullRenderer.java b/client/src/client/renderer/tileentity/TileEntitySkullRenderer.java index 577b18a..86478f3 100755 --- a/client/src/client/renderer/tileentity/TileEntitySkullRenderer.java +++ b/client/src/client/renderer/tileentity/TileEntitySkullRenderer.java @@ -4,8 +4,8 @@ import org.lwjgl.opengl.GL11; import client.renderer.GlState; import client.renderer.model.ModelHumanoidHead; -import game.tileentity.TileEntitySkull; -import game.world.Facing; +import common.tileentity.TileEntitySkull; +import common.world.Facing; public class TileEntitySkullRenderer extends TileEntitySpecialRenderer diff --git a/client/src/client/renderer/tileentity/TileEntitySpecialRenderer.java b/client/src/client/renderer/tileentity/TileEntitySpecialRenderer.java index 8903943..fa30d2f 100755 --- a/client/src/client/renderer/tileentity/TileEntitySpecialRenderer.java +++ b/client/src/client/renderer/tileentity/TileEntitySpecialRenderer.java @@ -1,8 +1,8 @@ package client.renderer.tileentity; import client.renderer.texture.TextureManager; -import game.tileentity.TileEntity; -import game.world.World; +import common.tileentity.TileEntity; +import common.world.World; public abstract class TileEntitySpecialRenderer { diff --git a/client/src/game/vars/BaseVar.java b/client/src/client/vars/BaseVar.java similarity index 97% rename from client/src/game/vars/BaseVar.java rename to client/src/client/vars/BaseVar.java index 2029a09..e6c4c33 100644 --- a/client/src/game/vars/BaseVar.java +++ b/client/src/client/vars/BaseVar.java @@ -1,4 +1,4 @@ -package game.vars; +package client.vars; import java.lang.reflect.Field; diff --git a/client/src/game/vars/BoolVar.java b/client/src/client/vars/BoolVar.java similarity index 95% rename from client/src/game/vars/BoolVar.java rename to client/src/client/vars/BoolVar.java index 388ccc8..af51d6b 100644 --- a/client/src/game/vars/BoolVar.java +++ b/client/src/client/vars/BoolVar.java @@ -1,10 +1,10 @@ -package game.vars; +package client.vars; import java.lang.reflect.Field; import client.gui.element.Toggle; -import game.color.TextColor; -import game.util.Util; +import common.color.TextColor; +import common.util.Util; public class BoolVar extends BaseVar { public static interface BoolFunction extends VarFunction { diff --git a/client/src/game/vars/CVar.java b/client/src/client/vars/CVar.java similarity index 86% rename from client/src/game/vars/CVar.java rename to client/src/client/vars/CVar.java index 26649cb..07a86bb 100644 --- a/client/src/game/vars/CVar.java +++ b/client/src/client/vars/CVar.java @@ -1,7 +1,7 @@ -package game.vars; +package client.vars; import client.gui.element.Element; -import game.util.Displayable; +import common.util.Displayable; public interface CVar extends Displayable { String getType(); diff --git a/client/src/game/vars/CVarCategory.java b/client/src/client/vars/CVarCategory.java similarity index 89% rename from client/src/game/vars/CVarCategory.java rename to client/src/client/vars/CVarCategory.java index 8445c25..aa40d07 100644 --- a/client/src/game/vars/CVarCategory.java +++ b/client/src/client/vars/CVarCategory.java @@ -1,6 +1,6 @@ -package game.vars; +package client.vars; -import game.color.TextColor; +import common.color.TextColor; public enum CVarCategory { SYSTEM(TextColor.RED + "system"), diff --git a/client/src/game/vars/ColorVar.java b/client/src/client/vars/ColorVar.java similarity index 95% rename from client/src/game/vars/ColorVar.java rename to client/src/client/vars/ColorVar.java index e361a08..2a1bfb1 100644 --- a/client/src/game/vars/ColorVar.java +++ b/client/src/client/vars/ColorVar.java @@ -1,4 +1,4 @@ -package game.vars; +package client.vars; import java.lang.reflect.Field; @@ -7,8 +7,8 @@ import client.gui.element.Label; import client.gui.element.Slider; import client.gui.element.Textbox; import client.gui.element.Textbox.Action; -import game.color.TextColor; -import game.util.Util; +import common.color.TextColor; +import common.util.Util; public class ColorVar extends IntVar { private final boolean alpha; diff --git a/client/src/game/vars/EnumVar.java b/client/src/client/vars/EnumVar.java similarity index 96% rename from client/src/game/vars/EnumVar.java rename to client/src/client/vars/EnumVar.java index def5478..ed30980 100644 --- a/client/src/game/vars/EnumVar.java +++ b/client/src/client/vars/EnumVar.java @@ -1,13 +1,13 @@ -package game.vars; +package client.vars; import java.lang.reflect.Field; import client.gui.element.Dropdown; import client.gui.element.Element; import client.gui.element.Switch; -import game.color.TextColor; -import game.util.Identifyable; -import game.util.Util; +import common.color.TextColor; +import common.util.Identifyable; +import common.util.Util; public class EnumVar extends BaseVar { public static interface EnumFunction extends VarFunction { diff --git a/client/src/game/vars/FloatVar.java b/client/src/client/vars/FloatVar.java similarity index 97% rename from client/src/game/vars/FloatVar.java rename to client/src/client/vars/FloatVar.java index 734ca49..2343af1 100644 --- a/client/src/game/vars/FloatVar.java +++ b/client/src/client/vars/FloatVar.java @@ -1,10 +1,10 @@ -package game.vars; +package client.vars; import java.lang.reflect.Field; import client.gui.element.Slider; -import game.color.TextColor; -import game.util.ExtMath; +import common.color.TextColor; +import common.util.ExtMath; public class FloatVar extends BaseVar { public static interface FloatFunction extends VarFunction { diff --git a/client/src/game/vars/IntVar.java b/client/src/client/vars/IntVar.java similarity index 95% rename from client/src/game/vars/IntVar.java rename to client/src/client/vars/IntVar.java index 3d87ef5..06282fb 100644 --- a/client/src/game/vars/IntVar.java +++ b/client/src/client/vars/IntVar.java @@ -1,11 +1,11 @@ -package game.vars; +package client.vars; import java.lang.reflect.Field; import client.gui.element.Slider; -import game.color.TextColor; -import game.util.ExtMath; -import game.util.Util; +import common.color.TextColor; +import common.util.ExtMath; +import common.util.Util; public class IntVar extends BaseVar { public static interface IntFunction extends VarFunction { diff --git a/client/src/game/vars/StringVar.java b/client/src/client/vars/StringVar.java similarity index 96% rename from client/src/game/vars/StringVar.java rename to client/src/client/vars/StringVar.java index c761585..66dea94 100644 --- a/client/src/game/vars/StringVar.java +++ b/client/src/client/vars/StringVar.java @@ -1,11 +1,11 @@ -package game.vars; +package client.vars; import java.lang.reflect.Field; import client.gui.element.Textbox; import client.gui.element.Textbox.Action; -import game.color.TextColor; -import game.util.CharValidator; +import common.color.TextColor; +import common.util.CharValidator; public class StringVar extends BaseVar { public static interface StringFunction extends VarFunction { diff --git a/client/src/game/vars/Variable.java b/client/src/client/vars/Variable.java similarity index 88% rename from client/src/game/vars/Variable.java rename to client/src/client/vars/Variable.java index 606fd9e..4c16bb8 100644 --- a/client/src/game/vars/Variable.java +++ b/client/src/client/vars/Variable.java @@ -1,4 +1,4 @@ -package game.vars; +package client.vars; import static java.lang.annotation.ElementType.FIELD; @@ -6,8 +6,8 @@ import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; -import game.util.CharValidator; -import game.vars.BaseVar.VarFunction; +import client.vars.BaseVar.VarFunction; +import common.util.CharValidator; @Target(FIELD) @Retention(value = RetentionPolicy.RUNTIME) diff --git a/client/src/client/window/Bind.java b/client/src/client/window/Bind.java index 040ea95..2cbf390 100644 --- a/client/src/client/window/Bind.java +++ b/client/src/client/window/Bind.java @@ -2,11 +2,11 @@ package client.window; import client.Game; import client.gui.element.Element; -import game.color.TextColor; -import game.util.Identifyable; -import game.util.Util; -import game.vars.CVar; -import game.vars.CVarCategory; +import client.vars.CVar; +import client.vars.CVarCategory; +import common.color.TextColor; +import common.util.Identifyable; +import common.util.Util; public enum Bind implements Identifyable, CVar { FORWARD("forward", "Vorwärts", Keysym.W), diff --git a/client/src/client/window/Input.java b/client/src/client/window/Input.java index b4700a4..f1a3d33 100644 --- a/client/src/client/window/Input.java +++ b/client/src/client/window/Input.java @@ -1,7 +1,7 @@ package client.window; -import game.util.Displayable; -import game.util.Identifyable; +import common.util.Displayable; +import common.util.Identifyable; public interface Input extends Identifyable, Displayable { public boolean read(); diff --git a/client/src/client/window/Window.java b/client/src/client/window/Window.java index 5356abe..515c79c 100644 --- a/client/src/client/window/Window.java +++ b/client/src/client/window/Window.java @@ -74,7 +74,7 @@ import org.lwjgl.glfw.GLFWWindowRefreshCallback; import org.lwjgl.opengl.GL; import org.lwjgl.system.APIUtil; -import game.log.Log; +import common.log.Log; public abstract class Window { public static void setWindowed(int xpos, int ypos, int xsize, int ysize) { diff --git a/client/src/game/world/Converter.java b/client/src/client/world/Converter.java similarity index 95% rename from client/src/game/world/Converter.java rename to client/src/client/world/Converter.java index c50ebe0..6a81987 100644 --- a/client/src/game/world/Converter.java +++ b/client/src/client/world/Converter.java @@ -1,4 +1,4 @@ -package game.world; +package client.world; import java.io.BufferedInputStream; import java.io.ByteArrayInputStream; @@ -17,77 +17,83 @@ import client.Game; import client.gui.GuiConvert; import client.gui.GuiLoading; import client.gui.GuiLoading.Callback; -import game.biome.Biome; -import game.block.Block; -import game.block.BlockCactus; -import game.block.BlockCarpet; -import game.block.BlockColored; -import game.block.BlockDirt; -import game.block.BlockFire; -import game.block.BlockFlower; -import game.block.BlockFlowerPot; -import game.block.BlockLeaves; -import game.block.BlockLiquid; -import game.block.BlockLog; -import game.block.BlockPistonBase; -import game.block.BlockPistonHead; -import game.block.BlockQuartz; -import game.block.BlockRock; -import game.block.BlockSand; -import game.block.BlockSandStone; -import game.block.BlockSlab; -import game.block.BlockStainedGlass; -import game.block.BlockStainedGlassPane; -import game.block.BlockStoneBrick; -import game.block.BlockTNT; -import game.block.BlockTallGrass; -import game.block.BlockWall; -import game.block.LeavesType; -import game.collect.Maps; -import game.color.DyeColor; -import game.entity.Entity; -import game.entity.animal.EntityBat; -import game.entity.animal.EntityChicken; -import game.entity.animal.EntityCow; -import game.entity.animal.EntityHorse; -import game.entity.animal.EntityMooshroom; -import game.entity.animal.EntityOcelot; -import game.entity.animal.EntityPig; -import game.entity.animal.EntityRabbit; -import game.entity.animal.EntitySheep; -import game.entity.animal.EntitySquid; -import game.entity.animal.EntityWolf; -import game.entity.item.EntityBoat; -import game.entity.item.EntityMinecart; -import game.init.BlockRegistry; -import game.init.Blocks; -import game.init.Config; -import game.init.EntityRegistry; -import game.init.TileRegistry; -import game.init.UniverseRegistry; -import game.log.Log; -import game.nbt.NBTLoader; -import game.nbt.NBTTagCompound; -import game.nbt.NBTTagList; -import game.rng.Random; -import game.tileentity.TileEntity; -import game.tileentity.TileEntityBanner; -import game.tileentity.TileEntityBeacon; -import game.tileentity.TileEntityChest; -import game.tileentity.TileEntityComparator; -import game.tileentity.TileEntityDaylightDetector; -import game.tileentity.TileEntityDispenser; -import game.tileentity.TileEntityDropper; -import game.tileentity.TileEntityEnchantmentTable; -import game.tileentity.TileEntityFurnace; -import game.tileentity.TileEntityHopper; -import game.tileentity.TileEntityMobSpawner; -import game.tileentity.TileEntityNote; -import game.tileentity.TileEntityPiston; -import game.tileentity.TileEntitySign; -import game.tileentity.TileEntitySkull; -import game.world.Region.FolderInfo; -import game.world.Region.SaveVersion; +import common.biome.Biome; +import common.block.Block; +import common.block.BlockCactus; +import common.block.BlockCarpet; +import common.block.BlockColored; +import common.block.BlockDirt; +import common.block.BlockFire; +import common.block.BlockFlower; +import common.block.BlockFlowerPot; +import common.block.BlockLeaves; +import common.block.BlockLiquid; +import common.block.BlockLog; +import common.block.BlockPistonBase; +import common.block.BlockPistonHead; +import common.block.BlockQuartz; +import common.block.BlockRock; +import common.block.BlockSand; +import common.block.BlockSandStone; +import common.block.BlockSlab; +import common.block.BlockStainedGlass; +import common.block.BlockStainedGlassPane; +import common.block.BlockStoneBrick; +import common.block.BlockTNT; +import common.block.BlockTallGrass; +import common.block.BlockWall; +import common.block.LeavesType; +import common.collect.Maps; +import common.color.DyeColor; +import common.entity.Entity; +import common.entity.animal.EntityBat; +import common.entity.animal.EntityChicken; +import common.entity.animal.EntityCow; +import common.entity.animal.EntityHorse; +import common.entity.animal.EntityMooshroom; +import common.entity.animal.EntityOcelot; +import common.entity.animal.EntityPig; +import common.entity.animal.EntityRabbit; +import common.entity.animal.EntitySheep; +import common.entity.animal.EntitySquid; +import common.entity.animal.EntityWolf; +import common.entity.item.EntityBoat; +import common.entity.item.EntityMinecart; +import common.init.BlockRegistry; +import common.init.Blocks; +import common.init.Config; +import common.init.EntityRegistry; +import common.init.TileRegistry; +import common.init.UniverseRegistry; +import common.log.Log; +import common.nbt.NBTLoader; +import common.nbt.NBTTagCompound; +import common.nbt.NBTTagList; +import common.rng.Random; +import common.tileentity.TileEntity; +import common.tileentity.TileEntityBanner; +import common.tileentity.TileEntityBeacon; +import common.tileentity.TileEntityChest; +import common.tileentity.TileEntityComparator; +import common.tileentity.TileEntityDaylightDetector; +import common.tileentity.TileEntityDispenser; +import common.tileentity.TileEntityDropper; +import common.tileentity.TileEntityEnchantmentTable; +import common.tileentity.TileEntityFurnace; +import common.tileentity.TileEntityHopper; +import common.tileentity.TileEntityMobSpawner; +import common.tileentity.TileEntityNote; +import common.tileentity.TileEntityPiston; +import common.tileentity.TileEntitySign; +import common.tileentity.TileEntitySkull; +import common.world.Facing; +import common.world.NibbleArray; +import common.world.Region; +import common.world.State; +import common.world.Weather; +import common.world.World; +import common.world.Region.FolderInfo; +import common.world.Region.SaveVersion; public final class Converter { // public static interface Callback { diff --git a/java/src/game/IClient.java b/java/src/common/IClient.java similarity index 78% rename from java/src/game/IClient.java rename to java/src/common/IClient.java index 3049938..1e0ed74 100644 --- a/java/src/game/IClient.java +++ b/java/src/common/IClient.java @@ -1,13 +1,13 @@ -package game; +package common; -import game.entity.Entity; -import game.entity.npc.EntityNPC; -import game.entity.types.IEntityFX; -import game.model.ParticleType; -import game.nbt.NBTTagCompound; -import game.sound.Sound; -import game.world.BlockPos; -import game.world.State; +import common.entity.Entity; +import common.entity.npc.EntityNPC; +import common.entity.types.IEntityFX; +import common.model.ParticleType; +import common.nbt.NBTTagCompound; +import common.sound.Sound; +import common.world.BlockPos; +import common.world.State; public interface IClient { int getRenderDistance(); diff --git a/java/src/game/IServer.java b/java/src/common/IServer.java similarity index 69% rename from java/src/game/IServer.java rename to java/src/common/IServer.java index bae8d70..cd3fd18 100644 --- a/java/src/game/IServer.java +++ b/java/src/common/IServer.java @@ -1,16 +1,16 @@ -package game; +package common; import java.util.List; import java.util.Map; -import game.entity.Entity; -import game.entity.npc.EntityNPC; -import game.network.IPlayer; -import game.network.Packet; -import game.world.BlockPos; -import game.world.PortalType; -import game.world.Position; -import game.world.WorldServer; +import common.entity.Entity; +import common.entity.npc.EntityNPC; +import common.network.IPlayer; +import common.network.Packet; +import common.world.BlockPos; +import common.world.PortalType; +import common.world.Position; +import common.world.WorldServer; public interface IServer { List getIPlayers(); diff --git a/java/src/game/ai/AIFireballAttack.java b/java/src/common/ai/AIFireballAttack.java similarity index 92% rename from java/src/game/ai/AIFireballAttack.java rename to java/src/common/ai/AIFireballAttack.java index ec933eb..6790164 100755 --- a/java/src/game/ai/AIFireballAttack.java +++ b/java/src/common/ai/AIFireballAttack.java @@ -1,13 +1,13 @@ -package game.ai; +package common.ai; -import game.entity.npc.EntityNPC; -import game.entity.projectile.EntityFireball; -import game.entity.types.EntityLiving; -import game.init.Items; -import game.item.ItemStack; -import game.world.BlockPos; -import game.world.Vec3; -import game.world.World; +import common.entity.npc.EntityNPC; +import common.entity.projectile.EntityFireball; +import common.entity.types.EntityLiving; +import common.init.Items; +import common.item.ItemStack; +import common.world.BlockPos; +import common.world.Vec3; +import common.world.World; public class AIFireballAttack extends EntityAIBase { diff --git a/java/src/game/ai/AIFlyingBoxAttack.java b/java/src/common/ai/AIFlyingBoxAttack.java similarity index 94% rename from java/src/game/ai/AIFlyingBoxAttack.java rename to java/src/common/ai/AIFlyingBoxAttack.java index f7825b6..4477be0 100755 --- a/java/src/game/ai/AIFlyingBoxAttack.java +++ b/java/src/common/ai/AIFlyingBoxAttack.java @@ -1,9 +1,9 @@ -package game.ai; +package common.ai; -import game.entity.npc.EntityNPC; -import game.entity.projectile.EntityBox; -import game.entity.types.EntityLiving; -import game.world.BlockPos; +import common.entity.npc.EntityNPC; +import common.entity.projectile.EntityBox; +import common.entity.types.EntityLiving; +import common.world.BlockPos; public class AIFlyingBoxAttack extends EntityAIBase { diff --git a/java/src/game/ai/AIRangedAttack.java b/java/src/common/ai/AIRangedAttack.java similarity index 96% rename from java/src/game/ai/AIRangedAttack.java rename to java/src/common/ai/AIRangedAttack.java index 6104b95..caf7d72 100755 --- a/java/src/game/ai/AIRangedAttack.java +++ b/java/src/common/ai/AIRangedAttack.java @@ -1,8 +1,8 @@ -package game.ai; +package common.ai; -import game.entity.npc.EntityNPC; -import game.entity.types.EntityLiving; -import game.util.ExtMath; +import common.entity.npc.EntityNPC; +import common.entity.types.EntityLiving; +import common.util.ExtMath; public class AIRangedAttack extends EntityAIBase { diff --git a/java/src/game/ai/AISmallFireballAttack.java b/java/src/common/ai/AISmallFireballAttack.java similarity index 94% rename from java/src/game/ai/AISmallFireballAttack.java rename to java/src/common/ai/AISmallFireballAttack.java index ce27ce7..9bdbd59 100755 --- a/java/src/game/ai/AISmallFireballAttack.java +++ b/java/src/common/ai/AISmallFireballAttack.java @@ -1,9 +1,9 @@ -package game.ai; +package common.ai; -import game.entity.npc.EntityNPC; -import game.entity.projectile.EntityFireCharge; -import game.entity.types.EntityLiving; -import game.world.BlockPos; +import common.entity.npc.EntityNPC; +import common.entity.projectile.EntityFireCharge; +import common.entity.types.EntityLiving; +import common.world.BlockPos; public class AISmallFireballAttack extends EntityAIBase { diff --git a/java/src/game/ai/EntityAIAttackOnCollide.java b/java/src/common/ai/EntityAIAttackOnCollide.java similarity index 96% rename from java/src/game/ai/EntityAIAttackOnCollide.java rename to java/src/common/ai/EntityAIAttackOnCollide.java index 3c21879..26ab783 100755 --- a/java/src/game/ai/EntityAIAttackOnCollide.java +++ b/java/src/common/ai/EntityAIAttackOnCollide.java @@ -1,10 +1,10 @@ -package game.ai; +package common.ai; -import game.entity.Entity; -import game.entity.types.EntityLiving; -import game.pathfinding.PathEntity; -import game.world.BlockPos; -import game.world.World; +import common.entity.Entity; +import common.entity.types.EntityLiving; +import common.pathfinding.PathEntity; +import common.world.BlockPos; +import common.world.World; public class EntityAIAttackOnCollide extends EntityAIBase { diff --git a/java/src/game/ai/EntityAIAvoidEntity.java b/java/src/common/ai/EntityAIAvoidEntity.java similarity index 94% rename from java/src/game/ai/EntityAIAvoidEntity.java rename to java/src/common/ai/EntityAIAvoidEntity.java index 8fe4468..90cd980 100755 --- a/java/src/game/ai/EntityAIAvoidEntity.java +++ b/java/src/common/ai/EntityAIAvoidEntity.java @@ -1,14 +1,14 @@ -package game.ai; +package common.ai; import java.util.List; import java.util.function.Predicate; -import game.entity.Entity; -import game.entity.types.EntityLiving; -import game.pathfinding.PathEntity; -import game.pathfinding.PathNavigate; -import game.util.Predicates; -import game.world.Vec3; +import common.entity.Entity; +import common.entity.types.EntityLiving; +import common.pathfinding.PathEntity; +import common.pathfinding.PathNavigate; +import common.util.Predicates; +import common.world.Vec3; public class EntityAIAvoidEntity extends EntityAIBase { diff --git a/java/src/game/ai/EntityAIBase.java b/java/src/common/ai/EntityAIBase.java similarity index 98% rename from java/src/game/ai/EntityAIBase.java rename to java/src/common/ai/EntityAIBase.java index 3b706ea..9eccf20 100755 --- a/java/src/game/ai/EntityAIBase.java +++ b/java/src/common/ai/EntityAIBase.java @@ -1,4 +1,4 @@ -package game.ai; +package common.ai; public abstract class EntityAIBase { diff --git a/java/src/game/ai/EntityAIBeg.java b/java/src/common/ai/EntityAIBeg.java similarity index 92% rename from java/src/game/ai/EntityAIBeg.java rename to java/src/common/ai/EntityAIBeg.java index 5347d54..752e455 100755 --- a/java/src/game/ai/EntityAIBeg.java +++ b/java/src/common/ai/EntityAIBeg.java @@ -1,10 +1,10 @@ -package game.ai; +package common.ai; -import game.entity.animal.EntityWolf; -import game.entity.npc.EntityNPC; -import game.init.Items; -import game.item.ItemStack; -import game.world.World; +import common.entity.animal.EntityWolf; +import common.entity.npc.EntityNPC; +import common.init.Items; +import common.item.ItemStack; +import common.world.World; public class EntityAIBeg extends EntityAIBase { diff --git a/java/src/game/ai/EntityAIControlledByPlayer.java b/java/src/common/ai/EntityAIControlledByPlayer.java similarity index 94% rename from java/src/game/ai/EntityAIControlledByPlayer.java rename to java/src/common/ai/EntityAIControlledByPlayer.java index dcee7b8..4975645 100755 --- a/java/src/game/ai/EntityAIControlledByPlayer.java +++ b/java/src/common/ai/EntityAIControlledByPlayer.java @@ -1,16 +1,16 @@ -package game.ai; +package common.ai; -import game.block.Block; -import game.block.BlockSlab; -import game.block.BlockStairs; -import game.entity.npc.EntityNPC; -import game.entity.types.EntityLiving; -import game.init.Items; -import game.item.ItemStack; -import game.material.Material; -import game.pathfinding.WalkNodeProcessor; -import game.util.ExtMath; -import game.world.BlockPos; +import common.block.Block; +import common.block.BlockSlab; +import common.block.BlockStairs; +import common.entity.npc.EntityNPC; +import common.entity.types.EntityLiving; +import common.init.Items; +import common.item.ItemStack; +import common.material.Material; +import common.pathfinding.WalkNodeProcessor; +import common.util.ExtMath; +import common.world.BlockPos; public class EntityAIControlledByPlayer extends EntityAIBase { diff --git a/java/src/game/ai/EntityAIDoorInteract.java b/java/src/common/ai/EntityAIDoorInteract.java similarity index 92% rename from java/src/game/ai/EntityAIDoorInteract.java rename to java/src/common/ai/EntityAIDoorInteract.java index 2a11706..e45f438 100755 --- a/java/src/game/ai/EntityAIDoorInteract.java +++ b/java/src/common/ai/EntityAIDoorInteract.java @@ -1,13 +1,13 @@ -package game.ai; +package common.ai; -import game.block.Block; -import game.block.BlockDoor; -import game.entity.types.EntityLiving; -import game.material.Material; -import game.pathfinding.PathEntity; -import game.pathfinding.PathNavigateGround; -import game.pathfinding.PathPoint; -import game.world.BlockPos; +import common.block.Block; +import common.block.BlockDoor; +import common.entity.types.EntityLiving; +import common.material.Material; +import common.pathfinding.PathEntity; +import common.pathfinding.PathNavigateGround; +import common.pathfinding.PathPoint; +import common.world.BlockPos; public abstract class EntityAIDoorInteract extends EntityAIBase { diff --git a/java/src/game/ai/EntityAIEatGrass.java b/java/src/common/ai/EntityAIEatGrass.java similarity index 90% rename from java/src/game/ai/EntityAIEatGrass.java rename to java/src/common/ai/EntityAIEatGrass.java index 4996966..5930c11 100755 --- a/java/src/game/ai/EntityAIEatGrass.java +++ b/java/src/common/ai/EntityAIEatGrass.java @@ -1,17 +1,17 @@ -package game.ai; +package common.ai; import java.util.function.Predicate; -import game.block.BlockTallGrass; -import game.entity.animal.EntitySheep; -import game.init.BlockRegistry; -import game.init.Blocks; -import game.init.Config; -import game.pattern.BlockStateHelper; -import game.util.Predicates; -import game.world.BlockPos; -import game.world.State; -import game.world.World; +import common.block.BlockTallGrass; +import common.entity.animal.EntitySheep; +import common.init.BlockRegistry; +import common.init.Blocks; +import common.init.Config; +import common.pattern.BlockStateHelper; +import common.util.Predicates; +import common.world.BlockPos; +import common.world.State; +import common.world.World; public class EntityAIEatGrass extends EntityAIBase { diff --git a/java/src/game/ai/EntityAIExplode.java b/java/src/common/ai/EntityAIExplode.java similarity index 93% rename from java/src/game/ai/EntityAIExplode.java rename to java/src/common/ai/EntityAIExplode.java index d5223b7..16ec2a4 100755 --- a/java/src/game/ai/EntityAIExplode.java +++ b/java/src/common/ai/EntityAIExplode.java @@ -1,7 +1,7 @@ -package game.ai; +package common.ai; -import game.entity.npc.EntityHaunter; -import game.entity.types.EntityLiving; +import common.entity.npc.EntityHaunter; +import common.entity.types.EntityLiving; public class EntityAIExplode extends EntityAIBase { diff --git a/java/src/game/ai/EntityAIFindEntityNearest.java b/java/src/common/ai/EntityAIFindEntityNearest.java similarity index 95% rename from java/src/game/ai/EntityAIFindEntityNearest.java rename to java/src/common/ai/EntityAIFindEntityNearest.java index 5d9af13..ee34588 100755 --- a/java/src/game/ai/EntityAIFindEntityNearest.java +++ b/java/src/common/ai/EntityAIFindEntityNearest.java @@ -1,12 +1,12 @@ -package game.ai; +package common.ai; import java.util.Collections; import java.util.List; import java.util.function.Predicate; -import game.entity.attributes.AttributeInstance; -import game.entity.attributes.Attributes; -import game.entity.types.EntityLiving; +import common.entity.attributes.AttributeInstance; +import common.entity.attributes.Attributes; +import common.entity.types.EntityLiving; public class EntityAIFindEntityNearest extends EntityAIBase { diff --git a/java/src/game/ai/EntityAIFleeSun.java b/java/src/common/ai/EntityAIFleeSun.java similarity index 92% rename from java/src/game/ai/EntityAIFleeSun.java rename to java/src/common/ai/EntityAIFleeSun.java index 135d923..d6e9733 100755 --- a/java/src/game/ai/EntityAIFleeSun.java +++ b/java/src/common/ai/EntityAIFleeSun.java @@ -1,11 +1,11 @@ -package game.ai; +package common.ai; -import game.entity.types.EntityLiving; -import game.rng.Random; -import game.world.BlockPos; -import game.world.Vec3; -import game.world.World; -import game.world.WorldServer; +import common.entity.types.EntityLiving; +import common.rng.Random; +import common.world.BlockPos; +import common.world.Vec3; +import common.world.World; +import common.world.WorldServer; public class EntityAIFleeSun extends EntityAIBase { diff --git a/java/src/game/ai/EntityAIFollowOwner.java b/java/src/common/ai/EntityAIFollowOwner.java similarity index 93% rename from java/src/game/ai/EntityAIFollowOwner.java rename to java/src/common/ai/EntityAIFollowOwner.java index 6e30917..0d03d68 100755 --- a/java/src/game/ai/EntityAIFollowOwner.java +++ b/java/src/common/ai/EntityAIFollowOwner.java @@ -1,10 +1,10 @@ -package game.ai; +package common.ai; -import game.entity.types.EntityLiving; -import game.entity.types.EntityTameable; -import game.pathfinding.PathNavigate; -import game.pathfinding.PathNavigateGround; -import game.world.World; +import common.entity.types.EntityLiving; +import common.entity.types.EntityTameable; +import common.pathfinding.PathNavigate; +import common.pathfinding.PathNavigateGround; +import common.world.World; public class EntityAIFollowOwner extends EntityAIBase { diff --git a/java/src/game/ai/EntityAIFollowParent.java b/java/src/common/ai/EntityAIFollowParent.java similarity index 97% rename from java/src/game/ai/EntityAIFollowParent.java rename to java/src/common/ai/EntityAIFollowParent.java index c7db17e..d61e1f5 100755 --- a/java/src/game/ai/EntityAIFollowParent.java +++ b/java/src/common/ai/EntityAIFollowParent.java @@ -1,8 +1,8 @@ -package game.ai; +package common.ai; import java.util.List; -import game.entity.types.EntityAnimal; +import common.entity.types.EntityAnimal; public class EntityAIFollowParent extends EntityAIBase { diff --git a/java/src/game/ai/EntityAIHarvestFarmland.java b/java/src/common/ai/EntityAIHarvestFarmland.java similarity index 97% rename from java/src/game/ai/EntityAIHarvestFarmland.java rename to java/src/common/ai/EntityAIHarvestFarmland.java index a35503f..3bcc9a9 100755 --- a/java/src/game/ai/EntityAIHarvestFarmland.java +++ b/java/src/common/ai/EntityAIHarvestFarmland.java @@ -1,8 +1,8 @@ -package game.ai; +package common.ai; -import game.entity.types.EntityLiving; -import game.world.BlockPos; -import game.world.World; +import common.entity.types.EntityLiving; +import common.world.BlockPos; +import common.world.World; public class EntityAIHarvestFarmland extends EntityAIMoveToBlock { diff --git a/java/src/game/ai/EntityAIHurtByTarget.java b/java/src/common/ai/EntityAIHurtByTarget.java similarity index 96% rename from java/src/game/ai/EntityAIHurtByTarget.java rename to java/src/common/ai/EntityAIHurtByTarget.java index 51ab111..096dd21 100755 --- a/java/src/game/ai/EntityAIHurtByTarget.java +++ b/java/src/common/ai/EntityAIHurtByTarget.java @@ -1,7 +1,7 @@ -package game.ai; +package common.ai; -import game.entity.types.EntityLiving; -import game.world.BoundingBox; +import common.entity.types.EntityLiving; +import common.world.BoundingBox; public class EntityAIHurtByTarget extends EntityAITarget { diff --git a/java/src/game/ai/EntityAILeapAtTarget.java b/java/src/common/ai/EntityAILeapAtTarget.java similarity index 95% rename from java/src/game/ai/EntityAILeapAtTarget.java rename to java/src/common/ai/EntityAILeapAtTarget.java index f772265..8b62906 100755 --- a/java/src/game/ai/EntityAILeapAtTarget.java +++ b/java/src/common/ai/EntityAILeapAtTarget.java @@ -1,7 +1,7 @@ -package game.ai; +package common.ai; -import game.entity.types.EntityLiving; -import game.util.ExtMath; +import common.entity.types.EntityLiving; +import common.util.ExtMath; public class EntityAILeapAtTarget extends EntityAIBase { diff --git a/java/src/game/ai/EntityAILookAtTalkingPlayer.java b/java/src/common/ai/EntityAILookAtTalkingPlayer.java similarity index 90% rename from java/src/game/ai/EntityAILookAtTalkingPlayer.java rename to java/src/common/ai/EntityAILookAtTalkingPlayer.java index d268ddc..ce521e0 100755 --- a/java/src/game/ai/EntityAILookAtTalkingPlayer.java +++ b/java/src/common/ai/EntityAILookAtTalkingPlayer.java @@ -1,6 +1,6 @@ -package game.ai; +package common.ai; -import game.entity.npc.EntityNPC; +import common.entity.npc.EntityNPC; public class EntityAILookAtTalkingPlayer extends EntityAIWatchClosest { diff --git a/java/src/game/ai/EntityAILookIdle.java b/java/src/common/ai/EntityAILookIdle.java similarity index 96% rename from java/src/game/ai/EntityAILookIdle.java rename to java/src/common/ai/EntityAILookIdle.java index c8858f4..59f9f1b 100755 --- a/java/src/game/ai/EntityAILookIdle.java +++ b/java/src/common/ai/EntityAILookIdle.java @@ -1,6 +1,6 @@ -package game.ai; +package common.ai; -import game.entity.types.EntityLiving; +import common.entity.types.EntityLiving; public class EntityAILookIdle extends EntityAIBase { diff --git a/java/src/game/ai/EntityAIMate.java b/java/src/common/ai/EntityAIMate.java similarity index 94% rename from java/src/game/ai/EntityAIMate.java rename to java/src/common/ai/EntityAIMate.java index ec0c071..adff92f 100755 --- a/java/src/game/ai/EntityAIMate.java +++ b/java/src/common/ai/EntityAIMate.java @@ -1,15 +1,15 @@ -package game.ai; +package common.ai; import java.util.List; -import game.entity.item.EntityXp; -import game.entity.npc.EntityNPC; -import game.entity.types.EntityAnimal; -import game.entity.types.EntityLiving; -import game.init.Config; -import game.model.ParticleType; -import game.rng.Random; -import game.world.World; +import common.entity.item.EntityXp; +import common.entity.npc.EntityNPC; +import common.entity.types.EntityAnimal; +import common.entity.types.EntityLiving; +import common.init.Config; +import common.model.ParticleType; +import common.rng.Random; +import common.world.World; public class EntityAIMate extends EntityAIBase { diff --git a/java/src/game/ai/EntityAIMoveIndoors.java b/java/src/common/ai/EntityAIMoveIndoors.java similarity index 93% rename from java/src/game/ai/EntityAIMoveIndoors.java rename to java/src/common/ai/EntityAIMoveIndoors.java index abc69f3..609f82e 100755 --- a/java/src/game/ai/EntityAIMoveIndoors.java +++ b/java/src/common/ai/EntityAIMoveIndoors.java @@ -1,11 +1,11 @@ -package game.ai; +package common.ai; -import game.entity.types.EntityLiving; -import game.village.Village; -import game.village.VillageDoorInfo; -import game.world.BlockPos; -import game.world.Vec3; -import game.world.WorldServer; +import common.entity.types.EntityLiving; +import common.village.Village; +import common.village.VillageDoorInfo; +import common.world.BlockPos; +import common.world.Vec3; +import common.world.WorldServer; public class EntityAIMoveIndoors extends EntityAIBase { diff --git a/java/src/game/ai/EntityAIMoveThroughVillage.java b/java/src/common/ai/EntityAIMoveThroughVillage.java similarity index 93% rename from java/src/game/ai/EntityAIMoveThroughVillage.java rename to java/src/common/ai/EntityAIMoveThroughVillage.java index fa7b075..ac2428f 100755 --- a/java/src/game/ai/EntityAIMoveThroughVillage.java +++ b/java/src/common/ai/EntityAIMoveThroughVillage.java @@ -1,17 +1,17 @@ -package game.ai; +package common.ai; import java.util.List; -import game.collect.Lists; -import game.entity.types.EntityLiving; -import game.pathfinding.PathEntity; -import game.pathfinding.PathNavigateGround; -import game.util.ExtMath; -import game.village.Village; -import game.village.VillageDoorInfo; -import game.world.BlockPos; -import game.world.Vec3; -import game.world.WorldServer; +import common.collect.Lists; +import common.entity.types.EntityLiving; +import common.pathfinding.PathEntity; +import common.pathfinding.PathNavigateGround; +import common.util.ExtMath; +import common.village.Village; +import common.village.VillageDoorInfo; +import common.world.BlockPos; +import common.world.Vec3; +import common.world.WorldServer; public class EntityAIMoveThroughVillage extends EntityAIBase { diff --git a/java/src/game/ai/EntityAIMoveToBlock.java b/java/src/common/ai/EntityAIMoveToBlock.java similarity index 97% rename from java/src/game/ai/EntityAIMoveToBlock.java rename to java/src/common/ai/EntityAIMoveToBlock.java index 25d3d75..83f1416 100755 --- a/java/src/game/ai/EntityAIMoveToBlock.java +++ b/java/src/common/ai/EntityAIMoveToBlock.java @@ -1,8 +1,8 @@ -package game.ai; +package common.ai; -import game.entity.types.EntityLiving; -import game.world.BlockPos; -import game.world.World; +import common.entity.types.EntityLiving; +import common.world.BlockPos; +import common.world.World; public abstract class EntityAIMoveToBlock extends EntityAIBase { diff --git a/java/src/game/ai/EntityAIMoveTowardsRestriction.java b/java/src/common/ai/EntityAIMoveTowardsRestriction.java similarity index 93% rename from java/src/game/ai/EntityAIMoveTowardsRestriction.java rename to java/src/common/ai/EntityAIMoveTowardsRestriction.java index 900d49b..daf2b9b 100755 --- a/java/src/game/ai/EntityAIMoveTowardsRestriction.java +++ b/java/src/common/ai/EntityAIMoveTowardsRestriction.java @@ -1,8 +1,8 @@ -package game.ai; +package common.ai; -import game.entity.types.EntityLiving; -import game.world.BlockPos; -import game.world.Vec3; +import common.entity.types.EntityLiving; +import common.world.BlockPos; +import common.world.Vec3; public class EntityAIMoveTowardsRestriction extends EntityAIBase { diff --git a/java/src/game/ai/EntityAIMoveTowardsTarget.java b/java/src/common/ai/EntityAIMoveTowardsTarget.java similarity index 96% rename from java/src/game/ai/EntityAIMoveTowardsTarget.java rename to java/src/common/ai/EntityAIMoveTowardsTarget.java index c85bd02..eaff1e3 100755 --- a/java/src/game/ai/EntityAIMoveTowardsTarget.java +++ b/java/src/common/ai/EntityAIMoveTowardsTarget.java @@ -1,7 +1,7 @@ -package game.ai; +package common.ai; -import game.entity.types.EntityLiving; -import game.world.Vec3; +import common.entity.types.EntityLiving; +import common.world.Vec3; public class EntityAIMoveTowardsTarget extends EntityAIBase { diff --git a/java/src/game/ai/EntityAINagPlayer.java b/java/src/common/ai/EntityAINagPlayer.java similarity index 91% rename from java/src/game/ai/EntityAINagPlayer.java rename to java/src/common/ai/EntityAINagPlayer.java index b880895..e83c0c0 100755 --- a/java/src/game/ai/EntityAINagPlayer.java +++ b/java/src/common/ai/EntityAINagPlayer.java @@ -1,7 +1,7 @@ -package game.ai; +package common.ai; -import game.entity.npc.EntityNPC; -import game.inventory.ContainerMerchant; +import common.entity.npc.EntityNPC; +import common.inventory.ContainerMerchant; public class EntityAINagPlayer extends EntityAIBase { diff --git a/java/src/game/ai/EntityAINearestAttackableTarget.java b/java/src/common/ai/EntityAINearestAttackableTarget.java similarity index 98% rename from java/src/game/ai/EntityAINearestAttackableTarget.java rename to java/src/common/ai/EntityAINearestAttackableTarget.java index 3e7ed3b..05d3245 100755 --- a/java/src/game/ai/EntityAINearestAttackableTarget.java +++ b/java/src/common/ai/EntityAINearestAttackableTarget.java @@ -1,12 +1,12 @@ -package game.ai; +package common.ai; import java.util.Collections; import java.util.Comparator; import java.util.List; import java.util.function.Predicate; -import game.entity.Entity; -import game.entity.types.EntityLiving; +import common.entity.Entity; +import common.entity.types.EntityLiving; public class EntityAINearestAttackableTarget extends EntityAITarget { diff --git a/java/src/game/ai/EntityAINpcInteract.java b/java/src/common/ai/EntityAINpcInteract.java similarity index 95% rename from java/src/game/ai/EntityAINpcInteract.java rename to java/src/common/ai/EntityAINpcInteract.java index 82c5c4c..99849a0 100755 --- a/java/src/game/ai/EntityAINpcInteract.java +++ b/java/src/common/ai/EntityAINpcInteract.java @@ -1,6 +1,6 @@ -package game.ai; +package common.ai; -import game.entity.npc.EntityNPC; +import common.entity.npc.EntityNPC; public class EntityAINpcInteract extends EntityAIWatchClosest2 { diff --git a/java/src/game/ai/EntityAINpcMate.java b/java/src/common/ai/EntityAINpcMate.java similarity index 95% rename from java/src/game/ai/EntityAINpcMate.java rename to java/src/common/ai/EntityAINpcMate.java index ee555de..654af34 100755 --- a/java/src/game/ai/EntityAINpcMate.java +++ b/java/src/common/ai/EntityAINpcMate.java @@ -1,9 +1,9 @@ -package game.ai; +package common.ai; -import game.entity.Entity; -import game.entity.npc.EntityNPC; -import game.world.World; -import game.world.WorldServer; +import common.entity.Entity; +import common.entity.npc.EntityNPC; +import common.world.World; +import common.world.WorldServer; public class EntityAINpcMate extends EntityAIBase { diff --git a/java/src/game/ai/EntityAIOcelotAttack.java b/java/src/common/ai/EntityAIOcelotAttack.java similarity index 96% rename from java/src/game/ai/EntityAIOcelotAttack.java rename to java/src/common/ai/EntityAIOcelotAttack.java index cb48c13..87c61e8 100755 --- a/java/src/game/ai/EntityAIOcelotAttack.java +++ b/java/src/common/ai/EntityAIOcelotAttack.java @@ -1,7 +1,7 @@ -package game.ai; +package common.ai; -import game.entity.types.EntityLiving; -import game.world.World; +import common.entity.types.EntityLiving; +import common.world.World; public class EntityAIOcelotAttack extends EntityAIBase { diff --git a/java/src/game/ai/EntityAIOcelotSit.java b/java/src/common/ai/EntityAIOcelotSit.java similarity index 88% rename from java/src/game/ai/EntityAIOcelotSit.java rename to java/src/common/ai/EntityAIOcelotSit.java index cfa2b7e..f6d329d 100755 --- a/java/src/game/ai/EntityAIOcelotSit.java +++ b/java/src/common/ai/EntityAIOcelotSit.java @@ -1,14 +1,14 @@ -package game.ai; +package common.ai; -import game.block.Block; -import game.block.BlockBed; -import game.entity.animal.EntityOcelot; -import game.init.Blocks; -import game.tileentity.TileEntity; -import game.tileentity.TileEntityChest; -import game.world.BlockPos; -import game.world.State; -import game.world.World; +import common.block.Block; +import common.block.BlockBed; +import common.entity.animal.EntityOcelot; +import common.init.Blocks; +import common.tileentity.TileEntity; +import common.tileentity.TileEntityChest; +import common.world.BlockPos; +import common.world.State; +import common.world.World; public class EntityAIOcelotSit extends EntityAIMoveToBlock { diff --git a/java/src/game/ai/EntityAIOpenDoor.java b/java/src/common/ai/EntityAIOpenDoor.java similarity index 95% rename from java/src/game/ai/EntityAIOpenDoor.java rename to java/src/common/ai/EntityAIOpenDoor.java index 50879d0..7956a61 100755 --- a/java/src/game/ai/EntityAIOpenDoor.java +++ b/java/src/common/ai/EntityAIOpenDoor.java @@ -1,6 +1,6 @@ -package game.ai; +package common.ai; -import game.entity.types.EntityLiving; +import common.entity.types.EntityLiving; public class EntityAIOpenDoor extends EntityAIDoorInteract { diff --git a/java/src/game/ai/EntityAIOwnerHurtByTarget.java b/java/src/common/ai/EntityAIOwnerHurtByTarget.java similarity index 94% rename from java/src/game/ai/EntityAIOwnerHurtByTarget.java rename to java/src/common/ai/EntityAIOwnerHurtByTarget.java index 0230e15..70c3b95 100755 --- a/java/src/game/ai/EntityAIOwnerHurtByTarget.java +++ b/java/src/common/ai/EntityAIOwnerHurtByTarget.java @@ -1,7 +1,7 @@ -package game.ai; +package common.ai; -import game.entity.types.EntityLiving; -import game.entity.types.EntityTameable; +import common.entity.types.EntityLiving; +import common.entity.types.EntityTameable; public class EntityAIOwnerHurtByTarget extends EntityAITarget { diff --git a/java/src/game/ai/EntityAIOwnerHurtTarget.java b/java/src/common/ai/EntityAIOwnerHurtTarget.java similarity index 93% rename from java/src/game/ai/EntityAIOwnerHurtTarget.java rename to java/src/common/ai/EntityAIOwnerHurtTarget.java index 8dc2e2a..27d9d53 100755 --- a/java/src/game/ai/EntityAIOwnerHurtTarget.java +++ b/java/src/common/ai/EntityAIOwnerHurtTarget.java @@ -1,7 +1,7 @@ -package game.ai; +package common.ai; -import game.entity.types.EntityLiving; -import game.entity.types.EntityTameable; +import common.entity.types.EntityLiving; +import common.entity.types.EntityTameable; public class EntityAIOwnerHurtTarget extends EntityAITarget { diff --git a/java/src/game/ai/EntityAIPanic.java b/java/src/common/ai/EntityAIPanic.java similarity index 94% rename from java/src/game/ai/EntityAIPanic.java rename to java/src/common/ai/EntityAIPanic.java index 0735848..ab28240 100755 --- a/java/src/game/ai/EntityAIPanic.java +++ b/java/src/common/ai/EntityAIPanic.java @@ -1,7 +1,7 @@ -package game.ai; +package common.ai; -import game.entity.types.EntityLiving; -import game.world.Vec3; +import common.entity.types.EntityLiving; +import common.world.Vec3; public class EntityAIPanic extends EntityAIBase { diff --git a/java/src/game/ai/EntityAIPlay.java b/java/src/common/ai/EntityAIPlay.java similarity index 93% rename from java/src/game/ai/EntityAIPlay.java rename to java/src/common/ai/EntityAIPlay.java index 83fec8f..38363e6 100755 --- a/java/src/game/ai/EntityAIPlay.java +++ b/java/src/common/ai/EntityAIPlay.java @@ -1,10 +1,10 @@ -package game.ai; +package common.ai; import java.util.List; -import game.entity.npc.EntityNPC; -import game.entity.types.EntityLiving; -import game.world.Vec3; +import common.entity.npc.EntityNPC; +import common.entity.types.EntityLiving; +import common.world.Vec3; public class EntityAIPlay extends EntityAIBase { private EntityNPC entity; diff --git a/java/src/game/ai/EntityAIRestrictOpenDoor.java b/java/src/common/ai/EntityAIRestrictOpenDoor.java similarity index 90% rename from java/src/game/ai/EntityAIRestrictOpenDoor.java rename to java/src/common/ai/EntityAIRestrictOpenDoor.java index 94991dc..c89644b 100755 --- a/java/src/game/ai/EntityAIRestrictOpenDoor.java +++ b/java/src/common/ai/EntityAIRestrictOpenDoor.java @@ -1,11 +1,11 @@ -package game.ai; +package common.ai; -import game.entity.types.EntityLiving; -import game.pathfinding.PathNavigateGround; -import game.village.Village; -import game.village.VillageDoorInfo; -import game.world.BlockPos; -import game.world.WorldServer; +import common.entity.types.EntityLiving; +import common.pathfinding.PathNavigateGround; +import common.village.Village; +import common.village.VillageDoorInfo; +import common.world.BlockPos; +import common.world.WorldServer; public class EntityAIRestrictOpenDoor extends EntityAIBase { diff --git a/java/src/game/ai/EntityAIRestrictSun.java b/java/src/common/ai/EntityAIRestrictSun.java similarity index 84% rename from java/src/game/ai/EntityAIRestrictSun.java rename to java/src/common/ai/EntityAIRestrictSun.java index 80068d0..2734f28 100755 --- a/java/src/game/ai/EntityAIRestrictSun.java +++ b/java/src/common/ai/EntityAIRestrictSun.java @@ -1,8 +1,8 @@ -package game.ai; +package common.ai; -import game.entity.types.EntityLiving; -import game.pathfinding.PathNavigateGround; -import game.world.WorldServer; +import common.entity.types.EntityLiving; +import common.pathfinding.PathNavigateGround; +import common.world.WorldServer; public class EntityAIRestrictSun extends EntityAIBase { diff --git a/java/src/game/ai/EntityAIRunAroundLikeCrazy.java b/java/src/common/ai/EntityAIRunAroundLikeCrazy.java similarity index 94% rename from java/src/game/ai/EntityAIRunAroundLikeCrazy.java rename to java/src/common/ai/EntityAIRunAroundLikeCrazy.java index baaeb2c..9b02e75 100755 --- a/java/src/game/ai/EntityAIRunAroundLikeCrazy.java +++ b/java/src/common/ai/EntityAIRunAroundLikeCrazy.java @@ -1,9 +1,9 @@ -package game.ai; +package common.ai; -import game.entity.Entity; -import game.entity.animal.EntityHorse; -import game.entity.npc.EntityNPC; -import game.world.Vec3; +import common.entity.Entity; +import common.entity.animal.EntityHorse; +import common.entity.npc.EntityNPC; +import common.world.Vec3; public class EntityAIRunAroundLikeCrazy extends EntityAIBase { diff --git a/java/src/game/ai/EntityAIShareItems.java b/java/src/common/ai/EntityAIShareItems.java similarity index 93% rename from java/src/game/ai/EntityAIShareItems.java rename to java/src/common/ai/EntityAIShareItems.java index e0bda32..b22235c 100755 --- a/java/src/game/ai/EntityAIShareItems.java +++ b/java/src/common/ai/EntityAIShareItems.java @@ -1,12 +1,12 @@ -package game.ai; +package common.ai; -import game.entity.item.EntityItem; -import game.entity.npc.EntityNPC; -import game.init.Items; -import game.inventory.InventoryBasic; -import game.item.Item; -import game.item.ItemStack; -import game.util.ExtMath; +import common.entity.item.EntityItem; +import common.entity.npc.EntityNPC; +import common.init.Items; +import common.inventory.InventoryBasic; +import common.item.Item; +import common.item.ItemStack; +import common.util.ExtMath; public class EntityAIShareItems extends EntityAIWatchClosest2 { diff --git a/java/src/game/ai/EntityAISit.java b/java/src/common/ai/EntityAISit.java similarity index 93% rename from java/src/game/ai/EntityAISit.java rename to java/src/common/ai/EntityAISit.java index 48d0b4f..6ffb567 100755 --- a/java/src/game/ai/EntityAISit.java +++ b/java/src/common/ai/EntityAISit.java @@ -1,7 +1,7 @@ -package game.ai; +package common.ai; -import game.entity.types.EntityLiving; -import game.entity.types.EntityTameable; +import common.entity.types.EntityLiving; +import common.entity.types.EntityTameable; public class EntityAISit extends EntityAIBase { diff --git a/java/src/game/ai/EntityAISwimming.java b/java/src/common/ai/EntityAISwimming.java similarity index 87% rename from java/src/game/ai/EntityAISwimming.java rename to java/src/common/ai/EntityAISwimming.java index eb7e86a..b7a6193 100755 --- a/java/src/game/ai/EntityAISwimming.java +++ b/java/src/common/ai/EntityAISwimming.java @@ -1,7 +1,7 @@ -package game.ai; +package common.ai; -import game.entity.types.EntityLiving; -import game.pathfinding.PathNavigateGround; +import common.entity.types.EntityLiving; +import common.pathfinding.PathNavigateGround; public class EntityAISwimming extends EntityAIBase { diff --git a/java/src/game/ai/EntityAITakePlace.java b/java/src/common/ai/EntityAITakePlace.java similarity index 93% rename from java/src/game/ai/EntityAITakePlace.java rename to java/src/common/ai/EntityAITakePlace.java index 597bf01..bde8a0a 100755 --- a/java/src/game/ai/EntityAITakePlace.java +++ b/java/src/common/ai/EntityAITakePlace.java @@ -1,20 +1,20 @@ -package game.ai; +package common.ai; import java.util.Map; -import game.block.Block; -import game.collect.Maps; -import game.entity.npc.EntityNPC; -import game.init.Blocks; -import game.init.Config; -import game.init.ItemRegistry; -import game.item.ItemStack; -import game.material.Material; -import game.rng.Random; -import game.util.ExtMath; -import game.world.BlockPos; -import game.world.State; -import game.world.World; +import common.block.Block; +import common.collect.Maps; +import common.entity.npc.EntityNPC; +import common.init.Blocks; +import common.init.Config; +import common.init.ItemRegistry; +import common.item.ItemStack; +import common.material.Material; +import common.rng.Random; +import common.util.ExtMath; +import common.world.BlockPos; +import common.world.State; +import common.world.World; public class EntityAITakePlace extends EntityAIBase { diff --git a/java/src/game/ai/EntityAITarget.java b/java/src/common/ai/EntityAITarget.java similarity index 95% rename from java/src/game/ai/EntityAITarget.java rename to java/src/common/ai/EntityAITarget.java index 506cf60..7890657 100755 --- a/java/src/game/ai/EntityAITarget.java +++ b/java/src/common/ai/EntityAITarget.java @@ -1,14 +1,14 @@ -package game.ai; +package common.ai; -import game.entity.attributes.AttributeInstance; -import game.entity.attributes.Attributes; -import game.entity.types.EntityLiving; -import game.entity.types.IEntityOwnable; -import game.init.Config; -import game.pathfinding.PathEntity; -import game.pathfinding.PathPoint; -import game.util.ExtMath; -import game.world.BlockPos; +import common.entity.attributes.AttributeInstance; +import common.entity.attributes.Attributes; +import common.entity.types.EntityLiving; +import common.entity.types.IEntityOwnable; +import common.init.Config; +import common.pathfinding.PathEntity; +import common.pathfinding.PathPoint; +import common.util.ExtMath; +import common.world.BlockPos; public abstract class EntityAITarget extends EntityAIBase { diff --git a/java/src/game/ai/EntityAITargetNonTamed.java b/java/src/common/ai/EntityAITargetNonTamed.java similarity index 86% rename from java/src/game/ai/EntityAITargetNonTamed.java rename to java/src/common/ai/EntityAITargetNonTamed.java index 4b9fd5b..2b0cfc3 100755 --- a/java/src/game/ai/EntityAITargetNonTamed.java +++ b/java/src/common/ai/EntityAITargetNonTamed.java @@ -1,9 +1,9 @@ -package game.ai; +package common.ai; import java.util.function.Predicate; -import game.entity.types.EntityLiving; -import game.entity.types.EntityTameable; +import common.entity.types.EntityLiving; +import common.entity.types.EntityTameable; public class EntityAITargetNonTamed extends EntityAINearestAttackableTarget { diff --git a/java/src/game/ai/EntityAITasks.java b/java/src/common/ai/EntityAITasks.java similarity index 99% rename from java/src/game/ai/EntityAITasks.java rename to java/src/common/ai/EntityAITasks.java index 3db2a95..98f50c9 100755 --- a/java/src/game/ai/EntityAITasks.java +++ b/java/src/common/ai/EntityAITasks.java @@ -1,9 +1,9 @@ -package game.ai; +package common.ai; import java.util.Iterator; import java.util.List; -import game.collect.Lists; +import common.collect.Lists; public class EntityAITasks { diff --git a/java/src/game/ai/EntityAITempt.java b/java/src/common/ai/EntityAITempt.java similarity index 96% rename from java/src/game/ai/EntityAITempt.java rename to java/src/common/ai/EntityAITempt.java index ff230ba..a7008c7 100755 --- a/java/src/game/ai/EntityAITempt.java +++ b/java/src/common/ai/EntityAITempt.java @@ -1,10 +1,10 @@ -package game.ai; +package common.ai; -import game.entity.npc.EntityNPC; -import game.entity.types.EntityLiving; -import game.item.Item; -import game.item.ItemStack; -import game.pathfinding.PathNavigateGround; +import common.entity.npc.EntityNPC; +import common.entity.types.EntityLiving; +import common.item.Item; +import common.item.ItemStack; +import common.pathfinding.PathNavigateGround; public class EntityAITempt extends EntityAIBase { diff --git a/java/src/game/ai/EntityAIWander.java b/java/src/common/ai/EntityAIWander.java similarity index 96% rename from java/src/game/ai/EntityAIWander.java rename to java/src/common/ai/EntityAIWander.java index 29e1c68..f1ae22a 100755 --- a/java/src/game/ai/EntityAIWander.java +++ b/java/src/common/ai/EntityAIWander.java @@ -1,7 +1,7 @@ -package game.ai; +package common.ai; -import game.entity.types.EntityLiving; -import game.world.Vec3; +import common.entity.types.EntityLiving; +import common.world.Vec3; public class EntityAIWander extends EntityAIBase { diff --git a/java/src/game/ai/EntityAIWatchClosest.java b/java/src/common/ai/EntityAIWatchClosest.java similarity index 96% rename from java/src/game/ai/EntityAIWatchClosest.java rename to java/src/common/ai/EntityAIWatchClosest.java index 54c17a7..81b0a9e 100755 --- a/java/src/game/ai/EntityAIWatchClosest.java +++ b/java/src/common/ai/EntityAIWatchClosest.java @@ -1,8 +1,8 @@ -package game.ai; +package common.ai; -import game.entity.Entity; -import game.entity.types.EntityLiving; -import game.world.WorldServer; +import common.entity.Entity; +import common.entity.types.EntityLiving; +import common.world.WorldServer; public class EntityAIWatchClosest extends EntityAIBase { diff --git a/java/src/game/ai/EntityAIWatchClosest2.java b/java/src/common/ai/EntityAIWatchClosest2.java similarity index 78% rename from java/src/game/ai/EntityAIWatchClosest2.java rename to java/src/common/ai/EntityAIWatchClosest2.java index 8991e82..0684c41 100755 --- a/java/src/game/ai/EntityAIWatchClosest2.java +++ b/java/src/common/ai/EntityAIWatchClosest2.java @@ -1,7 +1,7 @@ -package game.ai; +package common.ai; -import game.entity.Entity; -import game.entity.types.EntityLiving; +import common.entity.Entity; +import common.entity.types.EntityLiving; public class EntityAIWatchClosest2 extends EntityAIWatchClosest { diff --git a/java/src/game/ai/EntityJumpHelper.java b/java/src/common/ai/EntityJumpHelper.java similarity index 88% rename from java/src/game/ai/EntityJumpHelper.java rename to java/src/common/ai/EntityJumpHelper.java index 461cff0..cf9b91c 100755 --- a/java/src/game/ai/EntityJumpHelper.java +++ b/java/src/common/ai/EntityJumpHelper.java @@ -1,6 +1,6 @@ -package game.ai; +package common.ai; -import game.entity.types.EntityLiving; +import common.entity.types.EntityLiving; public class EntityJumpHelper { diff --git a/java/src/game/ai/EntityLookHelper.java b/java/src/common/ai/EntityLookHelper.java similarity index 96% rename from java/src/game/ai/EntityLookHelper.java rename to java/src/common/ai/EntityLookHelper.java index e2a5243..26e5d7e 100755 --- a/java/src/game/ai/EntityLookHelper.java +++ b/java/src/common/ai/EntityLookHelper.java @@ -1,8 +1,8 @@ -package game.ai; +package common.ai; -import game.entity.Entity; -import game.entity.types.EntityLiving; -import game.util.ExtMath; +import common.entity.Entity; +import common.entity.types.EntityLiving; +import common.util.ExtMath; public class EntityLookHelper { diff --git a/java/src/game/ai/EntityMoveHelper.java b/java/src/common/ai/EntityMoveHelper.java similarity index 95% rename from java/src/game/ai/EntityMoveHelper.java rename to java/src/common/ai/EntityMoveHelper.java index a7f8e5c..1528c0e 100755 --- a/java/src/game/ai/EntityMoveHelper.java +++ b/java/src/common/ai/EntityMoveHelper.java @@ -1,8 +1,8 @@ -package game.ai; +package common.ai; -import game.entity.attributes.Attributes; -import game.entity.types.EntityLiving; -import game.util.ExtMath; +import common.entity.attributes.Attributes; +import common.entity.types.EntityLiving; +import common.util.ExtMath; public class EntityMoveHelper { diff --git a/java/src/game/ai/EntitySenses.java b/java/src/common/ai/EntitySenses.java similarity index 91% rename from java/src/game/ai/EntitySenses.java rename to java/src/common/ai/EntitySenses.java index 245cafb..b0aa429 100755 --- a/java/src/game/ai/EntitySenses.java +++ b/java/src/common/ai/EntitySenses.java @@ -1,10 +1,10 @@ -package game.ai; +package common.ai; import java.util.List; -import game.collect.Lists; -import game.entity.Entity; -import game.entity.types.EntityLiving; +import common.collect.Lists; +import common.entity.Entity; +import common.entity.types.EntityLiving; public class EntitySenses { diff --git a/java/src/game/ai/RandomPositionGenerator.java b/java/src/common/ai/RandomPositionGenerator.java similarity index 96% rename from java/src/game/ai/RandomPositionGenerator.java rename to java/src/common/ai/RandomPositionGenerator.java index 57712ba..74c03ed 100755 --- a/java/src/game/ai/RandomPositionGenerator.java +++ b/java/src/common/ai/RandomPositionGenerator.java @@ -1,10 +1,10 @@ -package game.ai; +package common.ai; -import game.entity.types.EntityLiving; -import game.rng.Random; -import game.util.ExtMath; -import game.world.BlockPos; -import game.world.Vec3; +import common.entity.types.EntityLiving; +import common.rng.Random; +import common.util.ExtMath; +import common.world.BlockPos; +import common.world.Vec3; public class RandomPositionGenerator { diff --git a/java/src/game/biome/Biome.java b/java/src/common/biome/Biome.java similarity index 93% rename from java/src/game/biome/Biome.java rename to java/src/common/biome/Biome.java index b7a60d3..cabe35b 100755 --- a/java/src/game/biome/Biome.java +++ b/java/src/common/biome/Biome.java @@ -1,61 +1,61 @@ -package game.biome; +package common.biome; import java.util.List; import java.util.Map; -import game.block.Block; -import game.block.BlockColored; -import game.block.BlockFlower; -import game.block.BlockSand; -import game.block.BlockTallGrass; -import game.collect.Lists; -import game.collect.Maps; -import game.color.Colorizer; -import game.color.DyeColor; -import game.entity.animal.EntityBat; -import game.entity.animal.EntityChicken; -import game.entity.animal.EntityCow; -import game.entity.animal.EntityMouse; -import game.entity.animal.EntityPig; -import game.entity.animal.EntityRabbit; -import game.entity.animal.EntitySheep; -import game.entity.animal.EntitySquid; -import game.entity.npc.EntityArachnoid; -import game.entity.npc.EntityHaunter; -import game.entity.npc.EntityMage; -import game.entity.npc.EntitySlime; -import game.entity.npc.EntityUndead; -import game.entity.npc.EntityZombie; -import game.init.Blocks; -import game.log.Log; -import game.material.Material; -import game.rng.PerlinGen; -import game.rng.Random; -import game.rng.WeightedList; -import game.util.ExtMath; -import game.world.BlockPos; -import game.world.State; -import game.world.World; -import game.world.WorldServer; -import game.worldgen.ChunkPrimer; -import game.worldgen.FeatureGenerator; -import game.worldgen.feature.WorldGenClay; -import game.worldgen.feature.WorldGenClayExt; -import game.worldgen.feature.WorldGenSand; -import game.worldgen.foliage.FeatureDoublePlant; -import game.worldgen.foliage.WorldGenBigMushroom; -import game.worldgen.foliage.WorldGenCactus; -import game.worldgen.foliage.WorldGenDeadBush; -import game.worldgen.foliage.WorldGenFlowers; -import game.worldgen.foliage.WorldGenMushroom; -import game.worldgen.foliage.WorldGenPumpkin; -import game.worldgen.foliage.WorldGenReed; -import game.worldgen.foliage.WorldGenTallGrass; -import game.worldgen.foliage.WorldGenWaterlily; -import game.worldgen.tree.WorldGenBaseTree; -import game.worldgen.tree.WorldGenBigTree; -import game.worldgen.tree.WorldGenSwamp; -import game.worldgen.tree.WorldGenTree; +import common.block.Block; +import common.block.BlockColored; +import common.block.BlockFlower; +import common.block.BlockSand; +import common.block.BlockTallGrass; +import common.collect.Lists; +import common.collect.Maps; +import common.color.Colorizer; +import common.color.DyeColor; +import common.entity.animal.EntityBat; +import common.entity.animal.EntityChicken; +import common.entity.animal.EntityCow; +import common.entity.animal.EntityMouse; +import common.entity.animal.EntityPig; +import common.entity.animal.EntityRabbit; +import common.entity.animal.EntitySheep; +import common.entity.animal.EntitySquid; +import common.entity.npc.EntityArachnoid; +import common.entity.npc.EntityHaunter; +import common.entity.npc.EntityMage; +import common.entity.npc.EntitySlime; +import common.entity.npc.EntityUndead; +import common.entity.npc.EntityZombie; +import common.init.Blocks; +import common.log.Log; +import common.material.Material; +import common.rng.PerlinGen; +import common.rng.Random; +import common.rng.WeightedList; +import common.util.ExtMath; +import common.world.BlockPos; +import common.world.State; +import common.world.World; +import common.world.WorldServer; +import common.worldgen.ChunkPrimer; +import common.worldgen.FeatureGenerator; +import common.worldgen.feature.WorldGenClay; +import common.worldgen.feature.WorldGenClayExt; +import common.worldgen.feature.WorldGenSand; +import common.worldgen.foliage.FeatureDoublePlant; +import common.worldgen.foliage.WorldGenBigMushroom; +import common.worldgen.foliage.WorldGenCactus; +import common.worldgen.foliage.WorldGenDeadBush; +import common.worldgen.foliage.WorldGenFlowers; +import common.worldgen.foliage.WorldGenMushroom; +import common.worldgen.foliage.WorldGenPumpkin; +import common.worldgen.foliage.WorldGenReed; +import common.worldgen.foliage.WorldGenTallGrass; +import common.worldgen.foliage.WorldGenWaterlily; +import common.worldgen.tree.WorldGenBaseTree; +import common.worldgen.tree.WorldGenBigTree; +import common.worldgen.tree.WorldGenSwamp; +import common.worldgen.tree.WorldGenTree; public abstract class Biome { private static final Biome[] BIOMES = new Biome[256]; diff --git a/java/src/game/biome/BiomeBeach.java b/java/src/common/biome/BiomeBeach.java similarity index 83% rename from java/src/game/biome/BiomeBeach.java rename to java/src/common/biome/BiomeBeach.java index 982f2c6..f73c715 100755 --- a/java/src/game/biome/BiomeBeach.java +++ b/java/src/common/biome/BiomeBeach.java @@ -1,7 +1,7 @@ -package game.biome; +package common.biome; -import game.init.Blocks; -import game.rng.WeightedList; +import common.init.Blocks; +import common.rng.WeightedList; public class BiomeBeach extends Biome { diff --git a/java/src/game/biome/BiomeBlackened.java b/java/src/common/biome/BiomeBlackened.java similarity index 70% rename from java/src/game/biome/BiomeBlackened.java rename to java/src/common/biome/BiomeBlackened.java index 996197e..082be75 100644 --- a/java/src/game/biome/BiomeBlackened.java +++ b/java/src/common/biome/BiomeBlackened.java @@ -1,13 +1,13 @@ -package game.biome; +package common.biome; -import game.block.BlockFlower; -import game.entity.npc.EntityMetalhead; -import game.init.Blocks; -import game.rng.Random; -import game.rng.WeightedList; -import game.world.BlockPos; -import game.worldgen.tree.WorldGenBaseTree; -import game.worldgen.tree.WorldGenTree; +import common.block.BlockFlower; +import common.entity.npc.EntityMetalhead; +import common.init.Blocks; +import common.rng.Random; +import common.rng.WeightedList; +import common.world.BlockPos; +import common.worldgen.tree.WorldGenBaseTree; +import common.worldgen.tree.WorldGenTree; public class BiomeBlackened extends Biome { protected final WorldGenTree treeGen = new WorldGenBaseTree(false, Blocks.blackwood_log.getState(), Blocks.blackwood_leaves.getState()); diff --git a/java/src/game/biome/BiomeChaos.java b/java/src/common/biome/BiomeChaos.java similarity index 73% rename from java/src/game/biome/BiomeChaos.java rename to java/src/common/biome/BiomeChaos.java index 01203b9..a068043 100755 --- a/java/src/game/biome/BiomeChaos.java +++ b/java/src/common/biome/BiomeChaos.java @@ -1,15 +1,15 @@ -package game.biome; +package common.biome; -import game.entity.Entity; -import game.entity.types.EntityLiving; -import game.init.Blocks; -import game.init.EntityRegistry; -import game.rng.Random; -import game.rng.WeightedList; -import game.world.BlockPos; -import game.world.WorldServer; -import game.worldgen.FeatureGenerator; -import game.worldgen.foliage.WorldGenMushroom; +import common.entity.Entity; +import common.entity.types.EntityLiving; +import common.init.Blocks; +import common.init.EntityRegistry; +import common.rng.Random; +import common.rng.WeightedList; +import common.world.BlockPos; +import common.world.WorldServer; +import common.worldgen.FeatureGenerator; +import common.worldgen.foliage.WorldGenMushroom; public class BiomeChaos extends Biome { diff --git a/java/src/game/biome/BiomeDesert.java b/java/src/common/biome/BiomeDesert.java similarity index 79% rename from java/src/game/biome/BiomeDesert.java rename to java/src/common/biome/BiomeDesert.java index 895310a..56da83c 100755 --- a/java/src/game/biome/BiomeDesert.java +++ b/java/src/common/biome/BiomeDesert.java @@ -1,11 +1,11 @@ -package game.biome; +package common.biome; -import game.init.Blocks; -import game.rng.Random; -import game.rng.WeightedList; -import game.world.BlockPos; -import game.world.WorldServer; -import game.worldgen.feature.WorldGenDesertWells; +import common.init.Blocks; +import common.rng.Random; +import common.rng.WeightedList; +import common.world.BlockPos; +import common.world.WorldServer; +import common.worldgen.feature.WorldGenDesertWells; public class BiomeDesert extends Biome { diff --git a/java/src/game/biome/BiomeExterminated.java b/java/src/common/biome/BiomeExterminated.java similarity index 73% rename from java/src/game/biome/BiomeExterminated.java rename to java/src/common/biome/BiomeExterminated.java index 076c215..837aaaf 100755 --- a/java/src/game/biome/BiomeExterminated.java +++ b/java/src/common/biome/BiomeExterminated.java @@ -1,10 +1,10 @@ -package game.biome; +package common.biome; -import game.init.Blocks; -import game.rng.Random; -import game.rng.WeightedList; -import game.world.BlockPos; -import game.world.WorldServer; +import common.init.Blocks; +import common.rng.Random; +import common.rng.WeightedList; +import common.world.BlockPos; +import common.world.WorldServer; public class BiomeExterminated extends Biome { public BiomeExterminated(int id) { diff --git a/java/src/game/biome/BiomeForest.java b/java/src/common/biome/BiomeForest.java similarity index 93% rename from java/src/game/biome/BiomeForest.java rename to java/src/common/biome/BiomeForest.java index 01a409c..183668b 100755 --- a/java/src/game/biome/BiomeForest.java +++ b/java/src/common/biome/BiomeForest.java @@ -1,22 +1,22 @@ -package game.biome; +package common.biome; -import game.block.BlockDoublePlant; -import game.block.BlockFlower; -import game.color.Colorizer; -import game.entity.animal.EntityWolf; -import game.entity.npc.EntityElf; -import game.entity.npc.EntityWoodElf; -import game.init.Blocks; -import game.rng.Random; -import game.util.ExtMath; -import game.world.BlockPos; -import game.world.WorldServer; -import game.worldgen.foliage.WorldGenBigMushroom; -import game.worldgen.tree.WorldGenBaseTree; -import game.worldgen.tree.WorldGenBigTree; -import game.worldgen.tree.WorldGenBirch; -import game.worldgen.tree.WorldGenDarkOak; -import game.worldgen.tree.WorldGenTree; +import common.block.BlockDoublePlant; +import common.block.BlockFlower; +import common.color.Colorizer; +import common.entity.animal.EntityWolf; +import common.entity.npc.EntityElf; +import common.entity.npc.EntityWoodElf; +import common.init.Blocks; +import common.rng.Random; +import common.util.ExtMath; +import common.world.BlockPos; +import common.world.WorldServer; +import common.worldgen.foliage.WorldGenBigMushroom; +import common.worldgen.tree.WorldGenBaseTree; +import common.worldgen.tree.WorldGenBigTree; +import common.worldgen.tree.WorldGenBirch; +import common.worldgen.tree.WorldGenDarkOak; +import common.worldgen.tree.WorldGenTree; public class BiomeForest extends Biome { diff --git a/java/src/game/biome/BiomeHell.java b/java/src/common/biome/BiomeHell.java similarity index 87% rename from java/src/game/biome/BiomeHell.java rename to java/src/common/biome/BiomeHell.java index 8f4d3c3..0591795 100755 --- a/java/src/game/biome/BiomeHell.java +++ b/java/src/common/biome/BiomeHell.java @@ -1,21 +1,21 @@ -package game.biome; +package common.biome; -import game.entity.npc.EntityBloodElf; -import game.entity.npc.EntityCultivator; -import game.entity.npc.EntityFireDemon; -import game.entity.npc.EntityMagma; -import game.entity.npc.EntityMetalhead; -import game.entity.npc.EntityTiefling; -import game.init.Blocks; -import game.rng.Random; -import game.rng.WeightedList; -import game.world.BlockPos; -import game.world.WorldServer; -import game.worldgen.FeatureOres; -import game.worldgen.feature.WorldGenFire; -import game.worldgen.feature.WorldGenGlowStone; -import game.worldgen.feature.WorldGenHellLava; -import game.worldgen.foliage.WorldGenMushroom; +import common.entity.npc.EntityBloodElf; +import common.entity.npc.EntityCultivator; +import common.entity.npc.EntityFireDemon; +import common.entity.npc.EntityMagma; +import common.entity.npc.EntityMetalhead; +import common.entity.npc.EntityTiefling; +import common.init.Blocks; +import common.rng.Random; +import common.rng.WeightedList; +import common.world.BlockPos; +import common.world.WorldServer; +import common.worldgen.FeatureOres; +import common.worldgen.feature.WorldGenFire; +import common.worldgen.feature.WorldGenGlowStone; +import common.worldgen.feature.WorldGenHellLava; +import common.worldgen.foliage.WorldGenMushroom; public class BiomeHell extends Biome { diff --git a/java/src/game/biome/BiomeHills.java b/java/src/common/biome/BiomeHills.java similarity index 91% rename from java/src/game/biome/BiomeHills.java rename to java/src/common/biome/BiomeHills.java index 7f86b7b..125e977 100755 --- a/java/src/game/biome/BiomeHills.java +++ b/java/src/common/biome/BiomeHills.java @@ -1,13 +1,13 @@ -package game.biome; +package common.biome; -import game.init.Blocks; -import game.rng.Random; -import game.world.BlockPos; -import game.world.WorldServer; -import game.worldgen.ChunkPrimer; -import game.worldgen.FeatureOres; -import game.worldgen.tree.WorldGenTaiga2; -import game.worldgen.tree.WorldGenTree; +import common.init.Blocks; +import common.rng.Random; +import common.world.BlockPos; +import common.world.WorldServer; +import common.worldgen.ChunkPrimer; +import common.worldgen.FeatureOres; +import common.worldgen.tree.WorldGenTaiga2; +import common.worldgen.tree.WorldGenTree; public class BiomeHills extends Biome { diff --git a/java/src/game/biome/BiomeJungle.java b/java/src/common/biome/BiomeJungle.java similarity index 78% rename from java/src/game/biome/BiomeJungle.java rename to java/src/common/biome/BiomeJungle.java index ce45cb2..dbbc6d6 100755 --- a/java/src/game/biome/BiomeJungle.java +++ b/java/src/common/biome/BiomeJungle.java @@ -1,21 +1,21 @@ -package game.biome; +package common.biome; -import game.block.BlockTallGrass; -import game.entity.animal.EntityChicken; -import game.entity.animal.EntityOcelot; -import game.init.Blocks; -import game.rng.Random; -import game.world.BlockPos; -import game.world.State; -import game.world.WorldServer; -import game.worldgen.FeatureGenerator; -import game.worldgen.foliage.WorldGenMelon; -import game.worldgen.foliage.WorldGenShrub; -import game.worldgen.foliage.WorldGenTallGrass; -import game.worldgen.foliage.WorldGenVines; -import game.worldgen.tree.WorldGenBaseTree; -import game.worldgen.tree.WorldGenJungle; -import game.worldgen.tree.WorldGenTree; +import common.block.BlockTallGrass; +import common.entity.animal.EntityChicken; +import common.entity.animal.EntityOcelot; +import common.init.Blocks; +import common.rng.Random; +import common.world.BlockPos; +import common.world.State; +import common.world.WorldServer; +import common.worldgen.FeatureGenerator; +import common.worldgen.foliage.WorldGenMelon; +import common.worldgen.foliage.WorldGenShrub; +import common.worldgen.foliage.WorldGenTallGrass; +import common.worldgen.foliage.WorldGenVines; +import common.worldgen.tree.WorldGenBaseTree; +import common.worldgen.tree.WorldGenJungle; +import common.worldgen.tree.WorldGenTree; public class BiomeJungle extends Biome { diff --git a/java/src/game/biome/BiomeMesa.java b/java/src/common/biome/BiomeMesa.java similarity index 95% rename from java/src/game/biome/BiomeMesa.java rename to java/src/common/biome/BiomeMesa.java index edf1000..29c92b7 100755 --- a/java/src/game/biome/BiomeMesa.java +++ b/java/src/common/biome/BiomeMesa.java @@ -1,22 +1,22 @@ -package game.biome; +package common.biome; import java.util.Arrays; -import game.block.Block; -import game.block.BlockColored; -import game.block.BlockDirt; -import game.block.BlockSand; -import game.color.DyeColor; -import game.init.Blocks; -import game.material.Material; -import game.rng.PerlinGen; -import game.rng.Random; -import game.rng.WeightedList; -import game.world.BlockPos; -import game.world.State; -import game.world.WorldServer; -import game.worldgen.ChunkPrimer; -import game.worldgen.tree.WorldGenTree; +import common.block.Block; +import common.block.BlockColored; +import common.block.BlockDirt; +import common.block.BlockSand; +import common.color.DyeColor; +import common.init.Blocks; +import common.material.Material; +import common.rng.PerlinGen; +import common.rng.Random; +import common.rng.WeightedList; +import common.world.BlockPos; +import common.world.State; +import common.world.WorldServer; +import common.worldgen.ChunkPrimer; +import common.worldgen.tree.WorldGenTree; public class BiomeMesa extends Biome { diff --git a/java/src/game/biome/BiomeMoon.java b/java/src/common/biome/BiomeMoon.java similarity index 70% rename from java/src/game/biome/BiomeMoon.java rename to java/src/common/biome/BiomeMoon.java index 6a3baad..297eabe 100755 --- a/java/src/game/biome/BiomeMoon.java +++ b/java/src/common/biome/BiomeMoon.java @@ -1,11 +1,11 @@ -package game.biome; +package common.biome; -import game.init.Blocks; -import game.rng.Random; -import game.rng.WeightedList; -import game.world.BlockPos; -import game.world.WorldServer; -import game.worldgen.FeatureOres; +import common.init.Blocks; +import common.rng.Random; +import common.rng.WeightedList; +import common.world.BlockPos; +import common.world.WorldServer; +import common.worldgen.FeatureOres; public class BiomeMoon extends Biome { private FeatureOres cheeseGenerator = new FeatureOres(Blocks.moon_cheese.getState(), 8, 8, 12, 24, 52, false); diff --git a/java/src/game/biome/BiomeMushroom.java b/java/src/common/biome/BiomeMushroom.java similarity index 79% rename from java/src/game/biome/BiomeMushroom.java rename to java/src/common/biome/BiomeMushroom.java index 07ebec9..5133daa 100755 --- a/java/src/game/biome/BiomeMushroom.java +++ b/java/src/common/biome/BiomeMushroom.java @@ -1,8 +1,8 @@ -package game.biome; +package common.biome; -import game.entity.animal.EntityMooshroom; -import game.init.Blocks; -import game.rng.WeightedList; +import common.entity.animal.EntityMooshroom; +import common.init.Blocks; +import common.rng.WeightedList; public class BiomeMushroom extends Biome { diff --git a/java/src/game/biome/BiomeMutated.java b/java/src/common/biome/BiomeMutated.java similarity index 92% rename from java/src/game/biome/BiomeMutated.java rename to java/src/common/biome/BiomeMutated.java index 95d4d93..d0d5f7b 100755 --- a/java/src/game/biome/BiomeMutated.java +++ b/java/src/common/biome/BiomeMutated.java @@ -1,11 +1,11 @@ -package game.biome; +package common.biome; -import game.rng.Random; -import game.rng.WeightedList; -import game.world.BlockPos; -import game.world.WorldServer; -import game.worldgen.ChunkPrimer; -import game.worldgen.tree.WorldGenTree; +import common.rng.Random; +import common.rng.WeightedList; +import common.world.BlockPos; +import common.world.WorldServer; +import common.worldgen.ChunkPrimer; +import common.worldgen.tree.WorldGenTree; public class BiomeMutated extends Biome { diff --git a/java/src/game/biome/BiomeNone.java b/java/src/common/biome/BiomeNone.java similarity index 71% rename from java/src/game/biome/BiomeNone.java rename to java/src/common/biome/BiomeNone.java index bac124c..9c84a6f 100755 --- a/java/src/game/biome/BiomeNone.java +++ b/java/src/common/biome/BiomeNone.java @@ -1,11 +1,11 @@ -package game.biome; +package common.biome; -import game.init.Blocks; -import game.rng.Random; -import game.rng.WeightedList; -import game.world.BlockPos; -import game.world.WorldServer; -import game.worldgen.ChunkPrimer; +import common.init.Blocks; +import common.rng.Random; +import common.rng.WeightedList; +import common.world.BlockPos; +import common.world.WorldServer; +import common.worldgen.ChunkPrimer; public class BiomeNone extends Biome { public BiomeNone(int id) { diff --git a/java/src/game/biome/BiomePlains.java b/java/src/common/biome/BiomePlains.java similarity index 94% rename from java/src/game/biome/BiomePlains.java rename to java/src/common/biome/BiomePlains.java index 35ee03b..f652fb5 100755 --- a/java/src/game/biome/BiomePlains.java +++ b/java/src/common/biome/BiomePlains.java @@ -1,11 +1,11 @@ -package game.biome; +package common.biome; -import game.block.BlockDoublePlant; -import game.block.BlockFlower; -import game.entity.animal.EntityHorse; -import game.rng.Random; -import game.world.BlockPos; -import game.world.WorldServer; +import common.block.BlockDoublePlant; +import common.block.BlockFlower; +import common.entity.animal.EntityHorse; +import common.rng.Random; +import common.world.BlockPos; +import common.world.WorldServer; public class BiomePlains extends Biome { diff --git a/java/src/game/biome/BiomeSavanna.java b/java/src/common/biome/BiomeSavanna.java similarity index 87% rename from java/src/game/biome/BiomeSavanna.java rename to java/src/common/biome/BiomeSavanna.java index fd987cf..aae7642 100755 --- a/java/src/game/biome/BiomeSavanna.java +++ b/java/src/common/biome/BiomeSavanna.java @@ -1,15 +1,15 @@ -package game.biome; +package common.biome; -import game.block.BlockDirt; -import game.block.BlockDoublePlant; -import game.entity.animal.EntityHorse; -import game.init.Blocks; -import game.rng.Random; -import game.world.BlockPos; -import game.world.WorldServer; -import game.worldgen.ChunkPrimer; -import game.worldgen.tree.WorldGenSavanna; -import game.worldgen.tree.WorldGenTree; +import common.block.BlockDirt; +import common.block.BlockDoublePlant; +import common.entity.animal.EntityHorse; +import common.init.Blocks; +import common.rng.Random; +import common.world.BlockPos; +import common.world.WorldServer; +import common.worldgen.ChunkPrimer; +import common.worldgen.tree.WorldGenSavanna; +import common.worldgen.tree.WorldGenTree; public class BiomeSavanna extends Biome { diff --git a/java/src/game/biome/BiomeSnow.java b/java/src/common/biome/BiomeSnow.java similarity index 82% rename from java/src/game/biome/BiomeSnow.java rename to java/src/common/biome/BiomeSnow.java index 44767cf..5e0e697 100755 --- a/java/src/game/biome/BiomeSnow.java +++ b/java/src/common/biome/BiomeSnow.java @@ -1,14 +1,14 @@ -package game.biome; +package common.biome; -import game.init.Blocks; -import game.rng.Random; -import game.rng.WeightedList; -import game.world.BlockPos; -import game.world.WorldServer; -import game.worldgen.feature.WorldGenIcePath; -import game.worldgen.feature.WorldGenIceSpike; -import game.worldgen.tree.WorldGenTaiga2; -import game.worldgen.tree.WorldGenTree; +import common.init.Blocks; +import common.rng.Random; +import common.rng.WeightedList; +import common.world.BlockPos; +import common.world.WorldServer; +import common.worldgen.feature.WorldGenIcePath; +import common.worldgen.feature.WorldGenIceSpike; +import common.worldgen.tree.WorldGenTaiga2; +import common.worldgen.tree.WorldGenTree; public class BiomeSnow extends Biome { diff --git a/java/src/game/biome/BiomeSnowLand.java b/java/src/common/biome/BiomeSnowLand.java similarity index 73% rename from java/src/game/biome/BiomeSnowLand.java rename to java/src/common/biome/BiomeSnowLand.java index 8ad0d4a..5699886 100755 --- a/java/src/game/biome/BiomeSnowLand.java +++ b/java/src/common/biome/BiomeSnowLand.java @@ -1,9 +1,9 @@ -package game.biome; +package common.biome; -import game.entity.animal.EntitySheep; -import game.entity.npc.EntitySpirit; -import game.init.Blocks; -import game.rng.WeightedList; +import common.entity.animal.EntitySheep; +import common.entity.npc.EntitySpirit; +import common.init.Blocks; +import common.rng.WeightedList; public class BiomeSnowLand extends Biome { diff --git a/java/src/game/biome/BiomeSpace.java b/java/src/common/biome/BiomeSpace.java similarity index 74% rename from java/src/game/biome/BiomeSpace.java rename to java/src/common/biome/BiomeSpace.java index 67a3cf1..da3953e 100755 --- a/java/src/game/biome/BiomeSpace.java +++ b/java/src/common/biome/BiomeSpace.java @@ -1,13 +1,13 @@ -package game.biome; +package common.biome; -import game.block.BlockDirt; -import game.init.Blocks; -import game.rng.Random; -import game.rng.WeightedList; -import game.world.BlockPos; -import game.world.WorldServer; -import game.worldgen.FeatureGenerator; -import game.worldgen.feature.WorldGenAsteroid; +import common.block.BlockDirt; +import common.init.Blocks; +import common.rng.Random; +import common.rng.WeightedList; +import common.world.BlockPos; +import common.world.WorldServer; +import common.worldgen.FeatureGenerator; +import common.worldgen.feature.WorldGenAsteroid; public class BiomeSpace extends Biome { diff --git a/java/src/game/biome/BiomeStoneBeach.java b/java/src/common/biome/BiomeStoneBeach.java similarity index 84% rename from java/src/game/biome/BiomeStoneBeach.java rename to java/src/common/biome/BiomeStoneBeach.java index 550a07b..41c1926 100755 --- a/java/src/game/biome/BiomeStoneBeach.java +++ b/java/src/common/biome/BiomeStoneBeach.java @@ -1,7 +1,7 @@ -package game.biome; +package common.biome; -import game.init.Blocks; -import game.rng.WeightedList; +import common.init.Blocks; +import common.rng.WeightedList; public class BiomeStoneBeach extends Biome { diff --git a/java/src/game/biome/BiomeSwamp.java b/java/src/common/biome/BiomeSwamp.java similarity index 85% rename from java/src/game/biome/BiomeSwamp.java rename to java/src/common/biome/BiomeSwamp.java index c742d0a..41a39a3 100755 --- a/java/src/game/biome/BiomeSwamp.java +++ b/java/src/common/biome/BiomeSwamp.java @@ -1,16 +1,16 @@ -package game.biome; +package common.biome; -import game.block.BlockDirectional; -import game.block.BlockFlower; -import game.entity.npc.EntitySlime; -import game.init.Blocks; -import game.material.Material; -import game.rng.Random; -import game.world.BlockPos; -import game.world.Facing; -import game.world.WorldServer; -import game.worldgen.ChunkPrimer; -import game.worldgen.tree.WorldGenTree; +import common.block.BlockDirectional; +import common.block.BlockFlower; +import common.entity.npc.EntitySlime; +import common.init.Blocks; +import common.material.Material; +import common.rng.Random; +import common.world.BlockPos; +import common.world.Facing; +import common.world.WorldServer; +import common.worldgen.ChunkPrimer; +import common.worldgen.tree.WorldGenTree; public class BiomeSwamp extends Biome { diff --git a/java/src/game/biome/BiomeTaiga.java b/java/src/common/biome/BiomeTaiga.java similarity index 85% rename from java/src/game/biome/BiomeTaiga.java rename to java/src/common/biome/BiomeTaiga.java index f5b4b7e..2281c1d 100755 --- a/java/src/game/biome/BiomeTaiga.java +++ b/java/src/common/biome/BiomeTaiga.java @@ -1,21 +1,21 @@ -package game.biome; +package common.biome; -import game.block.BlockDirt; -import game.block.BlockDoublePlant; -import game.block.BlockTallGrass; -import game.entity.animal.EntityWolf; -import game.init.Blocks; -import game.rng.Random; -import game.world.BlockPos; -import game.world.WorldServer; -import game.worldgen.ChunkPrimer; -import game.worldgen.FeatureGenerator; -import game.worldgen.feature.WorldGenBlockBlob; -import game.worldgen.foliage.WorldGenTallGrass; -import game.worldgen.tree.WorldGenPine; -import game.worldgen.tree.WorldGenTaiga1; -import game.worldgen.tree.WorldGenTaiga2; -import game.worldgen.tree.WorldGenTree; +import common.block.BlockDirt; +import common.block.BlockDoublePlant; +import common.block.BlockTallGrass; +import common.entity.animal.EntityWolf; +import common.init.Blocks; +import common.rng.Random; +import common.world.BlockPos; +import common.world.WorldServer; +import common.worldgen.ChunkPrimer; +import common.worldgen.FeatureGenerator; +import common.worldgen.feature.WorldGenBlockBlob; +import common.worldgen.foliage.WorldGenTallGrass; +import common.worldgen.tree.WorldGenPine; +import common.worldgen.tree.WorldGenTaiga1; +import common.worldgen.tree.WorldGenTaiga2; +import common.worldgen.tree.WorldGenTree; public class BiomeTaiga extends Biome { diff --git a/java/src/game/biome/BiomeTian.java b/java/src/common/biome/BiomeTian.java similarity index 80% rename from java/src/game/biome/BiomeTian.java rename to java/src/common/biome/BiomeTian.java index 1382e11..933eaf3 100755 --- a/java/src/game/biome/BiomeTian.java +++ b/java/src/common/biome/BiomeTian.java @@ -1,21 +1,21 @@ -package game.biome; +package common.biome; -import game.block.BlockFlower; -import game.entity.animal.EntityBat; -import game.entity.animal.EntityMouse; -import game.entity.animal.EntityRabbit; -import game.entity.npc.EntityCultivator; -import game.init.Blocks; -import game.rng.Random; -import game.rng.WeightedList; -import game.world.BlockPos; -import game.world.WorldServer; -import game.worldgen.FeatureGenerator; -import game.worldgen.feature.WorldGenSpikes; -import game.worldgen.foliage.WorldGenMushroom; -import game.worldgen.tree.WorldGenBaseTree; -import game.worldgen.tree.WorldGenBigTree; -import game.worldgen.tree.WorldGenTree; +import common.block.BlockFlower; +import common.entity.animal.EntityBat; +import common.entity.animal.EntityMouse; +import common.entity.animal.EntityRabbit; +import common.entity.npc.EntityCultivator; +import common.init.Blocks; +import common.rng.Random; +import common.rng.WeightedList; +import common.world.BlockPos; +import common.world.WorldServer; +import common.worldgen.FeatureGenerator; +import common.worldgen.feature.WorldGenSpikes; +import common.worldgen.foliage.WorldGenMushroom; +import common.worldgen.tree.WorldGenBaseTree; +import common.worldgen.tree.WorldGenBigTree; +import common.worldgen.tree.WorldGenTree; public class BiomeTian extends Biome { diff --git a/java/src/game/biome/BiomeWater.java b/java/src/common/biome/BiomeWater.java similarity index 80% rename from java/src/game/biome/BiomeWater.java rename to java/src/common/biome/BiomeWater.java index 6c68df8..af521da 100755 --- a/java/src/game/biome/BiomeWater.java +++ b/java/src/common/biome/BiomeWater.java @@ -1,7 +1,7 @@ -package game.biome; +package common.biome; -import game.entity.animal.EntitySquid; -import game.rng.WeightedList; +import common.entity.animal.EntitySquid; +import common.rng.WeightedList; public class BiomeWater extends Biome { private final boolean river; diff --git a/java/src/game/biome/RngSpawn.java b/java/src/common/biome/RngSpawn.java similarity index 77% rename from java/src/game/biome/RngSpawn.java rename to java/src/common/biome/RngSpawn.java index 25ba373..969bdca 100644 --- a/java/src/game/biome/RngSpawn.java +++ b/java/src/common/biome/RngSpawn.java @@ -1,7 +1,7 @@ -package game.biome; +package common.biome; -import game.entity.types.EntityLiving; -import game.rng.RngItem; +import common.entity.types.EntityLiving; +import common.rng.RngItem; public class RngSpawn extends RngItem { public final Class type; diff --git a/java/src/game/biome/Scaling.java b/java/src/common/biome/Scaling.java similarity index 96% rename from java/src/game/biome/Scaling.java rename to java/src/common/biome/Scaling.java index 6629d78..1518b57 100644 --- a/java/src/game/biome/Scaling.java +++ b/java/src/common/biome/Scaling.java @@ -1,4 +1,4 @@ -package game.biome; +package common.biome; public enum Scaling { VARYING_LOW(0.1F, 0.2F), diff --git a/java/src/game/biome/Temperature.java b/java/src/common/biome/Temperature.java similarity index 71% rename from java/src/game/biome/Temperature.java rename to java/src/common/biome/Temperature.java index b9acbf2..3c809c9 100644 --- a/java/src/game/biome/Temperature.java +++ b/java/src/common/biome/Temperature.java @@ -1,4 +1,4 @@ -package game.biome; +package common.biome; public enum Temperature { SEA, COLD, MEDIUM, WARM; diff --git a/java/src/game/block/Block.java b/java/src/common/block/Block.java similarity index 96% rename from java/src/game/block/Block.java rename to java/src/common/block/Block.java index 16e974a..92d3ab9 100755 --- a/java/src/game/block/Block.java +++ b/java/src/common/block/Block.java @@ -1,4 +1,4 @@ -package game.block; +package common.block; import java.lang.reflect.Array; import java.util.Arrays; @@ -11,45 +11,45 @@ import java.util.Map; import java.util.NoSuchElementException; import java.util.function.Function; -import game.collect.ImmutableList; -import game.collect.ImmutableMap; -import game.collect.Iterables; -import game.collect.Lists; -import game.collect.Maps; -import game.collect.UnmodifiableIterator; -import game.enchantment.EnchantmentHelper; -import game.entity.Entity; -import game.entity.item.EntityItem; -import game.entity.item.EntityXp; -import game.entity.npc.EntityNPC; -import game.entity.types.EntityLiving; -import game.init.Config; -import game.init.ItemRegistry; -import game.item.CheatTab; -import game.item.Item; -import game.item.ItemStack; -import game.material.Material; -import game.model.BlockLayer; -import game.model.Model; -import game.model.ModelProvider; -import game.model.Transforms; -import game.properties.IProperty; -import game.rng.Random; -import game.tileentity.TileEntity; -import game.util.ExtMath; -import game.world.BlockPos; -import game.world.BoundingBox; -import game.world.Explosion; -import game.world.Facing; -import game.world.HitPosition; -import game.world.HitPosition.ObjectType; -import game.world.IBlockAccess; -import game.world.IWorldAccess; -import game.world.State; -import game.world.Vec3; -import game.world.World; -import game.world.WorldClient; -import game.world.WorldServer; +import common.collect.ImmutableList; +import common.collect.ImmutableMap; +import common.collect.Iterables; +import common.collect.Lists; +import common.collect.Maps; +import common.collect.UnmodifiableIterator; +import common.enchantment.EnchantmentHelper; +import common.entity.Entity; +import common.entity.item.EntityItem; +import common.entity.item.EntityXp; +import common.entity.npc.EntityNPC; +import common.entity.types.EntityLiving; +import common.init.Config; +import common.init.ItemRegistry; +import common.item.CheatTab; +import common.item.Item; +import common.item.ItemStack; +import common.material.Material; +import common.model.BlockLayer; +import common.model.Model; +import common.model.ModelProvider; +import common.model.Transforms; +import common.properties.IProperty; +import common.rng.Random; +import common.tileentity.TileEntity; +import common.util.ExtMath; +import common.world.BlockPos; +import common.world.BoundingBox; +import common.world.Explosion; +import common.world.Facing; +import common.world.HitPosition; +import common.world.IBlockAccess; +import common.world.IWorldAccess; +import common.world.State; +import common.world.Vec3; +import common.world.World; +import common.world.WorldClient; +import common.world.WorldServer; +import common.world.HitPosition.ObjectType; public class Block { diff --git a/java/src/game/block/BlockAir.java b/java/src/common/block/BlockAir.java similarity index 86% rename from java/src/game/block/BlockAir.java rename to java/src/common/block/BlockAir.java index 55fdb2b..f0c60bb 100755 --- a/java/src/game/block/BlockAir.java +++ b/java/src/common/block/BlockAir.java @@ -1,10 +1,10 @@ -package game.block; +package common.block; -import game.material.Material; -import game.world.BlockPos; -import game.world.BoundingBox; -import game.world.State; -import game.world.World; +import common.material.Material; +import common.world.BlockPos; +import common.world.BoundingBox; +import common.world.State; +import common.world.World; public class BlockAir extends Block { diff --git a/java/src/game/block/BlockAnvil.java b/java/src/common/block/BlockAnvil.java similarity index 88% rename from java/src/game/block/BlockAnvil.java rename to java/src/common/block/BlockAnvil.java index cfca9f7..f7519e3 100755 --- a/java/src/game/block/BlockAnvil.java +++ b/java/src/common/block/BlockAnvil.java @@ -1,30 +1,30 @@ -package game.block; +package common.block; import java.util.List; -import game.entity.item.EntityFalling; -import game.entity.npc.EntityNPC; -import game.entity.types.EntityLiving; -import game.inventory.Container; -import game.inventory.ContainerRepair; -import game.inventory.InventoryPlayer; -import game.item.CheatTab; -import game.item.Item; -import game.item.ItemStack; -import game.material.Material; -import game.model.Model; -import game.model.ModelProvider; -import game.model.ModelRotation; -import game.model.Transforms; -import game.properties.IProperty; -import game.properties.PropertyDirection; -import game.properties.PropertyInteger; -import game.tileentity.IInteractionObject; -import game.world.BlockPos; -import game.world.Facing; -import game.world.IWorldAccess; -import game.world.State; -import game.world.World; +import common.entity.item.EntityFalling; +import common.entity.npc.EntityNPC; +import common.entity.types.EntityLiving; +import common.inventory.Container; +import common.inventory.ContainerRepair; +import common.inventory.InventoryPlayer; +import common.item.CheatTab; +import common.item.Item; +import common.item.ItemStack; +import common.material.Material; +import common.model.Model; +import common.model.ModelProvider; +import common.model.ModelRotation; +import common.model.Transforms; +import common.properties.IProperty; +import common.properties.PropertyDirection; +import common.properties.PropertyInteger; +import common.tileentity.IInteractionObject; +import common.world.BlockPos; +import common.world.Facing; +import common.world.IWorldAccess; +import common.world.State; +import common.world.World; public class BlockAnvil extends BlockFalling { diff --git a/java/src/game/block/BlockBanner.java b/java/src/common/block/BlockBanner.java similarity index 91% rename from java/src/game/block/BlockBanner.java rename to java/src/common/block/BlockBanner.java index 889a8f0..2994082 100755 --- a/java/src/game/block/BlockBanner.java +++ b/java/src/common/block/BlockBanner.java @@ -1,25 +1,25 @@ -package game.block; +package common.block; -import game.entity.npc.EntityNPC; -import game.init.Items; -import game.item.Item; -import game.item.ItemStack; -import game.material.Material; -import game.model.Transforms; -import game.nbt.NBTTagCompound; -import game.properties.IProperty; -import game.properties.PropertyDirection; -import game.properties.PropertyInteger; -import game.rng.Random; -import game.tileentity.TileEntity; -import game.tileentity.TileEntityBanner; -import game.world.BlockPos; -import game.world.BoundingBox; -import game.world.Facing; -import game.world.IBlockAccess; -import game.world.IWorldAccess; -import game.world.State; -import game.world.World; +import common.entity.npc.EntityNPC; +import common.init.Items; +import common.item.Item; +import common.item.ItemStack; +import common.material.Material; +import common.model.Transforms; +import common.nbt.NBTTagCompound; +import common.properties.IProperty; +import common.properties.PropertyDirection; +import common.properties.PropertyInteger; +import common.rng.Random; +import common.tileentity.TileEntity; +import common.tileentity.TileEntityBanner; +import common.world.BlockPos; +import common.world.BoundingBox; +import common.world.Facing; +import common.world.IBlockAccess; +import common.world.IWorldAccess; +import common.world.State; +import common.world.World; public class BlockBanner extends BlockContainer { diff --git a/java/src/game/block/BlockBaseFlower.java b/java/src/common/block/BlockBaseFlower.java similarity index 88% rename from java/src/game/block/BlockBaseFlower.java rename to java/src/common/block/BlockBaseFlower.java index 205a707..5d07b1b 100755 --- a/java/src/game/block/BlockBaseFlower.java +++ b/java/src/common/block/BlockBaseFlower.java @@ -1,4 +1,4 @@ -package game.block; +package common.block; public class BlockBaseFlower extends BlockFlower { diff --git a/java/src/game/block/BlockBasePressurePlate.java b/java/src/common/block/BlockBasePressurePlate.java similarity index 93% rename from java/src/game/block/BlockBasePressurePlate.java rename to java/src/common/block/BlockBasePressurePlate.java index 1e60e30..339f4c2 100755 --- a/java/src/game/block/BlockBasePressurePlate.java +++ b/java/src/common/block/BlockBasePressurePlate.java @@ -1,20 +1,20 @@ -package game.block; +package common.block; -import game.entity.Entity; -import game.init.SoundEvent; -import game.item.CheatTab; -import game.material.Material; -import game.model.Model; -import game.model.ModelProvider; -import game.rng.Random; -import game.world.BlockPos; -import game.world.BoundingBox; -import game.world.Facing; -import game.world.IBlockAccess; -import game.world.IWorldAccess; -import game.world.State; -import game.world.World; -import game.world.WorldServer; +import common.entity.Entity; +import common.init.SoundEvent; +import common.item.CheatTab; +import common.material.Material; +import common.model.Model; +import common.model.ModelProvider; +import common.rng.Random; +import common.world.BlockPos; +import common.world.BoundingBox; +import common.world.Facing; +import common.world.IBlockAccess; +import common.world.IWorldAccess; +import common.world.State; +import common.world.World; +import common.world.WorldServer; public abstract class BlockBasePressurePlate extends Block { diff --git a/java/src/game/block/BlockBeacon.java b/java/src/common/block/BlockBeacon.java similarity index 89% rename from java/src/game/block/BlockBeacon.java rename to java/src/common/block/BlockBeacon.java index 48bf1a1..7ac615b 100755 --- a/java/src/game/block/BlockBeacon.java +++ b/java/src/common/block/BlockBeacon.java @@ -1,17 +1,17 @@ -package game.block; +package common.block; -import game.entity.npc.EntityNPC; -import game.item.CheatTab; -import game.material.Material; -import game.model.BlockLayer; -import game.model.Model; -import game.model.ModelProvider; -import game.tileentity.TileEntity; -import game.tileentity.TileEntityBeacon; -import game.world.BlockPos; -import game.world.Facing; -import game.world.State; -import game.world.World; +import common.entity.npc.EntityNPC; +import common.item.CheatTab; +import common.material.Material; +import common.model.BlockLayer; +import common.model.Model; +import common.model.ModelProvider; +import common.tileentity.TileEntity; +import common.tileentity.TileEntityBeacon; +import common.world.BlockPos; +import common.world.Facing; +import common.world.State; +import common.world.World; public class BlockBeacon extends BlockContainer { diff --git a/java/src/game/block/BlockBed.java b/java/src/common/block/BlockBed.java similarity index 91% rename from java/src/game/block/BlockBed.java rename to java/src/common/block/BlockBed.java index 9ed32a2..f602551 100755 --- a/java/src/game/block/BlockBed.java +++ b/java/src/common/block/BlockBed.java @@ -1,25 +1,25 @@ -package game.block; +package common.block; -import game.color.DyeColor; -import game.color.TextColor; -import game.entity.npc.EntityNPC; -import game.init.ItemRegistry; -import game.item.Item; -import game.material.Material; -import game.model.BlockLayer; -import game.model.Model; -import game.model.ModelProvider; -import game.model.ModelRotation; -import game.properties.IProperty; -import game.properties.PropertyEnum; -import game.rng.Random; -import game.util.Identifyable; -import game.world.BlockPos; -import game.world.Facing; -import game.world.IWorldAccess; -import game.world.State; -import game.world.World; -import game.world.WorldPos; +import common.color.DyeColor; +import common.color.TextColor; +import common.entity.npc.EntityNPC; +import common.init.ItemRegistry; +import common.item.Item; +import common.material.Material; +import common.model.BlockLayer; +import common.model.Model; +import common.model.ModelProvider; +import common.model.ModelRotation; +import common.properties.IProperty; +import common.properties.PropertyEnum; +import common.rng.Random; +import common.util.Identifyable; +import common.world.BlockPos; +import common.world.Facing; +import common.world.IWorldAccess; +import common.world.State; +import common.world.World; +import common.world.WorldPos; public class BlockBed extends BlockDirectional { public static enum EnumPartType implements Identifyable { diff --git a/java/src/game/block/BlockBedrock.java b/java/src/common/block/BlockBedrock.java similarity index 68% rename from java/src/game/block/BlockBedrock.java rename to java/src/common/block/BlockBedrock.java index 42c60eb..78c30f7 100755 --- a/java/src/game/block/BlockBedrock.java +++ b/java/src/common/block/BlockBedrock.java @@ -1,11 +1,11 @@ -package game.block; +package common.block; -import game.material.Material; -import game.model.ParticleType; -import game.rng.Random; -import game.world.BlockPos; -import game.world.State; -import game.world.WorldClient; +import common.material.Material; +import common.model.ParticleType; +import common.rng.Random; +import common.world.BlockPos; +import common.world.State; +import common.world.WorldClient; public class BlockBedrock extends Block { public BlockBedrock() { diff --git a/java/src/game/block/BlockBlackenedDirt.java b/java/src/common/block/BlockBlackenedDirt.java similarity index 83% rename from java/src/game/block/BlockBlackenedDirt.java rename to java/src/common/block/BlockBlackenedDirt.java index 9021411..e3552c5 100644 --- a/java/src/game/block/BlockBlackenedDirt.java +++ b/java/src/common/block/BlockBlackenedDirt.java @@ -1,13 +1,13 @@ -package game.block; +package common.block; -import game.init.Blocks; -import game.init.Config; -import game.item.CheatTab; -import game.material.Material; -import game.rng.Random; -import game.world.BlockPos; -import game.world.State; -import game.world.WorldServer; +import common.init.Blocks; +import common.init.Config; +import common.item.CheatTab; +import common.material.Material; +import common.rng.Random; +import common.world.BlockPos; +import common.world.State; +import common.world.WorldServer; public class BlockBlackenedDirt extends Block { diff --git a/java/src/game/block/BlockBlackenedSoil.java b/java/src/common/block/BlockBlackenedSoil.java similarity index 83% rename from java/src/game/block/BlockBlackenedSoil.java rename to java/src/common/block/BlockBlackenedSoil.java index d1427ba..7918522 100644 --- a/java/src/game/block/BlockBlackenedSoil.java +++ b/java/src/common/block/BlockBlackenedSoil.java @@ -1,16 +1,16 @@ -package game.block; +package common.block; -import game.init.Blocks; -import game.init.Config; -import game.item.CheatTab; -import game.item.Item; -import game.material.Material; -import game.model.Model; -import game.model.ModelProvider; -import game.rng.Random; -import game.world.BlockPos; -import game.world.State; -import game.world.WorldServer; +import common.init.Blocks; +import common.init.Config; +import common.item.CheatTab; +import common.item.Item; +import common.material.Material; +import common.model.Model; +import common.model.ModelProvider; +import common.rng.Random; +import common.world.BlockPos; +import common.world.State; +import common.world.WorldServer; public class BlockBlackenedSoil extends Block { diff --git a/java/src/game/block/BlockBlackenedStone.java b/java/src/common/block/BlockBlackenedStone.java similarity index 56% rename from java/src/game/block/BlockBlackenedStone.java rename to java/src/common/block/BlockBlackenedStone.java index 7454eae..a28fdae 100644 --- a/java/src/game/block/BlockBlackenedStone.java +++ b/java/src/common/block/BlockBlackenedStone.java @@ -1,12 +1,12 @@ -package game.block; +package common.block; -import game.init.Blocks; -import game.init.ItemRegistry; -import game.item.CheatTab; -import game.item.Item; -import game.material.Material; -import game.rng.Random; -import game.world.State; +import common.init.Blocks; +import common.init.ItemRegistry; +import common.item.CheatTab; +import common.item.Item; +import common.material.Material; +import common.rng.Random; +import common.world.State; public class BlockBlackenedStone extends Block { public BlockBlackenedStone() { diff --git a/java/src/game/block/BlockBlueShroom.java b/java/src/common/block/BlockBlueShroom.java similarity index 89% rename from java/src/game/block/BlockBlueShroom.java rename to java/src/common/block/BlockBlueShroom.java index d8b7ffe..7e9b87c 100755 --- a/java/src/game/block/BlockBlueShroom.java +++ b/java/src/common/block/BlockBlueShroom.java @@ -1,14 +1,14 @@ -package game.block; +package common.block; -import game.init.Blocks; -import game.init.Config; -import game.model.Model; -import game.model.ModelProvider; -import game.rng.Random; -import game.world.BlockPos; -import game.world.State; -import game.world.World; -import game.world.WorldServer; +import common.init.Blocks; +import common.init.Config; +import common.model.Model; +import common.model.ModelProvider; +import common.rng.Random; +import common.world.BlockPos; +import common.world.State; +import common.world.World; +import common.world.WorldServer; public class BlockBlueShroom extends BlockBush { diff --git a/java/src/game/block/BlockBookshelf.java b/java/src/common/block/BlockBookshelf.java similarity index 72% rename from java/src/game/block/BlockBookshelf.java rename to java/src/common/block/BlockBookshelf.java index 7d871f4..a555b4c 100755 --- a/java/src/game/block/BlockBookshelf.java +++ b/java/src/common/block/BlockBookshelf.java @@ -1,13 +1,13 @@ -package game.block; +package common.block; -import game.init.Items; -import game.item.CheatTab; -import game.item.Item; -import game.material.Material; -import game.model.Model; -import game.model.ModelProvider; -import game.rng.Random; -import game.world.State; +import common.init.Items; +import common.item.CheatTab; +import common.item.Item; +import common.material.Material; +import common.model.Model; +import common.model.ModelProvider; +import common.rng.Random; +import common.world.State; public class BlockBookshelf extends Block { diff --git a/java/src/game/block/BlockBreakable.java b/java/src/common/block/BlockBreakable.java similarity index 83% rename from java/src/game/block/BlockBreakable.java rename to java/src/common/block/BlockBreakable.java index f99b134..e60acea 100755 --- a/java/src/game/block/BlockBreakable.java +++ b/java/src/common/block/BlockBreakable.java @@ -1,11 +1,11 @@ -package game.block; +package common.block; -import game.init.Blocks; -import game.material.Material; -import game.world.BlockPos; -import game.world.Facing; -import game.world.IWorldAccess; -import game.world.State; +import common.init.Blocks; +import common.material.Material; +import common.world.BlockPos; +import common.world.Facing; +import common.world.IWorldAccess; +import common.world.State; public class BlockBreakable extends Block { diff --git a/java/src/game/block/BlockBrewingStand.java b/java/src/common/block/BlockBrewingStand.java similarity index 96% rename from java/src/game/block/BlockBrewingStand.java rename to java/src/common/block/BlockBrewingStand.java index 5a51b4b..4de9271 100755 --- a/java/src/game/block/BlockBrewingStand.java +++ b/java/src/common/block/BlockBrewingStand.java @@ -1,32 +1,32 @@ -package game.block; +package common.block; import java.util.List; -import game.entity.Entity; -import game.entity.npc.EntityNPC; -import game.entity.types.EntityLiving; -import game.init.Items; -import game.inventory.Container; -import game.inventory.InventoryHelper; -import game.item.Item; -import game.item.ItemStack; -import game.material.Material; -import game.model.BlockLayer; -import game.model.Model; -import game.model.ModelProvider; -import game.model.ParticleType; -import game.properties.IProperty; -import game.properties.PropertyBool; -import game.rng.Random; -import game.tileentity.TileEntity; -import game.tileentity.TileEntityBrewingStand; -import game.world.BlockPos; -import game.world.BoundingBox; -import game.world.Facing; -import game.world.State; -import game.world.World; -import game.world.WorldClient; -import game.world.WorldServer; +import common.entity.Entity; +import common.entity.npc.EntityNPC; +import common.entity.types.EntityLiving; +import common.init.Items; +import common.inventory.Container; +import common.inventory.InventoryHelper; +import common.item.Item; +import common.item.ItemStack; +import common.material.Material; +import common.model.BlockLayer; +import common.model.Model; +import common.model.ModelProvider; +import common.model.ParticleType; +import common.properties.IProperty; +import common.properties.PropertyBool; +import common.rng.Random; +import common.tileentity.TileEntity; +import common.tileentity.TileEntityBrewingStand; +import common.world.BlockPos; +import common.world.BoundingBox; +import common.world.Facing; +import common.world.State; +import common.world.World; +import common.world.WorldClient; +import common.world.WorldServer; public class BlockBrewingStand extends BlockContainer { diff --git a/java/src/game/block/BlockBush.java b/java/src/common/block/BlockBush.java similarity index 87% rename from java/src/game/block/BlockBush.java rename to java/src/common/block/BlockBush.java index efc7592..79b8a13 100755 --- a/java/src/game/block/BlockBush.java +++ b/java/src/common/block/BlockBush.java @@ -1,15 +1,15 @@ -package game.block; +package common.block; -import game.init.Blocks; -import game.item.CheatTab; -import game.material.Material; -import game.model.BlockLayer; -import game.rng.Random; -import game.world.BlockPos; -import game.world.BoundingBox; -import game.world.State; -import game.world.World; -import game.world.WorldServer; +import common.init.Blocks; +import common.item.CheatTab; +import common.material.Material; +import common.model.BlockLayer; +import common.rng.Random; +import common.world.BlockPos; +import common.world.BoundingBox; +import common.world.State; +import common.world.World; +import common.world.WorldServer; public class BlockBush extends Block { diff --git a/java/src/game/block/BlockButton.java b/java/src/common/block/BlockButton.java similarity index 94% rename from java/src/game/block/BlockButton.java rename to java/src/common/block/BlockButton.java index 982d1a6..ea3415a 100755 --- a/java/src/game/block/BlockButton.java +++ b/java/src/common/block/BlockButton.java @@ -1,30 +1,30 @@ -package game.block; +package common.block; import java.util.List; -import game.collect.Lists; -import game.entity.Entity; -import game.entity.npc.EntityNPC; -import game.entity.projectile.EntityArrow; -import game.entity.types.EntityLiving; -import game.init.SoundEvent; -import game.item.CheatTab; -import game.material.Material; -import game.model.Model; -import game.model.ModelProvider; -import game.model.ModelRotation; -import game.model.Transforms; -import game.properties.IProperty; -import game.properties.PropertyBool; -import game.properties.PropertyDirection; -import game.rng.Random; -import game.world.BlockPos; -import game.world.BoundingBox; -import game.world.Facing; -import game.world.IWorldAccess; -import game.world.State; -import game.world.World; -import game.world.WorldServer; +import common.collect.Lists; +import common.entity.Entity; +import common.entity.npc.EntityNPC; +import common.entity.projectile.EntityArrow; +import common.entity.types.EntityLiving; +import common.init.SoundEvent; +import common.item.CheatTab; +import common.material.Material; +import common.model.Model; +import common.model.ModelProvider; +import common.model.ModelRotation; +import common.model.Transforms; +import common.properties.IProperty; +import common.properties.PropertyBool; +import common.properties.PropertyDirection; +import common.rng.Random; +import common.world.BlockPos; +import common.world.BoundingBox; +import common.world.Facing; +import common.world.IWorldAccess; +import common.world.State; +import common.world.World; +import common.world.WorldServer; public class BlockButton extends Block { diff --git a/java/src/game/block/BlockCactus.java b/java/src/common/block/BlockCactus.java similarity index 89% rename from java/src/game/block/BlockCactus.java rename to java/src/common/block/BlockCactus.java index fa0cf2a..03777da 100755 --- a/java/src/game/block/BlockCactus.java +++ b/java/src/common/block/BlockCactus.java @@ -1,23 +1,23 @@ -package game.block; +package common.block; -import game.entity.DamageSource; -import game.entity.Entity; -import game.init.Blocks; -import game.init.Config; -import game.item.CheatTab; -import game.material.Material; -import game.model.BlockLayer; -import game.model.Model; -import game.model.ModelProvider; -import game.properties.IProperty; -import game.properties.PropertyInteger; -import game.rng.Random; -import game.world.BlockPos; -import game.world.BoundingBox; -import game.world.Facing; -import game.world.State; -import game.world.World; -import game.world.WorldServer; +import common.entity.DamageSource; +import common.entity.Entity; +import common.init.Blocks; +import common.init.Config; +import common.item.CheatTab; +import common.material.Material; +import common.model.BlockLayer; +import common.model.Model; +import common.model.ModelProvider; +import common.properties.IProperty; +import common.properties.PropertyInteger; +import common.rng.Random; +import common.world.BlockPos; +import common.world.BoundingBox; +import common.world.Facing; +import common.world.State; +import common.world.World; +import common.world.WorldServer; public class BlockCactus extends Block { diff --git a/java/src/game/block/BlockCake.java b/java/src/common/block/BlockCake.java similarity index 93% rename from java/src/game/block/BlockCake.java rename to java/src/common/block/BlockCake.java index bf8995d..4a62734 100755 --- a/java/src/game/block/BlockCake.java +++ b/java/src/common/block/BlockCake.java @@ -1,21 +1,21 @@ -package game.block; +package common.block; -import game.entity.npc.EntityNPC; -import game.init.Items; -import game.item.Item; -import game.material.Material; -import game.model.BlockLayer; -import game.model.Model; -import game.model.ModelProvider; -import game.properties.IProperty; -import game.properties.PropertyInteger; -import game.rng.Random; -import game.world.BlockPos; -import game.world.BoundingBox; -import game.world.Facing; -import game.world.IWorldAccess; -import game.world.State; -import game.world.World; +import common.entity.npc.EntityNPC; +import common.init.Items; +import common.item.Item; +import common.material.Material; +import common.model.BlockLayer; +import common.model.Model; +import common.model.ModelProvider; +import common.properties.IProperty; +import common.properties.PropertyInteger; +import common.rng.Random; +import common.world.BlockPos; +import common.world.BoundingBox; +import common.world.Facing; +import common.world.IWorldAccess; +import common.world.State; +import common.world.World; public class BlockCake extends Block { diff --git a/java/src/game/block/BlockCarpet.java b/java/src/common/block/BlockCarpet.java similarity index 89% rename from java/src/game/block/BlockCarpet.java rename to java/src/common/block/BlockCarpet.java index a54cc4d..8a93ae1 100755 --- a/java/src/game/block/BlockCarpet.java +++ b/java/src/common/block/BlockCarpet.java @@ -1,22 +1,22 @@ -package game.block; +package common.block; import java.util.List; -import game.color.DyeColor; -import game.item.CheatTab; -import game.item.Item; -import game.item.ItemStack; -import game.material.Material; -import game.model.Model; -import game.model.ModelProvider; -import game.model.Transforms; -import game.properties.IProperty; -import game.properties.PropertyEnum; -import game.world.BlockPos; -import game.world.Facing; -import game.world.IWorldAccess; -import game.world.State; -import game.world.World; +import common.color.DyeColor; +import common.item.CheatTab; +import common.item.Item; +import common.item.ItemStack; +import common.material.Material; +import common.model.Model; +import common.model.ModelProvider; +import common.model.Transforms; +import common.properties.IProperty; +import common.properties.PropertyEnum; +import common.world.BlockPos; +import common.world.Facing; +import common.world.IWorldAccess; +import common.world.State; +import common.world.World; public class BlockCarpet extends Block { diff --git a/java/src/game/block/BlockCarrot.java b/java/src/common/block/BlockCarrot.java similarity index 70% rename from java/src/game/block/BlockCarrot.java rename to java/src/common/block/BlockCarrot.java index 54088e8..be7f274 100755 --- a/java/src/game/block/BlockCarrot.java +++ b/java/src/common/block/BlockCarrot.java @@ -1,10 +1,10 @@ -package game.block; +package common.block; -import game.init.Items; -import game.item.Item; -import game.model.Model; -import game.model.ModelProvider; -import game.world.State; +import common.init.Items; +import common.item.Item; +import common.model.Model; +import common.model.ModelProvider; +import common.world.State; public class BlockCarrot extends BlockCrops { diff --git a/java/src/game/block/BlockCauldron.java b/java/src/common/block/BlockCauldron.java similarity index 96% rename from java/src/game/block/BlockCauldron.java rename to java/src/common/block/BlockCauldron.java index 37296d8..5ed3371 100755 --- a/java/src/game/block/BlockCauldron.java +++ b/java/src/common/block/BlockCauldron.java @@ -1,30 +1,30 @@ -package game.block; +package common.block; import java.util.List; -import game.entity.Entity; -import game.entity.item.EntityItem; -import game.entity.npc.EntityNPC; -import game.init.Blocks; -import game.init.FluidRegistry; -import game.init.Items; -import game.item.Item; -import game.item.ItemArmor; -import game.item.ItemBanner; -import game.item.ItemStack; -import game.material.Material; -import game.model.Model; -import game.model.ModelProvider; -import game.properties.IProperty; -import game.properties.PropertyInteger; -import game.rng.Random; -import game.tileentity.TileEntityBanner; -import game.util.ExtMath; -import game.world.BlockPos; -import game.world.BoundingBox; -import game.world.Facing; -import game.world.State; -import game.world.World; +import common.entity.Entity; +import common.entity.item.EntityItem; +import common.entity.npc.EntityNPC; +import common.init.Blocks; +import common.init.FluidRegistry; +import common.init.Items; +import common.item.Item; +import common.item.ItemArmor; +import common.item.ItemBanner; +import common.item.ItemStack; +import common.material.Material; +import common.model.Model; +import common.model.ModelProvider; +import common.properties.IProperty; +import common.properties.PropertyInteger; +import common.rng.Random; +import common.tileentity.TileEntityBanner; +import common.util.ExtMath; +import common.world.BlockPos; +import common.world.BoundingBox; +import common.world.Facing; +import common.world.State; +import common.world.World; public class BlockCauldron extends Block { diff --git a/java/src/game/block/BlockChest.java b/java/src/common/block/BlockChest.java similarity index 94% rename from java/src/game/block/BlockChest.java rename to java/src/common/block/BlockChest.java index bcb3356..92d3821 100755 --- a/java/src/game/block/BlockChest.java +++ b/java/src/common/block/BlockChest.java @@ -1,35 +1,35 @@ -package game.block; +package common.block; -import game.color.TextColor; -import game.entity.Entity; -import game.entity.animal.EntityOcelot; -import game.entity.npc.EntityNPC; -import game.entity.types.EntityLiving; -import game.init.Config; -import game.init.Items; -import game.init.SoundEvent; -import game.inventory.Container; -import game.inventory.IInventory; -import game.inventory.InventoryHelper; -import game.inventory.InventoryLargeChest; -import game.item.CheatTab; -import game.item.ItemStack; -import game.material.Material; -import game.packet.S29PacketSoundEffect; -import game.properties.IProperty; -import game.properties.PropertyDirection; -import game.tileentity.ILockableContainer; -import game.tileentity.LockCode; -import game.tileentity.TileEntity; -import game.tileentity.TileEntityChest; -import game.util.ExtMath; -import game.world.BlockPos; -import game.world.BoundingBox; -import game.world.Facing; -import game.world.IWorldAccess; -import game.world.State; -import game.world.World; -import game.world.WorldServer; +import common.color.TextColor; +import common.entity.Entity; +import common.entity.animal.EntityOcelot; +import common.entity.npc.EntityNPC; +import common.entity.types.EntityLiving; +import common.init.Config; +import common.init.Items; +import common.init.SoundEvent; +import common.inventory.Container; +import common.inventory.IInventory; +import common.inventory.InventoryHelper; +import common.inventory.InventoryLargeChest; +import common.item.CheatTab; +import common.item.ItemStack; +import common.material.Material; +import common.packet.S29PacketSoundEffect; +import common.properties.IProperty; +import common.properties.PropertyDirection; +import common.tileentity.ILockableContainer; +import common.tileentity.LockCode; +import common.tileentity.TileEntity; +import common.tileentity.TileEntityChest; +import common.util.ExtMath; +import common.world.BlockPos; +import common.world.BoundingBox; +import common.world.Facing; +import common.world.IWorldAccess; +import common.world.State; +import common.world.World; +import common.world.WorldServer; public class BlockChest extends BlockContainer { diff --git a/java/src/game/block/BlockClay.java b/java/src/common/block/BlockClay.java similarity index 72% rename from java/src/game/block/BlockClay.java rename to java/src/common/block/BlockClay.java index 0637152..c1d0259 100755 --- a/java/src/game/block/BlockClay.java +++ b/java/src/common/block/BlockClay.java @@ -1,11 +1,11 @@ -package game.block; +package common.block; -import game.init.Items; -import game.item.CheatTab; -import game.item.Item; -import game.material.Material; -import game.rng.Random; -import game.world.State; +import common.init.Items; +import common.item.CheatTab; +import common.item.Item; +import common.material.Material; +import common.rng.Random; +import common.world.State; public class BlockClay extends Block { diff --git a/java/src/game/block/BlockCocoa.java b/java/src/common/block/BlockCocoa.java similarity index 92% rename from java/src/game/block/BlockCocoa.java rename to java/src/common/block/BlockCocoa.java index 0f24db0..baad0fa 100755 --- a/java/src/game/block/BlockCocoa.java +++ b/java/src/common/block/BlockCocoa.java @@ -1,27 +1,27 @@ -package game.block; +package common.block; -import game.color.DyeColor; -import game.entity.types.EntityLiving; -import game.init.Blocks; -import game.init.Config; -import game.init.Items; -import game.item.Item; -import game.item.ItemStack; -import game.material.Material; -import game.model.BlockLayer; -import game.model.Model; -import game.model.ModelProvider; -import game.model.ModelRotation; -import game.properties.IProperty; -import game.properties.PropertyInteger; -import game.rng.Random; -import game.world.BlockPos; -import game.world.BoundingBox; -import game.world.Facing; -import game.world.IWorldAccess; -import game.world.State; -import game.world.World; -import game.world.WorldServer; +import common.color.DyeColor; +import common.entity.types.EntityLiving; +import common.init.Blocks; +import common.init.Config; +import common.init.Items; +import common.item.Item; +import common.item.ItemStack; +import common.material.Material; +import common.model.BlockLayer; +import common.model.Model; +import common.model.ModelProvider; +import common.model.ModelRotation; +import common.properties.IProperty; +import common.properties.PropertyInteger; +import common.rng.Random; +import common.world.BlockPos; +import common.world.BoundingBox; +import common.world.Facing; +import common.world.IWorldAccess; +import common.world.State; +import common.world.World; +import common.world.WorldServer; public class BlockCocoa extends BlockDirectional implements IGrowable { diff --git a/java/src/game/block/BlockColored.java b/java/src/common/block/BlockColored.java similarity index 85% rename from java/src/game/block/BlockColored.java rename to java/src/common/block/BlockColored.java index 9aee9e4..8516cbc 100755 --- a/java/src/game/block/BlockColored.java +++ b/java/src/common/block/BlockColored.java @@ -1,17 +1,17 @@ -package game.block; +package common.block; import java.util.List; -import game.color.DyeColor; -import game.item.CheatTab; -import game.item.Item; -import game.item.ItemStack; -import game.material.Material; -import game.model.Model; -import game.model.ModelProvider; -import game.properties.IProperty; -import game.properties.PropertyEnum; -import game.world.State; +import common.color.DyeColor; +import common.item.CheatTab; +import common.item.Item; +import common.item.ItemStack; +import common.material.Material; +import common.model.Model; +import common.model.ModelProvider; +import common.properties.IProperty; +import common.properties.PropertyEnum; +import common.world.State; public class BlockColored extends Block { diff --git a/java/src/game/block/BlockCompressedPowered.java b/java/src/common/block/BlockCompressedPowered.java similarity index 75% rename from java/src/game/block/BlockCompressedPowered.java rename to java/src/common/block/BlockCompressedPowered.java index 39d2736..f78ab13 100755 --- a/java/src/game/block/BlockCompressedPowered.java +++ b/java/src/common/block/BlockCompressedPowered.java @@ -1,10 +1,10 @@ -package game.block; +package common.block; -import game.material.Material; -import game.world.BlockPos; -import game.world.Facing; -import game.world.IWorldAccess; -import game.world.State; +import common.material.Material; +import common.world.BlockPos; +import common.world.Facing; +import common.world.IWorldAccess; +import common.world.State; public class BlockCompressedPowered extends Block { diff --git a/java/src/game/block/BlockContainer.java b/java/src/common/block/BlockContainer.java similarity index 87% rename from java/src/game/block/BlockContainer.java rename to java/src/common/block/BlockContainer.java index 909b5d6..84bec0f 100755 --- a/java/src/game/block/BlockContainer.java +++ b/java/src/common/block/BlockContainer.java @@ -1,12 +1,12 @@ -package game.block; +package common.block; -import game.material.Material; -import game.tileentity.TileEntity; -import game.world.BlockPos; -import game.world.Facing; -import game.world.State; -import game.world.World; -import game.world.WorldServer; +import common.material.Material; +import common.tileentity.TileEntity; +import common.world.BlockPos; +import common.world.Facing; +import common.world.State; +import common.world.World; +import common.world.WorldServer; public abstract class BlockContainer extends Block implements ITileEntityProvider { diff --git a/java/src/game/block/BlockCore.java b/java/src/common/block/BlockCore.java similarity index 66% rename from java/src/game/block/BlockCore.java rename to java/src/common/block/BlockCore.java index 03ac7e9..b125c14 100755 --- a/java/src/game/block/BlockCore.java +++ b/java/src/common/block/BlockCore.java @@ -1,11 +1,11 @@ -package game.block; +package common.block; -import game.init.Config; -import game.item.CheatTab; -import game.material.Material; -import game.world.BlockPos; -import game.world.State; -import game.world.WorldServer; +import common.init.Config; +import common.item.CheatTab; +import common.material.Material; +import common.world.BlockPos; +import common.world.State; +import common.world.WorldServer; public class BlockCore extends Block { public BlockCore() { diff --git a/java/src/game/block/BlockCrops.java b/java/src/common/block/BlockCrops.java similarity index 93% rename from java/src/game/block/BlockCrops.java rename to java/src/common/block/BlockCrops.java index cb052a9..979ebaf 100755 --- a/java/src/game/block/BlockCrops.java +++ b/java/src/common/block/BlockCrops.java @@ -1,20 +1,20 @@ -package game.block; +package common.block; -import game.init.Blocks; -import game.init.Config; -import game.init.Items; -import game.item.CheatTab; -import game.item.Item; -import game.item.ItemStack; -import game.model.Model; -import game.model.ModelProvider; -import game.properties.IProperty; -import game.properties.PropertyInteger; -import game.rng.Random; -import game.world.BlockPos; -import game.world.State; -import game.world.World; -import game.world.WorldServer; +import common.init.Blocks; +import common.init.Config; +import common.init.Items; +import common.item.CheatTab; +import common.item.Item; +import common.item.ItemStack; +import common.model.Model; +import common.model.ModelProvider; +import common.properties.IProperty; +import common.properties.PropertyInteger; +import common.rng.Random; +import common.world.BlockPos; +import common.world.State; +import common.world.World; +import common.world.WorldServer; public class BlockCrops extends BlockBush implements IGrowable { diff --git a/java/src/game/block/BlockDaylightDetector.java b/java/src/common/block/BlockDaylightDetector.java similarity index 87% rename from java/src/game/block/BlockDaylightDetector.java rename to java/src/common/block/BlockDaylightDetector.java index 5ce1ee7..8e0a6f9 100755 --- a/java/src/game/block/BlockDaylightDetector.java +++ b/java/src/common/block/BlockDaylightDetector.java @@ -1,30 +1,30 @@ -package game.block; +package common.block; import java.util.List; -import game.entity.npc.EntityNPC; -import game.init.Blocks; -import game.init.ItemRegistry; -import game.item.CheatTab; -import game.item.Item; -import game.item.ItemStack; -import game.material.Material; -import game.model.Model; -import game.model.ModelProvider; -import game.model.Transforms; -import game.properties.IProperty; -import game.properties.PropertyInteger; -import game.rng.Random; -import game.tileentity.TileEntity; -import game.tileentity.TileEntityDaylightDetector; -import game.util.ExtMath; -import game.world.BlockPos; -import game.world.Facing; -import game.world.IWorldAccess; -import game.world.LightType; -import game.world.State; -import game.world.World; -import game.world.WorldServer; +import common.entity.npc.EntityNPC; +import common.init.Blocks; +import common.init.ItemRegistry; +import common.item.CheatTab; +import common.item.Item; +import common.item.ItemStack; +import common.material.Material; +import common.model.Model; +import common.model.ModelProvider; +import common.model.Transforms; +import common.properties.IProperty; +import common.properties.PropertyInteger; +import common.rng.Random; +import common.tileentity.TileEntity; +import common.tileentity.TileEntityDaylightDetector; +import common.util.ExtMath; +import common.world.BlockPos; +import common.world.Facing; +import common.world.IWorldAccess; +import common.world.LightType; +import common.world.State; +import common.world.World; +import common.world.WorldServer; public class BlockDaylightDetector extends BlockContainer { diff --git a/java/src/game/block/BlockDeadBush.java b/java/src/common/block/BlockDeadBush.java similarity index 80% rename from java/src/game/block/BlockDeadBush.java rename to java/src/common/block/BlockDeadBush.java index 0badc17..f81d79b 100755 --- a/java/src/game/block/BlockDeadBush.java +++ b/java/src/common/block/BlockDeadBush.java @@ -1,19 +1,19 @@ -package game.block; +package common.block; -import game.entity.npc.EntityNPC; -import game.init.Blocks; -import game.init.Items; -import game.item.Item; -import game.item.ItemShears; -import game.item.ItemStack; -import game.material.Material; -import game.model.Model; -import game.model.ModelProvider; -import game.rng.Random; -import game.tileentity.TileEntity; -import game.world.BlockPos; -import game.world.State; -import game.world.World; +import common.entity.npc.EntityNPC; +import common.init.Blocks; +import common.init.Items; +import common.item.Item; +import common.item.ItemShears; +import common.item.ItemStack; +import common.material.Material; +import common.model.Model; +import common.model.ModelProvider; +import common.rng.Random; +import common.tileentity.TileEntity; +import common.world.BlockPos; +import common.world.State; +import common.world.World; public class BlockDeadBush extends BlockBush { diff --git a/java/src/game/block/BlockDirectional.java b/java/src/common/block/BlockDirectional.java similarity index 67% rename from java/src/game/block/BlockDirectional.java rename to java/src/common/block/BlockDirectional.java index 5c2c881..79113df 100755 --- a/java/src/game/block/BlockDirectional.java +++ b/java/src/common/block/BlockDirectional.java @@ -1,8 +1,8 @@ -package game.block; +package common.block; -import game.material.Material; -import game.properties.PropertyDirection; -import game.world.Facing; +import common.material.Material; +import common.properties.PropertyDirection; +import common.world.Facing; public abstract class BlockDirectional extends Block { diff --git a/java/src/game/block/BlockDirt.java b/java/src/common/block/BlockDirt.java similarity index 91% rename from java/src/game/block/BlockDirt.java rename to java/src/common/block/BlockDirt.java index 159bbda..ab9f792 100755 --- a/java/src/game/block/BlockDirt.java +++ b/java/src/common/block/BlockDirt.java @@ -1,22 +1,22 @@ -package game.block; +package common.block; import java.util.List; -import game.init.Blocks; -import game.item.CheatTab; -import game.item.Item; -import game.item.ItemStack; -import game.material.Material; -import game.model.Model; -import game.model.ModelProvider; -import game.properties.IProperty; -import game.properties.PropertyBool; -import game.properties.PropertyEnum; -import game.util.Identifyable; -import game.world.BlockPos; -import game.world.IWorldAccess; -import game.world.State; -import game.world.World; +import common.init.Blocks; +import common.item.CheatTab; +import common.item.Item; +import common.item.ItemStack; +import common.material.Material; +import common.model.Model; +import common.model.ModelProvider; +import common.properties.IProperty; +import common.properties.PropertyBool; +import common.properties.PropertyEnum; +import common.util.Identifyable; +import common.world.BlockPos; +import common.world.IWorldAccess; +import common.world.State; +import common.world.World; public class BlockDirt extends Block { diff --git a/java/src/game/block/BlockDispenser.java b/java/src/common/block/BlockDispenser.java similarity index 90% rename from java/src/game/block/BlockDispenser.java rename to java/src/common/block/BlockDispenser.java index f4f6e51..4c693c8 100755 --- a/java/src/game/block/BlockDispenser.java +++ b/java/src/common/block/BlockDispenser.java @@ -1,34 +1,34 @@ -package game.block; +package common.block; -import game.dispenser.BehaviorDefaultDispenseItem; -import game.dispenser.IBehaviorDispenseItem; -import game.dispenser.IBlockSource; -import game.dispenser.IPosition; -import game.dispenser.PositionImpl; -import game.entity.npc.EntityNPC; -import game.entity.types.EntityLiving; -import game.init.DispenserRegistry; -import game.init.RegistryDefaulted; -import game.inventory.Container; -import game.inventory.InventoryHelper; -import game.item.CheatTab; -import game.item.Item; -import game.item.ItemStack; -import game.material.Material; -import game.model.Model; -import game.model.ModelProvider; -import game.model.ModelRotation; -import game.properties.IProperty; -import game.properties.PropertyBool; -import game.properties.PropertyDirection; -import game.rng.Random; -import game.tileentity.TileEntity; -import game.tileentity.TileEntityDispenser; -import game.world.BlockPos; -import game.world.Facing; -import game.world.State; -import game.world.World; -import game.world.WorldServer; +import common.dispenser.BehaviorDefaultDispenseItem; +import common.dispenser.IBehaviorDispenseItem; +import common.dispenser.IBlockSource; +import common.dispenser.IPosition; +import common.dispenser.PositionImpl; +import common.entity.npc.EntityNPC; +import common.entity.types.EntityLiving; +import common.init.DispenserRegistry; +import common.init.RegistryDefaulted; +import common.inventory.Container; +import common.inventory.InventoryHelper; +import common.item.CheatTab; +import common.item.Item; +import common.item.ItemStack; +import common.material.Material; +import common.model.Model; +import common.model.ModelProvider; +import common.model.ModelRotation; +import common.properties.IProperty; +import common.properties.PropertyBool; +import common.properties.PropertyDirection; +import common.rng.Random; +import common.tileentity.TileEntity; +import common.tileentity.TileEntityDispenser; +import common.world.BlockPos; +import common.world.Facing; +import common.world.State; +import common.world.World; +import common.world.WorldServer; public class BlockDispenser extends BlockContainer { diff --git a/java/src/game/block/BlockDoor.java b/java/src/common/block/BlockDoor.java similarity index 95% rename from java/src/game/block/BlockDoor.java rename to java/src/common/block/BlockDoor.java index 8addee0..d0fa735 100755 --- a/java/src/game/block/BlockDoor.java +++ b/java/src/common/block/BlockDoor.java @@ -1,32 +1,32 @@ -package game.block; +package common.block; import java.util.List; -import game.collect.Lists; -import game.entity.npc.EntityNPC; -import game.init.Blocks; -import game.init.Items; -import game.item.Item; -import game.material.Material; -import game.model.BlockLayer; -import game.model.Model; -import game.model.ModelProvider; -import game.model.ModelRotation; -import game.properties.IProperty; -import game.properties.PropertyBool; -import game.properties.PropertyDirection; -import game.properties.PropertyEnum; -import game.rng.Random; -import game.util.Identifyable; -import game.world.BlockPos; -import game.world.BoundingBox; -import game.world.Facing; -import game.world.HitPosition; -import game.world.IBlockAccess; -import game.world.IWorldAccess; -import game.world.State; -import game.world.Vec3; -import game.world.World; +import common.collect.Lists; +import common.entity.npc.EntityNPC; +import common.init.Blocks; +import common.init.Items; +import common.item.Item; +import common.material.Material; +import common.model.BlockLayer; +import common.model.Model; +import common.model.ModelProvider; +import common.model.ModelRotation; +import common.properties.IProperty; +import common.properties.PropertyBool; +import common.properties.PropertyDirection; +import common.properties.PropertyEnum; +import common.rng.Random; +import common.util.Identifyable; +import common.world.BlockPos; +import common.world.BoundingBox; +import common.world.Facing; +import common.world.HitPosition; +import common.world.IBlockAccess; +import common.world.IWorldAccess; +import common.world.State; +import common.world.Vec3; +import common.world.World; public class BlockDoor extends Block { diff --git a/java/src/game/block/BlockDoublePlant.java b/java/src/common/block/BlockDoublePlant.java similarity index 95% rename from java/src/game/block/BlockDoublePlant.java rename to java/src/common/block/BlockDoublePlant.java index ce68511..a580050 100755 --- a/java/src/game/block/BlockDoublePlant.java +++ b/java/src/common/block/BlockDoublePlant.java @@ -1,33 +1,33 @@ -package game.block; +package common.block; import java.util.List; -import game.color.Colorizer; -import game.entity.npc.EntityNPC; -import game.entity.types.EntityLiving; -import game.init.Blocks; -import game.init.Config; -import game.init.ItemRegistry; -import game.init.Items; -import game.item.CheatTab; -import game.item.Item; -import game.item.ItemShears; -import game.item.ItemStack; -import game.material.Material; -import game.model.Model; -import game.model.ModelProvider; -import game.properties.IProperty; -import game.properties.PropertyEnum; -import game.rng.Random; -import game.tileentity.TileEntity; -import game.util.Identifyable; -import game.world.BlockPos; -import game.world.Facing; -import game.world.Facing.Axis; -import game.world.IWorldAccess; -import game.world.State; -import game.world.World; -import game.world.WorldServer; +import common.color.Colorizer; +import common.entity.npc.EntityNPC; +import common.entity.types.EntityLiving; +import common.init.Blocks; +import common.init.Config; +import common.init.ItemRegistry; +import common.init.Items; +import common.item.CheatTab; +import common.item.Item; +import common.item.ItemShears; +import common.item.ItemStack; +import common.material.Material; +import common.model.Model; +import common.model.ModelProvider; +import common.properties.IProperty; +import common.properties.PropertyEnum; +import common.rng.Random; +import common.tileentity.TileEntity; +import common.util.Identifyable; +import common.world.BlockPos; +import common.world.Facing; +import common.world.IWorldAccess; +import common.world.State; +import common.world.World; +import common.world.WorldServer; +import common.world.Facing.Axis; public class BlockDoublePlant extends BlockBush implements IGrowable { diff --git a/java/src/game/block/BlockDragonEgg.java b/java/src/common/block/BlockDragonEgg.java similarity index 93% rename from java/src/game/block/BlockDragonEgg.java rename to java/src/common/block/BlockDragonEgg.java index e343fa7..ef360b2 100755 --- a/java/src/game/block/BlockDragonEgg.java +++ b/java/src/common/block/BlockDragonEgg.java @@ -1,19 +1,19 @@ -package game.block; +package common.block; -import game.entity.item.EntityFalling; -import game.entity.npc.EntityNPC; -import game.init.Config; -import game.material.Material; -import game.model.Model; -import game.model.ModelProvider; -import game.model.ParticleType; -import game.rng.Random; -import game.world.BlockPos; -import game.world.Facing; -import game.world.IWorldAccess; -import game.world.State; -import game.world.World; -import game.world.WorldServer; +import common.entity.item.EntityFalling; +import common.entity.npc.EntityNPC; +import common.init.Config; +import common.material.Material; +import common.model.Model; +import common.model.ModelProvider; +import common.model.ParticleType; +import common.rng.Random; +import common.world.BlockPos; +import common.world.Facing; +import common.world.IWorldAccess; +import common.world.State; +import common.world.World; +import common.world.WorldServer; public class BlockDragonEgg extends Block { diff --git a/java/src/game/block/BlockDropper.java b/java/src/common/block/BlockDropper.java similarity index 85% rename from java/src/game/block/BlockDropper.java rename to java/src/common/block/BlockDropper.java index 668378a..b939e09 100755 --- a/java/src/game/block/BlockDropper.java +++ b/java/src/common/block/BlockDropper.java @@ -1,16 +1,16 @@ -package game.block; +package common.block; -import game.dispenser.BehaviorDefaultDispenseItem; -import game.dispenser.IBehaviorDispenseItem; -import game.inventory.IInventory; -import game.item.ItemStack; -import game.tileentity.TileEntity; -import game.tileentity.TileEntityDispenser; -import game.tileentity.TileEntityDropper; -import game.tileentity.TileEntityHopper; -import game.world.BlockPos; -import game.world.Facing; -import game.world.World; +import common.dispenser.BehaviorDefaultDispenseItem; +import common.dispenser.IBehaviorDispenseItem; +import common.inventory.IInventory; +import common.item.ItemStack; +import common.tileentity.TileEntity; +import common.tileentity.TileEntityDispenser; +import common.tileentity.TileEntityDropper; +import common.tileentity.TileEntityHopper; +import common.world.BlockPos; +import common.world.Facing; +import common.world.World; public class BlockDropper extends BlockDispenser { diff --git a/java/src/game/block/BlockDryLeaves.java b/java/src/common/block/BlockDryLeaves.java similarity index 88% rename from java/src/game/block/BlockDryLeaves.java rename to java/src/common/block/BlockDryLeaves.java index 2cfd685..5ed08d6 100755 --- a/java/src/game/block/BlockDryLeaves.java +++ b/java/src/common/block/BlockDryLeaves.java @@ -1,11 +1,11 @@ -package game.block; +package common.block; -import game.init.Items; -import game.item.CheatTab; -import game.item.Item; -import game.material.Material; -import game.rng.Random; -import game.world.State; +import common.init.Items; +import common.item.CheatTab; +import common.item.Item; +import common.material.Material; +import common.rng.Random; +import common.world.State; public class BlockDryLeaves extends BlockLeavesBase { diff --git a/java/src/game/block/BlockDynamicLiquid.java b/java/src/common/block/BlockDynamicLiquid.java similarity index 96% rename from java/src/game/block/BlockDynamicLiquid.java rename to java/src/common/block/BlockDynamicLiquid.java index 98c362f..df8128b 100755 --- a/java/src/game/block/BlockDynamicLiquid.java +++ b/java/src/common/block/BlockDynamicLiquid.java @@ -1,17 +1,17 @@ -package game.block; +package common.block; import java.util.EnumSet; import java.util.Set; -import game.init.Blocks; -import game.init.Config; -import game.material.Material; -import game.rng.Random; -import game.world.BlockPos; -import game.world.Facing; -import game.world.State; -import game.world.World; -import game.world.WorldServer; +import common.init.Blocks; +import common.init.Config; +import common.material.Material; +import common.rng.Random; +import common.world.BlockPos; +import common.world.Facing; +import common.world.State; +import common.world.World; +import common.world.WorldServer; public class BlockDynamicLiquid extends BlockLiquid { diff --git a/java/src/game/block/BlockEnchantmentTable.java b/java/src/common/block/BlockEnchantmentTable.java similarity index 87% rename from java/src/game/block/BlockEnchantmentTable.java rename to java/src/common/block/BlockEnchantmentTable.java index 1f0bd32..d33874e 100755 --- a/java/src/game/block/BlockEnchantmentTable.java +++ b/java/src/common/block/BlockEnchantmentTable.java @@ -1,22 +1,22 @@ -package game.block; +package common.block; -import game.entity.npc.EntityNPC; -import game.entity.types.EntityLiving; -import game.init.Blocks; -import game.item.CheatTab; -import game.item.ItemStack; -import game.material.Material; -import game.model.Model; -import game.model.ModelProvider; -import game.model.ParticleType; -import game.rng.Random; -import game.tileentity.TileEntity; -import game.tileentity.TileEntityEnchantmentTable; -import game.world.BlockPos; -import game.world.Facing; -import game.world.State; -import game.world.World; -import game.world.WorldClient; +import common.entity.npc.EntityNPC; +import common.entity.types.EntityLiving; +import common.init.Blocks; +import common.item.CheatTab; +import common.item.ItemStack; +import common.material.Material; +import common.model.Model; +import common.model.ModelProvider; +import common.model.ParticleType; +import common.rng.Random; +import common.tileentity.TileEntity; +import common.tileentity.TileEntityEnchantmentTable; +import common.world.BlockPos; +import common.world.Facing; +import common.world.State; +import common.world.World; +import common.world.WorldClient; public class BlockEnchantmentTable extends BlockContainer { diff --git a/java/src/game/block/BlockEventData.java b/java/src/common/block/BlockEventData.java similarity index 96% rename from java/src/game/block/BlockEventData.java rename to java/src/common/block/BlockEventData.java index b595cbb..5df52e1 100755 --- a/java/src/game/block/BlockEventData.java +++ b/java/src/common/block/BlockEventData.java @@ -1,6 +1,6 @@ -package game.block; +package common.block; -import game.world.BlockPos; +import common.world.BlockPos; public class BlockEventData { diff --git a/java/src/game/block/BlockFalling.java b/java/src/common/block/BlockFalling.java similarity index 88% rename from java/src/game/block/BlockFalling.java rename to java/src/common/block/BlockFalling.java index 9546e4d..c80b15c 100755 --- a/java/src/game/block/BlockFalling.java +++ b/java/src/common/block/BlockFalling.java @@ -1,15 +1,15 @@ -package game.block; +package common.block; -import game.entity.item.EntityFalling; -import game.init.Blocks; -import game.init.Config; -import game.item.CheatTab; -import game.material.Material; -import game.rng.Random; -import game.world.BlockPos; -import game.world.State; -import game.world.World; -import game.world.WorldServer; +import common.entity.item.EntityFalling; +import common.init.Blocks; +import common.init.Config; +import common.item.CheatTab; +import common.material.Material; +import common.rng.Random; +import common.world.BlockPos; +import common.world.State; +import common.world.World; +import common.world.WorldServer; public class BlockFalling extends Block { diff --git a/java/src/game/block/BlockFarmland.java b/java/src/common/block/BlockFarmland.java similarity index 89% rename from java/src/game/block/BlockFarmland.java rename to java/src/common/block/BlockFarmland.java index 1885e73..38f6359 100755 --- a/java/src/game/block/BlockFarmland.java +++ b/java/src/common/block/BlockFarmland.java @@ -1,24 +1,24 @@ -package game.block; +package common.block; -import game.entity.Entity; -import game.entity.types.EntityLiving; -import game.init.Blocks; -import game.init.Config; -import game.init.ItemRegistry; -import game.item.Item; -import game.material.Material; -import game.model.Model; -import game.model.ModelProvider; -import game.properties.IProperty; -import game.properties.PropertyInteger; -import game.rng.Random; -import game.world.BlockPos; -import game.world.BoundingBox; -import game.world.Facing; -import game.world.IWorldAccess; -import game.world.State; -import game.world.World; -import game.world.WorldServer; +import common.entity.Entity; +import common.entity.types.EntityLiving; +import common.init.Blocks; +import common.init.Config; +import common.init.ItemRegistry; +import common.item.Item; +import common.material.Material; +import common.model.Model; +import common.model.ModelProvider; +import common.properties.IProperty; +import common.properties.PropertyInteger; +import common.rng.Random; +import common.world.BlockPos; +import common.world.BoundingBox; +import common.world.Facing; +import common.world.IWorldAccess; +import common.world.State; +import common.world.World; +import common.world.WorldServer; public class BlockFarmland extends Block { diff --git a/java/src/game/block/BlockFence.java b/java/src/common/block/BlockFence.java similarity index 95% rename from java/src/game/block/BlockFence.java rename to java/src/common/block/BlockFence.java index 715bfcc..37ad1a4 100755 --- a/java/src/game/block/BlockFence.java +++ b/java/src/common/block/BlockFence.java @@ -1,26 +1,26 @@ -package game.block; +package common.block; import java.util.List; -import game.collect.Lists; -import game.entity.Entity; -import game.entity.npc.EntityNPC; -import game.item.CheatTab; -import game.item.ItemLead; -import game.material.Material; -import game.model.Model; -import game.model.ModelProvider; -import game.model.ModelRotation; -import game.model.Transforms; -import game.properties.IProperty; -import game.properties.PropertyBool; -import game.world.BlockPos; -import game.world.BoundingBox; -import game.world.Facing; -import game.world.IBlockAccess; -import game.world.IWorldAccess; -import game.world.State; -import game.world.World; +import common.collect.Lists; +import common.entity.Entity; +import common.entity.npc.EntityNPC; +import common.item.CheatTab; +import common.item.ItemLead; +import common.material.Material; +import common.model.Model; +import common.model.ModelProvider; +import common.model.ModelRotation; +import common.model.Transforms; +import common.properties.IProperty; +import common.properties.PropertyBool; +import common.world.BlockPos; +import common.world.BoundingBox; +import common.world.Facing; +import common.world.IBlockAccess; +import common.world.IWorldAccess; +import common.world.State; +import common.world.World; public class BlockFence extends Block { diff --git a/java/src/game/block/BlockFenceGate.java b/java/src/common/block/BlockFenceGate.java similarity index 95% rename from java/src/game/block/BlockFenceGate.java rename to java/src/common/block/BlockFenceGate.java index 1d5d2a1..fbf6658 100755 --- a/java/src/game/block/BlockFenceGate.java +++ b/java/src/common/block/BlockFenceGate.java @@ -1,24 +1,24 @@ -package game.block; +package common.block; -import game.entity.npc.EntityNPC; -import game.entity.types.EntityLiving; -import game.init.Blocks; -import game.init.WoodType; -import game.item.CheatTab; -import game.material.Material; -import game.model.Model; -import game.model.ModelProvider; -import game.model.ModelRotation; -import game.model.Transforms; -import game.properties.IProperty; -import game.properties.PropertyBool; -import game.world.BlockPos; -import game.world.BoundingBox; -import game.world.Facing; -import game.world.IBlockAccess; -import game.world.IWorldAccess; -import game.world.State; -import game.world.World; +import common.entity.npc.EntityNPC; +import common.entity.types.EntityLiving; +import common.init.Blocks; +import common.init.WoodType; +import common.item.CheatTab; +import common.material.Material; +import common.model.Model; +import common.model.ModelProvider; +import common.model.ModelRotation; +import common.model.Transforms; +import common.properties.IProperty; +import common.properties.PropertyBool; +import common.world.BlockPos; +import common.world.BoundingBox; +import common.world.Facing; +import common.world.IBlockAccess; +import common.world.IWorldAccess; +import common.world.State; +import common.world.World; public class BlockFenceGate extends BlockDirectional { diff --git a/java/src/game/block/BlockFire.java b/java/src/common/block/BlockFire.java similarity index 98% rename from java/src/game/block/BlockFire.java rename to java/src/common/block/BlockFire.java index 3374010..18a13bb 100755 --- a/java/src/game/block/BlockFire.java +++ b/java/src/common/block/BlockFire.java @@ -1,30 +1,30 @@ -package game.block; +package common.block; import java.util.Map; -import game.collect.Maps; -import game.init.Blocks; -import game.init.Config; -import game.init.SoundEvent; -import game.material.Material; -import game.model.BlockLayer; -import game.model.Model; -import game.model.ModelProvider; -import game.model.ModelRotation; -import game.model.ParticleType; -import game.properties.IProperty; -import game.properties.PropertyBool; -import game.properties.PropertyInteger; -import game.rng.Random; -import game.world.BlockPos; -import game.world.BoundingBox; -import game.world.Facing; -import game.world.IBlockAccess; -import game.world.IWorldAccess; -import game.world.State; -import game.world.World; -import game.world.WorldClient; -import game.world.WorldServer; +import common.collect.Maps; +import common.init.Blocks; +import common.init.Config; +import common.init.SoundEvent; +import common.material.Material; +import common.model.BlockLayer; +import common.model.Model; +import common.model.ModelProvider; +import common.model.ModelRotation; +import common.model.ParticleType; +import common.properties.IProperty; +import common.properties.PropertyBool; +import common.properties.PropertyInteger; +import common.rng.Random; +import common.world.BlockPos; +import common.world.BoundingBox; +import common.world.Facing; +import common.world.IBlockAccess; +import common.world.IWorldAccess; +import common.world.State; +import common.world.World; +import common.world.WorldClient; +import common.world.WorldServer; public class BlockFire extends Block { diff --git a/java/src/game/block/BlockFloorPortal.java b/java/src/common/block/BlockFloorPortal.java similarity index 90% rename from java/src/game/block/BlockFloorPortal.java rename to java/src/common/block/BlockFloorPortal.java index acc7dfb..347e4e1 100755 --- a/java/src/game/block/BlockFloorPortal.java +++ b/java/src/common/block/BlockFloorPortal.java @@ -1,24 +1,24 @@ -package game.block; +package common.block; import java.util.List; import java.util.Map; import java.util.Set; -import game.collect.Sets; -import game.entity.Entity; -import game.item.Item; -import game.material.Material; -import game.model.Model; -import game.model.ModelProvider; -import game.model.ParticleType; -import game.rng.Random; -import game.world.BlockPos; -import game.world.BoundingBox; -import game.world.Facing; -import game.world.IWorldAccess; -import game.world.State; -import game.world.World; -import game.world.WorldClient; +import common.collect.Sets; +import common.entity.Entity; +import common.item.Item; +import common.material.Material; +import common.model.Model; +import common.model.ModelProvider; +import common.model.ParticleType; +import common.rng.Random; +import common.world.BlockPos; +import common.world.BoundingBox; +import common.world.Facing; +import common.world.IWorldAccess; +import common.world.State; +import common.world.World; +import common.world.WorldClient; public class BlockFloorPortal extends Block { diff --git a/java/src/game/block/BlockFlower.java b/java/src/common/block/BlockFlower.java similarity index 93% rename from java/src/game/block/BlockFlower.java rename to java/src/common/block/BlockFlower.java index fff920c..3ce19a9 100755 --- a/java/src/game/block/BlockFlower.java +++ b/java/src/common/block/BlockFlower.java @@ -1,25 +1,25 @@ -package game.block; +package common.block; import java.util.Collection; import java.util.List; import java.util.function.Predicate; -import game.collect.Filter; -import game.collect.Lists; -import game.init.Blocks; -import game.init.Config; -import game.item.CheatTab; -import game.item.Item; -import game.item.ItemStack; -import game.model.Model; -import game.model.ModelProvider; -import game.properties.IProperty; -import game.properties.PropertyEnum; -import game.rng.Random; -import game.util.Identifyable; -import game.world.BlockPos; -import game.world.State; -import game.world.WorldServer; +import common.collect.Filter; +import common.collect.Lists; +import common.init.Blocks; +import common.init.Config; +import common.item.CheatTab; +import common.item.Item; +import common.item.ItemStack; +import common.model.Model; +import common.model.ModelProvider; +import common.properties.IProperty; +import common.properties.PropertyEnum; +import common.rng.Random; +import common.util.Identifyable; +import common.world.BlockPos; +import common.world.State; +import common.world.WorldServer; public abstract class BlockFlower extends BlockBush { diff --git a/java/src/game/block/BlockFlowerPot.java b/java/src/common/block/BlockFlowerPot.java similarity index 95% rename from java/src/game/block/BlockFlowerPot.java rename to java/src/common/block/BlockFlowerPot.java index 852df5b..133ea9f 100755 --- a/java/src/game/block/BlockFlowerPot.java +++ b/java/src/common/block/BlockFlowerPot.java @@ -1,24 +1,24 @@ -package game.block; +package common.block; -import game.entity.npc.EntityNPC; -import game.init.Blocks; -import game.init.ItemRegistry; -import game.init.Items; -import game.item.Item; -import game.item.ItemBlock; -import game.item.ItemStack; -import game.material.Material; -import game.model.BlockLayer; -import game.model.Model; -import game.model.ModelProvider; -import game.properties.IProperty; -import game.properties.PropertyInteger; -import game.rng.Random; -import game.world.BlockPos; -import game.world.Facing; -import game.world.State; -import game.world.World; -import game.world.WorldServer; +import common.entity.npc.EntityNPC; +import common.init.Blocks; +import common.init.ItemRegistry; +import common.init.Items; +import common.item.Item; +import common.item.ItemBlock; +import common.item.ItemStack; +import common.material.Material; +import common.model.BlockLayer; +import common.model.Model; +import common.model.ModelProvider; +import common.properties.IProperty; +import common.properties.PropertyInteger; +import common.rng.Random; +import common.world.BlockPos; +import common.world.Facing; +import common.world.State; +import common.world.World; +import common.world.WorldServer; public class BlockFlowerPot extends Block // Container { diff --git a/java/src/game/block/BlockFurnace.java b/java/src/common/block/BlockFurnace.java similarity index 91% rename from java/src/game/block/BlockFurnace.java rename to java/src/common/block/BlockFurnace.java index 1e89482..8e225cd 100755 --- a/java/src/game/block/BlockFurnace.java +++ b/java/src/common/block/BlockFurnace.java @@ -1,29 +1,29 @@ -package game.block; +package common.block; -import game.entity.npc.EntityNPC; -import game.entity.types.EntityLiving; -import game.init.Blocks; -import game.init.ItemRegistry; -import game.inventory.Container; -import game.inventory.InventoryHelper; -import game.item.Item; -import game.item.ItemStack; -import game.material.Material; -import game.model.Model; -import game.model.ModelProvider; -import game.model.ModelRotation; -import game.model.ParticleType; -import game.properties.IProperty; -import game.properties.PropertyDirection; -import game.rng.Random; -import game.tileentity.TileEntity; -import game.tileentity.TileEntityFurnace; -import game.world.BlockPos; -import game.world.Facing; -import game.world.State; -import game.world.World; -import game.world.WorldClient; -import game.world.WorldServer; +import common.entity.npc.EntityNPC; +import common.entity.types.EntityLiving; +import common.init.Blocks; +import common.init.ItemRegistry; +import common.inventory.Container; +import common.inventory.InventoryHelper; +import common.item.Item; +import common.item.ItemStack; +import common.material.Material; +import common.model.Model; +import common.model.ModelProvider; +import common.model.ModelRotation; +import common.model.ParticleType; +import common.properties.IProperty; +import common.properties.PropertyDirection; +import common.rng.Random; +import common.tileentity.TileEntity; +import common.tileentity.TileEntityFurnace; +import common.world.BlockPos; +import common.world.Facing; +import common.world.State; +import common.world.World; +import common.world.WorldClient; +import common.world.WorldServer; public class BlockFurnace extends BlockContainer { diff --git a/java/src/game/block/BlockGlass.java b/java/src/common/block/BlockGlass.java similarity index 80% rename from java/src/game/block/BlockGlass.java rename to java/src/common/block/BlockGlass.java index 4445d66..adc1e63 100755 --- a/java/src/game/block/BlockGlass.java +++ b/java/src/common/block/BlockGlass.java @@ -1,9 +1,9 @@ -package game.block; +package common.block; -import game.item.CheatTab; -import game.material.Material; -import game.model.BlockLayer; -import game.rng.Random; +import common.item.CheatTab; +import common.material.Material; +import common.model.BlockLayer; +import common.rng.Random; public class BlockGlass extends BlockBreakable { diff --git a/java/src/game/block/BlockGlowstone.java b/java/src/common/block/BlockGlowstone.java similarity index 82% rename from java/src/game/block/BlockGlowstone.java rename to java/src/common/block/BlockGlowstone.java index 99cbce4..ddcdf75 100755 --- a/java/src/game/block/BlockGlowstone.java +++ b/java/src/common/block/BlockGlowstone.java @@ -1,12 +1,12 @@ -package game.block; +package common.block; -import game.init.Items; -import game.item.CheatTab; -import game.item.Item; -import game.material.Material; -import game.rng.Random; -import game.util.ExtMath; -import game.world.State; +import common.init.Items; +import common.item.CheatTab; +import common.item.Item; +import common.material.Material; +import common.rng.Random; +import common.util.ExtMath; +import common.world.State; public class BlockGlowstone extends Block { diff --git a/java/src/game/block/BlockGrass.java b/java/src/common/block/BlockGrass.java similarity index 91% rename from java/src/game/block/BlockGrass.java rename to java/src/common/block/BlockGrass.java index 39cd89c..95a32d1 100755 --- a/java/src/game/block/BlockGrass.java +++ b/java/src/common/block/BlockGrass.java @@ -1,22 +1,22 @@ -package game.block; +package common.block; -import game.color.Colorizer; -import game.init.Blocks; -import game.init.Config; -import game.item.CheatTab; -import game.item.Item; -import game.material.Material; -import game.model.BlockLayer; -import game.model.Model; -import game.model.ModelProvider; -import game.properties.IProperty; -import game.properties.PropertyBool; -import game.rng.Random; -import game.world.BlockPos; -import game.world.IWorldAccess; -import game.world.State; -import game.world.World; -import game.world.WorldServer; +import common.color.Colorizer; +import common.init.Blocks; +import common.init.Config; +import common.item.CheatTab; +import common.item.Item; +import common.material.Material; +import common.model.BlockLayer; +import common.model.Model; +import common.model.ModelProvider; +import common.properties.IProperty; +import common.properties.PropertyBool; +import common.rng.Random; +import common.world.BlockPos; +import common.world.IWorldAccess; +import common.world.State; +import common.world.World; +import common.world.WorldServer; public class BlockGrass extends Block implements IGrowable { diff --git a/java/src/game/block/BlockGravel.java b/java/src/common/block/BlockGravel.java similarity index 74% rename from java/src/game/block/BlockGravel.java rename to java/src/common/block/BlockGravel.java index 8684acb..9206e53 100755 --- a/java/src/game/block/BlockGravel.java +++ b/java/src/common/block/BlockGravel.java @@ -1,11 +1,11 @@ -package game.block; +package common.block; -import game.init.Config; -import game.init.ItemRegistry; -import game.init.Items; -import game.item.Item; -import game.rng.Random; -import game.world.State; +import common.init.Config; +import common.init.ItemRegistry; +import common.init.Items; +import common.item.Item; +import common.rng.Random; +import common.world.State; public class BlockGravel extends BlockFalling { diff --git a/java/src/game/block/BlockHardenedClay.java b/java/src/common/block/BlockHardenedClay.java similarity index 80% rename from java/src/game/block/BlockHardenedClay.java rename to java/src/common/block/BlockHardenedClay.java index 4f3cbdb..d3be1c4 100755 --- a/java/src/game/block/BlockHardenedClay.java +++ b/java/src/common/block/BlockHardenedClay.java @@ -1,7 +1,7 @@ -package game.block; +package common.block; -import game.item.CheatTab; -import game.material.Material; +import common.item.CheatTab; +import common.material.Material; public class BlockHardenedClay extends Block { diff --git a/java/src/game/block/BlockHay.java b/java/src/common/block/BlockHay.java similarity index 84% rename from java/src/game/block/BlockHay.java rename to java/src/common/block/BlockHay.java index 6aad1cc..c48465c 100755 --- a/java/src/game/block/BlockHay.java +++ b/java/src/common/block/BlockHay.java @@ -1,15 +1,15 @@ -package game.block; +package common.block; -import game.entity.types.EntityLiving; -import game.init.ItemRegistry; -import game.item.CheatTab; -import game.item.ItemStack; -import game.material.Material; -import game.properties.IProperty; -import game.world.BlockPos; -import game.world.Facing; -import game.world.State; -import game.world.World; +import common.entity.types.EntityLiving; +import common.init.ItemRegistry; +import common.item.CheatTab; +import common.item.ItemStack; +import common.material.Material; +import common.properties.IProperty; +import common.world.BlockPos; +import common.world.Facing; +import common.world.State; +import common.world.World; public class BlockHay extends BlockRotatedPillar { diff --git a/java/src/game/block/BlockHellRock.java b/java/src/common/block/BlockHellRock.java similarity index 83% rename from java/src/game/block/BlockHellRock.java rename to java/src/common/block/BlockHellRock.java index 664aad4..26a4859 100755 --- a/java/src/game/block/BlockHellRock.java +++ b/java/src/common/block/BlockHellRock.java @@ -1,7 +1,7 @@ -package game.block; +package common.block; -import game.item.CheatTab; -import game.material.Material; +import common.item.CheatTab; +import common.material.Material; public class BlockHellRock extends Block { diff --git a/java/src/game/block/BlockHopper.java b/java/src/common/block/BlockHopper.java similarity index 92% rename from java/src/game/block/BlockHopper.java rename to java/src/common/block/BlockHopper.java index 6d4fd33..489f8f6 100755 --- a/java/src/game/block/BlockHopper.java +++ b/java/src/common/block/BlockHopper.java @@ -1,32 +1,32 @@ -package game.block; +package common.block; import java.util.List; import java.util.function.Predicate; -import game.entity.Entity; -import game.entity.npc.EntityNPC; -import game.entity.types.EntityLiving; -import game.inventory.Container; -import game.inventory.InventoryHelper; -import game.item.CheatTab; -import game.item.ItemStack; -import game.material.Material; -import game.model.BlockLayer; -import game.model.Model; -import game.model.ModelProvider; -import game.model.ModelRotation; -import game.properties.IProperty; -import game.properties.PropertyBool; -import game.properties.PropertyDirection; -import game.tileentity.TileEntity; -import game.tileentity.TileEntityHopper; -import game.world.BlockPos; -import game.world.BoundingBox; -import game.world.Facing; -import game.world.IWorldAccess; -import game.world.State; -import game.world.World; -import game.world.WorldServer; +import common.entity.Entity; +import common.entity.npc.EntityNPC; +import common.entity.types.EntityLiving; +import common.inventory.Container; +import common.inventory.InventoryHelper; +import common.item.CheatTab; +import common.item.ItemStack; +import common.material.Material; +import common.model.BlockLayer; +import common.model.Model; +import common.model.ModelProvider; +import common.model.ModelRotation; +import common.properties.IProperty; +import common.properties.PropertyBool; +import common.properties.PropertyDirection; +import common.tileentity.TileEntity; +import common.tileentity.TileEntityHopper; +import common.world.BlockPos; +import common.world.BoundingBox; +import common.world.Facing; +import common.world.IWorldAccess; +import common.world.State; +import common.world.World; +import common.world.WorldServer; public class BlockHopper extends BlockContainer { diff --git a/java/src/game/block/BlockHugeMushroom.java b/java/src/common/block/BlockHugeMushroom.java similarity index 93% rename from java/src/game/block/BlockHugeMushroom.java rename to java/src/common/block/BlockHugeMushroom.java index ba36f71..6493036 100755 --- a/java/src/game/block/BlockHugeMushroom.java +++ b/java/src/common/block/BlockHugeMushroom.java @@ -1,19 +1,19 @@ -package game.block; +package common.block; -import game.entity.types.EntityLiving; -import game.init.ItemRegistry; -import game.item.Item; -import game.material.Material; -import game.model.Model; -import game.model.ModelProvider; -import game.properties.IProperty; -import game.properties.PropertyEnum; -import game.rng.Random; -import game.util.Identifyable; -import game.world.BlockPos; -import game.world.Facing; -import game.world.State; -import game.world.World; +import common.entity.types.EntityLiving; +import common.init.ItemRegistry; +import common.item.Item; +import common.material.Material; +import common.model.Model; +import common.model.ModelProvider; +import common.properties.IProperty; +import common.properties.PropertyEnum; +import common.rng.Random; +import common.util.Identifyable; +import common.world.BlockPos; +import common.world.Facing; +import common.world.State; +import common.world.World; public class BlockHugeMushroom extends Block { diff --git a/java/src/game/block/BlockIce.java b/java/src/common/block/BlockIce.java similarity index 81% rename from java/src/game/block/BlockIce.java rename to java/src/common/block/BlockIce.java index 565104a..1adca24 100755 --- a/java/src/game/block/BlockIce.java +++ b/java/src/common/block/BlockIce.java @@ -1,20 +1,20 @@ -package game.block; +package common.block; -import game.enchantment.EnchantmentHelper; -import game.entity.npc.EntityNPC; -import game.init.Blocks; -import game.init.Config; -import game.item.CheatTab; -import game.item.ItemStack; -import game.material.Material; -import game.model.BlockLayer; -import game.rng.Random; -import game.tileentity.TileEntity; -import game.world.BlockPos; -import game.world.LightType; -import game.world.State; -import game.world.World; -import game.world.WorldServer; +import common.enchantment.EnchantmentHelper; +import common.entity.npc.EntityNPC; +import common.init.Blocks; +import common.init.Config; +import common.item.CheatTab; +import common.item.ItemStack; +import common.material.Material; +import common.model.BlockLayer; +import common.rng.Random; +import common.tileentity.TileEntity; +import common.world.BlockPos; +import common.world.LightType; +import common.world.State; +import common.world.World; +import common.world.WorldServer; public class BlockIce extends BlockBreakable { diff --git a/java/src/game/block/BlockJukebox.java b/java/src/common/block/BlockJukebox.java similarity index 64% rename from java/src/game/block/BlockJukebox.java rename to java/src/common/block/BlockJukebox.java index 839ae8e..f37d8b2 100755 --- a/java/src/game/block/BlockJukebox.java +++ b/java/src/common/block/BlockJukebox.java @@ -1,15 +1,15 @@ -package game.block; +package common.block; -import game.entity.npc.EntityNPC; -import game.init.SoundEvent; -import game.item.CheatTab; -import game.material.Material; -import game.model.Model; -import game.model.ModelProvider; -import game.world.BlockPos; -import game.world.Facing; -import game.world.State; -import game.world.World; +import common.entity.npc.EntityNPC; +import common.init.SoundEvent; +import common.item.CheatTab; +import common.material.Material; +import common.model.Model; +import common.model.ModelProvider; +import common.world.BlockPos; +import common.world.Facing; +import common.world.State; +import common.world.World; public class BlockJukebox extends Block { public BlockJukebox() { diff --git a/java/src/game/block/BlockLadder.java b/java/src/common/block/BlockLadder.java similarity index 90% rename from java/src/game/block/BlockLadder.java rename to java/src/common/block/BlockLadder.java index 3c8df92..f22b33f 100755 --- a/java/src/game/block/BlockLadder.java +++ b/java/src/common/block/BlockLadder.java @@ -1,20 +1,20 @@ -package game.block; +package common.block; -import game.entity.types.EntityLiving; -import game.item.CheatTab; -import game.material.Material; -import game.model.BlockLayer; -import game.model.Model; -import game.model.ModelProvider; -import game.model.ModelRotation; -import game.properties.IProperty; -import game.properties.PropertyDirection; -import game.world.BlockPos; -import game.world.BoundingBox; -import game.world.Facing; -import game.world.IWorldAccess; -import game.world.State; -import game.world.World; +import common.entity.types.EntityLiving; +import common.item.CheatTab; +import common.material.Material; +import common.model.BlockLayer; +import common.model.Model; +import common.model.ModelProvider; +import common.model.ModelRotation; +import common.properties.IProperty; +import common.properties.PropertyDirection; +import common.world.BlockPos; +import common.world.BoundingBox; +import common.world.Facing; +import common.world.IWorldAccess; +import common.world.State; +import common.world.World; public class BlockLadder extends Block { diff --git a/java/src/game/block/BlockLeaves.java b/java/src/common/block/BlockLeaves.java similarity index 93% rename from java/src/game/block/BlockLeaves.java rename to java/src/common/block/BlockLeaves.java index d37c901..e5f2d51 100755 --- a/java/src/game/block/BlockLeaves.java +++ b/java/src/common/block/BlockLeaves.java @@ -1,33 +1,33 @@ -package game.block; +package common.block; import java.util.List; -import game.collect.Lists; -import game.color.Colorizer; -import game.entity.npc.EntityNPC; -import game.init.Blocks; -import game.init.Config; -import game.init.ItemRegistry; -import game.init.WoodType; -import game.item.CheatTab; -import game.item.Item; -import game.item.ItemShears; -import game.item.ItemStack; -import game.material.Material; -import game.model.Model; -import game.model.ModelProvider; -import game.model.ParticleType; -import game.properties.IProperty; -import game.properties.PropertyBool; -import game.properties.PropertyEnum; -import game.rng.Random; -import game.tileentity.TileEntity; -import game.world.BlockPos; -import game.world.IWorldAccess; -import game.world.State; -import game.world.World; -import game.world.WorldClient; -import game.world.WorldServer; +import common.collect.Lists; +import common.color.Colorizer; +import common.entity.npc.EntityNPC; +import common.init.Blocks; +import common.init.Config; +import common.init.ItemRegistry; +import common.init.WoodType; +import common.item.CheatTab; +import common.item.Item; +import common.item.ItemShears; +import common.item.ItemStack; +import common.material.Material; +import common.model.Model; +import common.model.ModelProvider; +import common.model.ParticleType; +import common.properties.IProperty; +import common.properties.PropertyBool; +import common.properties.PropertyEnum; +import common.rng.Random; +import common.tileentity.TileEntity; +import common.world.BlockPos; +import common.world.IWorldAccess; +import common.world.State; +import common.world.World; +import common.world.WorldClient; +import common.world.WorldServer; public class BlockLeaves extends BlockLeavesBase { diff --git a/java/src/game/block/BlockLeavesBase.java b/java/src/common/block/BlockLeavesBase.java similarity index 91% rename from java/src/game/block/BlockLeavesBase.java rename to java/src/common/block/BlockLeavesBase.java index e9b871d..2c7a3c2 100755 --- a/java/src/game/block/BlockLeavesBase.java +++ b/java/src/common/block/BlockLeavesBase.java @@ -1,7 +1,7 @@ -package game.block; +package common.block; -import game.material.Material; -import game.model.BlockLayer; +import common.material.Material; +import common.model.BlockLayer; public class BlockLeavesBase extends Block { diff --git a/java/src/game/block/BlockLever.java b/java/src/common/block/BlockLever.java similarity index 94% rename from java/src/game/block/BlockLever.java rename to java/src/common/block/BlockLever.java index 0592a0d..6766b57 100755 --- a/java/src/game/block/BlockLever.java +++ b/java/src/common/block/BlockLever.java @@ -1,24 +1,24 @@ -package game.block; +package common.block; -import game.entity.npc.EntityNPC; -import game.entity.types.EntityLiving; -import game.init.SoundEvent; -import game.item.CheatTab; -import game.material.Material; -import game.model.Model; -import game.model.ModelProvider; -import game.model.ModelRotation; -import game.properties.IProperty; -import game.properties.PropertyBool; -import game.properties.PropertyEnum; -import game.util.Identifyable; -import game.world.BlockPos; -import game.world.BoundingBox; -import game.world.Facing; -import game.world.IWorldAccess; -import game.world.State; -import game.world.World; -import game.world.WorldServer; +import common.entity.npc.EntityNPC; +import common.entity.types.EntityLiving; +import common.init.SoundEvent; +import common.item.CheatTab; +import common.material.Material; +import common.model.Model; +import common.model.ModelProvider; +import common.model.ModelRotation; +import common.properties.IProperty; +import common.properties.PropertyBool; +import common.properties.PropertyEnum; +import common.util.Identifyable; +import common.world.BlockPos; +import common.world.BoundingBox; +import common.world.Facing; +import common.world.IWorldAccess; +import common.world.State; +import common.world.World; +import common.world.WorldServer; public class BlockLever extends Block { diff --git a/java/src/game/block/BlockLilyPad.java b/java/src/common/block/BlockLilyPad.java similarity index 86% rename from java/src/game/block/BlockLilyPad.java rename to java/src/common/block/BlockLilyPad.java index 1e67c54..a117b36 100755 --- a/java/src/game/block/BlockLilyPad.java +++ b/java/src/common/block/BlockLilyPad.java @@ -1,22 +1,22 @@ -package game.block; +package common.block; import java.util.List; -import game.entity.Entity; -import game.entity.item.EntityBoat; -import game.entity.types.EntityLiving; -import game.init.Blocks; -import game.item.CheatTab; -import game.model.Model; -import game.model.ModelProvider; -import game.model.ModelRotation; -import game.properties.IProperty; -import game.world.BlockPos; -import game.world.BoundingBox; -import game.world.Facing; -import game.world.IWorldAccess; -import game.world.State; -import game.world.World; +import common.entity.Entity; +import common.entity.item.EntityBoat; +import common.entity.types.EntityLiving; +import common.init.Blocks; +import common.item.CheatTab; +import common.model.Model; +import common.model.ModelProvider; +import common.model.ModelRotation; +import common.properties.IProperty; +import common.world.BlockPos; +import common.world.BoundingBox; +import common.world.Facing; +import common.world.IWorldAccess; +import common.world.State; +import common.world.World; public class BlockLilyPad extends BlockBush { diff --git a/java/src/game/block/BlockLiquid.java b/java/src/common/block/BlockLiquid.java similarity index 94% rename from java/src/game/block/BlockLiquid.java rename to java/src/common/block/BlockLiquid.java index 940ffd7..570baaa 100755 --- a/java/src/game/block/BlockLiquid.java +++ b/java/src/common/block/BlockLiquid.java @@ -1,29 +1,29 @@ -package game.block; +package common.block; -import game.color.Colorizer; -import game.entity.Entity; -import game.init.Blocks; -import game.init.Config; -import game.init.FluidRegistry; -import game.init.SoundEvent; -import game.item.Item; -import game.material.Material; -import game.model.BlockLayer; -import game.model.ParticleType; -import game.properties.IProperty; -import game.properties.PropertyInteger; -import game.rng.Random; -import game.util.ExtMath; -import game.world.BlockPos; -import game.world.BoundingBox; -import game.world.Facing; -import game.world.IBlockAccess; -import game.world.IWorldAccess; -import game.world.State; -import game.world.Vec3; -import game.world.World; -import game.world.WorldClient; -import game.world.WorldServer; +import common.color.Colorizer; +import common.entity.Entity; +import common.init.Blocks; +import common.init.Config; +import common.init.FluidRegistry; +import common.init.SoundEvent; +import common.item.Item; +import common.material.Material; +import common.model.BlockLayer; +import common.model.ParticleType; +import common.properties.IProperty; +import common.properties.PropertyInteger; +import common.rng.Random; +import common.util.ExtMath; +import common.world.BlockPos; +import common.world.BoundingBox; +import common.world.Facing; +import common.world.IBlockAccess; +import common.world.IWorldAccess; +import common.world.State; +import common.world.Vec3; +import common.world.World; +import common.world.WorldClient; +import common.world.WorldServer; public abstract class BlockLiquid extends Block { diff --git a/java/src/game/block/BlockLog.java b/java/src/common/block/BlockLog.java similarity index 90% rename from java/src/game/block/BlockLog.java rename to java/src/common/block/BlockLog.java index c3de107..9162608 100755 --- a/java/src/game/block/BlockLog.java +++ b/java/src/common/block/BlockLog.java @@ -1,19 +1,19 @@ -package game.block; +package common.block; -import game.entity.types.EntityLiving; -import game.item.CheatTab; -import game.material.Material; -import game.model.Model; -import game.model.ModelProvider; -import game.model.ModelRotation; -import game.properties.IProperty; -import game.properties.PropertyEnum; -import game.util.Identifyable; -import game.world.BlockPos; -import game.world.Facing; -import game.world.State; -import game.world.World; -import game.world.WorldServer; +import common.entity.types.EntityLiving; +import common.item.CheatTab; +import common.material.Material; +import common.model.Model; +import common.model.ModelProvider; +import common.model.ModelRotation; +import common.properties.IProperty; +import common.properties.PropertyEnum; +import common.util.Identifyable; +import common.world.BlockPos; +import common.world.Facing; +import common.world.State; +import common.world.World; +import common.world.WorldServer; public class BlockLog extends BlockRotatedPillar { diff --git a/java/src/game/block/BlockMachine.java b/java/src/common/block/BlockMachine.java similarity index 85% rename from java/src/game/block/BlockMachine.java rename to java/src/common/block/BlockMachine.java index 55d7719..efe8555 100755 --- a/java/src/game/block/BlockMachine.java +++ b/java/src/common/block/BlockMachine.java @@ -1,19 +1,19 @@ -package game.block; +package common.block; -import game.entity.npc.EntityNPC; -import game.entity.types.EntityLiving; -import game.inventory.Container; -import game.inventory.InventoryHelper; -import game.item.CheatTab; -import game.material.Material; -import game.properties.IProperty; -import game.tileentity.TileEntity; -import game.tileentity.TileEntityMachine; -import game.world.BlockPos; -import game.world.Facing; -import game.world.State; -import game.world.World; -import game.world.WorldServer; +import common.entity.npc.EntityNPC; +import common.entity.types.EntityLiving; +import common.inventory.Container; +import common.inventory.InventoryHelper; +import common.item.CheatTab; +import common.material.Material; +import common.properties.IProperty; +import common.tileentity.TileEntity; +import common.tileentity.TileEntityMachine; +import common.world.BlockPos; +import common.world.Facing; +import common.world.State; +import common.world.World; +import common.world.WorldServer; public abstract class BlockMachine extends BlockDirectional implements ITileEntityProvider { public BlockMachine() { diff --git a/java/src/game/block/BlockMelon.java b/java/src/common/block/BlockMelon.java similarity index 78% rename from java/src/game/block/BlockMelon.java rename to java/src/common/block/BlockMelon.java index 6ce8e2d..53e8c84 100755 --- a/java/src/game/block/BlockMelon.java +++ b/java/src/common/block/BlockMelon.java @@ -1,13 +1,13 @@ -package game.block; +package common.block; -import game.init.Items; -import game.item.CheatTab; -import game.item.Item; -import game.material.Material; -import game.model.Model; -import game.model.ModelProvider; -import game.rng.Random; -import game.world.State; +import common.init.Items; +import common.item.CheatTab; +import common.item.Item; +import common.material.Material; +import common.model.Model; +import common.model.ModelProvider; +import common.rng.Random; +import common.world.State; public class BlockMelon extends Block { diff --git a/java/src/game/block/BlockMobSpawner.java b/java/src/common/block/BlockMobSpawner.java similarity index 84% rename from java/src/game/block/BlockMobSpawner.java rename to java/src/common/block/BlockMobSpawner.java index 3e79503..9263baa 100755 --- a/java/src/game/block/BlockMobSpawner.java +++ b/java/src/common/block/BlockMobSpawner.java @@ -1,15 +1,15 @@ -package game.block; +package common.block; -import game.item.CheatTab; -import game.item.Item; -import game.material.Material; -import game.model.BlockLayer; -import game.rng.Random; -import game.tileentity.TileEntity; -import game.tileentity.TileEntityMobSpawner; -import game.world.BlockPos; -import game.world.State; -import game.world.World; +import common.item.CheatTab; +import common.item.Item; +import common.material.Material; +import common.model.BlockLayer; +import common.rng.Random; +import common.tileentity.TileEntity; +import common.tileentity.TileEntityMobSpawner; +import common.world.BlockPos; +import common.world.State; +import common.world.World; public class BlockMobSpawner extends BlockContainer { diff --git a/java/src/game/block/BlockMushroom.java b/java/src/common/block/BlockMushroom.java similarity index 90% rename from java/src/game/block/BlockMushroom.java rename to java/src/common/block/BlockMushroom.java index 9fb2154..a69d71a 100755 --- a/java/src/game/block/BlockMushroom.java +++ b/java/src/common/block/BlockMushroom.java @@ -1,16 +1,16 @@ -package game.block; +package common.block; -import game.init.Blocks; -import game.init.Config; -import game.model.Model; -import game.model.ModelProvider; -import game.rng.Random; -import game.world.BlockPos; -import game.world.State; -import game.world.World; -import game.world.WorldServer; -import game.worldgen.FeatureGenerator; -import game.worldgen.foliage.WorldGenBigMushroom; +import common.init.Blocks; +import common.init.Config; +import common.model.Model; +import common.model.ModelProvider; +import common.rng.Random; +import common.world.BlockPos; +import common.world.State; +import common.world.World; +import common.world.WorldServer; +import common.worldgen.FeatureGenerator; +import common.worldgen.foliage.WorldGenBigMushroom; public class BlockMushroom extends BlockBush implements IGrowable { diff --git a/java/src/game/block/BlockMycelium.java b/java/src/common/block/BlockMycelium.java similarity index 86% rename from java/src/game/block/BlockMycelium.java rename to java/src/common/block/BlockMycelium.java index d014d87..38fed42 100755 --- a/java/src/game/block/BlockMycelium.java +++ b/java/src/common/block/BlockMycelium.java @@ -1,21 +1,21 @@ -package game.block; +package common.block; -import game.init.Blocks; -import game.init.Config; -import game.item.CheatTab; -import game.item.Item; -import game.material.Material; -import game.model.Model; -import game.model.ModelProvider; -import game.model.ParticleType; -import game.properties.IProperty; -import game.properties.PropertyBool; -import game.rng.Random; -import game.world.BlockPos; -import game.world.IWorldAccess; -import game.world.State; -import game.world.WorldClient; -import game.world.WorldServer; +import common.init.Blocks; +import common.init.Config; +import common.item.CheatTab; +import common.item.Item; +import common.material.Material; +import common.model.Model; +import common.model.ModelProvider; +import common.model.ParticleType; +import common.properties.IProperty; +import common.properties.PropertyBool; +import common.rng.Random; +import common.world.BlockPos; +import common.world.IWorldAccess; +import common.world.State; +import common.world.WorldClient; +import common.world.WorldServer; public class BlockMycelium extends Block { diff --git a/java/src/game/block/BlockNote.java b/java/src/common/block/BlockNote.java similarity index 90% rename from java/src/game/block/BlockNote.java rename to java/src/common/block/BlockNote.java index 1413107..9a548f9 100755 --- a/java/src/game/block/BlockNote.java +++ b/java/src/common/block/BlockNote.java @@ -1,16 +1,16 @@ -package game.block; +package common.block; -import game.entity.npc.EntityNPC; -import game.init.SoundEvent; -import game.item.CheatTab; -import game.material.Material; -import game.model.ParticleType; -import game.tileentity.TileEntity; -import game.tileentity.TileEntityNote; -import game.world.BlockPos; -import game.world.Facing; -import game.world.State; -import game.world.World; +import common.entity.npc.EntityNPC; +import common.init.SoundEvent; +import common.item.CheatTab; +import common.material.Material; +import common.model.ParticleType; +import common.tileentity.TileEntity; +import common.tileentity.TileEntityNote; +import common.world.BlockPos; +import common.world.Facing; +import common.world.State; +import common.world.World; public class BlockNote extends BlockContainer { diff --git a/java/src/game/block/BlockNuke.java b/java/src/common/block/BlockNuke.java similarity index 81% rename from java/src/game/block/BlockNuke.java rename to java/src/common/block/BlockNuke.java index f666ba6..e993151 100755 --- a/java/src/game/block/BlockNuke.java +++ b/java/src/common/block/BlockNuke.java @@ -1,17 +1,17 @@ -package game.block; +package common.block; -import game.entity.item.EntityNuke; -import game.init.Blocks; -import game.init.SoundEvent; -import game.item.CheatTab; -import game.material.Material; -import game.model.Model; -import game.model.ModelProvider; -import game.world.BlockPos; -import game.world.Explosion; -import game.world.State; -import game.world.World; -import game.world.WorldServer; +import common.entity.item.EntityNuke; +import common.init.Blocks; +import common.init.SoundEvent; +import common.item.CheatTab; +import common.material.Material; +import common.model.Model; +import common.model.ModelProvider; +import common.world.BlockPos; +import common.world.Explosion; +import common.world.State; +import common.world.World; +import common.world.WorldServer; public class BlockNuke extends Block { diff --git a/java/src/game/block/BlockObsidian.java b/java/src/common/block/BlockObsidian.java similarity index 72% rename from java/src/game/block/BlockObsidian.java rename to java/src/common/block/BlockObsidian.java index 86aab37..b2c80f9 100755 --- a/java/src/game/block/BlockObsidian.java +++ b/java/src/common/block/BlockObsidian.java @@ -1,12 +1,12 @@ -package game.block; +package common.block; -import game.init.Blocks; -import game.init.ItemRegistry; -import game.item.CheatTab; -import game.item.Item; -import game.material.Material; -import game.rng.Random; -import game.world.State; +import common.init.Blocks; +import common.init.ItemRegistry; +import common.item.CheatTab; +import common.item.Item; +import common.material.Material; +import common.rng.Random; +import common.world.State; public class BlockObsidian extends Block { diff --git a/java/src/game/block/BlockOre.java b/java/src/common/block/BlockOre.java similarity index 93% rename from java/src/game/block/BlockOre.java rename to java/src/common/block/BlockOre.java index ebec758..008fdf9 100755 --- a/java/src/game/block/BlockOre.java +++ b/java/src/common/block/BlockOre.java @@ -1,15 +1,15 @@ -package game.block; +package common.block; -import game.init.Config; -import game.init.ItemRegistry; -import game.item.CheatTab; -import game.item.Item; -import game.item.ItemStack; -import game.material.Material; -import game.rng.Random; -import game.world.BlockPos; -import game.world.State; -import game.world.World; +import common.init.Config; +import common.init.ItemRegistry; +import common.item.CheatTab; +import common.item.Item; +import common.item.ItemStack; +import common.material.Material; +import common.rng.Random; +import common.world.BlockPos; +import common.world.State; +import common.world.World; public class BlockOre extends Block { diff --git a/java/src/game/block/BlockPackedIce.java b/java/src/common/block/BlockPackedIce.java similarity index 76% rename from java/src/game/block/BlockPackedIce.java rename to java/src/common/block/BlockPackedIce.java index ca2270c..c21ff05 100755 --- a/java/src/game/block/BlockPackedIce.java +++ b/java/src/common/block/BlockPackedIce.java @@ -1,8 +1,8 @@ -package game.block; +package common.block; -import game.item.CheatTab; -import game.material.Material; -import game.rng.Random; +import common.item.CheatTab; +import common.material.Material; +import common.rng.Random; public class BlockPackedIce extends Block { diff --git a/java/src/game/block/BlockPane.java b/java/src/common/block/BlockPane.java similarity index 96% rename from java/src/game/block/BlockPane.java rename to java/src/common/block/BlockPane.java index 7b01c70..66db2be 100755 --- a/java/src/game/block/BlockPane.java +++ b/java/src/common/block/BlockPane.java @@ -1,25 +1,25 @@ -package game.block; +package common.block; import java.util.List; -import game.entity.Entity; -import game.init.Blocks; -import game.item.CheatTab; -import game.item.Item; -import game.material.Material; -import game.model.BlockLayer; -import game.model.Model; -import game.model.ModelProvider; -import game.model.ModelRotation; -import game.properties.IProperty; -import game.properties.PropertyBool; -import game.rng.Random; -import game.world.BlockPos; -import game.world.BoundingBox; -import game.world.Facing; -import game.world.IWorldAccess; -import game.world.State; -import game.world.World; +import common.entity.Entity; +import common.init.Blocks; +import common.item.CheatTab; +import common.item.Item; +import common.material.Material; +import common.model.BlockLayer; +import common.model.Model; +import common.model.ModelProvider; +import common.model.ModelRotation; +import common.properties.IProperty; +import common.properties.PropertyBool; +import common.rng.Random; +import common.world.BlockPos; +import common.world.BoundingBox; +import common.world.Facing; +import common.world.IWorldAccess; +import common.world.State; +import common.world.World; public class BlockPane extends Block { diff --git a/java/src/game/block/BlockPistonBase.java b/java/src/common/block/BlockPistonBase.java similarity index 96% rename from java/src/game/block/BlockPistonBase.java rename to java/src/common/block/BlockPistonBase.java index 03a2622..3304a32 100755 --- a/java/src/game/block/BlockPistonBase.java +++ b/java/src/common/block/BlockPistonBase.java @@ -1,32 +1,32 @@ -package game.block; +package common.block; import java.util.List; -import game.collect.Lists; -import game.entity.Entity; -import game.entity.types.EntityLiving; -import game.init.Blocks; -import game.init.Config; -import game.init.SoundEvent; -import game.item.CheatTab; -import game.item.ItemStack; -import game.material.Material; -import game.model.Model; -import game.model.ModelProvider; -import game.model.ModelRotation; -import game.properties.IProperty; -import game.properties.PropertyBool; -import game.properties.PropertyDirection; -import game.tileentity.TileEntity; -import game.tileentity.TileEntityPiston; -import game.util.ExtMath; -import game.world.BlockPos; -import game.world.BoundingBox; -import game.world.Facing; -import game.world.IWorldAccess; -import game.world.State; -import game.world.World; -import game.world.WorldServer; +import common.collect.Lists; +import common.entity.Entity; +import common.entity.types.EntityLiving; +import common.init.Blocks; +import common.init.Config; +import common.init.SoundEvent; +import common.item.CheatTab; +import common.item.ItemStack; +import common.material.Material; +import common.model.Model; +import common.model.ModelProvider; +import common.model.ModelRotation; +import common.properties.IProperty; +import common.properties.PropertyBool; +import common.properties.PropertyDirection; +import common.tileentity.TileEntity; +import common.tileentity.TileEntityPiston; +import common.util.ExtMath; +import common.world.BlockPos; +import common.world.BoundingBox; +import common.world.Facing; +import common.world.IWorldAccess; +import common.world.State; +import common.world.World; +import common.world.WorldServer; public class BlockPistonBase extends Block { diff --git a/java/src/game/block/BlockPistonHead.java b/java/src/common/block/BlockPistonHead.java similarity index 93% rename from java/src/game/block/BlockPistonHead.java rename to java/src/common/block/BlockPistonHead.java index 911638d..3c8870b 100755 --- a/java/src/game/block/BlockPistonHead.java +++ b/java/src/common/block/BlockPistonHead.java @@ -1,28 +1,28 @@ -package game.block; +package common.block; import java.util.List; -import game.entity.Entity; -import game.init.Blocks; -import game.init.ItemRegistry; -import game.item.Item; -import game.material.Material; -import game.model.Model; -import game.model.ModelProvider; -import game.model.ModelRotation; -import game.properties.IProperty; -import game.properties.PropertyBool; -import game.properties.PropertyDirection; -import game.properties.PropertyEnum; -import game.rng.Random; -import game.util.Identifyable; -import game.world.BlockPos; -import game.world.BoundingBox; -import game.world.Facing; -import game.world.IWorldAccess; -import game.world.State; -import game.world.World; -import game.world.WorldServer; +import common.entity.Entity; +import common.init.Blocks; +import common.init.ItemRegistry; +import common.item.Item; +import common.material.Material; +import common.model.Model; +import common.model.ModelProvider; +import common.model.ModelRotation; +import common.properties.IProperty; +import common.properties.PropertyBool; +import common.properties.PropertyDirection; +import common.properties.PropertyEnum; +import common.rng.Random; +import common.util.Identifyable; +import common.world.BlockPos; +import common.world.BoundingBox; +import common.world.Facing; +import common.world.IWorldAccess; +import common.world.State; +import common.world.World; +import common.world.WorldServer; public class BlockPistonHead extends Block { diff --git a/java/src/game/block/BlockPistonMoving.java b/java/src/common/block/BlockPistonMoving.java similarity index 93% rename from java/src/game/block/BlockPistonMoving.java rename to java/src/common/block/BlockPistonMoving.java index 89fea3b..bf0792a 100755 --- a/java/src/game/block/BlockPistonMoving.java +++ b/java/src/common/block/BlockPistonMoving.java @@ -1,24 +1,24 @@ -package game.block; +package common.block; -import game.entity.npc.EntityNPC; -import game.init.Blocks; -import game.item.Item; -import game.material.Material; -import game.properties.IProperty; -import game.properties.PropertyDirection; -import game.properties.PropertyEnum; -import game.rng.Random; -import game.tileentity.TileEntity; -import game.tileentity.TileEntityPiston; -import game.world.BlockPos; -import game.world.BoundingBox; -import game.world.Facing; -import game.world.HitPosition; -import game.world.IWorldAccess; -import game.world.State; -import game.world.Vec3; -import game.world.World; -import game.world.WorldServer; +import common.entity.npc.EntityNPC; +import common.init.Blocks; +import common.item.Item; +import common.material.Material; +import common.properties.IProperty; +import common.properties.PropertyDirection; +import common.properties.PropertyEnum; +import common.rng.Random; +import common.tileentity.TileEntity; +import common.tileentity.TileEntityPiston; +import common.world.BlockPos; +import common.world.BoundingBox; +import common.world.Facing; +import common.world.HitPosition; +import common.world.IWorldAccess; +import common.world.State; +import common.world.Vec3; +import common.world.World; +import common.world.WorldServer; public class BlockPistonMoving extends BlockContainer { diff --git a/java/src/game/block/BlockPortal.java b/java/src/common/block/BlockPortal.java similarity index 96% rename from java/src/game/block/BlockPortal.java rename to java/src/common/block/BlockPortal.java index 33cd0ab..679cdfc 100755 --- a/java/src/game/block/BlockPortal.java +++ b/java/src/common/block/BlockPortal.java @@ -1,27 +1,27 @@ -package game.block; +package common.block; import java.util.Map; -import game.entity.Entity; -import game.init.Blocks; -import game.item.Item; -import game.material.Material; -import game.model.BlockLayer; -import game.model.Model; -import game.model.ModelProvider; -import game.model.ParticleType; -import game.properties.IProperty; -import game.properties.PropertyEnum; -import game.properties.PropertyInteger; -import game.rng.Random; -import game.world.BlockPos; -import game.world.BoundingBox; -import game.world.Facing; -import game.world.Facing.Axis; -import game.world.IWorldAccess; -import game.world.State; -import game.world.World; -import game.world.WorldClient; +import common.entity.Entity; +import common.init.Blocks; +import common.item.Item; +import common.material.Material; +import common.model.BlockLayer; +import common.model.Model; +import common.model.ModelProvider; +import common.model.ParticleType; +import common.properties.IProperty; +import common.properties.PropertyEnum; +import common.properties.PropertyInteger; +import common.rng.Random; +import common.world.BlockPos; +import common.world.BoundingBox; +import common.world.Facing; +import common.world.IWorldAccess; +import common.world.State; +import common.world.World; +import common.world.WorldClient; +import common.world.Facing.Axis; public class BlockPortal extends BlockBreakable { diff --git a/java/src/game/block/BlockPortalFrame.java b/java/src/common/block/BlockPortalFrame.java similarity index 87% rename from java/src/game/block/BlockPortalFrame.java rename to java/src/common/block/BlockPortalFrame.java index aefda08..c3dbab6 100755 --- a/java/src/game/block/BlockPortalFrame.java +++ b/java/src/common/block/BlockPortalFrame.java @@ -1,29 +1,29 @@ -package game.block; +package common.block; import java.util.List; -import game.entity.Entity; -import game.entity.npc.EntityNPC; -import game.entity.types.EntityLiving; -import game.init.Blocks; -import game.init.ItemRegistry; -import game.init.Items; -import game.item.Item; -import game.item.ItemStack; -import game.material.Material; -import game.model.Model; -import game.model.ModelProvider; -import game.model.ModelRotation; -import game.properties.IProperty; -import game.properties.PropertyBool; -import game.properties.PropertyDirection; -import game.rng.Random; -import game.tileentity.TileEntity; -import game.world.BlockPos; -import game.world.BoundingBox; -import game.world.Facing; -import game.world.State; -import game.world.World; +import common.entity.Entity; +import common.entity.npc.EntityNPC; +import common.entity.types.EntityLiving; +import common.init.Blocks; +import common.init.ItemRegistry; +import common.init.Items; +import common.item.Item; +import common.item.ItemStack; +import common.material.Material; +import common.model.Model; +import common.model.ModelProvider; +import common.model.ModelRotation; +import common.properties.IProperty; +import common.properties.PropertyBool; +import common.properties.PropertyDirection; +import common.rng.Random; +import common.tileentity.TileEntity; +import common.world.BlockPos; +import common.world.BoundingBox; +import common.world.Facing; +import common.world.State; +import common.world.World; public class BlockPortalFrame extends Block { diff --git a/java/src/game/block/BlockPotato.java b/java/src/common/block/BlockPotato.java similarity index 78% rename from java/src/game/block/BlockPotato.java rename to java/src/common/block/BlockPotato.java index 68d5c30..d1b2e33 100755 --- a/java/src/game/block/BlockPotato.java +++ b/java/src/common/block/BlockPotato.java @@ -1,13 +1,13 @@ -package game.block; +package common.block; -import game.init.Items; -import game.item.Item; -import game.item.ItemStack; -import game.model.Model; -import game.model.ModelProvider; -import game.world.BlockPos; -import game.world.State; -import game.world.World; +import common.init.Items; +import common.item.Item; +import common.item.ItemStack; +import common.model.Model; +import common.model.ModelProvider; +import common.world.BlockPos; +import common.world.State; +import common.world.World; public class BlockPotato extends BlockCrops { diff --git a/java/src/game/block/BlockPressurePlate.java b/java/src/common/block/BlockPressurePlate.java similarity index 88% rename from java/src/game/block/BlockPressurePlate.java rename to java/src/common/block/BlockPressurePlate.java index 64bafb7..cd29000 100755 --- a/java/src/game/block/BlockPressurePlate.java +++ b/java/src/common/block/BlockPressurePlate.java @@ -1,16 +1,16 @@ -package game.block; +package common.block; import java.util.List; -import game.entity.Entity; -import game.entity.types.EntityLiving; -import game.material.Material; -import game.properties.IProperty; -import game.properties.PropertyBool; -import game.world.BlockPos; -import game.world.BoundingBox; -import game.world.State; -import game.world.World; +import common.entity.Entity; +import common.entity.types.EntityLiving; +import common.material.Material; +import common.properties.IProperty; +import common.properties.PropertyBool; +import common.world.BlockPos; +import common.world.BoundingBox; +import common.world.State; +import common.world.World; public class BlockPressurePlate extends BlockBasePressurePlate { diff --git a/java/src/game/block/BlockPressurePlateWeighted.java b/java/src/common/block/BlockPressurePlateWeighted.java similarity index 88% rename from java/src/game/block/BlockPressurePlateWeighted.java rename to java/src/common/block/BlockPressurePlateWeighted.java index ddce333..2468a10 100755 --- a/java/src/game/block/BlockPressurePlateWeighted.java +++ b/java/src/common/block/BlockPressurePlateWeighted.java @@ -1,13 +1,13 @@ -package game.block; +package common.block; -import game.entity.Entity; -import game.material.Material; -import game.properties.IProperty; -import game.properties.PropertyInteger; -import game.util.ExtMath; -import game.world.BlockPos; -import game.world.State; -import game.world.World; +import common.entity.Entity; +import common.material.Material; +import common.properties.IProperty; +import common.properties.PropertyInteger; +import common.util.ExtMath; +import common.world.BlockPos; +import common.world.State; +import common.world.World; public class BlockPressurePlateWeighted extends BlockBasePressurePlate { diff --git a/java/src/game/block/BlockPumpkin.java b/java/src/common/block/BlockPumpkin.java similarity index 95% rename from java/src/game/block/BlockPumpkin.java rename to java/src/common/block/BlockPumpkin.java index e3a6fa8..8cc3b9d 100755 --- a/java/src/game/block/BlockPumpkin.java +++ b/java/src/common/block/BlockPumpkin.java @@ -1,16 +1,16 @@ -package game.block; +package common.block; -import game.entity.types.EntityLiving; -import game.item.CheatTab; -import game.material.Material; -import game.model.Model; -import game.model.ModelProvider; -import game.model.ModelRotation; -import game.properties.IProperty; -import game.world.BlockPos; -import game.world.Facing; -import game.world.State; -import game.world.World; +import common.entity.types.EntityLiving; +import common.item.CheatTab; +import common.material.Material; +import common.model.Model; +import common.model.ModelProvider; +import common.model.ModelRotation; +import common.properties.IProperty; +import common.world.BlockPos; +import common.world.Facing; +import common.world.State; +import common.world.World; public class BlockPumpkin extends BlockDirectional { diff --git a/java/src/game/block/BlockQuartz.java b/java/src/common/block/BlockQuartz.java similarity index 92% rename from java/src/game/block/BlockQuartz.java rename to java/src/common/block/BlockQuartz.java index dafd6c6..a6cccc3 100755 --- a/java/src/game/block/BlockQuartz.java +++ b/java/src/common/block/BlockQuartz.java @@ -1,23 +1,23 @@ -package game.block; +package common.block; import java.util.List; -import game.entity.types.EntityLiving; -import game.init.ItemRegistry; -import game.item.CheatTab; -import game.item.Item; -import game.item.ItemStack; -import game.material.Material; -import game.model.Model; -import game.model.ModelProvider; -import game.model.ModelRotation; -import game.properties.IProperty; -import game.properties.PropertyEnum; -import game.util.Identifyable; -import game.world.BlockPos; -import game.world.Facing; -import game.world.State; -import game.world.World; +import common.entity.types.EntityLiving; +import common.init.ItemRegistry; +import common.item.CheatTab; +import common.item.Item; +import common.item.ItemStack; +import common.material.Material; +import common.model.Model; +import common.model.ModelProvider; +import common.model.ModelRotation; +import common.properties.IProperty; +import common.properties.PropertyEnum; +import common.util.Identifyable; +import common.world.BlockPos; +import common.world.Facing; +import common.world.State; +import common.world.World; public class BlockQuartz extends Block { diff --git a/java/src/game/block/BlockRail.java b/java/src/common/block/BlockRail.java similarity index 88% rename from java/src/game/block/BlockRail.java rename to java/src/common/block/BlockRail.java index 92bab17..6b50f52 100755 --- a/java/src/game/block/BlockRail.java +++ b/java/src/common/block/BlockRail.java @@ -1,10 +1,10 @@ -package game.block; +package common.block; -import game.properties.IProperty; -import game.properties.PropertyEnum; -import game.world.BlockPos; -import game.world.State; -import game.world.World; +import common.properties.IProperty; +import common.properties.PropertyEnum; +import common.world.BlockPos; +import common.world.State; +import common.world.World; public class BlockRail extends BlockRailBase { diff --git a/java/src/game/block/BlockRailBase.java b/java/src/common/block/BlockRailBase.java similarity index 97% rename from java/src/game/block/BlockRailBase.java rename to java/src/common/block/BlockRailBase.java index a64c897..ec47041 100755 --- a/java/src/game/block/BlockRailBase.java +++ b/java/src/common/block/BlockRailBase.java @@ -1,26 +1,26 @@ -package game.block; +package common.block; import java.util.List; -import game.collect.Lists; -import game.init.Blocks; -import game.item.CheatTab; -import game.material.Material; -import game.model.BlockLayer; -import game.model.Model; -import game.model.ModelProvider; -import game.model.ModelRotation; -import game.properties.IProperty; -import game.util.Identifyable; -import game.world.BlockPos; -import game.world.BoundingBox; -import game.world.Facing; -import game.world.HitPosition; -import game.world.IWorldAccess; -import game.world.State; -import game.world.Vec3; -import game.world.World; -import game.world.WorldServer; +import common.collect.Lists; +import common.init.Blocks; +import common.item.CheatTab; +import common.material.Material; +import common.model.BlockLayer; +import common.model.Model; +import common.model.ModelProvider; +import common.model.ModelRotation; +import common.properties.IProperty; +import common.util.Identifyable; +import common.world.BlockPos; +import common.world.BoundingBox; +import common.world.Facing; +import common.world.HitPosition; +import common.world.IWorldAccess; +import common.world.State; +import common.world.Vec3; +import common.world.World; +import common.world.WorldServer; public abstract class BlockRailBase extends Block { diff --git a/java/src/game/block/BlockRailDetector.java b/java/src/common/block/BlockRailDetector.java similarity index 92% rename from java/src/game/block/BlockRailDetector.java rename to java/src/common/block/BlockRailDetector.java index 7070c82..28e977c 100755 --- a/java/src/game/block/BlockRailDetector.java +++ b/java/src/common/block/BlockRailDetector.java @@ -1,25 +1,25 @@ -package game.block; +package common.block; import java.util.List; import java.util.function.Predicate; -import game.entity.Entity; -import game.entity.item.EntityCart; -import game.inventory.Container; -import game.inventory.IInventory; -import game.model.Model; -import game.model.ModelProvider; -import game.properties.IProperty; -import game.properties.PropertyBool; -import game.properties.PropertyEnum; -import game.rng.Random; -import game.world.BlockPos; -import game.world.BoundingBox; -import game.world.Facing; -import game.world.IWorldAccess; -import game.world.State; -import game.world.World; -import game.world.WorldServer; +import common.entity.Entity; +import common.entity.item.EntityCart; +import common.inventory.Container; +import common.inventory.IInventory; +import common.model.Model; +import common.model.ModelProvider; +import common.properties.IProperty; +import common.properties.PropertyBool; +import common.properties.PropertyEnum; +import common.rng.Random; +import common.world.BlockPos; +import common.world.BoundingBox; +import common.world.Facing; +import common.world.IWorldAccess; +import common.world.State; +import common.world.World; +import common.world.WorldServer; public class BlockRailDetector extends BlockRailBase { diff --git a/java/src/game/block/BlockRailPowered.java b/java/src/common/block/BlockRailPowered.java similarity index 96% rename from java/src/game/block/BlockRailPowered.java rename to java/src/common/block/BlockRailPowered.java index f7b6181..65e978a 100755 --- a/java/src/game/block/BlockRailPowered.java +++ b/java/src/common/block/BlockRailPowered.java @@ -1,15 +1,15 @@ -package game.block; +package common.block; import java.util.function.Predicate; -import game.model.Model; -import game.model.ModelProvider; -import game.properties.IProperty; -import game.properties.PropertyBool; -import game.properties.PropertyEnum; -import game.world.BlockPos; -import game.world.State; -import game.world.World; +import common.model.Model; +import common.model.ModelProvider; +import common.properties.IProperty; +import common.properties.PropertyBool; +import common.properties.PropertyEnum; +import common.world.BlockPos; +import common.world.State; +import common.world.World; public class BlockRailPowered extends BlockRailBase { diff --git a/java/src/game/block/BlockRedstoneComparator.java b/java/src/common/block/BlockRedstoneComparator.java similarity index 95% rename from java/src/game/block/BlockRedstoneComparator.java rename to java/src/common/block/BlockRedstoneComparator.java index 5d61b94..b6f3859 100755 --- a/java/src/game/block/BlockRedstoneComparator.java +++ b/java/src/common/block/BlockRedstoneComparator.java @@ -1,27 +1,27 @@ -package game.block; +package common.block; -import game.entity.npc.EntityNPC; -import game.entity.types.EntityLiving; -import game.init.Blocks; -import game.init.Items; -import game.init.SoundEvent; -import game.item.Item; -import game.model.Model; -import game.model.ModelProvider; -import game.model.ModelRotation; -import game.properties.IProperty; -import game.properties.PropertyBool; -import game.properties.PropertyEnum; -import game.rng.Random; -import game.tileentity.TileEntity; -import game.tileentity.TileEntityComparator; -import game.util.Identifyable; -import game.world.BlockPos; -import game.world.Facing; -import game.world.IWorldAccess; -import game.world.State; -import game.world.World; -import game.world.WorldServer; +import common.entity.npc.EntityNPC; +import common.entity.types.EntityLiving; +import common.init.Blocks; +import common.init.Items; +import common.init.SoundEvent; +import common.item.Item; +import common.model.Model; +import common.model.ModelProvider; +import common.model.ModelRotation; +import common.properties.IProperty; +import common.properties.PropertyBool; +import common.properties.PropertyEnum; +import common.rng.Random; +import common.tileentity.TileEntity; +import common.tileentity.TileEntityComparator; +import common.util.Identifyable; +import common.world.BlockPos; +import common.world.Facing; +import common.world.IWorldAccess; +import common.world.State; +import common.world.World; +import common.world.WorldServer; public class BlockRedstoneComparator extends BlockRedstoneDiode implements ITileEntityProvider { diff --git a/java/src/game/block/BlockRedstoneDiode.java b/java/src/common/block/BlockRedstoneDiode.java similarity index 95% rename from java/src/game/block/BlockRedstoneDiode.java rename to java/src/common/block/BlockRedstoneDiode.java index a510f6e..e12d943 100755 --- a/java/src/game/block/BlockRedstoneDiode.java +++ b/java/src/common/block/BlockRedstoneDiode.java @@ -1,17 +1,17 @@ -package game.block; +package common.block; -import game.entity.types.EntityLiving; -import game.init.Blocks; -import game.item.ItemStack; -import game.material.Material; -import game.model.BlockLayer; -import game.rng.Random; -import game.world.BlockPos; -import game.world.Facing; -import game.world.IWorldAccess; -import game.world.State; -import game.world.World; -import game.world.WorldServer; +import common.entity.types.EntityLiving; +import common.init.Blocks; +import common.item.ItemStack; +import common.material.Material; +import common.model.BlockLayer; +import common.rng.Random; +import common.world.BlockPos; +import common.world.Facing; +import common.world.IWorldAccess; +import common.world.State; +import common.world.World; +import common.world.WorldServer; public abstract class BlockRedstoneDiode extends BlockDirectional { diff --git a/java/src/game/block/BlockRedstoneLight.java b/java/src/common/block/BlockRedstoneLight.java similarity index 87% rename from java/src/game/block/BlockRedstoneLight.java rename to java/src/common/block/BlockRedstoneLight.java index b3fda33..49cb79b 100755 --- a/java/src/game/block/BlockRedstoneLight.java +++ b/java/src/common/block/BlockRedstoneLight.java @@ -1,15 +1,15 @@ -package game.block; +package common.block; -import game.init.Blocks; -import game.init.ItemRegistry; -import game.item.Item; -import game.item.ItemStack; -import game.material.Material; -import game.rng.Random; -import game.world.BlockPos; -import game.world.State; -import game.world.World; -import game.world.WorldServer; +import common.init.Blocks; +import common.init.ItemRegistry; +import common.item.Item; +import common.item.ItemStack; +import common.material.Material; +import common.rng.Random; +import common.world.BlockPos; +import common.world.State; +import common.world.World; +import common.world.WorldServer; public class BlockRedstoneLight extends Block { diff --git a/java/src/game/block/BlockRedstoneOre.java b/java/src/common/block/BlockRedstoneOre.java similarity index 90% rename from java/src/game/block/BlockRedstoneOre.java rename to java/src/common/block/BlockRedstoneOre.java index f5736f1..09aa47a 100755 --- a/java/src/game/block/BlockRedstoneOre.java +++ b/java/src/common/block/BlockRedstoneOre.java @@ -1,23 +1,23 @@ -package game.block; +package common.block; -import game.entity.Entity; -import game.entity.npc.EntityNPC; -import game.init.Blocks; -import game.init.ItemRegistry; -import game.init.Items; -import game.item.Item; -import game.item.ItemStack; -import game.material.Material; -import game.model.Model; -import game.model.ModelProvider; -import game.model.ParticleType; -import game.rng.Random; -import game.world.BlockPos; -import game.world.Facing; -import game.world.State; -import game.world.World; -import game.world.WorldClient; -import game.world.WorldServer; +import common.entity.Entity; +import common.entity.npc.EntityNPC; +import common.init.Blocks; +import common.init.ItemRegistry; +import common.init.Items; +import common.item.Item; +import common.item.ItemStack; +import common.material.Material; +import common.model.Model; +import common.model.ModelProvider; +import common.model.ParticleType; +import common.rng.Random; +import common.world.BlockPos; +import common.world.Facing; +import common.world.State; +import common.world.World; +import common.world.WorldClient; +import common.world.WorldServer; public class BlockRedstoneOre extends Block { diff --git a/java/src/game/block/BlockRedstoneRepeater.java b/java/src/common/block/BlockRedstoneRepeater.java similarity index 97% rename from java/src/game/block/BlockRedstoneRepeater.java rename to java/src/common/block/BlockRedstoneRepeater.java index a43adfd..30c64ec 100755 --- a/java/src/game/block/BlockRedstoneRepeater.java +++ b/java/src/common/block/BlockRedstoneRepeater.java @@ -1,24 +1,24 @@ -package game.block; +package common.block; -import game.entity.npc.EntityNPC; -import game.init.Blocks; -import game.init.Items; -import game.item.Item; -import game.model.Model; -import game.model.ModelProvider; -import game.model.ModelRotation; -import game.model.ParticleType; -import game.properties.IProperty; -import game.properties.PropertyBool; -import game.properties.PropertyInteger; -import game.rng.Random; -import game.world.BlockPos; -import game.world.Facing; -import game.world.IWorldAccess; -import game.world.State; -import game.world.World; -import game.world.WorldClient; -import game.world.WorldServer; +import common.entity.npc.EntityNPC; +import common.init.Blocks; +import common.init.Items; +import common.item.Item; +import common.model.Model; +import common.model.ModelProvider; +import common.model.ModelRotation; +import common.model.ParticleType; +import common.properties.IProperty; +import common.properties.PropertyBool; +import common.properties.PropertyInteger; +import common.rng.Random; +import common.world.BlockPos; +import common.world.Facing; +import common.world.IWorldAccess; +import common.world.State; +import common.world.World; +import common.world.WorldClient; +import common.world.WorldServer; public class BlockRedstoneRepeater extends BlockRedstoneDiode { diff --git a/java/src/game/block/BlockRedstoneTorch.java b/java/src/common/block/BlockRedstoneTorch.java similarity index 93% rename from java/src/game/block/BlockRedstoneTorch.java rename to java/src/common/block/BlockRedstoneTorch.java index 2590c67..04cbe22 100755 --- a/java/src/game/block/BlockRedstoneTorch.java +++ b/java/src/common/block/BlockRedstoneTorch.java @@ -1,24 +1,24 @@ -package game.block; +package common.block; import java.util.List; import java.util.Map; -import game.collect.Lists; -import game.collect.Maps; -import game.init.Blocks; -import game.init.ItemRegistry; -import game.init.SoundEvent; -import game.item.CheatTab; -import game.item.Item; -import game.model.ParticleType; -import game.rng.Random; -import game.world.BlockPos; -import game.world.Facing; -import game.world.IWorldAccess; -import game.world.State; -import game.world.World; -import game.world.WorldClient; -import game.world.WorldServer; +import common.collect.Lists; +import common.collect.Maps; +import common.init.Blocks; +import common.init.ItemRegistry; +import common.init.SoundEvent; +import common.item.CheatTab; +import common.item.Item; +import common.model.ParticleType; +import common.rng.Random; +import common.world.BlockPos; +import common.world.Facing; +import common.world.IWorldAccess; +import common.world.State; +import common.world.World; +import common.world.WorldClient; +import common.world.WorldServer; public class BlockRedstoneTorch extends BlockTorch { diff --git a/java/src/game/block/BlockRedstoneWire.java b/java/src/common/block/BlockRedstoneWire.java similarity index 97% rename from java/src/game/block/BlockRedstoneWire.java rename to java/src/common/block/BlockRedstoneWire.java index 3b119ab..b5aac93 100755 --- a/java/src/game/block/BlockRedstoneWire.java +++ b/java/src/common/block/BlockRedstoneWire.java @@ -1,35 +1,35 @@ -package game.block; +package common.block; import java.util.EnumSet; import java.util.List; import java.util.Set; -import game.collect.Lists; -import game.collect.Sets; -import game.init.Blocks; -import game.init.Items; -import game.item.Item; -import game.material.Material; -import game.model.BlockLayer; -import game.model.Model; -import game.model.ModelProvider; -import game.model.ModelRotation; -import game.model.ParticleType; -import game.properties.IProperty; -import game.properties.PropertyEnum; -import game.properties.PropertyInteger; -import game.rng.Random; -import game.util.ExtMath; -import game.util.Identifyable; -import game.world.BlockPos; -import game.world.BoundingBox; -import game.world.Facing; -import game.world.IBlockAccess; -import game.world.IWorldAccess; -import game.world.State; -import game.world.World; -import game.world.WorldClient; -import game.world.WorldServer; +import common.collect.Lists; +import common.collect.Sets; +import common.init.Blocks; +import common.init.Items; +import common.item.Item; +import common.material.Material; +import common.model.BlockLayer; +import common.model.Model; +import common.model.ModelProvider; +import common.model.ModelRotation; +import common.model.ParticleType; +import common.properties.IProperty; +import common.properties.PropertyEnum; +import common.properties.PropertyInteger; +import common.rng.Random; +import common.util.ExtMath; +import common.util.Identifyable; +import common.world.BlockPos; +import common.world.BoundingBox; +import common.world.Facing; +import common.world.IBlockAccess; +import common.world.IWorldAccess; +import common.world.State; +import common.world.World; +import common.world.WorldClient; +import common.world.WorldServer; public class BlockRedstoneWire extends Block { diff --git a/java/src/game/block/BlockReed.java b/java/src/common/block/BlockReed.java similarity index 89% rename from java/src/game/block/BlockReed.java rename to java/src/common/block/BlockReed.java index a60106d..816e6e7 100755 --- a/java/src/game/block/BlockReed.java +++ b/java/src/common/block/BlockReed.java @@ -1,23 +1,23 @@ -package game.block; +package common.block; -import game.init.Blocks; -import game.init.Config; -import game.init.Items; -import game.item.Item; -import game.material.Material; -import game.model.BlockLayer; -import game.model.Model; -import game.model.ModelProvider; -import game.properties.IProperty; -import game.properties.PropertyInteger; -import game.rng.Random; -import game.world.BlockPos; -import game.world.BoundingBox; -import game.world.Facing; -import game.world.IWorldAccess; -import game.world.State; -import game.world.World; -import game.world.WorldServer; +import common.init.Blocks; +import common.init.Config; +import common.init.Items; +import common.item.Item; +import common.material.Material; +import common.model.BlockLayer; +import common.model.Model; +import common.model.ModelProvider; +import common.properties.IProperty; +import common.properties.PropertyInteger; +import common.rng.Random; +import common.world.BlockPos; +import common.world.BoundingBox; +import common.world.Facing; +import common.world.IWorldAccess; +import common.world.State; +import common.world.World; +import common.world.WorldServer; public class BlockReed extends Block { diff --git a/java/src/game/block/BlockRock.java b/java/src/common/block/BlockRock.java similarity index 76% rename from java/src/game/block/BlockRock.java rename to java/src/common/block/BlockRock.java index 607027f..a6f0e4d 100755 --- a/java/src/game/block/BlockRock.java +++ b/java/src/common/block/BlockRock.java @@ -1,16 +1,16 @@ -package game.block; +package common.block; import java.util.List; -import game.item.CheatTab; -import game.item.Item; -import game.item.ItemStack; -import game.material.Material; -import game.model.Model; -import game.model.ModelProvider; -import game.properties.IProperty; -import game.properties.PropertyBool; -import game.world.State; +import common.item.CheatTab; +import common.item.Item; +import common.item.ItemStack; +import common.material.Material; +import common.model.Model; +import common.model.ModelProvider; +import common.properties.IProperty; +import common.properties.PropertyBool; +import common.world.State; public class BlockRock extends Block { public static final PropertyBool SMOOTH = PropertyBool.create("smooth"); diff --git a/java/src/game/block/BlockRotatedPillar.java b/java/src/common/block/BlockRotatedPillar.java similarity index 78% rename from java/src/game/block/BlockRotatedPillar.java rename to java/src/common/block/BlockRotatedPillar.java index 1bcc08f..a4b59a3 100755 --- a/java/src/game/block/BlockRotatedPillar.java +++ b/java/src/common/block/BlockRotatedPillar.java @@ -1,12 +1,12 @@ -package game.block; +package common.block; -import game.material.Material; -import game.model.Model; -import game.model.ModelProvider; -import game.model.ModelRotation; -import game.properties.PropertyEnum; -import game.world.Facing; -import game.world.State; +import common.material.Material; +import common.model.Model; +import common.model.ModelProvider; +import common.model.ModelRotation; +import common.properties.PropertyEnum; +import common.world.Facing; +import common.world.State; public abstract class BlockRotatedPillar extends Block { diff --git a/java/src/game/block/BlockSand.java b/java/src/common/block/BlockSand.java similarity index 91% rename from java/src/game/block/BlockSand.java rename to java/src/common/block/BlockSand.java index 37e93c6..147941b 100755 --- a/java/src/game/block/BlockSand.java +++ b/java/src/common/block/BlockSand.java @@ -1,16 +1,16 @@ -package game.block; +package common.block; import java.util.List; -import game.item.CheatTab; -import game.item.Item; -import game.item.ItemStack; -import game.model.Model; -import game.model.ModelProvider; -import game.properties.IProperty; -import game.properties.PropertyEnum; -import game.util.Identifyable; -import game.world.State; +import common.item.CheatTab; +import common.item.Item; +import common.item.ItemStack; +import common.model.Model; +import common.model.ModelProvider; +import common.properties.IProperty; +import common.properties.PropertyEnum; +import common.util.Identifyable; +import common.world.State; public class BlockSand extends BlockFalling { diff --git a/java/src/game/block/BlockSandStone.java b/java/src/common/block/BlockSandStone.java similarity index 92% rename from java/src/game/block/BlockSandStone.java rename to java/src/common/block/BlockSandStone.java index b92213c..3ed7fcc 100755 --- a/java/src/game/block/BlockSandStone.java +++ b/java/src/common/block/BlockSandStone.java @@ -1,17 +1,17 @@ -package game.block; +package common.block; import java.util.List; -import game.item.CheatTab; -import game.item.Item; -import game.item.ItemStack; -import game.material.Material; -import game.model.Model; -import game.model.ModelProvider; -import game.properties.IProperty; -import game.properties.PropertyEnum; -import game.util.Identifyable; -import game.world.State; +import common.item.CheatTab; +import common.item.Item; +import common.item.ItemStack; +import common.material.Material; +import common.model.Model; +import common.model.ModelProvider; +import common.properties.IProperty; +import common.properties.PropertyEnum; +import common.util.Identifyable; +import common.world.State; public class BlockSandStone extends Block { diff --git a/java/src/game/block/BlockSapling.java b/java/src/common/block/BlockSapling.java similarity index 92% rename from java/src/game/block/BlockSapling.java rename to java/src/common/block/BlockSapling.java index 5f2eddf..5615ffc 100755 --- a/java/src/game/block/BlockSapling.java +++ b/java/src/common/block/BlockSapling.java @@ -1,30 +1,30 @@ -package game.block; +package common.block; import java.util.List; -import game.collect.Lists; -import game.init.Blocks; -import game.init.Config; -import game.init.WoodType; -import game.item.CheatTab; -import game.model.Model; -import game.model.ModelProvider; -import game.properties.IProperty; -import game.properties.PropertyInteger; -import game.rng.Random; -import game.world.BlockPos; -import game.world.State; -import game.world.World; -import game.world.WorldServer; -import game.worldgen.FeatureGenerator; -import game.worldgen.tree.WorldGenBaseTree; -import game.worldgen.tree.WorldGenBigTree; -import game.worldgen.tree.WorldGenBirch; -import game.worldgen.tree.WorldGenDarkOak; -import game.worldgen.tree.WorldGenJungle; -import game.worldgen.tree.WorldGenPine; -import game.worldgen.tree.WorldGenSavanna; -import game.worldgen.tree.WorldGenTaiga2; +import common.collect.Lists; +import common.init.Blocks; +import common.init.Config; +import common.init.WoodType; +import common.item.CheatTab; +import common.model.Model; +import common.model.ModelProvider; +import common.properties.IProperty; +import common.properties.PropertyInteger; +import common.rng.Random; +import common.world.BlockPos; +import common.world.State; +import common.world.World; +import common.world.WorldServer; +import common.worldgen.FeatureGenerator; +import common.worldgen.tree.WorldGenBaseTree; +import common.worldgen.tree.WorldGenBigTree; +import common.worldgen.tree.WorldGenBirch; +import common.worldgen.tree.WorldGenDarkOak; +import common.worldgen.tree.WorldGenJungle; +import common.worldgen.tree.WorldGenPine; +import common.worldgen.tree.WorldGenSavanna; +import common.worldgen.tree.WorldGenTaiga2; public class BlockSapling extends BlockBush implements IGrowable { diff --git a/java/src/game/block/BlockSign.java b/java/src/common/block/BlockSign.java similarity index 88% rename from java/src/game/block/BlockSign.java rename to java/src/common/block/BlockSign.java index 28730a3..a42b21d 100755 --- a/java/src/game/block/BlockSign.java +++ b/java/src/common/block/BlockSign.java @@ -1,16 +1,16 @@ -package game.block; +package common.block; -import game.init.Items; -import game.item.Item; -import game.material.Material; -import game.rng.Random; -import game.tileentity.TileEntity; -import game.tileentity.TileEntitySign; -import game.world.BlockPos; -import game.world.BoundingBox; -import game.world.IBlockAccess; -import game.world.State; -import game.world.World; +import common.init.Items; +import common.item.Item; +import common.material.Material; +import common.rng.Random; +import common.tileentity.TileEntity; +import common.tileentity.TileEntitySign; +import common.world.BlockPos; +import common.world.BoundingBox; +import common.world.IBlockAccess; +import common.world.State; +import common.world.World; public class BlockSign extends BlockContainer { diff --git a/java/src/game/block/BlockSkull.java b/java/src/common/block/BlockSkull.java similarity index 86% rename from java/src/game/block/BlockSkull.java rename to java/src/common/block/BlockSkull.java index b3575c6..3730ffe 100755 --- a/java/src/game/block/BlockSkull.java +++ b/java/src/common/block/BlockSkull.java @@ -1,23 +1,23 @@ -package game.block; +package common.block; -import game.entity.types.EntityLiving; -import game.init.Items; -import game.item.Item; -import game.item.ItemStack; -import game.material.Material; -import game.model.Transforms; -import game.properties.IProperty; -import game.properties.PropertyDirection; -import game.rng.Random; -import game.tileentity.TileEntity; -import game.tileentity.TileEntitySkull; -import game.world.BlockPos; -import game.world.BoundingBox; -import game.world.Facing; -import game.world.IWorldAccess; -import game.world.State; -import game.world.World; -import game.world.WorldServer; +import common.entity.types.EntityLiving; +import common.init.Items; +import common.item.Item; +import common.item.ItemStack; +import common.material.Material; +import common.model.Transforms; +import common.properties.IProperty; +import common.properties.PropertyDirection; +import common.rng.Random; +import common.tileentity.TileEntity; +import common.tileentity.TileEntitySkull; +import common.world.BlockPos; +import common.world.BoundingBox; +import common.world.Facing; +import common.world.IWorldAccess; +import common.world.State; +import common.world.World; +import common.world.WorldServer; public class BlockSkull extends BlockContainer { diff --git a/java/src/game/block/BlockSlab.java b/java/src/common/block/BlockSlab.java similarity index 95% rename from java/src/game/block/BlockSlab.java rename to java/src/common/block/BlockSlab.java index 222d216..6ad12a3 100755 --- a/java/src/game/block/BlockSlab.java +++ b/java/src/common/block/BlockSlab.java @@ -1,26 +1,26 @@ -package game.block; +package common.block; import java.util.List; -import game.collect.Lists; -import game.entity.Entity; -import game.entity.types.EntityLiving; -import game.item.CheatTab; -import game.item.Item; -import game.item.ItemStack; -import game.material.Material; -import game.model.Model; -import game.model.ModelProvider; -import game.properties.IProperty; -import game.properties.PropertyBool; -import game.properties.PropertyDirection; -import game.world.BlockPos; -import game.world.BoundingBox; -import game.world.Facing; -import game.world.Facing.Axis; -import game.world.IWorldAccess; -import game.world.State; -import game.world.World; +import common.collect.Lists; +import common.entity.Entity; +import common.entity.types.EntityLiving; +import common.item.CheatTab; +import common.item.Item; +import common.item.ItemStack; +import common.material.Material; +import common.model.Model; +import common.model.ModelProvider; +import common.properties.IProperty; +import common.properties.PropertyBool; +import common.properties.PropertyDirection; +import common.world.BlockPos; +import common.world.BoundingBox; +import common.world.Facing; +import common.world.IWorldAccess; +import common.world.State; +import common.world.World; +import common.world.Facing.Axis; public class BlockSlab extends Block { diff --git a/java/src/game/block/BlockSlime.java b/java/src/common/block/BlockSlime.java similarity index 88% rename from java/src/game/block/BlockSlime.java rename to java/src/common/block/BlockSlime.java index 81f0625..4d4a1f7 100755 --- a/java/src/game/block/BlockSlime.java +++ b/java/src/common/block/BlockSlime.java @@ -1,14 +1,14 @@ -package game.block; +package common.block; -import game.entity.Entity; -import game.item.CheatTab; -import game.material.Material; -import game.model.BlockLayer; -import game.model.Model; -import game.model.ModelProvider; -import game.world.BlockPos; -import game.world.State; -import game.world.World; +import common.entity.Entity; +import common.item.CheatTab; +import common.material.Material; +import common.model.BlockLayer; +import common.model.Model; +import common.model.ModelProvider; +import common.world.BlockPos; +import common.world.State; +import common.world.World; public class BlockSlime extends BlockBreakable { diff --git a/java/src/game/block/BlockSnow.java b/java/src/common/block/BlockSnow.java similarity index 87% rename from java/src/game/block/BlockSnow.java rename to java/src/common/block/BlockSnow.java index f8b68fd..588918b 100755 --- a/java/src/game/block/BlockSnow.java +++ b/java/src/common/block/BlockSnow.java @@ -1,29 +1,29 @@ -package game.block; +package common.block; -import game.entity.npc.EntityNPC; -import game.init.Blocks; -import game.init.Config; -import game.init.Items; -import game.item.CheatTab; -import game.item.Item; -import game.item.ItemStack; -import game.material.Material; -import game.model.Model; -import game.model.ModelProvider; -import game.model.Transforms; -import game.properties.IProperty; -import game.properties.PropertyInteger; -import game.rng.Random; -import game.tileentity.TileEntity; -import game.world.BlockPos; -import game.world.BoundingBox; -import game.world.Facing; -import game.world.IBlockAccess; -import game.world.IWorldAccess; -import game.world.LightType; -import game.world.State; -import game.world.World; -import game.world.WorldServer; +import common.entity.npc.EntityNPC; +import common.init.Blocks; +import common.init.Config; +import common.init.Items; +import common.item.CheatTab; +import common.item.Item; +import common.item.ItemStack; +import common.material.Material; +import common.model.Model; +import common.model.ModelProvider; +import common.model.Transforms; +import common.properties.IProperty; +import common.properties.PropertyInteger; +import common.rng.Random; +import common.tileentity.TileEntity; +import common.world.BlockPos; +import common.world.BoundingBox; +import common.world.Facing; +import common.world.IBlockAccess; +import common.world.IWorldAccess; +import common.world.LightType; +import common.world.State; +import common.world.World; +import common.world.WorldServer; public class BlockSnow extends Block { diff --git a/java/src/game/block/BlockSnowBlock.java b/java/src/common/block/BlockSnowBlock.java similarity index 73% rename from java/src/game/block/BlockSnowBlock.java rename to java/src/common/block/BlockSnowBlock.java index 9eb13c3..5f8411f 100755 --- a/java/src/game/block/BlockSnowBlock.java +++ b/java/src/common/block/BlockSnowBlock.java @@ -1,15 +1,15 @@ -package game.block; +package common.block; -import game.init.Config; -import game.init.Items; -import game.item.CheatTab; -import game.item.Item; -import game.material.Material; -import game.rng.Random; -import game.world.BlockPos; -import game.world.LightType; -import game.world.State; -import game.world.WorldServer; +import common.init.Config; +import common.init.Items; +import common.item.CheatTab; +import common.item.Item; +import common.material.Material; +import common.rng.Random; +import common.world.BlockPos; +import common.world.LightType; +import common.world.State; +import common.world.WorldServer; public class BlockSnowBlock extends Block { diff --git a/java/src/game/block/BlockSoulSand.java b/java/src/common/block/BlockSoulSand.java similarity index 75% rename from java/src/game/block/BlockSoulSand.java rename to java/src/common/block/BlockSoulSand.java index 70641d0..5344f81 100755 --- a/java/src/game/block/BlockSoulSand.java +++ b/java/src/common/block/BlockSoulSand.java @@ -1,12 +1,12 @@ -package game.block; +package common.block; -import game.entity.Entity; -import game.item.CheatTab; -import game.material.Material; -import game.world.BlockPos; -import game.world.BoundingBox; -import game.world.State; -import game.world.World; +import common.entity.Entity; +import common.item.CheatTab; +import common.material.Material; +import common.world.BlockPos; +import common.world.BoundingBox; +import common.world.State; +import common.world.World; public class BlockSoulSand extends Block { diff --git a/java/src/game/block/BlockSourceImpl.java b/java/src/common/block/BlockSourceImpl.java similarity index 84% rename from java/src/game/block/BlockSourceImpl.java rename to java/src/common/block/BlockSourceImpl.java index 6243f42..63f297b 100755 --- a/java/src/game/block/BlockSourceImpl.java +++ b/java/src/common/block/BlockSourceImpl.java @@ -1,10 +1,10 @@ -package game.block; +package common.block; -import game.dispenser.IBlockSource; -import game.tileentity.TileEntity; -import game.world.BlockPos; -import game.world.State; -import game.world.World; +import common.dispenser.IBlockSource; +import common.tileentity.TileEntity; +import common.world.BlockPos; +import common.world.State; +import common.world.World; public class BlockSourceImpl implements IBlockSource { diff --git a/java/src/game/block/BlockStainedGlass.java b/java/src/common/block/BlockStainedGlass.java similarity index 87% rename from java/src/game/block/BlockStainedGlass.java rename to java/src/common/block/BlockStainedGlass.java index 8cd1807..47ae319 100755 --- a/java/src/game/block/BlockStainedGlass.java +++ b/java/src/common/block/BlockStainedGlass.java @@ -1,19 +1,19 @@ -package game.block; +package common.block; import java.util.List; -import game.color.DyeColor; -import game.item.CheatTab; -import game.item.Item; -import game.item.ItemStack; -import game.material.Material; -import game.model.BlockLayer; -import game.model.Model; -import game.model.ModelProvider; -import game.properties.IProperty; -import game.properties.PropertyEnum; -import game.rng.Random; -import game.world.State; +import common.color.DyeColor; +import common.item.CheatTab; +import common.item.Item; +import common.item.ItemStack; +import common.material.Material; +import common.model.BlockLayer; +import common.model.Model; +import common.model.ModelProvider; +import common.properties.IProperty; +import common.properties.PropertyEnum; +import common.rng.Random; +import common.world.State; public class BlockStainedGlass extends BlockBreakable { diff --git a/java/src/game/block/BlockStainedGlassPane.java b/java/src/common/block/BlockStainedGlassPane.java similarity index 90% rename from java/src/game/block/BlockStainedGlassPane.java rename to java/src/common/block/BlockStainedGlassPane.java index 405b2b1..eb50a9e 100755 --- a/java/src/game/block/BlockStainedGlassPane.java +++ b/java/src/common/block/BlockStainedGlassPane.java @@ -1,16 +1,16 @@ -package game.block; +package common.block; import java.util.List; -import game.color.DyeColor; -import game.item.CheatTab; -import game.item.Item; -import game.item.ItemStack; -import game.material.Material; -import game.model.BlockLayer; -import game.properties.IProperty; -import game.properties.PropertyEnum; -import game.world.State; +import common.color.DyeColor; +import common.item.CheatTab; +import common.item.Item; +import common.item.ItemStack; +import common.material.Material; +import common.model.BlockLayer; +import common.properties.IProperty; +import common.properties.PropertyEnum; +import common.world.State; public class BlockStainedGlassPane extends BlockPane { diff --git a/java/src/game/block/BlockStairs.java b/java/src/common/block/BlockStairs.java similarity index 96% rename from java/src/game/block/BlockStairs.java rename to java/src/common/block/BlockStairs.java index ed7fb59..437f98f 100755 --- a/java/src/game/block/BlockStairs.java +++ b/java/src/common/block/BlockStairs.java @@ -1,36 +1,36 @@ -package game.block; +package common.block; import java.util.Arrays; import java.util.List; -import game.entity.Entity; -import game.entity.npc.EntityNPC; -import game.entity.types.EntityLiving; -import game.init.BlockRegistry; -import game.init.Blocks; -import game.item.CheatTab; -import game.material.Material; -import game.model.BlockLayer; -import game.model.Model; -import game.model.ModelProvider; -import game.model.Transforms; -import game.properties.IProperty; -import game.properties.PropertyDirection; -import game.properties.PropertyEnum; -import game.rng.Random; -import game.util.Identifyable; -import game.world.BlockPos; -import game.world.BoundingBox; -import game.world.Explosion; -import game.world.Facing; -import game.world.HitPosition; -import game.world.IBlockAccess; -import game.world.IWorldAccess; -import game.world.State; -import game.world.Vec3; -import game.world.World; -import game.world.WorldClient; -import game.world.WorldServer; +import common.entity.Entity; +import common.entity.npc.EntityNPC; +import common.entity.types.EntityLiving; +import common.init.BlockRegistry; +import common.init.Blocks; +import common.item.CheatTab; +import common.material.Material; +import common.model.BlockLayer; +import common.model.Model; +import common.model.ModelProvider; +import common.model.Transforms; +import common.properties.IProperty; +import common.properties.PropertyDirection; +import common.properties.PropertyEnum; +import common.rng.Random; +import common.util.Identifyable; +import common.world.BlockPos; +import common.world.BoundingBox; +import common.world.Explosion; +import common.world.Facing; +import common.world.HitPosition; +import common.world.IBlockAccess; +import common.world.IWorldAccess; +import common.world.State; +import common.world.Vec3; +import common.world.World; +import common.world.WorldClient; +import common.world.WorldServer; public class BlockStairs extends Block { diff --git a/java/src/game/block/BlockStandingSign.java b/java/src/common/block/BlockStandingSign.java similarity index 87% rename from java/src/game/block/BlockStandingSign.java rename to java/src/common/block/BlockStandingSign.java index 0eaaf14..754535a 100755 --- a/java/src/game/block/BlockStandingSign.java +++ b/java/src/common/block/BlockStandingSign.java @@ -1,10 +1,10 @@ -package game.block; +package common.block; -import game.properties.IProperty; -import game.properties.PropertyInteger; -import game.world.BlockPos; -import game.world.State; -import game.world.World; +import common.properties.IProperty; +import common.properties.PropertyInteger; +import common.world.BlockPos; +import common.world.State; +import common.world.World; public class BlockStandingSign extends BlockSign { diff --git a/java/src/game/block/BlockStaticLiquid.java b/java/src/common/block/BlockStaticLiquid.java similarity index 91% rename from java/src/game/block/BlockStaticLiquid.java rename to java/src/common/block/BlockStaticLiquid.java index c34411c..88791ab 100755 --- a/java/src/game/block/BlockStaticLiquid.java +++ b/java/src/common/block/BlockStaticLiquid.java @@ -1,14 +1,14 @@ -package game.block; +package common.block; -import game.init.Blocks; -import game.init.Config; -import game.material.Material; -import game.rng.Random; -import game.world.BlockPos; -import game.world.Facing; -import game.world.State; -import game.world.World; -import game.world.WorldServer; +import common.init.Blocks; +import common.init.Config; +import common.material.Material; +import common.rng.Random; +import common.world.BlockPos; +import common.world.Facing; +import common.world.State; +import common.world.World; +import common.world.WorldServer; public class BlockStaticLiquid extends BlockLiquid { diff --git a/java/src/game/block/BlockStem.java b/java/src/common/block/BlockStem.java similarity index 94% rename from java/src/game/block/BlockStem.java rename to java/src/common/block/BlockStem.java index 5b715de..c6d37f8 100755 --- a/java/src/game/block/BlockStem.java +++ b/java/src/common/block/BlockStem.java @@ -1,27 +1,27 @@ -package game.block; +package common.block; import java.util.function.Predicate; -import game.init.Blocks; -import game.init.Config; -import game.init.Items; -import game.item.CheatTab; -import game.item.Item; -import game.item.ItemStack; -import game.material.Material; -import game.model.Model; -import game.model.ModelProvider; -import game.model.ModelRotation; -import game.properties.IProperty; -import game.properties.PropertyDirection; -import game.properties.PropertyInteger; -import game.rng.Random; -import game.world.BlockPos; -import game.world.Facing; -import game.world.IWorldAccess; -import game.world.State; -import game.world.World; -import game.world.WorldServer; +import common.init.Blocks; +import common.init.Config; +import common.init.Items; +import common.item.CheatTab; +import common.item.Item; +import common.item.ItemStack; +import common.material.Material; +import common.model.Model; +import common.model.ModelProvider; +import common.model.ModelRotation; +import common.properties.IProperty; +import common.properties.PropertyDirection; +import common.properties.PropertyInteger; +import common.rng.Random; +import common.world.BlockPos; +import common.world.Facing; +import common.world.IWorldAccess; +import common.world.State; +import common.world.World; +import common.world.WorldServer; public class BlockStem extends BlockBush implements IGrowable { diff --git a/java/src/game/block/BlockStone.java b/java/src/common/block/BlockStone.java similarity index 54% rename from java/src/game/block/BlockStone.java rename to java/src/common/block/BlockStone.java index 89d99a6..bbfe84c 100755 --- a/java/src/game/block/BlockStone.java +++ b/java/src/common/block/BlockStone.java @@ -1,12 +1,12 @@ -package game.block; +package common.block; -import game.init.Blocks; -import game.init.ItemRegistry; -import game.item.CheatTab; -import game.item.Item; -import game.material.Material; -import game.rng.Random; -import game.world.State; +import common.init.Blocks; +import common.init.ItemRegistry; +import common.item.CheatTab; +import common.item.Item; +import common.material.Material; +import common.rng.Random; +import common.world.State; public class BlockStone extends Block { public BlockStone() { diff --git a/java/src/game/block/BlockStoneBrick.java b/java/src/common/block/BlockStoneBrick.java similarity index 92% rename from java/src/game/block/BlockStoneBrick.java rename to java/src/common/block/BlockStoneBrick.java index 5300cf5..0d38a04 100755 --- a/java/src/game/block/BlockStoneBrick.java +++ b/java/src/common/block/BlockStoneBrick.java @@ -1,17 +1,17 @@ -package game.block; +package common.block; import java.util.List; -import game.item.CheatTab; -import game.item.Item; -import game.item.ItemStack; -import game.material.Material; -import game.model.Model; -import game.model.ModelProvider; -import game.properties.IProperty; -import game.properties.PropertyEnum; -import game.util.Identifyable; -import game.world.State; +import common.item.CheatTab; +import common.item.Item; +import common.item.ItemStack; +import common.material.Material; +import common.model.Model; +import common.model.ModelProvider; +import common.properties.IProperty; +import common.properties.PropertyEnum; +import common.util.Identifyable; +import common.world.State; public class BlockStoneBrick extends Block { diff --git a/java/src/game/block/BlockTNT.java b/java/src/common/block/BlockTNT.java similarity index 89% rename from java/src/game/block/BlockTNT.java rename to java/src/common/block/BlockTNT.java index 17e4550..ceec575 100755 --- a/java/src/game/block/BlockTNT.java +++ b/java/src/common/block/BlockTNT.java @@ -1,29 +1,29 @@ -package game.block; +package common.block; import java.util.List; -import game.entity.Entity; -import game.entity.item.EntityTnt; -import game.entity.npc.EntityNPC; -import game.entity.projectile.EntityArrow; -import game.entity.types.EntityLiving; -import game.init.Items; -import game.init.SoundEvent; -import game.item.CheatTab; -import game.item.Item; -import game.item.ItemStack; -import game.material.Material; -import game.model.Model; -import game.model.ModelProvider; -import game.properties.IProperty; -import game.properties.PropertyBool; -import game.properties.PropertyInteger; -import game.world.BlockPos; -import game.world.Explosion; -import game.world.Facing; -import game.world.State; -import game.world.World; -import game.world.WorldServer; +import common.entity.Entity; +import common.entity.item.EntityTnt; +import common.entity.npc.EntityNPC; +import common.entity.projectile.EntityArrow; +import common.entity.types.EntityLiving; +import common.init.Items; +import common.init.SoundEvent; +import common.item.CheatTab; +import common.item.Item; +import common.item.ItemStack; +import common.material.Material; +import common.model.Model; +import common.model.ModelProvider; +import common.properties.IProperty; +import common.properties.PropertyBool; +import common.properties.PropertyInteger; +import common.world.BlockPos; +import common.world.Explosion; +import common.world.Facing; +import common.world.State; +import common.world.World; +import common.world.WorldServer; public class BlockTNT extends Block { diff --git a/java/src/game/block/BlockTallGrass.java b/java/src/common/block/BlockTallGrass.java similarity index 90% rename from java/src/game/block/BlockTallGrass.java rename to java/src/common/block/BlockTallGrass.java index bcf86a7..9724595 100755 --- a/java/src/game/block/BlockTallGrass.java +++ b/java/src/common/block/BlockTallGrass.java @@ -1,29 +1,29 @@ -package game.block; +package common.block; import java.util.List; -import game.color.Colorizer; -import game.entity.npc.EntityNPC; -import game.init.Blocks; -import game.init.Config; -import game.init.Items; -import game.item.CheatTab; -import game.item.Item; -import game.item.ItemShears; -import game.item.ItemStack; -import game.material.Material; -import game.model.Model; -import game.model.ModelProvider; -import game.properties.IProperty; -import game.properties.PropertyEnum; -import game.rng.Random; -import game.tileentity.TileEntity; -import game.util.Identifyable; -import game.world.BlockPos; -import game.world.IWorldAccess; -import game.world.State; -import game.world.World; -import game.world.WorldServer; +import common.color.Colorizer; +import common.entity.npc.EntityNPC; +import common.init.Blocks; +import common.init.Config; +import common.init.Items; +import common.item.CheatTab; +import common.item.Item; +import common.item.ItemShears; +import common.item.ItemStack; +import common.material.Material; +import common.model.Model; +import common.model.ModelProvider; +import common.properties.IProperty; +import common.properties.PropertyEnum; +import common.rng.Random; +import common.tileentity.TileEntity; +import common.util.Identifyable; +import common.world.BlockPos; +import common.world.IWorldAccess; +import common.world.State; +import common.world.World; +import common.world.WorldServer; public class BlockTallGrass extends BlockBush implements IGrowable { diff --git a/java/src/game/block/BlockTianReactor.java b/java/src/common/block/BlockTianReactor.java similarity index 70% rename from java/src/game/block/BlockTianReactor.java rename to java/src/common/block/BlockTianReactor.java index f1b7ca0..a073032 100755 --- a/java/src/game/block/BlockTianReactor.java +++ b/java/src/common/block/BlockTianReactor.java @@ -1,14 +1,14 @@ -package game.block; +package common.block; import java.util.Map; -import game.model.Model; -import game.model.ModelProvider; -import game.model.ModelRotation; -import game.tileentity.TileEntity; -import game.tileentity.TileEntityTianReactor; -import game.world.State; -import game.world.World; +import common.model.Model; +import common.model.ModelProvider; +import common.model.ModelRotation; +import common.tileentity.TileEntity; +import common.tileentity.TileEntityTianReactor; +import common.world.State; +import common.world.World; public class BlockTianReactor extends BlockMachine { public TileEntity createNewTileEntity(World worldIn, int meta) { diff --git a/java/src/game/block/BlockTianSoil.java b/java/src/common/block/BlockTianSoil.java similarity index 76% rename from java/src/game/block/BlockTianSoil.java rename to java/src/common/block/BlockTianSoil.java index e898bae..339851a 100755 --- a/java/src/game/block/BlockTianSoil.java +++ b/java/src/common/block/BlockTianSoil.java @@ -1,17 +1,17 @@ -package game.block; +package common.block; -import game.init.Blocks; -import game.item.CheatTab; -import game.item.Item; -import game.material.Material; -import game.model.Model; -import game.model.ModelProvider; -import game.properties.IProperty; -import game.properties.PropertyBool; -import game.rng.Random; -import game.world.BlockPos; -import game.world.IWorldAccess; -import game.world.State; +import common.init.Blocks; +import common.item.CheatTab; +import common.item.Item; +import common.material.Material; +import common.model.Model; +import common.model.ModelProvider; +import common.properties.IProperty; +import common.properties.PropertyBool; +import common.rng.Random; +import common.world.BlockPos; +import common.world.IWorldAccess; +import common.world.State; public class BlockTianSoil extends Block { diff --git a/java/src/game/block/BlockTorch.java b/java/src/common/block/BlockTorch.java similarity index 93% rename from java/src/game/block/BlockTorch.java rename to java/src/common/block/BlockTorch.java index 717009c..571d4c3 100755 --- a/java/src/game/block/BlockTorch.java +++ b/java/src/common/block/BlockTorch.java @@ -1,29 +1,29 @@ -package game.block; +package common.block; import java.util.function.Predicate; -import game.entity.types.EntityLiving; -import game.init.Blocks; -import game.item.CheatTab; -import game.material.Material; -import game.model.BlockLayer; -import game.model.Model; -import game.model.ModelProvider; -import game.model.ModelRotation; -import game.model.ParticleType; -import game.properties.IProperty; -import game.properties.PropertyDirection; -import game.rng.Random; -import game.world.BlockPos; -import game.world.BoundingBox; -import game.world.Chunk; -import game.world.Facing; -import game.world.HitPosition; -import game.world.State; -import game.world.Vec3; -import game.world.World; -import game.world.WorldClient; -import game.world.WorldServer; +import common.entity.types.EntityLiving; +import common.init.Blocks; +import common.item.CheatTab; +import common.material.Material; +import common.model.BlockLayer; +import common.model.Model; +import common.model.ModelProvider; +import common.model.ModelRotation; +import common.model.ParticleType; +import common.properties.IProperty; +import common.properties.PropertyDirection; +import common.rng.Random; +import common.world.BlockPos; +import common.world.BoundingBox; +import common.world.Chunk; +import common.world.Facing; +import common.world.HitPosition; +import common.world.State; +import common.world.Vec3; +import common.world.World; +import common.world.WorldClient; +import common.world.WorldServer; public class BlockTorch extends Block { diff --git a/java/src/game/block/BlockTrapDoor.java b/java/src/common/block/BlockTrapDoor.java similarity index 92% rename from java/src/game/block/BlockTrapDoor.java rename to java/src/common/block/BlockTrapDoor.java index 55ffc46..f6f9eae 100755 --- a/java/src/game/block/BlockTrapDoor.java +++ b/java/src/common/block/BlockTrapDoor.java @@ -1,29 +1,29 @@ -package game.block; +package common.block; -import game.entity.npc.EntityNPC; -import game.entity.types.EntityLiving; -import game.init.Blocks; -import game.item.CheatTab; -import game.material.Material; -import game.model.BlockLayer; -import game.model.Model; -import game.model.ModelProvider; -import game.model.ModelRotation; -import game.model.Transforms; -import game.properties.IProperty; -import game.properties.PropertyBool; -import game.properties.PropertyDirection; -import game.properties.PropertyEnum; -import game.util.Identifyable; -import game.world.BlockPos; -import game.world.BoundingBox; -import game.world.Facing; -import game.world.HitPosition; -import game.world.IBlockAccess; -import game.world.IWorldAccess; -import game.world.State; -import game.world.Vec3; -import game.world.World; +import common.entity.npc.EntityNPC; +import common.entity.types.EntityLiving; +import common.init.Blocks; +import common.item.CheatTab; +import common.material.Material; +import common.model.BlockLayer; +import common.model.Model; +import common.model.ModelProvider; +import common.model.ModelRotation; +import common.model.Transforms; +import common.properties.IProperty; +import common.properties.PropertyBool; +import common.properties.PropertyDirection; +import common.properties.PropertyEnum; +import common.util.Identifyable; +import common.world.BlockPos; +import common.world.BoundingBox; +import common.world.Facing; +import common.world.HitPosition; +import common.world.IBlockAccess; +import common.world.IWorldAccess; +import common.world.State; +import common.world.Vec3; +import common.world.World; public class BlockTrapDoor extends Block { diff --git a/java/src/game/block/BlockTreasure.java b/java/src/common/block/BlockTreasure.java similarity index 75% rename from java/src/game/block/BlockTreasure.java rename to java/src/common/block/BlockTreasure.java index fd5c5f7..7f79172 100755 --- a/java/src/game/block/BlockTreasure.java +++ b/java/src/common/block/BlockTreasure.java @@ -1,6 +1,6 @@ -package game.block; +package common.block; -import game.material.Material; +import common.material.Material; public class BlockTreasure extends Block { public BlockTreasure(Material materialIn) { diff --git a/java/src/game/block/BlockTripWire.java b/java/src/common/block/BlockTripWire.java similarity index 97% rename from java/src/game/block/BlockTripWire.java rename to java/src/common/block/BlockTripWire.java index 11e1a08..cbd9299 100755 --- a/java/src/game/block/BlockTripWire.java +++ b/java/src/common/block/BlockTripWire.java @@ -1,29 +1,29 @@ -package game.block; +package common.block; import java.util.List; -import game.entity.Entity; -import game.entity.npc.EntityNPC; -import game.init.Blocks; -import game.init.Items; -import game.item.Item; -import game.item.ItemShears; -import game.material.Material; -import game.model.BlockLayer; -import game.model.Model; -import game.model.ModelProvider; -import game.model.ModelRotation; -import game.properties.IProperty; -import game.properties.PropertyBool; -import game.rng.Random; -import game.world.BlockPos; -import game.world.BoundingBox; -import game.world.Facing; -import game.world.IBlockAccess; -import game.world.IWorldAccess; -import game.world.State; -import game.world.World; -import game.world.WorldServer; +import common.entity.Entity; +import common.entity.npc.EntityNPC; +import common.init.Blocks; +import common.init.Items; +import common.item.Item; +import common.item.ItemShears; +import common.material.Material; +import common.model.BlockLayer; +import common.model.Model; +import common.model.ModelProvider; +import common.model.ModelRotation; +import common.properties.IProperty; +import common.properties.PropertyBool; +import common.rng.Random; +import common.world.BlockPos; +import common.world.BoundingBox; +import common.world.Facing; +import common.world.IBlockAccess; +import common.world.IWorldAccess; +import common.world.State; +import common.world.World; +import common.world.WorldServer; public class BlockTripWire extends Block { diff --git a/java/src/game/block/BlockTripWireHook.java b/java/src/common/block/BlockTripWireHook.java similarity index 97% rename from java/src/game/block/BlockTripWireHook.java rename to java/src/common/block/BlockTripWireHook.java index 5dc6835..fb66590 100755 --- a/java/src/game/block/BlockTripWireHook.java +++ b/java/src/common/block/BlockTripWireHook.java @@ -1,26 +1,26 @@ -package game.block; +package common.block; -import game.entity.types.EntityLiving; -import game.init.Blocks; -import game.init.SoundEvent; -import game.item.CheatTab; -import game.item.ItemStack; -import game.material.Material; -import game.model.BlockLayer; -import game.model.Model; -import game.model.ModelProvider; -import game.model.ModelRotation; -import game.properties.IProperty; -import game.properties.PropertyBool; -import game.properties.PropertyDirection; -import game.rng.Random; -import game.world.BlockPos; -import game.world.BoundingBox; -import game.world.Facing; -import game.world.IWorldAccess; -import game.world.State; -import game.world.World; -import game.world.WorldServer; +import common.entity.types.EntityLiving; +import common.init.Blocks; +import common.init.SoundEvent; +import common.item.CheatTab; +import common.item.ItemStack; +import common.material.Material; +import common.model.BlockLayer; +import common.model.Model; +import common.model.ModelProvider; +import common.model.ModelRotation; +import common.properties.IProperty; +import common.properties.PropertyBool; +import common.properties.PropertyDirection; +import common.rng.Random; +import common.world.BlockPos; +import common.world.BoundingBox; +import common.world.Facing; +import common.world.IWorldAccess; +import common.world.State; +import common.world.World; +import common.world.WorldServer; public class BlockTripWireHook extends Block { diff --git a/java/src/game/block/BlockVine.java b/java/src/common/block/BlockVine.java similarity index 96% rename from java/src/game/block/BlockVine.java rename to java/src/common/block/BlockVine.java index b7d516e..10443c8 100755 --- a/java/src/game/block/BlockVine.java +++ b/java/src/common/block/BlockVine.java @@ -1,30 +1,30 @@ -package game.block; +package common.block; -import game.color.Colorizer; -import game.entity.npc.EntityNPC; -import game.entity.types.EntityLiving; -import game.init.Blocks; -import game.init.Config; -import game.item.CheatTab; -import game.item.Item; -import game.item.ItemShears; -import game.item.ItemStack; -import game.material.Material; -import game.model.BlockLayer; -import game.model.Model; -import game.model.ModelProvider; -import game.model.ModelRotation; -import game.properties.IProperty; -import game.properties.PropertyBool; -import game.rng.Random; -import game.tileentity.TileEntity; -import game.world.BlockPos; -import game.world.BoundingBox; -import game.world.Facing; -import game.world.IWorldAccess; -import game.world.State; -import game.world.World; -import game.world.WorldServer; +import common.color.Colorizer; +import common.entity.npc.EntityNPC; +import common.entity.types.EntityLiving; +import common.init.Blocks; +import common.init.Config; +import common.item.CheatTab; +import common.item.Item; +import common.item.ItemShears; +import common.item.ItemStack; +import common.material.Material; +import common.model.BlockLayer; +import common.model.Model; +import common.model.ModelProvider; +import common.model.ModelRotation; +import common.properties.IProperty; +import common.properties.PropertyBool; +import common.rng.Random; +import common.tileentity.TileEntity; +import common.world.BlockPos; +import common.world.BoundingBox; +import common.world.Facing; +import common.world.IWorldAccess; +import common.world.State; +import common.world.World; +import common.world.WorldServer; public class BlockVine extends Block { diff --git a/java/src/game/block/BlockWall.java b/java/src/common/block/BlockWall.java similarity index 95% rename from java/src/game/block/BlockWall.java rename to java/src/common/block/BlockWall.java index c49c0ca..de001d2 100755 --- a/java/src/game/block/BlockWall.java +++ b/java/src/common/block/BlockWall.java @@ -1,25 +1,25 @@ -package game.block; +package common.block; import java.util.List; -import game.item.CheatTab; -import game.item.Item; -import game.item.ItemStack; -import game.material.Material; -import game.model.Model; -import game.model.ModelProvider; -import game.model.ModelRotation; -import game.properties.IProperty; -import game.properties.PropertyBool; -import game.properties.PropertyEnum; -import game.util.Identifyable; -import game.world.BlockPos; -import game.world.BoundingBox; -import game.world.Facing; -import game.world.IBlockAccess; -import game.world.IWorldAccess; -import game.world.State; -import game.world.World; +import common.item.CheatTab; +import common.item.Item; +import common.item.ItemStack; +import common.material.Material; +import common.model.Model; +import common.model.ModelProvider; +import common.model.ModelRotation; +import common.properties.IProperty; +import common.properties.PropertyBool; +import common.properties.PropertyEnum; +import common.util.Identifyable; +import common.world.BlockPos; +import common.world.BoundingBox; +import common.world.Facing; +import common.world.IBlockAccess; +import common.world.IWorldAccess; +import common.world.State; +import common.world.World; public class BlockWall extends Block { diff --git a/java/src/game/block/BlockWallSign.java b/java/src/common/block/BlockWallSign.java similarity index 90% rename from java/src/game/block/BlockWallSign.java rename to java/src/common/block/BlockWallSign.java index 55133c0..75fdc0f 100755 --- a/java/src/game/block/BlockWallSign.java +++ b/java/src/common/block/BlockWallSign.java @@ -1,12 +1,12 @@ -package game.block; +package common.block; -import game.properties.IProperty; -import game.properties.PropertyDirection; -import game.world.BlockPos; -import game.world.Facing; -import game.world.IWorldAccess; -import game.world.State; -import game.world.World; +import common.properties.IProperty; +import common.properties.PropertyDirection; +import common.world.BlockPos; +import common.world.Facing; +import common.world.IWorldAccess; +import common.world.State; +import common.world.World; public class BlockWallSign extends BlockSign { diff --git a/java/src/game/block/BlockWarpChest.java b/java/src/common/block/BlockWarpChest.java similarity index 86% rename from java/src/game/block/BlockWarpChest.java rename to java/src/common/block/BlockWarpChest.java index a8776d2..d32b60e 100755 --- a/java/src/game/block/BlockWarpChest.java +++ b/java/src/common/block/BlockWarpChest.java @@ -1,26 +1,26 @@ -package game.block; +package common.block; -import game.entity.npc.EntityNPC; -import game.entity.types.EntityLiving; -import game.init.Blocks; -import game.init.ItemRegistry; -import game.inventory.InventoryWarpChest; -import game.item.CheatTab; -import game.item.Item; -import game.item.ItemStack; -import game.material.Material; -import game.model.Model; -import game.model.ModelProvider; -import game.model.ModelRotation; -import game.model.ParticleType; -import game.properties.IProperty; -import game.properties.PropertyDirection; -import game.rng.Random; -import game.world.BlockPos; -import game.world.Facing; -import game.world.State; -import game.world.World; -import game.world.WorldClient; +import common.entity.npc.EntityNPC; +import common.entity.types.EntityLiving; +import common.init.Blocks; +import common.init.ItemRegistry; +import common.inventory.InventoryWarpChest; +import common.item.CheatTab; +import common.item.Item; +import common.item.ItemStack; +import common.material.Material; +import common.model.Model; +import common.model.ModelProvider; +import common.model.ModelRotation; +import common.model.ParticleType; +import common.properties.IProperty; +import common.properties.PropertyDirection; +import common.rng.Random; +import common.world.BlockPos; +import common.world.Facing; +import common.world.State; +import common.world.World; +import common.world.WorldClient; public class BlockWarpChest extends Block { diff --git a/java/src/game/block/BlockWart.java b/java/src/common/block/BlockWart.java similarity index 86% rename from java/src/game/block/BlockWart.java rename to java/src/common/block/BlockWart.java index c77813c..380e4eb 100755 --- a/java/src/game/block/BlockWart.java +++ b/java/src/common/block/BlockWart.java @@ -1,21 +1,21 @@ -package game.block; +package common.block; -import game.init.Blocks; -import game.init.Config; -import game.init.Items; -import game.item.CheatTab; -import game.item.Item; -import game.item.ItemStack; -import game.material.Material; -import game.model.Model; -import game.model.ModelProvider; -import game.properties.IProperty; -import game.properties.PropertyInteger; -import game.rng.Random; -import game.world.BlockPos; -import game.world.State; -import game.world.World; -import game.world.WorldServer; +import common.init.Blocks; +import common.init.Config; +import common.init.Items; +import common.item.CheatTab; +import common.item.Item; +import common.item.ItemStack; +import common.material.Material; +import common.model.Model; +import common.model.ModelProvider; +import common.properties.IProperty; +import common.properties.PropertyInteger; +import common.rng.Random; +import common.world.BlockPos; +import common.world.State; +import common.world.World; +import common.world.WorldServer; public class BlockWart extends BlockBush { diff --git a/java/src/game/block/BlockWeb.java b/java/src/common/block/BlockWeb.java similarity index 74% rename from java/src/game/block/BlockWeb.java rename to java/src/common/block/BlockWeb.java index 261b092..959cb0f 100755 --- a/java/src/game/block/BlockWeb.java +++ b/java/src/common/block/BlockWeb.java @@ -1,18 +1,18 @@ -package game.block; +package common.block; -import game.entity.Entity; -import game.init.Items; -import game.item.CheatTab; -import game.item.Item; -import game.material.Material; -import game.model.BlockLayer; -import game.model.Model; -import game.model.ModelProvider; -import game.rng.Random; -import game.world.BlockPos; -import game.world.BoundingBox; -import game.world.State; -import game.world.World; +import common.entity.Entity; +import common.init.Items; +import common.item.CheatTab; +import common.item.Item; +import common.material.Material; +import common.model.BlockLayer; +import common.model.Model; +import common.model.ModelProvider; +import common.rng.Random; +import common.world.BlockPos; +import common.world.BoundingBox; +import common.world.State; +import common.world.World; public class BlockWeb extends Block { diff --git a/java/src/game/block/BlockWorkbench.java b/java/src/common/block/BlockWorkbench.java similarity index 79% rename from java/src/game/block/BlockWorkbench.java rename to java/src/common/block/BlockWorkbench.java index a970372..0489d2c 100755 --- a/java/src/game/block/BlockWorkbench.java +++ b/java/src/common/block/BlockWorkbench.java @@ -1,18 +1,18 @@ -package game.block; +package common.block; -import game.entity.npc.EntityNPC; -import game.inventory.Container; -import game.inventory.ContainerWorkbench; -import game.inventory.InventoryPlayer; -import game.item.CheatTab; -import game.material.Material; -import game.model.Model; -import game.model.ModelProvider; -import game.tileentity.IInteractionObject; -import game.world.BlockPos; -import game.world.Facing; -import game.world.State; -import game.world.World; +import common.entity.npc.EntityNPC; +import common.inventory.Container; +import common.inventory.ContainerWorkbench; +import common.inventory.InventoryPlayer; +import common.item.CheatTab; +import common.material.Material; +import common.model.Model; +import common.model.ModelProvider; +import common.tileentity.IInteractionObject; +import common.world.BlockPos; +import common.world.Facing; +import common.world.State; +import common.world.World; public class BlockWorkbench extends Block { diff --git a/java/src/game/block/IGrowable.java b/java/src/common/block/IGrowable.java similarity index 62% rename from java/src/game/block/IGrowable.java rename to java/src/common/block/IGrowable.java index 6c9561d..35def7f 100755 --- a/java/src/game/block/IGrowable.java +++ b/java/src/common/block/IGrowable.java @@ -1,10 +1,10 @@ -package game.block; +package common.block; -import game.rng.Random; -import game.world.BlockPos; -import game.world.State; -import game.world.World; -import game.world.WorldServer; +import common.rng.Random; +import common.world.BlockPos; +import common.world.State; +import common.world.World; +import common.world.WorldServer; public interface IGrowable { diff --git a/java/src/game/block/ITileEntityProvider.java b/java/src/common/block/ITileEntityProvider.java similarity index 71% rename from java/src/game/block/ITileEntityProvider.java rename to java/src/common/block/ITileEntityProvider.java index af5e3cd..f4628a7 100755 --- a/java/src/game/block/ITileEntityProvider.java +++ b/java/src/common/block/ITileEntityProvider.java @@ -1,7 +1,7 @@ -package game.block; +package common.block; -import game.tileentity.TileEntity; -import game.world.World; +import common.tileentity.TileEntity; +import common.world.World; public interface ITileEntityProvider { diff --git a/java/src/game/block/LeavesType.java b/java/src/common/block/LeavesType.java similarity index 91% rename from java/src/game/block/LeavesType.java rename to java/src/common/block/LeavesType.java index faa13f1..25b730d 100755 --- a/java/src/game/block/LeavesType.java +++ b/java/src/common/block/LeavesType.java @@ -1,6 +1,6 @@ -package game.block; +package common.block; -import game.util.Identifyable; +import common.util.Identifyable; public enum LeavesType implements Identifyable { SPRING(0, "spring", true, "Frühling"), diff --git a/java/src/game/block/SoundType.java b/java/src/common/block/SoundType.java similarity index 91% rename from java/src/game/block/SoundType.java rename to java/src/common/block/SoundType.java index 9dfc4ec..4b1e988 100755 --- a/java/src/game/block/SoundType.java +++ b/java/src/common/block/SoundType.java @@ -1,6 +1,6 @@ -package game.block; +package common.block; -import game.init.SoundEvent; +import common.init.SoundEvent; public enum SoundType { STONE(SoundEvent.STONE), diff --git a/java/src/game/clipboard/BlockTransform.java b/java/src/common/clipboard/BlockTransform.java similarity index 99% rename from java/src/game/clipboard/BlockTransform.java rename to java/src/common/clipboard/BlockTransform.java index f17f475..62ae4b2 100755 --- a/java/src/game/clipboard/BlockTransform.java +++ b/java/src/common/clipboard/BlockTransform.java @@ -1,4 +1,4 @@ -package game.clipboard; +package common.clipboard; public class BlockTransform { private double m00, m01, m02, m03; diff --git a/java/src/game/clipboard/ClipboardBlock.java b/java/src/common/clipboard/ClipboardBlock.java similarity index 82% rename from java/src/game/clipboard/ClipboardBlock.java rename to java/src/common/clipboard/ClipboardBlock.java index 546b2fa..8ed9ea5 100755 --- a/java/src/game/clipboard/ClipboardBlock.java +++ b/java/src/common/clipboard/ClipboardBlock.java @@ -1,8 +1,8 @@ -package game.clipboard; +package common.clipboard; -import game.nbt.NBTTagCompound; -import game.tileentity.TileEntity; -import game.world.State; +import common.nbt.NBTTagCompound; +import common.tileentity.TileEntity; +import common.world.State; public class ClipboardBlock { private State state; diff --git a/java/src/game/clipboard/ClipboardPlacer.java b/java/src/common/clipboard/ClipboardPlacer.java similarity index 93% rename from java/src/game/clipboard/ClipboardPlacer.java rename to java/src/common/clipboard/ClipboardPlacer.java index 5a94c52..a6525c0 100755 --- a/java/src/game/clipboard/ClipboardPlacer.java +++ b/java/src/common/clipboard/ClipboardPlacer.java @@ -1,4 +1,4 @@ -package game.clipboard; +package common.clipboard; import java.util.Deque; import java.util.HashMap; @@ -8,18 +8,18 @@ import java.util.List; import java.util.Map; import java.util.Set; -import game.block.Block; -import game.block.BlockDoor; -import game.block.BlockRailBase; -import game.block.ITileEntityProvider; -import game.collect.Lists; -import game.init.Blocks; -import game.init.ReorderRegistry; -import game.inventory.IInventory; -import game.tileentity.TileEntity; -import game.world.BlockPos; -import game.world.Vec3i; -import game.world.WorldServer; +import common.block.Block; +import common.block.BlockDoor; +import common.block.BlockRailBase; +import common.block.ITileEntityProvider; +import common.collect.Lists; +import common.init.Blocks; +import common.init.ReorderRegistry; +import common.inventory.IInventory; +import common.tileentity.TileEntity; +import common.world.BlockPos; +import common.world.Vec3i; +import common.world.WorldServer; public class ClipboardPlacer { private static class BlockEntry { diff --git a/java/src/game/clipboard/Rotation.java b/java/src/common/clipboard/Rotation.java similarity index 97% rename from java/src/game/clipboard/Rotation.java rename to java/src/common/clipboard/Rotation.java index f70cb46..51e4d1b 100755 --- a/java/src/game/clipboard/Rotation.java +++ b/java/src/common/clipboard/Rotation.java @@ -1,4 +1,4 @@ -package game.clipboard; +package common.clipboard; import java.util.function.Predicate; diff --git a/java/src/game/clipboard/RotationValue.java b/java/src/common/clipboard/RotationValue.java similarity index 95% rename from java/src/game/clipboard/RotationValue.java rename to java/src/common/clipboard/RotationValue.java index c6b6f88..46319c6 100755 --- a/java/src/game/clipboard/RotationValue.java +++ b/java/src/common/clipboard/RotationValue.java @@ -1,4 +1,4 @@ -package game.clipboard; +package common.clipboard; public class RotationValue { public final byte mask; diff --git a/java/src/game/clipboard/Vector.java b/java/src/common/clipboard/Vector.java similarity index 99% rename from java/src/game/clipboard/Vector.java rename to java/src/common/clipboard/Vector.java index 084cf12..71fdb4d 100755 --- a/java/src/game/clipboard/Vector.java +++ b/java/src/common/clipboard/Vector.java @@ -1,4 +1,4 @@ -package game.clipboard; +package common.clipboard; public class Vector implements Comparable { public static final Vector ZERO = new Vector(0, 0, 0); diff --git a/java/src/game/collect/AbstractBiMap.java b/java/src/common/collect/AbstractBiMap.java similarity index 98% rename from java/src/game/collect/AbstractBiMap.java rename to java/src/common/collect/AbstractBiMap.java index d2c3336..f1ebdfa 100644 --- a/java/src/game/collect/AbstractBiMap.java +++ b/java/src/common/collect/AbstractBiMap.java @@ -14,11 +14,11 @@ * limitations under the License. */ -package game.collect; +package common.collect; -import static game.collect.CollectPreconditions.checkRemove; -import static game.collect.Preconditions.checkArgument; -import static game.collect.Preconditions.checkState; +import static common.collect.CollectPreconditions.checkRemove; +import static common.collect.Preconditions.checkArgument; +import static common.collect.Preconditions.checkState; import java.io.IOException; import java.io.ObjectInputStream; diff --git a/java/src/game/collect/AbstractIndexedListIterator.java b/java/src/common/collect/AbstractIndexedListIterator.java similarity index 97% rename from java/src/game/collect/AbstractIndexedListIterator.java rename to java/src/common/collect/AbstractIndexedListIterator.java index a2056ae..224444d 100644 --- a/java/src/game/collect/AbstractIndexedListIterator.java +++ b/java/src/common/collect/AbstractIndexedListIterator.java @@ -14,9 +14,9 @@ * limitations under the License. */ -package game.collect; +package common.collect; -import static game.collect.Preconditions.checkPositionIndex; +import static common.collect.Preconditions.checkPositionIndex; import java.util.NoSuchElementException; diff --git a/java/src/game/collect/AbstractIterator.java b/java/src/common/collect/AbstractIterator.java similarity index 98% rename from java/src/game/collect/AbstractIterator.java rename to java/src/common/collect/AbstractIterator.java index 7ba15e0..a33bfe7 100644 --- a/java/src/game/collect/AbstractIterator.java +++ b/java/src/common/collect/AbstractIterator.java @@ -14,9 +14,9 @@ * limitations under the License. */ -package game.collect; +package common.collect; -import static game.collect.Preconditions.checkState; +import static common.collect.Preconditions.checkState; import java.util.NoSuchElementException; diff --git a/java/src/game/collect/AbstractMapEntry.java b/java/src/common/collect/AbstractMapEntry.java similarity index 98% rename from java/src/game/collect/AbstractMapEntry.java rename to java/src/common/collect/AbstractMapEntry.java index 4c89223..18c350c 100644 --- a/java/src/game/collect/AbstractMapEntry.java +++ b/java/src/common/collect/AbstractMapEntry.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package game.collect; +package common.collect; import java.util.Map.Entry; diff --git a/java/src/game/collect/AbstractTable.java b/java/src/common/collect/AbstractTable.java similarity index 99% rename from java/src/game/collect/AbstractTable.java rename to java/src/common/collect/AbstractTable.java index b19ada4..60a7906 100644 --- a/java/src/game/collect/AbstractTable.java +++ b/java/src/common/collect/AbstractTable.java @@ -12,7 +12,7 @@ * the License. */ -package game.collect; +package common.collect; import java.util.AbstractCollection; import java.util.AbstractSet; diff --git a/java/src/game/collect/BiMap.java b/java/src/common/collect/BiMap.java similarity index 99% rename from java/src/game/collect/BiMap.java rename to java/src/common/collect/BiMap.java index 3b920df..7effc10 100644 --- a/java/src/game/collect/BiMap.java +++ b/java/src/common/collect/BiMap.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package game.collect; +package common.collect; import java.util.Map; import java.util.Set; diff --git a/java/src/game/collect/CollectPreconditions.java b/java/src/common/collect/CollectPreconditions.java similarity index 94% rename from java/src/game/collect/CollectPreconditions.java rename to java/src/common/collect/CollectPreconditions.java index 520d5d2..f84a833 100644 --- a/java/src/game/collect/CollectPreconditions.java +++ b/java/src/common/collect/CollectPreconditions.java @@ -14,9 +14,9 @@ * limitations under the License. */ -package game.collect; +package common.collect; -import static game.collect.Preconditions.checkState; +import static common.collect.Preconditions.checkState; /** * Precondition checks useful in collection implementations. diff --git a/java/src/game/collect/DenseImmutableTable.java b/java/src/common/collect/DenseImmutableTable.java similarity index 98% rename from java/src/game/collect/DenseImmutableTable.java rename to java/src/common/collect/DenseImmutableTable.java index 5afd429..a4e1611 100644 --- a/java/src/game/collect/DenseImmutableTable.java +++ b/java/src/common/collect/DenseImmutableTable.java @@ -12,9 +12,9 @@ * the License. */ -package game.collect; +package common.collect; -import static game.collect.Preconditions.checkArgument; +import static common.collect.Preconditions.checkArgument; import java.util.Map; diff --git a/java/src/game/collect/EmptyImmutableMap.java b/java/src/common/collect/EmptyImmutableMap.java similarity index 99% rename from java/src/game/collect/EmptyImmutableMap.java rename to java/src/common/collect/EmptyImmutableMap.java index 866868a..84d8d06 100644 --- a/java/src/game/collect/EmptyImmutableMap.java +++ b/java/src/common/collect/EmptyImmutableMap.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package game.collect; +package common.collect; /** * Bimap with no mappings. diff --git a/java/src/game/collect/EmptyImmutableSet.java b/java/src/common/collect/EmptyImmutableSet.java similarity index 98% rename from java/src/game/collect/EmptyImmutableSet.java rename to java/src/common/collect/EmptyImmutableSet.java index f86b50f..9605ea9 100644 --- a/java/src/game/collect/EmptyImmutableSet.java +++ b/java/src/common/collect/EmptyImmutableSet.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package game.collect; +package common.collect; import java.util.Collection; import java.util.Set; diff --git a/java/src/game/collect/Filter.java b/java/src/common/collect/Filter.java similarity index 98% rename from java/src/game/collect/Filter.java rename to java/src/common/collect/Filter.java index 3d45f77..a9f4fd1 100644 --- a/java/src/game/collect/Filter.java +++ b/java/src/common/collect/Filter.java @@ -14,20 +14,20 @@ * limitations under the License. */ -package game.collect; +package common.collect; -import static game.collect.Preconditions.checkArgument; -import static game.collect.Preconditions.checkNotNull; -import static game.util.Predicates.and; -import static game.util.Predicates.in; -import static game.util.Predicates.not; +import static common.collect.Preconditions.checkArgument; +import static common.collect.Preconditions.checkNotNull; +import static common.util.Predicates.and; +import static common.util.Predicates.in; +import static common.util.Predicates.not; import java.util.AbstractCollection; import java.util.Collection; import java.util.Iterator; import java.util.function.Predicate; -import game.util.Predicates; +import common.util.Predicates; /** * Provides static methods for working with {@code Collection} instances. diff --git a/java/src/game/collect/ForwardingCollection.java b/java/src/common/collect/ForwardingCollection.java similarity index 99% rename from java/src/game/collect/ForwardingCollection.java rename to java/src/common/collect/ForwardingCollection.java index 3d1733a..57b8d80 100644 --- a/java/src/game/collect/ForwardingCollection.java +++ b/java/src/common/collect/ForwardingCollection.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package game.collect; +package common.collect; import java.util.Collection; import java.util.Iterator; diff --git a/java/src/game/collect/ForwardingMap.java b/java/src/common/collect/ForwardingMap.java similarity index 99% rename from java/src/game/collect/ForwardingMap.java rename to java/src/common/collect/ForwardingMap.java index b810066..8294acf 100644 --- a/java/src/game/collect/ForwardingMap.java +++ b/java/src/common/collect/ForwardingMap.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package game.collect; +package common.collect; import java.util.Collection; import java.util.Map; diff --git a/java/src/game/collect/ForwardingMapEntry.java b/java/src/common/collect/ForwardingMapEntry.java similarity index 99% rename from java/src/game/collect/ForwardingMapEntry.java rename to java/src/common/collect/ForwardingMapEntry.java index a4f4d03..515a3b1 100644 --- a/java/src/game/collect/ForwardingMapEntry.java +++ b/java/src/common/collect/ForwardingMapEntry.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package game.collect; +package common.collect; import java.util.Map; import java.util.Map.Entry; diff --git a/java/src/game/collect/ForwardingObject.java b/java/src/common/collect/ForwardingObject.java similarity index 99% rename from java/src/game/collect/ForwardingObject.java rename to java/src/common/collect/ForwardingObject.java index d5b64e8..6894d30 100644 --- a/java/src/game/collect/ForwardingObject.java +++ b/java/src/common/collect/ForwardingObject.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package game.collect; +package common.collect; /** * An abstract base class for implementing the { public class GeneratorSettings { diff --git a/java/src/game/dimension/Domain.java b/java/src/common/dimension/Domain.java similarity index 90% rename from java/src/game/dimension/Domain.java rename to java/src/common/dimension/Domain.java index 91e640c..f209714 100755 --- a/java/src/game/dimension/Domain.java +++ b/java/src/common/dimension/Domain.java @@ -1,8 +1,8 @@ -package game.dimension; +package common.dimension; import java.util.Set; -import game.collect.Sets; +import common.collect.Sets; public final class Domain extends Nameable implements Comparable { public final String id; diff --git a/java/src/game/dimension/Galaxy.java b/java/src/common/dimension/Galaxy.java similarity index 90% rename from java/src/game/dimension/Galaxy.java rename to java/src/common/dimension/Galaxy.java index fa44e2f..9203107 100755 --- a/java/src/game/dimension/Galaxy.java +++ b/java/src/common/dimension/Galaxy.java @@ -1,8 +1,8 @@ -package game.dimension; +package common.dimension; import java.util.Set; -import game.collect.Sets; +import common.collect.Sets; public final class Galaxy extends Nameable implements Comparable { public final String id; diff --git a/java/src/game/dimension/Moon.java b/java/src/common/dimension/Moon.java similarity index 95% rename from java/src/game/dimension/Moon.java rename to java/src/common/dimension/Moon.java index 10eeff6..cab561c 100755 --- a/java/src/game/dimension/Moon.java +++ b/java/src/common/dimension/Moon.java @@ -1,4 +1,4 @@ -package game.dimension; +package common.dimension; public final class Moon extends Dimension { Moon(int id, String name) { diff --git a/java/src/game/dimension/Nameable.java b/java/src/common/dimension/Nameable.java similarity index 95% rename from java/src/game/dimension/Nameable.java rename to java/src/common/dimension/Nameable.java index 9e9454b..922630d 100755 --- a/java/src/game/dimension/Nameable.java +++ b/java/src/common/dimension/Nameable.java @@ -1,6 +1,6 @@ -package game.dimension; +package common.dimension; -import game.nbt.NBTTagCompound; +import common.nbt.NBTTagCompound; public abstract class Nameable { protected String customName = null; diff --git a/java/src/game/dimension/Planet.java b/java/src/common/dimension/Planet.java similarity index 96% rename from java/src/game/dimension/Planet.java rename to java/src/common/dimension/Planet.java index 19689b7..37fa250 100755 --- a/java/src/game/dimension/Planet.java +++ b/java/src/common/dimension/Planet.java @@ -1,8 +1,8 @@ -package game.dimension; +package common.dimension; import java.util.Set; -import game.collect.Sets; +import common.collect.Sets; public final class Planet extends Dimension { private final Set moons = Sets.newTreeSet(); diff --git a/java/src/game/dimension/Sector.java b/java/src/common/dimension/Sector.java similarity index 90% rename from java/src/game/dimension/Sector.java rename to java/src/common/dimension/Sector.java index 4d11d4e..6327744 100755 --- a/java/src/game/dimension/Sector.java +++ b/java/src/common/dimension/Sector.java @@ -1,8 +1,8 @@ -package game.dimension; +package common.dimension; import java.util.Set; -import game.collect.Sets; +import common.collect.Sets; public final class Sector extends Nameable implements Comparable { public final String id; diff --git a/java/src/game/dimension/Semi.java b/java/src/common/dimension/Semi.java similarity index 95% rename from java/src/game/dimension/Semi.java rename to java/src/common/dimension/Semi.java index 798d6ca..d5e8b58 100755 --- a/java/src/game/dimension/Semi.java +++ b/java/src/common/dimension/Semi.java @@ -1,4 +1,4 @@ -package game.dimension; +package common.dimension; public final class Semi extends Dimension { Semi(int id, String name) { diff --git a/java/src/game/dimension/Space.java b/java/src/common/dimension/Space.java similarity index 98% rename from java/src/game/dimension/Space.java rename to java/src/common/dimension/Space.java index 02f21bc..3eac115 100755 --- a/java/src/game/dimension/Space.java +++ b/java/src/common/dimension/Space.java @@ -1,6 +1,6 @@ -package game.dimension; +package common.dimension; -import game.biome.Biome; +import common.biome.Biome; public final class Space extends Dimension { public static final Space INSTANCE = new Space(); diff --git a/java/src/game/dimension/Star.java b/java/src/common/dimension/Star.java similarity index 96% rename from java/src/game/dimension/Star.java rename to java/src/common/dimension/Star.java index 4a2452b..14af9e6 100755 --- a/java/src/game/dimension/Star.java +++ b/java/src/common/dimension/Star.java @@ -1,9 +1,9 @@ -package game.dimension; +package common.dimension; import java.util.Set; -import game.collect.Sets; -import game.world.State; +import common.collect.Sets; +import common.world.State; public final class Star extends Dimension { private final Set planets = Sets.newTreeSet(); diff --git a/java/src/game/dispenser/BehaviorDefaultDispenseItem.java b/java/src/common/dispenser/BehaviorDefaultDispenseItem.java similarity index 93% rename from java/src/game/dispenser/BehaviorDefaultDispenseItem.java rename to java/src/common/dispenser/BehaviorDefaultDispenseItem.java index 50057a4..937a1ec 100755 --- a/java/src/game/dispenser/BehaviorDefaultDispenseItem.java +++ b/java/src/common/dispenser/BehaviorDefaultDispenseItem.java @@ -1,10 +1,10 @@ -package game.dispenser; +package common.dispenser; -import game.block.BlockDispenser; -import game.entity.item.EntityItem; -import game.item.ItemStack; -import game.world.Facing; -import game.world.World; +import common.block.BlockDispenser; +import common.entity.item.EntityItem; +import common.item.ItemStack; +import common.world.Facing; +import common.world.World; public class BehaviorDefaultDispenseItem implements IBehaviorDispenseItem { diff --git a/java/src/game/dispenser/BehaviorProjectileDispense.java b/java/src/common/dispenser/BehaviorProjectileDispense.java similarity index 86% rename from java/src/game/dispenser/BehaviorProjectileDispense.java rename to java/src/common/dispenser/BehaviorProjectileDispense.java index 98ce906..71230cf 100755 --- a/java/src/game/dispenser/BehaviorProjectileDispense.java +++ b/java/src/common/dispenser/BehaviorProjectileDispense.java @@ -1,11 +1,11 @@ -package game.dispenser; +package common.dispenser; -import game.block.BlockDispenser; -import game.entity.Entity; -import game.entity.types.IProjectile; -import game.item.ItemStack; -import game.world.Facing; -import game.world.World; +import common.block.BlockDispenser; +import common.entity.Entity; +import common.entity.types.IProjectile; +import common.item.ItemStack; +import common.world.Facing; +import common.world.World; public abstract class BehaviorProjectileDispense extends BehaviorDefaultDispenseItem { diff --git a/java/src/game/dispenser/IBehaviorDispenseItem.java b/java/src/common/dispenser/IBehaviorDispenseItem.java similarity index 87% rename from java/src/game/dispenser/IBehaviorDispenseItem.java rename to java/src/common/dispenser/IBehaviorDispenseItem.java index 2b68bf5..d15ef84 100755 --- a/java/src/game/dispenser/IBehaviorDispenseItem.java +++ b/java/src/common/dispenser/IBehaviorDispenseItem.java @@ -1,6 +1,6 @@ -package game.dispenser; +package common.dispenser; -import game.item.ItemStack; +import common.item.ItemStack; public interface IBehaviorDispenseItem { diff --git a/java/src/game/dispenser/IBlockSource.java b/java/src/common/dispenser/IBlockSource.java similarity index 71% rename from java/src/game/dispenser/IBlockSource.java rename to java/src/common/dispenser/IBlockSource.java index 8e6359e..f6d6d8f 100755 --- a/java/src/game/dispenser/IBlockSource.java +++ b/java/src/common/dispenser/IBlockSource.java @@ -1,7 +1,7 @@ -package game.dispenser; +package common.dispenser; -import game.tileentity.TileEntity; -import game.world.BlockPos; +import common.tileentity.TileEntity; +import common.world.BlockPos; public interface IBlockSource extends ILocatableSource { diff --git a/java/src/game/dispenser/ILocatableSource.java b/java/src/common/dispenser/ILocatableSource.java similarity index 68% rename from java/src/game/dispenser/ILocatableSource.java rename to java/src/common/dispenser/ILocatableSource.java index ea67a66..b0875cb 100755 --- a/java/src/game/dispenser/ILocatableSource.java +++ b/java/src/common/dispenser/ILocatableSource.java @@ -1,4 +1,4 @@ -package game.dispenser; +package common.dispenser; public interface ILocatableSource extends ILocation { diff --git a/java/src/game/dispenser/ILocation.java b/java/src/common/dispenser/ILocation.java similarity index 57% rename from java/src/game/dispenser/ILocation.java rename to java/src/common/dispenser/ILocation.java index c4a4142..e4eb4ae 100755 --- a/java/src/game/dispenser/ILocation.java +++ b/java/src/common/dispenser/ILocation.java @@ -1,6 +1,6 @@ -package game.dispenser; +package common.dispenser; -import game.world.World; +import common.world.World; public interface ILocation extends IPosition { diff --git a/java/src/game/dispenser/IPosition.java b/java/src/common/dispenser/IPosition.java similarity index 77% rename from java/src/game/dispenser/IPosition.java rename to java/src/common/dispenser/IPosition.java index d7ec2f1..aa1ebe7 100755 --- a/java/src/game/dispenser/IPosition.java +++ b/java/src/common/dispenser/IPosition.java @@ -1,4 +1,4 @@ -package game.dispenser; +package common.dispenser; public interface IPosition { diff --git a/java/src/game/dispenser/PositionImpl.java b/java/src/common/dispenser/PositionImpl.java similarity index 94% rename from java/src/game/dispenser/PositionImpl.java rename to java/src/common/dispenser/PositionImpl.java index a268ee3..9150126 100755 --- a/java/src/game/dispenser/PositionImpl.java +++ b/java/src/common/dispenser/PositionImpl.java @@ -1,4 +1,4 @@ -package game.dispenser; +package common.dispenser; public class PositionImpl implements IPosition { diff --git a/java/src/game/enchantment/Enchantment.java b/java/src/common/enchantment/Enchantment.java similarity index 97% rename from java/src/game/enchantment/Enchantment.java rename to java/src/common/enchantment/Enchantment.java index 2241101..a83fe87 100755 --- a/java/src/game/enchantment/Enchantment.java +++ b/java/src/common/enchantment/Enchantment.java @@ -1,15 +1,15 @@ -package game.enchantment; +package common.enchantment; import java.util.List; import java.util.Map; import java.util.Set; -import game.collect.Lists; -import game.collect.Maps; -import game.entity.DamageSource; -import game.entity.Entity; -import game.entity.types.EntityLiving; -import game.item.ItemStack; +import common.collect.Lists; +import common.collect.Maps; +import common.entity.DamageSource; +import common.entity.Entity; +import common.entity.types.EntityLiving; +import common.item.ItemStack; public abstract class Enchantment { diff --git a/java/src/game/enchantment/EnchantmentArrowDamage.java b/java/src/common/enchantment/EnchantmentArrowDamage.java similarity index 96% rename from java/src/game/enchantment/EnchantmentArrowDamage.java rename to java/src/common/enchantment/EnchantmentArrowDamage.java index 7d6b93e..0525e6a 100755 --- a/java/src/game/enchantment/EnchantmentArrowDamage.java +++ b/java/src/common/enchantment/EnchantmentArrowDamage.java @@ -1,4 +1,4 @@ -package game.enchantment; +package common.enchantment; diff --git a/java/src/game/enchantment/EnchantmentArrowFire.java b/java/src/common/enchantment/EnchantmentArrowFire.java similarity index 96% rename from java/src/game/enchantment/EnchantmentArrowFire.java rename to java/src/common/enchantment/EnchantmentArrowFire.java index 4e0121e..e5e2658 100755 --- a/java/src/game/enchantment/EnchantmentArrowFire.java +++ b/java/src/common/enchantment/EnchantmentArrowFire.java @@ -1,4 +1,4 @@ -package game.enchantment; +package common.enchantment; diff --git a/java/src/game/enchantment/EnchantmentArrowInfinite.java b/java/src/common/enchantment/EnchantmentArrowInfinite.java similarity index 96% rename from java/src/game/enchantment/EnchantmentArrowInfinite.java rename to java/src/common/enchantment/EnchantmentArrowInfinite.java index 7845109..860a44a 100755 --- a/java/src/game/enchantment/EnchantmentArrowInfinite.java +++ b/java/src/common/enchantment/EnchantmentArrowInfinite.java @@ -1,4 +1,4 @@ -package game.enchantment; +package common.enchantment; diff --git a/java/src/game/enchantment/EnchantmentArrowKnockback.java b/java/src/common/enchantment/EnchantmentArrowKnockback.java similarity index 96% rename from java/src/game/enchantment/EnchantmentArrowKnockback.java rename to java/src/common/enchantment/EnchantmentArrowKnockback.java index 3619294..2e15fae 100755 --- a/java/src/game/enchantment/EnchantmentArrowKnockback.java +++ b/java/src/common/enchantment/EnchantmentArrowKnockback.java @@ -1,4 +1,4 @@ -package game.enchantment; +package common.enchantment; diff --git a/java/src/game/enchantment/EnchantmentDamage.java b/java/src/common/enchantment/EnchantmentDamage.java similarity index 96% rename from java/src/game/enchantment/EnchantmentDamage.java rename to java/src/common/enchantment/EnchantmentDamage.java index ffe689f..9be0458 100755 --- a/java/src/game/enchantment/EnchantmentDamage.java +++ b/java/src/common/enchantment/EnchantmentDamage.java @@ -1,7 +1,7 @@ -package game.enchantment; +package common.enchantment; -import game.item.ItemAxe; -import game.item.ItemStack; +import common.item.ItemAxe; +import common.item.ItemStack; public class EnchantmentDamage extends Enchantment diff --git a/java/src/game/enchantment/EnchantmentDigging.java b/java/src/common/enchantment/EnchantmentDigging.java similarity index 92% rename from java/src/game/enchantment/EnchantmentDigging.java rename to java/src/common/enchantment/EnchantmentDigging.java index 32b3031..a504816 100755 --- a/java/src/game/enchantment/EnchantmentDigging.java +++ b/java/src/common/enchantment/EnchantmentDigging.java @@ -1,7 +1,7 @@ -package game.enchantment; +package common.enchantment; -import game.item.ItemShears; -import game.item.ItemStack; +import common.item.ItemShears; +import common.item.ItemStack; public class EnchantmentDigging extends Enchantment diff --git a/java/src/game/enchantment/EnchantmentDraining.java b/java/src/common/enchantment/EnchantmentDraining.java similarity index 85% rename from java/src/game/enchantment/EnchantmentDraining.java rename to java/src/common/enchantment/EnchantmentDraining.java index ed9f589..ec8be82 100755 --- a/java/src/game/enchantment/EnchantmentDraining.java +++ b/java/src/common/enchantment/EnchantmentDraining.java @@ -1,10 +1,10 @@ -package game.enchantment; +package common.enchantment; -import game.entity.DamageSource; -import game.entity.Entity; -import game.entity.types.EntityLiving; -import game.item.ItemAxe; -import game.item.ItemStack; +import common.entity.DamageSource; +import common.entity.Entity; +import common.entity.types.EntityLiving; +import common.item.ItemAxe; +import common.item.ItemStack; public class EnchantmentDraining extends Enchantment { diff --git a/java/src/game/enchantment/EnchantmentDurability.java b/java/src/common/enchantment/EnchantmentDurability.java similarity index 93% rename from java/src/game/enchantment/EnchantmentDurability.java rename to java/src/common/enchantment/EnchantmentDurability.java index a8854bb..8181411 100755 --- a/java/src/game/enchantment/EnchantmentDurability.java +++ b/java/src/common/enchantment/EnchantmentDurability.java @@ -1,8 +1,8 @@ -package game.enchantment; +package common.enchantment; -import game.item.ItemArmor; -import game.item.ItemStack; -import game.rng.Random; +import common.item.ItemArmor; +import common.item.ItemStack; +import common.rng.Random; public class EnchantmentDurability extends Enchantment diff --git a/java/src/game/enchantment/EnchantmentFireAspect.java b/java/src/common/enchantment/EnchantmentFireAspect.java similarity index 96% rename from java/src/game/enchantment/EnchantmentFireAspect.java rename to java/src/common/enchantment/EnchantmentFireAspect.java index 956374f..0e91e40 100755 --- a/java/src/game/enchantment/EnchantmentFireAspect.java +++ b/java/src/common/enchantment/EnchantmentFireAspect.java @@ -1,4 +1,4 @@ -package game.enchantment; +package common.enchantment; diff --git a/java/src/game/enchantment/EnchantmentFishingSpeed.java b/java/src/common/enchantment/EnchantmentFishingSpeed.java similarity index 96% rename from java/src/game/enchantment/EnchantmentFishingSpeed.java rename to java/src/common/enchantment/EnchantmentFishingSpeed.java index a1e4cc7..0ba0dd0 100755 --- a/java/src/game/enchantment/EnchantmentFishingSpeed.java +++ b/java/src/common/enchantment/EnchantmentFishingSpeed.java @@ -1,4 +1,4 @@ -package game.enchantment; +package common.enchantment; diff --git a/java/src/game/enchantment/EnchantmentHelper.java b/java/src/common/enchantment/EnchantmentHelper.java similarity index 97% rename from java/src/game/enchantment/EnchantmentHelper.java rename to java/src/common/enchantment/EnchantmentHelper.java index 6a74e6e..a6ce979 100755 --- a/java/src/game/enchantment/EnchantmentHelper.java +++ b/java/src/common/enchantment/EnchantmentHelper.java @@ -1,21 +1,21 @@ -package game.enchantment; +package common.enchantment; import java.util.Iterator; import java.util.List; import java.util.Map; -import game.collect.Lists; -import game.collect.Maps; -import game.entity.DamageSource; -import game.entity.Entity; -import game.entity.types.EntityLiving; -import game.init.Items; -import game.item.Item; -import game.item.ItemStack; -import game.nbt.NBTTagCompound; -import game.nbt.NBTTagList; -import game.rng.Random; -import game.rng.WeightedList; +import common.collect.Lists; +import common.collect.Maps; +import common.entity.DamageSource; +import common.entity.Entity; +import common.entity.types.EntityLiving; +import common.init.Items; +import common.item.Item; +import common.item.ItemStack; +import common.nbt.NBTTagCompound; +import common.nbt.NBTTagList; +import common.rng.Random; +import common.rng.WeightedList; public class EnchantmentHelper { diff --git a/java/src/game/enchantment/EnchantmentKnockback.java b/java/src/common/enchantment/EnchantmentKnockback.java similarity index 96% rename from java/src/game/enchantment/EnchantmentKnockback.java rename to java/src/common/enchantment/EnchantmentKnockback.java index 295f00a..5fd4642 100755 --- a/java/src/game/enchantment/EnchantmentKnockback.java +++ b/java/src/common/enchantment/EnchantmentKnockback.java @@ -1,4 +1,4 @@ -package game.enchantment; +package common.enchantment; diff --git a/java/src/game/enchantment/EnchantmentLootBonus.java b/java/src/common/enchantment/EnchantmentLootBonus.java similarity index 98% rename from java/src/game/enchantment/EnchantmentLootBonus.java rename to java/src/common/enchantment/EnchantmentLootBonus.java index 63b683a..036fdb8 100755 --- a/java/src/game/enchantment/EnchantmentLootBonus.java +++ b/java/src/common/enchantment/EnchantmentLootBonus.java @@ -1,4 +1,4 @@ -package game.enchantment; +package common.enchantment; diff --git a/java/src/game/enchantment/EnchantmentProtection.java b/java/src/common/enchantment/EnchantmentProtection.java similarity index 97% rename from java/src/game/enchantment/EnchantmentProtection.java rename to java/src/common/enchantment/EnchantmentProtection.java index 9c4d0fb..6cfe6bc 100755 --- a/java/src/game/enchantment/EnchantmentProtection.java +++ b/java/src/common/enchantment/EnchantmentProtection.java @@ -1,8 +1,8 @@ -package game.enchantment; +package common.enchantment; -import game.entity.DamageSource; -import game.entity.Entity; -import game.util.ExtMath; +import common.entity.DamageSource; +import common.entity.Entity; +import common.util.ExtMath; public class EnchantmentProtection extends Enchantment diff --git a/java/src/game/enchantment/EnchantmentThorns.java b/java/src/common/enchantment/EnchantmentThorns.java similarity index 90% rename from java/src/game/enchantment/EnchantmentThorns.java rename to java/src/common/enchantment/EnchantmentThorns.java index 67844c4..3693045 100755 --- a/java/src/game/enchantment/EnchantmentThorns.java +++ b/java/src/common/enchantment/EnchantmentThorns.java @@ -1,12 +1,12 @@ -package game.enchantment; +package common.enchantment; -import game.entity.DamageSource; -import game.entity.Entity; -import game.entity.types.EntityLiving; -import game.init.Config; -import game.item.ItemArmor; -import game.item.ItemStack; -import game.rng.Random; +import common.entity.DamageSource; +import common.entity.Entity; +import common.entity.types.EntityLiving; +import common.init.Config; +import common.item.ItemArmor; +import common.item.ItemStack; +import common.rng.Random; public class EnchantmentThorns extends Enchantment { diff --git a/java/src/game/enchantment/EnchantmentUntouching.java b/java/src/common/enchantment/EnchantmentUntouching.java similarity index 93% rename from java/src/game/enchantment/EnchantmentUntouching.java rename to java/src/common/enchantment/EnchantmentUntouching.java index 090d142..3508fca 100755 --- a/java/src/game/enchantment/EnchantmentUntouching.java +++ b/java/src/common/enchantment/EnchantmentUntouching.java @@ -1,7 +1,7 @@ -package game.enchantment; +package common.enchantment; -import game.item.ItemShears; -import game.item.ItemStack; +import common.item.ItemShears; +import common.item.ItemStack; public class EnchantmentUntouching extends Enchantment diff --git a/java/src/game/enchantment/EnumEnchantmentType.java b/java/src/common/enchantment/EnumEnchantmentType.java similarity index 86% rename from java/src/game/enchantment/EnumEnchantmentType.java rename to java/src/common/enchantment/EnumEnchantmentType.java index adc56dc..7c7e2c9 100755 --- a/java/src/game/enchantment/EnumEnchantmentType.java +++ b/java/src/common/enchantment/EnumEnchantmentType.java @@ -1,11 +1,11 @@ -package game.enchantment; +package common.enchantment; -import game.item.Item; -import game.item.ItemArmor; -import game.item.ItemBow; -import game.item.ItemFishingRod; -import game.item.ItemSword; -import game.item.ItemTool; +import common.item.Item; +import common.item.ItemArmor; +import common.item.ItemBow; +import common.item.ItemFishingRod; +import common.item.ItemSword; +import common.item.ItemTool; public enum EnumEnchantmentType { diff --git a/java/src/game/enchantment/RngEnchantment.java b/java/src/common/enchantment/RngEnchantment.java similarity index 89% rename from java/src/game/enchantment/RngEnchantment.java rename to java/src/common/enchantment/RngEnchantment.java index b945bde..d517860 100755 --- a/java/src/game/enchantment/RngEnchantment.java +++ b/java/src/common/enchantment/RngEnchantment.java @@ -1,6 +1,6 @@ -package game.enchantment; +package common.enchantment; -import game.rng.RngItem; +import common.rng.RngItem; public class RngEnchantment extends RngItem { diff --git a/java/src/game/entity/DamageSource.java b/java/src/common/entity/DamageSource.java similarity index 98% rename from java/src/game/entity/DamageSource.java rename to java/src/common/entity/DamageSource.java index abb897f..e46f59b 100755 --- a/java/src/game/entity/DamageSource.java +++ b/java/src/common/entity/DamageSource.java @@ -1,9 +1,9 @@ -package game.entity; +package common.entity; -import game.color.TextColor; -import game.entity.projectile.EntityProjectile; -import game.entity.types.EntityLiving; -import game.world.Explosion; +import common.color.TextColor; +import common.entity.projectile.EntityProjectile; +import common.entity.types.EntityLiving; +import common.world.Explosion; public class DamageSource { diff --git a/java/src/game/entity/DataWatcher.java b/java/src/common/entity/DataWatcher.java similarity index 98% rename from java/src/game/entity/DataWatcher.java rename to java/src/common/entity/DataWatcher.java index bc7f2a7..7b061b3 100755 --- a/java/src/game/entity/DataWatcher.java +++ b/java/src/common/entity/DataWatcher.java @@ -1,4 +1,4 @@ -package game.entity; +package common.entity; import java.io.IOException; import java.util.List; @@ -6,11 +6,11 @@ import java.util.Map; import java.util.concurrent.locks.ReadWriteLock; import java.util.concurrent.locks.ReentrantReadWriteLock; -import game.collect.Lists; -import game.collect.Maps; -import game.item.ItemStack; -import game.network.PacketBuffer; -import game.world.BlockPos; +import common.collect.Lists; +import common.collect.Maps; +import common.item.ItemStack; +import common.network.PacketBuffer; +import common.world.BlockPos; public class DataWatcher { private static final Map, Integer> dataTypes = Maps., Integer>newHashMap(); diff --git a/java/src/game/entity/Entity.java b/java/src/common/entity/Entity.java similarity index 98% rename from java/src/game/entity/Entity.java rename to java/src/common/entity/Entity.java index 331864e..0daa035 100755 --- a/java/src/game/entity/Entity.java +++ b/java/src/common/entity/Entity.java @@ -1,49 +1,49 @@ -package game.entity; +package common.entity; import java.util.List; -import game.block.Block; -import game.block.BlockFence; -import game.block.BlockFenceGate; -import game.block.BlockLiquid; -import game.block.BlockWall; -import game.block.SoundType; -import game.color.TextColor; -import game.dimension.DimType; -import game.enchantment.EnchantmentHelper; -import game.enchantment.EnchantmentProtection; -import game.entity.effect.EntityLightning; -import game.entity.item.EntityItem; -import game.entity.npc.EntityNPC; -import game.entity.types.EntityLiving; -import game.init.BlockRegistry; -import game.init.Blocks; -import game.init.Config; -import game.init.EntityRegistry; -import game.init.ItemRegistry; -import game.init.SoundEvent; -import game.init.UniverseRegistry; -import game.item.Item; -import game.item.ItemStack; -import game.material.Material; -import game.model.ParticleType; -import game.nbt.NBTTagCompound; -import game.nbt.NBTTagDouble; -import game.nbt.NBTTagFloat; -import game.nbt.NBTTagList; -import game.rng.Random; -import game.util.ExtMath; -import game.world.BlockPos; -import game.world.BoundingBox; -import game.world.Explosion; -import game.world.Facing; -import game.world.HitPosition; -import game.world.PortalType; -import game.world.Position; -import game.world.State; -import game.world.Vec3; -import game.world.World; -import game.world.WorldServer; +import common.block.Block; +import common.block.BlockFence; +import common.block.BlockFenceGate; +import common.block.BlockLiquid; +import common.block.BlockWall; +import common.block.SoundType; +import common.color.TextColor; +import common.dimension.DimType; +import common.enchantment.EnchantmentHelper; +import common.enchantment.EnchantmentProtection; +import common.entity.effect.EntityLightning; +import common.entity.item.EntityItem; +import common.entity.npc.EntityNPC; +import common.entity.types.EntityLiving; +import common.init.BlockRegistry; +import common.init.Blocks; +import common.init.Config; +import common.init.EntityRegistry; +import common.init.ItemRegistry; +import common.init.SoundEvent; +import common.init.UniverseRegistry; +import common.item.Item; +import common.item.ItemStack; +import common.material.Material; +import common.model.ParticleType; +import common.nbt.NBTTagCompound; +import common.nbt.NBTTagDouble; +import common.nbt.NBTTagFloat; +import common.nbt.NBTTagList; +import common.rng.Random; +import common.util.ExtMath; +import common.world.BlockPos; +import common.world.BoundingBox; +import common.world.Explosion; +import common.world.Facing; +import common.world.HitPosition; +import common.world.PortalType; +import common.world.Position; +import common.world.State; +import common.world.Vec3; +import common.world.World; +import common.world.WorldServer; public abstract class Entity { diff --git a/java/src/game/entity/EntityDamageSource.java b/java/src/common/entity/EntityDamageSource.java similarity index 94% rename from java/src/game/entity/EntityDamageSource.java rename to java/src/common/entity/EntityDamageSource.java index ecb22c7..971a33c 100755 --- a/java/src/game/entity/EntityDamageSource.java +++ b/java/src/common/entity/EntityDamageSource.java @@ -1,8 +1,8 @@ -package game.entity; +package common.entity; -import game.color.TextColor; -import game.entity.types.EntityLiving; -import game.item.ItemStack; +import common.color.TextColor; +import common.entity.types.EntityLiving; +import common.item.ItemStack; public class EntityDamageSource extends DamageSource { diff --git a/java/src/game/entity/EntityDamageSourceIndirect.java b/java/src/common/entity/EntityDamageSourceIndirect.java similarity index 92% rename from java/src/game/entity/EntityDamageSourceIndirect.java rename to java/src/common/entity/EntityDamageSourceIndirect.java index a50bb18..a28b70a 100755 --- a/java/src/game/entity/EntityDamageSourceIndirect.java +++ b/java/src/common/entity/EntityDamageSourceIndirect.java @@ -1,8 +1,8 @@ -package game.entity; +package common.entity; -import game.color.TextColor; -import game.entity.types.EntityLiving; -import game.item.ItemStack; +import common.color.TextColor; +import common.entity.types.EntityLiving; +import common.item.ItemStack; public class EntityDamageSourceIndirect extends EntityDamageSource { diff --git a/java/src/game/entity/EntityTrackerEntry.java b/java/src/common/entity/EntityTrackerEntry.java similarity index 93% rename from java/src/game/entity/EntityTrackerEntry.java rename to java/src/common/entity/EntityTrackerEntry.java index e661a3d..f70867f 100755 --- a/java/src/game/entity/EntityTrackerEntry.java +++ b/java/src/common/entity/EntityTrackerEntry.java @@ -1,34 +1,34 @@ -package game.entity; +package common.entity; import java.util.Collection; import java.util.List; import java.util.Set; -import game.collect.Sets; -import game.entity.attributes.AttributeInstance; -import game.entity.attributes.AttributeMap; -import game.entity.npc.EntityNPC; -import game.entity.projectile.EntityArrow; -import game.entity.types.EntityLiving; -import game.item.ItemStack; -import game.log.Log; -import game.nbt.NBTTagCompound; -import game.network.Packet; -import game.packet.S14PacketEntity; -import game.packet.S18PacketEntityTeleport; -import game.packet.S19PacketEntityHeadLook; -import game.packet.S1BPacketEntityAttach; -import game.packet.S1CPacketEntityMetadata; -import game.packet.S1DPacketEntityEffect; -import game.packet.S20PacketEntityProperties; -import game.packet.S43PacketUpdateEntityNBT; -import game.packet.SPacketEntityEquipment; -import game.packet.SPacketEntityVelocity; -import game.packet.SPacketSpawnMob; -import game.packet.SPacketSpawnObject; -import game.packet.SPacketSpawnPlayer; -import game.potion.PotionEffect; -import game.util.ExtMath; +import common.collect.Sets; +import common.entity.attributes.AttributeInstance; +import common.entity.attributes.AttributeMap; +import common.entity.npc.EntityNPC; +import common.entity.projectile.EntityArrow; +import common.entity.types.EntityLiving; +import common.item.ItemStack; +import common.log.Log; +import common.nbt.NBTTagCompound; +import common.network.Packet; +import common.packet.S14PacketEntity; +import common.packet.S18PacketEntityTeleport; +import common.packet.S19PacketEntityHeadLook; +import common.packet.S1BPacketEntityAttach; +import common.packet.S1CPacketEntityMetadata; +import common.packet.S1DPacketEntityEffect; +import common.packet.S20PacketEntityProperties; +import common.packet.S43PacketUpdateEntityNBT; +import common.packet.SPacketEntityEquipment; +import common.packet.SPacketEntityVelocity; +import common.packet.SPacketSpawnMob; +import common.packet.SPacketSpawnObject; +import common.packet.SPacketSpawnPlayer; +import common.potion.PotionEffect; +import common.util.ExtMath; public class EntityTrackerEntry { public final Entity trackedEntity; diff --git a/java/src/game/entity/EntityType.java b/java/src/common/entity/EntityType.java similarity index 93% rename from java/src/game/entity/EntityType.java rename to java/src/common/entity/EntityType.java index 55ca7fe..1bfbfd7 100644 --- a/java/src/game/entity/EntityType.java +++ b/java/src/common/entity/EntityType.java @@ -1,8 +1,8 @@ -package game.entity; +package common.entity; import java.util.Map; -import game.collect.Maps; +import common.collect.Maps; public enum EntityType { OBJECT("Object", "Objekt"), diff --git a/java/src/game/entity/animal/EntityBat.java b/java/src/common/entity/animal/EntityBat.java similarity index 95% rename from java/src/game/entity/animal/EntityBat.java rename to java/src/common/entity/animal/EntityBat.java index 7478685..7f30243 100755 --- a/java/src/game/entity/animal/EntityBat.java +++ b/java/src/common/entity/animal/EntityBat.java @@ -1,17 +1,17 @@ -package game.entity.animal; +package common.entity.animal; -import game.block.Block; -import game.entity.DamageSource; -import game.entity.Entity; -import game.entity.EntityType; -import game.entity.npc.Alignment; -import game.entity.npc.EntityNPC; -import game.entity.types.EntityLiving; -import game.init.SoundEvent; -import game.nbt.NBTTagCompound; -import game.util.ExtMath; -import game.world.BlockPos; -import game.world.World; +import common.block.Block; +import common.entity.DamageSource; +import common.entity.Entity; +import common.entity.EntityType; +import common.entity.npc.Alignment; +import common.entity.npc.EntityNPC; +import common.entity.types.EntityLiving; +import common.init.SoundEvent; +import common.nbt.NBTTagCompound; +import common.util.ExtMath; +import common.world.BlockPos; +import common.world.World; public class EntityBat extends EntityLiving { diff --git a/java/src/game/entity/animal/EntityChicken.java b/java/src/common/entity/animal/EntityChicken.java similarity index 90% rename from java/src/game/entity/animal/EntityChicken.java rename to java/src/common/entity/animal/EntityChicken.java index dd39420..c809c9f 100755 --- a/java/src/game/entity/animal/EntityChicken.java +++ b/java/src/common/entity/animal/EntityChicken.java @@ -1,25 +1,25 @@ -package game.entity.animal; +package common.entity.animal; -import game.ai.EntityAIFollowParent; -import game.ai.EntityAILookIdle; -import game.ai.EntityAIMate; -import game.ai.EntityAIPanic; -import game.ai.EntityAISwimming; -import game.ai.EntityAITempt; -import game.ai.EntityAIWander; -import game.ai.EntityAIWatchClosest; -import game.entity.attributes.Attributes; -import game.entity.npc.EntityNPC; -import game.entity.types.EntityAnimal; -import game.entity.types.EntityLiving; -import game.init.Config; -import game.init.Items; -import game.init.SoundEvent; -import game.item.Item; -import game.item.ItemStack; -import game.nbt.NBTTagCompound; -import game.util.ExtMath; -import game.world.World; +import common.ai.EntityAIFollowParent; +import common.ai.EntityAILookIdle; +import common.ai.EntityAIMate; +import common.ai.EntityAIPanic; +import common.ai.EntityAISwimming; +import common.ai.EntityAITempt; +import common.ai.EntityAIWander; +import common.ai.EntityAIWatchClosest; +import common.entity.attributes.Attributes; +import common.entity.npc.EntityNPC; +import common.entity.types.EntityAnimal; +import common.entity.types.EntityLiving; +import common.init.Config; +import common.init.Items; +import common.init.SoundEvent; +import common.item.Item; +import common.item.ItemStack; +import common.nbt.NBTTagCompound; +import common.util.ExtMath; +import common.world.World; public class EntityChicken extends EntityAnimal { diff --git a/java/src/game/entity/animal/EntityCow.java b/java/src/common/entity/animal/EntityCow.java similarity index 85% rename from java/src/game/entity/animal/EntityCow.java rename to java/src/common/entity/animal/EntityCow.java index 84bef6e..cadd0a3 100755 --- a/java/src/game/entity/animal/EntityCow.java +++ b/java/src/common/entity/animal/EntityCow.java @@ -1,23 +1,23 @@ -package game.entity.animal; +package common.entity.animal; -import game.ai.EntityAIFollowParent; -import game.ai.EntityAILookIdle; -import game.ai.EntityAIMate; -import game.ai.EntityAIPanic; -import game.ai.EntityAISwimming; -import game.ai.EntityAITempt; -import game.ai.EntityAIWander; -import game.ai.EntityAIWatchClosest; -import game.entity.attributes.Attributes; -import game.entity.npc.EntityNPC; -import game.entity.types.EntityAnimal; -import game.entity.types.EntityLiving; -import game.init.Items; -import game.init.SoundEvent; -import game.item.Item; -import game.item.ItemStack; -import game.pathfinding.PathNavigateGround; -import game.world.World; +import common.ai.EntityAIFollowParent; +import common.ai.EntityAILookIdle; +import common.ai.EntityAIMate; +import common.ai.EntityAIPanic; +import common.ai.EntityAISwimming; +import common.ai.EntityAITempt; +import common.ai.EntityAIWander; +import common.ai.EntityAIWatchClosest; +import common.entity.attributes.Attributes; +import common.entity.npc.EntityNPC; +import common.entity.types.EntityAnimal; +import common.entity.types.EntityLiving; +import common.init.Items; +import common.init.SoundEvent; +import common.item.Item; +import common.item.ItemStack; +import common.pathfinding.PathNavigateGround; +import common.world.World; public class EntityCow extends EntityAnimal { diff --git a/java/src/game/entity/animal/EntityDragon.java b/java/src/common/entity/animal/EntityDragon.java similarity index 97% rename from java/src/game/entity/animal/EntityDragon.java rename to java/src/common/entity/animal/EntityDragon.java index 4084f10..dc1953e 100755 --- a/java/src/game/entity/animal/EntityDragon.java +++ b/java/src/common/entity/animal/EntityDragon.java @@ -1,22 +1,22 @@ -package game.entity.animal; +package common.entity.animal; import java.util.List; -import game.collect.Lists; -import game.entity.DamageSource; -import game.entity.Entity; -import game.entity.EntityType; -import game.entity.npc.Alignment; -import game.entity.npc.EntityNPC; -import game.entity.types.EntityLiving; -import game.entity.types.IEntityMultiPart; -import game.init.Config; -import game.init.SoundEvent; -import game.model.ParticleType; -import game.util.ExtMath; -import game.world.Vec3; -import game.world.World; -import game.world.WorldClient; +import common.collect.Lists; +import common.entity.DamageSource; +import common.entity.Entity; +import common.entity.EntityType; +import common.entity.npc.Alignment; +import common.entity.npc.EntityNPC; +import common.entity.types.EntityLiving; +import common.entity.types.IEntityMultiPart; +import common.init.Config; +import common.init.SoundEvent; +import common.model.ParticleType; +import common.util.ExtMath; +import common.world.Vec3; +import common.world.World; +import common.world.WorldClient; public class EntityDragon extends EntityLiving implements IEntityMultiPart { diff --git a/java/src/game/entity/animal/EntityDragonPart.java b/java/src/common/entity/animal/EntityDragonPart.java similarity index 89% rename from java/src/game/entity/animal/EntityDragonPart.java rename to java/src/common/entity/animal/EntityDragonPart.java index 3f9bf65..c78dc53 100755 --- a/java/src/game/entity/animal/EntityDragonPart.java +++ b/java/src/common/entity/animal/EntityDragonPart.java @@ -1,10 +1,10 @@ -package game.entity.animal; +package common.entity.animal; -import game.entity.DamageSource; -import game.entity.Entity; -import game.entity.EntityType; -import game.entity.types.IEntityMultiPart; -import game.nbt.NBTTagCompound; +import common.entity.DamageSource; +import common.entity.Entity; +import common.entity.EntityType; +import common.entity.types.IEntityMultiPart; +import common.nbt.NBTTagCompound; public class EntityDragonPart extends Entity { diff --git a/java/src/game/entity/animal/EntityHorse.java b/java/src/common/entity/animal/EntityHorse.java similarity index 97% rename from java/src/game/entity/animal/EntityHorse.java rename to java/src/common/entity/animal/EntityHorse.java index 515a0e5..041aa2a 100755 --- a/java/src/game/entity/animal/EntityHorse.java +++ b/java/src/common/entity/animal/EntityHorse.java @@ -1,44 +1,44 @@ -package game.entity.animal; +package common.entity.animal; import java.util.function.Predicate; -import game.ai.EntityAIFollowParent; -import game.ai.EntityAILookIdle; -import game.ai.EntityAIMate; -import game.ai.EntityAIPanic; -import game.ai.EntityAIRunAroundLikeCrazy; -import game.ai.EntityAISwimming; -import game.ai.EntityAIWander; -import game.ai.EntityAIWatchClosest; -import game.block.Block; -import game.block.SoundType; -import game.entity.DamageSource; -import game.entity.Entity; -import game.entity.attributes.AttributeInstance; -import game.entity.attributes.Attributes; -import game.entity.npc.EntityNPC; -import game.entity.types.EntityAnimal; -import game.entity.types.EntityLiving; -import game.init.Blocks; -import game.init.Config; -import game.init.ItemRegistry; -import game.init.Items; -import game.init.SoundEvent; -import game.inventory.AnimalChest; -import game.inventory.IInvBasic; -import game.inventory.InventoryBasic; -import game.item.Item; -import game.item.ItemMonsterPlacer; -import game.item.ItemStack; -import game.material.Material; -import game.model.ParticleType; -import game.nbt.NBTTagCompound; -import game.nbt.NBTTagList; -import game.pathfinding.PathNavigateGround; -import game.potion.Potion; -import game.util.ExtMath; -import game.world.BlockPos; -import game.world.World; +import common.ai.EntityAIFollowParent; +import common.ai.EntityAILookIdle; +import common.ai.EntityAIMate; +import common.ai.EntityAIPanic; +import common.ai.EntityAIRunAroundLikeCrazy; +import common.ai.EntityAISwimming; +import common.ai.EntityAIWander; +import common.ai.EntityAIWatchClosest; +import common.block.Block; +import common.block.SoundType; +import common.entity.DamageSource; +import common.entity.Entity; +import common.entity.attributes.AttributeInstance; +import common.entity.attributes.Attributes; +import common.entity.npc.EntityNPC; +import common.entity.types.EntityAnimal; +import common.entity.types.EntityLiving; +import common.init.Blocks; +import common.init.Config; +import common.init.ItemRegistry; +import common.init.Items; +import common.init.SoundEvent; +import common.inventory.AnimalChest; +import common.inventory.IInvBasic; +import common.inventory.InventoryBasic; +import common.item.Item; +import common.item.ItemMonsterPlacer; +import common.item.ItemStack; +import common.material.Material; +import common.model.ParticleType; +import common.nbt.NBTTagCompound; +import common.nbt.NBTTagList; +import common.pathfinding.PathNavigateGround; +import common.potion.Potion; +import common.util.ExtMath; +import common.world.BlockPos; +import common.world.World; public class EntityHorse extends EntityAnimal implements IInvBasic { diff --git a/java/src/game/entity/animal/EntityMooshroom.java b/java/src/common/entity/animal/EntityMooshroom.java similarity index 88% rename from java/src/game/entity/animal/EntityMooshroom.java rename to java/src/common/entity/animal/EntityMooshroom.java index 3b57c9b..b87afa5 100755 --- a/java/src/game/entity/animal/EntityMooshroom.java +++ b/java/src/common/entity/animal/EntityMooshroom.java @@ -1,15 +1,15 @@ -package game.entity.animal; +package common.entity.animal; -import game.entity.item.EntityItem; -import game.entity.npc.EntityNPC; -import game.entity.types.EntityLiving; -import game.init.Blocks; -import game.init.Items; -import game.init.SoundEvent; -import game.item.ItemShears; -import game.item.ItemStack; -import game.model.ParticleType; -import game.world.World; +import common.entity.item.EntityItem; +import common.entity.npc.EntityNPC; +import common.entity.types.EntityLiving; +import common.init.Blocks; +import common.init.Items; +import common.init.SoundEvent; +import common.item.ItemShears; +import common.item.ItemStack; +import common.model.ParticleType; +import common.world.World; public class EntityMooshroom extends EntityCow { diff --git a/java/src/game/entity/animal/EntityMouse.java b/java/src/common/entity/animal/EntityMouse.java similarity index 80% rename from java/src/game/entity/animal/EntityMouse.java rename to java/src/common/entity/animal/EntityMouse.java index f1c803f..86195f2 100755 --- a/java/src/game/entity/animal/EntityMouse.java +++ b/java/src/common/entity/animal/EntityMouse.java @@ -1,27 +1,27 @@ -package game.entity.animal; +package common.entity.animal; import java.util.Collections; -import game.ai.EntityAIFollowParent; -import game.ai.EntityAILookIdle; -import game.ai.EntityAIMate; -import game.ai.EntityAIPanic; -import game.ai.EntityAISwimming; -import game.ai.EntityAITempt; -import game.ai.EntityAIWander; -import game.ai.EntityAIWatchClosest; -import game.block.Block; -import game.entity.attributes.AttributeInstance; -import game.entity.attributes.Attributes; -import game.entity.npc.EntityNPC; -import game.entity.types.EntityAnimal; -import game.entity.types.EntityLiving; -import game.init.Blocks; -import game.init.Items; -import game.init.SoundEvent; -import game.item.ItemStack; -import game.world.BlockPos; -import game.world.World; +import common.ai.EntityAIFollowParent; +import common.ai.EntityAILookIdle; +import common.ai.EntityAIMate; +import common.ai.EntityAIPanic; +import common.ai.EntityAISwimming; +import common.ai.EntityAITempt; +import common.ai.EntityAIWander; +import common.ai.EntityAIWatchClosest; +import common.block.Block; +import common.entity.attributes.AttributeInstance; +import common.entity.attributes.Attributes; +import common.entity.npc.EntityNPC; +import common.entity.types.EntityAnimal; +import common.entity.types.EntityLiving; +import common.init.Blocks; +import common.init.Items; +import common.init.SoundEvent; +import common.item.ItemStack; +import common.world.BlockPos; +import common.world.World; public class EntityMouse extends EntityAnimal { public EntityMouse(World world) { diff --git a/java/src/game/entity/animal/EntityOcelot.java b/java/src/common/entity/animal/EntityOcelot.java similarity index 92% rename from java/src/game/entity/animal/EntityOcelot.java rename to java/src/common/entity/animal/EntityOcelot.java index 85b685c..78acf63 100755 --- a/java/src/game/entity/animal/EntityOcelot.java +++ b/java/src/common/entity/animal/EntityOcelot.java @@ -1,34 +1,34 @@ -package game.entity.animal; +package common.entity.animal; import java.util.function.Predicate; -import game.ai.EntityAIAvoidEntity; -import game.ai.EntityAIFollowOwner; -import game.ai.EntityAILeapAtTarget; -import game.ai.EntityAIMate; -import game.ai.EntityAIOcelotAttack; -import game.ai.EntityAIOcelotSit; -import game.ai.EntityAISwimming; -import game.ai.EntityAITargetNonTamed; -import game.ai.EntityAITempt; -import game.ai.EntityAIWander; -import game.ai.EntityAIWatchClosest; -import game.entity.DamageSource; -import game.entity.Entity; -import game.entity.attributes.Attributes; -import game.entity.npc.Alignment; -import game.entity.npc.EntityNPC; -import game.entity.types.EntityAnimal; -import game.entity.types.EntityLiving; -import game.entity.types.EntityTameable; -import game.init.Config; -import game.init.Items; -import game.init.SoundEvent; -import game.item.Item; -import game.item.ItemStack; -import game.nbt.NBTTagCompound; -import game.pathfinding.PathNavigateGround; -import game.world.World; +import common.ai.EntityAIAvoidEntity; +import common.ai.EntityAIFollowOwner; +import common.ai.EntityAILeapAtTarget; +import common.ai.EntityAIMate; +import common.ai.EntityAIOcelotAttack; +import common.ai.EntityAIOcelotSit; +import common.ai.EntityAISwimming; +import common.ai.EntityAITargetNonTamed; +import common.ai.EntityAITempt; +import common.ai.EntityAIWander; +import common.ai.EntityAIWatchClosest; +import common.entity.DamageSource; +import common.entity.Entity; +import common.entity.attributes.Attributes; +import common.entity.npc.Alignment; +import common.entity.npc.EntityNPC; +import common.entity.types.EntityAnimal; +import common.entity.types.EntityLiving; +import common.entity.types.EntityTameable; +import common.init.Config; +import common.init.Items; +import common.init.SoundEvent; +import common.item.Item; +import common.item.ItemStack; +import common.nbt.NBTTagCompound; +import common.pathfinding.PathNavigateGround; +import common.world.World; public class EntityOcelot extends EntityTameable { diff --git a/java/src/game/entity/animal/EntityPig.java b/java/src/common/entity/animal/EntityPig.java similarity index 90% rename from java/src/game/entity/animal/EntityPig.java rename to java/src/common/entity/animal/EntityPig.java index 6a9e189..b094e99 100755 --- a/java/src/game/entity/animal/EntityPig.java +++ b/java/src/common/entity/animal/EntityPig.java @@ -1,25 +1,25 @@ -package game.entity.animal; +package common.entity.animal; -import game.ai.EntityAIControlledByPlayer; -import game.ai.EntityAIFollowParent; -import game.ai.EntityAILookIdle; -import game.ai.EntityAIMate; -import game.ai.EntityAIPanic; -import game.ai.EntityAISwimming; -import game.ai.EntityAITempt; -import game.ai.EntityAIWander; -import game.ai.EntityAIWatchClosest; -import game.entity.attributes.Attributes; -import game.entity.npc.EntityNPC; -import game.entity.types.EntityAnimal; -import game.entity.types.EntityLiving; -import game.init.Items; -import game.init.SoundEvent; -import game.item.Item; -import game.item.ItemStack; -import game.nbt.NBTTagCompound; -import game.pathfinding.PathNavigateGround; -import game.world.World; +import common.ai.EntityAIControlledByPlayer; +import common.ai.EntityAIFollowParent; +import common.ai.EntityAILookIdle; +import common.ai.EntityAIMate; +import common.ai.EntityAIPanic; +import common.ai.EntityAISwimming; +import common.ai.EntityAITempt; +import common.ai.EntityAIWander; +import common.ai.EntityAIWatchClosest; +import common.entity.attributes.Attributes; +import common.entity.npc.EntityNPC; +import common.entity.types.EntityAnimal; +import common.entity.types.EntityLiving; +import common.init.Items; +import common.init.SoundEvent; +import common.item.Item; +import common.item.ItemStack; +import common.nbt.NBTTagCompound; +import common.pathfinding.PathNavigateGround; +import common.world.World; public class EntityPig extends EntityAnimal { diff --git a/java/src/game/entity/animal/EntityRabbit.java b/java/src/common/entity/animal/EntityRabbit.java similarity index 92% rename from java/src/game/entity/animal/EntityRabbit.java rename to java/src/common/entity/animal/EntityRabbit.java index 1a58e41..49e09cf 100755 --- a/java/src/game/entity/animal/EntityRabbit.java +++ b/java/src/common/entity/animal/EntityRabbit.java @@ -1,48 +1,48 @@ -package game.entity.animal; +package common.entity.animal; import java.util.function.Predicate; -import game.ai.EntityAIAttackOnCollide; -import game.ai.EntityAIAvoidEntity; -import game.ai.EntityAIHurtByTarget; -import game.ai.EntityAIMate; -import game.ai.EntityAIMoveToBlock; -import game.ai.EntityAINearestAttackableTarget; -import game.ai.EntityAIPanic; -import game.ai.EntityAISwimming; -import game.ai.EntityAITempt; -import game.ai.EntityAIWander; -import game.ai.EntityAIWatchClosest; -import game.ai.EntityJumpHelper; -import game.ai.EntityMoveHelper; -import game.block.Block; -import game.block.BlockTallGrass; -import game.entity.DamageSource; -import game.entity.Entity; -import game.entity.attributes.Attributes; -import game.entity.npc.Alignment; -import game.entity.npc.EntityNPC; -import game.entity.types.EntityAnimal; -import game.entity.types.EntityLiving; -import game.init.BlockRegistry; -import game.init.Blocks; -import game.init.Config; -import game.init.ItemRegistry; -import game.init.Items; -import game.init.SoundEvent; -import game.item.Item; -import game.item.ItemStack; -import game.model.ParticleType; -import game.nbt.NBTTagCompound; -import game.pathfinding.PathEntity; -import game.pathfinding.PathNavigateGround; -import game.potion.Potion; -import game.potion.PotionEffect; -import game.util.ExtMath; -import game.world.BlockPos; -import game.world.State; -import game.world.Vec3; -import game.world.World; +import common.ai.EntityAIAttackOnCollide; +import common.ai.EntityAIAvoidEntity; +import common.ai.EntityAIHurtByTarget; +import common.ai.EntityAIMate; +import common.ai.EntityAIMoveToBlock; +import common.ai.EntityAINearestAttackableTarget; +import common.ai.EntityAIPanic; +import common.ai.EntityAISwimming; +import common.ai.EntityAITempt; +import common.ai.EntityAIWander; +import common.ai.EntityAIWatchClosest; +import common.ai.EntityJumpHelper; +import common.ai.EntityMoveHelper; +import common.block.Block; +import common.block.BlockTallGrass; +import common.entity.DamageSource; +import common.entity.Entity; +import common.entity.attributes.Attributes; +import common.entity.npc.Alignment; +import common.entity.npc.EntityNPC; +import common.entity.types.EntityAnimal; +import common.entity.types.EntityLiving; +import common.init.BlockRegistry; +import common.init.Blocks; +import common.init.Config; +import common.init.ItemRegistry; +import common.init.Items; +import common.init.SoundEvent; +import common.item.Item; +import common.item.ItemStack; +import common.model.ParticleType; +import common.nbt.NBTTagCompound; +import common.pathfinding.PathEntity; +import common.pathfinding.PathNavigateGround; +import common.potion.Potion; +import common.potion.PotionEffect; +import common.util.ExtMath; +import common.world.BlockPos; +import common.world.State; +import common.world.Vec3; +import common.world.World; public class EntityRabbit extends EntityAnimal { private static final int TYPES = 10; diff --git a/java/src/game/entity/animal/EntitySheep.java b/java/src/common/entity/animal/EntitySheep.java similarity index 91% rename from java/src/game/entity/animal/EntitySheep.java rename to java/src/common/entity/animal/EntitySheep.java index 71f19b8..2c2ab93 100755 --- a/java/src/game/entity/animal/EntitySheep.java +++ b/java/src/common/entity/animal/EntitySheep.java @@ -1,39 +1,39 @@ -package game.entity.animal; +package common.entity.animal; import java.util.Map; -import game.ai.EntityAIEatGrass; -import game.ai.EntityAIFollowParent; -import game.ai.EntityAILookIdle; -import game.ai.EntityAIMate; -import game.ai.EntityAIPanic; -import game.ai.EntityAISwimming; -import game.ai.EntityAITempt; -import game.ai.EntityAIWander; -import game.ai.EntityAIWatchClosest; -import game.biome.Biome; -import game.collect.Maps; -import game.color.DyeColor; -import game.entity.attributes.Attributes; -import game.entity.item.EntityItem; -import game.entity.npc.EntityNPC; -import game.entity.types.EntityAnimal; -import game.entity.types.EntityLiving; -import game.init.Blocks; -import game.init.CraftingRegistry; -import game.init.ItemRegistry; -import game.init.Items; -import game.init.SoundEvent; -import game.inventory.Container; -import game.inventory.InventoryCrafting; -import game.item.Item; -import game.item.ItemShears; -import game.item.ItemStack; -import game.nbt.NBTTagCompound; -import game.pathfinding.PathNavigateGround; -import game.rng.Random; -import game.util.ExtMath; -import game.world.World; +import common.ai.EntityAIEatGrass; +import common.ai.EntityAIFollowParent; +import common.ai.EntityAILookIdle; +import common.ai.EntityAIMate; +import common.ai.EntityAIPanic; +import common.ai.EntityAISwimming; +import common.ai.EntityAITempt; +import common.ai.EntityAIWander; +import common.ai.EntityAIWatchClosest; +import common.biome.Biome; +import common.collect.Maps; +import common.color.DyeColor; +import common.entity.attributes.Attributes; +import common.entity.item.EntityItem; +import common.entity.npc.EntityNPC; +import common.entity.types.EntityAnimal; +import common.entity.types.EntityLiving; +import common.init.Blocks; +import common.init.CraftingRegistry; +import common.init.ItemRegistry; +import common.init.Items; +import common.init.SoundEvent; +import common.inventory.Container; +import common.inventory.InventoryCrafting; +import common.item.Item; +import common.item.ItemShears; +import common.item.ItemStack; +import common.nbt.NBTTagCompound; +import common.pathfinding.PathNavigateGround; +import common.rng.Random; +import common.util.ExtMath; +import common.world.World; public class EntitySheep extends EntityAnimal { diff --git a/java/src/game/entity/animal/EntitySquid.java b/java/src/common/entity/animal/EntitySquid.java similarity index 96% rename from java/src/game/entity/animal/EntitySquid.java rename to java/src/common/entity/animal/EntitySquid.java index 22ccf33..1650e15 100755 --- a/java/src/game/entity/animal/EntitySquid.java +++ b/java/src/common/entity/animal/EntitySquid.java @@ -1,15 +1,15 @@ -package game.entity.animal; +package common.entity.animal; -import game.ai.EntityAIBase; -import game.color.DyeColor; -import game.entity.npc.Alignment; -import game.entity.types.EntityWaterMob; -import game.init.Items; -import game.init.SoundEvent; -import game.item.Item; -import game.item.ItemStack; -import game.util.ExtMath; -import game.world.World; +import common.ai.EntityAIBase; +import common.color.DyeColor; +import common.entity.npc.Alignment; +import common.entity.types.EntityWaterMob; +import common.init.Items; +import common.init.SoundEvent; +import common.item.Item; +import common.item.ItemStack; +import common.util.ExtMath; +import common.world.World; public class EntitySquid extends EntityWaterMob { diff --git a/java/src/game/entity/animal/EntityWolf.java b/java/src/common/entity/animal/EntityWolf.java similarity index 94% rename from java/src/game/entity/animal/EntityWolf.java rename to java/src/common/entity/animal/EntityWolf.java index 5f2ddd7..c99ffad 100755 --- a/java/src/game/entity/animal/EntityWolf.java +++ b/java/src/common/entity/animal/EntityWolf.java @@ -1,40 +1,40 @@ -package game.entity.animal; +package common.entity.animal; import java.util.function.Predicate; -import game.ai.EntityAIAttackOnCollide; -import game.ai.EntityAIBeg; -import game.ai.EntityAIFollowOwner; -import game.ai.EntityAIHurtByTarget; -import game.ai.EntityAILeapAtTarget; -import game.ai.EntityAILookIdle; -import game.ai.EntityAIMate; -import game.ai.EntityAIOwnerHurtByTarget; -import game.ai.EntityAIOwnerHurtTarget; -import game.ai.EntityAISwimming; -import game.ai.EntityAITargetNonTamed; -import game.ai.EntityAIWander; -import game.ai.EntityAIWatchClosest; -import game.color.DyeColor; -import game.entity.DamageSource; -import game.entity.Entity; -import game.entity.attributes.Attributes; -import game.entity.npc.Alignment; -import game.entity.npc.EntityNPC; -import game.entity.types.EntityAnimal; -import game.entity.types.EntityLiving; -import game.entity.types.EntityTameable; -import game.init.Config; -import game.init.Items; -import game.init.SoundEvent; -import game.item.Item; -import game.item.ItemFood; -import game.item.ItemStack; -import game.model.ParticleType; -import game.nbt.NBTTagCompound; -import game.pathfinding.PathNavigateGround; -import game.util.ExtMath; -import game.world.World; +import common.ai.EntityAIAttackOnCollide; +import common.ai.EntityAIBeg; +import common.ai.EntityAIFollowOwner; +import common.ai.EntityAIHurtByTarget; +import common.ai.EntityAILeapAtTarget; +import common.ai.EntityAILookIdle; +import common.ai.EntityAIMate; +import common.ai.EntityAIOwnerHurtByTarget; +import common.ai.EntityAIOwnerHurtTarget; +import common.ai.EntityAISwimming; +import common.ai.EntityAITargetNonTamed; +import common.ai.EntityAIWander; +import common.ai.EntityAIWatchClosest; +import common.color.DyeColor; +import common.entity.DamageSource; +import common.entity.Entity; +import common.entity.attributes.Attributes; +import common.entity.npc.Alignment; +import common.entity.npc.EntityNPC; +import common.entity.types.EntityAnimal; +import common.entity.types.EntityLiving; +import common.entity.types.EntityTameable; +import common.init.Config; +import common.init.Items; +import common.init.SoundEvent; +import common.item.Item; +import common.item.ItemFood; +import common.item.ItemStack; +import common.model.ParticleType; +import common.nbt.NBTTagCompound; +import common.pathfinding.PathNavigateGround; +import common.util.ExtMath; +import common.world.World; public class EntityWolf extends EntityTameable { diff --git a/java/src/game/entity/attributes/Attribute.java b/java/src/common/entity/attributes/Attribute.java similarity index 95% rename from java/src/game/entity/attributes/Attribute.java rename to java/src/common/entity/attributes/Attribute.java index 81ea3b4..3e56630 100755 --- a/java/src/game/entity/attributes/Attribute.java +++ b/java/src/common/entity/attributes/Attribute.java @@ -1,9 +1,9 @@ -package game.entity.attributes; +package common.entity.attributes; import java.util.Map; -import game.collect.Maps; -import game.util.ExtMath; +import common.collect.Maps; +import common.util.ExtMath; public class Attribute { diff --git a/java/src/game/entity/attributes/AttributeInstance.java b/java/src/common/entity/attributes/AttributeInstance.java similarity index 97% rename from java/src/game/entity/attributes/AttributeInstance.java rename to java/src/common/entity/attributes/AttributeInstance.java index e2e2cb3..7204633 100755 --- a/java/src/game/entity/attributes/AttributeInstance.java +++ b/java/src/common/entity/attributes/AttributeInstance.java @@ -1,12 +1,12 @@ -package game.entity.attributes; +package common.entity.attributes; import java.util.Collection; import java.util.Map; import java.util.Set; -import game.collect.Lists; -import game.collect.Maps; -import game.collect.Sets; +import common.collect.Lists; +import common.collect.Maps; +import common.collect.Sets; public class AttributeInstance { diff --git a/java/src/game/entity/attributes/AttributeMap.java b/java/src/common/entity/attributes/AttributeMap.java similarity index 98% rename from java/src/game/entity/attributes/AttributeMap.java rename to java/src/common/entity/attributes/AttributeMap.java index af5666e..a19fcba 100755 --- a/java/src/game/entity/attributes/AttributeMap.java +++ b/java/src/common/entity/attributes/AttributeMap.java @@ -1,12 +1,13 @@ -package game.entity.attributes; +package common.entity.attributes; import java.util.Collection; import java.util.Map; import java.util.Map.Entry; -import java.util.Set; -import game.collect.Maps; -import game.collect.Sets; +import common.collect.Maps; +import common.collect.Sets; + +import java.util.Set; public class AttributeMap { diff --git a/java/src/game/entity/attributes/AttributeModifier.java b/java/src/common/entity/attributes/AttributeModifier.java similarity index 98% rename from java/src/game/entity/attributes/AttributeModifier.java rename to java/src/common/entity/attributes/AttributeModifier.java index 176417f..9081bd1 100755 --- a/java/src/game/entity/attributes/AttributeModifier.java +++ b/java/src/common/entity/attributes/AttributeModifier.java @@ -1,6 +1,6 @@ -package game.entity.attributes; +package common.entity.attributes; -import game.rng.Random; +import common.rng.Random; public class AttributeModifier { diff --git a/java/src/game/entity/attributes/Attributes.java b/java/src/common/entity/attributes/Attributes.java similarity index 98% rename from java/src/game/entity/attributes/Attributes.java rename to java/src/common/entity/attributes/Attributes.java index cf4736b..c23c629 100755 --- a/java/src/game/entity/attributes/Attributes.java +++ b/java/src/common/entity/attributes/Attributes.java @@ -1,10 +1,10 @@ -package game.entity.attributes; +package common.entity.attributes; import java.util.Collection; -import game.log.Log; -import game.nbt.NBTTagCompound; -import game.nbt.NBTTagList; +import common.log.Log; +import common.nbt.NBTTagCompound; +import common.nbt.NBTTagList; public class Attributes { diff --git a/java/src/game/entity/attributes/LowerStringMap.java b/java/src/common/entity/attributes/LowerStringMap.java similarity index 96% rename from java/src/game/entity/attributes/LowerStringMap.java rename to java/src/common/entity/attributes/LowerStringMap.java index 11110bb..091cc27 100755 --- a/java/src/game/entity/attributes/LowerStringMap.java +++ b/java/src/common/entity/attributes/LowerStringMap.java @@ -1,10 +1,10 @@ -package game.entity.attributes; +package common.entity.attributes; import java.util.Collection; import java.util.Map; import java.util.Set; -import game.collect.Maps; +import common.collect.Maps; public class LowerStringMap implements Map { diff --git a/java/src/game/entity/effect/EntityLightning.java b/java/src/common/entity/effect/EntityLightning.java similarity index 87% rename from java/src/game/entity/effect/EntityLightning.java rename to java/src/common/entity/effect/EntityLightning.java index dd405db..4e9eccd 100755 --- a/java/src/game/entity/effect/EntityLightning.java +++ b/java/src/common/entity/effect/EntityLightning.java @@ -1,18 +1,18 @@ -package game.entity.effect; +package common.entity.effect; import java.util.List; -import game.entity.Entity; -import game.entity.types.EntityLiving; -import game.entity.types.EntityWeatherEffect; -import game.init.Blocks; -import game.init.Config; -import game.init.SoundEvent; -import game.material.Material; -import game.world.BlockPos; -import game.world.BoundingBox; -import game.world.World; -import game.world.WorldClient; +import common.entity.Entity; +import common.entity.types.EntityLiving; +import common.entity.types.EntityWeatherEffect; +import common.init.Blocks; +import common.init.Config; +import common.init.SoundEvent; +import common.material.Material; +import common.world.BlockPos; +import common.world.BoundingBox; +import common.world.World; +import common.world.WorldClient; public class EntityLightning extends EntityWeatherEffect { diff --git a/java/src/game/entity/item/EntityBoat.java b/java/src/common/entity/item/EntityBoat.java similarity index 97% rename from java/src/game/entity/item/EntityBoat.java rename to java/src/common/entity/item/EntityBoat.java index ca7e129..98d133c 100755 --- a/java/src/game/entity/item/EntityBoat.java +++ b/java/src/common/entity/item/EntityBoat.java @@ -1,25 +1,25 @@ -package game.entity.item; +package common.entity.item; import java.util.List; -import game.block.Block; -import game.entity.DamageSource; -import game.entity.Entity; -import game.entity.EntityDamageSourceIndirect; -import game.entity.EntityType; -import game.entity.npc.EntityNPC; -import game.entity.types.EntityLiving; -import game.init.Blocks; -import game.init.Config; -import game.init.ItemRegistry; -import game.init.Items; -import game.item.Item; -import game.model.ParticleType; -import game.nbt.NBTTagCompound; -import game.util.ExtMath; -import game.world.BlockPos; -import game.world.BoundingBox; -import game.world.World; +import common.block.Block; +import common.entity.DamageSource; +import common.entity.Entity; +import common.entity.EntityDamageSourceIndirect; +import common.entity.EntityType; +import common.entity.npc.EntityNPC; +import common.entity.types.EntityLiving; +import common.init.Blocks; +import common.init.Config; +import common.init.ItemRegistry; +import common.init.Items; +import common.item.Item; +import common.model.ParticleType; +import common.nbt.NBTTagCompound; +import common.util.ExtMath; +import common.world.BlockPos; +import common.world.BoundingBox; +import common.world.World; public class EntityBoat extends Entity { diff --git a/java/src/game/entity/item/EntityCart.java b/java/src/common/entity/item/EntityCart.java similarity index 98% rename from java/src/game/entity/item/EntityCart.java rename to java/src/common/entity/item/EntityCart.java index d1f0058..113d137 100755 --- a/java/src/game/entity/item/EntityCart.java +++ b/java/src/common/entity/item/EntityCart.java @@ -1,26 +1,26 @@ -package game.entity.item; +package common.entity.item; -import game.block.Block; -import game.block.BlockRailBase; -import game.block.BlockRailPowered; -import game.entity.DamageSource; -import game.entity.Entity; -import game.entity.EntityType; -import game.entity.types.EntityLiving; -import game.init.BlockRegistry; -import game.init.Blocks; -import game.init.Config; -import game.init.Items; -import game.item.Item; -import game.item.ItemStack; -import game.nbt.NBTTagCompound; -import game.tileentity.IWorldNameable; -import game.util.ExtMath; -import game.world.BlockPos; -import game.world.BoundingBox; -import game.world.State; -import game.world.Vec3; -import game.world.World; +import common.block.Block; +import common.block.BlockRailBase; +import common.block.BlockRailPowered; +import common.entity.DamageSource; +import common.entity.Entity; +import common.entity.EntityType; +import common.entity.types.EntityLiving; +import common.init.BlockRegistry; +import common.init.Blocks; +import common.init.Config; +import common.init.Items; +import common.item.Item; +import common.item.ItemStack; +import common.nbt.NBTTagCompound; +import common.tileentity.IWorldNameable; +import common.util.ExtMath; +import common.world.BlockPos; +import common.world.BoundingBox; +import common.world.State; +import common.world.Vec3; +import common.world.World; public abstract class EntityCart extends Entity implements IWorldNameable { diff --git a/java/src/game/entity/item/EntityCartContainer.java b/java/src/common/entity/item/EntityCartContainer.java similarity index 93% rename from java/src/game/entity/item/EntityCartContainer.java rename to java/src/common/entity/item/EntityCartContainer.java index 26c633a..daf7d7c 100755 --- a/java/src/game/entity/item/EntityCartContainer.java +++ b/java/src/common/entity/item/EntityCartContainer.java @@ -1,19 +1,19 @@ -package game.entity.item; +package common.entity.item; -import game.entity.DamageSource; -import game.entity.Entity; -import game.entity.npc.EntityNPC; -import game.init.Config; -import game.inventory.Container; -import game.inventory.InventoryHelper; -import game.item.ItemStack; -import game.nbt.NBTTagCompound; -import game.nbt.NBTTagList; -import game.tileentity.ILockableContainer; -import game.tileentity.LockCode; -import game.world.BlockPos; -import game.world.PortalType; -import game.world.World; +import common.entity.DamageSource; +import common.entity.Entity; +import common.entity.npc.EntityNPC; +import common.init.Config; +import common.inventory.Container; +import common.inventory.InventoryHelper; +import common.item.ItemStack; +import common.nbt.NBTTagCompound; +import common.nbt.NBTTagList; +import common.tileentity.ILockableContainer; +import common.tileentity.LockCode; +import common.world.BlockPos; +import common.world.PortalType; +import common.world.World; public abstract class EntityCartContainer extends EntityCart implements ILockableContainer { diff --git a/java/src/game/entity/item/EntityChestCart.java b/java/src/common/entity/item/EntityChestCart.java similarity index 74% rename from java/src/game/entity/item/EntityChestCart.java rename to java/src/common/entity/item/EntityChestCart.java index e39c128..783dbc1 100755 --- a/java/src/game/entity/item/EntityChestCart.java +++ b/java/src/common/entity/item/EntityChestCart.java @@ -1,17 +1,17 @@ -package game.entity.item; +package common.entity.item; -import game.block.BlockChest; -import game.entity.DamageSource; -import game.entity.npc.EntityNPC; -import game.init.Blocks; -import game.init.Config; -import game.init.ItemRegistry; -import game.inventory.Container; -import game.inventory.ContainerChest; -import game.inventory.InventoryPlayer; -import game.world.Facing; -import game.world.State; -import game.world.World; +import common.block.BlockChest; +import common.entity.DamageSource; +import common.entity.npc.EntityNPC; +import common.init.Blocks; +import common.init.Config; +import common.init.ItemRegistry; +import common.inventory.Container; +import common.inventory.ContainerChest; +import common.inventory.InventoryPlayer; +import common.world.Facing; +import common.world.State; +import common.world.World; public class EntityChestCart extends EntityCartContainer { diff --git a/java/src/game/entity/item/EntityCrystal.java b/java/src/common/entity/item/EntityCrystal.java similarity index 94% rename from java/src/game/entity/item/EntityCrystal.java rename to java/src/common/entity/item/EntityCrystal.java index b348d57..d7b4073 100755 --- a/java/src/game/entity/item/EntityCrystal.java +++ b/java/src/common/entity/item/EntityCrystal.java @@ -1,10 +1,10 @@ -package game.entity.item; +package common.entity.item; -import game.entity.DamageSource; -import game.entity.Entity; -import game.entity.EntityType; -import game.nbt.NBTTagCompound; -import game.world.World; +import common.entity.DamageSource; +import common.entity.Entity; +import common.entity.EntityType; +import common.nbt.NBTTagCompound; +import common.world.World; public class EntityCrystal extends Entity { diff --git a/java/src/game/entity/item/EntityExplosion.java b/java/src/common/entity/item/EntityExplosion.java similarity index 91% rename from java/src/game/entity/item/EntityExplosion.java rename to java/src/common/entity/item/EntityExplosion.java index 260e5b1..e8892bf 100755 --- a/java/src/game/entity/item/EntityExplosion.java +++ b/java/src/common/entity/item/EntityExplosion.java @@ -1,10 +1,10 @@ -package game.entity.item; +package common.entity.item; -import game.entity.Entity; -import game.entity.EntityType; -import game.nbt.NBTTagCompound; -import game.world.Explosion; -import game.world.World; +import common.entity.Entity; +import common.entity.EntityType; +import common.nbt.NBTTagCompound; +import common.world.Explosion; +import common.world.World; public class EntityExplosion extends Entity { diff --git a/java/src/game/entity/item/EntityFalling.java b/java/src/common/entity/item/EntityFalling.java similarity index 93% rename from java/src/game/entity/item/EntityFalling.java rename to java/src/common/entity/item/EntityFalling.java index 8196747..ffb8a7b 100755 --- a/java/src/game/entity/item/EntityFalling.java +++ b/java/src/common/entity/item/EntityFalling.java @@ -1,29 +1,29 @@ -package game.entity.item; +package common.entity.item; import java.util.List; -import game.block.Block; -import game.block.BlockAnvil; -import game.block.BlockFalling; -import game.block.ITileEntityProvider; -import game.collect.Lists; -import game.entity.DamageSource; -import game.entity.Entity; -import game.entity.EntityType; -import game.entity.types.IObjectData; -import game.init.BlockRegistry; -import game.init.Blocks; -import game.init.Config; -import game.item.ItemStack; -import game.material.Material; -import game.nbt.NBTBase; -import game.nbt.NBTTagCompound; -import game.tileentity.TileEntity; -import game.util.ExtMath; -import game.world.BlockPos; -import game.world.Facing; -import game.world.State; -import game.world.World; +import common.block.Block; +import common.block.BlockAnvil; +import common.block.BlockFalling; +import common.block.ITileEntityProvider; +import common.collect.Lists; +import common.entity.DamageSource; +import common.entity.Entity; +import common.entity.EntityType; +import common.entity.types.IObjectData; +import common.init.BlockRegistry; +import common.init.Blocks; +import common.init.Config; +import common.item.ItemStack; +import common.material.Material; +import common.nbt.NBTBase; +import common.nbt.NBTTagCompound; +import common.tileentity.TileEntity; +import common.util.ExtMath; +import common.world.BlockPos; +import common.world.Facing; +import common.world.State; +import common.world.World; public class EntityFalling extends Entity implements IObjectData { diff --git a/java/src/game/entity/item/EntityFireworks.java b/java/src/common/entity/item/EntityFireworks.java similarity index 95% rename from java/src/game/entity/item/EntityFireworks.java rename to java/src/common/entity/item/EntityFireworks.java index dc20a18..1e1e2eb 100755 --- a/java/src/game/entity/item/EntityFireworks.java +++ b/java/src/common/entity/item/EntityFireworks.java @@ -1,14 +1,14 @@ -package game.entity.item; +package common.entity.item; -import game.entity.Entity; -import game.entity.EntityType; -import game.init.SoundEvent; -import game.item.ItemStack; -import game.model.ParticleType; -import game.nbt.NBTTagCompound; -import game.util.ExtMath; -import game.world.World; -import game.world.WorldClient; +import common.entity.Entity; +import common.entity.EntityType; +import common.init.SoundEvent; +import common.item.ItemStack; +import common.model.ParticleType; +import common.nbt.NBTTagCompound; +import common.util.ExtMath; +import common.world.World; +import common.world.WorldClient; public class EntityFireworks extends Entity { diff --git a/java/src/game/entity/item/EntityHopperCart.java b/java/src/common/entity/item/EntityHopperCart.java similarity index 91% rename from java/src/game/entity/item/EntityHopperCart.java rename to java/src/common/entity/item/EntityHopperCart.java index 9441c6a..4083659 100755 --- a/java/src/game/entity/item/EntityHopperCart.java +++ b/java/src/common/entity/item/EntityHopperCart.java @@ -1,22 +1,22 @@ -package game.entity.item; +package common.entity.item; import java.util.List; import java.util.function.Predicate; -import game.entity.DamageSource; -import game.entity.npc.EntityNPC; -import game.init.Blocks; -import game.init.Config; -import game.init.ItemRegistry; -import game.inventory.Container; -import game.inventory.ContainerHopper; -import game.inventory.InventoryPlayer; -import game.nbt.NBTTagCompound; -import game.tileentity.IHopper; -import game.tileentity.TileEntityHopper; -import game.world.BlockPos; -import game.world.State; -import game.world.World; +import common.entity.DamageSource; +import common.entity.npc.EntityNPC; +import common.init.Blocks; +import common.init.Config; +import common.init.ItemRegistry; +import common.inventory.Container; +import common.inventory.ContainerHopper; +import common.inventory.InventoryPlayer; +import common.nbt.NBTTagCompound; +import common.tileentity.IHopper; +import common.tileentity.TileEntityHopper; +import common.world.BlockPos; +import common.world.State; +import common.world.World; public class EntityHopperCart extends EntityCartContainer implements IHopper { diff --git a/java/src/game/entity/item/EntityItem.java b/java/src/common/entity/item/EntityItem.java similarity index 96% rename from java/src/game/entity/item/EntityItem.java rename to java/src/common/entity/item/EntityItem.java index fb04bbd..14abe9b 100755 --- a/java/src/game/entity/item/EntityItem.java +++ b/java/src/common/entity/item/EntityItem.java @@ -1,25 +1,25 @@ -package game.entity.item; +package common.entity.item; -import game.color.TextColor; -import game.entity.DamageSource; -import game.entity.Entity; -import game.entity.EntityType; -import game.entity.npc.EntityNPC; -import game.entity.types.EntityLiving; -import game.init.Blocks; -import game.init.Config; -import game.init.ItemRegistry; -import game.init.SoundEvent; -import game.item.ItemStack; -import game.log.Log; -import game.material.Material; -import game.model.ParticleType; -import game.nbt.NBTTagCompound; -import game.util.ExtMath; -import game.world.BlockPos; -import game.world.PortalType; -import game.world.World; -import game.world.WorldServer; +import common.color.TextColor; +import common.entity.DamageSource; +import common.entity.Entity; +import common.entity.EntityType; +import common.entity.npc.EntityNPC; +import common.entity.types.EntityLiving; +import common.init.Blocks; +import common.init.Config; +import common.init.ItemRegistry; +import common.init.SoundEvent; +import common.item.ItemStack; +import common.log.Log; +import common.material.Material; +import common.model.ParticleType; +import common.nbt.NBTTagCompound; +import common.util.ExtMath; +import common.world.BlockPos; +import common.world.PortalType; +import common.world.World; +import common.world.WorldServer; public class EntityItem extends Entity { diff --git a/java/src/game/entity/item/EntityLeashKnot.java b/java/src/common/entity/item/EntityLeashKnot.java similarity index 96% rename from java/src/game/entity/item/EntityLeashKnot.java rename to java/src/common/entity/item/EntityLeashKnot.java index ff89910..e3aebe6 100755 --- a/java/src/game/entity/item/EntityLeashKnot.java +++ b/java/src/common/entity/item/EntityLeashKnot.java @@ -1,19 +1,19 @@ -package game.entity.item; +package common.entity.item; -import game.block.BlockFence; -import game.entity.DamageSource; -import game.entity.Entity; -import game.entity.EntityType; -import game.entity.npc.EntityNPC; -import game.entity.types.EntityLiving; -import game.init.Items; -import game.item.Item; -import game.item.ItemStack; -import game.nbt.NBTTagCompound; -import game.util.ExtMath; -import game.world.BlockPos; -import game.world.BoundingBox; -import game.world.World; +import common.block.BlockFence; +import common.entity.DamageSource; +import common.entity.Entity; +import common.entity.EntityType; +import common.entity.npc.EntityNPC; +import common.entity.types.EntityLiving; +import common.init.Items; +import common.item.Item; +import common.item.ItemStack; +import common.nbt.NBTTagCompound; +import common.util.ExtMath; +import common.world.BlockPos; +import common.world.BoundingBox; +import common.world.World; public class EntityLeashKnot extends Entity { diff --git a/java/src/game/entity/item/EntityMinecart.java b/java/src/common/entity/item/EntityMinecart.java similarity index 93% rename from java/src/game/entity/item/EntityMinecart.java rename to java/src/common/entity/item/EntityMinecart.java index 52ae07e..008c898 100755 --- a/java/src/game/entity/item/EntityMinecart.java +++ b/java/src/common/entity/item/EntityMinecart.java @@ -1,8 +1,8 @@ -package game.entity.item; +package common.entity.item; -import game.entity.Entity; -import game.entity.npc.EntityNPC; -import game.world.World; +import common.entity.Entity; +import common.entity.npc.EntityNPC; +import common.world.World; public class EntityMinecart extends EntityCart { diff --git a/java/src/game/entity/item/EntityNuke.java b/java/src/common/entity/item/EntityNuke.java similarity index 94% rename from java/src/game/entity/item/EntityNuke.java rename to java/src/common/entity/item/EntityNuke.java index 9828a96..75ee50c 100755 --- a/java/src/game/entity/item/EntityNuke.java +++ b/java/src/common/entity/item/EntityNuke.java @@ -1,10 +1,10 @@ -package game.entity.item; +package common.entity.item; -import game.entity.Entity; -import game.entity.EntityType; -import game.model.ParticleType; -import game.nbt.NBTTagCompound; -import game.world.World; +import common.entity.Entity; +import common.entity.EntityType; +import common.model.ParticleType; +import common.nbt.NBTTagCompound; +import common.world.World; public class EntityNuke extends Entity { diff --git a/java/src/game/entity/item/EntityOrb.java b/java/src/common/entity/item/EntityOrb.java similarity index 93% rename from java/src/game/entity/item/EntityOrb.java rename to java/src/common/entity/item/EntityOrb.java index bd1f534..6a3ecf8 100755 --- a/java/src/game/entity/item/EntityOrb.java +++ b/java/src/common/entity/item/EntityOrb.java @@ -1,13 +1,13 @@ -package game.entity.item; +package common.entity.item; -import game.entity.DamageSource; -import game.entity.Entity; -import game.entity.types.EntityLiving; -import game.entity.types.EntityThrowable; -import game.init.Config; -import game.model.ParticleType; -import game.world.HitPosition; -import game.world.World; +import common.entity.DamageSource; +import common.entity.Entity; +import common.entity.types.EntityLiving; +import common.entity.types.EntityThrowable; +import common.init.Config; +import common.model.ParticleType; +import common.world.HitPosition; +import common.world.World; public class EntityOrb extends EntityThrowable { diff --git a/java/src/game/entity/item/EntityTnt.java b/java/src/common/entity/item/EntityTnt.java similarity index 93% rename from java/src/game/entity/item/EntityTnt.java rename to java/src/common/entity/item/EntityTnt.java index e306bf9..b68cb74 100755 --- a/java/src/game/entity/item/EntityTnt.java +++ b/java/src/common/entity/item/EntityTnt.java @@ -1,12 +1,12 @@ -package game.entity.item; +package common.entity.item; -import game.entity.Entity; -import game.entity.EntityType; -import game.entity.types.EntityLiving; -import game.entity.types.IObjectData; -import game.model.ParticleType; -import game.nbt.NBTTagCompound; -import game.world.World; +import common.entity.Entity; +import common.entity.EntityType; +import common.entity.types.EntityLiving; +import common.entity.types.IObjectData; +import common.model.ParticleType; +import common.nbt.NBTTagCompound; +import common.world.World; public class EntityTnt extends Entity implements IObjectData { diff --git a/java/src/game/entity/item/EntityTntCart.java b/java/src/common/entity/item/EntityTntCart.java similarity index 92% rename from java/src/game/entity/item/EntityTntCart.java rename to java/src/common/entity/item/EntityTntCart.java index 16fa7c7..4adfbc4 100755 --- a/java/src/game/entity/item/EntityTntCart.java +++ b/java/src/common/entity/item/EntityTntCart.java @@ -1,19 +1,19 @@ -package game.entity.item; +package common.entity.item; -import game.block.BlockRailBase; -import game.entity.DamageSource; -import game.entity.Entity; -import game.entity.projectile.EntityArrow; -import game.init.Blocks; -import game.init.Config; -import game.init.SoundEvent; -import game.item.ItemStack; -import game.model.ParticleType; -import game.nbt.NBTTagCompound; -import game.world.BlockPos; -import game.world.Explosion; -import game.world.State; -import game.world.World; +import common.block.BlockRailBase; +import common.entity.DamageSource; +import common.entity.Entity; +import common.entity.projectile.EntityArrow; +import common.init.Blocks; +import common.init.Config; +import common.init.SoundEvent; +import common.item.ItemStack; +import common.model.ParticleType; +import common.nbt.NBTTagCompound; +import common.world.BlockPos; +import common.world.Explosion; +import common.world.State; +import common.world.World; public class EntityTntCart extends EntityCart { diff --git a/java/src/game/entity/item/EntityXp.java b/java/src/common/entity/item/EntityXp.java similarity index 95% rename from java/src/game/entity/item/EntityXp.java rename to java/src/common/entity/item/EntityXp.java index 3ab09b2..ab9642c 100755 --- a/java/src/game/entity/item/EntityXp.java +++ b/java/src/common/entity/item/EntityXp.java @@ -1,20 +1,20 @@ -package game.entity.item; +package common.entity.item; -import game.color.TextColor; -import game.entity.DamageSource; -import game.entity.Entity; -import game.entity.EntityType; -import game.entity.npc.EntityNPC; -import game.entity.types.IObjectData; -import game.init.Config; -import game.init.SoundEvent; -import game.material.Material; -import game.model.ParticleType; -import game.nbt.NBTTagCompound; -import game.util.ExtMath; -import game.world.BlockPos; -import game.world.PortalType; -import game.world.World; +import common.color.TextColor; +import common.entity.DamageSource; +import common.entity.Entity; +import common.entity.EntityType; +import common.entity.npc.EntityNPC; +import common.entity.types.IObjectData; +import common.init.Config; +import common.init.SoundEvent; +import common.material.Material; +import common.model.ParticleType; +import common.nbt.NBTTagCompound; +import common.util.ExtMath; +import common.world.BlockPos; +import common.world.PortalType; +import common.world.World; public class EntityXp extends Entity implements IObjectData { diff --git a/java/src/game/entity/item/EntityXpBottle.java b/java/src/common/entity/item/EntityXpBottle.java similarity index 86% rename from java/src/game/entity/item/EntityXpBottle.java rename to java/src/common/entity/item/EntityXpBottle.java index f4c377d..09a969b 100755 --- a/java/src/game/entity/item/EntityXpBottle.java +++ b/java/src/common/entity/item/EntityXpBottle.java @@ -1,10 +1,10 @@ -package game.entity.item; +package common.entity.item; -import game.entity.types.EntityLiving; -import game.entity.types.EntityThrowable; -import game.world.BlockPos; -import game.world.HitPosition; -import game.world.World; +import common.entity.types.EntityLiving; +import common.entity.types.EntityThrowable; +import common.world.BlockPos; +import common.world.HitPosition; +import common.world.World; public class EntityXpBottle extends EntityThrowable { diff --git a/java/src/game/entity/npc/Alignment.java b/java/src/common/entity/npc/Alignment.java similarity index 95% rename from java/src/game/entity/npc/Alignment.java rename to java/src/common/entity/npc/Alignment.java index 8e96033..9c5fba6 100755 --- a/java/src/game/entity/npc/Alignment.java +++ b/java/src/common/entity/npc/Alignment.java @@ -1,9 +1,9 @@ -package game.entity.npc; +package common.entity.npc; import java.util.Map; -import game.collect.Maps; -import game.color.TextColor; +import common.collect.Maps; +import common.color.TextColor; public enum Alignment { LAWFUL_GOOD("lgood", "Rechtsch. gut", 1, 1, TextColor.NEON), diff --git a/java/src/game/entity/npc/CharacterInfo.java b/java/src/common/entity/npc/CharacterInfo.java similarity index 86% rename from java/src/game/entity/npc/CharacterInfo.java rename to java/src/common/entity/npc/CharacterInfo.java index 44c375c..02318a6 100755 --- a/java/src/game/entity/npc/CharacterInfo.java +++ b/java/src/common/entity/npc/CharacterInfo.java @@ -1,7 +1,7 @@ -package game.entity.npc; +package common.entity.npc; -import game.init.SpeciesRegistry; -import game.item.ItemStack; +import common.init.SpeciesRegistry; +import common.item.ItemStack; public class CharacterInfo extends NpcInfo { public final boolean spawner; diff --git a/java/src/game/entity/npc/ClassInfo.java b/java/src/common/entity/npc/ClassInfo.java similarity index 80% rename from java/src/game/entity/npc/ClassInfo.java rename to java/src/common/entity/npc/ClassInfo.java index 7802003..e4561a0 100755 --- a/java/src/game/entity/npc/ClassInfo.java +++ b/java/src/common/entity/npc/ClassInfo.java @@ -1,4 +1,4 @@ -package game.entity.npc; +package common.entity.npc; public class ClassInfo { public final Enum type; diff --git a/java/src/game/entity/npc/Energy.java b/java/src/common/entity/npc/Energy.java similarity index 96% rename from java/src/game/entity/npc/Energy.java rename to java/src/common/entity/npc/Energy.java index da81e6e..1f060f2 100755 --- a/java/src/game/entity/npc/Energy.java +++ b/java/src/common/entity/npc/Energy.java @@ -1,4 +1,4 @@ -package game.entity.npc; +package common.entity.npc; public enum Energy { SPIRITUAL(-100, 'S', "spiritual", "SPR", 0x00ff00, 0x00ffff), // angelic diff --git a/java/src/game/entity/npc/EntityArachnoid.java b/java/src/common/entity/npc/EntityArachnoid.java similarity index 94% rename from java/src/game/entity/npc/EntityArachnoid.java rename to java/src/common/entity/npc/EntityArachnoid.java index ac04013..f56a9bf 100755 --- a/java/src/game/entity/npc/EntityArachnoid.java +++ b/java/src/common/entity/npc/EntityArachnoid.java @@ -1,16 +1,16 @@ -package game.entity.npc; +package common.entity.npc; -import game.ai.EntityAIAttackOnCollide; -import game.ai.EntityAILeapAtTarget; -import game.entity.Entity; -import game.entity.types.EntityLiving; -import game.pathfinding.PathNavigate; -import game.pathfinding.PathNavigateClimber; -import game.potion.Potion; -import game.potion.PotionEffect; -import game.rng.Random; -import game.world.BlockPos; -import game.world.World; +import common.ai.EntityAIAttackOnCollide; +import common.ai.EntityAILeapAtTarget; +import common.entity.Entity; +import common.entity.types.EntityLiving; +import common.pathfinding.PathNavigate; +import common.pathfinding.PathNavigateClimber; +import common.potion.Potion; +import common.potion.PotionEffect; +import common.rng.Random; +import common.world.BlockPos; +import common.world.World; public class EntityArachnoid extends EntityNPC { diff --git a/java/src/game/entity/npc/EntityBloodElf.java b/java/src/common/entity/npc/EntityBloodElf.java similarity index 91% rename from java/src/game/entity/npc/EntityBloodElf.java rename to java/src/common/entity/npc/EntityBloodElf.java index 66e5a4e..4870276 100755 --- a/java/src/game/entity/npc/EntityBloodElf.java +++ b/java/src/common/entity/npc/EntityBloodElf.java @@ -1,10 +1,10 @@ -package game.entity.npc; +package common.entity.npc; -import game.init.Items; -import game.init.NameRegistry; -import game.item.ItemStack; -import game.rng.Random; -import game.world.World; +import common.init.Items; +import common.init.NameRegistry; +import common.item.ItemStack; +import common.rng.Random; +import common.world.World; public class EntityBloodElf extends EntityNPC { public EntityBloodElf(World worldIn) { diff --git a/java/src/game/entity/npc/EntityChaosMarine.java b/java/src/common/entity/npc/EntityChaosMarine.java similarity index 91% rename from java/src/game/entity/npc/EntityChaosMarine.java rename to java/src/common/entity/npc/EntityChaosMarine.java index a988ac3..cccb1b3 100755 --- a/java/src/game/entity/npc/EntityChaosMarine.java +++ b/java/src/common/entity/npc/EntityChaosMarine.java @@ -1,15 +1,15 @@ -package game.entity.npc; +package common.entity.npc; import java.util.List; -import game.collect.Lists; -import game.entity.attributes.Attributes; -import game.init.Items; -import game.init.SpeciesRegistry; -import game.item.ItemStack; -import game.rng.Random; -import game.util.Identifyable; -import game.world.World; +import common.collect.Lists; +import common.entity.attributes.Attributes; +import common.init.Items; +import common.init.SpeciesRegistry; +import common.item.ItemStack; +import common.rng.Random; +import common.util.Identifyable; +import common.world.World; public class EntityChaosMarine extends EntityNPC { public static enum Legion implements Identifyable { diff --git a/java/src/game/entity/npc/EntityCpu.java b/java/src/common/entity/npc/EntityCpu.java similarity index 89% rename from java/src/game/entity/npc/EntityCpu.java rename to java/src/common/entity/npc/EntityCpu.java index bd8ce4e..e9aaa3a 100755 --- a/java/src/game/entity/npc/EntityCpu.java +++ b/java/src/common/entity/npc/EntityCpu.java @@ -1,9 +1,9 @@ -package game.entity.npc; +package common.entity.npc; -import game.init.Items; -import game.item.ItemStack; -import game.rng.Random; -import game.world.World; +import common.init.Items; +import common.item.ItemStack; +import common.rng.Random; +import common.world.World; public class EntityCpu extends EntityNPC { public EntityCpu(World worldIn) { diff --git a/java/src/game/entity/npc/EntityCultivator.java b/java/src/common/entity/npc/EntityCultivator.java similarity index 91% rename from java/src/game/entity/npc/EntityCultivator.java rename to java/src/common/entity/npc/EntityCultivator.java index 5ce5805..84206cd 100755 --- a/java/src/game/entity/npc/EntityCultivator.java +++ b/java/src/common/entity/npc/EntityCultivator.java @@ -1,14 +1,14 @@ -package game.entity.npc; +package common.entity.npc; -import game.ai.EntityAITakePlace; -import game.ai.EntityAITempt; -import game.ai.EntityAIWatchClosest2; -import game.entity.effect.EntityLightning; -import game.init.Items; -import game.item.ItemStack; -import game.rng.Random; -import game.world.BlockPos; -import game.world.World; +import common.ai.EntityAITakePlace; +import common.ai.EntityAITempt; +import common.ai.EntityAIWatchClosest2; +import common.entity.effect.EntityLightning; +import common.init.Items; +import common.item.ItemStack; +import common.rng.Random; +import common.world.BlockPos; +import common.world.World; public class EntityCultivator extends EntityNPC { public EntityCultivator(World worldIn) { diff --git a/java/src/game/entity/npc/EntityDarkMage.java b/java/src/common/entity/npc/EntityDarkMage.java similarity index 90% rename from java/src/game/entity/npc/EntityDarkMage.java rename to java/src/common/entity/npc/EntityDarkMage.java index 790cc12..5d5712b 100755 --- a/java/src/game/entity/npc/EntityDarkMage.java +++ b/java/src/common/entity/npc/EntityDarkMage.java @@ -1,11 +1,11 @@ -package game.entity.npc; +package common.entity.npc; -import game.ai.AISmallFireballAttack; -import game.init.SoundEvent; -import game.model.ParticleType; -import game.rng.Random; -import game.world.World; -import game.world.WorldClient; +import common.ai.AISmallFireballAttack; +import common.init.SoundEvent; +import common.model.ParticleType; +import common.rng.Random; +import common.world.World; +import common.world.WorldClient; public class EntityDarkMage extends EntityHoveringNPC { public EntityDarkMage(World worldIn) { diff --git a/java/src/game/entity/npc/EntityDwarf.java b/java/src/common/entity/npc/EntityDwarf.java similarity index 92% rename from java/src/game/entity/npc/EntityDwarf.java rename to java/src/common/entity/npc/EntityDwarf.java index 0872ad5..8e78631 100755 --- a/java/src/game/entity/npc/EntityDwarf.java +++ b/java/src/common/entity/npc/EntityDwarf.java @@ -1,8 +1,8 @@ -package game.entity.npc; +package common.entity.npc; -import game.entity.types.EntityLiving; -import game.rng.Random; -import game.world.World; +import common.entity.types.EntityLiving; +import common.rng.Random; +import common.world.World; public class EntityDwarf extends EntityNPC { public EntityDwarf(World worldIn) { diff --git a/java/src/game/entity/npc/EntityElf.java b/java/src/common/entity/npc/EntityElf.java similarity index 89% rename from java/src/game/entity/npc/EntityElf.java rename to java/src/common/entity/npc/EntityElf.java index d61c7a6..2a70a38 100755 --- a/java/src/game/entity/npc/EntityElf.java +++ b/java/src/common/entity/npc/EntityElf.java @@ -1,11 +1,11 @@ -package game.entity.npc; +package common.entity.npc; -import game.entity.types.EntityLiving; -import game.init.Items; -import game.init.NameRegistry; -import game.item.ItemStack; -import game.rng.Random; -import game.world.World; +import common.entity.types.EntityLiving; +import common.init.Items; +import common.init.NameRegistry; +import common.item.ItemStack; +import common.rng.Random; +import common.world.World; public class EntityElf extends EntityNPC { public EntityElf(World worldIn) { diff --git a/java/src/game/entity/npc/EntityFireDemon.java b/java/src/common/entity/npc/EntityFireDemon.java similarity index 89% rename from java/src/game/entity/npc/EntityFireDemon.java rename to java/src/common/entity/npc/EntityFireDemon.java index 81a11db..e982fff 100755 --- a/java/src/game/entity/npc/EntityFireDemon.java +++ b/java/src/common/entity/npc/EntityFireDemon.java @@ -1,10 +1,10 @@ -package game.entity.npc; +package common.entity.npc; -import game.ai.AIFireballAttack; -import game.entity.DamageSource; -import game.entity.effect.EntityLightning; -import game.rng.Random; -import game.world.World; +import common.ai.AIFireballAttack; +import common.entity.DamageSource; +import common.entity.effect.EntityLightning; +import common.rng.Random; +import common.world.World; public class EntityFireDemon extends EntityFlyingNPC { public EntityFireDemon(World worldIn) { diff --git a/java/src/game/entity/npc/EntityFlyingNPC.java b/java/src/common/entity/npc/EntityFlyingNPC.java similarity index 95% rename from java/src/game/entity/npc/EntityFlyingNPC.java rename to java/src/common/entity/npc/EntityFlyingNPC.java index 886e41d..56dcfb3 100755 --- a/java/src/game/entity/npc/EntityFlyingNPC.java +++ b/java/src/common/entity/npc/EntityFlyingNPC.java @@ -1,16 +1,16 @@ -package game.entity.npc; +package common.entity.npc; -import game.ai.EntityAIBase; -import game.ai.EntityMoveHelper; -import game.block.Block; -import game.entity.attributes.Attributes; -import game.entity.types.EntityLiving; -import game.potion.Potion; -import game.rng.Random; -import game.util.ExtMath; -import game.world.BlockPos; -import game.world.BoundingBox; -import game.world.World; +import common.ai.EntityAIBase; +import common.ai.EntityMoveHelper; +import common.block.Block; +import common.entity.attributes.Attributes; +import common.entity.types.EntityLiving; +import common.potion.Potion; +import common.rng.Random; +import common.util.ExtMath; +import common.world.BlockPos; +import common.world.BoundingBox; +import common.world.World; public abstract class EntityFlyingNPC extends EntityNPC { diff --git a/java/src/game/entity/npc/EntityGargoyle.java b/java/src/common/entity/npc/EntityGargoyle.java similarity index 95% rename from java/src/game/entity/npc/EntityGargoyle.java rename to java/src/common/entity/npc/EntityGargoyle.java index 9443e01..0f6b358 100755 --- a/java/src/game/entity/npc/EntityGargoyle.java +++ b/java/src/common/entity/npc/EntityGargoyle.java @@ -1,14 +1,14 @@ -package game.entity.npc; +package common.entity.npc; -import game.ai.AIFlyingBoxAttack; -import game.entity.DamageSource; -import game.entity.attributes.Attributes; -import game.init.Config; -import game.item.ItemStack; -import game.model.ParticleType; -import game.nbt.NBTTagCompound; -import game.rng.Random; -import game.world.World; +import common.ai.AIFlyingBoxAttack; +import common.entity.DamageSource; +import common.entity.attributes.Attributes; +import common.init.Config; +import common.item.ItemStack; +import common.model.ParticleType; +import common.nbt.NBTTagCompound; +import common.rng.Random; +import common.world.World; public class EntityGargoyle extends EntityFlyingNPC { diff --git a/java/src/game/entity/npc/EntityGoblin.java b/java/src/common/entity/npc/EntityGoblin.java similarity index 87% rename from java/src/game/entity/npc/EntityGoblin.java rename to java/src/common/entity/npc/EntityGoblin.java index 44038c4..3b0db10 100755 --- a/java/src/game/entity/npc/EntityGoblin.java +++ b/java/src/common/entity/npc/EntityGoblin.java @@ -1,9 +1,9 @@ -package game.entity.npc; +package common.entity.npc; -import game.entity.attributes.Attributes; -import game.entity.types.EntityLiving; -import game.rng.Random; -import game.world.World; +import common.entity.attributes.Attributes; +import common.entity.types.EntityLiving; +import common.rng.Random; +import common.world.World; public class EntityGoblin extends EntityNPC { public EntityGoblin(World worldIn) { diff --git a/java/src/game/entity/npc/EntityHaunter.java b/java/src/common/entity/npc/EntityHaunter.java similarity index 95% rename from java/src/game/entity/npc/EntityHaunter.java rename to java/src/common/entity/npc/EntityHaunter.java index 9d1c216..4f1e389 100755 --- a/java/src/game/entity/npc/EntityHaunter.java +++ b/java/src/common/entity/npc/EntityHaunter.java @@ -1,18 +1,18 @@ -package game.entity.npc; +package common.entity.npc; -import game.ai.EntityAIExplode; -import game.entity.Entity; -import game.entity.attributes.Attributes; -import game.entity.effect.EntityLightning; -import game.entity.types.EntityLiving; -import game.init.Config; -import game.init.Items; -import game.init.SoundEvent; -import game.item.ItemStack; -import game.nbt.NBTTagCompound; -import game.rng.Random; -import game.world.World; -import game.world.WorldServer; +import common.ai.EntityAIExplode; +import common.entity.Entity; +import common.entity.attributes.Attributes; +import common.entity.effect.EntityLightning; +import common.entity.types.EntityLiving; +import common.init.Config; +import common.init.Items; +import common.init.SoundEvent; +import common.item.ItemStack; +import common.nbt.NBTTagCompound; +import common.rng.Random; +import common.world.World; +import common.world.WorldServer; public class EntityHaunter extends EntityNPC { // private int lastActiveTime; diff --git a/java/src/game/entity/npc/EntityHoveringNPC.java b/java/src/common/entity/npc/EntityHoveringNPC.java similarity index 97% rename from java/src/game/entity/npc/EntityHoveringNPC.java rename to java/src/common/entity/npc/EntityHoveringNPC.java index c413458..d35b423 100755 --- a/java/src/game/entity/npc/EntityHoveringNPC.java +++ b/java/src/common/entity/npc/EntityHoveringNPC.java @@ -1,9 +1,9 @@ -package game.entity.npc; +package common.entity.npc; -import game.entity.attributes.Attributes; -import game.entity.types.EntityLiving; -import game.packet.CPacketAction; -import game.world.World; +import common.entity.attributes.Attributes; +import common.entity.types.EntityLiving; +import common.packet.CPacketAction; +import common.world.World; public abstract class EntityHoveringNPC extends EntityNPC { diff --git a/java/src/game/entity/npc/EntityHuman.java b/java/src/common/entity/npc/EntityHuman.java similarity index 91% rename from java/src/game/entity/npc/EntityHuman.java rename to java/src/common/entity/npc/EntityHuman.java index aa68011..18bbea1 100755 --- a/java/src/game/entity/npc/EntityHuman.java +++ b/java/src/common/entity/npc/EntityHuman.java @@ -1,14 +1,14 @@ -package game.entity.npc; +package common.entity.npc; -import game.entity.types.EntityLiving; -import game.init.Items; -import game.item.ItemStack; -import game.rng.Random; -import game.util.Identifyable; -import game.village.Village; -import game.world.BlockPos; -import game.world.World; -import game.world.WorldServer; +import common.entity.types.EntityLiving; +import common.init.Items; +import common.item.ItemStack; +import common.rng.Random; +import common.util.Identifyable; +import common.village.Village; +import common.world.BlockPos; +import common.world.World; +import common.world.WorldServer; public class EntityHuman extends EntityNPC { public static enum ClassType implements Identifyable { diff --git a/java/src/game/entity/npc/EntityMage.java b/java/src/common/entity/npc/EntityMage.java similarity index 92% rename from java/src/game/entity/npc/EntityMage.java rename to java/src/common/entity/npc/EntityMage.java index 691d82f..09c4134 100755 --- a/java/src/game/entity/npc/EntityMage.java +++ b/java/src/common/entity/npc/EntityMage.java @@ -1,17 +1,17 @@ -package game.entity.npc; +package common.entity.npc; import java.util.List; -import game.entity.attributes.AttributeInstance; -import game.entity.attributes.Attributes; -import game.entity.effect.EntityLightning; -import game.entity.types.EntityLiving; -import game.init.Items; -import game.item.ItemStack; -import game.potion.Potion; -import game.potion.PotionEffect; -import game.rng.Random; -import game.world.World; +import common.entity.attributes.AttributeInstance; +import common.entity.attributes.Attributes; +import common.entity.effect.EntityLightning; +import common.entity.types.EntityLiving; +import common.init.Items; +import common.item.ItemStack; +import common.potion.Potion; +import common.potion.PotionEffect; +import common.rng.Random; +import common.world.World; public class EntityMage extends EntityNPC { diff --git a/java/src/game/entity/npc/EntityMagma.java b/java/src/common/entity/npc/EntityMagma.java similarity index 97% rename from java/src/game/entity/npc/EntityMagma.java rename to java/src/common/entity/npc/EntityMagma.java index 049852c..3610e17 100755 --- a/java/src/game/entity/npc/EntityMagma.java +++ b/java/src/common/entity/npc/EntityMagma.java @@ -1,7 +1,7 @@ -package game.entity.npc; +package common.entity.npc; -import game.model.ParticleType; -import game.world.World; +import common.model.ParticleType; +import common.world.World; public class EntityMagma extends EntitySlime { diff --git a/java/src/game/entity/npc/EntityMetalhead.java b/java/src/common/entity/npc/EntityMetalhead.java similarity index 89% rename from java/src/game/entity/npc/EntityMetalhead.java rename to java/src/common/entity/npc/EntityMetalhead.java index 0113cbe..0de0841 100755 --- a/java/src/game/entity/npc/EntityMetalhead.java +++ b/java/src/common/entity/npc/EntityMetalhead.java @@ -1,11 +1,11 @@ -package game.entity.npc; +package common.entity.npc; -import game.init.ItemRegistry; -import game.init.MetalType; -import game.item.ItemMetal; -import game.item.ItemStack; -import game.rng.Random; -import game.world.World; +import common.init.ItemRegistry; +import common.init.MetalType; +import common.item.ItemMetal; +import common.item.ItemStack; +import common.rng.Random; +import common.world.World; public class EntityMetalhead extends EntityNPC { public EntityMetalhead(World worldIn) { diff --git a/java/src/game/entity/npc/EntityMobNPC.java b/java/src/common/entity/npc/EntityMobNPC.java similarity index 96% rename from java/src/game/entity/npc/EntityMobNPC.java rename to java/src/common/entity/npc/EntityMobNPC.java index 2a39783..e36c35f 100755 --- a/java/src/game/entity/npc/EntityMobNPC.java +++ b/java/src/common/entity/npc/EntityMobNPC.java @@ -1,13 +1,13 @@ -package game.entity.npc; +package common.entity.npc; -import game.ai.EntityAIHurtByTarget; -import game.entity.DamageSource; -import game.entity.Entity; -import game.entity.attributes.AttributeInstance; -import game.entity.attributes.Attributes; -import game.entity.types.EntityLiving; -import game.nbt.NBTTagCompound; -import game.world.World; +import common.ai.EntityAIHurtByTarget; +import common.entity.DamageSource; +import common.entity.Entity; +import common.entity.attributes.AttributeInstance; +import common.entity.attributes.Attributes; +import common.entity.types.EntityLiving; +import common.nbt.NBTTagCompound; +import common.world.World; public abstract class EntityMobNPC extends EntityNPC { diff --git a/java/src/game/entity/npc/EntityNPC.java b/java/src/common/entity/npc/EntityNPC.java similarity index 97% rename from java/src/game/entity/npc/EntityNPC.java rename to java/src/common/entity/npc/EntityNPC.java index 196893c..26b4075 100755 --- a/java/src/game/entity/npc/EntityNPC.java +++ b/java/src/common/entity/npc/EntityNPC.java @@ -1,102 +1,102 @@ -package game.entity.npc; +package common.entity.npc; import java.lang.reflect.InvocationTargetException; import java.util.List; import java.util.function.Predicate; -import game.IClient; -import game.ai.AIRangedAttack; -import game.ai.EntityAIAttackOnCollide; -import game.ai.EntityAIAvoidEntity; -import game.ai.EntityAIHurtByTarget; -import game.ai.EntityAILookAtTalkingPlayer; -import game.ai.EntityAINagPlayer; -import game.ai.EntityAINearestAttackableTarget; -import game.ai.EntityAINpcInteract; -import game.ai.EntityAINpcMate; -import game.ai.EntityAIOpenDoor; -import game.ai.EntityAIPlay; -import game.ai.EntityAISwimming; -import game.ai.EntityAIWander; -import game.ai.EntityAIWatchClosest; -import game.ai.EntityAIWatchClosest2; -import game.block.Block; -import game.block.BlockBed; -import game.dimension.Space; -import game.enchantment.Enchantment; -import game.enchantment.EnchantmentHelper; -import game.entity.DamageSource; -import game.entity.Entity; -import game.entity.EntityType; -import game.entity.animal.EntityDragonPart; -import game.entity.animal.EntityHorse; -import game.entity.animal.EntityPig; -import game.entity.attributes.AttributeInstance; -import game.entity.attributes.Attributes; -import game.entity.item.EntityBoat; -import game.entity.item.EntityCart; -import game.entity.item.EntityItem; -import game.entity.projectile.EntityArrow; -import game.entity.projectile.EntityBullet; -import game.entity.projectile.EntityHook; -import game.entity.projectile.EntityPotion; -import game.entity.projectile.EntitySnowball; -import game.entity.types.EntityLiving; -import game.entity.types.IEntityMultiPart; -import game.init.Config; -import game.init.ItemRegistry; -import game.init.Items; -import game.init.NameRegistry; -import game.init.SoundEvent; -import game.init.SpeciesRegistry; -import game.init.SpeciesRegistry.ModelType; -import game.init.TradeRegistry; -import game.inventory.Container; -import game.inventory.ContainerPlayer; -import game.inventory.IInventory; -import game.inventory.InventoryBasic; -import game.inventory.InventoryPlayer; -import game.inventory.InventoryWarpChest; -import game.item.Item; -import game.item.ItemAction; -import game.item.ItemArmor; -import game.item.ItemBow; -import game.item.ItemGunBase; -import game.item.ItemHoe; -import game.item.ItemShears; -import game.item.ItemStack; -import game.item.ItemSword; -import game.item.ItemTool; -import game.model.ParticleType; -import game.nbt.NBTTagCompound; -import game.nbt.NBTTagList; -import game.network.IClientPlayer; -import game.network.IPlayer; -import game.packet.CPacketAction; -import game.packet.CPacketBreak; -import game.packet.CPacketInput; -import game.packet.CPacketPlayer; -import game.packet.SPacketEntityEquipment; -import game.packet.SPacketEntityVelocity; -import game.pathfinding.PathNavigateGround; -import game.potion.Potion; -import game.potion.PotionEffect; -import game.rng.Random; -import game.sound.MovingSoundMinecartRiding; -import game.tileentity.IInteractionObject; -import game.tileentity.LockCode; -import game.tileentity.TileEntitySign; -import game.util.ExtMath; -import game.village.MerchantRecipeList; -import game.world.BlockPos; -import game.world.BoundingBox; -import game.world.Facing; -import game.world.PortalType; -import game.world.Vec3; -import game.world.World; -import game.world.WorldClient; -import game.world.WorldPos; -import game.world.WorldServer; +import common.IClient; +import common.ai.AIRangedAttack; +import common.ai.EntityAIAttackOnCollide; +import common.ai.EntityAIAvoidEntity; +import common.ai.EntityAIHurtByTarget; +import common.ai.EntityAILookAtTalkingPlayer; +import common.ai.EntityAINagPlayer; +import common.ai.EntityAINearestAttackableTarget; +import common.ai.EntityAINpcInteract; +import common.ai.EntityAINpcMate; +import common.ai.EntityAIOpenDoor; +import common.ai.EntityAIPlay; +import common.ai.EntityAISwimming; +import common.ai.EntityAIWander; +import common.ai.EntityAIWatchClosest; +import common.ai.EntityAIWatchClosest2; +import common.block.Block; +import common.block.BlockBed; +import common.dimension.Space; +import common.enchantment.Enchantment; +import common.enchantment.EnchantmentHelper; +import common.entity.DamageSource; +import common.entity.Entity; +import common.entity.EntityType; +import common.entity.animal.EntityDragonPart; +import common.entity.animal.EntityHorse; +import common.entity.animal.EntityPig; +import common.entity.attributes.AttributeInstance; +import common.entity.attributes.Attributes; +import common.entity.item.EntityBoat; +import common.entity.item.EntityCart; +import common.entity.item.EntityItem; +import common.entity.projectile.EntityArrow; +import common.entity.projectile.EntityBullet; +import common.entity.projectile.EntityHook; +import common.entity.projectile.EntityPotion; +import common.entity.projectile.EntitySnowball; +import common.entity.types.EntityLiving; +import common.entity.types.IEntityMultiPart; +import common.init.Config; +import common.init.ItemRegistry; +import common.init.Items; +import common.init.NameRegistry; +import common.init.SoundEvent; +import common.init.SpeciesRegistry; +import common.init.TradeRegistry; +import common.init.SpeciesRegistry.ModelType; +import common.inventory.Container; +import common.inventory.ContainerPlayer; +import common.inventory.IInventory; +import common.inventory.InventoryBasic; +import common.inventory.InventoryPlayer; +import common.inventory.InventoryWarpChest; +import common.item.Item; +import common.item.ItemAction; +import common.item.ItemArmor; +import common.item.ItemBow; +import common.item.ItemGunBase; +import common.item.ItemHoe; +import common.item.ItemShears; +import common.item.ItemStack; +import common.item.ItemSword; +import common.item.ItemTool; +import common.model.ParticleType; +import common.nbt.NBTTagCompound; +import common.nbt.NBTTagList; +import common.network.IClientPlayer; +import common.network.IPlayer; +import common.packet.CPacketAction; +import common.packet.CPacketBreak; +import common.packet.CPacketInput; +import common.packet.CPacketPlayer; +import common.packet.SPacketEntityEquipment; +import common.packet.SPacketEntityVelocity; +import common.pathfinding.PathNavigateGround; +import common.potion.Potion; +import common.potion.PotionEffect; +import common.rng.Random; +import common.sound.MovingSoundMinecartRiding; +import common.tileentity.IInteractionObject; +import common.tileentity.LockCode; +import common.tileentity.TileEntitySign; +import common.util.ExtMath; +import common.village.MerchantRecipeList; +import common.world.BlockPos; +import common.world.BoundingBox; +import common.world.Facing; +import common.world.PortalType; +import common.world.Vec3; +import common.world.World; +import common.world.WorldClient; +import common.world.WorldPos; +import common.world.WorldServer; public abstract class EntityNPC extends EntityLiving { diff --git a/java/src/game/entity/npc/EntityOrc.java b/java/src/common/entity/npc/EntityOrc.java similarity index 92% rename from java/src/game/entity/npc/EntityOrc.java rename to java/src/common/entity/npc/EntityOrc.java index 47cc5df..e6cc4c0 100755 --- a/java/src/game/entity/npc/EntityOrc.java +++ b/java/src/common/entity/npc/EntityOrc.java @@ -1,8 +1,8 @@ -package game.entity.npc; +package common.entity.npc; -import game.entity.attributes.Attributes; -import game.rng.Random; -import game.world.World; +import common.entity.attributes.Attributes; +import common.rng.Random; +import common.world.World; public class EntityOrc extends EntityNPC { public EntityOrc(World worldIn) { diff --git a/java/src/game/entity/npc/EntityPrimarch.java b/java/src/common/entity/npc/EntityPrimarch.java similarity index 96% rename from java/src/game/entity/npc/EntityPrimarch.java rename to java/src/common/entity/npc/EntityPrimarch.java index 9edcf12..b20a047 100755 --- a/java/src/game/entity/npc/EntityPrimarch.java +++ b/java/src/common/entity/npc/EntityPrimarch.java @@ -1,12 +1,12 @@ -package game.entity.npc; +package common.entity.npc; import java.util.List; -import game.collect.Lists; -import game.entity.attributes.Attributes; -import game.rng.Random; -import game.util.Identifyable; -import game.world.World; +import common.collect.Lists; +import common.entity.attributes.Attributes; +import common.rng.Random; +import common.util.Identifyable; +import common.world.World; public class EntityPrimarch extends EntityMobNPC { public static enum Founding implements Identifyable { diff --git a/java/src/game/entity/npc/EntitySlime.java b/java/src/common/entity/npc/EntitySlime.java similarity index 97% rename from java/src/game/entity/npc/EntitySlime.java rename to java/src/common/entity/npc/EntitySlime.java index 578b1b9..0c9d04d 100755 --- a/java/src/game/entity/npc/EntitySlime.java +++ b/java/src/common/entity/npc/EntitySlime.java @@ -1,23 +1,23 @@ -package game.entity.npc; +package common.entity.npc; -import game.ai.EntityAIBase; -import game.ai.EntityMoveHelper; -import game.biome.Biome; -import game.entity.DamageSource; -import game.entity.Entity; -import game.entity.attributes.Attributes; -import game.entity.types.EntityLiving; -import game.init.Config; -import game.init.SoundEvent; -import game.model.ParticleType; -import game.nbt.NBTTagCompound; -import game.pathfinding.PathNavigateGround; -import game.rng.Random; -import game.util.ExtMath; -import game.world.BlockPos; -import game.world.Chunk; -import game.world.World; -import game.world.WorldServer; +import common.ai.EntityAIBase; +import common.ai.EntityMoveHelper; +import common.biome.Biome; +import common.entity.DamageSource; +import common.entity.Entity; +import common.entity.attributes.Attributes; +import common.entity.types.EntityLiving; +import common.init.Config; +import common.init.SoundEvent; +import common.model.ParticleType; +import common.nbt.NBTTagCompound; +import common.pathfinding.PathNavigateGround; +import common.rng.Random; +import common.util.ExtMath; +import common.world.BlockPos; +import common.world.Chunk; +import common.world.World; +import common.world.WorldServer; public class EntitySlime extends EntityNPC { diff --git a/java/src/game/entity/npc/EntitySpaceMarine.java b/java/src/common/entity/npc/EntitySpaceMarine.java similarity index 91% rename from java/src/game/entity/npc/EntitySpaceMarine.java rename to java/src/common/entity/npc/EntitySpaceMarine.java index 18cbf31..9bc645f 100755 --- a/java/src/game/entity/npc/EntitySpaceMarine.java +++ b/java/src/common/entity/npc/EntitySpaceMarine.java @@ -1,15 +1,15 @@ -package game.entity.npc; +package common.entity.npc; import java.util.List; -import game.collect.Lists; -import game.entity.attributes.Attributes; -import game.init.Items; -import game.init.SpeciesRegistry; -import game.item.ItemStack; -import game.rng.Random; -import game.util.Identifyable; -import game.world.World; +import common.collect.Lists; +import common.entity.attributes.Attributes; +import common.init.Items; +import common.init.SpeciesRegistry; +import common.item.ItemStack; +import common.rng.Random; +import common.util.Identifyable; +import common.world.World; public class EntitySpaceMarine extends EntityNPC { public static enum Legion implements Identifyable { diff --git a/java/src/game/entity/npc/EntitySpirit.java b/java/src/common/entity/npc/EntitySpirit.java similarity index 92% rename from java/src/game/entity/npc/EntitySpirit.java rename to java/src/common/entity/npc/EntitySpirit.java index 9f27ab5..a2003b3 100755 --- a/java/src/game/entity/npc/EntitySpirit.java +++ b/java/src/common/entity/npc/EntitySpirit.java @@ -1,9 +1,9 @@ -package game.entity.npc; +package common.entity.npc; -import game.init.Items; -import game.item.ItemStack; -import game.rng.Random; -import game.world.World; +import common.init.Items; +import common.item.ItemStack; +import common.rng.Random; +import common.world.World; public class EntitySpirit extends EntityNPC { public EntitySpirit(World worldIn) { diff --git a/java/src/game/entity/npc/EntityTiefling.java b/java/src/common/entity/npc/EntityTiefling.java similarity index 92% rename from java/src/game/entity/npc/EntityTiefling.java rename to java/src/common/entity/npc/EntityTiefling.java index f41e20f..7a075df 100755 --- a/java/src/game/entity/npc/EntityTiefling.java +++ b/java/src/common/entity/npc/EntityTiefling.java @@ -1,8 +1,8 @@ -package game.entity.npc; +package common.entity.npc; -import game.entity.attributes.Attributes; -import game.rng.Random; -import game.world.World; +import common.entity.attributes.Attributes; +import common.rng.Random; +import common.world.World; public class EntityTiefling extends EntityMobNPC { public EntityTiefling(World worldIn) { diff --git a/java/src/game/entity/npc/EntityUndead.java b/java/src/common/entity/npc/EntityUndead.java similarity index 87% rename from java/src/game/entity/npc/EntityUndead.java rename to java/src/common/entity/npc/EntityUndead.java index 47d471c..d35adeb 100755 --- a/java/src/game/entity/npc/EntityUndead.java +++ b/java/src/common/entity/npc/EntityUndead.java @@ -1,14 +1,14 @@ -package game.entity.npc; +package common.entity.npc; -import game.ai.EntityAIAvoidEntity; -import game.entity.animal.EntityWolf; -import game.entity.attributes.Attributes; -import game.entity.types.EntityLiving; -import game.init.Items; -import game.item.ItemStack; -import game.rng.Random; -import game.world.World; -import game.world.WorldServer; +import common.ai.EntityAIAvoidEntity; +import common.entity.animal.EntityWolf; +import common.entity.attributes.Attributes; +import common.entity.types.EntityLiving; +import common.init.Items; +import common.item.ItemStack; +import common.rng.Random; +import common.world.World; +import common.world.WorldServer; public class EntityUndead extends EntityNPC { diff --git a/java/src/game/entity/npc/EntityVampire.java b/java/src/common/entity/npc/EntityVampire.java similarity index 90% rename from java/src/game/entity/npc/EntityVampire.java rename to java/src/common/entity/npc/EntityVampire.java index 38c57d7..374a691 100755 --- a/java/src/game/entity/npc/EntityVampire.java +++ b/java/src/common/entity/npc/EntityVampire.java @@ -1,9 +1,9 @@ -package game.entity.npc; +package common.entity.npc; -import game.entity.attributes.Attributes; -import game.entity.effect.EntityLightning; -import game.rng.Random; -import game.world.World; +import common.entity.attributes.Attributes; +import common.entity.effect.EntityLightning; +import common.rng.Random; +import common.world.World; public class EntityVampire extends EntityNPC { public EntityVampire(World worldIn) { diff --git a/java/src/game/entity/npc/EntityWoodElf.java b/java/src/common/entity/npc/EntityWoodElf.java similarity index 88% rename from java/src/game/entity/npc/EntityWoodElf.java rename to java/src/common/entity/npc/EntityWoodElf.java index 0e4fc0a..c131b6a 100755 --- a/java/src/game/entity/npc/EntityWoodElf.java +++ b/java/src/common/entity/npc/EntityWoodElf.java @@ -1,11 +1,11 @@ -package game.entity.npc; +package common.entity.npc; -import game.entity.types.EntityLiving; -import game.init.Items; -import game.init.NameRegistry; -import game.item.ItemStack; -import game.rng.Random; -import game.world.World; +import common.entity.types.EntityLiving; +import common.init.Items; +import common.init.NameRegistry; +import common.item.ItemStack; +import common.rng.Random; +import common.world.World; public class EntityWoodElf extends EntityNPC { public EntityWoodElf(World worldIn) { diff --git a/java/src/game/entity/npc/EntityZombie.java b/java/src/common/entity/npc/EntityZombie.java similarity index 96% rename from java/src/game/entity/npc/EntityZombie.java rename to java/src/common/entity/npc/EntityZombie.java index 8ca32f5..449d5b6 100755 --- a/java/src/game/entity/npc/EntityZombie.java +++ b/java/src/common/entity/npc/EntityZombie.java @@ -1,20 +1,20 @@ -package game.entity.npc; +package common.entity.npc; import java.util.List; import java.util.function.Predicate; -import game.ai.EntityAIMoveThroughVillage; -import game.entity.DamageSource; -import game.entity.animal.EntityChicken; -import game.entity.attributes.AttributeModifier; -import game.entity.attributes.Attributes; -import game.entity.types.EntityLiving; -import game.init.Config; -import game.rng.Random; -import game.util.ExtMath; -import game.world.BlockPos; -import game.world.World; -import game.world.WorldServer; +import common.ai.EntityAIMoveThroughVillage; +import common.entity.DamageSource; +import common.entity.animal.EntityChicken; +import common.entity.attributes.AttributeModifier; +import common.entity.attributes.Attributes; +import common.entity.types.EntityLiving; +import common.init.Config; +import common.rng.Random; +import common.util.ExtMath; +import common.world.BlockPos; +import common.world.World; +import common.world.WorldServer; public class EntityZombie extends EntityNPC { diff --git a/java/src/game/entity/npc/NpcInfo.java b/java/src/common/entity/npc/NpcInfo.java similarity index 89% rename from java/src/game/entity/npc/NpcInfo.java rename to java/src/common/entity/npc/NpcInfo.java index b6b985a..f0ba67c 100644 --- a/java/src/game/entity/npc/NpcInfo.java +++ b/java/src/common/entity/npc/NpcInfo.java @@ -1,6 +1,6 @@ -package game.entity.npc; +package common.entity.npc; -import game.item.ItemStack; +import common.item.ItemStack; public class NpcInfo { public final Enum type; diff --git a/java/src/game/entity/npc/PlayerCharacter.java b/java/src/common/entity/npc/PlayerCharacter.java similarity index 89% rename from java/src/game/entity/npc/PlayerCharacter.java rename to java/src/common/entity/npc/PlayerCharacter.java index cc39e4e..75ce463 100644 --- a/java/src/game/entity/npc/PlayerCharacter.java +++ b/java/src/common/entity/npc/PlayerCharacter.java @@ -1,6 +1,6 @@ -package game.entity.npc; +package common.entity.npc; -import game.world.BlockPos; +import common.world.BlockPos; public class PlayerCharacter { public final String name; diff --git a/java/src/game/entity/npc/SpeciesInfo.java b/java/src/common/entity/npc/SpeciesInfo.java similarity index 92% rename from java/src/game/entity/npc/SpeciesInfo.java rename to java/src/common/entity/npc/SpeciesInfo.java index 9e8242f..1c9cbad 100755 --- a/java/src/game/entity/npc/SpeciesInfo.java +++ b/java/src/common/entity/npc/SpeciesInfo.java @@ -1,14 +1,14 @@ -package game.entity.npc; +package common.entity.npc; import java.util.List; -import game.collect.BiMap; -import game.collect.HashBiMap; -import game.collect.Lists; -import game.init.SpeciesRegistry; -import game.init.SpeciesRegistry.ModelType; -import game.rng.Random; -import game.util.Identifyable; +import common.collect.BiMap; +import common.collect.HashBiMap; +import common.collect.Lists; +import common.init.SpeciesRegistry; +import common.init.SpeciesRegistry.ModelType; +import common.rng.Random; +import common.util.Identifyable; public class SpeciesInfo { public final BiMap classnames; diff --git a/java/src/game/entity/projectile/EntityArrow.java b/java/src/common/entity/projectile/EntityArrow.java similarity index 96% rename from java/src/game/entity/projectile/EntityArrow.java rename to java/src/common/entity/projectile/EntityArrow.java index 59180f1..6e3dd50 100755 --- a/java/src/game/entity/projectile/EntityArrow.java +++ b/java/src/common/entity/projectile/EntityArrow.java @@ -1,31 +1,31 @@ -package game.entity.projectile; +package common.entity.projectile; import java.util.List; -import game.block.Block; -import game.enchantment.EnchantmentHelper; -import game.entity.DamageSource; -import game.entity.Entity; -import game.entity.EntityType; -import game.entity.npc.EntityNPC; -import game.entity.types.EntityLiving; -import game.entity.types.IObjectData; -import game.entity.types.IProjectile; -import game.init.BlockRegistry; -import game.init.Config; -import game.init.Items; -import game.init.SoundEvent; -import game.item.ItemStack; -import game.material.Material; -import game.model.ParticleType; -import game.nbt.NBTTagCompound; -import game.util.ExtMath; -import game.world.BlockPos; -import game.world.BoundingBox; -import game.world.HitPosition; -import game.world.State; -import game.world.Vec3; -import game.world.World; +import common.block.Block; +import common.enchantment.EnchantmentHelper; +import common.entity.DamageSource; +import common.entity.Entity; +import common.entity.EntityType; +import common.entity.npc.EntityNPC; +import common.entity.types.EntityLiving; +import common.entity.types.IObjectData; +import common.entity.types.IProjectile; +import common.init.BlockRegistry; +import common.init.Config; +import common.init.Items; +import common.init.SoundEvent; +import common.item.ItemStack; +import common.material.Material; +import common.model.ParticleType; +import common.nbt.NBTTagCompound; +import common.util.ExtMath; +import common.world.BlockPos; +import common.world.BoundingBox; +import common.world.HitPosition; +import common.world.State; +import common.world.Vec3; +import common.world.World; public class EntityArrow extends Entity implements IProjectile, IObjectData { diff --git a/java/src/game/entity/projectile/EntityBox.java b/java/src/common/entity/projectile/EntityBox.java similarity index 94% rename from java/src/game/entity/projectile/EntityBox.java rename to java/src/common/entity/projectile/EntityBox.java index ccb85f1..17c92d9 100755 --- a/java/src/game/entity/projectile/EntityBox.java +++ b/java/src/common/entity/projectile/EntityBox.java @@ -1,13 +1,13 @@ -package game.entity.projectile; +package common.entity.projectile; -import game.entity.DamageSource; -import game.entity.npc.EntityGargoyle; -import game.entity.types.EntityLiving; -import game.init.Config; -import game.potion.Potion; -import game.potion.PotionEffect; -import game.world.HitPosition; -import game.world.World; +import common.entity.DamageSource; +import common.entity.npc.EntityGargoyle; +import common.entity.types.EntityLiving; +import common.init.Config; +import common.potion.Potion; +import common.potion.PotionEffect; +import common.world.HitPosition; +import common.world.World; public class EntityBox extends EntityProjectile { diff --git a/java/src/game/entity/projectile/EntityBullet.java b/java/src/common/entity/projectile/EntityBullet.java similarity index 96% rename from java/src/game/entity/projectile/EntityBullet.java rename to java/src/common/entity/projectile/EntityBullet.java index 035e8a9..040336e 100755 --- a/java/src/game/entity/projectile/EntityBullet.java +++ b/java/src/common/entity/projectile/EntityBullet.java @@ -1,22 +1,22 @@ -package game.entity.projectile; +package common.entity.projectile; import java.util.List; -import game.enchantment.EnchantmentHelper; -import game.entity.DamageSource; -import game.entity.Entity; -import game.entity.EntityType; -import game.entity.types.EntityLiving; -import game.entity.types.IObjectData; -import game.entity.types.IProjectile; -import game.init.Config; -import game.init.SoundEvent; -import game.nbt.NBTTagCompound; -import game.util.ExtMath; -import game.world.BoundingBox; -import game.world.HitPosition; -import game.world.Vec3; -import game.world.World; +import common.enchantment.EnchantmentHelper; +import common.entity.DamageSource; +import common.entity.Entity; +import common.entity.EntityType; +import common.entity.types.EntityLiving; +import common.entity.types.IObjectData; +import common.entity.types.IProjectile; +import common.init.Config; +import common.init.SoundEvent; +import common.nbt.NBTTagCompound; +import common.util.ExtMath; +import common.world.BoundingBox; +import common.world.HitPosition; +import common.world.Vec3; +import common.world.World; public class EntityBullet extends Entity implements IProjectile, IObjectData { diff --git a/java/src/game/entity/projectile/EntityDie.java b/java/src/common/entity/projectile/EntityDie.java similarity index 89% rename from java/src/game/entity/projectile/EntityDie.java rename to java/src/common/entity/projectile/EntityDie.java index f242b73..80ad963 100755 --- a/java/src/game/entity/projectile/EntityDie.java +++ b/java/src/common/entity/projectile/EntityDie.java @@ -1,17 +1,17 @@ -package game.entity.projectile; +package common.entity.projectile; -import game.entity.DamageSource; -import game.entity.npc.EntityNPC; -import game.entity.types.EntityLiving; -import game.entity.types.EntityThrowable; -import game.entity.types.IObjectData; -import game.init.Items; -import game.init.SoundEvent; -import game.item.ItemDie; -import game.item.ItemStack; -import game.nbt.NBTTagCompound; -import game.world.HitPosition; -import game.world.World; +import common.entity.DamageSource; +import common.entity.npc.EntityNPC; +import common.entity.types.EntityLiving; +import common.entity.types.EntityThrowable; +import common.entity.types.IObjectData; +import common.init.Items; +import common.init.SoundEvent; +import common.item.ItemDie; +import common.item.ItemStack; +import common.nbt.NBTTagCompound; +import common.world.HitPosition; +import common.world.World; public class EntityDie extends EntityThrowable implements IObjectData { diff --git a/java/src/game/entity/projectile/EntityDynamite.java b/java/src/common/entity/projectile/EntityDynamite.java similarity index 82% rename from java/src/game/entity/projectile/EntityDynamite.java rename to java/src/common/entity/projectile/EntityDynamite.java index abe2a29..3c24d55 100755 --- a/java/src/game/entity/projectile/EntityDynamite.java +++ b/java/src/common/entity/projectile/EntityDynamite.java @@ -1,17 +1,17 @@ -package game.entity.projectile; +package common.entity.projectile; -import game.entity.DamageSource; -import game.entity.EntityType; -import game.entity.types.EntityLiving; -import game.entity.types.EntityThrowable; -import game.entity.types.IObjectData; -import game.init.Config; -import game.init.ItemRegistry; -import game.init.Items; -import game.model.ParticleType; -import game.nbt.NBTTagCompound; -import game.world.HitPosition; -import game.world.World; +import common.entity.DamageSource; +import common.entity.EntityType; +import common.entity.types.EntityLiving; +import common.entity.types.EntityThrowable; +import common.entity.types.IObjectData; +import common.init.Config; +import common.init.ItemRegistry; +import common.init.Items; +import common.model.ParticleType; +import common.nbt.NBTTagCompound; +import common.world.HitPosition; +import common.world.World; public class EntityDynamite extends EntityThrowable implements IObjectData { diff --git a/java/src/game/entity/projectile/EntityEgg.java b/java/src/common/entity/projectile/EntityEgg.java similarity index 82% rename from java/src/game/entity/projectile/EntityEgg.java rename to java/src/common/entity/projectile/EntityEgg.java index 2b5f183..5f22a96 100755 --- a/java/src/game/entity/projectile/EntityEgg.java +++ b/java/src/common/entity/projectile/EntityEgg.java @@ -1,15 +1,15 @@ -package game.entity.projectile; +package common.entity.projectile; -import game.entity.DamageSource; -import game.entity.animal.EntityChicken; -import game.entity.types.EntityLiving; -import game.entity.types.EntityThrowable; -import game.init.Config; -import game.init.ItemRegistry; -import game.init.Items; -import game.model.ParticleType; -import game.world.HitPosition; -import game.world.World; +import common.entity.DamageSource; +import common.entity.animal.EntityChicken; +import common.entity.types.EntityLiving; +import common.entity.types.EntityThrowable; +import common.init.Config; +import common.init.ItemRegistry; +import common.init.Items; +import common.model.ParticleType; +import common.world.HitPosition; +import common.world.World; public class EntityEgg extends EntityThrowable { diff --git a/java/src/game/entity/projectile/EntityFireCharge.java b/java/src/common/entity/projectile/EntityFireCharge.java similarity index 91% rename from java/src/game/entity/projectile/EntityFireCharge.java rename to java/src/common/entity/projectile/EntityFireCharge.java index 4776022..999c561 100755 --- a/java/src/game/entity/projectile/EntityFireCharge.java +++ b/java/src/common/entity/projectile/EntityFireCharge.java @@ -1,12 +1,12 @@ -package game.entity.projectile; +package common.entity.projectile; -import game.entity.DamageSource; -import game.entity.types.EntityLiving; -import game.init.Blocks; -import game.init.Config; -import game.world.BlockPos; -import game.world.HitPosition; -import game.world.World; +import common.entity.DamageSource; +import common.entity.types.EntityLiving; +import common.init.Blocks; +import common.init.Config; +import common.world.BlockPos; +import common.world.HitPosition; +import common.world.World; public class EntityFireCharge extends EntityProjectile { diff --git a/java/src/game/entity/projectile/EntityFireball.java b/java/src/common/entity/projectile/EntityFireball.java similarity index 89% rename from java/src/game/entity/projectile/EntityFireball.java rename to java/src/common/entity/projectile/EntityFireball.java index 93cc5d9..3aa02c6 100755 --- a/java/src/game/entity/projectile/EntityFireball.java +++ b/java/src/common/entity/projectile/EntityFireball.java @@ -1,11 +1,11 @@ -package game.entity.projectile; +package common.entity.projectile; -import game.entity.DamageSource; -import game.entity.types.EntityLiving; -import game.init.Config; -import game.nbt.NBTTagCompound; -import game.world.HitPosition; -import game.world.World; +import common.entity.DamageSource; +import common.entity.types.EntityLiving; +import common.init.Config; +import common.nbt.NBTTagCompound; +import common.world.HitPosition; +import common.world.World; public class EntityFireball extends EntityProjectile { diff --git a/java/src/game/entity/projectile/EntityHook.java b/java/src/common/entity/projectile/EntityHook.java similarity index 96% rename from java/src/game/entity/projectile/EntityHook.java rename to java/src/common/entity/projectile/EntityHook.java index d5ef76a..d348d73 100755 --- a/java/src/game/entity/projectile/EntityHook.java +++ b/java/src/common/entity/projectile/EntityHook.java @@ -1,32 +1,32 @@ -package game.entity.projectile; +package common.entity.projectile; import java.util.List; -import game.block.Block; -import game.enchantment.EnchantmentHelper; -import game.entity.DamageSource; -import game.entity.Entity; -import game.entity.EntityType; -import game.entity.item.EntityItem; -import game.entity.item.EntityXp; -import game.entity.npc.EntityNPC; -import game.entity.types.IObjectData; -import game.init.BlockRegistry; -import game.init.Blocks; -import game.init.Config; -import game.init.Items; -import game.init.SoundEvent; -import game.item.ItemStack; -import game.model.ParticleType; -import game.nbt.NBTTagCompound; -import game.util.ExtMath; -import game.world.BlockPos; -import game.world.BoundingBox; -import game.world.HitPosition; -import game.world.Vec3; -import game.world.World; -import game.world.WorldServer; -import game.worldgen.LootConstants; +import common.block.Block; +import common.enchantment.EnchantmentHelper; +import common.entity.DamageSource; +import common.entity.Entity; +import common.entity.EntityType; +import common.entity.item.EntityItem; +import common.entity.item.EntityXp; +import common.entity.npc.EntityNPC; +import common.entity.types.IObjectData; +import common.init.BlockRegistry; +import common.init.Blocks; +import common.init.Config; +import common.init.Items; +import common.init.SoundEvent; +import common.item.ItemStack; +import common.model.ParticleType; +import common.nbt.NBTTagCompound; +import common.util.ExtMath; +import common.world.BlockPos; +import common.world.BoundingBox; +import common.world.HitPosition; +import common.world.Vec3; +import common.world.World; +import common.world.WorldServer; +import common.worldgen.LootConstants; public class EntityHook extends Entity implements IObjectData { diff --git a/java/src/game/entity/projectile/EntityPotion.java b/java/src/common/entity/projectile/EntityPotion.java similarity index 92% rename from java/src/game/entity/projectile/EntityPotion.java rename to java/src/common/entity/projectile/EntityPotion.java index 21f86b5..93e1fbb 100755 --- a/java/src/game/entity/projectile/EntityPotion.java +++ b/java/src/common/entity/projectile/EntityPotion.java @@ -1,19 +1,19 @@ -package game.entity.projectile; +package common.entity.projectile; import java.util.List; -import game.entity.types.EntityLiving; -import game.entity.types.EntityThrowable; -import game.entity.types.IObjectData; -import game.init.Items; -import game.item.ItemStack; -import game.nbt.NBTTagCompound; -import game.potion.Potion; -import game.potion.PotionEffect; -import game.world.BlockPos; -import game.world.BoundingBox; -import game.world.HitPosition; -import game.world.World; +import common.entity.types.EntityLiving; +import common.entity.types.EntityThrowable; +import common.entity.types.IObjectData; +import common.init.Items; +import common.item.ItemStack; +import common.nbt.NBTTagCompound; +import common.potion.Potion; +import common.potion.PotionEffect; +import common.world.BlockPos; +import common.world.BoundingBox; +import common.world.HitPosition; +import common.world.World; public class EntityPotion extends EntityThrowable implements IObjectData { diff --git a/java/src/game/entity/projectile/EntityProjectile.java b/java/src/common/entity/projectile/EntityProjectile.java similarity index 96% rename from java/src/game/entity/projectile/EntityProjectile.java rename to java/src/common/entity/projectile/EntityProjectile.java index 97d0578..a8ab021 100755 --- a/java/src/game/entity/projectile/EntityProjectile.java +++ b/java/src/common/entity/projectile/EntityProjectile.java @@ -1,22 +1,22 @@ -package game.entity.projectile; +package common.entity.projectile; import java.util.List; -import game.block.Block; -import game.entity.DamageSource; -import game.entity.Entity; -import game.entity.EntityType; -import game.entity.types.EntityLiving; -import game.init.BlockRegistry; -import game.model.ParticleType; -import game.nbt.NBTTagCompound; -import game.nbt.NBTTagList; -import game.util.ExtMath; -import game.world.BlockPos; -import game.world.BoundingBox; -import game.world.HitPosition; -import game.world.Vec3; -import game.world.World; +import common.block.Block; +import common.entity.DamageSource; +import common.entity.Entity; +import common.entity.EntityType; +import common.entity.types.EntityLiving; +import common.init.BlockRegistry; +import common.model.ParticleType; +import common.nbt.NBTTagCompound; +import common.nbt.NBTTagList; +import common.util.ExtMath; +import common.world.BlockPos; +import common.world.BoundingBox; +import common.world.HitPosition; +import common.world.Vec3; +import common.world.World; public abstract class EntityProjectile extends Entity { diff --git a/java/src/game/entity/projectile/EntitySnowball.java b/java/src/common/entity/projectile/EntitySnowball.java similarity index 80% rename from java/src/game/entity/projectile/EntitySnowball.java rename to java/src/common/entity/projectile/EntitySnowball.java index 9c0ee15..b1801de 100755 --- a/java/src/game/entity/projectile/EntitySnowball.java +++ b/java/src/common/entity/projectile/EntitySnowball.java @@ -1,12 +1,12 @@ -package game.entity.projectile; +package common.entity.projectile; -import game.entity.DamageSource; -import game.entity.types.EntityLiving; -import game.entity.types.EntityThrowable; -import game.init.Config; -import game.model.ParticleType; -import game.world.HitPosition; -import game.world.World; +import common.entity.DamageSource; +import common.entity.types.EntityLiving; +import common.entity.types.EntityThrowable; +import common.init.Config; +import common.model.ParticleType; +import common.world.HitPosition; +import common.world.World; public class EntitySnowball extends EntityThrowable { diff --git a/java/src/game/entity/projectile/RngFishable.java b/java/src/common/entity/projectile/RngFishable.java similarity index 88% rename from java/src/game/entity/projectile/RngFishable.java rename to java/src/common/entity/projectile/RngFishable.java index 9d4c6c8..700ec68 100755 --- a/java/src/game/entity/projectile/RngFishable.java +++ b/java/src/common/entity/projectile/RngFishable.java @@ -1,9 +1,9 @@ -package game.entity.projectile; +package common.entity.projectile; -import game.enchantment.EnchantmentHelper; -import game.item.ItemStack; -import game.rng.Random; -import game.rng.RngItem; +import common.enchantment.EnchantmentHelper; +import common.item.ItemStack; +import common.rng.Random; +import common.rng.RngItem; public class RngFishable extends RngItem { diff --git a/java/src/game/entity/types/CombatEntry.java b/java/src/common/entity/types/CombatEntry.java similarity index 91% rename from java/src/game/entity/types/CombatEntry.java rename to java/src/common/entity/types/CombatEntry.java index 5239d4f..d630ff5 100755 --- a/java/src/game/entity/types/CombatEntry.java +++ b/java/src/common/entity/types/CombatEntry.java @@ -1,6 +1,6 @@ -package game.entity.types; +package common.entity.types; -import game.entity.DamageSource; +import common.entity.DamageSource; public class CombatEntry { private final DamageSource source; diff --git a/java/src/game/entity/types/EntityAnimal.java b/java/src/common/entity/types/EntityAnimal.java similarity index 94% rename from java/src/game/entity/types/EntityAnimal.java rename to java/src/common/entity/types/EntityAnimal.java index 85c8944..f3565c6 100755 --- a/java/src/game/entity/types/EntityAnimal.java +++ b/java/src/common/entity/types/EntityAnimal.java @@ -1,21 +1,21 @@ -package game.entity.types; +package common.entity.types; import java.util.Set; -import game.block.Block; -import game.collect.Sets; -import game.entity.DamageSource; -import game.entity.EntityType; -import game.entity.npc.Alignment; -import game.entity.npc.EntityNPC; -import game.init.Blocks; -import game.init.Items; -import game.item.ItemStack; -import game.model.ParticleType; -import game.nbt.NBTTagCompound; -import game.util.ExtMath; -import game.world.BlockPos; -import game.world.World; +import common.block.Block; +import common.collect.Sets; +import common.entity.DamageSource; +import common.entity.EntityType; +import common.entity.npc.Alignment; +import common.entity.npc.EntityNPC; +import common.init.Blocks; +import common.init.Items; +import common.item.ItemStack; +import common.model.ParticleType; +import common.nbt.NBTTagCompound; +import common.util.ExtMath; +import common.world.BlockPos; +import common.world.World; public abstract class EntityAnimal extends EntityLiving { diff --git a/java/src/game/entity/types/EntityBodyHelper.java b/java/src/common/entity/types/EntityBodyHelper.java similarity index 97% rename from java/src/game/entity/types/EntityBodyHelper.java rename to java/src/common/entity/types/EntityBodyHelper.java index 0fa1d8c..26160ea 100755 --- a/java/src/game/entity/types/EntityBodyHelper.java +++ b/java/src/common/entity/types/EntityBodyHelper.java @@ -1,6 +1,6 @@ -package game.entity.types; +package common.entity.types; -import game.util.ExtMath; +import common.util.ExtMath; public class EntityBodyHelper { diff --git a/java/src/game/entity/types/EntityLiving.java b/java/src/common/entity/types/EntityLiving.java similarity index 97% rename from java/src/game/entity/types/EntityLiving.java rename to java/src/common/entity/types/EntityLiving.java index baa92d7..2bb0f27 100755 --- a/java/src/game/entity/types/EntityLiving.java +++ b/java/src/common/entity/types/EntityLiving.java @@ -1,4 +1,4 @@ -package game.entity.types; +package common.entity.types; import java.util.Collection; import java.util.Iterator; @@ -6,67 +6,67 @@ import java.util.List; import java.util.Map; import java.util.function.Predicate; -import game.ai.EntityAIBase; -import game.ai.EntityAIMoveTowardsRestriction; -import game.ai.EntityAITasks; -import game.ai.EntityJumpHelper; -import game.ai.EntityLookHelper; -import game.ai.EntityMoveHelper; -import game.ai.EntitySenses; -import game.block.Block; -import game.block.SoundType; -import game.collect.Lists; -import game.collect.Maps; -import game.color.TextColor; -import game.enchantment.EnchantmentHelper; -import game.entity.DamageSource; -import game.entity.Entity; -import game.entity.EntityDamageSource; -import game.entity.animal.EntityWolf; -import game.entity.attributes.Attribute; -import game.entity.attributes.AttributeInstance; -import game.entity.attributes.AttributeMap; -import game.entity.attributes.AttributeModifier; -import game.entity.attributes.Attributes; -import game.entity.item.EntityItem; -import game.entity.item.EntityLeashKnot; -import game.entity.item.EntityXp; -import game.entity.npc.Alignment; -import game.entity.npc.Energy; -import game.entity.npc.EntityNPC; -import game.entity.projectile.EntityArrow; -import game.init.BlockRegistry; -import game.init.Blocks; -import game.init.Config; -import game.init.EntityRegistry; -import game.init.ItemRegistry; -import game.init.Items; -import game.init.SoundEvent; -import game.item.Item; -import game.item.ItemArmor; -import game.item.ItemMonsterPlacer; -import game.item.ItemStack; -import game.material.Material; -import game.model.ParticleType; -import game.nbt.NBTTagCompound; -import game.nbt.NBTTagList; -import game.network.IPlayer; -import game.packet.S1BPacketEntityAttach; -import game.packet.SPacketAnimation; -import game.packet.SPacketCollectItem; -import game.pathfinding.PathNavigate; -import game.pathfinding.PathNavigateGround; -import game.potion.Potion; -import game.potion.PotionEffect; -import game.potion.PotionHelper; -import game.rng.Random; -import game.util.ExtMath; -import game.world.BlockPos; -import game.world.BoundingBox; -import game.world.State; -import game.world.Vec3; -import game.world.World; -import game.world.WorldServer; +import common.ai.EntityAIBase; +import common.ai.EntityAIMoveTowardsRestriction; +import common.ai.EntityAITasks; +import common.ai.EntityJumpHelper; +import common.ai.EntityLookHelper; +import common.ai.EntityMoveHelper; +import common.ai.EntitySenses; +import common.block.Block; +import common.block.SoundType; +import common.collect.Lists; +import common.collect.Maps; +import common.color.TextColor; +import common.enchantment.EnchantmentHelper; +import common.entity.DamageSource; +import common.entity.Entity; +import common.entity.EntityDamageSource; +import common.entity.animal.EntityWolf; +import common.entity.attributes.Attribute; +import common.entity.attributes.AttributeInstance; +import common.entity.attributes.AttributeMap; +import common.entity.attributes.AttributeModifier; +import common.entity.attributes.Attributes; +import common.entity.item.EntityItem; +import common.entity.item.EntityLeashKnot; +import common.entity.item.EntityXp; +import common.entity.npc.Alignment; +import common.entity.npc.Energy; +import common.entity.npc.EntityNPC; +import common.entity.projectile.EntityArrow; +import common.init.BlockRegistry; +import common.init.Blocks; +import common.init.Config; +import common.init.EntityRegistry; +import common.init.ItemRegistry; +import common.init.Items; +import common.init.SoundEvent; +import common.item.Item; +import common.item.ItemArmor; +import common.item.ItemMonsterPlacer; +import common.item.ItemStack; +import common.material.Material; +import common.model.ParticleType; +import common.nbt.NBTTagCompound; +import common.nbt.NBTTagList; +import common.network.IPlayer; +import common.packet.S1BPacketEntityAttach; +import common.packet.SPacketAnimation; +import common.packet.SPacketCollectItem; +import common.pathfinding.PathNavigate; +import common.pathfinding.PathNavigateGround; +import common.potion.Potion; +import common.potion.PotionEffect; +import common.potion.PotionHelper; +import common.rng.Random; +import common.util.ExtMath; +import common.world.BlockPos; +import common.world.BoundingBox; +import common.world.State; +import common.world.Vec3; +import common.world.World; +import common.world.WorldServer; public abstract class EntityLiving extends Entity { diff --git a/java/src/game/entity/types/EntityTameable.java b/java/src/common/entity/types/EntityTameable.java similarity index 97% rename from java/src/game/entity/types/EntityTameable.java rename to java/src/common/entity/types/EntityTameable.java index ab00c53..877b9c9 100755 --- a/java/src/game/entity/types/EntityTameable.java +++ b/java/src/common/entity/types/EntityTameable.java @@ -1,9 +1,9 @@ -package game.entity.types; +package common.entity.types; -import game.ai.EntityAISit; -import game.model.ParticleType; -import game.nbt.NBTTagCompound; -import game.world.World; +import common.ai.EntityAISit; +import common.model.ParticleType; +import common.nbt.NBTTagCompound; +import common.world.World; public abstract class EntityTameable extends EntityAnimal implements IEntityOwnable { diff --git a/java/src/game/entity/types/EntityThrowable.java b/java/src/common/entity/types/EntityThrowable.java similarity index 96% rename from java/src/game/entity/types/EntityThrowable.java rename to java/src/common/entity/types/EntityThrowable.java index 79395d4..3eac442 100755 --- a/java/src/game/entity/types/EntityThrowable.java +++ b/java/src/common/entity/types/EntityThrowable.java @@ -1,22 +1,22 @@ -package game.entity.types; +package common.entity.types; import java.util.List; -import game.block.Block; -import game.block.BlockPortal; -import game.entity.Entity; -import game.entity.EntityType; -import game.init.BlockRegistry; -import game.init.Blocks; -import game.model.ParticleType; -import game.nbt.NBTTagCompound; -import game.util.ExtMath; -import game.world.BlockPos; -import game.world.BoundingBox; -import game.world.HitPosition; -import game.world.State; -import game.world.Vec3; -import game.world.World; +import common.block.Block; +import common.block.BlockPortal; +import common.entity.Entity; +import common.entity.EntityType; +import common.init.BlockRegistry; +import common.init.Blocks; +import common.model.ParticleType; +import common.nbt.NBTTagCompound; +import common.util.ExtMath; +import common.world.BlockPos; +import common.world.BoundingBox; +import common.world.HitPosition; +import common.world.State; +import common.world.Vec3; +import common.world.World; public abstract class EntityThrowable extends Entity implements IProjectile { diff --git a/java/src/game/entity/types/EntityWaterMob.java b/java/src/common/entity/types/EntityWaterMob.java similarity index 92% rename from java/src/game/entity/types/EntityWaterMob.java rename to java/src/common/entity/types/EntityWaterMob.java index bca942d..7b9e27e 100755 --- a/java/src/game/entity/types/EntityWaterMob.java +++ b/java/src/common/entity/types/EntityWaterMob.java @@ -1,10 +1,10 @@ -package game.entity.types; +package common.entity.types; -import game.entity.DamageSource; -import game.entity.EntityType; -import game.entity.npc.EntityNPC; -import game.init.Config; -import game.world.World; +import common.entity.DamageSource; +import common.entity.EntityType; +import common.entity.npc.EntityNPC; +import common.init.Config; +import common.world.World; public abstract class EntityWaterMob extends EntityLiving { diff --git a/java/src/game/entity/types/EntityWeatherEffect.java b/java/src/common/entity/types/EntityWeatherEffect.java similarity index 81% rename from java/src/game/entity/types/EntityWeatherEffect.java rename to java/src/common/entity/types/EntityWeatherEffect.java index b958937..3604e81 100755 --- a/java/src/game/entity/types/EntityWeatherEffect.java +++ b/java/src/common/entity/types/EntityWeatherEffect.java @@ -1,9 +1,9 @@ -package game.entity.types; +package common.entity.types; -import game.entity.Entity; -import game.entity.EntityType; -import game.nbt.NBTTagCompound; -import game.world.World; +import common.entity.Entity; +import common.entity.EntityType; +import common.nbt.NBTTagCompound; +import common.world.World; public abstract class EntityWeatherEffect extends Entity { public EntityWeatherEffect(World world) { diff --git a/java/src/game/entity/types/IEntityFX.java b/java/src/common/entity/types/IEntityFX.java similarity index 84% rename from java/src/game/entity/types/IEntityFX.java rename to java/src/common/entity/types/IEntityFX.java index cf4aece..2676179 100644 --- a/java/src/game/entity/types/IEntityFX.java +++ b/java/src/common/entity/types/IEntityFX.java @@ -1,4 +1,4 @@ -package game.entity.types; +package common.entity.types; public interface IEntityFX { diff --git a/java/src/game/entity/types/IEntityMultiPart.java b/java/src/common/entity/types/IEntityMultiPart.java similarity index 54% rename from java/src/game/entity/types/IEntityMultiPart.java rename to java/src/common/entity/types/IEntityMultiPart.java index a8b4692..5ad5770 100755 --- a/java/src/game/entity/types/IEntityMultiPart.java +++ b/java/src/common/entity/types/IEntityMultiPart.java @@ -1,8 +1,8 @@ -package game.entity.types; +package common.entity.types; -import game.entity.DamageSource; -import game.entity.animal.EntityDragonPart; -import game.world.World; +import common.entity.DamageSource; +import common.entity.animal.EntityDragonPart; +import common.world.World; public interface IEntityMultiPart { diff --git a/java/src/game/entity/types/IEntityOwnable.java b/java/src/common/entity/types/IEntityOwnable.java similarity index 60% rename from java/src/game/entity/types/IEntityOwnable.java rename to java/src/common/entity/types/IEntityOwnable.java index a048caa..4dd194d 100755 --- a/java/src/game/entity/types/IEntityOwnable.java +++ b/java/src/common/entity/types/IEntityOwnable.java @@ -1,6 +1,6 @@ -package game.entity.types; +package common.entity.types; -import game.entity.Entity; +import common.entity.Entity; public interface IEntityOwnable { diff --git a/java/src/game/entity/types/IObjectData.java b/java/src/common/entity/types/IObjectData.java similarity index 65% rename from java/src/game/entity/types/IObjectData.java rename to java/src/common/entity/types/IObjectData.java index 1e206e9..2174539 100755 --- a/java/src/game/entity/types/IObjectData.java +++ b/java/src/common/entity/types/IObjectData.java @@ -1,4 +1,4 @@ -package game.entity.types; +package common.entity.types; public interface IObjectData { int getPacketData(); diff --git a/java/src/game/entity/types/IProjectile.java b/java/src/common/entity/types/IProjectile.java similarity index 81% rename from java/src/game/entity/types/IProjectile.java rename to java/src/common/entity/types/IProjectile.java index d4d6b9d..3f71083 100755 --- a/java/src/game/entity/types/IProjectile.java +++ b/java/src/common/entity/types/IProjectile.java @@ -1,4 +1,4 @@ -package game.entity.types; +package common.entity.types; public interface IProjectile { void setThrowableHeading(double x, double y, double z, float velocity, float inaccuracy); diff --git a/java/src/game/future/AbstractFuture.java b/java/src/common/future/AbstractFuture.java similarity index 99% rename from java/src/game/future/AbstractFuture.java rename to java/src/common/future/AbstractFuture.java index e63a476..280f3af 100644 --- a/java/src/game/future/AbstractFuture.java +++ b/java/src/common/future/AbstractFuture.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package game.future; +package common.future; import java.util.concurrent.CancellationException; import java.util.concurrent.ExecutionException; diff --git a/java/src/game/future/ExecutionError.java b/java/src/common/future/ExecutionError.java similarity index 98% rename from java/src/game/future/ExecutionError.java rename to java/src/common/future/ExecutionError.java index cf8eae0..73fe3f1 100644 --- a/java/src/game/future/ExecutionError.java +++ b/java/src/common/future/ExecutionError.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package game.future; +package common.future; /** * {@link Error} variant of {@link java.util.concurrent.ExecutionException}. As diff --git a/java/src/game/future/ExecutionList.java b/java/src/common/future/ExecutionList.java similarity index 99% rename from java/src/game/future/ExecutionList.java rename to java/src/common/future/ExecutionList.java index 79e86cf..46a757c 100644 --- a/java/src/game/future/ExecutionList.java +++ b/java/src/common/future/ExecutionList.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package game.future; +package common.future; import java.util.concurrent.Executor; import java.util.logging.Level; diff --git a/java/src/game/future/FutureCallback.java b/java/src/common/future/FutureCallback.java similarity index 98% rename from java/src/game/future/FutureCallback.java rename to java/src/common/future/FutureCallback.java index cdb9092..6e5b529 100644 --- a/java/src/game/future/FutureCallback.java +++ b/java/src/common/future/FutureCallback.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package game.future; +package common.future; /** * A callback for accepting the results of a {@link java.util.concurrent.Future} diff --git a/java/src/game/future/Futures.java b/java/src/common/future/Futures.java similarity index 99% rename from java/src/game/future/Futures.java rename to java/src/common/future/Futures.java index 08fe41f..6dbce5f 100644 --- a/java/src/game/future/Futures.java +++ b/java/src/common/future/Futures.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package game.future; +package common.future; import java.util.ArrayList; import java.util.List; @@ -28,8 +28,8 @@ import java.util.concurrent.atomic.AtomicInteger; import java.util.logging.Level; import java.util.logging.Logger; -import game.collect.ImmutableList; -import game.collect.Sets; +import common.collect.ImmutableList; +import common.collect.Sets; /** * Static utility methods pertaining to the {@link Future} interface. diff --git a/java/src/game/future/ListenableFuture.java b/java/src/common/future/ListenableFuture.java similarity index 99% rename from java/src/game/future/ListenableFuture.java rename to java/src/common/future/ListenableFuture.java index ab19dd2..c841794 100644 --- a/java/src/game/future/ListenableFuture.java +++ b/java/src/common/future/ListenableFuture.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package game.future; +package common.future; import java.util.concurrent.Executor; import java.util.concurrent.Future; diff --git a/java/src/game/future/ListenableFutureTask.java b/java/src/common/future/ListenableFutureTask.java similarity index 99% rename from java/src/game/future/ListenableFutureTask.java rename to java/src/common/future/ListenableFutureTask.java index 38b0621..e2b9450 100644 --- a/java/src/game/future/ListenableFutureTask.java +++ b/java/src/common/future/ListenableFutureTask.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package game.future; +package common.future; import java.util.concurrent.Callable; import java.util.concurrent.Executor; diff --git a/java/src/game/future/MoreExecutors.java b/java/src/common/future/MoreExecutors.java similarity index 99% rename from java/src/game/future/MoreExecutors.java rename to java/src/common/future/MoreExecutors.java index 5e3e49a..ad8b8f1 100644 --- a/java/src/game/future/MoreExecutors.java +++ b/java/src/common/future/MoreExecutors.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package game.future; +package common.future; import java.util.Collections; import java.util.List; diff --git a/java/src/game/future/ThreadFactoryBuilder.java b/java/src/common/future/ThreadFactoryBuilder.java similarity index 99% rename from java/src/game/future/ThreadFactoryBuilder.java rename to java/src/common/future/ThreadFactoryBuilder.java index 611bdf0..a115d0f 100644 --- a/java/src/game/future/ThreadFactoryBuilder.java +++ b/java/src/common/future/ThreadFactoryBuilder.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package game.future; +package common.future; import java.lang.Thread.UncaughtExceptionHandler; import java.util.concurrent.Executors; diff --git a/java/src/game/future/UncheckedExecutionException.java b/java/src/common/future/UncheckedExecutionException.java similarity index 98% rename from java/src/game/future/UncheckedExecutionException.java rename to java/src/common/future/UncheckedExecutionException.java index 4f25bf8..b080867 100644 --- a/java/src/game/future/UncheckedExecutionException.java +++ b/java/src/common/future/UncheckedExecutionException.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package game.future; +package common.future; /** * Unchecked variant of {@link java.util.concurrent.ExecutionException}. As with diff --git a/java/src/game/init/BlockRegistry.java b/java/src/common/init/BlockRegistry.java similarity index 97% rename from java/src/game/init/BlockRegistry.java rename to java/src/common/init/BlockRegistry.java index 1008a5f..2486248 100755 --- a/java/src/game/init/BlockRegistry.java +++ b/java/src/common/init/BlockRegistry.java @@ -1,11 +1,11 @@ -package game.init; +package common.init; -import game.block.*; -import game.color.DyeColor; -import game.init.FluidRegistry.LiquidType; -import game.item.CheatTab; -import game.material.Material; -import game.world.State; +import common.block.*; +import common.color.DyeColor; +import common.init.FluidRegistry.LiquidType; +import common.item.CheatTab; +import common.material.Material; +import common.world.State; public abstract class BlockRegistry { private static final String AIR_ID = "air"; diff --git a/java/src/game/init/Blocks.java b/java/src/common/init/Blocks.java similarity index 94% rename from java/src/game/init/Blocks.java rename to java/src/common/init/Blocks.java index adf4bff..eb86097 100755 --- a/java/src/game/init/Blocks.java +++ b/java/src/common/init/Blocks.java @@ -1,42 +1,42 @@ -package game.init; +package common.init; -import game.block.Block; -import game.block.BlockBeacon; -import game.block.BlockBed; -import game.block.BlockBlackenedSoil; -import game.block.BlockBush; -import game.block.BlockCactus; -import game.block.BlockCauldron; -import game.block.BlockChest; -import game.block.BlockDaylightDetector; -import game.block.BlockDeadBush; -import game.block.BlockDoublePlant; -import game.block.BlockDryLeaves; -import game.block.BlockDynamicLiquid; -import game.block.BlockFire; -import game.block.BlockFlower; -import game.block.BlockGrass; -import game.block.BlockHopper; -import game.block.BlockLeaves; -import game.block.BlockMycelium; -import game.block.BlockOre; -import game.block.BlockPistonBase; -import game.block.BlockPistonHead; -import game.block.BlockPistonMoving; -import game.block.BlockPortal; -import game.block.BlockRedstoneComparator; -import game.block.BlockRedstoneRepeater; -import game.block.BlockRedstoneWire; -import game.block.BlockReed; -import game.block.BlockSand; -import game.block.BlockSkull; -import game.block.BlockSlab; -import game.block.BlockStainedGlass; -import game.block.BlockStainedGlassPane; -import game.block.BlockStaticLiquid; -import game.block.BlockTallGrass; -import game.block.BlockTianReactor; -import game.block.BlockTripWireHook; +import common.block.Block; +import common.block.BlockBeacon; +import common.block.BlockBed; +import common.block.BlockBlackenedSoil; +import common.block.BlockBush; +import common.block.BlockCactus; +import common.block.BlockCauldron; +import common.block.BlockChest; +import common.block.BlockDaylightDetector; +import common.block.BlockDeadBush; +import common.block.BlockDoublePlant; +import common.block.BlockDryLeaves; +import common.block.BlockDynamicLiquid; +import common.block.BlockFire; +import common.block.BlockFlower; +import common.block.BlockGrass; +import common.block.BlockHopper; +import common.block.BlockLeaves; +import common.block.BlockMycelium; +import common.block.BlockOre; +import common.block.BlockPistonBase; +import common.block.BlockPistonHead; +import common.block.BlockPistonMoving; +import common.block.BlockPortal; +import common.block.BlockRedstoneComparator; +import common.block.BlockRedstoneRepeater; +import common.block.BlockRedstoneWire; +import common.block.BlockReed; +import common.block.BlockSand; +import common.block.BlockSkull; +import common.block.BlockSlab; +import common.block.BlockStainedGlass; +import common.block.BlockStainedGlassPane; +import common.block.BlockStaticLiquid; +import common.block.BlockTallGrass; +import common.block.BlockTianReactor; +import common.block.BlockTripWireHook; public abstract class Blocks { diff --git a/java/src/game/init/Config.java b/java/src/common/init/Config.java similarity index 99% rename from java/src/game/init/Config.java rename to java/src/common/init/Config.java index e59968e..5415de3 100755 --- a/java/src/game/init/Config.java +++ b/java/src/common/init/Config.java @@ -1,4 +1,4 @@ -package game.init; +package common.init; import static java.lang.annotation.ElementType.FIELD; @@ -11,10 +11,10 @@ import java.lang.reflect.Modifier; import java.util.Map; import java.util.TreeMap; -import game.packet.SPacketWorld; -import game.util.ExtMath; -import game.world.WorldServer; -import game.IServer; +import common.IServer; +import common.packet.SPacketWorld; +import common.util.ExtMath; +import common.world.WorldServer; public abstract class Config { public static enum ValueType { diff --git a/java/src/game/init/CraftingRegistry.java b/java/src/common/init/CraftingRegistry.java similarity index 99% rename from java/src/game/init/CraftingRegistry.java rename to java/src/common/init/CraftingRegistry.java index 58f80df..7e5ea06 100755 --- a/java/src/game/init/CraftingRegistry.java +++ b/java/src/common/init/CraftingRegistry.java @@ -1,4 +1,4 @@ -package game.init; +package common.init; import java.util.Collections; import java.util.Comparator; @@ -6,29 +6,29 @@ import java.util.List; import java.util.Map; import java.util.Set; -import game.block.Block; -import game.block.BlockBed; -import game.block.BlockDirt; -import game.block.BlockDoublePlant; -import game.block.BlockFlower; -import game.block.BlockQuartz; -import game.block.BlockSand; -import game.block.BlockSandStone; -import game.block.BlockStoneBrick; -import game.block.BlockWall; -import game.collect.Lists; -import game.collect.Maps; -import game.color.DyeColor; -import game.entity.animal.EntitySheep; -import game.inventory.InventoryCrafting; -import game.item.Item; -import game.item.ItemArmor; -import game.item.ItemDye; -import game.item.ItemStack; -import game.nbt.NBTTagCompound; -import game.nbt.NBTTagList; -import game.tileentity.TileEntityBanner; -import game.world.World; +import common.block.Block; +import common.block.BlockBed; +import common.block.BlockDirt; +import common.block.BlockDoublePlant; +import common.block.BlockFlower; +import common.block.BlockQuartz; +import common.block.BlockSand; +import common.block.BlockSandStone; +import common.block.BlockStoneBrick; +import common.block.BlockWall; +import common.collect.Lists; +import common.collect.Maps; +import common.color.DyeColor; +import common.entity.animal.EntitySheep; +import common.inventory.InventoryCrafting; +import common.item.Item; +import common.item.ItemArmor; +import common.item.ItemDye; +import common.item.ItemStack; +import common.nbt.NBTTagCompound; +import common.nbt.NBTTagList; +import common.tileentity.TileEntityBanner; +import common.world.World; public abstract class CraftingRegistry { diff --git a/java/src/game/init/DecoType.java b/java/src/common/init/DecoType.java similarity index 95% rename from java/src/game/init/DecoType.java rename to java/src/common/init/DecoType.java index 1765119..2ae9779 100755 --- a/java/src/game/init/DecoType.java +++ b/java/src/common/init/DecoType.java @@ -1,4 +1,4 @@ -package game.init; +package common.init; public enum DecoType { FLOOR("floor_tiles", "Schwarz-weiße Bodenfliesen"), diff --git a/java/src/game/init/DispenserRegistry.java b/java/src/common/init/DispenserRegistry.java similarity index 91% rename from java/src/game/init/DispenserRegistry.java rename to java/src/common/init/DispenserRegistry.java index eef268e..74a0bdb 100755 --- a/java/src/game/init/DispenserRegistry.java +++ b/java/src/common/init/DispenserRegistry.java @@ -1,45 +1,45 @@ -package game.init; +package common.init; -import game.block.Block; -import game.block.BlockDispenser; -import game.block.BlockDynamicLiquid; -import game.block.BlockLiquid; -import game.block.BlockTNT; -import game.color.DyeColor; -import game.dispenser.BehaviorDefaultDispenseItem; -import game.dispenser.BehaviorProjectileDispense; -import game.dispenser.IBehaviorDispenseItem; -import game.dispenser.IBlockSource; -import game.dispenser.IPosition; -import game.entity.Entity; -import game.entity.item.EntityBoat; -import game.entity.item.EntityFireworks; -import game.entity.item.EntityTnt; -import game.entity.item.EntityXpBottle; -import game.entity.projectile.EntityArrow; -import game.entity.projectile.EntityDie; -import game.entity.projectile.EntityDynamite; -import game.entity.projectile.EntityEgg; -import game.entity.projectile.EntityFireCharge; -import game.entity.projectile.EntityPotion; -import game.entity.projectile.EntitySnowball; -import game.entity.types.EntityLiving; -import game.entity.types.IProjectile; -import game.item.Item; -import game.item.ItemBucket; -import game.item.ItemDie; -import game.item.ItemDye; -import game.item.ItemMonsterPlacer; -import game.item.ItemPotion; -import game.item.ItemStack; -import game.material.Material; -import game.rng.Random; -import game.tileentity.TileEntityDispenser; -import game.util.ExtMath; -import game.world.BlockPos; -import game.world.Facing; -import game.world.State; -import game.world.World; +import common.block.Block; +import common.block.BlockDispenser; +import common.block.BlockDynamicLiquid; +import common.block.BlockLiquid; +import common.block.BlockTNT; +import common.color.DyeColor; +import common.dispenser.BehaviorDefaultDispenseItem; +import common.dispenser.BehaviorProjectileDispense; +import common.dispenser.IBehaviorDispenseItem; +import common.dispenser.IBlockSource; +import common.dispenser.IPosition; +import common.entity.Entity; +import common.entity.item.EntityBoat; +import common.entity.item.EntityFireworks; +import common.entity.item.EntityTnt; +import common.entity.item.EntityXpBottle; +import common.entity.projectile.EntityArrow; +import common.entity.projectile.EntityDie; +import common.entity.projectile.EntityDynamite; +import common.entity.projectile.EntityEgg; +import common.entity.projectile.EntityFireCharge; +import common.entity.projectile.EntityPotion; +import common.entity.projectile.EntitySnowball; +import common.entity.types.EntityLiving; +import common.entity.types.IProjectile; +import common.item.Item; +import common.item.ItemBucket; +import common.item.ItemDie; +import common.item.ItemDye; +import common.item.ItemMonsterPlacer; +import common.item.ItemPotion; +import common.item.ItemStack; +import common.material.Material; +import common.rng.Random; +import common.tileentity.TileEntityDispenser; +import common.util.ExtMath; +import common.world.BlockPos; +import common.world.Facing; +import common.world.State; +import common.world.World; public abstract class DispenserRegistry { public static final RegistryDefaulted REGISTRY = new RegistryDefaulted(new BehaviorDefaultDispenseItem()); diff --git a/java/src/game/init/EntityEggInfo.java b/java/src/common/init/EntityEggInfo.java similarity index 94% rename from java/src/game/init/EntityEggInfo.java rename to java/src/common/init/EntityEggInfo.java index 380ab00..8f7b708 100755 --- a/java/src/game/init/EntityEggInfo.java +++ b/java/src/common/init/EntityEggInfo.java @@ -1,4 +1,4 @@ -package game.init; +package common.init; public class EntityEggInfo { diff --git a/java/src/game/init/EntityRegistry.java b/java/src/common/init/EntityRegistry.java similarity index 84% rename from java/src/game/init/EntityRegistry.java rename to java/src/common/init/EntityRegistry.java index 86d8e97..7e58afe 100755 --- a/java/src/game/init/EntityRegistry.java +++ b/java/src/common/init/EntityRegistry.java @@ -1,56 +1,56 @@ -package game.init; +package common.init; import java.util.Map; import java.util.Set; -import game.collect.Maps; -import game.entity.Entity; -import game.entity.animal.EntityBat; -import game.entity.animal.EntityChicken; -import game.entity.animal.EntityCow; -import game.entity.animal.EntityDragon; -import game.entity.animal.EntityHorse; -import game.entity.animal.EntityMooshroom; -import game.entity.animal.EntityMouse; -import game.entity.animal.EntityOcelot; -import game.entity.animal.EntityPig; -import game.entity.animal.EntityRabbit; -import game.entity.animal.EntitySheep; -import game.entity.animal.EntitySquid; -import game.entity.animal.EntityWolf; -import game.entity.item.EntityBoat; -import game.entity.item.EntityChestCart; -import game.entity.item.EntityCrystal; -import game.entity.item.EntityExplosion; -import game.entity.item.EntityFalling; -import game.entity.item.EntityFireworks; -import game.entity.item.EntityHopperCart; -import game.entity.item.EntityItem; -import game.entity.item.EntityLeashKnot; -import game.entity.item.EntityMinecart; -import game.entity.item.EntityNuke; -import game.entity.item.EntityOrb; -import game.entity.item.EntityTnt; -import game.entity.item.EntityTntCart; -import game.entity.item.EntityXp; -import game.entity.item.EntityXpBottle; -import game.entity.npc.SpeciesInfo; -import game.entity.projectile.EntityArrow; -import game.entity.projectile.EntityBox; -import game.entity.projectile.EntityBullet; -import game.entity.projectile.EntityDie; -import game.entity.projectile.EntityDynamite; -import game.entity.projectile.EntityEgg; -import game.entity.projectile.EntityFireCharge; -import game.entity.projectile.EntityFireball; -import game.entity.projectile.EntityHook; -import game.entity.projectile.EntityPotion; -import game.entity.projectile.EntitySnowball; -import game.entity.types.EntityLiving; -import game.entity.types.IObjectData; -import game.log.Log; -import game.nbt.NBTTagCompound; -import game.world.World; +import common.collect.Maps; +import common.entity.Entity; +import common.entity.animal.EntityBat; +import common.entity.animal.EntityChicken; +import common.entity.animal.EntityCow; +import common.entity.animal.EntityDragon; +import common.entity.animal.EntityHorse; +import common.entity.animal.EntityMooshroom; +import common.entity.animal.EntityMouse; +import common.entity.animal.EntityOcelot; +import common.entity.animal.EntityPig; +import common.entity.animal.EntityRabbit; +import common.entity.animal.EntitySheep; +import common.entity.animal.EntitySquid; +import common.entity.animal.EntityWolf; +import common.entity.item.EntityBoat; +import common.entity.item.EntityChestCart; +import common.entity.item.EntityCrystal; +import common.entity.item.EntityExplosion; +import common.entity.item.EntityFalling; +import common.entity.item.EntityFireworks; +import common.entity.item.EntityHopperCart; +import common.entity.item.EntityItem; +import common.entity.item.EntityLeashKnot; +import common.entity.item.EntityMinecart; +import common.entity.item.EntityNuke; +import common.entity.item.EntityOrb; +import common.entity.item.EntityTnt; +import common.entity.item.EntityTntCart; +import common.entity.item.EntityXp; +import common.entity.item.EntityXpBottle; +import common.entity.npc.SpeciesInfo; +import common.entity.projectile.EntityArrow; +import common.entity.projectile.EntityBox; +import common.entity.projectile.EntityBullet; +import common.entity.projectile.EntityDie; +import common.entity.projectile.EntityDynamite; +import common.entity.projectile.EntityEgg; +import common.entity.projectile.EntityFireCharge; +import common.entity.projectile.EntityFireball; +import common.entity.projectile.EntityHook; +import common.entity.projectile.EntityPotion; +import common.entity.projectile.EntitySnowball; +import common.entity.types.EntityLiving; +import common.entity.types.IObjectData; +import common.log.Log; +import common.nbt.NBTTagCompound; +import common.world.World; public abstract class EntityRegistry { private static final Map> STRING_TO_CLASS = Maps.>newHashMap(); diff --git a/java/src/game/init/FlammabilityRegistry.java b/java/src/common/init/FlammabilityRegistry.java similarity index 96% rename from java/src/game/init/FlammabilityRegistry.java rename to java/src/common/init/FlammabilityRegistry.java index a0d5536..8403c97 100755 --- a/java/src/game/init/FlammabilityRegistry.java +++ b/java/src/common/init/FlammabilityRegistry.java @@ -1,6 +1,6 @@ -package game.init; +package common.init; -import game.block.Block; +import common.block.Block; public abstract class FlammabilityRegistry { private static void setFlammable(Block blockIn, int encouragement, int flammability) { diff --git a/java/src/game/init/FluidRegistry.java b/java/src/common/init/FluidRegistry.java similarity index 89% rename from java/src/game/init/FluidRegistry.java rename to java/src/common/init/FluidRegistry.java index 88545a9..e585f54 100755 --- a/java/src/game/init/FluidRegistry.java +++ b/java/src/common/init/FluidRegistry.java @@ -1,15 +1,15 @@ -package game.init; +package common.init; import java.util.List; import java.util.Map; -import game.block.Block; -import game.block.BlockDynamicLiquid; -import game.block.BlockLiquid; -import game.block.BlockStaticLiquid; -import game.collect.Lists; -import game.collect.Maps; -import game.material.Material; +import common.block.Block; +import common.block.BlockDynamicLiquid; +import common.block.BlockLiquid; +import common.block.BlockStaticLiquid; +import common.collect.Lists; +import common.collect.Maps; +import common.material.Material; public abstract class FluidRegistry { public static enum LiquidType { diff --git a/java/src/game/init/IObjectIntIterable.java b/java/src/common/init/IObjectIntIterable.java similarity index 75% rename from java/src/game/init/IObjectIntIterable.java rename to java/src/common/init/IObjectIntIterable.java index 201259a..20e5fbf 100755 --- a/java/src/game/init/IObjectIntIterable.java +++ b/java/src/common/init/IObjectIntIterable.java @@ -1,4 +1,4 @@ -package game.init; +package common.init; public interface IObjectIntIterable extends Iterable { diff --git a/java/src/game/init/IRegistry.java b/java/src/common/init/IRegistry.java similarity index 89% rename from java/src/game/init/IRegistry.java rename to java/src/common/init/IRegistry.java index bec97a9..9dc54b3 100755 --- a/java/src/game/init/IRegistry.java +++ b/java/src/common/init/IRegistry.java @@ -1,4 +1,4 @@ -package game.init; +package common.init; public interface IRegistry extends Iterable { diff --git a/java/src/game/init/ItemRegistry.java b/java/src/common/init/ItemRegistry.java similarity index 88% rename from java/src/game/init/ItemRegistry.java rename to java/src/common/init/ItemRegistry.java index 161ba68..1621698 100755 --- a/java/src/game/init/ItemRegistry.java +++ b/java/src/common/init/ItemRegistry.java @@ -1,129 +1,129 @@ -package game.init; +package common.init; import java.util.Map; import java.util.Set; import java.util.function.Function; -import game.block.Block; -import game.block.BlockBed; -import game.block.BlockButton; -import game.block.BlockDirt; -import game.block.BlockDoor; -import game.block.BlockDoublePlant; -import game.block.BlockFence; -import game.block.BlockFlower; -import game.block.BlockLeaves; -import game.block.BlockOre; -import game.block.BlockSand; -import game.block.BlockSandStone; -import game.block.BlockSapling; -import game.block.BlockSlab; -import game.block.BlockStoneBrick; -import game.block.BlockWall; -import game.collect.Maps; -import game.collect.Sets; -import game.color.DyeColor; -import game.color.TextColor; -import game.entity.item.EntityCart; -import game.entity.npc.CharacterInfo; -import game.entity.npc.SpeciesInfo; -import game.item.CheatTab; -import game.item.Item; -import game.item.ItemAmmo; -import game.item.ItemAnvilBlock; -import game.item.ItemAppleGold; -import game.item.ItemArmor; -import game.item.ItemAxe; -import game.item.ItemBanHammer; -import game.item.ItemBanner; -import game.item.ItemBed; -import game.item.ItemBlock; -import game.item.ItemBoat; -import game.item.ItemBoltgun; -import game.item.ItemBook; -import game.item.ItemBow; -import game.item.ItemBucket; -import game.item.ItemBucketMilk; -import game.item.ItemButton; -import game.item.ItemCamera; -import game.item.ItemCarrotOnAStick; -import game.item.ItemChargedOrb; -import game.item.ItemChest; -import game.item.ItemCloth; -import game.item.ItemCoal; -import game.item.ItemColored; -import game.item.ItemDie; -import game.item.ItemDispenser; -import game.item.ItemDoor; -import game.item.ItemDoublePlant; -import game.item.ItemDye; -import game.item.ItemDynamite; -import game.item.ItemEditWand; -import game.item.ItemEffect; -import game.item.ItemEgg; -import game.item.ItemEnchantedBook; -import game.item.ItemExpBottle; -import game.item.ItemExterminator; -import game.item.ItemFence; -import game.item.ItemFireball; -import game.item.ItemFirework; -import game.item.ItemFireworkCharge; -import game.item.ItemFishFood; -import game.item.ItemFishingRod; -import game.item.ItemFlintAndSteel; -import game.item.ItemFood; -import game.item.ItemFragile; -import game.item.ItemGlassBottle; -import game.item.ItemHoe; -import game.item.ItemHorseArmor; -import game.item.ItemHugeMushroom; -import game.item.ItemInfoWand; -import game.item.ItemKey; -import game.item.ItemLead; -import game.item.ItemLeaves; -import game.item.ItemLightning; -import game.item.ItemLilyPad; -import game.item.ItemMagnet; -import game.item.ItemMagnetic; -import game.item.ItemMetal; -import game.item.ItemMetalBlock; -import game.item.ItemMinecart; -import game.item.ItemMonsterPlacer; -import game.item.ItemMultiTexture; -import game.item.ItemNameTag; -import game.item.ItemNpcSpawner; -import game.item.ItemNugget; -import game.item.ItemPickaxe; -import game.item.ItemPiston; -import game.item.ItemPotion; -import game.item.ItemPressurePlate; -import game.item.ItemRecord; -import game.item.ItemRedstone; -import game.item.ItemReed; -import game.item.ItemRod; -import game.item.ItemSaddle; -import game.item.ItemSeedFood; -import game.item.ItemSeeds; -import game.item.ItemShears; -import game.item.ItemSign; -import game.item.ItemSkull; -import game.item.ItemSlab; -import game.item.ItemSmall; -import game.item.ItemSnow; -import game.item.ItemSnowball; -import game.item.ItemSoup; -import game.item.ItemSpaceNavigator; -import game.item.ItemSpade; -import game.item.ItemStack; -import game.item.ItemStick; -import game.item.ItemSword; -import game.item.ItemTNT; -import game.item.ItemTiny; -import game.item.ItemWall; -import game.item.ItemWeatherToken; -import game.potion.Potion; -import game.potion.PotionHelper; -import game.world.Weather; +import common.block.Block; +import common.block.BlockBed; +import common.block.BlockButton; +import common.block.BlockDirt; +import common.block.BlockDoor; +import common.block.BlockDoublePlant; +import common.block.BlockFence; +import common.block.BlockFlower; +import common.block.BlockLeaves; +import common.block.BlockOre; +import common.block.BlockSand; +import common.block.BlockSandStone; +import common.block.BlockSapling; +import common.block.BlockSlab; +import common.block.BlockStoneBrick; +import common.block.BlockWall; +import common.collect.Maps; +import common.collect.Sets; +import common.color.DyeColor; +import common.color.TextColor; +import common.entity.item.EntityCart; +import common.entity.npc.CharacterInfo; +import common.entity.npc.SpeciesInfo; +import common.item.CheatTab; +import common.item.Item; +import common.item.ItemAmmo; +import common.item.ItemAnvilBlock; +import common.item.ItemAppleGold; +import common.item.ItemArmor; +import common.item.ItemAxe; +import common.item.ItemBanHammer; +import common.item.ItemBanner; +import common.item.ItemBed; +import common.item.ItemBlock; +import common.item.ItemBoat; +import common.item.ItemBoltgun; +import common.item.ItemBook; +import common.item.ItemBow; +import common.item.ItemBucket; +import common.item.ItemBucketMilk; +import common.item.ItemButton; +import common.item.ItemCamera; +import common.item.ItemCarrotOnAStick; +import common.item.ItemChargedOrb; +import common.item.ItemChest; +import common.item.ItemCloth; +import common.item.ItemCoal; +import common.item.ItemColored; +import common.item.ItemDie; +import common.item.ItemDispenser; +import common.item.ItemDoor; +import common.item.ItemDoublePlant; +import common.item.ItemDye; +import common.item.ItemDynamite; +import common.item.ItemEditWand; +import common.item.ItemEffect; +import common.item.ItemEgg; +import common.item.ItemEnchantedBook; +import common.item.ItemExpBottle; +import common.item.ItemExterminator; +import common.item.ItemFence; +import common.item.ItemFireball; +import common.item.ItemFirework; +import common.item.ItemFireworkCharge; +import common.item.ItemFishFood; +import common.item.ItemFishingRod; +import common.item.ItemFlintAndSteel; +import common.item.ItemFood; +import common.item.ItemFragile; +import common.item.ItemGlassBottle; +import common.item.ItemHoe; +import common.item.ItemHorseArmor; +import common.item.ItemHugeMushroom; +import common.item.ItemInfoWand; +import common.item.ItemKey; +import common.item.ItemLead; +import common.item.ItemLeaves; +import common.item.ItemLightning; +import common.item.ItemLilyPad; +import common.item.ItemMagnet; +import common.item.ItemMagnetic; +import common.item.ItemMetal; +import common.item.ItemMetalBlock; +import common.item.ItemMinecart; +import common.item.ItemMonsterPlacer; +import common.item.ItemMultiTexture; +import common.item.ItemNameTag; +import common.item.ItemNpcSpawner; +import common.item.ItemNugget; +import common.item.ItemPickaxe; +import common.item.ItemPiston; +import common.item.ItemPotion; +import common.item.ItemPressurePlate; +import common.item.ItemRecord; +import common.item.ItemRedstone; +import common.item.ItemReed; +import common.item.ItemRod; +import common.item.ItemSaddle; +import common.item.ItemSeedFood; +import common.item.ItemSeeds; +import common.item.ItemShears; +import common.item.ItemSign; +import common.item.ItemSkull; +import common.item.ItemSlab; +import common.item.ItemSmall; +import common.item.ItemSnow; +import common.item.ItemSnowball; +import common.item.ItemSoup; +import common.item.ItemSpaceNavigator; +import common.item.ItemSpade; +import common.item.ItemStack; +import common.item.ItemStick; +import common.item.ItemSword; +import common.item.ItemTNT; +import common.item.ItemTiny; +import common.item.ItemWall; +import common.item.ItemWeatherToken; +import common.potion.Potion; +import common.potion.PotionHelper; +import common.world.Weather; public abstract class ItemRegistry { public static final RegistryNamespaced REGISTRY = new RegistryNamespaced(); diff --git a/java/src/game/init/Items.java b/java/src/common/init/Items.java similarity index 98% rename from java/src/game/init/Items.java rename to java/src/common/init/Items.java index 8ee522f..099bf36 100755 --- a/java/src/game/init/Items.java +++ b/java/src/common/init/Items.java @@ -1,13 +1,13 @@ -package game.init; +package common.init; -import game.item.Item; -import game.item.ItemAmmo; -import game.item.ItemArmor; -import game.item.ItemBow; -import game.item.ItemEnchantedBook; -import game.item.ItemFishingRod; -import game.item.ItemPotion; -import game.item.ItemShears; +import common.item.Item; +import common.item.ItemAmmo; +import common.item.ItemArmor; +import common.item.ItemBow; +import common.item.ItemEnchantedBook; +import common.item.ItemFishingRod; +import common.item.ItemPotion; +import common.item.ItemShears; public abstract class Items { diff --git a/java/src/game/init/MetalType.java b/java/src/common/init/MetalType.java similarity index 98% rename from java/src/game/init/MetalType.java rename to java/src/common/init/MetalType.java index 3b6ea86..77b63bf 100755 --- a/java/src/game/init/MetalType.java +++ b/java/src/common/init/MetalType.java @@ -1,6 +1,6 @@ -package game.init; +package common.init; -import game.color.TextColor; +import common.color.TextColor; public enum MetalType { IRON("iron", 26, "Fe", "Eisen", 0, new ToolMaterial(2, 8.0f, 0.0f, 250, 6.0F, 2, 14, true, 15, 9, 2, 6, 5, 2).setMagnetic()), diff --git a/java/src/game/init/NameRegistry.java b/java/src/common/init/NameRegistry.java similarity index 99% rename from java/src/game/init/NameRegistry.java rename to java/src/common/init/NameRegistry.java index fcd8d2f..5b9583e 100755 --- a/java/src/game/init/NameRegistry.java +++ b/java/src/common/init/NameRegistry.java @@ -1,6 +1,6 @@ -package game.init; +package common.init; -import game.rng.Random; +import common.rng.Random; /** * This class is released under the GNU general public license (GPL) diff --git a/java/src/game/init/ObjectIntIdentityMap.java b/java/src/common/init/ObjectIntIdentityMap.java similarity index 89% rename from java/src/game/init/ObjectIntIdentityMap.java rename to java/src/common/init/ObjectIntIdentityMap.java index 42b0642..c6cb6b2 100755 --- a/java/src/game/init/ObjectIntIdentityMap.java +++ b/java/src/common/init/ObjectIntIdentityMap.java @@ -1,12 +1,12 @@ -package game.init; +package common.init; import java.util.IdentityHashMap; import java.util.Iterator; import java.util.List; -import game.collect.Iterators; -import game.collect.Lists; -import game.util.Predicates; +import common.collect.Iterators; +import common.collect.Lists; +import common.util.Predicates; public class ObjectIntIdentityMap implements IObjectIntIterable { diff --git a/java/src/game/init/OreType.java b/java/src/common/init/OreType.java similarity index 98% rename from java/src/game/init/OreType.java rename to java/src/common/init/OreType.java index 95b80ff..764b288 100755 --- a/java/src/game/init/OreType.java +++ b/java/src/common/init/OreType.java @@ -1,4 +1,4 @@ -package game.init; +package common.init; public enum OreType { DIAMOND("diamond", "Diamant", new ToolMaterial(3, 12.0f, 2.0f, 1561, 8.0F, 3, 10, true, 33, 10, 3, 8, 6, 3), "diamond", 3, 1, 0), diff --git a/java/src/game/init/Registry.java b/java/src/common/init/Registry.java similarity index 98% rename from java/src/game/init/Registry.java rename to java/src/common/init/Registry.java index 7623cd8..43ddaf4 100755 --- a/java/src/game/init/Registry.java +++ b/java/src/common/init/Registry.java @@ -1,4 +1,4 @@ -package game.init; +package common.init; import java.awt.Desktop; import java.io.File; @@ -14,7 +14,7 @@ import java.util.Locale; import javax.imageio.ImageIO; -import game.log.NettyLogger; +import common.log.NettyLogger; public abstract class Registry { private static boolean crashed; diff --git a/java/src/game/init/RegistryDefaulted.java b/java/src/common/init/RegistryDefaulted.java similarity index 95% rename from java/src/game/init/RegistryDefaulted.java rename to java/src/common/init/RegistryDefaulted.java index 08b45a3..9b313bc 100755 --- a/java/src/game/init/RegistryDefaulted.java +++ b/java/src/common/init/RegistryDefaulted.java @@ -1,4 +1,4 @@ -package game.init; +package common.init; public class RegistryDefaulted extends RegistrySimple { diff --git a/java/src/game/init/RegistryNamespaced.java b/java/src/common/init/RegistryNamespaced.java similarity index 96% rename from java/src/game/init/RegistryNamespaced.java rename to java/src/common/init/RegistryNamespaced.java index 0b48909..e7c7806 100755 --- a/java/src/game/init/RegistryNamespaced.java +++ b/java/src/common/init/RegistryNamespaced.java @@ -1,10 +1,10 @@ -package game.init; +package common.init; import java.util.Iterator; import java.util.Map; -import game.collect.BiMap; -import game.collect.HashBiMap; +import common.collect.BiMap; +import common.collect.HashBiMap; public class RegistryNamespaced extends RegistrySimple implements IObjectIntIterable { diff --git a/java/src/game/init/RegistryNamespacedDefaultedByKey.java b/java/src/common/init/RegistryNamespacedDefaultedByKey.java similarity index 98% rename from java/src/game/init/RegistryNamespacedDefaultedByKey.java rename to java/src/common/init/RegistryNamespacedDefaultedByKey.java index 8d8d89c..f616966 100755 --- a/java/src/game/init/RegistryNamespacedDefaultedByKey.java +++ b/java/src/common/init/RegistryNamespacedDefaultedByKey.java @@ -1,4 +1,4 @@ -package game.init; +package common.init; public class RegistryNamespacedDefaultedByKey extends RegistryNamespaced { diff --git a/java/src/game/init/RegistrySimple.java b/java/src/common/init/RegistrySimple.java similarity index 96% rename from java/src/game/init/RegistrySimple.java rename to java/src/common/init/RegistrySimple.java index 5b41625..9bc6efc 100755 --- a/java/src/game/init/RegistrySimple.java +++ b/java/src/common/init/RegistrySimple.java @@ -1,11 +1,11 @@ -package game.init; +package common.init; import java.util.Collections; import java.util.Iterator; import java.util.Map; import java.util.Set; -import game.collect.Maps; +import common.collect.Maps; public class RegistrySimple implements IRegistry { diff --git a/java/src/game/init/ReorderRegistry.java b/java/src/common/init/ReorderRegistry.java similarity index 97% rename from java/src/game/init/ReorderRegistry.java rename to java/src/common/init/ReorderRegistry.java index 9e35668..181e48c 100755 --- a/java/src/game/init/ReorderRegistry.java +++ b/java/src/common/init/ReorderRegistry.java @@ -1,17 +1,17 @@ -package game.init; +package common.init; import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; -import game.block.Block; -import game.block.BlockBed; -import game.block.BlockDoor; -import game.color.DyeColor; -import game.world.Facing; -import game.world.State; -import game.world.Vec3i; +import common.block.Block; +import common.block.BlockBed; +import common.block.BlockDoor; +import common.color.DyeColor; +import common.world.Facing; +import common.world.State; +import common.world.Vec3i; public abstract class ReorderRegistry { private static final Set PLACE_LAST = new HashSet(); diff --git a/java/src/game/init/RotationRegistry.java b/java/src/common/init/RotationRegistry.java similarity index 81% rename from java/src/game/init/RotationRegistry.java rename to java/src/common/init/RotationRegistry.java index e8b38ff..be4d0a9 100755 --- a/java/src/game/init/RotationRegistry.java +++ b/java/src/common/init/RotationRegistry.java @@ -1,37 +1,37 @@ -package game.init; +package common.init; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.function.Predicate; -import game.block.Block; -import game.block.BlockDoor; -import game.block.BlockLever; -import game.block.BlockLog; -import game.block.BlockPortal; -import game.block.BlockQuartz; -import game.block.BlockRail; -import game.block.BlockRailBase; -import game.block.BlockRailDetector; -import game.block.BlockRailPowered; -import game.block.BlockRotatedPillar; -import game.clipboard.Rotation; -import game.clipboard.RotationValue; -import game.clipboard.Vector; -import game.collect.Lists; -import game.collect.Maps; -import game.properties.IProperty; -import game.properties.PropertyDirection; -import game.world.Facing; -import game.world.State; -import game.world.Vec3i; +import common.block.Block; +import common.block.BlockDoor; +import common.block.BlockLever; +import common.block.BlockLog; +import common.block.BlockPortal; +import common.block.BlockQuartz; +import common.block.BlockRail; +import common.block.BlockRailBase; +import common.block.BlockRailDetector; +import common.block.BlockRailPowered; +import common.block.BlockRotatedPillar; +import common.clipboard.Rotation; +import common.clipboard.RotationValue; +import common.clipboard.Vector; +import common.collect.Lists; +import common.collect.Maps; +import common.properties.IProperty; +import common.properties.PropertyDirection; +import common.world.Facing; +import common.world.State; +import common.world.Vec3i; public abstract class RotationRegistry { private static final Map MAP = new HashMap(); static void register() { - for(Block block : game.init.BlockRegistry.REGISTRY) { + for(Block block : common.init.BlockRegistry.REGISTRY) { for(IProperty prop : block.getPropertyMap()) { Predicate predicate = null; if(prop == BlockDoor.FACING) { @@ -113,7 +113,7 @@ public abstract class RotationRegistry { } } if(!values.isEmpty()) { - int legacyId = game.init.BlockRegistry.getIdFromBlock(block); + int legacyId = common.init.BlockRegistry.getIdFromBlock(block); Rotation state = new Rotation(values.toArray(new RotationValue[values.size()]), predicate); // Log.CONFIG.debug("Block " + game.init.BlockRegistry.REGISTRY.getNameForObject(block) + "/" + legacyId + " mask = " + String.format("0x%x", mask)); // for(RotationValue value : values) { diff --git a/java/src/game/init/SmeltingRegistry.java b/java/src/common/init/SmeltingRegistry.java similarity index 95% rename from java/src/game/init/SmeltingRegistry.java rename to java/src/common/init/SmeltingRegistry.java index 1d2e404..f47f6b2 100755 --- a/java/src/game/init/SmeltingRegistry.java +++ b/java/src/common/init/SmeltingRegistry.java @@ -1,16 +1,17 @@ -package game.init; +package common.init; import java.util.Map; import java.util.Map.Entry; -import java.util.Set; -import game.block.Block; -import game.block.BlockStoneBrick; -import game.collect.Maps; -import game.color.DyeColor; -import game.item.Item; -import game.item.ItemFishFood; -import game.item.ItemStack; +import common.block.Block; +import common.block.BlockStoneBrick; +import common.collect.Maps; +import common.color.DyeColor; +import common.item.Item; +import common.item.ItemFishFood; +import common.item.ItemStack; + +import java.util.Set; public abstract class SmeltingRegistry { diff --git a/java/src/game/init/SoundEvent.java b/java/src/common/init/SoundEvent.java similarity index 99% rename from java/src/game/init/SoundEvent.java rename to java/src/common/init/SoundEvent.java index ddeb5b2..b5cb1b9 100755 --- a/java/src/game/init/SoundEvent.java +++ b/java/src/common/init/SoundEvent.java @@ -1,4 +1,4 @@ -package game.init; +package common.init; public enum SoundEvent { CLOTH("cloth1", "cloth2", "cloth3", "cloth4"), diff --git a/java/src/game/init/SpeciesRegistry.java b/java/src/common/init/SpeciesRegistry.java similarity index 85% rename from java/src/game/init/SpeciesRegistry.java rename to java/src/common/init/SpeciesRegistry.java index 5afa09e..9126171 100755 --- a/java/src/game/init/SpeciesRegistry.java +++ b/java/src/common/init/SpeciesRegistry.java @@ -1,40 +1,40 @@ -package game.init; +package common.init; import java.util.List; import java.util.Map; import java.util.Set; -import game.collect.Lists; -import game.collect.Maps; -import game.collect.Sets; -import game.entity.npc.EntityArachnoid; -import game.entity.npc.EntityBloodElf; -import game.entity.npc.EntityChaosMarine; -import game.entity.npc.EntityCpu; -import game.entity.npc.EntityCultivator; -import game.entity.npc.EntityDarkMage; -import game.entity.npc.EntityDwarf; -import game.entity.npc.EntityElf; -import game.entity.npc.EntityFireDemon; -import game.entity.npc.EntityGargoyle; -import game.entity.npc.EntityGoblin; -import game.entity.npc.EntityHaunter; -import game.entity.npc.EntityHuman; -import game.entity.npc.EntityMage; -import game.entity.npc.EntityMagma; -import game.entity.npc.EntityMetalhead; -import game.entity.npc.EntityNPC; -import game.entity.npc.EntityOrc; -import game.entity.npc.EntityPrimarch; -import game.entity.npc.EntitySlime; -import game.entity.npc.EntitySpaceMarine; -import game.entity.npc.EntitySpirit; -import game.entity.npc.EntityTiefling; -import game.entity.npc.EntityUndead; -import game.entity.npc.EntityVampire; -import game.entity.npc.EntityWoodElf; -import game.entity.npc.EntityZombie; -import game.entity.npc.SpeciesInfo; +import common.collect.Lists; +import common.collect.Maps; +import common.collect.Sets; +import common.entity.npc.EntityArachnoid; +import common.entity.npc.EntityBloodElf; +import common.entity.npc.EntityChaosMarine; +import common.entity.npc.EntityCpu; +import common.entity.npc.EntityCultivator; +import common.entity.npc.EntityDarkMage; +import common.entity.npc.EntityDwarf; +import common.entity.npc.EntityElf; +import common.entity.npc.EntityFireDemon; +import common.entity.npc.EntityGargoyle; +import common.entity.npc.EntityGoblin; +import common.entity.npc.EntityHaunter; +import common.entity.npc.EntityHuman; +import common.entity.npc.EntityMage; +import common.entity.npc.EntityMagma; +import common.entity.npc.EntityMetalhead; +import common.entity.npc.EntityNPC; +import common.entity.npc.EntityOrc; +import common.entity.npc.EntityPrimarch; +import common.entity.npc.EntitySlime; +import common.entity.npc.EntitySpaceMarine; +import common.entity.npc.EntitySpirit; +import common.entity.npc.EntityTiefling; +import common.entity.npc.EntityUndead; +import common.entity.npc.EntityVampire; +import common.entity.npc.EntityWoodElf; +import common.entity.npc.EntityZombie; +import common.entity.npc.SpeciesInfo; public abstract class SpeciesRegistry { public static enum ModelType { diff --git a/java/src/game/init/TileRegistry.java b/java/src/common/init/TileRegistry.java similarity index 69% rename from java/src/game/init/TileRegistry.java rename to java/src/common/init/TileRegistry.java index 8da4f9d..2f74da8 100755 --- a/java/src/game/init/TileRegistry.java +++ b/java/src/common/init/TileRegistry.java @@ -1,26 +1,26 @@ -package game.init; +package common.init; import java.util.Map; -import game.collect.Maps; -import game.tileentity.TileEntity; -import game.tileentity.TileEntityBanner; -import game.tileentity.TileEntityBeacon; -import game.tileentity.TileEntityBrewingStand; -import game.tileentity.TileEntityChest; -import game.tileentity.TileEntityComparator; -import game.tileentity.TileEntityDaylightDetector; -import game.tileentity.TileEntityDispenser; -import game.tileentity.TileEntityDropper; -import game.tileentity.TileEntityEnchantmentTable; -import game.tileentity.TileEntityFurnace; -import game.tileentity.TileEntityHopper; -import game.tileentity.TileEntityMobSpawner; -import game.tileentity.TileEntityNote; -import game.tileentity.TileEntityPiston; -import game.tileentity.TileEntitySign; -import game.tileentity.TileEntitySkull; -import game.tileentity.TileEntityTianReactor; +import common.collect.Maps; +import common.tileentity.TileEntity; +import common.tileentity.TileEntityBanner; +import common.tileentity.TileEntityBeacon; +import common.tileentity.TileEntityBrewingStand; +import common.tileentity.TileEntityChest; +import common.tileentity.TileEntityComparator; +import common.tileentity.TileEntityDaylightDetector; +import common.tileentity.TileEntityDispenser; +import common.tileentity.TileEntityDropper; +import common.tileentity.TileEntityEnchantmentTable; +import common.tileentity.TileEntityFurnace; +import common.tileentity.TileEntityHopper; +import common.tileentity.TileEntityMobSpawner; +import common.tileentity.TileEntityNote; +import common.tileentity.TileEntityPiston; +import common.tileentity.TileEntitySign; +import common.tileentity.TileEntitySkull; +import common.tileentity.TileEntityTianReactor; public abstract class TileRegistry { public static final Map> nameToClassMap = Maps.>newHashMap(); diff --git a/java/src/game/init/ToolMaterial.java b/java/src/common/init/ToolMaterial.java similarity index 98% rename from java/src/game/init/ToolMaterial.java rename to java/src/common/init/ToolMaterial.java index 85fade6..7b3b548 100755 --- a/java/src/game/init/ToolMaterial.java +++ b/java/src/common/init/ToolMaterial.java @@ -1,9 +1,9 @@ -package game.init; +package common.init; import java.util.Set; -import game.collect.Sets; -import game.item.Item; +import common.collect.Sets; +import common.item.Item; public class ToolMaterial { diff --git a/java/src/game/init/ToolType.java b/java/src/common/init/ToolType.java similarity index 97% rename from java/src/game/init/ToolType.java rename to java/src/common/init/ToolType.java index 94cff02..893269f 100755 --- a/java/src/game/init/ToolType.java +++ b/java/src/common/init/ToolType.java @@ -1,4 +1,4 @@ -package game.init; +package common.init; public enum ToolType { WOOD("wood", "Holz", new ToolMaterial(0, 59, 2.0F, 0, 15, true), WoodType.getNames("planks")), diff --git a/java/src/game/init/TradeRegistry.java b/java/src/common/init/TradeRegistry.java similarity index 96% rename from java/src/game/init/TradeRegistry.java rename to java/src/common/init/TradeRegistry.java index 5ff6029..9d20098 100755 --- a/java/src/game/init/TradeRegistry.java +++ b/java/src/common/init/TradeRegistry.java @@ -1,14 +1,14 @@ -package game.init; +package common.init; -import game.color.DyeColor; -import game.enchantment.Enchantment; -import game.enchantment.EnchantmentHelper; -import game.enchantment.RngEnchantment; -import game.item.Item; -import game.item.ItemStack; -import game.rng.Random; -import game.village.MerchantRecipe; -import game.village.MerchantRecipeList; +import common.color.DyeColor; +import common.enchantment.Enchantment; +import common.enchantment.EnchantmentHelper; +import common.enchantment.RngEnchantment; +import common.item.Item; +import common.item.ItemStack; +import common.rng.Random; +import common.village.MerchantRecipe; +import common.village.MerchantRecipeList; public abstract class TradeRegistry { public interface ITradeList { diff --git a/java/src/game/init/UniverseRegistry.java b/java/src/common/init/UniverseRegistry.java similarity index 97% rename from java/src/game/init/UniverseRegistry.java rename to java/src/common/init/UniverseRegistry.java index 396de6c..9f8451e 100755 --- a/java/src/game/init/UniverseRegistry.java +++ b/java/src/common/init/UniverseRegistry.java @@ -1,40 +1,41 @@ -package game.init; +package common.init; import java.util.List; import java.util.Map; import java.util.Map.Entry; -import java.util.Set; -import game.biome.Biome; -import game.block.BlockColored; -import game.block.BlockSand; -import game.block.LeavesType; -import game.collect.Lists; -import game.collect.Maps; -import game.collect.Sets; -import game.color.DyeColor; -import game.dimension.Area; -import game.dimension.DimType; -import game.dimension.Dimension; -import game.dimension.Dimension.GeneratorType; -import game.dimension.Dimension.ReplacerType; -import game.dimension.Domain; -import game.dimension.Galaxy; -import game.dimension.Moon; -import game.dimension.Planet; -import game.dimension.Sector; -import game.dimension.Semi; -import game.dimension.Space; -import game.dimension.Star; -import game.log.Log; -import game.nbt.NBTException; -import game.nbt.NBTParser; -import game.nbt.NBTTagCompound; -import game.nbt.NBTTagList; -import game.rng.Random; -import game.world.PortalType; -import game.world.State; -import game.world.Weather; +import common.biome.Biome; +import common.block.BlockColored; +import common.block.BlockSand; +import common.block.LeavesType; +import common.collect.Lists; +import common.collect.Maps; +import common.collect.Sets; +import common.color.DyeColor; +import common.dimension.Area; +import common.dimension.DimType; +import common.dimension.Dimension; +import common.dimension.Domain; +import common.dimension.Galaxy; +import common.dimension.Moon; +import common.dimension.Planet; +import common.dimension.Sector; +import common.dimension.Semi; +import common.dimension.Space; +import common.dimension.Star; +import common.dimension.Dimension.GeneratorType; +import common.dimension.Dimension.ReplacerType; +import common.log.Log; +import common.nbt.NBTException; +import common.nbt.NBTParser; +import common.nbt.NBTTagCompound; +import common.nbt.NBTTagList; +import common.rng.Random; +import common.world.PortalType; +import common.world.State; +import common.world.Weather; + +import java.util.Set; public abstract class UniverseRegistry { public static final int MORE_DIM_ID = 1000; diff --git a/java/src/game/init/WoodType.java b/java/src/common/init/WoodType.java similarity index 96% rename from java/src/game/init/WoodType.java rename to java/src/common/init/WoodType.java index 53105c9..aa76f8d 100755 --- a/java/src/game/init/WoodType.java +++ b/java/src/common/init/WoodType.java @@ -1,6 +1,6 @@ -package game.init; +package common.init; -import game.color.Colorizer; +import common.color.Colorizer; public enum WoodType { OAK("oak", "Eichen", null, 20, "apple"), diff --git a/java/src/game/inventory/AnimalChest.java b/java/src/common/inventory/AnimalChest.java similarity index 92% rename from java/src/game/inventory/AnimalChest.java rename to java/src/common/inventory/AnimalChest.java index 1e3edb9..8823e5c 100755 --- a/java/src/game/inventory/AnimalChest.java +++ b/java/src/common/inventory/AnimalChest.java @@ -1,4 +1,4 @@ -package game.inventory; +package common.inventory; public class AnimalChest extends InventoryBasic { diff --git a/java/src/game/inventory/Container.java b/java/src/common/inventory/Container.java similarity index 99% rename from java/src/game/inventory/Container.java rename to java/src/common/inventory/Container.java index 8472563..80ae090 100755 --- a/java/src/game/inventory/Container.java +++ b/java/src/common/inventory/Container.java @@ -1,15 +1,15 @@ -package game.inventory; +package common.inventory; import java.util.List; import java.util.Set; -import game.collect.Lists; -import game.collect.Sets; -import game.entity.npc.EntityNPC; -import game.item.Item; -import game.item.ItemStack; -import game.tileentity.TileEntity; -import game.util.ExtMath; +import common.collect.Lists; +import common.collect.Sets; +import common.entity.npc.EntityNPC; +import common.item.Item; +import common.item.ItemStack; +import common.tileentity.TileEntity; +import common.util.ExtMath; public abstract class Container { diff --git a/java/src/game/inventory/ContainerBrewingStand.java b/java/src/common/inventory/ContainerBrewingStand.java similarity index 98% rename from java/src/game/inventory/ContainerBrewingStand.java rename to java/src/common/inventory/ContainerBrewingStand.java index 79b09a4..d4c461a 100755 --- a/java/src/game/inventory/ContainerBrewingStand.java +++ b/java/src/common/inventory/ContainerBrewingStand.java @@ -1,8 +1,8 @@ -package game.inventory; +package common.inventory; -import game.entity.npc.EntityNPC; -import game.init.Items; -import game.item.ItemStack; +import common.entity.npc.EntityNPC; +import common.init.Items; +import common.item.ItemStack; public class ContainerBrewingStand extends Container { diff --git a/java/src/game/inventory/ContainerChest.java b/java/src/common/inventory/ContainerChest.java similarity index 96% rename from java/src/game/inventory/ContainerChest.java rename to java/src/common/inventory/ContainerChest.java index ed12ad5..f53fe5e 100755 --- a/java/src/game/inventory/ContainerChest.java +++ b/java/src/common/inventory/ContainerChest.java @@ -1,7 +1,7 @@ -package game.inventory; +package common.inventory; -import game.entity.npc.EntityNPC; -import game.item.ItemStack; +import common.entity.npc.EntityNPC; +import common.item.ItemStack; public class ContainerChest extends Container { diff --git a/java/src/game/inventory/ContainerDispenser.java b/java/src/common/inventory/ContainerDispenser.java similarity index 95% rename from java/src/game/inventory/ContainerDispenser.java rename to java/src/common/inventory/ContainerDispenser.java index 34a52c8..6caa6dc 100755 --- a/java/src/game/inventory/ContainerDispenser.java +++ b/java/src/common/inventory/ContainerDispenser.java @@ -1,7 +1,7 @@ -package game.inventory; +package common.inventory; -import game.entity.npc.EntityNPC; -import game.item.ItemStack; +import common.entity.npc.EntityNPC; +import common.item.ItemStack; public class ContainerDispenser extends Container { diff --git a/java/src/game/inventory/ContainerEnchantment.java b/java/src/common/inventory/ContainerEnchantment.java similarity index 97% rename from java/src/game/inventory/ContainerEnchantment.java rename to java/src/common/inventory/ContainerEnchantment.java index 4e7bcea..551053a 100755 --- a/java/src/game/inventory/ContainerEnchantment.java +++ b/java/src/common/inventory/ContainerEnchantment.java @@ -1,16 +1,16 @@ -package game.inventory; +package common.inventory; import java.util.List; -import game.enchantment.EnchantmentHelper; -import game.enchantment.RngEnchantment; -import game.entity.npc.EntityNPC; -import game.init.Blocks; -import game.init.Items; -import game.item.ItemStack; -import game.rng.Random; -import game.world.BlockPos; -import game.world.World; +import common.enchantment.EnchantmentHelper; +import common.enchantment.RngEnchantment; +import common.entity.npc.EntityNPC; +import common.init.Blocks; +import common.init.Items; +import common.item.ItemStack; +import common.rng.Random; +import common.world.BlockPos; +import common.world.World; public class ContainerEnchantment extends Container { diff --git a/java/src/game/inventory/ContainerFurnace.java b/java/src/common/inventory/ContainerFurnace.java similarity index 96% rename from java/src/game/inventory/ContainerFurnace.java rename to java/src/common/inventory/ContainerFurnace.java index 860c51b..ae7cc2d 100755 --- a/java/src/game/inventory/ContainerFurnace.java +++ b/java/src/common/inventory/ContainerFurnace.java @@ -1,9 +1,9 @@ -package game.inventory; +package common.inventory; -import game.entity.npc.EntityNPC; -import game.init.SmeltingRegistry; -import game.item.ItemStack; -import game.tileentity.TileEntityFurnace; +import common.entity.npc.EntityNPC; +import common.init.SmeltingRegistry; +import common.item.ItemStack; +import common.tileentity.TileEntityFurnace; public class ContainerFurnace extends Container { diff --git a/java/src/game/inventory/ContainerHopper.java b/java/src/common/inventory/ContainerHopper.java similarity index 96% rename from java/src/game/inventory/ContainerHopper.java rename to java/src/common/inventory/ContainerHopper.java index e3b0a09..99d9283 100755 --- a/java/src/game/inventory/ContainerHopper.java +++ b/java/src/common/inventory/ContainerHopper.java @@ -1,7 +1,7 @@ -package game.inventory; +package common.inventory; -import game.entity.npc.EntityNPC; -import game.item.ItemStack; +import common.entity.npc.EntityNPC; +import common.item.ItemStack; public class ContainerHopper extends Container { diff --git a/java/src/game/inventory/ContainerHorseInventory.java b/java/src/common/inventory/ContainerHorseInventory.java similarity index 96% rename from java/src/game/inventory/ContainerHorseInventory.java rename to java/src/common/inventory/ContainerHorseInventory.java index a53e790..928b183 100755 --- a/java/src/game/inventory/ContainerHorseInventory.java +++ b/java/src/common/inventory/ContainerHorseInventory.java @@ -1,9 +1,9 @@ -package game.inventory; +package common.inventory; -import game.entity.animal.EntityHorse; -import game.entity.npc.EntityNPC; -import game.init.Items; -import game.item.ItemStack; +import common.entity.animal.EntityHorse; +import common.entity.npc.EntityNPC; +import common.init.Items; +import common.item.ItemStack; public class ContainerHorseInventory extends Container { diff --git a/java/src/game/inventory/ContainerLocalMenu.java b/java/src/common/inventory/ContainerLocalMenu.java similarity index 87% rename from java/src/game/inventory/ContainerLocalMenu.java rename to java/src/common/inventory/ContainerLocalMenu.java index 08d7992..c8f636e 100755 --- a/java/src/game/inventory/ContainerLocalMenu.java +++ b/java/src/common/inventory/ContainerLocalMenu.java @@ -1,11 +1,11 @@ -package game.inventory; +package common.inventory; import java.util.Map; -import game.collect.Maps; -import game.entity.npc.EntityNPC; -import game.tileentity.ILockableContainer; -import game.tileentity.LockCode; +import common.collect.Maps; +import common.entity.npc.EntityNPC; +import common.tileentity.ILockableContainer; +import common.tileentity.LockCode; public class ContainerLocalMenu extends InventoryBasic implements ILockableContainer { diff --git a/java/src/game/inventory/ContainerMachine.java b/java/src/common/inventory/ContainerMachine.java similarity index 95% rename from java/src/game/inventory/ContainerMachine.java rename to java/src/common/inventory/ContainerMachine.java index 1b7085b..0a71f19 100755 --- a/java/src/game/inventory/ContainerMachine.java +++ b/java/src/common/inventory/ContainerMachine.java @@ -1,9 +1,9 @@ -package game.inventory; +package common.inventory; -import game.entity.npc.EntityNPC; -import game.item.ItemStack; -import game.tileentity.TileEntityMachine; -import game.tileentity.TileEntityMachine.Status; +import common.entity.npc.EntityNPC; +import common.item.ItemStack; +import common.tileentity.TileEntityMachine; +import common.tileentity.TileEntityMachine.Status; public class ContainerMachine extends Container { diff --git a/java/src/game/inventory/ContainerMerchant.java b/java/src/common/inventory/ContainerMerchant.java similarity index 97% rename from java/src/game/inventory/ContainerMerchant.java rename to java/src/common/inventory/ContainerMerchant.java index 44ae587..dd43752 100755 --- a/java/src/game/inventory/ContainerMerchant.java +++ b/java/src/common/inventory/ContainerMerchant.java @@ -1,8 +1,8 @@ -package game.inventory; +package common.inventory; -import game.entity.npc.EntityNPC; -import game.item.ItemStack; -import game.world.World; +import common.entity.npc.EntityNPC; +import common.item.ItemStack; +import common.world.World; public class ContainerMerchant extends Container { diff --git a/java/src/game/inventory/ContainerPlayer.java b/java/src/common/inventory/ContainerPlayer.java similarity index 96% rename from java/src/game/inventory/ContainerPlayer.java rename to java/src/common/inventory/ContainerPlayer.java index c5ce694..2a1253d 100755 --- a/java/src/game/inventory/ContainerPlayer.java +++ b/java/src/common/inventory/ContainerPlayer.java @@ -1,13 +1,13 @@ -package game.inventory; +package common.inventory; import java.util.List; -import game.collect.Lists; -import game.entity.attributes.AttributeMap; -import game.entity.npc.EntityNPC; -import game.init.CraftingRegistry; -import game.item.ItemArmor; -import game.item.ItemStack; +import common.collect.Lists; +import common.entity.attributes.AttributeMap; +import common.entity.npc.EntityNPC; +import common.init.CraftingRegistry; +import common.item.ItemArmor; +import common.item.ItemStack; public class ContainerPlayer extends Container { diff --git a/java/src/game/inventory/ContainerRepair.java b/java/src/common/inventory/ContainerRepair.java similarity index 97% rename from java/src/game/inventory/ContainerRepair.java rename to java/src/common/inventory/ContainerRepair.java index 50e25f0..c2fa9d2 100755 --- a/java/src/game/inventory/ContainerRepair.java +++ b/java/src/common/inventory/ContainerRepair.java @@ -1,19 +1,19 @@ -package game.inventory; +package common.inventory; import java.util.Iterator; import java.util.Map; -import game.block.BlockAnvil; -import game.enchantment.Enchantment; -import game.enchantment.EnchantmentHelper; -import game.entity.npc.EntityNPC; -import game.init.Blocks; -import game.init.Config; -import game.init.Items; -import game.item.ItemStack; -import game.world.BlockPos; -import game.world.State; -import game.world.World; +import common.block.BlockAnvil; +import common.enchantment.Enchantment; +import common.enchantment.EnchantmentHelper; +import common.entity.npc.EntityNPC; +import common.init.Blocks; +import common.init.Config; +import common.init.Items; +import common.item.ItemStack; +import common.world.BlockPos; +import common.world.State; +import common.world.World; public class ContainerRepair extends Container { diff --git a/java/src/game/inventory/ContainerWorkbench.java b/java/src/common/inventory/ContainerWorkbench.java similarity index 95% rename from java/src/game/inventory/ContainerWorkbench.java rename to java/src/common/inventory/ContainerWorkbench.java index 16904af..2162e9e 100755 --- a/java/src/game/inventory/ContainerWorkbench.java +++ b/java/src/common/inventory/ContainerWorkbench.java @@ -1,11 +1,11 @@ -package game.inventory; +package common.inventory; -import game.entity.npc.EntityNPC; -import game.init.Blocks; -import game.init.CraftingRegistry; -import game.item.ItemStack; -import game.world.BlockPos; -import game.world.World; +import common.entity.npc.EntityNPC; +import common.init.Blocks; +import common.init.CraftingRegistry; +import common.item.ItemStack; +import common.world.BlockPos; +import common.world.World; public class ContainerWorkbench extends Container { diff --git a/java/src/game/inventory/ICrafting.java b/java/src/common/inventory/ICrafting.java similarity index 87% rename from java/src/game/inventory/ICrafting.java rename to java/src/common/inventory/ICrafting.java index 68b1ffd..ce90d83 100755 --- a/java/src/game/inventory/ICrafting.java +++ b/java/src/common/inventory/ICrafting.java @@ -1,8 +1,8 @@ -package game.inventory; +package common.inventory; import java.util.List; -import game.item.ItemStack; +import common.item.ItemStack; public interface ICrafting { diff --git a/java/src/game/inventory/IInvBasic.java b/java/src/common/inventory/IInvBasic.java similarity index 87% rename from java/src/game/inventory/IInvBasic.java rename to java/src/common/inventory/IInvBasic.java index b0a8f76..880e0a2 100755 --- a/java/src/game/inventory/IInvBasic.java +++ b/java/src/common/inventory/IInvBasic.java @@ -1,4 +1,4 @@ -package game.inventory; +package common.inventory; public interface IInvBasic { diff --git a/java/src/game/inventory/IInventory.java b/java/src/common/inventory/IInventory.java similarity index 92% rename from java/src/game/inventory/IInventory.java rename to java/src/common/inventory/IInventory.java index b9ed4bb..e65cf6e 100755 --- a/java/src/game/inventory/IInventory.java +++ b/java/src/common/inventory/IInventory.java @@ -1,8 +1,8 @@ -package game.inventory; +package common.inventory; -import game.entity.npc.EntityNPC; -import game.item.ItemStack; -import game.tileentity.IWorldNameable; +import common.entity.npc.EntityNPC; +import common.item.ItemStack; +import common.tileentity.IWorldNameable; public interface IInventory extends IWorldNameable { diff --git a/java/src/game/inventory/ISidedInventory.java b/java/src/common/inventory/ISidedInventory.java similarity index 86% rename from java/src/game/inventory/ISidedInventory.java rename to java/src/common/inventory/ISidedInventory.java index 076b4ae..ad72573 100755 --- a/java/src/game/inventory/ISidedInventory.java +++ b/java/src/common/inventory/ISidedInventory.java @@ -1,7 +1,7 @@ -package game.inventory; +package common.inventory; -import game.item.ItemStack; -import game.world.Facing; +import common.item.ItemStack; +import common.world.Facing; public interface ISidedInventory extends IInventory { diff --git a/java/src/game/inventory/InventoryBasic.java b/java/src/common/inventory/InventoryBasic.java similarity index 98% rename from java/src/game/inventory/InventoryBasic.java rename to java/src/common/inventory/InventoryBasic.java index c7667da..15853bd 100755 --- a/java/src/game/inventory/InventoryBasic.java +++ b/java/src/common/inventory/InventoryBasic.java @@ -1,10 +1,10 @@ -package game.inventory; +package common.inventory; import java.util.List; -import game.collect.Lists; -import game.entity.npc.EntityNPC; -import game.item.ItemStack; +import common.collect.Lists; +import common.entity.npc.EntityNPC; +import common.item.ItemStack; public class InventoryBasic implements IInventory { diff --git a/java/src/game/inventory/InventoryCraftResult.java b/java/src/common/inventory/InventoryCraftResult.java similarity index 97% rename from java/src/game/inventory/InventoryCraftResult.java rename to java/src/common/inventory/InventoryCraftResult.java index fe1a88f..6b41b16 100755 --- a/java/src/game/inventory/InventoryCraftResult.java +++ b/java/src/common/inventory/InventoryCraftResult.java @@ -1,7 +1,7 @@ -package game.inventory; +package common.inventory; -import game.entity.npc.EntityNPC; -import game.item.ItemStack; +import common.entity.npc.EntityNPC; +import common.item.ItemStack; public class InventoryCraftResult implements IInventory { diff --git a/java/src/game/inventory/InventoryCrafting.java b/java/src/common/inventory/InventoryCrafting.java similarity index 98% rename from java/src/game/inventory/InventoryCrafting.java rename to java/src/common/inventory/InventoryCrafting.java index debb209..e1b6d39 100755 --- a/java/src/game/inventory/InventoryCrafting.java +++ b/java/src/common/inventory/InventoryCrafting.java @@ -1,7 +1,7 @@ -package game.inventory; +package common.inventory; -import game.entity.npc.EntityNPC; -import game.item.ItemStack; +import common.entity.npc.EntityNPC; +import common.item.ItemStack; public class InventoryCrafting implements IInventory { diff --git a/java/src/game/inventory/InventoryHelper.java b/java/src/common/inventory/InventoryHelper.java similarity index 89% rename from java/src/game/inventory/InventoryHelper.java rename to java/src/common/inventory/InventoryHelper.java index 28e04fa..0bfc5d8 100755 --- a/java/src/game/inventory/InventoryHelper.java +++ b/java/src/common/inventory/InventoryHelper.java @@ -1,12 +1,12 @@ -package game.inventory; +package common.inventory; -import game.entity.Entity; -import game.entity.item.EntityItem; -import game.item.ItemStack; -import game.nbt.NBTTagCompound; -import game.rng.Random; -import game.world.BlockPos; -import game.world.World; +import common.entity.Entity; +import common.entity.item.EntityItem; +import common.item.ItemStack; +import common.nbt.NBTTagCompound; +import common.rng.Random; +import common.world.BlockPos; +import common.world.World; public class InventoryHelper { diff --git a/java/src/game/inventory/InventoryLargeChest.java b/java/src/common/inventory/InventoryLargeChest.java similarity index 96% rename from java/src/game/inventory/InventoryLargeChest.java rename to java/src/common/inventory/InventoryLargeChest.java index 3de2405..85d9844 100755 --- a/java/src/game/inventory/InventoryLargeChest.java +++ b/java/src/common/inventory/InventoryLargeChest.java @@ -1,10 +1,10 @@ -package game.inventory; +package common.inventory; -import game.entity.npc.EntityNPC; -import game.item.ItemStack; -import game.tileentity.ILockableContainer; -import game.tileentity.LockCode; -import game.tileentity.TileEntityChest; +import common.entity.npc.EntityNPC; +import common.item.ItemStack; +import common.tileentity.ILockableContainer; +import common.tileentity.LockCode; +import common.tileentity.TileEntityChest; public class InventoryLargeChest implements ILockableContainer { diff --git a/java/src/game/inventory/InventoryMerchant.java b/java/src/common/inventory/InventoryMerchant.java similarity index 97% rename from java/src/game/inventory/InventoryMerchant.java rename to java/src/common/inventory/InventoryMerchant.java index 58a4ef1..223bf4d 100755 --- a/java/src/game/inventory/InventoryMerchant.java +++ b/java/src/common/inventory/InventoryMerchant.java @@ -1,9 +1,9 @@ -package game.inventory; +package common.inventory; -import game.entity.npc.EntityNPC; -import game.item.ItemStack; -import game.village.MerchantRecipe; -import game.village.MerchantRecipeList; +import common.entity.npc.EntityNPC; +import common.item.ItemStack; +import common.village.MerchantRecipe; +import common.village.MerchantRecipeList; public class InventoryMerchant implements IInventory { diff --git a/java/src/game/inventory/InventoryPlayer.java b/java/src/common/inventory/InventoryPlayer.java similarity index 98% rename from java/src/game/inventory/InventoryPlayer.java rename to java/src/common/inventory/InventoryPlayer.java index 5450415..7b651c8 100755 --- a/java/src/game/inventory/InventoryPlayer.java +++ b/java/src/common/inventory/InventoryPlayer.java @@ -1,12 +1,12 @@ -package game.inventory; +package common.inventory; -import game.block.Block; -import game.entity.npc.EntityNPC; -import game.item.Item; -import game.item.ItemArmor; -import game.item.ItemStack; -import game.nbt.NBTTagCompound; -import game.nbt.NBTTagList; +import common.block.Block; +import common.entity.npc.EntityNPC; +import common.item.Item; +import common.item.ItemArmor; +import common.item.ItemStack; +import common.nbt.NBTTagCompound; +import common.nbt.NBTTagList; public class InventoryPlayer implements IInventory { diff --git a/java/src/game/inventory/InventoryWarpChest.java b/java/src/common/inventory/InventoryWarpChest.java similarity index 91% rename from java/src/game/inventory/InventoryWarpChest.java rename to java/src/common/inventory/InventoryWarpChest.java index 0685445..11656be 100755 --- a/java/src/game/inventory/InventoryWarpChest.java +++ b/java/src/common/inventory/InventoryWarpChest.java @@ -1,11 +1,11 @@ -package game.inventory; +package common.inventory; -import game.entity.npc.EntityNPC; -import game.init.Blocks; -import game.item.ItemStack; -import game.nbt.NBTTagCompound; -import game.nbt.NBTTagList; -import game.world.BlockPos; +import common.entity.npc.EntityNPC; +import common.init.Blocks; +import common.item.ItemStack; +import common.nbt.NBTTagCompound; +import common.nbt.NBTTagList; +import common.world.BlockPos; public class InventoryWarpChest extends InventoryBasic { diff --git a/java/src/game/inventory/Slot.java b/java/src/common/inventory/Slot.java similarity index 97% rename from java/src/game/inventory/Slot.java rename to java/src/common/inventory/Slot.java index 1c22e6b..9176b08 100755 --- a/java/src/game/inventory/Slot.java +++ b/java/src/common/inventory/Slot.java @@ -1,7 +1,7 @@ -package game.inventory; +package common.inventory; -import game.entity.npc.EntityNPC; -import game.item.ItemStack; +import common.entity.npc.EntityNPC; +import common.item.ItemStack; public class Slot { diff --git a/java/src/game/inventory/SlotCrafting.java b/java/src/common/inventory/SlotCrafting.java similarity index 97% rename from java/src/game/inventory/SlotCrafting.java rename to java/src/common/inventory/SlotCrafting.java index 4bc90b2..a598f45 100755 --- a/java/src/game/inventory/SlotCrafting.java +++ b/java/src/common/inventory/SlotCrafting.java @@ -1,8 +1,8 @@ -package game.inventory; +package common.inventory; -import game.entity.npc.EntityNPC; -import game.init.CraftingRegistry; -import game.item.ItemStack; +import common.entity.npc.EntityNPC; +import common.init.CraftingRegistry; +import common.item.ItemStack; public class SlotCrafting extends Slot { diff --git a/java/src/game/inventory/SlotFurnaceFuel.java b/java/src/common/inventory/SlotFurnaceFuel.java similarity index 85% rename from java/src/game/inventory/SlotFurnaceFuel.java rename to java/src/common/inventory/SlotFurnaceFuel.java index 422a196..23edd12 100755 --- a/java/src/game/inventory/SlotFurnaceFuel.java +++ b/java/src/common/inventory/SlotFurnaceFuel.java @@ -1,8 +1,8 @@ -package game.inventory; +package common.inventory; -import game.init.Items; -import game.item.ItemStack; -import game.tileentity.TileEntityFurnace; +import common.init.Items; +import common.item.ItemStack; +import common.tileentity.TileEntityFurnace; public class SlotFurnaceFuel extends Slot { diff --git a/java/src/game/inventory/SlotFurnaceOutput.java b/java/src/common/inventory/SlotFurnaceOutput.java similarity index 93% rename from java/src/game/inventory/SlotFurnaceOutput.java rename to java/src/common/inventory/SlotFurnaceOutput.java index e8ff6b2..930318a 100755 --- a/java/src/game/inventory/SlotFurnaceOutput.java +++ b/java/src/common/inventory/SlotFurnaceOutput.java @@ -1,11 +1,11 @@ -package game.inventory; +package common.inventory; -import game.entity.item.EntityXp; -import game.entity.npc.EntityNPC; -import game.init.Config; -import game.init.SmeltingRegistry; -import game.item.ItemStack; -import game.util.ExtMath; +import common.entity.item.EntityXp; +import common.entity.npc.EntityNPC; +import common.init.Config; +import common.init.SmeltingRegistry; +import common.item.ItemStack; +import common.util.ExtMath; public class SlotFurnaceOutput extends Slot { diff --git a/java/src/game/inventory/SlotMerchantResult.java b/java/src/common/inventory/SlotMerchantResult.java similarity index 96% rename from java/src/game/inventory/SlotMerchantResult.java rename to java/src/common/inventory/SlotMerchantResult.java index 11c65a6..01998ee 100755 --- a/java/src/game/inventory/SlotMerchantResult.java +++ b/java/src/common/inventory/SlotMerchantResult.java @@ -1,8 +1,8 @@ -package game.inventory; +package common.inventory; -import game.entity.npc.EntityNPC; -import game.item.ItemStack; -import game.village.MerchantRecipe; +import common.entity.npc.EntityNPC; +import common.item.ItemStack; +import common.village.MerchantRecipe; public class SlotMerchantResult extends Slot { diff --git a/java/src/game/item/CheatTab.java b/java/src/common/item/CheatTab.java similarity index 96% rename from java/src/game/item/CheatTab.java rename to java/src/common/item/CheatTab.java index 2c9363c..3e4ea89 100755 --- a/java/src/game/item/CheatTab.java +++ b/java/src/common/item/CheatTab.java @@ -1,10 +1,10 @@ -package game.item; +package common.item; import java.util.List; -import game.init.Blocks; -import game.init.ItemRegistry; -import game.init.Items; +import common.init.Blocks; +import common.init.ItemRegistry; +import common.init.Items; public enum CheatTab { diff --git a/java/src/game/item/Item.java b/java/src/common/item/Item.java similarity index 96% rename from java/src/game/item/Item.java rename to java/src/common/item/Item.java index 7f68355..a0885d9 100755 --- a/java/src/game/item/Item.java +++ b/java/src/common/item/Item.java @@ -1,29 +1,29 @@ -package game.item; +package common.item; import java.util.List; import java.util.Map; import java.util.Set; -import game.block.Block; -import game.collect.Maps; -import game.collect.Sets; -import game.color.TextColor; -import game.entity.attributes.Attribute; -import game.entity.attributes.AttributeModifier; -import game.entity.npc.EntityNPC; -import game.entity.types.EntityLiving; -import game.model.ItemMeshDefinition; -import game.model.Model; -import game.model.ModelProvider; -import game.model.Transforms; -import game.nbt.NBTTagCompound; -import game.rng.Random; -import game.util.ExtMath; -import game.world.BlockPos; -import game.world.Facing; -import game.world.HitPosition; -import game.world.Vec3; -import game.world.World; +import common.block.Block; +import common.collect.Maps; +import common.collect.Sets; +import common.color.TextColor; +import common.entity.attributes.Attribute; +import common.entity.attributes.AttributeModifier; +import common.entity.npc.EntityNPC; +import common.entity.types.EntityLiving; +import common.model.ItemMeshDefinition; +import common.model.Model; +import common.model.ModelProvider; +import common.model.Transforms; +import common.nbt.NBTTagCompound; +import common.rng.Random; +import common.util.ExtMath; +import common.world.BlockPos; +import common.world.Facing; +import common.world.HitPosition; +import common.world.Vec3; +import common.world.World; public class Item { diff --git a/java/src/game/item/ItemAction.java b/java/src/common/item/ItemAction.java similarity index 74% rename from java/src/game/item/ItemAction.java rename to java/src/common/item/ItemAction.java index 7e05c46..faf64d2 100755 --- a/java/src/game/item/ItemAction.java +++ b/java/src/common/item/ItemAction.java @@ -1,4 +1,4 @@ -package game.item; +package common.item; public enum ItemAction { NONE, EAT, DRINK, BLOCK, AIM; diff --git a/java/src/game/item/ItemAmmo.java b/java/src/common/item/ItemAmmo.java similarity index 95% rename from java/src/game/item/ItemAmmo.java rename to java/src/common/item/ItemAmmo.java index 0df9250..9f1b64b 100755 --- a/java/src/game/item/ItemAmmo.java +++ b/java/src/common/item/ItemAmmo.java @@ -1,4 +1,4 @@ -package game.item; +package common.item; public class ItemAmmo extends ItemMagnetic { private final int damage; diff --git a/java/src/game/item/ItemAnvilBlock.java b/java/src/common/item/ItemAnvilBlock.java similarity index 92% rename from java/src/game/item/ItemAnvilBlock.java rename to java/src/common/item/ItemAnvilBlock.java index 898f96e..8bf8549 100755 --- a/java/src/game/item/ItemAnvilBlock.java +++ b/java/src/common/item/ItemAnvilBlock.java @@ -1,6 +1,6 @@ -package game.item; +package common.item; -import game.block.Block; +import common.block.Block; public class ItemAnvilBlock extends ItemMultiTexture { diff --git a/java/src/game/item/ItemAppleGold.java b/java/src/common/item/ItemAppleGold.java similarity index 89% rename from java/src/game/item/ItemAppleGold.java rename to java/src/common/item/ItemAppleGold.java index 5528983..a2b796a 100755 --- a/java/src/game/item/ItemAppleGold.java +++ b/java/src/common/item/ItemAppleGold.java @@ -1,12 +1,12 @@ -package game.item; +package common.item; import java.util.List; -import game.color.TextColor; -import game.entity.npc.EntityNPC; -import game.potion.Potion; -import game.potion.PotionEffect; -import game.world.World; +import common.color.TextColor; +import common.entity.npc.EntityNPC; +import common.potion.Potion; +import common.potion.PotionEffect; +import common.world.World; public class ItemAppleGold extends ItemFood { diff --git a/java/src/game/item/ItemArmor.java b/java/src/common/item/ItemArmor.java similarity index 93% rename from java/src/game/item/ItemArmor.java rename to java/src/common/item/ItemArmor.java index cc0f01b..8fc63a8 100755 --- a/java/src/game/item/ItemArmor.java +++ b/java/src/common/item/ItemArmor.java @@ -1,29 +1,29 @@ -package game.item; +package common.item; import java.util.List; import java.util.Map; import java.util.Set; import java.util.function.Predicate; -import game.block.BlockDispenser; -import game.collect.Sets; -import game.dispenser.BehaviorDefaultDispenseItem; -import game.dispenser.IBehaviorDispenseItem; -import game.dispenser.IBlockSource; -import game.entity.attributes.Attribute; -import game.entity.attributes.AttributeModifier; -import game.entity.attributes.Attributes; -import game.entity.npc.EntityNPC; -import game.entity.types.EntityLiving; -import game.init.DispenserRegistry; -import game.init.ToolMaterial; -import game.model.Model; -import game.model.ModelProvider; -import game.model.Transforms; -import game.nbt.NBTTagCompound; -import game.world.BlockPos; -import game.world.BoundingBox; -import game.world.World; +import common.block.BlockDispenser; +import common.collect.Sets; +import common.dispenser.BehaviorDefaultDispenseItem; +import common.dispenser.IBehaviorDispenseItem; +import common.dispenser.IBlockSource; +import common.entity.attributes.Attribute; +import common.entity.attributes.AttributeModifier; +import common.entity.attributes.Attributes; +import common.entity.npc.EntityNPC; +import common.entity.types.EntityLiving; +import common.init.DispenserRegistry; +import common.init.ToolMaterial; +import common.model.Model; +import common.model.ModelProvider; +import common.model.Transforms; +import common.nbt.NBTTagCompound; +import common.world.BlockPos; +import common.world.BoundingBox; +import common.world.World; public class ItemArmor extends Item { diff --git a/java/src/game/item/ItemAxe.java b/java/src/common/item/ItemAxe.java similarity index 88% rename from java/src/game/item/ItemAxe.java rename to java/src/common/item/ItemAxe.java index ead3549..2a2ccc6 100755 --- a/java/src/game/item/ItemAxe.java +++ b/java/src/common/item/ItemAxe.java @@ -1,7 +1,7 @@ -package game.item; +package common.item; -import game.block.Block; -import game.init.ToolMaterial; +import common.block.Block; +import common.init.ToolMaterial; public class ItemAxe extends ItemTool { diff --git a/java/src/game/item/ItemBanHammer.java b/java/src/common/item/ItemBanHammer.java similarity index 78% rename from java/src/game/item/ItemBanHammer.java rename to java/src/common/item/ItemBanHammer.java index 573af3f..db93716 100755 --- a/java/src/game/item/ItemBanHammer.java +++ b/java/src/common/item/ItemBanHammer.java @@ -1,14 +1,14 @@ -package game.item; +package common.item; import java.util.List; -import game.color.TextColor; -import game.entity.DamageSource; -import game.entity.npc.EntityNPC; -import game.entity.types.EntityLiving; -import game.world.BoundingBox; -import game.world.Vec3; -import game.world.WorldServer; +import common.color.TextColor; +import common.entity.DamageSource; +import common.entity.npc.EntityNPC; +import common.entity.types.EntityLiving; +import common.world.BoundingBox; +import common.world.Vec3; +import common.world.WorldServer; public class ItemBanHammer extends ItemWand { public ItemBanHammer() { diff --git a/java/src/game/item/ItemBanner.java b/java/src/common/item/ItemBanner.java similarity index 92% rename from java/src/game/item/ItemBanner.java rename to java/src/common/item/ItemBanner.java index 46f28bf..6a41313 100755 --- a/java/src/game/item/ItemBanner.java +++ b/java/src/common/item/ItemBanner.java @@ -1,23 +1,23 @@ -package game.item; +package common.item; import java.util.List; -import game.block.BlockStandingSign; -import game.block.BlockWallSign; -import game.color.DyeColor; -import game.entity.npc.EntityNPC; -import game.init.Blocks; -import game.model.ItemMeshDefinition; -import game.model.Model; -import game.model.ModelProvider; -import game.nbt.NBTTagCompound; -import game.nbt.NBTTagList; -import game.tileentity.TileEntity; -import game.tileentity.TileEntityBanner; -import game.util.ExtMath; -import game.world.BlockPos; -import game.world.Facing; -import game.world.World; +import common.block.BlockStandingSign; +import common.block.BlockWallSign; +import common.color.DyeColor; +import common.entity.npc.EntityNPC; +import common.init.Blocks; +import common.model.ItemMeshDefinition; +import common.model.Model; +import common.model.ModelProvider; +import common.nbt.NBTTagCompound; +import common.nbt.NBTTagList; +import common.tileentity.TileEntity; +import common.tileentity.TileEntityBanner; +import common.util.ExtMath; +import common.world.BlockPos; +import common.world.Facing; +import common.world.World; public class ItemBanner extends ItemBlock { diff --git a/java/src/game/item/ItemBed.java b/java/src/common/item/ItemBed.java similarity index 90% rename from java/src/game/item/ItemBed.java rename to java/src/common/item/ItemBed.java index 8e5f276..04a9b51 100755 --- a/java/src/game/item/ItemBed.java +++ b/java/src/common/item/ItemBed.java @@ -1,13 +1,13 @@ -package game.item; +package common.item; -import game.block.Block; -import game.block.BlockBed; -import game.entity.npc.EntityNPC; -import game.util.ExtMath; -import game.world.BlockPos; -import game.world.Facing; -import game.world.State; -import game.world.World; +import common.block.Block; +import common.block.BlockBed; +import common.entity.npc.EntityNPC; +import common.util.ExtMath; +import common.world.BlockPos; +import common.world.Facing; +import common.world.State; +import common.world.World; public class ItemBed extends Item { diff --git a/java/src/game/item/ItemBlock.java b/java/src/common/item/ItemBlock.java similarity index 93% rename from java/src/game/item/ItemBlock.java rename to java/src/common/item/ItemBlock.java index b619ade..0a2de57 100755 --- a/java/src/game/item/ItemBlock.java +++ b/java/src/common/item/ItemBlock.java @@ -1,22 +1,22 @@ -package game.item; +package common.item; import java.util.List; -import game.block.Block; -import game.color.TextColor; -import game.entity.Entity; -import game.entity.npc.EntityNPC; -import game.init.BlockRegistry; -import game.init.Blocks; -import game.model.Model; -import game.model.ModelProvider; -import game.model.Transforms; -import game.nbt.NBTTagCompound; -import game.tileentity.TileEntity; -import game.world.BlockPos; -import game.world.Facing; -import game.world.State; -import game.world.World; +import common.block.Block; +import common.color.TextColor; +import common.entity.Entity; +import common.entity.npc.EntityNPC; +import common.init.BlockRegistry; +import common.init.Blocks; +import common.model.Model; +import common.model.ModelProvider; +import common.model.Transforms; +import common.nbt.NBTTagCompound; +import common.tileentity.TileEntity; +import common.world.BlockPos; +import common.world.Facing; +import common.world.State; +import common.world.World; public class ItemBlock extends Item { diff --git a/java/src/game/item/ItemBoat.java b/java/src/common/item/ItemBoat.java similarity index 92% rename from java/src/game/item/ItemBoat.java rename to java/src/common/item/ItemBoat.java index d33ba25..21894ed 100755 --- a/java/src/game/item/ItemBoat.java +++ b/java/src/common/item/ItemBoat.java @@ -1,17 +1,17 @@ -package game.item; +package common.item; import java.util.List; -import game.entity.Entity; -import game.entity.item.EntityBoat; -import game.entity.npc.EntityNPC; -import game.init.Blocks; -import game.util.ExtMath; -import game.world.BlockPos; -import game.world.BoundingBox; -import game.world.HitPosition; -import game.world.Vec3; -import game.world.World; +import common.entity.Entity; +import common.entity.item.EntityBoat; +import common.entity.npc.EntityNPC; +import common.init.Blocks; +import common.util.ExtMath; +import common.world.BlockPos; +import common.world.BoundingBox; +import common.world.HitPosition; +import common.world.Vec3; +import common.world.World; public class ItemBoat extends Item { diff --git a/java/src/game/item/ItemBoltgun.java b/java/src/common/item/ItemBoltgun.java similarity index 80% rename from java/src/game/item/ItemBoltgun.java rename to java/src/common/item/ItemBoltgun.java index 3d25c5d..4c4f387 100755 --- a/java/src/game/item/ItemBoltgun.java +++ b/java/src/common/item/ItemBoltgun.java @@ -1,6 +1,6 @@ -package game.item; +package common.item; -import game.init.Items; +import common.init.Items; public class ItemBoltgun extends ItemGunBase { public ItemBoltgun() { diff --git a/java/src/game/item/ItemBook.java b/java/src/common/item/ItemBook.java similarity index 94% rename from java/src/game/item/ItemBook.java rename to java/src/common/item/ItemBook.java index cc4dd7d..f1d7b20 100755 --- a/java/src/game/item/ItemBook.java +++ b/java/src/common/item/ItemBook.java @@ -1,4 +1,4 @@ -package game.item; +package common.item; public class ItemBook extends Item { diff --git a/java/src/game/item/ItemBow.java b/java/src/common/item/ItemBow.java similarity index 91% rename from java/src/game/item/ItemBow.java rename to java/src/common/item/ItemBow.java index 4670914..ddd477d 100755 --- a/java/src/game/item/ItemBow.java +++ b/java/src/common/item/ItemBow.java @@ -1,17 +1,17 @@ -package game.item; +package common.item; import java.util.List; -import game.enchantment.Enchantment; -import game.enchantment.EnchantmentHelper; -import game.entity.npc.EntityNPC; -import game.entity.projectile.EntityArrow; -import game.init.Items; -import game.init.SoundEvent; -import game.model.Model; -import game.model.ModelProvider; -import game.model.Transforms; -import game.world.World; +import common.enchantment.Enchantment; +import common.enchantment.EnchantmentHelper; +import common.entity.npc.EntityNPC; +import common.entity.projectile.EntityArrow; +import common.init.Items; +import common.init.SoundEvent; +import common.model.Model; +import common.model.ModelProvider; +import common.model.Transforms; +import common.world.World; public class ItemBow extends Item { diff --git a/java/src/game/item/ItemBucket.java b/java/src/common/item/ItemBucket.java similarity index 94% rename from java/src/game/item/ItemBucket.java rename to java/src/common/item/ItemBucket.java index ee2f4de..f66c84a 100755 --- a/java/src/game/item/ItemBucket.java +++ b/java/src/common/item/ItemBucket.java @@ -1,4 +1,4 @@ -package game.item; +package common.item; import java.util.ArrayDeque; import java.util.ArrayList; @@ -7,28 +7,28 @@ import java.util.List; import java.util.Queue; import java.util.Set; -import game.block.Block; -import game.block.BlockDynamicLiquid; -import game.block.BlockLiquid; -import game.block.BlockStaticLiquid; -import game.collect.Sets; -import game.entity.npc.EntityNPC; -import game.init.BlockRegistry; -import game.init.Blocks; -import game.init.FluidRegistry; -import game.init.ItemRegistry; -import game.init.Items; -import game.init.SoundEvent; -import game.material.Material; -import game.model.Model; -import game.model.ModelProvider; -import game.model.ParticleType; -import game.world.BlockPos; -import game.world.HitPosition; -import game.world.State; -import game.world.Vec3i; -import game.world.World; -import game.world.WorldServer; +import common.block.Block; +import common.block.BlockDynamicLiquid; +import common.block.BlockLiquid; +import common.block.BlockStaticLiquid; +import common.collect.Sets; +import common.entity.npc.EntityNPC; +import common.init.BlockRegistry; +import common.init.Blocks; +import common.init.FluidRegistry; +import common.init.ItemRegistry; +import common.init.Items; +import common.init.SoundEvent; +import common.material.Material; +import common.model.Model; +import common.model.ModelProvider; +import common.model.ParticleType; +import common.world.BlockPos; +import common.world.HitPosition; +import common.world.State; +import common.world.Vec3i; +import common.world.World; +import common.world.WorldServer; public class ItemBucket extends Item { diff --git a/java/src/game/item/ItemBucketMilk.java b/java/src/common/item/ItemBucketMilk.java similarity index 87% rename from java/src/game/item/ItemBucketMilk.java rename to java/src/common/item/ItemBucketMilk.java index d6aea49..ada9fb5 100755 --- a/java/src/game/item/ItemBucketMilk.java +++ b/java/src/common/item/ItemBucketMilk.java @@ -1,15 +1,15 @@ -package game.item; +package common.item; import java.util.Map; import java.util.Set; -import game.collect.Sets; -import game.entity.attributes.Attribute; -import game.entity.attributes.AttributeModifier; -import game.entity.attributes.Attributes; -import game.entity.npc.EntityNPC; -import game.init.Items; -import game.world.World; +import common.collect.Sets; +import common.entity.attributes.Attribute; +import common.entity.attributes.AttributeModifier; +import common.entity.attributes.Attributes; +import common.entity.npc.EntityNPC; +import common.init.Items; +import common.world.World; public class ItemBucketMilk extends Item { diff --git a/java/src/game/item/ItemButton.java b/java/src/common/item/ItemButton.java similarity index 81% rename from java/src/game/item/ItemButton.java rename to java/src/common/item/ItemButton.java index 7645145..34c50ce 100755 --- a/java/src/game/item/ItemButton.java +++ b/java/src/common/item/ItemButton.java @@ -1,8 +1,8 @@ -package game.item; +package common.item; -import game.block.BlockButton; -import game.model.Model; -import game.model.ModelProvider; +import common.block.BlockButton; +import common.model.Model; +import common.model.ModelProvider; public class ItemButton extends ItemBlock { private final BlockButton button; diff --git a/java/src/game/item/ItemCamera.java b/java/src/common/item/ItemCamera.java similarity index 85% rename from java/src/game/item/ItemCamera.java rename to java/src/common/item/ItemCamera.java index 482f7b8..30fbb78 100755 --- a/java/src/game/item/ItemCamera.java +++ b/java/src/common/item/ItemCamera.java @@ -1,8 +1,8 @@ -package game.item; +package common.item; -import game.entity.npc.EntityNPC; -import game.world.BlockPos; -import game.world.World; +import common.entity.npc.EntityNPC; +import common.world.BlockPos; +import common.world.World; public class ItemCamera extends ItemMagnetic { public ItemCamera() { diff --git a/java/src/game/item/ItemCarrotOnAStick.java b/java/src/common/item/ItemCarrotOnAStick.java similarity index 90% rename from java/src/game/item/ItemCarrotOnAStick.java rename to java/src/common/item/ItemCarrotOnAStick.java index 6eb5c1d..1a7983e 100755 --- a/java/src/game/item/ItemCarrotOnAStick.java +++ b/java/src/common/item/ItemCarrotOnAStick.java @@ -1,10 +1,10 @@ -package game.item; +package common.item; -import game.entity.animal.EntityPig; -import game.entity.npc.EntityNPC; -import game.init.Items; -import game.model.Transforms; -import game.world.World; +import common.entity.animal.EntityPig; +import common.entity.npc.EntityNPC; +import common.init.Items; +import common.model.Transforms; +import common.world.World; public class ItemCarrotOnAStick extends Item { diff --git a/java/src/game/item/ItemChargedOrb.java b/java/src/common/item/ItemChargedOrb.java similarity index 93% rename from java/src/game/item/ItemChargedOrb.java rename to java/src/common/item/ItemChargedOrb.java index 7cd9990..e156296 100755 --- a/java/src/game/item/ItemChargedOrb.java +++ b/java/src/common/item/ItemChargedOrb.java @@ -1,17 +1,17 @@ -package game.item; +package common.item; -import game.block.BlockPortalFrame; -import game.color.TextColor; -import game.entity.item.EntityOrb; -import game.entity.npc.EntityNPC; -import game.init.Blocks; -import game.init.Items; -import game.init.SoundEvent; -import game.model.ParticleType; -import game.world.BlockPos; -import game.world.Facing; -import game.world.State; -import game.world.World; +import common.block.BlockPortalFrame; +import common.color.TextColor; +import common.entity.item.EntityOrb; +import common.entity.npc.EntityNPC; +import common.init.Blocks; +import common.init.Items; +import common.init.SoundEvent; +import common.model.ParticleType; +import common.world.BlockPos; +import common.world.Facing; +import common.world.State; +import common.world.World; public class ItemChargedOrb extends ItemFragile { diff --git a/java/src/game/item/ItemChest.java b/java/src/common/item/ItemChest.java similarity index 70% rename from java/src/game/item/ItemChest.java rename to java/src/common/item/ItemChest.java index 50c11e7..57e502c 100755 --- a/java/src/game/item/ItemChest.java +++ b/java/src/common/item/ItemChest.java @@ -1,9 +1,9 @@ -package game.item; +package common.item; -import game.block.Block; -import game.model.Model; -import game.model.ModelProvider; -import game.model.Transforms; +import common.block.Block; +import common.model.Model; +import common.model.ModelProvider; +import common.model.Transforms; public class ItemChest extends ItemBlock { public ItemChest(Block block) { diff --git a/java/src/game/item/ItemCloth.java b/java/src/common/item/ItemCloth.java similarity index 90% rename from java/src/game/item/ItemCloth.java rename to java/src/common/item/ItemCloth.java index 791a8cd..6c20acb 100755 --- a/java/src/game/item/ItemCloth.java +++ b/java/src/common/item/ItemCloth.java @@ -1,9 +1,9 @@ -package game.item; +package common.item; -import game.block.Block; -import game.color.DyeColor; -import game.model.Model; -import game.model.ModelProvider; +import common.block.Block; +import common.color.DyeColor; +import common.model.Model; +import common.model.ModelProvider; public class ItemCloth extends ItemBlock { diff --git a/java/src/game/item/ItemCoal.java b/java/src/common/item/ItemCoal.java similarity index 92% rename from java/src/game/item/ItemCoal.java rename to java/src/common/item/ItemCoal.java index 637ddaa..bef0689 100755 --- a/java/src/game/item/ItemCoal.java +++ b/java/src/common/item/ItemCoal.java @@ -1,9 +1,9 @@ -package game.item; +package common.item; import java.util.List; -import game.model.Model; -import game.model.ModelProvider; +import common.model.Model; +import common.model.ModelProvider; public class ItemCoal extends Item { diff --git a/java/src/game/item/ItemColored.java b/java/src/common/item/ItemColored.java similarity index 97% rename from java/src/game/item/ItemColored.java rename to java/src/common/item/ItemColored.java index 4bddb9e..97f58a3 100755 --- a/java/src/game/item/ItemColored.java +++ b/java/src/common/item/ItemColored.java @@ -1,6 +1,6 @@ -package game.item; +package common.item; -import game.block.Block; +import common.block.Block; public class ItemColored extends ItemBlock { diff --git a/java/src/game/item/ItemControl.java b/java/src/common/item/ItemControl.java similarity index 77% rename from java/src/game/item/ItemControl.java rename to java/src/common/item/ItemControl.java index 064f390..ececfaa 100755 --- a/java/src/game/item/ItemControl.java +++ b/java/src/common/item/ItemControl.java @@ -1,4 +1,4 @@ -package game.item; +package common.item; public enum ItemControl { PRIMARY, SECONDARY, TERTIARY, QUARTERNARY; diff --git a/java/src/game/item/ItemDie.java b/java/src/common/item/ItemDie.java similarity index 85% rename from java/src/game/item/ItemDie.java rename to java/src/common/item/ItemDie.java index 86c7b86..5565fb4 100755 --- a/java/src/game/item/ItemDie.java +++ b/java/src/common/item/ItemDie.java @@ -1,16 +1,16 @@ -package game.item; +package common.item; import java.util.List; -import game.color.TextColor; -import game.entity.npc.EntityNPC; -import game.entity.projectile.EntityDie; -import game.init.SoundEvent; -import game.model.Model; -import game.model.ModelProvider; -import game.model.Transforms; -import game.util.ExtMath; -import game.world.World; +import common.color.TextColor; +import common.entity.npc.EntityNPC; +import common.entity.projectile.EntityDie; +import common.init.SoundEvent; +import common.model.Model; +import common.model.ModelProvider; +import common.model.Transforms; +import common.util.ExtMath; +import common.world.World; public class ItemDie extends Item { diff --git a/java/src/game/item/ItemDispenser.java b/java/src/common/item/ItemDispenser.java similarity index 78% rename from java/src/game/item/ItemDispenser.java rename to java/src/common/item/ItemDispenser.java index fd60883..1a90ccf 100755 --- a/java/src/game/item/ItemDispenser.java +++ b/java/src/common/item/ItemDispenser.java @@ -1,6 +1,6 @@ -package game.item; +package common.item; -import game.block.Block; +import common.block.Block; public class ItemDispenser extends ItemBlock { public ItemDispenser(Block block) { diff --git a/java/src/game/item/ItemDoor.java b/java/src/common/item/ItemDoor.java similarity index 91% rename from java/src/game/item/ItemDoor.java rename to java/src/common/item/ItemDoor.java index 8cff1fb..54a41a7 100755 --- a/java/src/game/item/ItemDoor.java +++ b/java/src/common/item/ItemDoor.java @@ -1,14 +1,14 @@ -package game.item; +package common.item; -import game.block.Block; -import game.block.BlockDoor; -import game.entity.npc.EntityNPC; -import game.init.Blocks; -import game.material.Material; -import game.world.BlockPos; -import game.world.Facing; -import game.world.State; -import game.world.World; +import common.block.Block; +import common.block.BlockDoor; +import common.entity.npc.EntityNPC; +import common.init.Blocks; +import common.material.Material; +import common.world.BlockPos; +import common.world.Facing; +import common.world.State; +import common.world.World; public class ItemDoor extends Item { diff --git a/java/src/game/item/ItemDoublePlant.java b/java/src/common/item/ItemDoublePlant.java similarity index 81% rename from java/src/game/item/ItemDoublePlant.java rename to java/src/common/item/ItemDoublePlant.java index 3ac9222..fe2b963 100755 --- a/java/src/game/item/ItemDoublePlant.java +++ b/java/src/common/item/ItemDoublePlant.java @@ -1,13 +1,13 @@ -package game.item; +package common.item; import java.util.function.Function; -import game.block.Block; -import game.block.BlockDoublePlant; -import game.block.BlockDoublePlant.EnumPlantType; -import game.color.Colorizer; -import game.model.Model; -import game.model.ModelProvider; +import common.block.Block; +import common.block.BlockDoublePlant; +import common.block.BlockDoublePlant.EnumPlantType; +import common.color.Colorizer; +import common.model.Model; +import common.model.ModelProvider; public class ItemDoublePlant extends ItemMultiTexture { diff --git a/java/src/game/item/ItemDye.java b/java/src/common/item/ItemDye.java similarity index 91% rename from java/src/game/item/ItemDye.java rename to java/src/common/item/ItemDye.java index b74ef3e..d2fa2e2 100755 --- a/java/src/game/item/ItemDye.java +++ b/java/src/common/item/ItemDye.java @@ -1,27 +1,27 @@ -package game.item; +package common.item; import java.util.List; -import game.block.Block; -import game.block.BlockBed; -import game.block.IGrowable; -import game.color.DyeColor; -import game.entity.animal.EntitySheep; -import game.entity.npc.EntityNPC; -import game.entity.types.EntityLiving; -import game.init.BlockRegistry; -import game.init.Blocks; -import game.material.Material; -import game.model.Model; -import game.model.ModelProvider; -import game.model.ParticleType; -import game.tileentity.TileEntity; -import game.tileentity.TileEntityBeacon; -import game.world.BlockPos; -import game.world.Facing; -import game.world.State; -import game.world.World; -import game.world.WorldServer; +import common.block.Block; +import common.block.BlockBed; +import common.block.IGrowable; +import common.color.DyeColor; +import common.entity.animal.EntitySheep; +import common.entity.npc.EntityNPC; +import common.entity.types.EntityLiving; +import common.init.BlockRegistry; +import common.init.Blocks; +import common.material.Material; +import common.model.Model; +import common.model.ModelProvider; +import common.model.ParticleType; +import common.tileentity.TileEntity; +import common.tileentity.TileEntityBeacon; +import common.world.BlockPos; +import common.world.Facing; +import common.world.State; +import common.world.World; +import common.world.WorldServer; public class ItemDye extends Item { diff --git a/java/src/game/item/ItemDynamite.java b/java/src/common/item/ItemDynamite.java similarity index 87% rename from java/src/game/item/ItemDynamite.java rename to java/src/common/item/ItemDynamite.java index d6b695a..56a3d46 100755 --- a/java/src/game/item/ItemDynamite.java +++ b/java/src/common/item/ItemDynamite.java @@ -1,13 +1,13 @@ -package game.item; +package common.item; import java.util.List; -import game.entity.npc.EntityNPC; -import game.entity.projectile.EntityDynamite; -import game.init.SoundEvent; -import game.model.Model; -import game.model.ModelProvider; -import game.world.World; +import common.entity.npc.EntityNPC; +import common.entity.projectile.EntityDynamite; +import common.init.SoundEvent; +import common.model.Model; +import common.model.ModelProvider; +import common.world.World; public class ItemDynamite extends Item { diff --git a/java/src/game/item/ItemEditWand.java b/java/src/common/item/ItemEditWand.java similarity index 88% rename from java/src/game/item/ItemEditWand.java rename to java/src/common/item/ItemEditWand.java index e5248f7..bf73170 100755 --- a/java/src/game/item/ItemEditWand.java +++ b/java/src/common/item/ItemEditWand.java @@ -1,9 +1,9 @@ -package game.item; +package common.item; -import game.entity.npc.EntityNPC; -import game.model.Transforms; -import game.world.BlockPos; -import game.world.World; +import common.entity.npc.EntityNPC; +import common.model.Transforms; +import common.world.BlockPos; +import common.world.World; public class ItemEditWand extends Item { public ItemEditWand() { diff --git a/java/src/game/item/ItemEffect.java b/java/src/common/item/ItemEffect.java similarity index 85% rename from java/src/game/item/ItemEffect.java rename to java/src/common/item/ItemEffect.java index fd5d017..c68b31a 100755 --- a/java/src/game/item/ItemEffect.java +++ b/java/src/common/item/ItemEffect.java @@ -1,4 +1,4 @@ -package game.item; +package common.item; public class ItemEffect extends Item { diff --git a/java/src/game/item/ItemEgg.java b/java/src/common/item/ItemEgg.java similarity index 83% rename from java/src/game/item/ItemEgg.java rename to java/src/common/item/ItemEgg.java index 2f95774..ec3c8ff 100755 --- a/java/src/game/item/ItemEgg.java +++ b/java/src/common/item/ItemEgg.java @@ -1,9 +1,9 @@ -package game.item; +package common.item; -import game.entity.npc.EntityNPC; -import game.entity.projectile.EntityEgg; -import game.init.SoundEvent; -import game.world.World; +import common.entity.npc.EntityNPC; +import common.entity.projectile.EntityEgg; +import common.init.SoundEvent; +import common.world.World; public class ItemEgg extends Item { diff --git a/java/src/game/item/ItemEnchantedBook.java b/java/src/common/item/ItemEnchantedBook.java similarity index 94% rename from java/src/game/item/ItemEnchantedBook.java rename to java/src/common/item/ItemEnchantedBook.java index ebdf3e9..c923726 100755 --- a/java/src/game/item/ItemEnchantedBook.java +++ b/java/src/common/item/ItemEnchantedBook.java @@ -1,17 +1,17 @@ -package game.item; +package common.item; import java.util.List; -import game.color.TextColor; -import game.enchantment.Enchantment; -import game.enchantment.EnchantmentHelper; -import game.enchantment.RngEnchantment; -import game.entity.npc.EntityNPC; -import game.init.Items; -import game.model.ItemMeshDefinition; -import game.nbt.NBTTagCompound; -import game.nbt.NBTTagList; -import game.rng.Random; +import common.color.TextColor; +import common.enchantment.Enchantment; +import common.enchantment.EnchantmentHelper; +import common.enchantment.RngEnchantment; +import common.entity.npc.EntityNPC; +import common.init.Items; +import common.model.ItemMeshDefinition; +import common.nbt.NBTTagCompound; +import common.nbt.NBTTagList; +import common.rng.Random; public class ItemEnchantedBook extends Item { diff --git a/java/src/game/item/ItemExpBottle.java b/java/src/common/item/ItemExpBottle.java similarity index 84% rename from java/src/game/item/ItemExpBottle.java rename to java/src/common/item/ItemExpBottle.java index 9d5fd72..ce0b567 100755 --- a/java/src/game/item/ItemExpBottle.java +++ b/java/src/common/item/ItemExpBottle.java @@ -1,9 +1,9 @@ -package game.item; +package common.item; -import game.entity.item.EntityXpBottle; -import game.entity.npc.EntityNPC; -import game.init.SoundEvent; -import game.world.World; +import common.entity.item.EntityXpBottle; +import common.entity.npc.EntityNPC; +import common.init.SoundEvent; +import common.world.World; public class ItemExpBottle extends Item { diff --git a/java/src/game/item/ItemExterminator.java b/java/src/common/item/ItemExterminator.java similarity index 84% rename from java/src/game/item/ItemExterminator.java rename to java/src/common/item/ItemExterminator.java index 002554b..6892a5d 100755 --- a/java/src/game/item/ItemExterminator.java +++ b/java/src/common/item/ItemExterminator.java @@ -1,11 +1,11 @@ -package game.item; +package common.item; -import game.color.TextColor; -import game.dimension.Space; -import game.entity.npc.EntityNPC; -import game.init.SoundEvent; -import game.world.World; -import game.world.WorldServer; +import common.color.TextColor; +import common.dimension.Space; +import common.entity.npc.EntityNPC; +import common.init.SoundEvent; +import common.world.World; +import common.world.WorldServer; public class ItemExterminator extends ItemMagnetic { public ItemExterminator() { diff --git a/java/src/game/item/ItemFence.java b/java/src/common/item/ItemFence.java similarity index 90% rename from java/src/game/item/ItemFence.java rename to java/src/common/item/ItemFence.java index 846c9dc..38089d5 100755 --- a/java/src/game/item/ItemFence.java +++ b/java/src/common/item/ItemFence.java @@ -1,9 +1,9 @@ -package game.item; +package common.item; -import game.block.Block; -import game.block.BlockFence; -import game.model.Model; -import game.model.ModelProvider; +import common.block.Block; +import common.block.BlockFence; +import common.model.Model; +import common.model.ModelProvider; public class ItemFence extends ItemBlock { public ItemFence(Block block) { diff --git a/java/src/game/item/ItemFireball.java b/java/src/common/item/ItemFireball.java similarity index 83% rename from java/src/game/item/ItemFireball.java rename to java/src/common/item/ItemFireball.java index dc9dc57..e3d7746 100755 --- a/java/src/game/item/ItemFireball.java +++ b/java/src/common/item/ItemFireball.java @@ -1,12 +1,12 @@ -package game.item; +package common.item; -import game.entity.npc.EntityNPC; -import game.init.Blocks; -import game.init.SoundEvent; -import game.material.Material; -import game.world.BlockPos; -import game.world.Facing; -import game.world.World; +import common.entity.npc.EntityNPC; +import common.init.Blocks; +import common.init.SoundEvent; +import common.material.Material; +import common.world.BlockPos; +import common.world.Facing; +import common.world.World; public class ItemFireball extends Item { diff --git a/java/src/game/item/ItemFirework.java b/java/src/common/item/ItemFirework.java similarity index 89% rename from java/src/game/item/ItemFirework.java rename to java/src/common/item/ItemFirework.java index 5f606c9..7adeda8 100755 --- a/java/src/game/item/ItemFirework.java +++ b/java/src/common/item/ItemFirework.java @@ -1,15 +1,15 @@ -package game.item; +package common.item; import java.util.List; -import game.collect.Lists; -import game.entity.item.EntityFireworks; -import game.entity.npc.EntityNPC; -import game.nbt.NBTTagCompound; -import game.nbt.NBTTagList; -import game.world.BlockPos; -import game.world.Facing; -import game.world.World; +import common.collect.Lists; +import common.entity.item.EntityFireworks; +import common.entity.npc.EntityNPC; +import common.nbt.NBTTagCompound; +import common.nbt.NBTTagList; +import common.world.BlockPos; +import common.world.Facing; +import common.world.World; public class ItemFirework extends Item { diff --git a/java/src/game/item/ItemFireworkCharge.java b/java/src/common/item/ItemFireworkCharge.java similarity index 95% rename from java/src/game/item/ItemFireworkCharge.java rename to java/src/common/item/ItemFireworkCharge.java index e239551..9d0a7f8 100755 --- a/java/src/game/item/ItemFireworkCharge.java +++ b/java/src/common/item/ItemFireworkCharge.java @@ -1,14 +1,14 @@ -package game.item; +package common.item; import java.util.List; -import game.color.DyeColor; -import game.entity.npc.EntityNPC; -import game.model.Model; -import game.model.ModelProvider; -import game.nbt.NBTBase; -import game.nbt.NBTTagCompound; -import game.nbt.NBTTagIntArray; +import common.color.DyeColor; +import common.entity.npc.EntityNPC; +import common.model.Model; +import common.model.ModelProvider; +import common.nbt.NBTBase; +import common.nbt.NBTTagCompound; +import common.nbt.NBTTagIntArray; public class ItemFireworkCharge extends Item { diff --git a/java/src/game/item/ItemFishFood.java b/java/src/common/item/ItemFishFood.java similarity index 94% rename from java/src/game/item/ItemFishFood.java rename to java/src/common/item/ItemFishFood.java index c5464fa..2a0f9b4 100755 --- a/java/src/game/item/ItemFishFood.java +++ b/java/src/common/item/ItemFishFood.java @@ -1,16 +1,16 @@ -package game.item; +package common.item; import java.util.List; import java.util.Map; -import game.collect.Maps; -import game.entity.npc.EntityNPC; -import game.model.Model; -import game.model.ModelProvider; -import game.potion.Potion; -import game.potion.PotionEffect; -import game.potion.PotionHelper; -import game.world.World; +import common.collect.Maps; +import common.entity.npc.EntityNPC; +import common.model.Model; +import common.model.ModelProvider; +import common.potion.Potion; +import common.potion.PotionEffect; +import common.potion.PotionHelper; +import common.world.World; public class ItemFishFood extends ItemFood { diff --git a/java/src/game/item/ItemFishingRod.java b/java/src/common/item/ItemFishingRod.java similarity index 90% rename from java/src/game/item/ItemFishingRod.java rename to java/src/common/item/ItemFishingRod.java index da31478..91f0c75 100755 --- a/java/src/game/item/ItemFishingRod.java +++ b/java/src/common/item/ItemFishingRod.java @@ -1,14 +1,14 @@ -package game.item; +package common.item; import java.util.List; -import game.entity.npc.EntityNPC; -import game.entity.projectile.EntityHook; -import game.init.SoundEvent; -import game.model.Model; -import game.model.ModelProvider; -import game.model.Transforms; -import game.world.World; +import common.entity.npc.EntityNPC; +import common.entity.projectile.EntityHook; +import common.init.SoundEvent; +import common.model.Model; +import common.model.ModelProvider; +import common.model.Transforms; +import common.world.World; public class ItemFishingRod extends Item { diff --git a/java/src/game/item/ItemFlintAndSteel.java b/java/src/common/item/ItemFlintAndSteel.java similarity index 81% rename from java/src/game/item/ItemFlintAndSteel.java rename to java/src/common/item/ItemFlintAndSteel.java index 677ca10..ac5e63e 100755 --- a/java/src/game/item/ItemFlintAndSteel.java +++ b/java/src/common/item/ItemFlintAndSteel.java @@ -1,12 +1,12 @@ -package game.item; +package common.item; -import game.entity.npc.EntityNPC; -import game.init.Blocks; -import game.init.SoundEvent; -import game.material.Material; -import game.world.BlockPos; -import game.world.Facing; -import game.world.World; +import common.entity.npc.EntityNPC; +import common.init.Blocks; +import common.init.SoundEvent; +import common.material.Material; +import common.world.BlockPos; +import common.world.Facing; +import common.world.World; public class ItemFlintAndSteel extends Item { diff --git a/java/src/game/item/ItemFood.java b/java/src/common/item/ItemFood.java similarity index 94% rename from java/src/game/item/ItemFood.java rename to java/src/common/item/ItemFood.java index 346a215..cf71fa5 100755 --- a/java/src/game/item/ItemFood.java +++ b/java/src/common/item/ItemFood.java @@ -1,10 +1,10 @@ -package game.item; +package common.item; -import game.entity.npc.EntityNPC; -import game.init.SoundEvent; -import game.potion.Potion; -import game.potion.PotionEffect; -import game.world.World; +import common.entity.npc.EntityNPC; +import common.init.SoundEvent; +import common.potion.Potion; +import common.potion.PotionEffect; +import common.world.World; public class ItemFood extends Item { diff --git a/java/src/game/item/ItemFragile.java b/java/src/common/item/ItemFragile.java similarity index 82% rename from java/src/game/item/ItemFragile.java rename to java/src/common/item/ItemFragile.java index 1b0087b..3905b3a 100755 --- a/java/src/game/item/ItemFragile.java +++ b/java/src/common/item/ItemFragile.java @@ -1,4 +1,4 @@ -package game.item; +package common.item; public class ItemFragile extends Item { public boolean isFragile() { diff --git a/java/src/game/item/ItemGlassBottle.java b/java/src/common/item/ItemGlassBottle.java similarity index 88% rename from java/src/game/item/ItemGlassBottle.java rename to java/src/common/item/ItemGlassBottle.java index 5d765c6..84e73ed 100755 --- a/java/src/game/item/ItemGlassBottle.java +++ b/java/src/common/item/ItemGlassBottle.java @@ -1,13 +1,13 @@ -package game.item; +package common.item; -import game.entity.npc.EntityNPC; -import game.init.Items; -import game.material.Material; -import game.model.Model; -import game.model.ModelProvider; -import game.world.BlockPos; -import game.world.HitPosition; -import game.world.World; +import common.entity.npc.EntityNPC; +import common.init.Items; +import common.material.Material; +import common.model.Model; +import common.model.ModelProvider; +import common.world.BlockPos; +import common.world.HitPosition; +import common.world.World; public class ItemGlassBottle extends Item { diff --git a/java/src/game/item/ItemGunBase.java b/java/src/common/item/ItemGunBase.java similarity index 88% rename from java/src/game/item/ItemGunBase.java rename to java/src/common/item/ItemGunBase.java index 437bb77..26fbc81 100755 --- a/java/src/game/item/ItemGunBase.java +++ b/java/src/common/item/ItemGunBase.java @@ -1,12 +1,12 @@ -package game.item; +package common.item; -import game.enchantment.Enchantment; -import game.enchantment.EnchantmentHelper; -import game.entity.npc.EntityNPC; -import game.entity.projectile.EntityBullet; -import game.init.SoundEvent; -import game.model.Transforms; -import game.world.World; +import common.enchantment.Enchantment; +import common.enchantment.EnchantmentHelper; +import common.entity.npc.EntityNPC; +import common.entity.projectile.EntityBullet; +import common.init.SoundEvent; +import common.model.Transforms; +import common.world.World; public abstract class ItemGunBase extends Item { diff --git a/java/src/game/item/ItemHoe.java b/java/src/common/item/ItemHoe.java similarity index 89% rename from java/src/game/item/ItemHoe.java rename to java/src/common/item/ItemHoe.java index 30ab087..c0cee67 100755 --- a/java/src/game/item/ItemHoe.java +++ b/java/src/common/item/ItemHoe.java @@ -1,16 +1,16 @@ -package game.item; +package common.item; -import game.block.Block; -import game.block.BlockDirt; -import game.entity.npc.EntityNPC; -import game.init.Blocks; -import game.init.ToolMaterial; -import game.material.Material; -import game.model.Transforms; -import game.world.BlockPos; -import game.world.Facing; -import game.world.State; -import game.world.World; +import common.block.Block; +import common.block.BlockDirt; +import common.entity.npc.EntityNPC; +import common.init.Blocks; +import common.init.ToolMaterial; +import common.material.Material; +import common.model.Transforms; +import common.world.BlockPos; +import common.world.Facing; +import common.world.State; +import common.world.World; public class ItemHoe extends Item { diff --git a/java/src/game/item/ItemHorseArmor.java b/java/src/common/item/ItemHorseArmor.java similarity index 87% rename from java/src/game/item/ItemHorseArmor.java rename to java/src/common/item/ItemHorseArmor.java index d987a42..a976e1a 100755 --- a/java/src/game/item/ItemHorseArmor.java +++ b/java/src/common/item/ItemHorseArmor.java @@ -1,6 +1,6 @@ -package game.item; +package common.item; -import game.init.ToolMaterial; +import common.init.ToolMaterial; public class ItemHorseArmor extends Item { private final ToolMaterial material; diff --git a/java/src/game/item/ItemHugeMushroom.java b/java/src/common/item/ItemHugeMushroom.java similarity index 79% rename from java/src/game/item/ItemHugeMushroom.java rename to java/src/common/item/ItemHugeMushroom.java index 06f4969..9ed6841 100755 --- a/java/src/game/item/ItemHugeMushroom.java +++ b/java/src/common/item/ItemHugeMushroom.java @@ -1,6 +1,6 @@ -package game.item; +package common.item; -import game.block.Block; +import common.block.Block; public class ItemHugeMushroom extends ItemBlock { public ItemHugeMushroom(Block block) { diff --git a/java/src/game/item/ItemInfoWand.java b/java/src/common/item/ItemInfoWand.java similarity index 76% rename from java/src/game/item/ItemInfoWand.java rename to java/src/common/item/ItemInfoWand.java index c203564..3b93afb 100755 --- a/java/src/game/item/ItemInfoWand.java +++ b/java/src/common/item/ItemInfoWand.java @@ -1,11 +1,11 @@ -package game.item; +package common.item; -import game.biome.Biome; -import game.color.TextColor; -import game.entity.npc.EntityNPC; -import game.world.BlockPos; -import game.world.Vec3; -import game.world.WorldServer; +import common.biome.Biome; +import common.color.TextColor; +import common.entity.npc.EntityNPC; +import common.world.BlockPos; +import common.world.Vec3; +import common.world.WorldServer; public class ItemInfoWand extends ItemWand { public ItemInfoWand() { diff --git a/java/src/game/item/ItemKey.java b/java/src/common/item/ItemKey.java similarity index 69% rename from java/src/game/item/ItemKey.java rename to java/src/common/item/ItemKey.java index 27438c7..3eef65b 100755 --- a/java/src/game/item/ItemKey.java +++ b/java/src/common/item/ItemKey.java @@ -1,6 +1,6 @@ -package game.item; +package common.item; -import game.model.Transforms; +import common.model.Transforms; public class ItemKey extends ItemMagnetic { public Transforms getTransform() { diff --git a/java/src/game/item/ItemLead.java b/java/src/common/item/ItemLead.java similarity index 84% rename from java/src/game/item/ItemLead.java rename to java/src/common/item/ItemLead.java index 03c7103..fb8e6e8 100755 --- a/java/src/game/item/ItemLead.java +++ b/java/src/common/item/ItemLead.java @@ -1,14 +1,14 @@ -package game.item; +package common.item; -import game.block.Block; -import game.block.BlockFence; -import game.entity.item.EntityLeashKnot; -import game.entity.npc.EntityNPC; -import game.entity.types.EntityLiving; -import game.world.BlockPos; -import game.world.BoundingBox; -import game.world.Facing; -import game.world.World; +import common.block.Block; +import common.block.BlockFence; +import common.entity.item.EntityLeashKnot; +import common.entity.npc.EntityNPC; +import common.entity.types.EntityLiving; +import common.world.BlockPos; +import common.world.BoundingBox; +import common.world.Facing; +import common.world.World; public class ItemLead extends Item { diff --git a/java/src/game/item/ItemLeaves.java b/java/src/common/item/ItemLeaves.java similarity index 93% rename from java/src/game/item/ItemLeaves.java rename to java/src/common/item/ItemLeaves.java index b2b08fc..16e91d0 100755 --- a/java/src/game/item/ItemLeaves.java +++ b/java/src/common/item/ItemLeaves.java @@ -1,7 +1,7 @@ -package game.item; +package common.item; -import game.block.BlockLeaves; -import game.block.LeavesType; +import common.block.BlockLeaves; +import common.block.LeavesType; public class ItemLeaves extends ItemBlock { diff --git a/java/src/game/item/ItemLightning.java b/java/src/common/item/ItemLightning.java similarity index 77% rename from java/src/game/item/ItemLightning.java rename to java/src/common/item/ItemLightning.java index f796fd4..e3c8080 100755 --- a/java/src/game/item/ItemLightning.java +++ b/java/src/common/item/ItemLightning.java @@ -1,9 +1,9 @@ -package game.item; +package common.item; -import game.color.TextColor; -import game.entity.npc.EntityNPC; -import game.world.Vec3; -import game.world.WorldServer; +import common.color.TextColor; +import common.entity.npc.EntityNPC; +import common.world.Vec3; +import common.world.WorldServer; public class ItemLightning extends ItemWand { public ItemLightning() { diff --git a/java/src/game/item/ItemLilyPad.java b/java/src/common/item/ItemLilyPad.java similarity index 86% rename from java/src/game/item/ItemLilyPad.java rename to java/src/common/item/ItemLilyPad.java index 3e533a6..d56843e 100755 --- a/java/src/game/item/ItemLilyPad.java +++ b/java/src/common/item/ItemLilyPad.java @@ -1,14 +1,14 @@ -package game.item; +package common.item; -import game.block.Block; -import game.block.BlockDirectional; -import game.block.BlockLiquid; -import game.entity.npc.EntityNPC; -import game.init.Blocks; -import game.world.BlockPos; -import game.world.HitPosition; -import game.world.State; -import game.world.World; +import common.block.Block; +import common.block.BlockDirectional; +import common.block.BlockLiquid; +import common.entity.npc.EntityNPC; +import common.init.Blocks; +import common.world.BlockPos; +import common.world.HitPosition; +import common.world.State; +import common.world.World; public class ItemLilyPad extends ItemColored { diff --git a/java/src/game/item/ItemMagnet.java b/java/src/common/item/ItemMagnet.java similarity index 88% rename from java/src/game/item/ItemMagnet.java rename to java/src/common/item/ItemMagnet.java index 2a03a84..bf9c45a 100755 --- a/java/src/game/item/ItemMagnet.java +++ b/java/src/common/item/ItemMagnet.java @@ -1,15 +1,15 @@ -package game.item; +package common.item; import java.util.List; import java.util.function.Predicate; -import game.entity.Entity; -import game.entity.animal.EntityChicken; -import game.entity.npc.EntityNPC; -import game.model.Transforms; -import game.world.BoundingBox; -import game.world.Vec3; -import game.world.World; +import common.entity.Entity; +import common.entity.animal.EntityChicken; +import common.entity.npc.EntityNPC; +import common.model.Transforms; +import common.world.BoundingBox; +import common.world.Vec3; +import common.world.World; public class ItemMagnet extends Item { private final boolean chicken; diff --git a/java/src/game/item/ItemMagnetic.java b/java/src/common/item/ItemMagnetic.java similarity index 82% rename from java/src/game/item/ItemMagnetic.java rename to java/src/common/item/ItemMagnetic.java index 9bc1b6b..bcf2d1c 100755 --- a/java/src/game/item/ItemMagnetic.java +++ b/java/src/common/item/ItemMagnetic.java @@ -1,4 +1,4 @@ -package game.item; +package common.item; public class ItemMagnetic extends Item { public boolean isMagnetic() { diff --git a/java/src/game/item/ItemMetal.java b/java/src/common/item/ItemMetal.java similarity index 82% rename from java/src/game/item/ItemMetal.java rename to java/src/common/item/ItemMetal.java index 428ac93..9d798b3 100755 --- a/java/src/game/item/ItemMetal.java +++ b/java/src/common/item/ItemMetal.java @@ -1,16 +1,16 @@ -package game.item; +package common.item; import java.util.List; import java.util.Map; import java.util.Set; -import game.collect.Sets; -import game.color.TextColor; -import game.entity.attributes.Attribute; -import game.entity.attributes.AttributeModifier; -import game.entity.attributes.Attributes; -import game.entity.npc.EntityNPC; -import game.init.MetalType; +import common.collect.Sets; +import common.color.TextColor; +import common.entity.attributes.Attribute; +import common.entity.attributes.AttributeModifier; +import common.entity.attributes.Attributes; +import common.entity.npc.EntityNPC; +import common.init.MetalType; public class ItemMetal extends Item { private final MetalType metal; diff --git a/java/src/game/item/ItemMetalBlock.java b/java/src/common/item/ItemMetalBlock.java similarity index 83% rename from java/src/game/item/ItemMetalBlock.java rename to java/src/common/item/ItemMetalBlock.java index 68a09cb..4a6a37e 100755 --- a/java/src/game/item/ItemMetalBlock.java +++ b/java/src/common/item/ItemMetalBlock.java @@ -1,17 +1,17 @@ -package game.item; +package common.item; import java.util.List; import java.util.Map; import java.util.Set; -import game.block.Block; -import game.collect.Sets; -import game.color.TextColor; -import game.entity.attributes.Attribute; -import game.entity.attributes.AttributeModifier; -import game.entity.attributes.Attributes; -import game.entity.npc.EntityNPC; -import game.init.MetalType; +import common.block.Block; +import common.collect.Sets; +import common.color.TextColor; +import common.entity.attributes.Attribute; +import common.entity.attributes.AttributeModifier; +import common.entity.attributes.Attributes; +import common.entity.npc.EntityNPC; +import common.init.MetalType; public class ItemMetalBlock extends ItemBlock { private final MetalType metal; diff --git a/java/src/game/item/ItemMinecart.java b/java/src/common/item/ItemMinecart.java similarity index 91% rename from java/src/game/item/ItemMinecart.java rename to java/src/common/item/ItemMinecart.java index 8193a71..66e8a4d 100755 --- a/java/src/game/item/ItemMinecart.java +++ b/java/src/common/item/ItemMinecart.java @@ -1,18 +1,18 @@ -package game.item; +package common.item; -import game.block.BlockDispenser; -import game.block.BlockRailBase; -import game.dispenser.BehaviorDefaultDispenseItem; -import game.dispenser.IBehaviorDispenseItem; -import game.dispenser.IBlockSource; -import game.entity.item.EntityCart; -import game.entity.npc.EntityNPC; -import game.init.DispenserRegistry; -import game.material.Material; -import game.world.BlockPos; -import game.world.Facing; -import game.world.State; -import game.world.World; +import common.block.BlockDispenser; +import common.block.BlockRailBase; +import common.dispenser.BehaviorDefaultDispenseItem; +import common.dispenser.IBehaviorDispenseItem; +import common.dispenser.IBlockSource; +import common.entity.item.EntityCart; +import common.entity.npc.EntityNPC; +import common.init.DispenserRegistry; +import common.material.Material; +import common.world.BlockPos; +import common.world.Facing; +import common.world.State; +import common.world.World; public class ItemMinecart extends Item { diff --git a/java/src/game/item/ItemMonsterPlacer.java b/java/src/common/item/ItemMonsterPlacer.java similarity index 92% rename from java/src/game/item/ItemMonsterPlacer.java rename to java/src/common/item/ItemMonsterPlacer.java index a1768de..f24d1d6 100755 --- a/java/src/game/item/ItemMonsterPlacer.java +++ b/java/src/common/item/ItemMonsterPlacer.java @@ -1,28 +1,28 @@ -package game.item; +package common.item; import java.util.List; -import game.block.BlockFence; -import game.block.BlockLiquid; -import game.color.TextColor; -import game.dimension.Dimension; -import game.entity.Entity; -import game.entity.npc.EntityNPC; -import game.entity.types.EntityLiving; -import game.init.Blocks; -import game.init.EntityEggInfo; -import game.init.EntityRegistry; -import game.init.UniverseRegistry; -import game.model.Model; -import game.model.ModelProvider; -import game.tileentity.TileEntity; -import game.tileentity.TileEntityMobSpawner; -import game.util.ExtMath; -import game.world.BlockPos; -import game.world.Facing; -import game.world.HitPosition; -import game.world.State; -import game.world.World; +import common.block.BlockFence; +import common.block.BlockLiquid; +import common.color.TextColor; +import common.dimension.Dimension; +import common.entity.Entity; +import common.entity.npc.EntityNPC; +import common.entity.types.EntityLiving; +import common.init.Blocks; +import common.init.EntityEggInfo; +import common.init.EntityRegistry; +import common.init.UniverseRegistry; +import common.model.Model; +import common.model.ModelProvider; +import common.tileentity.TileEntity; +import common.tileentity.TileEntityMobSpawner; +import common.util.ExtMath; +import common.world.BlockPos; +import common.world.Facing; +import common.world.HitPosition; +import common.world.State; +import common.world.World; public class ItemMonsterPlacer extends Item { diff --git a/java/src/game/item/ItemMultiTexture.java b/java/src/common/item/ItemMultiTexture.java similarity index 97% rename from java/src/game/item/ItemMultiTexture.java rename to java/src/common/item/ItemMultiTexture.java index 4fc0196..4a85c9f 100755 --- a/java/src/game/item/ItemMultiTexture.java +++ b/java/src/common/item/ItemMultiTexture.java @@ -1,8 +1,8 @@ -package game.item; +package common.item; import java.util.function.Function; -import game.block.Block; +import common.block.Block; public class ItemMultiTexture extends ItemBlock { diff --git a/java/src/game/item/ItemNameTag.java b/java/src/common/item/ItemNameTag.java similarity index 89% rename from java/src/game/item/ItemNameTag.java rename to java/src/common/item/ItemNameTag.java index 641f803..8b6d2dd 100755 --- a/java/src/game/item/ItemNameTag.java +++ b/java/src/common/item/ItemNameTag.java @@ -1,7 +1,7 @@ -package game.item; +package common.item; -import game.entity.npc.EntityNPC; -import game.entity.types.EntityLiving; +import common.entity.npc.EntityNPC; +import common.entity.types.EntityLiving; public class ItemNameTag extends Item { diff --git a/java/src/game/item/ItemNpcSpawner.java b/java/src/common/item/ItemNpcSpawner.java similarity index 90% rename from java/src/game/item/ItemNpcSpawner.java rename to java/src/common/item/ItemNpcSpawner.java index 5758549..31fa225 100755 --- a/java/src/game/item/ItemNpcSpawner.java +++ b/java/src/common/item/ItemNpcSpawner.java @@ -1,27 +1,27 @@ -package game.item; +package common.item; import java.lang.reflect.InvocationTargetException; import java.util.List; -import game.block.BlockFence; -import game.block.BlockLiquid; -import game.color.TextColor; -import game.dimension.Dimension; -import game.entity.Entity; -import game.entity.npc.CharacterInfo; -import game.entity.npc.EntityNPC; -import game.entity.npc.EntityNPC.CharacterTypeData; -import game.entity.types.EntityLiving; -import game.init.EntityRegistry; -import game.init.UniverseRegistry; -import game.model.Model; -import game.model.ModelProvider; -import game.util.ExtMath; -import game.world.BlockPos; -import game.world.Facing; -import game.world.HitPosition; -import game.world.State; -import game.world.World; +import common.block.BlockFence; +import common.block.BlockLiquid; +import common.color.TextColor; +import common.dimension.Dimension; +import common.entity.Entity; +import common.entity.npc.CharacterInfo; +import common.entity.npc.EntityNPC; +import common.entity.npc.EntityNPC.CharacterTypeData; +import common.entity.types.EntityLiving; +import common.init.EntityRegistry; +import common.init.UniverseRegistry; +import common.model.Model; +import common.model.ModelProvider; +import common.util.ExtMath; +import common.world.BlockPos; +import common.world.Facing; +import common.world.HitPosition; +import common.world.State; +import common.world.World; public class ItemNpcSpawner extends Item { diff --git a/java/src/game/item/ItemNugget.java b/java/src/common/item/ItemNugget.java similarity index 69% rename from java/src/game/item/ItemNugget.java rename to java/src/common/item/ItemNugget.java index ad2f783..2fd2aef 100755 --- a/java/src/game/item/ItemNugget.java +++ b/java/src/common/item/ItemNugget.java @@ -1,6 +1,6 @@ -package game.item; +package common.item; -import game.model.Transforms; +import common.model.Transforms; public class ItemNugget extends Item { public Transforms getTransform() { diff --git a/java/src/game/item/ItemPickaxe.java b/java/src/common/item/ItemPickaxe.java similarity index 96% rename from java/src/game/item/ItemPickaxe.java rename to java/src/common/item/ItemPickaxe.java index 222e01b..1abbc61 100755 --- a/java/src/game/item/ItemPickaxe.java +++ b/java/src/common/item/ItemPickaxe.java @@ -1,7 +1,7 @@ -package game.item; +package common.item; -import game.block.Block; -import game.init.ToolMaterial; +import common.block.Block; +import common.init.ToolMaterial; public class ItemPickaxe extends ItemTool { diff --git a/java/src/game/item/ItemPiston.java b/java/src/common/item/ItemPiston.java similarity index 84% rename from java/src/game/item/ItemPiston.java rename to java/src/common/item/ItemPiston.java index e5b6723..1b83d88 100755 --- a/java/src/game/item/ItemPiston.java +++ b/java/src/common/item/ItemPiston.java @@ -1,9 +1,9 @@ -package game.item; +package common.item; -import game.block.Block; -import game.init.Blocks; -import game.model.Model; -import game.model.ModelProvider; +import common.block.Block; +import common.init.Blocks; +import common.model.Model; +import common.model.ModelProvider; public class ItemPiston extends ItemBlock { diff --git a/java/src/game/item/ItemPotion.java b/java/src/common/item/ItemPotion.java similarity index 96% rename from java/src/game/item/ItemPotion.java rename to java/src/common/item/ItemPotion.java index 556090e..40aa95f 100755 --- a/java/src/game/item/ItemPotion.java +++ b/java/src/common/item/ItemPotion.java @@ -1,27 +1,28 @@ -package game.item; +package common.item; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Map.Entry; -import java.util.Set; -import game.collect.Maps; -import game.collect.Sets; -import game.color.TextColor; -import game.entity.attributes.Attribute; -import game.entity.attributes.AttributeModifier; -import game.entity.npc.EntityNPC; -import game.entity.projectile.EntityPotion; -import game.init.Items; -import game.init.SoundEvent; -import game.model.ItemMeshDefinition; -import game.model.Model; -import game.model.ModelProvider; -import game.potion.Potion; -import game.potion.PotionEffect; -import game.potion.PotionHelper; -import game.world.World; +import common.collect.Maps; +import common.collect.Sets; +import common.color.TextColor; +import common.entity.attributes.Attribute; +import common.entity.attributes.AttributeModifier; +import common.entity.npc.EntityNPC; +import common.entity.projectile.EntityPotion; +import common.init.Items; +import common.init.SoundEvent; +import common.model.ItemMeshDefinition; +import common.model.Model; +import common.model.ModelProvider; +import common.potion.Potion; +import common.potion.PotionEffect; +import common.potion.PotionHelper; +import common.world.World; + +import java.util.Set; public class ItemPotion extends Item { diff --git a/java/src/game/item/ItemPressurePlate.java b/java/src/common/item/ItemPressurePlate.java similarity index 78% rename from java/src/game/item/ItemPressurePlate.java rename to java/src/common/item/ItemPressurePlate.java index 0488c5b..5a246b2 100755 --- a/java/src/game/item/ItemPressurePlate.java +++ b/java/src/common/item/ItemPressurePlate.java @@ -1,9 +1,9 @@ -package game.item; +package common.item; -import game.block.Block; -import game.block.BlockBasePressurePlate; -import game.model.Model; -import game.model.ModelProvider; +import common.block.Block; +import common.block.BlockBasePressurePlate; +import common.model.Model; +import common.model.ModelProvider; public class ItemPressurePlate extends ItemBlock { public ItemPressurePlate(Block block) { diff --git a/java/src/game/item/ItemRecord.java b/java/src/common/item/ItemRecord.java similarity index 75% rename from java/src/game/item/ItemRecord.java rename to java/src/common/item/ItemRecord.java index 1cd10dd..ae209bc 100755 --- a/java/src/game/item/ItemRecord.java +++ b/java/src/common/item/ItemRecord.java @@ -1,7 +1,7 @@ -package game.item; +package common.item; -import game.model.Model; -import game.model.ModelProvider; +import common.model.Model; +import common.model.ModelProvider; public class ItemRecord extends Item { public ItemRecord() { diff --git a/java/src/game/item/ItemRedstone.java b/java/src/common/item/ItemRedstone.java similarity index 85% rename from java/src/game/item/ItemRedstone.java rename to java/src/common/item/ItemRedstone.java index 0c8fe07..53fc6be 100755 --- a/java/src/game/item/ItemRedstone.java +++ b/java/src/common/item/ItemRedstone.java @@ -1,12 +1,12 @@ -package game.item; +package common.item; -import game.block.Block; -import game.entity.Entity; -import game.entity.npc.EntityNPC; -import game.init.Blocks; -import game.world.BlockPos; -import game.world.Facing; -import game.world.World; +import common.block.Block; +import common.entity.Entity; +import common.entity.npc.EntityNPC; +import common.init.Blocks; +import common.world.BlockPos; +import common.world.Facing; +import common.world.World; public class ItemRedstone extends Item { diff --git a/java/src/game/item/ItemReed.java b/java/src/common/item/ItemReed.java similarity index 88% rename from java/src/game/item/ItemReed.java rename to java/src/common/item/ItemReed.java index 99722fd..1538e73 100755 --- a/java/src/game/item/ItemReed.java +++ b/java/src/common/item/ItemReed.java @@ -1,14 +1,14 @@ -package game.item; +package common.item; -import game.block.Block; -import game.block.BlockSnow; -import game.entity.Entity; -import game.entity.npc.EntityNPC; -import game.init.Blocks; -import game.world.BlockPos; -import game.world.Facing; -import game.world.State; -import game.world.World; +import common.block.Block; +import common.block.BlockSnow; +import common.entity.Entity; +import common.entity.npc.EntityNPC; +import common.init.Blocks; +import common.world.BlockPos; +import common.world.Facing; +import common.world.State; +import common.world.World; public class ItemReed extends Item { diff --git a/java/src/game/item/ItemRod.java b/java/src/common/item/ItemRod.java similarity index 68% rename from java/src/game/item/ItemRod.java rename to java/src/common/item/ItemRod.java index 8e5934f..567d491 100755 --- a/java/src/game/item/ItemRod.java +++ b/java/src/common/item/ItemRod.java @@ -1,6 +1,6 @@ -package game.item; +package common.item; -import game.model.Transforms; +import common.model.Transforms; public class ItemRod extends Item { public Transforms getTransform() { diff --git a/java/src/game/item/ItemSaddle.java b/java/src/common/item/ItemSaddle.java similarity index 89% rename from java/src/game/item/ItemSaddle.java rename to java/src/common/item/ItemSaddle.java index 60c9022..f872541 100755 --- a/java/src/game/item/ItemSaddle.java +++ b/java/src/common/item/ItemSaddle.java @@ -1,8 +1,8 @@ -package game.item; +package common.item; -import game.entity.animal.EntityPig; -import game.entity.npc.EntityNPC; -import game.entity.types.EntityLiving; +import common.entity.animal.EntityPig; +import common.entity.npc.EntityNPC; +import common.entity.types.EntityLiving; public class ItemSaddle extends Item { diff --git a/java/src/game/item/ItemSeedFood.java b/java/src/common/item/ItemSeedFood.java similarity index 87% rename from java/src/game/item/ItemSeedFood.java rename to java/src/common/item/ItemSeedFood.java index c268093..abe4ad1 100755 --- a/java/src/game/item/ItemSeedFood.java +++ b/java/src/common/item/ItemSeedFood.java @@ -1,10 +1,10 @@ -package game.item; +package common.item; -import game.block.Block; -import game.entity.npc.EntityNPC; -import game.world.BlockPos; -import game.world.Facing; -import game.world.World; +import common.block.Block; +import common.entity.npc.EntityNPC; +import common.world.BlockPos; +import common.world.Facing; +import common.world.World; public class ItemSeedFood extends ItemFood { diff --git a/java/src/game/item/ItemSeeds.java b/java/src/common/item/ItemSeeds.java similarity index 85% rename from java/src/game/item/ItemSeeds.java rename to java/src/common/item/ItemSeeds.java index c9e243c..9cbcadf 100755 --- a/java/src/game/item/ItemSeeds.java +++ b/java/src/common/item/ItemSeeds.java @@ -1,11 +1,11 @@ -package game.item; +package common.item; -import game.block.Block; -import game.entity.npc.EntityNPC; -import game.model.Transforms; -import game.world.BlockPos; -import game.world.Facing; -import game.world.World; +import common.block.Block; +import common.entity.npc.EntityNPC; +import common.model.Transforms; +import common.world.BlockPos; +import common.world.Facing; +import common.world.World; public class ItemSeeds extends Item { diff --git a/java/src/game/item/ItemShears.java b/java/src/common/item/ItemShears.java similarity index 88% rename from java/src/game/item/ItemShears.java rename to java/src/common/item/ItemShears.java index 4e7ecf3..dc40068 100755 --- a/java/src/game/item/ItemShears.java +++ b/java/src/common/item/ItemShears.java @@ -1,12 +1,12 @@ -package game.item; +package common.item; -import game.block.Block; -import game.entity.types.EntityLiving; -import game.init.Blocks; -import game.init.ToolMaterial; -import game.material.Material; -import game.world.BlockPos; -import game.world.World; +import common.block.Block; +import common.entity.types.EntityLiving; +import common.init.Blocks; +import common.init.ToolMaterial; +import common.material.Material; +import common.world.BlockPos; +import common.world.World; public class ItemShears extends Item { diff --git a/java/src/game/item/ItemSign.java b/java/src/common/item/ItemSign.java similarity index 85% rename from java/src/game/item/ItemSign.java rename to java/src/common/item/ItemSign.java index 81e2b7f..07affb8 100755 --- a/java/src/game/item/ItemSign.java +++ b/java/src/common/item/ItemSign.java @@ -1,16 +1,16 @@ -package game.item; +package common.item; -import game.block.Block; -import game.block.BlockStandingSign; -import game.block.BlockWallSign; -import game.entity.npc.EntityNPC; -import game.init.Blocks; -import game.tileentity.TileEntity; -import game.tileentity.TileEntitySign; -import game.util.ExtMath; -import game.world.BlockPos; -import game.world.Facing; -import game.world.World; +import common.block.Block; +import common.block.BlockStandingSign; +import common.block.BlockWallSign; +import common.entity.npc.EntityNPC; +import common.init.Blocks; +import common.tileentity.TileEntity; +import common.tileentity.TileEntitySign; +import common.util.ExtMath; +import common.world.BlockPos; +import common.world.Facing; +import common.world.World; public class ItemSign extends Item { diff --git a/java/src/game/item/ItemSkull.java b/java/src/common/item/ItemSkull.java similarity index 91% rename from java/src/game/item/ItemSkull.java rename to java/src/common/item/ItemSkull.java index 0def762..da83cc3 100755 --- a/java/src/game/item/ItemSkull.java +++ b/java/src/common/item/ItemSkull.java @@ -1,19 +1,19 @@ -package game.item; +package common.item; -import game.block.Block; -import game.block.BlockSkull; -import game.entity.npc.EntityNPC; -import game.init.Blocks; -import game.model.Model; -import game.model.ModelProvider; -import game.model.Transforms; -import game.tileentity.TileEntity; -import game.tileentity.TileEntitySkull; -import game.util.ExtMath; -import game.world.BlockPos; -import game.world.Facing; -import game.world.State; -import game.world.World; +import common.block.Block; +import common.block.BlockSkull; +import common.entity.npc.EntityNPC; +import common.init.Blocks; +import common.model.Model; +import common.model.ModelProvider; +import common.model.Transforms; +import common.tileentity.TileEntity; +import common.tileentity.TileEntitySkull; +import common.util.ExtMath; +import common.world.BlockPos; +import common.world.Facing; +import common.world.State; +import common.world.World; public class ItemSkull extends Item { diff --git a/java/src/game/item/ItemSlab.java b/java/src/common/item/ItemSlab.java similarity index 96% rename from java/src/game/item/ItemSlab.java rename to java/src/common/item/ItemSlab.java index 6665cf7..fa3d824 100755 --- a/java/src/game/item/ItemSlab.java +++ b/java/src/common/item/ItemSlab.java @@ -1,12 +1,12 @@ -package game.item; +package common.item; -import game.block.Block; -import game.block.BlockSlab; -import game.entity.npc.EntityNPC; -import game.world.BlockPos; -import game.world.Facing; -import game.world.State; -import game.world.World; +import common.block.Block; +import common.block.BlockSlab; +import common.entity.npc.EntityNPC; +import common.world.BlockPos; +import common.world.Facing; +import common.world.State; +import common.world.World; public class ItemSlab extends ItemBlock { diff --git a/java/src/game/item/ItemSmall.java b/java/src/common/item/ItemSmall.java similarity index 68% rename from java/src/game/item/ItemSmall.java rename to java/src/common/item/ItemSmall.java index 0278dbc..8ddcaa2 100755 --- a/java/src/game/item/ItemSmall.java +++ b/java/src/common/item/ItemSmall.java @@ -1,6 +1,6 @@ -package game.item; +package common.item; -import game.model.Transforms; +import common.model.Transforms; public class ItemSmall extends Item { public Transforms getTransform() { diff --git a/java/src/game/item/ItemSnow.java b/java/src/common/item/ItemSnow.java similarity index 89% rename from java/src/game/item/ItemSnow.java rename to java/src/common/item/ItemSnow.java index b51dcf1..4dbd517 100755 --- a/java/src/game/item/ItemSnow.java +++ b/java/src/common/item/ItemSnow.java @@ -1,13 +1,13 @@ -package game.item; +package common.item; -import game.block.Block; -import game.block.BlockSnow; -import game.entity.npc.EntityNPC; -import game.world.BlockPos; -import game.world.BoundingBox; -import game.world.Facing; -import game.world.State; -import game.world.World; +import common.block.Block; +import common.block.BlockSnow; +import common.entity.npc.EntityNPC; +import common.world.BlockPos; +import common.world.BoundingBox; +import common.world.Facing; +import common.world.State; +import common.world.World; public class ItemSnow extends ItemBlock { diff --git a/java/src/game/item/ItemSnowball.java b/java/src/common/item/ItemSnowball.java similarity index 82% rename from java/src/game/item/ItemSnowball.java rename to java/src/common/item/ItemSnowball.java index 7d1cb5e..efdf480 100755 --- a/java/src/game/item/ItemSnowball.java +++ b/java/src/common/item/ItemSnowball.java @@ -1,9 +1,9 @@ -package game.item; +package common.item; -import game.entity.npc.EntityNPC; -import game.entity.projectile.EntitySnowball; -import game.init.SoundEvent; -import game.world.World; +import common.entity.npc.EntityNPC; +import common.entity.projectile.EntitySnowball; +import common.init.SoundEvent; +import common.world.World; public class ItemSnowball extends Item { diff --git a/java/src/game/item/ItemSoup.java b/java/src/common/item/ItemSoup.java similarity index 81% rename from java/src/game/item/ItemSoup.java rename to java/src/common/item/ItemSoup.java index 0cd6946..daf6eba 100755 --- a/java/src/game/item/ItemSoup.java +++ b/java/src/common/item/ItemSoup.java @@ -1,9 +1,9 @@ -package game.item; +package common.item; -import game.entity.npc.EntityNPC; -import game.init.Items; -import game.model.Transforms; -import game.world.World; +import common.entity.npc.EntityNPC; +import common.init.Items; +import common.model.Transforms; +import common.world.World; public class ItemSoup extends ItemFood { diff --git a/java/src/game/item/ItemSpaceNavigator.java b/java/src/common/item/ItemSpaceNavigator.java similarity index 91% rename from java/src/game/item/ItemSpaceNavigator.java rename to java/src/common/item/ItemSpaceNavigator.java index 0a78457..5702a15 100755 --- a/java/src/game/item/ItemSpaceNavigator.java +++ b/java/src/common/item/ItemSpaceNavigator.java @@ -1,12 +1,12 @@ -package game.item; +package common.item; import java.util.List; -import game.color.TextColor; -import game.entity.npc.EntityNPC; -import game.init.UniverseRegistry; -import game.world.BlockPos; -import game.world.World; +import common.color.TextColor; +import common.entity.npc.EntityNPC; +import common.init.UniverseRegistry; +import common.world.BlockPos; +import common.world.World; public class ItemSpaceNavigator extends ItemMagnetic { public static String formatImperialTime(World world, boolean days) { diff --git a/java/src/game/item/ItemSpade.java b/java/src/common/item/ItemSpade.java similarity index 86% rename from java/src/game/item/ItemSpade.java rename to java/src/common/item/ItemSpade.java index 0ffae40..f2633c7 100755 --- a/java/src/game/item/ItemSpade.java +++ b/java/src/common/item/ItemSpade.java @@ -1,8 +1,8 @@ -package game.item; +package common.item; -import game.block.Block; -import game.init.ToolMaterial; -import game.material.Material; +import common.block.Block; +import common.init.ToolMaterial; +import common.material.Material; public class ItemSpade extends ItemTool { diff --git a/java/src/game/item/ItemStack.java b/java/src/common/item/ItemStack.java similarity index 98% rename from java/src/game/item/ItemStack.java rename to java/src/common/item/ItemStack.java index 11c034a..a24ad02 100755 --- a/java/src/game/item/ItemStack.java +++ b/java/src/common/item/ItemStack.java @@ -1,32 +1,33 @@ -package game.item; +package common.item; import java.text.DecimalFormat; import java.util.List; import java.util.Map; import java.util.Map.Entry; -import java.util.Set; -import game.block.Block; -import game.collect.Lists; -import game.collect.Maps; -import game.color.TextColor; -import game.enchantment.Enchantment; -import game.enchantment.EnchantmentDurability; -import game.enchantment.EnchantmentHelper; -import game.entity.attributes.Attribute; -import game.entity.attributes.AttributeModifier; -import game.entity.attributes.Attributes; -import game.entity.npc.EntityNPC; -import game.entity.types.EntityLiving; -import game.init.BlockRegistry; -import game.init.ItemRegistry; -import game.nbt.NBTBase; -import game.nbt.NBTTagCompound; -import game.nbt.NBTTagList; -import game.rng.Random; -import game.world.BlockPos; -import game.world.Facing; -import game.world.World; +import common.block.Block; +import common.collect.Lists; +import common.collect.Maps; +import common.color.TextColor; +import common.enchantment.Enchantment; +import common.enchantment.EnchantmentDurability; +import common.enchantment.EnchantmentHelper; +import common.entity.attributes.Attribute; +import common.entity.attributes.AttributeModifier; +import common.entity.attributes.Attributes; +import common.entity.npc.EntityNPC; +import common.entity.types.EntityLiving; +import common.init.BlockRegistry; +import common.init.ItemRegistry; +import common.nbt.NBTBase; +import common.nbt.NBTTagCompound; +import common.nbt.NBTTagList; +import common.rng.Random; +import common.world.BlockPos; +import common.world.Facing; +import common.world.World; + +import java.util.Set; public final class ItemStack { diff --git a/java/src/game/item/ItemStick.java b/java/src/common/item/ItemStick.java similarity index 68% rename from java/src/game/item/ItemStick.java rename to java/src/common/item/ItemStick.java index fe18c93..20113f5 100755 --- a/java/src/game/item/ItemStick.java +++ b/java/src/common/item/ItemStick.java @@ -1,6 +1,6 @@ -package game.item; +package common.item; -import game.model.Transforms; +import common.model.Transforms; public class ItemStick extends Item { public Transforms getTransform() { diff --git a/java/src/game/item/ItemSword.java b/java/src/common/item/ItemSword.java similarity index 90% rename from java/src/game/item/ItemSword.java rename to java/src/common/item/ItemSword.java index a3e942b..fb9c576 100755 --- a/java/src/game/item/ItemSword.java +++ b/java/src/common/item/ItemSword.java @@ -1,21 +1,21 @@ -package game.item; +package common.item; import java.util.Map; import java.util.Set; -import game.block.Block; -import game.collect.Sets; -import game.entity.attributes.Attribute; -import game.entity.attributes.AttributeModifier; -import game.entity.attributes.Attributes; -import game.entity.npc.EntityNPC; -import game.entity.types.EntityLiving; -import game.init.Blocks; -import game.init.ToolMaterial; -import game.material.Material; -import game.model.Transforms; -import game.world.BlockPos; -import game.world.World; +import common.block.Block; +import common.collect.Sets; +import common.entity.attributes.Attribute; +import common.entity.attributes.AttributeModifier; +import common.entity.attributes.Attributes; +import common.entity.npc.EntityNPC; +import common.entity.types.EntityLiving; +import common.init.Blocks; +import common.init.ToolMaterial; +import common.material.Material; +import common.model.Transforms; +import common.world.BlockPos; +import common.world.World; public class ItemSword extends Item { diff --git a/java/src/game/item/ItemTNT.java b/java/src/common/item/ItemTNT.java similarity index 88% rename from java/src/game/item/ItemTNT.java rename to java/src/common/item/ItemTNT.java index 4e3548a..6aa1b7d 100755 --- a/java/src/game/item/ItemTNT.java +++ b/java/src/common/item/ItemTNT.java @@ -1,7 +1,7 @@ -package game.item; +package common.item; -import game.block.Block; -import game.color.TextColor; +import common.block.Block; +import common.color.TextColor; public class ItemTNT extends ItemBlock { diff --git a/java/src/game/item/ItemTiny.java b/java/src/common/item/ItemTiny.java similarity index 68% rename from java/src/game/item/ItemTiny.java rename to java/src/common/item/ItemTiny.java index 5afe04c..96b9e8f 100755 --- a/java/src/game/item/ItemTiny.java +++ b/java/src/common/item/ItemTiny.java @@ -1,6 +1,6 @@ -package game.item; +package common.item; -import game.model.Transforms; +import common.model.Transforms; public class ItemTiny extends Item { public Transforms getTransform() { diff --git a/java/src/game/item/ItemTool.java b/java/src/common/item/ItemTool.java similarity index 89% rename from java/src/game/item/ItemTool.java rename to java/src/common/item/ItemTool.java index ae32886..039ca45 100755 --- a/java/src/game/item/ItemTool.java +++ b/java/src/common/item/ItemTool.java @@ -1,18 +1,18 @@ -package game.item; +package common.item; import java.util.Map; import java.util.Set; -import game.block.Block; -import game.collect.Sets; -import game.entity.attributes.Attribute; -import game.entity.attributes.AttributeModifier; -import game.entity.attributes.Attributes; -import game.entity.types.EntityLiving; -import game.init.ToolMaterial; -import game.model.Transforms; -import game.world.BlockPos; -import game.world.World; +import common.block.Block; +import common.collect.Sets; +import common.entity.attributes.Attribute; +import common.entity.attributes.AttributeModifier; +import common.entity.attributes.Attributes; +import common.entity.types.EntityLiving; +import common.init.ToolMaterial; +import common.model.Transforms; +import common.world.BlockPos; +import common.world.World; public abstract class ItemTool extends Item { diff --git a/java/src/game/item/ItemWall.java b/java/src/common/item/ItemWall.java similarity index 86% rename from java/src/game/item/ItemWall.java rename to java/src/common/item/ItemWall.java index af0d374..0579baa 100755 --- a/java/src/game/item/ItemWall.java +++ b/java/src/common/item/ItemWall.java @@ -1,11 +1,11 @@ -package game.item; +package common.item; import java.util.function.Function; -import game.block.Block; -import game.block.BlockWall; -import game.model.Model; -import game.model.ModelProvider; +import common.block.Block; +import common.block.BlockWall; +import common.model.Model; +import common.model.ModelProvider; public class ItemWall extends ItemMultiTexture { public ItemWall(Block block, Block block2, Function nameFunction) { diff --git a/java/src/game/item/ItemWand.java b/java/src/common/item/ItemWand.java similarity index 89% rename from java/src/game/item/ItemWand.java rename to java/src/common/item/ItemWand.java index 1e0b191..34eb6f6 100755 --- a/java/src/game/item/ItemWand.java +++ b/java/src/common/item/ItemWand.java @@ -1,16 +1,16 @@ -package game.item; +package common.item; import java.util.List; -import game.color.TextColor; -import game.entity.npc.EntityNPC; -import game.model.Transforms; -import game.util.ExtMath; -import game.world.BlockPos; -import game.world.Facing; -import game.world.Vec3; -import game.world.World; -import game.world.WorldServer; +import common.color.TextColor; +import common.entity.npc.EntityNPC; +import common.model.Transforms; +import common.util.ExtMath; +import common.world.BlockPos; +import common.world.Facing; +import common.world.Vec3; +import common.world.World; +import common.world.WorldServer; public abstract class ItemWand extends Item { public ItemWand() { diff --git a/java/src/game/item/ItemWeatherToken.java b/java/src/common/item/ItemWeatherToken.java similarity index 83% rename from java/src/game/item/ItemWeatherToken.java rename to java/src/common/item/ItemWeatherToken.java index 2bc3fb7..50ddb53 100755 --- a/java/src/game/item/ItemWeatherToken.java +++ b/java/src/common/item/ItemWeatherToken.java @@ -1,11 +1,11 @@ -package game.item; +package common.item; -import game.color.TextColor; -import game.entity.npc.EntityNPC; -import game.init.SoundEvent; -import game.world.Weather; -import game.world.World; -import game.world.WorldServer; +import common.color.TextColor; +import common.entity.npc.EntityNPC; +import common.init.SoundEvent; +import common.world.Weather; +import common.world.World; +import common.world.WorldServer; public class ItemWeatherToken extends ItemMagnetic { private final Weather weather; diff --git a/java/src/game/item/RngLoot.java b/java/src/common/item/RngLoot.java similarity index 94% rename from java/src/game/item/RngLoot.java rename to java/src/common/item/RngLoot.java index b4599cd..8c59985 100755 --- a/java/src/game/item/RngLoot.java +++ b/java/src/common/item/RngLoot.java @@ -1,12 +1,12 @@ -package game.item; +package common.item; import java.util.Collections; -import game.inventory.IInventory; -import game.rng.Random; -import game.rng.RngItem; -import game.rng.WeightedList; -import game.tileentity.TileEntityDispenser; +import common.inventory.IInventory; +import common.rng.Random; +import common.rng.RngItem; +import common.rng.WeightedList; +import common.tileentity.TileEntityDispenser; public class RngLoot extends RngItem { diff --git a/java/src/game/log/Log.java b/java/src/common/log/Log.java similarity index 97% rename from java/src/game/log/Log.java rename to java/src/common/log/Log.java index 099f10b..c6deea4 100644 --- a/java/src/game/log/Log.java +++ b/java/src/common/log/Log.java @@ -1,14 +1,14 @@ -package game.log; +package common.log; import java.io.PrintWriter; import java.io.StringWriter; import java.util.List; -import game.collect.Lists; -import game.color.TextColor; -import game.future.ListenableFuture; -import game.network.IThreadListener; -import game.util.Util; +import common.collect.Lists; +import common.color.TextColor; +import common.future.ListenableFuture; +import common.network.IThreadListener; +import common.util.Util; public enum Log { SYSTEM("System"), diff --git a/java/src/game/log/LogLevel.java b/java/src/common/log/LogLevel.java similarity index 87% rename from java/src/game/log/LogLevel.java rename to java/src/common/log/LogLevel.java index c299bf0..c16ba5a 100644 --- a/java/src/game/log/LogLevel.java +++ b/java/src/common/log/LogLevel.java @@ -1,8 +1,8 @@ -package game.log; +package common.log; -import game.color.TextColor; -import game.util.Displayable; -import game.util.Identifyable; +import common.color.TextColor; +import common.util.Displayable; +import common.util.Identifyable; public enum LogLevel implements Displayable, Identifyable { SILENT("silent", "Nichts", "UNK?", TextColor.BLACK), diff --git a/java/src/game/log/Message.java b/java/src/common/log/Message.java similarity index 89% rename from java/src/game/log/Message.java rename to java/src/common/log/Message.java index 47146fe..939962d 100644 --- a/java/src/game/log/Message.java +++ b/java/src/common/log/Message.java @@ -1,4 +1,4 @@ -package game.log; +package common.log; public class Message { public final String message; diff --git a/java/src/game/log/NettyLogger.java b/java/src/common/log/NettyLogger.java similarity index 99% rename from java/src/game/log/NettyLogger.java rename to java/src/common/log/NettyLogger.java index dde460e..8371653 100644 --- a/java/src/game/log/NettyLogger.java +++ b/java/src/common/log/NettyLogger.java @@ -1,4 +1,4 @@ -package game.log; +package common.log; import java.io.PrintWriter; import java.io.StringWriter; diff --git a/java/src/game/material/Material.java b/java/src/common/material/Material.java similarity index 99% rename from java/src/game/material/Material.java rename to java/src/common/material/Material.java index a9205f3..c71b80c 100755 --- a/java/src/game/material/Material.java +++ b/java/src/common/material/Material.java @@ -1,4 +1,4 @@ -package game.material; +package common.material; public class Material { diff --git a/java/src/game/material/MaterialColdFluid.java b/java/src/common/material/MaterialColdFluid.java similarity index 93% rename from java/src/game/material/MaterialColdFluid.java rename to java/src/common/material/MaterialColdFluid.java index 5d27283..9187ad2 100755 --- a/java/src/game/material/MaterialColdFluid.java +++ b/java/src/common/material/MaterialColdFluid.java @@ -1,4 +1,4 @@ -package game.material; +package common.material; public class MaterialColdFluid extends Material { public MaterialColdFluid() { diff --git a/java/src/game/material/MaterialHotFluid.java b/java/src/common/material/MaterialHotFluid.java similarity index 93% rename from java/src/game/material/MaterialHotFluid.java rename to java/src/common/material/MaterialHotFluid.java index e7a31b1..03b6ca1 100755 --- a/java/src/game/material/MaterialHotFluid.java +++ b/java/src/common/material/MaterialHotFluid.java @@ -1,4 +1,4 @@ -package game.material; +package common.material; public class MaterialHotFluid extends Material { public MaterialHotFluid() { diff --git a/java/src/game/material/MaterialLogic.java b/java/src/common/material/MaterialLogic.java similarity index 95% rename from java/src/game/material/MaterialLogic.java rename to java/src/common/material/MaterialLogic.java index a5572c6..137eb9a 100755 --- a/java/src/game/material/MaterialLogic.java +++ b/java/src/common/material/MaterialLogic.java @@ -1,4 +1,4 @@ -package game.material; +package common.material; public class MaterialLogic extends Material { diff --git a/java/src/game/material/MaterialPortal.java b/java/src/common/material/MaterialPortal.java similarity index 95% rename from java/src/game/material/MaterialPortal.java rename to java/src/common/material/MaterialPortal.java index 56d0362..778d739 100755 --- a/java/src/game/material/MaterialPortal.java +++ b/java/src/common/material/MaterialPortal.java @@ -1,4 +1,4 @@ -package game.material; +package common.material; public class MaterialPortal extends Material { diff --git a/java/src/game/material/MaterialTransparent.java b/java/src/common/material/MaterialTransparent.java similarity index 96% rename from java/src/game/material/MaterialTransparent.java rename to java/src/common/material/MaterialTransparent.java index 2ab99c4..82af6d1 100755 --- a/java/src/game/material/MaterialTransparent.java +++ b/java/src/common/material/MaterialTransparent.java @@ -1,4 +1,4 @@ -package game.material; +package common.material; public class MaterialTransparent extends Material { diff --git a/java/src/game/model/BlockLayer.java b/java/src/common/model/BlockLayer.java similarity index 93% rename from java/src/game/model/BlockLayer.java rename to java/src/common/model/BlockLayer.java index 3be6166..ec9f03a 100755 --- a/java/src/game/model/BlockLayer.java +++ b/java/src/common/model/BlockLayer.java @@ -1,4 +1,4 @@ -package game.model; +package common.model; public enum BlockLayer { diff --git a/java/src/game/model/ItemMeshDefinition.java b/java/src/common/model/ItemMeshDefinition.java similarity index 62% rename from java/src/game/model/ItemMeshDefinition.java rename to java/src/common/model/ItemMeshDefinition.java index 91b59e2..cd7942e 100755 --- a/java/src/game/model/ItemMeshDefinition.java +++ b/java/src/common/model/ItemMeshDefinition.java @@ -1,6 +1,6 @@ -package game.model; +package common.model; -import game.item.ItemStack; +import common.item.ItemStack; public interface ItemMeshDefinition { diff --git a/java/src/game/model/Model.java b/java/src/common/model/Model.java similarity index 99% rename from java/src/game/model/Model.java rename to java/src/common/model/Model.java index c0c78a8..378a18a 100644 --- a/java/src/game/model/Model.java +++ b/java/src/common/model/Model.java @@ -1,6 +1,6 @@ -package game.model; +package common.model; -import game.world.Facing; +import common.world.Facing; public abstract class Model { public abstract Model noOcclude(); diff --git a/java/src/game/model/ModelProvider.java b/java/src/common/model/ModelProvider.java similarity index 95% rename from java/src/game/model/ModelProvider.java rename to java/src/common/model/ModelProvider.java index d08c37f..5805eaf 100644 --- a/java/src/game/model/ModelProvider.java +++ b/java/src/common/model/ModelProvider.java @@ -1,7 +1,7 @@ -package game.model; +package common.model; -import game.world.Facing; -import game.world.Facing.Axis; +import common.world.Facing; +import common.world.Facing.Axis; public interface ModelProvider { Model getModel(String primary); diff --git a/java/src/game/model/ModelRotation.java b/java/src/common/model/ModelRotation.java similarity index 95% rename from java/src/game/model/ModelRotation.java rename to java/src/common/model/ModelRotation.java index 4551b8a..0329240 100755 --- a/java/src/game/model/ModelRotation.java +++ b/java/src/common/model/ModelRotation.java @@ -1,12 +1,12 @@ -package game.model; +package common.model; import java.util.Map; -import game.collect.Maps; -import game.util.ExtMath; -import game.util.Matrix4f; -import game.util.Vector3f; -import game.world.Facing; +import common.collect.Maps; +import common.util.ExtMath; +import common.util.Matrix4f; +import common.util.Vector3f; +import common.world.Facing; public enum ModelRotation { diff --git a/java/src/game/model/ParticleType.java b/java/src/common/model/ParticleType.java similarity index 97% rename from java/src/game/model/ParticleType.java rename to java/src/common/model/ParticleType.java index 792b8e1..cace491 100755 --- a/java/src/game/model/ParticleType.java +++ b/java/src/common/model/ParticleType.java @@ -1,10 +1,10 @@ -package game.model; +package common.model; import java.util.List; import java.util.Map; -import game.collect.Lists; -import game.collect.Maps; +import common.collect.Lists; +import common.collect.Maps; public enum ParticleType { diff --git a/java/src/game/model/Transform.java b/java/src/common/model/Transform.java similarity index 95% rename from java/src/game/model/Transform.java rename to java/src/common/model/Transform.java index e546145..4bb0994 100755 --- a/java/src/game/model/Transform.java +++ b/java/src/common/model/Transform.java @@ -1,6 +1,6 @@ -package game.model; +package common.model; -import game.util.Vector3f; +import common.util.Vector3f; public class Transform { public static final Transform IDENTITY = new Transform(0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f); diff --git a/java/src/game/model/Transforms.java b/java/src/common/model/Transforms.java similarity index 99% rename from java/src/game/model/Transforms.java rename to java/src/common/model/Transforms.java index 60c722c..6333c89 100755 --- a/java/src/game/model/Transforms.java +++ b/java/src/common/model/Transforms.java @@ -1,4 +1,4 @@ -package game.model; +package common.model; public enum Transforms { DEFAULT( diff --git a/java/src/game/nbt/NBTBase.java b/java/src/common/nbt/NBTBase.java similarity index 99% rename from java/src/game/nbt/NBTBase.java rename to java/src/common/nbt/NBTBase.java index 9e9e144..4fe8be1 100755 --- a/java/src/game/nbt/NBTBase.java +++ b/java/src/common/nbt/NBTBase.java @@ -1,4 +1,4 @@ -package game.nbt; +package common.nbt; import java.io.DataInput; import java.io.DataOutput; diff --git a/java/src/game/nbt/NBTException.java b/java/src/common/nbt/NBTException.java similarity index 86% rename from java/src/game/nbt/NBTException.java rename to java/src/common/nbt/NBTException.java index af15215..0290c39 100755 --- a/java/src/game/nbt/NBTException.java +++ b/java/src/common/nbt/NBTException.java @@ -1,4 +1,4 @@ -package game.nbt; +package common.nbt; public class NBTException extends Exception { diff --git a/java/src/game/nbt/NBTLoader.java b/java/src/common/nbt/NBTLoader.java similarity index 99% rename from java/src/game/nbt/NBTLoader.java rename to java/src/common/nbt/NBTLoader.java index c135579..a1d0073 100755 --- a/java/src/game/nbt/NBTLoader.java +++ b/java/src/common/nbt/NBTLoader.java @@ -1,4 +1,4 @@ -package game.nbt; +package common.nbt; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; diff --git a/java/src/game/nbt/NBTParser.java b/java/src/common/nbt/NBTParser.java similarity index 99% rename from java/src/game/nbt/NBTParser.java rename to java/src/common/nbt/NBTParser.java index e4a2e97..8bb650f 100755 --- a/java/src/game/nbt/NBTParser.java +++ b/java/src/common/nbt/NBTParser.java @@ -1,9 +1,9 @@ -package game.nbt; +package common.nbt; import java.util.Stack; import java.util.regex.Pattern; -import game.collect.Lists; +import common.collect.Lists; public class NBTParser { diff --git a/java/src/game/nbt/NBTSizeTracker.java b/java/src/common/nbt/NBTSizeTracker.java similarity index 97% rename from java/src/game/nbt/NBTSizeTracker.java rename to java/src/common/nbt/NBTSizeTracker.java index 6075e06..140df95 100755 --- a/java/src/game/nbt/NBTSizeTracker.java +++ b/java/src/common/nbt/NBTSizeTracker.java @@ -1,4 +1,4 @@ -package game.nbt; +package common.nbt; public class NBTSizeTracker { diff --git a/java/src/game/nbt/NBTTagByte.java b/java/src/common/nbt/NBTTagByte.java similarity index 98% rename from java/src/game/nbt/NBTTagByte.java rename to java/src/common/nbt/NBTTagByte.java index 7bf606b..b5a0644 100755 --- a/java/src/game/nbt/NBTTagByte.java +++ b/java/src/common/nbt/NBTTagByte.java @@ -1,4 +1,4 @@ -package game.nbt; +package common.nbt; import java.io.DataInput; import java.io.DataOutput; diff --git a/java/src/game/nbt/NBTTagByteArray.java b/java/src/common/nbt/NBTTagByteArray.java similarity index 98% rename from java/src/game/nbt/NBTTagByteArray.java rename to java/src/common/nbt/NBTTagByteArray.java index eb68b0f..c5c0417 100755 --- a/java/src/game/nbt/NBTTagByteArray.java +++ b/java/src/common/nbt/NBTTagByteArray.java @@ -1,4 +1,4 @@ -package game.nbt; +package common.nbt; import java.io.DataInput; import java.io.DataOutput; diff --git a/java/src/game/nbt/NBTTagCompound.java b/java/src/common/nbt/NBTTagCompound.java similarity index 99% rename from java/src/game/nbt/NBTTagCompound.java rename to java/src/common/nbt/NBTTagCompound.java index 4606414..b64ce1c 100755 --- a/java/src/game/nbt/NBTTagCompound.java +++ b/java/src/common/nbt/NBTTagCompound.java @@ -1,13 +1,14 @@ -package game.nbt; +package common.nbt; import java.io.DataInput; import java.io.DataOutput; import java.io.IOException; import java.util.Map; import java.util.Map.Entry; -import java.util.Set; -import game.collect.Maps; +import common.collect.Maps; + +import java.util.Set; public class NBTTagCompound extends NBTBase { diff --git a/java/src/game/nbt/NBTTagDouble.java b/java/src/common/nbt/NBTTagDouble.java similarity index 97% rename from java/src/game/nbt/NBTTagDouble.java rename to java/src/common/nbt/NBTTagDouble.java index 13d6180..2a711b3 100755 --- a/java/src/game/nbt/NBTTagDouble.java +++ b/java/src/common/nbt/NBTTagDouble.java @@ -1,10 +1,10 @@ -package game.nbt; +package common.nbt; import java.io.DataInput; import java.io.DataOutput; import java.io.IOException; -import game.util.ExtMath; +import common.util.ExtMath; public class NBTTagDouble extends NBTBase.NBTPrimitive { diff --git a/java/src/game/nbt/NBTTagEnd.java b/java/src/common/nbt/NBTTagEnd.java similarity index 97% rename from java/src/game/nbt/NBTTagEnd.java rename to java/src/common/nbt/NBTTagEnd.java index dfcf2c4..69fc4a7 100755 --- a/java/src/game/nbt/NBTTagEnd.java +++ b/java/src/common/nbt/NBTTagEnd.java @@ -1,4 +1,4 @@ -package game.nbt; +package common.nbt; import java.io.DataInput; import java.io.DataOutput; diff --git a/java/src/game/nbt/NBTTagFloat.java b/java/src/common/nbt/NBTTagFloat.java similarity index 97% rename from java/src/game/nbt/NBTTagFloat.java rename to java/src/common/nbt/NBTTagFloat.java index c9fce4e..a51869e 100755 --- a/java/src/game/nbt/NBTTagFloat.java +++ b/java/src/common/nbt/NBTTagFloat.java @@ -1,10 +1,10 @@ -package game.nbt; +package common.nbt; import java.io.DataInput; import java.io.DataOutput; import java.io.IOException; -import game.util.ExtMath; +import common.util.ExtMath; public class NBTTagFloat extends NBTBase.NBTPrimitive { diff --git a/java/src/game/nbt/NBTTagInt.java b/java/src/common/nbt/NBTTagInt.java similarity index 98% rename from java/src/game/nbt/NBTTagInt.java rename to java/src/common/nbt/NBTTagInt.java index d5622fe..50dc226 100755 --- a/java/src/game/nbt/NBTTagInt.java +++ b/java/src/common/nbt/NBTTagInt.java @@ -1,4 +1,4 @@ -package game.nbt; +package common.nbt; import java.io.DataInput; import java.io.DataOutput; diff --git a/java/src/game/nbt/NBTTagIntArray.java b/java/src/common/nbt/NBTTagIntArray.java similarity index 98% rename from java/src/game/nbt/NBTTagIntArray.java rename to java/src/common/nbt/NBTTagIntArray.java index d0c85b8..657abbe 100755 --- a/java/src/game/nbt/NBTTagIntArray.java +++ b/java/src/common/nbt/NBTTagIntArray.java @@ -1,4 +1,4 @@ -package game.nbt; +package common.nbt; import java.io.DataInput; import java.io.DataOutput; diff --git a/java/src/game/nbt/NBTTagList.java b/java/src/common/nbt/NBTTagList.java similarity index 99% rename from java/src/game/nbt/NBTTagList.java rename to java/src/common/nbt/NBTTagList.java index 2ce7cfa..c20a725 100755 --- a/java/src/game/nbt/NBTTagList.java +++ b/java/src/common/nbt/NBTTagList.java @@ -1,4 +1,4 @@ -package game.nbt; +package common.nbt; import java.io.DataInput; import java.io.DataOutput; @@ -6,8 +6,8 @@ import java.io.IOException; import java.util.ArrayList; import java.util.List; -import game.collect.Lists; -import game.log.Log; +import common.collect.Lists; +import common.log.Log; public class NBTTagList extends NBTBase { diff --git a/java/src/game/nbt/NBTTagLong.java b/java/src/common/nbt/NBTTagLong.java similarity index 98% rename from java/src/game/nbt/NBTTagLong.java rename to java/src/common/nbt/NBTTagLong.java index 989c6c4..aa9313a 100755 --- a/java/src/game/nbt/NBTTagLong.java +++ b/java/src/common/nbt/NBTTagLong.java @@ -1,4 +1,4 @@ -package game.nbt; +package common.nbt; import java.io.DataInput; import java.io.DataOutput; diff --git a/java/src/game/nbt/NBTTagShort.java b/java/src/common/nbt/NBTTagShort.java similarity index 98% rename from java/src/game/nbt/NBTTagShort.java rename to java/src/common/nbt/NBTTagShort.java index 3ebc2ab..684aa95 100755 --- a/java/src/game/nbt/NBTTagShort.java +++ b/java/src/common/nbt/NBTTagShort.java @@ -1,4 +1,4 @@ -package game.nbt; +package common.nbt; import java.io.DataInput; import java.io.DataOutput; diff --git a/java/src/game/nbt/NBTTagString.java b/java/src/common/nbt/NBTTagString.java similarity index 98% rename from java/src/game/nbt/NBTTagString.java rename to java/src/common/nbt/NBTTagString.java index 4eef986..5968697 100755 --- a/java/src/game/nbt/NBTTagString.java +++ b/java/src/common/nbt/NBTTagString.java @@ -1,4 +1,4 @@ -package game.nbt; +package common.nbt; import java.io.DataInput; import java.io.DataOutput; diff --git a/java/src/game/nbt/NBTUtil.java b/java/src/common/nbt/NBTUtil.java similarity index 99% rename from java/src/game/nbt/NBTUtil.java rename to java/src/common/nbt/NBTUtil.java index f6f4f74..8d3eaf8 100755 --- a/java/src/game/nbt/NBTUtil.java +++ b/java/src/common/nbt/NBTUtil.java @@ -1,4 +1,4 @@ -package game.nbt; +package common.nbt; public final class NBTUtil { diff --git a/java/src/game/network/IClientLoginHandler.java b/java/src/common/network/IClientLoginHandler.java similarity index 58% rename from java/src/game/network/IClientLoginHandler.java rename to java/src/common/network/IClientLoginHandler.java index b06b99e..99ac69d 100644 --- a/java/src/game/network/IClientLoginHandler.java +++ b/java/src/common/network/IClientLoginHandler.java @@ -1,8 +1,8 @@ -package game.network; +package common.network; -import game.packet.RPacketDisconnect; -import game.packet.RPacketEnableCompression; -import game.packet.RPacketLoginSuccess; +import common.packet.RPacketDisconnect; +import common.packet.RPacketEnableCompression; +import common.packet.RPacketLoginSuccess; public interface IClientLoginHandler { diff --git a/java/src/game/network/IClientPlayer.java b/java/src/common/network/IClientPlayer.java similarity index 76% rename from java/src/game/network/IClientPlayer.java rename to java/src/common/network/IClientPlayer.java index 4fb6331..881d9cb 100644 --- a/java/src/game/network/IClientPlayer.java +++ b/java/src/common/network/IClientPlayer.java @@ -1,72 +1,72 @@ -package game.network; +package common.network; -import game.entity.animal.EntityHorse; -import game.inventory.IInventory; -import game.inventory.InventoryPlayer; -import game.packet.S14PacketEntity; -import game.packet.S18PacketEntityTeleport; -import game.packet.S19PacketEntityHeadLook; -import game.packet.S1APacketEntityStatus; -import game.packet.S1BPacketEntityAttach; -import game.packet.S1CPacketEntityMetadata; -import game.packet.S1DPacketEntityEffect; -import game.packet.S1EPacketRemoveEntityEffect; -import game.packet.S20PacketEntityProperties; -import game.packet.S27PacketExplosion; -import game.packet.S28PacketEffect; -import game.packet.S29PacketSoundEffect; -import game.packet.S2APacketParticles; -import game.packet.S2BPacketChangeGameState; -import game.packet.S2CPacketSpawnGlobalEntity; -import game.packet.S2DPacketOpenWindow; -import game.packet.S2EPacketCloseWindow; -import game.packet.S2FPacketSetSlot; -import game.packet.S30PacketWindowItems; -import game.packet.S31PacketWindowProperty; -import game.packet.S32PacketConfirmTransaction; -import game.packet.S33PacketUpdateSign; -import game.packet.S35PacketUpdateTileEntity; -import game.packet.S36PacketSignEditorOpen; -import game.packet.S38PacketPlayerListItem; -import game.packet.S39PacketPlayerAbilities; -import game.packet.S3APacketTabComplete; -import game.packet.S43PacketUpdateEntityNBT; -import game.packet.SPacketAnimation; -import game.packet.SPacketBiomes; -import game.packet.SPacketBlockAction; -import game.packet.SPacketBlockBreakAnim; -import game.packet.SPacketBlockChange; -import game.packet.SPacketCamera; -import game.packet.SPacketCharacterList; -import game.packet.SPacketChunkData; -import game.packet.SPacketCollectItem; -import game.packet.SPacketDestroyEntities; -import game.packet.SPacketDimensionName; -import game.packet.SPacketDisconnect; -import game.packet.SPacketEntityEquipment; -import game.packet.SPacketEntityVelocity; -import game.packet.SPacketHeldItemChange; -import game.packet.SPacketJoinGame; -import game.packet.SPacketKeepAlive; -import game.packet.SPacketLoading; -import game.packet.SPacketMapChunkBulk; -import game.packet.SPacketMessage; -import game.packet.SPacketMultiBlockChange; -import game.packet.SPacketPlayerPosLook; -import game.packet.SPacketRespawn; -import game.packet.SPacketServerTick; -import game.packet.SPacketSetExperience; -import game.packet.SPacketSkin; -import game.packet.SPacketSpawnMob; -import game.packet.SPacketSpawnObject; -import game.packet.SPacketSpawnPlayer; -import game.packet.SPacketTimeUpdate; -import game.packet.SPacketTrades; -import game.packet.SPacketUpdateHealth; -import game.packet.SPacketWorld; -import game.tileentity.IInteractionObject; -import game.world.BlockPos; -import game.world.World; +import common.entity.animal.EntityHorse; +import common.inventory.IInventory; +import common.inventory.InventoryPlayer; +import common.packet.S14PacketEntity; +import common.packet.S18PacketEntityTeleport; +import common.packet.S19PacketEntityHeadLook; +import common.packet.S1APacketEntityStatus; +import common.packet.S1BPacketEntityAttach; +import common.packet.S1CPacketEntityMetadata; +import common.packet.S1DPacketEntityEffect; +import common.packet.S1EPacketRemoveEntityEffect; +import common.packet.S20PacketEntityProperties; +import common.packet.S27PacketExplosion; +import common.packet.S28PacketEffect; +import common.packet.S29PacketSoundEffect; +import common.packet.S2APacketParticles; +import common.packet.S2BPacketChangeGameState; +import common.packet.S2CPacketSpawnGlobalEntity; +import common.packet.S2DPacketOpenWindow; +import common.packet.S2EPacketCloseWindow; +import common.packet.S2FPacketSetSlot; +import common.packet.S30PacketWindowItems; +import common.packet.S31PacketWindowProperty; +import common.packet.S32PacketConfirmTransaction; +import common.packet.S33PacketUpdateSign; +import common.packet.S35PacketUpdateTileEntity; +import common.packet.S36PacketSignEditorOpen; +import common.packet.S38PacketPlayerListItem; +import common.packet.S39PacketPlayerAbilities; +import common.packet.S3APacketTabComplete; +import common.packet.S43PacketUpdateEntityNBT; +import common.packet.SPacketAnimation; +import common.packet.SPacketBiomes; +import common.packet.SPacketBlockAction; +import common.packet.SPacketBlockBreakAnim; +import common.packet.SPacketBlockChange; +import common.packet.SPacketCamera; +import common.packet.SPacketCharacterList; +import common.packet.SPacketChunkData; +import common.packet.SPacketCollectItem; +import common.packet.SPacketDestroyEntities; +import common.packet.SPacketDimensionName; +import common.packet.SPacketDisconnect; +import common.packet.SPacketEntityEquipment; +import common.packet.SPacketEntityVelocity; +import common.packet.SPacketHeldItemChange; +import common.packet.SPacketJoinGame; +import common.packet.SPacketKeepAlive; +import common.packet.SPacketLoading; +import common.packet.SPacketMapChunkBulk; +import common.packet.SPacketMessage; +import common.packet.SPacketMultiBlockChange; +import common.packet.SPacketPlayerPosLook; +import common.packet.SPacketRespawn; +import common.packet.SPacketServerTick; +import common.packet.SPacketSetExperience; +import common.packet.SPacketSkin; +import common.packet.SPacketSpawnMob; +import common.packet.SPacketSpawnObject; +import common.packet.SPacketSpawnPlayer; +import common.packet.SPacketTimeUpdate; +import common.packet.SPacketTrades; +import common.packet.SPacketUpdateHealth; +import common.packet.SPacketWorld; +import common.tileentity.IInteractionObject; +import common.world.BlockPos; +import common.world.World; public interface IClientPlayer { void addToSendQueue(Packet packet); diff --git a/java/src/game/network/IHandshakeHandler.java b/java/src/common/network/IHandshakeHandler.java similarity index 58% rename from java/src/game/network/IHandshakeHandler.java rename to java/src/common/network/IHandshakeHandler.java index 73af36d..b6815e8 100644 --- a/java/src/game/network/IHandshakeHandler.java +++ b/java/src/common/network/IHandshakeHandler.java @@ -1,6 +1,6 @@ -package game.network; +package common.network; -import game.packet.HPacketHandshake; +import common.packet.HPacketHandshake; public interface IHandshakeHandler { diff --git a/java/src/game/network/ILoginHandler.java b/java/src/common/network/ILoginHandler.java similarity index 58% rename from java/src/game/network/ILoginHandler.java rename to java/src/common/network/ILoginHandler.java index 45f6ff3..5361bc1 100644 --- a/java/src/game/network/ILoginHandler.java +++ b/java/src/common/network/ILoginHandler.java @@ -1,6 +1,6 @@ -package game.network; +package common.network; -import game.packet.LPacketPasswordResponse; +import common.packet.LPacketPasswordResponse; public interface ILoginHandler { diff --git a/java/src/game/network/IPlayer.java b/java/src/common/network/IPlayer.java similarity index 77% rename from java/src/game/network/IPlayer.java rename to java/src/common/network/IPlayer.java index 2ec04ba..e819468 100644 --- a/java/src/game/network/IPlayer.java +++ b/java/src/common/network/IPlayer.java @@ -1,35 +1,35 @@ -package game.network; +package common.network; import java.util.List; -import game.entity.Entity; -import game.entity.animal.EntityHorse; -import game.entity.npc.EntityNPC; -import game.entity.types.EntityLiving; -import game.init.SoundEvent; -import game.inventory.Container; -import game.inventory.IInventory; -import game.item.ItemStack; -import game.packet.CPacketAction; -import game.packet.CPacketBook; -import game.packet.CPacketBreak; -import game.packet.CPacketCheat; -import game.packet.CPacketClick; -import game.packet.CPacketComplete; -import game.packet.CPacketInput; -import game.packet.CPacketKeepAlive; -import game.packet.CPacketMessage; -import game.packet.CPacketPlace; -import game.packet.CPacketPlayer; -import game.packet.CPacketSign; -import game.packet.CPacketSkin; -import game.potion.PotionEffect; -import game.tileentity.IInteractionObject; -import game.tileentity.TileEntitySign; -import game.util.CharValidator; -import game.world.BlockPos; -import game.world.ChunkPos; -import game.world.PortalType; +import common.entity.Entity; +import common.entity.animal.EntityHorse; +import common.entity.npc.EntityNPC; +import common.entity.types.EntityLiving; +import common.init.SoundEvent; +import common.inventory.Container; +import common.inventory.IInventory; +import common.item.ItemStack; +import common.packet.CPacketAction; +import common.packet.CPacketBook; +import common.packet.CPacketBreak; +import common.packet.CPacketCheat; +import common.packet.CPacketClick; +import common.packet.CPacketComplete; +import common.packet.CPacketInput; +import common.packet.CPacketKeepAlive; +import common.packet.CPacketMessage; +import common.packet.CPacketPlace; +import common.packet.CPacketPlayer; +import common.packet.CPacketSign; +import common.packet.CPacketSkin; +import common.potion.PotionEffect; +import common.tileentity.IInteractionObject; +import common.tileentity.TileEntitySign; +import common.util.CharValidator; +import common.world.BlockPos; +import common.world.ChunkPos; +import common.world.PortalType; public interface IPlayer { public static class UserValidator implements CharValidator { diff --git a/java/src/game/network/IThreadListener.java b/java/src/common/network/IThreadListener.java similarity index 73% rename from java/src/game/network/IThreadListener.java rename to java/src/common/network/IThreadListener.java index 2f19842..e6f14d4 100755 --- a/java/src/game/network/IThreadListener.java +++ b/java/src/common/network/IThreadListener.java @@ -1,6 +1,6 @@ -package game.network; +package common.network; -import game.future.ListenableFuture; +import common.future.ListenableFuture; public interface IThreadListener { diff --git a/java/src/game/network/NetConnection.java b/java/src/common/network/NetConnection.java similarity index 98% rename from java/src/game/network/NetConnection.java rename to java/src/common/network/NetConnection.java index 3941f3f..89c055a 100755 --- a/java/src/game/network/NetConnection.java +++ b/java/src/common/network/NetConnection.java @@ -1,4 +1,4 @@ -package game.network; +package common.network; import java.net.InetAddress; import java.net.SocketAddress; @@ -7,10 +7,10 @@ import java.util.concurrent.ConcurrentLinkedQueue; import java.util.concurrent.locks.ReentrantReadWriteLock; import java.util.regex.Pattern; -import game.future.ThreadFactoryBuilder; -import game.log.Log; -import game.network.NetHandler.ThreadQuickExitException; -import game.util.LazyLoadBase; +import common.future.ThreadFactoryBuilder; +import common.log.Log; +import common.network.NetHandler.ThreadQuickExitException; +import common.util.LazyLoadBase; import io.netty.bootstrap.Bootstrap; import io.netty.channel.Channel; import io.netty.channel.ChannelException; diff --git a/java/src/game/network/NetHandler.java b/java/src/common/network/NetHandler.java similarity index 97% rename from java/src/game/network/NetHandler.java rename to java/src/common/network/NetHandler.java index 0d47cb4..1454ec5 100755 --- a/java/src/game/network/NetHandler.java +++ b/java/src/common/network/NetHandler.java @@ -1,4 +1,4 @@ -package game.network; +package common.network; public abstract class NetHandler { private static final ThreadQuickExitException EXIT = new ThreadQuickExitException(); diff --git a/java/src/game/network/NettyCompressionDecoder.java b/java/src/common/network/NettyCompressionDecoder.java similarity index 98% rename from java/src/game/network/NettyCompressionDecoder.java rename to java/src/common/network/NettyCompressionDecoder.java index 0d7d95e..d77de45 100755 --- a/java/src/game/network/NettyCompressionDecoder.java +++ b/java/src/common/network/NettyCompressionDecoder.java @@ -1,4 +1,4 @@ -package game.network; +package common.network; import java.util.List; import java.util.zip.DataFormatException; diff --git a/java/src/game/network/NettyCompressionEncoder.java b/java/src/common/network/NettyCompressionEncoder.java similarity index 98% rename from java/src/game/network/NettyCompressionEncoder.java rename to java/src/common/network/NettyCompressionEncoder.java index b19cfd2..9719f99 100755 --- a/java/src/game/network/NettyCompressionEncoder.java +++ b/java/src/common/network/NettyCompressionEncoder.java @@ -1,4 +1,4 @@ -package game.network; +package common.network; import java.util.zip.Deflater; diff --git a/java/src/game/network/Packet.java b/java/src/common/network/Packet.java similarity index 90% rename from java/src/game/network/Packet.java rename to java/src/common/network/Packet.java index ced4621..4ba381f 100755 --- a/java/src/game/network/Packet.java +++ b/java/src/common/network/Packet.java @@ -1,4 +1,4 @@ -package game.network; +package common.network; import java.io.IOException; diff --git a/java/src/game/network/PacketBuffer.java b/java/src/common/network/PacketBuffer.java similarity index 98% rename from java/src/game/network/PacketBuffer.java rename to java/src/common/network/PacketBuffer.java index ccc6b8e..a845416 100755 --- a/java/src/game/network/PacketBuffer.java +++ b/java/src/common/network/PacketBuffer.java @@ -1,14 +1,14 @@ -package game.network; +package common.network; import java.io.IOException; import java.nio.charset.Charset; -import game.init.ItemRegistry; -import game.item.ItemStack; -import game.nbt.NBTLoader; -import game.nbt.NBTSizeTracker; -import game.nbt.NBTTagCompound; -import game.world.BlockPos; +import common.init.ItemRegistry; +import common.item.ItemStack; +import common.nbt.NBTLoader; +import common.nbt.NBTSizeTracker; +import common.nbt.NBTTagCompound; +import common.world.BlockPos; import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBufInputStream; import io.netty.buffer.ByteBufOutputStream; diff --git a/java/src/game/network/PacketDecoder.java b/java/src/common/network/PacketDecoder.java similarity index 98% rename from java/src/game/network/PacketDecoder.java rename to java/src/common/network/PacketDecoder.java index 3fb1715..e00089d 100755 --- a/java/src/game/network/PacketDecoder.java +++ b/java/src/common/network/PacketDecoder.java @@ -1,4 +1,4 @@ -package game.network; +package common.network; import java.io.IOException; import java.util.List; diff --git a/java/src/game/network/PacketEncoder.java b/java/src/common/network/PacketEncoder.java similarity index 96% rename from java/src/game/network/PacketEncoder.java rename to java/src/common/network/PacketEncoder.java index e00af33..ff7cdbf 100755 --- a/java/src/game/network/PacketEncoder.java +++ b/java/src/common/network/PacketEncoder.java @@ -1,8 +1,8 @@ -package game.network; +package common.network; import java.io.IOException; -import game.log.Log; +import common.log.Log; import io.netty.buffer.ByteBuf; import io.netty.channel.ChannelHandlerContext; import io.netty.handler.codec.MessageToByteEncoder; diff --git a/java/src/game/network/PacketPrepender.java b/java/src/common/network/PacketPrepender.java similarity index 97% rename from java/src/game/network/PacketPrepender.java rename to java/src/common/network/PacketPrepender.java index 9dd9ab7..670f337 100755 --- a/java/src/game/network/PacketPrepender.java +++ b/java/src/common/network/PacketPrepender.java @@ -1,4 +1,4 @@ -package game.network; +package common.network; import io.netty.buffer.ByteBuf; import io.netty.channel.ChannelHandlerContext; diff --git a/java/src/game/network/PacketRegistry.java b/java/src/common/network/PacketRegistry.java similarity index 69% rename from java/src/game/network/PacketRegistry.java rename to java/src/common/network/PacketRegistry.java index 28ae74b..60f2e0d 100755 --- a/java/src/game/network/PacketRegistry.java +++ b/java/src/common/network/PacketRegistry.java @@ -1,89 +1,89 @@ -package game.network; +package common.network; import java.util.Map; -import game.collect.BiMap; -import game.collect.HashBiMap; -import game.collect.Maps; -import game.packet.CPacketAction; -import game.packet.CPacketBook; -import game.packet.CPacketBreak; -import game.packet.CPacketCheat; -import game.packet.CPacketClick; -import game.packet.CPacketComplete; -import game.packet.CPacketInput; -import game.packet.CPacketKeepAlive; -import game.packet.CPacketMessage; -import game.packet.CPacketPlace; -import game.packet.CPacketPlayer; -import game.packet.CPacketSign; -import game.packet.CPacketSkin; -import game.packet.HPacketHandshake; -import game.packet.LPacketPasswordResponse; -import game.packet.RPacketDisconnect; -import game.packet.RPacketEnableCompression; -import game.packet.RPacketLoginSuccess; -import game.packet.S14PacketEntity; -import game.packet.S18PacketEntityTeleport; -import game.packet.S19PacketEntityHeadLook; -import game.packet.S1APacketEntityStatus; -import game.packet.S1BPacketEntityAttach; -import game.packet.S1CPacketEntityMetadata; -import game.packet.S1DPacketEntityEffect; -import game.packet.S1EPacketRemoveEntityEffect; -import game.packet.S20PacketEntityProperties; -import game.packet.S27PacketExplosion; -import game.packet.S28PacketEffect; -import game.packet.S29PacketSoundEffect; -import game.packet.S2APacketParticles; -import game.packet.S2BPacketChangeGameState; -import game.packet.S2CPacketSpawnGlobalEntity; -import game.packet.S2DPacketOpenWindow; -import game.packet.S2EPacketCloseWindow; -import game.packet.S2FPacketSetSlot; -import game.packet.S30PacketWindowItems; -import game.packet.S31PacketWindowProperty; -import game.packet.S32PacketConfirmTransaction; -import game.packet.S33PacketUpdateSign; -import game.packet.S35PacketUpdateTileEntity; -import game.packet.S36PacketSignEditorOpen; -import game.packet.S38PacketPlayerListItem; -import game.packet.S39PacketPlayerAbilities; -import game.packet.S3APacketTabComplete; -import game.packet.S43PacketUpdateEntityNBT; -import game.packet.SPacketAnimation; -import game.packet.SPacketBiomes; -import game.packet.SPacketBlockAction; -import game.packet.SPacketBlockBreakAnim; -import game.packet.SPacketBlockChange; -import game.packet.SPacketCamera; -import game.packet.SPacketCharacterList; -import game.packet.SPacketChunkData; -import game.packet.SPacketCollectItem; -import game.packet.SPacketDestroyEntities; -import game.packet.SPacketDimensionName; -import game.packet.SPacketDisconnect; -import game.packet.SPacketEntityEquipment; -import game.packet.SPacketEntityVelocity; -import game.packet.SPacketHeldItemChange; -import game.packet.SPacketJoinGame; -import game.packet.SPacketKeepAlive; -import game.packet.SPacketLoading; -import game.packet.SPacketMapChunkBulk; -import game.packet.SPacketMessage; -import game.packet.SPacketMultiBlockChange; -import game.packet.SPacketPlayerPosLook; -import game.packet.SPacketRespawn; -import game.packet.SPacketServerTick; -import game.packet.SPacketSetExperience; -import game.packet.SPacketSkin; -import game.packet.SPacketSpawnMob; -import game.packet.SPacketSpawnObject; -import game.packet.SPacketSpawnPlayer; -import game.packet.SPacketTimeUpdate; -import game.packet.SPacketTrades; -import game.packet.SPacketUpdateHealth; -import game.packet.SPacketWorld; +import common.collect.BiMap; +import common.collect.HashBiMap; +import common.collect.Maps; +import common.packet.CPacketAction; +import common.packet.CPacketBook; +import common.packet.CPacketBreak; +import common.packet.CPacketCheat; +import common.packet.CPacketClick; +import common.packet.CPacketComplete; +import common.packet.CPacketInput; +import common.packet.CPacketKeepAlive; +import common.packet.CPacketMessage; +import common.packet.CPacketPlace; +import common.packet.CPacketPlayer; +import common.packet.CPacketSign; +import common.packet.CPacketSkin; +import common.packet.HPacketHandshake; +import common.packet.LPacketPasswordResponse; +import common.packet.RPacketDisconnect; +import common.packet.RPacketEnableCompression; +import common.packet.RPacketLoginSuccess; +import common.packet.S14PacketEntity; +import common.packet.S18PacketEntityTeleport; +import common.packet.S19PacketEntityHeadLook; +import common.packet.S1APacketEntityStatus; +import common.packet.S1BPacketEntityAttach; +import common.packet.S1CPacketEntityMetadata; +import common.packet.S1DPacketEntityEffect; +import common.packet.S1EPacketRemoveEntityEffect; +import common.packet.S20PacketEntityProperties; +import common.packet.S27PacketExplosion; +import common.packet.S28PacketEffect; +import common.packet.S29PacketSoundEffect; +import common.packet.S2APacketParticles; +import common.packet.S2BPacketChangeGameState; +import common.packet.S2CPacketSpawnGlobalEntity; +import common.packet.S2DPacketOpenWindow; +import common.packet.S2EPacketCloseWindow; +import common.packet.S2FPacketSetSlot; +import common.packet.S30PacketWindowItems; +import common.packet.S31PacketWindowProperty; +import common.packet.S32PacketConfirmTransaction; +import common.packet.S33PacketUpdateSign; +import common.packet.S35PacketUpdateTileEntity; +import common.packet.S36PacketSignEditorOpen; +import common.packet.S38PacketPlayerListItem; +import common.packet.S39PacketPlayerAbilities; +import common.packet.S3APacketTabComplete; +import common.packet.S43PacketUpdateEntityNBT; +import common.packet.SPacketAnimation; +import common.packet.SPacketBiomes; +import common.packet.SPacketBlockAction; +import common.packet.SPacketBlockBreakAnim; +import common.packet.SPacketBlockChange; +import common.packet.SPacketCamera; +import common.packet.SPacketCharacterList; +import common.packet.SPacketChunkData; +import common.packet.SPacketCollectItem; +import common.packet.SPacketDestroyEntities; +import common.packet.SPacketDimensionName; +import common.packet.SPacketDisconnect; +import common.packet.SPacketEntityEquipment; +import common.packet.SPacketEntityVelocity; +import common.packet.SPacketHeldItemChange; +import common.packet.SPacketJoinGame; +import common.packet.SPacketKeepAlive; +import common.packet.SPacketLoading; +import common.packet.SPacketMapChunkBulk; +import common.packet.SPacketMessage; +import common.packet.SPacketMultiBlockChange; +import common.packet.SPacketPlayerPosLook; +import common.packet.SPacketRespawn; +import common.packet.SPacketServerTick; +import common.packet.SPacketSetExperience; +import common.packet.SPacketSkin; +import common.packet.SPacketSpawnMob; +import common.packet.SPacketSpawnObject; +import common.packet.SPacketSpawnPlayer; +import common.packet.SPacketTimeUpdate; +import common.packet.SPacketTrades; +import common.packet.SPacketUpdateHealth; +import common.packet.SPacketWorld; public enum PacketRegistry { diff --git a/java/src/game/network/PacketSplitter.java b/java/src/common/network/PacketSplitter.java similarity index 98% rename from java/src/game/network/PacketSplitter.java rename to java/src/common/network/PacketSplitter.java index dec0660..7540257 100755 --- a/java/src/game/network/PacketSplitter.java +++ b/java/src/common/network/PacketSplitter.java @@ -1,4 +1,4 @@ -package game.network; +package common.network; import java.util.List; diff --git a/java/src/game/packet/APacketEmpty.java b/java/src/common/packet/APacketEmpty.java similarity index 73% rename from java/src/game/packet/APacketEmpty.java rename to java/src/common/packet/APacketEmpty.java index 8fede40..dfc7ceb 100755 --- a/java/src/game/packet/APacketEmpty.java +++ b/java/src/common/packet/APacketEmpty.java @@ -1,9 +1,9 @@ -package game.packet; +package common.packet; import java.io.IOException; -import game.network.Packet; -import game.network.PacketBuffer; +import common.network.Packet; +import common.network.PacketBuffer; public abstract class APacketEmpty implements Packet { public final void readPacketData(PacketBuffer buf) throws IOException { diff --git a/java/src/game/packet/APacketVarInt.java b/java/src/common/packet/APacketVarInt.java similarity index 84% rename from java/src/game/packet/APacketVarInt.java rename to java/src/common/packet/APacketVarInt.java index 87d9b79..e3196af 100755 --- a/java/src/game/packet/APacketVarInt.java +++ b/java/src/common/packet/APacketVarInt.java @@ -1,9 +1,9 @@ -package game.packet; +package common.packet; import java.io.IOException; -import game.network.Packet; -import game.network.PacketBuffer; +import common.network.Packet; +import common.network.PacketBuffer; public abstract class APacketVarInt implements Packet { private int value; diff --git a/java/src/game/packet/CPacketAction.java b/java/src/common/packet/CPacketAction.java similarity index 94% rename from java/src/game/packet/CPacketAction.java rename to java/src/common/packet/CPacketAction.java index 34b6229..1df60fb 100755 --- a/java/src/game/packet/CPacketAction.java +++ b/java/src/common/packet/CPacketAction.java @@ -1,10 +1,10 @@ -package game.packet; +package common.packet; import java.io.IOException; -import game.network.Packet; -import game.network.PacketBuffer; -import game.network.IPlayer; +import common.network.IPlayer; +import common.network.Packet; +import common.network.PacketBuffer; public class CPacketAction implements Packet { diff --git a/java/src/game/packet/CPacketBook.java b/java/src/common/packet/CPacketBook.java similarity index 89% rename from java/src/game/packet/CPacketBook.java rename to java/src/common/packet/CPacketBook.java index 1bd02f4..771fa06 100755 --- a/java/src/game/packet/CPacketBook.java +++ b/java/src/common/packet/CPacketBook.java @@ -1,10 +1,10 @@ -package game.packet; +package common.packet; import java.io.IOException; -import game.network.Packet; -import game.network.PacketBuffer; -import game.network.IPlayer; +import common.network.IPlayer; +import common.network.Packet; +import common.network.PacketBuffer; public class CPacketBook implements Packet { diff --git a/java/src/game/packet/CPacketBreak.java b/java/src/common/packet/CPacketBreak.java similarity index 89% rename from java/src/game/packet/CPacketBreak.java rename to java/src/common/packet/CPacketBreak.java index bb4b869..1de2c0b 100755 --- a/java/src/game/packet/CPacketBreak.java +++ b/java/src/common/packet/CPacketBreak.java @@ -1,12 +1,12 @@ -package game.packet; +package common.packet; import java.io.IOException; -import game.network.Packet; -import game.network.PacketBuffer; -import game.network.IPlayer; -import game.world.BlockPos; -import game.world.Facing; +import common.network.IPlayer; +import common.network.Packet; +import common.network.PacketBuffer; +import common.world.BlockPos; +import common.world.Facing; public class CPacketBreak implements Packet { diff --git a/java/src/game/packet/CPacketCheat.java b/java/src/common/packet/CPacketCheat.java similarity index 86% rename from java/src/game/packet/CPacketCheat.java rename to java/src/common/packet/CPacketCheat.java index 3ce4a6e..f2b0715 100755 --- a/java/src/game/packet/CPacketCheat.java +++ b/java/src/common/packet/CPacketCheat.java @@ -1,11 +1,11 @@ -package game.packet; +package common.packet; import java.io.IOException; -import game.item.ItemStack; -import game.network.Packet; -import game.network.PacketBuffer; -import game.network.IPlayer; +import common.item.ItemStack; +import common.network.IPlayer; +import common.network.Packet; +import common.network.PacketBuffer; public class CPacketCheat implements Packet { diff --git a/java/src/game/packet/CPacketClick.java b/java/src/common/packet/CPacketClick.java similarity index 93% rename from java/src/game/packet/CPacketClick.java rename to java/src/common/packet/CPacketClick.java index 8d03eb6..cb4e282 100755 --- a/java/src/game/packet/CPacketClick.java +++ b/java/src/common/packet/CPacketClick.java @@ -1,11 +1,11 @@ -package game.packet; +package common.packet; import java.io.IOException; -import game.item.ItemStack; -import game.network.Packet; -import game.network.PacketBuffer; -import game.network.IPlayer; +import common.item.ItemStack; +import common.network.IPlayer; +import common.network.Packet; +import common.network.PacketBuffer; public class CPacketClick implements Packet { diff --git a/java/src/game/packet/CPacketComplete.java b/java/src/common/packet/CPacketComplete.java similarity index 89% rename from java/src/game/packet/CPacketComplete.java rename to java/src/common/packet/CPacketComplete.java index f4bcd82..74190cc 100755 --- a/java/src/game/packet/CPacketComplete.java +++ b/java/src/common/packet/CPacketComplete.java @@ -1,11 +1,11 @@ -package game.packet; +package common.packet; import java.io.IOException; -import game.network.Packet; -import game.network.PacketBuffer; -import game.network.IPlayer; -import game.world.BlockPos; +import common.network.IPlayer; +import common.network.Packet; +import common.network.PacketBuffer; +import common.world.BlockPos; public class CPacketComplete implements Packet { diff --git a/java/src/game/packet/CPacketInput.java b/java/src/common/packet/CPacketInput.java similarity index 92% rename from java/src/game/packet/CPacketInput.java rename to java/src/common/packet/CPacketInput.java index 5618427..1bc90df 100755 --- a/java/src/game/packet/CPacketInput.java +++ b/java/src/common/packet/CPacketInput.java @@ -1,10 +1,10 @@ -package game.packet; +package common.packet; import java.io.IOException; -import game.network.Packet; -import game.network.PacketBuffer; -import game.network.IPlayer; +import common.network.IPlayer; +import common.network.Packet; +import common.network.PacketBuffer; public class CPacketInput implements Packet { diff --git a/java/src/game/packet/CPacketKeepAlive.java b/java/src/common/packet/CPacketKeepAlive.java similarity index 83% rename from java/src/game/packet/CPacketKeepAlive.java rename to java/src/common/packet/CPacketKeepAlive.java index 6cbf08d..6e6a9ad 100755 --- a/java/src/game/packet/CPacketKeepAlive.java +++ b/java/src/common/packet/CPacketKeepAlive.java @@ -1,6 +1,6 @@ -package game.packet; +package common.packet; -import game.network.IPlayer; +import common.network.IPlayer; public class CPacketKeepAlive extends APacketVarInt { diff --git a/java/src/game/packet/CPacketMessage.java b/java/src/common/packet/CPacketMessage.java similarity index 91% rename from java/src/game/packet/CPacketMessage.java rename to java/src/common/packet/CPacketMessage.java index 427b22e..c7141ea 100755 --- a/java/src/game/packet/CPacketMessage.java +++ b/java/src/common/packet/CPacketMessage.java @@ -1,10 +1,10 @@ -package game.packet; +package common.packet; import java.io.IOException; -import game.network.Packet; -import game.network.PacketBuffer; -import game.network.IPlayer; +import common.network.IPlayer; +import common.network.Packet; +import common.network.PacketBuffer; public class CPacketMessage implements Packet { diff --git a/java/src/game/packet/CPacketPlace.java b/java/src/common/packet/CPacketPlace.java similarity index 92% rename from java/src/game/packet/CPacketPlace.java rename to java/src/common/packet/CPacketPlace.java index 8dd4e11..9c91b4b 100755 --- a/java/src/game/packet/CPacketPlace.java +++ b/java/src/common/packet/CPacketPlace.java @@ -1,12 +1,12 @@ -package game.packet; +package common.packet; import java.io.IOException; -import game.item.ItemStack; -import game.network.Packet; -import game.network.PacketBuffer; -import game.network.IPlayer; -import game.world.BlockPos; +import common.item.ItemStack; +import common.network.IPlayer; +import common.network.Packet; +import common.network.PacketBuffer; +import common.world.BlockPos; public class CPacketPlace implements Packet { diff --git a/java/src/game/packet/CPacketPlayer.java b/java/src/common/packet/CPacketPlayer.java similarity index 97% rename from java/src/game/packet/CPacketPlayer.java rename to java/src/common/packet/CPacketPlayer.java index 6298845..58c70e7 100755 --- a/java/src/game/packet/CPacketPlayer.java +++ b/java/src/common/packet/CPacketPlayer.java @@ -1,10 +1,10 @@ -package game.packet; +package common.packet; import java.io.IOException; -import game.network.Packet; -import game.network.PacketBuffer; -import game.network.IPlayer; +import common.network.IPlayer; +import common.network.Packet; +import common.network.PacketBuffer; public class CPacketPlayer implements Packet { diff --git a/java/src/game/packet/CPacketSign.java b/java/src/common/packet/CPacketSign.java similarity index 90% rename from java/src/game/packet/CPacketSign.java rename to java/src/common/packet/CPacketSign.java index dd60ed6..3158172 100755 --- a/java/src/game/packet/CPacketSign.java +++ b/java/src/common/packet/CPacketSign.java @@ -1,11 +1,11 @@ -package game.packet; +package common.packet; import java.io.IOException; -import game.network.Packet; -import game.network.PacketBuffer; -import game.network.IPlayer; -import game.world.BlockPos; +import common.network.IPlayer; +import common.network.Packet; +import common.network.PacketBuffer; +import common.world.BlockPos; public class CPacketSign implements Packet { diff --git a/java/src/game/packet/CPacketSkin.java b/java/src/common/packet/CPacketSkin.java similarity index 90% rename from java/src/game/packet/CPacketSkin.java rename to java/src/common/packet/CPacketSkin.java index 180c49b..30e476c 100755 --- a/java/src/game/packet/CPacketSkin.java +++ b/java/src/common/packet/CPacketSkin.java @@ -1,10 +1,10 @@ -package game.packet; +package common.packet; import java.io.IOException; -import game.network.Packet; -import game.network.PacketBuffer; -import game.network.IPlayer; +import common.network.IPlayer; +import common.network.Packet; +import common.network.PacketBuffer; public class CPacketSkin implements Packet { private byte[] texture; diff --git a/java/src/game/packet/HPacketHandshake.java b/java/src/common/packet/HPacketHandshake.java similarity index 85% rename from java/src/game/packet/HPacketHandshake.java rename to java/src/common/packet/HPacketHandshake.java index 36a3994..e2a0018 100755 --- a/java/src/game/packet/HPacketHandshake.java +++ b/java/src/common/packet/HPacketHandshake.java @@ -1,10 +1,10 @@ -package game.packet; +package common.packet; import java.io.IOException; -import game.network.IHandshakeHandler; -import game.network.Packet; -import game.network.PacketBuffer; +import common.network.IHandshakeHandler; +import common.network.Packet; +import common.network.PacketBuffer; public class HPacketHandshake implements Packet { private int protocol; diff --git a/java/src/game/packet/LPacketPasswordResponse.java b/java/src/common/packet/LPacketPasswordResponse.java similarity index 90% rename from java/src/game/packet/LPacketPasswordResponse.java rename to java/src/common/packet/LPacketPasswordResponse.java index f2735b4..073009c 100755 --- a/java/src/game/packet/LPacketPasswordResponse.java +++ b/java/src/common/packet/LPacketPasswordResponse.java @@ -1,11 +1,11 @@ -package game.packet; +package common.packet; import java.io.IOException; -import game.network.IPlayer; -import game.network.ILoginHandler; -import game.network.Packet; -import game.network.PacketBuffer; +import common.network.ILoginHandler; +import common.network.IPlayer; +import common.network.Packet; +import common.network.PacketBuffer; public class LPacketPasswordResponse implements Packet { diff --git a/java/src/game/packet/RPacketDisconnect.java b/java/src/common/packet/RPacketDisconnect.java similarity index 87% rename from java/src/game/packet/RPacketDisconnect.java rename to java/src/common/packet/RPacketDisconnect.java index a81019b..3e1c8cb 100755 --- a/java/src/game/packet/RPacketDisconnect.java +++ b/java/src/common/packet/RPacketDisconnect.java @@ -1,10 +1,10 @@ -package game.packet; +package common.packet; import java.io.IOException; -import game.network.IClientLoginHandler; -import game.network.Packet; -import game.network.PacketBuffer; +import common.network.IClientLoginHandler; +import common.network.Packet; +import common.network.PacketBuffer; public class RPacketDisconnect implements Packet { diff --git a/java/src/game/packet/RPacketEnableCompression.java b/java/src/common/packet/RPacketEnableCompression.java similarity index 83% rename from java/src/game/packet/RPacketEnableCompression.java rename to java/src/common/packet/RPacketEnableCompression.java index 4fed689..8aceabb 100755 --- a/java/src/game/packet/RPacketEnableCompression.java +++ b/java/src/common/packet/RPacketEnableCompression.java @@ -1,6 +1,6 @@ -package game.packet; +package common.packet; -import game.network.IClientLoginHandler; +import common.network.IClientLoginHandler; public class RPacketEnableCompression extends APacketVarInt { diff --git a/java/src/game/packet/RPacketLoginSuccess.java b/java/src/common/packet/RPacketLoginSuccess.java similarity index 74% rename from java/src/game/packet/RPacketLoginSuccess.java rename to java/src/common/packet/RPacketLoginSuccess.java index 4bff216..6e46fa0 100755 --- a/java/src/game/packet/RPacketLoginSuccess.java +++ b/java/src/common/packet/RPacketLoginSuccess.java @@ -1,6 +1,6 @@ -package game.packet; +package common.packet; -import game.network.IClientLoginHandler; +import common.network.IClientLoginHandler; public class RPacketLoginSuccess extends APacketEmpty { diff --git a/java/src/game/packet/S14PacketEntity.java b/java/src/common/packet/S14PacketEntity.java similarity index 96% rename from java/src/game/packet/S14PacketEntity.java rename to java/src/common/packet/S14PacketEntity.java index e720185..68507af 100755 --- a/java/src/game/packet/S14PacketEntity.java +++ b/java/src/common/packet/S14PacketEntity.java @@ -1,12 +1,12 @@ -package game.packet; +package common.packet; import java.io.IOException; -import game.entity.Entity; -import game.network.IClientPlayer; -import game.network.Packet; -import game.network.PacketBuffer; -import game.world.World; +import common.entity.Entity; +import common.network.IClientPlayer; +import common.network.Packet; +import common.network.PacketBuffer; +import common.world.World; public class S14PacketEntity implements Packet { diff --git a/java/src/game/packet/S18PacketEntityTeleport.java b/java/src/common/packet/S18PacketEntityTeleport.java similarity index 93% rename from java/src/game/packet/S18PacketEntityTeleport.java rename to java/src/common/packet/S18PacketEntityTeleport.java index 955fd66..67f4118 100755 --- a/java/src/game/packet/S18PacketEntityTeleport.java +++ b/java/src/common/packet/S18PacketEntityTeleport.java @@ -1,12 +1,12 @@ -package game.packet; +package common.packet; import java.io.IOException; -import game.entity.Entity; -import game.network.IClientPlayer; -import game.network.Packet; -import game.network.PacketBuffer; -import game.util.ExtMath; +import common.entity.Entity; +import common.network.IClientPlayer; +import common.network.Packet; +import common.network.PacketBuffer; +import common.util.ExtMath; public class S18PacketEntityTeleport implements Packet { diff --git a/java/src/game/packet/S19PacketEntityHeadLook.java b/java/src/common/packet/S19PacketEntityHeadLook.java similarity index 86% rename from java/src/game/packet/S19PacketEntityHeadLook.java rename to java/src/common/packet/S19PacketEntityHeadLook.java index 97f4853..885659e 100755 --- a/java/src/game/packet/S19PacketEntityHeadLook.java +++ b/java/src/common/packet/S19PacketEntityHeadLook.java @@ -1,12 +1,12 @@ -package game.packet; +package common.packet; import java.io.IOException; -import game.entity.Entity; -import game.network.IClientPlayer; -import game.network.Packet; -import game.network.PacketBuffer; -import game.world.World; +import common.entity.Entity; +import common.network.IClientPlayer; +import common.network.Packet; +import common.network.PacketBuffer; +import common.world.World; public class S19PacketEntityHeadLook implements Packet { diff --git a/java/src/game/packet/S1APacketEntityStatus.java b/java/src/common/packet/S1APacketEntityStatus.java similarity index 86% rename from java/src/game/packet/S1APacketEntityStatus.java rename to java/src/common/packet/S1APacketEntityStatus.java index 4fd3017..1775cec 100755 --- a/java/src/game/packet/S1APacketEntityStatus.java +++ b/java/src/common/packet/S1APacketEntityStatus.java @@ -1,12 +1,12 @@ -package game.packet; +package common.packet; import java.io.IOException; -import game.entity.Entity; -import game.network.IClientPlayer; -import game.network.Packet; -import game.network.PacketBuffer; -import game.world.World; +import common.entity.Entity; +import common.network.IClientPlayer; +import common.network.Packet; +import common.network.PacketBuffer; +import common.world.World; public class S1APacketEntityStatus implements Packet { diff --git a/java/src/game/packet/S1BPacketEntityAttach.java b/java/src/common/packet/S1BPacketEntityAttach.java similarity index 90% rename from java/src/game/packet/S1BPacketEntityAttach.java rename to java/src/common/packet/S1BPacketEntityAttach.java index a0e6c6b..24c0807 100755 --- a/java/src/game/packet/S1BPacketEntityAttach.java +++ b/java/src/common/packet/S1BPacketEntityAttach.java @@ -1,11 +1,11 @@ -package game.packet; +package common.packet; import java.io.IOException; -import game.entity.Entity; -import game.network.IClientPlayer; -import game.network.Packet; -import game.network.PacketBuffer; +import common.entity.Entity; +import common.network.IClientPlayer; +import common.network.Packet; +import common.network.PacketBuffer; public class S1BPacketEntityAttach implements Packet { diff --git a/java/src/game/packet/S1CPacketEntityMetadata.java b/java/src/common/packet/S1CPacketEntityMetadata.java similarity index 90% rename from java/src/game/packet/S1CPacketEntityMetadata.java rename to java/src/common/packet/S1CPacketEntityMetadata.java index 3eda517..645e1a2 100755 --- a/java/src/game/packet/S1CPacketEntityMetadata.java +++ b/java/src/common/packet/S1CPacketEntityMetadata.java @@ -1,12 +1,12 @@ -package game.packet; +package common.packet; import java.io.IOException; import java.util.List; -import game.entity.DataWatcher; -import game.network.IClientPlayer; -import game.network.Packet; -import game.network.PacketBuffer; +import common.entity.DataWatcher; +import common.network.IClientPlayer; +import common.network.Packet; +import common.network.PacketBuffer; public class S1CPacketEntityMetadata implements Packet { diff --git a/java/src/game/packet/S1DPacketEntityEffect.java b/java/src/common/packet/S1DPacketEntityEffect.java similarity index 92% rename from java/src/game/packet/S1DPacketEntityEffect.java rename to java/src/common/packet/S1DPacketEntityEffect.java index 661aa94..faf5dc6 100755 --- a/java/src/game/packet/S1DPacketEntityEffect.java +++ b/java/src/common/packet/S1DPacketEntityEffect.java @@ -1,12 +1,12 @@ -package game.packet; +package common.packet; import java.io.IOException; -import game.network.IClientPlayer; -import game.network.Packet; -import game.network.PacketBuffer; -import game.potion.Potion; -import game.potion.PotionEffect; +import common.network.IClientPlayer; +import common.network.Packet; +import common.network.PacketBuffer; +import common.potion.Potion; +import common.potion.PotionEffect; public class S1DPacketEntityEffect implements Packet { diff --git a/java/src/game/packet/S1EPacketRemoveEntityEffect.java b/java/src/common/packet/S1EPacketRemoveEntityEffect.java similarity index 86% rename from java/src/game/packet/S1EPacketRemoveEntityEffect.java rename to java/src/common/packet/S1EPacketRemoveEntityEffect.java index a7872cf..9cd091e 100755 --- a/java/src/game/packet/S1EPacketRemoveEntityEffect.java +++ b/java/src/common/packet/S1EPacketRemoveEntityEffect.java @@ -1,12 +1,12 @@ -package game.packet; +package common.packet; import java.io.IOException; -import game.network.IClientPlayer; -import game.network.Packet; -import game.network.PacketBuffer; -import game.potion.Potion; -import game.potion.PotionEffect; +import common.network.IClientPlayer; +import common.network.Packet; +import common.network.PacketBuffer; +import common.potion.Potion; +import common.potion.PotionEffect; public class S1EPacketRemoveEntityEffect implements Packet { diff --git a/java/src/game/packet/S20PacketEntityProperties.java b/java/src/common/packet/S20PacketEntityProperties.java similarity index 93% rename from java/src/game/packet/S20PacketEntityProperties.java rename to java/src/common/packet/S20PacketEntityProperties.java index 6fa51f3..0d0a1f0 100755 --- a/java/src/game/packet/S20PacketEntityProperties.java +++ b/java/src/common/packet/S20PacketEntityProperties.java @@ -1,15 +1,15 @@ -package game.packet; +package common.packet; import java.io.IOException; import java.util.Collection; import java.util.List; -import game.collect.Lists; -import game.entity.attributes.AttributeInstance; -import game.entity.attributes.AttributeModifier; -import game.network.IClientPlayer; -import game.network.Packet; -import game.network.PacketBuffer; +import common.collect.Lists; +import common.entity.attributes.AttributeInstance; +import common.entity.attributes.AttributeModifier; +import common.network.IClientPlayer; +import common.network.Packet; +import common.network.PacketBuffer; public class S20PacketEntityProperties implements Packet { diff --git a/java/src/game/packet/S27PacketExplosion.java b/java/src/common/packet/S27PacketExplosion.java similarity index 94% rename from java/src/game/packet/S27PacketExplosion.java rename to java/src/common/packet/S27PacketExplosion.java index 24aa5ee..4d76e68 100755 --- a/java/src/game/packet/S27PacketExplosion.java +++ b/java/src/common/packet/S27PacketExplosion.java @@ -1,15 +1,15 @@ -package game.packet; +package common.packet; import java.io.IOException; import java.util.ArrayList; import java.util.List; -import game.collect.Lists; -import game.network.IClientPlayer; -import game.network.Packet; -import game.network.PacketBuffer; -import game.world.BlockPos; -import game.world.Vec3; +import common.collect.Lists; +import common.network.IClientPlayer; +import common.network.Packet; +import common.network.PacketBuffer; +import common.world.BlockPos; +import common.world.Vec3; public class S27PacketExplosion implements Packet { diff --git a/java/src/game/packet/S28PacketEffect.java b/java/src/common/packet/S28PacketEffect.java similarity index 86% rename from java/src/game/packet/S28PacketEffect.java rename to java/src/common/packet/S28PacketEffect.java index a64be06..6e9915f 100755 --- a/java/src/game/packet/S28PacketEffect.java +++ b/java/src/common/packet/S28PacketEffect.java @@ -1,11 +1,11 @@ -package game.packet; +package common.packet; import java.io.IOException; -import game.network.IClientPlayer; -import game.network.Packet; -import game.network.PacketBuffer; -import game.world.BlockPos; +import common.network.IClientPlayer; +import common.network.Packet; +import common.network.PacketBuffer; +import common.world.BlockPos; public class S28PacketEffect implements Packet { private int soundType; diff --git a/java/src/game/packet/S29PacketSoundEffect.java b/java/src/common/packet/S29PacketSoundEffect.java similarity index 92% rename from java/src/game/packet/S29PacketSoundEffect.java rename to java/src/common/packet/S29PacketSoundEffect.java index e0581b6..c39ca1a 100755 --- a/java/src/game/packet/S29PacketSoundEffect.java +++ b/java/src/common/packet/S29PacketSoundEffect.java @@ -1,11 +1,11 @@ -package game.packet; +package common.packet; import java.io.IOException; -import game.init.SoundEvent; -import game.network.IClientPlayer; -import game.network.Packet; -import game.network.PacketBuffer; +import common.init.SoundEvent; +import common.network.IClientPlayer; +import common.network.Packet; +import common.network.PacketBuffer; public class S29PacketSoundEffect implements Packet { diff --git a/java/src/game/packet/S2APacketParticles.java b/java/src/common/packet/S2APacketParticles.java similarity index 96% rename from java/src/game/packet/S2APacketParticles.java rename to java/src/common/packet/S2APacketParticles.java index 198ecf8..0d6329c 100755 --- a/java/src/game/packet/S2APacketParticles.java +++ b/java/src/common/packet/S2APacketParticles.java @@ -1,11 +1,11 @@ -package game.packet; +package common.packet; import java.io.IOException; -import game.model.ParticleType; -import game.network.IClientPlayer; -import game.network.Packet; -import game.network.PacketBuffer; +import common.model.ParticleType; +import common.network.IClientPlayer; +import common.network.Packet; +import common.network.PacketBuffer; public class S2APacketParticles implements Packet { diff --git a/java/src/game/packet/S2BPacketChangeGameState.java b/java/src/common/packet/S2BPacketChangeGameState.java similarity index 90% rename from java/src/game/packet/S2BPacketChangeGameState.java rename to java/src/common/packet/S2BPacketChangeGameState.java index 4c9272c..488573a 100755 --- a/java/src/game/packet/S2BPacketChangeGameState.java +++ b/java/src/common/packet/S2BPacketChangeGameState.java @@ -1,11 +1,11 @@ -package game.packet; +package common.packet; import java.io.IOException; -import game.network.IClientPlayer; -import game.network.Packet; -import game.network.PacketBuffer; -import game.util.ExtMath; +import common.network.IClientPlayer; +import common.network.Packet; +import common.network.PacketBuffer; +import common.util.ExtMath; public class S2BPacketChangeGameState implements Packet { diff --git a/java/src/game/packet/S2CPacketSpawnGlobalEntity.java b/java/src/common/packet/S2CPacketSpawnGlobalEntity.java similarity index 91% rename from java/src/game/packet/S2CPacketSpawnGlobalEntity.java rename to java/src/common/packet/S2CPacketSpawnGlobalEntity.java index df86f15..4741c44 100755 --- a/java/src/game/packet/S2CPacketSpawnGlobalEntity.java +++ b/java/src/common/packet/S2CPacketSpawnGlobalEntity.java @@ -1,12 +1,12 @@ -package game.packet; +package common.packet; import java.io.IOException; -import game.entity.Entity; -import game.network.IClientPlayer; -import game.network.Packet; -import game.network.PacketBuffer; -import game.util.ExtMath; +import common.entity.Entity; +import common.network.IClientPlayer; +import common.network.Packet; +import common.network.PacketBuffer; +import common.util.ExtMath; public class S2CPacketSpawnGlobalEntity implements Packet { diff --git a/java/src/game/packet/S2DPacketOpenWindow.java b/java/src/common/packet/S2DPacketOpenWindow.java similarity index 95% rename from java/src/game/packet/S2DPacketOpenWindow.java rename to java/src/common/packet/S2DPacketOpenWindow.java index c1f7c70..38246fe 100755 --- a/java/src/game/packet/S2DPacketOpenWindow.java +++ b/java/src/common/packet/S2DPacketOpenWindow.java @@ -1,11 +1,11 @@ -package game.packet; +package common.packet; import java.io.IOException; -import game.network.IClientPlayer; -import game.network.Packet; -import game.network.PacketBuffer; -import game.world.BlockPos; +import common.network.IClientPlayer; +import common.network.Packet; +import common.network.PacketBuffer; +import common.world.BlockPos; public class S2DPacketOpenWindow implements Packet { diff --git a/java/src/game/packet/S2EPacketCloseWindow.java b/java/src/common/packet/S2EPacketCloseWindow.java similarity index 87% rename from java/src/game/packet/S2EPacketCloseWindow.java rename to java/src/common/packet/S2EPacketCloseWindow.java index a6652cc..7629715 100755 --- a/java/src/game/packet/S2EPacketCloseWindow.java +++ b/java/src/common/packet/S2EPacketCloseWindow.java @@ -1,10 +1,10 @@ -package game.packet; +package common.packet; import java.io.IOException; -import game.network.IClientPlayer; -import game.network.Packet; -import game.network.PacketBuffer; +import common.network.IClientPlayer; +import common.network.Packet; +import common.network.PacketBuffer; public class S2EPacketCloseWindow implements Packet { diff --git a/java/src/game/packet/S2FPacketSetSlot.java b/java/src/common/packet/S2FPacketSetSlot.java similarity index 89% rename from java/src/game/packet/S2FPacketSetSlot.java rename to java/src/common/packet/S2FPacketSetSlot.java index 6b307f1..def36be 100755 --- a/java/src/game/packet/S2FPacketSetSlot.java +++ b/java/src/common/packet/S2FPacketSetSlot.java @@ -1,11 +1,11 @@ -package game.packet; +package common.packet; import java.io.IOException; -import game.item.ItemStack; -import game.network.IClientPlayer; -import game.network.Packet; -import game.network.PacketBuffer; +import common.item.ItemStack; +import common.network.IClientPlayer; +import common.network.Packet; +import common.network.PacketBuffer; public class S2FPacketSetSlot implements Packet { diff --git a/java/src/game/packet/S30PacketWindowItems.java b/java/src/common/packet/S30PacketWindowItems.java similarity index 91% rename from java/src/game/packet/S30PacketWindowItems.java rename to java/src/common/packet/S30PacketWindowItems.java index a7dc2c1..c3e37f3 100755 --- a/java/src/game/packet/S30PacketWindowItems.java +++ b/java/src/common/packet/S30PacketWindowItems.java @@ -1,12 +1,12 @@ -package game.packet; +package common.packet; import java.io.IOException; import java.util.List; -import game.item.ItemStack; -import game.network.IClientPlayer; -import game.network.Packet; -import game.network.PacketBuffer; +import common.item.ItemStack; +import common.network.IClientPlayer; +import common.network.Packet; +import common.network.PacketBuffer; public class S30PacketWindowItems implements Packet { diff --git a/java/src/game/packet/S31PacketWindowProperty.java b/java/src/common/packet/S31PacketWindowProperty.java similarity index 91% rename from java/src/game/packet/S31PacketWindowProperty.java rename to java/src/common/packet/S31PacketWindowProperty.java index 50b5ed1..e8b02ff 100755 --- a/java/src/game/packet/S31PacketWindowProperty.java +++ b/java/src/common/packet/S31PacketWindowProperty.java @@ -1,10 +1,10 @@ -package game.packet; +package common.packet; import java.io.IOException; -import game.network.IClientPlayer; -import game.network.Packet; -import game.network.PacketBuffer; +import common.network.IClientPlayer; +import common.network.Packet; +import common.network.PacketBuffer; public class S31PacketWindowProperty implements Packet { diff --git a/java/src/game/packet/S32PacketConfirmTransaction.java b/java/src/common/packet/S32PacketConfirmTransaction.java similarity index 92% rename from java/src/game/packet/S32PacketConfirmTransaction.java rename to java/src/common/packet/S32PacketConfirmTransaction.java index f323a67..2bf7c0f 100755 --- a/java/src/game/packet/S32PacketConfirmTransaction.java +++ b/java/src/common/packet/S32PacketConfirmTransaction.java @@ -1,10 +1,10 @@ -package game.packet; +package common.packet; import java.io.IOException; -import game.network.IClientPlayer; -import game.network.Packet; -import game.network.PacketBuffer; +import common.network.IClientPlayer; +import common.network.Packet; +import common.network.PacketBuffer; public class S32PacketConfirmTransaction implements Packet { diff --git a/java/src/game/packet/S33PacketUpdateSign.java b/java/src/common/packet/S33PacketUpdateSign.java similarity index 91% rename from java/src/game/packet/S33PacketUpdateSign.java rename to java/src/common/packet/S33PacketUpdateSign.java index 798140b..dc8b266 100755 --- a/java/src/game/packet/S33PacketUpdateSign.java +++ b/java/src/common/packet/S33PacketUpdateSign.java @@ -1,12 +1,12 @@ -package game.packet; +package common.packet; import java.io.IOException; -import game.network.IClientPlayer; -import game.network.Packet; -import game.network.PacketBuffer; -import game.world.BlockPos; -import game.world.World; +import common.network.IClientPlayer; +import common.network.Packet; +import common.network.PacketBuffer; +import common.world.BlockPos; +import common.world.World; public class S33PacketUpdateSign implements Packet { diff --git a/java/src/game/packet/S35PacketUpdateTileEntity.java b/java/src/common/packet/S35PacketUpdateTileEntity.java similarity index 85% rename from java/src/game/packet/S35PacketUpdateTileEntity.java rename to java/src/common/packet/S35PacketUpdateTileEntity.java index eb8e079..7c0aa3d 100755 --- a/java/src/game/packet/S35PacketUpdateTileEntity.java +++ b/java/src/common/packet/S35PacketUpdateTileEntity.java @@ -1,14 +1,14 @@ -package game.packet; +package common.packet; import java.io.IOException; -import game.init.TileRegistry; -import game.nbt.NBTTagCompound; -import game.network.IClientPlayer; -import game.network.Packet; -import game.network.PacketBuffer; -import game.tileentity.TileEntity; -import game.world.BlockPos; +import common.init.TileRegistry; +import common.nbt.NBTTagCompound; +import common.network.IClientPlayer; +import common.network.Packet; +import common.network.PacketBuffer; +import common.tileentity.TileEntity; +import common.world.BlockPos; public class S35PacketUpdateTileEntity implements Packet { diff --git a/java/src/game/packet/S36PacketSignEditorOpen.java b/java/src/common/packet/S36PacketSignEditorOpen.java similarity index 86% rename from java/src/game/packet/S36PacketSignEditorOpen.java rename to java/src/common/packet/S36PacketSignEditorOpen.java index 6d5b2d4..29d3f03 100755 --- a/java/src/game/packet/S36PacketSignEditorOpen.java +++ b/java/src/common/packet/S36PacketSignEditorOpen.java @@ -1,11 +1,11 @@ -package game.packet; +package common.packet; import java.io.IOException; -import game.network.IClientPlayer; -import game.network.Packet; -import game.network.PacketBuffer; -import game.world.BlockPos; +import common.network.IClientPlayer; +import common.network.Packet; +import common.network.PacketBuffer; +import common.world.BlockPos; public class S36PacketSignEditorOpen implements Packet { diff --git a/java/src/game/packet/S38PacketPlayerListItem.java b/java/src/common/packet/S38PacketPlayerListItem.java similarity index 87% rename from java/src/game/packet/S38PacketPlayerListItem.java rename to java/src/common/packet/S38PacketPlayerListItem.java index afcde9f..f83caa5 100755 --- a/java/src/game/packet/S38PacketPlayerListItem.java +++ b/java/src/common/packet/S38PacketPlayerListItem.java @@ -1,15 +1,15 @@ -package game.packet; +package common.packet; import java.io.IOException; import java.util.Collection; import java.util.Map; import java.util.Map.Entry; -import game.collect.Maps; -import game.network.IClientPlayer; -import game.network.Packet; -import game.network.PacketBuffer; -import game.network.IPlayer; +import common.collect.Maps; +import common.network.IClientPlayer; +import common.network.IPlayer; +import common.network.Packet; +import common.network.PacketBuffer; public class S38PacketPlayerListItem implements Packet { private final Map players = Maps.newHashMap(); diff --git a/java/src/game/packet/S39PacketPlayerAbilities.java b/java/src/common/packet/S39PacketPlayerAbilities.java similarity index 84% rename from java/src/game/packet/S39PacketPlayerAbilities.java rename to java/src/common/packet/S39PacketPlayerAbilities.java index 740aa08..24f0537 100755 --- a/java/src/game/packet/S39PacketPlayerAbilities.java +++ b/java/src/common/packet/S39PacketPlayerAbilities.java @@ -1,11 +1,11 @@ -package game.packet; +package common.packet; import java.io.IOException; -import game.entity.npc.EntityNPC; -import game.network.IClientPlayer; -import game.network.Packet; -import game.network.PacketBuffer; +import common.entity.npc.EntityNPC; +import common.network.IClientPlayer; +import common.network.Packet; +import common.network.PacketBuffer; public class S39PacketPlayerAbilities implements Packet { private boolean flying; diff --git a/java/src/game/packet/S3APacketTabComplete.java b/java/src/common/packet/S3APacketTabComplete.java similarity index 90% rename from java/src/game/packet/S3APacketTabComplete.java rename to java/src/common/packet/S3APacketTabComplete.java index 680df6a..76beea3 100755 --- a/java/src/game/packet/S3APacketTabComplete.java +++ b/java/src/common/packet/S3APacketTabComplete.java @@ -1,10 +1,10 @@ -package game.packet; +package common.packet; import java.io.IOException; -import game.network.IClientPlayer; -import game.network.Packet; -import game.network.PacketBuffer; +import common.network.IClientPlayer; +import common.network.Packet; +import common.network.PacketBuffer; public class S3APacketTabComplete implements Packet { diff --git a/java/src/game/packet/S43PacketUpdateEntityNBT.java b/java/src/common/packet/S43PacketUpdateEntityNBT.java similarity index 85% rename from java/src/game/packet/S43PacketUpdateEntityNBT.java rename to java/src/common/packet/S43PacketUpdateEntityNBT.java index 1982acc..ad56eac 100755 --- a/java/src/game/packet/S43PacketUpdateEntityNBT.java +++ b/java/src/common/packet/S43PacketUpdateEntityNBT.java @@ -1,13 +1,13 @@ -package game.packet; +package common.packet; import java.io.IOException; -import game.entity.Entity; -import game.nbt.NBTTagCompound; -import game.network.IClientPlayer; -import game.network.Packet; -import game.network.PacketBuffer; -import game.world.World; +import common.entity.Entity; +import common.nbt.NBTTagCompound; +import common.network.IClientPlayer; +import common.network.Packet; +import common.network.PacketBuffer; +import common.world.World; public class S43PacketUpdateEntityNBT implements Packet { diff --git a/java/src/game/packet/SPacketAnimation.java b/java/src/common/packet/SPacketAnimation.java similarity index 89% rename from java/src/game/packet/SPacketAnimation.java rename to java/src/common/packet/SPacketAnimation.java index f04fa3f..ad62a60 100755 --- a/java/src/game/packet/SPacketAnimation.java +++ b/java/src/common/packet/SPacketAnimation.java @@ -1,11 +1,11 @@ -package game.packet; +package common.packet; import java.io.IOException; -import game.entity.Entity; -import game.network.IClientPlayer; -import game.network.Packet; -import game.network.PacketBuffer; +import common.entity.Entity; +import common.network.IClientPlayer; +import common.network.Packet; +import common.network.PacketBuffer; public class SPacketAnimation implements Packet { diff --git a/java/src/game/packet/SPacketBiomes.java b/java/src/common/packet/SPacketBiomes.java similarity index 87% rename from java/src/game/packet/SPacketBiomes.java rename to java/src/common/packet/SPacketBiomes.java index 9af8bdf..3d83aed 100755 --- a/java/src/game/packet/SPacketBiomes.java +++ b/java/src/common/packet/SPacketBiomes.java @@ -1,10 +1,10 @@ -package game.packet; +package common.packet; import java.io.IOException; -import game.network.IClientPlayer; -import game.network.Packet; -import game.network.PacketBuffer; +import common.network.IClientPlayer; +import common.network.Packet; +import common.network.PacketBuffer; public class SPacketBiomes implements Packet { private int chunkX; diff --git a/java/src/game/packet/SPacketBlockAction.java b/java/src/common/packet/SPacketBlockAction.java similarity index 89% rename from java/src/game/packet/SPacketBlockAction.java rename to java/src/common/packet/SPacketBlockAction.java index b20f782..5de2cac 100755 --- a/java/src/game/packet/SPacketBlockAction.java +++ b/java/src/common/packet/SPacketBlockAction.java @@ -1,13 +1,13 @@ -package game.packet; +package common.packet; import java.io.IOException; -import game.block.Block; -import game.init.BlockRegistry; -import game.network.IClientPlayer; -import game.network.Packet; -import game.network.PacketBuffer; -import game.world.BlockPos; +import common.block.Block; +import common.init.BlockRegistry; +import common.network.IClientPlayer; +import common.network.Packet; +import common.network.PacketBuffer; +import common.world.BlockPos; public class SPacketBlockAction implements Packet { diff --git a/java/src/game/packet/SPacketBlockBreakAnim.java b/java/src/common/packet/SPacketBlockBreakAnim.java similarity index 90% rename from java/src/game/packet/SPacketBlockBreakAnim.java rename to java/src/common/packet/SPacketBlockBreakAnim.java index 8621320..d6f613c 100755 --- a/java/src/game/packet/SPacketBlockBreakAnim.java +++ b/java/src/common/packet/SPacketBlockBreakAnim.java @@ -1,11 +1,11 @@ -package game.packet; +package common.packet; import java.io.IOException; -import game.network.IClientPlayer; -import game.network.Packet; -import game.network.PacketBuffer; -import game.world.BlockPos; +import common.network.IClientPlayer; +import common.network.Packet; +import common.network.PacketBuffer; +import common.world.BlockPos; public class SPacketBlockBreakAnim implements Packet { diff --git a/java/src/game/packet/SPacketBlockChange.java b/java/src/common/packet/SPacketBlockChange.java similarity index 84% rename from java/src/game/packet/SPacketBlockChange.java rename to java/src/common/packet/SPacketBlockChange.java index 801050a..d60fd10 100755 --- a/java/src/game/packet/SPacketBlockChange.java +++ b/java/src/common/packet/SPacketBlockChange.java @@ -1,14 +1,14 @@ -package game.packet; +package common.packet; import java.io.IOException; -import game.init.BlockRegistry; -import game.network.IClientPlayer; -import game.network.Packet; -import game.network.PacketBuffer; -import game.world.BlockPos; -import game.world.State; -import game.world.World; +import common.init.BlockRegistry; +import common.network.IClientPlayer; +import common.network.Packet; +import common.network.PacketBuffer; +import common.world.BlockPos; +import common.world.State; +import common.world.World; public class SPacketBlockChange implements Packet { diff --git a/java/src/game/packet/SPacketCamera.java b/java/src/common/packet/SPacketCamera.java similarity index 80% rename from java/src/game/packet/SPacketCamera.java rename to java/src/common/packet/SPacketCamera.java index a22f016..40edc45 100755 --- a/java/src/game/packet/SPacketCamera.java +++ b/java/src/common/packet/SPacketCamera.java @@ -1,12 +1,12 @@ -package game.packet; +package common.packet; import java.io.IOException; -import game.entity.Entity; -import game.network.IClientPlayer; -import game.network.Packet; -import game.network.PacketBuffer; -import game.world.World; +import common.entity.Entity; +import common.network.IClientPlayer; +import common.network.Packet; +import common.network.PacketBuffer; +import common.world.World; public class SPacketCamera implements Packet { diff --git a/java/src/game/packet/SPacketCharacterList.java b/java/src/common/packet/SPacketCharacterList.java similarity index 89% rename from java/src/game/packet/SPacketCharacterList.java rename to java/src/common/packet/SPacketCharacterList.java index e9f3c74..b5b13b8 100644 --- a/java/src/game/packet/SPacketCharacterList.java +++ b/java/src/common/packet/SPacketCharacterList.java @@ -1,18 +1,18 @@ -package game.packet; +package common.packet; import java.io.IOException; import java.util.Collection; import java.util.Map; import java.util.Map.Entry; -import game.collect.Maps; -import game.entity.npc.Alignment; -import game.entity.npc.PlayerCharacter; -import game.network.IClientPlayer; -import game.network.IPlayer; -import game.network.Packet; -import game.network.PacketBuffer; -import game.world.BlockPos; +import common.collect.Maps; +import common.entity.npc.Alignment; +import common.entity.npc.PlayerCharacter; +import common.network.IClientPlayer; +import common.network.IPlayer; +import common.network.Packet; +import common.network.PacketBuffer; +import common.world.BlockPos; public class SPacketCharacterList implements Packet { private final Map players = Maps.newHashMap(); diff --git a/java/src/game/packet/SPacketChunkData.java b/java/src/common/packet/SPacketChunkData.java similarity index 95% rename from java/src/game/packet/SPacketChunkData.java rename to java/src/common/packet/SPacketChunkData.java index c0122d8..1996522 100755 --- a/java/src/game/packet/SPacketChunkData.java +++ b/java/src/common/packet/SPacketChunkData.java @@ -1,14 +1,14 @@ -package game.packet; +package common.packet; import java.io.IOException; import java.util.List; -import game.collect.Lists; -import game.network.IClientPlayer; -import game.network.Packet; -import game.network.PacketBuffer; -import game.world.BlockArray; -import game.world.Chunk; +import common.collect.Lists; +import common.network.IClientPlayer; +import common.network.Packet; +import common.network.PacketBuffer; +import common.world.BlockArray; +import common.world.Chunk; public class SPacketChunkData implements Packet { diff --git a/java/src/game/packet/SPacketCollectItem.java b/java/src/common/packet/SPacketCollectItem.java similarity index 91% rename from java/src/game/packet/SPacketCollectItem.java rename to java/src/common/packet/SPacketCollectItem.java index 3763c56..4c0deb7 100755 --- a/java/src/game/packet/SPacketCollectItem.java +++ b/java/src/common/packet/SPacketCollectItem.java @@ -1,10 +1,10 @@ -package game.packet; +package common.packet; import java.io.IOException; -import game.network.IClientPlayer; -import game.network.Packet; -import game.network.PacketBuffer; +import common.network.IClientPlayer; +import common.network.Packet; +import common.network.PacketBuffer; public class SPacketCollectItem implements Packet { diff --git a/java/src/game/packet/SPacketDestroyEntities.java b/java/src/common/packet/SPacketDestroyEntities.java similarity index 90% rename from java/src/game/packet/SPacketDestroyEntities.java rename to java/src/common/packet/SPacketDestroyEntities.java index 4afc384..9927461 100755 --- a/java/src/game/packet/SPacketDestroyEntities.java +++ b/java/src/common/packet/SPacketDestroyEntities.java @@ -1,10 +1,10 @@ -package game.packet; +package common.packet; import java.io.IOException; -import game.network.IClientPlayer; -import game.network.Packet; -import game.network.PacketBuffer; +import common.network.IClientPlayer; +import common.network.Packet; +import common.network.PacketBuffer; public class SPacketDestroyEntities implements Packet { diff --git a/java/src/game/packet/SPacketDimensionName.java b/java/src/common/packet/SPacketDimensionName.java similarity index 86% rename from java/src/game/packet/SPacketDimensionName.java rename to java/src/common/packet/SPacketDimensionName.java index e0160a2..feb1c80 100755 --- a/java/src/game/packet/SPacketDimensionName.java +++ b/java/src/common/packet/SPacketDimensionName.java @@ -1,11 +1,11 @@ -package game.packet; +package common.packet; import java.io.IOException; -import game.dimension.Dimension; -import game.network.IClientPlayer; -import game.network.Packet; -import game.network.PacketBuffer; +import common.dimension.Dimension; +import common.network.IClientPlayer; +import common.network.Packet; +import common.network.PacketBuffer; public class SPacketDimensionName implements Packet { private String fullName; diff --git a/java/src/game/packet/SPacketDisconnect.java b/java/src/common/packet/SPacketDisconnect.java similarity index 77% rename from java/src/game/packet/SPacketDisconnect.java rename to java/src/common/packet/SPacketDisconnect.java index 1ff1234..5b690b7 100755 --- a/java/src/game/packet/SPacketDisconnect.java +++ b/java/src/common/packet/SPacketDisconnect.java @@ -1,10 +1,10 @@ -package game.packet; +package common.packet; import java.io.IOException; -import game.network.IClientPlayer; -import game.network.Packet; -import game.network.PacketBuffer; +import common.network.IClientPlayer; +import common.network.Packet; +import common.network.PacketBuffer; public class SPacketDisconnect implements Packet { diff --git a/java/src/game/packet/SPacketEntityEquipment.java b/java/src/common/packet/SPacketEntityEquipment.java similarity index 90% rename from java/src/game/packet/SPacketEntityEquipment.java rename to java/src/common/packet/SPacketEntityEquipment.java index d90e86d..0ee5fd8 100755 --- a/java/src/game/packet/SPacketEntityEquipment.java +++ b/java/src/common/packet/SPacketEntityEquipment.java @@ -1,11 +1,11 @@ -package game.packet; +package common.packet; import java.io.IOException; -import game.item.ItemStack; -import game.network.IClientPlayer; -import game.network.Packet; -import game.network.PacketBuffer; +import common.item.ItemStack; +import common.network.IClientPlayer; +import common.network.Packet; +import common.network.PacketBuffer; public class SPacketEntityEquipment implements Packet { diff --git a/java/src/game/packet/SPacketEntityVelocity.java b/java/src/common/packet/SPacketEntityVelocity.java similarity index 93% rename from java/src/game/packet/SPacketEntityVelocity.java rename to java/src/common/packet/SPacketEntityVelocity.java index ccca607..8b6520c 100755 --- a/java/src/game/packet/SPacketEntityVelocity.java +++ b/java/src/common/packet/SPacketEntityVelocity.java @@ -1,11 +1,11 @@ -package game.packet; +package common.packet; import java.io.IOException; -import game.entity.Entity; -import game.network.IClientPlayer; -import game.network.Packet; -import game.network.PacketBuffer; +import common.entity.Entity; +import common.network.IClientPlayer; +import common.network.Packet; +import common.network.PacketBuffer; public class SPacketEntityVelocity implements Packet { diff --git a/java/src/game/packet/SPacketHeldItemChange.java b/java/src/common/packet/SPacketHeldItemChange.java similarity index 88% rename from java/src/game/packet/SPacketHeldItemChange.java rename to java/src/common/packet/SPacketHeldItemChange.java index 8c36e08..a2066f1 100755 --- a/java/src/game/packet/SPacketHeldItemChange.java +++ b/java/src/common/packet/SPacketHeldItemChange.java @@ -1,10 +1,10 @@ -package game.packet; +package common.packet; import java.io.IOException; -import game.network.IClientPlayer; -import game.network.Packet; -import game.network.PacketBuffer; +import common.network.IClientPlayer; +import common.network.Packet; +import common.network.PacketBuffer; public class SPacketHeldItemChange implements Packet { diff --git a/java/src/game/packet/SPacketJoinGame.java b/java/src/common/packet/SPacketJoinGame.java similarity index 86% rename from java/src/game/packet/SPacketJoinGame.java rename to java/src/common/packet/SPacketJoinGame.java index 6c9e0ac..1f452fd 100755 --- a/java/src/game/packet/SPacketJoinGame.java +++ b/java/src/common/packet/SPacketJoinGame.java @@ -1,12 +1,12 @@ -package game.packet; +package common.packet; import java.io.IOException; -import game.dimension.Dimension; -import game.nbt.NBTTagCompound; -import game.network.IClientPlayer; -import game.network.Packet; -import game.network.PacketBuffer; +import common.dimension.Dimension; +import common.nbt.NBTTagCompound; +import common.network.IClientPlayer; +import common.network.Packet; +import common.network.PacketBuffer; public class SPacketJoinGame implements Packet { private int entityId; diff --git a/java/src/game/packet/SPacketKeepAlive.java b/java/src/common/packet/SPacketKeepAlive.java similarity index 83% rename from java/src/game/packet/SPacketKeepAlive.java rename to java/src/common/packet/SPacketKeepAlive.java index 9c5cbb9..6451e5e 100755 --- a/java/src/game/packet/SPacketKeepAlive.java +++ b/java/src/common/packet/SPacketKeepAlive.java @@ -1,6 +1,6 @@ -package game.packet; +package common.packet; -import game.network.IClientPlayer; +import common.network.IClientPlayer; public class SPacketKeepAlive extends APacketVarInt { diff --git a/java/src/game/packet/SPacketLoading.java b/java/src/common/packet/SPacketLoading.java similarity index 92% rename from java/src/game/packet/SPacketLoading.java rename to java/src/common/packet/SPacketLoading.java index ae2214c..4daa761 100644 --- a/java/src/game/packet/SPacketLoading.java +++ b/java/src/common/packet/SPacketLoading.java @@ -1,10 +1,10 @@ -package game.packet; +package common.packet; import java.io.IOException; -import game.network.IClientPlayer; -import game.network.Packet; -import game.network.PacketBuffer; +import common.network.IClientPlayer; +import common.network.Packet; +import common.network.PacketBuffer; public class SPacketLoading implements Packet { private String message; diff --git a/java/src/game/packet/SPacketMapChunkBulk.java b/java/src/common/packet/SPacketMapChunkBulk.java similarity index 95% rename from java/src/game/packet/SPacketMapChunkBulk.java rename to java/src/common/packet/SPacketMapChunkBulk.java index 4b119fe..aebfac5 100755 --- a/java/src/game/packet/SPacketMapChunkBulk.java +++ b/java/src/common/packet/SPacketMapChunkBulk.java @@ -1,12 +1,12 @@ -package game.packet; +package common.packet; import java.io.IOException; import java.util.List; -import game.network.IClientPlayer; -import game.network.Packet; -import game.network.PacketBuffer; -import game.world.Chunk; +import common.network.IClientPlayer; +import common.network.Packet; +import common.network.PacketBuffer; +import common.world.Chunk; public class SPacketMapChunkBulk implements Packet { diff --git a/java/src/game/packet/SPacketMessage.java b/java/src/common/packet/SPacketMessage.java similarity index 86% rename from java/src/game/packet/SPacketMessage.java rename to java/src/common/packet/SPacketMessage.java index d73032e..3832c29 100755 --- a/java/src/game/packet/SPacketMessage.java +++ b/java/src/common/packet/SPacketMessage.java @@ -1,10 +1,10 @@ -package game.packet; +package common.packet; import java.io.IOException; -import game.network.IClientPlayer; -import game.network.Packet; -import game.network.PacketBuffer; +import common.network.IClientPlayer; +import common.network.Packet; +import common.network.PacketBuffer; public class SPacketMessage implements Packet { public static enum Type { diff --git a/java/src/game/packet/SPacketMultiBlockChange.java b/java/src/common/packet/SPacketMultiBlockChange.java similarity index 91% rename from java/src/game/packet/SPacketMultiBlockChange.java rename to java/src/common/packet/SPacketMultiBlockChange.java index 1fcf7fd..8769e0a 100755 --- a/java/src/game/packet/SPacketMultiBlockChange.java +++ b/java/src/common/packet/SPacketMultiBlockChange.java @@ -1,15 +1,15 @@ -package game.packet; +package common.packet; import java.io.IOException; -import game.init.BlockRegistry; -import game.network.IClientPlayer; -import game.network.Packet; -import game.network.PacketBuffer; -import game.world.BlockPos; -import game.world.Chunk; -import game.world.ChunkPos; -import game.world.State; +import common.init.BlockRegistry; +import common.network.IClientPlayer; +import common.network.Packet; +import common.network.PacketBuffer; +import common.world.BlockPos; +import common.world.Chunk; +import common.world.ChunkPos; +import common.world.State; public class SPacketMultiBlockChange implements Packet { diff --git a/java/src/game/packet/SPacketPlayerPosLook.java b/java/src/common/packet/SPacketPlayerPosLook.java similarity index 96% rename from java/src/game/packet/SPacketPlayerPosLook.java rename to java/src/common/packet/SPacketPlayerPosLook.java index 74b4b2d..29d51ba 100755 --- a/java/src/game/packet/SPacketPlayerPosLook.java +++ b/java/src/common/packet/SPacketPlayerPosLook.java @@ -1,12 +1,12 @@ -package game.packet; +package common.packet; import java.io.IOException; import java.util.EnumSet; import java.util.Set; -import game.network.IClientPlayer; -import game.network.Packet; -import game.network.PacketBuffer; +import common.network.IClientPlayer; +import common.network.Packet; +import common.network.PacketBuffer; public class SPacketPlayerPosLook implements Packet { diff --git a/java/src/game/packet/SPacketRespawn.java b/java/src/common/packet/SPacketRespawn.java similarity index 86% rename from java/src/game/packet/SPacketRespawn.java rename to java/src/common/packet/SPacketRespawn.java index d577276..3e8d3fd 100755 --- a/java/src/game/packet/SPacketRespawn.java +++ b/java/src/common/packet/SPacketRespawn.java @@ -1,12 +1,12 @@ -package game.packet; +package common.packet; import java.io.IOException; -import game.dimension.Dimension; -import game.nbt.NBTTagCompound; -import game.network.IClientPlayer; -import game.network.Packet; -import game.network.PacketBuffer; +import common.dimension.Dimension; +import common.nbt.NBTTagCompound; +import common.network.IClientPlayer; +import common.network.Packet; +import common.network.PacketBuffer; public class SPacketRespawn implements Packet { diff --git a/java/src/game/packet/SPacketServerTick.java b/java/src/common/packet/SPacketServerTick.java similarity index 81% rename from java/src/game/packet/SPacketServerTick.java rename to java/src/common/packet/SPacketServerTick.java index 03ad7ec..0a9eac1 100644 --- a/java/src/game/packet/SPacketServerTick.java +++ b/java/src/common/packet/SPacketServerTick.java @@ -1,10 +1,10 @@ -package game.packet; +package common.packet; import java.io.IOException; -import game.network.IClientPlayer; -import game.network.Packet; -import game.network.PacketBuffer; +import common.network.IClientPlayer; +import common.network.Packet; +import common.network.PacketBuffer; public class SPacketServerTick implements Packet { private int time; diff --git a/java/src/game/packet/SPacketSetExperience.java b/java/src/common/packet/SPacketSetExperience.java similarity index 92% rename from java/src/game/packet/SPacketSetExperience.java rename to java/src/common/packet/SPacketSetExperience.java index b317b66..1b60ca9 100755 --- a/java/src/game/packet/SPacketSetExperience.java +++ b/java/src/common/packet/SPacketSetExperience.java @@ -1,10 +1,10 @@ -package game.packet; +package common.packet; import java.io.IOException; -import game.network.IClientPlayer; -import game.network.Packet; -import game.network.PacketBuffer; +import common.network.IClientPlayer; +import common.network.Packet; +import common.network.PacketBuffer; public class SPacketSetExperience implements Packet { diff --git a/java/src/game/packet/SPacketSkin.java b/java/src/common/packet/SPacketSkin.java similarity index 86% rename from java/src/game/packet/SPacketSkin.java rename to java/src/common/packet/SPacketSkin.java index 23b619f..2efdcc9 100755 --- a/java/src/game/packet/SPacketSkin.java +++ b/java/src/common/packet/SPacketSkin.java @@ -1,13 +1,13 @@ -package game.packet; +package common.packet; import java.io.IOException; -import game.entity.Entity; -import game.network.IClientPlayer; -import game.network.IPlayer; -import game.network.Packet; -import game.network.PacketBuffer; -import game.world.World; +import common.entity.Entity; +import common.network.IClientPlayer; +import common.network.IPlayer; +import common.network.Packet; +import common.network.PacketBuffer; +import common.world.World; public class SPacketSkin implements Packet { diff --git a/java/src/game/packet/SPacketSpawnMob.java b/java/src/common/packet/SPacketSpawnMob.java similarity index 93% rename from java/src/game/packet/SPacketSpawnMob.java rename to java/src/common/packet/SPacketSpawnMob.java index 2bd5afe..b26ba57 100755 --- a/java/src/game/packet/SPacketSpawnMob.java +++ b/java/src/common/packet/SPacketSpawnMob.java @@ -1,15 +1,15 @@ -package game.packet; +package common.packet; import java.io.IOException; import java.util.List; -import game.entity.DataWatcher; -import game.entity.types.EntityLiving; -import game.init.EntityRegistry; -import game.network.IClientPlayer; -import game.network.Packet; -import game.network.PacketBuffer; -import game.util.ExtMath; +import common.entity.DataWatcher; +import common.entity.types.EntityLiving; +import common.init.EntityRegistry; +import common.network.IClientPlayer; +import common.network.Packet; +import common.network.PacketBuffer; +import common.util.ExtMath; public class SPacketSpawnMob implements Packet { diff --git a/java/src/game/packet/SPacketSpawnObject.java b/java/src/common/packet/SPacketSpawnObject.java similarity index 91% rename from java/src/game/packet/SPacketSpawnObject.java rename to java/src/common/packet/SPacketSpawnObject.java index 238e1ef..5058f62 100755 --- a/java/src/game/packet/SPacketSpawnObject.java +++ b/java/src/common/packet/SPacketSpawnObject.java @@ -1,18 +1,18 @@ -package game.packet; +package common.packet; import java.io.IOException; -import game.entity.Entity; -import game.entity.item.EntityLeashKnot; -import game.entity.projectile.EntityProjectile; -import game.entity.types.IObjectData; -import game.init.EntityRegistry; -import game.network.IClientPlayer; -import game.network.Packet; -import game.network.PacketBuffer; -import game.util.ExtMath; -import game.world.BlockPos; -import game.world.Vec3; +import common.entity.Entity; +import common.entity.item.EntityLeashKnot; +import common.entity.projectile.EntityProjectile; +import common.entity.types.IObjectData; +import common.init.EntityRegistry; +import common.network.IClientPlayer; +import common.network.Packet; +import common.network.PacketBuffer; +import common.util.ExtMath; +import common.world.BlockPos; +import common.world.Vec3; public class SPacketSpawnObject implements Packet { diff --git a/java/src/game/packet/SPacketSpawnPlayer.java b/java/src/common/packet/SPacketSpawnPlayer.java similarity index 90% rename from java/src/game/packet/SPacketSpawnPlayer.java rename to java/src/common/packet/SPacketSpawnPlayer.java index 89702e6..7c1ab02 100755 --- a/java/src/game/packet/SPacketSpawnPlayer.java +++ b/java/src/common/packet/SPacketSpawnPlayer.java @@ -1,18 +1,18 @@ -package game.packet; +package common.packet; import java.io.IOException; import java.util.List; -import game.entity.DataWatcher; -import game.entity.npc.EntityNPC; -import game.init.EntityRegistry; -import game.init.ItemRegistry; -import game.item.ItemStack; -import game.network.IClientPlayer; -import game.network.IPlayer; -import game.network.Packet; -import game.network.PacketBuffer; -import game.util.ExtMath; +import common.entity.DataWatcher; +import common.entity.npc.EntityNPC; +import common.init.EntityRegistry; +import common.init.ItemRegistry; +import common.item.ItemStack; +import common.network.IClientPlayer; +import common.network.IPlayer; +import common.network.Packet; +import common.network.PacketBuffer; +import common.util.ExtMath; public class SPacketSpawnPlayer implements Packet { diff --git a/java/src/game/packet/SPacketTimeUpdate.java b/java/src/common/packet/SPacketTimeUpdate.java similarity index 86% rename from java/src/game/packet/SPacketTimeUpdate.java rename to java/src/common/packet/SPacketTimeUpdate.java index f8b28fa..3885c3a 100755 --- a/java/src/game/packet/SPacketTimeUpdate.java +++ b/java/src/common/packet/SPacketTimeUpdate.java @@ -1,10 +1,10 @@ -package game.packet; +package common.packet; import java.io.IOException; -import game.network.IClientPlayer; -import game.network.Packet; -import game.network.PacketBuffer; +import common.network.IClientPlayer; +import common.network.Packet; +import common.network.PacketBuffer; public class SPacketTimeUpdate implements Packet { private long worldTime; diff --git a/java/src/game/packet/SPacketTrades.java b/java/src/common/packet/SPacketTrades.java similarity index 91% rename from java/src/game/packet/SPacketTrades.java rename to java/src/common/packet/SPacketTrades.java index 4c64a65..94a5e65 100755 --- a/java/src/game/packet/SPacketTrades.java +++ b/java/src/common/packet/SPacketTrades.java @@ -1,13 +1,13 @@ -package game.packet; +package common.packet; import java.io.IOException; -import game.item.ItemStack; -import game.network.IClientPlayer; -import game.network.Packet; -import game.network.PacketBuffer; -import game.village.MerchantRecipe; -import game.village.MerchantRecipeList; +import common.item.ItemStack; +import common.network.IClientPlayer; +import common.network.Packet; +import common.network.PacketBuffer; +import common.village.MerchantRecipe; +import common.village.MerchantRecipeList; public class SPacketTrades implements Packet { diff --git a/java/src/game/packet/SPacketUpdateHealth.java b/java/src/common/packet/SPacketUpdateHealth.java similarity index 82% rename from java/src/game/packet/SPacketUpdateHealth.java rename to java/src/common/packet/SPacketUpdateHealth.java index cda549b..532f069 100755 --- a/java/src/game/packet/SPacketUpdateHealth.java +++ b/java/src/common/packet/SPacketUpdateHealth.java @@ -1,10 +1,10 @@ -package game.packet; +package common.packet; import java.io.IOException; -import game.network.IClientPlayer; -import game.network.Packet; -import game.network.PacketBuffer; +import common.network.IClientPlayer; +import common.network.Packet; +import common.network.PacketBuffer; public class SPacketUpdateHealth implements Packet { private int health; diff --git a/java/src/game/packet/SPacketWorld.java b/java/src/common/packet/SPacketWorld.java similarity index 89% rename from java/src/game/packet/SPacketWorld.java rename to java/src/common/packet/SPacketWorld.java index 3c68f29..17ff613 100755 --- a/java/src/game/packet/SPacketWorld.java +++ b/java/src/common/packet/SPacketWorld.java @@ -1,10 +1,10 @@ -package game.packet; +package common.packet; import java.io.IOException; -import game.network.IClientPlayer; -import game.network.Packet; -import game.network.PacketBuffer; +import common.network.IClientPlayer; +import common.network.Packet; +import common.network.PacketBuffer; public class SPacketWorld implements Packet { private float gravity; diff --git a/java/src/game/pathfinding/NodeProcessor.java b/java/src/common/pathfinding/NodeProcessor.java similarity index 93% rename from java/src/game/pathfinding/NodeProcessor.java rename to java/src/common/pathfinding/NodeProcessor.java index 3bf08d0..8dc172e 100755 --- a/java/src/game/pathfinding/NodeProcessor.java +++ b/java/src/common/pathfinding/NodeProcessor.java @@ -1,8 +1,8 @@ -package game.pathfinding; +package common.pathfinding; -import game.entity.Entity; -import game.util.ExtMath; -import game.world.IntHashMap; +import common.entity.Entity; +import common.util.ExtMath; +import common.world.IntHashMap; public abstract class NodeProcessor { diff --git a/java/src/game/pathfinding/Path.java b/java/src/common/pathfinding/Path.java similarity index 99% rename from java/src/game/pathfinding/Path.java rename to java/src/common/pathfinding/Path.java index 65e0cf9..ed5d9c3 100755 --- a/java/src/game/pathfinding/Path.java +++ b/java/src/common/pathfinding/Path.java @@ -1,4 +1,4 @@ -package game.pathfinding; +package common.pathfinding; public class Path { diff --git a/java/src/game/pathfinding/PathCache.java b/java/src/common/pathfinding/PathCache.java similarity index 76% rename from java/src/game/pathfinding/PathCache.java rename to java/src/common/pathfinding/PathCache.java index 55d88e8..1dc0239 100755 --- a/java/src/game/pathfinding/PathCache.java +++ b/java/src/common/pathfinding/PathCache.java @@ -1,12 +1,12 @@ -package game.pathfinding; +package common.pathfinding; -import game.init.Blocks; -import game.world.BlockPos; -import game.world.Chunk; -import game.world.ChunkCache; -import game.world.IBlockAccess; -import game.world.State; -import game.world.World; +import common.init.Blocks; +import common.world.BlockPos; +import common.world.Chunk; +import common.world.ChunkCache; +import common.world.IBlockAccess; +import common.world.State; +import common.world.World; public class PathCache extends ChunkCache implements IBlockAccess { diff --git a/java/src/game/pathfinding/PathEntity.java b/java/src/common/pathfinding/PathEntity.java similarity index 97% rename from java/src/game/pathfinding/PathEntity.java rename to java/src/common/pathfinding/PathEntity.java index 6f71dc7..593e6e3 100755 --- a/java/src/game/pathfinding/PathEntity.java +++ b/java/src/common/pathfinding/PathEntity.java @@ -1,7 +1,7 @@ -package game.pathfinding; +package common.pathfinding; -import game.entity.Entity; -import game.world.Vec3; +import common.entity.Entity; +import common.world.Vec3; public class PathEntity { diff --git a/java/src/game/pathfinding/PathFinder.java b/java/src/common/pathfinding/PathFinder.java similarity index 98% rename from java/src/game/pathfinding/PathFinder.java rename to java/src/common/pathfinding/PathFinder.java index a18a568..db9798e 100755 --- a/java/src/game/pathfinding/PathFinder.java +++ b/java/src/common/pathfinding/PathFinder.java @@ -1,7 +1,7 @@ -package game.pathfinding; +package common.pathfinding; -import game.entity.Entity; -import game.world.BlockPos; +import common.entity.Entity; +import common.world.BlockPos; public class PathFinder { diff --git a/java/src/game/pathfinding/PathNavigate.java b/java/src/common/pathfinding/PathNavigate.java similarity index 96% rename from java/src/game/pathfinding/PathNavigate.java rename to java/src/common/pathfinding/PathNavigate.java index 484e8ce..fb749ca 100755 --- a/java/src/game/pathfinding/PathNavigate.java +++ b/java/src/common/pathfinding/PathNavigate.java @@ -1,16 +1,16 @@ -package game.pathfinding; +package common.pathfinding; import java.util.List; -import game.entity.Entity; -import game.entity.attributes.AttributeInstance; -import game.entity.attributes.Attributes; -import game.entity.types.EntityLiving; -import game.util.ExtMath; -import game.world.BlockPos; -import game.world.BoundingBox; -import game.world.Vec3; -import game.world.World; +import common.entity.Entity; +import common.entity.attributes.AttributeInstance; +import common.entity.attributes.Attributes; +import common.entity.types.EntityLiving; +import common.util.ExtMath; +import common.world.BlockPos; +import common.world.BoundingBox; +import common.world.Vec3; +import common.world.World; public abstract class PathNavigate { diff --git a/java/src/game/pathfinding/PathNavigateClimber.java b/java/src/common/pathfinding/PathNavigateClimber.java similarity index 92% rename from java/src/game/pathfinding/PathNavigateClimber.java rename to java/src/common/pathfinding/PathNavigateClimber.java index 45d1726..02388f6 100755 --- a/java/src/game/pathfinding/PathNavigateClimber.java +++ b/java/src/common/pathfinding/PathNavigateClimber.java @@ -1,10 +1,10 @@ -package game.pathfinding; +package common.pathfinding; -import game.entity.Entity; -import game.entity.types.EntityLiving; -import game.util.ExtMath; -import game.world.BlockPos; -import game.world.World; +import common.entity.Entity; +import common.entity.types.EntityLiving; +import common.util.ExtMath; +import common.world.BlockPos; +import common.world.World; public class PathNavigateClimber extends PathNavigateGround { diff --git a/java/src/game/pathfinding/PathNavigateGround.java b/java/src/common/pathfinding/PathNavigateGround.java similarity index 96% rename from java/src/game/pathfinding/PathNavigateGround.java rename to java/src/common/pathfinding/PathNavigateGround.java index 989c21f..0fd0d79 100755 --- a/java/src/game/pathfinding/PathNavigateGround.java +++ b/java/src/common/pathfinding/PathNavigateGround.java @@ -1,14 +1,14 @@ -package game.pathfinding; +package common.pathfinding; -import game.block.Block; -import game.entity.animal.EntityChicken; -import game.entity.npc.EntityZombie; -import game.entity.types.EntityLiving; -import game.material.Material; -import game.util.ExtMath; -import game.world.BlockPos; -import game.world.Vec3; -import game.world.World; +import common.block.Block; +import common.entity.animal.EntityChicken; +import common.entity.npc.EntityZombie; +import common.entity.types.EntityLiving; +import common.material.Material; +import common.util.ExtMath; +import common.world.BlockPos; +import common.world.Vec3; +import common.world.World; public class PathNavigateGround extends PathNavigate { diff --git a/java/src/game/pathfinding/PathPoint.java b/java/src/common/pathfinding/PathPoint.java similarity index 97% rename from java/src/game/pathfinding/PathPoint.java rename to java/src/common/pathfinding/PathPoint.java index 453383c..92e9731 100755 --- a/java/src/game/pathfinding/PathPoint.java +++ b/java/src/common/pathfinding/PathPoint.java @@ -1,6 +1,6 @@ -package game.pathfinding; +package common.pathfinding; -import game.util.ExtMath; +import common.util.ExtMath; public class PathPoint { diff --git a/java/src/game/pathfinding/SwimNodeProcessor.java b/java/src/common/pathfinding/SwimNodeProcessor.java similarity index 94% rename from java/src/game/pathfinding/SwimNodeProcessor.java rename to java/src/common/pathfinding/SwimNodeProcessor.java index 4790091..57e13ae 100755 --- a/java/src/game/pathfinding/SwimNodeProcessor.java +++ b/java/src/common/pathfinding/SwimNodeProcessor.java @@ -1,10 +1,10 @@ -package game.pathfinding; +package common.pathfinding; -import game.block.Block; -import game.entity.Entity; -import game.util.ExtMath; -import game.world.BlockPos; -import game.world.Facing; +import common.block.Block; +import common.entity.Entity; +import common.util.ExtMath; +import common.world.BlockPos; +import common.world.Facing; public class SwimNodeProcessor extends NodeProcessor { diff --git a/java/src/game/pathfinding/WalkNodeProcessor.java b/java/src/common/pathfinding/WalkNodeProcessor.java similarity index 96% rename from java/src/game/pathfinding/WalkNodeProcessor.java rename to java/src/common/pathfinding/WalkNodeProcessor.java index 815abec..1f6a96e 100755 --- a/java/src/game/pathfinding/WalkNodeProcessor.java +++ b/java/src/common/pathfinding/WalkNodeProcessor.java @@ -1,17 +1,17 @@ -package game.pathfinding; +package common.pathfinding; -import game.block.Block; -import game.block.BlockDoor; -import game.block.BlockFence; -import game.block.BlockFenceGate; -import game.block.BlockRailBase; -import game.block.BlockWall; -import game.entity.Entity; -import game.init.Blocks; -import game.material.Material; -import game.util.ExtMath; -import game.world.BlockPos; -import game.world.IBlockAccess; +import common.block.Block; +import common.block.BlockDoor; +import common.block.BlockFence; +import common.block.BlockFenceGate; +import common.block.BlockRailBase; +import common.block.BlockWall; +import common.entity.Entity; +import common.init.Blocks; +import common.material.Material; +import common.util.ExtMath; +import common.world.BlockPos; +import common.world.IBlockAccess; public class WalkNodeProcessor extends NodeProcessor { diff --git a/java/src/game/pattern/BlockStateHelper.java b/java/src/common/pattern/BlockStateHelper.java similarity index 91% rename from java/src/game/pattern/BlockStateHelper.java rename to java/src/common/pattern/BlockStateHelper.java index 2e3972e..df47558 100755 --- a/java/src/game/pattern/BlockStateHelper.java +++ b/java/src/common/pattern/BlockStateHelper.java @@ -1,13 +1,13 @@ -package game.pattern; +package common.pattern; import java.util.Map; import java.util.Map.Entry; import java.util.function.Predicate; -import game.block.Block; -import game.collect.Maps; -import game.properties.IProperty; -import game.world.State; +import common.block.Block; +import common.collect.Maps; +import common.properties.IProperty; +import common.world.State; public class BlockStateHelper implements Predicate { diff --git a/java/src/game/potion/Potion.java b/java/src/common/potion/Potion.java similarity index 95% rename from java/src/game/potion/Potion.java rename to java/src/common/potion/Potion.java index b298f83..cf03a29 100755 --- a/java/src/game/potion/Potion.java +++ b/java/src/common/potion/Potion.java @@ -1,18 +1,18 @@ -package game.potion; +package common.potion; import java.util.Map; import java.util.Map.Entry; -import game.collect.Maps; -import game.entity.DamageSource; -import game.entity.attributes.Attribute; -import game.entity.attributes.AttributeInstance; -import game.entity.attributes.AttributeMap; -import game.entity.attributes.AttributeModifier; -import game.entity.attributes.Attributes; -import game.entity.projectile.EntityPotion; -import game.entity.types.EntityLiving; -import game.init.Config; +import common.collect.Maps; +import common.entity.DamageSource; +import common.entity.attributes.Attribute; +import common.entity.attributes.AttributeInstance; +import common.entity.attributes.AttributeMap; +import common.entity.attributes.AttributeModifier; +import common.entity.attributes.Attributes; +import common.entity.projectile.EntityPotion; +import common.entity.types.EntityLiving; +import common.init.Config; public enum Potion { SPEED("speed", "Schnelligkeit", "Trank der Schnelligkeit", false, 8171462, new PotionModifier(Attributes.MOVEMENT_SPEED, "PotSpd", 0.2, true)), diff --git a/java/src/game/potion/PotionEffect.java b/java/src/common/potion/PotionEffect.java similarity index 97% rename from java/src/game/potion/PotionEffect.java rename to java/src/common/potion/PotionEffect.java index fdc7468..ccbfae5 100755 --- a/java/src/game/potion/PotionEffect.java +++ b/java/src/common/potion/PotionEffect.java @@ -1,8 +1,8 @@ -package game.potion; +package common.potion; -import game.entity.types.EntityLiving; -import game.log.Log; -import game.nbt.NBTTagCompound; +import common.entity.types.EntityLiving; +import common.log.Log; +import common.nbt.NBTTagCompound; public class PotionEffect { private final Potion potion; diff --git a/java/src/game/potion/PotionHelper.java b/java/src/common/potion/PotionHelper.java similarity index 99% rename from java/src/game/potion/PotionHelper.java rename to java/src/common/potion/PotionHelper.java index a907121..967a346 100755 --- a/java/src/game/potion/PotionHelper.java +++ b/java/src/common/potion/PotionHelper.java @@ -1,11 +1,11 @@ -package game.potion; +package common.potion; import java.util.Collection; import java.util.List; import java.util.Map; -import game.collect.Lists; -import game.collect.Maps; +import common.collect.Lists; +import common.collect.Maps; public class PotionHelper { diff --git a/java/src/game/properties/IProperty.java b/java/src/common/properties/IProperty.java similarity index 90% rename from java/src/game/properties/IProperty.java rename to java/src/common/properties/IProperty.java index 8869760..af1e388 100755 --- a/java/src/game/properties/IProperty.java +++ b/java/src/common/properties/IProperty.java @@ -1,4 +1,4 @@ -package game.properties; +package common.properties; import java.util.Collection; diff --git a/java/src/game/properties/PropertyBool.java b/java/src/common/properties/PropertyBool.java similarity index 91% rename from java/src/game/properties/PropertyBool.java rename to java/src/common/properties/PropertyBool.java index 4d3a8a5..2db7c37 100755 --- a/java/src/game/properties/PropertyBool.java +++ b/java/src/common/properties/PropertyBool.java @@ -1,8 +1,8 @@ -package game.properties; +package common.properties; import java.util.Collection; -import game.collect.ImmutableSet; +import common.collect.ImmutableSet; public class PropertyBool extends PropertyHelper { diff --git a/java/src/game/properties/PropertyDirection.java b/java/src/common/properties/PropertyDirection.java similarity index 87% rename from java/src/game/properties/PropertyDirection.java rename to java/src/common/properties/PropertyDirection.java index fbcb34a..4c08522 100755 --- a/java/src/game/properties/PropertyDirection.java +++ b/java/src/common/properties/PropertyDirection.java @@ -1,12 +1,12 @@ -package game.properties; +package common.properties; import java.util.Collection; import java.util.function.Predicate; -import game.collect.Filter; -import game.collect.Lists; -import game.util.Predicates; -import game.world.Facing; +import common.collect.Filter; +import common.collect.Lists; +import common.util.Predicates; +import common.world.Facing; public class PropertyDirection extends PropertyEnum { diff --git a/java/src/game/properties/PropertyEnum.java b/java/src/common/properties/PropertyEnum.java similarity index 89% rename from java/src/game/properties/PropertyEnum.java rename to java/src/common/properties/PropertyEnum.java index 6501431..eccbeeb 100755 --- a/java/src/game/properties/PropertyEnum.java +++ b/java/src/common/properties/PropertyEnum.java @@ -1,15 +1,15 @@ -package game.properties; +package common.properties; import java.util.Collection; import java.util.Map; import java.util.function.Predicate; -import game.collect.Filter; -import game.collect.ImmutableSet; -import game.collect.Lists; -import game.collect.Maps; -import game.util.Identifyable; -import game.util.Predicates; +import common.collect.Filter; +import common.collect.ImmutableSet; +import common.collect.Lists; +import common.collect.Maps; +import common.util.Identifyable; +import common.util.Predicates; public class PropertyEnum & Identifyable> extends PropertyHelper { diff --git a/java/src/game/properties/PropertyHelper.java b/java/src/common/properties/PropertyHelper.java similarity index 97% rename from java/src/game/properties/PropertyHelper.java rename to java/src/common/properties/PropertyHelper.java index 5de1517..671ff28 100755 --- a/java/src/game/properties/PropertyHelper.java +++ b/java/src/common/properties/PropertyHelper.java @@ -1,4 +1,4 @@ -package game.properties; +package common.properties; public abstract class PropertyHelper> implements IProperty { diff --git a/java/src/game/properties/PropertyInteger.java b/java/src/common/properties/PropertyInteger.java similarity index 95% rename from java/src/game/properties/PropertyInteger.java rename to java/src/common/properties/PropertyInteger.java index d3ff44f..c6bd59b 100755 --- a/java/src/game/properties/PropertyInteger.java +++ b/java/src/common/properties/PropertyInteger.java @@ -1,10 +1,10 @@ -package game.properties; +package common.properties; import java.util.Collection; import java.util.Set; -import game.collect.ImmutableSet; -import game.collect.Sets; +import common.collect.ImmutableSet; +import common.collect.Sets; public class PropertyInteger extends PropertyHelper { diff --git a/java/src/game/rng/ImprovedGen.java b/java/src/common/rng/ImprovedGen.java similarity index 99% rename from java/src/game/rng/ImprovedGen.java rename to java/src/common/rng/ImprovedGen.java index a709119..d86559b 100755 --- a/java/src/game/rng/ImprovedGen.java +++ b/java/src/common/rng/ImprovedGen.java @@ -1,4 +1,4 @@ -package game.rng; +package common.rng; class ImprovedGen { private static final double[] dir3X = new double[] { 1.0D, -1.0D, 1.0D, -1.0D, 1.0D, -1.0D, 1.0D, -1.0D, 0.0D, 0.0D, 0.0D, 0.0D, 1.0D, 0.0D, diff --git a/java/src/game/rng/ImprovedGenOld.java b/java/src/common/rng/ImprovedGenOld.java similarity index 96% rename from java/src/game/rng/ImprovedGenOld.java rename to java/src/common/rng/ImprovedGenOld.java index 2809b54..fb3c406 100755 --- a/java/src/game/rng/ImprovedGenOld.java +++ b/java/src/common/rng/ImprovedGenOld.java @@ -1,4 +1,4 @@ -package game.rng; +package common.rng; class ImprovedGenOld { private final int permutations[]; diff --git a/java/src/game/rng/NoiseGen.java b/java/src/common/rng/NoiseGen.java similarity index 95% rename from java/src/game/rng/NoiseGen.java rename to java/src/common/rng/NoiseGen.java index cb247f9..114d7f4 100755 --- a/java/src/game/rng/NoiseGen.java +++ b/java/src/common/rng/NoiseGen.java @@ -1,4 +1,4 @@ -package game.rng; +package common.rng; public abstract class NoiseGen { public abstract void generate(double[] noise, int xoff, int yoff, int zoff, int xsize, int ysize, int zsize, double xscale, double yscale, diff --git a/java/src/game/rng/OctaveGen.java b/java/src/common/rng/OctaveGen.java similarity index 98% rename from java/src/game/rng/OctaveGen.java rename to java/src/common/rng/OctaveGen.java index df68d2a..6e58b5a 100755 --- a/java/src/game/rng/OctaveGen.java +++ b/java/src/common/rng/OctaveGen.java @@ -1,4 +1,4 @@ -package game.rng; +package common.rng; public class OctaveGen extends NoiseGen { private final ImprovedGen[] generators; diff --git a/java/src/game/rng/OctaveGenOld.java b/java/src/common/rng/OctaveGenOld.java similarity index 94% rename from java/src/game/rng/OctaveGenOld.java rename to java/src/common/rng/OctaveGenOld.java index ebca8c7..f8a8787 100755 --- a/java/src/game/rng/OctaveGenOld.java +++ b/java/src/common/rng/OctaveGenOld.java @@ -1,4 +1,4 @@ -package game.rng; +package common.rng; public class OctaveGenOld extends NoiseGen { private final ImprovedGenOld generators[]; diff --git a/java/src/game/rng/PerlinGen.java b/java/src/common/rng/PerlinGen.java similarity index 98% rename from java/src/game/rng/PerlinGen.java rename to java/src/common/rng/PerlinGen.java index e2513cc..0149806 100755 --- a/java/src/game/rng/PerlinGen.java +++ b/java/src/common/rng/PerlinGen.java @@ -1,4 +1,4 @@ -package game.rng; +package common.rng; public class PerlinGen { private final SimplexGen[] generators; diff --git a/java/src/game/rng/PerlinGenOld.java b/java/src/common/rng/PerlinGenOld.java similarity index 94% rename from java/src/game/rng/PerlinGenOld.java rename to java/src/common/rng/PerlinGenOld.java index 44d5002..02ff25b 100755 --- a/java/src/game/rng/PerlinGenOld.java +++ b/java/src/common/rng/PerlinGenOld.java @@ -1,4 +1,4 @@ -package game.rng; +package common.rng; public class PerlinGenOld { private final SimplexGenOld generators[]; diff --git a/java/src/game/rng/Random.java b/java/src/common/rng/Random.java similarity index 99% rename from java/src/game/rng/Random.java rename to java/src/common/rng/Random.java index b9a6c5a..875f2f1 100755 --- a/java/src/game/rng/Random.java +++ b/java/src/common/rng/Random.java @@ -1,4 +1,4 @@ -package game.rng; +package common.rng; import java.util.List; import java.util.concurrent.atomic.AtomicLong; diff --git a/java/src/game/rng/RngItem.java b/java/src/common/rng/RngItem.java similarity index 84% rename from java/src/game/rng/RngItem.java rename to java/src/common/rng/RngItem.java index f74db06..920d53c 100755 --- a/java/src/game/rng/RngItem.java +++ b/java/src/common/rng/RngItem.java @@ -1,4 +1,4 @@ -package game.rng; +package common.rng; public abstract class RngItem { public final int weight; diff --git a/java/src/game/rng/SimplexGen.java b/java/src/common/rng/SimplexGen.java similarity index 99% rename from java/src/game/rng/SimplexGen.java rename to java/src/common/rng/SimplexGen.java index f29c828..a1f3b20 100755 --- a/java/src/game/rng/SimplexGen.java +++ b/java/src/common/rng/SimplexGen.java @@ -1,4 +1,4 @@ -package game.rng; +package common.rng; class SimplexGen { private static final int[][] DIRS = new int[][] { { 1, 1, 0 }, { -1, 1, 0 }, { 1, -1, 0 }, { -1, -1, 0 }, { 1, 0, 1 }, { -1, 0, 1 }, { 1, 0, -1 }, diff --git a/java/src/game/rng/SimplexGenOld.java b/java/src/common/rng/SimplexGenOld.java similarity index 95% rename from java/src/game/rng/SimplexGenOld.java rename to java/src/common/rng/SimplexGenOld.java index 3ac1dd2..e597895 100755 --- a/java/src/game/rng/SimplexGenOld.java +++ b/java/src/common/rng/SimplexGenOld.java @@ -1,4 +1,4 @@ -package game.rng; +package common.rng; class SimplexGenOld { private static final int DIRS[][] = { { 1, 1, 0 }, { -1, 1, 0 }, { 1, -1, 0 }, { -1, -1, 0 }, { 1, 0, 1 }, { -1, 0, 1 }, { 1, 0, -1 }, diff --git a/java/src/game/rng/WeightedList.java b/java/src/common/rng/WeightedList.java similarity index 99% rename from java/src/game/rng/WeightedList.java rename to java/src/common/rng/WeightedList.java index 575c324..2eb9f3e 100755 --- a/java/src/game/rng/WeightedList.java +++ b/java/src/common/rng/WeightedList.java @@ -1,4 +1,4 @@ -package game.rng; +package common.rng; import java.util.ArrayList; import java.util.Collection; diff --git a/java/src/game/sound/EventType.java b/java/src/common/sound/EventType.java similarity index 71% rename from java/src/game/sound/EventType.java rename to java/src/common/sound/EventType.java index e234d21..5028abc 100644 --- a/java/src/game/sound/EventType.java +++ b/java/src/common/sound/EventType.java @@ -1,4 +1,4 @@ -package game.sound; +package common.sound; public enum EventType { SOUND_EFFECT, UI_INTERFACE; diff --git a/java/src/game/sound/MovingSound.java b/java/src/common/sound/MovingSound.java similarity index 84% rename from java/src/game/sound/MovingSound.java rename to java/src/common/sound/MovingSound.java index c3f5fc9..b8dc64c 100755 --- a/java/src/game/sound/MovingSound.java +++ b/java/src/common/sound/MovingSound.java @@ -1,6 +1,6 @@ -package game.sound; +package common.sound; -import game.init.SoundEvent; +import common.init.SoundEvent; public abstract class MovingSound extends Sound { diff --git a/java/src/game/sound/MovingSoundMinecart.java b/java/src/common/sound/MovingSoundMinecart.java similarity index 90% rename from java/src/game/sound/MovingSoundMinecart.java rename to java/src/common/sound/MovingSoundMinecart.java index aa4f110..605044b 100755 --- a/java/src/game/sound/MovingSoundMinecart.java +++ b/java/src/common/sound/MovingSoundMinecart.java @@ -1,8 +1,8 @@ -package game.sound; +package common.sound; -import game.entity.item.EntityCart; -import game.init.SoundEvent; -import game.util.ExtMath; +import common.entity.item.EntityCart; +import common.init.SoundEvent; +import common.util.ExtMath; public class MovingSoundMinecart extends MovingSound { diff --git a/java/src/game/sound/MovingSoundMinecartRiding.java b/java/src/common/sound/MovingSoundMinecartRiding.java similarity index 87% rename from java/src/game/sound/MovingSoundMinecartRiding.java rename to java/src/common/sound/MovingSoundMinecartRiding.java index 42ba8be..ec4c6ab 100755 --- a/java/src/game/sound/MovingSoundMinecartRiding.java +++ b/java/src/common/sound/MovingSoundMinecartRiding.java @@ -1,9 +1,9 @@ -package game.sound; +package common.sound; -import game.entity.item.EntityCart; -import game.entity.npc.EntityNPC; -import game.init.SoundEvent; -import game.util.ExtMath; +import common.entity.item.EntityCart; +import common.entity.npc.EntityNPC; +import common.init.SoundEvent; +import common.util.ExtMath; public class MovingSoundMinecartRiding extends MovingSound { diff --git a/java/src/game/sound/PositionedSound.java b/java/src/common/sound/PositionedSound.java similarity index 92% rename from java/src/game/sound/PositionedSound.java rename to java/src/common/sound/PositionedSound.java index ff4a221..86a76c9 100755 --- a/java/src/game/sound/PositionedSound.java +++ b/java/src/common/sound/PositionedSound.java @@ -1,6 +1,6 @@ -package game.sound; +package common.sound; -import game.init.SoundEvent; +import common.init.SoundEvent; public class PositionedSound extends Sound { public PositionedSound(SoundEvent event, EventType type) { diff --git a/java/src/game/sound/Sound.java b/java/src/common/sound/Sound.java similarity index 94% rename from java/src/game/sound/Sound.java rename to java/src/common/sound/Sound.java index fb4247f..d7b8477 100755 --- a/java/src/game/sound/Sound.java +++ b/java/src/common/sound/Sound.java @@ -1,6 +1,6 @@ -package game.sound; +package common.sound; -import game.init.SoundEvent; +import common.init.SoundEvent; public abstract class Sound { diff --git a/java/src/game/tileentity/IHopper.java b/java/src/common/tileentity/IHopper.java similarity index 82% rename from java/src/game/tileentity/IHopper.java rename to java/src/common/tileentity/IHopper.java index 0990c7a..a314d15 100755 --- a/java/src/game/tileentity/IHopper.java +++ b/java/src/common/tileentity/IHopper.java @@ -1,7 +1,7 @@ -package game.tileentity; +package common.tileentity; -import game.inventory.IInventory; -import game.world.World; +import common.inventory.IInventory; +import common.world.World; public interface IHopper extends IInventory { diff --git a/java/src/game/tileentity/IInteractionObject.java b/java/src/common/tileentity/IInteractionObject.java similarity index 55% rename from java/src/game/tileentity/IInteractionObject.java rename to java/src/common/tileentity/IInteractionObject.java index 5b273e6..fc0e98e 100755 --- a/java/src/game/tileentity/IInteractionObject.java +++ b/java/src/common/tileentity/IInteractionObject.java @@ -1,8 +1,8 @@ -package game.tileentity; +package common.tileentity; -import game.entity.npc.EntityNPC; -import game.inventory.Container; -import game.inventory.InventoryPlayer; +import common.entity.npc.EntityNPC; +import common.inventory.Container; +import common.inventory.InventoryPlayer; public interface IInteractionObject extends IWorldNameable { diff --git a/java/src/game/tileentity/ILockableContainer.java b/java/src/common/tileentity/ILockableContainer.java similarity index 73% rename from java/src/game/tileentity/ILockableContainer.java rename to java/src/common/tileentity/ILockableContainer.java index 54e6125..df4cbca 100755 --- a/java/src/game/tileentity/ILockableContainer.java +++ b/java/src/common/tileentity/ILockableContainer.java @@ -1,6 +1,6 @@ -package game.tileentity; +package common.tileentity; -import game.inventory.IInventory; +import common.inventory.IInventory; public interface ILockableContainer extends IInventory, IInteractionObject { diff --git a/java/src/game/tileentity/ITickable.java b/java/src/common/tileentity/ITickable.java similarity index 65% rename from java/src/game/tileentity/ITickable.java rename to java/src/common/tileentity/ITickable.java index 65c97a4..7227b5e 100755 --- a/java/src/game/tileentity/ITickable.java +++ b/java/src/common/tileentity/ITickable.java @@ -1,4 +1,4 @@ -package game.tileentity; +package common.tileentity; public interface ITickable { diff --git a/java/src/game/tileentity/IWorldNameable.java b/java/src/common/tileentity/IWorldNameable.java similarity index 70% rename from java/src/game/tileentity/IWorldNameable.java rename to java/src/common/tileentity/IWorldNameable.java index 48d70eb..4fa737b 100755 --- a/java/src/game/tileentity/IWorldNameable.java +++ b/java/src/common/tileentity/IWorldNameable.java @@ -1,4 +1,4 @@ -package game.tileentity; +package common.tileentity; public interface IWorldNameable { diff --git a/java/src/game/tileentity/LocalBlockIntercommunication.java b/java/src/common/tileentity/LocalBlockIntercommunication.java similarity index 87% rename from java/src/game/tileentity/LocalBlockIntercommunication.java rename to java/src/common/tileentity/LocalBlockIntercommunication.java index 7c1d406..caa5a25 100755 --- a/java/src/game/tileentity/LocalBlockIntercommunication.java +++ b/java/src/common/tileentity/LocalBlockIntercommunication.java @@ -1,8 +1,8 @@ -package game.tileentity; +package common.tileentity; -import game.entity.npc.EntityNPC; -import game.inventory.Container; -import game.inventory.InventoryPlayer; +import common.entity.npc.EntityNPC; +import common.inventory.Container; +import common.inventory.InventoryPlayer; public class LocalBlockIntercommunication implements IInteractionObject { diff --git a/java/src/game/tileentity/LockCode.java b/java/src/common/tileentity/LockCode.java similarity index 92% rename from java/src/game/tileentity/LockCode.java rename to java/src/common/tileentity/LockCode.java index 39b276e..cc8da4e 100755 --- a/java/src/game/tileentity/LockCode.java +++ b/java/src/common/tileentity/LockCode.java @@ -1,6 +1,6 @@ -package game.tileentity; +package common.tileentity; -import game.nbt.NBTTagCompound; +import common.nbt.NBTTagCompound; public class LockCode { diff --git a/java/src/game/tileentity/MachineResource.java b/java/src/common/tileentity/MachineResource.java similarity index 97% rename from java/src/game/tileentity/MachineResource.java rename to java/src/common/tileentity/MachineResource.java index 72390f1..07075bd 100755 --- a/java/src/game/tileentity/MachineResource.java +++ b/java/src/common/tileentity/MachineResource.java @@ -1,6 +1,6 @@ -package game.tileentity; +package common.tileentity; -import game.nbt.NBTTagCompound; +import common.nbt.NBTTagCompound; public class MachineResource { public static enum Type { diff --git a/java/src/game/tileentity/TileEntity.java b/java/src/common/tileentity/TileEntity.java similarity index 94% rename from java/src/game/tileentity/TileEntity.java rename to java/src/common/tileentity/TileEntity.java index 8b25565..ea72613 100755 --- a/java/src/game/tileentity/TileEntity.java +++ b/java/src/common/tileentity/TileEntity.java @@ -1,14 +1,14 @@ -package game.tileentity; +package common.tileentity; -import game.block.Block; -import game.init.Blocks; -import game.init.TileRegistry; -import game.log.Log; -import game.nbt.NBTTagCompound; -import game.network.Packet; -import game.world.BlockPos; -import game.world.State; -import game.world.World; +import common.block.Block; +import common.init.Blocks; +import common.init.TileRegistry; +import common.log.Log; +import common.nbt.NBTTagCompound; +import common.network.Packet; +import common.world.BlockPos; +import common.world.State; +import common.world.World; public abstract class TileEntity { diff --git a/java/src/game/tileentity/TileEntityBanner.java b/java/src/common/tileentity/TileEntityBanner.java similarity index 97% rename from java/src/game/tileentity/TileEntityBanner.java rename to java/src/common/tileentity/TileEntityBanner.java index 24b8210..90e0668 100755 --- a/java/src/game/tileentity/TileEntityBanner.java +++ b/java/src/common/tileentity/TileEntityBanner.java @@ -1,17 +1,17 @@ -package game.tileentity; +package common.tileentity; import java.util.List; -import game.block.BlockFlower; -import game.collect.Lists; -import game.color.DyeColor; -import game.init.Blocks; -import game.init.Items; -import game.item.ItemStack; -import game.nbt.NBTTagCompound; -import game.nbt.NBTTagList; -import game.network.Packet; -import game.packet.S35PacketUpdateTileEntity; +import common.block.BlockFlower; +import common.collect.Lists; +import common.color.DyeColor; +import common.init.Blocks; +import common.init.Items; +import common.item.ItemStack; +import common.nbt.NBTTagCompound; +import common.nbt.NBTTagList; +import common.network.Packet; +import common.packet.S35PacketUpdateTileEntity; public class TileEntityBanner extends TileEntity { diff --git a/java/src/game/tileentity/TileEntityBeacon.java b/java/src/common/tileentity/TileEntityBeacon.java similarity index 97% rename from java/src/game/tileentity/TileEntityBeacon.java rename to java/src/common/tileentity/TileEntityBeacon.java index 6b57ffa..23ecca3 100755 --- a/java/src/game/tileentity/TileEntityBeacon.java +++ b/java/src/common/tileentity/TileEntityBeacon.java @@ -1,21 +1,21 @@ -package game.tileentity; +package common.tileentity; import java.util.List; -import game.block.Block; -import game.color.DyeColor; -import game.entity.types.EntityLiving; -import game.init.Blocks; -import game.nbt.NBTTagCompound; -import game.network.Packet; -import game.packet.S35PacketUpdateTileEntity; -import game.potion.Potion; -import game.potion.PotionEffect; -import game.world.BlockPos; -import game.world.BoundingBox; -import game.world.State; -import game.world.World; -import game.world.WorldServer; +import common.block.Block; +import common.color.DyeColor; +import common.entity.types.EntityLiving; +import common.init.Blocks; +import common.nbt.NBTTagCompound; +import common.network.Packet; +import common.packet.S35PacketUpdateTileEntity; +import common.potion.Potion; +import common.potion.PotionEffect; +import common.world.BlockPos; +import common.world.BoundingBox; +import common.world.State; +import common.world.World; +import common.world.WorldServer; public class TileEntityBeacon extends TileEntity implements ITickable { diff --git a/java/src/game/tileentity/TileEntityBrewingStand.java b/java/src/common/tileentity/TileEntityBrewingStand.java similarity index 95% rename from java/src/game/tileentity/TileEntityBrewingStand.java rename to java/src/common/tileentity/TileEntityBrewingStand.java index c24d117..8af4271 100755 --- a/java/src/game/tileentity/TileEntityBrewingStand.java +++ b/java/src/common/tileentity/TileEntityBrewingStand.java @@ -1,24 +1,24 @@ -package game.tileentity; +package common.tileentity; import java.util.Arrays; import java.util.List; -import game.block.BlockBrewingStand; -import game.entity.npc.EntityNPC; -import game.init.Items; -import game.inventory.Container; -import game.inventory.ContainerBrewingStand; -import game.inventory.ISidedInventory; -import game.inventory.InventoryPlayer; -import game.item.Item; -import game.item.ItemPotion; -import game.item.ItemStack; -import game.nbt.NBTTagCompound; -import game.nbt.NBTTagList; -import game.potion.PotionEffect; -import game.potion.PotionHelper; -import game.world.Facing; -import game.world.State; +import common.block.BlockBrewingStand; +import common.entity.npc.EntityNPC; +import common.init.Items; +import common.inventory.Container; +import common.inventory.ContainerBrewingStand; +import common.inventory.ISidedInventory; +import common.inventory.InventoryPlayer; +import common.item.Item; +import common.item.ItemPotion; +import common.item.ItemStack; +import common.nbt.NBTTagCompound; +import common.nbt.NBTTagList; +import common.potion.PotionEffect; +import common.potion.PotionHelper; +import common.world.Facing; +import common.world.State; public class TileEntityBrewingStand extends TileEntityLockable implements ITickable, ISidedInventory { diff --git a/java/src/game/tileentity/TileEntityChest.java b/java/src/common/tileentity/TileEntityChest.java similarity index 96% rename from java/src/game/tileentity/TileEntityChest.java rename to java/src/common/tileentity/TileEntityChest.java index e0481a8..c1e465f 100755 --- a/java/src/game/tileentity/TileEntityChest.java +++ b/java/src/common/tileentity/TileEntityChest.java @@ -1,20 +1,20 @@ -package game.tileentity; +package common.tileentity; -import game.block.Block; -import game.block.BlockChest; -import game.entity.npc.EntityNPC; -import game.init.SoundEvent; -import game.inventory.Container; -import game.inventory.ContainerChest; -import game.inventory.IInventory; -import game.inventory.InventoryLargeChest; -import game.inventory.InventoryPlayer; -import game.item.ItemStack; -import game.nbt.NBTTagCompound; -import game.nbt.NBTTagList; -import game.world.BlockPos; -import game.world.BoundingBox; -import game.world.Facing; +import common.block.Block; +import common.block.BlockChest; +import common.entity.npc.EntityNPC; +import common.init.SoundEvent; +import common.inventory.Container; +import common.inventory.ContainerChest; +import common.inventory.IInventory; +import common.inventory.InventoryLargeChest; +import common.inventory.InventoryPlayer; +import common.item.ItemStack; +import common.nbt.NBTTagCompound; +import common.nbt.NBTTagList; +import common.world.BlockPos; +import common.world.BoundingBox; +import common.world.Facing; public class TileEntityChest extends TileEntityLockable implements ITickable, IInventory { diff --git a/java/src/game/tileentity/TileEntityComparator.java b/java/src/common/tileentity/TileEntityComparator.java similarity index 91% rename from java/src/game/tileentity/TileEntityComparator.java rename to java/src/common/tileentity/TileEntityComparator.java index 4506c20..55b488d 100755 --- a/java/src/game/tileentity/TileEntityComparator.java +++ b/java/src/common/tileentity/TileEntityComparator.java @@ -1,6 +1,6 @@ -package game.tileentity; +package common.tileentity; -import game.nbt.NBTTagCompound; +import common.nbt.NBTTagCompound; public class TileEntityComparator extends TileEntity { diff --git a/java/src/game/tileentity/TileEntityDaylightDetector.java b/java/src/common/tileentity/TileEntityDaylightDetector.java similarity index 86% rename from java/src/game/tileentity/TileEntityDaylightDetector.java rename to java/src/common/tileentity/TileEntityDaylightDetector.java index 493f01c..02ca54d 100755 --- a/java/src/game/tileentity/TileEntityDaylightDetector.java +++ b/java/src/common/tileentity/TileEntityDaylightDetector.java @@ -1,7 +1,7 @@ -package game.tileentity; +package common.tileentity; -import game.block.BlockDaylightDetector; -import game.world.WorldServer; +import common.block.BlockDaylightDetector; +import common.world.WorldServer; public class TileEntityDaylightDetector extends TileEntity implements ITickable { diff --git a/java/src/game/tileentity/TileEntityDispenser.java b/java/src/common/tileentity/TileEntityDispenser.java similarity index 94% rename from java/src/game/tileentity/TileEntityDispenser.java rename to java/src/common/tileentity/TileEntityDispenser.java index c903470..d7910b0 100755 --- a/java/src/game/tileentity/TileEntityDispenser.java +++ b/java/src/common/tileentity/TileEntityDispenser.java @@ -1,14 +1,14 @@ -package game.tileentity; +package common.tileentity; -import game.entity.npc.EntityNPC; -import game.inventory.Container; -import game.inventory.ContainerDispenser; -import game.inventory.IInventory; -import game.inventory.InventoryPlayer; -import game.item.ItemStack; -import game.nbt.NBTTagCompound; -import game.nbt.NBTTagList; -import game.rng.Random; +import common.entity.npc.EntityNPC; +import common.inventory.Container; +import common.inventory.ContainerDispenser; +import common.inventory.IInventory; +import common.inventory.InventoryPlayer; +import common.item.ItemStack; +import common.nbt.NBTTagCompound; +import common.nbt.NBTTagList; +import common.rng.Random; public class TileEntityDispenser extends TileEntityLockable implements IInventory { diff --git a/java/src/game/tileentity/TileEntityDropper.java b/java/src/common/tileentity/TileEntityDropper.java similarity index 92% rename from java/src/game/tileentity/TileEntityDropper.java rename to java/src/common/tileentity/TileEntityDropper.java index e33a09e..7842d1a 100755 --- a/java/src/game/tileentity/TileEntityDropper.java +++ b/java/src/common/tileentity/TileEntityDropper.java @@ -1,4 +1,4 @@ -package game.tileentity; +package common.tileentity; public class TileEntityDropper extends TileEntityDispenser { diff --git a/java/src/game/tileentity/TileEntityEnchantmentTable.java b/java/src/common/tileentity/TileEntityEnchantmentTable.java similarity index 94% rename from java/src/game/tileentity/TileEntityEnchantmentTable.java rename to java/src/common/tileentity/TileEntityEnchantmentTable.java index 8e18c65..b3ae645 100755 --- a/java/src/game/tileentity/TileEntityEnchantmentTable.java +++ b/java/src/common/tileentity/TileEntityEnchantmentTable.java @@ -1,12 +1,12 @@ -package game.tileentity; +package common.tileentity; -import game.entity.npc.EntityNPC; -import game.inventory.Container; -import game.inventory.ContainerEnchantment; -import game.inventory.InventoryPlayer; -import game.nbt.NBTTagCompound; -import game.rng.Random; -import game.util.ExtMath; +import common.entity.npc.EntityNPC; +import common.inventory.Container; +import common.inventory.ContainerEnchantment; +import common.inventory.InventoryPlayer; +import common.nbt.NBTTagCompound; +import common.rng.Random; +import common.util.ExtMath; public class TileEntityEnchantmentTable extends TileEntity implements ITickable, IInteractionObject { diff --git a/java/src/game/tileentity/TileEntityFurnace.java b/java/src/common/tileentity/TileEntityFurnace.java similarity index 94% rename from java/src/game/tileentity/TileEntityFurnace.java rename to java/src/common/tileentity/TileEntityFurnace.java index a7225f7..f2dae36 100755 --- a/java/src/game/tileentity/TileEntityFurnace.java +++ b/java/src/common/tileentity/TileEntityFurnace.java @@ -1,32 +1,32 @@ -package game.tileentity; +package common.tileentity; -import game.block.Block; -import game.block.BlockFurnace; -import game.block.BlockSapling; -import game.block.BlockSlab; -import game.entity.npc.EntityNPC; -import game.init.Blocks; -import game.init.Items; -import game.init.SmeltingRegistry; -import game.init.ToolType; -import game.inventory.Container; -import game.inventory.ContainerFurnace; -import game.inventory.IInventory; -import game.inventory.ISidedInventory; -import game.inventory.InventoryPlayer; -import game.inventory.SlotFurnaceFuel; -import game.item.Item; -import game.item.ItemBlock; -import game.item.ItemBucket; -import game.item.ItemHoe; -import game.item.ItemStack; -import game.item.ItemSword; -import game.item.ItemTool; -import game.material.Material; -import game.nbt.NBTTagCompound; -import game.nbt.NBTTagList; -import game.util.ExtMath; -import game.world.Facing; +import common.block.Block; +import common.block.BlockFurnace; +import common.block.BlockSapling; +import common.block.BlockSlab; +import common.entity.npc.EntityNPC; +import common.init.Blocks; +import common.init.Items; +import common.init.SmeltingRegistry; +import common.init.ToolType; +import common.inventory.Container; +import common.inventory.ContainerFurnace; +import common.inventory.IInventory; +import common.inventory.ISidedInventory; +import common.inventory.InventoryPlayer; +import common.inventory.SlotFurnaceFuel; +import common.item.Item; +import common.item.ItemBlock; +import common.item.ItemBucket; +import common.item.ItemHoe; +import common.item.ItemStack; +import common.item.ItemSword; +import common.item.ItemTool; +import common.material.Material; +import common.nbt.NBTTagCompound; +import common.nbt.NBTTagList; +import common.util.ExtMath; +import common.world.Facing; public class TileEntityFurnace extends TileEntityLockable implements ITickable, ISidedInventory { diff --git a/java/src/game/tileentity/TileEntityHopper.java b/java/src/common/tileentity/TileEntityHopper.java similarity index 96% rename from java/src/game/tileentity/TileEntityHopper.java rename to java/src/common/tileentity/TileEntityHopper.java index 80d75de..736bc88 100755 --- a/java/src/game/tileentity/TileEntityHopper.java +++ b/java/src/common/tileentity/TileEntityHopper.java @@ -1,28 +1,28 @@ -package game.tileentity; +package common.tileentity; import java.util.List; import java.util.function.Predicate; -import game.block.Block; -import game.block.BlockChest; -import game.block.BlockHopper; -import game.entity.Entity; -import game.entity.item.EntityItem; -import game.entity.npc.EntityNPC; -import game.init.Config; -import game.inventory.Container; -import game.inventory.ContainerHopper; -import game.inventory.IInventory; -import game.inventory.ISidedInventory; -import game.inventory.InventoryPlayer; -import game.item.ItemStack; -import game.nbt.NBTTagCompound; -import game.nbt.NBTTagList; -import game.util.ExtMath; -import game.world.BlockPos; -import game.world.BoundingBox; -import game.world.Facing; -import game.world.World; +import common.block.Block; +import common.block.BlockChest; +import common.block.BlockHopper; +import common.entity.Entity; +import common.entity.item.EntityItem; +import common.entity.npc.EntityNPC; +import common.init.Config; +import common.inventory.Container; +import common.inventory.ContainerHopper; +import common.inventory.IInventory; +import common.inventory.ISidedInventory; +import common.inventory.InventoryPlayer; +import common.item.ItemStack; +import common.nbt.NBTTagCompound; +import common.nbt.NBTTagList; +import common.util.ExtMath; +import common.world.BlockPos; +import common.world.BoundingBox; +import common.world.Facing; +import common.world.World; public class TileEntityHopper extends TileEntityLockable implements IHopper, ITickable { diff --git a/java/src/game/tileentity/TileEntityLockable.java b/java/src/common/tileentity/TileEntityLockable.java similarity index 94% rename from java/src/game/tileentity/TileEntityLockable.java rename to java/src/common/tileentity/TileEntityLockable.java index 5b9a1ea..64bb470 100755 --- a/java/src/game/tileentity/TileEntityLockable.java +++ b/java/src/common/tileentity/TileEntityLockable.java @@ -1,6 +1,6 @@ -package game.tileentity; +package common.tileentity; -import game.nbt.NBTTagCompound; +import common.nbt.NBTTagCompound; public abstract class TileEntityLockable extends TileEntity implements IInteractionObject, ILockableContainer { diff --git a/java/src/game/tileentity/TileEntityMachine.java b/java/src/common/tileentity/TileEntityMachine.java similarity index 94% rename from java/src/game/tileentity/TileEntityMachine.java rename to java/src/common/tileentity/TileEntityMachine.java index 367afb6..45d9d6b 100755 --- a/java/src/game/tileentity/TileEntityMachine.java +++ b/java/src/common/tileentity/TileEntityMachine.java @@ -1,17 +1,17 @@ -package game.tileentity; +package common.tileentity; -import game.color.TextColor; -import game.entity.npc.EntityNPC; -import game.inventory.Container; -import game.inventory.ContainerMachine; -import game.inventory.InventoryPlayer; -import game.item.ItemStack; -import game.nbt.NBTTagCompound; -import game.nbt.NBTTagList; -import game.network.Packet; -import game.packet.S35PacketUpdateTileEntity; -import game.rng.Random; -import game.util.ExtMath; +import common.color.TextColor; +import common.entity.npc.EntityNPC; +import common.inventory.Container; +import common.inventory.ContainerMachine; +import common.inventory.InventoryPlayer; +import common.item.ItemStack; +import common.nbt.NBTTagCompound; +import common.nbt.NBTTagList; +import common.network.Packet; +import common.packet.S35PacketUpdateTileEntity; +import common.rng.Random; +import common.util.ExtMath; public abstract class TileEntityMachine extends TileEntityLockable implements IHopper, ITickable { public static enum Status { diff --git a/java/src/game/tileentity/TileEntityMobSpawner.java b/java/src/common/tileentity/TileEntityMobSpawner.java similarity index 94% rename from java/src/game/tileentity/TileEntityMobSpawner.java rename to java/src/common/tileentity/TileEntityMobSpawner.java index e8a8765..1105fa3 100755 --- a/java/src/game/tileentity/TileEntityMobSpawner.java +++ b/java/src/common/tileentity/TileEntityMobSpawner.java @@ -1,17 +1,17 @@ -package game.tileentity; +package common.tileentity; -import game.entity.Entity; -import game.entity.types.EntityLiving; -import game.init.Blocks; -import game.init.Config; -import game.init.EntityRegistry; -import game.model.ParticleType; -import game.nbt.NBTTagCompound; -import game.network.Packet; -import game.packet.S35PacketUpdateTileEntity; -import game.world.BlockPos; -import game.world.BoundingBox; -import game.world.World; +import common.entity.Entity; +import common.entity.types.EntityLiving; +import common.init.Blocks; +import common.init.Config; +import common.init.EntityRegistry; +import common.model.ParticleType; +import common.nbt.NBTTagCompound; +import common.network.Packet; +import common.packet.S35PacketUpdateTileEntity; +import common.world.BlockPos; +import common.world.BoundingBox; +import common.world.World; public class TileEntityMobSpawner extends TileEntity implements ITickable { diff --git a/java/src/game/tileentity/TileEntityNote.java b/java/src/common/tileentity/TileEntityNote.java similarity index 88% rename from java/src/game/tileentity/TileEntityNote.java rename to java/src/common/tileentity/TileEntityNote.java index ee2bf52..c3d4238 100755 --- a/java/src/game/tileentity/TileEntityNote.java +++ b/java/src/common/tileentity/TileEntityNote.java @@ -1,11 +1,11 @@ -package game.tileentity; +package common.tileentity; -import game.init.Blocks; -import game.material.Material; -import game.nbt.NBTTagCompound; -import game.util.ExtMath; -import game.world.BlockPos; -import game.world.World; +import common.init.Blocks; +import common.material.Material; +import common.nbt.NBTTagCompound; +import common.util.ExtMath; +import common.world.BlockPos; +import common.world.World; public class TileEntityNote extends TileEntity { diff --git a/java/src/game/tileentity/TileEntityPiston.java b/java/src/common/tileentity/TileEntityPiston.java similarity index 96% rename from java/src/game/tileentity/TileEntityPiston.java rename to java/src/common/tileentity/TileEntityPiston.java index 98fdb26..e84301f 100755 --- a/java/src/game/tileentity/TileEntityPiston.java +++ b/java/src/common/tileentity/TileEntityPiston.java @@ -1,15 +1,15 @@ -package game.tileentity; +package common.tileentity; import java.util.List; -import game.collect.Lists; -import game.entity.Entity; -import game.init.BlockRegistry; -import game.init.Blocks; -import game.nbt.NBTTagCompound; -import game.world.BoundingBox; -import game.world.Facing; -import game.world.State; +import common.collect.Lists; +import common.entity.Entity; +import common.init.BlockRegistry; +import common.init.Blocks; +import common.nbt.NBTTagCompound; +import common.world.BoundingBox; +import common.world.Facing; +import common.world.State; public class TileEntityPiston extends TileEntity implements ITickable { diff --git a/java/src/game/tileentity/TileEntitySign.java b/java/src/common/tileentity/TileEntitySign.java similarity index 95% rename from java/src/game/tileentity/TileEntitySign.java rename to java/src/common/tileentity/TileEntitySign.java index b0b9fa7..4c5301a 100755 --- a/java/src/game/tileentity/TileEntitySign.java +++ b/java/src/common/tileentity/TileEntitySign.java @@ -1,9 +1,9 @@ -package game.tileentity; +package common.tileentity; -import game.entity.npc.EntityNPC; -import game.nbt.NBTTagCompound; -import game.network.Packet; -import game.packet.S33PacketUpdateSign; +import common.entity.npc.EntityNPC; +import common.nbt.NBTTagCompound; +import common.network.Packet; +import common.packet.S33PacketUpdateSign; public class TileEntitySign extends TileEntity { public final String[] signText = new String[] {"", "", "", ""}; diff --git a/java/src/game/tileentity/TileEntitySkull.java b/java/src/common/tileentity/TileEntitySkull.java similarity index 91% rename from java/src/game/tileentity/TileEntitySkull.java rename to java/src/common/tileentity/TileEntitySkull.java index 66becb1..48f9349 100755 --- a/java/src/game/tileentity/TileEntitySkull.java +++ b/java/src/common/tileentity/TileEntitySkull.java @@ -1,8 +1,8 @@ -package game.tileentity; +package common.tileentity; -import game.nbt.NBTTagCompound; -import game.network.Packet; -import game.packet.S35PacketUpdateTileEntity; +import common.nbt.NBTTagCompound; +import common.network.Packet; +import common.packet.S35PacketUpdateTileEntity; public class TileEntitySkull extends TileEntity { diff --git a/java/src/game/tileentity/TileEntityTianReactor.java b/java/src/common/tileentity/TileEntityTianReactor.java similarity index 88% rename from java/src/game/tileentity/TileEntityTianReactor.java rename to java/src/common/tileentity/TileEntityTianReactor.java index 6896773..b2d4939 100755 --- a/java/src/game/tileentity/TileEntityTianReactor.java +++ b/java/src/common/tileentity/TileEntityTianReactor.java @@ -1,10 +1,10 @@ -package game.tileentity; +package common.tileentity; -import game.init.Blocks; -import game.init.ItemRegistry; -import game.init.Items; -import game.item.ItemStack; -import game.tileentity.MachineResource.Type; +import common.init.Blocks; +import common.init.ItemRegistry; +import common.init.Items; +import common.item.ItemStack; +import common.tileentity.MachineResource.Type; public class TileEntityTianReactor extends TileEntityMachine { public TileEntityTianReactor() { diff --git a/java/src/game/util/CharValidator.java b/java/src/common/util/CharValidator.java similarity index 95% rename from java/src/game/util/CharValidator.java rename to java/src/common/util/CharValidator.java index 2a22181..e2c8407 100644 --- a/java/src/game/util/CharValidator.java +++ b/java/src/common/util/CharValidator.java @@ -1,4 +1,4 @@ -package game.util; +package common.util; public interface CharValidator { boolean valid(char ch); diff --git a/java/src/game/util/DC32.java b/java/src/common/util/DC32.java similarity index 99% rename from java/src/game/util/DC32.java rename to java/src/common/util/DC32.java index 2a22138..1e40cc4 100644 --- a/java/src/game/util/DC32.java +++ b/java/src/common/util/DC32.java @@ -1,4 +1,4 @@ -package game.util; +package common.util; public class DC32 { public static final byte[] ASCII = { // 0x1f -> AUX1 diff --git a/java/src/game/util/Displayable.java b/java/src/common/util/Displayable.java similarity index 75% rename from java/src/game/util/Displayable.java rename to java/src/common/util/Displayable.java index 376ddff..90f83e5 100644 --- a/java/src/game/util/Displayable.java +++ b/java/src/common/util/Displayable.java @@ -1,4 +1,4 @@ -package game.util; +package common.util; public interface Displayable { public String getDisplay(); diff --git a/java/src/game/util/ExtMath.java b/java/src/common/util/ExtMath.java similarity index 99% rename from java/src/game/util/ExtMath.java rename to java/src/common/util/ExtMath.java index be7b98b..2554a03 100755 --- a/java/src/game/util/ExtMath.java +++ b/java/src/common/util/ExtMath.java @@ -1,4 +1,4 @@ -package game.util; +package common.util; public abstract class ExtMath { private static final float[] SIN_TABLE = new float[65536]; diff --git a/java/src/game/util/FileUtils.java b/java/src/common/util/FileUtils.java similarity index 97% rename from java/src/game/util/FileUtils.java rename to java/src/common/util/FileUtils.java index b2b86d2..5c01c4b 100644 --- a/java/src/game/util/FileUtils.java +++ b/java/src/common/util/FileUtils.java @@ -1,4 +1,4 @@ -package game.util; +package common.util; import java.io.ByteArrayOutputStream; import java.io.File; @@ -8,7 +8,7 @@ import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; -import game.log.Log; +import common.log.Log; import io.netty.util.CharsetUtil; public class FileUtils { diff --git a/java/src/game/util/Identifyable.java b/java/src/common/util/Identifyable.java similarity index 73% rename from java/src/game/util/Identifyable.java rename to java/src/common/util/Identifyable.java index 03fa092..11dee69 100755 --- a/java/src/game/util/Identifyable.java +++ b/java/src/common/util/Identifyable.java @@ -1,4 +1,4 @@ -package game.util; +package common.util; public interface Identifyable { diff --git a/java/src/game/util/LazyLoadBase.java b/java/src/common/util/LazyLoadBase.java similarity index 93% rename from java/src/game/util/LazyLoadBase.java rename to java/src/common/util/LazyLoadBase.java index d40c4e7..11e3858 100755 --- a/java/src/game/util/LazyLoadBase.java +++ b/java/src/common/util/LazyLoadBase.java @@ -1,4 +1,4 @@ -package game.util; +package common.util; public abstract class LazyLoadBase { diff --git a/java/src/game/util/Matrix4f.java b/java/src/common/util/Matrix4f.java similarity index 99% rename from java/src/game/util/Matrix4f.java rename to java/src/common/util/Matrix4f.java index 813d579..8e61925 100644 --- a/java/src/game/util/Matrix4f.java +++ b/java/src/common/util/Matrix4f.java @@ -29,7 +29,7 @@ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package game.util; +package common.util; import java.io.Serializable; import java.nio.FloatBuffer; diff --git a/java/src/game/util/Predicates.java b/java/src/common/util/Predicates.java similarity index 99% rename from java/src/game/util/Predicates.java rename to java/src/common/util/Predicates.java index 6bdfe63..4570723 100644 --- a/java/src/game/util/Predicates.java +++ b/java/src/common/util/Predicates.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package game.util; +package common.util; import java.io.Serializable; import java.util.ArrayList; diff --git a/java/src/game/util/Tuple.java b/java/src/common/util/Tuple.java similarity index 88% rename from java/src/game/util/Tuple.java rename to java/src/common/util/Tuple.java index f41da46..20a5a73 100644 --- a/java/src/game/util/Tuple.java +++ b/java/src/common/util/Tuple.java @@ -1,4 +1,4 @@ -package game.util; +package common.util; public class Tuple { public final S first; diff --git a/java/src/game/util/Util.java b/java/src/common/util/Util.java similarity index 99% rename from java/src/game/util/Util.java rename to java/src/common/util/Util.java index 92704a1..e66fb25 100644 --- a/java/src/game/util/Util.java +++ b/java/src/common/util/Util.java @@ -1,4 +1,4 @@ -package game.util; +package common.util; import java.awt.GraphicsEnvironment; import java.util.List; @@ -7,9 +7,9 @@ import java.util.function.Function; import javax.swing.JOptionPane; -import game.collect.Lists; -import game.collect.Maps; -import game.log.Log; +import common.collect.Lists; +import common.collect.Maps; +import common.log.Log; public abstract class Util { private static long start = getTime(); diff --git a/java/src/game/util/Vector.java b/java/src/common/util/Vector.java similarity index 99% rename from java/src/game/util/Vector.java rename to java/src/common/util/Vector.java index 4e2385a..2388ca6 100644 --- a/java/src/game/util/Vector.java +++ b/java/src/common/util/Vector.java @@ -29,7 +29,7 @@ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package game.util; +package common.util; import java.io.Serializable; import java.nio.FloatBuffer; diff --git a/java/src/game/util/Vector3f.java b/java/src/common/util/Vector3f.java similarity index 99% rename from java/src/game/util/Vector3f.java rename to java/src/common/util/Vector3f.java index e9f56db..cab132d 100644 --- a/java/src/game/util/Vector3f.java +++ b/java/src/common/util/Vector3f.java @@ -29,7 +29,7 @@ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package game.util; +package common.util; import java.io.Serializable; import java.nio.FloatBuffer; diff --git a/java/src/game/util/Vector4f.java b/java/src/common/util/Vector4f.java similarity index 99% rename from java/src/game/util/Vector4f.java rename to java/src/common/util/Vector4f.java index bfd95fc..ce15037 100644 --- a/java/src/game/util/Vector4f.java +++ b/java/src/common/util/Vector4f.java @@ -29,7 +29,7 @@ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package game.util; +package common.util; import java.io.Serializable; import java.nio.FloatBuffer; diff --git a/java/src/game/village/MerchantRecipe.java b/java/src/common/village/MerchantRecipe.java similarity index 94% rename from java/src/game/village/MerchantRecipe.java rename to java/src/common/village/MerchantRecipe.java index c17d4a6..28e4dfe 100755 --- a/java/src/game/village/MerchantRecipe.java +++ b/java/src/common/village/MerchantRecipe.java @@ -1,8 +1,8 @@ -package game.village; +package common.village; -import game.item.Item; -import game.item.ItemStack; -import game.nbt.NBTTagCompound; +import common.item.Item; +import common.item.ItemStack; +import common.nbt.NBTTagCompound; public class MerchantRecipe { diff --git a/java/src/game/village/MerchantRecipeList.java b/java/src/common/village/MerchantRecipeList.java similarity index 97% rename from java/src/game/village/MerchantRecipeList.java rename to java/src/common/village/MerchantRecipeList.java index abc4098..d28a1c7 100755 --- a/java/src/game/village/MerchantRecipeList.java +++ b/java/src/common/village/MerchantRecipeList.java @@ -1,11 +1,11 @@ -package game.village; +package common.village; import java.util.ArrayList; -import game.item.ItemStack; -import game.nbt.NBTTagCompound; -import game.nbt.NBTTagList; -import game.nbt.NBTUtil; +import common.item.ItemStack; +import common.nbt.NBTTagCompound; +import common.nbt.NBTTagList; +import common.nbt.NBTUtil; public class MerchantRecipeList extends ArrayList { diff --git a/java/src/game/village/Village.java b/java/src/common/village/Village.java similarity index 96% rename from java/src/game/village/Village.java rename to java/src/common/village/Village.java index 5c80e39..9185f6a 100755 --- a/java/src/game/village/Village.java +++ b/java/src/common/village/Village.java @@ -1,16 +1,16 @@ -package game.village; +package common.village; import java.util.Iterator; import java.util.List; -import game.block.Block; -import game.block.BlockDoor; -import game.collect.Lists; -import game.material.Material; -import game.nbt.NBTTagCompound; -import game.nbt.NBTTagList; -import game.world.BlockPos; -import game.world.WorldServer; +import common.block.Block; +import common.block.BlockDoor; +import common.collect.Lists; +import common.material.Material; +import common.nbt.NBTTagCompound; +import common.nbt.NBTTagList; +import common.world.BlockPos; +import common.world.WorldServer; public class Village { diff --git a/java/src/game/village/VillageCollection.java b/java/src/common/village/VillageCollection.java similarity index 96% rename from java/src/game/village/VillageCollection.java rename to java/src/common/village/VillageCollection.java index 74b0a9e..6872619 100755 --- a/java/src/game/village/VillageCollection.java +++ b/java/src/common/village/VillageCollection.java @@ -1,17 +1,17 @@ -package game.village; +package common.village; import java.util.Iterator; import java.util.List; -import game.block.Block; -import game.block.BlockDoor; -import game.collect.Lists; -import game.material.Material; -import game.nbt.NBTTagCompound; -import game.nbt.NBTTagList; -import game.world.BlockPos; -import game.world.Facing; -import game.world.WorldServer; +import common.block.Block; +import common.block.BlockDoor; +import common.collect.Lists; +import common.material.Material; +import common.nbt.NBTTagCompound; +import common.nbt.NBTTagList; +import common.world.BlockPos; +import common.world.Facing; +import common.world.WorldServer; public class VillageCollection { diff --git a/java/src/game/village/VillageDoorInfo.java b/java/src/common/village/VillageDoorInfo.java similarity index 97% rename from java/src/game/village/VillageDoorInfo.java rename to java/src/common/village/VillageDoorInfo.java index 4a27a2d..69b229e 100755 --- a/java/src/game/village/VillageDoorInfo.java +++ b/java/src/common/village/VillageDoorInfo.java @@ -1,7 +1,7 @@ -package game.village; +package common.village; -import game.world.BlockPos; -import game.world.Facing; +import common.world.BlockPos; +import common.world.Facing; public class VillageDoorInfo { diff --git a/java/src/game/world/BlockArray.java b/java/src/common/world/BlockArray.java similarity index 95% rename from java/src/game/world/BlockArray.java rename to java/src/common/world/BlockArray.java index e838cb8..cd89a55 100755 --- a/java/src/game/world/BlockArray.java +++ b/java/src/common/world/BlockArray.java @@ -1,8 +1,8 @@ -package game.world; +package common.world; -import game.block.Block; -import game.init.BlockRegistry; -import game.init.Blocks; +import common.block.Block; +import common.init.BlockRegistry; +import common.init.Blocks; public class BlockArray { private int yBase; diff --git a/java/src/game/world/BlockPos.java b/java/src/common/world/BlockPos.java similarity index 99% rename from java/src/game/world/BlockPos.java rename to java/src/common/world/BlockPos.java index 9a8abf2..1288f53 100755 --- a/java/src/game/world/BlockPos.java +++ b/java/src/common/world/BlockPos.java @@ -1,9 +1,9 @@ -package game.world; +package common.world; import java.util.Iterator; -import game.collect.AbstractIterator; -import game.entity.Entity; +import common.collect.AbstractIterator; +import common.entity.Entity; public class BlockPos extends Vec3i { diff --git a/java/src/game/world/BoundingBox.java b/java/src/common/world/BoundingBox.java similarity index 99% rename from java/src/game/world/BoundingBox.java rename to java/src/common/world/BoundingBox.java index 1aeb90d..c7b02c1 100755 --- a/java/src/game/world/BoundingBox.java +++ b/java/src/common/world/BoundingBox.java @@ -1,6 +1,6 @@ -package game.world; +package common.world; -import game.world.HitPosition.ObjectType; +import common.world.HitPosition.ObjectType; public class BoundingBox { diff --git a/java/src/game/world/Chunk.java b/java/src/common/world/Chunk.java similarity index 98% rename from java/src/game/world/Chunk.java rename to java/src/common/world/Chunk.java index 336e6fb..9f4be01 100755 --- a/java/src/game/world/Chunk.java +++ b/java/src/common/world/Chunk.java @@ -1,4 +1,4 @@ -package game.world; +package common.world; import java.util.Arrays; import java.util.List; @@ -6,20 +6,20 @@ import java.util.Map; import java.util.concurrent.ConcurrentLinkedQueue; import java.util.function.Predicate; -import game.biome.Biome; -import game.block.Block; -import game.block.ITileEntityProvider; -import game.collect.Maps; -import game.entity.Entity; -import game.init.Blocks; -import game.log.Log; -import game.material.Material; -import game.rng.Random; -import game.tileentity.TileEntity; -import game.util.ExtMath; -import game.worldgen.BiomeGenerator; -import game.worldgen.ChunkPrimer; -import game.worldgen.GeneratorDebug; +import common.biome.Biome; +import common.block.Block; +import common.block.ITileEntityProvider; +import common.collect.Maps; +import common.entity.Entity; +import common.init.Blocks; +import common.log.Log; +import common.material.Material; +import common.rng.Random; +import common.tileentity.TileEntity; +import common.util.ExtMath; +import common.worldgen.BiomeGenerator; +import common.worldgen.ChunkPrimer; +import common.worldgen.GeneratorDebug; public class Chunk { public final int xPos; diff --git a/java/src/game/world/ChunkCache.java b/java/src/common/world/ChunkCache.java similarity index 97% rename from java/src/game/world/ChunkCache.java rename to java/src/common/world/ChunkCache.java index cd79161..e213ba5 100755 --- a/java/src/game/world/ChunkCache.java +++ b/java/src/common/world/ChunkCache.java @@ -1,4 +1,4 @@ -package game.world; +package common.world; public class ChunkCache { diff --git a/java/src/game/world/ChunkPos.java b/java/src/common/world/ChunkPos.java similarity index 96% rename from java/src/game/world/ChunkPos.java rename to java/src/common/world/ChunkPos.java index b97a738..0e8fc2e 100755 --- a/java/src/game/world/ChunkPos.java +++ b/java/src/common/world/ChunkPos.java @@ -1,4 +1,4 @@ -package game.world; +package common.world; public class ChunkPos { public final int x; diff --git a/java/src/game/world/ClassInheritanceMultiMap.java b/java/src/common/world/ClassInheritanceMultiMap.java similarity index 97% rename from java/src/game/world/ClassInheritanceMultiMap.java rename to java/src/common/world/ClassInheritanceMultiMap.java index 5137011..c5f9e93 100755 --- a/java/src/game/world/ClassInheritanceMultiMap.java +++ b/java/src/common/world/ClassInheritanceMultiMap.java @@ -1,4 +1,4 @@ -package game.world; +package common.world; import java.util.AbstractSet; import java.util.Collections; @@ -8,9 +8,9 @@ import java.util.Map; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; -import game.collect.Iterators; -import game.collect.Lists; -import game.collect.Maps; +import common.collect.Iterators; +import common.collect.Lists; +import common.collect.Maps; public class ClassInheritanceMultiMap extends AbstractSet { diff --git a/java/src/game/world/EmptyChunk.java b/java/src/common/world/EmptyChunk.java similarity index 91% rename from java/src/game/world/EmptyChunk.java rename to java/src/common/world/EmptyChunk.java index 00392cd..29bc0c0 100755 --- a/java/src/game/world/EmptyChunk.java +++ b/java/src/common/world/EmptyChunk.java @@ -1,12 +1,12 @@ -package game.world; +package common.world; import java.util.List; import java.util.function.Predicate; -import game.block.Block; -import game.entity.Entity; -import game.init.Blocks; -import game.tileentity.TileEntity; +import common.block.Block; +import common.entity.Entity; +import common.init.Blocks; +import common.tileentity.TileEntity; public class EmptyChunk extends Chunk { public EmptyChunk(WorldClient world) { diff --git a/java/src/game/world/Explosion.java b/java/src/common/world/Explosion.java similarity index 96% rename from java/src/game/world/Explosion.java rename to java/src/common/world/Explosion.java index ac9438f..04fbc1c 100755 --- a/java/src/game/world/Explosion.java +++ b/java/src/common/world/Explosion.java @@ -1,26 +1,26 @@ -package game.world; +package common.world; import java.util.List; import java.util.Map; import java.util.Set; -import game.block.Block; -import game.collect.Lists; -import game.collect.Maps; -import game.collect.Sets; -import game.enchantment.EnchantmentProtection; -import game.entity.DamageSource; -import game.entity.Entity; -import game.entity.item.EntityTnt; -import game.entity.npc.EntityNPC; -import game.entity.types.EntityLiving; -import game.init.Blocks; -import game.init.Config; -import game.init.SoundEvent; -import game.material.Material; -import game.model.ParticleType; -import game.rng.Random; -import game.util.ExtMath; +import common.block.Block; +import common.collect.Lists; +import common.collect.Maps; +import common.collect.Sets; +import common.enchantment.EnchantmentProtection; +import common.entity.DamageSource; +import common.entity.Entity; +import common.entity.item.EntityTnt; +import common.entity.npc.EntityNPC; +import common.entity.types.EntityLiving; +import common.init.Blocks; +import common.init.Config; +import common.init.SoundEvent; +import common.material.Material; +import common.model.ParticleType; +import common.rng.Random; +import common.util.ExtMath; public class Explosion { diff --git a/java/src/game/world/Facing.java b/java/src/common/world/Facing.java similarity index 98% rename from java/src/game/world/Facing.java rename to java/src/common/world/Facing.java index c94d154..66d901a 100755 --- a/java/src/game/world/Facing.java +++ b/java/src/common/world/Facing.java @@ -1,14 +1,14 @@ -package game.world; +package common.world; import java.util.Iterator; import java.util.Map; import java.util.function.Predicate; -import game.collect.Iterators; -import game.collect.Maps; -import game.rng.Random; -import game.util.ExtMath; -import game.util.Identifyable; +import common.collect.Iterators; +import common.collect.Maps; +import common.rng.Random; +import common.util.ExtMath; +import common.util.Identifyable; public enum Facing implements Identifyable { diff --git a/java/src/game/world/HitPosition.java b/java/src/common/world/HitPosition.java similarity index 93% rename from java/src/game/world/HitPosition.java rename to java/src/common/world/HitPosition.java index 4271e0e..940d092 100755 --- a/java/src/game/world/HitPosition.java +++ b/java/src/common/world/HitPosition.java @@ -1,6 +1,6 @@ -package game.world; +package common.world; -import game.entity.Entity; +import common.entity.Entity; public class HitPosition { public static enum ObjectType { diff --git a/java/src/game/world/IBlockAccess.java b/java/src/common/world/IBlockAccess.java similarity index 75% rename from java/src/game/world/IBlockAccess.java rename to java/src/common/world/IBlockAccess.java index 79cb6fd..2b0fb24 100755 --- a/java/src/game/world/IBlockAccess.java +++ b/java/src/common/world/IBlockAccess.java @@ -1,4 +1,4 @@ -package game.world; +package common.world; public interface IBlockAccess { diff --git a/java/src/game/world/IWorldAccess.java b/java/src/common/world/IWorldAccess.java similarity index 70% rename from java/src/game/world/IWorldAccess.java rename to java/src/common/world/IWorldAccess.java index c829d7f..b06a2fa 100755 --- a/java/src/game/world/IWorldAccess.java +++ b/java/src/common/world/IWorldAccess.java @@ -1,7 +1,7 @@ -package game.world; +package common.world; -import game.biome.Biome; -import game.tileentity.TileEntity; +import common.biome.Biome; +import common.tileentity.TileEntity; public interface IWorldAccess extends IBlockAccess { diff --git a/java/src/game/world/IntHashMap.java b/java/src/common/world/IntHashMap.java similarity index 99% rename from java/src/game/world/IntHashMap.java rename to java/src/common/world/IntHashMap.java index 47122b4..12e3470 100755 --- a/java/src/game/world/IntHashMap.java +++ b/java/src/common/world/IntHashMap.java @@ -1,4 +1,4 @@ -package game.world; +package common.world; public class IntHashMap { diff --git a/java/src/game/world/LightType.java b/java/src/common/world/LightType.java similarity index 85% rename from java/src/game/world/LightType.java rename to java/src/common/world/LightType.java index ce17dd2..e1bfdbb 100755 --- a/java/src/game/world/LightType.java +++ b/java/src/common/world/LightType.java @@ -1,4 +1,4 @@ -package game.world; +package common.world; public enum LightType { SKY(15), BLOCK(0); diff --git a/java/src/game/world/LongHashMap.java b/java/src/common/world/LongHashMap.java similarity index 99% rename from java/src/game/world/LongHashMap.java rename to java/src/common/world/LongHashMap.java index c396c47..35fad96 100755 --- a/java/src/game/world/LongHashMap.java +++ b/java/src/common/world/LongHashMap.java @@ -1,4 +1,4 @@ -package game.world; +package common.world; public class LongHashMap { diff --git a/java/src/game/world/NextTickListEntry.java b/java/src/common/world/NextTickListEntry.java similarity index 96% rename from java/src/game/world/NextTickListEntry.java rename to java/src/common/world/NextTickListEntry.java index 4f15717..d208b2f 100755 --- a/java/src/game/world/NextTickListEntry.java +++ b/java/src/common/world/NextTickListEntry.java @@ -1,7 +1,7 @@ -package game.world; +package common.world; -import game.block.Block; -import game.init.BlockRegistry; +import common.block.Block; +import common.init.BlockRegistry; public class NextTickListEntry implements Comparable { diff --git a/java/src/game/world/NibbleArray.java b/java/src/common/world/NibbleArray.java similarity index 97% rename from java/src/game/world/NibbleArray.java rename to java/src/common/world/NibbleArray.java index c5801a2..3a53b8d 100755 --- a/java/src/game/world/NibbleArray.java +++ b/java/src/common/world/NibbleArray.java @@ -1,4 +1,4 @@ -package game.world; +package common.world; public class NibbleArray { private final byte[] data; diff --git a/java/src/game/world/PortalType.java b/java/src/common/world/PortalType.java similarity index 86% rename from java/src/game/world/PortalType.java rename to java/src/common/world/PortalType.java index 37ca835..06e214f 100755 --- a/java/src/game/world/PortalType.java +++ b/java/src/common/world/PortalType.java @@ -1,4 +1,4 @@ -package game.world; +package common.world; public enum PortalType { STAND_BLACK, STAND_RED, STAND_YELLOW, STAND_GREEN, STAND_CYAN, STAND_BLUE, STAND_MAGENTA, STAND_WHITE, FLOOR, VOID; diff --git a/java/src/game/world/Position.java b/java/src/common/world/Position.java similarity index 94% rename from java/src/game/world/Position.java rename to java/src/common/world/Position.java index 3453499..59eaf24 100755 --- a/java/src/game/world/Position.java +++ b/java/src/common/world/Position.java @@ -1,4 +1,4 @@ -package game.world; +package common.world; public class Position { public final double x; diff --git a/java/src/game/world/Region.java b/java/src/common/world/Region.java similarity index 98% rename from java/src/game/world/Region.java rename to java/src/common/world/Region.java index a3df508..6990839 100755 --- a/java/src/game/world/Region.java +++ b/java/src/common/world/Region.java @@ -1,4 +1,4 @@ -package game.world; +package common.world; import java.io.BufferedInputStream; import java.io.ByteArrayInputStream; @@ -17,19 +17,19 @@ import java.util.Map; import java.util.zip.DeflaterOutputStream; import java.util.zip.InflaterInputStream; -import game.block.Block; -import game.collect.Lists; -import game.collect.Maps; -import game.entity.Entity; -import game.init.BlockRegistry; -import game.init.Config; -import game.init.EntityRegistry; -import game.init.UniverseRegistry; -import game.log.Log; -import game.nbt.NBTLoader; -import game.nbt.NBTTagCompound; -import game.nbt.NBTTagList; -import game.tileentity.TileEntity; +import common.block.Block; +import common.collect.Lists; +import common.collect.Maps; +import common.entity.Entity; +import common.init.BlockRegistry; +import common.init.Config; +import common.init.EntityRegistry; +import common.init.UniverseRegistry; +import common.log.Log; +import common.nbt.NBTLoader; +import common.nbt.NBTTagCompound; +import common.nbt.NBTTagList; +import common.tileentity.TileEntity; public class Region { public static enum SaveVersion { diff --git a/java/src/game/world/Spawner.java b/java/src/common/world/Spawner.java similarity index 94% rename from java/src/game/world/Spawner.java rename to java/src/common/world/Spawner.java index 05a830c..b9e323a 100755 --- a/java/src/game/world/Spawner.java +++ b/java/src/common/world/Spawner.java @@ -1,19 +1,19 @@ -package game.world; +package common.world; import java.util.Set; -import game.biome.Biome; -import game.biome.RngSpawn; -import game.block.Block; -import game.collect.Sets; -import game.entity.npc.EntityNPC; -import game.entity.types.EntityLiving; -import game.entity.types.EntityWaterMob; -import game.init.Blocks; -import game.init.Config; -import game.rng.Random; -import game.rng.WeightedList; -import game.util.ExtMath; +import common.biome.Biome; +import common.biome.RngSpawn; +import common.block.Block; +import common.collect.Sets; +import common.entity.npc.EntityNPC; +import common.entity.types.EntityLiving; +import common.entity.types.EntityWaterMob; +import common.init.Blocks; +import common.init.Config; +import common.rng.Random; +import common.rng.WeightedList; +import common.util.ExtMath; public abstract class Spawner { private static final int MOB_COUNT_DIV = (int)Math.pow(17.0D, 2.0D); diff --git a/java/src/game/world/State.java b/java/src/common/world/State.java similarity index 92% rename from java/src/game/world/State.java rename to java/src/common/world/State.java index 8e05fc8..c4ab565 100755 --- a/java/src/game/world/State.java +++ b/java/src/common/world/State.java @@ -1,4 +1,4 @@ -package game.world; +package common.world; import java.util.Collection; import java.util.Collections; @@ -7,15 +7,15 @@ import java.util.Map; import java.util.Map.Entry; import java.util.function.Function; -import game.block.Block; -import game.collect.ImmutableMap; -import game.collect.ImmutableTable; -import game.collect.Iterables; -import game.collect.Maps; -import game.collect.StandardTable; -import game.collect.Table; -import game.init.BlockRegistry; -import game.properties.IProperty; +import common.block.Block; +import common.collect.ImmutableMap; +import common.collect.ImmutableTable; +import common.collect.Iterables; +import common.collect.Maps; +import common.collect.StandardTable; +import common.collect.Table; +import common.init.BlockRegistry; +import common.properties.IProperty; public class State { // private static final Joiner COMMA_JOINER = Joiner.on(','); diff --git a/java/src/game/world/Vec3.java b/java/src/common/world/Vec3.java similarity index 99% rename from java/src/game/world/Vec3.java rename to java/src/common/world/Vec3.java index 460787f..88b95ed 100755 --- a/java/src/game/world/Vec3.java +++ b/java/src/common/world/Vec3.java @@ -1,6 +1,6 @@ -package game.world; +package common.world; -import game.util.ExtMath; +import common.util.ExtMath; public class Vec3 { diff --git a/java/src/game/world/Vec3i.java b/java/src/common/world/Vec3i.java similarity index 98% rename from java/src/game/world/Vec3i.java rename to java/src/common/world/Vec3i.java index 6c03512..fa1cd58 100755 --- a/java/src/game/world/Vec3i.java +++ b/java/src/common/world/Vec3i.java @@ -1,6 +1,6 @@ -package game.world; +package common.world; -import game.util.ExtMath; +import common.util.ExtMath; public class Vec3i implements Comparable { diff --git a/java/src/game/world/Weather.java b/java/src/common/world/Weather.java similarity index 96% rename from java/src/game/world/Weather.java rename to java/src/common/world/Weather.java index d5b52f3..89a99c7 100755 --- a/java/src/game/world/Weather.java +++ b/java/src/common/world/Weather.java @@ -1,11 +1,11 @@ -package game.world; +package common.world; import java.util.Map; -import game.collect.Maps; -import game.rng.Random; -import game.rng.RngItem; -import game.rng.WeightedList; +import common.collect.Maps; +import common.rng.Random; +import common.rng.RngItem; +import common.rng.WeightedList; public enum Weather { CLEAR("clear", "Schön", 0.0f, 0.0f, 12, 30, 9, 7), diff --git a/java/src/game/world/World.java b/java/src/common/world/World.java similarity index 98% rename from java/src/game/world/World.java rename to java/src/common/world/World.java index 76ad069..d651ac2 100755 --- a/java/src/game/world/World.java +++ b/java/src/common/world/World.java @@ -1,4 +1,4 @@ -package game.world; +package common.world; import java.util.Collection; import java.util.Iterator; @@ -6,30 +6,30 @@ import java.util.List; import java.util.Set; import java.util.function.Predicate; -import game.biome.Biome; -import game.block.Block; -import game.block.BlockHopper; -import game.block.BlockLiquid; -import game.block.BlockSlab; -import game.block.BlockSnow; -import game.block.BlockStairs; -import game.block.LeavesType; -import game.collect.Lists; -import game.collect.Sets; -import game.dimension.Dimension; -import game.entity.Entity; -import game.entity.item.EntityExplosion; -import game.entity.npc.EntityNPC; -import game.init.BlockRegistry; -import game.init.Blocks; -import game.init.SoundEvent; -import game.item.ItemStack; -import game.material.Material; -import game.model.ParticleType; -import game.rng.Random; -import game.tileentity.ITickable; -import game.tileentity.TileEntity; -import game.util.ExtMath; +import common.biome.Biome; +import common.block.Block; +import common.block.BlockHopper; +import common.block.BlockLiquid; +import common.block.BlockSlab; +import common.block.BlockSnow; +import common.block.BlockStairs; +import common.block.LeavesType; +import common.collect.Lists; +import common.collect.Sets; +import common.dimension.Dimension; +import common.entity.Entity; +import common.entity.item.EntityExplosion; +import common.entity.npc.EntityNPC; +import common.init.BlockRegistry; +import common.init.Blocks; +import common.init.SoundEvent; +import common.item.ItemStack; +import common.material.Material; +import common.model.ParticleType; +import common.rng.Random; +import common.tileentity.ITickable; +import common.tileentity.TileEntity; +import common.util.ExtMath; public abstract class World implements IWorldAccess { public static final float[][] BRIGHTNESS = new float[16][16]; diff --git a/java/src/game/world/WorldClient.java b/java/src/common/world/WorldClient.java similarity index 97% rename from java/src/game/world/WorldClient.java rename to java/src/common/world/WorldClient.java index e03a9cd..0365190 100755 --- a/java/src/game/world/WorldClient.java +++ b/java/src/common/world/WorldClient.java @@ -1,33 +1,33 @@ -package game.world; +package common.world; import java.util.List; import java.util.Set; -import game.IClient; -import game.biome.Biome; -import game.block.Block; -import game.collect.Lists; -import game.collect.Sets; -import game.dimension.Dimension; -import game.entity.Entity; -import game.entity.item.EntityCart; -import game.entity.npc.EntityNPC; -import game.entity.types.IEntityFX; -import game.init.BlockRegistry; -import game.init.ItemRegistry; -import game.init.Items; -import game.init.SoundEvent; -import game.item.ItemDye; -import game.log.Log; -import game.material.Material; -import game.model.ParticleType; -import game.nbt.NBTTagCompound; -import game.rng.Random; -import game.sound.MovingSoundMinecart; -import game.sound.PositionedSound; -import game.tileentity.TileEntity; -import game.util.ExtMath; -import game.world.BlockPos.MutableBlockPos; +import common.IClient; +import common.biome.Biome; +import common.block.Block; +import common.collect.Lists; +import common.collect.Sets; +import common.dimension.Dimension; +import common.entity.Entity; +import common.entity.item.EntityCart; +import common.entity.npc.EntityNPC; +import common.entity.types.IEntityFX; +import common.init.BlockRegistry; +import common.init.ItemRegistry; +import common.init.Items; +import common.init.SoundEvent; +import common.item.ItemDye; +import common.log.Log; +import common.material.Material; +import common.model.ParticleType; +import common.nbt.NBTTagCompound; +import common.rng.Random; +import common.sound.MovingSoundMinecart; +import common.sound.PositionedSound; +import common.tileentity.TileEntity; +import common.util.ExtMath; +import common.world.BlockPos.MutableBlockPos; public class WorldClient extends World { diff --git a/java/src/game/world/WorldPos.java b/java/src/common/world/WorldPos.java similarity index 97% rename from java/src/game/world/WorldPos.java rename to java/src/common/world/WorldPos.java index bf49eac..8c5608b 100755 --- a/java/src/game/world/WorldPos.java +++ b/java/src/common/world/WorldPos.java @@ -1,4 +1,4 @@ -package game.world; +package common.world; public class WorldPos extends BlockPos { private final int dim; diff --git a/java/src/game/world/WorldServer.java b/java/src/common/world/WorldServer.java similarity index 97% rename from java/src/game/world/WorldServer.java rename to java/src/common/world/WorldServer.java index 69fa871..9b8d8dc 100755 --- a/java/src/game/world/WorldServer.java +++ b/java/src/common/world/WorldServer.java @@ -1,4 +1,4 @@ -package game.world; +package common.world; import java.io.File; import java.io.FileFilter; @@ -13,80 +13,80 @@ import java.util.TreeSet; import java.util.concurrent.ConcurrentHashMap; import java.util.function.Predicate; -import game.IServer; -import game.biome.Biome; -import game.biome.RngSpawn; -import game.block.Block; -import game.block.BlockDoor; -import game.block.BlockEventData; -import game.block.BlockFalling; -import game.block.BlockLiquid; -import game.block.BlockSnow; -import game.clipboard.ClipboardBlock; -import game.collect.Lists; -import game.collect.Maps; -import game.collect.Sets; -import game.dimension.Dimension; -import game.entity.DamageSource; -import game.entity.Entity; -import game.entity.EntityTrackerEntry; -import game.entity.effect.EntityLightning; -import game.entity.npc.EntityNPC; -import game.entity.types.EntityLiving; -import game.init.Blocks; -import game.init.Config; -import game.init.SoundEvent; -import game.init.UniverseRegistry; -import game.item.ItemDoor; -import game.log.Log; -import game.material.Material; -import game.model.ParticleType; -import game.nbt.NBTLoader; -import game.nbt.NBTTagCompound; -import game.nbt.NBTTagInt; -import game.nbt.NBTTagList; -import game.network.IPlayer; -import game.network.Packet; -import game.packet.S1APacketEntityStatus; -import game.packet.S27PacketExplosion; -import game.packet.S28PacketEffect; -import game.packet.S29PacketSoundEffect; -import game.packet.S2APacketParticles; -import game.packet.S2BPacketChangeGameState; -import game.packet.S2CPacketSpawnGlobalEntity; -import game.packet.SPacketBiomes; -import game.packet.SPacketBlockAction; -import game.packet.SPacketBlockBreakAnim; -import game.packet.SPacketBlockChange; -import game.packet.SPacketChunkData; -import game.packet.SPacketMultiBlockChange; -import game.rng.Random; -import game.rng.WeightedList; -import game.tileentity.TileEntity; -import game.util.ExtMath; -import game.util.FileUtils; -import game.village.Village; -import game.village.VillageCollection; -import game.worldgen.BiomeGenSingle; -import game.worldgen.BiomeGenerator; -import game.worldgen.BlockReplacer; -import game.worldgen.ChunkGenerator; -import game.worldgen.ChunkPrimer; -import game.worldgen.FeatureDungeons; -import game.worldgen.FeatureLakes; -import game.worldgen.FeatureLiquids; -import game.worldgen.FeatureOres; -import game.worldgen.GeneratorDebug; -import game.worldgen.GeneratorDestroyed; -import game.worldgen.LootConstants; -import game.worldgen.caves.MapGenBigCaves; -import game.worldgen.caves.MapGenCaves; -import game.worldgen.caves.MapGenRavine; -import game.worldgen.structure.MapGenBridge; -import game.worldgen.structure.MapGenMineshaft; -import game.worldgen.structure.MapGenScatteredFeature; -import game.worldgen.structure.MapGenStronghold; -import game.worldgen.structure.MapGenVillage; +import common.IServer; +import common.biome.Biome; +import common.biome.RngSpawn; +import common.block.Block; +import common.block.BlockDoor; +import common.block.BlockEventData; +import common.block.BlockFalling; +import common.block.BlockLiquid; +import common.block.BlockSnow; +import common.clipboard.ClipboardBlock; +import common.collect.Lists; +import common.collect.Maps; +import common.collect.Sets; +import common.dimension.Dimension; +import common.entity.DamageSource; +import common.entity.Entity; +import common.entity.EntityTrackerEntry; +import common.entity.effect.EntityLightning; +import common.entity.npc.EntityNPC; +import common.entity.types.EntityLiving; +import common.init.Blocks; +import common.init.Config; +import common.init.SoundEvent; +import common.init.UniverseRegistry; +import common.item.ItemDoor; +import common.log.Log; +import common.material.Material; +import common.model.ParticleType; +import common.nbt.NBTLoader; +import common.nbt.NBTTagCompound; +import common.nbt.NBTTagInt; +import common.nbt.NBTTagList; +import common.network.IPlayer; +import common.network.Packet; +import common.packet.S1APacketEntityStatus; +import common.packet.S27PacketExplosion; +import common.packet.S28PacketEffect; +import common.packet.S29PacketSoundEffect; +import common.packet.S2APacketParticles; +import common.packet.S2BPacketChangeGameState; +import common.packet.S2CPacketSpawnGlobalEntity; +import common.packet.SPacketBiomes; +import common.packet.SPacketBlockAction; +import common.packet.SPacketBlockBreakAnim; +import common.packet.SPacketBlockChange; +import common.packet.SPacketChunkData; +import common.packet.SPacketMultiBlockChange; +import common.rng.Random; +import common.rng.WeightedList; +import common.tileentity.TileEntity; +import common.util.ExtMath; +import common.util.FileUtils; +import common.village.Village; +import common.village.VillageCollection; +import common.worldgen.BiomeGenSingle; +import common.worldgen.BiomeGenerator; +import common.worldgen.BlockReplacer; +import common.worldgen.ChunkGenerator; +import common.worldgen.ChunkPrimer; +import common.worldgen.FeatureDungeons; +import common.worldgen.FeatureLakes; +import common.worldgen.FeatureLiquids; +import common.worldgen.FeatureOres; +import common.worldgen.GeneratorDebug; +import common.worldgen.GeneratorDestroyed; +import common.worldgen.LootConstants; +import common.worldgen.caves.MapGenBigCaves; +import common.worldgen.caves.MapGenCaves; +import common.worldgen.caves.MapGenRavine; +import common.worldgen.structure.MapGenBridge; +import common.worldgen.structure.MapGenMineshaft; +import common.worldgen.structure.MapGenScatteredFeature; +import common.worldgen.structure.MapGenStronghold; +import common.worldgen.structure.MapGenVillage; public final class WorldServer extends World { private static final int[][] XZ_DIRS = new int[][] {{1, 0}, {0, 1}, {-1, 0}, {0, -1}}; diff --git a/java/src/game/worldgen/BiomeGenLayered.java b/java/src/common/worldgen/BiomeGenLayered.java similarity index 89% rename from java/src/game/worldgen/BiomeGenLayered.java rename to java/src/common/worldgen/BiomeGenLayered.java index f78abbc..d5e0230 100755 --- a/java/src/game/worldgen/BiomeGenLayered.java +++ b/java/src/common/worldgen/BiomeGenLayered.java @@ -1,32 +1,32 @@ -package game.worldgen; +package common.worldgen; import java.util.List; import java.util.Set; -import game.biome.Biome; -import game.collect.Lists; -import game.world.BlockPos; -import game.world.LongHashMap; -import game.worldgen.layer.GenLayer; -import game.worldgen.layer.GenLayerAddAreas; -import game.worldgen.layer.GenLayerAddExtra; -import game.worldgen.layer.GenLayerAddSea; -import game.worldgen.layer.GenLayerAddSnow; -import game.worldgen.layer.GenLayerBase; -import game.worldgen.layer.GenLayerBiome; -import game.worldgen.layer.GenLayerBiomeEdge; -import game.worldgen.layer.GenLayerEdge; -import game.worldgen.layer.GenLayerFuzzyZoom; -import game.worldgen.layer.GenLayerHills; -import game.worldgen.layer.GenLayerRemoveEmpty; -import game.worldgen.layer.GenLayerRiver; -import game.worldgen.layer.GenLayerRiverInit; -import game.worldgen.layer.GenLayerRiverMix; -import game.worldgen.layer.GenLayerShore; -import game.worldgen.layer.GenLayerSmooth; -import game.worldgen.layer.GenLayerVoronoiZoom; -import game.worldgen.layer.GenLayerZoom; -import game.worldgen.layer.IntCache; +import common.biome.Biome; +import common.collect.Lists; +import common.world.BlockPos; +import common.world.LongHashMap; +import common.worldgen.layer.GenLayer; +import common.worldgen.layer.GenLayerAddAreas; +import common.worldgen.layer.GenLayerAddExtra; +import common.worldgen.layer.GenLayerAddSea; +import common.worldgen.layer.GenLayerAddSnow; +import common.worldgen.layer.GenLayerBase; +import common.worldgen.layer.GenLayerBiome; +import common.worldgen.layer.GenLayerBiomeEdge; +import common.worldgen.layer.GenLayerEdge; +import common.worldgen.layer.GenLayerFuzzyZoom; +import common.worldgen.layer.GenLayerHills; +import common.worldgen.layer.GenLayerRemoveEmpty; +import common.worldgen.layer.GenLayerRiver; +import common.worldgen.layer.GenLayerRiverInit; +import common.worldgen.layer.GenLayerRiverMix; +import common.worldgen.layer.GenLayerShore; +import common.worldgen.layer.GenLayerSmooth; +import common.worldgen.layer.GenLayerVoronoiZoom; +import common.worldgen.layer.GenLayerZoom; +import common.worldgen.layer.IntCache; public class BiomeGenLayered implements BiomeGenerator { private class CacheBlock diff --git a/java/src/game/worldgen/BiomeGenPerlin.java b/java/src/common/worldgen/BiomeGenPerlin.java similarity index 93% rename from java/src/game/worldgen/BiomeGenPerlin.java rename to java/src/common/worldgen/BiomeGenPerlin.java index 4ff7756..ae0e0df 100755 --- a/java/src/game/worldgen/BiomeGenPerlin.java +++ b/java/src/common/worldgen/BiomeGenPerlin.java @@ -1,7 +1,7 @@ -package game.worldgen; +package common.worldgen; -import game.rng.PerlinGenOld; -import game.rng.Random; +import common.rng.PerlinGenOld; +import common.rng.Random; public class BiomeGenPerlin { private final PerlinGenOld tempNoiseGen; diff --git a/java/src/game/worldgen/BiomeGenSingle.java b/java/src/common/worldgen/BiomeGenSingle.java similarity index 94% rename from java/src/game/worldgen/BiomeGenSingle.java rename to java/src/common/worldgen/BiomeGenSingle.java index 15462fc..aad396d 100755 --- a/java/src/game/worldgen/BiomeGenSingle.java +++ b/java/src/common/worldgen/BiomeGenSingle.java @@ -1,10 +1,10 @@ -package game.worldgen; +package common.worldgen; import java.util.Arrays; import java.util.Set; -import game.biome.Biome; -import game.world.BlockPos; +import common.biome.Biome; +import common.world.BlockPos; public class BiomeGenSingle implements BiomeGenerator { private final Biome biome; diff --git a/java/src/game/worldgen/BiomeGenerator.java b/java/src/common/worldgen/BiomeGenerator.java similarity index 87% rename from java/src/game/worldgen/BiomeGenerator.java rename to java/src/common/worldgen/BiomeGenerator.java index 80f8d11..d975d42 100755 --- a/java/src/game/worldgen/BiomeGenerator.java +++ b/java/src/common/worldgen/BiomeGenerator.java @@ -1,9 +1,9 @@ -package game.worldgen; +package common.worldgen; import java.util.Set; -import game.biome.Biome; -import game.world.BlockPos; +import common.biome.Biome; +import common.world.BlockPos; public interface BiomeGenerator { public void genFactors(double[] factors, int xPos, int zPos, int sizeX, int sizeZ); diff --git a/java/src/game/worldgen/BlockReplacer.java b/java/src/common/worldgen/BlockReplacer.java similarity index 55% rename from java/src/game/worldgen/BlockReplacer.java rename to java/src/common/worldgen/BlockReplacer.java index 3ccc8f5..e45c63b 100755 --- a/java/src/game/worldgen/BlockReplacer.java +++ b/java/src/common/worldgen/BlockReplacer.java @@ -1,8 +1,8 @@ -package game.worldgen; +package common.worldgen; -import game.biome.Biome; -import game.rng.Random; -import game.world.WorldServer; +import common.biome.Biome; +import common.rng.Random; +import common.world.WorldServer; public interface BlockReplacer { public void replaceBlocks(WorldServer world, int x, int z, ChunkPrimer primer, Random rand, Biome[] biomes); diff --git a/java/src/game/worldgen/ChunkGenerator.java b/java/src/common/worldgen/ChunkGenerator.java similarity index 69% rename from java/src/game/worldgen/ChunkGenerator.java rename to java/src/common/worldgen/ChunkGenerator.java index d7d14ac..df3ae2d 100755 --- a/java/src/game/worldgen/ChunkGenerator.java +++ b/java/src/common/worldgen/ChunkGenerator.java @@ -1,6 +1,6 @@ -package game.worldgen; +package common.worldgen; -import game.world.WorldServer; +import common.world.WorldServer; public interface ChunkGenerator { public void generateChunk(WorldServer world, int x, int z, ChunkPrimer primer); diff --git a/java/src/game/worldgen/ChunkPrimer.java b/java/src/common/worldgen/ChunkPrimer.java similarity index 82% rename from java/src/game/worldgen/ChunkPrimer.java rename to java/src/common/worldgen/ChunkPrimer.java index 2053420..d0c6f0e 100755 --- a/java/src/game/worldgen/ChunkPrimer.java +++ b/java/src/common/worldgen/ChunkPrimer.java @@ -1,8 +1,8 @@ -package game.worldgen; +package common.worldgen; -import game.init.BlockRegistry; -import game.init.Blocks; -import game.world.State; +import common.init.BlockRegistry; +import common.init.Blocks; +import common.world.State; public class ChunkPrimer { public final int height; diff --git a/java/src/game/worldgen/FeatureDungeons.java b/java/src/common/worldgen/FeatureDungeons.java similarity index 93% rename from java/src/game/worldgen/FeatureDungeons.java rename to java/src/common/worldgen/FeatureDungeons.java index c63e856..3f22b7a 100755 --- a/java/src/game/worldgen/FeatureDungeons.java +++ b/java/src/common/worldgen/FeatureDungeons.java @@ -1,18 +1,18 @@ -package game.worldgen; +package common.worldgen; -import game.init.Blocks; -import game.init.Items; -import game.item.RngLoot; -import game.log.Log; -import game.material.Material; -import game.rng.Random; -import game.rng.WeightedList; -import game.tileentity.TileEntity; -import game.tileentity.TileEntityChest; -import game.tileentity.TileEntityMobSpawner; -import game.world.BlockPos; -import game.world.Facing; -import game.world.WorldServer; +import common.init.Blocks; +import common.init.Items; +import common.item.RngLoot; +import common.log.Log; +import common.material.Material; +import common.rng.Random; +import common.rng.WeightedList; +import common.tileentity.TileEntity; +import common.tileentity.TileEntityChest; +import common.tileentity.TileEntityMobSpawner; +import common.world.BlockPos; +import common.world.Facing; +import common.world.WorldServer; public class FeatureDungeons { diff --git a/java/src/game/worldgen/FeatureGenerator.java b/java/src/common/worldgen/FeatureGenerator.java similarity index 81% rename from java/src/game/worldgen/FeatureGenerator.java rename to java/src/common/worldgen/FeatureGenerator.java index 252d686..d93b260 100755 --- a/java/src/game/worldgen/FeatureGenerator.java +++ b/java/src/common/worldgen/FeatureGenerator.java @@ -1,9 +1,9 @@ -package game.worldgen; +package common.worldgen; -import game.rng.Random; -import game.world.BlockPos; -import game.world.State; -import game.world.WorldServer; +import common.rng.Random; +import common.world.BlockPos; +import common.world.State; +import common.world.WorldServer; public abstract class FeatureGenerator { diff --git a/java/src/game/worldgen/FeatureLakes.java b/java/src/common/worldgen/FeatureLakes.java similarity index 96% rename from java/src/game/worldgen/FeatureLakes.java rename to java/src/common/worldgen/FeatureLakes.java index dd1c3e5..3bb47d4 100755 --- a/java/src/game/worldgen/FeatureLakes.java +++ b/java/src/common/worldgen/FeatureLakes.java @@ -1,14 +1,14 @@ -package game.worldgen; +package common.worldgen; -import game.biome.Biome; -import game.block.Block; -import game.init.Blocks; -import game.material.Material; -import game.rng.Random; -import game.world.BlockPos; -import game.world.LightType; -import game.world.State; -import game.world.WorldServer; +import common.biome.Biome; +import common.block.Block; +import common.init.Blocks; +import common.material.Material; +import common.rng.Random; +import common.world.BlockPos; +import common.world.LightType; +import common.world.State; +import common.world.WorldServer; public class FeatureLakes { diff --git a/java/src/game/worldgen/FeatureLiquids.java b/java/src/common/worldgen/FeatureLiquids.java similarity index 94% rename from java/src/game/worldgen/FeatureLiquids.java rename to java/src/common/worldgen/FeatureLiquids.java index 27c9abc..bd050b8 100755 --- a/java/src/game/worldgen/FeatureLiquids.java +++ b/java/src/common/worldgen/FeatureLiquids.java @@ -1,11 +1,11 @@ -package game.worldgen; +package common.worldgen; -import game.block.Block; -import game.material.Material; -import game.rng.Random; -import game.world.BlockPos; -import game.world.State; -import game.world.WorldServer; +import common.block.Block; +import common.material.Material; +import common.rng.Random; +import common.world.BlockPos; +import common.world.State; +import common.world.WorldServer; public class FeatureLiquids { diff --git a/java/src/game/worldgen/FeatureOres.java b/java/src/common/worldgen/FeatureOres.java similarity index 97% rename from java/src/game/worldgen/FeatureOres.java rename to java/src/common/worldgen/FeatureOres.java index 3383655..bb30028 100755 --- a/java/src/game/worldgen/FeatureOres.java +++ b/java/src/common/worldgen/FeatureOres.java @@ -1,11 +1,11 @@ -package game.worldgen; +package common.worldgen; -import game.block.Block; -import game.rng.Random; -import game.util.ExtMath; -import game.world.BlockPos; -import game.world.State; -import game.world.WorldServer; +import common.block.Block; +import common.rng.Random; +import common.util.ExtMath; +import common.world.BlockPos; +import common.world.State; +import common.world.WorldServer; public class FeatureOres { diff --git a/java/src/game/worldgen/GeneratorCavern.java b/java/src/common/worldgen/GeneratorCavern.java similarity index 97% rename from java/src/game/worldgen/GeneratorCavern.java rename to java/src/common/worldgen/GeneratorCavern.java index adec0aa..0aed076 100755 --- a/java/src/game/worldgen/GeneratorCavern.java +++ b/java/src/common/worldgen/GeneratorCavern.java @@ -1,10 +1,10 @@ -package game.worldgen; +package common.worldgen; -import game.rng.OctaveGen; -import game.rng.Random; -import game.util.ExtMath; -import game.world.State; -import game.world.WorldServer; +import common.rng.OctaveGen; +import common.rng.Random; +import common.util.ExtMath; +import common.world.State; +import common.world.WorldServer; public class GeneratorCavern implements ChunkGenerator { diff --git a/java/src/game/worldgen/GeneratorDebug.java b/java/src/common/worldgen/GeneratorDebug.java similarity index 82% rename from java/src/game/worldgen/GeneratorDebug.java rename to java/src/common/worldgen/GeneratorDebug.java index b945e86..58ca6c1 100755 --- a/java/src/game/worldgen/GeneratorDebug.java +++ b/java/src/common/worldgen/GeneratorDebug.java @@ -1,13 +1,13 @@ -package game.worldgen; +package common.worldgen; import java.util.List; -import game.block.Block; -import game.collect.Lists; -import game.init.BlockRegistry; -import game.util.ExtMath; -import game.world.State; -import game.world.WorldServer; +import common.block.Block; +import common.collect.Lists; +import common.init.BlockRegistry; +import common.util.ExtMath; +import common.world.State; +import common.world.WorldServer; public class GeneratorDebug implements ChunkGenerator { diff --git a/java/src/game/worldgen/GeneratorDestroyed.java b/java/src/common/worldgen/GeneratorDestroyed.java similarity index 86% rename from java/src/game/worldgen/GeneratorDestroyed.java rename to java/src/common/worldgen/GeneratorDestroyed.java index 03ae28b..5eea1c5 100755 --- a/java/src/game/worldgen/GeneratorDestroyed.java +++ b/java/src/common/worldgen/GeneratorDestroyed.java @@ -1,9 +1,9 @@ -package game.worldgen; +package common.worldgen; -import game.init.Blocks; -import game.rng.Random; -import game.world.State; -import game.world.WorldServer; +import common.init.Blocks; +import common.rng.Random; +import common.world.State; +import common.world.WorldServer; public class GeneratorDestroyed implements ChunkGenerator { diff --git a/java/src/game/worldgen/GeneratorFlat.java b/java/src/common/worldgen/GeneratorFlat.java similarity index 90% rename from java/src/game/worldgen/GeneratorFlat.java rename to java/src/common/worldgen/GeneratorFlat.java index 464e66a..2c0071b 100755 --- a/java/src/game/worldgen/GeneratorFlat.java +++ b/java/src/common/worldgen/GeneratorFlat.java @@ -1,9 +1,9 @@ -package game.worldgen; +package common.worldgen; import java.util.Arrays; -import game.world.State; -import game.world.WorldServer; +import common.world.State; +import common.world.WorldServer; public class GeneratorFlat implements ChunkGenerator { private final State[] layers; diff --git a/java/src/game/worldgen/GeneratorIsland.java b/java/src/common/worldgen/GeneratorIsland.java similarity index 97% rename from java/src/game/worldgen/GeneratorIsland.java rename to java/src/common/worldgen/GeneratorIsland.java index f202525..14c3b81 100755 --- a/java/src/game/worldgen/GeneratorIsland.java +++ b/java/src/common/worldgen/GeneratorIsland.java @@ -1,10 +1,10 @@ -package game.worldgen; +package common.worldgen; -import game.rng.OctaveGen; -import game.rng.Random; -import game.util.ExtMath; -import game.world.State; -import game.world.WorldServer; +import common.rng.OctaveGen; +import common.rng.Random; +import common.util.ExtMath; +import common.world.State; +import common.world.WorldServer; public class GeneratorIsland implements ChunkGenerator { diff --git a/java/src/game/worldgen/GeneratorPerlin.java b/java/src/common/worldgen/GeneratorPerlin.java similarity index 97% rename from java/src/game/worldgen/GeneratorPerlin.java rename to java/src/common/worldgen/GeneratorPerlin.java index 2b4ff2d..f9156a9 100755 --- a/java/src/game/worldgen/GeneratorPerlin.java +++ b/java/src/common/worldgen/GeneratorPerlin.java @@ -1,13 +1,13 @@ -package game.worldgen; +package common.worldgen; -import game.biome.Biome; -import game.dimension.Dimension; -import game.rng.NoiseGen; -import game.rng.OctaveGen; -import game.rng.Random; -import game.util.ExtMath; -import game.world.State; -import game.world.WorldServer; +import common.biome.Biome; +import common.dimension.Dimension; +import common.rng.NoiseGen; +import common.rng.OctaveGen; +import common.rng.Random; +import common.util.ExtMath; +import common.world.State; +import common.world.WorldServer; public class GeneratorPerlin implements ChunkGenerator { diff --git a/java/src/game/worldgen/GeneratorSimple.java b/java/src/common/worldgen/GeneratorSimple.java similarity index 95% rename from java/src/game/worldgen/GeneratorSimple.java rename to java/src/common/worldgen/GeneratorSimple.java index deec5a5..3ba0303 100755 --- a/java/src/game/worldgen/GeneratorSimple.java +++ b/java/src/common/worldgen/GeneratorSimple.java @@ -1,10 +1,10 @@ -package game.worldgen; +package common.worldgen; -import game.rng.NoiseGen; -import game.rng.OctaveGen; -import game.rng.Random; -import game.world.State; -import game.world.WorldServer; +import common.rng.NoiseGen; +import common.rng.OctaveGen; +import common.rng.Random; +import common.world.State; +import common.world.WorldServer; public class GeneratorSimple implements ChunkGenerator { diff --git a/java/src/game/worldgen/LootConstants.java b/java/src/common/worldgen/LootConstants.java similarity index 94% rename from java/src/game/worldgen/LootConstants.java rename to java/src/common/worldgen/LootConstants.java index 5eb0b1e..9e52c59 100755 --- a/java/src/game/worldgen/LootConstants.java +++ b/java/src/common/worldgen/LootConstants.java @@ -1,20 +1,20 @@ -package game.worldgen; +package common.worldgen; -import game.biome.RngSpawn; -import game.color.DyeColor; -import game.entity.npc.EntityDarkMage; -import game.entity.npc.EntityMage; -import game.entity.npc.EntityMagma; -import game.entity.npc.EntityTiefling; -import game.entity.npc.EntityUndead; -import game.entity.projectile.RngFishable; -import game.init.Blocks; -import game.init.ItemRegistry; -import game.init.Items; -import game.item.ItemFishFood; -import game.item.ItemStack; -import game.item.RngLoot; -import game.rng.WeightedList; +import common.biome.RngSpawn; +import common.color.DyeColor; +import common.entity.npc.EntityDarkMage; +import common.entity.npc.EntityMage; +import common.entity.npc.EntityMagma; +import common.entity.npc.EntityTiefling; +import common.entity.npc.EntityUndead; +import common.entity.projectile.RngFishable; +import common.init.Blocks; +import common.init.ItemRegistry; +import common.init.Items; +import common.item.ItemFishFood; +import common.item.ItemStack; +import common.item.RngLoot; +import common.rng.WeightedList; public abstract class LootConstants { public static final WeightedList FISHING_JUNK = new WeightedList( diff --git a/java/src/game/worldgen/ReplacerAltBiome.java b/java/src/common/worldgen/ReplacerAltBiome.java similarity index 93% rename from java/src/game/worldgen/ReplacerAltBiome.java rename to java/src/common/worldgen/ReplacerAltBiome.java index 45aa85a..549d8c9 100755 --- a/java/src/game/worldgen/ReplacerAltBiome.java +++ b/java/src/common/worldgen/ReplacerAltBiome.java @@ -1,13 +1,13 @@ -package game.worldgen; +package common.worldgen; -import game.biome.Biome; -import game.block.Block; -import game.init.Blocks; -import game.rng.NoiseGen; -import game.rng.OctaveGen; -import game.rng.Random; -import game.world.State; -import game.world.WorldServer; +import common.biome.Biome; +import common.block.Block; +import common.init.Blocks; +import common.rng.NoiseGen; +import common.rng.OctaveGen; +import common.rng.Random; +import common.world.State; +import common.world.WorldServer; public class ReplacerAltBiome implements BlockReplacer { diff --git a/java/src/game/worldgen/ReplacerAltSurface.java b/java/src/common/worldgen/ReplacerAltSurface.java similarity index 95% rename from java/src/game/worldgen/ReplacerAltSurface.java rename to java/src/common/worldgen/ReplacerAltSurface.java index 26f76b3..3dc3c58 100755 --- a/java/src/game/worldgen/ReplacerAltSurface.java +++ b/java/src/common/worldgen/ReplacerAltSurface.java @@ -1,12 +1,12 @@ -package game.worldgen; +package common.worldgen; -import game.biome.Biome; -import game.block.Block; -import game.material.Material; -import game.rng.OctaveGen; -import game.rng.Random; -import game.world.State; -import game.world.WorldServer; +import common.biome.Biome; +import common.block.Block; +import common.material.Material; +import common.rng.OctaveGen; +import common.rng.Random; +import common.world.State; +import common.world.WorldServer; public class ReplacerAltSurface implements BlockReplacer { diff --git a/java/src/game/worldgen/ReplacerBiome.java b/java/src/common/worldgen/ReplacerBiome.java similarity index 84% rename from java/src/game/worldgen/ReplacerBiome.java rename to java/src/common/worldgen/ReplacerBiome.java index 74a8acb..aa3d70a 100755 --- a/java/src/game/worldgen/ReplacerBiome.java +++ b/java/src/common/worldgen/ReplacerBiome.java @@ -1,9 +1,9 @@ -package game.worldgen; +package common.worldgen; -import game.biome.Biome; -import game.rng.PerlinGen; -import game.rng.Random; -import game.world.WorldServer; +import common.biome.Biome; +import common.rng.PerlinGen; +import common.rng.Random; +import common.world.WorldServer; public class ReplacerBiome implements BlockReplacer { diff --git a/java/src/game/worldgen/ReplacerTopLayer.java b/java/src/common/worldgen/ReplacerTopLayer.java similarity index 90% rename from java/src/game/worldgen/ReplacerTopLayer.java rename to java/src/common/worldgen/ReplacerTopLayer.java index ab62aa1..d27dc7e 100755 --- a/java/src/game/worldgen/ReplacerTopLayer.java +++ b/java/src/common/worldgen/ReplacerTopLayer.java @@ -1,12 +1,12 @@ -package game.worldgen; +package common.worldgen; -import game.biome.Biome; -import game.block.Block; -import game.init.Blocks; -import game.material.Material; -import game.rng.Random; -import game.world.State; -import game.world.WorldServer; +import common.biome.Biome; +import common.block.Block; +import common.init.Blocks; +import common.material.Material; +import common.rng.Random; +import common.world.State; +import common.world.WorldServer; public class ReplacerTopLayer implements BlockReplacer { diff --git a/java/src/game/worldgen/caves/MapGenBase.java b/java/src/common/worldgen/caves/MapGenBase.java similarity index 90% rename from java/src/game/worldgen/caves/MapGenBase.java rename to java/src/common/worldgen/caves/MapGenBase.java index ecb6bec..82fb296 100755 --- a/java/src/game/worldgen/caves/MapGenBase.java +++ b/java/src/common/worldgen/caves/MapGenBase.java @@ -1,8 +1,8 @@ -package game.worldgen.caves; +package common.worldgen.caves; -import game.rng.Random; -import game.world.WorldServer; -import game.worldgen.ChunkPrimer; +import common.rng.Random; +import common.world.WorldServer; +import common.worldgen.ChunkPrimer; public class MapGenBase { diff --git a/java/src/game/worldgen/caves/MapGenBigCaves.java b/java/src/common/worldgen/caves/MapGenBigCaves.java similarity index 97% rename from java/src/game/worldgen/caves/MapGenBigCaves.java rename to java/src/common/worldgen/caves/MapGenBigCaves.java index a24947e..c04c80b 100755 --- a/java/src/game/worldgen/caves/MapGenBigCaves.java +++ b/java/src/common/worldgen/caves/MapGenBigCaves.java @@ -1,12 +1,12 @@ -package game.worldgen.caves; +package common.worldgen.caves; -import game.block.Block; -import game.init.Blocks; -import game.rng.Random; -import game.util.ExtMath; -import game.world.State; -import game.world.WorldServer; -import game.worldgen.ChunkPrimer; +import common.block.Block; +import common.init.Blocks; +import common.rng.Random; +import common.util.ExtMath; +import common.world.State; +import common.world.WorldServer; +import common.worldgen.ChunkPrimer; public class MapGenBigCaves extends MapGenBase { diff --git a/java/src/game/worldgen/caves/MapGenCaves.java b/java/src/common/worldgen/caves/MapGenCaves.java similarity index 97% rename from java/src/game/worldgen/caves/MapGenCaves.java rename to java/src/common/worldgen/caves/MapGenCaves.java index c7fb66c..6f2a15e 100755 --- a/java/src/game/worldgen/caves/MapGenCaves.java +++ b/java/src/common/worldgen/caves/MapGenCaves.java @@ -1,16 +1,16 @@ -package game.worldgen.caves; +package common.worldgen.caves; -import game.block.Block; -import game.block.BlockColored; -import game.block.BlockSand; -import game.color.DyeColor; -import game.init.Blocks; -import game.rng.Random; -import game.util.ExtMath; -import game.world.BlockPos; -import game.world.State; -import game.world.WorldServer; -import game.worldgen.ChunkPrimer; +import common.block.Block; +import common.block.BlockColored; +import common.block.BlockSand; +import common.color.DyeColor; +import common.init.Blocks; +import common.rng.Random; +import common.util.ExtMath; +import common.world.BlockPos; +import common.world.State; +import common.world.WorldServer; +import common.worldgen.ChunkPrimer; public class MapGenCaves extends MapGenBase { diff --git a/java/src/game/worldgen/caves/MapGenRavine.java b/java/src/common/worldgen/caves/MapGenRavine.java similarity index 97% rename from java/src/game/worldgen/caves/MapGenRavine.java rename to java/src/common/worldgen/caves/MapGenRavine.java index a9e8958..13d30c0 100755 --- a/java/src/game/worldgen/caves/MapGenRavine.java +++ b/java/src/common/worldgen/caves/MapGenRavine.java @@ -1,13 +1,13 @@ -package game.worldgen.caves; +package common.worldgen.caves; -import game.block.Block; -import game.init.Blocks; -import game.rng.Random; -import game.util.ExtMath; -import game.world.BlockPos; -import game.world.State; -import game.world.WorldServer; -import game.worldgen.ChunkPrimer; +import common.block.Block; +import common.init.Blocks; +import common.rng.Random; +import common.util.ExtMath; +import common.world.BlockPos; +import common.world.State; +import common.world.WorldServer; +import common.worldgen.ChunkPrimer; public class MapGenRavine extends MapGenBase { diff --git a/java/src/game/worldgen/feature/WorldGenAbandonedChest.java b/java/src/common/worldgen/feature/WorldGenAbandonedChest.java similarity index 79% rename from java/src/game/worldgen/feature/WorldGenAbandonedChest.java rename to java/src/common/worldgen/feature/WorldGenAbandonedChest.java index 72bd27a..79206eb 100755 --- a/java/src/game/worldgen/feature/WorldGenAbandonedChest.java +++ b/java/src/common/worldgen/feature/WorldGenAbandonedChest.java @@ -1,17 +1,17 @@ -package game.worldgen.feature; +package common.worldgen.feature; -import game.block.Block; -import game.init.Blocks; -import game.item.RngLoot; -import game.material.Material; -import game.rng.Random; -import game.rng.WeightedList; -import game.tileentity.TileEntity; -import game.tileentity.TileEntityChest; -import game.world.BlockPos; -import game.world.WorldServer; -import game.worldgen.FeatureGenerator; -import game.worldgen.LootConstants; +import common.block.Block; +import common.init.Blocks; +import common.item.RngLoot; +import common.material.Material; +import common.rng.Random; +import common.rng.WeightedList; +import common.tileentity.TileEntity; +import common.tileentity.TileEntityChest; +import common.world.BlockPos; +import common.world.WorldServer; +import common.worldgen.FeatureGenerator; +import common.worldgen.LootConstants; public class WorldGenAbandonedChest extends FeatureGenerator { diff --git a/java/src/game/worldgen/feature/WorldGenAsteroid.java b/java/src/common/worldgen/feature/WorldGenAsteroid.java similarity index 91% rename from java/src/game/worldgen/feature/WorldGenAsteroid.java rename to java/src/common/worldgen/feature/WorldGenAsteroid.java index bf8d2fc..35c2fea 100755 --- a/java/src/game/worldgen/feature/WorldGenAsteroid.java +++ b/java/src/common/worldgen/feature/WorldGenAsteroid.java @@ -1,10 +1,10 @@ -package game.worldgen.feature; +package common.worldgen.feature; -import game.rng.Random; -import game.world.BlockPos; -import game.world.State; -import game.world.WorldServer; -import game.worldgen.FeatureGenerator; +import common.rng.Random; +import common.world.BlockPos; +import common.world.State; +import common.world.WorldServer; +import common.worldgen.FeatureGenerator; public class WorldGenAsteroid extends FeatureGenerator { private final State[] blocks; diff --git a/java/src/game/worldgen/feature/WorldGenBlockBlob.java b/java/src/common/worldgen/feature/WorldGenBlockBlob.java similarity index 90% rename from java/src/game/worldgen/feature/WorldGenBlockBlob.java rename to java/src/common/worldgen/feature/WorldGenBlockBlob.java index c6eda23..98e6f18 100755 --- a/java/src/game/worldgen/feature/WorldGenBlockBlob.java +++ b/java/src/common/worldgen/feature/WorldGenBlockBlob.java @@ -1,11 +1,11 @@ -package game.worldgen.feature; +package common.worldgen.feature; -import game.block.Block; -import game.init.Blocks; -import game.rng.Random; -import game.world.BlockPos; -import game.world.WorldServer; -import game.worldgen.FeatureGenerator; +import common.block.Block; +import common.init.Blocks; +import common.rng.Random; +import common.world.BlockPos; +import common.world.WorldServer; +import common.worldgen.FeatureGenerator; public class WorldGenBlockBlob extends FeatureGenerator { diff --git a/java/src/game/worldgen/feature/WorldGenClay.java b/java/src/common/worldgen/feature/WorldGenClay.java similarity index 87% rename from java/src/game/worldgen/feature/WorldGenClay.java rename to java/src/common/worldgen/feature/WorldGenClay.java index 7f7fdce..1be9142 100755 --- a/java/src/game/worldgen/feature/WorldGenClay.java +++ b/java/src/common/worldgen/feature/WorldGenClay.java @@ -1,11 +1,11 @@ -package game.worldgen.feature; +package common.worldgen.feature; -import game.block.Block; -import game.init.Blocks; -import game.rng.Random; -import game.world.BlockPos; -import game.world.WorldServer; -import game.worldgen.FeatureGenerator; +import common.block.Block; +import common.init.Blocks; +import common.rng.Random; +import common.world.BlockPos; +import common.world.WorldServer; +import common.worldgen.FeatureGenerator; public class WorldGenClay extends FeatureGenerator { diff --git a/java/src/game/worldgen/feature/WorldGenClayExt.java b/java/src/common/worldgen/feature/WorldGenClayExt.java similarity index 90% rename from java/src/game/worldgen/feature/WorldGenClayExt.java rename to java/src/common/worldgen/feature/WorldGenClayExt.java index 93b99bd..9f9499e 100755 --- a/java/src/game/worldgen/feature/WorldGenClayExt.java +++ b/java/src/common/worldgen/feature/WorldGenClayExt.java @@ -1,11 +1,11 @@ -package game.worldgen.feature; +package common.worldgen.feature; -import game.block.Block; -import game.init.Blocks; -import game.rng.Random; -import game.util.ExtMath; -import game.world.BlockPos; -import game.world.WorldServer; +import common.block.Block; +import common.init.Blocks; +import common.rng.Random; +import common.util.ExtMath; +import common.world.BlockPos; +import common.world.WorldServer; public class WorldGenClayExt extends WorldGenClay { public WorldGenClayExt(int blocks) { diff --git a/java/src/game/worldgen/feature/WorldGenDesertWells.java b/java/src/common/worldgen/feature/WorldGenDesertWells.java similarity index 89% rename from java/src/game/worldgen/feature/WorldGenDesertWells.java rename to java/src/common/worldgen/feature/WorldGenDesertWells.java index b0e233d..3412134 100755 --- a/java/src/game/worldgen/feature/WorldGenDesertWells.java +++ b/java/src/common/worldgen/feature/WorldGenDesertWells.java @@ -1,16 +1,16 @@ -package game.worldgen.feature; +package common.worldgen.feature; -import game.block.BlockSand; -import game.block.BlockSlab; -import game.init.Blocks; -import game.pattern.BlockStateHelper; -import game.rng.Random; -import game.util.Predicates; -import game.world.BlockPos; -import game.world.Facing; -import game.world.State; -import game.world.WorldServer; -import game.worldgen.FeatureGenerator; +import common.block.BlockSand; +import common.block.BlockSlab; +import common.init.Blocks; +import common.pattern.BlockStateHelper; +import common.rng.Random; +import common.util.Predicates; +import common.world.BlockPos; +import common.world.Facing; +import common.world.State; +import common.world.WorldServer; +import common.worldgen.FeatureGenerator; public class WorldGenDesertWells extends FeatureGenerator { diff --git a/java/src/game/worldgen/feature/WorldGenFire.java b/java/src/common/worldgen/feature/WorldGenFire.java similarity index 75% rename from java/src/game/worldgen/feature/WorldGenFire.java rename to java/src/common/worldgen/feature/WorldGenFire.java index f878e76..09e1665 100755 --- a/java/src/game/worldgen/feature/WorldGenFire.java +++ b/java/src/common/worldgen/feature/WorldGenFire.java @@ -1,10 +1,10 @@ -package game.worldgen.feature; +package common.worldgen.feature; -import game.init.Blocks; -import game.rng.Random; -import game.world.BlockPos; -import game.world.WorldServer; -import game.worldgen.FeatureGenerator; +import common.init.Blocks; +import common.rng.Random; +import common.world.BlockPos; +import common.world.WorldServer; +import common.worldgen.FeatureGenerator; public class WorldGenFire extends FeatureGenerator { diff --git a/java/src/game/worldgen/feature/WorldGenGlowStone.java b/java/src/common/worldgen/feature/WorldGenGlowStone.java similarity index 85% rename from java/src/game/worldgen/feature/WorldGenGlowStone.java rename to java/src/common/worldgen/feature/WorldGenGlowStone.java index 9ec482f..3dd6047 100755 --- a/java/src/game/worldgen/feature/WorldGenGlowStone.java +++ b/java/src/common/worldgen/feature/WorldGenGlowStone.java @@ -1,12 +1,12 @@ -package game.worldgen.feature; +package common.worldgen.feature; -import game.init.Blocks; -import game.material.Material; -import game.rng.Random; -import game.world.BlockPos; -import game.world.Facing; -import game.world.WorldServer; -import game.worldgen.FeatureGenerator; +import common.init.Blocks; +import common.material.Material; +import common.rng.Random; +import common.world.BlockPos; +import common.world.Facing; +import common.world.WorldServer; +import common.worldgen.FeatureGenerator; public class WorldGenGlowStone extends FeatureGenerator { diff --git a/java/src/game/worldgen/feature/WorldGenHellLava.java b/java/src/common/worldgen/feature/WorldGenHellLava.java similarity index 90% rename from java/src/game/worldgen/feature/WorldGenHellLava.java rename to java/src/common/worldgen/feature/WorldGenHellLava.java index 762423d..a878c5c 100755 --- a/java/src/game/worldgen/feature/WorldGenHellLava.java +++ b/java/src/common/worldgen/feature/WorldGenHellLava.java @@ -1,12 +1,12 @@ -package game.worldgen.feature; +package common.worldgen.feature; -import game.block.Block; -import game.init.Blocks; -import game.material.Material; -import game.rng.Random; -import game.world.BlockPos; -import game.world.WorldServer; -import game.worldgen.FeatureGenerator; +import common.block.Block; +import common.init.Blocks; +import common.material.Material; +import common.rng.Random; +import common.world.BlockPos; +import common.world.WorldServer; +import common.worldgen.FeatureGenerator; public class WorldGenHellLava extends FeatureGenerator { diff --git a/java/src/game/worldgen/feature/WorldGenIcePath.java b/java/src/common/worldgen/feature/WorldGenIcePath.java similarity index 88% rename from java/src/game/worldgen/feature/WorldGenIcePath.java rename to java/src/common/worldgen/feature/WorldGenIcePath.java index 7012684..f0b26ba 100755 --- a/java/src/game/worldgen/feature/WorldGenIcePath.java +++ b/java/src/common/worldgen/feature/WorldGenIcePath.java @@ -1,11 +1,11 @@ -package game.worldgen.feature; +package common.worldgen.feature; -import game.block.Block; -import game.init.Blocks; -import game.rng.Random; -import game.world.BlockPos; -import game.world.WorldServer; -import game.worldgen.FeatureGenerator; +import common.block.Block; +import common.init.Blocks; +import common.rng.Random; +import common.world.BlockPos; +import common.world.WorldServer; +import common.worldgen.FeatureGenerator; public class WorldGenIcePath extends FeatureGenerator { diff --git a/java/src/game/worldgen/feature/WorldGenIceSpike.java b/java/src/common/worldgen/feature/WorldGenIceSpike.java similarity index 93% rename from java/src/game/worldgen/feature/WorldGenIceSpike.java rename to java/src/common/worldgen/feature/WorldGenIceSpike.java index 6e916f7..3f78db2 100755 --- a/java/src/game/worldgen/feature/WorldGenIceSpike.java +++ b/java/src/common/worldgen/feature/WorldGenIceSpike.java @@ -1,13 +1,13 @@ -package game.worldgen.feature; +package common.worldgen.feature; -import game.block.Block; -import game.init.Blocks; -import game.material.Material; -import game.rng.Random; -import game.util.ExtMath; -import game.world.BlockPos; -import game.world.WorldServer; -import game.worldgen.FeatureGenerator; +import common.block.Block; +import common.init.Blocks; +import common.material.Material; +import common.rng.Random; +import common.util.ExtMath; +import common.world.BlockPos; +import common.world.WorldServer; +import common.worldgen.FeatureGenerator; public class WorldGenIceSpike extends FeatureGenerator { diff --git a/java/src/game/worldgen/feature/WorldGenSand.java b/java/src/common/worldgen/feature/WorldGenSand.java similarity index 88% rename from java/src/game/worldgen/feature/WorldGenSand.java rename to java/src/common/worldgen/feature/WorldGenSand.java index d1bed59..178abdd 100755 --- a/java/src/game/worldgen/feature/WorldGenSand.java +++ b/java/src/common/worldgen/feature/WorldGenSand.java @@ -1,11 +1,11 @@ -package game.worldgen.feature; +package common.worldgen.feature; -import game.block.Block; -import game.init.Blocks; -import game.rng.Random; -import game.world.BlockPos; -import game.world.WorldServer; -import game.worldgen.FeatureGenerator; +import common.block.Block; +import common.init.Blocks; +import common.rng.Random; +import common.world.BlockPos; +import common.world.WorldServer; +import common.worldgen.FeatureGenerator; public class WorldGenSand extends FeatureGenerator { diff --git a/java/src/game/worldgen/feature/WorldGenSpikes.java b/java/src/common/worldgen/feature/WorldGenSpikes.java similarity index 90% rename from java/src/game/worldgen/feature/WorldGenSpikes.java rename to java/src/common/worldgen/feature/WorldGenSpikes.java index ea88f57..c22daf1 100755 --- a/java/src/game/worldgen/feature/WorldGenSpikes.java +++ b/java/src/common/worldgen/feature/WorldGenSpikes.java @@ -1,13 +1,13 @@ -package game.worldgen.feature; +package common.worldgen.feature; -import game.block.Block; -import game.entity.Entity; -import game.entity.item.EntityCrystal; -import game.rng.Random; -import game.world.BlockPos; -import game.world.State; -import game.world.WorldServer; -import game.worldgen.FeatureGenerator; +import common.block.Block; +import common.entity.Entity; +import common.entity.item.EntityCrystal; +import common.rng.Random; +import common.world.BlockPos; +import common.world.State; +import common.world.WorldServer; +import common.worldgen.FeatureGenerator; public class WorldGenSpikes extends FeatureGenerator { diff --git a/java/src/game/worldgen/foliage/FeatureDoublePlant.java b/java/src/common/worldgen/foliage/FeatureDoublePlant.java similarity index 81% rename from java/src/game/worldgen/foliage/FeatureDoublePlant.java rename to java/src/common/worldgen/foliage/FeatureDoublePlant.java index a276dc2..9d61b5b 100755 --- a/java/src/game/worldgen/foliage/FeatureDoublePlant.java +++ b/java/src/common/worldgen/foliage/FeatureDoublePlant.java @@ -1,10 +1,10 @@ -package game.worldgen.foliage; +package common.worldgen.foliage; -import game.block.BlockDoublePlant; -import game.init.Blocks; -import game.rng.Random; -import game.world.BlockPos; -import game.world.WorldServer; +import common.block.BlockDoublePlant; +import common.init.Blocks; +import common.rng.Random; +import common.world.BlockPos; +import common.world.WorldServer; public class FeatureDoublePlant { diff --git a/java/src/game/worldgen/foliage/WorldGenBigMushroom.java b/java/src/common/worldgen/foliage/WorldGenBigMushroom.java similarity index 96% rename from java/src/game/worldgen/foliage/WorldGenBigMushroom.java rename to java/src/common/worldgen/foliage/WorldGenBigMushroom.java index 11523ae..09b707e 100755 --- a/java/src/game/worldgen/foliage/WorldGenBigMushroom.java +++ b/java/src/common/worldgen/foliage/WorldGenBigMushroom.java @@ -1,13 +1,13 @@ -package game.worldgen.foliage; +package common.worldgen.foliage; -import game.block.Block; -import game.block.BlockHugeMushroom; -import game.init.Blocks; -import game.material.Material; -import game.rng.Random; -import game.world.BlockPos; -import game.world.WorldServer; -import game.worldgen.FeatureGenerator; +import common.block.Block; +import common.block.BlockHugeMushroom; +import common.init.Blocks; +import common.material.Material; +import common.rng.Random; +import common.world.BlockPos; +import common.world.WorldServer; +import common.worldgen.FeatureGenerator; public class WorldGenBigMushroom extends FeatureGenerator { diff --git a/java/src/game/worldgen/foliage/WorldGenCactus.java b/java/src/common/worldgen/foliage/WorldGenCactus.java similarity index 80% rename from java/src/game/worldgen/foliage/WorldGenCactus.java rename to java/src/common/worldgen/foliage/WorldGenCactus.java index 195223b..a148c2e 100755 --- a/java/src/game/worldgen/foliage/WorldGenCactus.java +++ b/java/src/common/worldgen/foliage/WorldGenCactus.java @@ -1,10 +1,10 @@ -package game.worldgen.foliage; +package common.worldgen.foliage; -import game.init.Blocks; -import game.rng.Random; -import game.world.BlockPos; -import game.world.WorldServer; -import game.worldgen.FeatureGenerator; +import common.init.Blocks; +import common.rng.Random; +import common.world.BlockPos; +import common.world.WorldServer; +import common.worldgen.FeatureGenerator; public class WorldGenCactus extends FeatureGenerator { diff --git a/java/src/game/worldgen/foliage/WorldGenDeadBush.java b/java/src/common/worldgen/foliage/WorldGenDeadBush.java similarity index 77% rename from java/src/game/worldgen/foliage/WorldGenDeadBush.java rename to java/src/common/worldgen/foliage/WorldGenDeadBush.java index 32d52b3..4bff100 100755 --- a/java/src/game/worldgen/foliage/WorldGenDeadBush.java +++ b/java/src/common/worldgen/foliage/WorldGenDeadBush.java @@ -1,12 +1,12 @@ -package game.worldgen.foliage; +package common.worldgen.foliage; -import game.block.Block; -import game.init.Blocks; -import game.material.Material; -import game.rng.Random; -import game.world.BlockPos; -import game.world.WorldServer; -import game.worldgen.FeatureGenerator; +import common.block.Block; +import common.init.Blocks; +import common.material.Material; +import common.rng.Random; +import common.world.BlockPos; +import common.world.WorldServer; +import common.worldgen.FeatureGenerator; public class WorldGenDeadBush extends FeatureGenerator { diff --git a/java/src/game/worldgen/foliage/WorldGenFlowers.java b/java/src/common/worldgen/foliage/WorldGenFlowers.java similarity index 83% rename from java/src/game/worldgen/foliage/WorldGenFlowers.java rename to java/src/common/worldgen/foliage/WorldGenFlowers.java index 452e279..b8ab2da 100755 --- a/java/src/game/worldgen/foliage/WorldGenFlowers.java +++ b/java/src/common/worldgen/foliage/WorldGenFlowers.java @@ -1,11 +1,11 @@ -package game.worldgen.foliage; +package common.worldgen.foliage; -import game.block.BlockFlower; -import game.rng.Random; -import game.world.BlockPos; -import game.world.State; -import game.world.WorldServer; -import game.worldgen.FeatureGenerator; +import common.block.BlockFlower; +import common.rng.Random; +import common.world.BlockPos; +import common.world.State; +import common.world.WorldServer; +import common.worldgen.FeatureGenerator; public class WorldGenFlowers extends FeatureGenerator { diff --git a/java/src/game/worldgen/foliage/WorldGenMelon.java b/java/src/common/worldgen/foliage/WorldGenMelon.java similarity index 76% rename from java/src/game/worldgen/foliage/WorldGenMelon.java rename to java/src/common/worldgen/foliage/WorldGenMelon.java index 50f3029..b48dedf 100755 --- a/java/src/game/worldgen/foliage/WorldGenMelon.java +++ b/java/src/common/worldgen/foliage/WorldGenMelon.java @@ -1,10 +1,10 @@ -package game.worldgen.foliage; +package common.worldgen.foliage; -import game.init.Blocks; -import game.rng.Random; -import game.world.BlockPos; -import game.world.WorldServer; -import game.worldgen.FeatureGenerator; +import common.init.Blocks; +import common.rng.Random; +import common.world.BlockPos; +import common.world.WorldServer; +import common.worldgen.FeatureGenerator; public class WorldGenMelon extends FeatureGenerator { diff --git a/java/src/game/worldgen/foliage/WorldGenMushroom.java b/java/src/common/worldgen/foliage/WorldGenMushroom.java similarity index 80% rename from java/src/game/worldgen/foliage/WorldGenMushroom.java rename to java/src/common/worldgen/foliage/WorldGenMushroom.java index 113a43d..a23509c 100755 --- a/java/src/game/worldgen/foliage/WorldGenMushroom.java +++ b/java/src/common/worldgen/foliage/WorldGenMushroom.java @@ -1,10 +1,10 @@ -package game.worldgen.foliage; +package common.worldgen.foliage; -import game.block.BlockBush; -import game.rng.Random; -import game.world.BlockPos; -import game.world.WorldServer; -import game.worldgen.FeatureGenerator; +import common.block.BlockBush; +import common.rng.Random; +import common.world.BlockPos; +import common.world.WorldServer; +import common.worldgen.FeatureGenerator; public class WorldGenMushroom extends FeatureGenerator { diff --git a/java/src/game/worldgen/foliage/WorldGenPumpkin.java b/java/src/common/worldgen/foliage/WorldGenPumpkin.java similarity index 73% rename from java/src/game/worldgen/foliage/WorldGenPumpkin.java rename to java/src/common/worldgen/foliage/WorldGenPumpkin.java index e93d8c0..e15fec5 100755 --- a/java/src/game/worldgen/foliage/WorldGenPumpkin.java +++ b/java/src/common/worldgen/foliage/WorldGenPumpkin.java @@ -1,12 +1,12 @@ -package game.worldgen.foliage; +package common.worldgen.foliage; -import game.block.BlockPumpkin; -import game.init.Blocks; -import game.rng.Random; -import game.world.BlockPos; -import game.world.Facing; -import game.world.WorldServer; -import game.worldgen.FeatureGenerator; +import common.block.BlockPumpkin; +import common.init.Blocks; +import common.rng.Random; +import common.world.BlockPos; +import common.world.Facing; +import common.world.WorldServer; +import common.worldgen.FeatureGenerator; public class WorldGenPumpkin extends FeatureGenerator { diff --git a/java/src/game/worldgen/foliage/WorldGenReed.java b/java/src/common/worldgen/foliage/WorldGenReed.java similarity index 84% rename from java/src/game/worldgen/foliage/WorldGenReed.java rename to java/src/common/worldgen/foliage/WorldGenReed.java index d540343..5162668 100755 --- a/java/src/game/worldgen/foliage/WorldGenReed.java +++ b/java/src/common/worldgen/foliage/WorldGenReed.java @@ -1,11 +1,11 @@ -package game.worldgen.foliage; +package common.worldgen.foliage; -import game.init.Blocks; -import game.material.Material; -import game.rng.Random; -import game.world.BlockPos; -import game.world.WorldServer; -import game.worldgen.FeatureGenerator; +import common.init.Blocks; +import common.material.Material; +import common.rng.Random; +import common.world.BlockPos; +import common.world.WorldServer; +import common.worldgen.FeatureGenerator; public class WorldGenReed extends FeatureGenerator { diff --git a/java/src/game/worldgen/foliage/WorldGenShrub.java b/java/src/common/worldgen/foliage/WorldGenShrub.java similarity index 86% rename from java/src/game/worldgen/foliage/WorldGenShrub.java rename to java/src/common/worldgen/foliage/WorldGenShrub.java index 01f342e..1ae5474 100755 --- a/java/src/game/worldgen/foliage/WorldGenShrub.java +++ b/java/src/common/worldgen/foliage/WorldGenShrub.java @@ -1,14 +1,14 @@ -package game.worldgen.foliage; +package common.worldgen.foliage; -import game.block.Block; -import game.block.BlockLeaves; -import game.init.Blocks; -import game.material.Material; -import game.rng.Random; -import game.world.BlockPos; -import game.world.State; -import game.world.WorldServer; -import game.worldgen.tree.WorldGenBaseTree; +import common.block.Block; +import common.block.BlockLeaves; +import common.init.Blocks; +import common.material.Material; +import common.rng.Random; +import common.world.BlockPos; +import common.world.State; +import common.world.WorldServer; +import common.worldgen.tree.WorldGenBaseTree; public class WorldGenShrub extends WorldGenBaseTree { diff --git a/java/src/game/worldgen/foliage/WorldGenTallGrass.java b/java/src/common/worldgen/foliage/WorldGenTallGrass.java similarity index 77% rename from java/src/game/worldgen/foliage/WorldGenTallGrass.java rename to java/src/common/worldgen/foliage/WorldGenTallGrass.java index d841f23..2bfeb28 100755 --- a/java/src/game/worldgen/foliage/WorldGenTallGrass.java +++ b/java/src/common/worldgen/foliage/WorldGenTallGrass.java @@ -1,14 +1,14 @@ -package game.worldgen.foliage; +package common.worldgen.foliage; -import game.block.Block; -import game.block.BlockTallGrass; -import game.init.Blocks; -import game.material.Material; -import game.rng.Random; -import game.world.BlockPos; -import game.world.State; -import game.world.WorldServer; -import game.worldgen.FeatureGenerator; +import common.block.Block; +import common.block.BlockTallGrass; +import common.init.Blocks; +import common.material.Material; +import common.rng.Random; +import common.world.BlockPos; +import common.world.State; +import common.world.WorldServer; +import common.worldgen.FeatureGenerator; public class WorldGenTallGrass extends FeatureGenerator { diff --git a/java/src/game/worldgen/foliage/WorldGenVines.java b/java/src/common/worldgen/foliage/WorldGenVines.java similarity index 81% rename from java/src/game/worldgen/foliage/WorldGenVines.java rename to java/src/common/worldgen/foliage/WorldGenVines.java index fb2333b..7b42cf0 100755 --- a/java/src/game/worldgen/foliage/WorldGenVines.java +++ b/java/src/common/worldgen/foliage/WorldGenVines.java @@ -1,13 +1,13 @@ -package game.worldgen.foliage; +package common.worldgen.foliage; -import game.block.BlockVine; -import game.init.Blocks; -import game.rng.Random; -import game.world.BlockPos; -import game.world.Facing; -import game.world.State; -import game.world.WorldServer; -import game.worldgen.FeatureGenerator; +import common.block.BlockVine; +import common.init.Blocks; +import common.rng.Random; +import common.world.BlockPos; +import common.world.Facing; +import common.world.State; +import common.world.WorldServer; +import common.worldgen.FeatureGenerator; public class WorldGenVines extends FeatureGenerator { diff --git a/java/src/game/worldgen/foliage/WorldGenWaterlily.java b/java/src/common/worldgen/foliage/WorldGenWaterlily.java similarity index 74% rename from java/src/game/worldgen/foliage/WorldGenWaterlily.java rename to java/src/common/worldgen/foliage/WorldGenWaterlily.java index 02d2df0..333505f 100755 --- a/java/src/game/worldgen/foliage/WorldGenWaterlily.java +++ b/java/src/common/worldgen/foliage/WorldGenWaterlily.java @@ -1,12 +1,12 @@ -package game.worldgen.foliage; +package common.worldgen.foliage; -import game.block.BlockDirectional; -import game.init.Blocks; -import game.rng.Random; -import game.world.BlockPos; -import game.world.Facing; -import game.world.WorldServer; -import game.worldgen.FeatureGenerator; +import common.block.BlockDirectional; +import common.init.Blocks; +import common.rng.Random; +import common.world.BlockPos; +import common.world.Facing; +import common.world.WorldServer; +import common.worldgen.FeatureGenerator; public class WorldGenWaterlily extends FeatureGenerator { diff --git a/java/src/game/worldgen/layer/GenLayer.java b/java/src/common/worldgen/layer/GenLayer.java similarity index 98% rename from java/src/game/worldgen/layer/GenLayer.java rename to java/src/common/worldgen/layer/GenLayer.java index 321cb6f..82c3c5b 100755 --- a/java/src/game/worldgen/layer/GenLayer.java +++ b/java/src/common/worldgen/layer/GenLayer.java @@ -1,6 +1,6 @@ -package game.worldgen.layer; +package common.worldgen.layer; -import game.biome.Biome; +import common.biome.Biome; public abstract class GenLayer { private long worldGenSeed; diff --git a/java/src/game/worldgen/layer/GenLayerAddAreas.java b/java/src/common/worldgen/layer/GenLayerAddAreas.java similarity index 99% rename from java/src/game/worldgen/layer/GenLayerAddAreas.java rename to java/src/common/worldgen/layer/GenLayerAddAreas.java index fa9a323..f5913b0 100755 --- a/java/src/game/worldgen/layer/GenLayerAddAreas.java +++ b/java/src/common/worldgen/layer/GenLayerAddAreas.java @@ -1,4 +1,4 @@ -package game.worldgen.layer; +package common.worldgen.layer; public class GenLayerAddAreas extends GenLayer { diff --git a/java/src/game/worldgen/layer/GenLayerAddExtra.java b/java/src/common/worldgen/layer/GenLayerAddExtra.java similarity index 96% rename from java/src/game/worldgen/layer/GenLayerAddExtra.java rename to java/src/common/worldgen/layer/GenLayerAddExtra.java index f18e670..e9a2cc0 100755 --- a/java/src/game/worldgen/layer/GenLayerAddExtra.java +++ b/java/src/common/worldgen/layer/GenLayerAddExtra.java @@ -1,6 +1,6 @@ -package game.worldgen.layer; +package common.worldgen.layer; -import game.biome.Biome; +import common.biome.Biome; public class GenLayerAddExtra extends GenLayer { diff --git a/java/src/game/worldgen/layer/GenLayerAddSea.java b/java/src/common/worldgen/layer/GenLayerAddSea.java similarity index 97% rename from java/src/game/worldgen/layer/GenLayerAddSea.java rename to java/src/common/worldgen/layer/GenLayerAddSea.java index e573bec..4e21a0c 100755 --- a/java/src/game/worldgen/layer/GenLayerAddSea.java +++ b/java/src/common/worldgen/layer/GenLayerAddSea.java @@ -1,6 +1,6 @@ -package game.worldgen.layer; +package common.worldgen.layer; -import game.biome.Biome; +import common.biome.Biome; public class GenLayerAddSea extends GenLayer { diff --git a/java/src/game/worldgen/layer/GenLayerAddSnow.java b/java/src/common/worldgen/layer/GenLayerAddSnow.java similarity index 98% rename from java/src/game/worldgen/layer/GenLayerAddSnow.java rename to java/src/common/worldgen/layer/GenLayerAddSnow.java index 4e8cfe2..de257dc 100755 --- a/java/src/game/worldgen/layer/GenLayerAddSnow.java +++ b/java/src/common/worldgen/layer/GenLayerAddSnow.java @@ -1,4 +1,4 @@ -package game.worldgen.layer; +package common.worldgen.layer; public class GenLayerAddSnow extends GenLayer { diff --git a/java/src/game/worldgen/layer/GenLayerBase.java b/java/src/common/worldgen/layer/GenLayerBase.java similarity index 95% rename from java/src/game/worldgen/layer/GenLayerBase.java rename to java/src/common/worldgen/layer/GenLayerBase.java index d82ae3e..bd1403d 100755 --- a/java/src/game/worldgen/layer/GenLayerBase.java +++ b/java/src/common/worldgen/layer/GenLayerBase.java @@ -1,4 +1,4 @@ -package game.worldgen.layer; +package common.worldgen.layer; public class GenLayerBase extends GenLayer { diff --git a/java/src/game/worldgen/layer/GenLayerBiome.java b/java/src/common/worldgen/layer/GenLayerBiome.java similarity index 97% rename from java/src/game/worldgen/layer/GenLayerBiome.java rename to java/src/common/worldgen/layer/GenLayerBiome.java index d20fd9f..e4a58e6 100755 --- a/java/src/game/worldgen/layer/GenLayerBiome.java +++ b/java/src/common/worldgen/layer/GenLayerBiome.java @@ -1,6 +1,6 @@ -package game.worldgen.layer; +package common.worldgen.layer; -import game.biome.Biome; +import common.biome.Biome; public class GenLayerBiome extends GenLayer { diff --git a/java/src/game/worldgen/layer/GenLayerBiomeEdge.java b/java/src/common/worldgen/layer/GenLayerBiomeEdge.java similarity index 98% rename from java/src/game/worldgen/layer/GenLayerBiomeEdge.java rename to java/src/common/worldgen/layer/GenLayerBiomeEdge.java index 9fd5068..f3653f7 100755 --- a/java/src/game/worldgen/layer/GenLayerBiomeEdge.java +++ b/java/src/common/worldgen/layer/GenLayerBiomeEdge.java @@ -1,7 +1,7 @@ -package game.worldgen.layer; +package common.worldgen.layer; -import game.biome.Biome; -import game.biome.Temperature; +import common.biome.Biome; +import common.biome.Temperature; public class GenLayerBiomeEdge extends GenLayer { diff --git a/java/src/game/worldgen/layer/GenLayerEdge.java b/java/src/common/worldgen/layer/GenLayerEdge.java similarity index 99% rename from java/src/game/worldgen/layer/GenLayerEdge.java rename to java/src/common/worldgen/layer/GenLayerEdge.java index 243506e..dda413d 100755 --- a/java/src/game/worldgen/layer/GenLayerEdge.java +++ b/java/src/common/worldgen/layer/GenLayerEdge.java @@ -1,4 +1,4 @@ -package game.worldgen.layer; +package common.worldgen.layer; public class GenLayerEdge extends GenLayer { diff --git a/java/src/game/worldgen/layer/GenLayerFuzzyZoom.java b/java/src/common/worldgen/layer/GenLayerFuzzyZoom.java similarity index 94% rename from java/src/game/worldgen/layer/GenLayerFuzzyZoom.java rename to java/src/common/worldgen/layer/GenLayerFuzzyZoom.java index b4c4fc7..d38e3de 100755 --- a/java/src/game/worldgen/layer/GenLayerFuzzyZoom.java +++ b/java/src/common/worldgen/layer/GenLayerFuzzyZoom.java @@ -1,4 +1,4 @@ -package game.worldgen.layer; +package common.worldgen.layer; public class GenLayerFuzzyZoom extends GenLayerZoom { diff --git a/java/src/game/worldgen/layer/GenLayerHills.java b/java/src/common/worldgen/layer/GenLayerHills.java similarity index 98% rename from java/src/game/worldgen/layer/GenLayerHills.java rename to java/src/common/worldgen/layer/GenLayerHills.java index 284261a..e8c4318 100755 --- a/java/src/game/worldgen/layer/GenLayerHills.java +++ b/java/src/common/worldgen/layer/GenLayerHills.java @@ -1,7 +1,7 @@ -package game.worldgen.layer; +package common.worldgen.layer; -import game.biome.Biome; -import game.log.Log; +import common.biome.Biome; +import common.log.Log; public class GenLayerHills extends GenLayer { diff --git a/java/src/game/worldgen/layer/GenLayerRemoveEmpty.java b/java/src/common/worldgen/layer/GenLayerRemoveEmpty.java similarity index 98% rename from java/src/game/worldgen/layer/GenLayerRemoveEmpty.java rename to java/src/common/worldgen/layer/GenLayerRemoveEmpty.java index e35145c..ef77ef2 100755 --- a/java/src/game/worldgen/layer/GenLayerRemoveEmpty.java +++ b/java/src/common/worldgen/layer/GenLayerRemoveEmpty.java @@ -1,4 +1,4 @@ -package game.worldgen.layer; +package common.worldgen.layer; public class GenLayerRemoveEmpty extends GenLayer { diff --git a/java/src/game/worldgen/layer/GenLayerRiver.java b/java/src/common/worldgen/layer/GenLayerRiver.java similarity index 96% rename from java/src/game/worldgen/layer/GenLayerRiver.java rename to java/src/common/worldgen/layer/GenLayerRiver.java index cced208..1bf51e0 100755 --- a/java/src/game/worldgen/layer/GenLayerRiver.java +++ b/java/src/common/worldgen/layer/GenLayerRiver.java @@ -1,6 +1,6 @@ -package game.worldgen.layer; +package common.worldgen.layer; -import game.biome.Biome; +import common.biome.Biome; public class GenLayerRiver extends GenLayer { diff --git a/java/src/game/worldgen/layer/GenLayerRiverInit.java b/java/src/common/worldgen/layer/GenLayerRiverInit.java similarity index 96% rename from java/src/game/worldgen/layer/GenLayerRiverInit.java rename to java/src/common/worldgen/layer/GenLayerRiverInit.java index 80a65a2..04bd0e8 100755 --- a/java/src/game/worldgen/layer/GenLayerRiverInit.java +++ b/java/src/common/worldgen/layer/GenLayerRiverInit.java @@ -1,4 +1,4 @@ -package game.worldgen.layer; +package common.worldgen.layer; public class GenLayerRiverInit extends GenLayer { diff --git a/java/src/game/worldgen/layer/GenLayerRiverMix.java b/java/src/common/worldgen/layer/GenLayerRiverMix.java similarity index 97% rename from java/src/game/worldgen/layer/GenLayerRiverMix.java rename to java/src/common/worldgen/layer/GenLayerRiverMix.java index a98d6d8..0796530 100755 --- a/java/src/game/worldgen/layer/GenLayerRiverMix.java +++ b/java/src/common/worldgen/layer/GenLayerRiverMix.java @@ -1,6 +1,6 @@ -package game.worldgen.layer; +package common.worldgen.layer; -import game.biome.Biome; +import common.biome.Biome; public class GenLayerRiverMix extends GenLayer { diff --git a/java/src/game/worldgen/layer/GenLayerShore.java b/java/src/common/worldgen/layer/GenLayerShore.java similarity index 98% rename from java/src/game/worldgen/layer/GenLayerShore.java rename to java/src/common/worldgen/layer/GenLayerShore.java index 4e94d33..c3936aa 100755 --- a/java/src/game/worldgen/layer/GenLayerShore.java +++ b/java/src/common/worldgen/layer/GenLayerShore.java @@ -1,7 +1,7 @@ -package game.worldgen.layer; +package common.worldgen.layer; -import game.biome.Biome; -import game.biome.BiomeJungle; +import common.biome.Biome; +import common.biome.BiomeJungle; public class GenLayerShore extends GenLayer { diff --git a/java/src/game/worldgen/layer/GenLayerSmooth.java b/java/src/common/worldgen/layer/GenLayerSmooth.java similarity index 98% rename from java/src/game/worldgen/layer/GenLayerSmooth.java rename to java/src/common/worldgen/layer/GenLayerSmooth.java index 1893663..d67a516 100755 --- a/java/src/game/worldgen/layer/GenLayerSmooth.java +++ b/java/src/common/worldgen/layer/GenLayerSmooth.java @@ -1,4 +1,4 @@ -package game.worldgen.layer; +package common.worldgen.layer; public class GenLayerSmooth extends GenLayer { diff --git a/java/src/game/worldgen/layer/GenLayerVoronoiZoom.java b/java/src/common/worldgen/layer/GenLayerVoronoiZoom.java similarity index 99% rename from java/src/game/worldgen/layer/GenLayerVoronoiZoom.java rename to java/src/common/worldgen/layer/GenLayerVoronoiZoom.java index e8c76ac..c53921c 100755 --- a/java/src/game/worldgen/layer/GenLayerVoronoiZoom.java +++ b/java/src/common/worldgen/layer/GenLayerVoronoiZoom.java @@ -1,4 +1,4 @@ -package game.worldgen.layer; +package common.worldgen.layer; public class GenLayerVoronoiZoom extends GenLayer { diff --git a/java/src/game/worldgen/layer/GenLayerZoom.java b/java/src/common/worldgen/layer/GenLayerZoom.java similarity index 98% rename from java/src/game/worldgen/layer/GenLayerZoom.java rename to java/src/common/worldgen/layer/GenLayerZoom.java index 8dd4565..72ef702 100755 --- a/java/src/game/worldgen/layer/GenLayerZoom.java +++ b/java/src/common/worldgen/layer/GenLayerZoom.java @@ -1,4 +1,4 @@ -package game.worldgen.layer; +package common.worldgen.layer; public class GenLayerZoom extends GenLayer { diff --git a/java/src/game/worldgen/layer/IntCache.java b/java/src/common/worldgen/layer/IntCache.java similarity index 97% rename from java/src/game/worldgen/layer/IntCache.java rename to java/src/common/worldgen/layer/IntCache.java index 38a4766..e275dc7 100755 --- a/java/src/game/worldgen/layer/IntCache.java +++ b/java/src/common/worldgen/layer/IntCache.java @@ -1,8 +1,8 @@ -package game.worldgen.layer; +package common.worldgen.layer; import java.util.List; -import game.collect.Lists; +import common.collect.Lists; public class IntCache { diff --git a/java/src/game/worldgen/structure/MapGenBridge.java b/java/src/common/worldgen/structure/MapGenBridge.java similarity index 94% rename from java/src/game/worldgen/structure/MapGenBridge.java rename to java/src/common/worldgen/structure/MapGenBridge.java index 2fa6862..3a428b4 100755 --- a/java/src/game/worldgen/structure/MapGenBridge.java +++ b/java/src/common/worldgen/structure/MapGenBridge.java @@ -1,9 +1,9 @@ -package game.worldgen.structure; +package common.worldgen.structure; import java.util.List; -import game.rng.Random; -import game.world.WorldServer; +import common.rng.Random; +import common.world.WorldServer; public class MapGenBridge extends MapGenStructure { diff --git a/java/src/game/worldgen/structure/MapGenMineshaft.java b/java/src/common/worldgen/structure/MapGenMineshaft.java similarity index 96% rename from java/src/game/worldgen/structure/MapGenMineshaft.java rename to java/src/common/worldgen/structure/MapGenMineshaft.java index 6a5ca50..e464c18 100755 --- a/java/src/game/worldgen/structure/MapGenMineshaft.java +++ b/java/src/common/worldgen/structure/MapGenMineshaft.java @@ -1,4 +1,4 @@ -package game.worldgen.structure; +package common.worldgen.structure; public class MapGenMineshaft extends MapGenStructure { diff --git a/java/src/game/worldgen/structure/MapGenScatteredFeature.java b/java/src/common/worldgen/structure/MapGenScatteredFeature.java similarity index 96% rename from java/src/game/worldgen/structure/MapGenScatteredFeature.java rename to java/src/common/worldgen/structure/MapGenScatteredFeature.java index 0228027..16c54e2 100755 --- a/java/src/game/worldgen/structure/MapGenScatteredFeature.java +++ b/java/src/common/worldgen/structure/MapGenScatteredFeature.java @@ -1,12 +1,12 @@ -package game.worldgen.structure; +package common.worldgen.structure; import java.util.Arrays; import java.util.List; -import game.biome.Biome; -import game.rng.Random; -import game.world.BlockPos; -import game.world.WorldServer; +import common.biome.Biome; +import common.rng.Random; +import common.world.BlockPos; +import common.world.WorldServer; public class MapGenScatteredFeature extends MapGenStructure { diff --git a/java/src/game/worldgen/structure/MapGenStronghold.java b/java/src/common/worldgen/structure/MapGenStronghold.java similarity index 98% rename from java/src/game/worldgen/structure/MapGenStronghold.java rename to java/src/common/worldgen/structure/MapGenStronghold.java index 760a240..10d7f64 100755 --- a/java/src/game/worldgen/structure/MapGenStronghold.java +++ b/java/src/common/worldgen/structure/MapGenStronghold.java @@ -1,9 +1,9 @@ -package game.worldgen.structure; +package common.worldgen.structure; import java.util.List; -import game.rng.Random; -import game.world.WorldServer; +import common.rng.Random; +import common.world.WorldServer; public class MapGenStronghold extends MapGenStructure { diff --git a/java/src/game/worldgen/structure/MapGenStructure.java b/java/src/common/worldgen/structure/MapGenStructure.java similarity index 94% rename from java/src/game/worldgen/structure/MapGenStructure.java rename to java/src/common/worldgen/structure/MapGenStructure.java index 360f058..5cd21bf 100755 --- a/java/src/game/worldgen/structure/MapGenStructure.java +++ b/java/src/common/worldgen/structure/MapGenStructure.java @@ -1,20 +1,20 @@ -package game.worldgen.structure; +package common.worldgen.structure; import java.util.Iterator; import java.util.Map; -import game.collect.Maps; -import game.nbt.NBTBase; -import game.nbt.NBTTagCompound; -import game.rng.Random; -import game.world.BlockPos; -import game.world.ChunkPos; -import game.world.LongHashMap; -import game.world.World; -import game.world.WorldServer; -import game.world.WorldServer.WorldSavedData; -import game.worldgen.ChunkPrimer; -import game.worldgen.caves.MapGenBase; +import common.collect.Maps; +import common.nbt.NBTBase; +import common.nbt.NBTTagCompound; +import common.rng.Random; +import common.world.BlockPos; +import common.world.ChunkPos; +import common.world.LongHashMap; +import common.world.World; +import common.world.WorldServer; +import common.world.WorldServer.WorldSavedData; +import common.worldgen.ChunkPrimer; +import common.worldgen.caves.MapGenBase; public abstract class MapGenStructure extends MapGenBase { diff --git a/java/src/game/worldgen/structure/MapGenStructureIO.java b/java/src/common/worldgen/structure/MapGenStructureIO.java similarity index 96% rename from java/src/game/worldgen/structure/MapGenStructureIO.java rename to java/src/common/worldgen/structure/MapGenStructureIO.java index 94c185c..2556af7 100755 --- a/java/src/game/worldgen/structure/MapGenStructureIO.java +++ b/java/src/common/worldgen/structure/MapGenStructureIO.java @@ -1,11 +1,11 @@ -package game.worldgen.structure; +package common.worldgen.structure; import java.util.Map; -import game.collect.Maps; -import game.log.Log; -import game.nbt.NBTTagCompound; -import game.world.WorldServer; +import common.collect.Maps; +import common.log.Log; +import common.nbt.NBTTagCompound; +import common.world.WorldServer; public class MapGenStructureIO { diff --git a/java/src/game/worldgen/structure/MapGenVillage.java b/java/src/common/worldgen/structure/MapGenVillage.java similarity index 96% rename from java/src/game/worldgen/structure/MapGenVillage.java rename to java/src/common/worldgen/structure/MapGenVillage.java index 9a81a77..b907379 100755 --- a/java/src/game/worldgen/structure/MapGenVillage.java +++ b/java/src/common/worldgen/structure/MapGenVillage.java @@ -1,13 +1,13 @@ -package game.worldgen.structure; +package common.worldgen.structure; import java.util.List; import java.util.Set; -import game.biome.Biome; -import game.collect.Sets; -import game.nbt.NBTTagCompound; -import game.rng.Random; -import game.world.WorldServer; +import common.biome.Biome; +import common.collect.Sets; +import common.nbt.NBTTagCompound; +import common.rng.Random; +import common.world.WorldServer; public class MapGenVillage extends MapGenStructure { diff --git a/java/src/game/worldgen/structure/StructureBoundingBox.java b/java/src/common/worldgen/structure/StructureBoundingBox.java similarity index 98% rename from java/src/game/worldgen/structure/StructureBoundingBox.java rename to java/src/common/worldgen/structure/StructureBoundingBox.java index 43bf49f..418f011 100755 --- a/java/src/game/worldgen/structure/StructureBoundingBox.java +++ b/java/src/common/worldgen/structure/StructureBoundingBox.java @@ -1,9 +1,9 @@ -package game.worldgen.structure; +package common.worldgen.structure; -import game.nbt.NBTTagIntArray; -import game.world.BlockPos; -import game.world.Facing; -import game.world.Vec3i; +import common.nbt.NBTTagIntArray; +import common.world.BlockPos; +import common.world.Facing; +import common.world.Vec3i; public class StructureBoundingBox { diff --git a/java/src/game/worldgen/structure/StructureBridge.java b/java/src/common/worldgen/structure/StructureBridge.java similarity index 99% rename from java/src/game/worldgen/structure/StructureBridge.java rename to java/src/common/worldgen/structure/StructureBridge.java index a04e30a..ab35d0e 100755 --- a/java/src/game/worldgen/structure/StructureBridge.java +++ b/java/src/common/worldgen/structure/StructureBridge.java @@ -1,17 +1,17 @@ -package game.worldgen.structure; +package common.worldgen.structure; import java.util.List; -import game.collect.Lists; -import game.init.Blocks; -import game.nbt.NBTTagCompound; -import game.rng.Random; -import game.tileentity.TileEntity; -import game.tileentity.TileEntityMobSpawner; -import game.world.BlockPos; -import game.world.Facing; -import game.world.WorldServer; -import game.worldgen.LootConstants; +import common.collect.Lists; +import common.init.Blocks; +import common.nbt.NBTTagCompound; +import common.rng.Random; +import common.tileentity.TileEntity; +import common.tileentity.TileEntityMobSpawner; +import common.world.BlockPos; +import common.world.Facing; +import common.world.WorldServer; +import common.worldgen.LootConstants; public class StructureBridge diff --git a/java/src/game/worldgen/structure/StructureComponent.java b/java/src/common/worldgen/structure/StructureComponent.java similarity index 97% rename from java/src/game/worldgen/structure/StructureComponent.java rename to java/src/common/worldgen/structure/StructureComponent.java index 4a3fb47..b01bff9 100755 --- a/java/src/game/worldgen/structure/StructureComponent.java +++ b/java/src/common/worldgen/structure/StructureComponent.java @@ -1,24 +1,24 @@ -package game.worldgen.structure; +package common.worldgen.structure; import java.util.List; -import game.block.Block; -import game.block.BlockDirectional; -import game.block.BlockDoor; -import game.init.Blocks; -import game.item.ItemDoor; -import game.item.RngLoot; -import game.material.Material; -import game.nbt.NBTTagCompound; -import game.rng.Random; -import game.rng.WeightedList; -import game.tileentity.TileEntity; -import game.tileentity.TileEntityChest; -import game.tileentity.TileEntityDispenser; -import game.world.BlockPos; -import game.world.Facing; -import game.world.State; -import game.world.WorldServer; +import common.block.Block; +import common.block.BlockDirectional; +import common.block.BlockDoor; +import common.init.Blocks; +import common.item.ItemDoor; +import common.item.RngLoot; +import common.material.Material; +import common.nbt.NBTTagCompound; +import common.rng.Random; +import common.rng.WeightedList; +import common.tileentity.TileEntity; +import common.tileentity.TileEntityChest; +import common.tileentity.TileEntityDispenser; +import common.world.BlockPos; +import common.world.Facing; +import common.world.State; +import common.world.WorldServer; public abstract class StructureComponent { diff --git a/java/src/game/worldgen/structure/StructureMineshaft.java b/java/src/common/worldgen/structure/StructureMineshaft.java similarity index 98% rename from java/src/game/worldgen/structure/StructureMineshaft.java rename to java/src/common/worldgen/structure/StructureMineshaft.java index c73f00f..cadc388 100755 --- a/java/src/game/worldgen/structure/StructureMineshaft.java +++ b/java/src/common/worldgen/structure/StructureMineshaft.java @@ -1,24 +1,24 @@ -package game.worldgen.structure; +package common.worldgen.structure; import java.util.LinkedList; import java.util.List; -import game.entity.item.EntityChestCart; -import game.init.Blocks; -import game.init.Items; -import game.item.RngLoot; -import game.material.Material; -import game.nbt.NBTTagCompound; -import game.nbt.NBTTagList; -import game.rng.Random; -import game.rng.WeightedList; -import game.tileentity.TileEntity; -import game.tileentity.TileEntityMobSpawner; -import game.world.BlockPos; -import game.world.Facing; -import game.world.State; -import game.world.WorldServer; -import game.worldgen.LootConstants; +import common.entity.item.EntityChestCart; +import common.init.Blocks; +import common.init.Items; +import common.item.RngLoot; +import common.material.Material; +import common.nbt.NBTTagCompound; +import common.nbt.NBTTagList; +import common.rng.Random; +import common.rng.WeightedList; +import common.tileentity.TileEntity; +import common.tileentity.TileEntityMobSpawner; +import common.world.BlockPos; +import common.world.Facing; +import common.world.State; +import common.world.WorldServer; +import common.worldgen.LootConstants; public class StructureMineshaft diff --git a/java/src/game/worldgen/structure/StructureMineshaftStart.java b/java/src/common/worldgen/structure/StructureMineshaftStart.java similarity index 87% rename from java/src/game/worldgen/structure/StructureMineshaftStart.java rename to java/src/common/worldgen/structure/StructureMineshaftStart.java index bd1763b..72dc9b0 100755 --- a/java/src/game/worldgen/structure/StructureMineshaftStart.java +++ b/java/src/common/worldgen/structure/StructureMineshaftStart.java @@ -1,7 +1,7 @@ -package game.worldgen.structure; +package common.worldgen.structure; -import game.rng.Random; -import game.world.WorldServer; +import common.rng.Random; +import common.world.WorldServer; public class StructureMineshaftStart extends StructureStart { diff --git a/java/src/game/worldgen/structure/StructureScattered.java b/java/src/common/worldgen/structure/StructureScattered.java similarity index 98% rename from java/src/game/worldgen/structure/StructureScattered.java rename to java/src/common/worldgen/structure/StructureScattered.java index fe095d1..b031a72 100755 --- a/java/src/game/worldgen/structure/StructureScattered.java +++ b/java/src/common/worldgen/structure/StructureScattered.java @@ -1,24 +1,24 @@ -package game.worldgen.structure; +package common.worldgen.structure; -import game.block.BlockFlower; -import game.block.BlockFlowerPot; -import game.block.BlockLever; -import game.block.BlockSandStone; -import game.block.BlockStoneBrick; -import game.block.BlockTripWire; -import game.block.BlockTripWireHook; -import game.color.DyeColor; -import game.entity.npc.EntityMage; -import game.init.Blocks; -import game.init.Config; -import game.init.Items; -import game.item.RngLoot; -import game.nbt.NBTTagCompound; -import game.rng.Random; -import game.world.BlockPos; -import game.world.Facing; -import game.world.WorldServer; -import game.worldgen.LootConstants; +import common.block.BlockFlower; +import common.block.BlockFlowerPot; +import common.block.BlockLever; +import common.block.BlockSandStone; +import common.block.BlockStoneBrick; +import common.block.BlockTripWire; +import common.block.BlockTripWireHook; +import common.color.DyeColor; +import common.entity.npc.EntityMage; +import common.init.Blocks; +import common.init.Config; +import common.init.Items; +import common.item.RngLoot; +import common.nbt.NBTTagCompound; +import common.rng.Random; +import common.world.BlockPos; +import common.world.Facing; +import common.world.WorldServer; +import common.worldgen.LootConstants; public class StructureScattered { diff --git a/java/src/game/worldgen/structure/StructureStart.java b/java/src/common/worldgen/structure/StructureStart.java similarity index 96% rename from java/src/game/worldgen/structure/StructureStart.java rename to java/src/common/worldgen/structure/StructureStart.java index 0f200c3..5cee450 100755 --- a/java/src/game/worldgen/structure/StructureStart.java +++ b/java/src/common/worldgen/structure/StructureStart.java @@ -1,13 +1,13 @@ -package game.worldgen.structure; +package common.worldgen.structure; import java.util.Iterator; import java.util.LinkedList; -import game.nbt.NBTTagCompound; -import game.nbt.NBTTagList; -import game.rng.Random; -import game.world.ChunkPos; -import game.world.WorldServer; +import common.nbt.NBTTagCompound; +import common.nbt.NBTTagList; +import common.rng.Random; +import common.world.ChunkPos; +import common.world.WorldServer; public abstract class StructureStart { diff --git a/java/src/game/worldgen/structure/StructureStronghold.java b/java/src/common/worldgen/structure/StructureStronghold.java similarity index 99% rename from java/src/game/worldgen/structure/StructureStronghold.java rename to java/src/common/worldgen/structure/StructureStronghold.java index 6d4f792..3d10553 100755 --- a/java/src/game/worldgen/structure/StructureStronghold.java +++ b/java/src/common/worldgen/structure/StructureStronghold.java @@ -1,23 +1,23 @@ -package game.worldgen.structure; +package common.worldgen.structure; import java.util.List; import java.util.Map; -import game.block.BlockSlab; -import game.block.BlockStoneBrick; -import game.collect.Lists; -import game.collect.Maps; -import game.init.Blocks; -import game.init.Items; -import game.item.RngLoot; -import game.nbt.NBTTagCompound; -import game.rng.Random; -import game.tileentity.TileEntity; -import game.tileentity.TileEntityMobSpawner; -import game.world.BlockPos; -import game.world.Facing; -import game.world.WorldServer; -import game.worldgen.LootConstants; +import common.block.BlockSlab; +import common.block.BlockStoneBrick; +import common.collect.Lists; +import common.collect.Maps; +import common.init.Blocks; +import common.init.Items; +import common.item.RngLoot; +import common.nbt.NBTTagCompound; +import common.rng.Random; +import common.tileentity.TileEntity; +import common.tileentity.TileEntityMobSpawner; +import common.world.BlockPos; +import common.world.Facing; +import common.world.WorldServer; +import common.worldgen.LootConstants; public class StructureStronghold diff --git a/java/src/game/worldgen/structure/StructureVillage.java b/java/src/common/worldgen/structure/StructureVillage.java similarity index 99% rename from java/src/game/worldgen/structure/StructureVillage.java rename to java/src/common/worldgen/structure/StructureVillage.java index 79b793d..aa850da 100755 --- a/java/src/game/worldgen/structure/StructureVillage.java +++ b/java/src/common/worldgen/structure/StructureVillage.java @@ -1,30 +1,30 @@ -package game.worldgen.structure; +package common.worldgen.structure; import java.util.Iterator; import java.util.List; -import game.biome.Biome; -import game.block.Block; -import game.block.BlockLog; -import game.block.BlockSandStone; -import game.block.BlockSlab; -import game.block.BlockStairs; -import game.block.BlockTorch; -import game.collect.Lists; -import game.color.DyeColor; -import game.entity.npc.EntityHuman; -import game.init.BlockRegistry; -import game.init.Blocks; -import game.init.Config; -import game.material.Material; -import game.nbt.NBTTagCompound; -import game.rng.Random; -import game.world.BlockPos; -import game.world.Facing; -import game.world.State; -import game.world.WorldServer; -import game.worldgen.BiomeGenerator; -import game.worldgen.LootConstants; +import common.biome.Biome; +import common.block.Block; +import common.block.BlockLog; +import common.block.BlockSandStone; +import common.block.BlockSlab; +import common.block.BlockStairs; +import common.block.BlockTorch; +import common.collect.Lists; +import common.color.DyeColor; +import common.entity.npc.EntityHuman; +import common.init.BlockRegistry; +import common.init.Blocks; +import common.init.Config; +import common.material.Material; +import common.nbt.NBTTagCompound; +import common.rng.Random; +import common.world.BlockPos; +import common.world.Facing; +import common.world.State; +import common.world.WorldServer; +import common.worldgen.BiomeGenerator; +import common.worldgen.LootConstants; public class StructureVillage diff --git a/java/src/game/worldgen/tree/WorldGenBaseTree.java b/java/src/common/worldgen/tree/WorldGenBaseTree.java similarity index 96% rename from java/src/game/worldgen/tree/WorldGenBaseTree.java rename to java/src/common/worldgen/tree/WorldGenBaseTree.java index 464f038..c1e3017 100755 --- a/java/src/game/worldgen/tree/WorldGenBaseTree.java +++ b/java/src/common/worldgen/tree/WorldGenBaseTree.java @@ -1,17 +1,17 @@ -package game.worldgen.tree; +package common.worldgen.tree; -import game.block.Block; -import game.block.BlockCocoa; -import game.block.BlockLeaves; -import game.block.BlockVine; -import game.init.Blocks; -import game.material.Material; -import game.properties.PropertyBool; -import game.rng.Random; -import game.world.BlockPos; -import game.world.Facing; -import game.world.State; -import game.world.WorldServer; +import common.block.Block; +import common.block.BlockCocoa; +import common.block.BlockLeaves; +import common.block.BlockVine; +import common.init.Blocks; +import common.material.Material; +import common.properties.PropertyBool; +import common.rng.Random; +import common.world.BlockPos; +import common.world.Facing; +import common.world.State; +import common.world.WorldServer; public class WorldGenBaseTree extends WorldGenTree { diff --git a/java/src/game/worldgen/tree/WorldGenBigTree.java b/java/src/common/worldgen/tree/WorldGenBigTree.java similarity index 97% rename from java/src/game/worldgen/tree/WorldGenBigTree.java rename to java/src/common/worldgen/tree/WorldGenBigTree.java index 9655450..8a5580c 100755 --- a/java/src/game/worldgen/tree/WorldGenBigTree.java +++ b/java/src/common/worldgen/tree/WorldGenBigTree.java @@ -1,18 +1,18 @@ -package game.worldgen.tree; +package common.worldgen.tree; import java.util.List; -import game.block.Block; -import game.block.BlockLeaves; -import game.block.BlockLog; -import game.collect.Lists; -import game.init.Blocks; -import game.material.Material; -import game.rng.Random; -import game.util.ExtMath; -import game.world.BlockPos; -import game.world.State; -import game.world.WorldServer; +import common.block.Block; +import common.block.BlockLeaves; +import common.block.BlockLog; +import common.collect.Lists; +import common.init.Blocks; +import common.material.Material; +import common.rng.Random; +import common.util.ExtMath; +import common.world.BlockPos; +import common.world.State; +import common.world.WorldServer; public class WorldGenBigTree extends WorldGenTree { diff --git a/java/src/game/worldgen/tree/WorldGenBirch.java b/java/src/common/worldgen/tree/WorldGenBirch.java similarity index 94% rename from java/src/game/worldgen/tree/WorldGenBirch.java rename to java/src/common/worldgen/tree/WorldGenBirch.java index bde4f4e..d0c4af8 100755 --- a/java/src/game/worldgen/tree/WorldGenBirch.java +++ b/java/src/common/worldgen/tree/WorldGenBirch.java @@ -1,13 +1,13 @@ -package game.worldgen.tree; +package common.worldgen.tree; -import game.block.Block; -import game.block.BlockLeaves; -import game.init.Blocks; -import game.material.Material; -import game.rng.Random; -import game.world.BlockPos; -import game.world.State; -import game.world.WorldServer; +import common.block.Block; +import common.block.BlockLeaves; +import common.init.Blocks; +import common.material.Material; +import common.rng.Random; +import common.world.BlockPos; +import common.world.State; +import common.world.WorldServer; public class WorldGenBirch extends WorldGenTree { diff --git a/java/src/game/worldgen/tree/WorldGenDarkOak.java b/java/src/common/worldgen/tree/WorldGenDarkOak.java similarity index 96% rename from java/src/game/worldgen/tree/WorldGenDarkOak.java rename to java/src/common/worldgen/tree/WorldGenDarkOak.java index 6c7379a..43cf4bc 100755 --- a/java/src/game/worldgen/tree/WorldGenDarkOak.java +++ b/java/src/common/worldgen/tree/WorldGenDarkOak.java @@ -1,14 +1,14 @@ -package game.worldgen.tree; +package common.worldgen.tree; -import game.block.Block; -import game.block.BlockLeaves; -import game.init.Blocks; -import game.material.Material; -import game.rng.Random; -import game.world.BlockPos; -import game.world.Facing; -import game.world.State; -import game.world.WorldServer; +import common.block.Block; +import common.block.BlockLeaves; +import common.init.Blocks; +import common.material.Material; +import common.rng.Random; +import common.world.BlockPos; +import common.world.Facing; +import common.world.State; +import common.world.WorldServer; public class WorldGenDarkOak extends WorldGenTree { diff --git a/java/src/game/worldgen/tree/WorldGenHugeTree.java b/java/src/common/worldgen/tree/WorldGenHugeTree.java similarity index 94% rename from java/src/game/worldgen/tree/WorldGenHugeTree.java rename to java/src/common/worldgen/tree/WorldGenHugeTree.java index 145f879..bd57382 100755 --- a/java/src/game/worldgen/tree/WorldGenHugeTree.java +++ b/java/src/common/worldgen/tree/WorldGenHugeTree.java @@ -1,13 +1,13 @@ -package game.worldgen.tree; +package common.worldgen.tree; -import game.block.Block; -import game.block.BlockLeaves; -import game.init.Blocks; -import game.material.Material; -import game.rng.Random; -import game.world.BlockPos; -import game.world.State; -import game.world.WorldServer; +import common.block.Block; +import common.block.BlockLeaves; +import common.init.Blocks; +import common.material.Material; +import common.rng.Random; +import common.world.BlockPos; +import common.world.State; +import common.world.WorldServer; public abstract class WorldGenHugeTree extends WorldGenTree { diff --git a/java/src/game/worldgen/tree/WorldGenJungle.java b/java/src/common/worldgen/tree/WorldGenJungle.java similarity index 94% rename from java/src/game/worldgen/tree/WorldGenJungle.java rename to java/src/common/worldgen/tree/WorldGenJungle.java index 92e7057..d9fef45 100755 --- a/java/src/game/worldgen/tree/WorldGenJungle.java +++ b/java/src/common/worldgen/tree/WorldGenJungle.java @@ -1,13 +1,13 @@ -package game.worldgen.tree; +package common.worldgen.tree; -import game.block.BlockVine; -import game.init.Blocks; -import game.properties.PropertyBool; -import game.rng.Random; -import game.util.ExtMath; -import game.world.BlockPos; -import game.world.State; -import game.world.WorldServer; +import common.block.BlockVine; +import common.init.Blocks; +import common.properties.PropertyBool; +import common.rng.Random; +import common.util.ExtMath; +import common.world.BlockPos; +import common.world.State; +import common.world.WorldServer; public class WorldGenJungle extends WorldGenHugeTree { diff --git a/java/src/game/worldgen/tree/WorldGenPine.java b/java/src/common/worldgen/tree/WorldGenPine.java similarity index 94% rename from java/src/game/worldgen/tree/WorldGenPine.java rename to java/src/common/worldgen/tree/WorldGenPine.java index 8351b5b..c7000ed 100755 --- a/java/src/game/worldgen/tree/WorldGenPine.java +++ b/java/src/common/worldgen/tree/WorldGenPine.java @@ -1,14 +1,14 @@ -package game.worldgen.tree; +package common.worldgen.tree; -import game.block.Block; -import game.block.BlockDirt; -import game.init.Blocks; -import game.material.Material; -import game.rng.Random; -import game.util.ExtMath; -import game.world.BlockPos; -import game.world.State; -import game.world.WorldServer; +import common.block.Block; +import common.block.BlockDirt; +import common.init.Blocks; +import common.material.Material; +import common.rng.Random; +import common.util.ExtMath; +import common.world.BlockPos; +import common.world.State; +import common.world.WorldServer; public class WorldGenPine extends WorldGenHugeTree { diff --git a/java/src/game/worldgen/tree/WorldGenSavanna.java b/java/src/common/worldgen/tree/WorldGenSavanna.java similarity index 96% rename from java/src/game/worldgen/tree/WorldGenSavanna.java rename to java/src/common/worldgen/tree/WorldGenSavanna.java index 7ad81aa..f4b98d2 100755 --- a/java/src/game/worldgen/tree/WorldGenSavanna.java +++ b/java/src/common/worldgen/tree/WorldGenSavanna.java @@ -1,14 +1,14 @@ -package game.worldgen.tree; +package common.worldgen.tree; -import game.block.Block; -import game.block.BlockLeaves; -import game.init.Blocks; -import game.material.Material; -import game.rng.Random; -import game.world.BlockPos; -import game.world.Facing; -import game.world.State; -import game.world.WorldServer; +import common.block.Block; +import common.block.BlockLeaves; +import common.init.Blocks; +import common.material.Material; +import common.rng.Random; +import common.world.BlockPos; +import common.world.Facing; +import common.world.State; +import common.world.WorldServer; public class WorldGenSavanna extends WorldGenTree { diff --git a/java/src/game/worldgen/tree/WorldGenSwamp.java b/java/src/common/worldgen/tree/WorldGenSwamp.java similarity index 95% rename from java/src/game/worldgen/tree/WorldGenSwamp.java rename to java/src/common/worldgen/tree/WorldGenSwamp.java index 9f440a2..264c763 100755 --- a/java/src/game/worldgen/tree/WorldGenSwamp.java +++ b/java/src/common/worldgen/tree/WorldGenSwamp.java @@ -1,15 +1,15 @@ -package game.worldgen.tree; +package common.worldgen.tree; -import game.block.Block; -import game.block.BlockLeaves; -import game.block.BlockVine; -import game.init.Blocks; -import game.material.Material; -import game.properties.PropertyBool; -import game.rng.Random; -import game.world.BlockPos; -import game.world.State; -import game.world.WorldServer; +import common.block.Block; +import common.block.BlockLeaves; +import common.block.BlockVine; +import common.init.Blocks; +import common.material.Material; +import common.properties.PropertyBool; +import common.rng.Random; +import common.world.BlockPos; +import common.world.State; +import common.world.WorldServer; public class WorldGenSwamp extends WorldGenTree { diff --git a/java/src/game/worldgen/tree/WorldGenTaiga1.java b/java/src/common/worldgen/tree/WorldGenTaiga1.java similarity index 94% rename from java/src/game/worldgen/tree/WorldGenTaiga1.java rename to java/src/common/worldgen/tree/WorldGenTaiga1.java index 8427191..f5f6b85 100755 --- a/java/src/game/worldgen/tree/WorldGenTaiga1.java +++ b/java/src/common/worldgen/tree/WorldGenTaiga1.java @@ -1,13 +1,13 @@ -package game.worldgen.tree; +package common.worldgen.tree; -import game.block.Block; -import game.block.BlockLeaves; -import game.init.Blocks; -import game.material.Material; -import game.rng.Random; -import game.world.BlockPos; -import game.world.State; -import game.world.WorldServer; +import common.block.Block; +import common.block.BlockLeaves; +import common.init.Blocks; +import common.material.Material; +import common.rng.Random; +import common.world.BlockPos; +import common.world.State; +import common.world.WorldServer; public class WorldGenTaiga1 extends WorldGenTree { diff --git a/java/src/game/worldgen/tree/WorldGenTaiga2.java b/java/src/common/worldgen/tree/WorldGenTaiga2.java similarity index 94% rename from java/src/game/worldgen/tree/WorldGenTaiga2.java rename to java/src/common/worldgen/tree/WorldGenTaiga2.java index 0adba2a..f085cdb 100755 --- a/java/src/game/worldgen/tree/WorldGenTaiga2.java +++ b/java/src/common/worldgen/tree/WorldGenTaiga2.java @@ -1,13 +1,13 @@ -package game.worldgen.tree; +package common.worldgen.tree; -import game.block.Block; -import game.block.BlockLeaves; -import game.init.Blocks; -import game.material.Material; -import game.rng.Random; -import game.world.BlockPos; -import game.world.State; -import game.world.WorldServer; +import common.block.Block; +import common.block.BlockLeaves; +import common.init.Blocks; +import common.material.Material; +import common.rng.Random; +import common.world.BlockPos; +import common.world.State; +import common.world.WorldServer; public class WorldGenTaiga2 extends WorldGenTree { diff --git a/java/src/game/worldgen/tree/WorldGenTree.java b/java/src/common/worldgen/tree/WorldGenTree.java similarity index 73% rename from java/src/game/worldgen/tree/WorldGenTree.java rename to java/src/common/worldgen/tree/WorldGenTree.java index 260c603..1ea362b 100755 --- a/java/src/game/worldgen/tree/WorldGenTree.java +++ b/java/src/common/worldgen/tree/WorldGenTree.java @@ -1,14 +1,14 @@ -package game.worldgen.tree; +package common.worldgen.tree; -import game.block.Block; -import game.block.BlockLog; -import game.block.BlockSapling; -import game.init.Blocks; -import game.material.Material; -import game.rng.Random; -import game.world.BlockPos; -import game.world.WorldServer; -import game.worldgen.FeatureGenerator; +import common.block.Block; +import common.block.BlockLog; +import common.block.BlockSapling; +import common.init.Blocks; +import common.material.Material; +import common.rng.Random; +import common.world.BlockPos; +import common.world.WorldServer; +import common.worldgen.FeatureGenerator; public abstract class WorldGenTree extends FeatureGenerator { diff --git a/server/src/server/Server.java b/server/src/server/Server.java index 1419a7d..7781080 100755 --- a/server/src/server/Server.java +++ b/server/src/server/Server.java @@ -18,63 +18,63 @@ import java.util.concurrent.ExecutionException; import java.util.concurrent.Executors; import java.util.concurrent.FutureTask; -import game.IServer; -import game.collect.Lists; -import game.collect.Maps; -import game.color.TextColor; -import game.dimension.Dimension; -import game.dimension.Space; -import game.entity.Entity; -import game.entity.npc.EntityHuman; -import game.entity.npc.EntityNPC; -import game.future.Futures; -import game.future.ListenableFuture; -import game.future.ListenableFutureTask; -import game.future.ThreadFactoryBuilder; -import game.init.Config; -import game.init.EntityRegistry; -import game.init.Registry; -import game.init.UniverseRegistry; -import game.log.Log; -import game.nbt.NBTLoader; -import game.nbt.NBTTagCompound; -import game.nbt.NBTTagList; -import game.network.IPlayer; -import game.network.IThreadListener; -import game.network.NetConnection; -import game.network.NetHandler.ThreadQuickExitException; -import game.network.Packet; -import game.network.PacketDecoder; -import game.network.PacketEncoder; -import game.network.PacketPrepender; -import game.network.PacketSplitter; -import game.packet.RPacketEnableCompression; -import game.packet.RPacketLoginSuccess; -import game.packet.S1DPacketEntityEffect; -import game.packet.S2BPacketChangeGameState; -import game.packet.S38PacketPlayerListItem; -import game.packet.S39PacketPlayerAbilities; -import game.packet.SPacketDisconnect; -import game.packet.SPacketHeldItemChange; -import game.packet.SPacketJoinGame; -import game.packet.SPacketRespawn; -import game.packet.SPacketSetExperience; -import game.packet.SPacketSkin; -import game.packet.SPacketTimeUpdate; -import game.packet.SPacketWorld; -import game.potion.PotionEffect; -import game.util.ExtMath; -import game.util.LazyLoadBase; -import game.util.Tuple; -import game.util.Util; -import game.world.BlockPos; -import game.world.PortalType; -import game.world.Position; -import game.world.Region; -import game.world.Region.FolderInfo; -import game.world.World; -import game.world.WorldPos; -import game.world.WorldServer; +import common.IServer; +import common.collect.Lists; +import common.collect.Maps; +import common.color.TextColor; +import common.dimension.Dimension; +import common.dimension.Space; +import common.entity.Entity; +import common.entity.npc.EntityHuman; +import common.entity.npc.EntityNPC; +import common.future.Futures; +import common.future.ListenableFuture; +import common.future.ListenableFutureTask; +import common.future.ThreadFactoryBuilder; +import common.init.Config; +import common.init.EntityRegistry; +import common.init.Registry; +import common.init.UniverseRegistry; +import common.log.Log; +import common.nbt.NBTLoader; +import common.nbt.NBTTagCompound; +import common.nbt.NBTTagList; +import common.network.IPlayer; +import common.network.IThreadListener; +import common.network.NetConnection; +import common.network.Packet; +import common.network.PacketDecoder; +import common.network.PacketEncoder; +import common.network.PacketPrepender; +import common.network.PacketSplitter; +import common.network.NetHandler.ThreadQuickExitException; +import common.packet.RPacketEnableCompression; +import common.packet.RPacketLoginSuccess; +import common.packet.S1DPacketEntityEffect; +import common.packet.S2BPacketChangeGameState; +import common.packet.S38PacketPlayerListItem; +import common.packet.S39PacketPlayerAbilities; +import common.packet.SPacketDisconnect; +import common.packet.SPacketHeldItemChange; +import common.packet.SPacketJoinGame; +import common.packet.SPacketRespawn; +import common.packet.SPacketSetExperience; +import common.packet.SPacketSkin; +import common.packet.SPacketTimeUpdate; +import common.packet.SPacketWorld; +import common.potion.PotionEffect; +import common.util.ExtMath; +import common.util.LazyLoadBase; +import common.util.Tuple; +import common.util.Util; +import common.world.BlockPos; +import common.world.PortalType; +import common.world.Position; +import common.world.Region; +import common.world.World; +import common.world.WorldPos; +import common.world.WorldServer; +import common.world.Region.FolderInfo; import io.netty.bootstrap.ServerBootstrap; import io.netty.channel.Channel; import io.netty.channel.ChannelException; diff --git a/server/src/server/command/ArgumentParser.java b/server/src/server/command/ArgumentParser.java index e6a90d7..4d55712 100644 --- a/server/src/server/command/ArgumentParser.java +++ b/server/src/server/command/ArgumentParser.java @@ -3,7 +3,7 @@ package server.command; import java.util.Collection; import java.util.List; -import game.collect.Lists; +import common.collect.Lists; public abstract class ArgumentParser { public static String[][] splitString(String str) { diff --git a/server/src/server/command/ArgumentSplitter.java b/server/src/server/command/ArgumentSplitter.java index 6e746a9..58ba45a 100644 --- a/server/src/server/command/ArgumentSplitter.java +++ b/server/src/server/command/ArgumentSplitter.java @@ -4,9 +4,9 @@ import java.util.List; import java.util.Map; import java.util.Set; -import game.collect.Lists; -import game.collect.Maps; -import game.collect.Sets; +import common.collect.Lists; +import common.collect.Maps; +import common.collect.Sets; public class ArgumentSplitter { private final String command; diff --git a/server/src/server/command/CachedExecutable.java b/server/src/server/command/CachedExecutable.java index d3e97c4..55e64bb 100644 --- a/server/src/server/command/CachedExecutable.java +++ b/server/src/server/command/CachedExecutable.java @@ -4,8 +4,8 @@ import java.lang.reflect.Method; import java.util.List; import java.util.Map; -import game.collect.Lists; -import game.collect.Maps; +import common.collect.Lists; +import common.collect.Maps; public class CachedExecutable { private final Executable executable; diff --git a/server/src/server/command/ColorParser.java b/server/src/server/command/ColorParser.java index 191568b..0a3e49c 100644 --- a/server/src/server/command/ColorParser.java +++ b/server/src/server/command/ColorParser.java @@ -1,6 +1,6 @@ package server.command; -import game.color.DyeColor; +import common.color.DyeColor; public class ColorParser extends IntParser { public ColorParser(String name, Integer def, Object ... completions) { diff --git a/server/src/server/command/Command.java b/server/src/server/command/Command.java index 1a7074f..2598c0f 100644 --- a/server/src/server/command/Command.java +++ b/server/src/server/command/Command.java @@ -5,10 +5,10 @@ import java.util.Collection; import java.util.List; import java.util.Map; -import game.collect.Lists; -import game.collect.Maps; -import game.world.Vec3; -import game.world.World; +import common.collect.Lists; +import common.collect.Maps; +import common.world.Vec3; +import common.world.World; import server.command.DoubleParser.DefType; public abstract class Command implements Executable { diff --git a/server/src/server/command/CommandEnvironment.java b/server/src/server/command/CommandEnvironment.java index d416d93..34d7fbf 100644 --- a/server/src/server/command/CommandEnvironment.java +++ b/server/src/server/command/CommandEnvironment.java @@ -7,11 +7,11 @@ import java.util.Map; import java.util.Set; import java.util.function.Function; -import game.collect.Lists; -import game.collect.Maps; -import game.collect.Sets; -import game.color.TextColor; -import game.log.Log; +import common.collect.Lists; +import common.collect.Maps; +import common.collect.Sets; +import common.color.TextColor; +import common.log.Log; import server.Server; import server.command.commands.CommandAdmin; import server.command.commands.CommandHelp; diff --git a/server/src/server/command/DimensionParser.java b/server/src/server/command/DimensionParser.java index 268702f..523f4b9 100644 --- a/server/src/server/command/DimensionParser.java +++ b/server/src/server/command/DimensionParser.java @@ -2,9 +2,9 @@ package server.command; import java.util.Collection; -import game.dimension.Dimension; -import game.init.UniverseRegistry; -import game.world.Position; +import common.dimension.Dimension; +import common.init.UniverseRegistry; +import common.world.Position; public class DimensionParser extends CompletingParser { private final boolean useSender; diff --git a/server/src/server/command/DoubleParser.java b/server/src/server/command/DoubleParser.java index 9401ae5..cb071b4 100644 --- a/server/src/server/command/DoubleParser.java +++ b/server/src/server/command/DoubleParser.java @@ -2,9 +2,9 @@ package server.command; import java.util.Collection; -import game.collect.Lists; -import game.world.BlockPos; -import game.world.Position; +import common.collect.Lists; +import common.world.BlockPos; +import common.world.Position; public class DoubleParser extends DefaultingParser { public static enum DefType { diff --git a/server/src/server/command/EntityListParser.java b/server/src/server/command/EntityListParser.java index c221a28..c62aeaf 100644 --- a/server/src/server/command/EntityListParser.java +++ b/server/src/server/command/EntityListParser.java @@ -5,13 +5,13 @@ import java.util.Collections; import java.util.List; import java.util.Set; -import game.collect.Lists; -import game.collect.Sets; -import game.entity.Entity; -import game.entity.EntityType; -import game.entity.types.EntityLiving; -import game.init.EntityRegistry; -import game.world.WorldServer; +import common.collect.Lists; +import common.collect.Sets; +import common.entity.Entity; +import common.entity.EntityType; +import common.entity.types.EntityLiving; +import common.init.EntityRegistry; +import common.world.WorldServer; import server.network.Player; public class EntityListParser extends EntityParser { diff --git a/server/src/server/command/EntityParser.java b/server/src/server/command/EntityParser.java index 93a1934..3b5ff7a 100644 --- a/server/src/server/command/EntityParser.java +++ b/server/src/server/command/EntityParser.java @@ -3,10 +3,10 @@ package server.command; import java.util.Collection; import java.util.List; -import game.collect.Lists; -import game.entity.Entity; -import game.entity.types.EntityLiving; -import game.world.WorldServer; +import common.collect.Lists; +import common.entity.Entity; +import common.entity.types.EntityLiving; +import common.world.WorldServer; public class EntityParser extends PlayerEntityParser { protected final boolean livingOnly; diff --git a/server/src/server/command/EnumParser.java b/server/src/server/command/EnumParser.java index b39653b..a8b7a78 100644 --- a/server/src/server/command/EnumParser.java +++ b/server/src/server/command/EnumParser.java @@ -2,7 +2,7 @@ package server.command; import java.util.Map; -import game.collect.Maps; +import common.collect.Maps; public class EnumParser extends DefaultingParser { private final Class clazz; diff --git a/server/src/server/command/Executor.java b/server/src/server/command/Executor.java index cde825c..02207b4 100644 --- a/server/src/server/command/Executor.java +++ b/server/src/server/command/Executor.java @@ -1,8 +1,8 @@ package server.command; -import game.entity.Entity; -import game.world.BlockPos; -import game.world.Position; +import common.entity.Entity; +import common.world.BlockPos; +import common.world.Position; public interface Executor { void logConsole(String msg); diff --git a/server/src/server/command/FixedExecutor.java b/server/src/server/command/FixedExecutor.java index c609f8c..df9e3fb 100644 --- a/server/src/server/command/FixedExecutor.java +++ b/server/src/server/command/FixedExecutor.java @@ -1,8 +1,8 @@ package server.command; -import game.entity.Entity; -import game.world.BlockPos; -import game.world.Position; +import common.entity.Entity; +import common.world.BlockPos; +import common.world.Position; import server.Server; public class FixedExecutor implements Executor { diff --git a/server/src/server/command/PlayerEntityListParser.java b/server/src/server/command/PlayerEntityListParser.java index 45adab1..d97c1e6 100644 --- a/server/src/server/command/PlayerEntityListParser.java +++ b/server/src/server/command/PlayerEntityListParser.java @@ -4,10 +4,10 @@ import java.util.Collection; import java.util.List; import java.util.Set; -import game.collect.Lists; -import game.collect.Sets; -import game.entity.Entity; -import game.entity.npc.EntityNPC; +import common.collect.Lists; +import common.collect.Sets; +import common.entity.Entity; +import common.entity.npc.EntityNPC; import server.network.Player; public class PlayerEntityListParser extends PlayerEntityParser { diff --git a/server/src/server/command/PlayerEntityParser.java b/server/src/server/command/PlayerEntityParser.java index f202478..ff9eeb7 100644 --- a/server/src/server/command/PlayerEntityParser.java +++ b/server/src/server/command/PlayerEntityParser.java @@ -1,6 +1,6 @@ package server.command; -import game.entity.npc.EntityNPC; +import common.entity.npc.EntityNPC; import server.network.Player; public class PlayerEntityParser extends PlayerParser { diff --git a/server/src/server/command/PlayerListParser.java b/server/src/server/command/PlayerListParser.java index 3bc9d57..aed9691 100644 --- a/server/src/server/command/PlayerListParser.java +++ b/server/src/server/command/PlayerListParser.java @@ -4,8 +4,8 @@ import java.util.Collection; import java.util.List; import java.util.Set; -import game.collect.Lists; -import game.collect.Sets; +import common.collect.Lists; +import common.collect.Sets; import server.network.Player; public class PlayerListParser extends PlayerParser { diff --git a/server/src/server/command/StringParser.java b/server/src/server/command/StringParser.java index b676e21..b4ce0e8 100644 --- a/server/src/server/command/StringParser.java +++ b/server/src/server/command/StringParser.java @@ -2,7 +2,7 @@ package server.command; import java.util.Collection; -import game.util.CharValidator; +import common.util.CharValidator; public class StringParser extends DefaultingParser { private final boolean allowEmpty; diff --git a/server/src/server/command/TagParser.java b/server/src/server/command/TagParser.java index ffef156..848f6d8 100644 --- a/server/src/server/command/TagParser.java +++ b/server/src/server/command/TagParser.java @@ -1,8 +1,8 @@ package server.command; -import game.nbt.NBTException; -import game.nbt.NBTParser; -import game.nbt.NBTTagCompound; +import common.nbt.NBTException; +import common.nbt.NBTParser; +import common.nbt.NBTTagCompound; public class TagParser extends DefaultingParser { public TagParser(String name, NBTTagCompound def, Object ... completions) { diff --git a/server/src/server/command/WorldParser.java b/server/src/server/command/WorldParser.java index 8659362..87c9d43 100644 --- a/server/src/server/command/WorldParser.java +++ b/server/src/server/command/WorldParser.java @@ -3,9 +3,9 @@ package server.command; import java.util.Collection; import java.util.List; -import game.collect.Lists; -import game.dimension.Dimension; -import game.world.WorldServer; +import common.collect.Lists; +import common.dimension.Dimension; +import common.world.WorldServer; public class WorldParser extends DimensionParser { private final boolean loadedOnly; diff --git a/server/src/server/command/commands/CommandHelp.java b/server/src/server/command/commands/CommandHelp.java index 2ec6e9d..f5df1b8 100644 --- a/server/src/server/command/commands/CommandHelp.java +++ b/server/src/server/command/commands/CommandHelp.java @@ -4,8 +4,8 @@ import java.util.List; import java.util.Map.Entry; import java.util.function.Function; -import game.collect.Lists; -import game.util.Util; +import common.collect.Lists; +import common.util.Util; import server.command.ArgumentParser; import server.command.CachedExecutable; import server.command.Command; diff --git a/server/src/server/command/commands/CommandMessage.java b/server/src/server/command/commands/CommandMessage.java index ba0fd94..177ba6c 100644 --- a/server/src/server/command/commands/CommandMessage.java +++ b/server/src/server/command/commands/CommandMessage.java @@ -1,6 +1,6 @@ package server.command.commands; -import game.packet.SPacketMessage; +import common.packet.SPacketMessage; import server.command.Command; import server.command.CommandEnvironment; import server.command.Executor; diff --git a/server/src/server/command/commands/CommandMilk.java b/server/src/server/command/commands/CommandMilk.java index c858882..9ebb7f3 100644 --- a/server/src/server/command/commands/CommandMilk.java +++ b/server/src/server/command/commands/CommandMilk.java @@ -2,9 +2,9 @@ package server.command.commands; import java.util.List; -import game.collect.Lists; -import game.entity.types.EntityLiving; -import game.potion.Potion; +import common.collect.Lists; +import common.entity.types.EntityLiving; +import common.potion.Potion; import server.command.Command; import server.command.CommandEnvironment; import server.command.Executor; diff --git a/server/src/server/command/commands/CommandOfflinetp.java b/server/src/server/command/commands/CommandOfflinetp.java index 892bbb9..6966524 100644 --- a/server/src/server/command/commands/CommandOfflinetp.java +++ b/server/src/server/command/commands/CommandOfflinetp.java @@ -3,10 +3,10 @@ package server.command.commands; import java.util.Collection; import java.util.List; -import game.collect.Lists; -import game.entity.Entity; -import game.init.UniverseRegistry; -import game.world.Position; +import common.collect.Lists; +import common.entity.Entity; +import common.init.UniverseRegistry; +import common.world.Position; import server.command.Command; import server.command.CommandEnvironment; import server.command.Executor; diff --git a/server/src/server/command/commands/CommandPotion.java b/server/src/server/command/commands/CommandPotion.java index d3262ec..b814346 100644 --- a/server/src/server/command/commands/CommandPotion.java +++ b/server/src/server/command/commands/CommandPotion.java @@ -2,9 +2,9 @@ package server.command.commands; import java.util.List; -import game.entity.types.EntityLiving; -import game.potion.Potion; -import game.potion.PotionEffect; +import common.entity.types.EntityLiving; +import common.potion.Potion; +import common.potion.PotionEffect; import server.command.Command; import server.command.CommandEnvironment; import server.command.Executor; diff --git a/server/src/server/command/commands/CommandRemove.java b/server/src/server/command/commands/CommandRemove.java index e3265f4..2ecf0b6 100644 --- a/server/src/server/command/commands/CommandRemove.java +++ b/server/src/server/command/commands/CommandRemove.java @@ -2,7 +2,7 @@ package server.command.commands; import java.util.List; -import game.entity.Entity; +import common.entity.Entity; import server.command.Command; import server.command.CommandEnvironment; import server.command.Executor; diff --git a/server/src/server/command/commands/CommandSpawn.java b/server/src/server/command/commands/CommandSpawn.java index 74f3ffb..93e522e 100644 --- a/server/src/server/command/commands/CommandSpawn.java +++ b/server/src/server/command/commands/CommandSpawn.java @@ -3,15 +3,15 @@ package server.command.commands; import java.util.List; import java.util.Set; -import game.collect.Lists; -import game.collect.Sets; -import game.entity.Entity; -import game.entity.types.EntityLiving; -import game.init.EntityRegistry; -import game.nbt.NBTTagCompound; -import game.util.Util; -import game.world.Vec3; -import game.world.WorldServer; +import common.collect.Lists; +import common.collect.Sets; +import common.entity.Entity; +import common.entity.types.EntityLiving; +import common.init.EntityRegistry; +import common.nbt.NBTTagCompound; +import common.util.Util; +import common.world.Vec3; +import common.world.WorldServer; import server.command.Command; import server.command.CommandEnvironment; import server.command.Executor; diff --git a/server/src/server/command/commands/CommandTele.java b/server/src/server/command/commands/CommandTele.java index 427111f..19766bf 100644 --- a/server/src/server/command/commands/CommandTele.java +++ b/server/src/server/command/commands/CommandTele.java @@ -2,9 +2,9 @@ package server.command.commands; import java.util.List; -import game.dimension.Dimension; -import game.entity.Entity; -import game.world.Vec3; +import common.dimension.Dimension; +import common.entity.Entity; +import common.world.Vec3; import server.command.Command; import server.command.CommandEnvironment; import server.command.Executor; diff --git a/server/src/server/command/commands/CommandTime.java b/server/src/server/command/commands/CommandTime.java index 2cedd0a..1a4676e 100644 --- a/server/src/server/command/commands/CommandTime.java +++ b/server/src/server/command/commands/CommandTime.java @@ -1,9 +1,9 @@ package server.command.commands; -import game.dimension.Dimension; -import game.item.ItemSpaceNavigator; -import game.world.Position; -import game.world.WorldServer; +import common.dimension.Dimension; +import common.item.ItemSpaceNavigator; +import common.world.Position; +import common.world.WorldServer; import server.command.Command; import server.command.CommandEnvironment; import server.command.Executor; diff --git a/server/src/server/command/commands/CommandTp.java b/server/src/server/command/commands/CommandTp.java index 9011787..e300ae7 100644 --- a/server/src/server/command/commands/CommandTp.java +++ b/server/src/server/command/commands/CommandTp.java @@ -2,9 +2,9 @@ package server.command.commands; import java.util.List; -import game.entity.Entity; -import game.init.UniverseRegistry; -import game.world.Position; +import common.entity.Entity; +import common.init.UniverseRegistry; +import common.world.Position; import server.command.Command; import server.command.CommandEnvironment; import server.command.Executor; diff --git a/server/src/server/command/commands/CommandWarp.java b/server/src/server/command/commands/CommandWarp.java index 0e4802e..987e9de 100644 --- a/server/src/server/command/commands/CommandWarp.java +++ b/server/src/server/command/commands/CommandWarp.java @@ -3,9 +3,9 @@ package server.command.commands; import java.util.Collection; import java.util.List; -import game.entity.Entity; -import game.init.UniverseRegistry; -import game.world.Position; +import common.entity.Entity; +import common.init.UniverseRegistry; +import common.world.Position; import server.command.Command; import server.command.CommandEnvironment; import server.command.Executor; diff --git a/server/src/server/command/commands/CommandWeather.java b/server/src/server/command/commands/CommandWeather.java index 2e8b8bd..ea62180 100644 --- a/server/src/server/command/commands/CommandWeather.java +++ b/server/src/server/command/commands/CommandWeather.java @@ -1,7 +1,7 @@ package server.command.commands; -import game.world.Weather; -import game.world.WorldServer; +import common.world.Weather; +import common.world.WorldServer; import server.command.Command; import server.command.CommandEnvironment; import server.command.Executor; diff --git a/server/src/server/command/commands/CommandWorld.java b/server/src/server/command/commands/CommandWorld.java index 0fba0c4..3b02edb 100644 --- a/server/src/server/command/commands/CommandWorld.java +++ b/server/src/server/command/commands/CommandWorld.java @@ -2,9 +2,9 @@ package server.command.commands; import java.util.List; -import game.entity.Entity; -import game.world.BlockPos; -import game.world.WorldServer; +import common.entity.Entity; +import common.world.BlockPos; +import common.world.WorldServer; import server.command.Command; import server.command.CommandEnvironment; import server.command.Executor; diff --git a/server/src/server/network/HandshakeHandler.java b/server/src/server/network/HandshakeHandler.java index 4d79d09..a3fc59e 100755 --- a/server/src/server/network/HandshakeHandler.java +++ b/server/src/server/network/HandshakeHandler.java @@ -1,12 +1,12 @@ package server.network; -import game.init.Config; -import game.network.IHandshakeHandler; -import game.network.NetConnection; -import game.network.NetHandler; -import game.network.PacketRegistry; -import game.packet.HPacketHandshake; -import game.packet.RPacketDisconnect; +import common.init.Config; +import common.network.IHandshakeHandler; +import common.network.NetConnection; +import common.network.NetHandler; +import common.network.PacketRegistry; +import common.packet.HPacketHandshake; +import common.packet.RPacketDisconnect; import server.Server; public class HandshakeHandler extends NetHandler implements IHandshakeHandler diff --git a/server/src/server/network/LoginHandler.java b/server/src/server/network/LoginHandler.java index 51d9e22..a215180 100755 --- a/server/src/server/network/LoginHandler.java +++ b/server/src/server/network/LoginHandler.java @@ -1,14 +1,14 @@ package server.network; -import game.color.TextColor; -import game.init.Config; -import game.log.Log; -import game.network.ILoginHandler; -import game.network.IPlayer; -import game.network.NetConnection; -import game.network.NetHandler; -import game.packet.LPacketPasswordResponse; -import game.packet.RPacketDisconnect; +import common.color.TextColor; +import common.init.Config; +import common.log.Log; +import common.network.ILoginHandler; +import common.network.IPlayer; +import common.network.NetConnection; +import common.network.NetHandler; +import common.packet.LPacketPasswordResponse; +import common.packet.RPacketDisconnect; import server.Server; public class LoginHandler extends NetHandler implements ILoginHandler diff --git a/server/src/server/network/Player.java b/server/src/server/network/Player.java index 97fab53..544e4ef 100755 --- a/server/src/server/network/Player.java +++ b/server/src/server/network/Player.java @@ -8,128 +8,128 @@ import java.util.Map.Entry; import java.util.Set; import java.util.function.Predicate; -import game.block.Block; -import game.block.BlockFence; -import game.block.BlockFenceGate; -import game.block.BlockWall; -import game.clipboard.BlockTransform; -import game.clipboard.ClipboardBlock; -import game.clipboard.ClipboardPlacer; -import game.clipboard.Rotation; -import game.clipboard.RotationValue; -import game.clipboard.Vector; -import game.collect.Lists; -import game.color.TextColor; -import game.dimension.Dimension; -import game.entity.Entity; -import game.entity.animal.EntityHorse; -import game.entity.item.EntityItem; -import game.entity.item.EntityXp; -import game.entity.npc.Alignment; -import game.entity.npc.EntityHuman; -import game.entity.npc.EntityNPC; -import game.entity.npc.PlayerCharacter; -import game.entity.projectile.EntityArrow; -import game.entity.types.EntityLiving; -import game.future.Futures; -import game.init.BlockRegistry; -import game.init.Config; -import game.init.Config.ValueType; -import game.init.EntityRegistry; -import game.init.Items; -import game.init.RotationRegistry; -import game.init.SoundEvent; -import game.init.UniverseRegistry; -import game.inventory.Container; -import game.inventory.ContainerChest; -import game.inventory.ContainerHorseInventory; -import game.inventory.ContainerMerchant; -import game.inventory.ICrafting; -import game.inventory.IInventory; -import game.inventory.InventoryPlayer; -import game.inventory.Slot; -import game.inventory.SlotCrafting; -import game.item.ItemArmor; -import game.item.ItemControl; -import game.item.ItemStack; -import game.log.Log; -import game.material.Material; -import game.nbt.NBTTagCompound; -import game.nbt.NBTTagList; -import game.nbt.NBTTagString; -import game.network.IPlayer; -import game.network.NetConnection; -import game.network.NetHandler; -import game.network.Packet; -import game.packet.CPacketAction; -import game.packet.CPacketAction.Action; -import game.packet.CPacketBook; -import game.packet.CPacketBreak; -import game.packet.CPacketCheat; -import game.packet.CPacketClick; -import game.packet.CPacketComplete; -import game.packet.CPacketInput; -import game.packet.CPacketKeepAlive; -import game.packet.CPacketMessage; -import game.packet.CPacketPlace; -import game.packet.CPacketPlayer; -import game.packet.CPacketSign; -import game.packet.CPacketSkin; -import game.packet.S18PacketEntityTeleport; -import game.packet.S1APacketEntityStatus; -import game.packet.S1BPacketEntityAttach; -import game.packet.S1DPacketEntityEffect; -import game.packet.S1EPacketRemoveEntityEffect; -import game.packet.S29PacketSoundEffect; -import game.packet.S2DPacketOpenWindow; -import game.packet.S2EPacketCloseWindow; -import game.packet.S2FPacketSetSlot; -import game.packet.S30PacketWindowItems; -import game.packet.S31PacketWindowProperty; -import game.packet.S32PacketConfirmTransaction; -import game.packet.S36PacketSignEditorOpen; -import game.packet.S39PacketPlayerAbilities; -import game.packet.S3APacketTabComplete; -import game.packet.SPacketAnimation; -import game.packet.SPacketBlockChange; -import game.packet.SPacketCharacterList; -import game.packet.SPacketChunkData; -import game.packet.SPacketDestroyEntities; -import game.packet.SPacketDisconnect; -import game.packet.SPacketKeepAlive; -import game.packet.SPacketLoading; -import game.packet.SPacketMapChunkBulk; -import game.packet.SPacketMessage; -import game.packet.SPacketMessage.Type; -import game.packet.SPacketPlayerPosLook; -import game.packet.SPacketServerTick; -import game.packet.SPacketSetExperience; -import game.packet.SPacketSkin; -import game.packet.SPacketTrades; -import game.packet.SPacketUpdateHealth; -import game.potion.Potion; -import game.potion.PotionEffect; -import game.tileentity.IInteractionObject; -import game.tileentity.ILockableContainer; -import game.tileentity.TileEntity; -import game.tileentity.TileEntityMachine; -import game.tileentity.TileEntitySign; -import game.util.ExtMath; -import game.village.MerchantRecipeList; -import game.world.BlockPos; -import game.world.BoundingBox; -import game.world.Chunk; -import game.world.ChunkPos; -import game.world.Facing; -import game.world.IntHashMap; -import game.world.PortalType; -import game.world.Position; -import game.world.Region; -import game.world.State; -import game.world.Vec3i; -import game.world.World; -import game.world.WorldPos; -import game.world.WorldServer; +import common.block.Block; +import common.block.BlockFence; +import common.block.BlockFenceGate; +import common.block.BlockWall; +import common.clipboard.BlockTransform; +import common.clipboard.ClipboardBlock; +import common.clipboard.ClipboardPlacer; +import common.clipboard.Rotation; +import common.clipboard.RotationValue; +import common.clipboard.Vector; +import common.collect.Lists; +import common.color.TextColor; +import common.dimension.Dimension; +import common.entity.Entity; +import common.entity.animal.EntityHorse; +import common.entity.item.EntityItem; +import common.entity.item.EntityXp; +import common.entity.npc.Alignment; +import common.entity.npc.EntityHuman; +import common.entity.npc.EntityNPC; +import common.entity.npc.PlayerCharacter; +import common.entity.projectile.EntityArrow; +import common.entity.types.EntityLiving; +import common.future.Futures; +import common.init.BlockRegistry; +import common.init.Config; +import common.init.EntityRegistry; +import common.init.Items; +import common.init.RotationRegistry; +import common.init.SoundEvent; +import common.init.UniverseRegistry; +import common.init.Config.ValueType; +import common.inventory.Container; +import common.inventory.ContainerChest; +import common.inventory.ContainerHorseInventory; +import common.inventory.ContainerMerchant; +import common.inventory.ICrafting; +import common.inventory.IInventory; +import common.inventory.InventoryPlayer; +import common.inventory.Slot; +import common.inventory.SlotCrafting; +import common.item.ItemArmor; +import common.item.ItemControl; +import common.item.ItemStack; +import common.log.Log; +import common.material.Material; +import common.nbt.NBTTagCompound; +import common.nbt.NBTTagList; +import common.nbt.NBTTagString; +import common.network.IPlayer; +import common.network.NetConnection; +import common.network.NetHandler; +import common.network.Packet; +import common.packet.CPacketAction; +import common.packet.CPacketBook; +import common.packet.CPacketBreak; +import common.packet.CPacketCheat; +import common.packet.CPacketClick; +import common.packet.CPacketComplete; +import common.packet.CPacketInput; +import common.packet.CPacketKeepAlive; +import common.packet.CPacketMessage; +import common.packet.CPacketPlace; +import common.packet.CPacketPlayer; +import common.packet.CPacketSign; +import common.packet.CPacketSkin; +import common.packet.S18PacketEntityTeleport; +import common.packet.S1APacketEntityStatus; +import common.packet.S1BPacketEntityAttach; +import common.packet.S1DPacketEntityEffect; +import common.packet.S1EPacketRemoveEntityEffect; +import common.packet.S29PacketSoundEffect; +import common.packet.S2DPacketOpenWindow; +import common.packet.S2EPacketCloseWindow; +import common.packet.S2FPacketSetSlot; +import common.packet.S30PacketWindowItems; +import common.packet.S31PacketWindowProperty; +import common.packet.S32PacketConfirmTransaction; +import common.packet.S36PacketSignEditorOpen; +import common.packet.S39PacketPlayerAbilities; +import common.packet.S3APacketTabComplete; +import common.packet.SPacketAnimation; +import common.packet.SPacketBlockChange; +import common.packet.SPacketCharacterList; +import common.packet.SPacketChunkData; +import common.packet.SPacketDestroyEntities; +import common.packet.SPacketDisconnect; +import common.packet.SPacketKeepAlive; +import common.packet.SPacketLoading; +import common.packet.SPacketMapChunkBulk; +import common.packet.SPacketMessage; +import common.packet.SPacketPlayerPosLook; +import common.packet.SPacketServerTick; +import common.packet.SPacketSetExperience; +import common.packet.SPacketSkin; +import common.packet.SPacketTrades; +import common.packet.SPacketUpdateHealth; +import common.packet.CPacketAction.Action; +import common.packet.SPacketMessage.Type; +import common.potion.Potion; +import common.potion.PotionEffect; +import common.tileentity.IInteractionObject; +import common.tileentity.ILockableContainer; +import common.tileentity.TileEntity; +import common.tileentity.TileEntityMachine; +import common.tileentity.TileEntitySign; +import common.util.ExtMath; +import common.village.MerchantRecipeList; +import common.world.BlockPos; +import common.world.BoundingBox; +import common.world.Chunk; +import common.world.ChunkPos; +import common.world.Facing; +import common.world.IntHashMap; +import common.world.PortalType; +import common.world.Position; +import common.world.Region; +import common.world.State; +import common.world.Vec3i; +import common.world.World; +import common.world.WorldPos; +import common.world.WorldServer; import io.netty.util.concurrent.Future; import io.netty.util.concurrent.GenericFutureListener; import server.Server; From 278fd0b7e20d6a37978e75d487dc7c0214fc83aa Mon Sep 17 00:00:00 2001 From: Sen Date: Wed, 7 May 2025 23:55:10 +0200 Subject: [PATCH 007/200] change gitignore --- .gitignore | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitignore b/.gitignore index 7730c2f..44084bc 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,7 @@ /java/run /java/bin +/client/bin +/server/bin /java/dev /export /.metadata From 6cab25e79f5a5f76bdfbb263ac3e802b030c582e Mon Sep 17 00:00:00 2001 From: Sen Date: Thu, 8 May 2025 11:47:10 +0200 Subject: [PATCH 008/200] change project names and libraries --- .gitignore | 7 ++++--- {java => common}/src/common/IClient.java | 0 {java => common}/src/common/IServer.java | 0 {java => common}/src/common/ai/AIFireballAttack.java | 0 {java => common}/src/common/ai/AIFlyingBoxAttack.java | 0 {java => common}/src/common/ai/AIRangedAttack.java | 0 {java => common}/src/common/ai/AISmallFireballAttack.java | 0 .../src/common/ai/EntityAIAttackOnCollide.java | 0 {java => common}/src/common/ai/EntityAIAvoidEntity.java | 0 {java => common}/src/common/ai/EntityAIBase.java | 0 {java => common}/src/common/ai/EntityAIBeg.java | 0 .../src/common/ai/EntityAIControlledByPlayer.java | 0 {java => common}/src/common/ai/EntityAIDoorInteract.java | 0 {java => common}/src/common/ai/EntityAIEatGrass.java | 0 {java => common}/src/common/ai/EntityAIExplode.java | 0 .../src/common/ai/EntityAIFindEntityNearest.java | 0 {java => common}/src/common/ai/EntityAIFleeSun.java | 0 {java => common}/src/common/ai/EntityAIFollowOwner.java | 0 {java => common}/src/common/ai/EntityAIFollowParent.java | 0 .../src/common/ai/EntityAIHarvestFarmland.java | 0 {java => common}/src/common/ai/EntityAIHurtByTarget.java | 0 {java => common}/src/common/ai/EntityAILeapAtTarget.java | 0 .../src/common/ai/EntityAILookAtTalkingPlayer.java | 0 {java => common}/src/common/ai/EntityAILookIdle.java | 0 {java => common}/src/common/ai/EntityAIMate.java | 0 {java => common}/src/common/ai/EntityAIMoveIndoors.java | 0 .../src/common/ai/EntityAIMoveThroughVillage.java | 0 {java => common}/src/common/ai/EntityAIMoveToBlock.java | 0 .../src/common/ai/EntityAIMoveTowardsRestriction.java | 0 .../src/common/ai/EntityAIMoveTowardsTarget.java | 0 {java => common}/src/common/ai/EntityAINagPlayer.java | 0 .../src/common/ai/EntityAINearestAttackableTarget.java | 0 {java => common}/src/common/ai/EntityAINpcInteract.java | 0 {java => common}/src/common/ai/EntityAINpcMate.java | 0 {java => common}/src/common/ai/EntityAIOcelotAttack.java | 0 {java => common}/src/common/ai/EntityAIOcelotSit.java | 0 {java => common}/src/common/ai/EntityAIOpenDoor.java | 0 .../src/common/ai/EntityAIOwnerHurtByTarget.java | 0 .../src/common/ai/EntityAIOwnerHurtTarget.java | 0 {java => common}/src/common/ai/EntityAIPanic.java | 0 {java => common}/src/common/ai/EntityAIPlay.java | 0 .../src/common/ai/EntityAIRestrictOpenDoor.java | 0 {java => common}/src/common/ai/EntityAIRestrictSun.java | 0 .../src/common/ai/EntityAIRunAroundLikeCrazy.java | 0 {java => common}/src/common/ai/EntityAIShareItems.java | 0 {java => common}/src/common/ai/EntityAISit.java | 0 {java => common}/src/common/ai/EntityAISwimming.java | 0 {java => common}/src/common/ai/EntityAITakePlace.java | 0 {java => common}/src/common/ai/EntityAITarget.java | 0 {java => common}/src/common/ai/EntityAITargetNonTamed.java | 0 {java => common}/src/common/ai/EntityAITasks.java | 0 {java => common}/src/common/ai/EntityAITempt.java | 0 {java => common}/src/common/ai/EntityAIWander.java | 0 {java => common}/src/common/ai/EntityAIWatchClosest.java | 0 {java => common}/src/common/ai/EntityAIWatchClosest2.java | 0 {java => common}/src/common/ai/EntityJumpHelper.java | 0 {java => common}/src/common/ai/EntityLookHelper.java | 0 {java => common}/src/common/ai/EntityMoveHelper.java | 0 {java => common}/src/common/ai/EntitySenses.java | 0 .../src/common/ai/RandomPositionGenerator.java | 0 {java => common}/src/common/biome/Biome.java | 0 {java => common}/src/common/biome/BiomeBeach.java | 0 {java => common}/src/common/biome/BiomeBlackened.java | 0 {java => common}/src/common/biome/BiomeChaos.java | 0 {java => common}/src/common/biome/BiomeDesert.java | 0 {java => common}/src/common/biome/BiomeExterminated.java | 0 {java => common}/src/common/biome/BiomeForest.java | 0 {java => common}/src/common/biome/BiomeHell.java | 0 {java => common}/src/common/biome/BiomeHills.java | 0 {java => common}/src/common/biome/BiomeJungle.java | 0 {java => common}/src/common/biome/BiomeMesa.java | 0 {java => common}/src/common/biome/BiomeMoon.java | 0 {java => common}/src/common/biome/BiomeMushroom.java | 0 {java => common}/src/common/biome/BiomeMutated.java | 0 {java => common}/src/common/biome/BiomeNone.java | 0 {java => common}/src/common/biome/BiomePlains.java | 0 {java => common}/src/common/biome/BiomeSavanna.java | 0 {java => common}/src/common/biome/BiomeSnow.java | 0 {java => common}/src/common/biome/BiomeSnowLand.java | 0 {java => common}/src/common/biome/BiomeSpace.java | 0 {java => common}/src/common/biome/BiomeStoneBeach.java | 0 {java => common}/src/common/biome/BiomeSwamp.java | 0 {java => common}/src/common/biome/BiomeTaiga.java | 0 {java => common}/src/common/biome/BiomeTian.java | 0 {java => common}/src/common/biome/BiomeWater.java | 0 {java => common}/src/common/biome/RngSpawn.java | 0 {java => common}/src/common/biome/Scaling.java | 0 {java => common}/src/common/biome/Temperature.java | 0 {java => common}/src/common/block/Block.java | 0 {java => common}/src/common/block/BlockAir.java | 0 {java => common}/src/common/block/BlockAnvil.java | 0 {java => common}/src/common/block/BlockBanner.java | 0 {java => common}/src/common/block/BlockBaseFlower.java | 0 .../src/common/block/BlockBasePressurePlate.java | 0 {java => common}/src/common/block/BlockBeacon.java | 0 {java => common}/src/common/block/BlockBed.java | 0 {java => common}/src/common/block/BlockBedrock.java | 0 {java => common}/src/common/block/BlockBlackenedDirt.java | 0 {java => common}/src/common/block/BlockBlackenedSoil.java | 0 {java => common}/src/common/block/BlockBlackenedStone.java | 0 {java => common}/src/common/block/BlockBlueShroom.java | 0 {java => common}/src/common/block/BlockBookshelf.java | 0 {java => common}/src/common/block/BlockBreakable.java | 0 {java => common}/src/common/block/BlockBrewingStand.java | 0 {java => common}/src/common/block/BlockBush.java | 0 {java => common}/src/common/block/BlockButton.java | 0 {java => common}/src/common/block/BlockCactus.java | 0 {java => common}/src/common/block/BlockCake.java | 0 {java => common}/src/common/block/BlockCarpet.java | 0 {java => common}/src/common/block/BlockCarrot.java | 0 {java => common}/src/common/block/BlockCauldron.java | 0 {java => common}/src/common/block/BlockChest.java | 0 {java => common}/src/common/block/BlockClay.java | 0 {java => common}/src/common/block/BlockCocoa.java | 0 {java => common}/src/common/block/BlockColored.java | 0 .../src/common/block/BlockCompressedPowered.java | 0 {java => common}/src/common/block/BlockContainer.java | 0 {java => common}/src/common/block/BlockCore.java | 0 {java => common}/src/common/block/BlockCrops.java | 0 .../src/common/block/BlockDaylightDetector.java | 0 {java => common}/src/common/block/BlockDeadBush.java | 0 {java => common}/src/common/block/BlockDirectional.java | 0 {java => common}/src/common/block/BlockDirt.java | 0 {java => common}/src/common/block/BlockDispenser.java | 0 {java => common}/src/common/block/BlockDoor.java | 0 {java => common}/src/common/block/BlockDoublePlant.java | 0 {java => common}/src/common/block/BlockDragonEgg.java | 0 {java => common}/src/common/block/BlockDropper.java | 0 {java => common}/src/common/block/BlockDryLeaves.java | 0 {java => common}/src/common/block/BlockDynamicLiquid.java | 0 .../src/common/block/BlockEnchantmentTable.java | 0 {java => common}/src/common/block/BlockEventData.java | 0 {java => common}/src/common/block/BlockFalling.java | 0 {java => common}/src/common/block/BlockFarmland.java | 0 {java => common}/src/common/block/BlockFence.java | 0 {java => common}/src/common/block/BlockFenceGate.java | 0 {java => common}/src/common/block/BlockFire.java | 0 {java => common}/src/common/block/BlockFloorPortal.java | 0 {java => common}/src/common/block/BlockFlower.java | 0 {java => common}/src/common/block/BlockFlowerPot.java | 0 {java => common}/src/common/block/BlockFurnace.java | 0 {java => common}/src/common/block/BlockGlass.java | 0 {java => common}/src/common/block/BlockGlowstone.java | 0 {java => common}/src/common/block/BlockGrass.java | 0 {java => common}/src/common/block/BlockGravel.java | 0 {java => common}/src/common/block/BlockHardenedClay.java | 0 {java => common}/src/common/block/BlockHay.java | 0 {java => common}/src/common/block/BlockHellRock.java | 0 {java => common}/src/common/block/BlockHopper.java | 0 {java => common}/src/common/block/BlockHugeMushroom.java | 0 {java => common}/src/common/block/BlockIce.java | 0 {java => common}/src/common/block/BlockJukebox.java | 0 {java => common}/src/common/block/BlockLadder.java | 0 {java => common}/src/common/block/BlockLeaves.java | 0 {java => common}/src/common/block/BlockLeavesBase.java | 0 {java => common}/src/common/block/BlockLever.java | 0 {java => common}/src/common/block/BlockLilyPad.java | 0 {java => common}/src/common/block/BlockLiquid.java | 0 {java => common}/src/common/block/BlockLog.java | 0 {java => common}/src/common/block/BlockMachine.java | 0 {java => common}/src/common/block/BlockMelon.java | 0 {java => common}/src/common/block/BlockMobSpawner.java | 0 {java => common}/src/common/block/BlockMushroom.java | 0 {java => common}/src/common/block/BlockMycelium.java | 0 {java => common}/src/common/block/BlockNote.java | 0 {java => common}/src/common/block/BlockNuke.java | 0 {java => common}/src/common/block/BlockObsidian.java | 0 {java => common}/src/common/block/BlockOre.java | 0 {java => common}/src/common/block/BlockPackedIce.java | 0 {java => common}/src/common/block/BlockPane.java | 0 {java => common}/src/common/block/BlockPistonBase.java | 0 {java => common}/src/common/block/BlockPistonHead.java | 0 {java => common}/src/common/block/BlockPistonMoving.java | 0 {java => common}/src/common/block/BlockPortal.java | 0 {java => common}/src/common/block/BlockPortalFrame.java | 0 {java => common}/src/common/block/BlockPotato.java | 0 {java => common}/src/common/block/BlockPressurePlate.java | 0 .../src/common/block/BlockPressurePlateWeighted.java | 0 {java => common}/src/common/block/BlockPumpkin.java | 0 {java => common}/src/common/block/BlockQuartz.java | 0 {java => common}/src/common/block/BlockRail.java | 0 {java => common}/src/common/block/BlockRailBase.java | 0 {java => common}/src/common/block/BlockRailDetector.java | 0 {java => common}/src/common/block/BlockRailPowered.java | 0 .../src/common/block/BlockRedstoneComparator.java | 0 {java => common}/src/common/block/BlockRedstoneDiode.java | 0 {java => common}/src/common/block/BlockRedstoneLight.java | 0 {java => common}/src/common/block/BlockRedstoneOre.java | 0 .../src/common/block/BlockRedstoneRepeater.java | 0 {java => common}/src/common/block/BlockRedstoneTorch.java | 0 {java => common}/src/common/block/BlockRedstoneWire.java | 0 {java => common}/src/common/block/BlockReed.java | 0 {java => common}/src/common/block/BlockRock.java | 0 {java => common}/src/common/block/BlockRotatedPillar.java | 0 {java => common}/src/common/block/BlockSand.java | 0 {java => common}/src/common/block/BlockSandStone.java | 0 {java => common}/src/common/block/BlockSapling.java | 0 {java => common}/src/common/block/BlockSign.java | 0 {java => common}/src/common/block/BlockSkull.java | 0 {java => common}/src/common/block/BlockSlab.java | 0 {java => common}/src/common/block/BlockSlime.java | 0 {java => common}/src/common/block/BlockSnow.java | 0 {java => common}/src/common/block/BlockSnowBlock.java | 0 {java => common}/src/common/block/BlockSoulSand.java | 0 {java => common}/src/common/block/BlockSourceImpl.java | 0 {java => common}/src/common/block/BlockStainedGlass.java | 0 .../src/common/block/BlockStainedGlassPane.java | 0 {java => common}/src/common/block/BlockStairs.java | 0 {java => common}/src/common/block/BlockStandingSign.java | 0 {java => common}/src/common/block/BlockStaticLiquid.java | 0 {java => common}/src/common/block/BlockStem.java | 0 {java => common}/src/common/block/BlockStone.java | 0 {java => common}/src/common/block/BlockStoneBrick.java | 0 {java => common}/src/common/block/BlockTNT.java | 0 {java => common}/src/common/block/BlockTallGrass.java | 0 {java => common}/src/common/block/BlockTianReactor.java | 0 {java => common}/src/common/block/BlockTianSoil.java | 0 {java => common}/src/common/block/BlockTorch.java | 0 {java => common}/src/common/block/BlockTrapDoor.java | 0 {java => common}/src/common/block/BlockTreasure.java | 0 {java => common}/src/common/block/BlockTripWire.java | 0 {java => common}/src/common/block/BlockTripWireHook.java | 0 {java => common}/src/common/block/BlockVine.java | 0 {java => common}/src/common/block/BlockWall.java | 0 {java => common}/src/common/block/BlockWallSign.java | 0 {java => common}/src/common/block/BlockWarpChest.java | 0 {java => common}/src/common/block/BlockWart.java | 0 {java => common}/src/common/block/BlockWeb.java | 0 {java => common}/src/common/block/BlockWorkbench.java | 0 {java => common}/src/common/block/IGrowable.java | 0 {java => common}/src/common/block/ITileEntityProvider.java | 0 {java => common}/src/common/block/LeavesType.java | 0 {java => common}/src/common/block/SoundType.java | 0 {java => common}/src/common/clipboard/BlockTransform.java | 0 {java => common}/src/common/clipboard/ClipboardBlock.java | 0 {java => common}/src/common/clipboard/ClipboardPlacer.java | 0 {java => common}/src/common/clipboard/Rotation.java | 0 {java => common}/src/common/clipboard/RotationValue.java | 0 {java => common}/src/common/clipboard/Vector.java | 0 {java => common}/src/common/collect/AbstractBiMap.java | 0 .../src/common/collect/AbstractIndexedListIterator.java | 0 {java => common}/src/common/collect/AbstractIterator.java | 0 {java => common}/src/common/collect/AbstractMapEntry.java | 0 {java => common}/src/common/collect/AbstractTable.java | 0 {java => common}/src/common/collect/BiMap.java | 0 .../src/common/collect/CollectPreconditions.java | 0 .../src/common/collect/DenseImmutableTable.java | 0 {java => common}/src/common/collect/EmptyImmutableMap.java | 0 {java => common}/src/common/collect/EmptyImmutableSet.java | 0 {java => common}/src/common/collect/Filter.java | 0 .../src/common/collect/ForwardingCollection.java | 0 {java => common}/src/common/collect/ForwardingMap.java | 0 .../src/common/collect/ForwardingMapEntry.java | 0 {java => common}/src/common/collect/ForwardingObject.java | 0 {java => common}/src/common/collect/ForwardingSet.java | 0 {java => common}/src/common/collect/HashBiMap.java | 0 {java => common}/src/common/collect/Hashing.java | 0 {java => common}/src/common/collect/ImmutableAsList.java | 0 .../src/common/collect/ImmutableCollection.java | 0 {java => common}/src/common/collect/ImmutableEntry.java | 0 {java => common}/src/common/collect/ImmutableEnumMap.java | 0 {java => common}/src/common/collect/ImmutableEnumSet.java | 0 {java => common}/src/common/collect/ImmutableList.java | 0 {java => common}/src/common/collect/ImmutableMap.java | 0 {java => common}/src/common/collect/ImmutableMapEntry.java | 0 .../src/common/collect/ImmutableMapEntrySet.java | 0 .../src/common/collect/ImmutableMapKeySet.java | 0 .../src/common/collect/ImmutableMapValues.java | 0 {java => common}/src/common/collect/ImmutableSet.java | 0 {java => common}/src/common/collect/ImmutableTable.java | 0 {java => common}/src/common/collect/Iterables.java | 0 {java => common}/src/common/collect/Iterators.java | 0 {java => common}/src/common/collect/Lists.java | 0 {java => common}/src/common/collect/Maps.java | 0 {java => common}/src/common/collect/ObjectArrays.java | 0 {java => common}/src/common/collect/Preconditions.java | 0 .../src/common/collect/RegularImmutableAsList.java | 0 .../src/common/collect/RegularImmutableList.java | 0 .../src/common/collect/RegularImmutableMap.java | 0 .../src/common/collect/RegularImmutableSet.java | 0 .../src/common/collect/RegularImmutableTable.java | 0 {java => common}/src/common/collect/Sets.java | 0 .../src/common/collect/SparseImmutableTable.java | 0 {java => common}/src/common/collect/StandardTable.java | 0 {java => common}/src/common/collect/Table.java | 0 .../src/common/collect/TransformedIterator.java | 0 .../src/common/collect/UnmodifiableIterator.java | 0 .../src/common/collect/UnmodifiableListIterator.java | 0 {java => common}/src/common/color/Colorizer.java | 0 {java => common}/src/common/color/DyeColor.java | 0 {java => common}/src/common/color/TextColor.java | 0 {java => common}/src/common/dimension/Area.java | 0 {java => common}/src/common/dimension/DimType.java | 0 {java => common}/src/common/dimension/Dimension.java | 0 {java => common}/src/common/dimension/Domain.java | 0 {java => common}/src/common/dimension/Galaxy.java | 0 {java => common}/src/common/dimension/Moon.java | 0 {java => common}/src/common/dimension/Nameable.java | 0 {java => common}/src/common/dimension/Planet.java | 0 {java => common}/src/common/dimension/Sector.java | 0 {java => common}/src/common/dimension/Semi.java | 0 {java => common}/src/common/dimension/Space.java | 0 {java => common}/src/common/dimension/Star.java | 0 .../src/common/dispenser/BehaviorDefaultDispenseItem.java | 0 .../src/common/dispenser/BehaviorProjectileDispense.java | 0 .../src/common/dispenser/IBehaviorDispenseItem.java | 0 {java => common}/src/common/dispenser/IBlockSource.java | 0 .../src/common/dispenser/ILocatableSource.java | 0 {java => common}/src/common/dispenser/ILocation.java | 0 {java => common}/src/common/dispenser/IPosition.java | 0 {java => common}/src/common/dispenser/PositionImpl.java | 0 {java => common}/src/common/enchantment/Enchantment.java | 0 .../src/common/enchantment/EnchantmentArrowDamage.java | 0 .../src/common/enchantment/EnchantmentArrowFire.java | 0 .../src/common/enchantment/EnchantmentArrowInfinite.java | 0 .../src/common/enchantment/EnchantmentArrowKnockback.java | 0 .../src/common/enchantment/EnchantmentDamage.java | 0 .../src/common/enchantment/EnchantmentDigging.java | 0 .../src/common/enchantment/EnchantmentDraining.java | 0 .../src/common/enchantment/EnchantmentDurability.java | 0 .../src/common/enchantment/EnchantmentFireAspect.java | 0 .../src/common/enchantment/EnchantmentFishingSpeed.java | 0 .../src/common/enchantment/EnchantmentHelper.java | 0 .../src/common/enchantment/EnchantmentKnockback.java | 0 .../src/common/enchantment/EnchantmentLootBonus.java | 0 .../src/common/enchantment/EnchantmentProtection.java | 0 .../src/common/enchantment/EnchantmentThorns.java | 0 .../src/common/enchantment/EnchantmentUntouching.java | 0 .../src/common/enchantment/EnumEnchantmentType.java | 0 .../src/common/enchantment/RngEnchantment.java | 0 {java => common}/src/common/entity/DamageSource.java | 0 {java => common}/src/common/entity/DataWatcher.java | 0 {java => common}/src/common/entity/Entity.java | 0 {java => common}/src/common/entity/EntityDamageSource.java | 0 .../src/common/entity/EntityDamageSourceIndirect.java | 0 {java => common}/src/common/entity/EntityTrackerEntry.java | 0 {java => common}/src/common/entity/EntityType.java | 0 {java => common}/src/common/entity/animal/EntityBat.java | 0 .../src/common/entity/animal/EntityChicken.java | 0 {java => common}/src/common/entity/animal/EntityCow.java | 0 .../src/common/entity/animal/EntityDragon.java | 0 .../src/common/entity/animal/EntityDragonPart.java | 0 {java => common}/src/common/entity/animal/EntityHorse.java | 0 .../src/common/entity/animal/EntityMooshroom.java | 0 {java => common}/src/common/entity/animal/EntityMouse.java | 0 .../src/common/entity/animal/EntityOcelot.java | 0 {java => common}/src/common/entity/animal/EntityPig.java | 0 .../src/common/entity/animal/EntityRabbit.java | 0 {java => common}/src/common/entity/animal/EntitySheep.java | 0 {java => common}/src/common/entity/animal/EntitySquid.java | 0 {java => common}/src/common/entity/animal/EntityWolf.java | 0 .../src/common/entity/attributes/Attribute.java | 0 .../src/common/entity/attributes/AttributeInstance.java | 0 .../src/common/entity/attributes/AttributeMap.java | 0 .../src/common/entity/attributes/AttributeModifier.java | 0 .../src/common/entity/attributes/Attributes.java | 0 .../src/common/entity/attributes/LowerStringMap.java | 0 .../src/common/entity/effect/EntityLightning.java | 0 {java => common}/src/common/entity/item/EntityBoat.java | 0 {java => common}/src/common/entity/item/EntityCart.java | 0 .../src/common/entity/item/EntityCartContainer.java | 0 .../src/common/entity/item/EntityChestCart.java | 0 {java => common}/src/common/entity/item/EntityCrystal.java | 0 .../src/common/entity/item/EntityExplosion.java | 0 {java => common}/src/common/entity/item/EntityFalling.java | 0 .../src/common/entity/item/EntityFireworks.java | 0 .../src/common/entity/item/EntityHopperCart.java | 0 {java => common}/src/common/entity/item/EntityItem.java | 0 .../src/common/entity/item/EntityLeashKnot.java | 0 .../src/common/entity/item/EntityMinecart.java | 0 {java => common}/src/common/entity/item/EntityNuke.java | 0 {java => common}/src/common/entity/item/EntityOrb.java | 0 {java => common}/src/common/entity/item/EntityTnt.java | 0 {java => common}/src/common/entity/item/EntityTntCart.java | 0 {java => common}/src/common/entity/item/EntityXp.java | 0 .../src/common/entity/item/EntityXpBottle.java | 0 {java => common}/src/common/entity/npc/Alignment.java | 0 {java => common}/src/common/entity/npc/CharacterInfo.java | 0 {java => common}/src/common/entity/npc/ClassInfo.java | 0 {java => common}/src/common/entity/npc/Energy.java | 0 .../src/common/entity/npc/EntityArachnoid.java | 0 {java => common}/src/common/entity/npc/EntityBloodElf.java | 0 .../src/common/entity/npc/EntityChaosMarine.java | 0 {java => common}/src/common/entity/npc/EntityCpu.java | 0 .../src/common/entity/npc/EntityCultivator.java | 0 {java => common}/src/common/entity/npc/EntityDarkMage.java | 0 {java => common}/src/common/entity/npc/EntityDwarf.java | 0 {java => common}/src/common/entity/npc/EntityElf.java | 0 .../src/common/entity/npc/EntityFireDemon.java | 0 .../src/common/entity/npc/EntityFlyingNPC.java | 0 {java => common}/src/common/entity/npc/EntityGargoyle.java | 0 {java => common}/src/common/entity/npc/EntityGoblin.java | 0 {java => common}/src/common/entity/npc/EntityHaunter.java | 0 .../src/common/entity/npc/EntityHoveringNPC.java | 0 {java => common}/src/common/entity/npc/EntityHuman.java | 0 {java => common}/src/common/entity/npc/EntityMage.java | 0 {java => common}/src/common/entity/npc/EntityMagma.java | 0 .../src/common/entity/npc/EntityMetalhead.java | 0 {java => common}/src/common/entity/npc/EntityMobNPC.java | 0 {java => common}/src/common/entity/npc/EntityNPC.java | 0 {java => common}/src/common/entity/npc/EntityOrc.java | 0 {java => common}/src/common/entity/npc/EntityPrimarch.java | 0 {java => common}/src/common/entity/npc/EntitySlime.java | 0 .../src/common/entity/npc/EntitySpaceMarine.java | 0 {java => common}/src/common/entity/npc/EntitySpirit.java | 0 {java => common}/src/common/entity/npc/EntityTiefling.java | 0 {java => common}/src/common/entity/npc/EntityUndead.java | 0 {java => common}/src/common/entity/npc/EntityVampire.java | 0 {java => common}/src/common/entity/npc/EntityWoodElf.java | 0 {java => common}/src/common/entity/npc/EntityZombie.java | 0 {java => common}/src/common/entity/npc/NpcInfo.java | 0 .../src/common/entity/npc/PlayerCharacter.java | 0 {java => common}/src/common/entity/npc/SpeciesInfo.java | 0 .../src/common/entity/projectile/EntityArrow.java | 0 .../src/common/entity/projectile/EntityBox.java | 0 .../src/common/entity/projectile/EntityBullet.java | 0 .../src/common/entity/projectile/EntityDie.java | 0 .../src/common/entity/projectile/EntityDynamite.java | 0 .../src/common/entity/projectile/EntityEgg.java | 0 .../src/common/entity/projectile/EntityFireCharge.java | 0 .../src/common/entity/projectile/EntityFireball.java | 0 .../src/common/entity/projectile/EntityHook.java | 0 .../src/common/entity/projectile/EntityPotion.java | 0 .../src/common/entity/projectile/EntityProjectile.java | 0 .../src/common/entity/projectile/EntitySnowball.java | 0 .../src/common/entity/projectile/RngFishable.java | 0 {java => common}/src/common/entity/types/CombatEntry.java | 0 {java => common}/src/common/entity/types/EntityAnimal.java | 0 .../src/common/entity/types/EntityBodyHelper.java | 0 {java => common}/src/common/entity/types/EntityLiving.java | 0 .../src/common/entity/types/EntityTameable.java | 0 .../src/common/entity/types/EntityThrowable.java | 0 .../src/common/entity/types/EntityWaterMob.java | 0 .../src/common/entity/types/EntityWeatherEffect.java | 0 {java => common}/src/common/entity/types/IEntityFX.java | 0 .../src/common/entity/types/IEntityMultiPart.java | 0 .../src/common/entity/types/IEntityOwnable.java | 0 {java => common}/src/common/entity/types/IObjectData.java | 0 {java => common}/src/common/entity/types/IProjectile.java | 0 {java => common}/src/common/future/AbstractFuture.java | 0 {java => common}/src/common/future/ExecutionError.java | 0 {java => common}/src/common/future/ExecutionList.java | 0 {java => common}/src/common/future/FutureCallback.java | 0 {java => common}/src/common/future/Futures.java | 0 {java => common}/src/common/future/ListenableFuture.java | 0 .../src/common/future/ListenableFutureTask.java | 0 {java => common}/src/common/future/MoreExecutors.java | 0 .../src/common/future/ThreadFactoryBuilder.java | 0 .../src/common/future/UncheckedExecutionException.java | 0 {java => common}/src/common/init/BlockRegistry.java | 0 {java => common}/src/common/init/Blocks.java | 0 {java => common}/src/common/init/Config.java | 0 {java => common}/src/common/init/CraftingRegistry.java | 0 {java => common}/src/common/init/DecoType.java | 0 {java => common}/src/common/init/DispenserRegistry.java | 0 {java => common}/src/common/init/EntityEggInfo.java | 0 {java => common}/src/common/init/EntityRegistry.java | 0 {java => common}/src/common/init/FlammabilityRegistry.java | 0 {java => common}/src/common/init/FluidRegistry.java | 0 {java => common}/src/common/init/IObjectIntIterable.java | 0 {java => common}/src/common/init/IRegistry.java | 0 {java => common}/src/common/init/ItemRegistry.java | 0 {java => common}/src/common/init/Items.java | 0 {java => common}/src/common/init/MetalType.java | 0 {java => common}/src/common/init/NameRegistry.java | 0 {java => common}/src/common/init/ObjectIntIdentityMap.java | 0 {java => common}/src/common/init/OreType.java | 0 {java => common}/src/common/init/Registry.java | 0 {java => common}/src/common/init/RegistryDefaulted.java | 0 {java => common}/src/common/init/RegistryNamespaced.java | 0 .../src/common/init/RegistryNamespacedDefaultedByKey.java | 0 {java => common}/src/common/init/RegistrySimple.java | 0 {java => common}/src/common/init/ReorderRegistry.java | 0 {java => common}/src/common/init/RotationRegistry.java | 0 {java => common}/src/common/init/SmeltingRegistry.java | 0 {java => common}/src/common/init/SoundEvent.java | 0 {java => common}/src/common/init/SpeciesRegistry.java | 0 {java => common}/src/common/init/TileRegistry.java | 0 {java => common}/src/common/init/ToolMaterial.java | 0 {java => common}/src/common/init/ToolType.java | 0 {java => common}/src/common/init/TradeRegistry.java | 0 {java => common}/src/common/init/UniverseRegistry.java | 0 {java => common}/src/common/init/WoodType.java | 0 {java => common}/src/common/inventory/AnimalChest.java | 0 {java => common}/src/common/inventory/Container.java | 0 .../src/common/inventory/ContainerBrewingStand.java | 0 {java => common}/src/common/inventory/ContainerChest.java | 0 .../src/common/inventory/ContainerDispenser.java | 0 .../src/common/inventory/ContainerEnchantment.java | 0 .../src/common/inventory/ContainerFurnace.java | 0 {java => common}/src/common/inventory/ContainerHopper.java | 0 .../src/common/inventory/ContainerHorseInventory.java | 0 .../src/common/inventory/ContainerLocalMenu.java | 0 .../src/common/inventory/ContainerMachine.java | 0 .../src/common/inventory/ContainerMerchant.java | 0 {java => common}/src/common/inventory/ContainerPlayer.java | 0 {java => common}/src/common/inventory/ContainerRepair.java | 0 .../src/common/inventory/ContainerWorkbench.java | 0 {java => common}/src/common/inventory/ICrafting.java | 0 {java => common}/src/common/inventory/IInvBasic.java | 0 {java => common}/src/common/inventory/IInventory.java | 0 {java => common}/src/common/inventory/ISidedInventory.java | 0 {java => common}/src/common/inventory/InventoryBasic.java | 0 .../src/common/inventory/InventoryCraftResult.java | 0 .../src/common/inventory/InventoryCrafting.java | 0 {java => common}/src/common/inventory/InventoryHelper.java | 0 .../src/common/inventory/InventoryLargeChest.java | 0 .../src/common/inventory/InventoryMerchant.java | 0 {java => common}/src/common/inventory/InventoryPlayer.java | 0 .../src/common/inventory/InventoryWarpChest.java | 0 {java => common}/src/common/inventory/Slot.java | 0 {java => common}/src/common/inventory/SlotCrafting.java | 0 {java => common}/src/common/inventory/SlotFurnaceFuel.java | 0 .../src/common/inventory/SlotFurnaceOutput.java | 0 .../src/common/inventory/SlotMerchantResult.java | 0 {java => common}/src/common/item/CheatTab.java | 0 {java => common}/src/common/item/Item.java | 0 {java => common}/src/common/item/ItemAction.java | 0 {java => common}/src/common/item/ItemAmmo.java | 0 {java => common}/src/common/item/ItemAnvilBlock.java | 0 {java => common}/src/common/item/ItemAppleGold.java | 0 {java => common}/src/common/item/ItemArmor.java | 0 {java => common}/src/common/item/ItemAxe.java | 0 {java => common}/src/common/item/ItemBanHammer.java | 0 {java => common}/src/common/item/ItemBanner.java | 0 {java => common}/src/common/item/ItemBed.java | 0 {java => common}/src/common/item/ItemBlock.java | 0 {java => common}/src/common/item/ItemBoat.java | 0 {java => common}/src/common/item/ItemBoltgun.java | 0 {java => common}/src/common/item/ItemBook.java | 0 {java => common}/src/common/item/ItemBow.java | 0 {java => common}/src/common/item/ItemBucket.java | 0 {java => common}/src/common/item/ItemBucketMilk.java | 0 {java => common}/src/common/item/ItemButton.java | 0 {java => common}/src/common/item/ItemCamera.java | 0 {java => common}/src/common/item/ItemCarrotOnAStick.java | 0 {java => common}/src/common/item/ItemChargedOrb.java | 0 {java => common}/src/common/item/ItemChest.java | 0 {java => common}/src/common/item/ItemCloth.java | 0 {java => common}/src/common/item/ItemCoal.java | 0 {java => common}/src/common/item/ItemColored.java | 0 {java => common}/src/common/item/ItemControl.java | 0 {java => common}/src/common/item/ItemDie.java | 0 {java => common}/src/common/item/ItemDispenser.java | 0 {java => common}/src/common/item/ItemDoor.java | 0 {java => common}/src/common/item/ItemDoublePlant.java | 0 {java => common}/src/common/item/ItemDye.java | 0 {java => common}/src/common/item/ItemDynamite.java | 0 {java => common}/src/common/item/ItemEditWand.java | 0 {java => common}/src/common/item/ItemEffect.java | 0 {java => common}/src/common/item/ItemEgg.java | 0 {java => common}/src/common/item/ItemEnchantedBook.java | 0 {java => common}/src/common/item/ItemExpBottle.java | 0 {java => common}/src/common/item/ItemExterminator.java | 0 {java => common}/src/common/item/ItemFence.java | 0 {java => common}/src/common/item/ItemFireball.java | 0 {java => common}/src/common/item/ItemFirework.java | 0 {java => common}/src/common/item/ItemFireworkCharge.java | 0 {java => common}/src/common/item/ItemFishFood.java | 0 {java => common}/src/common/item/ItemFishingRod.java | 0 {java => common}/src/common/item/ItemFlintAndSteel.java | 0 {java => common}/src/common/item/ItemFood.java | 0 {java => common}/src/common/item/ItemFragile.java | 0 {java => common}/src/common/item/ItemGlassBottle.java | 0 {java => common}/src/common/item/ItemGunBase.java | 0 {java => common}/src/common/item/ItemHoe.java | 0 {java => common}/src/common/item/ItemHorseArmor.java | 0 {java => common}/src/common/item/ItemHugeMushroom.java | 0 {java => common}/src/common/item/ItemInfoWand.java | 0 {java => common}/src/common/item/ItemKey.java | 0 {java => common}/src/common/item/ItemLead.java | 0 {java => common}/src/common/item/ItemLeaves.java | 0 {java => common}/src/common/item/ItemLightning.java | 0 {java => common}/src/common/item/ItemLilyPad.java | 0 {java => common}/src/common/item/ItemMagnet.java | 0 {java => common}/src/common/item/ItemMagnetic.java | 0 {java => common}/src/common/item/ItemMetal.java | 0 {java => common}/src/common/item/ItemMetalBlock.java | 0 {java => common}/src/common/item/ItemMinecart.java | 0 {java => common}/src/common/item/ItemMonsterPlacer.java | 0 {java => common}/src/common/item/ItemMultiTexture.java | 0 {java => common}/src/common/item/ItemNameTag.java | 0 {java => common}/src/common/item/ItemNpcSpawner.java | 0 {java => common}/src/common/item/ItemNugget.java | 0 {java => common}/src/common/item/ItemPickaxe.java | 0 {java => common}/src/common/item/ItemPiston.java | 0 {java => common}/src/common/item/ItemPotion.java | 0 {java => common}/src/common/item/ItemPressurePlate.java | 0 {java => common}/src/common/item/ItemRecord.java | 0 {java => common}/src/common/item/ItemRedstone.java | 0 {java => common}/src/common/item/ItemReed.java | 0 {java => common}/src/common/item/ItemRod.java | 0 {java => common}/src/common/item/ItemSaddle.java | 0 {java => common}/src/common/item/ItemSeedFood.java | 0 {java => common}/src/common/item/ItemSeeds.java | 0 {java => common}/src/common/item/ItemShears.java | 0 {java => common}/src/common/item/ItemSign.java | 0 {java => common}/src/common/item/ItemSkull.java | 0 {java => common}/src/common/item/ItemSlab.java | 0 {java => common}/src/common/item/ItemSmall.java | 0 {java => common}/src/common/item/ItemSnow.java | 0 {java => common}/src/common/item/ItemSnowball.java | 0 {java => common}/src/common/item/ItemSoup.java | 0 {java => common}/src/common/item/ItemSpaceNavigator.java | 0 {java => common}/src/common/item/ItemSpade.java | 0 {java => common}/src/common/item/ItemStack.java | 0 {java => common}/src/common/item/ItemStick.java | 0 {java => common}/src/common/item/ItemSword.java | 0 {java => common}/src/common/item/ItemTNT.java | 0 {java => common}/src/common/item/ItemTiny.java | 0 {java => common}/src/common/item/ItemTool.java | 0 {java => common}/src/common/item/ItemWall.java | 0 {java => common}/src/common/item/ItemWand.java | 0 {java => common}/src/common/item/ItemWeatherToken.java | 0 {java => common}/src/common/item/RngLoot.java | 0 {java => common}/src/common/log/Log.java | 0 {java => common}/src/common/log/LogLevel.java | 0 {java => common}/src/common/log/Message.java | 0 {java => common}/src/common/log/NettyLogger.java | 0 {java => common}/src/common/material/Material.java | 0 .../src/common/material/MaterialColdFluid.java | 0 {java => common}/src/common/material/MaterialHotFluid.java | 0 {java => common}/src/common/material/MaterialLogic.java | 0 {java => common}/src/common/material/MaterialPortal.java | 0 .../src/common/material/MaterialTransparent.java | 0 {java => common}/src/common/model/BlockLayer.java | 0 {java => common}/src/common/model/ItemMeshDefinition.java | 0 {java => common}/src/common/model/Model.java | 0 {java => common}/src/common/model/ModelProvider.java | 0 {java => common}/src/common/model/ModelRotation.java | 0 {java => common}/src/common/model/ParticleType.java | 0 {java => common}/src/common/model/Transform.java | 0 {java => common}/src/common/model/Transforms.java | 0 {java => common}/src/common/nbt/NBTBase.java | 0 {java => common}/src/common/nbt/NBTException.java | 0 {java => common}/src/common/nbt/NBTLoader.java | 0 {java => common}/src/common/nbt/NBTParser.java | 0 {java => common}/src/common/nbt/NBTSizeTracker.java | 0 {java => common}/src/common/nbt/NBTTagByte.java | 0 {java => common}/src/common/nbt/NBTTagByteArray.java | 0 {java => common}/src/common/nbt/NBTTagCompound.java | 0 {java => common}/src/common/nbt/NBTTagDouble.java | 0 {java => common}/src/common/nbt/NBTTagEnd.java | 0 {java => common}/src/common/nbt/NBTTagFloat.java | 0 {java => common}/src/common/nbt/NBTTagInt.java | 0 {java => common}/src/common/nbt/NBTTagIntArray.java | 0 {java => common}/src/common/nbt/NBTTagList.java | 0 {java => common}/src/common/nbt/NBTTagLong.java | 0 {java => common}/src/common/nbt/NBTTagShort.java | 0 {java => common}/src/common/nbt/NBTTagString.java | 0 {java => common}/src/common/nbt/NBTUtil.java | 0 .../src/common/network/IClientLoginHandler.java | 0 {java => common}/src/common/network/IClientPlayer.java | 0 {java => common}/src/common/network/IHandshakeHandler.java | 0 {java => common}/src/common/network/ILoginHandler.java | 0 {java => common}/src/common/network/IPlayer.java | 0 {java => common}/src/common/network/IThreadListener.java | 0 {java => common}/src/common/network/NetConnection.java | 0 {java => common}/src/common/network/NetHandler.java | 0 .../src/common/network/NettyCompressionDecoder.java | 0 .../src/common/network/NettyCompressionEncoder.java | 0 {java => common}/src/common/network/Packet.java | 0 {java => common}/src/common/network/PacketBuffer.java | 0 {java => common}/src/common/network/PacketDecoder.java | 0 {java => common}/src/common/network/PacketEncoder.java | 0 {java => common}/src/common/network/PacketPrepender.java | 0 {java => common}/src/common/network/PacketRegistry.java | 0 {java => common}/src/common/network/PacketSplitter.java | 0 {java => common}/src/common/packet/APacketEmpty.java | 0 {java => common}/src/common/packet/APacketVarInt.java | 0 {java => common}/src/common/packet/CPacketAction.java | 0 {java => common}/src/common/packet/CPacketBook.java | 0 {java => common}/src/common/packet/CPacketBreak.java | 0 {java => common}/src/common/packet/CPacketCheat.java | 0 {java => common}/src/common/packet/CPacketClick.java | 0 {java => common}/src/common/packet/CPacketComplete.java | 0 {java => common}/src/common/packet/CPacketInput.java | 0 {java => common}/src/common/packet/CPacketKeepAlive.java | 0 {java => common}/src/common/packet/CPacketMessage.java | 0 {java => common}/src/common/packet/CPacketPlace.java | 0 {java => common}/src/common/packet/CPacketPlayer.java | 0 {java => common}/src/common/packet/CPacketSign.java | 0 {java => common}/src/common/packet/CPacketSkin.java | 0 {java => common}/src/common/packet/HPacketHandshake.java | 0 .../src/common/packet/LPacketPasswordResponse.java | 0 {java => common}/src/common/packet/RPacketDisconnect.java | 0 .../src/common/packet/RPacketEnableCompression.java | 0 .../src/common/packet/RPacketLoginSuccess.java | 0 {java => common}/src/common/packet/S14PacketEntity.java | 0 .../src/common/packet/S18PacketEntityTeleport.java | 0 .../src/common/packet/S19PacketEntityHeadLook.java | 0 .../src/common/packet/S1APacketEntityStatus.java | 0 .../src/common/packet/S1BPacketEntityAttach.java | 0 .../src/common/packet/S1CPacketEntityMetadata.java | 0 .../src/common/packet/S1DPacketEntityEffect.java | 0 .../src/common/packet/S1EPacketRemoveEntityEffect.java | 0 .../src/common/packet/S20PacketEntityProperties.java | 0 {java => common}/src/common/packet/S27PacketExplosion.java | 0 {java => common}/src/common/packet/S28PacketEffect.java | 0 .../src/common/packet/S29PacketSoundEffect.java | 0 {java => common}/src/common/packet/S2APacketParticles.java | 0 .../src/common/packet/S2BPacketChangeGameState.java | 0 .../src/common/packet/S2CPacketSpawnGlobalEntity.java | 0 .../src/common/packet/S2DPacketOpenWindow.java | 0 .../src/common/packet/S2EPacketCloseWindow.java | 0 {java => common}/src/common/packet/S2FPacketSetSlot.java | 0 .../src/common/packet/S30PacketWindowItems.java | 0 .../src/common/packet/S31PacketWindowProperty.java | 0 .../src/common/packet/S32PacketConfirmTransaction.java | 0 .../src/common/packet/S33PacketUpdateSign.java | 0 .../src/common/packet/S35PacketUpdateTileEntity.java | 0 .../src/common/packet/S36PacketSignEditorOpen.java | 0 .../src/common/packet/S38PacketPlayerListItem.java | 0 .../src/common/packet/S39PacketPlayerAbilities.java | 0 .../src/common/packet/S3APacketTabComplete.java | 0 .../src/common/packet/S43PacketUpdateEntityNBT.java | 0 {java => common}/src/common/packet/SPacketAnimation.java | 0 {java => common}/src/common/packet/SPacketBiomes.java | 0 {java => common}/src/common/packet/SPacketBlockAction.java | 0 .../src/common/packet/SPacketBlockBreakAnim.java | 0 {java => common}/src/common/packet/SPacketBlockChange.java | 0 {java => common}/src/common/packet/SPacketCamera.java | 0 .../src/common/packet/SPacketCharacterList.java | 0 {java => common}/src/common/packet/SPacketChunkData.java | 0 {java => common}/src/common/packet/SPacketCollectItem.java | 0 .../src/common/packet/SPacketDestroyEntities.java | 0 .../src/common/packet/SPacketDimensionName.java | 0 {java => common}/src/common/packet/SPacketDisconnect.java | 0 .../src/common/packet/SPacketEntityEquipment.java | 0 .../src/common/packet/SPacketEntityVelocity.java | 0 .../src/common/packet/SPacketHeldItemChange.java | 0 {java => common}/src/common/packet/SPacketJoinGame.java | 0 {java => common}/src/common/packet/SPacketKeepAlive.java | 0 {java => common}/src/common/packet/SPacketLoading.java | 0 .../src/common/packet/SPacketMapChunkBulk.java | 0 {java => common}/src/common/packet/SPacketMessage.java | 0 .../src/common/packet/SPacketMultiBlockChange.java | 0 .../src/common/packet/SPacketPlayerPosLook.java | 0 {java => common}/src/common/packet/SPacketRespawn.java | 0 {java => common}/src/common/packet/SPacketServerTick.java | 0 .../src/common/packet/SPacketSetExperience.java | 0 {java => common}/src/common/packet/SPacketSkin.java | 0 {java => common}/src/common/packet/SPacketSpawnMob.java | 0 {java => common}/src/common/packet/SPacketSpawnObject.java | 0 {java => common}/src/common/packet/SPacketSpawnPlayer.java | 0 {java => common}/src/common/packet/SPacketTimeUpdate.java | 0 {java => common}/src/common/packet/SPacketTrades.java | 0 .../src/common/packet/SPacketUpdateHealth.java | 0 {java => common}/src/common/packet/SPacketWorld.java | 0 {java => common}/src/common/pathfinding/NodeProcessor.java | 0 {java => common}/src/common/pathfinding/Path.java | 0 {java => common}/src/common/pathfinding/PathCache.java | 0 {java => common}/src/common/pathfinding/PathEntity.java | 0 {java => common}/src/common/pathfinding/PathFinder.java | 0 {java => common}/src/common/pathfinding/PathNavigate.java | 0 .../src/common/pathfinding/PathNavigateClimber.java | 0 .../src/common/pathfinding/PathNavigateGround.java | 0 {java => common}/src/common/pathfinding/PathPoint.java | 0 .../src/common/pathfinding/SwimNodeProcessor.java | 0 .../src/common/pathfinding/WalkNodeProcessor.java | 0 {java => common}/src/common/pattern/BlockStateHelper.java | 0 {java => common}/src/common/potion/Potion.java | 0 {java => common}/src/common/potion/PotionEffect.java | 0 {java => common}/src/common/potion/PotionHelper.java | 0 {java => common}/src/common/properties/IProperty.java | 0 {java => common}/src/common/properties/PropertyBool.java | 0 .../src/common/properties/PropertyDirection.java | 0 {java => common}/src/common/properties/PropertyEnum.java | 0 {java => common}/src/common/properties/PropertyHelper.java | 0 .../src/common/properties/PropertyInteger.java | 0 {java => common}/src/common/rng/ImprovedGen.java | 0 {java => common}/src/common/rng/ImprovedGenOld.java | 0 {java => common}/src/common/rng/NoiseGen.java | 0 {java => common}/src/common/rng/OctaveGen.java | 0 {java => common}/src/common/rng/OctaveGenOld.java | 0 {java => common}/src/common/rng/PerlinGen.java | 0 {java => common}/src/common/rng/PerlinGenOld.java | 0 {java => common}/src/common/rng/Random.java | 0 {java => common}/src/common/rng/RngItem.java | 0 {java => common}/src/common/rng/SimplexGen.java | 0 {java => common}/src/common/rng/SimplexGenOld.java | 0 {java => common}/src/common/rng/WeightedList.java | 0 {java => common}/src/common/sound/EventType.java | 0 {java => common}/src/common/sound/MovingSound.java | 0 {java => common}/src/common/sound/MovingSoundMinecart.java | 0 .../src/common/sound/MovingSoundMinecartRiding.java | 0 {java => common}/src/common/sound/PositionedSound.java | 0 {java => common}/src/common/sound/Sound.java | 0 {java => common}/src/common/tileentity/IHopper.java | 0 .../src/common/tileentity/IInteractionObject.java | 0 .../src/common/tileentity/ILockableContainer.java | 0 {java => common}/src/common/tileentity/ITickable.java | 0 {java => common}/src/common/tileentity/IWorldNameable.java | 0 .../common/tileentity/LocalBlockIntercommunication.java | 0 {java => common}/src/common/tileentity/LockCode.java | 0 .../src/common/tileentity/MachineResource.java | 0 {java => common}/src/common/tileentity/TileEntity.java | 0 .../src/common/tileentity/TileEntityBanner.java | 0 .../src/common/tileentity/TileEntityBeacon.java | 0 .../src/common/tileentity/TileEntityBrewingStand.java | 0 .../src/common/tileentity/TileEntityChest.java | 0 .../src/common/tileentity/TileEntityComparator.java | 0 .../src/common/tileentity/TileEntityDaylightDetector.java | 0 .../src/common/tileentity/TileEntityDispenser.java | 0 .../src/common/tileentity/TileEntityDropper.java | 0 .../src/common/tileentity/TileEntityEnchantmentTable.java | 0 .../src/common/tileentity/TileEntityFurnace.java | 0 .../src/common/tileentity/TileEntityHopper.java | 0 .../src/common/tileentity/TileEntityLockable.java | 0 .../src/common/tileentity/TileEntityMachine.java | 0 .../src/common/tileentity/TileEntityMobSpawner.java | 0 {java => common}/src/common/tileentity/TileEntityNote.java | 0 .../src/common/tileentity/TileEntityPiston.java | 0 {java => common}/src/common/tileentity/TileEntitySign.java | 0 .../src/common/tileentity/TileEntitySkull.java | 0 .../src/common/tileentity/TileEntityTianReactor.java | 0 {java => common}/src/common/util/CharValidator.java | 0 {java => common}/src/common/util/DC32.java | 0 {java => common}/src/common/util/Displayable.java | 0 {java => common}/src/common/util/ExtMath.java | 0 {java => common}/src/common/util/FileUtils.java | 0 {java => common}/src/common/util/Identifyable.java | 0 {java => common}/src/common/util/LazyLoadBase.java | 0 {java => common}/src/common/util/Matrix4f.java | 0 {java => common}/src/common/util/Predicates.java | 0 {java => common}/src/common/util/Tuple.java | 0 {java => common}/src/common/util/Util.java | 0 {java => common}/src/common/util/Vector.java | 0 {java => common}/src/common/util/Vector3f.java | 0 {java => common}/src/common/util/Vector4f.java | 0 {java => common}/src/common/village/MerchantRecipe.java | 0 .../src/common/village/MerchantRecipeList.java | 0 {java => common}/src/common/village/Village.java | 0 {java => common}/src/common/village/VillageCollection.java | 0 {java => common}/src/common/village/VillageDoorInfo.java | 0 {java => common}/src/common/world/BlockArray.java | 0 {java => common}/src/common/world/BlockPos.java | 0 {java => common}/src/common/world/BoundingBox.java | 0 {java => common}/src/common/world/Chunk.java | 0 {java => common}/src/common/world/ChunkCache.java | 0 {java => common}/src/common/world/ChunkPos.java | 0 .../src/common/world/ClassInheritanceMultiMap.java | 0 {java => common}/src/common/world/EmptyChunk.java | 0 {java => common}/src/common/world/Explosion.java | 0 {java => common}/src/common/world/Facing.java | 0 {java => common}/src/common/world/HitPosition.java | 0 {java => common}/src/common/world/IBlockAccess.java | 0 {java => common}/src/common/world/IWorldAccess.java | 0 {java => common}/src/common/world/IntHashMap.java | 0 {java => common}/src/common/world/LightType.java | 0 {java => common}/src/common/world/LongHashMap.java | 0 {java => common}/src/common/world/NextTickListEntry.java | 0 {java => common}/src/common/world/NibbleArray.java | 0 {java => common}/src/common/world/PortalType.java | 0 {java => common}/src/common/world/Position.java | 0 {java => common}/src/common/world/Region.java | 0 {java => common}/src/common/world/Spawner.java | 0 {java => common}/src/common/world/State.java | 0 {java => common}/src/common/world/Vec3.java | 0 {java => common}/src/common/world/Vec3i.java | 0 {java => common}/src/common/world/Weather.java | 0 {java => common}/src/common/world/World.java | 0 {java => common}/src/common/world/WorldClient.java | 0 {java => common}/src/common/world/WorldPos.java | 0 {java => common}/src/common/world/WorldServer.java | 0 {java => common}/src/common/worldgen/BiomeGenLayered.java | 0 {java => common}/src/common/worldgen/BiomeGenPerlin.java | 0 {java => common}/src/common/worldgen/BiomeGenSingle.java | 0 {java => common}/src/common/worldgen/BiomeGenerator.java | 0 {java => common}/src/common/worldgen/BlockReplacer.java | 0 {java => common}/src/common/worldgen/ChunkGenerator.java | 0 {java => common}/src/common/worldgen/ChunkPrimer.java | 0 {java => common}/src/common/worldgen/FeatureDungeons.java | 0 {java => common}/src/common/worldgen/FeatureGenerator.java | 0 {java => common}/src/common/worldgen/FeatureLakes.java | 0 {java => common}/src/common/worldgen/FeatureLiquids.java | 0 {java => common}/src/common/worldgen/FeatureOres.java | 0 {java => common}/src/common/worldgen/GeneratorCavern.java | 0 {java => common}/src/common/worldgen/GeneratorDebug.java | 0 .../src/common/worldgen/GeneratorDestroyed.java | 0 {java => common}/src/common/worldgen/GeneratorFlat.java | 0 {java => common}/src/common/worldgen/GeneratorIsland.java | 0 {java => common}/src/common/worldgen/GeneratorPerlin.java | 0 {java => common}/src/common/worldgen/GeneratorSimple.java | 0 {java => common}/src/common/worldgen/LootConstants.java | 0 {java => common}/src/common/worldgen/ReplacerAltBiome.java | 0 .../src/common/worldgen/ReplacerAltSurface.java | 0 {java => common}/src/common/worldgen/ReplacerBiome.java | 0 {java => common}/src/common/worldgen/ReplacerTopLayer.java | 0 {java => common}/src/common/worldgen/caves/MapGenBase.java | 0 .../src/common/worldgen/caves/MapGenBigCaves.java | 0 .../src/common/worldgen/caves/MapGenCaves.java | 0 .../src/common/worldgen/caves/MapGenRavine.java | 0 .../common/worldgen/feature/WorldGenAbandonedChest.java | 0 .../src/common/worldgen/feature/WorldGenAsteroid.java | 0 .../src/common/worldgen/feature/WorldGenBlockBlob.java | 0 .../src/common/worldgen/feature/WorldGenClay.java | 0 .../src/common/worldgen/feature/WorldGenClayExt.java | 0 .../src/common/worldgen/feature/WorldGenDesertWells.java | 0 .../src/common/worldgen/feature/WorldGenFire.java | 0 .../src/common/worldgen/feature/WorldGenGlowStone.java | 0 .../src/common/worldgen/feature/WorldGenHellLava.java | 0 .../src/common/worldgen/feature/WorldGenIcePath.java | 0 .../src/common/worldgen/feature/WorldGenIceSpike.java | 0 .../src/common/worldgen/feature/WorldGenSand.java | 0 .../src/common/worldgen/feature/WorldGenSpikes.java | 0 .../src/common/worldgen/foliage/FeatureDoublePlant.java | 0 .../src/common/worldgen/foliage/WorldGenBigMushroom.java | 0 .../src/common/worldgen/foliage/WorldGenCactus.java | 0 .../src/common/worldgen/foliage/WorldGenDeadBush.java | 0 .../src/common/worldgen/foliage/WorldGenFlowers.java | 0 .../src/common/worldgen/foliage/WorldGenMelon.java | 0 .../src/common/worldgen/foliage/WorldGenMushroom.java | 0 .../src/common/worldgen/foliage/WorldGenPumpkin.java | 0 .../src/common/worldgen/foliage/WorldGenReed.java | 0 .../src/common/worldgen/foliage/WorldGenShrub.java | 0 .../src/common/worldgen/foliage/WorldGenTallGrass.java | 0 .../src/common/worldgen/foliage/WorldGenVines.java | 0 .../src/common/worldgen/foliage/WorldGenWaterlily.java | 0 {java => common}/src/common/worldgen/layer/GenLayer.java | 0 .../src/common/worldgen/layer/GenLayerAddAreas.java | 0 .../src/common/worldgen/layer/GenLayerAddExtra.java | 0 .../src/common/worldgen/layer/GenLayerAddSea.java | 0 .../src/common/worldgen/layer/GenLayerAddSnow.java | 0 .../src/common/worldgen/layer/GenLayerBase.java | 0 .../src/common/worldgen/layer/GenLayerBiome.java | 0 .../src/common/worldgen/layer/GenLayerBiomeEdge.java | 0 .../src/common/worldgen/layer/GenLayerEdge.java | 0 .../src/common/worldgen/layer/GenLayerFuzzyZoom.java | 0 .../src/common/worldgen/layer/GenLayerHills.java | 0 .../src/common/worldgen/layer/GenLayerRemoveEmpty.java | 0 .../src/common/worldgen/layer/GenLayerRiver.java | 0 .../src/common/worldgen/layer/GenLayerRiverInit.java | 0 .../src/common/worldgen/layer/GenLayerRiverMix.java | 0 .../src/common/worldgen/layer/GenLayerShore.java | 0 .../src/common/worldgen/layer/GenLayerSmooth.java | 0 .../src/common/worldgen/layer/GenLayerVoronoiZoom.java | 0 .../src/common/worldgen/layer/GenLayerZoom.java | 0 {java => common}/src/common/worldgen/layer/IntCache.java | 0 .../src/common/worldgen/structure/MapGenBridge.java | 0 .../src/common/worldgen/structure/MapGenMineshaft.java | 0 .../common/worldgen/structure/MapGenScatteredFeature.java | 0 .../src/common/worldgen/structure/MapGenStronghold.java | 0 .../src/common/worldgen/structure/MapGenStructure.java | 0 .../src/common/worldgen/structure/MapGenStructureIO.java | 0 .../src/common/worldgen/structure/MapGenVillage.java | 0 .../common/worldgen/structure/StructureBoundingBox.java | 0 .../src/common/worldgen/structure/StructureBridge.java | 0 .../src/common/worldgen/structure/StructureComponent.java | 0 .../src/common/worldgen/structure/StructureMineshaft.java | 0 .../common/worldgen/structure/StructureMineshaftStart.java | 0 .../src/common/worldgen/structure/StructureScattered.java | 0 .../src/common/worldgen/structure/StructureStart.java | 0 .../src/common/worldgen/structure/StructureStronghold.java | 0 .../src/common/worldgen/structure/StructureVillage.java | 0 .../src/common/worldgen/tree/WorldGenBaseTree.java | 0 .../src/common/worldgen/tree/WorldGenBigTree.java | 0 .../src/common/worldgen/tree/WorldGenBirch.java | 0 .../src/common/worldgen/tree/WorldGenDarkOak.java | 0 .../src/common/worldgen/tree/WorldGenHugeTree.java | 0 .../src/common/worldgen/tree/WorldGenJungle.java | 0 .../src/common/worldgen/tree/WorldGenPine.java | 0 .../src/common/worldgen/tree/WorldGenSavanna.java | 0 .../src/common/worldgen/tree/WorldGenSwamp.java | 0 .../src/common/worldgen/tree/WorldGenTaiga1.java | 0 .../src/common/worldgen/tree/WorldGenTaiga2.java | 0 .../src/common/worldgen/tree/WorldGenTree.java | 0 967 files changed, 4 insertions(+), 3 deletions(-) rename {java => common}/src/common/IClient.java (100%) rename {java => common}/src/common/IServer.java (100%) rename {java => common}/src/common/ai/AIFireballAttack.java (100%) rename {java => common}/src/common/ai/AIFlyingBoxAttack.java (100%) rename {java => common}/src/common/ai/AIRangedAttack.java (100%) rename {java => common}/src/common/ai/AISmallFireballAttack.java (100%) rename {java => common}/src/common/ai/EntityAIAttackOnCollide.java (100%) rename {java => common}/src/common/ai/EntityAIAvoidEntity.java (100%) rename {java => common}/src/common/ai/EntityAIBase.java (100%) rename {java => common}/src/common/ai/EntityAIBeg.java (100%) rename {java => common}/src/common/ai/EntityAIControlledByPlayer.java (100%) rename {java => common}/src/common/ai/EntityAIDoorInteract.java (100%) rename {java => common}/src/common/ai/EntityAIEatGrass.java (100%) rename {java => common}/src/common/ai/EntityAIExplode.java (100%) rename {java => common}/src/common/ai/EntityAIFindEntityNearest.java (100%) rename {java => common}/src/common/ai/EntityAIFleeSun.java (100%) rename {java => common}/src/common/ai/EntityAIFollowOwner.java (100%) rename {java => common}/src/common/ai/EntityAIFollowParent.java (100%) rename {java => common}/src/common/ai/EntityAIHarvestFarmland.java (100%) rename {java => common}/src/common/ai/EntityAIHurtByTarget.java (100%) rename {java => common}/src/common/ai/EntityAILeapAtTarget.java (100%) rename {java => common}/src/common/ai/EntityAILookAtTalkingPlayer.java (100%) rename {java => common}/src/common/ai/EntityAILookIdle.java (100%) rename {java => common}/src/common/ai/EntityAIMate.java (100%) rename {java => common}/src/common/ai/EntityAIMoveIndoors.java (100%) rename {java => common}/src/common/ai/EntityAIMoveThroughVillage.java (100%) rename {java => common}/src/common/ai/EntityAIMoveToBlock.java (100%) rename {java => common}/src/common/ai/EntityAIMoveTowardsRestriction.java (100%) rename {java => common}/src/common/ai/EntityAIMoveTowardsTarget.java (100%) rename {java => common}/src/common/ai/EntityAINagPlayer.java (100%) rename {java => common}/src/common/ai/EntityAINearestAttackableTarget.java (100%) rename {java => common}/src/common/ai/EntityAINpcInteract.java (100%) rename {java => common}/src/common/ai/EntityAINpcMate.java (100%) rename {java => common}/src/common/ai/EntityAIOcelotAttack.java (100%) rename {java => common}/src/common/ai/EntityAIOcelotSit.java (100%) rename {java => common}/src/common/ai/EntityAIOpenDoor.java (100%) rename {java => common}/src/common/ai/EntityAIOwnerHurtByTarget.java (100%) rename {java => common}/src/common/ai/EntityAIOwnerHurtTarget.java (100%) rename {java => common}/src/common/ai/EntityAIPanic.java (100%) rename {java => common}/src/common/ai/EntityAIPlay.java (100%) rename {java => common}/src/common/ai/EntityAIRestrictOpenDoor.java (100%) rename {java => common}/src/common/ai/EntityAIRestrictSun.java (100%) rename {java => common}/src/common/ai/EntityAIRunAroundLikeCrazy.java (100%) rename {java => common}/src/common/ai/EntityAIShareItems.java (100%) rename {java => common}/src/common/ai/EntityAISit.java (100%) rename {java => common}/src/common/ai/EntityAISwimming.java (100%) rename {java => common}/src/common/ai/EntityAITakePlace.java (100%) rename {java => common}/src/common/ai/EntityAITarget.java (100%) rename {java => common}/src/common/ai/EntityAITargetNonTamed.java (100%) rename {java => common}/src/common/ai/EntityAITasks.java (100%) rename {java => common}/src/common/ai/EntityAITempt.java (100%) rename {java => common}/src/common/ai/EntityAIWander.java (100%) rename {java => common}/src/common/ai/EntityAIWatchClosest.java (100%) rename {java => common}/src/common/ai/EntityAIWatchClosest2.java (100%) rename {java => common}/src/common/ai/EntityJumpHelper.java (100%) rename {java => common}/src/common/ai/EntityLookHelper.java (100%) rename {java => common}/src/common/ai/EntityMoveHelper.java (100%) rename {java => common}/src/common/ai/EntitySenses.java (100%) rename {java => common}/src/common/ai/RandomPositionGenerator.java (100%) rename {java => common}/src/common/biome/Biome.java (100%) rename {java => common}/src/common/biome/BiomeBeach.java (100%) rename {java => common}/src/common/biome/BiomeBlackened.java (100%) rename {java => common}/src/common/biome/BiomeChaos.java (100%) rename {java => common}/src/common/biome/BiomeDesert.java (100%) rename {java => common}/src/common/biome/BiomeExterminated.java (100%) rename {java => common}/src/common/biome/BiomeForest.java (100%) rename {java => common}/src/common/biome/BiomeHell.java (100%) rename {java => common}/src/common/biome/BiomeHills.java (100%) rename {java => common}/src/common/biome/BiomeJungle.java (100%) rename {java => common}/src/common/biome/BiomeMesa.java (100%) rename {java => common}/src/common/biome/BiomeMoon.java (100%) rename {java => common}/src/common/biome/BiomeMushroom.java (100%) rename {java => common}/src/common/biome/BiomeMutated.java (100%) rename {java => common}/src/common/biome/BiomeNone.java (100%) rename {java => common}/src/common/biome/BiomePlains.java (100%) rename {java => common}/src/common/biome/BiomeSavanna.java (100%) rename {java => common}/src/common/biome/BiomeSnow.java (100%) rename {java => common}/src/common/biome/BiomeSnowLand.java (100%) rename {java => common}/src/common/biome/BiomeSpace.java (100%) rename {java => common}/src/common/biome/BiomeStoneBeach.java (100%) rename {java => common}/src/common/biome/BiomeSwamp.java (100%) rename {java => common}/src/common/biome/BiomeTaiga.java (100%) rename {java => common}/src/common/biome/BiomeTian.java (100%) rename {java => common}/src/common/biome/BiomeWater.java (100%) rename {java => common}/src/common/biome/RngSpawn.java (100%) rename {java => common}/src/common/biome/Scaling.java (100%) rename {java => common}/src/common/biome/Temperature.java (100%) rename {java => common}/src/common/block/Block.java (100%) rename {java => common}/src/common/block/BlockAir.java (100%) rename {java => common}/src/common/block/BlockAnvil.java (100%) rename {java => common}/src/common/block/BlockBanner.java (100%) rename {java => common}/src/common/block/BlockBaseFlower.java (100%) rename {java => common}/src/common/block/BlockBasePressurePlate.java (100%) rename {java => common}/src/common/block/BlockBeacon.java (100%) rename {java => common}/src/common/block/BlockBed.java (100%) rename {java => common}/src/common/block/BlockBedrock.java (100%) rename {java => common}/src/common/block/BlockBlackenedDirt.java (100%) rename {java => common}/src/common/block/BlockBlackenedSoil.java (100%) rename {java => common}/src/common/block/BlockBlackenedStone.java (100%) rename {java => common}/src/common/block/BlockBlueShroom.java (100%) rename {java => common}/src/common/block/BlockBookshelf.java (100%) rename {java => common}/src/common/block/BlockBreakable.java (100%) rename {java => common}/src/common/block/BlockBrewingStand.java (100%) rename {java => common}/src/common/block/BlockBush.java (100%) rename {java => common}/src/common/block/BlockButton.java (100%) rename {java => common}/src/common/block/BlockCactus.java (100%) rename {java => common}/src/common/block/BlockCake.java (100%) rename {java => common}/src/common/block/BlockCarpet.java (100%) rename {java => common}/src/common/block/BlockCarrot.java (100%) rename {java => common}/src/common/block/BlockCauldron.java (100%) rename {java => common}/src/common/block/BlockChest.java (100%) rename {java => common}/src/common/block/BlockClay.java (100%) rename {java => common}/src/common/block/BlockCocoa.java (100%) rename {java => common}/src/common/block/BlockColored.java (100%) rename {java => common}/src/common/block/BlockCompressedPowered.java (100%) rename {java => common}/src/common/block/BlockContainer.java (100%) rename {java => common}/src/common/block/BlockCore.java (100%) rename {java => common}/src/common/block/BlockCrops.java (100%) rename {java => common}/src/common/block/BlockDaylightDetector.java (100%) rename {java => common}/src/common/block/BlockDeadBush.java (100%) rename {java => common}/src/common/block/BlockDirectional.java (100%) rename {java => common}/src/common/block/BlockDirt.java (100%) rename {java => common}/src/common/block/BlockDispenser.java (100%) rename {java => common}/src/common/block/BlockDoor.java (100%) rename {java => common}/src/common/block/BlockDoublePlant.java (100%) rename {java => common}/src/common/block/BlockDragonEgg.java (100%) rename {java => common}/src/common/block/BlockDropper.java (100%) rename {java => common}/src/common/block/BlockDryLeaves.java (100%) rename {java => common}/src/common/block/BlockDynamicLiquid.java (100%) rename {java => common}/src/common/block/BlockEnchantmentTable.java (100%) rename {java => common}/src/common/block/BlockEventData.java (100%) rename {java => common}/src/common/block/BlockFalling.java (100%) rename {java => common}/src/common/block/BlockFarmland.java (100%) rename {java => common}/src/common/block/BlockFence.java (100%) rename {java => common}/src/common/block/BlockFenceGate.java (100%) rename {java => common}/src/common/block/BlockFire.java (100%) rename {java => common}/src/common/block/BlockFloorPortal.java (100%) rename {java => common}/src/common/block/BlockFlower.java (100%) rename {java => common}/src/common/block/BlockFlowerPot.java (100%) rename {java => common}/src/common/block/BlockFurnace.java (100%) rename {java => common}/src/common/block/BlockGlass.java (100%) rename {java => common}/src/common/block/BlockGlowstone.java (100%) rename {java => common}/src/common/block/BlockGrass.java (100%) rename {java => common}/src/common/block/BlockGravel.java (100%) rename {java => common}/src/common/block/BlockHardenedClay.java (100%) rename {java => common}/src/common/block/BlockHay.java (100%) rename {java => common}/src/common/block/BlockHellRock.java (100%) rename {java => common}/src/common/block/BlockHopper.java (100%) rename {java => common}/src/common/block/BlockHugeMushroom.java (100%) rename {java => common}/src/common/block/BlockIce.java (100%) rename {java => common}/src/common/block/BlockJukebox.java (100%) rename {java => common}/src/common/block/BlockLadder.java (100%) rename {java => common}/src/common/block/BlockLeaves.java (100%) rename {java => common}/src/common/block/BlockLeavesBase.java (100%) rename {java => common}/src/common/block/BlockLever.java (100%) rename {java => common}/src/common/block/BlockLilyPad.java (100%) rename {java => common}/src/common/block/BlockLiquid.java (100%) rename {java => common}/src/common/block/BlockLog.java (100%) rename {java => common}/src/common/block/BlockMachine.java (100%) rename {java => common}/src/common/block/BlockMelon.java (100%) rename {java => common}/src/common/block/BlockMobSpawner.java (100%) rename {java => common}/src/common/block/BlockMushroom.java (100%) rename {java => common}/src/common/block/BlockMycelium.java (100%) rename {java => common}/src/common/block/BlockNote.java (100%) rename {java => common}/src/common/block/BlockNuke.java (100%) rename {java => common}/src/common/block/BlockObsidian.java (100%) rename {java => common}/src/common/block/BlockOre.java (100%) rename {java => common}/src/common/block/BlockPackedIce.java (100%) rename {java => common}/src/common/block/BlockPane.java (100%) rename {java => common}/src/common/block/BlockPistonBase.java (100%) rename {java => common}/src/common/block/BlockPistonHead.java (100%) rename {java => common}/src/common/block/BlockPistonMoving.java (100%) rename {java => common}/src/common/block/BlockPortal.java (100%) rename {java => common}/src/common/block/BlockPortalFrame.java (100%) rename {java => common}/src/common/block/BlockPotato.java (100%) rename {java => common}/src/common/block/BlockPressurePlate.java (100%) rename {java => common}/src/common/block/BlockPressurePlateWeighted.java (100%) rename {java => common}/src/common/block/BlockPumpkin.java (100%) rename {java => common}/src/common/block/BlockQuartz.java (100%) rename {java => common}/src/common/block/BlockRail.java (100%) rename {java => common}/src/common/block/BlockRailBase.java (100%) rename {java => common}/src/common/block/BlockRailDetector.java (100%) rename {java => common}/src/common/block/BlockRailPowered.java (100%) rename {java => common}/src/common/block/BlockRedstoneComparator.java (100%) rename {java => common}/src/common/block/BlockRedstoneDiode.java (100%) rename {java => common}/src/common/block/BlockRedstoneLight.java (100%) rename {java => common}/src/common/block/BlockRedstoneOre.java (100%) rename {java => common}/src/common/block/BlockRedstoneRepeater.java (100%) rename {java => common}/src/common/block/BlockRedstoneTorch.java (100%) rename {java => common}/src/common/block/BlockRedstoneWire.java (100%) rename {java => common}/src/common/block/BlockReed.java (100%) rename {java => common}/src/common/block/BlockRock.java (100%) rename {java => common}/src/common/block/BlockRotatedPillar.java (100%) rename {java => common}/src/common/block/BlockSand.java (100%) rename {java => common}/src/common/block/BlockSandStone.java (100%) rename {java => common}/src/common/block/BlockSapling.java (100%) rename {java => common}/src/common/block/BlockSign.java (100%) rename {java => common}/src/common/block/BlockSkull.java (100%) rename {java => common}/src/common/block/BlockSlab.java (100%) rename {java => common}/src/common/block/BlockSlime.java (100%) rename {java => common}/src/common/block/BlockSnow.java (100%) rename {java => common}/src/common/block/BlockSnowBlock.java (100%) rename {java => common}/src/common/block/BlockSoulSand.java (100%) rename {java => common}/src/common/block/BlockSourceImpl.java (100%) rename {java => common}/src/common/block/BlockStainedGlass.java (100%) rename {java => common}/src/common/block/BlockStainedGlassPane.java (100%) rename {java => common}/src/common/block/BlockStairs.java (100%) rename {java => common}/src/common/block/BlockStandingSign.java (100%) rename {java => common}/src/common/block/BlockStaticLiquid.java (100%) rename {java => common}/src/common/block/BlockStem.java (100%) rename {java => common}/src/common/block/BlockStone.java (100%) rename {java => common}/src/common/block/BlockStoneBrick.java (100%) rename {java => common}/src/common/block/BlockTNT.java (100%) rename {java => common}/src/common/block/BlockTallGrass.java (100%) rename {java => common}/src/common/block/BlockTianReactor.java (100%) rename {java => common}/src/common/block/BlockTianSoil.java (100%) rename {java => common}/src/common/block/BlockTorch.java (100%) rename {java => common}/src/common/block/BlockTrapDoor.java (100%) rename {java => common}/src/common/block/BlockTreasure.java (100%) rename {java => common}/src/common/block/BlockTripWire.java (100%) rename {java => common}/src/common/block/BlockTripWireHook.java (100%) rename {java => common}/src/common/block/BlockVine.java (100%) rename {java => common}/src/common/block/BlockWall.java (100%) rename {java => common}/src/common/block/BlockWallSign.java (100%) rename {java => common}/src/common/block/BlockWarpChest.java (100%) rename {java => common}/src/common/block/BlockWart.java (100%) rename {java => common}/src/common/block/BlockWeb.java (100%) rename {java => common}/src/common/block/BlockWorkbench.java (100%) rename {java => common}/src/common/block/IGrowable.java (100%) rename {java => common}/src/common/block/ITileEntityProvider.java (100%) rename {java => common}/src/common/block/LeavesType.java (100%) rename {java => common}/src/common/block/SoundType.java (100%) rename {java => common}/src/common/clipboard/BlockTransform.java (100%) rename {java => common}/src/common/clipboard/ClipboardBlock.java (100%) rename {java => common}/src/common/clipboard/ClipboardPlacer.java (100%) rename {java => common}/src/common/clipboard/Rotation.java (100%) rename {java => common}/src/common/clipboard/RotationValue.java (100%) rename {java => common}/src/common/clipboard/Vector.java (100%) rename {java => common}/src/common/collect/AbstractBiMap.java (100%) rename {java => common}/src/common/collect/AbstractIndexedListIterator.java (100%) rename {java => common}/src/common/collect/AbstractIterator.java (100%) rename {java => common}/src/common/collect/AbstractMapEntry.java (100%) rename {java => common}/src/common/collect/AbstractTable.java (100%) rename {java => common}/src/common/collect/BiMap.java (100%) rename {java => common}/src/common/collect/CollectPreconditions.java (100%) rename {java => common}/src/common/collect/DenseImmutableTable.java (100%) rename {java => common}/src/common/collect/EmptyImmutableMap.java (100%) rename {java => common}/src/common/collect/EmptyImmutableSet.java (100%) rename {java => common}/src/common/collect/Filter.java (100%) rename {java => common}/src/common/collect/ForwardingCollection.java (100%) rename {java => common}/src/common/collect/ForwardingMap.java (100%) rename {java => common}/src/common/collect/ForwardingMapEntry.java (100%) rename {java => common}/src/common/collect/ForwardingObject.java (100%) rename {java => common}/src/common/collect/ForwardingSet.java (100%) rename {java => common}/src/common/collect/HashBiMap.java (100%) rename {java => common}/src/common/collect/Hashing.java (100%) rename {java => common}/src/common/collect/ImmutableAsList.java (100%) rename {java => common}/src/common/collect/ImmutableCollection.java (100%) rename {java => common}/src/common/collect/ImmutableEntry.java (100%) rename {java => common}/src/common/collect/ImmutableEnumMap.java (100%) rename {java => common}/src/common/collect/ImmutableEnumSet.java (100%) rename {java => common}/src/common/collect/ImmutableList.java (100%) rename {java => common}/src/common/collect/ImmutableMap.java (100%) rename {java => common}/src/common/collect/ImmutableMapEntry.java (100%) rename {java => common}/src/common/collect/ImmutableMapEntrySet.java (100%) rename {java => common}/src/common/collect/ImmutableMapKeySet.java (100%) rename {java => common}/src/common/collect/ImmutableMapValues.java (100%) rename {java => common}/src/common/collect/ImmutableSet.java (100%) rename {java => common}/src/common/collect/ImmutableTable.java (100%) rename {java => common}/src/common/collect/Iterables.java (100%) rename {java => common}/src/common/collect/Iterators.java (100%) rename {java => common}/src/common/collect/Lists.java (100%) rename {java => common}/src/common/collect/Maps.java (100%) rename {java => common}/src/common/collect/ObjectArrays.java (100%) rename {java => common}/src/common/collect/Preconditions.java (100%) rename {java => common}/src/common/collect/RegularImmutableAsList.java (100%) rename {java => common}/src/common/collect/RegularImmutableList.java (100%) rename {java => common}/src/common/collect/RegularImmutableMap.java (100%) rename {java => common}/src/common/collect/RegularImmutableSet.java (100%) rename {java => common}/src/common/collect/RegularImmutableTable.java (100%) rename {java => common}/src/common/collect/Sets.java (100%) rename {java => common}/src/common/collect/SparseImmutableTable.java (100%) rename {java => common}/src/common/collect/StandardTable.java (100%) rename {java => common}/src/common/collect/Table.java (100%) rename {java => common}/src/common/collect/TransformedIterator.java (100%) rename {java => common}/src/common/collect/UnmodifiableIterator.java (100%) rename {java => common}/src/common/collect/UnmodifiableListIterator.java (100%) rename {java => common}/src/common/color/Colorizer.java (100%) rename {java => common}/src/common/color/DyeColor.java (100%) rename {java => common}/src/common/color/TextColor.java (100%) rename {java => common}/src/common/dimension/Area.java (100%) rename {java => common}/src/common/dimension/DimType.java (100%) rename {java => common}/src/common/dimension/Dimension.java (100%) rename {java => common}/src/common/dimension/Domain.java (100%) rename {java => common}/src/common/dimension/Galaxy.java (100%) rename {java => common}/src/common/dimension/Moon.java (100%) rename {java => common}/src/common/dimension/Nameable.java (100%) rename {java => common}/src/common/dimension/Planet.java (100%) rename {java => common}/src/common/dimension/Sector.java (100%) rename {java => common}/src/common/dimension/Semi.java (100%) rename {java => common}/src/common/dimension/Space.java (100%) rename {java => common}/src/common/dimension/Star.java (100%) rename {java => common}/src/common/dispenser/BehaviorDefaultDispenseItem.java (100%) rename {java => common}/src/common/dispenser/BehaviorProjectileDispense.java (100%) rename {java => common}/src/common/dispenser/IBehaviorDispenseItem.java (100%) rename {java => common}/src/common/dispenser/IBlockSource.java (100%) rename {java => common}/src/common/dispenser/ILocatableSource.java (100%) rename {java => common}/src/common/dispenser/ILocation.java (100%) rename {java => common}/src/common/dispenser/IPosition.java (100%) rename {java => common}/src/common/dispenser/PositionImpl.java (100%) rename {java => common}/src/common/enchantment/Enchantment.java (100%) rename {java => common}/src/common/enchantment/EnchantmentArrowDamage.java (100%) rename {java => common}/src/common/enchantment/EnchantmentArrowFire.java (100%) rename {java => common}/src/common/enchantment/EnchantmentArrowInfinite.java (100%) rename {java => common}/src/common/enchantment/EnchantmentArrowKnockback.java (100%) rename {java => common}/src/common/enchantment/EnchantmentDamage.java (100%) rename {java => common}/src/common/enchantment/EnchantmentDigging.java (100%) rename {java => common}/src/common/enchantment/EnchantmentDraining.java (100%) rename {java => common}/src/common/enchantment/EnchantmentDurability.java (100%) rename {java => common}/src/common/enchantment/EnchantmentFireAspect.java (100%) rename {java => common}/src/common/enchantment/EnchantmentFishingSpeed.java (100%) rename {java => common}/src/common/enchantment/EnchantmentHelper.java (100%) rename {java => common}/src/common/enchantment/EnchantmentKnockback.java (100%) rename {java => common}/src/common/enchantment/EnchantmentLootBonus.java (100%) rename {java => common}/src/common/enchantment/EnchantmentProtection.java (100%) rename {java => common}/src/common/enchantment/EnchantmentThorns.java (100%) rename {java => common}/src/common/enchantment/EnchantmentUntouching.java (100%) rename {java => common}/src/common/enchantment/EnumEnchantmentType.java (100%) rename {java => common}/src/common/enchantment/RngEnchantment.java (100%) rename {java => common}/src/common/entity/DamageSource.java (100%) rename {java => common}/src/common/entity/DataWatcher.java (100%) rename {java => common}/src/common/entity/Entity.java (100%) rename {java => common}/src/common/entity/EntityDamageSource.java (100%) rename {java => common}/src/common/entity/EntityDamageSourceIndirect.java (100%) rename {java => common}/src/common/entity/EntityTrackerEntry.java (100%) rename {java => common}/src/common/entity/EntityType.java (100%) rename {java => common}/src/common/entity/animal/EntityBat.java (100%) rename {java => common}/src/common/entity/animal/EntityChicken.java (100%) rename {java => common}/src/common/entity/animal/EntityCow.java (100%) rename {java => common}/src/common/entity/animal/EntityDragon.java (100%) rename {java => common}/src/common/entity/animal/EntityDragonPart.java (100%) rename {java => common}/src/common/entity/animal/EntityHorse.java (100%) rename {java => common}/src/common/entity/animal/EntityMooshroom.java (100%) rename {java => common}/src/common/entity/animal/EntityMouse.java (100%) rename {java => common}/src/common/entity/animal/EntityOcelot.java (100%) rename {java => common}/src/common/entity/animal/EntityPig.java (100%) rename {java => common}/src/common/entity/animal/EntityRabbit.java (100%) rename {java => common}/src/common/entity/animal/EntitySheep.java (100%) rename {java => common}/src/common/entity/animal/EntitySquid.java (100%) rename {java => common}/src/common/entity/animal/EntityWolf.java (100%) rename {java => common}/src/common/entity/attributes/Attribute.java (100%) rename {java => common}/src/common/entity/attributes/AttributeInstance.java (100%) rename {java => common}/src/common/entity/attributes/AttributeMap.java (100%) rename {java => common}/src/common/entity/attributes/AttributeModifier.java (100%) rename {java => common}/src/common/entity/attributes/Attributes.java (100%) rename {java => common}/src/common/entity/attributes/LowerStringMap.java (100%) rename {java => common}/src/common/entity/effect/EntityLightning.java (100%) rename {java => common}/src/common/entity/item/EntityBoat.java (100%) rename {java => common}/src/common/entity/item/EntityCart.java (100%) rename {java => common}/src/common/entity/item/EntityCartContainer.java (100%) rename {java => common}/src/common/entity/item/EntityChestCart.java (100%) rename {java => common}/src/common/entity/item/EntityCrystal.java (100%) rename {java => common}/src/common/entity/item/EntityExplosion.java (100%) rename {java => common}/src/common/entity/item/EntityFalling.java (100%) rename {java => common}/src/common/entity/item/EntityFireworks.java (100%) rename {java => common}/src/common/entity/item/EntityHopperCart.java (100%) rename {java => common}/src/common/entity/item/EntityItem.java (100%) rename {java => common}/src/common/entity/item/EntityLeashKnot.java (100%) rename {java => common}/src/common/entity/item/EntityMinecart.java (100%) rename {java => common}/src/common/entity/item/EntityNuke.java (100%) rename {java => common}/src/common/entity/item/EntityOrb.java (100%) rename {java => common}/src/common/entity/item/EntityTnt.java (100%) rename {java => common}/src/common/entity/item/EntityTntCart.java (100%) rename {java => common}/src/common/entity/item/EntityXp.java (100%) rename {java => common}/src/common/entity/item/EntityXpBottle.java (100%) rename {java => common}/src/common/entity/npc/Alignment.java (100%) rename {java => common}/src/common/entity/npc/CharacterInfo.java (100%) rename {java => common}/src/common/entity/npc/ClassInfo.java (100%) rename {java => common}/src/common/entity/npc/Energy.java (100%) rename {java => common}/src/common/entity/npc/EntityArachnoid.java (100%) rename {java => common}/src/common/entity/npc/EntityBloodElf.java (100%) rename {java => common}/src/common/entity/npc/EntityChaosMarine.java (100%) rename {java => common}/src/common/entity/npc/EntityCpu.java (100%) rename {java => common}/src/common/entity/npc/EntityCultivator.java (100%) rename {java => common}/src/common/entity/npc/EntityDarkMage.java (100%) rename {java => common}/src/common/entity/npc/EntityDwarf.java (100%) rename {java => common}/src/common/entity/npc/EntityElf.java (100%) rename {java => common}/src/common/entity/npc/EntityFireDemon.java (100%) rename {java => common}/src/common/entity/npc/EntityFlyingNPC.java (100%) rename {java => common}/src/common/entity/npc/EntityGargoyle.java (100%) rename {java => common}/src/common/entity/npc/EntityGoblin.java (100%) rename {java => common}/src/common/entity/npc/EntityHaunter.java (100%) rename {java => common}/src/common/entity/npc/EntityHoveringNPC.java (100%) rename {java => common}/src/common/entity/npc/EntityHuman.java (100%) rename {java => common}/src/common/entity/npc/EntityMage.java (100%) rename {java => common}/src/common/entity/npc/EntityMagma.java (100%) rename {java => common}/src/common/entity/npc/EntityMetalhead.java (100%) rename {java => common}/src/common/entity/npc/EntityMobNPC.java (100%) rename {java => common}/src/common/entity/npc/EntityNPC.java (100%) rename {java => common}/src/common/entity/npc/EntityOrc.java (100%) rename {java => common}/src/common/entity/npc/EntityPrimarch.java (100%) rename {java => common}/src/common/entity/npc/EntitySlime.java (100%) rename {java => common}/src/common/entity/npc/EntitySpaceMarine.java (100%) rename {java => common}/src/common/entity/npc/EntitySpirit.java (100%) rename {java => common}/src/common/entity/npc/EntityTiefling.java (100%) rename {java => common}/src/common/entity/npc/EntityUndead.java (100%) rename {java => common}/src/common/entity/npc/EntityVampire.java (100%) rename {java => common}/src/common/entity/npc/EntityWoodElf.java (100%) rename {java => common}/src/common/entity/npc/EntityZombie.java (100%) rename {java => common}/src/common/entity/npc/NpcInfo.java (100%) rename {java => common}/src/common/entity/npc/PlayerCharacter.java (100%) rename {java => common}/src/common/entity/npc/SpeciesInfo.java (100%) rename {java => common}/src/common/entity/projectile/EntityArrow.java (100%) rename {java => common}/src/common/entity/projectile/EntityBox.java (100%) rename {java => common}/src/common/entity/projectile/EntityBullet.java (100%) rename {java => common}/src/common/entity/projectile/EntityDie.java (100%) rename {java => common}/src/common/entity/projectile/EntityDynamite.java (100%) rename {java => common}/src/common/entity/projectile/EntityEgg.java (100%) rename {java => common}/src/common/entity/projectile/EntityFireCharge.java (100%) rename {java => common}/src/common/entity/projectile/EntityFireball.java (100%) rename {java => common}/src/common/entity/projectile/EntityHook.java (100%) rename {java => common}/src/common/entity/projectile/EntityPotion.java (100%) rename {java => common}/src/common/entity/projectile/EntityProjectile.java (100%) rename {java => common}/src/common/entity/projectile/EntitySnowball.java (100%) rename {java => common}/src/common/entity/projectile/RngFishable.java (100%) rename {java => common}/src/common/entity/types/CombatEntry.java (100%) rename {java => common}/src/common/entity/types/EntityAnimal.java (100%) rename {java => common}/src/common/entity/types/EntityBodyHelper.java (100%) rename {java => common}/src/common/entity/types/EntityLiving.java (100%) rename {java => common}/src/common/entity/types/EntityTameable.java (100%) rename {java => common}/src/common/entity/types/EntityThrowable.java (100%) rename {java => common}/src/common/entity/types/EntityWaterMob.java (100%) rename {java => common}/src/common/entity/types/EntityWeatherEffect.java (100%) rename {java => common}/src/common/entity/types/IEntityFX.java (100%) rename {java => common}/src/common/entity/types/IEntityMultiPart.java (100%) rename {java => common}/src/common/entity/types/IEntityOwnable.java (100%) rename {java => common}/src/common/entity/types/IObjectData.java (100%) rename {java => common}/src/common/entity/types/IProjectile.java (100%) rename {java => common}/src/common/future/AbstractFuture.java (100%) rename {java => common}/src/common/future/ExecutionError.java (100%) rename {java => common}/src/common/future/ExecutionList.java (100%) rename {java => common}/src/common/future/FutureCallback.java (100%) rename {java => common}/src/common/future/Futures.java (100%) rename {java => common}/src/common/future/ListenableFuture.java (100%) rename {java => common}/src/common/future/ListenableFutureTask.java (100%) rename {java => common}/src/common/future/MoreExecutors.java (100%) rename {java => common}/src/common/future/ThreadFactoryBuilder.java (100%) rename {java => common}/src/common/future/UncheckedExecutionException.java (100%) rename {java => common}/src/common/init/BlockRegistry.java (100%) rename {java => common}/src/common/init/Blocks.java (100%) rename {java => common}/src/common/init/Config.java (100%) rename {java => common}/src/common/init/CraftingRegistry.java (100%) rename {java => common}/src/common/init/DecoType.java (100%) rename {java => common}/src/common/init/DispenserRegistry.java (100%) rename {java => common}/src/common/init/EntityEggInfo.java (100%) rename {java => common}/src/common/init/EntityRegistry.java (100%) rename {java => common}/src/common/init/FlammabilityRegistry.java (100%) rename {java => common}/src/common/init/FluidRegistry.java (100%) rename {java => common}/src/common/init/IObjectIntIterable.java (100%) rename {java => common}/src/common/init/IRegistry.java (100%) rename {java => common}/src/common/init/ItemRegistry.java (100%) rename {java => common}/src/common/init/Items.java (100%) rename {java => common}/src/common/init/MetalType.java (100%) rename {java => common}/src/common/init/NameRegistry.java (100%) rename {java => common}/src/common/init/ObjectIntIdentityMap.java (100%) rename {java => common}/src/common/init/OreType.java (100%) rename {java => common}/src/common/init/Registry.java (100%) rename {java => common}/src/common/init/RegistryDefaulted.java (100%) rename {java => common}/src/common/init/RegistryNamespaced.java (100%) rename {java => common}/src/common/init/RegistryNamespacedDefaultedByKey.java (100%) rename {java => common}/src/common/init/RegistrySimple.java (100%) rename {java => common}/src/common/init/ReorderRegistry.java (100%) rename {java => common}/src/common/init/RotationRegistry.java (100%) rename {java => common}/src/common/init/SmeltingRegistry.java (100%) rename {java => common}/src/common/init/SoundEvent.java (100%) rename {java => common}/src/common/init/SpeciesRegistry.java (100%) rename {java => common}/src/common/init/TileRegistry.java (100%) rename {java => common}/src/common/init/ToolMaterial.java (100%) rename {java => common}/src/common/init/ToolType.java (100%) rename {java => common}/src/common/init/TradeRegistry.java (100%) rename {java => common}/src/common/init/UniverseRegistry.java (100%) rename {java => common}/src/common/init/WoodType.java (100%) rename {java => common}/src/common/inventory/AnimalChest.java (100%) rename {java => common}/src/common/inventory/Container.java (100%) rename {java => common}/src/common/inventory/ContainerBrewingStand.java (100%) rename {java => common}/src/common/inventory/ContainerChest.java (100%) rename {java => common}/src/common/inventory/ContainerDispenser.java (100%) rename {java => common}/src/common/inventory/ContainerEnchantment.java (100%) rename {java => common}/src/common/inventory/ContainerFurnace.java (100%) rename {java => common}/src/common/inventory/ContainerHopper.java (100%) rename {java => common}/src/common/inventory/ContainerHorseInventory.java (100%) rename {java => common}/src/common/inventory/ContainerLocalMenu.java (100%) rename {java => common}/src/common/inventory/ContainerMachine.java (100%) rename {java => common}/src/common/inventory/ContainerMerchant.java (100%) rename {java => common}/src/common/inventory/ContainerPlayer.java (100%) rename {java => common}/src/common/inventory/ContainerRepair.java (100%) rename {java => common}/src/common/inventory/ContainerWorkbench.java (100%) rename {java => common}/src/common/inventory/ICrafting.java (100%) rename {java => common}/src/common/inventory/IInvBasic.java (100%) rename {java => common}/src/common/inventory/IInventory.java (100%) rename {java => common}/src/common/inventory/ISidedInventory.java (100%) rename {java => common}/src/common/inventory/InventoryBasic.java (100%) rename {java => common}/src/common/inventory/InventoryCraftResult.java (100%) rename {java => common}/src/common/inventory/InventoryCrafting.java (100%) rename {java => common}/src/common/inventory/InventoryHelper.java (100%) rename {java => common}/src/common/inventory/InventoryLargeChest.java (100%) rename {java => common}/src/common/inventory/InventoryMerchant.java (100%) rename {java => common}/src/common/inventory/InventoryPlayer.java (100%) rename {java => common}/src/common/inventory/InventoryWarpChest.java (100%) rename {java => common}/src/common/inventory/Slot.java (100%) rename {java => common}/src/common/inventory/SlotCrafting.java (100%) rename {java => common}/src/common/inventory/SlotFurnaceFuel.java (100%) rename {java => common}/src/common/inventory/SlotFurnaceOutput.java (100%) rename {java => common}/src/common/inventory/SlotMerchantResult.java (100%) rename {java => common}/src/common/item/CheatTab.java (100%) rename {java => common}/src/common/item/Item.java (100%) rename {java => common}/src/common/item/ItemAction.java (100%) rename {java => common}/src/common/item/ItemAmmo.java (100%) rename {java => common}/src/common/item/ItemAnvilBlock.java (100%) rename {java => common}/src/common/item/ItemAppleGold.java (100%) rename {java => common}/src/common/item/ItemArmor.java (100%) rename {java => common}/src/common/item/ItemAxe.java (100%) rename {java => common}/src/common/item/ItemBanHammer.java (100%) rename {java => common}/src/common/item/ItemBanner.java (100%) rename {java => common}/src/common/item/ItemBed.java (100%) rename {java => common}/src/common/item/ItemBlock.java (100%) rename {java => common}/src/common/item/ItemBoat.java (100%) rename {java => common}/src/common/item/ItemBoltgun.java (100%) rename {java => common}/src/common/item/ItemBook.java (100%) rename {java => common}/src/common/item/ItemBow.java (100%) rename {java => common}/src/common/item/ItemBucket.java (100%) rename {java => common}/src/common/item/ItemBucketMilk.java (100%) rename {java => common}/src/common/item/ItemButton.java (100%) rename {java => common}/src/common/item/ItemCamera.java (100%) rename {java => common}/src/common/item/ItemCarrotOnAStick.java (100%) rename {java => common}/src/common/item/ItemChargedOrb.java (100%) rename {java => common}/src/common/item/ItemChest.java (100%) rename {java => common}/src/common/item/ItemCloth.java (100%) rename {java => common}/src/common/item/ItemCoal.java (100%) rename {java => common}/src/common/item/ItemColored.java (100%) rename {java => common}/src/common/item/ItemControl.java (100%) rename {java => common}/src/common/item/ItemDie.java (100%) rename {java => common}/src/common/item/ItemDispenser.java (100%) rename {java => common}/src/common/item/ItemDoor.java (100%) rename {java => common}/src/common/item/ItemDoublePlant.java (100%) rename {java => common}/src/common/item/ItemDye.java (100%) rename {java => common}/src/common/item/ItemDynamite.java (100%) rename {java => common}/src/common/item/ItemEditWand.java (100%) rename {java => common}/src/common/item/ItemEffect.java (100%) rename {java => common}/src/common/item/ItemEgg.java (100%) rename {java => common}/src/common/item/ItemEnchantedBook.java (100%) rename {java => common}/src/common/item/ItemExpBottle.java (100%) rename {java => common}/src/common/item/ItemExterminator.java (100%) rename {java => common}/src/common/item/ItemFence.java (100%) rename {java => common}/src/common/item/ItemFireball.java (100%) rename {java => common}/src/common/item/ItemFirework.java (100%) rename {java => common}/src/common/item/ItemFireworkCharge.java (100%) rename {java => common}/src/common/item/ItemFishFood.java (100%) rename {java => common}/src/common/item/ItemFishingRod.java (100%) rename {java => common}/src/common/item/ItemFlintAndSteel.java (100%) rename {java => common}/src/common/item/ItemFood.java (100%) rename {java => common}/src/common/item/ItemFragile.java (100%) rename {java => common}/src/common/item/ItemGlassBottle.java (100%) rename {java => common}/src/common/item/ItemGunBase.java (100%) rename {java => common}/src/common/item/ItemHoe.java (100%) rename {java => common}/src/common/item/ItemHorseArmor.java (100%) rename {java => common}/src/common/item/ItemHugeMushroom.java (100%) rename {java => common}/src/common/item/ItemInfoWand.java (100%) rename {java => common}/src/common/item/ItemKey.java (100%) rename {java => common}/src/common/item/ItemLead.java (100%) rename {java => common}/src/common/item/ItemLeaves.java (100%) rename {java => common}/src/common/item/ItemLightning.java (100%) rename {java => common}/src/common/item/ItemLilyPad.java (100%) rename {java => common}/src/common/item/ItemMagnet.java (100%) rename {java => common}/src/common/item/ItemMagnetic.java (100%) rename {java => common}/src/common/item/ItemMetal.java (100%) rename {java => common}/src/common/item/ItemMetalBlock.java (100%) rename {java => common}/src/common/item/ItemMinecart.java (100%) rename {java => common}/src/common/item/ItemMonsterPlacer.java (100%) rename {java => common}/src/common/item/ItemMultiTexture.java (100%) rename {java => common}/src/common/item/ItemNameTag.java (100%) rename {java => common}/src/common/item/ItemNpcSpawner.java (100%) rename {java => common}/src/common/item/ItemNugget.java (100%) rename {java => common}/src/common/item/ItemPickaxe.java (100%) rename {java => common}/src/common/item/ItemPiston.java (100%) rename {java => common}/src/common/item/ItemPotion.java (100%) rename {java => common}/src/common/item/ItemPressurePlate.java (100%) rename {java => common}/src/common/item/ItemRecord.java (100%) rename {java => common}/src/common/item/ItemRedstone.java (100%) rename {java => common}/src/common/item/ItemReed.java (100%) rename {java => common}/src/common/item/ItemRod.java (100%) rename {java => common}/src/common/item/ItemSaddle.java (100%) rename {java => common}/src/common/item/ItemSeedFood.java (100%) rename {java => common}/src/common/item/ItemSeeds.java (100%) rename {java => common}/src/common/item/ItemShears.java (100%) rename {java => common}/src/common/item/ItemSign.java (100%) rename {java => common}/src/common/item/ItemSkull.java (100%) rename {java => common}/src/common/item/ItemSlab.java (100%) rename {java => common}/src/common/item/ItemSmall.java (100%) rename {java => common}/src/common/item/ItemSnow.java (100%) rename {java => common}/src/common/item/ItemSnowball.java (100%) rename {java => common}/src/common/item/ItemSoup.java (100%) rename {java => common}/src/common/item/ItemSpaceNavigator.java (100%) rename {java => common}/src/common/item/ItemSpade.java (100%) rename {java => common}/src/common/item/ItemStack.java (100%) rename {java => common}/src/common/item/ItemStick.java (100%) rename {java => common}/src/common/item/ItemSword.java (100%) rename {java => common}/src/common/item/ItemTNT.java (100%) rename {java => common}/src/common/item/ItemTiny.java (100%) rename {java => common}/src/common/item/ItemTool.java (100%) rename {java => common}/src/common/item/ItemWall.java (100%) rename {java => common}/src/common/item/ItemWand.java (100%) rename {java => common}/src/common/item/ItemWeatherToken.java (100%) rename {java => common}/src/common/item/RngLoot.java (100%) rename {java => common}/src/common/log/Log.java (100%) rename {java => common}/src/common/log/LogLevel.java (100%) rename {java => common}/src/common/log/Message.java (100%) rename {java => common}/src/common/log/NettyLogger.java (100%) rename {java => common}/src/common/material/Material.java (100%) rename {java => common}/src/common/material/MaterialColdFluid.java (100%) rename {java => common}/src/common/material/MaterialHotFluid.java (100%) rename {java => common}/src/common/material/MaterialLogic.java (100%) rename {java => common}/src/common/material/MaterialPortal.java (100%) rename {java => common}/src/common/material/MaterialTransparent.java (100%) rename {java => common}/src/common/model/BlockLayer.java (100%) rename {java => common}/src/common/model/ItemMeshDefinition.java (100%) rename {java => common}/src/common/model/Model.java (100%) rename {java => common}/src/common/model/ModelProvider.java (100%) rename {java => common}/src/common/model/ModelRotation.java (100%) rename {java => common}/src/common/model/ParticleType.java (100%) rename {java => common}/src/common/model/Transform.java (100%) rename {java => common}/src/common/model/Transforms.java (100%) rename {java => common}/src/common/nbt/NBTBase.java (100%) rename {java => common}/src/common/nbt/NBTException.java (100%) rename {java => common}/src/common/nbt/NBTLoader.java (100%) rename {java => common}/src/common/nbt/NBTParser.java (100%) rename {java => common}/src/common/nbt/NBTSizeTracker.java (100%) rename {java => common}/src/common/nbt/NBTTagByte.java (100%) rename {java => common}/src/common/nbt/NBTTagByteArray.java (100%) rename {java => common}/src/common/nbt/NBTTagCompound.java (100%) rename {java => common}/src/common/nbt/NBTTagDouble.java (100%) rename {java => common}/src/common/nbt/NBTTagEnd.java (100%) rename {java => common}/src/common/nbt/NBTTagFloat.java (100%) rename {java => common}/src/common/nbt/NBTTagInt.java (100%) rename {java => common}/src/common/nbt/NBTTagIntArray.java (100%) rename {java => common}/src/common/nbt/NBTTagList.java (100%) rename {java => common}/src/common/nbt/NBTTagLong.java (100%) rename {java => common}/src/common/nbt/NBTTagShort.java (100%) rename {java => common}/src/common/nbt/NBTTagString.java (100%) rename {java => common}/src/common/nbt/NBTUtil.java (100%) rename {java => common}/src/common/network/IClientLoginHandler.java (100%) rename {java => common}/src/common/network/IClientPlayer.java (100%) rename {java => common}/src/common/network/IHandshakeHandler.java (100%) rename {java => common}/src/common/network/ILoginHandler.java (100%) rename {java => common}/src/common/network/IPlayer.java (100%) rename {java => common}/src/common/network/IThreadListener.java (100%) rename {java => common}/src/common/network/NetConnection.java (100%) rename {java => common}/src/common/network/NetHandler.java (100%) rename {java => common}/src/common/network/NettyCompressionDecoder.java (100%) rename {java => common}/src/common/network/NettyCompressionEncoder.java (100%) rename {java => common}/src/common/network/Packet.java (100%) rename {java => common}/src/common/network/PacketBuffer.java (100%) rename {java => common}/src/common/network/PacketDecoder.java (100%) rename {java => common}/src/common/network/PacketEncoder.java (100%) rename {java => common}/src/common/network/PacketPrepender.java (100%) rename {java => common}/src/common/network/PacketRegistry.java (100%) rename {java => common}/src/common/network/PacketSplitter.java (100%) rename {java => common}/src/common/packet/APacketEmpty.java (100%) rename {java => common}/src/common/packet/APacketVarInt.java (100%) rename {java => common}/src/common/packet/CPacketAction.java (100%) rename {java => common}/src/common/packet/CPacketBook.java (100%) rename {java => common}/src/common/packet/CPacketBreak.java (100%) rename {java => common}/src/common/packet/CPacketCheat.java (100%) rename {java => common}/src/common/packet/CPacketClick.java (100%) rename {java => common}/src/common/packet/CPacketComplete.java (100%) rename {java => common}/src/common/packet/CPacketInput.java (100%) rename {java => common}/src/common/packet/CPacketKeepAlive.java (100%) rename {java => common}/src/common/packet/CPacketMessage.java (100%) rename {java => common}/src/common/packet/CPacketPlace.java (100%) rename {java => common}/src/common/packet/CPacketPlayer.java (100%) rename {java => common}/src/common/packet/CPacketSign.java (100%) rename {java => common}/src/common/packet/CPacketSkin.java (100%) rename {java => common}/src/common/packet/HPacketHandshake.java (100%) rename {java => common}/src/common/packet/LPacketPasswordResponse.java (100%) rename {java => common}/src/common/packet/RPacketDisconnect.java (100%) rename {java => common}/src/common/packet/RPacketEnableCompression.java (100%) rename {java => common}/src/common/packet/RPacketLoginSuccess.java (100%) rename {java => common}/src/common/packet/S14PacketEntity.java (100%) rename {java => common}/src/common/packet/S18PacketEntityTeleport.java (100%) rename {java => common}/src/common/packet/S19PacketEntityHeadLook.java (100%) rename {java => common}/src/common/packet/S1APacketEntityStatus.java (100%) rename {java => common}/src/common/packet/S1BPacketEntityAttach.java (100%) rename {java => common}/src/common/packet/S1CPacketEntityMetadata.java (100%) rename {java => common}/src/common/packet/S1DPacketEntityEffect.java (100%) rename {java => common}/src/common/packet/S1EPacketRemoveEntityEffect.java (100%) rename {java => common}/src/common/packet/S20PacketEntityProperties.java (100%) rename {java => common}/src/common/packet/S27PacketExplosion.java (100%) rename {java => common}/src/common/packet/S28PacketEffect.java (100%) rename {java => common}/src/common/packet/S29PacketSoundEffect.java (100%) rename {java => common}/src/common/packet/S2APacketParticles.java (100%) rename {java => common}/src/common/packet/S2BPacketChangeGameState.java (100%) rename {java => common}/src/common/packet/S2CPacketSpawnGlobalEntity.java (100%) rename {java => common}/src/common/packet/S2DPacketOpenWindow.java (100%) rename {java => common}/src/common/packet/S2EPacketCloseWindow.java (100%) rename {java => common}/src/common/packet/S2FPacketSetSlot.java (100%) rename {java => common}/src/common/packet/S30PacketWindowItems.java (100%) rename {java => common}/src/common/packet/S31PacketWindowProperty.java (100%) rename {java => common}/src/common/packet/S32PacketConfirmTransaction.java (100%) rename {java => common}/src/common/packet/S33PacketUpdateSign.java (100%) rename {java => common}/src/common/packet/S35PacketUpdateTileEntity.java (100%) rename {java => common}/src/common/packet/S36PacketSignEditorOpen.java (100%) rename {java => common}/src/common/packet/S38PacketPlayerListItem.java (100%) rename {java => common}/src/common/packet/S39PacketPlayerAbilities.java (100%) rename {java => common}/src/common/packet/S3APacketTabComplete.java (100%) rename {java => common}/src/common/packet/S43PacketUpdateEntityNBT.java (100%) rename {java => common}/src/common/packet/SPacketAnimation.java (100%) rename {java => common}/src/common/packet/SPacketBiomes.java (100%) rename {java => common}/src/common/packet/SPacketBlockAction.java (100%) rename {java => common}/src/common/packet/SPacketBlockBreakAnim.java (100%) rename {java => common}/src/common/packet/SPacketBlockChange.java (100%) rename {java => common}/src/common/packet/SPacketCamera.java (100%) rename {java => common}/src/common/packet/SPacketCharacterList.java (100%) rename {java => common}/src/common/packet/SPacketChunkData.java (100%) rename {java => common}/src/common/packet/SPacketCollectItem.java (100%) rename {java => common}/src/common/packet/SPacketDestroyEntities.java (100%) rename {java => common}/src/common/packet/SPacketDimensionName.java (100%) rename {java => common}/src/common/packet/SPacketDisconnect.java (100%) rename {java => common}/src/common/packet/SPacketEntityEquipment.java (100%) rename {java => common}/src/common/packet/SPacketEntityVelocity.java (100%) rename {java => common}/src/common/packet/SPacketHeldItemChange.java (100%) rename {java => common}/src/common/packet/SPacketJoinGame.java (100%) rename {java => common}/src/common/packet/SPacketKeepAlive.java (100%) rename {java => common}/src/common/packet/SPacketLoading.java (100%) rename {java => common}/src/common/packet/SPacketMapChunkBulk.java (100%) rename {java => common}/src/common/packet/SPacketMessage.java (100%) rename {java => common}/src/common/packet/SPacketMultiBlockChange.java (100%) rename {java => common}/src/common/packet/SPacketPlayerPosLook.java (100%) rename {java => common}/src/common/packet/SPacketRespawn.java (100%) rename {java => common}/src/common/packet/SPacketServerTick.java (100%) rename {java => common}/src/common/packet/SPacketSetExperience.java (100%) rename {java => common}/src/common/packet/SPacketSkin.java (100%) rename {java => common}/src/common/packet/SPacketSpawnMob.java (100%) rename {java => common}/src/common/packet/SPacketSpawnObject.java (100%) rename {java => common}/src/common/packet/SPacketSpawnPlayer.java (100%) rename {java => common}/src/common/packet/SPacketTimeUpdate.java (100%) rename {java => common}/src/common/packet/SPacketTrades.java (100%) rename {java => common}/src/common/packet/SPacketUpdateHealth.java (100%) rename {java => common}/src/common/packet/SPacketWorld.java (100%) rename {java => common}/src/common/pathfinding/NodeProcessor.java (100%) rename {java => common}/src/common/pathfinding/Path.java (100%) rename {java => common}/src/common/pathfinding/PathCache.java (100%) rename {java => common}/src/common/pathfinding/PathEntity.java (100%) rename {java => common}/src/common/pathfinding/PathFinder.java (100%) rename {java => common}/src/common/pathfinding/PathNavigate.java (100%) rename {java => common}/src/common/pathfinding/PathNavigateClimber.java (100%) rename {java => common}/src/common/pathfinding/PathNavigateGround.java (100%) rename {java => common}/src/common/pathfinding/PathPoint.java (100%) rename {java => common}/src/common/pathfinding/SwimNodeProcessor.java (100%) rename {java => common}/src/common/pathfinding/WalkNodeProcessor.java (100%) rename {java => common}/src/common/pattern/BlockStateHelper.java (100%) rename {java => common}/src/common/potion/Potion.java (100%) rename {java => common}/src/common/potion/PotionEffect.java (100%) rename {java => common}/src/common/potion/PotionHelper.java (100%) rename {java => common}/src/common/properties/IProperty.java (100%) rename {java => common}/src/common/properties/PropertyBool.java (100%) rename {java => common}/src/common/properties/PropertyDirection.java (100%) rename {java => common}/src/common/properties/PropertyEnum.java (100%) rename {java => common}/src/common/properties/PropertyHelper.java (100%) rename {java => common}/src/common/properties/PropertyInteger.java (100%) rename {java => common}/src/common/rng/ImprovedGen.java (100%) rename {java => common}/src/common/rng/ImprovedGenOld.java (100%) rename {java => common}/src/common/rng/NoiseGen.java (100%) rename {java => common}/src/common/rng/OctaveGen.java (100%) rename {java => common}/src/common/rng/OctaveGenOld.java (100%) rename {java => common}/src/common/rng/PerlinGen.java (100%) rename {java => common}/src/common/rng/PerlinGenOld.java (100%) rename {java => common}/src/common/rng/Random.java (100%) rename {java => common}/src/common/rng/RngItem.java (100%) rename {java => common}/src/common/rng/SimplexGen.java (100%) rename {java => common}/src/common/rng/SimplexGenOld.java (100%) rename {java => common}/src/common/rng/WeightedList.java (100%) rename {java => common}/src/common/sound/EventType.java (100%) rename {java => common}/src/common/sound/MovingSound.java (100%) rename {java => common}/src/common/sound/MovingSoundMinecart.java (100%) rename {java => common}/src/common/sound/MovingSoundMinecartRiding.java (100%) rename {java => common}/src/common/sound/PositionedSound.java (100%) rename {java => common}/src/common/sound/Sound.java (100%) rename {java => common}/src/common/tileentity/IHopper.java (100%) rename {java => common}/src/common/tileentity/IInteractionObject.java (100%) rename {java => common}/src/common/tileentity/ILockableContainer.java (100%) rename {java => common}/src/common/tileentity/ITickable.java (100%) rename {java => common}/src/common/tileentity/IWorldNameable.java (100%) rename {java => common}/src/common/tileentity/LocalBlockIntercommunication.java (100%) rename {java => common}/src/common/tileentity/LockCode.java (100%) rename {java => common}/src/common/tileentity/MachineResource.java (100%) rename {java => common}/src/common/tileentity/TileEntity.java (100%) rename {java => common}/src/common/tileentity/TileEntityBanner.java (100%) rename {java => common}/src/common/tileentity/TileEntityBeacon.java (100%) rename {java => common}/src/common/tileentity/TileEntityBrewingStand.java (100%) rename {java => common}/src/common/tileentity/TileEntityChest.java (100%) rename {java => common}/src/common/tileentity/TileEntityComparator.java (100%) rename {java => common}/src/common/tileentity/TileEntityDaylightDetector.java (100%) rename {java => common}/src/common/tileentity/TileEntityDispenser.java (100%) rename {java => common}/src/common/tileentity/TileEntityDropper.java (100%) rename {java => common}/src/common/tileentity/TileEntityEnchantmentTable.java (100%) rename {java => common}/src/common/tileentity/TileEntityFurnace.java (100%) rename {java => common}/src/common/tileentity/TileEntityHopper.java (100%) rename {java => common}/src/common/tileentity/TileEntityLockable.java (100%) rename {java => common}/src/common/tileentity/TileEntityMachine.java (100%) rename {java => common}/src/common/tileentity/TileEntityMobSpawner.java (100%) rename {java => common}/src/common/tileentity/TileEntityNote.java (100%) rename {java => common}/src/common/tileentity/TileEntityPiston.java (100%) rename {java => common}/src/common/tileentity/TileEntitySign.java (100%) rename {java => common}/src/common/tileentity/TileEntitySkull.java (100%) rename {java => common}/src/common/tileentity/TileEntityTianReactor.java (100%) rename {java => common}/src/common/util/CharValidator.java (100%) rename {java => common}/src/common/util/DC32.java (100%) rename {java => common}/src/common/util/Displayable.java (100%) rename {java => common}/src/common/util/ExtMath.java (100%) rename {java => common}/src/common/util/FileUtils.java (100%) rename {java => common}/src/common/util/Identifyable.java (100%) rename {java => common}/src/common/util/LazyLoadBase.java (100%) rename {java => common}/src/common/util/Matrix4f.java (100%) rename {java => common}/src/common/util/Predicates.java (100%) rename {java => common}/src/common/util/Tuple.java (100%) rename {java => common}/src/common/util/Util.java (100%) rename {java => common}/src/common/util/Vector.java (100%) rename {java => common}/src/common/util/Vector3f.java (100%) rename {java => common}/src/common/util/Vector4f.java (100%) rename {java => common}/src/common/village/MerchantRecipe.java (100%) rename {java => common}/src/common/village/MerchantRecipeList.java (100%) rename {java => common}/src/common/village/Village.java (100%) rename {java => common}/src/common/village/VillageCollection.java (100%) rename {java => common}/src/common/village/VillageDoorInfo.java (100%) rename {java => common}/src/common/world/BlockArray.java (100%) rename {java => common}/src/common/world/BlockPos.java (100%) rename {java => common}/src/common/world/BoundingBox.java (100%) rename {java => common}/src/common/world/Chunk.java (100%) rename {java => common}/src/common/world/ChunkCache.java (100%) rename {java => common}/src/common/world/ChunkPos.java (100%) rename {java => common}/src/common/world/ClassInheritanceMultiMap.java (100%) rename {java => common}/src/common/world/EmptyChunk.java (100%) rename {java => common}/src/common/world/Explosion.java (100%) rename {java => common}/src/common/world/Facing.java (100%) rename {java => common}/src/common/world/HitPosition.java (100%) rename {java => common}/src/common/world/IBlockAccess.java (100%) rename {java => common}/src/common/world/IWorldAccess.java (100%) rename {java => common}/src/common/world/IntHashMap.java (100%) rename {java => common}/src/common/world/LightType.java (100%) rename {java => common}/src/common/world/LongHashMap.java (100%) rename {java => common}/src/common/world/NextTickListEntry.java (100%) rename {java => common}/src/common/world/NibbleArray.java (100%) rename {java => common}/src/common/world/PortalType.java (100%) rename {java => common}/src/common/world/Position.java (100%) rename {java => common}/src/common/world/Region.java (100%) rename {java => common}/src/common/world/Spawner.java (100%) rename {java => common}/src/common/world/State.java (100%) rename {java => common}/src/common/world/Vec3.java (100%) rename {java => common}/src/common/world/Vec3i.java (100%) rename {java => common}/src/common/world/Weather.java (100%) rename {java => common}/src/common/world/World.java (100%) rename {java => common}/src/common/world/WorldClient.java (100%) rename {java => common}/src/common/world/WorldPos.java (100%) rename {java => common}/src/common/world/WorldServer.java (100%) rename {java => common}/src/common/worldgen/BiomeGenLayered.java (100%) rename {java => common}/src/common/worldgen/BiomeGenPerlin.java (100%) rename {java => common}/src/common/worldgen/BiomeGenSingle.java (100%) rename {java => common}/src/common/worldgen/BiomeGenerator.java (100%) rename {java => common}/src/common/worldgen/BlockReplacer.java (100%) rename {java => common}/src/common/worldgen/ChunkGenerator.java (100%) rename {java => common}/src/common/worldgen/ChunkPrimer.java (100%) rename {java => common}/src/common/worldgen/FeatureDungeons.java (100%) rename {java => common}/src/common/worldgen/FeatureGenerator.java (100%) rename {java => common}/src/common/worldgen/FeatureLakes.java (100%) rename {java => common}/src/common/worldgen/FeatureLiquids.java (100%) rename {java => common}/src/common/worldgen/FeatureOres.java (100%) rename {java => common}/src/common/worldgen/GeneratorCavern.java (100%) rename {java => common}/src/common/worldgen/GeneratorDebug.java (100%) rename {java => common}/src/common/worldgen/GeneratorDestroyed.java (100%) rename {java => common}/src/common/worldgen/GeneratorFlat.java (100%) rename {java => common}/src/common/worldgen/GeneratorIsland.java (100%) rename {java => common}/src/common/worldgen/GeneratorPerlin.java (100%) rename {java => common}/src/common/worldgen/GeneratorSimple.java (100%) rename {java => common}/src/common/worldgen/LootConstants.java (100%) rename {java => common}/src/common/worldgen/ReplacerAltBiome.java (100%) rename {java => common}/src/common/worldgen/ReplacerAltSurface.java (100%) rename {java => common}/src/common/worldgen/ReplacerBiome.java (100%) rename {java => common}/src/common/worldgen/ReplacerTopLayer.java (100%) rename {java => common}/src/common/worldgen/caves/MapGenBase.java (100%) rename {java => common}/src/common/worldgen/caves/MapGenBigCaves.java (100%) rename {java => common}/src/common/worldgen/caves/MapGenCaves.java (100%) rename {java => common}/src/common/worldgen/caves/MapGenRavine.java (100%) rename {java => common}/src/common/worldgen/feature/WorldGenAbandonedChest.java (100%) rename {java => common}/src/common/worldgen/feature/WorldGenAsteroid.java (100%) rename {java => common}/src/common/worldgen/feature/WorldGenBlockBlob.java (100%) rename {java => common}/src/common/worldgen/feature/WorldGenClay.java (100%) rename {java => common}/src/common/worldgen/feature/WorldGenClayExt.java (100%) rename {java => common}/src/common/worldgen/feature/WorldGenDesertWells.java (100%) rename {java => common}/src/common/worldgen/feature/WorldGenFire.java (100%) rename {java => common}/src/common/worldgen/feature/WorldGenGlowStone.java (100%) rename {java => common}/src/common/worldgen/feature/WorldGenHellLava.java (100%) rename {java => common}/src/common/worldgen/feature/WorldGenIcePath.java (100%) rename {java => common}/src/common/worldgen/feature/WorldGenIceSpike.java (100%) rename {java => common}/src/common/worldgen/feature/WorldGenSand.java (100%) rename {java => common}/src/common/worldgen/feature/WorldGenSpikes.java (100%) rename {java => common}/src/common/worldgen/foliage/FeatureDoublePlant.java (100%) rename {java => common}/src/common/worldgen/foliage/WorldGenBigMushroom.java (100%) rename {java => common}/src/common/worldgen/foliage/WorldGenCactus.java (100%) rename {java => common}/src/common/worldgen/foliage/WorldGenDeadBush.java (100%) rename {java => common}/src/common/worldgen/foliage/WorldGenFlowers.java (100%) rename {java => common}/src/common/worldgen/foliage/WorldGenMelon.java (100%) rename {java => common}/src/common/worldgen/foliage/WorldGenMushroom.java (100%) rename {java => common}/src/common/worldgen/foliage/WorldGenPumpkin.java (100%) rename {java => common}/src/common/worldgen/foliage/WorldGenReed.java (100%) rename {java => common}/src/common/worldgen/foliage/WorldGenShrub.java (100%) rename {java => common}/src/common/worldgen/foliage/WorldGenTallGrass.java (100%) rename {java => common}/src/common/worldgen/foliage/WorldGenVines.java (100%) rename {java => common}/src/common/worldgen/foliage/WorldGenWaterlily.java (100%) rename {java => common}/src/common/worldgen/layer/GenLayer.java (100%) rename {java => common}/src/common/worldgen/layer/GenLayerAddAreas.java (100%) rename {java => common}/src/common/worldgen/layer/GenLayerAddExtra.java (100%) rename {java => common}/src/common/worldgen/layer/GenLayerAddSea.java (100%) rename {java => common}/src/common/worldgen/layer/GenLayerAddSnow.java (100%) rename {java => common}/src/common/worldgen/layer/GenLayerBase.java (100%) rename {java => common}/src/common/worldgen/layer/GenLayerBiome.java (100%) rename {java => common}/src/common/worldgen/layer/GenLayerBiomeEdge.java (100%) rename {java => common}/src/common/worldgen/layer/GenLayerEdge.java (100%) rename {java => common}/src/common/worldgen/layer/GenLayerFuzzyZoom.java (100%) rename {java => common}/src/common/worldgen/layer/GenLayerHills.java (100%) rename {java => common}/src/common/worldgen/layer/GenLayerRemoveEmpty.java (100%) rename {java => common}/src/common/worldgen/layer/GenLayerRiver.java (100%) rename {java => common}/src/common/worldgen/layer/GenLayerRiverInit.java (100%) rename {java => common}/src/common/worldgen/layer/GenLayerRiverMix.java (100%) rename {java => common}/src/common/worldgen/layer/GenLayerShore.java (100%) rename {java => common}/src/common/worldgen/layer/GenLayerSmooth.java (100%) rename {java => common}/src/common/worldgen/layer/GenLayerVoronoiZoom.java (100%) rename {java => common}/src/common/worldgen/layer/GenLayerZoom.java (100%) rename {java => common}/src/common/worldgen/layer/IntCache.java (100%) rename {java => common}/src/common/worldgen/structure/MapGenBridge.java (100%) rename {java => common}/src/common/worldgen/structure/MapGenMineshaft.java (100%) rename {java => common}/src/common/worldgen/structure/MapGenScatteredFeature.java (100%) rename {java => common}/src/common/worldgen/structure/MapGenStronghold.java (100%) rename {java => common}/src/common/worldgen/structure/MapGenStructure.java (100%) rename {java => common}/src/common/worldgen/structure/MapGenStructureIO.java (100%) rename {java => common}/src/common/worldgen/structure/MapGenVillage.java (100%) rename {java => common}/src/common/worldgen/structure/StructureBoundingBox.java (100%) rename {java => common}/src/common/worldgen/structure/StructureBridge.java (100%) rename {java => common}/src/common/worldgen/structure/StructureComponent.java (100%) rename {java => common}/src/common/worldgen/structure/StructureMineshaft.java (100%) rename {java => common}/src/common/worldgen/structure/StructureMineshaftStart.java (100%) rename {java => common}/src/common/worldgen/structure/StructureScattered.java (100%) rename {java => common}/src/common/worldgen/structure/StructureStart.java (100%) rename {java => common}/src/common/worldgen/structure/StructureStronghold.java (100%) rename {java => common}/src/common/worldgen/structure/StructureVillage.java (100%) rename {java => common}/src/common/worldgen/tree/WorldGenBaseTree.java (100%) rename {java => common}/src/common/worldgen/tree/WorldGenBigTree.java (100%) rename {java => common}/src/common/worldgen/tree/WorldGenBirch.java (100%) rename {java => common}/src/common/worldgen/tree/WorldGenDarkOak.java (100%) rename {java => common}/src/common/worldgen/tree/WorldGenHugeTree.java (100%) rename {java => common}/src/common/worldgen/tree/WorldGenJungle.java (100%) rename {java => common}/src/common/worldgen/tree/WorldGenPine.java (100%) rename {java => common}/src/common/worldgen/tree/WorldGenSavanna.java (100%) rename {java => common}/src/common/worldgen/tree/WorldGenSwamp.java (100%) rename {java => common}/src/common/worldgen/tree/WorldGenTaiga1.java (100%) rename {java => common}/src/common/worldgen/tree/WorldGenTaiga2.java (100%) rename {java => common}/src/common/worldgen/tree/WorldGenTree.java (100%) diff --git a/.gitignore b/.gitignore index 44084bc..0da720f 100644 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,8 @@ -/java/run -/java/bin +/common/dev +/common/bin /client/bin +/client/run /server/bin -/java/dev +/server/run /export /.metadata diff --git a/java/src/common/IClient.java b/common/src/common/IClient.java similarity index 100% rename from java/src/common/IClient.java rename to common/src/common/IClient.java diff --git a/java/src/common/IServer.java b/common/src/common/IServer.java similarity index 100% rename from java/src/common/IServer.java rename to common/src/common/IServer.java diff --git a/java/src/common/ai/AIFireballAttack.java b/common/src/common/ai/AIFireballAttack.java similarity index 100% rename from java/src/common/ai/AIFireballAttack.java rename to common/src/common/ai/AIFireballAttack.java diff --git a/java/src/common/ai/AIFlyingBoxAttack.java b/common/src/common/ai/AIFlyingBoxAttack.java similarity index 100% rename from java/src/common/ai/AIFlyingBoxAttack.java rename to common/src/common/ai/AIFlyingBoxAttack.java diff --git a/java/src/common/ai/AIRangedAttack.java b/common/src/common/ai/AIRangedAttack.java similarity index 100% rename from java/src/common/ai/AIRangedAttack.java rename to common/src/common/ai/AIRangedAttack.java diff --git a/java/src/common/ai/AISmallFireballAttack.java b/common/src/common/ai/AISmallFireballAttack.java similarity index 100% rename from java/src/common/ai/AISmallFireballAttack.java rename to common/src/common/ai/AISmallFireballAttack.java diff --git a/java/src/common/ai/EntityAIAttackOnCollide.java b/common/src/common/ai/EntityAIAttackOnCollide.java similarity index 100% rename from java/src/common/ai/EntityAIAttackOnCollide.java rename to common/src/common/ai/EntityAIAttackOnCollide.java diff --git a/java/src/common/ai/EntityAIAvoidEntity.java b/common/src/common/ai/EntityAIAvoidEntity.java similarity index 100% rename from java/src/common/ai/EntityAIAvoidEntity.java rename to common/src/common/ai/EntityAIAvoidEntity.java diff --git a/java/src/common/ai/EntityAIBase.java b/common/src/common/ai/EntityAIBase.java similarity index 100% rename from java/src/common/ai/EntityAIBase.java rename to common/src/common/ai/EntityAIBase.java diff --git a/java/src/common/ai/EntityAIBeg.java b/common/src/common/ai/EntityAIBeg.java similarity index 100% rename from java/src/common/ai/EntityAIBeg.java rename to common/src/common/ai/EntityAIBeg.java diff --git a/java/src/common/ai/EntityAIControlledByPlayer.java b/common/src/common/ai/EntityAIControlledByPlayer.java similarity index 100% rename from java/src/common/ai/EntityAIControlledByPlayer.java rename to common/src/common/ai/EntityAIControlledByPlayer.java diff --git a/java/src/common/ai/EntityAIDoorInteract.java b/common/src/common/ai/EntityAIDoorInteract.java similarity index 100% rename from java/src/common/ai/EntityAIDoorInteract.java rename to common/src/common/ai/EntityAIDoorInteract.java diff --git a/java/src/common/ai/EntityAIEatGrass.java b/common/src/common/ai/EntityAIEatGrass.java similarity index 100% rename from java/src/common/ai/EntityAIEatGrass.java rename to common/src/common/ai/EntityAIEatGrass.java diff --git a/java/src/common/ai/EntityAIExplode.java b/common/src/common/ai/EntityAIExplode.java similarity index 100% rename from java/src/common/ai/EntityAIExplode.java rename to common/src/common/ai/EntityAIExplode.java diff --git a/java/src/common/ai/EntityAIFindEntityNearest.java b/common/src/common/ai/EntityAIFindEntityNearest.java similarity index 100% rename from java/src/common/ai/EntityAIFindEntityNearest.java rename to common/src/common/ai/EntityAIFindEntityNearest.java diff --git a/java/src/common/ai/EntityAIFleeSun.java b/common/src/common/ai/EntityAIFleeSun.java similarity index 100% rename from java/src/common/ai/EntityAIFleeSun.java rename to common/src/common/ai/EntityAIFleeSun.java diff --git a/java/src/common/ai/EntityAIFollowOwner.java b/common/src/common/ai/EntityAIFollowOwner.java similarity index 100% rename from java/src/common/ai/EntityAIFollowOwner.java rename to common/src/common/ai/EntityAIFollowOwner.java diff --git a/java/src/common/ai/EntityAIFollowParent.java b/common/src/common/ai/EntityAIFollowParent.java similarity index 100% rename from java/src/common/ai/EntityAIFollowParent.java rename to common/src/common/ai/EntityAIFollowParent.java diff --git a/java/src/common/ai/EntityAIHarvestFarmland.java b/common/src/common/ai/EntityAIHarvestFarmland.java similarity index 100% rename from java/src/common/ai/EntityAIHarvestFarmland.java rename to common/src/common/ai/EntityAIHarvestFarmland.java diff --git a/java/src/common/ai/EntityAIHurtByTarget.java b/common/src/common/ai/EntityAIHurtByTarget.java similarity index 100% rename from java/src/common/ai/EntityAIHurtByTarget.java rename to common/src/common/ai/EntityAIHurtByTarget.java diff --git a/java/src/common/ai/EntityAILeapAtTarget.java b/common/src/common/ai/EntityAILeapAtTarget.java similarity index 100% rename from java/src/common/ai/EntityAILeapAtTarget.java rename to common/src/common/ai/EntityAILeapAtTarget.java diff --git a/java/src/common/ai/EntityAILookAtTalkingPlayer.java b/common/src/common/ai/EntityAILookAtTalkingPlayer.java similarity index 100% rename from java/src/common/ai/EntityAILookAtTalkingPlayer.java rename to common/src/common/ai/EntityAILookAtTalkingPlayer.java diff --git a/java/src/common/ai/EntityAILookIdle.java b/common/src/common/ai/EntityAILookIdle.java similarity index 100% rename from java/src/common/ai/EntityAILookIdle.java rename to common/src/common/ai/EntityAILookIdle.java diff --git a/java/src/common/ai/EntityAIMate.java b/common/src/common/ai/EntityAIMate.java similarity index 100% rename from java/src/common/ai/EntityAIMate.java rename to common/src/common/ai/EntityAIMate.java diff --git a/java/src/common/ai/EntityAIMoveIndoors.java b/common/src/common/ai/EntityAIMoveIndoors.java similarity index 100% rename from java/src/common/ai/EntityAIMoveIndoors.java rename to common/src/common/ai/EntityAIMoveIndoors.java diff --git a/java/src/common/ai/EntityAIMoveThroughVillage.java b/common/src/common/ai/EntityAIMoveThroughVillage.java similarity index 100% rename from java/src/common/ai/EntityAIMoveThroughVillage.java rename to common/src/common/ai/EntityAIMoveThroughVillage.java diff --git a/java/src/common/ai/EntityAIMoveToBlock.java b/common/src/common/ai/EntityAIMoveToBlock.java similarity index 100% rename from java/src/common/ai/EntityAIMoveToBlock.java rename to common/src/common/ai/EntityAIMoveToBlock.java diff --git a/java/src/common/ai/EntityAIMoveTowardsRestriction.java b/common/src/common/ai/EntityAIMoveTowardsRestriction.java similarity index 100% rename from java/src/common/ai/EntityAIMoveTowardsRestriction.java rename to common/src/common/ai/EntityAIMoveTowardsRestriction.java diff --git a/java/src/common/ai/EntityAIMoveTowardsTarget.java b/common/src/common/ai/EntityAIMoveTowardsTarget.java similarity index 100% rename from java/src/common/ai/EntityAIMoveTowardsTarget.java rename to common/src/common/ai/EntityAIMoveTowardsTarget.java diff --git a/java/src/common/ai/EntityAINagPlayer.java b/common/src/common/ai/EntityAINagPlayer.java similarity index 100% rename from java/src/common/ai/EntityAINagPlayer.java rename to common/src/common/ai/EntityAINagPlayer.java diff --git a/java/src/common/ai/EntityAINearestAttackableTarget.java b/common/src/common/ai/EntityAINearestAttackableTarget.java similarity index 100% rename from java/src/common/ai/EntityAINearestAttackableTarget.java rename to common/src/common/ai/EntityAINearestAttackableTarget.java diff --git a/java/src/common/ai/EntityAINpcInteract.java b/common/src/common/ai/EntityAINpcInteract.java similarity index 100% rename from java/src/common/ai/EntityAINpcInteract.java rename to common/src/common/ai/EntityAINpcInteract.java diff --git a/java/src/common/ai/EntityAINpcMate.java b/common/src/common/ai/EntityAINpcMate.java similarity index 100% rename from java/src/common/ai/EntityAINpcMate.java rename to common/src/common/ai/EntityAINpcMate.java diff --git a/java/src/common/ai/EntityAIOcelotAttack.java b/common/src/common/ai/EntityAIOcelotAttack.java similarity index 100% rename from java/src/common/ai/EntityAIOcelotAttack.java rename to common/src/common/ai/EntityAIOcelotAttack.java diff --git a/java/src/common/ai/EntityAIOcelotSit.java b/common/src/common/ai/EntityAIOcelotSit.java similarity index 100% rename from java/src/common/ai/EntityAIOcelotSit.java rename to common/src/common/ai/EntityAIOcelotSit.java diff --git a/java/src/common/ai/EntityAIOpenDoor.java b/common/src/common/ai/EntityAIOpenDoor.java similarity index 100% rename from java/src/common/ai/EntityAIOpenDoor.java rename to common/src/common/ai/EntityAIOpenDoor.java diff --git a/java/src/common/ai/EntityAIOwnerHurtByTarget.java b/common/src/common/ai/EntityAIOwnerHurtByTarget.java similarity index 100% rename from java/src/common/ai/EntityAIOwnerHurtByTarget.java rename to common/src/common/ai/EntityAIOwnerHurtByTarget.java diff --git a/java/src/common/ai/EntityAIOwnerHurtTarget.java b/common/src/common/ai/EntityAIOwnerHurtTarget.java similarity index 100% rename from java/src/common/ai/EntityAIOwnerHurtTarget.java rename to common/src/common/ai/EntityAIOwnerHurtTarget.java diff --git a/java/src/common/ai/EntityAIPanic.java b/common/src/common/ai/EntityAIPanic.java similarity index 100% rename from java/src/common/ai/EntityAIPanic.java rename to common/src/common/ai/EntityAIPanic.java diff --git a/java/src/common/ai/EntityAIPlay.java b/common/src/common/ai/EntityAIPlay.java similarity index 100% rename from java/src/common/ai/EntityAIPlay.java rename to common/src/common/ai/EntityAIPlay.java diff --git a/java/src/common/ai/EntityAIRestrictOpenDoor.java b/common/src/common/ai/EntityAIRestrictOpenDoor.java similarity index 100% rename from java/src/common/ai/EntityAIRestrictOpenDoor.java rename to common/src/common/ai/EntityAIRestrictOpenDoor.java diff --git a/java/src/common/ai/EntityAIRestrictSun.java b/common/src/common/ai/EntityAIRestrictSun.java similarity index 100% rename from java/src/common/ai/EntityAIRestrictSun.java rename to common/src/common/ai/EntityAIRestrictSun.java diff --git a/java/src/common/ai/EntityAIRunAroundLikeCrazy.java b/common/src/common/ai/EntityAIRunAroundLikeCrazy.java similarity index 100% rename from java/src/common/ai/EntityAIRunAroundLikeCrazy.java rename to common/src/common/ai/EntityAIRunAroundLikeCrazy.java diff --git a/java/src/common/ai/EntityAIShareItems.java b/common/src/common/ai/EntityAIShareItems.java similarity index 100% rename from java/src/common/ai/EntityAIShareItems.java rename to common/src/common/ai/EntityAIShareItems.java diff --git a/java/src/common/ai/EntityAISit.java b/common/src/common/ai/EntityAISit.java similarity index 100% rename from java/src/common/ai/EntityAISit.java rename to common/src/common/ai/EntityAISit.java diff --git a/java/src/common/ai/EntityAISwimming.java b/common/src/common/ai/EntityAISwimming.java similarity index 100% rename from java/src/common/ai/EntityAISwimming.java rename to common/src/common/ai/EntityAISwimming.java diff --git a/java/src/common/ai/EntityAITakePlace.java b/common/src/common/ai/EntityAITakePlace.java similarity index 100% rename from java/src/common/ai/EntityAITakePlace.java rename to common/src/common/ai/EntityAITakePlace.java diff --git a/java/src/common/ai/EntityAITarget.java b/common/src/common/ai/EntityAITarget.java similarity index 100% rename from java/src/common/ai/EntityAITarget.java rename to common/src/common/ai/EntityAITarget.java diff --git a/java/src/common/ai/EntityAITargetNonTamed.java b/common/src/common/ai/EntityAITargetNonTamed.java similarity index 100% rename from java/src/common/ai/EntityAITargetNonTamed.java rename to common/src/common/ai/EntityAITargetNonTamed.java diff --git a/java/src/common/ai/EntityAITasks.java b/common/src/common/ai/EntityAITasks.java similarity index 100% rename from java/src/common/ai/EntityAITasks.java rename to common/src/common/ai/EntityAITasks.java diff --git a/java/src/common/ai/EntityAITempt.java b/common/src/common/ai/EntityAITempt.java similarity index 100% rename from java/src/common/ai/EntityAITempt.java rename to common/src/common/ai/EntityAITempt.java diff --git a/java/src/common/ai/EntityAIWander.java b/common/src/common/ai/EntityAIWander.java similarity index 100% rename from java/src/common/ai/EntityAIWander.java rename to common/src/common/ai/EntityAIWander.java diff --git a/java/src/common/ai/EntityAIWatchClosest.java b/common/src/common/ai/EntityAIWatchClosest.java similarity index 100% rename from java/src/common/ai/EntityAIWatchClosest.java rename to common/src/common/ai/EntityAIWatchClosest.java diff --git a/java/src/common/ai/EntityAIWatchClosest2.java b/common/src/common/ai/EntityAIWatchClosest2.java similarity index 100% rename from java/src/common/ai/EntityAIWatchClosest2.java rename to common/src/common/ai/EntityAIWatchClosest2.java diff --git a/java/src/common/ai/EntityJumpHelper.java b/common/src/common/ai/EntityJumpHelper.java similarity index 100% rename from java/src/common/ai/EntityJumpHelper.java rename to common/src/common/ai/EntityJumpHelper.java diff --git a/java/src/common/ai/EntityLookHelper.java b/common/src/common/ai/EntityLookHelper.java similarity index 100% rename from java/src/common/ai/EntityLookHelper.java rename to common/src/common/ai/EntityLookHelper.java diff --git a/java/src/common/ai/EntityMoveHelper.java b/common/src/common/ai/EntityMoveHelper.java similarity index 100% rename from java/src/common/ai/EntityMoveHelper.java rename to common/src/common/ai/EntityMoveHelper.java diff --git a/java/src/common/ai/EntitySenses.java b/common/src/common/ai/EntitySenses.java similarity index 100% rename from java/src/common/ai/EntitySenses.java rename to common/src/common/ai/EntitySenses.java diff --git a/java/src/common/ai/RandomPositionGenerator.java b/common/src/common/ai/RandomPositionGenerator.java similarity index 100% rename from java/src/common/ai/RandomPositionGenerator.java rename to common/src/common/ai/RandomPositionGenerator.java diff --git a/java/src/common/biome/Biome.java b/common/src/common/biome/Biome.java similarity index 100% rename from java/src/common/biome/Biome.java rename to common/src/common/biome/Biome.java diff --git a/java/src/common/biome/BiomeBeach.java b/common/src/common/biome/BiomeBeach.java similarity index 100% rename from java/src/common/biome/BiomeBeach.java rename to common/src/common/biome/BiomeBeach.java diff --git a/java/src/common/biome/BiomeBlackened.java b/common/src/common/biome/BiomeBlackened.java similarity index 100% rename from java/src/common/biome/BiomeBlackened.java rename to common/src/common/biome/BiomeBlackened.java diff --git a/java/src/common/biome/BiomeChaos.java b/common/src/common/biome/BiomeChaos.java similarity index 100% rename from java/src/common/biome/BiomeChaos.java rename to common/src/common/biome/BiomeChaos.java diff --git a/java/src/common/biome/BiomeDesert.java b/common/src/common/biome/BiomeDesert.java similarity index 100% rename from java/src/common/biome/BiomeDesert.java rename to common/src/common/biome/BiomeDesert.java diff --git a/java/src/common/biome/BiomeExterminated.java b/common/src/common/biome/BiomeExterminated.java similarity index 100% rename from java/src/common/biome/BiomeExterminated.java rename to common/src/common/biome/BiomeExterminated.java diff --git a/java/src/common/biome/BiomeForest.java b/common/src/common/biome/BiomeForest.java similarity index 100% rename from java/src/common/biome/BiomeForest.java rename to common/src/common/biome/BiomeForest.java diff --git a/java/src/common/biome/BiomeHell.java b/common/src/common/biome/BiomeHell.java similarity index 100% rename from java/src/common/biome/BiomeHell.java rename to common/src/common/biome/BiomeHell.java diff --git a/java/src/common/biome/BiomeHills.java b/common/src/common/biome/BiomeHills.java similarity index 100% rename from java/src/common/biome/BiomeHills.java rename to common/src/common/biome/BiomeHills.java diff --git a/java/src/common/biome/BiomeJungle.java b/common/src/common/biome/BiomeJungle.java similarity index 100% rename from java/src/common/biome/BiomeJungle.java rename to common/src/common/biome/BiomeJungle.java diff --git a/java/src/common/biome/BiomeMesa.java b/common/src/common/biome/BiomeMesa.java similarity index 100% rename from java/src/common/biome/BiomeMesa.java rename to common/src/common/biome/BiomeMesa.java diff --git a/java/src/common/biome/BiomeMoon.java b/common/src/common/biome/BiomeMoon.java similarity index 100% rename from java/src/common/biome/BiomeMoon.java rename to common/src/common/biome/BiomeMoon.java diff --git a/java/src/common/biome/BiomeMushroom.java b/common/src/common/biome/BiomeMushroom.java similarity index 100% rename from java/src/common/biome/BiomeMushroom.java rename to common/src/common/biome/BiomeMushroom.java diff --git a/java/src/common/biome/BiomeMutated.java b/common/src/common/biome/BiomeMutated.java similarity index 100% rename from java/src/common/biome/BiomeMutated.java rename to common/src/common/biome/BiomeMutated.java diff --git a/java/src/common/biome/BiomeNone.java b/common/src/common/biome/BiomeNone.java similarity index 100% rename from java/src/common/biome/BiomeNone.java rename to common/src/common/biome/BiomeNone.java diff --git a/java/src/common/biome/BiomePlains.java b/common/src/common/biome/BiomePlains.java similarity index 100% rename from java/src/common/biome/BiomePlains.java rename to common/src/common/biome/BiomePlains.java diff --git a/java/src/common/biome/BiomeSavanna.java b/common/src/common/biome/BiomeSavanna.java similarity index 100% rename from java/src/common/biome/BiomeSavanna.java rename to common/src/common/biome/BiomeSavanna.java diff --git a/java/src/common/biome/BiomeSnow.java b/common/src/common/biome/BiomeSnow.java similarity index 100% rename from java/src/common/biome/BiomeSnow.java rename to common/src/common/biome/BiomeSnow.java diff --git a/java/src/common/biome/BiomeSnowLand.java b/common/src/common/biome/BiomeSnowLand.java similarity index 100% rename from java/src/common/biome/BiomeSnowLand.java rename to common/src/common/biome/BiomeSnowLand.java diff --git a/java/src/common/biome/BiomeSpace.java b/common/src/common/biome/BiomeSpace.java similarity index 100% rename from java/src/common/biome/BiomeSpace.java rename to common/src/common/biome/BiomeSpace.java diff --git a/java/src/common/biome/BiomeStoneBeach.java b/common/src/common/biome/BiomeStoneBeach.java similarity index 100% rename from java/src/common/biome/BiomeStoneBeach.java rename to common/src/common/biome/BiomeStoneBeach.java diff --git a/java/src/common/biome/BiomeSwamp.java b/common/src/common/biome/BiomeSwamp.java similarity index 100% rename from java/src/common/biome/BiomeSwamp.java rename to common/src/common/biome/BiomeSwamp.java diff --git a/java/src/common/biome/BiomeTaiga.java b/common/src/common/biome/BiomeTaiga.java similarity index 100% rename from java/src/common/biome/BiomeTaiga.java rename to common/src/common/biome/BiomeTaiga.java diff --git a/java/src/common/biome/BiomeTian.java b/common/src/common/biome/BiomeTian.java similarity index 100% rename from java/src/common/biome/BiomeTian.java rename to common/src/common/biome/BiomeTian.java diff --git a/java/src/common/biome/BiomeWater.java b/common/src/common/biome/BiomeWater.java similarity index 100% rename from java/src/common/biome/BiomeWater.java rename to common/src/common/biome/BiomeWater.java diff --git a/java/src/common/biome/RngSpawn.java b/common/src/common/biome/RngSpawn.java similarity index 100% rename from java/src/common/biome/RngSpawn.java rename to common/src/common/biome/RngSpawn.java diff --git a/java/src/common/biome/Scaling.java b/common/src/common/biome/Scaling.java similarity index 100% rename from java/src/common/biome/Scaling.java rename to common/src/common/biome/Scaling.java diff --git a/java/src/common/biome/Temperature.java b/common/src/common/biome/Temperature.java similarity index 100% rename from java/src/common/biome/Temperature.java rename to common/src/common/biome/Temperature.java diff --git a/java/src/common/block/Block.java b/common/src/common/block/Block.java similarity index 100% rename from java/src/common/block/Block.java rename to common/src/common/block/Block.java diff --git a/java/src/common/block/BlockAir.java b/common/src/common/block/BlockAir.java similarity index 100% rename from java/src/common/block/BlockAir.java rename to common/src/common/block/BlockAir.java diff --git a/java/src/common/block/BlockAnvil.java b/common/src/common/block/BlockAnvil.java similarity index 100% rename from java/src/common/block/BlockAnvil.java rename to common/src/common/block/BlockAnvil.java diff --git a/java/src/common/block/BlockBanner.java b/common/src/common/block/BlockBanner.java similarity index 100% rename from java/src/common/block/BlockBanner.java rename to common/src/common/block/BlockBanner.java diff --git a/java/src/common/block/BlockBaseFlower.java b/common/src/common/block/BlockBaseFlower.java similarity index 100% rename from java/src/common/block/BlockBaseFlower.java rename to common/src/common/block/BlockBaseFlower.java diff --git a/java/src/common/block/BlockBasePressurePlate.java b/common/src/common/block/BlockBasePressurePlate.java similarity index 100% rename from java/src/common/block/BlockBasePressurePlate.java rename to common/src/common/block/BlockBasePressurePlate.java diff --git a/java/src/common/block/BlockBeacon.java b/common/src/common/block/BlockBeacon.java similarity index 100% rename from java/src/common/block/BlockBeacon.java rename to common/src/common/block/BlockBeacon.java diff --git a/java/src/common/block/BlockBed.java b/common/src/common/block/BlockBed.java similarity index 100% rename from java/src/common/block/BlockBed.java rename to common/src/common/block/BlockBed.java diff --git a/java/src/common/block/BlockBedrock.java b/common/src/common/block/BlockBedrock.java similarity index 100% rename from java/src/common/block/BlockBedrock.java rename to common/src/common/block/BlockBedrock.java diff --git a/java/src/common/block/BlockBlackenedDirt.java b/common/src/common/block/BlockBlackenedDirt.java similarity index 100% rename from java/src/common/block/BlockBlackenedDirt.java rename to common/src/common/block/BlockBlackenedDirt.java diff --git a/java/src/common/block/BlockBlackenedSoil.java b/common/src/common/block/BlockBlackenedSoil.java similarity index 100% rename from java/src/common/block/BlockBlackenedSoil.java rename to common/src/common/block/BlockBlackenedSoil.java diff --git a/java/src/common/block/BlockBlackenedStone.java b/common/src/common/block/BlockBlackenedStone.java similarity index 100% rename from java/src/common/block/BlockBlackenedStone.java rename to common/src/common/block/BlockBlackenedStone.java diff --git a/java/src/common/block/BlockBlueShroom.java b/common/src/common/block/BlockBlueShroom.java similarity index 100% rename from java/src/common/block/BlockBlueShroom.java rename to common/src/common/block/BlockBlueShroom.java diff --git a/java/src/common/block/BlockBookshelf.java b/common/src/common/block/BlockBookshelf.java similarity index 100% rename from java/src/common/block/BlockBookshelf.java rename to common/src/common/block/BlockBookshelf.java diff --git a/java/src/common/block/BlockBreakable.java b/common/src/common/block/BlockBreakable.java similarity index 100% rename from java/src/common/block/BlockBreakable.java rename to common/src/common/block/BlockBreakable.java diff --git a/java/src/common/block/BlockBrewingStand.java b/common/src/common/block/BlockBrewingStand.java similarity index 100% rename from java/src/common/block/BlockBrewingStand.java rename to common/src/common/block/BlockBrewingStand.java diff --git a/java/src/common/block/BlockBush.java b/common/src/common/block/BlockBush.java similarity index 100% rename from java/src/common/block/BlockBush.java rename to common/src/common/block/BlockBush.java diff --git a/java/src/common/block/BlockButton.java b/common/src/common/block/BlockButton.java similarity index 100% rename from java/src/common/block/BlockButton.java rename to common/src/common/block/BlockButton.java diff --git a/java/src/common/block/BlockCactus.java b/common/src/common/block/BlockCactus.java similarity index 100% rename from java/src/common/block/BlockCactus.java rename to common/src/common/block/BlockCactus.java diff --git a/java/src/common/block/BlockCake.java b/common/src/common/block/BlockCake.java similarity index 100% rename from java/src/common/block/BlockCake.java rename to common/src/common/block/BlockCake.java diff --git a/java/src/common/block/BlockCarpet.java b/common/src/common/block/BlockCarpet.java similarity index 100% rename from java/src/common/block/BlockCarpet.java rename to common/src/common/block/BlockCarpet.java diff --git a/java/src/common/block/BlockCarrot.java b/common/src/common/block/BlockCarrot.java similarity index 100% rename from java/src/common/block/BlockCarrot.java rename to common/src/common/block/BlockCarrot.java diff --git a/java/src/common/block/BlockCauldron.java b/common/src/common/block/BlockCauldron.java similarity index 100% rename from java/src/common/block/BlockCauldron.java rename to common/src/common/block/BlockCauldron.java diff --git a/java/src/common/block/BlockChest.java b/common/src/common/block/BlockChest.java similarity index 100% rename from java/src/common/block/BlockChest.java rename to common/src/common/block/BlockChest.java diff --git a/java/src/common/block/BlockClay.java b/common/src/common/block/BlockClay.java similarity index 100% rename from java/src/common/block/BlockClay.java rename to common/src/common/block/BlockClay.java diff --git a/java/src/common/block/BlockCocoa.java b/common/src/common/block/BlockCocoa.java similarity index 100% rename from java/src/common/block/BlockCocoa.java rename to common/src/common/block/BlockCocoa.java diff --git a/java/src/common/block/BlockColored.java b/common/src/common/block/BlockColored.java similarity index 100% rename from java/src/common/block/BlockColored.java rename to common/src/common/block/BlockColored.java diff --git a/java/src/common/block/BlockCompressedPowered.java b/common/src/common/block/BlockCompressedPowered.java similarity index 100% rename from java/src/common/block/BlockCompressedPowered.java rename to common/src/common/block/BlockCompressedPowered.java diff --git a/java/src/common/block/BlockContainer.java b/common/src/common/block/BlockContainer.java similarity index 100% rename from java/src/common/block/BlockContainer.java rename to common/src/common/block/BlockContainer.java diff --git a/java/src/common/block/BlockCore.java b/common/src/common/block/BlockCore.java similarity index 100% rename from java/src/common/block/BlockCore.java rename to common/src/common/block/BlockCore.java diff --git a/java/src/common/block/BlockCrops.java b/common/src/common/block/BlockCrops.java similarity index 100% rename from java/src/common/block/BlockCrops.java rename to common/src/common/block/BlockCrops.java diff --git a/java/src/common/block/BlockDaylightDetector.java b/common/src/common/block/BlockDaylightDetector.java similarity index 100% rename from java/src/common/block/BlockDaylightDetector.java rename to common/src/common/block/BlockDaylightDetector.java diff --git a/java/src/common/block/BlockDeadBush.java b/common/src/common/block/BlockDeadBush.java similarity index 100% rename from java/src/common/block/BlockDeadBush.java rename to common/src/common/block/BlockDeadBush.java diff --git a/java/src/common/block/BlockDirectional.java b/common/src/common/block/BlockDirectional.java similarity index 100% rename from java/src/common/block/BlockDirectional.java rename to common/src/common/block/BlockDirectional.java diff --git a/java/src/common/block/BlockDirt.java b/common/src/common/block/BlockDirt.java similarity index 100% rename from java/src/common/block/BlockDirt.java rename to common/src/common/block/BlockDirt.java diff --git a/java/src/common/block/BlockDispenser.java b/common/src/common/block/BlockDispenser.java similarity index 100% rename from java/src/common/block/BlockDispenser.java rename to common/src/common/block/BlockDispenser.java diff --git a/java/src/common/block/BlockDoor.java b/common/src/common/block/BlockDoor.java similarity index 100% rename from java/src/common/block/BlockDoor.java rename to common/src/common/block/BlockDoor.java diff --git a/java/src/common/block/BlockDoublePlant.java b/common/src/common/block/BlockDoublePlant.java similarity index 100% rename from java/src/common/block/BlockDoublePlant.java rename to common/src/common/block/BlockDoublePlant.java diff --git a/java/src/common/block/BlockDragonEgg.java b/common/src/common/block/BlockDragonEgg.java similarity index 100% rename from java/src/common/block/BlockDragonEgg.java rename to common/src/common/block/BlockDragonEgg.java diff --git a/java/src/common/block/BlockDropper.java b/common/src/common/block/BlockDropper.java similarity index 100% rename from java/src/common/block/BlockDropper.java rename to common/src/common/block/BlockDropper.java diff --git a/java/src/common/block/BlockDryLeaves.java b/common/src/common/block/BlockDryLeaves.java similarity index 100% rename from java/src/common/block/BlockDryLeaves.java rename to common/src/common/block/BlockDryLeaves.java diff --git a/java/src/common/block/BlockDynamicLiquid.java b/common/src/common/block/BlockDynamicLiquid.java similarity index 100% rename from java/src/common/block/BlockDynamicLiquid.java rename to common/src/common/block/BlockDynamicLiquid.java diff --git a/java/src/common/block/BlockEnchantmentTable.java b/common/src/common/block/BlockEnchantmentTable.java similarity index 100% rename from java/src/common/block/BlockEnchantmentTable.java rename to common/src/common/block/BlockEnchantmentTable.java diff --git a/java/src/common/block/BlockEventData.java b/common/src/common/block/BlockEventData.java similarity index 100% rename from java/src/common/block/BlockEventData.java rename to common/src/common/block/BlockEventData.java diff --git a/java/src/common/block/BlockFalling.java b/common/src/common/block/BlockFalling.java similarity index 100% rename from java/src/common/block/BlockFalling.java rename to common/src/common/block/BlockFalling.java diff --git a/java/src/common/block/BlockFarmland.java b/common/src/common/block/BlockFarmland.java similarity index 100% rename from java/src/common/block/BlockFarmland.java rename to common/src/common/block/BlockFarmland.java diff --git a/java/src/common/block/BlockFence.java b/common/src/common/block/BlockFence.java similarity index 100% rename from java/src/common/block/BlockFence.java rename to common/src/common/block/BlockFence.java diff --git a/java/src/common/block/BlockFenceGate.java b/common/src/common/block/BlockFenceGate.java similarity index 100% rename from java/src/common/block/BlockFenceGate.java rename to common/src/common/block/BlockFenceGate.java diff --git a/java/src/common/block/BlockFire.java b/common/src/common/block/BlockFire.java similarity index 100% rename from java/src/common/block/BlockFire.java rename to common/src/common/block/BlockFire.java diff --git a/java/src/common/block/BlockFloorPortal.java b/common/src/common/block/BlockFloorPortal.java similarity index 100% rename from java/src/common/block/BlockFloorPortal.java rename to common/src/common/block/BlockFloorPortal.java diff --git a/java/src/common/block/BlockFlower.java b/common/src/common/block/BlockFlower.java similarity index 100% rename from java/src/common/block/BlockFlower.java rename to common/src/common/block/BlockFlower.java diff --git a/java/src/common/block/BlockFlowerPot.java b/common/src/common/block/BlockFlowerPot.java similarity index 100% rename from java/src/common/block/BlockFlowerPot.java rename to common/src/common/block/BlockFlowerPot.java diff --git a/java/src/common/block/BlockFurnace.java b/common/src/common/block/BlockFurnace.java similarity index 100% rename from java/src/common/block/BlockFurnace.java rename to common/src/common/block/BlockFurnace.java diff --git a/java/src/common/block/BlockGlass.java b/common/src/common/block/BlockGlass.java similarity index 100% rename from java/src/common/block/BlockGlass.java rename to common/src/common/block/BlockGlass.java diff --git a/java/src/common/block/BlockGlowstone.java b/common/src/common/block/BlockGlowstone.java similarity index 100% rename from java/src/common/block/BlockGlowstone.java rename to common/src/common/block/BlockGlowstone.java diff --git a/java/src/common/block/BlockGrass.java b/common/src/common/block/BlockGrass.java similarity index 100% rename from java/src/common/block/BlockGrass.java rename to common/src/common/block/BlockGrass.java diff --git a/java/src/common/block/BlockGravel.java b/common/src/common/block/BlockGravel.java similarity index 100% rename from java/src/common/block/BlockGravel.java rename to common/src/common/block/BlockGravel.java diff --git a/java/src/common/block/BlockHardenedClay.java b/common/src/common/block/BlockHardenedClay.java similarity index 100% rename from java/src/common/block/BlockHardenedClay.java rename to common/src/common/block/BlockHardenedClay.java diff --git a/java/src/common/block/BlockHay.java b/common/src/common/block/BlockHay.java similarity index 100% rename from java/src/common/block/BlockHay.java rename to common/src/common/block/BlockHay.java diff --git a/java/src/common/block/BlockHellRock.java b/common/src/common/block/BlockHellRock.java similarity index 100% rename from java/src/common/block/BlockHellRock.java rename to common/src/common/block/BlockHellRock.java diff --git a/java/src/common/block/BlockHopper.java b/common/src/common/block/BlockHopper.java similarity index 100% rename from java/src/common/block/BlockHopper.java rename to common/src/common/block/BlockHopper.java diff --git a/java/src/common/block/BlockHugeMushroom.java b/common/src/common/block/BlockHugeMushroom.java similarity index 100% rename from java/src/common/block/BlockHugeMushroom.java rename to common/src/common/block/BlockHugeMushroom.java diff --git a/java/src/common/block/BlockIce.java b/common/src/common/block/BlockIce.java similarity index 100% rename from java/src/common/block/BlockIce.java rename to common/src/common/block/BlockIce.java diff --git a/java/src/common/block/BlockJukebox.java b/common/src/common/block/BlockJukebox.java similarity index 100% rename from java/src/common/block/BlockJukebox.java rename to common/src/common/block/BlockJukebox.java diff --git a/java/src/common/block/BlockLadder.java b/common/src/common/block/BlockLadder.java similarity index 100% rename from java/src/common/block/BlockLadder.java rename to common/src/common/block/BlockLadder.java diff --git a/java/src/common/block/BlockLeaves.java b/common/src/common/block/BlockLeaves.java similarity index 100% rename from java/src/common/block/BlockLeaves.java rename to common/src/common/block/BlockLeaves.java diff --git a/java/src/common/block/BlockLeavesBase.java b/common/src/common/block/BlockLeavesBase.java similarity index 100% rename from java/src/common/block/BlockLeavesBase.java rename to common/src/common/block/BlockLeavesBase.java diff --git a/java/src/common/block/BlockLever.java b/common/src/common/block/BlockLever.java similarity index 100% rename from java/src/common/block/BlockLever.java rename to common/src/common/block/BlockLever.java diff --git a/java/src/common/block/BlockLilyPad.java b/common/src/common/block/BlockLilyPad.java similarity index 100% rename from java/src/common/block/BlockLilyPad.java rename to common/src/common/block/BlockLilyPad.java diff --git a/java/src/common/block/BlockLiquid.java b/common/src/common/block/BlockLiquid.java similarity index 100% rename from java/src/common/block/BlockLiquid.java rename to common/src/common/block/BlockLiquid.java diff --git a/java/src/common/block/BlockLog.java b/common/src/common/block/BlockLog.java similarity index 100% rename from java/src/common/block/BlockLog.java rename to common/src/common/block/BlockLog.java diff --git a/java/src/common/block/BlockMachine.java b/common/src/common/block/BlockMachine.java similarity index 100% rename from java/src/common/block/BlockMachine.java rename to common/src/common/block/BlockMachine.java diff --git a/java/src/common/block/BlockMelon.java b/common/src/common/block/BlockMelon.java similarity index 100% rename from java/src/common/block/BlockMelon.java rename to common/src/common/block/BlockMelon.java diff --git a/java/src/common/block/BlockMobSpawner.java b/common/src/common/block/BlockMobSpawner.java similarity index 100% rename from java/src/common/block/BlockMobSpawner.java rename to common/src/common/block/BlockMobSpawner.java diff --git a/java/src/common/block/BlockMushroom.java b/common/src/common/block/BlockMushroom.java similarity index 100% rename from java/src/common/block/BlockMushroom.java rename to common/src/common/block/BlockMushroom.java diff --git a/java/src/common/block/BlockMycelium.java b/common/src/common/block/BlockMycelium.java similarity index 100% rename from java/src/common/block/BlockMycelium.java rename to common/src/common/block/BlockMycelium.java diff --git a/java/src/common/block/BlockNote.java b/common/src/common/block/BlockNote.java similarity index 100% rename from java/src/common/block/BlockNote.java rename to common/src/common/block/BlockNote.java diff --git a/java/src/common/block/BlockNuke.java b/common/src/common/block/BlockNuke.java similarity index 100% rename from java/src/common/block/BlockNuke.java rename to common/src/common/block/BlockNuke.java diff --git a/java/src/common/block/BlockObsidian.java b/common/src/common/block/BlockObsidian.java similarity index 100% rename from java/src/common/block/BlockObsidian.java rename to common/src/common/block/BlockObsidian.java diff --git a/java/src/common/block/BlockOre.java b/common/src/common/block/BlockOre.java similarity index 100% rename from java/src/common/block/BlockOre.java rename to common/src/common/block/BlockOre.java diff --git a/java/src/common/block/BlockPackedIce.java b/common/src/common/block/BlockPackedIce.java similarity index 100% rename from java/src/common/block/BlockPackedIce.java rename to common/src/common/block/BlockPackedIce.java diff --git a/java/src/common/block/BlockPane.java b/common/src/common/block/BlockPane.java similarity index 100% rename from java/src/common/block/BlockPane.java rename to common/src/common/block/BlockPane.java diff --git a/java/src/common/block/BlockPistonBase.java b/common/src/common/block/BlockPistonBase.java similarity index 100% rename from java/src/common/block/BlockPistonBase.java rename to common/src/common/block/BlockPistonBase.java diff --git a/java/src/common/block/BlockPistonHead.java b/common/src/common/block/BlockPistonHead.java similarity index 100% rename from java/src/common/block/BlockPistonHead.java rename to common/src/common/block/BlockPistonHead.java diff --git a/java/src/common/block/BlockPistonMoving.java b/common/src/common/block/BlockPistonMoving.java similarity index 100% rename from java/src/common/block/BlockPistonMoving.java rename to common/src/common/block/BlockPistonMoving.java diff --git a/java/src/common/block/BlockPortal.java b/common/src/common/block/BlockPortal.java similarity index 100% rename from java/src/common/block/BlockPortal.java rename to common/src/common/block/BlockPortal.java diff --git a/java/src/common/block/BlockPortalFrame.java b/common/src/common/block/BlockPortalFrame.java similarity index 100% rename from java/src/common/block/BlockPortalFrame.java rename to common/src/common/block/BlockPortalFrame.java diff --git a/java/src/common/block/BlockPotato.java b/common/src/common/block/BlockPotato.java similarity index 100% rename from java/src/common/block/BlockPotato.java rename to common/src/common/block/BlockPotato.java diff --git a/java/src/common/block/BlockPressurePlate.java b/common/src/common/block/BlockPressurePlate.java similarity index 100% rename from java/src/common/block/BlockPressurePlate.java rename to common/src/common/block/BlockPressurePlate.java diff --git a/java/src/common/block/BlockPressurePlateWeighted.java b/common/src/common/block/BlockPressurePlateWeighted.java similarity index 100% rename from java/src/common/block/BlockPressurePlateWeighted.java rename to common/src/common/block/BlockPressurePlateWeighted.java diff --git a/java/src/common/block/BlockPumpkin.java b/common/src/common/block/BlockPumpkin.java similarity index 100% rename from java/src/common/block/BlockPumpkin.java rename to common/src/common/block/BlockPumpkin.java diff --git a/java/src/common/block/BlockQuartz.java b/common/src/common/block/BlockQuartz.java similarity index 100% rename from java/src/common/block/BlockQuartz.java rename to common/src/common/block/BlockQuartz.java diff --git a/java/src/common/block/BlockRail.java b/common/src/common/block/BlockRail.java similarity index 100% rename from java/src/common/block/BlockRail.java rename to common/src/common/block/BlockRail.java diff --git a/java/src/common/block/BlockRailBase.java b/common/src/common/block/BlockRailBase.java similarity index 100% rename from java/src/common/block/BlockRailBase.java rename to common/src/common/block/BlockRailBase.java diff --git a/java/src/common/block/BlockRailDetector.java b/common/src/common/block/BlockRailDetector.java similarity index 100% rename from java/src/common/block/BlockRailDetector.java rename to common/src/common/block/BlockRailDetector.java diff --git a/java/src/common/block/BlockRailPowered.java b/common/src/common/block/BlockRailPowered.java similarity index 100% rename from java/src/common/block/BlockRailPowered.java rename to common/src/common/block/BlockRailPowered.java diff --git a/java/src/common/block/BlockRedstoneComparator.java b/common/src/common/block/BlockRedstoneComparator.java similarity index 100% rename from java/src/common/block/BlockRedstoneComparator.java rename to common/src/common/block/BlockRedstoneComparator.java diff --git a/java/src/common/block/BlockRedstoneDiode.java b/common/src/common/block/BlockRedstoneDiode.java similarity index 100% rename from java/src/common/block/BlockRedstoneDiode.java rename to common/src/common/block/BlockRedstoneDiode.java diff --git a/java/src/common/block/BlockRedstoneLight.java b/common/src/common/block/BlockRedstoneLight.java similarity index 100% rename from java/src/common/block/BlockRedstoneLight.java rename to common/src/common/block/BlockRedstoneLight.java diff --git a/java/src/common/block/BlockRedstoneOre.java b/common/src/common/block/BlockRedstoneOre.java similarity index 100% rename from java/src/common/block/BlockRedstoneOre.java rename to common/src/common/block/BlockRedstoneOre.java diff --git a/java/src/common/block/BlockRedstoneRepeater.java b/common/src/common/block/BlockRedstoneRepeater.java similarity index 100% rename from java/src/common/block/BlockRedstoneRepeater.java rename to common/src/common/block/BlockRedstoneRepeater.java diff --git a/java/src/common/block/BlockRedstoneTorch.java b/common/src/common/block/BlockRedstoneTorch.java similarity index 100% rename from java/src/common/block/BlockRedstoneTorch.java rename to common/src/common/block/BlockRedstoneTorch.java diff --git a/java/src/common/block/BlockRedstoneWire.java b/common/src/common/block/BlockRedstoneWire.java similarity index 100% rename from java/src/common/block/BlockRedstoneWire.java rename to common/src/common/block/BlockRedstoneWire.java diff --git a/java/src/common/block/BlockReed.java b/common/src/common/block/BlockReed.java similarity index 100% rename from java/src/common/block/BlockReed.java rename to common/src/common/block/BlockReed.java diff --git a/java/src/common/block/BlockRock.java b/common/src/common/block/BlockRock.java similarity index 100% rename from java/src/common/block/BlockRock.java rename to common/src/common/block/BlockRock.java diff --git a/java/src/common/block/BlockRotatedPillar.java b/common/src/common/block/BlockRotatedPillar.java similarity index 100% rename from java/src/common/block/BlockRotatedPillar.java rename to common/src/common/block/BlockRotatedPillar.java diff --git a/java/src/common/block/BlockSand.java b/common/src/common/block/BlockSand.java similarity index 100% rename from java/src/common/block/BlockSand.java rename to common/src/common/block/BlockSand.java diff --git a/java/src/common/block/BlockSandStone.java b/common/src/common/block/BlockSandStone.java similarity index 100% rename from java/src/common/block/BlockSandStone.java rename to common/src/common/block/BlockSandStone.java diff --git a/java/src/common/block/BlockSapling.java b/common/src/common/block/BlockSapling.java similarity index 100% rename from java/src/common/block/BlockSapling.java rename to common/src/common/block/BlockSapling.java diff --git a/java/src/common/block/BlockSign.java b/common/src/common/block/BlockSign.java similarity index 100% rename from java/src/common/block/BlockSign.java rename to common/src/common/block/BlockSign.java diff --git a/java/src/common/block/BlockSkull.java b/common/src/common/block/BlockSkull.java similarity index 100% rename from java/src/common/block/BlockSkull.java rename to common/src/common/block/BlockSkull.java diff --git a/java/src/common/block/BlockSlab.java b/common/src/common/block/BlockSlab.java similarity index 100% rename from java/src/common/block/BlockSlab.java rename to common/src/common/block/BlockSlab.java diff --git a/java/src/common/block/BlockSlime.java b/common/src/common/block/BlockSlime.java similarity index 100% rename from java/src/common/block/BlockSlime.java rename to common/src/common/block/BlockSlime.java diff --git a/java/src/common/block/BlockSnow.java b/common/src/common/block/BlockSnow.java similarity index 100% rename from java/src/common/block/BlockSnow.java rename to common/src/common/block/BlockSnow.java diff --git a/java/src/common/block/BlockSnowBlock.java b/common/src/common/block/BlockSnowBlock.java similarity index 100% rename from java/src/common/block/BlockSnowBlock.java rename to common/src/common/block/BlockSnowBlock.java diff --git a/java/src/common/block/BlockSoulSand.java b/common/src/common/block/BlockSoulSand.java similarity index 100% rename from java/src/common/block/BlockSoulSand.java rename to common/src/common/block/BlockSoulSand.java diff --git a/java/src/common/block/BlockSourceImpl.java b/common/src/common/block/BlockSourceImpl.java similarity index 100% rename from java/src/common/block/BlockSourceImpl.java rename to common/src/common/block/BlockSourceImpl.java diff --git a/java/src/common/block/BlockStainedGlass.java b/common/src/common/block/BlockStainedGlass.java similarity index 100% rename from java/src/common/block/BlockStainedGlass.java rename to common/src/common/block/BlockStainedGlass.java diff --git a/java/src/common/block/BlockStainedGlassPane.java b/common/src/common/block/BlockStainedGlassPane.java similarity index 100% rename from java/src/common/block/BlockStainedGlassPane.java rename to common/src/common/block/BlockStainedGlassPane.java diff --git a/java/src/common/block/BlockStairs.java b/common/src/common/block/BlockStairs.java similarity index 100% rename from java/src/common/block/BlockStairs.java rename to common/src/common/block/BlockStairs.java diff --git a/java/src/common/block/BlockStandingSign.java b/common/src/common/block/BlockStandingSign.java similarity index 100% rename from java/src/common/block/BlockStandingSign.java rename to common/src/common/block/BlockStandingSign.java diff --git a/java/src/common/block/BlockStaticLiquid.java b/common/src/common/block/BlockStaticLiquid.java similarity index 100% rename from java/src/common/block/BlockStaticLiquid.java rename to common/src/common/block/BlockStaticLiquid.java diff --git a/java/src/common/block/BlockStem.java b/common/src/common/block/BlockStem.java similarity index 100% rename from java/src/common/block/BlockStem.java rename to common/src/common/block/BlockStem.java diff --git a/java/src/common/block/BlockStone.java b/common/src/common/block/BlockStone.java similarity index 100% rename from java/src/common/block/BlockStone.java rename to common/src/common/block/BlockStone.java diff --git a/java/src/common/block/BlockStoneBrick.java b/common/src/common/block/BlockStoneBrick.java similarity index 100% rename from java/src/common/block/BlockStoneBrick.java rename to common/src/common/block/BlockStoneBrick.java diff --git a/java/src/common/block/BlockTNT.java b/common/src/common/block/BlockTNT.java similarity index 100% rename from java/src/common/block/BlockTNT.java rename to common/src/common/block/BlockTNT.java diff --git a/java/src/common/block/BlockTallGrass.java b/common/src/common/block/BlockTallGrass.java similarity index 100% rename from java/src/common/block/BlockTallGrass.java rename to common/src/common/block/BlockTallGrass.java diff --git a/java/src/common/block/BlockTianReactor.java b/common/src/common/block/BlockTianReactor.java similarity index 100% rename from java/src/common/block/BlockTianReactor.java rename to common/src/common/block/BlockTianReactor.java diff --git a/java/src/common/block/BlockTianSoil.java b/common/src/common/block/BlockTianSoil.java similarity index 100% rename from java/src/common/block/BlockTianSoil.java rename to common/src/common/block/BlockTianSoil.java diff --git a/java/src/common/block/BlockTorch.java b/common/src/common/block/BlockTorch.java similarity index 100% rename from java/src/common/block/BlockTorch.java rename to common/src/common/block/BlockTorch.java diff --git a/java/src/common/block/BlockTrapDoor.java b/common/src/common/block/BlockTrapDoor.java similarity index 100% rename from java/src/common/block/BlockTrapDoor.java rename to common/src/common/block/BlockTrapDoor.java diff --git a/java/src/common/block/BlockTreasure.java b/common/src/common/block/BlockTreasure.java similarity index 100% rename from java/src/common/block/BlockTreasure.java rename to common/src/common/block/BlockTreasure.java diff --git a/java/src/common/block/BlockTripWire.java b/common/src/common/block/BlockTripWire.java similarity index 100% rename from java/src/common/block/BlockTripWire.java rename to common/src/common/block/BlockTripWire.java diff --git a/java/src/common/block/BlockTripWireHook.java b/common/src/common/block/BlockTripWireHook.java similarity index 100% rename from java/src/common/block/BlockTripWireHook.java rename to common/src/common/block/BlockTripWireHook.java diff --git a/java/src/common/block/BlockVine.java b/common/src/common/block/BlockVine.java similarity index 100% rename from java/src/common/block/BlockVine.java rename to common/src/common/block/BlockVine.java diff --git a/java/src/common/block/BlockWall.java b/common/src/common/block/BlockWall.java similarity index 100% rename from java/src/common/block/BlockWall.java rename to common/src/common/block/BlockWall.java diff --git a/java/src/common/block/BlockWallSign.java b/common/src/common/block/BlockWallSign.java similarity index 100% rename from java/src/common/block/BlockWallSign.java rename to common/src/common/block/BlockWallSign.java diff --git a/java/src/common/block/BlockWarpChest.java b/common/src/common/block/BlockWarpChest.java similarity index 100% rename from java/src/common/block/BlockWarpChest.java rename to common/src/common/block/BlockWarpChest.java diff --git a/java/src/common/block/BlockWart.java b/common/src/common/block/BlockWart.java similarity index 100% rename from java/src/common/block/BlockWart.java rename to common/src/common/block/BlockWart.java diff --git a/java/src/common/block/BlockWeb.java b/common/src/common/block/BlockWeb.java similarity index 100% rename from java/src/common/block/BlockWeb.java rename to common/src/common/block/BlockWeb.java diff --git a/java/src/common/block/BlockWorkbench.java b/common/src/common/block/BlockWorkbench.java similarity index 100% rename from java/src/common/block/BlockWorkbench.java rename to common/src/common/block/BlockWorkbench.java diff --git a/java/src/common/block/IGrowable.java b/common/src/common/block/IGrowable.java similarity index 100% rename from java/src/common/block/IGrowable.java rename to common/src/common/block/IGrowable.java diff --git a/java/src/common/block/ITileEntityProvider.java b/common/src/common/block/ITileEntityProvider.java similarity index 100% rename from java/src/common/block/ITileEntityProvider.java rename to common/src/common/block/ITileEntityProvider.java diff --git a/java/src/common/block/LeavesType.java b/common/src/common/block/LeavesType.java similarity index 100% rename from java/src/common/block/LeavesType.java rename to common/src/common/block/LeavesType.java diff --git a/java/src/common/block/SoundType.java b/common/src/common/block/SoundType.java similarity index 100% rename from java/src/common/block/SoundType.java rename to common/src/common/block/SoundType.java diff --git a/java/src/common/clipboard/BlockTransform.java b/common/src/common/clipboard/BlockTransform.java similarity index 100% rename from java/src/common/clipboard/BlockTransform.java rename to common/src/common/clipboard/BlockTransform.java diff --git a/java/src/common/clipboard/ClipboardBlock.java b/common/src/common/clipboard/ClipboardBlock.java similarity index 100% rename from java/src/common/clipboard/ClipboardBlock.java rename to common/src/common/clipboard/ClipboardBlock.java diff --git a/java/src/common/clipboard/ClipboardPlacer.java b/common/src/common/clipboard/ClipboardPlacer.java similarity index 100% rename from java/src/common/clipboard/ClipboardPlacer.java rename to common/src/common/clipboard/ClipboardPlacer.java diff --git a/java/src/common/clipboard/Rotation.java b/common/src/common/clipboard/Rotation.java similarity index 100% rename from java/src/common/clipboard/Rotation.java rename to common/src/common/clipboard/Rotation.java diff --git a/java/src/common/clipboard/RotationValue.java b/common/src/common/clipboard/RotationValue.java similarity index 100% rename from java/src/common/clipboard/RotationValue.java rename to common/src/common/clipboard/RotationValue.java diff --git a/java/src/common/clipboard/Vector.java b/common/src/common/clipboard/Vector.java similarity index 100% rename from java/src/common/clipboard/Vector.java rename to common/src/common/clipboard/Vector.java diff --git a/java/src/common/collect/AbstractBiMap.java b/common/src/common/collect/AbstractBiMap.java similarity index 100% rename from java/src/common/collect/AbstractBiMap.java rename to common/src/common/collect/AbstractBiMap.java diff --git a/java/src/common/collect/AbstractIndexedListIterator.java b/common/src/common/collect/AbstractIndexedListIterator.java similarity index 100% rename from java/src/common/collect/AbstractIndexedListIterator.java rename to common/src/common/collect/AbstractIndexedListIterator.java diff --git a/java/src/common/collect/AbstractIterator.java b/common/src/common/collect/AbstractIterator.java similarity index 100% rename from java/src/common/collect/AbstractIterator.java rename to common/src/common/collect/AbstractIterator.java diff --git a/java/src/common/collect/AbstractMapEntry.java b/common/src/common/collect/AbstractMapEntry.java similarity index 100% rename from java/src/common/collect/AbstractMapEntry.java rename to common/src/common/collect/AbstractMapEntry.java diff --git a/java/src/common/collect/AbstractTable.java b/common/src/common/collect/AbstractTable.java similarity index 100% rename from java/src/common/collect/AbstractTable.java rename to common/src/common/collect/AbstractTable.java diff --git a/java/src/common/collect/BiMap.java b/common/src/common/collect/BiMap.java similarity index 100% rename from java/src/common/collect/BiMap.java rename to common/src/common/collect/BiMap.java diff --git a/java/src/common/collect/CollectPreconditions.java b/common/src/common/collect/CollectPreconditions.java similarity index 100% rename from java/src/common/collect/CollectPreconditions.java rename to common/src/common/collect/CollectPreconditions.java diff --git a/java/src/common/collect/DenseImmutableTable.java b/common/src/common/collect/DenseImmutableTable.java similarity index 100% rename from java/src/common/collect/DenseImmutableTable.java rename to common/src/common/collect/DenseImmutableTable.java diff --git a/java/src/common/collect/EmptyImmutableMap.java b/common/src/common/collect/EmptyImmutableMap.java similarity index 100% rename from java/src/common/collect/EmptyImmutableMap.java rename to common/src/common/collect/EmptyImmutableMap.java diff --git a/java/src/common/collect/EmptyImmutableSet.java b/common/src/common/collect/EmptyImmutableSet.java similarity index 100% rename from java/src/common/collect/EmptyImmutableSet.java rename to common/src/common/collect/EmptyImmutableSet.java diff --git a/java/src/common/collect/Filter.java b/common/src/common/collect/Filter.java similarity index 100% rename from java/src/common/collect/Filter.java rename to common/src/common/collect/Filter.java diff --git a/java/src/common/collect/ForwardingCollection.java b/common/src/common/collect/ForwardingCollection.java similarity index 100% rename from java/src/common/collect/ForwardingCollection.java rename to common/src/common/collect/ForwardingCollection.java diff --git a/java/src/common/collect/ForwardingMap.java b/common/src/common/collect/ForwardingMap.java similarity index 100% rename from java/src/common/collect/ForwardingMap.java rename to common/src/common/collect/ForwardingMap.java diff --git a/java/src/common/collect/ForwardingMapEntry.java b/common/src/common/collect/ForwardingMapEntry.java similarity index 100% rename from java/src/common/collect/ForwardingMapEntry.java rename to common/src/common/collect/ForwardingMapEntry.java diff --git a/java/src/common/collect/ForwardingObject.java b/common/src/common/collect/ForwardingObject.java similarity index 100% rename from java/src/common/collect/ForwardingObject.java rename to common/src/common/collect/ForwardingObject.java diff --git a/java/src/common/collect/ForwardingSet.java b/common/src/common/collect/ForwardingSet.java similarity index 100% rename from java/src/common/collect/ForwardingSet.java rename to common/src/common/collect/ForwardingSet.java diff --git a/java/src/common/collect/HashBiMap.java b/common/src/common/collect/HashBiMap.java similarity index 100% rename from java/src/common/collect/HashBiMap.java rename to common/src/common/collect/HashBiMap.java diff --git a/java/src/common/collect/Hashing.java b/common/src/common/collect/Hashing.java similarity index 100% rename from java/src/common/collect/Hashing.java rename to common/src/common/collect/Hashing.java diff --git a/java/src/common/collect/ImmutableAsList.java b/common/src/common/collect/ImmutableAsList.java similarity index 100% rename from java/src/common/collect/ImmutableAsList.java rename to common/src/common/collect/ImmutableAsList.java diff --git a/java/src/common/collect/ImmutableCollection.java b/common/src/common/collect/ImmutableCollection.java similarity index 100% rename from java/src/common/collect/ImmutableCollection.java rename to common/src/common/collect/ImmutableCollection.java diff --git a/java/src/common/collect/ImmutableEntry.java b/common/src/common/collect/ImmutableEntry.java similarity index 100% rename from java/src/common/collect/ImmutableEntry.java rename to common/src/common/collect/ImmutableEntry.java diff --git a/java/src/common/collect/ImmutableEnumMap.java b/common/src/common/collect/ImmutableEnumMap.java similarity index 100% rename from java/src/common/collect/ImmutableEnumMap.java rename to common/src/common/collect/ImmutableEnumMap.java diff --git a/java/src/common/collect/ImmutableEnumSet.java b/common/src/common/collect/ImmutableEnumSet.java similarity index 100% rename from java/src/common/collect/ImmutableEnumSet.java rename to common/src/common/collect/ImmutableEnumSet.java diff --git a/java/src/common/collect/ImmutableList.java b/common/src/common/collect/ImmutableList.java similarity index 100% rename from java/src/common/collect/ImmutableList.java rename to common/src/common/collect/ImmutableList.java diff --git a/java/src/common/collect/ImmutableMap.java b/common/src/common/collect/ImmutableMap.java similarity index 100% rename from java/src/common/collect/ImmutableMap.java rename to common/src/common/collect/ImmutableMap.java diff --git a/java/src/common/collect/ImmutableMapEntry.java b/common/src/common/collect/ImmutableMapEntry.java similarity index 100% rename from java/src/common/collect/ImmutableMapEntry.java rename to common/src/common/collect/ImmutableMapEntry.java diff --git a/java/src/common/collect/ImmutableMapEntrySet.java b/common/src/common/collect/ImmutableMapEntrySet.java similarity index 100% rename from java/src/common/collect/ImmutableMapEntrySet.java rename to common/src/common/collect/ImmutableMapEntrySet.java diff --git a/java/src/common/collect/ImmutableMapKeySet.java b/common/src/common/collect/ImmutableMapKeySet.java similarity index 100% rename from java/src/common/collect/ImmutableMapKeySet.java rename to common/src/common/collect/ImmutableMapKeySet.java diff --git a/java/src/common/collect/ImmutableMapValues.java b/common/src/common/collect/ImmutableMapValues.java similarity index 100% rename from java/src/common/collect/ImmutableMapValues.java rename to common/src/common/collect/ImmutableMapValues.java diff --git a/java/src/common/collect/ImmutableSet.java b/common/src/common/collect/ImmutableSet.java similarity index 100% rename from java/src/common/collect/ImmutableSet.java rename to common/src/common/collect/ImmutableSet.java diff --git a/java/src/common/collect/ImmutableTable.java b/common/src/common/collect/ImmutableTable.java similarity index 100% rename from java/src/common/collect/ImmutableTable.java rename to common/src/common/collect/ImmutableTable.java diff --git a/java/src/common/collect/Iterables.java b/common/src/common/collect/Iterables.java similarity index 100% rename from java/src/common/collect/Iterables.java rename to common/src/common/collect/Iterables.java diff --git a/java/src/common/collect/Iterators.java b/common/src/common/collect/Iterators.java similarity index 100% rename from java/src/common/collect/Iterators.java rename to common/src/common/collect/Iterators.java diff --git a/java/src/common/collect/Lists.java b/common/src/common/collect/Lists.java similarity index 100% rename from java/src/common/collect/Lists.java rename to common/src/common/collect/Lists.java diff --git a/java/src/common/collect/Maps.java b/common/src/common/collect/Maps.java similarity index 100% rename from java/src/common/collect/Maps.java rename to common/src/common/collect/Maps.java diff --git a/java/src/common/collect/ObjectArrays.java b/common/src/common/collect/ObjectArrays.java similarity index 100% rename from java/src/common/collect/ObjectArrays.java rename to common/src/common/collect/ObjectArrays.java diff --git a/java/src/common/collect/Preconditions.java b/common/src/common/collect/Preconditions.java similarity index 100% rename from java/src/common/collect/Preconditions.java rename to common/src/common/collect/Preconditions.java diff --git a/java/src/common/collect/RegularImmutableAsList.java b/common/src/common/collect/RegularImmutableAsList.java similarity index 100% rename from java/src/common/collect/RegularImmutableAsList.java rename to common/src/common/collect/RegularImmutableAsList.java diff --git a/java/src/common/collect/RegularImmutableList.java b/common/src/common/collect/RegularImmutableList.java similarity index 100% rename from java/src/common/collect/RegularImmutableList.java rename to common/src/common/collect/RegularImmutableList.java diff --git a/java/src/common/collect/RegularImmutableMap.java b/common/src/common/collect/RegularImmutableMap.java similarity index 100% rename from java/src/common/collect/RegularImmutableMap.java rename to common/src/common/collect/RegularImmutableMap.java diff --git a/java/src/common/collect/RegularImmutableSet.java b/common/src/common/collect/RegularImmutableSet.java similarity index 100% rename from java/src/common/collect/RegularImmutableSet.java rename to common/src/common/collect/RegularImmutableSet.java diff --git a/java/src/common/collect/RegularImmutableTable.java b/common/src/common/collect/RegularImmutableTable.java similarity index 100% rename from java/src/common/collect/RegularImmutableTable.java rename to common/src/common/collect/RegularImmutableTable.java diff --git a/java/src/common/collect/Sets.java b/common/src/common/collect/Sets.java similarity index 100% rename from java/src/common/collect/Sets.java rename to common/src/common/collect/Sets.java diff --git a/java/src/common/collect/SparseImmutableTable.java b/common/src/common/collect/SparseImmutableTable.java similarity index 100% rename from java/src/common/collect/SparseImmutableTable.java rename to common/src/common/collect/SparseImmutableTable.java diff --git a/java/src/common/collect/StandardTable.java b/common/src/common/collect/StandardTable.java similarity index 100% rename from java/src/common/collect/StandardTable.java rename to common/src/common/collect/StandardTable.java diff --git a/java/src/common/collect/Table.java b/common/src/common/collect/Table.java similarity index 100% rename from java/src/common/collect/Table.java rename to common/src/common/collect/Table.java diff --git a/java/src/common/collect/TransformedIterator.java b/common/src/common/collect/TransformedIterator.java similarity index 100% rename from java/src/common/collect/TransformedIterator.java rename to common/src/common/collect/TransformedIterator.java diff --git a/java/src/common/collect/UnmodifiableIterator.java b/common/src/common/collect/UnmodifiableIterator.java similarity index 100% rename from java/src/common/collect/UnmodifiableIterator.java rename to common/src/common/collect/UnmodifiableIterator.java diff --git a/java/src/common/collect/UnmodifiableListIterator.java b/common/src/common/collect/UnmodifiableListIterator.java similarity index 100% rename from java/src/common/collect/UnmodifiableListIterator.java rename to common/src/common/collect/UnmodifiableListIterator.java diff --git a/java/src/common/color/Colorizer.java b/common/src/common/color/Colorizer.java similarity index 100% rename from java/src/common/color/Colorizer.java rename to common/src/common/color/Colorizer.java diff --git a/java/src/common/color/DyeColor.java b/common/src/common/color/DyeColor.java similarity index 100% rename from java/src/common/color/DyeColor.java rename to common/src/common/color/DyeColor.java diff --git a/java/src/common/color/TextColor.java b/common/src/common/color/TextColor.java similarity index 100% rename from java/src/common/color/TextColor.java rename to common/src/common/color/TextColor.java diff --git a/java/src/common/dimension/Area.java b/common/src/common/dimension/Area.java similarity index 100% rename from java/src/common/dimension/Area.java rename to common/src/common/dimension/Area.java diff --git a/java/src/common/dimension/DimType.java b/common/src/common/dimension/DimType.java similarity index 100% rename from java/src/common/dimension/DimType.java rename to common/src/common/dimension/DimType.java diff --git a/java/src/common/dimension/Dimension.java b/common/src/common/dimension/Dimension.java similarity index 100% rename from java/src/common/dimension/Dimension.java rename to common/src/common/dimension/Dimension.java diff --git a/java/src/common/dimension/Domain.java b/common/src/common/dimension/Domain.java similarity index 100% rename from java/src/common/dimension/Domain.java rename to common/src/common/dimension/Domain.java diff --git a/java/src/common/dimension/Galaxy.java b/common/src/common/dimension/Galaxy.java similarity index 100% rename from java/src/common/dimension/Galaxy.java rename to common/src/common/dimension/Galaxy.java diff --git a/java/src/common/dimension/Moon.java b/common/src/common/dimension/Moon.java similarity index 100% rename from java/src/common/dimension/Moon.java rename to common/src/common/dimension/Moon.java diff --git a/java/src/common/dimension/Nameable.java b/common/src/common/dimension/Nameable.java similarity index 100% rename from java/src/common/dimension/Nameable.java rename to common/src/common/dimension/Nameable.java diff --git a/java/src/common/dimension/Planet.java b/common/src/common/dimension/Planet.java similarity index 100% rename from java/src/common/dimension/Planet.java rename to common/src/common/dimension/Planet.java diff --git a/java/src/common/dimension/Sector.java b/common/src/common/dimension/Sector.java similarity index 100% rename from java/src/common/dimension/Sector.java rename to common/src/common/dimension/Sector.java diff --git a/java/src/common/dimension/Semi.java b/common/src/common/dimension/Semi.java similarity index 100% rename from java/src/common/dimension/Semi.java rename to common/src/common/dimension/Semi.java diff --git a/java/src/common/dimension/Space.java b/common/src/common/dimension/Space.java similarity index 100% rename from java/src/common/dimension/Space.java rename to common/src/common/dimension/Space.java diff --git a/java/src/common/dimension/Star.java b/common/src/common/dimension/Star.java similarity index 100% rename from java/src/common/dimension/Star.java rename to common/src/common/dimension/Star.java diff --git a/java/src/common/dispenser/BehaviorDefaultDispenseItem.java b/common/src/common/dispenser/BehaviorDefaultDispenseItem.java similarity index 100% rename from java/src/common/dispenser/BehaviorDefaultDispenseItem.java rename to common/src/common/dispenser/BehaviorDefaultDispenseItem.java diff --git a/java/src/common/dispenser/BehaviorProjectileDispense.java b/common/src/common/dispenser/BehaviorProjectileDispense.java similarity index 100% rename from java/src/common/dispenser/BehaviorProjectileDispense.java rename to common/src/common/dispenser/BehaviorProjectileDispense.java diff --git a/java/src/common/dispenser/IBehaviorDispenseItem.java b/common/src/common/dispenser/IBehaviorDispenseItem.java similarity index 100% rename from java/src/common/dispenser/IBehaviorDispenseItem.java rename to common/src/common/dispenser/IBehaviorDispenseItem.java diff --git a/java/src/common/dispenser/IBlockSource.java b/common/src/common/dispenser/IBlockSource.java similarity index 100% rename from java/src/common/dispenser/IBlockSource.java rename to common/src/common/dispenser/IBlockSource.java diff --git a/java/src/common/dispenser/ILocatableSource.java b/common/src/common/dispenser/ILocatableSource.java similarity index 100% rename from java/src/common/dispenser/ILocatableSource.java rename to common/src/common/dispenser/ILocatableSource.java diff --git a/java/src/common/dispenser/ILocation.java b/common/src/common/dispenser/ILocation.java similarity index 100% rename from java/src/common/dispenser/ILocation.java rename to common/src/common/dispenser/ILocation.java diff --git a/java/src/common/dispenser/IPosition.java b/common/src/common/dispenser/IPosition.java similarity index 100% rename from java/src/common/dispenser/IPosition.java rename to common/src/common/dispenser/IPosition.java diff --git a/java/src/common/dispenser/PositionImpl.java b/common/src/common/dispenser/PositionImpl.java similarity index 100% rename from java/src/common/dispenser/PositionImpl.java rename to common/src/common/dispenser/PositionImpl.java diff --git a/java/src/common/enchantment/Enchantment.java b/common/src/common/enchantment/Enchantment.java similarity index 100% rename from java/src/common/enchantment/Enchantment.java rename to common/src/common/enchantment/Enchantment.java diff --git a/java/src/common/enchantment/EnchantmentArrowDamage.java b/common/src/common/enchantment/EnchantmentArrowDamage.java similarity index 100% rename from java/src/common/enchantment/EnchantmentArrowDamage.java rename to common/src/common/enchantment/EnchantmentArrowDamage.java diff --git a/java/src/common/enchantment/EnchantmentArrowFire.java b/common/src/common/enchantment/EnchantmentArrowFire.java similarity index 100% rename from java/src/common/enchantment/EnchantmentArrowFire.java rename to common/src/common/enchantment/EnchantmentArrowFire.java diff --git a/java/src/common/enchantment/EnchantmentArrowInfinite.java b/common/src/common/enchantment/EnchantmentArrowInfinite.java similarity index 100% rename from java/src/common/enchantment/EnchantmentArrowInfinite.java rename to common/src/common/enchantment/EnchantmentArrowInfinite.java diff --git a/java/src/common/enchantment/EnchantmentArrowKnockback.java b/common/src/common/enchantment/EnchantmentArrowKnockback.java similarity index 100% rename from java/src/common/enchantment/EnchantmentArrowKnockback.java rename to common/src/common/enchantment/EnchantmentArrowKnockback.java diff --git a/java/src/common/enchantment/EnchantmentDamage.java b/common/src/common/enchantment/EnchantmentDamage.java similarity index 100% rename from java/src/common/enchantment/EnchantmentDamage.java rename to common/src/common/enchantment/EnchantmentDamage.java diff --git a/java/src/common/enchantment/EnchantmentDigging.java b/common/src/common/enchantment/EnchantmentDigging.java similarity index 100% rename from java/src/common/enchantment/EnchantmentDigging.java rename to common/src/common/enchantment/EnchantmentDigging.java diff --git a/java/src/common/enchantment/EnchantmentDraining.java b/common/src/common/enchantment/EnchantmentDraining.java similarity index 100% rename from java/src/common/enchantment/EnchantmentDraining.java rename to common/src/common/enchantment/EnchantmentDraining.java diff --git a/java/src/common/enchantment/EnchantmentDurability.java b/common/src/common/enchantment/EnchantmentDurability.java similarity index 100% rename from java/src/common/enchantment/EnchantmentDurability.java rename to common/src/common/enchantment/EnchantmentDurability.java diff --git a/java/src/common/enchantment/EnchantmentFireAspect.java b/common/src/common/enchantment/EnchantmentFireAspect.java similarity index 100% rename from java/src/common/enchantment/EnchantmentFireAspect.java rename to common/src/common/enchantment/EnchantmentFireAspect.java diff --git a/java/src/common/enchantment/EnchantmentFishingSpeed.java b/common/src/common/enchantment/EnchantmentFishingSpeed.java similarity index 100% rename from java/src/common/enchantment/EnchantmentFishingSpeed.java rename to common/src/common/enchantment/EnchantmentFishingSpeed.java diff --git a/java/src/common/enchantment/EnchantmentHelper.java b/common/src/common/enchantment/EnchantmentHelper.java similarity index 100% rename from java/src/common/enchantment/EnchantmentHelper.java rename to common/src/common/enchantment/EnchantmentHelper.java diff --git a/java/src/common/enchantment/EnchantmentKnockback.java b/common/src/common/enchantment/EnchantmentKnockback.java similarity index 100% rename from java/src/common/enchantment/EnchantmentKnockback.java rename to common/src/common/enchantment/EnchantmentKnockback.java diff --git a/java/src/common/enchantment/EnchantmentLootBonus.java b/common/src/common/enchantment/EnchantmentLootBonus.java similarity index 100% rename from java/src/common/enchantment/EnchantmentLootBonus.java rename to common/src/common/enchantment/EnchantmentLootBonus.java diff --git a/java/src/common/enchantment/EnchantmentProtection.java b/common/src/common/enchantment/EnchantmentProtection.java similarity index 100% rename from java/src/common/enchantment/EnchantmentProtection.java rename to common/src/common/enchantment/EnchantmentProtection.java diff --git a/java/src/common/enchantment/EnchantmentThorns.java b/common/src/common/enchantment/EnchantmentThorns.java similarity index 100% rename from java/src/common/enchantment/EnchantmentThorns.java rename to common/src/common/enchantment/EnchantmentThorns.java diff --git a/java/src/common/enchantment/EnchantmentUntouching.java b/common/src/common/enchantment/EnchantmentUntouching.java similarity index 100% rename from java/src/common/enchantment/EnchantmentUntouching.java rename to common/src/common/enchantment/EnchantmentUntouching.java diff --git a/java/src/common/enchantment/EnumEnchantmentType.java b/common/src/common/enchantment/EnumEnchantmentType.java similarity index 100% rename from java/src/common/enchantment/EnumEnchantmentType.java rename to common/src/common/enchantment/EnumEnchantmentType.java diff --git a/java/src/common/enchantment/RngEnchantment.java b/common/src/common/enchantment/RngEnchantment.java similarity index 100% rename from java/src/common/enchantment/RngEnchantment.java rename to common/src/common/enchantment/RngEnchantment.java diff --git a/java/src/common/entity/DamageSource.java b/common/src/common/entity/DamageSource.java similarity index 100% rename from java/src/common/entity/DamageSource.java rename to common/src/common/entity/DamageSource.java diff --git a/java/src/common/entity/DataWatcher.java b/common/src/common/entity/DataWatcher.java similarity index 100% rename from java/src/common/entity/DataWatcher.java rename to common/src/common/entity/DataWatcher.java diff --git a/java/src/common/entity/Entity.java b/common/src/common/entity/Entity.java similarity index 100% rename from java/src/common/entity/Entity.java rename to common/src/common/entity/Entity.java diff --git a/java/src/common/entity/EntityDamageSource.java b/common/src/common/entity/EntityDamageSource.java similarity index 100% rename from java/src/common/entity/EntityDamageSource.java rename to common/src/common/entity/EntityDamageSource.java diff --git a/java/src/common/entity/EntityDamageSourceIndirect.java b/common/src/common/entity/EntityDamageSourceIndirect.java similarity index 100% rename from java/src/common/entity/EntityDamageSourceIndirect.java rename to common/src/common/entity/EntityDamageSourceIndirect.java diff --git a/java/src/common/entity/EntityTrackerEntry.java b/common/src/common/entity/EntityTrackerEntry.java similarity index 100% rename from java/src/common/entity/EntityTrackerEntry.java rename to common/src/common/entity/EntityTrackerEntry.java diff --git a/java/src/common/entity/EntityType.java b/common/src/common/entity/EntityType.java similarity index 100% rename from java/src/common/entity/EntityType.java rename to common/src/common/entity/EntityType.java diff --git a/java/src/common/entity/animal/EntityBat.java b/common/src/common/entity/animal/EntityBat.java similarity index 100% rename from java/src/common/entity/animal/EntityBat.java rename to common/src/common/entity/animal/EntityBat.java diff --git a/java/src/common/entity/animal/EntityChicken.java b/common/src/common/entity/animal/EntityChicken.java similarity index 100% rename from java/src/common/entity/animal/EntityChicken.java rename to common/src/common/entity/animal/EntityChicken.java diff --git a/java/src/common/entity/animal/EntityCow.java b/common/src/common/entity/animal/EntityCow.java similarity index 100% rename from java/src/common/entity/animal/EntityCow.java rename to common/src/common/entity/animal/EntityCow.java diff --git a/java/src/common/entity/animal/EntityDragon.java b/common/src/common/entity/animal/EntityDragon.java similarity index 100% rename from java/src/common/entity/animal/EntityDragon.java rename to common/src/common/entity/animal/EntityDragon.java diff --git a/java/src/common/entity/animal/EntityDragonPart.java b/common/src/common/entity/animal/EntityDragonPart.java similarity index 100% rename from java/src/common/entity/animal/EntityDragonPart.java rename to common/src/common/entity/animal/EntityDragonPart.java diff --git a/java/src/common/entity/animal/EntityHorse.java b/common/src/common/entity/animal/EntityHorse.java similarity index 100% rename from java/src/common/entity/animal/EntityHorse.java rename to common/src/common/entity/animal/EntityHorse.java diff --git a/java/src/common/entity/animal/EntityMooshroom.java b/common/src/common/entity/animal/EntityMooshroom.java similarity index 100% rename from java/src/common/entity/animal/EntityMooshroom.java rename to common/src/common/entity/animal/EntityMooshroom.java diff --git a/java/src/common/entity/animal/EntityMouse.java b/common/src/common/entity/animal/EntityMouse.java similarity index 100% rename from java/src/common/entity/animal/EntityMouse.java rename to common/src/common/entity/animal/EntityMouse.java diff --git a/java/src/common/entity/animal/EntityOcelot.java b/common/src/common/entity/animal/EntityOcelot.java similarity index 100% rename from java/src/common/entity/animal/EntityOcelot.java rename to common/src/common/entity/animal/EntityOcelot.java diff --git a/java/src/common/entity/animal/EntityPig.java b/common/src/common/entity/animal/EntityPig.java similarity index 100% rename from java/src/common/entity/animal/EntityPig.java rename to common/src/common/entity/animal/EntityPig.java diff --git a/java/src/common/entity/animal/EntityRabbit.java b/common/src/common/entity/animal/EntityRabbit.java similarity index 100% rename from java/src/common/entity/animal/EntityRabbit.java rename to common/src/common/entity/animal/EntityRabbit.java diff --git a/java/src/common/entity/animal/EntitySheep.java b/common/src/common/entity/animal/EntitySheep.java similarity index 100% rename from java/src/common/entity/animal/EntitySheep.java rename to common/src/common/entity/animal/EntitySheep.java diff --git a/java/src/common/entity/animal/EntitySquid.java b/common/src/common/entity/animal/EntitySquid.java similarity index 100% rename from java/src/common/entity/animal/EntitySquid.java rename to common/src/common/entity/animal/EntitySquid.java diff --git a/java/src/common/entity/animal/EntityWolf.java b/common/src/common/entity/animal/EntityWolf.java similarity index 100% rename from java/src/common/entity/animal/EntityWolf.java rename to common/src/common/entity/animal/EntityWolf.java diff --git a/java/src/common/entity/attributes/Attribute.java b/common/src/common/entity/attributes/Attribute.java similarity index 100% rename from java/src/common/entity/attributes/Attribute.java rename to common/src/common/entity/attributes/Attribute.java diff --git a/java/src/common/entity/attributes/AttributeInstance.java b/common/src/common/entity/attributes/AttributeInstance.java similarity index 100% rename from java/src/common/entity/attributes/AttributeInstance.java rename to common/src/common/entity/attributes/AttributeInstance.java diff --git a/java/src/common/entity/attributes/AttributeMap.java b/common/src/common/entity/attributes/AttributeMap.java similarity index 100% rename from java/src/common/entity/attributes/AttributeMap.java rename to common/src/common/entity/attributes/AttributeMap.java diff --git a/java/src/common/entity/attributes/AttributeModifier.java b/common/src/common/entity/attributes/AttributeModifier.java similarity index 100% rename from java/src/common/entity/attributes/AttributeModifier.java rename to common/src/common/entity/attributes/AttributeModifier.java diff --git a/java/src/common/entity/attributes/Attributes.java b/common/src/common/entity/attributes/Attributes.java similarity index 100% rename from java/src/common/entity/attributes/Attributes.java rename to common/src/common/entity/attributes/Attributes.java diff --git a/java/src/common/entity/attributes/LowerStringMap.java b/common/src/common/entity/attributes/LowerStringMap.java similarity index 100% rename from java/src/common/entity/attributes/LowerStringMap.java rename to common/src/common/entity/attributes/LowerStringMap.java diff --git a/java/src/common/entity/effect/EntityLightning.java b/common/src/common/entity/effect/EntityLightning.java similarity index 100% rename from java/src/common/entity/effect/EntityLightning.java rename to common/src/common/entity/effect/EntityLightning.java diff --git a/java/src/common/entity/item/EntityBoat.java b/common/src/common/entity/item/EntityBoat.java similarity index 100% rename from java/src/common/entity/item/EntityBoat.java rename to common/src/common/entity/item/EntityBoat.java diff --git a/java/src/common/entity/item/EntityCart.java b/common/src/common/entity/item/EntityCart.java similarity index 100% rename from java/src/common/entity/item/EntityCart.java rename to common/src/common/entity/item/EntityCart.java diff --git a/java/src/common/entity/item/EntityCartContainer.java b/common/src/common/entity/item/EntityCartContainer.java similarity index 100% rename from java/src/common/entity/item/EntityCartContainer.java rename to common/src/common/entity/item/EntityCartContainer.java diff --git a/java/src/common/entity/item/EntityChestCart.java b/common/src/common/entity/item/EntityChestCart.java similarity index 100% rename from java/src/common/entity/item/EntityChestCart.java rename to common/src/common/entity/item/EntityChestCart.java diff --git a/java/src/common/entity/item/EntityCrystal.java b/common/src/common/entity/item/EntityCrystal.java similarity index 100% rename from java/src/common/entity/item/EntityCrystal.java rename to common/src/common/entity/item/EntityCrystal.java diff --git a/java/src/common/entity/item/EntityExplosion.java b/common/src/common/entity/item/EntityExplosion.java similarity index 100% rename from java/src/common/entity/item/EntityExplosion.java rename to common/src/common/entity/item/EntityExplosion.java diff --git a/java/src/common/entity/item/EntityFalling.java b/common/src/common/entity/item/EntityFalling.java similarity index 100% rename from java/src/common/entity/item/EntityFalling.java rename to common/src/common/entity/item/EntityFalling.java diff --git a/java/src/common/entity/item/EntityFireworks.java b/common/src/common/entity/item/EntityFireworks.java similarity index 100% rename from java/src/common/entity/item/EntityFireworks.java rename to common/src/common/entity/item/EntityFireworks.java diff --git a/java/src/common/entity/item/EntityHopperCart.java b/common/src/common/entity/item/EntityHopperCart.java similarity index 100% rename from java/src/common/entity/item/EntityHopperCart.java rename to common/src/common/entity/item/EntityHopperCart.java diff --git a/java/src/common/entity/item/EntityItem.java b/common/src/common/entity/item/EntityItem.java similarity index 100% rename from java/src/common/entity/item/EntityItem.java rename to common/src/common/entity/item/EntityItem.java diff --git a/java/src/common/entity/item/EntityLeashKnot.java b/common/src/common/entity/item/EntityLeashKnot.java similarity index 100% rename from java/src/common/entity/item/EntityLeashKnot.java rename to common/src/common/entity/item/EntityLeashKnot.java diff --git a/java/src/common/entity/item/EntityMinecart.java b/common/src/common/entity/item/EntityMinecart.java similarity index 100% rename from java/src/common/entity/item/EntityMinecart.java rename to common/src/common/entity/item/EntityMinecart.java diff --git a/java/src/common/entity/item/EntityNuke.java b/common/src/common/entity/item/EntityNuke.java similarity index 100% rename from java/src/common/entity/item/EntityNuke.java rename to common/src/common/entity/item/EntityNuke.java diff --git a/java/src/common/entity/item/EntityOrb.java b/common/src/common/entity/item/EntityOrb.java similarity index 100% rename from java/src/common/entity/item/EntityOrb.java rename to common/src/common/entity/item/EntityOrb.java diff --git a/java/src/common/entity/item/EntityTnt.java b/common/src/common/entity/item/EntityTnt.java similarity index 100% rename from java/src/common/entity/item/EntityTnt.java rename to common/src/common/entity/item/EntityTnt.java diff --git a/java/src/common/entity/item/EntityTntCart.java b/common/src/common/entity/item/EntityTntCart.java similarity index 100% rename from java/src/common/entity/item/EntityTntCart.java rename to common/src/common/entity/item/EntityTntCart.java diff --git a/java/src/common/entity/item/EntityXp.java b/common/src/common/entity/item/EntityXp.java similarity index 100% rename from java/src/common/entity/item/EntityXp.java rename to common/src/common/entity/item/EntityXp.java diff --git a/java/src/common/entity/item/EntityXpBottle.java b/common/src/common/entity/item/EntityXpBottle.java similarity index 100% rename from java/src/common/entity/item/EntityXpBottle.java rename to common/src/common/entity/item/EntityXpBottle.java diff --git a/java/src/common/entity/npc/Alignment.java b/common/src/common/entity/npc/Alignment.java similarity index 100% rename from java/src/common/entity/npc/Alignment.java rename to common/src/common/entity/npc/Alignment.java diff --git a/java/src/common/entity/npc/CharacterInfo.java b/common/src/common/entity/npc/CharacterInfo.java similarity index 100% rename from java/src/common/entity/npc/CharacterInfo.java rename to common/src/common/entity/npc/CharacterInfo.java diff --git a/java/src/common/entity/npc/ClassInfo.java b/common/src/common/entity/npc/ClassInfo.java similarity index 100% rename from java/src/common/entity/npc/ClassInfo.java rename to common/src/common/entity/npc/ClassInfo.java diff --git a/java/src/common/entity/npc/Energy.java b/common/src/common/entity/npc/Energy.java similarity index 100% rename from java/src/common/entity/npc/Energy.java rename to common/src/common/entity/npc/Energy.java diff --git a/java/src/common/entity/npc/EntityArachnoid.java b/common/src/common/entity/npc/EntityArachnoid.java similarity index 100% rename from java/src/common/entity/npc/EntityArachnoid.java rename to common/src/common/entity/npc/EntityArachnoid.java diff --git a/java/src/common/entity/npc/EntityBloodElf.java b/common/src/common/entity/npc/EntityBloodElf.java similarity index 100% rename from java/src/common/entity/npc/EntityBloodElf.java rename to common/src/common/entity/npc/EntityBloodElf.java diff --git a/java/src/common/entity/npc/EntityChaosMarine.java b/common/src/common/entity/npc/EntityChaosMarine.java similarity index 100% rename from java/src/common/entity/npc/EntityChaosMarine.java rename to common/src/common/entity/npc/EntityChaosMarine.java diff --git a/java/src/common/entity/npc/EntityCpu.java b/common/src/common/entity/npc/EntityCpu.java similarity index 100% rename from java/src/common/entity/npc/EntityCpu.java rename to common/src/common/entity/npc/EntityCpu.java diff --git a/java/src/common/entity/npc/EntityCultivator.java b/common/src/common/entity/npc/EntityCultivator.java similarity index 100% rename from java/src/common/entity/npc/EntityCultivator.java rename to common/src/common/entity/npc/EntityCultivator.java diff --git a/java/src/common/entity/npc/EntityDarkMage.java b/common/src/common/entity/npc/EntityDarkMage.java similarity index 100% rename from java/src/common/entity/npc/EntityDarkMage.java rename to common/src/common/entity/npc/EntityDarkMage.java diff --git a/java/src/common/entity/npc/EntityDwarf.java b/common/src/common/entity/npc/EntityDwarf.java similarity index 100% rename from java/src/common/entity/npc/EntityDwarf.java rename to common/src/common/entity/npc/EntityDwarf.java diff --git a/java/src/common/entity/npc/EntityElf.java b/common/src/common/entity/npc/EntityElf.java similarity index 100% rename from java/src/common/entity/npc/EntityElf.java rename to common/src/common/entity/npc/EntityElf.java diff --git a/java/src/common/entity/npc/EntityFireDemon.java b/common/src/common/entity/npc/EntityFireDemon.java similarity index 100% rename from java/src/common/entity/npc/EntityFireDemon.java rename to common/src/common/entity/npc/EntityFireDemon.java diff --git a/java/src/common/entity/npc/EntityFlyingNPC.java b/common/src/common/entity/npc/EntityFlyingNPC.java similarity index 100% rename from java/src/common/entity/npc/EntityFlyingNPC.java rename to common/src/common/entity/npc/EntityFlyingNPC.java diff --git a/java/src/common/entity/npc/EntityGargoyle.java b/common/src/common/entity/npc/EntityGargoyle.java similarity index 100% rename from java/src/common/entity/npc/EntityGargoyle.java rename to common/src/common/entity/npc/EntityGargoyle.java diff --git a/java/src/common/entity/npc/EntityGoblin.java b/common/src/common/entity/npc/EntityGoblin.java similarity index 100% rename from java/src/common/entity/npc/EntityGoblin.java rename to common/src/common/entity/npc/EntityGoblin.java diff --git a/java/src/common/entity/npc/EntityHaunter.java b/common/src/common/entity/npc/EntityHaunter.java similarity index 100% rename from java/src/common/entity/npc/EntityHaunter.java rename to common/src/common/entity/npc/EntityHaunter.java diff --git a/java/src/common/entity/npc/EntityHoveringNPC.java b/common/src/common/entity/npc/EntityHoveringNPC.java similarity index 100% rename from java/src/common/entity/npc/EntityHoveringNPC.java rename to common/src/common/entity/npc/EntityHoveringNPC.java diff --git a/java/src/common/entity/npc/EntityHuman.java b/common/src/common/entity/npc/EntityHuman.java similarity index 100% rename from java/src/common/entity/npc/EntityHuman.java rename to common/src/common/entity/npc/EntityHuman.java diff --git a/java/src/common/entity/npc/EntityMage.java b/common/src/common/entity/npc/EntityMage.java similarity index 100% rename from java/src/common/entity/npc/EntityMage.java rename to common/src/common/entity/npc/EntityMage.java diff --git a/java/src/common/entity/npc/EntityMagma.java b/common/src/common/entity/npc/EntityMagma.java similarity index 100% rename from java/src/common/entity/npc/EntityMagma.java rename to common/src/common/entity/npc/EntityMagma.java diff --git a/java/src/common/entity/npc/EntityMetalhead.java b/common/src/common/entity/npc/EntityMetalhead.java similarity index 100% rename from java/src/common/entity/npc/EntityMetalhead.java rename to common/src/common/entity/npc/EntityMetalhead.java diff --git a/java/src/common/entity/npc/EntityMobNPC.java b/common/src/common/entity/npc/EntityMobNPC.java similarity index 100% rename from java/src/common/entity/npc/EntityMobNPC.java rename to common/src/common/entity/npc/EntityMobNPC.java diff --git a/java/src/common/entity/npc/EntityNPC.java b/common/src/common/entity/npc/EntityNPC.java similarity index 100% rename from java/src/common/entity/npc/EntityNPC.java rename to common/src/common/entity/npc/EntityNPC.java diff --git a/java/src/common/entity/npc/EntityOrc.java b/common/src/common/entity/npc/EntityOrc.java similarity index 100% rename from java/src/common/entity/npc/EntityOrc.java rename to common/src/common/entity/npc/EntityOrc.java diff --git a/java/src/common/entity/npc/EntityPrimarch.java b/common/src/common/entity/npc/EntityPrimarch.java similarity index 100% rename from java/src/common/entity/npc/EntityPrimarch.java rename to common/src/common/entity/npc/EntityPrimarch.java diff --git a/java/src/common/entity/npc/EntitySlime.java b/common/src/common/entity/npc/EntitySlime.java similarity index 100% rename from java/src/common/entity/npc/EntitySlime.java rename to common/src/common/entity/npc/EntitySlime.java diff --git a/java/src/common/entity/npc/EntitySpaceMarine.java b/common/src/common/entity/npc/EntitySpaceMarine.java similarity index 100% rename from java/src/common/entity/npc/EntitySpaceMarine.java rename to common/src/common/entity/npc/EntitySpaceMarine.java diff --git a/java/src/common/entity/npc/EntitySpirit.java b/common/src/common/entity/npc/EntitySpirit.java similarity index 100% rename from java/src/common/entity/npc/EntitySpirit.java rename to common/src/common/entity/npc/EntitySpirit.java diff --git a/java/src/common/entity/npc/EntityTiefling.java b/common/src/common/entity/npc/EntityTiefling.java similarity index 100% rename from java/src/common/entity/npc/EntityTiefling.java rename to common/src/common/entity/npc/EntityTiefling.java diff --git a/java/src/common/entity/npc/EntityUndead.java b/common/src/common/entity/npc/EntityUndead.java similarity index 100% rename from java/src/common/entity/npc/EntityUndead.java rename to common/src/common/entity/npc/EntityUndead.java diff --git a/java/src/common/entity/npc/EntityVampire.java b/common/src/common/entity/npc/EntityVampire.java similarity index 100% rename from java/src/common/entity/npc/EntityVampire.java rename to common/src/common/entity/npc/EntityVampire.java diff --git a/java/src/common/entity/npc/EntityWoodElf.java b/common/src/common/entity/npc/EntityWoodElf.java similarity index 100% rename from java/src/common/entity/npc/EntityWoodElf.java rename to common/src/common/entity/npc/EntityWoodElf.java diff --git a/java/src/common/entity/npc/EntityZombie.java b/common/src/common/entity/npc/EntityZombie.java similarity index 100% rename from java/src/common/entity/npc/EntityZombie.java rename to common/src/common/entity/npc/EntityZombie.java diff --git a/java/src/common/entity/npc/NpcInfo.java b/common/src/common/entity/npc/NpcInfo.java similarity index 100% rename from java/src/common/entity/npc/NpcInfo.java rename to common/src/common/entity/npc/NpcInfo.java diff --git a/java/src/common/entity/npc/PlayerCharacter.java b/common/src/common/entity/npc/PlayerCharacter.java similarity index 100% rename from java/src/common/entity/npc/PlayerCharacter.java rename to common/src/common/entity/npc/PlayerCharacter.java diff --git a/java/src/common/entity/npc/SpeciesInfo.java b/common/src/common/entity/npc/SpeciesInfo.java similarity index 100% rename from java/src/common/entity/npc/SpeciesInfo.java rename to common/src/common/entity/npc/SpeciesInfo.java diff --git a/java/src/common/entity/projectile/EntityArrow.java b/common/src/common/entity/projectile/EntityArrow.java similarity index 100% rename from java/src/common/entity/projectile/EntityArrow.java rename to common/src/common/entity/projectile/EntityArrow.java diff --git a/java/src/common/entity/projectile/EntityBox.java b/common/src/common/entity/projectile/EntityBox.java similarity index 100% rename from java/src/common/entity/projectile/EntityBox.java rename to common/src/common/entity/projectile/EntityBox.java diff --git a/java/src/common/entity/projectile/EntityBullet.java b/common/src/common/entity/projectile/EntityBullet.java similarity index 100% rename from java/src/common/entity/projectile/EntityBullet.java rename to common/src/common/entity/projectile/EntityBullet.java diff --git a/java/src/common/entity/projectile/EntityDie.java b/common/src/common/entity/projectile/EntityDie.java similarity index 100% rename from java/src/common/entity/projectile/EntityDie.java rename to common/src/common/entity/projectile/EntityDie.java diff --git a/java/src/common/entity/projectile/EntityDynamite.java b/common/src/common/entity/projectile/EntityDynamite.java similarity index 100% rename from java/src/common/entity/projectile/EntityDynamite.java rename to common/src/common/entity/projectile/EntityDynamite.java diff --git a/java/src/common/entity/projectile/EntityEgg.java b/common/src/common/entity/projectile/EntityEgg.java similarity index 100% rename from java/src/common/entity/projectile/EntityEgg.java rename to common/src/common/entity/projectile/EntityEgg.java diff --git a/java/src/common/entity/projectile/EntityFireCharge.java b/common/src/common/entity/projectile/EntityFireCharge.java similarity index 100% rename from java/src/common/entity/projectile/EntityFireCharge.java rename to common/src/common/entity/projectile/EntityFireCharge.java diff --git a/java/src/common/entity/projectile/EntityFireball.java b/common/src/common/entity/projectile/EntityFireball.java similarity index 100% rename from java/src/common/entity/projectile/EntityFireball.java rename to common/src/common/entity/projectile/EntityFireball.java diff --git a/java/src/common/entity/projectile/EntityHook.java b/common/src/common/entity/projectile/EntityHook.java similarity index 100% rename from java/src/common/entity/projectile/EntityHook.java rename to common/src/common/entity/projectile/EntityHook.java diff --git a/java/src/common/entity/projectile/EntityPotion.java b/common/src/common/entity/projectile/EntityPotion.java similarity index 100% rename from java/src/common/entity/projectile/EntityPotion.java rename to common/src/common/entity/projectile/EntityPotion.java diff --git a/java/src/common/entity/projectile/EntityProjectile.java b/common/src/common/entity/projectile/EntityProjectile.java similarity index 100% rename from java/src/common/entity/projectile/EntityProjectile.java rename to common/src/common/entity/projectile/EntityProjectile.java diff --git a/java/src/common/entity/projectile/EntitySnowball.java b/common/src/common/entity/projectile/EntitySnowball.java similarity index 100% rename from java/src/common/entity/projectile/EntitySnowball.java rename to common/src/common/entity/projectile/EntitySnowball.java diff --git a/java/src/common/entity/projectile/RngFishable.java b/common/src/common/entity/projectile/RngFishable.java similarity index 100% rename from java/src/common/entity/projectile/RngFishable.java rename to common/src/common/entity/projectile/RngFishable.java diff --git a/java/src/common/entity/types/CombatEntry.java b/common/src/common/entity/types/CombatEntry.java similarity index 100% rename from java/src/common/entity/types/CombatEntry.java rename to common/src/common/entity/types/CombatEntry.java diff --git a/java/src/common/entity/types/EntityAnimal.java b/common/src/common/entity/types/EntityAnimal.java similarity index 100% rename from java/src/common/entity/types/EntityAnimal.java rename to common/src/common/entity/types/EntityAnimal.java diff --git a/java/src/common/entity/types/EntityBodyHelper.java b/common/src/common/entity/types/EntityBodyHelper.java similarity index 100% rename from java/src/common/entity/types/EntityBodyHelper.java rename to common/src/common/entity/types/EntityBodyHelper.java diff --git a/java/src/common/entity/types/EntityLiving.java b/common/src/common/entity/types/EntityLiving.java similarity index 100% rename from java/src/common/entity/types/EntityLiving.java rename to common/src/common/entity/types/EntityLiving.java diff --git a/java/src/common/entity/types/EntityTameable.java b/common/src/common/entity/types/EntityTameable.java similarity index 100% rename from java/src/common/entity/types/EntityTameable.java rename to common/src/common/entity/types/EntityTameable.java diff --git a/java/src/common/entity/types/EntityThrowable.java b/common/src/common/entity/types/EntityThrowable.java similarity index 100% rename from java/src/common/entity/types/EntityThrowable.java rename to common/src/common/entity/types/EntityThrowable.java diff --git a/java/src/common/entity/types/EntityWaterMob.java b/common/src/common/entity/types/EntityWaterMob.java similarity index 100% rename from java/src/common/entity/types/EntityWaterMob.java rename to common/src/common/entity/types/EntityWaterMob.java diff --git a/java/src/common/entity/types/EntityWeatherEffect.java b/common/src/common/entity/types/EntityWeatherEffect.java similarity index 100% rename from java/src/common/entity/types/EntityWeatherEffect.java rename to common/src/common/entity/types/EntityWeatherEffect.java diff --git a/java/src/common/entity/types/IEntityFX.java b/common/src/common/entity/types/IEntityFX.java similarity index 100% rename from java/src/common/entity/types/IEntityFX.java rename to common/src/common/entity/types/IEntityFX.java diff --git a/java/src/common/entity/types/IEntityMultiPart.java b/common/src/common/entity/types/IEntityMultiPart.java similarity index 100% rename from java/src/common/entity/types/IEntityMultiPart.java rename to common/src/common/entity/types/IEntityMultiPart.java diff --git a/java/src/common/entity/types/IEntityOwnable.java b/common/src/common/entity/types/IEntityOwnable.java similarity index 100% rename from java/src/common/entity/types/IEntityOwnable.java rename to common/src/common/entity/types/IEntityOwnable.java diff --git a/java/src/common/entity/types/IObjectData.java b/common/src/common/entity/types/IObjectData.java similarity index 100% rename from java/src/common/entity/types/IObjectData.java rename to common/src/common/entity/types/IObjectData.java diff --git a/java/src/common/entity/types/IProjectile.java b/common/src/common/entity/types/IProjectile.java similarity index 100% rename from java/src/common/entity/types/IProjectile.java rename to common/src/common/entity/types/IProjectile.java diff --git a/java/src/common/future/AbstractFuture.java b/common/src/common/future/AbstractFuture.java similarity index 100% rename from java/src/common/future/AbstractFuture.java rename to common/src/common/future/AbstractFuture.java diff --git a/java/src/common/future/ExecutionError.java b/common/src/common/future/ExecutionError.java similarity index 100% rename from java/src/common/future/ExecutionError.java rename to common/src/common/future/ExecutionError.java diff --git a/java/src/common/future/ExecutionList.java b/common/src/common/future/ExecutionList.java similarity index 100% rename from java/src/common/future/ExecutionList.java rename to common/src/common/future/ExecutionList.java diff --git a/java/src/common/future/FutureCallback.java b/common/src/common/future/FutureCallback.java similarity index 100% rename from java/src/common/future/FutureCallback.java rename to common/src/common/future/FutureCallback.java diff --git a/java/src/common/future/Futures.java b/common/src/common/future/Futures.java similarity index 100% rename from java/src/common/future/Futures.java rename to common/src/common/future/Futures.java diff --git a/java/src/common/future/ListenableFuture.java b/common/src/common/future/ListenableFuture.java similarity index 100% rename from java/src/common/future/ListenableFuture.java rename to common/src/common/future/ListenableFuture.java diff --git a/java/src/common/future/ListenableFutureTask.java b/common/src/common/future/ListenableFutureTask.java similarity index 100% rename from java/src/common/future/ListenableFutureTask.java rename to common/src/common/future/ListenableFutureTask.java diff --git a/java/src/common/future/MoreExecutors.java b/common/src/common/future/MoreExecutors.java similarity index 100% rename from java/src/common/future/MoreExecutors.java rename to common/src/common/future/MoreExecutors.java diff --git a/java/src/common/future/ThreadFactoryBuilder.java b/common/src/common/future/ThreadFactoryBuilder.java similarity index 100% rename from java/src/common/future/ThreadFactoryBuilder.java rename to common/src/common/future/ThreadFactoryBuilder.java diff --git a/java/src/common/future/UncheckedExecutionException.java b/common/src/common/future/UncheckedExecutionException.java similarity index 100% rename from java/src/common/future/UncheckedExecutionException.java rename to common/src/common/future/UncheckedExecutionException.java diff --git a/java/src/common/init/BlockRegistry.java b/common/src/common/init/BlockRegistry.java similarity index 100% rename from java/src/common/init/BlockRegistry.java rename to common/src/common/init/BlockRegistry.java diff --git a/java/src/common/init/Blocks.java b/common/src/common/init/Blocks.java similarity index 100% rename from java/src/common/init/Blocks.java rename to common/src/common/init/Blocks.java diff --git a/java/src/common/init/Config.java b/common/src/common/init/Config.java similarity index 100% rename from java/src/common/init/Config.java rename to common/src/common/init/Config.java diff --git a/java/src/common/init/CraftingRegistry.java b/common/src/common/init/CraftingRegistry.java similarity index 100% rename from java/src/common/init/CraftingRegistry.java rename to common/src/common/init/CraftingRegistry.java diff --git a/java/src/common/init/DecoType.java b/common/src/common/init/DecoType.java similarity index 100% rename from java/src/common/init/DecoType.java rename to common/src/common/init/DecoType.java diff --git a/java/src/common/init/DispenserRegistry.java b/common/src/common/init/DispenserRegistry.java similarity index 100% rename from java/src/common/init/DispenserRegistry.java rename to common/src/common/init/DispenserRegistry.java diff --git a/java/src/common/init/EntityEggInfo.java b/common/src/common/init/EntityEggInfo.java similarity index 100% rename from java/src/common/init/EntityEggInfo.java rename to common/src/common/init/EntityEggInfo.java diff --git a/java/src/common/init/EntityRegistry.java b/common/src/common/init/EntityRegistry.java similarity index 100% rename from java/src/common/init/EntityRegistry.java rename to common/src/common/init/EntityRegistry.java diff --git a/java/src/common/init/FlammabilityRegistry.java b/common/src/common/init/FlammabilityRegistry.java similarity index 100% rename from java/src/common/init/FlammabilityRegistry.java rename to common/src/common/init/FlammabilityRegistry.java diff --git a/java/src/common/init/FluidRegistry.java b/common/src/common/init/FluidRegistry.java similarity index 100% rename from java/src/common/init/FluidRegistry.java rename to common/src/common/init/FluidRegistry.java diff --git a/java/src/common/init/IObjectIntIterable.java b/common/src/common/init/IObjectIntIterable.java similarity index 100% rename from java/src/common/init/IObjectIntIterable.java rename to common/src/common/init/IObjectIntIterable.java diff --git a/java/src/common/init/IRegistry.java b/common/src/common/init/IRegistry.java similarity index 100% rename from java/src/common/init/IRegistry.java rename to common/src/common/init/IRegistry.java diff --git a/java/src/common/init/ItemRegistry.java b/common/src/common/init/ItemRegistry.java similarity index 100% rename from java/src/common/init/ItemRegistry.java rename to common/src/common/init/ItemRegistry.java diff --git a/java/src/common/init/Items.java b/common/src/common/init/Items.java similarity index 100% rename from java/src/common/init/Items.java rename to common/src/common/init/Items.java diff --git a/java/src/common/init/MetalType.java b/common/src/common/init/MetalType.java similarity index 100% rename from java/src/common/init/MetalType.java rename to common/src/common/init/MetalType.java diff --git a/java/src/common/init/NameRegistry.java b/common/src/common/init/NameRegistry.java similarity index 100% rename from java/src/common/init/NameRegistry.java rename to common/src/common/init/NameRegistry.java diff --git a/java/src/common/init/ObjectIntIdentityMap.java b/common/src/common/init/ObjectIntIdentityMap.java similarity index 100% rename from java/src/common/init/ObjectIntIdentityMap.java rename to common/src/common/init/ObjectIntIdentityMap.java diff --git a/java/src/common/init/OreType.java b/common/src/common/init/OreType.java similarity index 100% rename from java/src/common/init/OreType.java rename to common/src/common/init/OreType.java diff --git a/java/src/common/init/Registry.java b/common/src/common/init/Registry.java similarity index 100% rename from java/src/common/init/Registry.java rename to common/src/common/init/Registry.java diff --git a/java/src/common/init/RegistryDefaulted.java b/common/src/common/init/RegistryDefaulted.java similarity index 100% rename from java/src/common/init/RegistryDefaulted.java rename to common/src/common/init/RegistryDefaulted.java diff --git a/java/src/common/init/RegistryNamespaced.java b/common/src/common/init/RegistryNamespaced.java similarity index 100% rename from java/src/common/init/RegistryNamespaced.java rename to common/src/common/init/RegistryNamespaced.java diff --git a/java/src/common/init/RegistryNamespacedDefaultedByKey.java b/common/src/common/init/RegistryNamespacedDefaultedByKey.java similarity index 100% rename from java/src/common/init/RegistryNamespacedDefaultedByKey.java rename to common/src/common/init/RegistryNamespacedDefaultedByKey.java diff --git a/java/src/common/init/RegistrySimple.java b/common/src/common/init/RegistrySimple.java similarity index 100% rename from java/src/common/init/RegistrySimple.java rename to common/src/common/init/RegistrySimple.java diff --git a/java/src/common/init/ReorderRegistry.java b/common/src/common/init/ReorderRegistry.java similarity index 100% rename from java/src/common/init/ReorderRegistry.java rename to common/src/common/init/ReorderRegistry.java diff --git a/java/src/common/init/RotationRegistry.java b/common/src/common/init/RotationRegistry.java similarity index 100% rename from java/src/common/init/RotationRegistry.java rename to common/src/common/init/RotationRegistry.java diff --git a/java/src/common/init/SmeltingRegistry.java b/common/src/common/init/SmeltingRegistry.java similarity index 100% rename from java/src/common/init/SmeltingRegistry.java rename to common/src/common/init/SmeltingRegistry.java diff --git a/java/src/common/init/SoundEvent.java b/common/src/common/init/SoundEvent.java similarity index 100% rename from java/src/common/init/SoundEvent.java rename to common/src/common/init/SoundEvent.java diff --git a/java/src/common/init/SpeciesRegistry.java b/common/src/common/init/SpeciesRegistry.java similarity index 100% rename from java/src/common/init/SpeciesRegistry.java rename to common/src/common/init/SpeciesRegistry.java diff --git a/java/src/common/init/TileRegistry.java b/common/src/common/init/TileRegistry.java similarity index 100% rename from java/src/common/init/TileRegistry.java rename to common/src/common/init/TileRegistry.java diff --git a/java/src/common/init/ToolMaterial.java b/common/src/common/init/ToolMaterial.java similarity index 100% rename from java/src/common/init/ToolMaterial.java rename to common/src/common/init/ToolMaterial.java diff --git a/java/src/common/init/ToolType.java b/common/src/common/init/ToolType.java similarity index 100% rename from java/src/common/init/ToolType.java rename to common/src/common/init/ToolType.java diff --git a/java/src/common/init/TradeRegistry.java b/common/src/common/init/TradeRegistry.java similarity index 100% rename from java/src/common/init/TradeRegistry.java rename to common/src/common/init/TradeRegistry.java diff --git a/java/src/common/init/UniverseRegistry.java b/common/src/common/init/UniverseRegistry.java similarity index 100% rename from java/src/common/init/UniverseRegistry.java rename to common/src/common/init/UniverseRegistry.java diff --git a/java/src/common/init/WoodType.java b/common/src/common/init/WoodType.java similarity index 100% rename from java/src/common/init/WoodType.java rename to common/src/common/init/WoodType.java diff --git a/java/src/common/inventory/AnimalChest.java b/common/src/common/inventory/AnimalChest.java similarity index 100% rename from java/src/common/inventory/AnimalChest.java rename to common/src/common/inventory/AnimalChest.java diff --git a/java/src/common/inventory/Container.java b/common/src/common/inventory/Container.java similarity index 100% rename from java/src/common/inventory/Container.java rename to common/src/common/inventory/Container.java diff --git a/java/src/common/inventory/ContainerBrewingStand.java b/common/src/common/inventory/ContainerBrewingStand.java similarity index 100% rename from java/src/common/inventory/ContainerBrewingStand.java rename to common/src/common/inventory/ContainerBrewingStand.java diff --git a/java/src/common/inventory/ContainerChest.java b/common/src/common/inventory/ContainerChest.java similarity index 100% rename from java/src/common/inventory/ContainerChest.java rename to common/src/common/inventory/ContainerChest.java diff --git a/java/src/common/inventory/ContainerDispenser.java b/common/src/common/inventory/ContainerDispenser.java similarity index 100% rename from java/src/common/inventory/ContainerDispenser.java rename to common/src/common/inventory/ContainerDispenser.java diff --git a/java/src/common/inventory/ContainerEnchantment.java b/common/src/common/inventory/ContainerEnchantment.java similarity index 100% rename from java/src/common/inventory/ContainerEnchantment.java rename to common/src/common/inventory/ContainerEnchantment.java diff --git a/java/src/common/inventory/ContainerFurnace.java b/common/src/common/inventory/ContainerFurnace.java similarity index 100% rename from java/src/common/inventory/ContainerFurnace.java rename to common/src/common/inventory/ContainerFurnace.java diff --git a/java/src/common/inventory/ContainerHopper.java b/common/src/common/inventory/ContainerHopper.java similarity index 100% rename from java/src/common/inventory/ContainerHopper.java rename to common/src/common/inventory/ContainerHopper.java diff --git a/java/src/common/inventory/ContainerHorseInventory.java b/common/src/common/inventory/ContainerHorseInventory.java similarity index 100% rename from java/src/common/inventory/ContainerHorseInventory.java rename to common/src/common/inventory/ContainerHorseInventory.java diff --git a/java/src/common/inventory/ContainerLocalMenu.java b/common/src/common/inventory/ContainerLocalMenu.java similarity index 100% rename from java/src/common/inventory/ContainerLocalMenu.java rename to common/src/common/inventory/ContainerLocalMenu.java diff --git a/java/src/common/inventory/ContainerMachine.java b/common/src/common/inventory/ContainerMachine.java similarity index 100% rename from java/src/common/inventory/ContainerMachine.java rename to common/src/common/inventory/ContainerMachine.java diff --git a/java/src/common/inventory/ContainerMerchant.java b/common/src/common/inventory/ContainerMerchant.java similarity index 100% rename from java/src/common/inventory/ContainerMerchant.java rename to common/src/common/inventory/ContainerMerchant.java diff --git a/java/src/common/inventory/ContainerPlayer.java b/common/src/common/inventory/ContainerPlayer.java similarity index 100% rename from java/src/common/inventory/ContainerPlayer.java rename to common/src/common/inventory/ContainerPlayer.java diff --git a/java/src/common/inventory/ContainerRepair.java b/common/src/common/inventory/ContainerRepair.java similarity index 100% rename from java/src/common/inventory/ContainerRepair.java rename to common/src/common/inventory/ContainerRepair.java diff --git a/java/src/common/inventory/ContainerWorkbench.java b/common/src/common/inventory/ContainerWorkbench.java similarity index 100% rename from java/src/common/inventory/ContainerWorkbench.java rename to common/src/common/inventory/ContainerWorkbench.java diff --git a/java/src/common/inventory/ICrafting.java b/common/src/common/inventory/ICrafting.java similarity index 100% rename from java/src/common/inventory/ICrafting.java rename to common/src/common/inventory/ICrafting.java diff --git a/java/src/common/inventory/IInvBasic.java b/common/src/common/inventory/IInvBasic.java similarity index 100% rename from java/src/common/inventory/IInvBasic.java rename to common/src/common/inventory/IInvBasic.java diff --git a/java/src/common/inventory/IInventory.java b/common/src/common/inventory/IInventory.java similarity index 100% rename from java/src/common/inventory/IInventory.java rename to common/src/common/inventory/IInventory.java diff --git a/java/src/common/inventory/ISidedInventory.java b/common/src/common/inventory/ISidedInventory.java similarity index 100% rename from java/src/common/inventory/ISidedInventory.java rename to common/src/common/inventory/ISidedInventory.java diff --git a/java/src/common/inventory/InventoryBasic.java b/common/src/common/inventory/InventoryBasic.java similarity index 100% rename from java/src/common/inventory/InventoryBasic.java rename to common/src/common/inventory/InventoryBasic.java diff --git a/java/src/common/inventory/InventoryCraftResult.java b/common/src/common/inventory/InventoryCraftResult.java similarity index 100% rename from java/src/common/inventory/InventoryCraftResult.java rename to common/src/common/inventory/InventoryCraftResult.java diff --git a/java/src/common/inventory/InventoryCrafting.java b/common/src/common/inventory/InventoryCrafting.java similarity index 100% rename from java/src/common/inventory/InventoryCrafting.java rename to common/src/common/inventory/InventoryCrafting.java diff --git a/java/src/common/inventory/InventoryHelper.java b/common/src/common/inventory/InventoryHelper.java similarity index 100% rename from java/src/common/inventory/InventoryHelper.java rename to common/src/common/inventory/InventoryHelper.java diff --git a/java/src/common/inventory/InventoryLargeChest.java b/common/src/common/inventory/InventoryLargeChest.java similarity index 100% rename from java/src/common/inventory/InventoryLargeChest.java rename to common/src/common/inventory/InventoryLargeChest.java diff --git a/java/src/common/inventory/InventoryMerchant.java b/common/src/common/inventory/InventoryMerchant.java similarity index 100% rename from java/src/common/inventory/InventoryMerchant.java rename to common/src/common/inventory/InventoryMerchant.java diff --git a/java/src/common/inventory/InventoryPlayer.java b/common/src/common/inventory/InventoryPlayer.java similarity index 100% rename from java/src/common/inventory/InventoryPlayer.java rename to common/src/common/inventory/InventoryPlayer.java diff --git a/java/src/common/inventory/InventoryWarpChest.java b/common/src/common/inventory/InventoryWarpChest.java similarity index 100% rename from java/src/common/inventory/InventoryWarpChest.java rename to common/src/common/inventory/InventoryWarpChest.java diff --git a/java/src/common/inventory/Slot.java b/common/src/common/inventory/Slot.java similarity index 100% rename from java/src/common/inventory/Slot.java rename to common/src/common/inventory/Slot.java diff --git a/java/src/common/inventory/SlotCrafting.java b/common/src/common/inventory/SlotCrafting.java similarity index 100% rename from java/src/common/inventory/SlotCrafting.java rename to common/src/common/inventory/SlotCrafting.java diff --git a/java/src/common/inventory/SlotFurnaceFuel.java b/common/src/common/inventory/SlotFurnaceFuel.java similarity index 100% rename from java/src/common/inventory/SlotFurnaceFuel.java rename to common/src/common/inventory/SlotFurnaceFuel.java diff --git a/java/src/common/inventory/SlotFurnaceOutput.java b/common/src/common/inventory/SlotFurnaceOutput.java similarity index 100% rename from java/src/common/inventory/SlotFurnaceOutput.java rename to common/src/common/inventory/SlotFurnaceOutput.java diff --git a/java/src/common/inventory/SlotMerchantResult.java b/common/src/common/inventory/SlotMerchantResult.java similarity index 100% rename from java/src/common/inventory/SlotMerchantResult.java rename to common/src/common/inventory/SlotMerchantResult.java diff --git a/java/src/common/item/CheatTab.java b/common/src/common/item/CheatTab.java similarity index 100% rename from java/src/common/item/CheatTab.java rename to common/src/common/item/CheatTab.java diff --git a/java/src/common/item/Item.java b/common/src/common/item/Item.java similarity index 100% rename from java/src/common/item/Item.java rename to common/src/common/item/Item.java diff --git a/java/src/common/item/ItemAction.java b/common/src/common/item/ItemAction.java similarity index 100% rename from java/src/common/item/ItemAction.java rename to common/src/common/item/ItemAction.java diff --git a/java/src/common/item/ItemAmmo.java b/common/src/common/item/ItemAmmo.java similarity index 100% rename from java/src/common/item/ItemAmmo.java rename to common/src/common/item/ItemAmmo.java diff --git a/java/src/common/item/ItemAnvilBlock.java b/common/src/common/item/ItemAnvilBlock.java similarity index 100% rename from java/src/common/item/ItemAnvilBlock.java rename to common/src/common/item/ItemAnvilBlock.java diff --git a/java/src/common/item/ItemAppleGold.java b/common/src/common/item/ItemAppleGold.java similarity index 100% rename from java/src/common/item/ItemAppleGold.java rename to common/src/common/item/ItemAppleGold.java diff --git a/java/src/common/item/ItemArmor.java b/common/src/common/item/ItemArmor.java similarity index 100% rename from java/src/common/item/ItemArmor.java rename to common/src/common/item/ItemArmor.java diff --git a/java/src/common/item/ItemAxe.java b/common/src/common/item/ItemAxe.java similarity index 100% rename from java/src/common/item/ItemAxe.java rename to common/src/common/item/ItemAxe.java diff --git a/java/src/common/item/ItemBanHammer.java b/common/src/common/item/ItemBanHammer.java similarity index 100% rename from java/src/common/item/ItemBanHammer.java rename to common/src/common/item/ItemBanHammer.java diff --git a/java/src/common/item/ItemBanner.java b/common/src/common/item/ItemBanner.java similarity index 100% rename from java/src/common/item/ItemBanner.java rename to common/src/common/item/ItemBanner.java diff --git a/java/src/common/item/ItemBed.java b/common/src/common/item/ItemBed.java similarity index 100% rename from java/src/common/item/ItemBed.java rename to common/src/common/item/ItemBed.java diff --git a/java/src/common/item/ItemBlock.java b/common/src/common/item/ItemBlock.java similarity index 100% rename from java/src/common/item/ItemBlock.java rename to common/src/common/item/ItemBlock.java diff --git a/java/src/common/item/ItemBoat.java b/common/src/common/item/ItemBoat.java similarity index 100% rename from java/src/common/item/ItemBoat.java rename to common/src/common/item/ItemBoat.java diff --git a/java/src/common/item/ItemBoltgun.java b/common/src/common/item/ItemBoltgun.java similarity index 100% rename from java/src/common/item/ItemBoltgun.java rename to common/src/common/item/ItemBoltgun.java diff --git a/java/src/common/item/ItemBook.java b/common/src/common/item/ItemBook.java similarity index 100% rename from java/src/common/item/ItemBook.java rename to common/src/common/item/ItemBook.java diff --git a/java/src/common/item/ItemBow.java b/common/src/common/item/ItemBow.java similarity index 100% rename from java/src/common/item/ItemBow.java rename to common/src/common/item/ItemBow.java diff --git a/java/src/common/item/ItemBucket.java b/common/src/common/item/ItemBucket.java similarity index 100% rename from java/src/common/item/ItemBucket.java rename to common/src/common/item/ItemBucket.java diff --git a/java/src/common/item/ItemBucketMilk.java b/common/src/common/item/ItemBucketMilk.java similarity index 100% rename from java/src/common/item/ItemBucketMilk.java rename to common/src/common/item/ItemBucketMilk.java diff --git a/java/src/common/item/ItemButton.java b/common/src/common/item/ItemButton.java similarity index 100% rename from java/src/common/item/ItemButton.java rename to common/src/common/item/ItemButton.java diff --git a/java/src/common/item/ItemCamera.java b/common/src/common/item/ItemCamera.java similarity index 100% rename from java/src/common/item/ItemCamera.java rename to common/src/common/item/ItemCamera.java diff --git a/java/src/common/item/ItemCarrotOnAStick.java b/common/src/common/item/ItemCarrotOnAStick.java similarity index 100% rename from java/src/common/item/ItemCarrotOnAStick.java rename to common/src/common/item/ItemCarrotOnAStick.java diff --git a/java/src/common/item/ItemChargedOrb.java b/common/src/common/item/ItemChargedOrb.java similarity index 100% rename from java/src/common/item/ItemChargedOrb.java rename to common/src/common/item/ItemChargedOrb.java diff --git a/java/src/common/item/ItemChest.java b/common/src/common/item/ItemChest.java similarity index 100% rename from java/src/common/item/ItemChest.java rename to common/src/common/item/ItemChest.java diff --git a/java/src/common/item/ItemCloth.java b/common/src/common/item/ItemCloth.java similarity index 100% rename from java/src/common/item/ItemCloth.java rename to common/src/common/item/ItemCloth.java diff --git a/java/src/common/item/ItemCoal.java b/common/src/common/item/ItemCoal.java similarity index 100% rename from java/src/common/item/ItemCoal.java rename to common/src/common/item/ItemCoal.java diff --git a/java/src/common/item/ItemColored.java b/common/src/common/item/ItemColored.java similarity index 100% rename from java/src/common/item/ItemColored.java rename to common/src/common/item/ItemColored.java diff --git a/java/src/common/item/ItemControl.java b/common/src/common/item/ItemControl.java similarity index 100% rename from java/src/common/item/ItemControl.java rename to common/src/common/item/ItemControl.java diff --git a/java/src/common/item/ItemDie.java b/common/src/common/item/ItemDie.java similarity index 100% rename from java/src/common/item/ItemDie.java rename to common/src/common/item/ItemDie.java diff --git a/java/src/common/item/ItemDispenser.java b/common/src/common/item/ItemDispenser.java similarity index 100% rename from java/src/common/item/ItemDispenser.java rename to common/src/common/item/ItemDispenser.java diff --git a/java/src/common/item/ItemDoor.java b/common/src/common/item/ItemDoor.java similarity index 100% rename from java/src/common/item/ItemDoor.java rename to common/src/common/item/ItemDoor.java diff --git a/java/src/common/item/ItemDoublePlant.java b/common/src/common/item/ItemDoublePlant.java similarity index 100% rename from java/src/common/item/ItemDoublePlant.java rename to common/src/common/item/ItemDoublePlant.java diff --git a/java/src/common/item/ItemDye.java b/common/src/common/item/ItemDye.java similarity index 100% rename from java/src/common/item/ItemDye.java rename to common/src/common/item/ItemDye.java diff --git a/java/src/common/item/ItemDynamite.java b/common/src/common/item/ItemDynamite.java similarity index 100% rename from java/src/common/item/ItemDynamite.java rename to common/src/common/item/ItemDynamite.java diff --git a/java/src/common/item/ItemEditWand.java b/common/src/common/item/ItemEditWand.java similarity index 100% rename from java/src/common/item/ItemEditWand.java rename to common/src/common/item/ItemEditWand.java diff --git a/java/src/common/item/ItemEffect.java b/common/src/common/item/ItemEffect.java similarity index 100% rename from java/src/common/item/ItemEffect.java rename to common/src/common/item/ItemEffect.java diff --git a/java/src/common/item/ItemEgg.java b/common/src/common/item/ItemEgg.java similarity index 100% rename from java/src/common/item/ItemEgg.java rename to common/src/common/item/ItemEgg.java diff --git a/java/src/common/item/ItemEnchantedBook.java b/common/src/common/item/ItemEnchantedBook.java similarity index 100% rename from java/src/common/item/ItemEnchantedBook.java rename to common/src/common/item/ItemEnchantedBook.java diff --git a/java/src/common/item/ItemExpBottle.java b/common/src/common/item/ItemExpBottle.java similarity index 100% rename from java/src/common/item/ItemExpBottle.java rename to common/src/common/item/ItemExpBottle.java diff --git a/java/src/common/item/ItemExterminator.java b/common/src/common/item/ItemExterminator.java similarity index 100% rename from java/src/common/item/ItemExterminator.java rename to common/src/common/item/ItemExterminator.java diff --git a/java/src/common/item/ItemFence.java b/common/src/common/item/ItemFence.java similarity index 100% rename from java/src/common/item/ItemFence.java rename to common/src/common/item/ItemFence.java diff --git a/java/src/common/item/ItemFireball.java b/common/src/common/item/ItemFireball.java similarity index 100% rename from java/src/common/item/ItemFireball.java rename to common/src/common/item/ItemFireball.java diff --git a/java/src/common/item/ItemFirework.java b/common/src/common/item/ItemFirework.java similarity index 100% rename from java/src/common/item/ItemFirework.java rename to common/src/common/item/ItemFirework.java diff --git a/java/src/common/item/ItemFireworkCharge.java b/common/src/common/item/ItemFireworkCharge.java similarity index 100% rename from java/src/common/item/ItemFireworkCharge.java rename to common/src/common/item/ItemFireworkCharge.java diff --git a/java/src/common/item/ItemFishFood.java b/common/src/common/item/ItemFishFood.java similarity index 100% rename from java/src/common/item/ItemFishFood.java rename to common/src/common/item/ItemFishFood.java diff --git a/java/src/common/item/ItemFishingRod.java b/common/src/common/item/ItemFishingRod.java similarity index 100% rename from java/src/common/item/ItemFishingRod.java rename to common/src/common/item/ItemFishingRod.java diff --git a/java/src/common/item/ItemFlintAndSteel.java b/common/src/common/item/ItemFlintAndSteel.java similarity index 100% rename from java/src/common/item/ItemFlintAndSteel.java rename to common/src/common/item/ItemFlintAndSteel.java diff --git a/java/src/common/item/ItemFood.java b/common/src/common/item/ItemFood.java similarity index 100% rename from java/src/common/item/ItemFood.java rename to common/src/common/item/ItemFood.java diff --git a/java/src/common/item/ItemFragile.java b/common/src/common/item/ItemFragile.java similarity index 100% rename from java/src/common/item/ItemFragile.java rename to common/src/common/item/ItemFragile.java diff --git a/java/src/common/item/ItemGlassBottle.java b/common/src/common/item/ItemGlassBottle.java similarity index 100% rename from java/src/common/item/ItemGlassBottle.java rename to common/src/common/item/ItemGlassBottle.java diff --git a/java/src/common/item/ItemGunBase.java b/common/src/common/item/ItemGunBase.java similarity index 100% rename from java/src/common/item/ItemGunBase.java rename to common/src/common/item/ItemGunBase.java diff --git a/java/src/common/item/ItemHoe.java b/common/src/common/item/ItemHoe.java similarity index 100% rename from java/src/common/item/ItemHoe.java rename to common/src/common/item/ItemHoe.java diff --git a/java/src/common/item/ItemHorseArmor.java b/common/src/common/item/ItemHorseArmor.java similarity index 100% rename from java/src/common/item/ItemHorseArmor.java rename to common/src/common/item/ItemHorseArmor.java diff --git a/java/src/common/item/ItemHugeMushroom.java b/common/src/common/item/ItemHugeMushroom.java similarity index 100% rename from java/src/common/item/ItemHugeMushroom.java rename to common/src/common/item/ItemHugeMushroom.java diff --git a/java/src/common/item/ItemInfoWand.java b/common/src/common/item/ItemInfoWand.java similarity index 100% rename from java/src/common/item/ItemInfoWand.java rename to common/src/common/item/ItemInfoWand.java diff --git a/java/src/common/item/ItemKey.java b/common/src/common/item/ItemKey.java similarity index 100% rename from java/src/common/item/ItemKey.java rename to common/src/common/item/ItemKey.java diff --git a/java/src/common/item/ItemLead.java b/common/src/common/item/ItemLead.java similarity index 100% rename from java/src/common/item/ItemLead.java rename to common/src/common/item/ItemLead.java diff --git a/java/src/common/item/ItemLeaves.java b/common/src/common/item/ItemLeaves.java similarity index 100% rename from java/src/common/item/ItemLeaves.java rename to common/src/common/item/ItemLeaves.java diff --git a/java/src/common/item/ItemLightning.java b/common/src/common/item/ItemLightning.java similarity index 100% rename from java/src/common/item/ItemLightning.java rename to common/src/common/item/ItemLightning.java diff --git a/java/src/common/item/ItemLilyPad.java b/common/src/common/item/ItemLilyPad.java similarity index 100% rename from java/src/common/item/ItemLilyPad.java rename to common/src/common/item/ItemLilyPad.java diff --git a/java/src/common/item/ItemMagnet.java b/common/src/common/item/ItemMagnet.java similarity index 100% rename from java/src/common/item/ItemMagnet.java rename to common/src/common/item/ItemMagnet.java diff --git a/java/src/common/item/ItemMagnetic.java b/common/src/common/item/ItemMagnetic.java similarity index 100% rename from java/src/common/item/ItemMagnetic.java rename to common/src/common/item/ItemMagnetic.java diff --git a/java/src/common/item/ItemMetal.java b/common/src/common/item/ItemMetal.java similarity index 100% rename from java/src/common/item/ItemMetal.java rename to common/src/common/item/ItemMetal.java diff --git a/java/src/common/item/ItemMetalBlock.java b/common/src/common/item/ItemMetalBlock.java similarity index 100% rename from java/src/common/item/ItemMetalBlock.java rename to common/src/common/item/ItemMetalBlock.java diff --git a/java/src/common/item/ItemMinecart.java b/common/src/common/item/ItemMinecart.java similarity index 100% rename from java/src/common/item/ItemMinecart.java rename to common/src/common/item/ItemMinecart.java diff --git a/java/src/common/item/ItemMonsterPlacer.java b/common/src/common/item/ItemMonsterPlacer.java similarity index 100% rename from java/src/common/item/ItemMonsterPlacer.java rename to common/src/common/item/ItemMonsterPlacer.java diff --git a/java/src/common/item/ItemMultiTexture.java b/common/src/common/item/ItemMultiTexture.java similarity index 100% rename from java/src/common/item/ItemMultiTexture.java rename to common/src/common/item/ItemMultiTexture.java diff --git a/java/src/common/item/ItemNameTag.java b/common/src/common/item/ItemNameTag.java similarity index 100% rename from java/src/common/item/ItemNameTag.java rename to common/src/common/item/ItemNameTag.java diff --git a/java/src/common/item/ItemNpcSpawner.java b/common/src/common/item/ItemNpcSpawner.java similarity index 100% rename from java/src/common/item/ItemNpcSpawner.java rename to common/src/common/item/ItemNpcSpawner.java diff --git a/java/src/common/item/ItemNugget.java b/common/src/common/item/ItemNugget.java similarity index 100% rename from java/src/common/item/ItemNugget.java rename to common/src/common/item/ItemNugget.java diff --git a/java/src/common/item/ItemPickaxe.java b/common/src/common/item/ItemPickaxe.java similarity index 100% rename from java/src/common/item/ItemPickaxe.java rename to common/src/common/item/ItemPickaxe.java diff --git a/java/src/common/item/ItemPiston.java b/common/src/common/item/ItemPiston.java similarity index 100% rename from java/src/common/item/ItemPiston.java rename to common/src/common/item/ItemPiston.java diff --git a/java/src/common/item/ItemPotion.java b/common/src/common/item/ItemPotion.java similarity index 100% rename from java/src/common/item/ItemPotion.java rename to common/src/common/item/ItemPotion.java diff --git a/java/src/common/item/ItemPressurePlate.java b/common/src/common/item/ItemPressurePlate.java similarity index 100% rename from java/src/common/item/ItemPressurePlate.java rename to common/src/common/item/ItemPressurePlate.java diff --git a/java/src/common/item/ItemRecord.java b/common/src/common/item/ItemRecord.java similarity index 100% rename from java/src/common/item/ItemRecord.java rename to common/src/common/item/ItemRecord.java diff --git a/java/src/common/item/ItemRedstone.java b/common/src/common/item/ItemRedstone.java similarity index 100% rename from java/src/common/item/ItemRedstone.java rename to common/src/common/item/ItemRedstone.java diff --git a/java/src/common/item/ItemReed.java b/common/src/common/item/ItemReed.java similarity index 100% rename from java/src/common/item/ItemReed.java rename to common/src/common/item/ItemReed.java diff --git a/java/src/common/item/ItemRod.java b/common/src/common/item/ItemRod.java similarity index 100% rename from java/src/common/item/ItemRod.java rename to common/src/common/item/ItemRod.java diff --git a/java/src/common/item/ItemSaddle.java b/common/src/common/item/ItemSaddle.java similarity index 100% rename from java/src/common/item/ItemSaddle.java rename to common/src/common/item/ItemSaddle.java diff --git a/java/src/common/item/ItemSeedFood.java b/common/src/common/item/ItemSeedFood.java similarity index 100% rename from java/src/common/item/ItemSeedFood.java rename to common/src/common/item/ItemSeedFood.java diff --git a/java/src/common/item/ItemSeeds.java b/common/src/common/item/ItemSeeds.java similarity index 100% rename from java/src/common/item/ItemSeeds.java rename to common/src/common/item/ItemSeeds.java diff --git a/java/src/common/item/ItemShears.java b/common/src/common/item/ItemShears.java similarity index 100% rename from java/src/common/item/ItemShears.java rename to common/src/common/item/ItemShears.java diff --git a/java/src/common/item/ItemSign.java b/common/src/common/item/ItemSign.java similarity index 100% rename from java/src/common/item/ItemSign.java rename to common/src/common/item/ItemSign.java diff --git a/java/src/common/item/ItemSkull.java b/common/src/common/item/ItemSkull.java similarity index 100% rename from java/src/common/item/ItemSkull.java rename to common/src/common/item/ItemSkull.java diff --git a/java/src/common/item/ItemSlab.java b/common/src/common/item/ItemSlab.java similarity index 100% rename from java/src/common/item/ItemSlab.java rename to common/src/common/item/ItemSlab.java diff --git a/java/src/common/item/ItemSmall.java b/common/src/common/item/ItemSmall.java similarity index 100% rename from java/src/common/item/ItemSmall.java rename to common/src/common/item/ItemSmall.java diff --git a/java/src/common/item/ItemSnow.java b/common/src/common/item/ItemSnow.java similarity index 100% rename from java/src/common/item/ItemSnow.java rename to common/src/common/item/ItemSnow.java diff --git a/java/src/common/item/ItemSnowball.java b/common/src/common/item/ItemSnowball.java similarity index 100% rename from java/src/common/item/ItemSnowball.java rename to common/src/common/item/ItemSnowball.java diff --git a/java/src/common/item/ItemSoup.java b/common/src/common/item/ItemSoup.java similarity index 100% rename from java/src/common/item/ItemSoup.java rename to common/src/common/item/ItemSoup.java diff --git a/java/src/common/item/ItemSpaceNavigator.java b/common/src/common/item/ItemSpaceNavigator.java similarity index 100% rename from java/src/common/item/ItemSpaceNavigator.java rename to common/src/common/item/ItemSpaceNavigator.java diff --git a/java/src/common/item/ItemSpade.java b/common/src/common/item/ItemSpade.java similarity index 100% rename from java/src/common/item/ItemSpade.java rename to common/src/common/item/ItemSpade.java diff --git a/java/src/common/item/ItemStack.java b/common/src/common/item/ItemStack.java similarity index 100% rename from java/src/common/item/ItemStack.java rename to common/src/common/item/ItemStack.java diff --git a/java/src/common/item/ItemStick.java b/common/src/common/item/ItemStick.java similarity index 100% rename from java/src/common/item/ItemStick.java rename to common/src/common/item/ItemStick.java diff --git a/java/src/common/item/ItemSword.java b/common/src/common/item/ItemSword.java similarity index 100% rename from java/src/common/item/ItemSword.java rename to common/src/common/item/ItemSword.java diff --git a/java/src/common/item/ItemTNT.java b/common/src/common/item/ItemTNT.java similarity index 100% rename from java/src/common/item/ItemTNT.java rename to common/src/common/item/ItemTNT.java diff --git a/java/src/common/item/ItemTiny.java b/common/src/common/item/ItemTiny.java similarity index 100% rename from java/src/common/item/ItemTiny.java rename to common/src/common/item/ItemTiny.java diff --git a/java/src/common/item/ItemTool.java b/common/src/common/item/ItemTool.java similarity index 100% rename from java/src/common/item/ItemTool.java rename to common/src/common/item/ItemTool.java diff --git a/java/src/common/item/ItemWall.java b/common/src/common/item/ItemWall.java similarity index 100% rename from java/src/common/item/ItemWall.java rename to common/src/common/item/ItemWall.java diff --git a/java/src/common/item/ItemWand.java b/common/src/common/item/ItemWand.java similarity index 100% rename from java/src/common/item/ItemWand.java rename to common/src/common/item/ItemWand.java diff --git a/java/src/common/item/ItemWeatherToken.java b/common/src/common/item/ItemWeatherToken.java similarity index 100% rename from java/src/common/item/ItemWeatherToken.java rename to common/src/common/item/ItemWeatherToken.java diff --git a/java/src/common/item/RngLoot.java b/common/src/common/item/RngLoot.java similarity index 100% rename from java/src/common/item/RngLoot.java rename to common/src/common/item/RngLoot.java diff --git a/java/src/common/log/Log.java b/common/src/common/log/Log.java similarity index 100% rename from java/src/common/log/Log.java rename to common/src/common/log/Log.java diff --git a/java/src/common/log/LogLevel.java b/common/src/common/log/LogLevel.java similarity index 100% rename from java/src/common/log/LogLevel.java rename to common/src/common/log/LogLevel.java diff --git a/java/src/common/log/Message.java b/common/src/common/log/Message.java similarity index 100% rename from java/src/common/log/Message.java rename to common/src/common/log/Message.java diff --git a/java/src/common/log/NettyLogger.java b/common/src/common/log/NettyLogger.java similarity index 100% rename from java/src/common/log/NettyLogger.java rename to common/src/common/log/NettyLogger.java diff --git a/java/src/common/material/Material.java b/common/src/common/material/Material.java similarity index 100% rename from java/src/common/material/Material.java rename to common/src/common/material/Material.java diff --git a/java/src/common/material/MaterialColdFluid.java b/common/src/common/material/MaterialColdFluid.java similarity index 100% rename from java/src/common/material/MaterialColdFluid.java rename to common/src/common/material/MaterialColdFluid.java diff --git a/java/src/common/material/MaterialHotFluid.java b/common/src/common/material/MaterialHotFluid.java similarity index 100% rename from java/src/common/material/MaterialHotFluid.java rename to common/src/common/material/MaterialHotFluid.java diff --git a/java/src/common/material/MaterialLogic.java b/common/src/common/material/MaterialLogic.java similarity index 100% rename from java/src/common/material/MaterialLogic.java rename to common/src/common/material/MaterialLogic.java diff --git a/java/src/common/material/MaterialPortal.java b/common/src/common/material/MaterialPortal.java similarity index 100% rename from java/src/common/material/MaterialPortal.java rename to common/src/common/material/MaterialPortal.java diff --git a/java/src/common/material/MaterialTransparent.java b/common/src/common/material/MaterialTransparent.java similarity index 100% rename from java/src/common/material/MaterialTransparent.java rename to common/src/common/material/MaterialTransparent.java diff --git a/java/src/common/model/BlockLayer.java b/common/src/common/model/BlockLayer.java similarity index 100% rename from java/src/common/model/BlockLayer.java rename to common/src/common/model/BlockLayer.java diff --git a/java/src/common/model/ItemMeshDefinition.java b/common/src/common/model/ItemMeshDefinition.java similarity index 100% rename from java/src/common/model/ItemMeshDefinition.java rename to common/src/common/model/ItemMeshDefinition.java diff --git a/java/src/common/model/Model.java b/common/src/common/model/Model.java similarity index 100% rename from java/src/common/model/Model.java rename to common/src/common/model/Model.java diff --git a/java/src/common/model/ModelProvider.java b/common/src/common/model/ModelProvider.java similarity index 100% rename from java/src/common/model/ModelProvider.java rename to common/src/common/model/ModelProvider.java diff --git a/java/src/common/model/ModelRotation.java b/common/src/common/model/ModelRotation.java similarity index 100% rename from java/src/common/model/ModelRotation.java rename to common/src/common/model/ModelRotation.java diff --git a/java/src/common/model/ParticleType.java b/common/src/common/model/ParticleType.java similarity index 100% rename from java/src/common/model/ParticleType.java rename to common/src/common/model/ParticleType.java diff --git a/java/src/common/model/Transform.java b/common/src/common/model/Transform.java similarity index 100% rename from java/src/common/model/Transform.java rename to common/src/common/model/Transform.java diff --git a/java/src/common/model/Transforms.java b/common/src/common/model/Transforms.java similarity index 100% rename from java/src/common/model/Transforms.java rename to common/src/common/model/Transforms.java diff --git a/java/src/common/nbt/NBTBase.java b/common/src/common/nbt/NBTBase.java similarity index 100% rename from java/src/common/nbt/NBTBase.java rename to common/src/common/nbt/NBTBase.java diff --git a/java/src/common/nbt/NBTException.java b/common/src/common/nbt/NBTException.java similarity index 100% rename from java/src/common/nbt/NBTException.java rename to common/src/common/nbt/NBTException.java diff --git a/java/src/common/nbt/NBTLoader.java b/common/src/common/nbt/NBTLoader.java similarity index 100% rename from java/src/common/nbt/NBTLoader.java rename to common/src/common/nbt/NBTLoader.java diff --git a/java/src/common/nbt/NBTParser.java b/common/src/common/nbt/NBTParser.java similarity index 100% rename from java/src/common/nbt/NBTParser.java rename to common/src/common/nbt/NBTParser.java diff --git a/java/src/common/nbt/NBTSizeTracker.java b/common/src/common/nbt/NBTSizeTracker.java similarity index 100% rename from java/src/common/nbt/NBTSizeTracker.java rename to common/src/common/nbt/NBTSizeTracker.java diff --git a/java/src/common/nbt/NBTTagByte.java b/common/src/common/nbt/NBTTagByte.java similarity index 100% rename from java/src/common/nbt/NBTTagByte.java rename to common/src/common/nbt/NBTTagByte.java diff --git a/java/src/common/nbt/NBTTagByteArray.java b/common/src/common/nbt/NBTTagByteArray.java similarity index 100% rename from java/src/common/nbt/NBTTagByteArray.java rename to common/src/common/nbt/NBTTagByteArray.java diff --git a/java/src/common/nbt/NBTTagCompound.java b/common/src/common/nbt/NBTTagCompound.java similarity index 100% rename from java/src/common/nbt/NBTTagCompound.java rename to common/src/common/nbt/NBTTagCompound.java diff --git a/java/src/common/nbt/NBTTagDouble.java b/common/src/common/nbt/NBTTagDouble.java similarity index 100% rename from java/src/common/nbt/NBTTagDouble.java rename to common/src/common/nbt/NBTTagDouble.java diff --git a/java/src/common/nbt/NBTTagEnd.java b/common/src/common/nbt/NBTTagEnd.java similarity index 100% rename from java/src/common/nbt/NBTTagEnd.java rename to common/src/common/nbt/NBTTagEnd.java diff --git a/java/src/common/nbt/NBTTagFloat.java b/common/src/common/nbt/NBTTagFloat.java similarity index 100% rename from java/src/common/nbt/NBTTagFloat.java rename to common/src/common/nbt/NBTTagFloat.java diff --git a/java/src/common/nbt/NBTTagInt.java b/common/src/common/nbt/NBTTagInt.java similarity index 100% rename from java/src/common/nbt/NBTTagInt.java rename to common/src/common/nbt/NBTTagInt.java diff --git a/java/src/common/nbt/NBTTagIntArray.java b/common/src/common/nbt/NBTTagIntArray.java similarity index 100% rename from java/src/common/nbt/NBTTagIntArray.java rename to common/src/common/nbt/NBTTagIntArray.java diff --git a/java/src/common/nbt/NBTTagList.java b/common/src/common/nbt/NBTTagList.java similarity index 100% rename from java/src/common/nbt/NBTTagList.java rename to common/src/common/nbt/NBTTagList.java diff --git a/java/src/common/nbt/NBTTagLong.java b/common/src/common/nbt/NBTTagLong.java similarity index 100% rename from java/src/common/nbt/NBTTagLong.java rename to common/src/common/nbt/NBTTagLong.java diff --git a/java/src/common/nbt/NBTTagShort.java b/common/src/common/nbt/NBTTagShort.java similarity index 100% rename from java/src/common/nbt/NBTTagShort.java rename to common/src/common/nbt/NBTTagShort.java diff --git a/java/src/common/nbt/NBTTagString.java b/common/src/common/nbt/NBTTagString.java similarity index 100% rename from java/src/common/nbt/NBTTagString.java rename to common/src/common/nbt/NBTTagString.java diff --git a/java/src/common/nbt/NBTUtil.java b/common/src/common/nbt/NBTUtil.java similarity index 100% rename from java/src/common/nbt/NBTUtil.java rename to common/src/common/nbt/NBTUtil.java diff --git a/java/src/common/network/IClientLoginHandler.java b/common/src/common/network/IClientLoginHandler.java similarity index 100% rename from java/src/common/network/IClientLoginHandler.java rename to common/src/common/network/IClientLoginHandler.java diff --git a/java/src/common/network/IClientPlayer.java b/common/src/common/network/IClientPlayer.java similarity index 100% rename from java/src/common/network/IClientPlayer.java rename to common/src/common/network/IClientPlayer.java diff --git a/java/src/common/network/IHandshakeHandler.java b/common/src/common/network/IHandshakeHandler.java similarity index 100% rename from java/src/common/network/IHandshakeHandler.java rename to common/src/common/network/IHandshakeHandler.java diff --git a/java/src/common/network/ILoginHandler.java b/common/src/common/network/ILoginHandler.java similarity index 100% rename from java/src/common/network/ILoginHandler.java rename to common/src/common/network/ILoginHandler.java diff --git a/java/src/common/network/IPlayer.java b/common/src/common/network/IPlayer.java similarity index 100% rename from java/src/common/network/IPlayer.java rename to common/src/common/network/IPlayer.java diff --git a/java/src/common/network/IThreadListener.java b/common/src/common/network/IThreadListener.java similarity index 100% rename from java/src/common/network/IThreadListener.java rename to common/src/common/network/IThreadListener.java diff --git a/java/src/common/network/NetConnection.java b/common/src/common/network/NetConnection.java similarity index 100% rename from java/src/common/network/NetConnection.java rename to common/src/common/network/NetConnection.java diff --git a/java/src/common/network/NetHandler.java b/common/src/common/network/NetHandler.java similarity index 100% rename from java/src/common/network/NetHandler.java rename to common/src/common/network/NetHandler.java diff --git a/java/src/common/network/NettyCompressionDecoder.java b/common/src/common/network/NettyCompressionDecoder.java similarity index 100% rename from java/src/common/network/NettyCompressionDecoder.java rename to common/src/common/network/NettyCompressionDecoder.java diff --git a/java/src/common/network/NettyCompressionEncoder.java b/common/src/common/network/NettyCompressionEncoder.java similarity index 100% rename from java/src/common/network/NettyCompressionEncoder.java rename to common/src/common/network/NettyCompressionEncoder.java diff --git a/java/src/common/network/Packet.java b/common/src/common/network/Packet.java similarity index 100% rename from java/src/common/network/Packet.java rename to common/src/common/network/Packet.java diff --git a/java/src/common/network/PacketBuffer.java b/common/src/common/network/PacketBuffer.java similarity index 100% rename from java/src/common/network/PacketBuffer.java rename to common/src/common/network/PacketBuffer.java diff --git a/java/src/common/network/PacketDecoder.java b/common/src/common/network/PacketDecoder.java similarity index 100% rename from java/src/common/network/PacketDecoder.java rename to common/src/common/network/PacketDecoder.java diff --git a/java/src/common/network/PacketEncoder.java b/common/src/common/network/PacketEncoder.java similarity index 100% rename from java/src/common/network/PacketEncoder.java rename to common/src/common/network/PacketEncoder.java diff --git a/java/src/common/network/PacketPrepender.java b/common/src/common/network/PacketPrepender.java similarity index 100% rename from java/src/common/network/PacketPrepender.java rename to common/src/common/network/PacketPrepender.java diff --git a/java/src/common/network/PacketRegistry.java b/common/src/common/network/PacketRegistry.java similarity index 100% rename from java/src/common/network/PacketRegistry.java rename to common/src/common/network/PacketRegistry.java diff --git a/java/src/common/network/PacketSplitter.java b/common/src/common/network/PacketSplitter.java similarity index 100% rename from java/src/common/network/PacketSplitter.java rename to common/src/common/network/PacketSplitter.java diff --git a/java/src/common/packet/APacketEmpty.java b/common/src/common/packet/APacketEmpty.java similarity index 100% rename from java/src/common/packet/APacketEmpty.java rename to common/src/common/packet/APacketEmpty.java diff --git a/java/src/common/packet/APacketVarInt.java b/common/src/common/packet/APacketVarInt.java similarity index 100% rename from java/src/common/packet/APacketVarInt.java rename to common/src/common/packet/APacketVarInt.java diff --git a/java/src/common/packet/CPacketAction.java b/common/src/common/packet/CPacketAction.java similarity index 100% rename from java/src/common/packet/CPacketAction.java rename to common/src/common/packet/CPacketAction.java diff --git a/java/src/common/packet/CPacketBook.java b/common/src/common/packet/CPacketBook.java similarity index 100% rename from java/src/common/packet/CPacketBook.java rename to common/src/common/packet/CPacketBook.java diff --git a/java/src/common/packet/CPacketBreak.java b/common/src/common/packet/CPacketBreak.java similarity index 100% rename from java/src/common/packet/CPacketBreak.java rename to common/src/common/packet/CPacketBreak.java diff --git a/java/src/common/packet/CPacketCheat.java b/common/src/common/packet/CPacketCheat.java similarity index 100% rename from java/src/common/packet/CPacketCheat.java rename to common/src/common/packet/CPacketCheat.java diff --git a/java/src/common/packet/CPacketClick.java b/common/src/common/packet/CPacketClick.java similarity index 100% rename from java/src/common/packet/CPacketClick.java rename to common/src/common/packet/CPacketClick.java diff --git a/java/src/common/packet/CPacketComplete.java b/common/src/common/packet/CPacketComplete.java similarity index 100% rename from java/src/common/packet/CPacketComplete.java rename to common/src/common/packet/CPacketComplete.java diff --git a/java/src/common/packet/CPacketInput.java b/common/src/common/packet/CPacketInput.java similarity index 100% rename from java/src/common/packet/CPacketInput.java rename to common/src/common/packet/CPacketInput.java diff --git a/java/src/common/packet/CPacketKeepAlive.java b/common/src/common/packet/CPacketKeepAlive.java similarity index 100% rename from java/src/common/packet/CPacketKeepAlive.java rename to common/src/common/packet/CPacketKeepAlive.java diff --git a/java/src/common/packet/CPacketMessage.java b/common/src/common/packet/CPacketMessage.java similarity index 100% rename from java/src/common/packet/CPacketMessage.java rename to common/src/common/packet/CPacketMessage.java diff --git a/java/src/common/packet/CPacketPlace.java b/common/src/common/packet/CPacketPlace.java similarity index 100% rename from java/src/common/packet/CPacketPlace.java rename to common/src/common/packet/CPacketPlace.java diff --git a/java/src/common/packet/CPacketPlayer.java b/common/src/common/packet/CPacketPlayer.java similarity index 100% rename from java/src/common/packet/CPacketPlayer.java rename to common/src/common/packet/CPacketPlayer.java diff --git a/java/src/common/packet/CPacketSign.java b/common/src/common/packet/CPacketSign.java similarity index 100% rename from java/src/common/packet/CPacketSign.java rename to common/src/common/packet/CPacketSign.java diff --git a/java/src/common/packet/CPacketSkin.java b/common/src/common/packet/CPacketSkin.java similarity index 100% rename from java/src/common/packet/CPacketSkin.java rename to common/src/common/packet/CPacketSkin.java diff --git a/java/src/common/packet/HPacketHandshake.java b/common/src/common/packet/HPacketHandshake.java similarity index 100% rename from java/src/common/packet/HPacketHandshake.java rename to common/src/common/packet/HPacketHandshake.java diff --git a/java/src/common/packet/LPacketPasswordResponse.java b/common/src/common/packet/LPacketPasswordResponse.java similarity index 100% rename from java/src/common/packet/LPacketPasswordResponse.java rename to common/src/common/packet/LPacketPasswordResponse.java diff --git a/java/src/common/packet/RPacketDisconnect.java b/common/src/common/packet/RPacketDisconnect.java similarity index 100% rename from java/src/common/packet/RPacketDisconnect.java rename to common/src/common/packet/RPacketDisconnect.java diff --git a/java/src/common/packet/RPacketEnableCompression.java b/common/src/common/packet/RPacketEnableCompression.java similarity index 100% rename from java/src/common/packet/RPacketEnableCompression.java rename to common/src/common/packet/RPacketEnableCompression.java diff --git a/java/src/common/packet/RPacketLoginSuccess.java b/common/src/common/packet/RPacketLoginSuccess.java similarity index 100% rename from java/src/common/packet/RPacketLoginSuccess.java rename to common/src/common/packet/RPacketLoginSuccess.java diff --git a/java/src/common/packet/S14PacketEntity.java b/common/src/common/packet/S14PacketEntity.java similarity index 100% rename from java/src/common/packet/S14PacketEntity.java rename to common/src/common/packet/S14PacketEntity.java diff --git a/java/src/common/packet/S18PacketEntityTeleport.java b/common/src/common/packet/S18PacketEntityTeleport.java similarity index 100% rename from java/src/common/packet/S18PacketEntityTeleport.java rename to common/src/common/packet/S18PacketEntityTeleport.java diff --git a/java/src/common/packet/S19PacketEntityHeadLook.java b/common/src/common/packet/S19PacketEntityHeadLook.java similarity index 100% rename from java/src/common/packet/S19PacketEntityHeadLook.java rename to common/src/common/packet/S19PacketEntityHeadLook.java diff --git a/java/src/common/packet/S1APacketEntityStatus.java b/common/src/common/packet/S1APacketEntityStatus.java similarity index 100% rename from java/src/common/packet/S1APacketEntityStatus.java rename to common/src/common/packet/S1APacketEntityStatus.java diff --git a/java/src/common/packet/S1BPacketEntityAttach.java b/common/src/common/packet/S1BPacketEntityAttach.java similarity index 100% rename from java/src/common/packet/S1BPacketEntityAttach.java rename to common/src/common/packet/S1BPacketEntityAttach.java diff --git a/java/src/common/packet/S1CPacketEntityMetadata.java b/common/src/common/packet/S1CPacketEntityMetadata.java similarity index 100% rename from java/src/common/packet/S1CPacketEntityMetadata.java rename to common/src/common/packet/S1CPacketEntityMetadata.java diff --git a/java/src/common/packet/S1DPacketEntityEffect.java b/common/src/common/packet/S1DPacketEntityEffect.java similarity index 100% rename from java/src/common/packet/S1DPacketEntityEffect.java rename to common/src/common/packet/S1DPacketEntityEffect.java diff --git a/java/src/common/packet/S1EPacketRemoveEntityEffect.java b/common/src/common/packet/S1EPacketRemoveEntityEffect.java similarity index 100% rename from java/src/common/packet/S1EPacketRemoveEntityEffect.java rename to common/src/common/packet/S1EPacketRemoveEntityEffect.java diff --git a/java/src/common/packet/S20PacketEntityProperties.java b/common/src/common/packet/S20PacketEntityProperties.java similarity index 100% rename from java/src/common/packet/S20PacketEntityProperties.java rename to common/src/common/packet/S20PacketEntityProperties.java diff --git a/java/src/common/packet/S27PacketExplosion.java b/common/src/common/packet/S27PacketExplosion.java similarity index 100% rename from java/src/common/packet/S27PacketExplosion.java rename to common/src/common/packet/S27PacketExplosion.java diff --git a/java/src/common/packet/S28PacketEffect.java b/common/src/common/packet/S28PacketEffect.java similarity index 100% rename from java/src/common/packet/S28PacketEffect.java rename to common/src/common/packet/S28PacketEffect.java diff --git a/java/src/common/packet/S29PacketSoundEffect.java b/common/src/common/packet/S29PacketSoundEffect.java similarity index 100% rename from java/src/common/packet/S29PacketSoundEffect.java rename to common/src/common/packet/S29PacketSoundEffect.java diff --git a/java/src/common/packet/S2APacketParticles.java b/common/src/common/packet/S2APacketParticles.java similarity index 100% rename from java/src/common/packet/S2APacketParticles.java rename to common/src/common/packet/S2APacketParticles.java diff --git a/java/src/common/packet/S2BPacketChangeGameState.java b/common/src/common/packet/S2BPacketChangeGameState.java similarity index 100% rename from java/src/common/packet/S2BPacketChangeGameState.java rename to common/src/common/packet/S2BPacketChangeGameState.java diff --git a/java/src/common/packet/S2CPacketSpawnGlobalEntity.java b/common/src/common/packet/S2CPacketSpawnGlobalEntity.java similarity index 100% rename from java/src/common/packet/S2CPacketSpawnGlobalEntity.java rename to common/src/common/packet/S2CPacketSpawnGlobalEntity.java diff --git a/java/src/common/packet/S2DPacketOpenWindow.java b/common/src/common/packet/S2DPacketOpenWindow.java similarity index 100% rename from java/src/common/packet/S2DPacketOpenWindow.java rename to common/src/common/packet/S2DPacketOpenWindow.java diff --git a/java/src/common/packet/S2EPacketCloseWindow.java b/common/src/common/packet/S2EPacketCloseWindow.java similarity index 100% rename from java/src/common/packet/S2EPacketCloseWindow.java rename to common/src/common/packet/S2EPacketCloseWindow.java diff --git a/java/src/common/packet/S2FPacketSetSlot.java b/common/src/common/packet/S2FPacketSetSlot.java similarity index 100% rename from java/src/common/packet/S2FPacketSetSlot.java rename to common/src/common/packet/S2FPacketSetSlot.java diff --git a/java/src/common/packet/S30PacketWindowItems.java b/common/src/common/packet/S30PacketWindowItems.java similarity index 100% rename from java/src/common/packet/S30PacketWindowItems.java rename to common/src/common/packet/S30PacketWindowItems.java diff --git a/java/src/common/packet/S31PacketWindowProperty.java b/common/src/common/packet/S31PacketWindowProperty.java similarity index 100% rename from java/src/common/packet/S31PacketWindowProperty.java rename to common/src/common/packet/S31PacketWindowProperty.java diff --git a/java/src/common/packet/S32PacketConfirmTransaction.java b/common/src/common/packet/S32PacketConfirmTransaction.java similarity index 100% rename from java/src/common/packet/S32PacketConfirmTransaction.java rename to common/src/common/packet/S32PacketConfirmTransaction.java diff --git a/java/src/common/packet/S33PacketUpdateSign.java b/common/src/common/packet/S33PacketUpdateSign.java similarity index 100% rename from java/src/common/packet/S33PacketUpdateSign.java rename to common/src/common/packet/S33PacketUpdateSign.java diff --git a/java/src/common/packet/S35PacketUpdateTileEntity.java b/common/src/common/packet/S35PacketUpdateTileEntity.java similarity index 100% rename from java/src/common/packet/S35PacketUpdateTileEntity.java rename to common/src/common/packet/S35PacketUpdateTileEntity.java diff --git a/java/src/common/packet/S36PacketSignEditorOpen.java b/common/src/common/packet/S36PacketSignEditorOpen.java similarity index 100% rename from java/src/common/packet/S36PacketSignEditorOpen.java rename to common/src/common/packet/S36PacketSignEditorOpen.java diff --git a/java/src/common/packet/S38PacketPlayerListItem.java b/common/src/common/packet/S38PacketPlayerListItem.java similarity index 100% rename from java/src/common/packet/S38PacketPlayerListItem.java rename to common/src/common/packet/S38PacketPlayerListItem.java diff --git a/java/src/common/packet/S39PacketPlayerAbilities.java b/common/src/common/packet/S39PacketPlayerAbilities.java similarity index 100% rename from java/src/common/packet/S39PacketPlayerAbilities.java rename to common/src/common/packet/S39PacketPlayerAbilities.java diff --git a/java/src/common/packet/S3APacketTabComplete.java b/common/src/common/packet/S3APacketTabComplete.java similarity index 100% rename from java/src/common/packet/S3APacketTabComplete.java rename to common/src/common/packet/S3APacketTabComplete.java diff --git a/java/src/common/packet/S43PacketUpdateEntityNBT.java b/common/src/common/packet/S43PacketUpdateEntityNBT.java similarity index 100% rename from java/src/common/packet/S43PacketUpdateEntityNBT.java rename to common/src/common/packet/S43PacketUpdateEntityNBT.java diff --git a/java/src/common/packet/SPacketAnimation.java b/common/src/common/packet/SPacketAnimation.java similarity index 100% rename from java/src/common/packet/SPacketAnimation.java rename to common/src/common/packet/SPacketAnimation.java diff --git a/java/src/common/packet/SPacketBiomes.java b/common/src/common/packet/SPacketBiomes.java similarity index 100% rename from java/src/common/packet/SPacketBiomes.java rename to common/src/common/packet/SPacketBiomes.java diff --git a/java/src/common/packet/SPacketBlockAction.java b/common/src/common/packet/SPacketBlockAction.java similarity index 100% rename from java/src/common/packet/SPacketBlockAction.java rename to common/src/common/packet/SPacketBlockAction.java diff --git a/java/src/common/packet/SPacketBlockBreakAnim.java b/common/src/common/packet/SPacketBlockBreakAnim.java similarity index 100% rename from java/src/common/packet/SPacketBlockBreakAnim.java rename to common/src/common/packet/SPacketBlockBreakAnim.java diff --git a/java/src/common/packet/SPacketBlockChange.java b/common/src/common/packet/SPacketBlockChange.java similarity index 100% rename from java/src/common/packet/SPacketBlockChange.java rename to common/src/common/packet/SPacketBlockChange.java diff --git a/java/src/common/packet/SPacketCamera.java b/common/src/common/packet/SPacketCamera.java similarity index 100% rename from java/src/common/packet/SPacketCamera.java rename to common/src/common/packet/SPacketCamera.java diff --git a/java/src/common/packet/SPacketCharacterList.java b/common/src/common/packet/SPacketCharacterList.java similarity index 100% rename from java/src/common/packet/SPacketCharacterList.java rename to common/src/common/packet/SPacketCharacterList.java diff --git a/java/src/common/packet/SPacketChunkData.java b/common/src/common/packet/SPacketChunkData.java similarity index 100% rename from java/src/common/packet/SPacketChunkData.java rename to common/src/common/packet/SPacketChunkData.java diff --git a/java/src/common/packet/SPacketCollectItem.java b/common/src/common/packet/SPacketCollectItem.java similarity index 100% rename from java/src/common/packet/SPacketCollectItem.java rename to common/src/common/packet/SPacketCollectItem.java diff --git a/java/src/common/packet/SPacketDestroyEntities.java b/common/src/common/packet/SPacketDestroyEntities.java similarity index 100% rename from java/src/common/packet/SPacketDestroyEntities.java rename to common/src/common/packet/SPacketDestroyEntities.java diff --git a/java/src/common/packet/SPacketDimensionName.java b/common/src/common/packet/SPacketDimensionName.java similarity index 100% rename from java/src/common/packet/SPacketDimensionName.java rename to common/src/common/packet/SPacketDimensionName.java diff --git a/java/src/common/packet/SPacketDisconnect.java b/common/src/common/packet/SPacketDisconnect.java similarity index 100% rename from java/src/common/packet/SPacketDisconnect.java rename to common/src/common/packet/SPacketDisconnect.java diff --git a/java/src/common/packet/SPacketEntityEquipment.java b/common/src/common/packet/SPacketEntityEquipment.java similarity index 100% rename from java/src/common/packet/SPacketEntityEquipment.java rename to common/src/common/packet/SPacketEntityEquipment.java diff --git a/java/src/common/packet/SPacketEntityVelocity.java b/common/src/common/packet/SPacketEntityVelocity.java similarity index 100% rename from java/src/common/packet/SPacketEntityVelocity.java rename to common/src/common/packet/SPacketEntityVelocity.java diff --git a/java/src/common/packet/SPacketHeldItemChange.java b/common/src/common/packet/SPacketHeldItemChange.java similarity index 100% rename from java/src/common/packet/SPacketHeldItemChange.java rename to common/src/common/packet/SPacketHeldItemChange.java diff --git a/java/src/common/packet/SPacketJoinGame.java b/common/src/common/packet/SPacketJoinGame.java similarity index 100% rename from java/src/common/packet/SPacketJoinGame.java rename to common/src/common/packet/SPacketJoinGame.java diff --git a/java/src/common/packet/SPacketKeepAlive.java b/common/src/common/packet/SPacketKeepAlive.java similarity index 100% rename from java/src/common/packet/SPacketKeepAlive.java rename to common/src/common/packet/SPacketKeepAlive.java diff --git a/java/src/common/packet/SPacketLoading.java b/common/src/common/packet/SPacketLoading.java similarity index 100% rename from java/src/common/packet/SPacketLoading.java rename to common/src/common/packet/SPacketLoading.java diff --git a/java/src/common/packet/SPacketMapChunkBulk.java b/common/src/common/packet/SPacketMapChunkBulk.java similarity index 100% rename from java/src/common/packet/SPacketMapChunkBulk.java rename to common/src/common/packet/SPacketMapChunkBulk.java diff --git a/java/src/common/packet/SPacketMessage.java b/common/src/common/packet/SPacketMessage.java similarity index 100% rename from java/src/common/packet/SPacketMessage.java rename to common/src/common/packet/SPacketMessage.java diff --git a/java/src/common/packet/SPacketMultiBlockChange.java b/common/src/common/packet/SPacketMultiBlockChange.java similarity index 100% rename from java/src/common/packet/SPacketMultiBlockChange.java rename to common/src/common/packet/SPacketMultiBlockChange.java diff --git a/java/src/common/packet/SPacketPlayerPosLook.java b/common/src/common/packet/SPacketPlayerPosLook.java similarity index 100% rename from java/src/common/packet/SPacketPlayerPosLook.java rename to common/src/common/packet/SPacketPlayerPosLook.java diff --git a/java/src/common/packet/SPacketRespawn.java b/common/src/common/packet/SPacketRespawn.java similarity index 100% rename from java/src/common/packet/SPacketRespawn.java rename to common/src/common/packet/SPacketRespawn.java diff --git a/java/src/common/packet/SPacketServerTick.java b/common/src/common/packet/SPacketServerTick.java similarity index 100% rename from java/src/common/packet/SPacketServerTick.java rename to common/src/common/packet/SPacketServerTick.java diff --git a/java/src/common/packet/SPacketSetExperience.java b/common/src/common/packet/SPacketSetExperience.java similarity index 100% rename from java/src/common/packet/SPacketSetExperience.java rename to common/src/common/packet/SPacketSetExperience.java diff --git a/java/src/common/packet/SPacketSkin.java b/common/src/common/packet/SPacketSkin.java similarity index 100% rename from java/src/common/packet/SPacketSkin.java rename to common/src/common/packet/SPacketSkin.java diff --git a/java/src/common/packet/SPacketSpawnMob.java b/common/src/common/packet/SPacketSpawnMob.java similarity index 100% rename from java/src/common/packet/SPacketSpawnMob.java rename to common/src/common/packet/SPacketSpawnMob.java diff --git a/java/src/common/packet/SPacketSpawnObject.java b/common/src/common/packet/SPacketSpawnObject.java similarity index 100% rename from java/src/common/packet/SPacketSpawnObject.java rename to common/src/common/packet/SPacketSpawnObject.java diff --git a/java/src/common/packet/SPacketSpawnPlayer.java b/common/src/common/packet/SPacketSpawnPlayer.java similarity index 100% rename from java/src/common/packet/SPacketSpawnPlayer.java rename to common/src/common/packet/SPacketSpawnPlayer.java diff --git a/java/src/common/packet/SPacketTimeUpdate.java b/common/src/common/packet/SPacketTimeUpdate.java similarity index 100% rename from java/src/common/packet/SPacketTimeUpdate.java rename to common/src/common/packet/SPacketTimeUpdate.java diff --git a/java/src/common/packet/SPacketTrades.java b/common/src/common/packet/SPacketTrades.java similarity index 100% rename from java/src/common/packet/SPacketTrades.java rename to common/src/common/packet/SPacketTrades.java diff --git a/java/src/common/packet/SPacketUpdateHealth.java b/common/src/common/packet/SPacketUpdateHealth.java similarity index 100% rename from java/src/common/packet/SPacketUpdateHealth.java rename to common/src/common/packet/SPacketUpdateHealth.java diff --git a/java/src/common/packet/SPacketWorld.java b/common/src/common/packet/SPacketWorld.java similarity index 100% rename from java/src/common/packet/SPacketWorld.java rename to common/src/common/packet/SPacketWorld.java diff --git a/java/src/common/pathfinding/NodeProcessor.java b/common/src/common/pathfinding/NodeProcessor.java similarity index 100% rename from java/src/common/pathfinding/NodeProcessor.java rename to common/src/common/pathfinding/NodeProcessor.java diff --git a/java/src/common/pathfinding/Path.java b/common/src/common/pathfinding/Path.java similarity index 100% rename from java/src/common/pathfinding/Path.java rename to common/src/common/pathfinding/Path.java diff --git a/java/src/common/pathfinding/PathCache.java b/common/src/common/pathfinding/PathCache.java similarity index 100% rename from java/src/common/pathfinding/PathCache.java rename to common/src/common/pathfinding/PathCache.java diff --git a/java/src/common/pathfinding/PathEntity.java b/common/src/common/pathfinding/PathEntity.java similarity index 100% rename from java/src/common/pathfinding/PathEntity.java rename to common/src/common/pathfinding/PathEntity.java diff --git a/java/src/common/pathfinding/PathFinder.java b/common/src/common/pathfinding/PathFinder.java similarity index 100% rename from java/src/common/pathfinding/PathFinder.java rename to common/src/common/pathfinding/PathFinder.java diff --git a/java/src/common/pathfinding/PathNavigate.java b/common/src/common/pathfinding/PathNavigate.java similarity index 100% rename from java/src/common/pathfinding/PathNavigate.java rename to common/src/common/pathfinding/PathNavigate.java diff --git a/java/src/common/pathfinding/PathNavigateClimber.java b/common/src/common/pathfinding/PathNavigateClimber.java similarity index 100% rename from java/src/common/pathfinding/PathNavigateClimber.java rename to common/src/common/pathfinding/PathNavigateClimber.java diff --git a/java/src/common/pathfinding/PathNavigateGround.java b/common/src/common/pathfinding/PathNavigateGround.java similarity index 100% rename from java/src/common/pathfinding/PathNavigateGround.java rename to common/src/common/pathfinding/PathNavigateGround.java diff --git a/java/src/common/pathfinding/PathPoint.java b/common/src/common/pathfinding/PathPoint.java similarity index 100% rename from java/src/common/pathfinding/PathPoint.java rename to common/src/common/pathfinding/PathPoint.java diff --git a/java/src/common/pathfinding/SwimNodeProcessor.java b/common/src/common/pathfinding/SwimNodeProcessor.java similarity index 100% rename from java/src/common/pathfinding/SwimNodeProcessor.java rename to common/src/common/pathfinding/SwimNodeProcessor.java diff --git a/java/src/common/pathfinding/WalkNodeProcessor.java b/common/src/common/pathfinding/WalkNodeProcessor.java similarity index 100% rename from java/src/common/pathfinding/WalkNodeProcessor.java rename to common/src/common/pathfinding/WalkNodeProcessor.java diff --git a/java/src/common/pattern/BlockStateHelper.java b/common/src/common/pattern/BlockStateHelper.java similarity index 100% rename from java/src/common/pattern/BlockStateHelper.java rename to common/src/common/pattern/BlockStateHelper.java diff --git a/java/src/common/potion/Potion.java b/common/src/common/potion/Potion.java similarity index 100% rename from java/src/common/potion/Potion.java rename to common/src/common/potion/Potion.java diff --git a/java/src/common/potion/PotionEffect.java b/common/src/common/potion/PotionEffect.java similarity index 100% rename from java/src/common/potion/PotionEffect.java rename to common/src/common/potion/PotionEffect.java diff --git a/java/src/common/potion/PotionHelper.java b/common/src/common/potion/PotionHelper.java similarity index 100% rename from java/src/common/potion/PotionHelper.java rename to common/src/common/potion/PotionHelper.java diff --git a/java/src/common/properties/IProperty.java b/common/src/common/properties/IProperty.java similarity index 100% rename from java/src/common/properties/IProperty.java rename to common/src/common/properties/IProperty.java diff --git a/java/src/common/properties/PropertyBool.java b/common/src/common/properties/PropertyBool.java similarity index 100% rename from java/src/common/properties/PropertyBool.java rename to common/src/common/properties/PropertyBool.java diff --git a/java/src/common/properties/PropertyDirection.java b/common/src/common/properties/PropertyDirection.java similarity index 100% rename from java/src/common/properties/PropertyDirection.java rename to common/src/common/properties/PropertyDirection.java diff --git a/java/src/common/properties/PropertyEnum.java b/common/src/common/properties/PropertyEnum.java similarity index 100% rename from java/src/common/properties/PropertyEnum.java rename to common/src/common/properties/PropertyEnum.java diff --git a/java/src/common/properties/PropertyHelper.java b/common/src/common/properties/PropertyHelper.java similarity index 100% rename from java/src/common/properties/PropertyHelper.java rename to common/src/common/properties/PropertyHelper.java diff --git a/java/src/common/properties/PropertyInteger.java b/common/src/common/properties/PropertyInteger.java similarity index 100% rename from java/src/common/properties/PropertyInteger.java rename to common/src/common/properties/PropertyInteger.java diff --git a/java/src/common/rng/ImprovedGen.java b/common/src/common/rng/ImprovedGen.java similarity index 100% rename from java/src/common/rng/ImprovedGen.java rename to common/src/common/rng/ImprovedGen.java diff --git a/java/src/common/rng/ImprovedGenOld.java b/common/src/common/rng/ImprovedGenOld.java similarity index 100% rename from java/src/common/rng/ImprovedGenOld.java rename to common/src/common/rng/ImprovedGenOld.java diff --git a/java/src/common/rng/NoiseGen.java b/common/src/common/rng/NoiseGen.java similarity index 100% rename from java/src/common/rng/NoiseGen.java rename to common/src/common/rng/NoiseGen.java diff --git a/java/src/common/rng/OctaveGen.java b/common/src/common/rng/OctaveGen.java similarity index 100% rename from java/src/common/rng/OctaveGen.java rename to common/src/common/rng/OctaveGen.java diff --git a/java/src/common/rng/OctaveGenOld.java b/common/src/common/rng/OctaveGenOld.java similarity index 100% rename from java/src/common/rng/OctaveGenOld.java rename to common/src/common/rng/OctaveGenOld.java diff --git a/java/src/common/rng/PerlinGen.java b/common/src/common/rng/PerlinGen.java similarity index 100% rename from java/src/common/rng/PerlinGen.java rename to common/src/common/rng/PerlinGen.java diff --git a/java/src/common/rng/PerlinGenOld.java b/common/src/common/rng/PerlinGenOld.java similarity index 100% rename from java/src/common/rng/PerlinGenOld.java rename to common/src/common/rng/PerlinGenOld.java diff --git a/java/src/common/rng/Random.java b/common/src/common/rng/Random.java similarity index 100% rename from java/src/common/rng/Random.java rename to common/src/common/rng/Random.java diff --git a/java/src/common/rng/RngItem.java b/common/src/common/rng/RngItem.java similarity index 100% rename from java/src/common/rng/RngItem.java rename to common/src/common/rng/RngItem.java diff --git a/java/src/common/rng/SimplexGen.java b/common/src/common/rng/SimplexGen.java similarity index 100% rename from java/src/common/rng/SimplexGen.java rename to common/src/common/rng/SimplexGen.java diff --git a/java/src/common/rng/SimplexGenOld.java b/common/src/common/rng/SimplexGenOld.java similarity index 100% rename from java/src/common/rng/SimplexGenOld.java rename to common/src/common/rng/SimplexGenOld.java diff --git a/java/src/common/rng/WeightedList.java b/common/src/common/rng/WeightedList.java similarity index 100% rename from java/src/common/rng/WeightedList.java rename to common/src/common/rng/WeightedList.java diff --git a/java/src/common/sound/EventType.java b/common/src/common/sound/EventType.java similarity index 100% rename from java/src/common/sound/EventType.java rename to common/src/common/sound/EventType.java diff --git a/java/src/common/sound/MovingSound.java b/common/src/common/sound/MovingSound.java similarity index 100% rename from java/src/common/sound/MovingSound.java rename to common/src/common/sound/MovingSound.java diff --git a/java/src/common/sound/MovingSoundMinecart.java b/common/src/common/sound/MovingSoundMinecart.java similarity index 100% rename from java/src/common/sound/MovingSoundMinecart.java rename to common/src/common/sound/MovingSoundMinecart.java diff --git a/java/src/common/sound/MovingSoundMinecartRiding.java b/common/src/common/sound/MovingSoundMinecartRiding.java similarity index 100% rename from java/src/common/sound/MovingSoundMinecartRiding.java rename to common/src/common/sound/MovingSoundMinecartRiding.java diff --git a/java/src/common/sound/PositionedSound.java b/common/src/common/sound/PositionedSound.java similarity index 100% rename from java/src/common/sound/PositionedSound.java rename to common/src/common/sound/PositionedSound.java diff --git a/java/src/common/sound/Sound.java b/common/src/common/sound/Sound.java similarity index 100% rename from java/src/common/sound/Sound.java rename to common/src/common/sound/Sound.java diff --git a/java/src/common/tileentity/IHopper.java b/common/src/common/tileentity/IHopper.java similarity index 100% rename from java/src/common/tileentity/IHopper.java rename to common/src/common/tileentity/IHopper.java diff --git a/java/src/common/tileentity/IInteractionObject.java b/common/src/common/tileentity/IInteractionObject.java similarity index 100% rename from java/src/common/tileentity/IInteractionObject.java rename to common/src/common/tileentity/IInteractionObject.java diff --git a/java/src/common/tileentity/ILockableContainer.java b/common/src/common/tileentity/ILockableContainer.java similarity index 100% rename from java/src/common/tileentity/ILockableContainer.java rename to common/src/common/tileentity/ILockableContainer.java diff --git a/java/src/common/tileentity/ITickable.java b/common/src/common/tileentity/ITickable.java similarity index 100% rename from java/src/common/tileentity/ITickable.java rename to common/src/common/tileentity/ITickable.java diff --git a/java/src/common/tileentity/IWorldNameable.java b/common/src/common/tileentity/IWorldNameable.java similarity index 100% rename from java/src/common/tileentity/IWorldNameable.java rename to common/src/common/tileentity/IWorldNameable.java diff --git a/java/src/common/tileentity/LocalBlockIntercommunication.java b/common/src/common/tileentity/LocalBlockIntercommunication.java similarity index 100% rename from java/src/common/tileentity/LocalBlockIntercommunication.java rename to common/src/common/tileentity/LocalBlockIntercommunication.java diff --git a/java/src/common/tileentity/LockCode.java b/common/src/common/tileentity/LockCode.java similarity index 100% rename from java/src/common/tileentity/LockCode.java rename to common/src/common/tileentity/LockCode.java diff --git a/java/src/common/tileentity/MachineResource.java b/common/src/common/tileentity/MachineResource.java similarity index 100% rename from java/src/common/tileentity/MachineResource.java rename to common/src/common/tileentity/MachineResource.java diff --git a/java/src/common/tileentity/TileEntity.java b/common/src/common/tileentity/TileEntity.java similarity index 100% rename from java/src/common/tileentity/TileEntity.java rename to common/src/common/tileentity/TileEntity.java diff --git a/java/src/common/tileentity/TileEntityBanner.java b/common/src/common/tileentity/TileEntityBanner.java similarity index 100% rename from java/src/common/tileentity/TileEntityBanner.java rename to common/src/common/tileentity/TileEntityBanner.java diff --git a/java/src/common/tileentity/TileEntityBeacon.java b/common/src/common/tileentity/TileEntityBeacon.java similarity index 100% rename from java/src/common/tileentity/TileEntityBeacon.java rename to common/src/common/tileentity/TileEntityBeacon.java diff --git a/java/src/common/tileentity/TileEntityBrewingStand.java b/common/src/common/tileentity/TileEntityBrewingStand.java similarity index 100% rename from java/src/common/tileentity/TileEntityBrewingStand.java rename to common/src/common/tileentity/TileEntityBrewingStand.java diff --git a/java/src/common/tileentity/TileEntityChest.java b/common/src/common/tileentity/TileEntityChest.java similarity index 100% rename from java/src/common/tileentity/TileEntityChest.java rename to common/src/common/tileentity/TileEntityChest.java diff --git a/java/src/common/tileentity/TileEntityComparator.java b/common/src/common/tileentity/TileEntityComparator.java similarity index 100% rename from java/src/common/tileentity/TileEntityComparator.java rename to common/src/common/tileentity/TileEntityComparator.java diff --git a/java/src/common/tileentity/TileEntityDaylightDetector.java b/common/src/common/tileentity/TileEntityDaylightDetector.java similarity index 100% rename from java/src/common/tileentity/TileEntityDaylightDetector.java rename to common/src/common/tileentity/TileEntityDaylightDetector.java diff --git a/java/src/common/tileentity/TileEntityDispenser.java b/common/src/common/tileentity/TileEntityDispenser.java similarity index 100% rename from java/src/common/tileentity/TileEntityDispenser.java rename to common/src/common/tileentity/TileEntityDispenser.java diff --git a/java/src/common/tileentity/TileEntityDropper.java b/common/src/common/tileentity/TileEntityDropper.java similarity index 100% rename from java/src/common/tileentity/TileEntityDropper.java rename to common/src/common/tileentity/TileEntityDropper.java diff --git a/java/src/common/tileentity/TileEntityEnchantmentTable.java b/common/src/common/tileentity/TileEntityEnchantmentTable.java similarity index 100% rename from java/src/common/tileentity/TileEntityEnchantmentTable.java rename to common/src/common/tileentity/TileEntityEnchantmentTable.java diff --git a/java/src/common/tileentity/TileEntityFurnace.java b/common/src/common/tileentity/TileEntityFurnace.java similarity index 100% rename from java/src/common/tileentity/TileEntityFurnace.java rename to common/src/common/tileentity/TileEntityFurnace.java diff --git a/java/src/common/tileentity/TileEntityHopper.java b/common/src/common/tileentity/TileEntityHopper.java similarity index 100% rename from java/src/common/tileentity/TileEntityHopper.java rename to common/src/common/tileentity/TileEntityHopper.java diff --git a/java/src/common/tileentity/TileEntityLockable.java b/common/src/common/tileentity/TileEntityLockable.java similarity index 100% rename from java/src/common/tileentity/TileEntityLockable.java rename to common/src/common/tileentity/TileEntityLockable.java diff --git a/java/src/common/tileentity/TileEntityMachine.java b/common/src/common/tileentity/TileEntityMachine.java similarity index 100% rename from java/src/common/tileentity/TileEntityMachine.java rename to common/src/common/tileentity/TileEntityMachine.java diff --git a/java/src/common/tileentity/TileEntityMobSpawner.java b/common/src/common/tileentity/TileEntityMobSpawner.java similarity index 100% rename from java/src/common/tileentity/TileEntityMobSpawner.java rename to common/src/common/tileentity/TileEntityMobSpawner.java diff --git a/java/src/common/tileentity/TileEntityNote.java b/common/src/common/tileentity/TileEntityNote.java similarity index 100% rename from java/src/common/tileentity/TileEntityNote.java rename to common/src/common/tileentity/TileEntityNote.java diff --git a/java/src/common/tileentity/TileEntityPiston.java b/common/src/common/tileentity/TileEntityPiston.java similarity index 100% rename from java/src/common/tileentity/TileEntityPiston.java rename to common/src/common/tileentity/TileEntityPiston.java diff --git a/java/src/common/tileentity/TileEntitySign.java b/common/src/common/tileentity/TileEntitySign.java similarity index 100% rename from java/src/common/tileentity/TileEntitySign.java rename to common/src/common/tileentity/TileEntitySign.java diff --git a/java/src/common/tileentity/TileEntitySkull.java b/common/src/common/tileentity/TileEntitySkull.java similarity index 100% rename from java/src/common/tileentity/TileEntitySkull.java rename to common/src/common/tileentity/TileEntitySkull.java diff --git a/java/src/common/tileentity/TileEntityTianReactor.java b/common/src/common/tileentity/TileEntityTianReactor.java similarity index 100% rename from java/src/common/tileentity/TileEntityTianReactor.java rename to common/src/common/tileentity/TileEntityTianReactor.java diff --git a/java/src/common/util/CharValidator.java b/common/src/common/util/CharValidator.java similarity index 100% rename from java/src/common/util/CharValidator.java rename to common/src/common/util/CharValidator.java diff --git a/java/src/common/util/DC32.java b/common/src/common/util/DC32.java similarity index 100% rename from java/src/common/util/DC32.java rename to common/src/common/util/DC32.java diff --git a/java/src/common/util/Displayable.java b/common/src/common/util/Displayable.java similarity index 100% rename from java/src/common/util/Displayable.java rename to common/src/common/util/Displayable.java diff --git a/java/src/common/util/ExtMath.java b/common/src/common/util/ExtMath.java similarity index 100% rename from java/src/common/util/ExtMath.java rename to common/src/common/util/ExtMath.java diff --git a/java/src/common/util/FileUtils.java b/common/src/common/util/FileUtils.java similarity index 100% rename from java/src/common/util/FileUtils.java rename to common/src/common/util/FileUtils.java diff --git a/java/src/common/util/Identifyable.java b/common/src/common/util/Identifyable.java similarity index 100% rename from java/src/common/util/Identifyable.java rename to common/src/common/util/Identifyable.java diff --git a/java/src/common/util/LazyLoadBase.java b/common/src/common/util/LazyLoadBase.java similarity index 100% rename from java/src/common/util/LazyLoadBase.java rename to common/src/common/util/LazyLoadBase.java diff --git a/java/src/common/util/Matrix4f.java b/common/src/common/util/Matrix4f.java similarity index 100% rename from java/src/common/util/Matrix4f.java rename to common/src/common/util/Matrix4f.java diff --git a/java/src/common/util/Predicates.java b/common/src/common/util/Predicates.java similarity index 100% rename from java/src/common/util/Predicates.java rename to common/src/common/util/Predicates.java diff --git a/java/src/common/util/Tuple.java b/common/src/common/util/Tuple.java similarity index 100% rename from java/src/common/util/Tuple.java rename to common/src/common/util/Tuple.java diff --git a/java/src/common/util/Util.java b/common/src/common/util/Util.java similarity index 100% rename from java/src/common/util/Util.java rename to common/src/common/util/Util.java diff --git a/java/src/common/util/Vector.java b/common/src/common/util/Vector.java similarity index 100% rename from java/src/common/util/Vector.java rename to common/src/common/util/Vector.java diff --git a/java/src/common/util/Vector3f.java b/common/src/common/util/Vector3f.java similarity index 100% rename from java/src/common/util/Vector3f.java rename to common/src/common/util/Vector3f.java diff --git a/java/src/common/util/Vector4f.java b/common/src/common/util/Vector4f.java similarity index 100% rename from java/src/common/util/Vector4f.java rename to common/src/common/util/Vector4f.java diff --git a/java/src/common/village/MerchantRecipe.java b/common/src/common/village/MerchantRecipe.java similarity index 100% rename from java/src/common/village/MerchantRecipe.java rename to common/src/common/village/MerchantRecipe.java diff --git a/java/src/common/village/MerchantRecipeList.java b/common/src/common/village/MerchantRecipeList.java similarity index 100% rename from java/src/common/village/MerchantRecipeList.java rename to common/src/common/village/MerchantRecipeList.java diff --git a/java/src/common/village/Village.java b/common/src/common/village/Village.java similarity index 100% rename from java/src/common/village/Village.java rename to common/src/common/village/Village.java diff --git a/java/src/common/village/VillageCollection.java b/common/src/common/village/VillageCollection.java similarity index 100% rename from java/src/common/village/VillageCollection.java rename to common/src/common/village/VillageCollection.java diff --git a/java/src/common/village/VillageDoorInfo.java b/common/src/common/village/VillageDoorInfo.java similarity index 100% rename from java/src/common/village/VillageDoorInfo.java rename to common/src/common/village/VillageDoorInfo.java diff --git a/java/src/common/world/BlockArray.java b/common/src/common/world/BlockArray.java similarity index 100% rename from java/src/common/world/BlockArray.java rename to common/src/common/world/BlockArray.java diff --git a/java/src/common/world/BlockPos.java b/common/src/common/world/BlockPos.java similarity index 100% rename from java/src/common/world/BlockPos.java rename to common/src/common/world/BlockPos.java diff --git a/java/src/common/world/BoundingBox.java b/common/src/common/world/BoundingBox.java similarity index 100% rename from java/src/common/world/BoundingBox.java rename to common/src/common/world/BoundingBox.java diff --git a/java/src/common/world/Chunk.java b/common/src/common/world/Chunk.java similarity index 100% rename from java/src/common/world/Chunk.java rename to common/src/common/world/Chunk.java diff --git a/java/src/common/world/ChunkCache.java b/common/src/common/world/ChunkCache.java similarity index 100% rename from java/src/common/world/ChunkCache.java rename to common/src/common/world/ChunkCache.java diff --git a/java/src/common/world/ChunkPos.java b/common/src/common/world/ChunkPos.java similarity index 100% rename from java/src/common/world/ChunkPos.java rename to common/src/common/world/ChunkPos.java diff --git a/java/src/common/world/ClassInheritanceMultiMap.java b/common/src/common/world/ClassInheritanceMultiMap.java similarity index 100% rename from java/src/common/world/ClassInheritanceMultiMap.java rename to common/src/common/world/ClassInheritanceMultiMap.java diff --git a/java/src/common/world/EmptyChunk.java b/common/src/common/world/EmptyChunk.java similarity index 100% rename from java/src/common/world/EmptyChunk.java rename to common/src/common/world/EmptyChunk.java diff --git a/java/src/common/world/Explosion.java b/common/src/common/world/Explosion.java similarity index 100% rename from java/src/common/world/Explosion.java rename to common/src/common/world/Explosion.java diff --git a/java/src/common/world/Facing.java b/common/src/common/world/Facing.java similarity index 100% rename from java/src/common/world/Facing.java rename to common/src/common/world/Facing.java diff --git a/java/src/common/world/HitPosition.java b/common/src/common/world/HitPosition.java similarity index 100% rename from java/src/common/world/HitPosition.java rename to common/src/common/world/HitPosition.java diff --git a/java/src/common/world/IBlockAccess.java b/common/src/common/world/IBlockAccess.java similarity index 100% rename from java/src/common/world/IBlockAccess.java rename to common/src/common/world/IBlockAccess.java diff --git a/java/src/common/world/IWorldAccess.java b/common/src/common/world/IWorldAccess.java similarity index 100% rename from java/src/common/world/IWorldAccess.java rename to common/src/common/world/IWorldAccess.java diff --git a/java/src/common/world/IntHashMap.java b/common/src/common/world/IntHashMap.java similarity index 100% rename from java/src/common/world/IntHashMap.java rename to common/src/common/world/IntHashMap.java diff --git a/java/src/common/world/LightType.java b/common/src/common/world/LightType.java similarity index 100% rename from java/src/common/world/LightType.java rename to common/src/common/world/LightType.java diff --git a/java/src/common/world/LongHashMap.java b/common/src/common/world/LongHashMap.java similarity index 100% rename from java/src/common/world/LongHashMap.java rename to common/src/common/world/LongHashMap.java diff --git a/java/src/common/world/NextTickListEntry.java b/common/src/common/world/NextTickListEntry.java similarity index 100% rename from java/src/common/world/NextTickListEntry.java rename to common/src/common/world/NextTickListEntry.java diff --git a/java/src/common/world/NibbleArray.java b/common/src/common/world/NibbleArray.java similarity index 100% rename from java/src/common/world/NibbleArray.java rename to common/src/common/world/NibbleArray.java diff --git a/java/src/common/world/PortalType.java b/common/src/common/world/PortalType.java similarity index 100% rename from java/src/common/world/PortalType.java rename to common/src/common/world/PortalType.java diff --git a/java/src/common/world/Position.java b/common/src/common/world/Position.java similarity index 100% rename from java/src/common/world/Position.java rename to common/src/common/world/Position.java diff --git a/java/src/common/world/Region.java b/common/src/common/world/Region.java similarity index 100% rename from java/src/common/world/Region.java rename to common/src/common/world/Region.java diff --git a/java/src/common/world/Spawner.java b/common/src/common/world/Spawner.java similarity index 100% rename from java/src/common/world/Spawner.java rename to common/src/common/world/Spawner.java diff --git a/java/src/common/world/State.java b/common/src/common/world/State.java similarity index 100% rename from java/src/common/world/State.java rename to common/src/common/world/State.java diff --git a/java/src/common/world/Vec3.java b/common/src/common/world/Vec3.java similarity index 100% rename from java/src/common/world/Vec3.java rename to common/src/common/world/Vec3.java diff --git a/java/src/common/world/Vec3i.java b/common/src/common/world/Vec3i.java similarity index 100% rename from java/src/common/world/Vec3i.java rename to common/src/common/world/Vec3i.java diff --git a/java/src/common/world/Weather.java b/common/src/common/world/Weather.java similarity index 100% rename from java/src/common/world/Weather.java rename to common/src/common/world/Weather.java diff --git a/java/src/common/world/World.java b/common/src/common/world/World.java similarity index 100% rename from java/src/common/world/World.java rename to common/src/common/world/World.java diff --git a/java/src/common/world/WorldClient.java b/common/src/common/world/WorldClient.java similarity index 100% rename from java/src/common/world/WorldClient.java rename to common/src/common/world/WorldClient.java diff --git a/java/src/common/world/WorldPos.java b/common/src/common/world/WorldPos.java similarity index 100% rename from java/src/common/world/WorldPos.java rename to common/src/common/world/WorldPos.java diff --git a/java/src/common/world/WorldServer.java b/common/src/common/world/WorldServer.java similarity index 100% rename from java/src/common/world/WorldServer.java rename to common/src/common/world/WorldServer.java diff --git a/java/src/common/worldgen/BiomeGenLayered.java b/common/src/common/worldgen/BiomeGenLayered.java similarity index 100% rename from java/src/common/worldgen/BiomeGenLayered.java rename to common/src/common/worldgen/BiomeGenLayered.java diff --git a/java/src/common/worldgen/BiomeGenPerlin.java b/common/src/common/worldgen/BiomeGenPerlin.java similarity index 100% rename from java/src/common/worldgen/BiomeGenPerlin.java rename to common/src/common/worldgen/BiomeGenPerlin.java diff --git a/java/src/common/worldgen/BiomeGenSingle.java b/common/src/common/worldgen/BiomeGenSingle.java similarity index 100% rename from java/src/common/worldgen/BiomeGenSingle.java rename to common/src/common/worldgen/BiomeGenSingle.java diff --git a/java/src/common/worldgen/BiomeGenerator.java b/common/src/common/worldgen/BiomeGenerator.java similarity index 100% rename from java/src/common/worldgen/BiomeGenerator.java rename to common/src/common/worldgen/BiomeGenerator.java diff --git a/java/src/common/worldgen/BlockReplacer.java b/common/src/common/worldgen/BlockReplacer.java similarity index 100% rename from java/src/common/worldgen/BlockReplacer.java rename to common/src/common/worldgen/BlockReplacer.java diff --git a/java/src/common/worldgen/ChunkGenerator.java b/common/src/common/worldgen/ChunkGenerator.java similarity index 100% rename from java/src/common/worldgen/ChunkGenerator.java rename to common/src/common/worldgen/ChunkGenerator.java diff --git a/java/src/common/worldgen/ChunkPrimer.java b/common/src/common/worldgen/ChunkPrimer.java similarity index 100% rename from java/src/common/worldgen/ChunkPrimer.java rename to common/src/common/worldgen/ChunkPrimer.java diff --git a/java/src/common/worldgen/FeatureDungeons.java b/common/src/common/worldgen/FeatureDungeons.java similarity index 100% rename from java/src/common/worldgen/FeatureDungeons.java rename to common/src/common/worldgen/FeatureDungeons.java diff --git a/java/src/common/worldgen/FeatureGenerator.java b/common/src/common/worldgen/FeatureGenerator.java similarity index 100% rename from java/src/common/worldgen/FeatureGenerator.java rename to common/src/common/worldgen/FeatureGenerator.java diff --git a/java/src/common/worldgen/FeatureLakes.java b/common/src/common/worldgen/FeatureLakes.java similarity index 100% rename from java/src/common/worldgen/FeatureLakes.java rename to common/src/common/worldgen/FeatureLakes.java diff --git a/java/src/common/worldgen/FeatureLiquids.java b/common/src/common/worldgen/FeatureLiquids.java similarity index 100% rename from java/src/common/worldgen/FeatureLiquids.java rename to common/src/common/worldgen/FeatureLiquids.java diff --git a/java/src/common/worldgen/FeatureOres.java b/common/src/common/worldgen/FeatureOres.java similarity index 100% rename from java/src/common/worldgen/FeatureOres.java rename to common/src/common/worldgen/FeatureOres.java diff --git a/java/src/common/worldgen/GeneratorCavern.java b/common/src/common/worldgen/GeneratorCavern.java similarity index 100% rename from java/src/common/worldgen/GeneratorCavern.java rename to common/src/common/worldgen/GeneratorCavern.java diff --git a/java/src/common/worldgen/GeneratorDebug.java b/common/src/common/worldgen/GeneratorDebug.java similarity index 100% rename from java/src/common/worldgen/GeneratorDebug.java rename to common/src/common/worldgen/GeneratorDebug.java diff --git a/java/src/common/worldgen/GeneratorDestroyed.java b/common/src/common/worldgen/GeneratorDestroyed.java similarity index 100% rename from java/src/common/worldgen/GeneratorDestroyed.java rename to common/src/common/worldgen/GeneratorDestroyed.java diff --git a/java/src/common/worldgen/GeneratorFlat.java b/common/src/common/worldgen/GeneratorFlat.java similarity index 100% rename from java/src/common/worldgen/GeneratorFlat.java rename to common/src/common/worldgen/GeneratorFlat.java diff --git a/java/src/common/worldgen/GeneratorIsland.java b/common/src/common/worldgen/GeneratorIsland.java similarity index 100% rename from java/src/common/worldgen/GeneratorIsland.java rename to common/src/common/worldgen/GeneratorIsland.java diff --git a/java/src/common/worldgen/GeneratorPerlin.java b/common/src/common/worldgen/GeneratorPerlin.java similarity index 100% rename from java/src/common/worldgen/GeneratorPerlin.java rename to common/src/common/worldgen/GeneratorPerlin.java diff --git a/java/src/common/worldgen/GeneratorSimple.java b/common/src/common/worldgen/GeneratorSimple.java similarity index 100% rename from java/src/common/worldgen/GeneratorSimple.java rename to common/src/common/worldgen/GeneratorSimple.java diff --git a/java/src/common/worldgen/LootConstants.java b/common/src/common/worldgen/LootConstants.java similarity index 100% rename from java/src/common/worldgen/LootConstants.java rename to common/src/common/worldgen/LootConstants.java diff --git a/java/src/common/worldgen/ReplacerAltBiome.java b/common/src/common/worldgen/ReplacerAltBiome.java similarity index 100% rename from java/src/common/worldgen/ReplacerAltBiome.java rename to common/src/common/worldgen/ReplacerAltBiome.java diff --git a/java/src/common/worldgen/ReplacerAltSurface.java b/common/src/common/worldgen/ReplacerAltSurface.java similarity index 100% rename from java/src/common/worldgen/ReplacerAltSurface.java rename to common/src/common/worldgen/ReplacerAltSurface.java diff --git a/java/src/common/worldgen/ReplacerBiome.java b/common/src/common/worldgen/ReplacerBiome.java similarity index 100% rename from java/src/common/worldgen/ReplacerBiome.java rename to common/src/common/worldgen/ReplacerBiome.java diff --git a/java/src/common/worldgen/ReplacerTopLayer.java b/common/src/common/worldgen/ReplacerTopLayer.java similarity index 100% rename from java/src/common/worldgen/ReplacerTopLayer.java rename to common/src/common/worldgen/ReplacerTopLayer.java diff --git a/java/src/common/worldgen/caves/MapGenBase.java b/common/src/common/worldgen/caves/MapGenBase.java similarity index 100% rename from java/src/common/worldgen/caves/MapGenBase.java rename to common/src/common/worldgen/caves/MapGenBase.java diff --git a/java/src/common/worldgen/caves/MapGenBigCaves.java b/common/src/common/worldgen/caves/MapGenBigCaves.java similarity index 100% rename from java/src/common/worldgen/caves/MapGenBigCaves.java rename to common/src/common/worldgen/caves/MapGenBigCaves.java diff --git a/java/src/common/worldgen/caves/MapGenCaves.java b/common/src/common/worldgen/caves/MapGenCaves.java similarity index 100% rename from java/src/common/worldgen/caves/MapGenCaves.java rename to common/src/common/worldgen/caves/MapGenCaves.java diff --git a/java/src/common/worldgen/caves/MapGenRavine.java b/common/src/common/worldgen/caves/MapGenRavine.java similarity index 100% rename from java/src/common/worldgen/caves/MapGenRavine.java rename to common/src/common/worldgen/caves/MapGenRavine.java diff --git a/java/src/common/worldgen/feature/WorldGenAbandonedChest.java b/common/src/common/worldgen/feature/WorldGenAbandonedChest.java similarity index 100% rename from java/src/common/worldgen/feature/WorldGenAbandonedChest.java rename to common/src/common/worldgen/feature/WorldGenAbandonedChest.java diff --git a/java/src/common/worldgen/feature/WorldGenAsteroid.java b/common/src/common/worldgen/feature/WorldGenAsteroid.java similarity index 100% rename from java/src/common/worldgen/feature/WorldGenAsteroid.java rename to common/src/common/worldgen/feature/WorldGenAsteroid.java diff --git a/java/src/common/worldgen/feature/WorldGenBlockBlob.java b/common/src/common/worldgen/feature/WorldGenBlockBlob.java similarity index 100% rename from java/src/common/worldgen/feature/WorldGenBlockBlob.java rename to common/src/common/worldgen/feature/WorldGenBlockBlob.java diff --git a/java/src/common/worldgen/feature/WorldGenClay.java b/common/src/common/worldgen/feature/WorldGenClay.java similarity index 100% rename from java/src/common/worldgen/feature/WorldGenClay.java rename to common/src/common/worldgen/feature/WorldGenClay.java diff --git a/java/src/common/worldgen/feature/WorldGenClayExt.java b/common/src/common/worldgen/feature/WorldGenClayExt.java similarity index 100% rename from java/src/common/worldgen/feature/WorldGenClayExt.java rename to common/src/common/worldgen/feature/WorldGenClayExt.java diff --git a/java/src/common/worldgen/feature/WorldGenDesertWells.java b/common/src/common/worldgen/feature/WorldGenDesertWells.java similarity index 100% rename from java/src/common/worldgen/feature/WorldGenDesertWells.java rename to common/src/common/worldgen/feature/WorldGenDesertWells.java diff --git a/java/src/common/worldgen/feature/WorldGenFire.java b/common/src/common/worldgen/feature/WorldGenFire.java similarity index 100% rename from java/src/common/worldgen/feature/WorldGenFire.java rename to common/src/common/worldgen/feature/WorldGenFire.java diff --git a/java/src/common/worldgen/feature/WorldGenGlowStone.java b/common/src/common/worldgen/feature/WorldGenGlowStone.java similarity index 100% rename from java/src/common/worldgen/feature/WorldGenGlowStone.java rename to common/src/common/worldgen/feature/WorldGenGlowStone.java diff --git a/java/src/common/worldgen/feature/WorldGenHellLava.java b/common/src/common/worldgen/feature/WorldGenHellLava.java similarity index 100% rename from java/src/common/worldgen/feature/WorldGenHellLava.java rename to common/src/common/worldgen/feature/WorldGenHellLava.java diff --git a/java/src/common/worldgen/feature/WorldGenIcePath.java b/common/src/common/worldgen/feature/WorldGenIcePath.java similarity index 100% rename from java/src/common/worldgen/feature/WorldGenIcePath.java rename to common/src/common/worldgen/feature/WorldGenIcePath.java diff --git a/java/src/common/worldgen/feature/WorldGenIceSpike.java b/common/src/common/worldgen/feature/WorldGenIceSpike.java similarity index 100% rename from java/src/common/worldgen/feature/WorldGenIceSpike.java rename to common/src/common/worldgen/feature/WorldGenIceSpike.java diff --git a/java/src/common/worldgen/feature/WorldGenSand.java b/common/src/common/worldgen/feature/WorldGenSand.java similarity index 100% rename from java/src/common/worldgen/feature/WorldGenSand.java rename to common/src/common/worldgen/feature/WorldGenSand.java diff --git a/java/src/common/worldgen/feature/WorldGenSpikes.java b/common/src/common/worldgen/feature/WorldGenSpikes.java similarity index 100% rename from java/src/common/worldgen/feature/WorldGenSpikes.java rename to common/src/common/worldgen/feature/WorldGenSpikes.java diff --git a/java/src/common/worldgen/foliage/FeatureDoublePlant.java b/common/src/common/worldgen/foliage/FeatureDoublePlant.java similarity index 100% rename from java/src/common/worldgen/foliage/FeatureDoublePlant.java rename to common/src/common/worldgen/foliage/FeatureDoublePlant.java diff --git a/java/src/common/worldgen/foliage/WorldGenBigMushroom.java b/common/src/common/worldgen/foliage/WorldGenBigMushroom.java similarity index 100% rename from java/src/common/worldgen/foliage/WorldGenBigMushroom.java rename to common/src/common/worldgen/foliage/WorldGenBigMushroom.java diff --git a/java/src/common/worldgen/foliage/WorldGenCactus.java b/common/src/common/worldgen/foliage/WorldGenCactus.java similarity index 100% rename from java/src/common/worldgen/foliage/WorldGenCactus.java rename to common/src/common/worldgen/foliage/WorldGenCactus.java diff --git a/java/src/common/worldgen/foliage/WorldGenDeadBush.java b/common/src/common/worldgen/foliage/WorldGenDeadBush.java similarity index 100% rename from java/src/common/worldgen/foliage/WorldGenDeadBush.java rename to common/src/common/worldgen/foliage/WorldGenDeadBush.java diff --git a/java/src/common/worldgen/foliage/WorldGenFlowers.java b/common/src/common/worldgen/foliage/WorldGenFlowers.java similarity index 100% rename from java/src/common/worldgen/foliage/WorldGenFlowers.java rename to common/src/common/worldgen/foliage/WorldGenFlowers.java diff --git a/java/src/common/worldgen/foliage/WorldGenMelon.java b/common/src/common/worldgen/foliage/WorldGenMelon.java similarity index 100% rename from java/src/common/worldgen/foliage/WorldGenMelon.java rename to common/src/common/worldgen/foliage/WorldGenMelon.java diff --git a/java/src/common/worldgen/foliage/WorldGenMushroom.java b/common/src/common/worldgen/foliage/WorldGenMushroom.java similarity index 100% rename from java/src/common/worldgen/foliage/WorldGenMushroom.java rename to common/src/common/worldgen/foliage/WorldGenMushroom.java diff --git a/java/src/common/worldgen/foliage/WorldGenPumpkin.java b/common/src/common/worldgen/foliage/WorldGenPumpkin.java similarity index 100% rename from java/src/common/worldgen/foliage/WorldGenPumpkin.java rename to common/src/common/worldgen/foliage/WorldGenPumpkin.java diff --git a/java/src/common/worldgen/foliage/WorldGenReed.java b/common/src/common/worldgen/foliage/WorldGenReed.java similarity index 100% rename from java/src/common/worldgen/foliage/WorldGenReed.java rename to common/src/common/worldgen/foliage/WorldGenReed.java diff --git a/java/src/common/worldgen/foliage/WorldGenShrub.java b/common/src/common/worldgen/foliage/WorldGenShrub.java similarity index 100% rename from java/src/common/worldgen/foliage/WorldGenShrub.java rename to common/src/common/worldgen/foliage/WorldGenShrub.java diff --git a/java/src/common/worldgen/foliage/WorldGenTallGrass.java b/common/src/common/worldgen/foliage/WorldGenTallGrass.java similarity index 100% rename from java/src/common/worldgen/foliage/WorldGenTallGrass.java rename to common/src/common/worldgen/foliage/WorldGenTallGrass.java diff --git a/java/src/common/worldgen/foliage/WorldGenVines.java b/common/src/common/worldgen/foliage/WorldGenVines.java similarity index 100% rename from java/src/common/worldgen/foliage/WorldGenVines.java rename to common/src/common/worldgen/foliage/WorldGenVines.java diff --git a/java/src/common/worldgen/foliage/WorldGenWaterlily.java b/common/src/common/worldgen/foliage/WorldGenWaterlily.java similarity index 100% rename from java/src/common/worldgen/foliage/WorldGenWaterlily.java rename to common/src/common/worldgen/foliage/WorldGenWaterlily.java diff --git a/java/src/common/worldgen/layer/GenLayer.java b/common/src/common/worldgen/layer/GenLayer.java similarity index 100% rename from java/src/common/worldgen/layer/GenLayer.java rename to common/src/common/worldgen/layer/GenLayer.java diff --git a/java/src/common/worldgen/layer/GenLayerAddAreas.java b/common/src/common/worldgen/layer/GenLayerAddAreas.java similarity index 100% rename from java/src/common/worldgen/layer/GenLayerAddAreas.java rename to common/src/common/worldgen/layer/GenLayerAddAreas.java diff --git a/java/src/common/worldgen/layer/GenLayerAddExtra.java b/common/src/common/worldgen/layer/GenLayerAddExtra.java similarity index 100% rename from java/src/common/worldgen/layer/GenLayerAddExtra.java rename to common/src/common/worldgen/layer/GenLayerAddExtra.java diff --git a/java/src/common/worldgen/layer/GenLayerAddSea.java b/common/src/common/worldgen/layer/GenLayerAddSea.java similarity index 100% rename from java/src/common/worldgen/layer/GenLayerAddSea.java rename to common/src/common/worldgen/layer/GenLayerAddSea.java diff --git a/java/src/common/worldgen/layer/GenLayerAddSnow.java b/common/src/common/worldgen/layer/GenLayerAddSnow.java similarity index 100% rename from java/src/common/worldgen/layer/GenLayerAddSnow.java rename to common/src/common/worldgen/layer/GenLayerAddSnow.java diff --git a/java/src/common/worldgen/layer/GenLayerBase.java b/common/src/common/worldgen/layer/GenLayerBase.java similarity index 100% rename from java/src/common/worldgen/layer/GenLayerBase.java rename to common/src/common/worldgen/layer/GenLayerBase.java diff --git a/java/src/common/worldgen/layer/GenLayerBiome.java b/common/src/common/worldgen/layer/GenLayerBiome.java similarity index 100% rename from java/src/common/worldgen/layer/GenLayerBiome.java rename to common/src/common/worldgen/layer/GenLayerBiome.java diff --git a/java/src/common/worldgen/layer/GenLayerBiomeEdge.java b/common/src/common/worldgen/layer/GenLayerBiomeEdge.java similarity index 100% rename from java/src/common/worldgen/layer/GenLayerBiomeEdge.java rename to common/src/common/worldgen/layer/GenLayerBiomeEdge.java diff --git a/java/src/common/worldgen/layer/GenLayerEdge.java b/common/src/common/worldgen/layer/GenLayerEdge.java similarity index 100% rename from java/src/common/worldgen/layer/GenLayerEdge.java rename to common/src/common/worldgen/layer/GenLayerEdge.java diff --git a/java/src/common/worldgen/layer/GenLayerFuzzyZoom.java b/common/src/common/worldgen/layer/GenLayerFuzzyZoom.java similarity index 100% rename from java/src/common/worldgen/layer/GenLayerFuzzyZoom.java rename to common/src/common/worldgen/layer/GenLayerFuzzyZoom.java diff --git a/java/src/common/worldgen/layer/GenLayerHills.java b/common/src/common/worldgen/layer/GenLayerHills.java similarity index 100% rename from java/src/common/worldgen/layer/GenLayerHills.java rename to common/src/common/worldgen/layer/GenLayerHills.java diff --git a/java/src/common/worldgen/layer/GenLayerRemoveEmpty.java b/common/src/common/worldgen/layer/GenLayerRemoveEmpty.java similarity index 100% rename from java/src/common/worldgen/layer/GenLayerRemoveEmpty.java rename to common/src/common/worldgen/layer/GenLayerRemoveEmpty.java diff --git a/java/src/common/worldgen/layer/GenLayerRiver.java b/common/src/common/worldgen/layer/GenLayerRiver.java similarity index 100% rename from java/src/common/worldgen/layer/GenLayerRiver.java rename to common/src/common/worldgen/layer/GenLayerRiver.java diff --git a/java/src/common/worldgen/layer/GenLayerRiverInit.java b/common/src/common/worldgen/layer/GenLayerRiverInit.java similarity index 100% rename from java/src/common/worldgen/layer/GenLayerRiverInit.java rename to common/src/common/worldgen/layer/GenLayerRiverInit.java diff --git a/java/src/common/worldgen/layer/GenLayerRiverMix.java b/common/src/common/worldgen/layer/GenLayerRiverMix.java similarity index 100% rename from java/src/common/worldgen/layer/GenLayerRiverMix.java rename to common/src/common/worldgen/layer/GenLayerRiverMix.java diff --git a/java/src/common/worldgen/layer/GenLayerShore.java b/common/src/common/worldgen/layer/GenLayerShore.java similarity index 100% rename from java/src/common/worldgen/layer/GenLayerShore.java rename to common/src/common/worldgen/layer/GenLayerShore.java diff --git a/java/src/common/worldgen/layer/GenLayerSmooth.java b/common/src/common/worldgen/layer/GenLayerSmooth.java similarity index 100% rename from java/src/common/worldgen/layer/GenLayerSmooth.java rename to common/src/common/worldgen/layer/GenLayerSmooth.java diff --git a/java/src/common/worldgen/layer/GenLayerVoronoiZoom.java b/common/src/common/worldgen/layer/GenLayerVoronoiZoom.java similarity index 100% rename from java/src/common/worldgen/layer/GenLayerVoronoiZoom.java rename to common/src/common/worldgen/layer/GenLayerVoronoiZoom.java diff --git a/java/src/common/worldgen/layer/GenLayerZoom.java b/common/src/common/worldgen/layer/GenLayerZoom.java similarity index 100% rename from java/src/common/worldgen/layer/GenLayerZoom.java rename to common/src/common/worldgen/layer/GenLayerZoom.java diff --git a/java/src/common/worldgen/layer/IntCache.java b/common/src/common/worldgen/layer/IntCache.java similarity index 100% rename from java/src/common/worldgen/layer/IntCache.java rename to common/src/common/worldgen/layer/IntCache.java diff --git a/java/src/common/worldgen/structure/MapGenBridge.java b/common/src/common/worldgen/structure/MapGenBridge.java similarity index 100% rename from java/src/common/worldgen/structure/MapGenBridge.java rename to common/src/common/worldgen/structure/MapGenBridge.java diff --git a/java/src/common/worldgen/structure/MapGenMineshaft.java b/common/src/common/worldgen/structure/MapGenMineshaft.java similarity index 100% rename from java/src/common/worldgen/structure/MapGenMineshaft.java rename to common/src/common/worldgen/structure/MapGenMineshaft.java diff --git a/java/src/common/worldgen/structure/MapGenScatteredFeature.java b/common/src/common/worldgen/structure/MapGenScatteredFeature.java similarity index 100% rename from java/src/common/worldgen/structure/MapGenScatteredFeature.java rename to common/src/common/worldgen/structure/MapGenScatteredFeature.java diff --git a/java/src/common/worldgen/structure/MapGenStronghold.java b/common/src/common/worldgen/structure/MapGenStronghold.java similarity index 100% rename from java/src/common/worldgen/structure/MapGenStronghold.java rename to common/src/common/worldgen/structure/MapGenStronghold.java diff --git a/java/src/common/worldgen/structure/MapGenStructure.java b/common/src/common/worldgen/structure/MapGenStructure.java similarity index 100% rename from java/src/common/worldgen/structure/MapGenStructure.java rename to common/src/common/worldgen/structure/MapGenStructure.java diff --git a/java/src/common/worldgen/structure/MapGenStructureIO.java b/common/src/common/worldgen/structure/MapGenStructureIO.java similarity index 100% rename from java/src/common/worldgen/structure/MapGenStructureIO.java rename to common/src/common/worldgen/structure/MapGenStructureIO.java diff --git a/java/src/common/worldgen/structure/MapGenVillage.java b/common/src/common/worldgen/structure/MapGenVillage.java similarity index 100% rename from java/src/common/worldgen/structure/MapGenVillage.java rename to common/src/common/worldgen/structure/MapGenVillage.java diff --git a/java/src/common/worldgen/structure/StructureBoundingBox.java b/common/src/common/worldgen/structure/StructureBoundingBox.java similarity index 100% rename from java/src/common/worldgen/structure/StructureBoundingBox.java rename to common/src/common/worldgen/structure/StructureBoundingBox.java diff --git a/java/src/common/worldgen/structure/StructureBridge.java b/common/src/common/worldgen/structure/StructureBridge.java similarity index 100% rename from java/src/common/worldgen/structure/StructureBridge.java rename to common/src/common/worldgen/structure/StructureBridge.java diff --git a/java/src/common/worldgen/structure/StructureComponent.java b/common/src/common/worldgen/structure/StructureComponent.java similarity index 100% rename from java/src/common/worldgen/structure/StructureComponent.java rename to common/src/common/worldgen/structure/StructureComponent.java diff --git a/java/src/common/worldgen/structure/StructureMineshaft.java b/common/src/common/worldgen/structure/StructureMineshaft.java similarity index 100% rename from java/src/common/worldgen/structure/StructureMineshaft.java rename to common/src/common/worldgen/structure/StructureMineshaft.java diff --git a/java/src/common/worldgen/structure/StructureMineshaftStart.java b/common/src/common/worldgen/structure/StructureMineshaftStart.java similarity index 100% rename from java/src/common/worldgen/structure/StructureMineshaftStart.java rename to common/src/common/worldgen/structure/StructureMineshaftStart.java diff --git a/java/src/common/worldgen/structure/StructureScattered.java b/common/src/common/worldgen/structure/StructureScattered.java similarity index 100% rename from java/src/common/worldgen/structure/StructureScattered.java rename to common/src/common/worldgen/structure/StructureScattered.java diff --git a/java/src/common/worldgen/structure/StructureStart.java b/common/src/common/worldgen/structure/StructureStart.java similarity index 100% rename from java/src/common/worldgen/structure/StructureStart.java rename to common/src/common/worldgen/structure/StructureStart.java diff --git a/java/src/common/worldgen/structure/StructureStronghold.java b/common/src/common/worldgen/structure/StructureStronghold.java similarity index 100% rename from java/src/common/worldgen/structure/StructureStronghold.java rename to common/src/common/worldgen/structure/StructureStronghold.java diff --git a/java/src/common/worldgen/structure/StructureVillage.java b/common/src/common/worldgen/structure/StructureVillage.java similarity index 100% rename from java/src/common/worldgen/structure/StructureVillage.java rename to common/src/common/worldgen/structure/StructureVillage.java diff --git a/java/src/common/worldgen/tree/WorldGenBaseTree.java b/common/src/common/worldgen/tree/WorldGenBaseTree.java similarity index 100% rename from java/src/common/worldgen/tree/WorldGenBaseTree.java rename to common/src/common/worldgen/tree/WorldGenBaseTree.java diff --git a/java/src/common/worldgen/tree/WorldGenBigTree.java b/common/src/common/worldgen/tree/WorldGenBigTree.java similarity index 100% rename from java/src/common/worldgen/tree/WorldGenBigTree.java rename to common/src/common/worldgen/tree/WorldGenBigTree.java diff --git a/java/src/common/worldgen/tree/WorldGenBirch.java b/common/src/common/worldgen/tree/WorldGenBirch.java similarity index 100% rename from java/src/common/worldgen/tree/WorldGenBirch.java rename to common/src/common/worldgen/tree/WorldGenBirch.java diff --git a/java/src/common/worldgen/tree/WorldGenDarkOak.java b/common/src/common/worldgen/tree/WorldGenDarkOak.java similarity index 100% rename from java/src/common/worldgen/tree/WorldGenDarkOak.java rename to common/src/common/worldgen/tree/WorldGenDarkOak.java diff --git a/java/src/common/worldgen/tree/WorldGenHugeTree.java b/common/src/common/worldgen/tree/WorldGenHugeTree.java similarity index 100% rename from java/src/common/worldgen/tree/WorldGenHugeTree.java rename to common/src/common/worldgen/tree/WorldGenHugeTree.java diff --git a/java/src/common/worldgen/tree/WorldGenJungle.java b/common/src/common/worldgen/tree/WorldGenJungle.java similarity index 100% rename from java/src/common/worldgen/tree/WorldGenJungle.java rename to common/src/common/worldgen/tree/WorldGenJungle.java diff --git a/java/src/common/worldgen/tree/WorldGenPine.java b/common/src/common/worldgen/tree/WorldGenPine.java similarity index 100% rename from java/src/common/worldgen/tree/WorldGenPine.java rename to common/src/common/worldgen/tree/WorldGenPine.java diff --git a/java/src/common/worldgen/tree/WorldGenSavanna.java b/common/src/common/worldgen/tree/WorldGenSavanna.java similarity index 100% rename from java/src/common/worldgen/tree/WorldGenSavanna.java rename to common/src/common/worldgen/tree/WorldGenSavanna.java diff --git a/java/src/common/worldgen/tree/WorldGenSwamp.java b/common/src/common/worldgen/tree/WorldGenSwamp.java similarity index 100% rename from java/src/common/worldgen/tree/WorldGenSwamp.java rename to common/src/common/worldgen/tree/WorldGenSwamp.java diff --git a/java/src/common/worldgen/tree/WorldGenTaiga1.java b/common/src/common/worldgen/tree/WorldGenTaiga1.java similarity index 100% rename from java/src/common/worldgen/tree/WorldGenTaiga1.java rename to common/src/common/worldgen/tree/WorldGenTaiga1.java diff --git a/java/src/common/worldgen/tree/WorldGenTaiga2.java b/common/src/common/worldgen/tree/WorldGenTaiga2.java similarity index 100% rename from java/src/common/worldgen/tree/WorldGenTaiga2.java rename to common/src/common/worldgen/tree/WorldGenTaiga2.java diff --git a/java/src/common/worldgen/tree/WorldGenTree.java b/common/src/common/worldgen/tree/WorldGenTree.java similarity index 100% rename from java/src/common/worldgen/tree/WorldGenTree.java rename to common/src/common/worldgen/tree/WorldGenTree.java From 6b7923cf41c985f9221ae40218fe4081edfa34d1 Mon Sep 17 00:00:00 2001 From: Sen Date: Thu, 8 May 2025 12:37:48 +0200 Subject: [PATCH 009/200] move packages --- client/src/client/Game.java | 10 ++++----- client/src/client/PlayerController.java | 6 ++--- client/src/client/gui/GuiConsole.java | 4 ++-- .../src/client/gui/container/GuiCrafting.java | 2 +- client/src/client/gui/ingame/GuiSign.java | 2 +- client/src/client/init/AnimationRegistry.java | 22 ------------------- ...enderRegistry.java => RenderRegistry.java} | 18 ++++++++++++++- client/src/client/network/ClientPlayer.java | 2 +- .../src/client/renderer/ActiveRenderInfo.java | 4 ++-- client/src/client/renderer/BlockRenderer.java | 6 ++--- .../src/client/renderer/EntityRenderer.java | 8 +++---- client/src/client/renderer/Frustum.java | 2 +- client/src/client/renderer/ItemRenderer.java | 4 ++-- .../client/renderer/RegionRenderCache.java | 6 ++--- client/src/client/renderer/RenderGlobal.java | 12 +++++----- client/src/client/renderer/ViewFrustum.java | 2 +- .../renderer/blockmodel/BakedModel.java | 2 +- .../client/renderer/blockmodel/BakedQuad.java | 2 +- .../client/renderer/blockmodel/BlockPart.java | 2 +- .../renderer/blockmodel/BlockPartFace.java | 2 +- .../blockmodel/BlockPartRotation.java | 2 +- .../renderer/blockmodel/BuiltInModel.java | 2 +- .../renderer/blockmodel/FaceBakery.java | 4 ++-- .../renderer/blockmodel/IBakedModel.java | 2 +- .../renderer/blockmodel/ModelBakery.java | 2 +- .../renderer/blockmodel/ModelBlock.java | 2 +- .../renderer/blockmodel/ModelGenerator.java | 2 +- .../client/renderer/chunk/CompiledChunk.java | 2 +- .../client/renderer/chunk/RenderChunk.java | 6 ++--- .../client/renderer/chunk/SetVisibility.java | 2 +- .../src/client/renderer/chunk/VisGraph.java | 4 ++-- client/src/client/renderer/entity/Render.java | 4 ++-- .../renderer/entity/RenderFallingBlock.java | 2 +- .../client/renderer/entity/RenderFish.java | 2 +- .../client/renderer/entity/RenderItem.java | 4 ++-- .../client/renderer/entity/RenderManager.java | 8 +++---- .../renderer/entity/RenderMinecart.java | 2 +- .../src/client/renderer/model/ModelBox.java | 4 ++-- .../renderer/model/PositionTextureVertex.java | 2 +- .../client/renderer/model/TexturedQuad.java | 2 +- .../renderer/particle/EffectRenderer.java | 4 ++-- .../renderer/particle/EntityBubbleFX.java | 2 +- .../renderer/particle/EntityDiggingFX.java | 2 +- .../renderer/particle/EntityDownfallFX.java | 2 +- .../particle/EntityDropParticleFX.java | 2 +- .../renderer/particle/EntityFirework.java | 2 +- .../renderer/particle/EntityFootStepFX.java | 2 +- .../renderer/particle/EntitySuspendFX.java | 2 +- .../client/renderer/texture/TextureMap.java | 4 ++-- .../tileentity/TileEntityBannerRenderer.java | 2 +- .../TileEntityItemStackRenderer.java | 2 +- .../tileentity/TileEntityPistonRenderer.java | 2 +- .../TileEntityRendererDispatcher.java | 2 +- .../tileentity/TileEntitySkullRenderer.java | 2 +- client/src/client/world/Converter.java | 4 ++-- common/src/common/IClient.java | 2 +- common/src/common/IServer.java | 6 ++--- common/src/common/ai/AIFireballAttack.java | 4 ++-- common/src/common/ai/AIFlyingBoxAttack.java | 2 +- .../src/common/ai/AISmallFireballAttack.java | 2 +- .../common/ai/EntityAIAttackOnCollide.java | 2 +- common/src/common/ai/EntityAIAvoidEntity.java | 2 +- .../common/ai/EntityAIControlledByPlayer.java | 2 +- .../src/common/ai/EntityAIDoorInteract.java | 2 +- common/src/common/ai/EntityAIEatGrass.java | 2 +- common/src/common/ai/EntityAIFleeSun.java | 4 ++-- .../common/ai/EntityAIHarvestFarmland.java | 2 +- .../src/common/ai/EntityAIHurtByTarget.java | 2 +- common/src/common/ai/EntityAIMoveIndoors.java | 4 ++-- .../common/ai/EntityAIMoveThroughVillage.java | 4 ++-- common/src/common/ai/EntityAIMoveToBlock.java | 2 +- .../ai/EntityAIMoveTowardsRestriction.java | 4 ++-- .../common/ai/EntityAIMoveTowardsTarget.java | 2 +- common/src/common/ai/EntityAIOcelotSit.java | 2 +- common/src/common/ai/EntityAIPanic.java | 2 +- common/src/common/ai/EntityAIPlay.java | 2 +- .../common/ai/EntityAIRestrictOpenDoor.java | 2 +- .../common/ai/EntityAIRunAroundLikeCrazy.java | 2 +- common/src/common/ai/EntityAITakePlace.java | 2 +- common/src/common/ai/EntityAITarget.java | 2 +- common/src/common/ai/EntityAIWander.java | 2 +- .../common/ai/RandomPositionGenerator.java | 4 ++-- common/src/common/biome/Biome.java | 2 +- common/src/common/biome/BiomeBlackened.java | 2 +- common/src/common/biome/BiomeChaos.java | 2 +- common/src/common/biome/BiomeDesert.java | 2 +- .../src/common/biome/BiomeExterminated.java | 2 +- common/src/common/biome/BiomeForest.java | 2 +- common/src/common/biome/BiomeHell.java | 2 +- common/src/common/biome/BiomeHills.java | 2 +- common/src/common/biome/BiomeJungle.java | 2 +- common/src/common/biome/BiomeMesa.java | 2 +- common/src/common/biome/BiomeMoon.java | 2 +- common/src/common/biome/BiomeMutated.java | 2 +- common/src/common/biome/BiomeNone.java | 2 +- common/src/common/biome/BiomePlains.java | 2 +- common/src/common/biome/BiomeSavanna.java | 2 +- common/src/common/biome/BiomeSnow.java | 2 +- common/src/common/biome/BiomeSpace.java | 2 +- common/src/common/biome/BiomeSwamp.java | 4 ++-- common/src/common/biome/BiomeTaiga.java | 2 +- common/src/common/biome/BiomeTian.java | 2 +- common/src/common/block/Block.java | 12 +++++----- common/src/common/block/BlockAir.java | 4 ++-- common/src/common/block/BlockAnvil.java | 4 ++-- common/src/common/block/BlockBanner.java | 6 ++--- .../common/block/BlockBasePressurePlate.java | 6 ++--- common/src/common/block/BlockBeacon.java | 4 ++-- common/src/common/block/BlockBed.java | 6 ++--- common/src/common/block/BlockBedrock.java | 2 +- .../src/common/block/BlockBlackenedDirt.java | 2 +- .../src/common/block/BlockBlackenedSoil.java | 2 +- common/src/common/block/BlockBlueShroom.java | 2 +- common/src/common/block/BlockBreakable.java | 4 ++-- .../src/common/block/BlockBrewingStand.java | 6 ++--- common/src/common/block/BlockBush.java | 4 ++-- common/src/common/block/BlockButton.java | 6 ++--- common/src/common/block/BlockCactus.java | 6 ++--- common/src/common/block/BlockCake.java | 6 ++--- common/src/common/block/BlockCarpet.java | 4 ++-- common/src/common/block/BlockCauldron.java | 6 ++--- common/src/common/block/BlockChest.java | 6 ++--- common/src/common/block/BlockCocoa.java | 6 ++--- .../common/block/BlockCompressedPowered.java | 4 ++-- common/src/common/block/BlockContainer.java | 4 ++-- common/src/common/block/BlockCore.java | 2 +- common/src/common/block/BlockCrops.java | 2 +- .../common/block/BlockDaylightDetector.java | 4 ++-- common/src/common/block/BlockDeadBush.java | 2 +- common/src/common/block/BlockDirectional.java | 2 +- common/src/common/block/BlockDirt.java | 2 +- common/src/common/block/BlockDispenser.java | 4 ++-- common/src/common/block/BlockDoor.java | 10 ++++----- common/src/common/block/BlockDoublePlant.java | 6 ++--- common/src/common/block/BlockDragonEgg.java | 4 ++-- common/src/common/block/BlockDropper.java | 4 ++-- .../src/common/block/BlockDynamicLiquid.java | 4 ++-- .../common/block/BlockEnchantmentTable.java | 4 ++-- common/src/common/block/BlockEventData.java | 2 +- common/src/common/block/BlockFalling.java | 2 +- common/src/common/block/BlockFarmland.java | 6 ++--- common/src/common/block/BlockFence.java | 6 ++--- common/src/common/block/BlockFenceGate.java | 6 ++--- common/src/common/block/BlockFire.java | 6 ++--- common/src/common/block/BlockFloorPortal.java | 6 ++--- common/src/common/block/BlockFlower.java | 2 +- common/src/common/block/BlockFlowerPot.java | 4 ++-- common/src/common/block/BlockFurnace.java | 4 ++-- common/src/common/block/BlockGrass.java | 2 +- common/src/common/block/BlockHay.java | 4 ++-- common/src/common/block/BlockHopper.java | 6 ++--- .../src/common/block/BlockHugeMushroom.java | 4 ++-- common/src/common/block/BlockIce.java | 2 +- common/src/common/block/BlockJukebox.java | 4 ++-- common/src/common/block/BlockLadder.java | 6 ++--- common/src/common/block/BlockLeaves.java | 2 +- common/src/common/block/BlockLever.java | 6 ++--- common/src/common/block/BlockLilyPad.java | 6 ++--- common/src/common/block/BlockLiquid.java | 8 +++---- common/src/common/block/BlockLog.java | 4 ++-- common/src/common/block/BlockMachine.java | 4 ++-- common/src/common/block/BlockMobSpawner.java | 2 +- common/src/common/block/BlockMushroom.java | 2 +- common/src/common/block/BlockMycelium.java | 2 +- common/src/common/block/BlockNote.java | 4 ++-- common/src/common/block/BlockNuke.java | 2 +- common/src/common/block/BlockOre.java | 2 +- common/src/common/block/BlockPane.java | 6 ++--- common/src/common/block/BlockPistonBase.java | 6 ++--- common/src/common/block/BlockPistonHead.java | 6 ++--- .../src/common/block/BlockPistonMoving.java | 10 ++++----- common/src/common/block/BlockPortal.java | 8 +++---- common/src/common/block/BlockPortalFrame.java | 6 ++--- common/src/common/block/BlockPotato.java | 2 +- .../src/common/block/BlockPressurePlate.java | 4 ++-- .../block/BlockPressurePlateWeighted.java | 2 +- common/src/common/block/BlockPumpkin.java | 4 ++-- common/src/common/block/BlockQuartz.java | 4 ++-- common/src/common/block/BlockRail.java | 2 +- common/src/common/block/BlockRailBase.java | 10 ++++----- .../src/common/block/BlockRailDetector.java | 6 ++--- common/src/common/block/BlockRailPowered.java | 2 +- .../common/block/BlockRedstoneComparator.java | 4 ++-- .../src/common/block/BlockRedstoneDiode.java | 4 ++-- .../src/common/block/BlockRedstoneLight.java | 2 +- common/src/common/block/BlockRedstoneOre.java | 4 ++-- .../common/block/BlockRedstoneRepeater.java | 4 ++-- .../src/common/block/BlockRedstoneTorch.java | 4 ++-- .../src/common/block/BlockRedstoneWire.java | 6 ++--- common/src/common/block/BlockReed.java | 6 ++--- .../src/common/block/BlockRotatedPillar.java | 2 +- common/src/common/block/BlockSapling.java | 2 +- common/src/common/block/BlockSign.java | 4 ++-- common/src/common/block/BlockSkull.java | 6 ++--- common/src/common/block/BlockSlab.java | 8 +++---- common/src/common/block/BlockSlime.java | 2 +- common/src/common/block/BlockSnow.java | 6 ++--- common/src/common/block/BlockSnowBlock.java | 2 +- common/src/common/block/BlockSoulSand.java | 4 ++-- common/src/common/block/BlockSourceImpl.java | 2 +- common/src/common/block/BlockStairs.java | 10 ++++----- .../src/common/block/BlockStandingSign.java | 2 +- .../src/common/block/BlockStaticLiquid.java | 4 ++-- common/src/common/block/BlockStem.java | 4 ++-- common/src/common/block/BlockTNT.java | 4 ++-- common/src/common/block/BlockTallGrass.java | 2 +- common/src/common/block/BlockTianSoil.java | 2 +- common/src/common/block/BlockTorch.java | 10 ++++----- common/src/common/block/BlockTrapDoor.java | 10 ++++----- common/src/common/block/BlockTripWire.java | 6 ++--- .../src/common/block/BlockTripWireHook.java | 6 ++--- common/src/common/block/BlockVine.java | 6 ++--- common/src/common/block/BlockWall.java | 6 ++--- common/src/common/block/BlockWallSign.java | 4 ++-- common/src/common/block/BlockWarpChest.java | 4 ++-- common/src/common/block/BlockWart.java | 2 +- common/src/common/block/BlockWeb.java | 4 ++-- common/src/common/block/BlockWorkbench.java | 4 ++-- common/src/common/block/IGrowable.java | 2 +- .../src/common/clipboard/ClipboardPlacer.java | 4 ++-- common/src/common/color/Colorizer.java | 2 +- common/src/common/dimension/Dimension.java | 2 +- .../BehaviorDefaultDispenseItem.java | 2 +- .../dispenser/BehaviorProjectileDispense.java | 2 +- common/src/common/dispenser/IBlockSource.java | 2 +- common/src/common/entity/DataWatcher.java | 2 +- common/src/common/entity/Entity.java | 14 ++++++------ .../src/common/entity/animal/EntityBat.java | 2 +- .../common/entity/animal/EntityDragon.java | 2 +- .../src/common/entity/animal/EntityHorse.java | 2 +- .../src/common/entity/animal/EntityMouse.java | 2 +- .../common/entity/animal/EntityRabbit.java | 4 ++-- .../common/entity/effect/EntityLightning.java | 4 ++-- common/src/common/entity/item/EntityBoat.java | 4 ++-- common/src/common/entity/item/EntityCart.java | 6 ++--- .../entity/item/EntityCartContainer.java | 4 ++-- .../common/entity/item/EntityChestCart.java | 2 +- .../src/common/entity/item/EntityFalling.java | 4 ++-- .../common/entity/item/EntityHopperCart.java | 2 +- common/src/common/entity/item/EntityItem.java | 4 ++-- .../common/entity/item/EntityLeashKnot.java | 4 ++-- common/src/common/entity/item/EntityOrb.java | 2 +- .../src/common/entity/item/EntityTntCart.java | 2 +- common/src/common/entity/item/EntityXp.java | 4 ++-- .../common/entity/item/EntityXpBottle.java | 4 ++-- .../common/entity/npc/EntityArachnoid.java | 2 +- .../common/entity/npc/EntityCultivator.java | 2 +- .../common/entity/npc/EntityFlyingNPC.java | 4 ++-- common/src/common/entity/npc/EntityHuman.java | 2 +- common/src/common/entity/npc/EntityNPC.java | 12 +++++----- common/src/common/entity/npc/EntitySlime.java | 2 +- .../src/common/entity/npc/EntityZombie.java | 2 +- .../common/entity/npc/PlayerCharacter.java | 2 +- .../common/entity/projectile/EntityArrow.java | 8 +++---- .../common/entity/projectile/EntityBox.java | 2 +- .../entity/projectile/EntityBullet.java | 6 ++--- .../common/entity/projectile/EntityDie.java | 2 +- .../entity/projectile/EntityDynamite.java | 2 +- .../common/entity/projectile/EntityEgg.java | 2 +- .../entity/projectile/EntityFireCharge.java | 4 ++-- .../entity/projectile/EntityFireball.java | 2 +- .../common/entity/projectile/EntityHook.java | 8 +++---- .../entity/projectile/EntityPotion.java | 6 ++--- .../entity/projectile/EntityProjectile.java | 8 +++---- .../entity/projectile/EntitySnowball.java | 2 +- .../src/common/entity/types/EntityAnimal.java | 2 +- .../src/common/entity/types/EntityLiving.java | 6 ++--- .../common/entity/types/EntityThrowable.java | 8 +++---- common/src/common/init/DispenserRegistry.java | 4 ++-- common/src/common/init/ReorderRegistry.java | 4 ++-- common/src/common/init/RotationRegistry.java | 4 ++-- common/src/common/init/UniverseRegistry.java | 2 +- .../inventory/ContainerEnchantment.java | 2 +- .../src/common/inventory/ContainerRepair.java | 2 +- .../common/inventory/ContainerWorkbench.java | 2 +- .../src/common/inventory/ISidedInventory.java | 2 +- .../src/common/inventory/InventoryHelper.java | 2 +- .../common/inventory/InventoryWarpChest.java | 2 +- common/src/common/item/Item.java | 8 +++---- common/src/common/item/ItemArmor.java | 4 ++-- common/src/common/item/ItemBanHammer.java | 4 ++-- common/src/common/item/ItemBanner.java | 4 ++-- common/src/common/item/ItemBed.java | 4 ++-- common/src/common/item/ItemBlock.java | 4 ++-- common/src/common/item/ItemBoat.java | 8 +++---- common/src/common/item/ItemBucket.java | 6 ++--- common/src/common/item/ItemCamera.java | 2 +- common/src/common/item/ItemChargedOrb.java | 4 ++-- common/src/common/item/ItemDoor.java | 4 ++-- common/src/common/item/ItemDye.java | 4 ++-- common/src/common/item/ItemEditWand.java | 2 +- common/src/common/item/ItemFireball.java | 4 ++-- common/src/common/item/ItemFirework.java | 4 ++-- common/src/common/item/ItemFlintAndSteel.java | 4 ++-- common/src/common/item/ItemGlassBottle.java | 4 ++-- common/src/common/item/ItemHoe.java | 4 ++-- common/src/common/item/ItemInfoWand.java | 4 ++-- common/src/common/item/ItemLead.java | 6 ++--- common/src/common/item/ItemLightning.java | 2 +- common/src/common/item/ItemLilyPad.java | 4 ++-- common/src/common/item/ItemMagnet.java | 4 ++-- common/src/common/item/ItemMinecart.java | 4 ++-- common/src/common/item/ItemMonsterPlacer.java | 6 ++--- common/src/common/item/ItemNpcSpawner.java | 6 ++--- common/src/common/item/ItemRedstone.java | 4 ++-- common/src/common/item/ItemReed.java | 4 ++-- common/src/common/item/ItemSeedFood.java | 4 ++-- common/src/common/item/ItemSeeds.java | 4 ++-- common/src/common/item/ItemShears.java | 2 +- common/src/common/item/ItemSign.java | 4 ++-- common/src/common/item/ItemSkull.java | 4 ++-- common/src/common/item/ItemSlab.java | 4 ++-- common/src/common/item/ItemSnow.java | 6 ++--- .../src/common/item/ItemSpaceNavigator.java | 2 +- common/src/common/item/ItemStack.java | 4 ++-- common/src/common/item/ItemSword.java | 2 +- common/src/common/item/ItemTool.java | 2 +- common/src/common/item/ItemWand.java | 6 ++--- common/src/common/model/Model.java | 2 +- common/src/common/model/ModelProvider.java | 4 ++-- common/src/common/model/ModelRotation.java | 2 +- common/src/common/network/IClientPlayer.java | 2 +- common/src/common/network/IPlayer.java | 6 ++--- common/src/common/network/PacketBuffer.java | 2 +- common/src/common/packet/CPacketBreak.java | 4 ++-- common/src/common/packet/CPacketComplete.java | 2 +- common/src/common/packet/CPacketPlace.java | 2 +- common/src/common/packet/CPacketSign.java | 2 +- .../src/common/packet/S27PacketExplosion.java | 4 ++-- common/src/common/packet/S28PacketEffect.java | 2 +- .../common/packet/S2DPacketOpenWindow.java | 2 +- .../common/packet/S33PacketUpdateSign.java | 2 +- .../packet/S35PacketUpdateTileEntity.java | 2 +- .../packet/S36PacketSignEditorOpen.java | 2 +- .../src/common/packet/SPacketBlockAction.java | 2 +- .../common/packet/SPacketBlockBreakAnim.java | 2 +- .../src/common/packet/SPacketBlockChange.java | 2 +- .../common/packet/SPacketCharacterList.java | 2 +- .../packet/SPacketMultiBlockChange.java | 4 ++-- .../src/common/packet/SPacketSpawnObject.java | 4 ++-- .../src/common/pathfinding/NodeProcessor.java | 2 +- common/src/common/pathfinding/PathCache.java | 2 +- common/src/common/pathfinding/PathEntity.java | 2 +- common/src/common/pathfinding/PathFinder.java | 2 +- .../src/common/pathfinding/PathNavigate.java | 6 ++--- .../pathfinding/PathNavigateClimber.java | 2 +- .../pathfinding/PathNavigateGround.java | 4 ++-- .../common/pathfinding/SwimNodeProcessor.java | 4 ++-- .../common/pathfinding/WalkNodeProcessor.java | 2 +- .../common/properties/PropertyDirection.java | 2 +- common/src/common/tileentity/TileEntity.java | 2 +- .../common/tileentity/TileEntityBeacon.java | 4 ++-- .../tileentity/TileEntityBrewingStand.java | 2 +- .../common/tileentity/TileEntityChest.java | 6 ++--- .../common/tileentity/TileEntityFurnace.java | 2 +- .../common/tileentity/TileEntityHopper.java | 6 ++--- .../tileentity/TileEntityMobSpawner.java | 4 ++-- .../src/common/tileentity/TileEntityNote.java | 2 +- .../common/tileentity/TileEntityPiston.java | 4 ++-- .../src/common/{world => util}/BlockPos.java | 2 +- .../common/{world => util}/BoundingBox.java | 4 ++-- .../src/common/{world => util}/ChunkPos.java | 2 +- .../ClassInheritanceMultiMap.java | 2 +- common/src/common/{world => util}/Facing.java | 4 +--- .../common/{world => util}/HitPosition.java | 2 +- .../common/{world => util}/IntHashMap.java | 2 +- .../common/{world => util}/LongHashMap.java | 2 +- .../{world => util}/NextTickListEntry.java | 2 +- .../common/{world => util}/NibbleArray.java | 2 +- .../common/{world => util}/PortalType.java | 2 +- .../src/common/{world => util}/Position.java | 2 +- common/src/common/{world => util}/Vec3.java | 4 +--- common/src/common/{world => util}/Vec3i.java | 4 +--- .../src/common/{world => util}/WorldPos.java | 2 +- common/src/common/village/Village.java | 2 +- .../src/common/village/VillageCollection.java | 4 ++-- .../src/common/village/VillageDoorInfo.java | 4 ++-- common/src/common/world/BlockArray.java | 1 + common/src/common/world/Chunk.java | 6 +++++ common/src/common/world/ChunkCache.java | 2 ++ common/src/common/world/EmptyChunk.java | 2 ++ common/src/common/world/Explosion.java | 3 +++ common/src/common/world/IBlockAccess.java | 2 ++ common/src/common/world/IWorldAccess.java | 1 + common/src/common/world/Region.java | 3 +++ common/src/common/world/Spawner.java | 2 ++ common/src/common/world/World.java | 7 ++++++ common/src/common/world/WorldClient.java | 6 ++++- common/src/common/world/WorldServer.java | 9 ++++++++ .../src/common/worldgen/BiomeGenLayered.java | 4 ++-- .../src/common/worldgen/BiomeGenSingle.java | 2 +- .../src/common/worldgen/BiomeGenerator.java | 2 +- .../src/common/worldgen/FeatureDungeons.java | 4 ++-- .../src/common/worldgen/FeatureGenerator.java | 2 +- common/src/common/worldgen/FeatureLakes.java | 2 +- .../src/common/worldgen/FeatureLiquids.java | 2 +- common/src/common/worldgen/FeatureOres.java | 2 +- .../common/worldgen/caves/MapGenCaves.java | 2 +- .../common/worldgen/caves/MapGenRavine.java | 2 +- .../feature/WorldGenAbandonedChest.java | 2 +- .../worldgen/feature/WorldGenAsteroid.java | 2 +- .../worldgen/feature/WorldGenBlockBlob.java | 2 +- .../common/worldgen/feature/WorldGenClay.java | 2 +- .../worldgen/feature/WorldGenClayExt.java | 2 +- .../worldgen/feature/WorldGenDesertWells.java | 4 ++-- .../common/worldgen/feature/WorldGenFire.java | 2 +- .../worldgen/feature/WorldGenGlowStone.java | 4 ++-- .../worldgen/feature/WorldGenHellLava.java | 2 +- .../worldgen/feature/WorldGenIcePath.java | 2 +- .../worldgen/feature/WorldGenIceSpike.java | 2 +- .../common/worldgen/feature/WorldGenSand.java | 2 +- .../worldgen/feature/WorldGenSpikes.java | 2 +- .../worldgen/foliage/FeatureDoublePlant.java | 2 +- .../worldgen/foliage/WorldGenBigMushroom.java | 2 +- .../worldgen/foliage/WorldGenCactus.java | 2 +- .../worldgen/foliage/WorldGenDeadBush.java | 2 +- .../worldgen/foliage/WorldGenFlowers.java | 2 +- .../worldgen/foliage/WorldGenMelon.java | 2 +- .../worldgen/foliage/WorldGenMushroom.java | 2 +- .../worldgen/foliage/WorldGenPumpkin.java | 4 ++-- .../common/worldgen/foliage/WorldGenReed.java | 2 +- .../worldgen/foliage/WorldGenShrub.java | 2 +- .../worldgen/foliage/WorldGenTallGrass.java | 2 +- .../worldgen/foliage/WorldGenVines.java | 4 ++-- .../worldgen/foliage/WorldGenWaterlily.java | 4 ++-- .../structure/MapGenScatteredFeature.java | 2 +- .../worldgen/structure/MapGenStructure.java | 6 ++--- .../structure/StructureBoundingBox.java | 6 ++--- .../worldgen/structure/StructureBridge.java | 4 ++-- .../structure/StructureComponent.java | 4 ++-- .../structure/StructureMineshaft.java | 4 ++-- .../structure/StructureScattered.java | 4 ++-- .../worldgen/structure/StructureStart.java | 2 +- .../structure/StructureStronghold.java | 4 ++-- .../worldgen/structure/StructureVillage.java | 4 ++-- .../worldgen/tree/WorldGenBaseTree.java | 4 ++-- .../common/worldgen/tree/WorldGenBigTree.java | 2 +- .../common/worldgen/tree/WorldGenBirch.java | 2 +- .../common/worldgen/tree/WorldGenDarkOak.java | 4 ++-- .../worldgen/tree/WorldGenHugeTree.java | 2 +- .../common/worldgen/tree/WorldGenJungle.java | 2 +- .../common/worldgen/tree/WorldGenPine.java | 2 +- .../common/worldgen/tree/WorldGenSavanna.java | 4 ++-- .../common/worldgen/tree/WorldGenSwamp.java | 2 +- .../common/worldgen/tree/WorldGenTaiga1.java | 2 +- .../common/worldgen/tree/WorldGenTaiga2.java | 2 +- .../common/worldgen/tree/WorldGenTree.java | 2 +- server/src/server/Server.java | 8 +++---- server/src/server/command/Command.java | 2 +- .../src/server/command/DimensionParser.java | 2 +- server/src/server/command/DoubleParser.java | 4 ++-- server/src/server/command/Executor.java | 4 ++-- server/src/server/command/FixedExecutor.java | 4 ++-- .../command/commands/CommandOfflinetp.java | 2 +- .../server/command/commands/CommandSpawn.java | 2 +- .../server/command/commands/CommandTele.java | 2 +- .../server/command/commands/CommandTime.java | 2 +- .../server/command/commands/CommandTp.java | 2 +- .../server/command/commands/CommandWarp.java | 2 +- .../server/command/commands/CommandWorld.java | 2 +- server/src/server/network/Player.java | 18 +++++++-------- 461 files changed, 837 insertions(+), 807 deletions(-) delete mode 100644 client/src/client/init/AnimationRegistry.java rename client/src/client/init/{EntityRenderRegistry.java => RenderRegistry.java} (91%) rename common/src/common/{world => util}/BlockPos.java (99%) rename common/src/common/{world => util}/BoundingBox.java (99%) rename common/src/common/{world => util}/ChunkPos.java (96%) rename common/src/common/{world => util}/ClassInheritanceMultiMap.java (99%) rename common/src/common/{world => util}/Facing.java (99%) rename common/src/common/{world => util}/HitPosition.java (97%) rename common/src/common/{world => util}/IntHashMap.java (99%) rename common/src/common/{world => util}/LongHashMap.java (99%) rename common/src/common/{world => util}/NextTickListEntry.java (98%) rename common/src/common/{world => util}/NibbleArray.java (97%) rename common/src/common/{world => util}/PortalType.java (86%) rename common/src/common/{world => util}/Position.java (94%) rename common/src/common/{world => util}/Vec3.java (99%) rename common/src/common/{world => util}/Vec3i.java (98%) rename common/src/common/{world => util}/WorldPos.java (97%) diff --git a/client/src/client/Game.java b/client/src/client/Game.java index f36f055..f754b50 100755 --- a/client/src/client/Game.java +++ b/client/src/client/Game.java @@ -144,21 +144,21 @@ import common.rng.Random; import common.sound.EventType; import common.sound.PositionedSound; import common.sound.Sound; +import common.util.BlockPos; +import common.util.BoundingBox; import common.util.CharValidator; import common.util.ExtMath; +import common.util.Facing; import common.util.FileUtils; +import common.util.HitPosition; import common.util.Util; -import common.world.BlockPos; -import common.world.BoundingBox; +import common.util.HitPosition.ObjectType; import common.world.Chunk; -import common.world.Facing; -import common.world.HitPosition; import common.world.LightType; import common.world.Region; import common.world.State; import common.world.World; import common.world.WorldClient; -import common.world.HitPosition.ObjectType; /* Een net ganz funktionierndes Programm ... diff --git a/client/src/client/PlayerController.java b/client/src/client/PlayerController.java index 579c38a..e6c48f4 100755 --- a/client/src/client/PlayerController.java +++ b/client/src/client/PlayerController.java @@ -15,10 +15,10 @@ import common.packet.CPacketBreak; import common.packet.CPacketClick; import common.packet.CPacketPlace; import common.sound.PositionedSound; -import common.world.BlockPos; -import common.world.Facing; +import common.util.BlockPos; +import common.util.Facing; +import common.util.Vec3; import common.world.State; -import common.world.Vec3; import common.world.World; import common.world.WorldClient; diff --git a/client/src/client/gui/GuiConsole.java b/client/src/client/gui/GuiConsole.java index 2bd506f..dafb2e7 100644 --- a/client/src/client/gui/GuiConsole.java +++ b/client/src/client/gui/GuiConsole.java @@ -16,9 +16,9 @@ import common.collect.Lists; import common.color.TextColor; import common.network.IPlayer; import common.packet.CPacketComplete; +import common.util.BlockPos; import common.util.ExtMath; -import common.world.BlockPos; -import common.world.HitPosition; +import common.util.HitPosition; public class GuiConsole extends Gui implements Textbox.Callback { public static final GuiConsole INSTANCE = new GuiConsole(); diff --git a/client/src/client/gui/container/GuiCrafting.java b/client/src/client/gui/container/GuiCrafting.java index e206188..d38e913 100755 --- a/client/src/client/gui/container/GuiCrafting.java +++ b/client/src/client/gui/container/GuiCrafting.java @@ -2,7 +2,7 @@ package client.gui.container; import common.inventory.ContainerWorkbench; import common.inventory.InventoryPlayer; -import common.world.BlockPos; +import common.util.BlockPos; import common.world.World; public class GuiCrafting extends GuiContainer diff --git a/client/src/client/gui/ingame/GuiSign.java b/client/src/client/gui/ingame/GuiSign.java index fbdfb60..457c151 100644 --- a/client/src/client/gui/ingame/GuiSign.java +++ b/client/src/client/gui/ingame/GuiSign.java @@ -6,7 +6,7 @@ import client.gui.element.Textbox; import client.gui.element.Textbox.Action; import client.network.ClientPlayer; import common.packet.CPacketSign; -import common.world.BlockPos; +import common.util.BlockPos; public class GuiSign extends Gui implements Textbox.Callback { private final BlockPos position; diff --git a/client/src/client/init/AnimationRegistry.java b/client/src/client/init/AnimationRegistry.java deleted file mode 100644 index 4120fbb..0000000 --- a/client/src/client/init/AnimationRegistry.java +++ /dev/null @@ -1,22 +0,0 @@ -package client.init; - -import java.util.Map; - -import client.renderer.texture.TextureTicked; -import client.renderer.ticked.TextureFlamesFX1; -import client.renderer.ticked.TextureFlamesFX2; -import client.renderer.ticked.TextureLavaFX; -import client.renderer.ticked.TextureLavaFlowFX; -import client.renderer.ticked.TextureWaterFX; -import client.renderer.ticked.TextureWaterFlowFX; - -public abstract class AnimationRegistry { - public static void registerAnimations(Map> anim) { - anim.put("fire1", TextureFlamesFX1.class); - anim.put("fire2", TextureFlamesFX2.class); - anim.put("lavaflow", TextureLavaFlowFX.class); - anim.put("lava", TextureLavaFX.class); - anim.put("waterflow", TextureWaterFlowFX.class); - anim.put("water", TextureWaterFX.class); - } -} diff --git a/client/src/client/init/EntityRenderRegistry.java b/client/src/client/init/RenderRegistry.java similarity index 91% rename from client/src/client/init/EntityRenderRegistry.java rename to client/src/client/init/RenderRegistry.java index 2abdd41..d57d794 100644 --- a/client/src/client/init/EntityRenderRegistry.java +++ b/client/src/client/init/RenderRegistry.java @@ -54,6 +54,13 @@ import client.renderer.model.ModelRabbit; import client.renderer.model.ModelSheep2; import client.renderer.model.ModelSquid; import client.renderer.model.ModelWolf; +import client.renderer.texture.TextureTicked; +import client.renderer.ticked.TextureFlamesFX1; +import client.renderer.ticked.TextureFlamesFX2; +import client.renderer.ticked.TextureLavaFX; +import client.renderer.ticked.TextureLavaFlowFX; +import client.renderer.ticked.TextureWaterFX; +import client.renderer.ticked.TextureWaterFlowFX; import common.entity.Entity; import common.entity.animal.EntityBat; import common.entity.animal.EntityChicken; @@ -99,7 +106,7 @@ import common.init.Items; import common.init.SpeciesRegistry; import common.init.SpeciesRegistry.ModelType; -public abstract class EntityRenderRegistry { +public abstract class RenderRegistry { public static void registerRenderers(Map, Render> map, Map models, RenderManager mgr, RenderItem ritem) { map.put(EntityPig.class, new RenderPig(mgr, new ModelPig())); @@ -154,4 +161,13 @@ public abstract class EntityRenderRegistry { map.put(info.clazz, models.get(info.renderer)); } } + + public static void registerAnimations(Map> anim) { + anim.put("fire1", TextureFlamesFX1.class); + anim.put("fire2", TextureFlamesFX2.class); + anim.put("lavaflow", TextureLavaFlowFX.class); + anim.put("lava", TextureLavaFX.class); + anim.put("waterflow", TextureWaterFlowFX.class); + anim.put("water", TextureWaterFX.class); + } } diff --git a/client/src/client/network/ClientPlayer.java b/client/src/client/network/ClientPlayer.java index 76fbc35..92b1b2e 100755 --- a/client/src/client/network/ClientPlayer.java +++ b/client/src/client/network/ClientPlayer.java @@ -131,8 +131,8 @@ import common.tileentity.LocalBlockIntercommunication; import common.tileentity.TileEntity; import common.tileentity.TileEntityMachine; import common.tileentity.TileEntitySign; +import common.util.BlockPos; import common.village.MerchantRecipeList; -import common.world.BlockPos; import common.world.Chunk; import common.world.Explosion; import common.world.Weather; diff --git a/client/src/client/renderer/ActiveRenderInfo.java b/client/src/client/renderer/ActiveRenderInfo.java index fc8a9ef..653eff6 100755 --- a/client/src/client/renderer/ActiveRenderInfo.java +++ b/client/src/client/renderer/ActiveRenderInfo.java @@ -11,10 +11,10 @@ import common.block.Block; import common.block.BlockLiquid; import common.entity.Entity; import common.entity.npc.EntityNPC; +import common.util.BlockPos; import common.util.ExtMath; -import common.world.BlockPos; +import common.util.Vec3; import common.world.State; -import common.world.Vec3; import common.world.World; public class ActiveRenderInfo diff --git a/client/src/client/renderer/BlockRenderer.java b/client/src/client/renderer/BlockRenderer.java index ba4e8d1..073fcd6 100755 --- a/client/src/client/renderer/BlockRenderer.java +++ b/client/src/client/renderer/BlockRenderer.java @@ -21,13 +21,13 @@ import common.init.BlockRegistry; import common.init.FluidRegistry; import common.item.ItemStack; import common.material.Material; +import common.util.BlockPos; import common.util.ExtMath; -import common.world.BlockPos; -import common.world.Facing; +import common.util.Facing; +import common.util.Vec3i; import common.world.IBlockAccess; import common.world.IWorldAccess; import common.world.State; -import common.world.Vec3i; public class BlockRenderer { diff --git a/client/src/client/renderer/EntityRenderer.java b/client/src/client/renderer/EntityRenderer.java index 94152e2..7f5d177 100755 --- a/client/src/client/renderer/EntityRenderer.java +++ b/client/src/client/renderer/EntityRenderer.java @@ -26,11 +26,11 @@ import common.model.BlockLayer; import common.model.ParticleType; import common.potion.Potion; import common.rng.Random; +import common.util.BlockPos; +import common.util.BoundingBox; import common.util.ExtMath; -import common.world.BlockPos; -import common.world.BoundingBox; -import common.world.HitPosition; -import common.world.Vec3; +import common.util.HitPosition; +import common.util.Vec3; import common.world.World; import common.world.WorldClient; diff --git a/client/src/client/renderer/Frustum.java b/client/src/client/renderer/Frustum.java index ba0a6f5..581321b 100755 --- a/client/src/client/renderer/Frustum.java +++ b/client/src/client/renderer/Frustum.java @@ -6,8 +6,8 @@ import java.nio.FloatBuffer; import org.lwjgl.opengl.GL11; +import common.util.BoundingBox; import common.util.ExtMath; -import common.world.BoundingBox; public class Frustum { private static class ClippingHelper { diff --git a/client/src/client/renderer/ItemRenderer.java b/client/src/client/renderer/ItemRenderer.java index 559e6a0..1a24321 100755 --- a/client/src/client/renderer/ItemRenderer.java +++ b/client/src/client/renderer/ItemRenderer.java @@ -22,10 +22,10 @@ import common.item.ItemAction; import common.item.ItemStack; import common.model.BlockLayer; import common.model.Transforms; +import common.util.BlockPos; import common.util.ExtMath; -import common.world.BlockPos; +import common.util.Vec3; import common.world.State; -import common.world.Vec3; public class ItemRenderer diff --git a/client/src/client/renderer/RegionRenderCache.java b/client/src/client/renderer/RegionRenderCache.java index 91c66d6..635a77a 100755 --- a/client/src/client/renderer/RegionRenderCache.java +++ b/client/src/client/renderer/RegionRenderCache.java @@ -5,14 +5,14 @@ import java.util.Arrays; import common.biome.Biome; import common.init.Blocks; import common.tileentity.TileEntity; -import common.world.BlockPos; +import common.util.BlockPos; +import common.util.Facing; +import common.util.Vec3i; import common.world.Chunk; import common.world.ChunkCache; -import common.world.Facing; import common.world.IWorldAccess; import common.world.LightType; import common.world.State; -import common.world.Vec3i; import common.world.World; public class RegionRenderCache extends ChunkCache implements IWorldAccess diff --git a/client/src/client/renderer/RenderGlobal.java b/client/src/client/renderer/RenderGlobal.java index c1a1d9d..1dfe3a1 100755 --- a/client/src/client/renderer/RenderGlobal.java +++ b/client/src/client/renderer/RenderGlobal.java @@ -42,16 +42,16 @@ import common.rng.Random; import common.sound.Sound; import common.tileentity.TileEntity; import common.tileentity.TileEntityChest; +import common.util.BlockPos; +import common.util.BoundingBox; +import common.util.ClassInheritanceMultiMap; import common.util.ExtMath; +import common.util.Facing; +import common.util.HitPosition; +import common.util.Vec3; import common.util.Vector3f; -import common.world.BlockPos; -import common.world.BoundingBox; import common.world.Chunk; -import common.world.ClassInheritanceMultiMap; -import common.world.Facing; -import common.world.HitPosition; import common.world.State; -import common.world.Vec3; import common.world.WorldClient; public class RenderGlobal diff --git a/client/src/client/renderer/ViewFrustum.java b/client/src/client/renderer/ViewFrustum.java index e4d4980..df65bd6 100755 --- a/client/src/client/renderer/ViewFrustum.java +++ b/client/src/client/renderer/ViewFrustum.java @@ -1,8 +1,8 @@ package client.renderer; import client.renderer.chunk.RenderChunk; +import common.util.BlockPos; import common.util.ExtMath; -import common.world.BlockPos; import common.world.World; public class ViewFrustum diff --git a/client/src/client/renderer/blockmodel/BakedModel.java b/client/src/client/renderer/blockmodel/BakedModel.java index 5a25ef0..d383523 100755 --- a/client/src/client/renderer/blockmodel/BakedModel.java +++ b/client/src/client/renderer/blockmodel/BakedModel.java @@ -6,7 +6,7 @@ import java.util.List; import client.renderer.texture.TextureAtlasSprite; import common.collect.Lists; import common.model.Transforms; -import common.world.Facing; +import common.util.Facing; public class BakedModel implements IBakedModel { diff --git a/client/src/client/renderer/blockmodel/BakedQuad.java b/client/src/client/renderer/blockmodel/BakedQuad.java index faefddb..e50b3d0 100755 --- a/client/src/client/renderer/blockmodel/BakedQuad.java +++ b/client/src/client/renderer/blockmodel/BakedQuad.java @@ -1,6 +1,6 @@ package client.renderer.blockmodel; -import common.world.Facing; +import common.util.Facing; public class BakedQuad { protected final int[] data; diff --git a/client/src/client/renderer/blockmodel/BlockPart.java b/client/src/client/renderer/blockmodel/BlockPart.java index f3a03e7..830f491 100755 --- a/client/src/client/renderer/blockmodel/BlockPart.java +++ b/client/src/client/renderer/blockmodel/BlockPart.java @@ -2,8 +2,8 @@ package client.renderer.blockmodel; import java.util.Map; +import common.util.Facing; import common.util.Vector3f; -import common.world.Facing; public class BlockPart { diff --git a/client/src/client/renderer/blockmodel/BlockPartFace.java b/client/src/client/renderer/blockmodel/BlockPartFace.java index 9d7e0fd..03791d7 100755 --- a/client/src/client/renderer/blockmodel/BlockPartFace.java +++ b/client/src/client/renderer/blockmodel/BlockPartFace.java @@ -1,7 +1,7 @@ package client.renderer.blockmodel; import client.renderer.texture.TextureMap; -import common.world.Facing; +import common.util.Facing; public class BlockPartFace { public Facing cull; diff --git a/client/src/client/renderer/blockmodel/BlockPartRotation.java b/client/src/client/renderer/blockmodel/BlockPartRotation.java index b3cfbea..7bde7ed 100755 --- a/client/src/client/renderer/blockmodel/BlockPartRotation.java +++ b/client/src/client/renderer/blockmodel/BlockPartRotation.java @@ -1,7 +1,7 @@ package client.renderer.blockmodel; +import common.util.Facing; import common.util.Vector3f; -import common.world.Facing; public class BlockPartRotation { public final Vector3f origin; diff --git a/client/src/client/renderer/blockmodel/BuiltInModel.java b/client/src/client/renderer/blockmodel/BuiltInModel.java index 7c9c306..802fcc9 100755 --- a/client/src/client/renderer/blockmodel/BuiltInModel.java +++ b/client/src/client/renderer/blockmodel/BuiltInModel.java @@ -4,7 +4,7 @@ import java.util.List; import client.renderer.texture.TextureAtlasSprite; import common.model.Transforms; -import common.world.Facing; +import common.util.Facing; public class BuiltInModel implements IBakedModel { diff --git a/client/src/client/renderer/blockmodel/FaceBakery.java b/client/src/client/renderer/blockmodel/FaceBakery.java index 09fd515..cb73b49 100755 --- a/client/src/client/renderer/blockmodel/FaceBakery.java +++ b/client/src/client/renderer/blockmodel/FaceBakery.java @@ -3,11 +3,11 @@ package client.renderer.blockmodel; import client.renderer.texture.TextureAtlasSprite; import common.model.ModelRotation; import common.util.ExtMath; +import common.util.Facing; import common.util.Matrix4f; +import common.util.Vec3i; import common.util.Vector3f; import common.util.Vector4f; -import common.world.Facing; -import common.world.Vec3i; public class FaceBakery { diff --git a/client/src/client/renderer/blockmodel/IBakedModel.java b/client/src/client/renderer/blockmodel/IBakedModel.java index 7e5b482..490f71b 100755 --- a/client/src/client/renderer/blockmodel/IBakedModel.java +++ b/client/src/client/renderer/blockmodel/IBakedModel.java @@ -4,7 +4,7 @@ import java.util.List; import client.renderer.texture.TextureAtlasSprite; import common.model.Transforms; -import common.world.Facing; +import common.util.Facing; public interface IBakedModel { diff --git a/client/src/client/renderer/blockmodel/ModelBakery.java b/client/src/client/renderer/blockmodel/ModelBakery.java index ef9e54c..aaa55a3 100755 --- a/client/src/client/renderer/blockmodel/ModelBakery.java +++ b/client/src/client/renderer/blockmodel/ModelBakery.java @@ -21,7 +21,7 @@ import common.init.RegistrySimple; import common.item.Item; import common.item.ItemStack; import common.model.ModelRotation; -import common.world.Facing; +import common.util.Facing; import common.world.State; public abstract class ModelBakery diff --git a/client/src/client/renderer/blockmodel/ModelBlock.java b/client/src/client/renderer/blockmodel/ModelBlock.java index c54e391..69504fa 100755 --- a/client/src/client/renderer/blockmodel/ModelBlock.java +++ b/client/src/client/renderer/blockmodel/ModelBlock.java @@ -9,8 +9,8 @@ import common.model.Model; import common.model.ModelProvider; import common.model.ModelRotation; import common.model.Transforms; +import common.util.Facing; import common.util.Vector3f; -import common.world.Facing; public class ModelBlock extends Model { static final ModelProvider PROVIDER = new ModelProvider() { diff --git a/client/src/client/renderer/blockmodel/ModelGenerator.java b/client/src/client/renderer/blockmodel/ModelGenerator.java index 178a13a..9e4ccc6 100755 --- a/client/src/client/renderer/blockmodel/ModelGenerator.java +++ b/client/src/client/renderer/blockmodel/ModelGenerator.java @@ -11,8 +11,8 @@ import client.renderer.texture.TextureUtil; import common.collect.Lists; import common.collect.Maps; import common.log.Log; +import common.util.Facing; import common.util.Vector3f; -import common.world.Facing; public abstract class ModelGenerator { // public static final List LAYERS = Lists.newArrayList("layer0", "layer1", "layer2", "layer3", "layer4"); diff --git a/client/src/client/renderer/chunk/CompiledChunk.java b/client/src/client/renderer/chunk/CompiledChunk.java index bdd2a33..7155915 100755 --- a/client/src/client/renderer/chunk/CompiledChunk.java +++ b/client/src/client/renderer/chunk/CompiledChunk.java @@ -6,7 +6,7 @@ import client.renderer.RenderBuffer; import common.collect.Lists; import common.model.BlockLayer; import common.tileentity.TileEntity; -import common.world.Facing; +import common.util.Facing; public class CompiledChunk { diff --git a/client/src/client/renderer/chunk/RenderChunk.java b/client/src/client/renderer/chunk/RenderChunk.java index c014e18..9e02136 100755 --- a/client/src/client/renderer/chunk/RenderChunk.java +++ b/client/src/client/renderer/chunk/RenderChunk.java @@ -24,9 +24,9 @@ import common.collect.Maps; import common.collect.Sets; import common.model.BlockLayer; import common.tileentity.TileEntity; -import common.world.BlockPos; -import common.world.BoundingBox; -import common.world.Facing; +import common.util.BlockPos; +import common.util.BoundingBox; +import common.util.Facing; import common.world.State; import common.world.World; diff --git a/client/src/client/renderer/chunk/SetVisibility.java b/client/src/client/renderer/chunk/SetVisibility.java index edbb073..3dfdebc 100755 --- a/client/src/client/renderer/chunk/SetVisibility.java +++ b/client/src/client/renderer/chunk/SetVisibility.java @@ -3,7 +3,7 @@ package client.renderer.chunk; import java.util.BitSet; import java.util.Set; -import common.world.Facing; +import common.util.Facing; public class SetVisibility { diff --git a/client/src/client/renderer/chunk/VisGraph.java b/client/src/client/renderer/chunk/VisGraph.java index 2294ec1..ebca265 100755 --- a/client/src/client/renderer/chunk/VisGraph.java +++ b/client/src/client/renderer/chunk/VisGraph.java @@ -6,8 +6,8 @@ import java.util.LinkedList; import java.util.Queue; import java.util.Set; -import common.world.BlockPos; -import common.world.Facing; +import common.util.BlockPos; +import common.util.Facing; public class VisGraph { diff --git a/client/src/client/renderer/entity/Render.java b/client/src/client/renderer/entity/Render.java index 74f181f..7c2a5e0 100755 --- a/client/src/client/renderer/entity/Render.java +++ b/client/src/client/renderer/entity/Render.java @@ -13,8 +13,8 @@ import client.renderer.texture.TextureAtlasSprite; import client.renderer.texture.TextureMap; import common.block.Block; import common.entity.Entity; -import common.world.BlockPos; -import common.world.BoundingBox; +import common.util.BlockPos; +import common.util.BoundingBox; import common.world.World; public abstract class Render diff --git a/client/src/client/renderer/entity/RenderFallingBlock.java b/client/src/client/renderer/entity/RenderFallingBlock.java index 5f12f22..b440c26 100755 --- a/client/src/client/renderer/entity/RenderFallingBlock.java +++ b/client/src/client/renderer/entity/RenderFallingBlock.java @@ -12,7 +12,7 @@ import client.renderer.blockmodel.IBakedModel; import client.renderer.texture.TextureMap; import common.block.Block; import common.entity.item.EntityFalling; -import common.world.BlockPos; +import common.util.BlockPos; import common.world.State; import common.world.World; diff --git a/client/src/client/renderer/entity/RenderFish.java b/client/src/client/renderer/entity/RenderFish.java index c9537ab..a053261 100755 --- a/client/src/client/renderer/entity/RenderFish.java +++ b/client/src/client/renderer/entity/RenderFish.java @@ -10,7 +10,7 @@ import client.renderer.Tessellator; import client.renderer.particle.EffectRenderer; import common.entity.projectile.EntityHook; import common.util.ExtMath; -import common.world.Vec3; +import common.util.Vec3; public class RenderFish extends Render { diff --git a/client/src/client/renderer/entity/RenderItem.java b/client/src/client/renderer/entity/RenderItem.java index b881350..d1ab920 100755 --- a/client/src/client/renderer/entity/RenderItem.java +++ b/client/src/client/renderer/entity/RenderItem.java @@ -22,8 +22,8 @@ import common.item.Item; import common.item.ItemStack; import common.model.Transform; import common.model.Transforms; -import common.world.Facing; -import common.world.Vec3i; +import common.util.Facing; +import common.util.Vec3i; public class RenderItem { diff --git a/client/src/client/renderer/entity/RenderManager.java b/client/src/client/renderer/entity/RenderManager.java index f88738d..065cb0d 100755 --- a/client/src/client/renderer/entity/RenderManager.java +++ b/client/src/client/renderer/entity/RenderManager.java @@ -6,7 +6,7 @@ import org.lwjgl.opengl.GL11; import org.lwjgl.opengl.GL13; import client.Game; -import client.init.EntityRenderRegistry; +import client.init.RenderRegistry; import client.renderer.DefaultVertexFormats; import client.renderer.GlState; import client.renderer.RenderBuffer; @@ -17,8 +17,8 @@ import common.collect.Maps; import common.entity.Entity; import common.entity.types.EntityLiving; import common.init.SpeciesRegistry.ModelType; -import common.world.BoundingBox; -import common.world.Vec3; +import common.util.BoundingBox; +import common.util.Vec3; import common.world.World; public class RenderManager @@ -68,7 +68,7 @@ public class RenderManager public RenderManager(TextureManager renderEngineIn, RenderItem itemRendererIn) { this.renderEngine = renderEngineIn; - EntityRenderRegistry.registerRenderers(this.entityRenderMap, this.models, this, itemRendererIn); + RenderRegistry.registerRenderers(this.entityRenderMap, this.models, this, itemRendererIn); for(RenderNpc render : this.models.values()) { render.initSegments(); } diff --git a/client/src/client/renderer/entity/RenderMinecart.java b/client/src/client/renderer/entity/RenderMinecart.java index 24255f9..050e8d2 100755 --- a/client/src/client/renderer/entity/RenderMinecart.java +++ b/client/src/client/renderer/entity/RenderMinecart.java @@ -9,8 +9,8 @@ import client.renderer.model.ModelMinecart; import client.renderer.texture.TextureMap; import common.entity.item.EntityCart; import common.util.ExtMath; +import common.util.Vec3; import common.world.State; -import common.world.Vec3; public class RenderMinecart extends Render { diff --git a/client/src/client/renderer/model/ModelBox.java b/client/src/client/renderer/model/ModelBox.java index 091e341..354eaea 100755 --- a/client/src/client/renderer/model/ModelBox.java +++ b/client/src/client/renderer/model/ModelBox.java @@ -1,8 +1,8 @@ package client.renderer.model; import client.renderer.RenderBuffer; -import common.world.Facing; -import common.world.Vec3; +import common.util.Facing; +import common.util.Vec3; public class ModelBox { private static Vec3[] getPoints(float x1, float y1, float z1, float x2, float y2, float z2, int dir) { diff --git a/client/src/client/renderer/model/PositionTextureVertex.java b/client/src/client/renderer/model/PositionTextureVertex.java index 8346105..4cde066 100755 --- a/client/src/client/renderer/model/PositionTextureVertex.java +++ b/client/src/client/renderer/model/PositionTextureVertex.java @@ -1,6 +1,6 @@ package client.renderer.model; -import common.world.Vec3; +import common.util.Vec3; public class PositionTextureVertex { diff --git a/client/src/client/renderer/model/TexturedQuad.java b/client/src/client/renderer/model/TexturedQuad.java index 53ec9a5..12da9c3 100755 --- a/client/src/client/renderer/model/TexturedQuad.java +++ b/client/src/client/renderer/model/TexturedQuad.java @@ -5,7 +5,7 @@ import org.lwjgl.opengl.GL11; import client.renderer.DefaultVertexFormats; import client.renderer.RenderBuffer; import client.renderer.Tessellator; -import common.world.Vec3; +import common.util.Vec3; public class TexturedQuad { diff --git a/client/src/client/renderer/particle/EffectRenderer.java b/client/src/client/renderer/particle/EffectRenderer.java index c1624c4..5d6ea5f 100755 --- a/client/src/client/renderer/particle/EffectRenderer.java +++ b/client/src/client/renderer/particle/EffectRenderer.java @@ -19,9 +19,9 @@ import common.entity.Entity; import common.material.Material; import common.model.ParticleType; import common.rng.Random; +import common.util.BlockPos; import common.util.ExtMath; -import common.world.BlockPos; -import common.world.Facing; +import common.util.Facing; import common.world.State; import common.world.World; diff --git a/client/src/client/renderer/particle/EntityBubbleFX.java b/client/src/client/renderer/particle/EntityBubbleFX.java index c21ba62..44c03f7 100755 --- a/client/src/client/renderer/particle/EntityBubbleFX.java +++ b/client/src/client/renderer/particle/EntityBubbleFX.java @@ -1,7 +1,7 @@ package client.renderer.particle; import common.material.Material; -import common.world.BlockPos; +import common.util.BlockPos; import common.world.World; public class EntityBubbleFX extends EntityFX diff --git a/client/src/client/renderer/particle/EntityDiggingFX.java b/client/src/client/renderer/particle/EntityDiggingFX.java index 8e3e89d..84ec999 100755 --- a/client/src/client/renderer/particle/EntityDiggingFX.java +++ b/client/src/client/renderer/particle/EntityDiggingFX.java @@ -6,7 +6,7 @@ import common.block.Block; import common.entity.Entity; import common.init.BlockRegistry; import common.init.Blocks; -import common.world.BlockPos; +import common.util.BlockPos; import common.world.State; import common.world.World; diff --git a/client/src/client/renderer/particle/EntityDownfallFX.java b/client/src/client/renderer/particle/EntityDownfallFX.java index c321d6b..b2bd951 100755 --- a/client/src/client/renderer/particle/EntityDownfallFX.java +++ b/client/src/client/renderer/particle/EntityDownfallFX.java @@ -3,8 +3,8 @@ package client.renderer.particle; import common.block.Block; import common.block.BlockLiquid; import common.material.Material; +import common.util.BlockPos; import common.util.ExtMath; -import common.world.BlockPos; import common.world.State; import common.world.World; diff --git a/client/src/client/renderer/particle/EntityDropParticleFX.java b/client/src/client/renderer/particle/EntityDropParticleFX.java index 8409e31..90542cd 100755 --- a/client/src/client/renderer/particle/EntityDropParticleFX.java +++ b/client/src/client/renderer/particle/EntityDropParticleFX.java @@ -3,8 +3,8 @@ package client.renderer.particle; import common.block.BlockLiquid; import common.material.Material; import common.model.ParticleType; +import common.util.BlockPos; import common.util.ExtMath; -import common.world.BlockPos; import common.world.State; import common.world.World; diff --git a/client/src/client/renderer/particle/EntityFirework.java b/client/src/client/renderer/particle/EntityFirework.java index 078c6fc..c34b444 100755 --- a/client/src/client/renderer/particle/EntityFirework.java +++ b/client/src/client/renderer/particle/EntityFirework.java @@ -7,8 +7,8 @@ import common.init.SoundEvent; import common.item.ItemDye; import common.nbt.NBTTagCompound; import common.nbt.NBTTagList; +import common.util.BoundingBox; import common.util.ExtMath; -import common.world.BoundingBox; import common.world.World; import common.world.WorldClient; diff --git a/client/src/client/renderer/particle/EntityFootStepFX.java b/client/src/client/renderer/particle/EntityFootStepFX.java index d8d47e9..5835284 100755 --- a/client/src/client/renderer/particle/EntityFootStepFX.java +++ b/client/src/client/renderer/particle/EntityFootStepFX.java @@ -9,7 +9,7 @@ import client.renderer.RenderBuffer; import client.renderer.Tessellator; import client.renderer.texture.TextureManager; import common.entity.Entity; -import common.world.BlockPos; +import common.util.BlockPos; import common.world.World; public class EntityFootStepFX extends EntityFX diff --git a/client/src/client/renderer/particle/EntitySuspendFX.java b/client/src/client/renderer/particle/EntitySuspendFX.java index aae9b5e..4047b03 100755 --- a/client/src/client/renderer/particle/EntitySuspendFX.java +++ b/client/src/client/renderer/particle/EntitySuspendFX.java @@ -1,7 +1,7 @@ package client.renderer.particle; import common.material.Material; -import common.world.BlockPos; +import common.util.BlockPos; import common.world.World; public class EntitySuspendFX extends EntityFX diff --git a/client/src/client/renderer/texture/TextureMap.java b/client/src/client/renderer/texture/TextureMap.java index afe4afd..5e5c2ee 100755 --- a/client/src/client/renderer/texture/TextureMap.java +++ b/client/src/client/renderer/texture/TextureMap.java @@ -7,7 +7,7 @@ import java.util.List; import java.util.Map; import java.util.Map.Entry; -import client.init.AnimationRegistry; +import client.init.RenderRegistry; import client.renderer.GlState; import common.block.Block; import common.collect.Lists; @@ -40,7 +40,7 @@ public class TextureMap extends Texture // RenderRegistry.registerAnimations(this); Map map = Maps.newHashMap(); Map> anim = Maps.newHashMap(); - AnimationRegistry.registerAnimations(anim); + RenderRegistry.registerAnimations(anim); for(Block block : BlockRegistry.REGISTRY) { block.getAnimatedTextures(map); } diff --git a/client/src/client/renderer/tileentity/TileEntityBannerRenderer.java b/client/src/client/renderer/tileentity/TileEntityBannerRenderer.java index 3e38162..bfa5ad0 100755 --- a/client/src/client/renderer/tileentity/TileEntityBannerRenderer.java +++ b/client/src/client/renderer/tileentity/TileEntityBannerRenderer.java @@ -15,8 +15,8 @@ import common.collect.Maps; import common.color.DyeColor; import common.init.Blocks; import common.tileentity.TileEntityBanner; +import common.util.BlockPos; import common.util.ExtMath; -import common.world.BlockPos; public class TileEntityBannerRenderer extends TileEntitySpecialRenderer { diff --git a/client/src/client/renderer/tileentity/TileEntityItemStackRenderer.java b/client/src/client/renderer/tileentity/TileEntityItemStackRenderer.java index ed89a94..df617b0 100755 --- a/client/src/client/renderer/tileentity/TileEntityItemStackRenderer.java +++ b/client/src/client/renderer/tileentity/TileEntityItemStackRenderer.java @@ -10,7 +10,7 @@ import common.item.ItemStack; import common.tileentity.TileEntityBanner; import common.tileentity.TileEntityChest; import common.tileentity.TileEntitySkull; -import common.world.Facing; +import common.util.Facing; public class TileEntityItemStackRenderer { diff --git a/client/src/client/renderer/tileentity/TileEntityPistonRenderer.java b/client/src/client/renderer/tileentity/TileEntityPistonRenderer.java index 9d0bfe7..eccb970 100755 --- a/client/src/client/renderer/tileentity/TileEntityPistonRenderer.java +++ b/client/src/client/renderer/tileentity/TileEntityPistonRenderer.java @@ -16,7 +16,7 @@ import common.block.BlockPistonHead; import common.init.Blocks; import common.material.Material; import common.tileentity.TileEntityPiston; -import common.world.BlockPos; +import common.util.BlockPos; import common.world.State; import common.world.World; diff --git a/client/src/client/renderer/tileentity/TileEntityRendererDispatcher.java b/client/src/client/renderer/tileentity/TileEntityRendererDispatcher.java index 1bf7bdc..d491221 100755 --- a/client/src/client/renderer/tileentity/TileEntityRendererDispatcher.java +++ b/client/src/client/renderer/tileentity/TileEntityRendererDispatcher.java @@ -15,7 +15,7 @@ import common.tileentity.TileEntityMobSpawner; import common.tileentity.TileEntityPiston; import common.tileentity.TileEntitySign; import common.tileentity.TileEntitySkull; -import common.world.BlockPos; +import common.util.BlockPos; import common.world.World; public class TileEntityRendererDispatcher diff --git a/client/src/client/renderer/tileentity/TileEntitySkullRenderer.java b/client/src/client/renderer/tileentity/TileEntitySkullRenderer.java index 86478f3..9cd2628 100755 --- a/client/src/client/renderer/tileentity/TileEntitySkullRenderer.java +++ b/client/src/client/renderer/tileentity/TileEntitySkullRenderer.java @@ -5,7 +5,7 @@ import org.lwjgl.opengl.GL11; import client.renderer.GlState; import client.renderer.model.ModelHumanoidHead; import common.tileentity.TileEntitySkull; -import common.world.Facing; +import common.util.Facing; public class TileEntitySkullRenderer extends TileEntitySpecialRenderer diff --git a/client/src/client/world/Converter.java b/client/src/client/world/Converter.java index 6a81987..f89812d 100644 --- a/client/src/client/world/Converter.java +++ b/client/src/client/world/Converter.java @@ -86,8 +86,8 @@ import common.tileentity.TileEntityNote; import common.tileentity.TileEntityPiston; import common.tileentity.TileEntitySign; import common.tileentity.TileEntitySkull; -import common.world.Facing; -import common.world.NibbleArray; +import common.util.Facing; +import common.util.NibbleArray; import common.world.Region; import common.world.State; import common.world.Weather; diff --git a/common/src/common/IClient.java b/common/src/common/IClient.java index 1e0ed74..6d050f4 100644 --- a/common/src/common/IClient.java +++ b/common/src/common/IClient.java @@ -6,7 +6,7 @@ import common.entity.types.IEntityFX; import common.model.ParticleType; import common.nbt.NBTTagCompound; import common.sound.Sound; -import common.world.BlockPos; +import common.util.BlockPos; import common.world.State; public interface IClient { diff --git a/common/src/common/IServer.java b/common/src/common/IServer.java index cd3fd18..c3fc135 100644 --- a/common/src/common/IServer.java +++ b/common/src/common/IServer.java @@ -7,9 +7,9 @@ import common.entity.Entity; import common.entity.npc.EntityNPC; import common.network.IPlayer; import common.network.Packet; -import common.world.BlockPos; -import common.world.PortalType; -import common.world.Position; +import common.util.BlockPos; +import common.util.PortalType; +import common.util.Position; import common.world.WorldServer; public interface IServer { diff --git a/common/src/common/ai/AIFireballAttack.java b/common/src/common/ai/AIFireballAttack.java index 6790164..87a3b8d 100755 --- a/common/src/common/ai/AIFireballAttack.java +++ b/common/src/common/ai/AIFireballAttack.java @@ -5,8 +5,8 @@ import common.entity.projectile.EntityFireball; import common.entity.types.EntityLiving; import common.init.Items; import common.item.ItemStack; -import common.world.BlockPos; -import common.world.Vec3; +import common.util.BlockPos; +import common.util.Vec3; import common.world.World; public class AIFireballAttack extends EntityAIBase diff --git a/common/src/common/ai/AIFlyingBoxAttack.java b/common/src/common/ai/AIFlyingBoxAttack.java index 4477be0..444a1dd 100755 --- a/common/src/common/ai/AIFlyingBoxAttack.java +++ b/common/src/common/ai/AIFlyingBoxAttack.java @@ -3,7 +3,7 @@ package common.ai; import common.entity.npc.EntityNPC; import common.entity.projectile.EntityBox; import common.entity.types.EntityLiving; -import common.world.BlockPos; +import common.util.BlockPos; public class AIFlyingBoxAttack extends EntityAIBase { diff --git a/common/src/common/ai/AISmallFireballAttack.java b/common/src/common/ai/AISmallFireballAttack.java index 9bdbd59..ed9c9b2 100755 --- a/common/src/common/ai/AISmallFireballAttack.java +++ b/common/src/common/ai/AISmallFireballAttack.java @@ -3,7 +3,7 @@ package common.ai; import common.entity.npc.EntityNPC; import common.entity.projectile.EntityFireCharge; import common.entity.types.EntityLiving; -import common.world.BlockPos; +import common.util.BlockPos; public class AISmallFireballAttack extends EntityAIBase { diff --git a/common/src/common/ai/EntityAIAttackOnCollide.java b/common/src/common/ai/EntityAIAttackOnCollide.java index 26ab783..ba225f2 100755 --- a/common/src/common/ai/EntityAIAttackOnCollide.java +++ b/common/src/common/ai/EntityAIAttackOnCollide.java @@ -3,7 +3,7 @@ package common.ai; import common.entity.Entity; import common.entity.types.EntityLiving; import common.pathfinding.PathEntity; -import common.world.BlockPos; +import common.util.BlockPos; import common.world.World; public class EntityAIAttackOnCollide extends EntityAIBase diff --git a/common/src/common/ai/EntityAIAvoidEntity.java b/common/src/common/ai/EntityAIAvoidEntity.java index 90cd980..2e26f2b 100755 --- a/common/src/common/ai/EntityAIAvoidEntity.java +++ b/common/src/common/ai/EntityAIAvoidEntity.java @@ -8,7 +8,7 @@ import common.entity.types.EntityLiving; import common.pathfinding.PathEntity; import common.pathfinding.PathNavigate; import common.util.Predicates; -import common.world.Vec3; +import common.util.Vec3; public class EntityAIAvoidEntity extends EntityAIBase { diff --git a/common/src/common/ai/EntityAIControlledByPlayer.java b/common/src/common/ai/EntityAIControlledByPlayer.java index 4975645..320f4d1 100755 --- a/common/src/common/ai/EntityAIControlledByPlayer.java +++ b/common/src/common/ai/EntityAIControlledByPlayer.java @@ -9,8 +9,8 @@ import common.init.Items; import common.item.ItemStack; import common.material.Material; import common.pathfinding.WalkNodeProcessor; +import common.util.BlockPos; import common.util.ExtMath; -import common.world.BlockPos; public class EntityAIControlledByPlayer extends EntityAIBase { diff --git a/common/src/common/ai/EntityAIDoorInteract.java b/common/src/common/ai/EntityAIDoorInteract.java index e45f438..c6a7538 100755 --- a/common/src/common/ai/EntityAIDoorInteract.java +++ b/common/src/common/ai/EntityAIDoorInteract.java @@ -7,7 +7,7 @@ import common.material.Material; import common.pathfinding.PathEntity; import common.pathfinding.PathNavigateGround; import common.pathfinding.PathPoint; -import common.world.BlockPos; +import common.util.BlockPos; public abstract class EntityAIDoorInteract extends EntityAIBase { diff --git a/common/src/common/ai/EntityAIEatGrass.java b/common/src/common/ai/EntityAIEatGrass.java index 5930c11..f04e8fd 100755 --- a/common/src/common/ai/EntityAIEatGrass.java +++ b/common/src/common/ai/EntityAIEatGrass.java @@ -8,8 +8,8 @@ import common.init.BlockRegistry; import common.init.Blocks; import common.init.Config; import common.pattern.BlockStateHelper; +import common.util.BlockPos; import common.util.Predicates; -import common.world.BlockPos; import common.world.State; import common.world.World; diff --git a/common/src/common/ai/EntityAIFleeSun.java b/common/src/common/ai/EntityAIFleeSun.java index d6e9733..0347580 100755 --- a/common/src/common/ai/EntityAIFleeSun.java +++ b/common/src/common/ai/EntityAIFleeSun.java @@ -2,8 +2,8 @@ package common.ai; import common.entity.types.EntityLiving; import common.rng.Random; -import common.world.BlockPos; -import common.world.Vec3; +import common.util.BlockPos; +import common.util.Vec3; import common.world.World; import common.world.WorldServer; diff --git a/common/src/common/ai/EntityAIHarvestFarmland.java b/common/src/common/ai/EntityAIHarvestFarmland.java index 3bcc9a9..9ea311b 100755 --- a/common/src/common/ai/EntityAIHarvestFarmland.java +++ b/common/src/common/ai/EntityAIHarvestFarmland.java @@ -1,7 +1,7 @@ package common.ai; import common.entity.types.EntityLiving; -import common.world.BlockPos; +import common.util.BlockPos; import common.world.World; public class EntityAIHarvestFarmland extends EntityAIMoveToBlock diff --git a/common/src/common/ai/EntityAIHurtByTarget.java b/common/src/common/ai/EntityAIHurtByTarget.java index 096dd21..c4ae5e8 100755 --- a/common/src/common/ai/EntityAIHurtByTarget.java +++ b/common/src/common/ai/EntityAIHurtByTarget.java @@ -1,7 +1,7 @@ package common.ai; import common.entity.types.EntityLiving; -import common.world.BoundingBox; +import common.util.BoundingBox; public class EntityAIHurtByTarget extends EntityAITarget { diff --git a/common/src/common/ai/EntityAIMoveIndoors.java b/common/src/common/ai/EntityAIMoveIndoors.java index 609f82e..0348347 100755 --- a/common/src/common/ai/EntityAIMoveIndoors.java +++ b/common/src/common/ai/EntityAIMoveIndoors.java @@ -1,10 +1,10 @@ package common.ai; import common.entity.types.EntityLiving; +import common.util.BlockPos; +import common.util.Vec3; import common.village.Village; import common.village.VillageDoorInfo; -import common.world.BlockPos; -import common.world.Vec3; import common.world.WorldServer; public class EntityAIMoveIndoors extends EntityAIBase diff --git a/common/src/common/ai/EntityAIMoveThroughVillage.java b/common/src/common/ai/EntityAIMoveThroughVillage.java index ac2428f..be583f8 100755 --- a/common/src/common/ai/EntityAIMoveThroughVillage.java +++ b/common/src/common/ai/EntityAIMoveThroughVillage.java @@ -6,11 +6,11 @@ import common.collect.Lists; import common.entity.types.EntityLiving; import common.pathfinding.PathEntity; import common.pathfinding.PathNavigateGround; +import common.util.BlockPos; import common.util.ExtMath; +import common.util.Vec3; import common.village.Village; import common.village.VillageDoorInfo; -import common.world.BlockPos; -import common.world.Vec3; import common.world.WorldServer; public class EntityAIMoveThroughVillage extends EntityAIBase diff --git a/common/src/common/ai/EntityAIMoveToBlock.java b/common/src/common/ai/EntityAIMoveToBlock.java index 83f1416..2eb4c0f 100755 --- a/common/src/common/ai/EntityAIMoveToBlock.java +++ b/common/src/common/ai/EntityAIMoveToBlock.java @@ -1,7 +1,7 @@ package common.ai; import common.entity.types.EntityLiving; -import common.world.BlockPos; +import common.util.BlockPos; import common.world.World; public abstract class EntityAIMoveToBlock extends EntityAIBase diff --git a/common/src/common/ai/EntityAIMoveTowardsRestriction.java b/common/src/common/ai/EntityAIMoveTowardsRestriction.java index daf2b9b..5df934d 100755 --- a/common/src/common/ai/EntityAIMoveTowardsRestriction.java +++ b/common/src/common/ai/EntityAIMoveTowardsRestriction.java @@ -1,8 +1,8 @@ package common.ai; import common.entity.types.EntityLiving; -import common.world.BlockPos; -import common.world.Vec3; +import common.util.BlockPos; +import common.util.Vec3; public class EntityAIMoveTowardsRestriction extends EntityAIBase { diff --git a/common/src/common/ai/EntityAIMoveTowardsTarget.java b/common/src/common/ai/EntityAIMoveTowardsTarget.java index eaff1e3..a77254d 100755 --- a/common/src/common/ai/EntityAIMoveTowardsTarget.java +++ b/common/src/common/ai/EntityAIMoveTowardsTarget.java @@ -1,7 +1,7 @@ package common.ai; import common.entity.types.EntityLiving; -import common.world.Vec3; +import common.util.Vec3; public class EntityAIMoveTowardsTarget extends EntityAIBase { diff --git a/common/src/common/ai/EntityAIOcelotSit.java b/common/src/common/ai/EntityAIOcelotSit.java index f6d329d..aa46aa0 100755 --- a/common/src/common/ai/EntityAIOcelotSit.java +++ b/common/src/common/ai/EntityAIOcelotSit.java @@ -6,7 +6,7 @@ import common.entity.animal.EntityOcelot; import common.init.Blocks; import common.tileentity.TileEntity; import common.tileentity.TileEntityChest; -import common.world.BlockPos; +import common.util.BlockPos; import common.world.State; import common.world.World; diff --git a/common/src/common/ai/EntityAIPanic.java b/common/src/common/ai/EntityAIPanic.java index ab28240..7848752 100755 --- a/common/src/common/ai/EntityAIPanic.java +++ b/common/src/common/ai/EntityAIPanic.java @@ -1,7 +1,7 @@ package common.ai; import common.entity.types.EntityLiving; -import common.world.Vec3; +import common.util.Vec3; public class EntityAIPanic extends EntityAIBase { diff --git a/common/src/common/ai/EntityAIPlay.java b/common/src/common/ai/EntityAIPlay.java index 38363e6..f64d219 100755 --- a/common/src/common/ai/EntityAIPlay.java +++ b/common/src/common/ai/EntityAIPlay.java @@ -4,7 +4,7 @@ import java.util.List; import common.entity.npc.EntityNPC; import common.entity.types.EntityLiving; -import common.world.Vec3; +import common.util.Vec3; public class EntityAIPlay extends EntityAIBase { private EntityNPC entity; diff --git a/common/src/common/ai/EntityAIRestrictOpenDoor.java b/common/src/common/ai/EntityAIRestrictOpenDoor.java index c89644b..d7a94c4 100755 --- a/common/src/common/ai/EntityAIRestrictOpenDoor.java +++ b/common/src/common/ai/EntityAIRestrictOpenDoor.java @@ -2,9 +2,9 @@ package common.ai; import common.entity.types.EntityLiving; import common.pathfinding.PathNavigateGround; +import common.util.BlockPos; import common.village.Village; import common.village.VillageDoorInfo; -import common.world.BlockPos; import common.world.WorldServer; public class EntityAIRestrictOpenDoor extends EntityAIBase diff --git a/common/src/common/ai/EntityAIRunAroundLikeCrazy.java b/common/src/common/ai/EntityAIRunAroundLikeCrazy.java index 9b02e75..08680dd 100755 --- a/common/src/common/ai/EntityAIRunAroundLikeCrazy.java +++ b/common/src/common/ai/EntityAIRunAroundLikeCrazy.java @@ -3,7 +3,7 @@ package common.ai; import common.entity.Entity; import common.entity.animal.EntityHorse; import common.entity.npc.EntityNPC; -import common.world.Vec3; +import common.util.Vec3; public class EntityAIRunAroundLikeCrazy extends EntityAIBase { diff --git a/common/src/common/ai/EntityAITakePlace.java b/common/src/common/ai/EntityAITakePlace.java index bde8a0a..e4fc53e 100755 --- a/common/src/common/ai/EntityAITakePlace.java +++ b/common/src/common/ai/EntityAITakePlace.java @@ -11,8 +11,8 @@ import common.init.ItemRegistry; import common.item.ItemStack; import common.material.Material; import common.rng.Random; +import common.util.BlockPos; import common.util.ExtMath; -import common.world.BlockPos; import common.world.State; import common.world.World; diff --git a/common/src/common/ai/EntityAITarget.java b/common/src/common/ai/EntityAITarget.java index 7890657..2c6b33b 100755 --- a/common/src/common/ai/EntityAITarget.java +++ b/common/src/common/ai/EntityAITarget.java @@ -7,8 +7,8 @@ import common.entity.types.IEntityOwnable; import common.init.Config; import common.pathfinding.PathEntity; import common.pathfinding.PathPoint; +import common.util.BlockPos; import common.util.ExtMath; -import common.world.BlockPos; public abstract class EntityAITarget extends EntityAIBase { diff --git a/common/src/common/ai/EntityAIWander.java b/common/src/common/ai/EntityAIWander.java index f1ae22a..79067a6 100755 --- a/common/src/common/ai/EntityAIWander.java +++ b/common/src/common/ai/EntityAIWander.java @@ -1,7 +1,7 @@ package common.ai; import common.entity.types.EntityLiving; -import common.world.Vec3; +import common.util.Vec3; public class EntityAIWander extends EntityAIBase { diff --git a/common/src/common/ai/RandomPositionGenerator.java b/common/src/common/ai/RandomPositionGenerator.java index 74c03ed..54b1bae 100755 --- a/common/src/common/ai/RandomPositionGenerator.java +++ b/common/src/common/ai/RandomPositionGenerator.java @@ -2,9 +2,9 @@ package common.ai; import common.entity.types.EntityLiving; import common.rng.Random; +import common.util.BlockPos; import common.util.ExtMath; -import common.world.BlockPos; -import common.world.Vec3; +import common.util.Vec3; public class RandomPositionGenerator { diff --git a/common/src/common/biome/Biome.java b/common/src/common/biome/Biome.java index cabe35b..bfb66bb 100755 --- a/common/src/common/biome/Biome.java +++ b/common/src/common/biome/Biome.java @@ -32,8 +32,8 @@ import common.material.Material; import common.rng.PerlinGen; import common.rng.Random; import common.rng.WeightedList; +import common.util.BlockPos; import common.util.ExtMath; -import common.world.BlockPos; import common.world.State; import common.world.World; import common.world.WorldServer; diff --git a/common/src/common/biome/BiomeBlackened.java b/common/src/common/biome/BiomeBlackened.java index 082be75..ffe2256 100644 --- a/common/src/common/biome/BiomeBlackened.java +++ b/common/src/common/biome/BiomeBlackened.java @@ -5,7 +5,7 @@ import common.entity.npc.EntityMetalhead; import common.init.Blocks; import common.rng.Random; import common.rng.WeightedList; -import common.world.BlockPos; +import common.util.BlockPos; import common.worldgen.tree.WorldGenBaseTree; import common.worldgen.tree.WorldGenTree; diff --git a/common/src/common/biome/BiomeChaos.java b/common/src/common/biome/BiomeChaos.java index a068043..d2353c7 100755 --- a/common/src/common/biome/BiomeChaos.java +++ b/common/src/common/biome/BiomeChaos.java @@ -6,7 +6,7 @@ import common.init.Blocks; import common.init.EntityRegistry; import common.rng.Random; import common.rng.WeightedList; -import common.world.BlockPos; +import common.util.BlockPos; import common.world.WorldServer; import common.worldgen.FeatureGenerator; import common.worldgen.foliage.WorldGenMushroom; diff --git a/common/src/common/biome/BiomeDesert.java b/common/src/common/biome/BiomeDesert.java index 56da83c..0890481 100755 --- a/common/src/common/biome/BiomeDesert.java +++ b/common/src/common/biome/BiomeDesert.java @@ -3,7 +3,7 @@ package common.biome; import common.init.Blocks; import common.rng.Random; import common.rng.WeightedList; -import common.world.BlockPos; +import common.util.BlockPos; import common.world.WorldServer; import common.worldgen.feature.WorldGenDesertWells; diff --git a/common/src/common/biome/BiomeExterminated.java b/common/src/common/biome/BiomeExterminated.java index 837aaaf..1ca72d5 100755 --- a/common/src/common/biome/BiomeExterminated.java +++ b/common/src/common/biome/BiomeExterminated.java @@ -3,7 +3,7 @@ package common.biome; import common.init.Blocks; import common.rng.Random; import common.rng.WeightedList; -import common.world.BlockPos; +import common.util.BlockPos; import common.world.WorldServer; public class BiomeExterminated extends Biome { diff --git a/common/src/common/biome/BiomeForest.java b/common/src/common/biome/BiomeForest.java index 183668b..9c30b45 100755 --- a/common/src/common/biome/BiomeForest.java +++ b/common/src/common/biome/BiomeForest.java @@ -8,8 +8,8 @@ import common.entity.npc.EntityElf; import common.entity.npc.EntityWoodElf; import common.init.Blocks; import common.rng.Random; +import common.util.BlockPos; import common.util.ExtMath; -import common.world.BlockPos; import common.world.WorldServer; import common.worldgen.foliage.WorldGenBigMushroom; import common.worldgen.tree.WorldGenBaseTree; diff --git a/common/src/common/biome/BiomeHell.java b/common/src/common/biome/BiomeHell.java index 0591795..d19e23c 100755 --- a/common/src/common/biome/BiomeHell.java +++ b/common/src/common/biome/BiomeHell.java @@ -9,7 +9,7 @@ import common.entity.npc.EntityTiefling; import common.init.Blocks; import common.rng.Random; import common.rng.WeightedList; -import common.world.BlockPos; +import common.util.BlockPos; import common.world.WorldServer; import common.worldgen.FeatureOres; import common.worldgen.feature.WorldGenFire; diff --git a/common/src/common/biome/BiomeHills.java b/common/src/common/biome/BiomeHills.java index 125e977..578fcab 100755 --- a/common/src/common/biome/BiomeHills.java +++ b/common/src/common/biome/BiomeHills.java @@ -2,7 +2,7 @@ package common.biome; import common.init.Blocks; import common.rng.Random; -import common.world.BlockPos; +import common.util.BlockPos; import common.world.WorldServer; import common.worldgen.ChunkPrimer; import common.worldgen.FeatureOres; diff --git a/common/src/common/biome/BiomeJungle.java b/common/src/common/biome/BiomeJungle.java index dbbc6d6..09c52dc 100755 --- a/common/src/common/biome/BiomeJungle.java +++ b/common/src/common/biome/BiomeJungle.java @@ -5,7 +5,7 @@ import common.entity.animal.EntityChicken; import common.entity.animal.EntityOcelot; import common.init.Blocks; import common.rng.Random; -import common.world.BlockPos; +import common.util.BlockPos; import common.world.State; import common.world.WorldServer; import common.worldgen.FeatureGenerator; diff --git a/common/src/common/biome/BiomeMesa.java b/common/src/common/biome/BiomeMesa.java index 29c92b7..a42e388 100755 --- a/common/src/common/biome/BiomeMesa.java +++ b/common/src/common/biome/BiomeMesa.java @@ -12,7 +12,7 @@ import common.material.Material; import common.rng.PerlinGen; import common.rng.Random; import common.rng.WeightedList; -import common.world.BlockPos; +import common.util.BlockPos; import common.world.State; import common.world.WorldServer; import common.worldgen.ChunkPrimer; diff --git a/common/src/common/biome/BiomeMoon.java b/common/src/common/biome/BiomeMoon.java index 297eabe..ded8deb 100755 --- a/common/src/common/biome/BiomeMoon.java +++ b/common/src/common/biome/BiomeMoon.java @@ -3,7 +3,7 @@ package common.biome; import common.init.Blocks; import common.rng.Random; import common.rng.WeightedList; -import common.world.BlockPos; +import common.util.BlockPos; import common.world.WorldServer; import common.worldgen.FeatureOres; diff --git a/common/src/common/biome/BiomeMutated.java b/common/src/common/biome/BiomeMutated.java index d0d5f7b..630b885 100755 --- a/common/src/common/biome/BiomeMutated.java +++ b/common/src/common/biome/BiomeMutated.java @@ -2,7 +2,7 @@ package common.biome; import common.rng.Random; import common.rng.WeightedList; -import common.world.BlockPos; +import common.util.BlockPos; import common.world.WorldServer; import common.worldgen.ChunkPrimer; import common.worldgen.tree.WorldGenTree; diff --git a/common/src/common/biome/BiomeNone.java b/common/src/common/biome/BiomeNone.java index 9c84a6f..27b2a97 100755 --- a/common/src/common/biome/BiomeNone.java +++ b/common/src/common/biome/BiomeNone.java @@ -3,7 +3,7 @@ package common.biome; import common.init.Blocks; import common.rng.Random; import common.rng.WeightedList; -import common.world.BlockPos; +import common.util.BlockPos; import common.world.WorldServer; import common.worldgen.ChunkPrimer; diff --git a/common/src/common/biome/BiomePlains.java b/common/src/common/biome/BiomePlains.java index f652fb5..d74d85a 100755 --- a/common/src/common/biome/BiomePlains.java +++ b/common/src/common/biome/BiomePlains.java @@ -4,7 +4,7 @@ import common.block.BlockDoublePlant; import common.block.BlockFlower; import common.entity.animal.EntityHorse; import common.rng.Random; -import common.world.BlockPos; +import common.util.BlockPos; import common.world.WorldServer; public class BiomePlains extends Biome diff --git a/common/src/common/biome/BiomeSavanna.java b/common/src/common/biome/BiomeSavanna.java index aae7642..fe9f069 100755 --- a/common/src/common/biome/BiomeSavanna.java +++ b/common/src/common/biome/BiomeSavanna.java @@ -5,7 +5,7 @@ import common.block.BlockDoublePlant; import common.entity.animal.EntityHorse; import common.init.Blocks; import common.rng.Random; -import common.world.BlockPos; +import common.util.BlockPos; import common.world.WorldServer; import common.worldgen.ChunkPrimer; import common.worldgen.tree.WorldGenSavanna; diff --git a/common/src/common/biome/BiomeSnow.java b/common/src/common/biome/BiomeSnow.java index 5e0e697..695ac5d 100755 --- a/common/src/common/biome/BiomeSnow.java +++ b/common/src/common/biome/BiomeSnow.java @@ -3,7 +3,7 @@ package common.biome; import common.init.Blocks; import common.rng.Random; import common.rng.WeightedList; -import common.world.BlockPos; +import common.util.BlockPos; import common.world.WorldServer; import common.worldgen.feature.WorldGenIcePath; import common.worldgen.feature.WorldGenIceSpike; diff --git a/common/src/common/biome/BiomeSpace.java b/common/src/common/biome/BiomeSpace.java index da3953e..a2ebccb 100755 --- a/common/src/common/biome/BiomeSpace.java +++ b/common/src/common/biome/BiomeSpace.java @@ -4,7 +4,7 @@ import common.block.BlockDirt; import common.init.Blocks; import common.rng.Random; import common.rng.WeightedList; -import common.world.BlockPos; +import common.util.BlockPos; import common.world.WorldServer; import common.worldgen.FeatureGenerator; import common.worldgen.feature.WorldGenAsteroid; diff --git a/common/src/common/biome/BiomeSwamp.java b/common/src/common/biome/BiomeSwamp.java index 41a39a3..b708632 100755 --- a/common/src/common/biome/BiomeSwamp.java +++ b/common/src/common/biome/BiomeSwamp.java @@ -6,8 +6,8 @@ import common.entity.npc.EntitySlime; import common.init.Blocks; import common.material.Material; import common.rng.Random; -import common.world.BlockPos; -import common.world.Facing; +import common.util.BlockPos; +import common.util.Facing; import common.world.WorldServer; import common.worldgen.ChunkPrimer; import common.worldgen.tree.WorldGenTree; diff --git a/common/src/common/biome/BiomeTaiga.java b/common/src/common/biome/BiomeTaiga.java index 2281c1d..5680a75 100755 --- a/common/src/common/biome/BiomeTaiga.java +++ b/common/src/common/biome/BiomeTaiga.java @@ -6,7 +6,7 @@ import common.block.BlockTallGrass; import common.entity.animal.EntityWolf; import common.init.Blocks; import common.rng.Random; -import common.world.BlockPos; +import common.util.BlockPos; import common.world.WorldServer; import common.worldgen.ChunkPrimer; import common.worldgen.FeatureGenerator; diff --git a/common/src/common/biome/BiomeTian.java b/common/src/common/biome/BiomeTian.java index 933eaf3..eae35ef 100755 --- a/common/src/common/biome/BiomeTian.java +++ b/common/src/common/biome/BiomeTian.java @@ -8,7 +8,7 @@ import common.entity.npc.EntityCultivator; import common.init.Blocks; import common.rng.Random; import common.rng.WeightedList; -import common.world.BlockPos; +import common.util.BlockPos; import common.world.WorldServer; import common.worldgen.FeatureGenerator; import common.worldgen.feature.WorldGenSpikes; diff --git a/common/src/common/block/Block.java b/common/src/common/block/Block.java index 92d3ab9..484a05f 100755 --- a/common/src/common/block/Block.java +++ b/common/src/common/block/Block.java @@ -36,20 +36,20 @@ import common.model.Transforms; import common.properties.IProperty; import common.rng.Random; import common.tileentity.TileEntity; +import common.util.BlockPos; +import common.util.BoundingBox; import common.util.ExtMath; -import common.world.BlockPos; -import common.world.BoundingBox; +import common.util.Facing; +import common.util.HitPosition; +import common.util.Vec3; +import common.util.HitPosition.ObjectType; import common.world.Explosion; -import common.world.Facing; -import common.world.HitPosition; import common.world.IBlockAccess; import common.world.IWorldAccess; import common.world.State; -import common.world.Vec3; import common.world.World; import common.world.WorldClient; import common.world.WorldServer; -import common.world.HitPosition.ObjectType; public class Block { diff --git a/common/src/common/block/BlockAir.java b/common/src/common/block/BlockAir.java index f0c60bb..e0a27ff 100755 --- a/common/src/common/block/BlockAir.java +++ b/common/src/common/block/BlockAir.java @@ -1,8 +1,8 @@ package common.block; import common.material.Material; -import common.world.BlockPos; -import common.world.BoundingBox; +import common.util.BlockPos; +import common.util.BoundingBox; import common.world.State; import common.world.World; diff --git a/common/src/common/block/BlockAnvil.java b/common/src/common/block/BlockAnvil.java index f7519e3..6b9406f 100755 --- a/common/src/common/block/BlockAnvil.java +++ b/common/src/common/block/BlockAnvil.java @@ -20,8 +20,8 @@ import common.properties.IProperty; import common.properties.PropertyDirection; import common.properties.PropertyInteger; import common.tileentity.IInteractionObject; -import common.world.BlockPos; -import common.world.Facing; +import common.util.BlockPos; +import common.util.Facing; import common.world.IWorldAccess; import common.world.State; import common.world.World; diff --git a/common/src/common/block/BlockBanner.java b/common/src/common/block/BlockBanner.java index 2994082..b025774 100755 --- a/common/src/common/block/BlockBanner.java +++ b/common/src/common/block/BlockBanner.java @@ -13,9 +13,9 @@ import common.properties.PropertyInteger; import common.rng.Random; import common.tileentity.TileEntity; import common.tileentity.TileEntityBanner; -import common.world.BlockPos; -import common.world.BoundingBox; -import common.world.Facing; +import common.util.BlockPos; +import common.util.BoundingBox; +import common.util.Facing; import common.world.IBlockAccess; import common.world.IWorldAccess; import common.world.State; diff --git a/common/src/common/block/BlockBasePressurePlate.java b/common/src/common/block/BlockBasePressurePlate.java index 339f4c2..d8e1366 100755 --- a/common/src/common/block/BlockBasePressurePlate.java +++ b/common/src/common/block/BlockBasePressurePlate.java @@ -7,9 +7,9 @@ import common.material.Material; import common.model.Model; import common.model.ModelProvider; import common.rng.Random; -import common.world.BlockPos; -import common.world.BoundingBox; -import common.world.Facing; +import common.util.BlockPos; +import common.util.BoundingBox; +import common.util.Facing; import common.world.IBlockAccess; import common.world.IWorldAccess; import common.world.State; diff --git a/common/src/common/block/BlockBeacon.java b/common/src/common/block/BlockBeacon.java index 7ac615b..2032c67 100755 --- a/common/src/common/block/BlockBeacon.java +++ b/common/src/common/block/BlockBeacon.java @@ -8,8 +8,8 @@ import common.model.Model; import common.model.ModelProvider; import common.tileentity.TileEntity; import common.tileentity.TileEntityBeacon; -import common.world.BlockPos; -import common.world.Facing; +import common.util.BlockPos; +import common.util.Facing; import common.world.State; import common.world.World; diff --git a/common/src/common/block/BlockBed.java b/common/src/common/block/BlockBed.java index f602551..02e759e 100755 --- a/common/src/common/block/BlockBed.java +++ b/common/src/common/block/BlockBed.java @@ -13,13 +13,13 @@ import common.model.ModelRotation; import common.properties.IProperty; import common.properties.PropertyEnum; import common.rng.Random; +import common.util.BlockPos; +import common.util.Facing; import common.util.Identifyable; -import common.world.BlockPos; -import common.world.Facing; +import common.util.WorldPos; import common.world.IWorldAccess; import common.world.State; import common.world.World; -import common.world.WorldPos; public class BlockBed extends BlockDirectional { public static enum EnumPartType implements Identifyable { diff --git a/common/src/common/block/BlockBedrock.java b/common/src/common/block/BlockBedrock.java index 78c30f7..0ea00ba 100755 --- a/common/src/common/block/BlockBedrock.java +++ b/common/src/common/block/BlockBedrock.java @@ -3,7 +3,7 @@ package common.block; import common.material.Material; import common.model.ParticleType; import common.rng.Random; -import common.world.BlockPos; +import common.util.BlockPos; import common.world.State; import common.world.WorldClient; diff --git a/common/src/common/block/BlockBlackenedDirt.java b/common/src/common/block/BlockBlackenedDirt.java index e3552c5..ac5909c 100644 --- a/common/src/common/block/BlockBlackenedDirt.java +++ b/common/src/common/block/BlockBlackenedDirt.java @@ -5,7 +5,7 @@ import common.init.Config; import common.item.CheatTab; import common.material.Material; import common.rng.Random; -import common.world.BlockPos; +import common.util.BlockPos; import common.world.State; import common.world.WorldServer; diff --git a/common/src/common/block/BlockBlackenedSoil.java b/common/src/common/block/BlockBlackenedSoil.java index 7918522..a77664e 100644 --- a/common/src/common/block/BlockBlackenedSoil.java +++ b/common/src/common/block/BlockBlackenedSoil.java @@ -8,7 +8,7 @@ import common.material.Material; import common.model.Model; import common.model.ModelProvider; import common.rng.Random; -import common.world.BlockPos; +import common.util.BlockPos; import common.world.State; import common.world.WorldServer; diff --git a/common/src/common/block/BlockBlueShroom.java b/common/src/common/block/BlockBlueShroom.java index 7e9b87c..d0097d9 100755 --- a/common/src/common/block/BlockBlueShroom.java +++ b/common/src/common/block/BlockBlueShroom.java @@ -5,7 +5,7 @@ import common.init.Config; import common.model.Model; import common.model.ModelProvider; import common.rng.Random; -import common.world.BlockPos; +import common.util.BlockPos; import common.world.State; import common.world.World; import common.world.WorldServer; diff --git a/common/src/common/block/BlockBreakable.java b/common/src/common/block/BlockBreakable.java index e60acea..23a1c5d 100755 --- a/common/src/common/block/BlockBreakable.java +++ b/common/src/common/block/BlockBreakable.java @@ -2,8 +2,8 @@ package common.block; import common.init.Blocks; import common.material.Material; -import common.world.BlockPos; -import common.world.Facing; +import common.util.BlockPos; +import common.util.Facing; import common.world.IWorldAccess; import common.world.State; diff --git a/common/src/common/block/BlockBrewingStand.java b/common/src/common/block/BlockBrewingStand.java index 4de9271..beb51cd 100755 --- a/common/src/common/block/BlockBrewingStand.java +++ b/common/src/common/block/BlockBrewingStand.java @@ -20,9 +20,9 @@ import common.properties.PropertyBool; import common.rng.Random; import common.tileentity.TileEntity; import common.tileentity.TileEntityBrewingStand; -import common.world.BlockPos; -import common.world.BoundingBox; -import common.world.Facing; +import common.util.BlockPos; +import common.util.BoundingBox; +import common.util.Facing; import common.world.State; import common.world.World; import common.world.WorldClient; diff --git a/common/src/common/block/BlockBush.java b/common/src/common/block/BlockBush.java index 79b8a13..94ff784 100755 --- a/common/src/common/block/BlockBush.java +++ b/common/src/common/block/BlockBush.java @@ -5,8 +5,8 @@ import common.item.CheatTab; import common.material.Material; import common.model.BlockLayer; import common.rng.Random; -import common.world.BlockPos; -import common.world.BoundingBox; +import common.util.BlockPos; +import common.util.BoundingBox; import common.world.State; import common.world.World; import common.world.WorldServer; diff --git a/common/src/common/block/BlockButton.java b/common/src/common/block/BlockButton.java index ea3415a..4c655c0 100755 --- a/common/src/common/block/BlockButton.java +++ b/common/src/common/block/BlockButton.java @@ -18,9 +18,9 @@ import common.properties.IProperty; import common.properties.PropertyBool; import common.properties.PropertyDirection; import common.rng.Random; -import common.world.BlockPos; -import common.world.BoundingBox; -import common.world.Facing; +import common.util.BlockPos; +import common.util.BoundingBox; +import common.util.Facing; import common.world.IWorldAccess; import common.world.State; import common.world.World; diff --git a/common/src/common/block/BlockCactus.java b/common/src/common/block/BlockCactus.java index 03777da..1ab3926 100755 --- a/common/src/common/block/BlockCactus.java +++ b/common/src/common/block/BlockCactus.java @@ -12,9 +12,9 @@ import common.model.ModelProvider; import common.properties.IProperty; import common.properties.PropertyInteger; import common.rng.Random; -import common.world.BlockPos; -import common.world.BoundingBox; -import common.world.Facing; +import common.util.BlockPos; +import common.util.BoundingBox; +import common.util.Facing; import common.world.State; import common.world.World; import common.world.WorldServer; diff --git a/common/src/common/block/BlockCake.java b/common/src/common/block/BlockCake.java index 4a62734..6422758 100755 --- a/common/src/common/block/BlockCake.java +++ b/common/src/common/block/BlockCake.java @@ -10,9 +10,9 @@ import common.model.ModelProvider; import common.properties.IProperty; import common.properties.PropertyInteger; import common.rng.Random; -import common.world.BlockPos; -import common.world.BoundingBox; -import common.world.Facing; +import common.util.BlockPos; +import common.util.BoundingBox; +import common.util.Facing; import common.world.IWorldAccess; import common.world.State; import common.world.World; diff --git a/common/src/common/block/BlockCarpet.java b/common/src/common/block/BlockCarpet.java index 8a93ae1..9b9a970 100755 --- a/common/src/common/block/BlockCarpet.java +++ b/common/src/common/block/BlockCarpet.java @@ -12,8 +12,8 @@ import common.model.ModelProvider; import common.model.Transforms; import common.properties.IProperty; import common.properties.PropertyEnum; -import common.world.BlockPos; -import common.world.Facing; +import common.util.BlockPos; +import common.util.Facing; import common.world.IWorldAccess; import common.world.State; import common.world.World; diff --git a/common/src/common/block/BlockCauldron.java b/common/src/common/block/BlockCauldron.java index 5ed3371..79f5739 100755 --- a/common/src/common/block/BlockCauldron.java +++ b/common/src/common/block/BlockCauldron.java @@ -19,10 +19,10 @@ import common.properties.IProperty; import common.properties.PropertyInteger; import common.rng.Random; import common.tileentity.TileEntityBanner; +import common.util.BlockPos; +import common.util.BoundingBox; import common.util.ExtMath; -import common.world.BlockPos; -import common.world.BoundingBox; -import common.world.Facing; +import common.util.Facing; import common.world.State; import common.world.World; diff --git a/common/src/common/block/BlockChest.java b/common/src/common/block/BlockChest.java index 92d3821..99af70f 100755 --- a/common/src/common/block/BlockChest.java +++ b/common/src/common/block/BlockChest.java @@ -22,10 +22,10 @@ import common.tileentity.ILockableContainer; import common.tileentity.LockCode; import common.tileentity.TileEntity; import common.tileentity.TileEntityChest; +import common.util.BlockPos; +import common.util.BoundingBox; import common.util.ExtMath; -import common.world.BlockPos; -import common.world.BoundingBox; -import common.world.Facing; +import common.util.Facing; import common.world.IWorldAccess; import common.world.State; import common.world.World; diff --git a/common/src/common/block/BlockCocoa.java b/common/src/common/block/BlockCocoa.java index baad0fa..2d5cff9 100755 --- a/common/src/common/block/BlockCocoa.java +++ b/common/src/common/block/BlockCocoa.java @@ -15,9 +15,9 @@ import common.model.ModelRotation; import common.properties.IProperty; import common.properties.PropertyInteger; import common.rng.Random; -import common.world.BlockPos; -import common.world.BoundingBox; -import common.world.Facing; +import common.util.BlockPos; +import common.util.BoundingBox; +import common.util.Facing; import common.world.IWorldAccess; import common.world.State; import common.world.World; diff --git a/common/src/common/block/BlockCompressedPowered.java b/common/src/common/block/BlockCompressedPowered.java index f78ab13..4168977 100755 --- a/common/src/common/block/BlockCompressedPowered.java +++ b/common/src/common/block/BlockCompressedPowered.java @@ -1,8 +1,8 @@ package common.block; import common.material.Material; -import common.world.BlockPos; -import common.world.Facing; +import common.util.BlockPos; +import common.util.Facing; import common.world.IWorldAccess; import common.world.State; diff --git a/common/src/common/block/BlockContainer.java b/common/src/common/block/BlockContainer.java index 84bec0f..8443549 100755 --- a/common/src/common/block/BlockContainer.java +++ b/common/src/common/block/BlockContainer.java @@ -2,8 +2,8 @@ package common.block; import common.material.Material; import common.tileentity.TileEntity; -import common.world.BlockPos; -import common.world.Facing; +import common.util.BlockPos; +import common.util.Facing; import common.world.State; import common.world.World; import common.world.WorldServer; diff --git a/common/src/common/block/BlockCore.java b/common/src/common/block/BlockCore.java index b125c14..68bf08a 100755 --- a/common/src/common/block/BlockCore.java +++ b/common/src/common/block/BlockCore.java @@ -3,7 +3,7 @@ package common.block; import common.init.Config; import common.item.CheatTab; import common.material.Material; -import common.world.BlockPos; +import common.util.BlockPos; import common.world.State; import common.world.WorldServer; diff --git a/common/src/common/block/BlockCrops.java b/common/src/common/block/BlockCrops.java index 979ebaf..a67fb61 100755 --- a/common/src/common/block/BlockCrops.java +++ b/common/src/common/block/BlockCrops.java @@ -11,7 +11,7 @@ import common.model.ModelProvider; import common.properties.IProperty; import common.properties.PropertyInteger; import common.rng.Random; -import common.world.BlockPos; +import common.util.BlockPos; import common.world.State; import common.world.World; import common.world.WorldServer; diff --git a/common/src/common/block/BlockDaylightDetector.java b/common/src/common/block/BlockDaylightDetector.java index 8e0a6f9..9e3110a 100755 --- a/common/src/common/block/BlockDaylightDetector.java +++ b/common/src/common/block/BlockDaylightDetector.java @@ -17,9 +17,9 @@ import common.properties.PropertyInteger; import common.rng.Random; import common.tileentity.TileEntity; import common.tileentity.TileEntityDaylightDetector; +import common.util.BlockPos; import common.util.ExtMath; -import common.world.BlockPos; -import common.world.Facing; +import common.util.Facing; import common.world.IWorldAccess; import common.world.LightType; import common.world.State; diff --git a/common/src/common/block/BlockDeadBush.java b/common/src/common/block/BlockDeadBush.java index f81d79b..3e091db 100755 --- a/common/src/common/block/BlockDeadBush.java +++ b/common/src/common/block/BlockDeadBush.java @@ -11,7 +11,7 @@ import common.model.Model; import common.model.ModelProvider; import common.rng.Random; import common.tileentity.TileEntity; -import common.world.BlockPos; +import common.util.BlockPos; import common.world.State; import common.world.World; diff --git a/common/src/common/block/BlockDirectional.java b/common/src/common/block/BlockDirectional.java index 79113df..b80351a 100755 --- a/common/src/common/block/BlockDirectional.java +++ b/common/src/common/block/BlockDirectional.java @@ -2,7 +2,7 @@ package common.block; import common.material.Material; import common.properties.PropertyDirection; -import common.world.Facing; +import common.util.Facing; public abstract class BlockDirectional extends Block { diff --git a/common/src/common/block/BlockDirt.java b/common/src/common/block/BlockDirt.java index ab9f792..11e24ab 100755 --- a/common/src/common/block/BlockDirt.java +++ b/common/src/common/block/BlockDirt.java @@ -12,8 +12,8 @@ import common.model.ModelProvider; import common.properties.IProperty; import common.properties.PropertyBool; import common.properties.PropertyEnum; +import common.util.BlockPos; import common.util.Identifyable; -import common.world.BlockPos; import common.world.IWorldAccess; import common.world.State; import common.world.World; diff --git a/common/src/common/block/BlockDispenser.java b/common/src/common/block/BlockDispenser.java index 4c693c8..6f0fd6c 100755 --- a/common/src/common/block/BlockDispenser.java +++ b/common/src/common/block/BlockDispenser.java @@ -24,8 +24,8 @@ import common.properties.PropertyDirection; import common.rng.Random; import common.tileentity.TileEntity; import common.tileentity.TileEntityDispenser; -import common.world.BlockPos; -import common.world.Facing; +import common.util.BlockPos; +import common.util.Facing; import common.world.State; import common.world.World; import common.world.WorldServer; diff --git a/common/src/common/block/BlockDoor.java b/common/src/common/block/BlockDoor.java index d0fa735..8388100 100755 --- a/common/src/common/block/BlockDoor.java +++ b/common/src/common/block/BlockDoor.java @@ -17,15 +17,15 @@ import common.properties.PropertyBool; import common.properties.PropertyDirection; import common.properties.PropertyEnum; import common.rng.Random; +import common.util.BlockPos; +import common.util.BoundingBox; +import common.util.Facing; +import common.util.HitPosition; import common.util.Identifyable; -import common.world.BlockPos; -import common.world.BoundingBox; -import common.world.Facing; -import common.world.HitPosition; +import common.util.Vec3; import common.world.IBlockAccess; import common.world.IWorldAccess; import common.world.State; -import common.world.Vec3; import common.world.World; public class BlockDoor extends Block diff --git a/common/src/common/block/BlockDoublePlant.java b/common/src/common/block/BlockDoublePlant.java index a580050..3164ea6 100755 --- a/common/src/common/block/BlockDoublePlant.java +++ b/common/src/common/block/BlockDoublePlant.java @@ -20,14 +20,14 @@ import common.properties.IProperty; import common.properties.PropertyEnum; import common.rng.Random; import common.tileentity.TileEntity; +import common.util.BlockPos; +import common.util.Facing; import common.util.Identifyable; -import common.world.BlockPos; -import common.world.Facing; +import common.util.Facing.Axis; import common.world.IWorldAccess; import common.world.State; import common.world.World; import common.world.WorldServer; -import common.world.Facing.Axis; public class BlockDoublePlant extends BlockBush implements IGrowable { diff --git a/common/src/common/block/BlockDragonEgg.java b/common/src/common/block/BlockDragonEgg.java index ef360b2..15dc5e2 100755 --- a/common/src/common/block/BlockDragonEgg.java +++ b/common/src/common/block/BlockDragonEgg.java @@ -8,8 +8,8 @@ import common.model.Model; import common.model.ModelProvider; import common.model.ParticleType; import common.rng.Random; -import common.world.BlockPos; -import common.world.Facing; +import common.util.BlockPos; +import common.util.Facing; import common.world.IWorldAccess; import common.world.State; import common.world.World; diff --git a/common/src/common/block/BlockDropper.java b/common/src/common/block/BlockDropper.java index b939e09..ec42106 100755 --- a/common/src/common/block/BlockDropper.java +++ b/common/src/common/block/BlockDropper.java @@ -8,8 +8,8 @@ import common.tileentity.TileEntity; import common.tileentity.TileEntityDispenser; import common.tileentity.TileEntityDropper; import common.tileentity.TileEntityHopper; -import common.world.BlockPos; -import common.world.Facing; +import common.util.BlockPos; +import common.util.Facing; import common.world.World; public class BlockDropper extends BlockDispenser diff --git a/common/src/common/block/BlockDynamicLiquid.java b/common/src/common/block/BlockDynamicLiquid.java index df8128b..48534b4 100755 --- a/common/src/common/block/BlockDynamicLiquid.java +++ b/common/src/common/block/BlockDynamicLiquid.java @@ -7,8 +7,8 @@ import common.init.Blocks; import common.init.Config; import common.material.Material; import common.rng.Random; -import common.world.BlockPos; -import common.world.Facing; +import common.util.BlockPos; +import common.util.Facing; import common.world.State; import common.world.World; import common.world.WorldServer; diff --git a/common/src/common/block/BlockEnchantmentTable.java b/common/src/common/block/BlockEnchantmentTable.java index d33874e..4dfc2d3 100755 --- a/common/src/common/block/BlockEnchantmentTable.java +++ b/common/src/common/block/BlockEnchantmentTable.java @@ -12,8 +12,8 @@ import common.model.ParticleType; import common.rng.Random; import common.tileentity.TileEntity; import common.tileentity.TileEntityEnchantmentTable; -import common.world.BlockPos; -import common.world.Facing; +import common.util.BlockPos; +import common.util.Facing; import common.world.State; import common.world.World; import common.world.WorldClient; diff --git a/common/src/common/block/BlockEventData.java b/common/src/common/block/BlockEventData.java index 5df52e1..e8fdcf4 100755 --- a/common/src/common/block/BlockEventData.java +++ b/common/src/common/block/BlockEventData.java @@ -1,6 +1,6 @@ package common.block; -import common.world.BlockPos; +import common.util.BlockPos; public class BlockEventData { diff --git a/common/src/common/block/BlockFalling.java b/common/src/common/block/BlockFalling.java index c80b15c..6ce696b 100755 --- a/common/src/common/block/BlockFalling.java +++ b/common/src/common/block/BlockFalling.java @@ -6,7 +6,7 @@ import common.init.Config; import common.item.CheatTab; import common.material.Material; import common.rng.Random; -import common.world.BlockPos; +import common.util.BlockPos; import common.world.State; import common.world.World; import common.world.WorldServer; diff --git a/common/src/common/block/BlockFarmland.java b/common/src/common/block/BlockFarmland.java index 38f6359..66cf24a 100755 --- a/common/src/common/block/BlockFarmland.java +++ b/common/src/common/block/BlockFarmland.java @@ -12,9 +12,9 @@ import common.model.ModelProvider; import common.properties.IProperty; import common.properties.PropertyInteger; import common.rng.Random; -import common.world.BlockPos; -import common.world.BoundingBox; -import common.world.Facing; +import common.util.BlockPos; +import common.util.BoundingBox; +import common.util.Facing; import common.world.IWorldAccess; import common.world.State; import common.world.World; diff --git a/common/src/common/block/BlockFence.java b/common/src/common/block/BlockFence.java index 37ad1a4..3bd2657 100755 --- a/common/src/common/block/BlockFence.java +++ b/common/src/common/block/BlockFence.java @@ -14,9 +14,9 @@ import common.model.ModelRotation; import common.model.Transforms; import common.properties.IProperty; import common.properties.PropertyBool; -import common.world.BlockPos; -import common.world.BoundingBox; -import common.world.Facing; +import common.util.BlockPos; +import common.util.BoundingBox; +import common.util.Facing; import common.world.IBlockAccess; import common.world.IWorldAccess; import common.world.State; diff --git a/common/src/common/block/BlockFenceGate.java b/common/src/common/block/BlockFenceGate.java index fbf6658..93421f8 100755 --- a/common/src/common/block/BlockFenceGate.java +++ b/common/src/common/block/BlockFenceGate.java @@ -12,9 +12,9 @@ import common.model.ModelRotation; import common.model.Transforms; import common.properties.IProperty; import common.properties.PropertyBool; -import common.world.BlockPos; -import common.world.BoundingBox; -import common.world.Facing; +import common.util.BlockPos; +import common.util.BoundingBox; +import common.util.Facing; import common.world.IBlockAccess; import common.world.IWorldAccess; import common.world.State; diff --git a/common/src/common/block/BlockFire.java b/common/src/common/block/BlockFire.java index 18a13bb..b2afa60 100755 --- a/common/src/common/block/BlockFire.java +++ b/common/src/common/block/BlockFire.java @@ -16,9 +16,9 @@ import common.properties.IProperty; import common.properties.PropertyBool; import common.properties.PropertyInteger; import common.rng.Random; -import common.world.BlockPos; -import common.world.BoundingBox; -import common.world.Facing; +import common.util.BlockPos; +import common.util.BoundingBox; +import common.util.Facing; import common.world.IBlockAccess; import common.world.IWorldAccess; import common.world.State; diff --git a/common/src/common/block/BlockFloorPortal.java b/common/src/common/block/BlockFloorPortal.java index 347e4e1..18b87df 100755 --- a/common/src/common/block/BlockFloorPortal.java +++ b/common/src/common/block/BlockFloorPortal.java @@ -12,9 +12,9 @@ import common.model.Model; import common.model.ModelProvider; import common.model.ParticleType; import common.rng.Random; -import common.world.BlockPos; -import common.world.BoundingBox; -import common.world.Facing; +import common.util.BlockPos; +import common.util.BoundingBox; +import common.util.Facing; import common.world.IWorldAccess; import common.world.State; import common.world.World; diff --git a/common/src/common/block/BlockFlower.java b/common/src/common/block/BlockFlower.java index 3ce19a9..dcdebbb 100755 --- a/common/src/common/block/BlockFlower.java +++ b/common/src/common/block/BlockFlower.java @@ -16,8 +16,8 @@ import common.model.ModelProvider; import common.properties.IProperty; import common.properties.PropertyEnum; import common.rng.Random; +import common.util.BlockPos; import common.util.Identifyable; -import common.world.BlockPos; import common.world.State; import common.world.WorldServer; diff --git a/common/src/common/block/BlockFlowerPot.java b/common/src/common/block/BlockFlowerPot.java index 133ea9f..da6046a 100755 --- a/common/src/common/block/BlockFlowerPot.java +++ b/common/src/common/block/BlockFlowerPot.java @@ -14,8 +14,8 @@ import common.model.ModelProvider; import common.properties.IProperty; import common.properties.PropertyInteger; import common.rng.Random; -import common.world.BlockPos; -import common.world.Facing; +import common.util.BlockPos; +import common.util.Facing; import common.world.State; import common.world.World; import common.world.WorldServer; diff --git a/common/src/common/block/BlockFurnace.java b/common/src/common/block/BlockFurnace.java index 8e225cd..8d4572d 100755 --- a/common/src/common/block/BlockFurnace.java +++ b/common/src/common/block/BlockFurnace.java @@ -18,8 +18,8 @@ import common.properties.PropertyDirection; import common.rng.Random; import common.tileentity.TileEntity; import common.tileentity.TileEntityFurnace; -import common.world.BlockPos; -import common.world.Facing; +import common.util.BlockPos; +import common.util.Facing; import common.world.State; import common.world.World; import common.world.WorldClient; diff --git a/common/src/common/block/BlockGrass.java b/common/src/common/block/BlockGrass.java index 95a32d1..dbf04d5 100755 --- a/common/src/common/block/BlockGrass.java +++ b/common/src/common/block/BlockGrass.java @@ -12,7 +12,7 @@ import common.model.ModelProvider; import common.properties.IProperty; import common.properties.PropertyBool; import common.rng.Random; -import common.world.BlockPos; +import common.util.BlockPos; import common.world.IWorldAccess; import common.world.State; import common.world.World; diff --git a/common/src/common/block/BlockHay.java b/common/src/common/block/BlockHay.java index c48465c..a051aa5 100755 --- a/common/src/common/block/BlockHay.java +++ b/common/src/common/block/BlockHay.java @@ -6,8 +6,8 @@ import common.item.CheatTab; import common.item.ItemStack; import common.material.Material; import common.properties.IProperty; -import common.world.BlockPos; -import common.world.Facing; +import common.util.BlockPos; +import common.util.Facing; import common.world.State; import common.world.World; diff --git a/common/src/common/block/BlockHopper.java b/common/src/common/block/BlockHopper.java index 489f8f6..70438d2 100755 --- a/common/src/common/block/BlockHopper.java +++ b/common/src/common/block/BlockHopper.java @@ -20,9 +20,9 @@ import common.properties.PropertyBool; import common.properties.PropertyDirection; import common.tileentity.TileEntity; import common.tileentity.TileEntityHopper; -import common.world.BlockPos; -import common.world.BoundingBox; -import common.world.Facing; +import common.util.BlockPos; +import common.util.BoundingBox; +import common.util.Facing; import common.world.IWorldAccess; import common.world.State; import common.world.World; diff --git a/common/src/common/block/BlockHugeMushroom.java b/common/src/common/block/BlockHugeMushroom.java index 6493036..f4d6262 100755 --- a/common/src/common/block/BlockHugeMushroom.java +++ b/common/src/common/block/BlockHugeMushroom.java @@ -9,9 +9,9 @@ import common.model.ModelProvider; import common.properties.IProperty; import common.properties.PropertyEnum; import common.rng.Random; +import common.util.BlockPos; +import common.util.Facing; import common.util.Identifyable; -import common.world.BlockPos; -import common.world.Facing; import common.world.State; import common.world.World; diff --git a/common/src/common/block/BlockIce.java b/common/src/common/block/BlockIce.java index 1adca24..fae0c6c 100755 --- a/common/src/common/block/BlockIce.java +++ b/common/src/common/block/BlockIce.java @@ -10,7 +10,7 @@ import common.material.Material; import common.model.BlockLayer; import common.rng.Random; import common.tileentity.TileEntity; -import common.world.BlockPos; +import common.util.BlockPos; import common.world.LightType; import common.world.State; import common.world.World; diff --git a/common/src/common/block/BlockJukebox.java b/common/src/common/block/BlockJukebox.java index f37d8b2..87f2fce 100755 --- a/common/src/common/block/BlockJukebox.java +++ b/common/src/common/block/BlockJukebox.java @@ -6,8 +6,8 @@ import common.item.CheatTab; import common.material.Material; import common.model.Model; import common.model.ModelProvider; -import common.world.BlockPos; -import common.world.Facing; +import common.util.BlockPos; +import common.util.Facing; import common.world.State; import common.world.World; diff --git a/common/src/common/block/BlockLadder.java b/common/src/common/block/BlockLadder.java index f22b33f..ee9d14a 100755 --- a/common/src/common/block/BlockLadder.java +++ b/common/src/common/block/BlockLadder.java @@ -9,9 +9,9 @@ import common.model.ModelProvider; import common.model.ModelRotation; import common.properties.IProperty; import common.properties.PropertyDirection; -import common.world.BlockPos; -import common.world.BoundingBox; -import common.world.Facing; +import common.util.BlockPos; +import common.util.BoundingBox; +import common.util.Facing; import common.world.IWorldAccess; import common.world.State; import common.world.World; diff --git a/common/src/common/block/BlockLeaves.java b/common/src/common/block/BlockLeaves.java index e5f2d51..bfe3d39 100755 --- a/common/src/common/block/BlockLeaves.java +++ b/common/src/common/block/BlockLeaves.java @@ -22,7 +22,7 @@ import common.properties.PropertyBool; import common.properties.PropertyEnum; import common.rng.Random; import common.tileentity.TileEntity; -import common.world.BlockPos; +import common.util.BlockPos; import common.world.IWorldAccess; import common.world.State; import common.world.World; diff --git a/common/src/common/block/BlockLever.java b/common/src/common/block/BlockLever.java index 6766b57..a48cb6d 100755 --- a/common/src/common/block/BlockLever.java +++ b/common/src/common/block/BlockLever.java @@ -11,10 +11,10 @@ import common.model.ModelRotation; import common.properties.IProperty; import common.properties.PropertyBool; import common.properties.PropertyEnum; +import common.util.BlockPos; +import common.util.BoundingBox; +import common.util.Facing; import common.util.Identifyable; -import common.world.BlockPos; -import common.world.BoundingBox; -import common.world.Facing; import common.world.IWorldAccess; import common.world.State; import common.world.World; diff --git a/common/src/common/block/BlockLilyPad.java b/common/src/common/block/BlockLilyPad.java index a117b36..25e614d 100755 --- a/common/src/common/block/BlockLilyPad.java +++ b/common/src/common/block/BlockLilyPad.java @@ -11,9 +11,9 @@ import common.model.Model; import common.model.ModelProvider; import common.model.ModelRotation; import common.properties.IProperty; -import common.world.BlockPos; -import common.world.BoundingBox; -import common.world.Facing; +import common.util.BlockPos; +import common.util.BoundingBox; +import common.util.Facing; import common.world.IWorldAccess; import common.world.State; import common.world.World; diff --git a/common/src/common/block/BlockLiquid.java b/common/src/common/block/BlockLiquid.java index 570baaa..ef20f41 100755 --- a/common/src/common/block/BlockLiquid.java +++ b/common/src/common/block/BlockLiquid.java @@ -13,14 +13,14 @@ import common.model.ParticleType; import common.properties.IProperty; import common.properties.PropertyInteger; import common.rng.Random; +import common.util.BlockPos; +import common.util.BoundingBox; import common.util.ExtMath; -import common.world.BlockPos; -import common.world.BoundingBox; -import common.world.Facing; +import common.util.Facing; +import common.util.Vec3; import common.world.IBlockAccess; import common.world.IWorldAccess; import common.world.State; -import common.world.Vec3; import common.world.World; import common.world.WorldClient; import common.world.WorldServer; diff --git a/common/src/common/block/BlockLog.java b/common/src/common/block/BlockLog.java index 9162608..234583e 100755 --- a/common/src/common/block/BlockLog.java +++ b/common/src/common/block/BlockLog.java @@ -8,9 +8,9 @@ import common.model.ModelProvider; import common.model.ModelRotation; import common.properties.IProperty; import common.properties.PropertyEnum; +import common.util.BlockPos; +import common.util.Facing; import common.util.Identifyable; -import common.world.BlockPos; -import common.world.Facing; import common.world.State; import common.world.World; import common.world.WorldServer; diff --git a/common/src/common/block/BlockMachine.java b/common/src/common/block/BlockMachine.java index efe8555..d65db95 100755 --- a/common/src/common/block/BlockMachine.java +++ b/common/src/common/block/BlockMachine.java @@ -9,8 +9,8 @@ import common.material.Material; import common.properties.IProperty; import common.tileentity.TileEntity; import common.tileentity.TileEntityMachine; -import common.world.BlockPos; -import common.world.Facing; +import common.util.BlockPos; +import common.util.Facing; import common.world.State; import common.world.World; import common.world.WorldServer; diff --git a/common/src/common/block/BlockMobSpawner.java b/common/src/common/block/BlockMobSpawner.java index 9263baa..e8d4f46 100755 --- a/common/src/common/block/BlockMobSpawner.java +++ b/common/src/common/block/BlockMobSpawner.java @@ -7,7 +7,7 @@ import common.model.BlockLayer; import common.rng.Random; import common.tileentity.TileEntity; import common.tileentity.TileEntityMobSpawner; -import common.world.BlockPos; +import common.util.BlockPos; import common.world.State; import common.world.World; diff --git a/common/src/common/block/BlockMushroom.java b/common/src/common/block/BlockMushroom.java index a69d71a..3e45fab 100755 --- a/common/src/common/block/BlockMushroom.java +++ b/common/src/common/block/BlockMushroom.java @@ -5,7 +5,7 @@ import common.init.Config; import common.model.Model; import common.model.ModelProvider; import common.rng.Random; -import common.world.BlockPos; +import common.util.BlockPos; import common.world.State; import common.world.World; import common.world.WorldServer; diff --git a/common/src/common/block/BlockMycelium.java b/common/src/common/block/BlockMycelium.java index 38fed42..a883235 100755 --- a/common/src/common/block/BlockMycelium.java +++ b/common/src/common/block/BlockMycelium.java @@ -11,7 +11,7 @@ import common.model.ParticleType; import common.properties.IProperty; import common.properties.PropertyBool; import common.rng.Random; -import common.world.BlockPos; +import common.util.BlockPos; import common.world.IWorldAccess; import common.world.State; import common.world.WorldClient; diff --git a/common/src/common/block/BlockNote.java b/common/src/common/block/BlockNote.java index 9a548f9..d1711a0 100755 --- a/common/src/common/block/BlockNote.java +++ b/common/src/common/block/BlockNote.java @@ -7,8 +7,8 @@ import common.material.Material; import common.model.ParticleType; import common.tileentity.TileEntity; import common.tileentity.TileEntityNote; -import common.world.BlockPos; -import common.world.Facing; +import common.util.BlockPos; +import common.util.Facing; import common.world.State; import common.world.World; diff --git a/common/src/common/block/BlockNuke.java b/common/src/common/block/BlockNuke.java index e993151..70e4c0e 100755 --- a/common/src/common/block/BlockNuke.java +++ b/common/src/common/block/BlockNuke.java @@ -7,7 +7,7 @@ import common.item.CheatTab; import common.material.Material; import common.model.Model; import common.model.ModelProvider; -import common.world.BlockPos; +import common.util.BlockPos; import common.world.Explosion; import common.world.State; import common.world.World; diff --git a/common/src/common/block/BlockOre.java b/common/src/common/block/BlockOre.java index 008fdf9..e83b028 100755 --- a/common/src/common/block/BlockOre.java +++ b/common/src/common/block/BlockOre.java @@ -7,7 +7,7 @@ import common.item.Item; import common.item.ItemStack; import common.material.Material; import common.rng.Random; -import common.world.BlockPos; +import common.util.BlockPos; import common.world.State; import common.world.World; diff --git a/common/src/common/block/BlockPane.java b/common/src/common/block/BlockPane.java index 66db2be..5de8821 100755 --- a/common/src/common/block/BlockPane.java +++ b/common/src/common/block/BlockPane.java @@ -14,9 +14,9 @@ import common.model.ModelRotation; import common.properties.IProperty; import common.properties.PropertyBool; import common.rng.Random; -import common.world.BlockPos; -import common.world.BoundingBox; -import common.world.Facing; +import common.util.BlockPos; +import common.util.BoundingBox; +import common.util.Facing; import common.world.IWorldAccess; import common.world.State; import common.world.World; diff --git a/common/src/common/block/BlockPistonBase.java b/common/src/common/block/BlockPistonBase.java index 3304a32..5fe919c 100755 --- a/common/src/common/block/BlockPistonBase.java +++ b/common/src/common/block/BlockPistonBase.java @@ -19,10 +19,10 @@ import common.properties.PropertyBool; import common.properties.PropertyDirection; import common.tileentity.TileEntity; import common.tileentity.TileEntityPiston; +import common.util.BlockPos; +import common.util.BoundingBox; import common.util.ExtMath; -import common.world.BlockPos; -import common.world.BoundingBox; -import common.world.Facing; +import common.util.Facing; import common.world.IWorldAccess; import common.world.State; import common.world.World; diff --git a/common/src/common/block/BlockPistonHead.java b/common/src/common/block/BlockPistonHead.java index 3c8870b..07c783e 100755 --- a/common/src/common/block/BlockPistonHead.java +++ b/common/src/common/block/BlockPistonHead.java @@ -15,10 +15,10 @@ import common.properties.PropertyBool; import common.properties.PropertyDirection; import common.properties.PropertyEnum; import common.rng.Random; +import common.util.BlockPos; +import common.util.BoundingBox; +import common.util.Facing; import common.util.Identifyable; -import common.world.BlockPos; -import common.world.BoundingBox; -import common.world.Facing; import common.world.IWorldAccess; import common.world.State; import common.world.World; diff --git a/common/src/common/block/BlockPistonMoving.java b/common/src/common/block/BlockPistonMoving.java index bf0792a..50fddc2 100755 --- a/common/src/common/block/BlockPistonMoving.java +++ b/common/src/common/block/BlockPistonMoving.java @@ -10,13 +10,13 @@ import common.properties.PropertyEnum; import common.rng.Random; import common.tileentity.TileEntity; import common.tileentity.TileEntityPiston; -import common.world.BlockPos; -import common.world.BoundingBox; -import common.world.Facing; -import common.world.HitPosition; +import common.util.BlockPos; +import common.util.BoundingBox; +import common.util.Facing; +import common.util.HitPosition; +import common.util.Vec3; import common.world.IWorldAccess; import common.world.State; -import common.world.Vec3; import common.world.World; import common.world.WorldServer; diff --git a/common/src/common/block/BlockPortal.java b/common/src/common/block/BlockPortal.java index 679cdfc..14112ba 100755 --- a/common/src/common/block/BlockPortal.java +++ b/common/src/common/block/BlockPortal.java @@ -14,14 +14,14 @@ import common.properties.IProperty; import common.properties.PropertyEnum; import common.properties.PropertyInteger; import common.rng.Random; -import common.world.BlockPos; -import common.world.BoundingBox; -import common.world.Facing; +import common.util.BlockPos; +import common.util.BoundingBox; +import common.util.Facing; +import common.util.Facing.Axis; import common.world.IWorldAccess; import common.world.State; import common.world.World; import common.world.WorldClient; -import common.world.Facing.Axis; public class BlockPortal extends BlockBreakable { diff --git a/common/src/common/block/BlockPortalFrame.java b/common/src/common/block/BlockPortalFrame.java index c3dbab6..2f2d61e 100755 --- a/common/src/common/block/BlockPortalFrame.java +++ b/common/src/common/block/BlockPortalFrame.java @@ -19,9 +19,9 @@ import common.properties.PropertyBool; import common.properties.PropertyDirection; import common.rng.Random; import common.tileentity.TileEntity; -import common.world.BlockPos; -import common.world.BoundingBox; -import common.world.Facing; +import common.util.BlockPos; +import common.util.BoundingBox; +import common.util.Facing; import common.world.State; import common.world.World; diff --git a/common/src/common/block/BlockPotato.java b/common/src/common/block/BlockPotato.java index d1b2e33..bc74922 100755 --- a/common/src/common/block/BlockPotato.java +++ b/common/src/common/block/BlockPotato.java @@ -5,7 +5,7 @@ import common.item.Item; import common.item.ItemStack; import common.model.Model; import common.model.ModelProvider; -import common.world.BlockPos; +import common.util.BlockPos; import common.world.State; import common.world.World; diff --git a/common/src/common/block/BlockPressurePlate.java b/common/src/common/block/BlockPressurePlate.java index cd29000..3efdea7 100755 --- a/common/src/common/block/BlockPressurePlate.java +++ b/common/src/common/block/BlockPressurePlate.java @@ -7,8 +7,8 @@ import common.entity.types.EntityLiving; import common.material.Material; import common.properties.IProperty; import common.properties.PropertyBool; -import common.world.BlockPos; -import common.world.BoundingBox; +import common.util.BlockPos; +import common.util.BoundingBox; import common.world.State; import common.world.World; diff --git a/common/src/common/block/BlockPressurePlateWeighted.java b/common/src/common/block/BlockPressurePlateWeighted.java index 2468a10..be01b35 100755 --- a/common/src/common/block/BlockPressurePlateWeighted.java +++ b/common/src/common/block/BlockPressurePlateWeighted.java @@ -4,8 +4,8 @@ import common.entity.Entity; import common.material.Material; import common.properties.IProperty; import common.properties.PropertyInteger; +import common.util.BlockPos; import common.util.ExtMath; -import common.world.BlockPos; import common.world.State; import common.world.World; diff --git a/common/src/common/block/BlockPumpkin.java b/common/src/common/block/BlockPumpkin.java index 8cc3b9d..caf602a 100755 --- a/common/src/common/block/BlockPumpkin.java +++ b/common/src/common/block/BlockPumpkin.java @@ -7,8 +7,8 @@ import common.model.Model; import common.model.ModelProvider; import common.model.ModelRotation; import common.properties.IProperty; -import common.world.BlockPos; -import common.world.Facing; +import common.util.BlockPos; +import common.util.Facing; import common.world.State; import common.world.World; diff --git a/common/src/common/block/BlockQuartz.java b/common/src/common/block/BlockQuartz.java index a6cccc3..d8e6619 100755 --- a/common/src/common/block/BlockQuartz.java +++ b/common/src/common/block/BlockQuartz.java @@ -13,9 +13,9 @@ import common.model.ModelProvider; import common.model.ModelRotation; import common.properties.IProperty; import common.properties.PropertyEnum; +import common.util.BlockPos; +import common.util.Facing; import common.util.Identifyable; -import common.world.BlockPos; -import common.world.Facing; import common.world.State; import common.world.World; diff --git a/common/src/common/block/BlockRail.java b/common/src/common/block/BlockRail.java index 6b50f52..db02ca7 100755 --- a/common/src/common/block/BlockRail.java +++ b/common/src/common/block/BlockRail.java @@ -2,7 +2,7 @@ package common.block; import common.properties.IProperty; import common.properties.PropertyEnum; -import common.world.BlockPos; +import common.util.BlockPos; import common.world.State; import common.world.World; diff --git a/common/src/common/block/BlockRailBase.java b/common/src/common/block/BlockRailBase.java index ec47041..ebcab36 100755 --- a/common/src/common/block/BlockRailBase.java +++ b/common/src/common/block/BlockRailBase.java @@ -11,14 +11,14 @@ import common.model.Model; import common.model.ModelProvider; import common.model.ModelRotation; import common.properties.IProperty; +import common.util.BlockPos; +import common.util.BoundingBox; +import common.util.Facing; +import common.util.HitPosition; import common.util.Identifyable; -import common.world.BlockPos; -import common.world.BoundingBox; -import common.world.Facing; -import common.world.HitPosition; +import common.util.Vec3; import common.world.IWorldAccess; import common.world.State; -import common.world.Vec3; import common.world.World; import common.world.WorldServer; diff --git a/common/src/common/block/BlockRailDetector.java b/common/src/common/block/BlockRailDetector.java index 28e977c..7579307 100755 --- a/common/src/common/block/BlockRailDetector.java +++ b/common/src/common/block/BlockRailDetector.java @@ -13,9 +13,9 @@ import common.properties.IProperty; import common.properties.PropertyBool; import common.properties.PropertyEnum; import common.rng.Random; -import common.world.BlockPos; -import common.world.BoundingBox; -import common.world.Facing; +import common.util.BlockPos; +import common.util.BoundingBox; +import common.util.Facing; import common.world.IWorldAccess; import common.world.State; import common.world.World; diff --git a/common/src/common/block/BlockRailPowered.java b/common/src/common/block/BlockRailPowered.java index 65e978a..5989b95 100755 --- a/common/src/common/block/BlockRailPowered.java +++ b/common/src/common/block/BlockRailPowered.java @@ -7,7 +7,7 @@ import common.model.ModelProvider; import common.properties.IProperty; import common.properties.PropertyBool; import common.properties.PropertyEnum; -import common.world.BlockPos; +import common.util.BlockPos; import common.world.State; import common.world.World; diff --git a/common/src/common/block/BlockRedstoneComparator.java b/common/src/common/block/BlockRedstoneComparator.java index b6f3859..9f6b9d2 100755 --- a/common/src/common/block/BlockRedstoneComparator.java +++ b/common/src/common/block/BlockRedstoneComparator.java @@ -15,9 +15,9 @@ import common.properties.PropertyEnum; import common.rng.Random; import common.tileentity.TileEntity; import common.tileentity.TileEntityComparator; +import common.util.BlockPos; +import common.util.Facing; import common.util.Identifyable; -import common.world.BlockPos; -import common.world.Facing; import common.world.IWorldAccess; import common.world.State; import common.world.World; diff --git a/common/src/common/block/BlockRedstoneDiode.java b/common/src/common/block/BlockRedstoneDiode.java index e12d943..4b0c3d3 100755 --- a/common/src/common/block/BlockRedstoneDiode.java +++ b/common/src/common/block/BlockRedstoneDiode.java @@ -6,8 +6,8 @@ import common.item.ItemStack; import common.material.Material; import common.model.BlockLayer; import common.rng.Random; -import common.world.BlockPos; -import common.world.Facing; +import common.util.BlockPos; +import common.util.Facing; import common.world.IWorldAccess; import common.world.State; import common.world.World; diff --git a/common/src/common/block/BlockRedstoneLight.java b/common/src/common/block/BlockRedstoneLight.java index 49cb79b..017346b 100755 --- a/common/src/common/block/BlockRedstoneLight.java +++ b/common/src/common/block/BlockRedstoneLight.java @@ -6,7 +6,7 @@ import common.item.Item; import common.item.ItemStack; import common.material.Material; import common.rng.Random; -import common.world.BlockPos; +import common.util.BlockPos; import common.world.State; import common.world.World; import common.world.WorldServer; diff --git a/common/src/common/block/BlockRedstoneOre.java b/common/src/common/block/BlockRedstoneOre.java index 09aa47a..9d7f947 100755 --- a/common/src/common/block/BlockRedstoneOre.java +++ b/common/src/common/block/BlockRedstoneOre.java @@ -12,8 +12,8 @@ import common.model.Model; import common.model.ModelProvider; import common.model.ParticleType; import common.rng.Random; -import common.world.BlockPos; -import common.world.Facing; +import common.util.BlockPos; +import common.util.Facing; import common.world.State; import common.world.World; import common.world.WorldClient; diff --git a/common/src/common/block/BlockRedstoneRepeater.java b/common/src/common/block/BlockRedstoneRepeater.java index 30c64ec..208e723 100755 --- a/common/src/common/block/BlockRedstoneRepeater.java +++ b/common/src/common/block/BlockRedstoneRepeater.java @@ -12,8 +12,8 @@ import common.properties.IProperty; import common.properties.PropertyBool; import common.properties.PropertyInteger; import common.rng.Random; -import common.world.BlockPos; -import common.world.Facing; +import common.util.BlockPos; +import common.util.Facing; import common.world.IWorldAccess; import common.world.State; import common.world.World; diff --git a/common/src/common/block/BlockRedstoneTorch.java b/common/src/common/block/BlockRedstoneTorch.java index 04cbe22..5e6bbdc 100755 --- a/common/src/common/block/BlockRedstoneTorch.java +++ b/common/src/common/block/BlockRedstoneTorch.java @@ -12,8 +12,8 @@ import common.item.CheatTab; import common.item.Item; import common.model.ParticleType; import common.rng.Random; -import common.world.BlockPos; -import common.world.Facing; +import common.util.BlockPos; +import common.util.Facing; import common.world.IWorldAccess; import common.world.State; import common.world.World; diff --git a/common/src/common/block/BlockRedstoneWire.java b/common/src/common/block/BlockRedstoneWire.java index b5aac93..e023983 100755 --- a/common/src/common/block/BlockRedstoneWire.java +++ b/common/src/common/block/BlockRedstoneWire.java @@ -19,11 +19,11 @@ import common.properties.IProperty; import common.properties.PropertyEnum; import common.properties.PropertyInteger; import common.rng.Random; +import common.util.BlockPos; +import common.util.BoundingBox; import common.util.ExtMath; +import common.util.Facing; import common.util.Identifyable; -import common.world.BlockPos; -import common.world.BoundingBox; -import common.world.Facing; import common.world.IBlockAccess; import common.world.IWorldAccess; import common.world.State; diff --git a/common/src/common/block/BlockReed.java b/common/src/common/block/BlockReed.java index 816e6e7..8ac6c66 100755 --- a/common/src/common/block/BlockReed.java +++ b/common/src/common/block/BlockReed.java @@ -11,9 +11,9 @@ import common.model.ModelProvider; import common.properties.IProperty; import common.properties.PropertyInteger; import common.rng.Random; -import common.world.BlockPos; -import common.world.BoundingBox; -import common.world.Facing; +import common.util.BlockPos; +import common.util.BoundingBox; +import common.util.Facing; import common.world.IWorldAccess; import common.world.State; import common.world.World; diff --git a/common/src/common/block/BlockRotatedPillar.java b/common/src/common/block/BlockRotatedPillar.java index a4b59a3..232db9c 100755 --- a/common/src/common/block/BlockRotatedPillar.java +++ b/common/src/common/block/BlockRotatedPillar.java @@ -5,7 +5,7 @@ import common.model.Model; import common.model.ModelProvider; import common.model.ModelRotation; import common.properties.PropertyEnum; -import common.world.Facing; +import common.util.Facing; import common.world.State; public abstract class BlockRotatedPillar extends Block diff --git a/common/src/common/block/BlockSapling.java b/common/src/common/block/BlockSapling.java index 5615ffc..3a8edb1 100755 --- a/common/src/common/block/BlockSapling.java +++ b/common/src/common/block/BlockSapling.java @@ -12,7 +12,7 @@ import common.model.ModelProvider; import common.properties.IProperty; import common.properties.PropertyInteger; import common.rng.Random; -import common.world.BlockPos; +import common.util.BlockPos; import common.world.State; import common.world.World; import common.world.WorldServer; diff --git a/common/src/common/block/BlockSign.java b/common/src/common/block/BlockSign.java index a42b21d..a440937 100755 --- a/common/src/common/block/BlockSign.java +++ b/common/src/common/block/BlockSign.java @@ -6,8 +6,8 @@ import common.material.Material; import common.rng.Random; import common.tileentity.TileEntity; import common.tileentity.TileEntitySign; -import common.world.BlockPos; -import common.world.BoundingBox; +import common.util.BlockPos; +import common.util.BoundingBox; import common.world.IBlockAccess; import common.world.State; import common.world.World; diff --git a/common/src/common/block/BlockSkull.java b/common/src/common/block/BlockSkull.java index 3730ffe..d73ccae 100755 --- a/common/src/common/block/BlockSkull.java +++ b/common/src/common/block/BlockSkull.java @@ -11,9 +11,9 @@ import common.properties.PropertyDirection; import common.rng.Random; import common.tileentity.TileEntity; import common.tileentity.TileEntitySkull; -import common.world.BlockPos; -import common.world.BoundingBox; -import common.world.Facing; +import common.util.BlockPos; +import common.util.BoundingBox; +import common.util.Facing; import common.world.IWorldAccess; import common.world.State; import common.world.World; diff --git a/common/src/common/block/BlockSlab.java b/common/src/common/block/BlockSlab.java index 6ad12a3..1daa63d 100755 --- a/common/src/common/block/BlockSlab.java +++ b/common/src/common/block/BlockSlab.java @@ -14,13 +14,13 @@ import common.model.ModelProvider; import common.properties.IProperty; import common.properties.PropertyBool; import common.properties.PropertyDirection; -import common.world.BlockPos; -import common.world.BoundingBox; -import common.world.Facing; +import common.util.BlockPos; +import common.util.BoundingBox; +import common.util.Facing; +import common.util.Facing.Axis; import common.world.IWorldAccess; import common.world.State; import common.world.World; -import common.world.Facing.Axis; public class BlockSlab extends Block { diff --git a/common/src/common/block/BlockSlime.java b/common/src/common/block/BlockSlime.java index 4d4a1f7..64ba03a 100755 --- a/common/src/common/block/BlockSlime.java +++ b/common/src/common/block/BlockSlime.java @@ -6,7 +6,7 @@ import common.material.Material; import common.model.BlockLayer; import common.model.Model; import common.model.ModelProvider; -import common.world.BlockPos; +import common.util.BlockPos; import common.world.State; import common.world.World; diff --git a/common/src/common/block/BlockSnow.java b/common/src/common/block/BlockSnow.java index 588918b..489585c 100755 --- a/common/src/common/block/BlockSnow.java +++ b/common/src/common/block/BlockSnow.java @@ -15,9 +15,9 @@ import common.properties.IProperty; import common.properties.PropertyInteger; import common.rng.Random; import common.tileentity.TileEntity; -import common.world.BlockPos; -import common.world.BoundingBox; -import common.world.Facing; +import common.util.BlockPos; +import common.util.BoundingBox; +import common.util.Facing; import common.world.IBlockAccess; import common.world.IWorldAccess; import common.world.LightType; diff --git a/common/src/common/block/BlockSnowBlock.java b/common/src/common/block/BlockSnowBlock.java index 5f8411f..a85f7cb 100755 --- a/common/src/common/block/BlockSnowBlock.java +++ b/common/src/common/block/BlockSnowBlock.java @@ -6,7 +6,7 @@ import common.item.CheatTab; import common.item.Item; import common.material.Material; import common.rng.Random; -import common.world.BlockPos; +import common.util.BlockPos; import common.world.LightType; import common.world.State; import common.world.WorldServer; diff --git a/common/src/common/block/BlockSoulSand.java b/common/src/common/block/BlockSoulSand.java index 5344f81..b9aa80a 100755 --- a/common/src/common/block/BlockSoulSand.java +++ b/common/src/common/block/BlockSoulSand.java @@ -3,8 +3,8 @@ package common.block; import common.entity.Entity; import common.item.CheatTab; import common.material.Material; -import common.world.BlockPos; -import common.world.BoundingBox; +import common.util.BlockPos; +import common.util.BoundingBox; import common.world.State; import common.world.World; diff --git a/common/src/common/block/BlockSourceImpl.java b/common/src/common/block/BlockSourceImpl.java index 63f297b..c5e241e 100755 --- a/common/src/common/block/BlockSourceImpl.java +++ b/common/src/common/block/BlockSourceImpl.java @@ -2,7 +2,7 @@ package common.block; import common.dispenser.IBlockSource; import common.tileentity.TileEntity; -import common.world.BlockPos; +import common.util.BlockPos; import common.world.State; import common.world.World; diff --git a/common/src/common/block/BlockStairs.java b/common/src/common/block/BlockStairs.java index 437f98f..cb917cf 100755 --- a/common/src/common/block/BlockStairs.java +++ b/common/src/common/block/BlockStairs.java @@ -18,16 +18,16 @@ import common.properties.IProperty; import common.properties.PropertyDirection; import common.properties.PropertyEnum; import common.rng.Random; +import common.util.BlockPos; +import common.util.BoundingBox; +import common.util.Facing; +import common.util.HitPosition; import common.util.Identifyable; -import common.world.BlockPos; -import common.world.BoundingBox; +import common.util.Vec3; import common.world.Explosion; -import common.world.Facing; -import common.world.HitPosition; import common.world.IBlockAccess; import common.world.IWorldAccess; import common.world.State; -import common.world.Vec3; import common.world.World; import common.world.WorldClient; import common.world.WorldServer; diff --git a/common/src/common/block/BlockStandingSign.java b/common/src/common/block/BlockStandingSign.java index 754535a..156dabe 100755 --- a/common/src/common/block/BlockStandingSign.java +++ b/common/src/common/block/BlockStandingSign.java @@ -2,7 +2,7 @@ package common.block; import common.properties.IProperty; import common.properties.PropertyInteger; -import common.world.BlockPos; +import common.util.BlockPos; import common.world.State; import common.world.World; diff --git a/common/src/common/block/BlockStaticLiquid.java b/common/src/common/block/BlockStaticLiquid.java index 88791ab..b087f92 100755 --- a/common/src/common/block/BlockStaticLiquid.java +++ b/common/src/common/block/BlockStaticLiquid.java @@ -4,8 +4,8 @@ import common.init.Blocks; import common.init.Config; import common.material.Material; import common.rng.Random; -import common.world.BlockPos; -import common.world.Facing; +import common.util.BlockPos; +import common.util.Facing; import common.world.State; import common.world.World; import common.world.WorldServer; diff --git a/common/src/common/block/BlockStem.java b/common/src/common/block/BlockStem.java index c6d37f8..171047a 100755 --- a/common/src/common/block/BlockStem.java +++ b/common/src/common/block/BlockStem.java @@ -16,8 +16,8 @@ import common.properties.IProperty; import common.properties.PropertyDirection; import common.properties.PropertyInteger; import common.rng.Random; -import common.world.BlockPos; -import common.world.Facing; +import common.util.BlockPos; +import common.util.Facing; import common.world.IWorldAccess; import common.world.State; import common.world.World; diff --git a/common/src/common/block/BlockTNT.java b/common/src/common/block/BlockTNT.java index ceec575..7f121a1 100755 --- a/common/src/common/block/BlockTNT.java +++ b/common/src/common/block/BlockTNT.java @@ -18,9 +18,9 @@ import common.model.ModelProvider; import common.properties.IProperty; import common.properties.PropertyBool; import common.properties.PropertyInteger; -import common.world.BlockPos; +import common.util.BlockPos; +import common.util.Facing; import common.world.Explosion; -import common.world.Facing; import common.world.State; import common.world.World; import common.world.WorldServer; diff --git a/common/src/common/block/BlockTallGrass.java b/common/src/common/block/BlockTallGrass.java index 9724595..aa2e686 100755 --- a/common/src/common/block/BlockTallGrass.java +++ b/common/src/common/block/BlockTallGrass.java @@ -18,8 +18,8 @@ import common.properties.IProperty; import common.properties.PropertyEnum; import common.rng.Random; import common.tileentity.TileEntity; +import common.util.BlockPos; import common.util.Identifyable; -import common.world.BlockPos; import common.world.IWorldAccess; import common.world.State; import common.world.World; diff --git a/common/src/common/block/BlockTianSoil.java b/common/src/common/block/BlockTianSoil.java index 339851a..ac03fd9 100755 --- a/common/src/common/block/BlockTianSoil.java +++ b/common/src/common/block/BlockTianSoil.java @@ -9,7 +9,7 @@ import common.model.ModelProvider; import common.properties.IProperty; import common.properties.PropertyBool; import common.rng.Random; -import common.world.BlockPos; +import common.util.BlockPos; import common.world.IWorldAccess; import common.world.State; diff --git a/common/src/common/block/BlockTorch.java b/common/src/common/block/BlockTorch.java index 571d4c3..53d5940 100755 --- a/common/src/common/block/BlockTorch.java +++ b/common/src/common/block/BlockTorch.java @@ -14,13 +14,13 @@ import common.model.ParticleType; import common.properties.IProperty; import common.properties.PropertyDirection; import common.rng.Random; -import common.world.BlockPos; -import common.world.BoundingBox; +import common.util.BlockPos; +import common.util.BoundingBox; +import common.util.Facing; +import common.util.HitPosition; +import common.util.Vec3; import common.world.Chunk; -import common.world.Facing; -import common.world.HitPosition; import common.world.State; -import common.world.Vec3; import common.world.World; import common.world.WorldClient; import common.world.WorldServer; diff --git a/common/src/common/block/BlockTrapDoor.java b/common/src/common/block/BlockTrapDoor.java index f6f9eae..c8fc2d7 100755 --- a/common/src/common/block/BlockTrapDoor.java +++ b/common/src/common/block/BlockTrapDoor.java @@ -14,15 +14,15 @@ import common.properties.IProperty; import common.properties.PropertyBool; import common.properties.PropertyDirection; import common.properties.PropertyEnum; +import common.util.BlockPos; +import common.util.BoundingBox; +import common.util.Facing; +import common.util.HitPosition; import common.util.Identifyable; -import common.world.BlockPos; -import common.world.BoundingBox; -import common.world.Facing; -import common.world.HitPosition; +import common.util.Vec3; import common.world.IBlockAccess; import common.world.IWorldAccess; import common.world.State; -import common.world.Vec3; import common.world.World; public class BlockTrapDoor extends Block diff --git a/common/src/common/block/BlockTripWire.java b/common/src/common/block/BlockTripWire.java index cbd9299..7512125 100755 --- a/common/src/common/block/BlockTripWire.java +++ b/common/src/common/block/BlockTripWire.java @@ -16,9 +16,9 @@ import common.model.ModelRotation; import common.properties.IProperty; import common.properties.PropertyBool; import common.rng.Random; -import common.world.BlockPos; -import common.world.BoundingBox; -import common.world.Facing; +import common.util.BlockPos; +import common.util.BoundingBox; +import common.util.Facing; import common.world.IBlockAccess; import common.world.IWorldAccess; import common.world.State; diff --git a/common/src/common/block/BlockTripWireHook.java b/common/src/common/block/BlockTripWireHook.java index fb66590..0c8afda 100755 --- a/common/src/common/block/BlockTripWireHook.java +++ b/common/src/common/block/BlockTripWireHook.java @@ -14,9 +14,9 @@ import common.properties.IProperty; import common.properties.PropertyBool; import common.properties.PropertyDirection; import common.rng.Random; -import common.world.BlockPos; -import common.world.BoundingBox; -import common.world.Facing; +import common.util.BlockPos; +import common.util.BoundingBox; +import common.util.Facing; import common.world.IWorldAccess; import common.world.State; import common.world.World; diff --git a/common/src/common/block/BlockVine.java b/common/src/common/block/BlockVine.java index 10443c8..8e82dcc 100755 --- a/common/src/common/block/BlockVine.java +++ b/common/src/common/block/BlockVine.java @@ -18,9 +18,9 @@ import common.properties.IProperty; import common.properties.PropertyBool; import common.rng.Random; import common.tileentity.TileEntity; -import common.world.BlockPos; -import common.world.BoundingBox; -import common.world.Facing; +import common.util.BlockPos; +import common.util.BoundingBox; +import common.util.Facing; import common.world.IWorldAccess; import common.world.State; import common.world.World; diff --git a/common/src/common/block/BlockWall.java b/common/src/common/block/BlockWall.java index de001d2..41ad2bf 100755 --- a/common/src/common/block/BlockWall.java +++ b/common/src/common/block/BlockWall.java @@ -12,10 +12,10 @@ import common.model.ModelRotation; import common.properties.IProperty; import common.properties.PropertyBool; import common.properties.PropertyEnum; +import common.util.BlockPos; +import common.util.BoundingBox; +import common.util.Facing; import common.util.Identifyable; -import common.world.BlockPos; -import common.world.BoundingBox; -import common.world.Facing; import common.world.IBlockAccess; import common.world.IWorldAccess; import common.world.State; diff --git a/common/src/common/block/BlockWallSign.java b/common/src/common/block/BlockWallSign.java index 75fdc0f..29da816 100755 --- a/common/src/common/block/BlockWallSign.java +++ b/common/src/common/block/BlockWallSign.java @@ -2,8 +2,8 @@ package common.block; import common.properties.IProperty; import common.properties.PropertyDirection; -import common.world.BlockPos; -import common.world.Facing; +import common.util.BlockPos; +import common.util.Facing; import common.world.IWorldAccess; import common.world.State; import common.world.World; diff --git a/common/src/common/block/BlockWarpChest.java b/common/src/common/block/BlockWarpChest.java index d32b60e..32b40c9 100755 --- a/common/src/common/block/BlockWarpChest.java +++ b/common/src/common/block/BlockWarpChest.java @@ -16,8 +16,8 @@ import common.model.ParticleType; import common.properties.IProperty; import common.properties.PropertyDirection; import common.rng.Random; -import common.world.BlockPos; -import common.world.Facing; +import common.util.BlockPos; +import common.util.Facing; import common.world.State; import common.world.World; import common.world.WorldClient; diff --git a/common/src/common/block/BlockWart.java b/common/src/common/block/BlockWart.java index 380e4eb..3c576a8 100755 --- a/common/src/common/block/BlockWart.java +++ b/common/src/common/block/BlockWart.java @@ -12,7 +12,7 @@ import common.model.ModelProvider; import common.properties.IProperty; import common.properties.PropertyInteger; import common.rng.Random; -import common.world.BlockPos; +import common.util.BlockPos; import common.world.State; import common.world.World; import common.world.WorldServer; diff --git a/common/src/common/block/BlockWeb.java b/common/src/common/block/BlockWeb.java index 959cb0f..9778a73 100755 --- a/common/src/common/block/BlockWeb.java +++ b/common/src/common/block/BlockWeb.java @@ -9,8 +9,8 @@ import common.model.BlockLayer; import common.model.Model; import common.model.ModelProvider; import common.rng.Random; -import common.world.BlockPos; -import common.world.BoundingBox; +import common.util.BlockPos; +import common.util.BoundingBox; import common.world.State; import common.world.World; diff --git a/common/src/common/block/BlockWorkbench.java b/common/src/common/block/BlockWorkbench.java index 0489d2c..3ac24c8 100755 --- a/common/src/common/block/BlockWorkbench.java +++ b/common/src/common/block/BlockWorkbench.java @@ -9,8 +9,8 @@ import common.material.Material; import common.model.Model; import common.model.ModelProvider; import common.tileentity.IInteractionObject; -import common.world.BlockPos; -import common.world.Facing; +import common.util.BlockPos; +import common.util.Facing; import common.world.State; import common.world.World; diff --git a/common/src/common/block/IGrowable.java b/common/src/common/block/IGrowable.java index 35def7f..a3c9ca0 100755 --- a/common/src/common/block/IGrowable.java +++ b/common/src/common/block/IGrowable.java @@ -1,7 +1,7 @@ package common.block; import common.rng.Random; -import common.world.BlockPos; +import common.util.BlockPos; import common.world.State; import common.world.World; import common.world.WorldServer; diff --git a/common/src/common/clipboard/ClipboardPlacer.java b/common/src/common/clipboard/ClipboardPlacer.java index a6525c0..b2dc5a7 100755 --- a/common/src/common/clipboard/ClipboardPlacer.java +++ b/common/src/common/clipboard/ClipboardPlacer.java @@ -17,8 +17,8 @@ import common.init.Blocks; import common.init.ReorderRegistry; import common.inventory.IInventory; import common.tileentity.TileEntity; -import common.world.BlockPos; -import common.world.Vec3i; +import common.util.BlockPos; +import common.util.Vec3i; import common.world.WorldServer; public class ClipboardPlacer { diff --git a/common/src/common/color/Colorizer.java b/common/src/common/color/Colorizer.java index ed175a7..dcae2c9 100755 --- a/common/src/common/color/Colorizer.java +++ b/common/src/common/color/Colorizer.java @@ -1,7 +1,7 @@ package common.color; import common.biome.Biome; -import common.world.BlockPos; +import common.util.BlockPos; import common.world.IWorldAccess; public enum Colorizer { diff --git a/common/src/common/dimension/Dimension.java b/common/src/common/dimension/Dimension.java index f8fb29b..32c7520 100755 --- a/common/src/common/dimension/Dimension.java +++ b/common/src/common/dimension/Dimension.java @@ -18,8 +18,8 @@ import common.nbt.NBTTagList; import common.nbt.NBTTagString; import common.rng.Random; import common.util.ExtMath; +import common.util.Vec3; import common.world.State; -import common.world.Vec3; import common.world.Weather; import common.worldgen.BiomeGenLayered; import common.worldgen.BiomeGenPerlin; diff --git a/common/src/common/dispenser/BehaviorDefaultDispenseItem.java b/common/src/common/dispenser/BehaviorDefaultDispenseItem.java index 937a1ec..e4aea80 100755 --- a/common/src/common/dispenser/BehaviorDefaultDispenseItem.java +++ b/common/src/common/dispenser/BehaviorDefaultDispenseItem.java @@ -3,7 +3,7 @@ package common.dispenser; import common.block.BlockDispenser; import common.entity.item.EntityItem; import common.item.ItemStack; -import common.world.Facing; +import common.util.Facing; import common.world.World; public class BehaviorDefaultDispenseItem implements IBehaviorDispenseItem diff --git a/common/src/common/dispenser/BehaviorProjectileDispense.java b/common/src/common/dispenser/BehaviorProjectileDispense.java index 71230cf..dc4dbaa 100755 --- a/common/src/common/dispenser/BehaviorProjectileDispense.java +++ b/common/src/common/dispenser/BehaviorProjectileDispense.java @@ -4,7 +4,7 @@ import common.block.BlockDispenser; import common.entity.Entity; import common.entity.types.IProjectile; import common.item.ItemStack; -import common.world.Facing; +import common.util.Facing; import common.world.World; public abstract class BehaviorProjectileDispense extends BehaviorDefaultDispenseItem diff --git a/common/src/common/dispenser/IBlockSource.java b/common/src/common/dispenser/IBlockSource.java index f6d6d8f..c56f8c3 100755 --- a/common/src/common/dispenser/IBlockSource.java +++ b/common/src/common/dispenser/IBlockSource.java @@ -1,7 +1,7 @@ package common.dispenser; import common.tileentity.TileEntity; -import common.world.BlockPos; +import common.util.BlockPos; public interface IBlockSource extends ILocatableSource { diff --git a/common/src/common/entity/DataWatcher.java b/common/src/common/entity/DataWatcher.java index 7b061b3..e4b9a7e 100755 --- a/common/src/common/entity/DataWatcher.java +++ b/common/src/common/entity/DataWatcher.java @@ -10,7 +10,7 @@ import common.collect.Lists; import common.collect.Maps; import common.item.ItemStack; import common.network.PacketBuffer; -import common.world.BlockPos; +import common.util.BlockPos; public class DataWatcher { private static final Map, Integer> dataTypes = Maps., Integer>newHashMap(); diff --git a/common/src/common/entity/Entity.java b/common/src/common/entity/Entity.java index 0daa035..b142d3d 100755 --- a/common/src/common/entity/Entity.java +++ b/common/src/common/entity/Entity.java @@ -32,16 +32,16 @@ import common.nbt.NBTTagDouble; import common.nbt.NBTTagFloat; import common.nbt.NBTTagList; import common.rng.Random; +import common.util.BlockPos; +import common.util.BoundingBox; import common.util.ExtMath; -import common.world.BlockPos; -import common.world.BoundingBox; +import common.util.Facing; +import common.util.HitPosition; +import common.util.PortalType; +import common.util.Position; +import common.util.Vec3; import common.world.Explosion; -import common.world.Facing; -import common.world.HitPosition; -import common.world.PortalType; -import common.world.Position; import common.world.State; -import common.world.Vec3; import common.world.World; import common.world.WorldServer; diff --git a/common/src/common/entity/animal/EntityBat.java b/common/src/common/entity/animal/EntityBat.java index 7f30243..a6c0d96 100755 --- a/common/src/common/entity/animal/EntityBat.java +++ b/common/src/common/entity/animal/EntityBat.java @@ -9,8 +9,8 @@ import common.entity.npc.EntityNPC; import common.entity.types.EntityLiving; import common.init.SoundEvent; import common.nbt.NBTTagCompound; +import common.util.BlockPos; import common.util.ExtMath; -import common.world.BlockPos; import common.world.World; public class EntityBat extends EntityLiving diff --git a/common/src/common/entity/animal/EntityDragon.java b/common/src/common/entity/animal/EntityDragon.java index dc1953e..4b97778 100755 --- a/common/src/common/entity/animal/EntityDragon.java +++ b/common/src/common/entity/animal/EntityDragon.java @@ -14,7 +14,7 @@ import common.init.Config; import common.init.SoundEvent; import common.model.ParticleType; import common.util.ExtMath; -import common.world.Vec3; +import common.util.Vec3; import common.world.World; import common.world.WorldClient; diff --git a/common/src/common/entity/animal/EntityHorse.java b/common/src/common/entity/animal/EntityHorse.java index 041aa2a..ed9d625 100755 --- a/common/src/common/entity/animal/EntityHorse.java +++ b/common/src/common/entity/animal/EntityHorse.java @@ -36,8 +36,8 @@ import common.nbt.NBTTagCompound; import common.nbt.NBTTagList; import common.pathfinding.PathNavigateGround; import common.potion.Potion; +import common.util.BlockPos; import common.util.ExtMath; -import common.world.BlockPos; import common.world.World; public class EntityHorse extends EntityAnimal implements IInvBasic diff --git a/common/src/common/entity/animal/EntityMouse.java b/common/src/common/entity/animal/EntityMouse.java index 86195f2..8456057 100755 --- a/common/src/common/entity/animal/EntityMouse.java +++ b/common/src/common/entity/animal/EntityMouse.java @@ -20,7 +20,7 @@ import common.init.Blocks; import common.init.Items; import common.init.SoundEvent; import common.item.ItemStack; -import common.world.BlockPos; +import common.util.BlockPos; import common.world.World; public class EntityMouse extends EntityAnimal { diff --git a/common/src/common/entity/animal/EntityRabbit.java b/common/src/common/entity/animal/EntityRabbit.java index 49e09cf..a8f319a 100755 --- a/common/src/common/entity/animal/EntityRabbit.java +++ b/common/src/common/entity/animal/EntityRabbit.java @@ -38,10 +38,10 @@ import common.pathfinding.PathEntity; import common.pathfinding.PathNavigateGround; import common.potion.Potion; import common.potion.PotionEffect; +import common.util.BlockPos; import common.util.ExtMath; -import common.world.BlockPos; +import common.util.Vec3; import common.world.State; -import common.world.Vec3; import common.world.World; public class EntityRabbit extends EntityAnimal { diff --git a/common/src/common/entity/effect/EntityLightning.java b/common/src/common/entity/effect/EntityLightning.java index 4e9eccd..e966314 100755 --- a/common/src/common/entity/effect/EntityLightning.java +++ b/common/src/common/entity/effect/EntityLightning.java @@ -9,8 +9,8 @@ import common.init.Blocks; import common.init.Config; import common.init.SoundEvent; import common.material.Material; -import common.world.BlockPos; -import common.world.BoundingBox; +import common.util.BlockPos; +import common.util.BoundingBox; import common.world.World; import common.world.WorldClient; diff --git a/common/src/common/entity/item/EntityBoat.java b/common/src/common/entity/item/EntityBoat.java index 98d133c..7fb57b2 100755 --- a/common/src/common/entity/item/EntityBoat.java +++ b/common/src/common/entity/item/EntityBoat.java @@ -16,9 +16,9 @@ import common.init.Items; import common.item.Item; import common.model.ParticleType; import common.nbt.NBTTagCompound; +import common.util.BlockPos; +import common.util.BoundingBox; import common.util.ExtMath; -import common.world.BlockPos; -import common.world.BoundingBox; import common.world.World; public class EntityBoat extends Entity diff --git a/common/src/common/entity/item/EntityCart.java b/common/src/common/entity/item/EntityCart.java index 113d137..a9222fe 100755 --- a/common/src/common/entity/item/EntityCart.java +++ b/common/src/common/entity/item/EntityCart.java @@ -15,11 +15,11 @@ import common.item.Item; import common.item.ItemStack; import common.nbt.NBTTagCompound; import common.tileentity.IWorldNameable; +import common.util.BlockPos; +import common.util.BoundingBox; import common.util.ExtMath; -import common.world.BlockPos; -import common.world.BoundingBox; +import common.util.Vec3; import common.world.State; -import common.world.Vec3; import common.world.World; public abstract class EntityCart extends Entity implements IWorldNameable diff --git a/common/src/common/entity/item/EntityCartContainer.java b/common/src/common/entity/item/EntityCartContainer.java index daf7d7c..4afb8f5 100755 --- a/common/src/common/entity/item/EntityCartContainer.java +++ b/common/src/common/entity/item/EntityCartContainer.java @@ -11,8 +11,8 @@ import common.nbt.NBTTagCompound; import common.nbt.NBTTagList; import common.tileentity.ILockableContainer; import common.tileentity.LockCode; -import common.world.BlockPos; -import common.world.PortalType; +import common.util.BlockPos; +import common.util.PortalType; import common.world.World; public abstract class EntityCartContainer extends EntityCart implements ILockableContainer diff --git a/common/src/common/entity/item/EntityChestCart.java b/common/src/common/entity/item/EntityChestCart.java index 783dbc1..73d7966 100755 --- a/common/src/common/entity/item/EntityChestCart.java +++ b/common/src/common/entity/item/EntityChestCart.java @@ -9,7 +9,7 @@ import common.init.ItemRegistry; import common.inventory.Container; import common.inventory.ContainerChest; import common.inventory.InventoryPlayer; -import common.world.Facing; +import common.util.Facing; import common.world.State; import common.world.World; diff --git a/common/src/common/entity/item/EntityFalling.java b/common/src/common/entity/item/EntityFalling.java index ffb8a7b..97b135e 100755 --- a/common/src/common/entity/item/EntityFalling.java +++ b/common/src/common/entity/item/EntityFalling.java @@ -19,9 +19,9 @@ import common.material.Material; import common.nbt.NBTBase; import common.nbt.NBTTagCompound; import common.tileentity.TileEntity; +import common.util.BlockPos; import common.util.ExtMath; -import common.world.BlockPos; -import common.world.Facing; +import common.util.Facing; import common.world.State; import common.world.World; diff --git a/common/src/common/entity/item/EntityHopperCart.java b/common/src/common/entity/item/EntityHopperCart.java index 4083659..398eccf 100755 --- a/common/src/common/entity/item/EntityHopperCart.java +++ b/common/src/common/entity/item/EntityHopperCart.java @@ -14,7 +14,7 @@ import common.inventory.InventoryPlayer; import common.nbt.NBTTagCompound; import common.tileentity.IHopper; import common.tileentity.TileEntityHopper; -import common.world.BlockPos; +import common.util.BlockPos; import common.world.State; import common.world.World; diff --git a/common/src/common/entity/item/EntityItem.java b/common/src/common/entity/item/EntityItem.java index 14abe9b..1647b97 100755 --- a/common/src/common/entity/item/EntityItem.java +++ b/common/src/common/entity/item/EntityItem.java @@ -15,9 +15,9 @@ import common.log.Log; import common.material.Material; import common.model.ParticleType; import common.nbt.NBTTagCompound; +import common.util.BlockPos; import common.util.ExtMath; -import common.world.BlockPos; -import common.world.PortalType; +import common.util.PortalType; import common.world.World; import common.world.WorldServer; diff --git a/common/src/common/entity/item/EntityLeashKnot.java b/common/src/common/entity/item/EntityLeashKnot.java index e3aebe6..764cc21 100755 --- a/common/src/common/entity/item/EntityLeashKnot.java +++ b/common/src/common/entity/item/EntityLeashKnot.java @@ -10,9 +10,9 @@ import common.init.Items; import common.item.Item; import common.item.ItemStack; import common.nbt.NBTTagCompound; +import common.util.BlockPos; +import common.util.BoundingBox; import common.util.ExtMath; -import common.world.BlockPos; -import common.world.BoundingBox; import common.world.World; public class EntityLeashKnot extends Entity diff --git a/common/src/common/entity/item/EntityOrb.java b/common/src/common/entity/item/EntityOrb.java index 6a3ecf8..055206c 100755 --- a/common/src/common/entity/item/EntityOrb.java +++ b/common/src/common/entity/item/EntityOrb.java @@ -6,7 +6,7 @@ import common.entity.types.EntityLiving; import common.entity.types.EntityThrowable; import common.init.Config; import common.model.ParticleType; -import common.world.HitPosition; +import common.util.HitPosition; import common.world.World; public class EntityOrb extends EntityThrowable diff --git a/common/src/common/entity/item/EntityTntCart.java b/common/src/common/entity/item/EntityTntCart.java index 4adfbc4..3f9005c 100755 --- a/common/src/common/entity/item/EntityTntCart.java +++ b/common/src/common/entity/item/EntityTntCart.java @@ -10,7 +10,7 @@ import common.init.SoundEvent; import common.item.ItemStack; import common.model.ParticleType; import common.nbt.NBTTagCompound; -import common.world.BlockPos; +import common.util.BlockPos; import common.world.Explosion; import common.world.State; import common.world.World; diff --git a/common/src/common/entity/item/EntityXp.java b/common/src/common/entity/item/EntityXp.java index ab9642c..43a5e6a 100755 --- a/common/src/common/entity/item/EntityXp.java +++ b/common/src/common/entity/item/EntityXp.java @@ -11,9 +11,9 @@ import common.init.SoundEvent; import common.material.Material; import common.model.ParticleType; import common.nbt.NBTTagCompound; +import common.util.BlockPos; import common.util.ExtMath; -import common.world.BlockPos; -import common.world.PortalType; +import common.util.PortalType; import common.world.World; public class EntityXp extends Entity implements IObjectData diff --git a/common/src/common/entity/item/EntityXpBottle.java b/common/src/common/entity/item/EntityXpBottle.java index 09a969b..fdef911 100755 --- a/common/src/common/entity/item/EntityXpBottle.java +++ b/common/src/common/entity/item/EntityXpBottle.java @@ -2,8 +2,8 @@ package common.entity.item; import common.entity.types.EntityLiving; import common.entity.types.EntityThrowable; -import common.world.BlockPos; -import common.world.HitPosition; +import common.util.BlockPos; +import common.util.HitPosition; import common.world.World; public class EntityXpBottle extends EntityThrowable diff --git a/common/src/common/entity/npc/EntityArachnoid.java b/common/src/common/entity/npc/EntityArachnoid.java index f56a9bf..becd804 100755 --- a/common/src/common/entity/npc/EntityArachnoid.java +++ b/common/src/common/entity/npc/EntityArachnoid.java @@ -9,7 +9,7 @@ import common.pathfinding.PathNavigateClimber; import common.potion.Potion; import common.potion.PotionEffect; import common.rng.Random; -import common.world.BlockPos; +import common.util.BlockPos; import common.world.World; public class EntityArachnoid extends EntityNPC diff --git a/common/src/common/entity/npc/EntityCultivator.java b/common/src/common/entity/npc/EntityCultivator.java index 84206cd..2376c0a 100755 --- a/common/src/common/entity/npc/EntityCultivator.java +++ b/common/src/common/entity/npc/EntityCultivator.java @@ -7,7 +7,7 @@ import common.entity.effect.EntityLightning; import common.init.Items; import common.item.ItemStack; import common.rng.Random; -import common.world.BlockPos; +import common.util.BlockPos; import common.world.World; public class EntityCultivator extends EntityNPC { diff --git a/common/src/common/entity/npc/EntityFlyingNPC.java b/common/src/common/entity/npc/EntityFlyingNPC.java index 56dcfb3..9827f40 100755 --- a/common/src/common/entity/npc/EntityFlyingNPC.java +++ b/common/src/common/entity/npc/EntityFlyingNPC.java @@ -7,9 +7,9 @@ import common.entity.attributes.Attributes; import common.entity.types.EntityLiving; import common.potion.Potion; import common.rng.Random; +import common.util.BlockPos; +import common.util.BoundingBox; import common.util.ExtMath; -import common.world.BlockPos; -import common.world.BoundingBox; import common.world.World; public abstract class EntityFlyingNPC extends EntityNPC diff --git a/common/src/common/entity/npc/EntityHuman.java b/common/src/common/entity/npc/EntityHuman.java index 18bbea1..cedc14b 100755 --- a/common/src/common/entity/npc/EntityHuman.java +++ b/common/src/common/entity/npc/EntityHuman.java @@ -4,9 +4,9 @@ import common.entity.types.EntityLiving; import common.init.Items; import common.item.ItemStack; import common.rng.Random; +import common.util.BlockPos; import common.util.Identifyable; import common.village.Village; -import common.world.BlockPos; import common.world.World; import common.world.WorldServer; diff --git a/common/src/common/entity/npc/EntityNPC.java b/common/src/common/entity/npc/EntityNPC.java index 26b4075..f261a8b 100755 --- a/common/src/common/entity/npc/EntityNPC.java +++ b/common/src/common/entity/npc/EntityNPC.java @@ -86,16 +86,16 @@ import common.sound.MovingSoundMinecartRiding; import common.tileentity.IInteractionObject; import common.tileentity.LockCode; import common.tileentity.TileEntitySign; +import common.util.BlockPos; +import common.util.BoundingBox; import common.util.ExtMath; +import common.util.Facing; +import common.util.PortalType; +import common.util.Vec3; +import common.util.WorldPos; import common.village.MerchantRecipeList; -import common.world.BlockPos; -import common.world.BoundingBox; -import common.world.Facing; -import common.world.PortalType; -import common.world.Vec3; import common.world.World; import common.world.WorldClient; -import common.world.WorldPos; import common.world.WorldServer; public abstract class EntityNPC extends EntityLiving diff --git a/common/src/common/entity/npc/EntitySlime.java b/common/src/common/entity/npc/EntitySlime.java index 0c9d04d..da31cab 100755 --- a/common/src/common/entity/npc/EntitySlime.java +++ b/common/src/common/entity/npc/EntitySlime.java @@ -13,8 +13,8 @@ import common.model.ParticleType; import common.nbt.NBTTagCompound; import common.pathfinding.PathNavigateGround; import common.rng.Random; +import common.util.BlockPos; import common.util.ExtMath; -import common.world.BlockPos; import common.world.Chunk; import common.world.World; import common.world.WorldServer; diff --git a/common/src/common/entity/npc/EntityZombie.java b/common/src/common/entity/npc/EntityZombie.java index 449d5b6..bdd5734 100755 --- a/common/src/common/entity/npc/EntityZombie.java +++ b/common/src/common/entity/npc/EntityZombie.java @@ -11,8 +11,8 @@ import common.entity.attributes.Attributes; import common.entity.types.EntityLiving; import common.init.Config; import common.rng.Random; +import common.util.BlockPos; import common.util.ExtMath; -import common.world.BlockPos; import common.world.World; import common.world.WorldServer; diff --git a/common/src/common/entity/npc/PlayerCharacter.java b/common/src/common/entity/npc/PlayerCharacter.java index 75ce463..c9e6c74 100644 --- a/common/src/common/entity/npc/PlayerCharacter.java +++ b/common/src/common/entity/npc/PlayerCharacter.java @@ -1,6 +1,6 @@ package common.entity.npc; -import common.world.BlockPos; +import common.util.BlockPos; public class PlayerCharacter { public final String name; diff --git a/common/src/common/entity/projectile/EntityArrow.java b/common/src/common/entity/projectile/EntityArrow.java index 6e3dd50..3174775 100755 --- a/common/src/common/entity/projectile/EntityArrow.java +++ b/common/src/common/entity/projectile/EntityArrow.java @@ -19,12 +19,12 @@ import common.item.ItemStack; import common.material.Material; import common.model.ParticleType; import common.nbt.NBTTagCompound; +import common.util.BlockPos; +import common.util.BoundingBox; import common.util.ExtMath; -import common.world.BlockPos; -import common.world.BoundingBox; -import common.world.HitPosition; +import common.util.HitPosition; +import common.util.Vec3; import common.world.State; -import common.world.Vec3; import common.world.World; public class EntityArrow extends Entity implements IProjectile, IObjectData diff --git a/common/src/common/entity/projectile/EntityBox.java b/common/src/common/entity/projectile/EntityBox.java index 17c92d9..de13b19 100755 --- a/common/src/common/entity/projectile/EntityBox.java +++ b/common/src/common/entity/projectile/EntityBox.java @@ -6,7 +6,7 @@ import common.entity.types.EntityLiving; import common.init.Config; import common.potion.Potion; import common.potion.PotionEffect; -import common.world.HitPosition; +import common.util.HitPosition; import common.world.World; public class EntityBox extends EntityProjectile diff --git a/common/src/common/entity/projectile/EntityBullet.java b/common/src/common/entity/projectile/EntityBullet.java index 040336e..51f2f9a 100755 --- a/common/src/common/entity/projectile/EntityBullet.java +++ b/common/src/common/entity/projectile/EntityBullet.java @@ -12,10 +12,10 @@ import common.entity.types.IProjectile; import common.init.Config; import common.init.SoundEvent; import common.nbt.NBTTagCompound; +import common.util.BoundingBox; import common.util.ExtMath; -import common.world.BoundingBox; -import common.world.HitPosition; -import common.world.Vec3; +import common.util.HitPosition; +import common.util.Vec3; import common.world.World; public class EntityBullet extends Entity implements IProjectile, IObjectData diff --git a/common/src/common/entity/projectile/EntityDie.java b/common/src/common/entity/projectile/EntityDie.java index 80ad963..1407ba2 100755 --- a/common/src/common/entity/projectile/EntityDie.java +++ b/common/src/common/entity/projectile/EntityDie.java @@ -10,7 +10,7 @@ import common.init.SoundEvent; import common.item.ItemDie; import common.item.ItemStack; import common.nbt.NBTTagCompound; -import common.world.HitPosition; +import common.util.HitPosition; import common.world.World; public class EntityDie extends EntityThrowable implements IObjectData diff --git a/common/src/common/entity/projectile/EntityDynamite.java b/common/src/common/entity/projectile/EntityDynamite.java index 3c24d55..1146bdb 100755 --- a/common/src/common/entity/projectile/EntityDynamite.java +++ b/common/src/common/entity/projectile/EntityDynamite.java @@ -10,7 +10,7 @@ import common.init.ItemRegistry; import common.init.Items; import common.model.ParticleType; import common.nbt.NBTTagCompound; -import common.world.HitPosition; +import common.util.HitPosition; import common.world.World; public class EntityDynamite extends EntityThrowable implements IObjectData diff --git a/common/src/common/entity/projectile/EntityEgg.java b/common/src/common/entity/projectile/EntityEgg.java index 5f22a96..0f7ef77 100755 --- a/common/src/common/entity/projectile/EntityEgg.java +++ b/common/src/common/entity/projectile/EntityEgg.java @@ -8,7 +8,7 @@ import common.init.Config; import common.init.ItemRegistry; import common.init.Items; import common.model.ParticleType; -import common.world.HitPosition; +import common.util.HitPosition; import common.world.World; public class EntityEgg extends EntityThrowable diff --git a/common/src/common/entity/projectile/EntityFireCharge.java b/common/src/common/entity/projectile/EntityFireCharge.java index 999c561..0a27a2c 100755 --- a/common/src/common/entity/projectile/EntityFireCharge.java +++ b/common/src/common/entity/projectile/EntityFireCharge.java @@ -4,8 +4,8 @@ import common.entity.DamageSource; import common.entity.types.EntityLiving; import common.init.Blocks; import common.init.Config; -import common.world.BlockPos; -import common.world.HitPosition; +import common.util.BlockPos; +import common.util.HitPosition; import common.world.World; public class EntityFireCharge extends EntityProjectile diff --git a/common/src/common/entity/projectile/EntityFireball.java b/common/src/common/entity/projectile/EntityFireball.java index 3aa02c6..04ad023 100755 --- a/common/src/common/entity/projectile/EntityFireball.java +++ b/common/src/common/entity/projectile/EntityFireball.java @@ -4,7 +4,7 @@ import common.entity.DamageSource; import common.entity.types.EntityLiving; import common.init.Config; import common.nbt.NBTTagCompound; -import common.world.HitPosition; +import common.util.HitPosition; import common.world.World; public class EntityFireball extends EntityProjectile diff --git a/common/src/common/entity/projectile/EntityHook.java b/common/src/common/entity/projectile/EntityHook.java index d348d73..318976c 100755 --- a/common/src/common/entity/projectile/EntityHook.java +++ b/common/src/common/entity/projectile/EntityHook.java @@ -19,11 +19,11 @@ import common.init.SoundEvent; import common.item.ItemStack; import common.model.ParticleType; import common.nbt.NBTTagCompound; +import common.util.BlockPos; +import common.util.BoundingBox; import common.util.ExtMath; -import common.world.BlockPos; -import common.world.BoundingBox; -import common.world.HitPosition; -import common.world.Vec3; +import common.util.HitPosition; +import common.util.Vec3; import common.world.World; import common.world.WorldServer; import common.worldgen.LootConstants; diff --git a/common/src/common/entity/projectile/EntityPotion.java b/common/src/common/entity/projectile/EntityPotion.java index 93e1fbb..3d477f6 100755 --- a/common/src/common/entity/projectile/EntityPotion.java +++ b/common/src/common/entity/projectile/EntityPotion.java @@ -10,9 +10,9 @@ import common.item.ItemStack; import common.nbt.NBTTagCompound; import common.potion.Potion; import common.potion.PotionEffect; -import common.world.BlockPos; -import common.world.BoundingBox; -import common.world.HitPosition; +import common.util.BlockPos; +import common.util.BoundingBox; +import common.util.HitPosition; import common.world.World; public class EntityPotion extends EntityThrowable implements IObjectData diff --git a/common/src/common/entity/projectile/EntityProjectile.java b/common/src/common/entity/projectile/EntityProjectile.java index a8ab021..32dd6d5 100755 --- a/common/src/common/entity/projectile/EntityProjectile.java +++ b/common/src/common/entity/projectile/EntityProjectile.java @@ -11,11 +11,11 @@ import common.init.BlockRegistry; import common.model.ParticleType; import common.nbt.NBTTagCompound; import common.nbt.NBTTagList; +import common.util.BlockPos; +import common.util.BoundingBox; import common.util.ExtMath; -import common.world.BlockPos; -import common.world.BoundingBox; -import common.world.HitPosition; -import common.world.Vec3; +import common.util.HitPosition; +import common.util.Vec3; import common.world.World; public abstract class EntityProjectile extends Entity diff --git a/common/src/common/entity/projectile/EntitySnowball.java b/common/src/common/entity/projectile/EntitySnowball.java index b1801de..6e4a137 100755 --- a/common/src/common/entity/projectile/EntitySnowball.java +++ b/common/src/common/entity/projectile/EntitySnowball.java @@ -5,7 +5,7 @@ import common.entity.types.EntityLiving; import common.entity.types.EntityThrowable; import common.init.Config; import common.model.ParticleType; -import common.world.HitPosition; +import common.util.HitPosition; import common.world.World; public class EntitySnowball extends EntityThrowable diff --git a/common/src/common/entity/types/EntityAnimal.java b/common/src/common/entity/types/EntityAnimal.java index f3565c6..3cfde3a 100755 --- a/common/src/common/entity/types/EntityAnimal.java +++ b/common/src/common/entity/types/EntityAnimal.java @@ -13,8 +13,8 @@ import common.init.Items; import common.item.ItemStack; import common.model.ParticleType; import common.nbt.NBTTagCompound; +import common.util.BlockPos; import common.util.ExtMath; -import common.world.BlockPos; import common.world.World; public abstract class EntityAnimal extends EntityLiving diff --git a/common/src/common/entity/types/EntityLiving.java b/common/src/common/entity/types/EntityLiving.java index 2bb0f27..c99cbb5 100755 --- a/common/src/common/entity/types/EntityLiving.java +++ b/common/src/common/entity/types/EntityLiving.java @@ -60,11 +60,11 @@ import common.potion.Potion; import common.potion.PotionEffect; import common.potion.PotionHelper; import common.rng.Random; +import common.util.BlockPos; +import common.util.BoundingBox; import common.util.ExtMath; -import common.world.BlockPos; -import common.world.BoundingBox; +import common.util.Vec3; import common.world.State; -import common.world.Vec3; import common.world.World; import common.world.WorldServer; diff --git a/common/src/common/entity/types/EntityThrowable.java b/common/src/common/entity/types/EntityThrowable.java index 3eac442..2833d82 100755 --- a/common/src/common/entity/types/EntityThrowable.java +++ b/common/src/common/entity/types/EntityThrowable.java @@ -10,12 +10,12 @@ import common.init.BlockRegistry; import common.init.Blocks; import common.model.ParticleType; import common.nbt.NBTTagCompound; +import common.util.BlockPos; +import common.util.BoundingBox; import common.util.ExtMath; -import common.world.BlockPos; -import common.world.BoundingBox; -import common.world.HitPosition; +import common.util.HitPosition; +import common.util.Vec3; import common.world.State; -import common.world.Vec3; import common.world.World; public abstract class EntityThrowable extends Entity implements IProjectile diff --git a/common/src/common/init/DispenserRegistry.java b/common/src/common/init/DispenserRegistry.java index 74a0bdb..64bc258 100755 --- a/common/src/common/init/DispenserRegistry.java +++ b/common/src/common/init/DispenserRegistry.java @@ -35,9 +35,9 @@ import common.item.ItemStack; import common.material.Material; import common.rng.Random; import common.tileentity.TileEntityDispenser; +import common.util.BlockPos; import common.util.ExtMath; -import common.world.BlockPos; -import common.world.Facing; +import common.util.Facing; import common.world.State; import common.world.World; diff --git a/common/src/common/init/ReorderRegistry.java b/common/src/common/init/ReorderRegistry.java index 181e48c..b5796fa 100755 --- a/common/src/common/init/ReorderRegistry.java +++ b/common/src/common/init/ReorderRegistry.java @@ -9,9 +9,9 @@ import common.block.Block; import common.block.BlockBed; import common.block.BlockDoor; import common.color.DyeColor; -import common.world.Facing; +import common.util.Facing; +import common.util.Vec3i; import common.world.State; -import common.world.Vec3i; public abstract class ReorderRegistry { private static final Set PLACE_LAST = new HashSet(); diff --git a/common/src/common/init/RotationRegistry.java b/common/src/common/init/RotationRegistry.java index be4d0a9..3c6eb32 100755 --- a/common/src/common/init/RotationRegistry.java +++ b/common/src/common/init/RotationRegistry.java @@ -23,9 +23,9 @@ import common.collect.Lists; import common.collect.Maps; import common.properties.IProperty; import common.properties.PropertyDirection; -import common.world.Facing; +import common.util.Facing; +import common.util.Vec3i; import common.world.State; -import common.world.Vec3i; public abstract class RotationRegistry { private static final Map MAP = new HashMap(); diff --git a/common/src/common/init/UniverseRegistry.java b/common/src/common/init/UniverseRegistry.java index 9f8451e..4986d28 100755 --- a/common/src/common/init/UniverseRegistry.java +++ b/common/src/common/init/UniverseRegistry.java @@ -31,7 +31,7 @@ import common.nbt.NBTParser; import common.nbt.NBTTagCompound; import common.nbt.NBTTagList; import common.rng.Random; -import common.world.PortalType; +import common.util.PortalType; import common.world.State; import common.world.Weather; diff --git a/common/src/common/inventory/ContainerEnchantment.java b/common/src/common/inventory/ContainerEnchantment.java index 551053a..f630bbe 100755 --- a/common/src/common/inventory/ContainerEnchantment.java +++ b/common/src/common/inventory/ContainerEnchantment.java @@ -9,7 +9,7 @@ import common.init.Blocks; import common.init.Items; import common.item.ItemStack; import common.rng.Random; -import common.world.BlockPos; +import common.util.BlockPos; import common.world.World; public class ContainerEnchantment extends Container diff --git a/common/src/common/inventory/ContainerRepair.java b/common/src/common/inventory/ContainerRepair.java index c2fa9d2..82da6ed 100755 --- a/common/src/common/inventory/ContainerRepair.java +++ b/common/src/common/inventory/ContainerRepair.java @@ -11,7 +11,7 @@ import common.init.Blocks; import common.init.Config; import common.init.Items; import common.item.ItemStack; -import common.world.BlockPos; +import common.util.BlockPos; import common.world.State; import common.world.World; diff --git a/common/src/common/inventory/ContainerWorkbench.java b/common/src/common/inventory/ContainerWorkbench.java index 2162e9e..2dce2fc 100755 --- a/common/src/common/inventory/ContainerWorkbench.java +++ b/common/src/common/inventory/ContainerWorkbench.java @@ -4,7 +4,7 @@ import common.entity.npc.EntityNPC; import common.init.Blocks; import common.init.CraftingRegistry; import common.item.ItemStack; -import common.world.BlockPos; +import common.util.BlockPos; import common.world.World; public class ContainerWorkbench extends Container diff --git a/common/src/common/inventory/ISidedInventory.java b/common/src/common/inventory/ISidedInventory.java index ad72573..2def255 100755 --- a/common/src/common/inventory/ISidedInventory.java +++ b/common/src/common/inventory/ISidedInventory.java @@ -1,7 +1,7 @@ package common.inventory; import common.item.ItemStack; -import common.world.Facing; +import common.util.Facing; public interface ISidedInventory extends IInventory { diff --git a/common/src/common/inventory/InventoryHelper.java b/common/src/common/inventory/InventoryHelper.java index 0bfc5d8..43d6151 100755 --- a/common/src/common/inventory/InventoryHelper.java +++ b/common/src/common/inventory/InventoryHelper.java @@ -5,7 +5,7 @@ import common.entity.item.EntityItem; import common.item.ItemStack; import common.nbt.NBTTagCompound; import common.rng.Random; -import common.world.BlockPos; +import common.util.BlockPos; import common.world.World; public class InventoryHelper diff --git a/common/src/common/inventory/InventoryWarpChest.java b/common/src/common/inventory/InventoryWarpChest.java index 11656be..4d83f60 100755 --- a/common/src/common/inventory/InventoryWarpChest.java +++ b/common/src/common/inventory/InventoryWarpChest.java @@ -5,7 +5,7 @@ import common.init.Blocks; import common.item.ItemStack; import common.nbt.NBTTagCompound; import common.nbt.NBTTagList; -import common.world.BlockPos; +import common.util.BlockPos; public class InventoryWarpChest extends InventoryBasic { diff --git a/common/src/common/item/Item.java b/common/src/common/item/Item.java index a0885d9..9212ab5 100755 --- a/common/src/common/item/Item.java +++ b/common/src/common/item/Item.java @@ -18,11 +18,11 @@ import common.model.ModelProvider; import common.model.Transforms; import common.nbt.NBTTagCompound; import common.rng.Random; +import common.util.BlockPos; import common.util.ExtMath; -import common.world.BlockPos; -import common.world.Facing; -import common.world.HitPosition; -import common.world.Vec3; +import common.util.Facing; +import common.util.HitPosition; +import common.util.Vec3; import common.world.World; public class Item diff --git a/common/src/common/item/ItemArmor.java b/common/src/common/item/ItemArmor.java index 8fc63a8..0529e9a 100755 --- a/common/src/common/item/ItemArmor.java +++ b/common/src/common/item/ItemArmor.java @@ -21,8 +21,8 @@ import common.model.Model; import common.model.ModelProvider; import common.model.Transforms; import common.nbt.NBTTagCompound; -import common.world.BlockPos; -import common.world.BoundingBox; +import common.util.BlockPos; +import common.util.BoundingBox; import common.world.World; public class ItemArmor extends Item diff --git a/common/src/common/item/ItemBanHammer.java b/common/src/common/item/ItemBanHammer.java index db93716..e9c61ff 100755 --- a/common/src/common/item/ItemBanHammer.java +++ b/common/src/common/item/ItemBanHammer.java @@ -6,8 +6,8 @@ import common.color.TextColor; import common.entity.DamageSource; import common.entity.npc.EntityNPC; import common.entity.types.EntityLiving; -import common.world.BoundingBox; -import common.world.Vec3; +import common.util.BoundingBox; +import common.util.Vec3; import common.world.WorldServer; public class ItemBanHammer extends ItemWand { diff --git a/common/src/common/item/ItemBanner.java b/common/src/common/item/ItemBanner.java index 6a41313..dc04e64 100755 --- a/common/src/common/item/ItemBanner.java +++ b/common/src/common/item/ItemBanner.java @@ -14,9 +14,9 @@ import common.nbt.NBTTagCompound; import common.nbt.NBTTagList; import common.tileentity.TileEntity; import common.tileentity.TileEntityBanner; +import common.util.BlockPos; import common.util.ExtMath; -import common.world.BlockPos; -import common.world.Facing; +import common.util.Facing; import common.world.World; public class ItemBanner extends ItemBlock diff --git a/common/src/common/item/ItemBed.java b/common/src/common/item/ItemBed.java index 04a9b51..f2c927e 100755 --- a/common/src/common/item/ItemBed.java +++ b/common/src/common/item/ItemBed.java @@ -3,9 +3,9 @@ package common.item; import common.block.Block; import common.block.BlockBed; import common.entity.npc.EntityNPC; +import common.util.BlockPos; import common.util.ExtMath; -import common.world.BlockPos; -import common.world.Facing; +import common.util.Facing; import common.world.State; import common.world.World; diff --git a/common/src/common/item/ItemBlock.java b/common/src/common/item/ItemBlock.java index 0a2de57..b6f4928 100755 --- a/common/src/common/item/ItemBlock.java +++ b/common/src/common/item/ItemBlock.java @@ -13,8 +13,8 @@ import common.model.ModelProvider; import common.model.Transforms; import common.nbt.NBTTagCompound; import common.tileentity.TileEntity; -import common.world.BlockPos; -import common.world.Facing; +import common.util.BlockPos; +import common.util.Facing; import common.world.State; import common.world.World; diff --git a/common/src/common/item/ItemBoat.java b/common/src/common/item/ItemBoat.java index 21894ed..1aa2ae3 100755 --- a/common/src/common/item/ItemBoat.java +++ b/common/src/common/item/ItemBoat.java @@ -6,11 +6,11 @@ import common.entity.Entity; import common.entity.item.EntityBoat; import common.entity.npc.EntityNPC; import common.init.Blocks; +import common.util.BlockPos; +import common.util.BoundingBox; import common.util.ExtMath; -import common.world.BlockPos; -import common.world.BoundingBox; -import common.world.HitPosition; -import common.world.Vec3; +import common.util.HitPosition; +import common.util.Vec3; import common.world.World; public class ItemBoat extends Item diff --git a/common/src/common/item/ItemBucket.java b/common/src/common/item/ItemBucket.java index f66c84a..b718e5b 100755 --- a/common/src/common/item/ItemBucket.java +++ b/common/src/common/item/ItemBucket.java @@ -23,10 +23,10 @@ import common.material.Material; import common.model.Model; import common.model.ModelProvider; import common.model.ParticleType; -import common.world.BlockPos; -import common.world.HitPosition; +import common.util.BlockPos; +import common.util.HitPosition; +import common.util.Vec3i; import common.world.State; -import common.world.Vec3i; import common.world.World; import common.world.WorldServer; diff --git a/common/src/common/item/ItemCamera.java b/common/src/common/item/ItemCamera.java index 30fbb78..7a19ef9 100755 --- a/common/src/common/item/ItemCamera.java +++ b/common/src/common/item/ItemCamera.java @@ -1,7 +1,7 @@ package common.item; import common.entity.npc.EntityNPC; -import common.world.BlockPos; +import common.util.BlockPos; import common.world.World; public class ItemCamera extends ItemMagnetic { diff --git a/common/src/common/item/ItemChargedOrb.java b/common/src/common/item/ItemChargedOrb.java index e156296..8e93c20 100755 --- a/common/src/common/item/ItemChargedOrb.java +++ b/common/src/common/item/ItemChargedOrb.java @@ -8,8 +8,8 @@ import common.init.Blocks; import common.init.Items; import common.init.SoundEvent; import common.model.ParticleType; -import common.world.BlockPos; -import common.world.Facing; +import common.util.BlockPos; +import common.util.Facing; import common.world.State; import common.world.World; diff --git a/common/src/common/item/ItemDoor.java b/common/src/common/item/ItemDoor.java index 54a41a7..ed84de0 100755 --- a/common/src/common/item/ItemDoor.java +++ b/common/src/common/item/ItemDoor.java @@ -5,8 +5,8 @@ import common.block.BlockDoor; import common.entity.npc.EntityNPC; import common.init.Blocks; import common.material.Material; -import common.world.BlockPos; -import common.world.Facing; +import common.util.BlockPos; +import common.util.Facing; import common.world.State; import common.world.World; diff --git a/common/src/common/item/ItemDye.java b/common/src/common/item/ItemDye.java index d2fa2e2..0849a20 100755 --- a/common/src/common/item/ItemDye.java +++ b/common/src/common/item/ItemDye.java @@ -17,8 +17,8 @@ import common.model.ModelProvider; import common.model.ParticleType; import common.tileentity.TileEntity; import common.tileentity.TileEntityBeacon; -import common.world.BlockPos; -import common.world.Facing; +import common.util.BlockPos; +import common.util.Facing; import common.world.State; import common.world.World; import common.world.WorldServer; diff --git a/common/src/common/item/ItemEditWand.java b/common/src/common/item/ItemEditWand.java index bf73170..ca542f9 100755 --- a/common/src/common/item/ItemEditWand.java +++ b/common/src/common/item/ItemEditWand.java @@ -2,7 +2,7 @@ package common.item; import common.entity.npc.EntityNPC; import common.model.Transforms; -import common.world.BlockPos; +import common.util.BlockPos; import common.world.World; public class ItemEditWand extends Item { diff --git a/common/src/common/item/ItemFireball.java b/common/src/common/item/ItemFireball.java index e3d7746..5870b25 100755 --- a/common/src/common/item/ItemFireball.java +++ b/common/src/common/item/ItemFireball.java @@ -4,8 +4,8 @@ import common.entity.npc.EntityNPC; import common.init.Blocks; import common.init.SoundEvent; import common.material.Material; -import common.world.BlockPos; -import common.world.Facing; +import common.util.BlockPos; +import common.util.Facing; import common.world.World; public class ItemFireball extends Item diff --git a/common/src/common/item/ItemFirework.java b/common/src/common/item/ItemFirework.java index 7adeda8..24450e4 100755 --- a/common/src/common/item/ItemFirework.java +++ b/common/src/common/item/ItemFirework.java @@ -7,8 +7,8 @@ import common.entity.item.EntityFireworks; import common.entity.npc.EntityNPC; import common.nbt.NBTTagCompound; import common.nbt.NBTTagList; -import common.world.BlockPos; -import common.world.Facing; +import common.util.BlockPos; +import common.util.Facing; import common.world.World; public class ItemFirework extends Item diff --git a/common/src/common/item/ItemFlintAndSteel.java b/common/src/common/item/ItemFlintAndSteel.java index ac5e63e..52ba772 100755 --- a/common/src/common/item/ItemFlintAndSteel.java +++ b/common/src/common/item/ItemFlintAndSteel.java @@ -4,8 +4,8 @@ import common.entity.npc.EntityNPC; import common.init.Blocks; import common.init.SoundEvent; import common.material.Material; -import common.world.BlockPos; -import common.world.Facing; +import common.util.BlockPos; +import common.util.Facing; import common.world.World; public class ItemFlintAndSteel extends Item diff --git a/common/src/common/item/ItemGlassBottle.java b/common/src/common/item/ItemGlassBottle.java index 84e73ed..aabb0ed 100755 --- a/common/src/common/item/ItemGlassBottle.java +++ b/common/src/common/item/ItemGlassBottle.java @@ -5,8 +5,8 @@ import common.init.Items; import common.material.Material; import common.model.Model; import common.model.ModelProvider; -import common.world.BlockPos; -import common.world.HitPosition; +import common.util.BlockPos; +import common.util.HitPosition; import common.world.World; public class ItemGlassBottle extends Item diff --git a/common/src/common/item/ItemHoe.java b/common/src/common/item/ItemHoe.java index c0cee67..d6e6678 100755 --- a/common/src/common/item/ItemHoe.java +++ b/common/src/common/item/ItemHoe.java @@ -7,8 +7,8 @@ import common.init.Blocks; import common.init.ToolMaterial; import common.material.Material; import common.model.Transforms; -import common.world.BlockPos; -import common.world.Facing; +import common.util.BlockPos; +import common.util.Facing; import common.world.State; import common.world.World; diff --git a/common/src/common/item/ItemInfoWand.java b/common/src/common/item/ItemInfoWand.java index 3b93afb..8cf4c33 100755 --- a/common/src/common/item/ItemInfoWand.java +++ b/common/src/common/item/ItemInfoWand.java @@ -3,8 +3,8 @@ package common.item; import common.biome.Biome; import common.color.TextColor; import common.entity.npc.EntityNPC; -import common.world.BlockPos; -import common.world.Vec3; +import common.util.BlockPos; +import common.util.Vec3; import common.world.WorldServer; public class ItemInfoWand extends ItemWand { diff --git a/common/src/common/item/ItemLead.java b/common/src/common/item/ItemLead.java index fb8e6e8..263e5f3 100755 --- a/common/src/common/item/ItemLead.java +++ b/common/src/common/item/ItemLead.java @@ -5,9 +5,9 @@ import common.block.BlockFence; import common.entity.item.EntityLeashKnot; import common.entity.npc.EntityNPC; import common.entity.types.EntityLiving; -import common.world.BlockPos; -import common.world.BoundingBox; -import common.world.Facing; +import common.util.BlockPos; +import common.util.BoundingBox; +import common.util.Facing; import common.world.World; public class ItemLead extends Item diff --git a/common/src/common/item/ItemLightning.java b/common/src/common/item/ItemLightning.java index e3c8080..68a4779 100755 --- a/common/src/common/item/ItemLightning.java +++ b/common/src/common/item/ItemLightning.java @@ -2,7 +2,7 @@ package common.item; import common.color.TextColor; import common.entity.npc.EntityNPC; -import common.world.Vec3; +import common.util.Vec3; import common.world.WorldServer; public class ItemLightning extends ItemWand { diff --git a/common/src/common/item/ItemLilyPad.java b/common/src/common/item/ItemLilyPad.java index d56843e..6a69dc2 100755 --- a/common/src/common/item/ItemLilyPad.java +++ b/common/src/common/item/ItemLilyPad.java @@ -5,8 +5,8 @@ import common.block.BlockDirectional; import common.block.BlockLiquid; import common.entity.npc.EntityNPC; import common.init.Blocks; -import common.world.BlockPos; -import common.world.HitPosition; +import common.util.BlockPos; +import common.util.HitPosition; import common.world.State; import common.world.World; diff --git a/common/src/common/item/ItemMagnet.java b/common/src/common/item/ItemMagnet.java index bf9c45a..c7dfa31 100755 --- a/common/src/common/item/ItemMagnet.java +++ b/common/src/common/item/ItemMagnet.java @@ -7,8 +7,8 @@ import common.entity.Entity; import common.entity.animal.EntityChicken; import common.entity.npc.EntityNPC; import common.model.Transforms; -import common.world.BoundingBox; -import common.world.Vec3; +import common.util.BoundingBox; +import common.util.Vec3; import common.world.World; public class ItemMagnet extends Item { diff --git a/common/src/common/item/ItemMinecart.java b/common/src/common/item/ItemMinecart.java index 66e8a4d..73ab5b6 100755 --- a/common/src/common/item/ItemMinecart.java +++ b/common/src/common/item/ItemMinecart.java @@ -9,8 +9,8 @@ import common.entity.item.EntityCart; import common.entity.npc.EntityNPC; import common.init.DispenserRegistry; import common.material.Material; -import common.world.BlockPos; -import common.world.Facing; +import common.util.BlockPos; +import common.util.Facing; import common.world.State; import common.world.World; diff --git a/common/src/common/item/ItemMonsterPlacer.java b/common/src/common/item/ItemMonsterPlacer.java index f24d1d6..45a1c85 100755 --- a/common/src/common/item/ItemMonsterPlacer.java +++ b/common/src/common/item/ItemMonsterPlacer.java @@ -17,10 +17,10 @@ import common.model.Model; import common.model.ModelProvider; import common.tileentity.TileEntity; import common.tileentity.TileEntityMobSpawner; +import common.util.BlockPos; import common.util.ExtMath; -import common.world.BlockPos; -import common.world.Facing; -import common.world.HitPosition; +import common.util.Facing; +import common.util.HitPosition; import common.world.State; import common.world.World; diff --git a/common/src/common/item/ItemNpcSpawner.java b/common/src/common/item/ItemNpcSpawner.java index 31fa225..1f81811 100755 --- a/common/src/common/item/ItemNpcSpawner.java +++ b/common/src/common/item/ItemNpcSpawner.java @@ -16,10 +16,10 @@ import common.init.EntityRegistry; import common.init.UniverseRegistry; import common.model.Model; import common.model.ModelProvider; +import common.util.BlockPos; import common.util.ExtMath; -import common.world.BlockPos; -import common.world.Facing; -import common.world.HitPosition; +import common.util.Facing; +import common.util.HitPosition; import common.world.State; import common.world.World; diff --git a/common/src/common/item/ItemRedstone.java b/common/src/common/item/ItemRedstone.java index 53fc6be..fa090d4 100755 --- a/common/src/common/item/ItemRedstone.java +++ b/common/src/common/item/ItemRedstone.java @@ -4,8 +4,8 @@ import common.block.Block; import common.entity.Entity; import common.entity.npc.EntityNPC; import common.init.Blocks; -import common.world.BlockPos; -import common.world.Facing; +import common.util.BlockPos; +import common.util.Facing; import common.world.World; public class ItemRedstone extends Item diff --git a/common/src/common/item/ItemReed.java b/common/src/common/item/ItemReed.java index 1538e73..263df61 100755 --- a/common/src/common/item/ItemReed.java +++ b/common/src/common/item/ItemReed.java @@ -5,8 +5,8 @@ import common.block.BlockSnow; import common.entity.Entity; import common.entity.npc.EntityNPC; import common.init.Blocks; -import common.world.BlockPos; -import common.world.Facing; +import common.util.BlockPos; +import common.util.Facing; import common.world.State; import common.world.World; diff --git a/common/src/common/item/ItemSeedFood.java b/common/src/common/item/ItemSeedFood.java index abe4ad1..7347a5c 100755 --- a/common/src/common/item/ItemSeedFood.java +++ b/common/src/common/item/ItemSeedFood.java @@ -2,8 +2,8 @@ package common.item; import common.block.Block; import common.entity.npc.EntityNPC; -import common.world.BlockPos; -import common.world.Facing; +import common.util.BlockPos; +import common.util.Facing; import common.world.World; public class ItemSeedFood extends ItemFood diff --git a/common/src/common/item/ItemSeeds.java b/common/src/common/item/ItemSeeds.java index 9cbcadf..2bf6656 100755 --- a/common/src/common/item/ItemSeeds.java +++ b/common/src/common/item/ItemSeeds.java @@ -3,8 +3,8 @@ package common.item; import common.block.Block; import common.entity.npc.EntityNPC; import common.model.Transforms; -import common.world.BlockPos; -import common.world.Facing; +import common.util.BlockPos; +import common.util.Facing; import common.world.World; public class ItemSeeds extends Item diff --git a/common/src/common/item/ItemShears.java b/common/src/common/item/ItemShears.java index dc40068..515d799 100755 --- a/common/src/common/item/ItemShears.java +++ b/common/src/common/item/ItemShears.java @@ -5,7 +5,7 @@ import common.entity.types.EntityLiving; import common.init.Blocks; import common.init.ToolMaterial; import common.material.Material; -import common.world.BlockPos; +import common.util.BlockPos; import common.world.World; public class ItemShears extends Item diff --git a/common/src/common/item/ItemSign.java b/common/src/common/item/ItemSign.java index 07affb8..81719ad 100755 --- a/common/src/common/item/ItemSign.java +++ b/common/src/common/item/ItemSign.java @@ -7,9 +7,9 @@ import common.entity.npc.EntityNPC; import common.init.Blocks; import common.tileentity.TileEntity; import common.tileentity.TileEntitySign; +import common.util.BlockPos; import common.util.ExtMath; -import common.world.BlockPos; -import common.world.Facing; +import common.util.Facing; import common.world.World; public class ItemSign extends Item diff --git a/common/src/common/item/ItemSkull.java b/common/src/common/item/ItemSkull.java index da83cc3..ce5443e 100755 --- a/common/src/common/item/ItemSkull.java +++ b/common/src/common/item/ItemSkull.java @@ -9,9 +9,9 @@ import common.model.ModelProvider; import common.model.Transforms; import common.tileentity.TileEntity; import common.tileentity.TileEntitySkull; +import common.util.BlockPos; import common.util.ExtMath; -import common.world.BlockPos; -import common.world.Facing; +import common.util.Facing; import common.world.State; import common.world.World; diff --git a/common/src/common/item/ItemSlab.java b/common/src/common/item/ItemSlab.java index fa3d824..4b171ba 100755 --- a/common/src/common/item/ItemSlab.java +++ b/common/src/common/item/ItemSlab.java @@ -3,8 +3,8 @@ package common.item; import common.block.Block; import common.block.BlockSlab; import common.entity.npc.EntityNPC; -import common.world.BlockPos; -import common.world.Facing; +import common.util.BlockPos; +import common.util.Facing; import common.world.State; import common.world.World; diff --git a/common/src/common/item/ItemSnow.java b/common/src/common/item/ItemSnow.java index 4dbd517..d98bc65 100755 --- a/common/src/common/item/ItemSnow.java +++ b/common/src/common/item/ItemSnow.java @@ -3,9 +3,9 @@ package common.item; import common.block.Block; import common.block.BlockSnow; import common.entity.npc.EntityNPC; -import common.world.BlockPos; -import common.world.BoundingBox; -import common.world.Facing; +import common.util.BlockPos; +import common.util.BoundingBox; +import common.util.Facing; import common.world.State; import common.world.World; diff --git a/common/src/common/item/ItemSpaceNavigator.java b/common/src/common/item/ItemSpaceNavigator.java index 5702a15..5c256ad 100755 --- a/common/src/common/item/ItemSpaceNavigator.java +++ b/common/src/common/item/ItemSpaceNavigator.java @@ -5,7 +5,7 @@ import java.util.List; import common.color.TextColor; import common.entity.npc.EntityNPC; import common.init.UniverseRegistry; -import common.world.BlockPos; +import common.util.BlockPos; import common.world.World; public class ItemSpaceNavigator extends ItemMagnetic { diff --git a/common/src/common/item/ItemStack.java b/common/src/common/item/ItemStack.java index a24ad02..a25e49c 100755 --- a/common/src/common/item/ItemStack.java +++ b/common/src/common/item/ItemStack.java @@ -23,8 +23,8 @@ import common.nbt.NBTBase; import common.nbt.NBTTagCompound; import common.nbt.NBTTagList; import common.rng.Random; -import common.world.BlockPos; -import common.world.Facing; +import common.util.BlockPos; +import common.util.Facing; import common.world.World; import java.util.Set; diff --git a/common/src/common/item/ItemSword.java b/common/src/common/item/ItemSword.java index fb9c576..9ae7bc8 100755 --- a/common/src/common/item/ItemSword.java +++ b/common/src/common/item/ItemSword.java @@ -14,7 +14,7 @@ import common.init.Blocks; import common.init.ToolMaterial; import common.material.Material; import common.model.Transforms; -import common.world.BlockPos; +import common.util.BlockPos; import common.world.World; public class ItemSword extends Item diff --git a/common/src/common/item/ItemTool.java b/common/src/common/item/ItemTool.java index 039ca45..4c58202 100755 --- a/common/src/common/item/ItemTool.java +++ b/common/src/common/item/ItemTool.java @@ -11,7 +11,7 @@ import common.entity.attributes.Attributes; import common.entity.types.EntityLiving; import common.init.ToolMaterial; import common.model.Transforms; -import common.world.BlockPos; +import common.util.BlockPos; import common.world.World; public abstract class ItemTool extends Item diff --git a/common/src/common/item/ItemWand.java b/common/src/common/item/ItemWand.java index 34eb6f6..880f6c8 100755 --- a/common/src/common/item/ItemWand.java +++ b/common/src/common/item/ItemWand.java @@ -5,10 +5,10 @@ import java.util.List; import common.color.TextColor; import common.entity.npc.EntityNPC; import common.model.Transforms; +import common.util.BlockPos; import common.util.ExtMath; -import common.world.BlockPos; -import common.world.Facing; -import common.world.Vec3; +import common.util.Facing; +import common.util.Vec3; import common.world.World; import common.world.WorldServer; diff --git a/common/src/common/model/Model.java b/common/src/common/model/Model.java index 378a18a..8affcad 100644 --- a/common/src/common/model/Model.java +++ b/common/src/common/model/Model.java @@ -1,6 +1,6 @@ package common.model; -import common.world.Facing; +import common.util.Facing; public abstract class Model { public abstract Model noOcclude(); diff --git a/common/src/common/model/ModelProvider.java b/common/src/common/model/ModelProvider.java index 5805eaf..f4cb0bf 100644 --- a/common/src/common/model/ModelProvider.java +++ b/common/src/common/model/ModelProvider.java @@ -1,7 +1,7 @@ package common.model; -import common.world.Facing; -import common.world.Facing.Axis; +import common.util.Facing; +import common.util.Facing.Axis; public interface ModelProvider { Model getModel(String primary); diff --git a/common/src/common/model/ModelRotation.java b/common/src/common/model/ModelRotation.java index 0329240..b4c1973 100755 --- a/common/src/common/model/ModelRotation.java +++ b/common/src/common/model/ModelRotation.java @@ -4,9 +4,9 @@ import java.util.Map; import common.collect.Maps; import common.util.ExtMath; +import common.util.Facing; import common.util.Matrix4f; import common.util.Vector3f; -import common.world.Facing; public enum ModelRotation { diff --git a/common/src/common/network/IClientPlayer.java b/common/src/common/network/IClientPlayer.java index 881d9cb..c5ff27d 100644 --- a/common/src/common/network/IClientPlayer.java +++ b/common/src/common/network/IClientPlayer.java @@ -65,7 +65,7 @@ import common.packet.SPacketTrades; import common.packet.SPacketUpdateHealth; import common.packet.SPacketWorld; import common.tileentity.IInteractionObject; -import common.world.BlockPos; +import common.util.BlockPos; import common.world.World; public interface IClientPlayer { diff --git a/common/src/common/network/IPlayer.java b/common/src/common/network/IPlayer.java index e819468..a78d4fb 100644 --- a/common/src/common/network/IPlayer.java +++ b/common/src/common/network/IPlayer.java @@ -26,10 +26,10 @@ import common.packet.CPacketSkin; import common.potion.PotionEffect; import common.tileentity.IInteractionObject; import common.tileentity.TileEntitySign; +import common.util.BlockPos; import common.util.CharValidator; -import common.world.BlockPos; -import common.world.ChunkPos; -import common.world.PortalType; +import common.util.ChunkPos; +import common.util.PortalType; public interface IPlayer { public static class UserValidator implements CharValidator { diff --git a/common/src/common/network/PacketBuffer.java b/common/src/common/network/PacketBuffer.java index a845416..4d0df41 100755 --- a/common/src/common/network/PacketBuffer.java +++ b/common/src/common/network/PacketBuffer.java @@ -8,7 +8,7 @@ import common.item.ItemStack; import common.nbt.NBTLoader; import common.nbt.NBTSizeTracker; import common.nbt.NBTTagCompound; -import common.world.BlockPos; +import common.util.BlockPos; import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBufInputStream; import io.netty.buffer.ByteBufOutputStream; diff --git a/common/src/common/packet/CPacketBreak.java b/common/src/common/packet/CPacketBreak.java index 1de2c0b..64dc2e4 100755 --- a/common/src/common/packet/CPacketBreak.java +++ b/common/src/common/packet/CPacketBreak.java @@ -5,8 +5,8 @@ import java.io.IOException; import common.network.IPlayer; import common.network.Packet; import common.network.PacketBuffer; -import common.world.BlockPos; -import common.world.Facing; +import common.util.BlockPos; +import common.util.Facing; public class CPacketBreak implements Packet { diff --git a/common/src/common/packet/CPacketComplete.java b/common/src/common/packet/CPacketComplete.java index 74190cc..31b0cc6 100755 --- a/common/src/common/packet/CPacketComplete.java +++ b/common/src/common/packet/CPacketComplete.java @@ -5,7 +5,7 @@ import java.io.IOException; import common.network.IPlayer; import common.network.Packet; import common.network.PacketBuffer; -import common.world.BlockPos; +import common.util.BlockPos; public class CPacketComplete implements Packet { diff --git a/common/src/common/packet/CPacketPlace.java b/common/src/common/packet/CPacketPlace.java index 9c91b4b..c082f6e 100755 --- a/common/src/common/packet/CPacketPlace.java +++ b/common/src/common/packet/CPacketPlace.java @@ -6,7 +6,7 @@ import common.item.ItemStack; import common.network.IPlayer; import common.network.Packet; import common.network.PacketBuffer; -import common.world.BlockPos; +import common.util.BlockPos; public class CPacketPlace implements Packet { diff --git a/common/src/common/packet/CPacketSign.java b/common/src/common/packet/CPacketSign.java index 3158172..3653f78 100755 --- a/common/src/common/packet/CPacketSign.java +++ b/common/src/common/packet/CPacketSign.java @@ -5,7 +5,7 @@ import java.io.IOException; import common.network.IPlayer; import common.network.Packet; import common.network.PacketBuffer; -import common.world.BlockPos; +import common.util.BlockPos; public class CPacketSign implements Packet { diff --git a/common/src/common/packet/S27PacketExplosion.java b/common/src/common/packet/S27PacketExplosion.java index 4d76e68..85f90ee 100755 --- a/common/src/common/packet/S27PacketExplosion.java +++ b/common/src/common/packet/S27PacketExplosion.java @@ -8,8 +8,8 @@ import common.collect.Lists; import common.network.IClientPlayer; import common.network.Packet; import common.network.PacketBuffer; -import common.world.BlockPos; -import common.world.Vec3; +import common.util.BlockPos; +import common.util.Vec3; public class S27PacketExplosion implements Packet { diff --git a/common/src/common/packet/S28PacketEffect.java b/common/src/common/packet/S28PacketEffect.java index 6e9915f..cd826e2 100755 --- a/common/src/common/packet/S28PacketEffect.java +++ b/common/src/common/packet/S28PacketEffect.java @@ -5,7 +5,7 @@ import java.io.IOException; import common.network.IClientPlayer; import common.network.Packet; import common.network.PacketBuffer; -import common.world.BlockPos; +import common.util.BlockPos; public class S28PacketEffect implements Packet { private int soundType; diff --git a/common/src/common/packet/S2DPacketOpenWindow.java b/common/src/common/packet/S2DPacketOpenWindow.java index 38246fe..6fb2370 100755 --- a/common/src/common/packet/S2DPacketOpenWindow.java +++ b/common/src/common/packet/S2DPacketOpenWindow.java @@ -5,7 +5,7 @@ import java.io.IOException; import common.network.IClientPlayer; import common.network.Packet; import common.network.PacketBuffer; -import common.world.BlockPos; +import common.util.BlockPos; public class S2DPacketOpenWindow implements Packet { diff --git a/common/src/common/packet/S33PacketUpdateSign.java b/common/src/common/packet/S33PacketUpdateSign.java index dc8b266..8c75e28 100755 --- a/common/src/common/packet/S33PacketUpdateSign.java +++ b/common/src/common/packet/S33PacketUpdateSign.java @@ -5,7 +5,7 @@ import java.io.IOException; import common.network.IClientPlayer; import common.network.Packet; import common.network.PacketBuffer; -import common.world.BlockPos; +import common.util.BlockPos; import common.world.World; public class S33PacketUpdateSign implements Packet diff --git a/common/src/common/packet/S35PacketUpdateTileEntity.java b/common/src/common/packet/S35PacketUpdateTileEntity.java index 7c0aa3d..c44844c 100755 --- a/common/src/common/packet/S35PacketUpdateTileEntity.java +++ b/common/src/common/packet/S35PacketUpdateTileEntity.java @@ -8,7 +8,7 @@ import common.network.IClientPlayer; import common.network.Packet; import common.network.PacketBuffer; import common.tileentity.TileEntity; -import common.world.BlockPos; +import common.util.BlockPos; public class S35PacketUpdateTileEntity implements Packet { diff --git a/common/src/common/packet/S36PacketSignEditorOpen.java b/common/src/common/packet/S36PacketSignEditorOpen.java index 29d3f03..1059d0c 100755 --- a/common/src/common/packet/S36PacketSignEditorOpen.java +++ b/common/src/common/packet/S36PacketSignEditorOpen.java @@ -5,7 +5,7 @@ import java.io.IOException; import common.network.IClientPlayer; import common.network.Packet; import common.network.PacketBuffer; -import common.world.BlockPos; +import common.util.BlockPos; public class S36PacketSignEditorOpen implements Packet { diff --git a/common/src/common/packet/SPacketBlockAction.java b/common/src/common/packet/SPacketBlockAction.java index 5de2cac..239d6eb 100755 --- a/common/src/common/packet/SPacketBlockAction.java +++ b/common/src/common/packet/SPacketBlockAction.java @@ -7,7 +7,7 @@ import common.init.BlockRegistry; import common.network.IClientPlayer; import common.network.Packet; import common.network.PacketBuffer; -import common.world.BlockPos; +import common.util.BlockPos; public class SPacketBlockAction implements Packet { diff --git a/common/src/common/packet/SPacketBlockBreakAnim.java b/common/src/common/packet/SPacketBlockBreakAnim.java index d6f613c..ccebc7e 100755 --- a/common/src/common/packet/SPacketBlockBreakAnim.java +++ b/common/src/common/packet/SPacketBlockBreakAnim.java @@ -5,7 +5,7 @@ import java.io.IOException; import common.network.IClientPlayer; import common.network.Packet; import common.network.PacketBuffer; -import common.world.BlockPos; +import common.util.BlockPos; public class SPacketBlockBreakAnim implements Packet { diff --git a/common/src/common/packet/SPacketBlockChange.java b/common/src/common/packet/SPacketBlockChange.java index d60fd10..9ab2a01 100755 --- a/common/src/common/packet/SPacketBlockChange.java +++ b/common/src/common/packet/SPacketBlockChange.java @@ -6,7 +6,7 @@ import common.init.BlockRegistry; import common.network.IClientPlayer; import common.network.Packet; import common.network.PacketBuffer; -import common.world.BlockPos; +import common.util.BlockPos; import common.world.State; import common.world.World; diff --git a/common/src/common/packet/SPacketCharacterList.java b/common/src/common/packet/SPacketCharacterList.java index b5b13b8..8978d9d 100644 --- a/common/src/common/packet/SPacketCharacterList.java +++ b/common/src/common/packet/SPacketCharacterList.java @@ -12,7 +12,7 @@ import common.network.IClientPlayer; import common.network.IPlayer; import common.network.Packet; import common.network.PacketBuffer; -import common.world.BlockPos; +import common.util.BlockPos; public class SPacketCharacterList implements Packet { private final Map players = Maps.newHashMap(); diff --git a/common/src/common/packet/SPacketMultiBlockChange.java b/common/src/common/packet/SPacketMultiBlockChange.java index 8769e0a..97d5e60 100755 --- a/common/src/common/packet/SPacketMultiBlockChange.java +++ b/common/src/common/packet/SPacketMultiBlockChange.java @@ -6,9 +6,9 @@ import common.init.BlockRegistry; import common.network.IClientPlayer; import common.network.Packet; import common.network.PacketBuffer; -import common.world.BlockPos; +import common.util.BlockPos; +import common.util.ChunkPos; import common.world.Chunk; -import common.world.ChunkPos; import common.world.State; public class SPacketMultiBlockChange implements Packet diff --git a/common/src/common/packet/SPacketSpawnObject.java b/common/src/common/packet/SPacketSpawnObject.java index 5058f62..6af450a 100755 --- a/common/src/common/packet/SPacketSpawnObject.java +++ b/common/src/common/packet/SPacketSpawnObject.java @@ -10,9 +10,9 @@ import common.init.EntityRegistry; import common.network.IClientPlayer; import common.network.Packet; import common.network.PacketBuffer; +import common.util.BlockPos; import common.util.ExtMath; -import common.world.BlockPos; -import common.world.Vec3; +import common.util.Vec3; public class SPacketSpawnObject implements Packet { diff --git a/common/src/common/pathfinding/NodeProcessor.java b/common/src/common/pathfinding/NodeProcessor.java index 8dc172e..ba397bc 100755 --- a/common/src/common/pathfinding/NodeProcessor.java +++ b/common/src/common/pathfinding/NodeProcessor.java @@ -2,7 +2,7 @@ package common.pathfinding; import common.entity.Entity; import common.util.ExtMath; -import common.world.IntHashMap; +import common.util.IntHashMap; public abstract class NodeProcessor { diff --git a/common/src/common/pathfinding/PathCache.java b/common/src/common/pathfinding/PathCache.java index 1dc0239..3af36a8 100755 --- a/common/src/common/pathfinding/PathCache.java +++ b/common/src/common/pathfinding/PathCache.java @@ -1,7 +1,7 @@ package common.pathfinding; import common.init.Blocks; -import common.world.BlockPos; +import common.util.BlockPos; import common.world.Chunk; import common.world.ChunkCache; import common.world.IBlockAccess; diff --git a/common/src/common/pathfinding/PathEntity.java b/common/src/common/pathfinding/PathEntity.java index 593e6e3..85f8e74 100755 --- a/common/src/common/pathfinding/PathEntity.java +++ b/common/src/common/pathfinding/PathEntity.java @@ -1,7 +1,7 @@ package common.pathfinding; import common.entity.Entity; -import common.world.Vec3; +import common.util.Vec3; public class PathEntity { diff --git a/common/src/common/pathfinding/PathFinder.java b/common/src/common/pathfinding/PathFinder.java index db9798e..52b4569 100755 --- a/common/src/common/pathfinding/PathFinder.java +++ b/common/src/common/pathfinding/PathFinder.java @@ -1,7 +1,7 @@ package common.pathfinding; import common.entity.Entity; -import common.world.BlockPos; +import common.util.BlockPos; public class PathFinder { diff --git a/common/src/common/pathfinding/PathNavigate.java b/common/src/common/pathfinding/PathNavigate.java index fb749ca..ee406dd 100755 --- a/common/src/common/pathfinding/PathNavigate.java +++ b/common/src/common/pathfinding/PathNavigate.java @@ -6,10 +6,10 @@ import common.entity.Entity; import common.entity.attributes.AttributeInstance; import common.entity.attributes.Attributes; import common.entity.types.EntityLiving; +import common.util.BlockPos; +import common.util.BoundingBox; import common.util.ExtMath; -import common.world.BlockPos; -import common.world.BoundingBox; -import common.world.Vec3; +import common.util.Vec3; import common.world.World; public abstract class PathNavigate diff --git a/common/src/common/pathfinding/PathNavigateClimber.java b/common/src/common/pathfinding/PathNavigateClimber.java index 02388f6..0632fe2 100755 --- a/common/src/common/pathfinding/PathNavigateClimber.java +++ b/common/src/common/pathfinding/PathNavigateClimber.java @@ -2,8 +2,8 @@ package common.pathfinding; import common.entity.Entity; import common.entity.types.EntityLiving; +import common.util.BlockPos; import common.util.ExtMath; -import common.world.BlockPos; import common.world.World; public class PathNavigateClimber extends PathNavigateGround diff --git a/common/src/common/pathfinding/PathNavigateGround.java b/common/src/common/pathfinding/PathNavigateGround.java index 0fd0d79..f12b1c8 100755 --- a/common/src/common/pathfinding/PathNavigateGround.java +++ b/common/src/common/pathfinding/PathNavigateGround.java @@ -5,9 +5,9 @@ import common.entity.animal.EntityChicken; import common.entity.npc.EntityZombie; import common.entity.types.EntityLiving; import common.material.Material; +import common.util.BlockPos; import common.util.ExtMath; -import common.world.BlockPos; -import common.world.Vec3; +import common.util.Vec3; import common.world.World; public class PathNavigateGround extends PathNavigate diff --git a/common/src/common/pathfinding/SwimNodeProcessor.java b/common/src/common/pathfinding/SwimNodeProcessor.java index 57e13ae..cebffbb 100755 --- a/common/src/common/pathfinding/SwimNodeProcessor.java +++ b/common/src/common/pathfinding/SwimNodeProcessor.java @@ -2,9 +2,9 @@ package common.pathfinding; import common.block.Block; import common.entity.Entity; +import common.util.BlockPos; import common.util.ExtMath; -import common.world.BlockPos; -import common.world.Facing; +import common.util.Facing; public class SwimNodeProcessor extends NodeProcessor { diff --git a/common/src/common/pathfinding/WalkNodeProcessor.java b/common/src/common/pathfinding/WalkNodeProcessor.java index 1f6a96e..1233bcd 100755 --- a/common/src/common/pathfinding/WalkNodeProcessor.java +++ b/common/src/common/pathfinding/WalkNodeProcessor.java @@ -9,8 +9,8 @@ import common.block.BlockWall; import common.entity.Entity; import common.init.Blocks; import common.material.Material; +import common.util.BlockPos; import common.util.ExtMath; -import common.world.BlockPos; import common.world.IBlockAccess; public class WalkNodeProcessor extends NodeProcessor diff --git a/common/src/common/properties/PropertyDirection.java b/common/src/common/properties/PropertyDirection.java index 4c08522..88ba891 100755 --- a/common/src/common/properties/PropertyDirection.java +++ b/common/src/common/properties/PropertyDirection.java @@ -5,8 +5,8 @@ import java.util.function.Predicate; import common.collect.Filter; import common.collect.Lists; +import common.util.Facing; import common.util.Predicates; -import common.world.Facing; public class PropertyDirection extends PropertyEnum { diff --git a/common/src/common/tileentity/TileEntity.java b/common/src/common/tileentity/TileEntity.java index ea72613..45c47a9 100755 --- a/common/src/common/tileentity/TileEntity.java +++ b/common/src/common/tileentity/TileEntity.java @@ -6,7 +6,7 @@ import common.init.TileRegistry; import common.log.Log; import common.nbt.NBTTagCompound; import common.network.Packet; -import common.world.BlockPos; +import common.util.BlockPos; import common.world.State; import common.world.World; diff --git a/common/src/common/tileentity/TileEntityBeacon.java b/common/src/common/tileentity/TileEntityBeacon.java index 23ecca3..97ffe57 100755 --- a/common/src/common/tileentity/TileEntityBeacon.java +++ b/common/src/common/tileentity/TileEntityBeacon.java @@ -11,8 +11,8 @@ import common.network.Packet; import common.packet.S35PacketUpdateTileEntity; import common.potion.Potion; import common.potion.PotionEffect; -import common.world.BlockPos; -import common.world.BoundingBox; +import common.util.BlockPos; +import common.util.BoundingBox; import common.world.State; import common.world.World; import common.world.WorldServer; diff --git a/common/src/common/tileentity/TileEntityBrewingStand.java b/common/src/common/tileentity/TileEntityBrewingStand.java index 8af4271..3ae0f5e 100755 --- a/common/src/common/tileentity/TileEntityBrewingStand.java +++ b/common/src/common/tileentity/TileEntityBrewingStand.java @@ -17,7 +17,7 @@ import common.nbt.NBTTagCompound; import common.nbt.NBTTagList; import common.potion.PotionEffect; import common.potion.PotionHelper; -import common.world.Facing; +import common.util.Facing; import common.world.State; public class TileEntityBrewingStand extends TileEntityLockable implements ITickable, ISidedInventory diff --git a/common/src/common/tileentity/TileEntityChest.java b/common/src/common/tileentity/TileEntityChest.java index c1e465f..b85965f 100755 --- a/common/src/common/tileentity/TileEntityChest.java +++ b/common/src/common/tileentity/TileEntityChest.java @@ -12,9 +12,9 @@ import common.inventory.InventoryPlayer; import common.item.ItemStack; import common.nbt.NBTTagCompound; import common.nbt.NBTTagList; -import common.world.BlockPos; -import common.world.BoundingBox; -import common.world.Facing; +import common.util.BlockPos; +import common.util.BoundingBox; +import common.util.Facing; public class TileEntityChest extends TileEntityLockable implements ITickable, IInventory { diff --git a/common/src/common/tileentity/TileEntityFurnace.java b/common/src/common/tileentity/TileEntityFurnace.java index f2dae36..af1c0f3 100755 --- a/common/src/common/tileentity/TileEntityFurnace.java +++ b/common/src/common/tileentity/TileEntityFurnace.java @@ -26,7 +26,7 @@ import common.material.Material; import common.nbt.NBTTagCompound; import common.nbt.NBTTagList; import common.util.ExtMath; -import common.world.Facing; +import common.util.Facing; public class TileEntityFurnace extends TileEntityLockable implements ITickable, ISidedInventory { diff --git a/common/src/common/tileentity/TileEntityHopper.java b/common/src/common/tileentity/TileEntityHopper.java index 736bc88..60db278 100755 --- a/common/src/common/tileentity/TileEntityHopper.java +++ b/common/src/common/tileentity/TileEntityHopper.java @@ -18,10 +18,10 @@ import common.inventory.InventoryPlayer; import common.item.ItemStack; import common.nbt.NBTTagCompound; import common.nbt.NBTTagList; +import common.util.BlockPos; +import common.util.BoundingBox; import common.util.ExtMath; -import common.world.BlockPos; -import common.world.BoundingBox; -import common.world.Facing; +import common.util.Facing; import common.world.World; public class TileEntityHopper extends TileEntityLockable implements IHopper, ITickable diff --git a/common/src/common/tileentity/TileEntityMobSpawner.java b/common/src/common/tileentity/TileEntityMobSpawner.java index 1105fa3..0847f04 100755 --- a/common/src/common/tileentity/TileEntityMobSpawner.java +++ b/common/src/common/tileentity/TileEntityMobSpawner.java @@ -9,8 +9,8 @@ import common.model.ParticleType; import common.nbt.NBTTagCompound; import common.network.Packet; import common.packet.S35PacketUpdateTileEntity; -import common.world.BlockPos; -import common.world.BoundingBox; +import common.util.BlockPos; +import common.util.BoundingBox; import common.world.World; public class TileEntityMobSpawner extends TileEntity implements ITickable diff --git a/common/src/common/tileentity/TileEntityNote.java b/common/src/common/tileentity/TileEntityNote.java index c3d4238..214d94c 100755 --- a/common/src/common/tileentity/TileEntityNote.java +++ b/common/src/common/tileentity/TileEntityNote.java @@ -3,8 +3,8 @@ package common.tileentity; import common.init.Blocks; import common.material.Material; import common.nbt.NBTTagCompound; +import common.util.BlockPos; import common.util.ExtMath; -import common.world.BlockPos; import common.world.World; public class TileEntityNote extends TileEntity diff --git a/common/src/common/tileentity/TileEntityPiston.java b/common/src/common/tileentity/TileEntityPiston.java index e84301f..d4cc931 100755 --- a/common/src/common/tileentity/TileEntityPiston.java +++ b/common/src/common/tileentity/TileEntityPiston.java @@ -7,8 +7,8 @@ import common.entity.Entity; import common.init.BlockRegistry; import common.init.Blocks; import common.nbt.NBTTagCompound; -import common.world.BoundingBox; -import common.world.Facing; +import common.util.BoundingBox; +import common.util.Facing; import common.world.State; public class TileEntityPiston extends TileEntity implements ITickable diff --git a/common/src/common/world/BlockPos.java b/common/src/common/util/BlockPos.java similarity index 99% rename from common/src/common/world/BlockPos.java rename to common/src/common/util/BlockPos.java index 1288f53..493452c 100755 --- a/common/src/common/world/BlockPos.java +++ b/common/src/common/util/BlockPos.java @@ -1,4 +1,4 @@ -package common.world; +package common.util; import java.util.Iterator; diff --git a/common/src/common/world/BoundingBox.java b/common/src/common/util/BoundingBox.java similarity index 99% rename from common/src/common/world/BoundingBox.java rename to common/src/common/util/BoundingBox.java index c7b02c1..15206f5 100755 --- a/common/src/common/world/BoundingBox.java +++ b/common/src/common/util/BoundingBox.java @@ -1,6 +1,6 @@ -package common.world; +package common.util; -import common.world.HitPosition.ObjectType; +import common.util.HitPosition.ObjectType; public class BoundingBox { diff --git a/common/src/common/world/ChunkPos.java b/common/src/common/util/ChunkPos.java similarity index 96% rename from common/src/common/world/ChunkPos.java rename to common/src/common/util/ChunkPos.java index 0e8fc2e..32a1c8e 100755 --- a/common/src/common/world/ChunkPos.java +++ b/common/src/common/util/ChunkPos.java @@ -1,4 +1,4 @@ -package common.world; +package common.util; public class ChunkPos { public final int x; diff --git a/common/src/common/world/ClassInheritanceMultiMap.java b/common/src/common/util/ClassInheritanceMultiMap.java similarity index 99% rename from common/src/common/world/ClassInheritanceMultiMap.java rename to common/src/common/util/ClassInheritanceMultiMap.java index c5f9e93..78b03ec 100755 --- a/common/src/common/world/ClassInheritanceMultiMap.java +++ b/common/src/common/util/ClassInheritanceMultiMap.java @@ -1,4 +1,4 @@ -package common.world; +package common.util; import java.util.AbstractSet; import java.util.Collections; diff --git a/common/src/common/world/Facing.java b/common/src/common/util/Facing.java similarity index 99% rename from common/src/common/world/Facing.java rename to common/src/common/util/Facing.java index 66d901a..47e093b 100755 --- a/common/src/common/world/Facing.java +++ b/common/src/common/util/Facing.java @@ -1,4 +1,4 @@ -package common.world; +package common.util; import java.util.Iterator; import java.util.Map; @@ -7,8 +7,6 @@ import java.util.function.Predicate; import common.collect.Iterators; import common.collect.Maps; import common.rng.Random; -import common.util.ExtMath; -import common.util.Identifyable; public enum Facing implements Identifyable { diff --git a/common/src/common/world/HitPosition.java b/common/src/common/util/HitPosition.java similarity index 97% rename from common/src/common/world/HitPosition.java rename to common/src/common/util/HitPosition.java index 940d092..74e90e1 100755 --- a/common/src/common/world/HitPosition.java +++ b/common/src/common/util/HitPosition.java @@ -1,4 +1,4 @@ -package common.world; +package common.util; import common.entity.Entity; diff --git a/common/src/common/world/IntHashMap.java b/common/src/common/util/IntHashMap.java similarity index 99% rename from common/src/common/world/IntHashMap.java rename to common/src/common/util/IntHashMap.java index 12e3470..885b3a2 100755 --- a/common/src/common/world/IntHashMap.java +++ b/common/src/common/util/IntHashMap.java @@ -1,4 +1,4 @@ -package common.world; +package common.util; public class IntHashMap { diff --git a/common/src/common/world/LongHashMap.java b/common/src/common/util/LongHashMap.java similarity index 99% rename from common/src/common/world/LongHashMap.java rename to common/src/common/util/LongHashMap.java index 35fad96..89aba64 100755 --- a/common/src/common/world/LongHashMap.java +++ b/common/src/common/util/LongHashMap.java @@ -1,4 +1,4 @@ -package common.world; +package common.util; public class LongHashMap { diff --git a/common/src/common/world/NextTickListEntry.java b/common/src/common/util/NextTickListEntry.java similarity index 98% rename from common/src/common/world/NextTickListEntry.java rename to common/src/common/util/NextTickListEntry.java index d208b2f..6f492ad 100755 --- a/common/src/common/world/NextTickListEntry.java +++ b/common/src/common/util/NextTickListEntry.java @@ -1,4 +1,4 @@ -package common.world; +package common.util; import common.block.Block; import common.init.BlockRegistry; diff --git a/common/src/common/world/NibbleArray.java b/common/src/common/util/NibbleArray.java similarity index 97% rename from common/src/common/world/NibbleArray.java rename to common/src/common/util/NibbleArray.java index 3a53b8d..629be8d 100755 --- a/common/src/common/world/NibbleArray.java +++ b/common/src/common/util/NibbleArray.java @@ -1,4 +1,4 @@ -package common.world; +package common.util; public class NibbleArray { private final byte[] data; diff --git a/common/src/common/world/PortalType.java b/common/src/common/util/PortalType.java similarity index 86% rename from common/src/common/world/PortalType.java rename to common/src/common/util/PortalType.java index 06e214f..91b7cd4 100755 --- a/common/src/common/world/PortalType.java +++ b/common/src/common/util/PortalType.java @@ -1,4 +1,4 @@ -package common.world; +package common.util; public enum PortalType { STAND_BLACK, STAND_RED, STAND_YELLOW, STAND_GREEN, STAND_CYAN, STAND_BLUE, STAND_MAGENTA, STAND_WHITE, FLOOR, VOID; diff --git a/common/src/common/world/Position.java b/common/src/common/util/Position.java similarity index 94% rename from common/src/common/world/Position.java rename to common/src/common/util/Position.java index 59eaf24..8d7aa6c 100755 --- a/common/src/common/world/Position.java +++ b/common/src/common/util/Position.java @@ -1,4 +1,4 @@ -package common.world; +package common.util; public class Position { public final double x; diff --git a/common/src/common/world/Vec3.java b/common/src/common/util/Vec3.java similarity index 99% rename from common/src/common/world/Vec3.java rename to common/src/common/util/Vec3.java index 88b95ed..e183bf1 100755 --- a/common/src/common/world/Vec3.java +++ b/common/src/common/util/Vec3.java @@ -1,6 +1,4 @@ -package common.world; - -import common.util.ExtMath; +package common.util; public class Vec3 { diff --git a/common/src/common/world/Vec3i.java b/common/src/common/util/Vec3i.java similarity index 98% rename from common/src/common/world/Vec3i.java rename to common/src/common/util/Vec3i.java index fa1cd58..87ad35e 100755 --- a/common/src/common/world/Vec3i.java +++ b/common/src/common/util/Vec3i.java @@ -1,6 +1,4 @@ -package common.world; - -import common.util.ExtMath; +package common.util; public class Vec3i implements Comparable { diff --git a/common/src/common/world/WorldPos.java b/common/src/common/util/WorldPos.java similarity index 97% rename from common/src/common/world/WorldPos.java rename to common/src/common/util/WorldPos.java index 8c5608b..c23895c 100755 --- a/common/src/common/world/WorldPos.java +++ b/common/src/common/util/WorldPos.java @@ -1,4 +1,4 @@ -package common.world; +package common.util; public class WorldPos extends BlockPos { private final int dim; diff --git a/common/src/common/village/Village.java b/common/src/common/village/Village.java index 9185f6a..adc573f 100755 --- a/common/src/common/village/Village.java +++ b/common/src/common/village/Village.java @@ -9,7 +9,7 @@ import common.collect.Lists; import common.material.Material; import common.nbt.NBTTagCompound; import common.nbt.NBTTagList; -import common.world.BlockPos; +import common.util.BlockPos; import common.world.WorldServer; public class Village diff --git a/common/src/common/village/VillageCollection.java b/common/src/common/village/VillageCollection.java index 6872619..ecc2d9f 100755 --- a/common/src/common/village/VillageCollection.java +++ b/common/src/common/village/VillageCollection.java @@ -9,8 +9,8 @@ import common.collect.Lists; import common.material.Material; import common.nbt.NBTTagCompound; import common.nbt.NBTTagList; -import common.world.BlockPos; -import common.world.Facing; +import common.util.BlockPos; +import common.util.Facing; import common.world.WorldServer; public class VillageCollection diff --git a/common/src/common/village/VillageDoorInfo.java b/common/src/common/village/VillageDoorInfo.java index 69b229e..530d309 100755 --- a/common/src/common/village/VillageDoorInfo.java +++ b/common/src/common/village/VillageDoorInfo.java @@ -1,7 +1,7 @@ package common.village; -import common.world.BlockPos; -import common.world.Facing; +import common.util.BlockPos; +import common.util.Facing; public class VillageDoorInfo { diff --git a/common/src/common/world/BlockArray.java b/common/src/common/world/BlockArray.java index cd89a55..44fba70 100755 --- a/common/src/common/world/BlockArray.java +++ b/common/src/common/world/BlockArray.java @@ -3,6 +3,7 @@ package common.world; import common.block.Block; import common.init.BlockRegistry; import common.init.Blocks; +import common.util.NibbleArray; public class BlockArray { private int yBase; diff --git a/common/src/common/world/Chunk.java b/common/src/common/world/Chunk.java index 9f4be01..68f14f5 100755 --- a/common/src/common/world/Chunk.java +++ b/common/src/common/world/Chunk.java @@ -16,7 +16,13 @@ import common.log.Log; import common.material.Material; import common.rng.Random; import common.tileentity.TileEntity; +import common.util.BlockPos; +import common.util.BoundingBox; +import common.util.ChunkPos; +import common.util.ClassInheritanceMultiMap; import common.util.ExtMath; +import common.util.Facing; +import common.util.NibbleArray; import common.worldgen.BiomeGenerator; import common.worldgen.ChunkPrimer; import common.worldgen.GeneratorDebug; diff --git a/common/src/common/world/ChunkCache.java b/common/src/common/world/ChunkCache.java index e213ba5..d495ab1 100755 --- a/common/src/common/world/ChunkCache.java +++ b/common/src/common/world/ChunkCache.java @@ -1,5 +1,7 @@ package common.world; +import common.util.BlockPos; + public class ChunkCache { protected final int chunkX; diff --git a/common/src/common/world/EmptyChunk.java b/common/src/common/world/EmptyChunk.java index 29bc0c0..66ef16f 100755 --- a/common/src/common/world/EmptyChunk.java +++ b/common/src/common/world/EmptyChunk.java @@ -7,6 +7,8 @@ import common.block.Block; import common.entity.Entity; import common.init.Blocks; import common.tileentity.TileEntity; +import common.util.BlockPos; +import common.util.BoundingBox; public class EmptyChunk extends Chunk { public EmptyChunk(WorldClient world) { diff --git a/common/src/common/world/Explosion.java b/common/src/common/world/Explosion.java index 04fbc1c..c2830a2 100755 --- a/common/src/common/world/Explosion.java +++ b/common/src/common/world/Explosion.java @@ -20,7 +20,10 @@ import common.init.SoundEvent; import common.material.Material; import common.model.ParticleType; import common.rng.Random; +import common.util.BlockPos; +import common.util.BoundingBox; import common.util.ExtMath; +import common.util.Vec3; public class Explosion { diff --git a/common/src/common/world/IBlockAccess.java b/common/src/common/world/IBlockAccess.java index 2b0fb24..11fa2ab 100755 --- a/common/src/common/world/IBlockAccess.java +++ b/common/src/common/world/IBlockAccess.java @@ -1,5 +1,7 @@ package common.world; +import common.util.BlockPos; + public interface IBlockAccess { State getState(BlockPos pos); diff --git a/common/src/common/world/IWorldAccess.java b/common/src/common/world/IWorldAccess.java index b06a2fa..b798152 100755 --- a/common/src/common/world/IWorldAccess.java +++ b/common/src/common/world/IWorldAccess.java @@ -2,6 +2,7 @@ package common.world; import common.biome.Biome; import common.tileentity.TileEntity; +import common.util.BlockPos; public interface IWorldAccess extends IBlockAccess { diff --git a/common/src/common/world/Region.java b/common/src/common/world/Region.java index 6990839..06bbb84 100755 --- a/common/src/common/world/Region.java +++ b/common/src/common/world/Region.java @@ -30,6 +30,9 @@ import common.nbt.NBTLoader; import common.nbt.NBTTagCompound; import common.nbt.NBTTagList; import common.tileentity.TileEntity; +import common.util.BlockPos; +import common.util.NextTickListEntry; +import common.util.NibbleArray; public class Region { public static enum SaveVersion { diff --git a/common/src/common/world/Spawner.java b/common/src/common/world/Spawner.java index b9e323a..b4a5468 100755 --- a/common/src/common/world/Spawner.java +++ b/common/src/common/world/Spawner.java @@ -13,6 +13,8 @@ import common.init.Blocks; import common.init.Config; import common.rng.Random; import common.rng.WeightedList; +import common.util.BlockPos; +import common.util.ChunkPos; import common.util.ExtMath; public abstract class Spawner { diff --git a/common/src/common/world/World.java b/common/src/common/world/World.java index d651ac2..519dc36 100755 --- a/common/src/common/world/World.java +++ b/common/src/common/world/World.java @@ -29,7 +29,14 @@ import common.model.ParticleType; import common.rng.Random; import common.tileentity.ITickable; import common.tileentity.TileEntity; +import common.util.BlockPos; +import common.util.BoundingBox; +import common.util.ChunkPos; import common.util.ExtMath; +import common.util.Facing; +import common.util.HitPosition; +import common.util.IntHashMap; +import common.util.Vec3; public abstract class World implements IWorldAccess { public static final float[][] BRIGHTNESS = new float[16][16]; diff --git a/common/src/common/world/WorldClient.java b/common/src/common/world/WorldClient.java index 0365190..998a254 100755 --- a/common/src/common/world/WorldClient.java +++ b/common/src/common/world/WorldClient.java @@ -26,8 +26,12 @@ import common.rng.Random; import common.sound.MovingSoundMinecart; import common.sound.PositionedSound; import common.tileentity.TileEntity; +import common.util.BlockPos; +import common.util.ChunkPos; import common.util.ExtMath; -import common.world.BlockPos.MutableBlockPos; +import common.util.LongHashMap; +import common.util.Vec3; +import common.util.BlockPos.MutableBlockPos; public class WorldClient extends World { diff --git a/common/src/common/world/WorldServer.java b/common/src/common/world/WorldServer.java index 9b8d8dc..934b9ee 100755 --- a/common/src/common/world/WorldServer.java +++ b/common/src/common/world/WorldServer.java @@ -63,8 +63,17 @@ import common.packet.SPacketMultiBlockChange; import common.rng.Random; import common.rng.WeightedList; import common.tileentity.TileEntity; +import common.util.BlockPos; +import common.util.BoundingBox; +import common.util.ChunkPos; import common.util.ExtMath; import common.util.FileUtils; +import common.util.IntHashMap; +import common.util.LongHashMap; +import common.util.NextTickListEntry; +import common.util.PortalType; +import common.util.Position; +import common.util.Vec3; import common.village.Village; import common.village.VillageCollection; import common.worldgen.BiomeGenSingle; diff --git a/common/src/common/worldgen/BiomeGenLayered.java b/common/src/common/worldgen/BiomeGenLayered.java index d5e0230..152ba93 100755 --- a/common/src/common/worldgen/BiomeGenLayered.java +++ b/common/src/common/worldgen/BiomeGenLayered.java @@ -5,8 +5,8 @@ import java.util.Set; import common.biome.Biome; import common.collect.Lists; -import common.world.BlockPos; -import common.world.LongHashMap; +import common.util.BlockPos; +import common.util.LongHashMap; import common.worldgen.layer.GenLayer; import common.worldgen.layer.GenLayerAddAreas; import common.worldgen.layer.GenLayerAddExtra; diff --git a/common/src/common/worldgen/BiomeGenSingle.java b/common/src/common/worldgen/BiomeGenSingle.java index aad396d..1dd6493 100755 --- a/common/src/common/worldgen/BiomeGenSingle.java +++ b/common/src/common/worldgen/BiomeGenSingle.java @@ -4,7 +4,7 @@ import java.util.Arrays; import java.util.Set; import common.biome.Biome; -import common.world.BlockPos; +import common.util.BlockPos; public class BiomeGenSingle implements BiomeGenerator { private final Biome biome; diff --git a/common/src/common/worldgen/BiomeGenerator.java b/common/src/common/worldgen/BiomeGenerator.java index d975d42..b6ef4e9 100755 --- a/common/src/common/worldgen/BiomeGenerator.java +++ b/common/src/common/worldgen/BiomeGenerator.java @@ -3,7 +3,7 @@ package common.worldgen; import java.util.Set; import common.biome.Biome; -import common.world.BlockPos; +import common.util.BlockPos; public interface BiomeGenerator { public void genFactors(double[] factors, int xPos, int zPos, int sizeX, int sizeZ); diff --git a/common/src/common/worldgen/FeatureDungeons.java b/common/src/common/worldgen/FeatureDungeons.java index 3f22b7a..5e01ee4 100755 --- a/common/src/common/worldgen/FeatureDungeons.java +++ b/common/src/common/worldgen/FeatureDungeons.java @@ -10,8 +10,8 @@ import common.rng.WeightedList; import common.tileentity.TileEntity; import common.tileentity.TileEntityChest; import common.tileentity.TileEntityMobSpawner; -import common.world.BlockPos; -import common.world.Facing; +import common.util.BlockPos; +import common.util.Facing; import common.world.WorldServer; public class FeatureDungeons diff --git a/common/src/common/worldgen/FeatureGenerator.java b/common/src/common/worldgen/FeatureGenerator.java index d93b260..19beb30 100755 --- a/common/src/common/worldgen/FeatureGenerator.java +++ b/common/src/common/worldgen/FeatureGenerator.java @@ -1,7 +1,7 @@ package common.worldgen; import common.rng.Random; -import common.world.BlockPos; +import common.util.BlockPos; import common.world.State; import common.world.WorldServer; diff --git a/common/src/common/worldgen/FeatureLakes.java b/common/src/common/worldgen/FeatureLakes.java index 3bb47d4..658d7d0 100755 --- a/common/src/common/worldgen/FeatureLakes.java +++ b/common/src/common/worldgen/FeatureLakes.java @@ -5,7 +5,7 @@ import common.block.Block; import common.init.Blocks; import common.material.Material; import common.rng.Random; -import common.world.BlockPos; +import common.util.BlockPos; import common.world.LightType; import common.world.State; import common.world.WorldServer; diff --git a/common/src/common/worldgen/FeatureLiquids.java b/common/src/common/worldgen/FeatureLiquids.java index bd050b8..900c594 100755 --- a/common/src/common/worldgen/FeatureLiquids.java +++ b/common/src/common/worldgen/FeatureLiquids.java @@ -3,7 +3,7 @@ package common.worldgen; import common.block.Block; import common.material.Material; import common.rng.Random; -import common.world.BlockPos; +import common.util.BlockPos; import common.world.State; import common.world.WorldServer; diff --git a/common/src/common/worldgen/FeatureOres.java b/common/src/common/worldgen/FeatureOres.java index bb30028..091d34b 100755 --- a/common/src/common/worldgen/FeatureOres.java +++ b/common/src/common/worldgen/FeatureOres.java @@ -2,8 +2,8 @@ package common.worldgen; import common.block.Block; import common.rng.Random; +import common.util.BlockPos; import common.util.ExtMath; -import common.world.BlockPos; import common.world.State; import common.world.WorldServer; diff --git a/common/src/common/worldgen/caves/MapGenCaves.java b/common/src/common/worldgen/caves/MapGenCaves.java index 6f2a15e..405603b 100755 --- a/common/src/common/worldgen/caves/MapGenCaves.java +++ b/common/src/common/worldgen/caves/MapGenCaves.java @@ -6,8 +6,8 @@ import common.block.BlockSand; import common.color.DyeColor; import common.init.Blocks; import common.rng.Random; +import common.util.BlockPos; import common.util.ExtMath; -import common.world.BlockPos; import common.world.State; import common.world.WorldServer; import common.worldgen.ChunkPrimer; diff --git a/common/src/common/worldgen/caves/MapGenRavine.java b/common/src/common/worldgen/caves/MapGenRavine.java index 13d30c0..02646d1 100755 --- a/common/src/common/worldgen/caves/MapGenRavine.java +++ b/common/src/common/worldgen/caves/MapGenRavine.java @@ -3,8 +3,8 @@ package common.worldgen.caves; import common.block.Block; import common.init.Blocks; import common.rng.Random; +import common.util.BlockPos; import common.util.ExtMath; -import common.world.BlockPos; import common.world.State; import common.world.WorldServer; import common.worldgen.ChunkPrimer; diff --git a/common/src/common/worldgen/feature/WorldGenAbandonedChest.java b/common/src/common/worldgen/feature/WorldGenAbandonedChest.java index 79206eb..c724150 100755 --- a/common/src/common/worldgen/feature/WorldGenAbandonedChest.java +++ b/common/src/common/worldgen/feature/WorldGenAbandonedChest.java @@ -8,7 +8,7 @@ import common.rng.Random; import common.rng.WeightedList; import common.tileentity.TileEntity; import common.tileentity.TileEntityChest; -import common.world.BlockPos; +import common.util.BlockPos; import common.world.WorldServer; import common.worldgen.FeatureGenerator; import common.worldgen.LootConstants; diff --git a/common/src/common/worldgen/feature/WorldGenAsteroid.java b/common/src/common/worldgen/feature/WorldGenAsteroid.java index 35c2fea..fdc1eef 100755 --- a/common/src/common/worldgen/feature/WorldGenAsteroid.java +++ b/common/src/common/worldgen/feature/WorldGenAsteroid.java @@ -1,7 +1,7 @@ package common.worldgen.feature; import common.rng.Random; -import common.world.BlockPos; +import common.util.BlockPos; import common.world.State; import common.world.WorldServer; import common.worldgen.FeatureGenerator; diff --git a/common/src/common/worldgen/feature/WorldGenBlockBlob.java b/common/src/common/worldgen/feature/WorldGenBlockBlob.java index 98e6f18..06929da 100755 --- a/common/src/common/worldgen/feature/WorldGenBlockBlob.java +++ b/common/src/common/worldgen/feature/WorldGenBlockBlob.java @@ -3,7 +3,7 @@ package common.worldgen.feature; import common.block.Block; import common.init.Blocks; import common.rng.Random; -import common.world.BlockPos; +import common.util.BlockPos; import common.world.WorldServer; import common.worldgen.FeatureGenerator; diff --git a/common/src/common/worldgen/feature/WorldGenClay.java b/common/src/common/worldgen/feature/WorldGenClay.java index 1be9142..9888fbc 100755 --- a/common/src/common/worldgen/feature/WorldGenClay.java +++ b/common/src/common/worldgen/feature/WorldGenClay.java @@ -3,7 +3,7 @@ package common.worldgen.feature; import common.block.Block; import common.init.Blocks; import common.rng.Random; -import common.world.BlockPos; +import common.util.BlockPos; import common.world.WorldServer; import common.worldgen.FeatureGenerator; diff --git a/common/src/common/worldgen/feature/WorldGenClayExt.java b/common/src/common/worldgen/feature/WorldGenClayExt.java index 9f9499e..c7fc80e 100755 --- a/common/src/common/worldgen/feature/WorldGenClayExt.java +++ b/common/src/common/worldgen/feature/WorldGenClayExt.java @@ -3,8 +3,8 @@ package common.worldgen.feature; import common.block.Block; import common.init.Blocks; import common.rng.Random; +import common.util.BlockPos; import common.util.ExtMath; -import common.world.BlockPos; import common.world.WorldServer; public class WorldGenClayExt extends WorldGenClay { diff --git a/common/src/common/worldgen/feature/WorldGenDesertWells.java b/common/src/common/worldgen/feature/WorldGenDesertWells.java index 3412134..75fab6b 100755 --- a/common/src/common/worldgen/feature/WorldGenDesertWells.java +++ b/common/src/common/worldgen/feature/WorldGenDesertWells.java @@ -5,9 +5,9 @@ import common.block.BlockSlab; import common.init.Blocks; import common.pattern.BlockStateHelper; import common.rng.Random; +import common.util.BlockPos; +import common.util.Facing; import common.util.Predicates; -import common.world.BlockPos; -import common.world.Facing; import common.world.State; import common.world.WorldServer; import common.worldgen.FeatureGenerator; diff --git a/common/src/common/worldgen/feature/WorldGenFire.java b/common/src/common/worldgen/feature/WorldGenFire.java index 09e1665..4623f68 100755 --- a/common/src/common/worldgen/feature/WorldGenFire.java +++ b/common/src/common/worldgen/feature/WorldGenFire.java @@ -2,7 +2,7 @@ package common.worldgen.feature; import common.init.Blocks; import common.rng.Random; -import common.world.BlockPos; +import common.util.BlockPos; import common.world.WorldServer; import common.worldgen.FeatureGenerator; diff --git a/common/src/common/worldgen/feature/WorldGenGlowStone.java b/common/src/common/worldgen/feature/WorldGenGlowStone.java index 3dd6047..a87146c 100755 --- a/common/src/common/worldgen/feature/WorldGenGlowStone.java +++ b/common/src/common/worldgen/feature/WorldGenGlowStone.java @@ -3,8 +3,8 @@ package common.worldgen.feature; import common.init.Blocks; import common.material.Material; import common.rng.Random; -import common.world.BlockPos; -import common.world.Facing; +import common.util.BlockPos; +import common.util.Facing; import common.world.WorldServer; import common.worldgen.FeatureGenerator; diff --git a/common/src/common/worldgen/feature/WorldGenHellLava.java b/common/src/common/worldgen/feature/WorldGenHellLava.java index a878c5c..7aee1b8 100755 --- a/common/src/common/worldgen/feature/WorldGenHellLava.java +++ b/common/src/common/worldgen/feature/WorldGenHellLava.java @@ -4,7 +4,7 @@ import common.block.Block; import common.init.Blocks; import common.material.Material; import common.rng.Random; -import common.world.BlockPos; +import common.util.BlockPos; import common.world.WorldServer; import common.worldgen.FeatureGenerator; diff --git a/common/src/common/worldgen/feature/WorldGenIcePath.java b/common/src/common/worldgen/feature/WorldGenIcePath.java index f0b26ba..69b9aac 100755 --- a/common/src/common/worldgen/feature/WorldGenIcePath.java +++ b/common/src/common/worldgen/feature/WorldGenIcePath.java @@ -3,7 +3,7 @@ package common.worldgen.feature; import common.block.Block; import common.init.Blocks; import common.rng.Random; -import common.world.BlockPos; +import common.util.BlockPos; import common.world.WorldServer; import common.worldgen.FeatureGenerator; diff --git a/common/src/common/worldgen/feature/WorldGenIceSpike.java b/common/src/common/worldgen/feature/WorldGenIceSpike.java index 3f78db2..8d7aaf1 100755 --- a/common/src/common/worldgen/feature/WorldGenIceSpike.java +++ b/common/src/common/worldgen/feature/WorldGenIceSpike.java @@ -4,8 +4,8 @@ import common.block.Block; import common.init.Blocks; import common.material.Material; import common.rng.Random; +import common.util.BlockPos; import common.util.ExtMath; -import common.world.BlockPos; import common.world.WorldServer; import common.worldgen.FeatureGenerator; diff --git a/common/src/common/worldgen/feature/WorldGenSand.java b/common/src/common/worldgen/feature/WorldGenSand.java index 178abdd..657a276 100755 --- a/common/src/common/worldgen/feature/WorldGenSand.java +++ b/common/src/common/worldgen/feature/WorldGenSand.java @@ -3,7 +3,7 @@ package common.worldgen.feature; import common.block.Block; import common.init.Blocks; import common.rng.Random; -import common.world.BlockPos; +import common.util.BlockPos; import common.world.WorldServer; import common.worldgen.FeatureGenerator; diff --git a/common/src/common/worldgen/feature/WorldGenSpikes.java b/common/src/common/worldgen/feature/WorldGenSpikes.java index c22daf1..76b6f07 100755 --- a/common/src/common/worldgen/feature/WorldGenSpikes.java +++ b/common/src/common/worldgen/feature/WorldGenSpikes.java @@ -4,7 +4,7 @@ import common.block.Block; import common.entity.Entity; import common.entity.item.EntityCrystal; import common.rng.Random; -import common.world.BlockPos; +import common.util.BlockPos; import common.world.State; import common.world.WorldServer; import common.worldgen.FeatureGenerator; diff --git a/common/src/common/worldgen/foliage/FeatureDoublePlant.java b/common/src/common/worldgen/foliage/FeatureDoublePlant.java index 9d61b5b..2e00419 100755 --- a/common/src/common/worldgen/foliage/FeatureDoublePlant.java +++ b/common/src/common/worldgen/foliage/FeatureDoublePlant.java @@ -3,7 +3,7 @@ package common.worldgen.foliage; import common.block.BlockDoublePlant; import common.init.Blocks; import common.rng.Random; -import common.world.BlockPos; +import common.util.BlockPos; import common.world.WorldServer; public class FeatureDoublePlant diff --git a/common/src/common/worldgen/foliage/WorldGenBigMushroom.java b/common/src/common/worldgen/foliage/WorldGenBigMushroom.java index 09b707e..96005ec 100755 --- a/common/src/common/worldgen/foliage/WorldGenBigMushroom.java +++ b/common/src/common/worldgen/foliage/WorldGenBigMushroom.java @@ -5,7 +5,7 @@ import common.block.BlockHugeMushroom; import common.init.Blocks; import common.material.Material; import common.rng.Random; -import common.world.BlockPos; +import common.util.BlockPos; import common.world.WorldServer; import common.worldgen.FeatureGenerator; diff --git a/common/src/common/worldgen/foliage/WorldGenCactus.java b/common/src/common/worldgen/foliage/WorldGenCactus.java index a148c2e..500a5ea 100755 --- a/common/src/common/worldgen/foliage/WorldGenCactus.java +++ b/common/src/common/worldgen/foliage/WorldGenCactus.java @@ -2,7 +2,7 @@ package common.worldgen.foliage; import common.init.Blocks; import common.rng.Random; -import common.world.BlockPos; +import common.util.BlockPos; import common.world.WorldServer; import common.worldgen.FeatureGenerator; diff --git a/common/src/common/worldgen/foliage/WorldGenDeadBush.java b/common/src/common/worldgen/foliage/WorldGenDeadBush.java index 4bff100..6e7bb2d 100755 --- a/common/src/common/worldgen/foliage/WorldGenDeadBush.java +++ b/common/src/common/worldgen/foliage/WorldGenDeadBush.java @@ -4,7 +4,7 @@ import common.block.Block; import common.init.Blocks; import common.material.Material; import common.rng.Random; -import common.world.BlockPos; +import common.util.BlockPos; import common.world.WorldServer; import common.worldgen.FeatureGenerator; diff --git a/common/src/common/worldgen/foliage/WorldGenFlowers.java b/common/src/common/worldgen/foliage/WorldGenFlowers.java index b8ab2da..9adc8b2 100755 --- a/common/src/common/worldgen/foliage/WorldGenFlowers.java +++ b/common/src/common/worldgen/foliage/WorldGenFlowers.java @@ -2,7 +2,7 @@ package common.worldgen.foliage; import common.block.BlockFlower; import common.rng.Random; -import common.world.BlockPos; +import common.util.BlockPos; import common.world.State; import common.world.WorldServer; import common.worldgen.FeatureGenerator; diff --git a/common/src/common/worldgen/foliage/WorldGenMelon.java b/common/src/common/worldgen/foliage/WorldGenMelon.java index b48dedf..fff25dc 100755 --- a/common/src/common/worldgen/foliage/WorldGenMelon.java +++ b/common/src/common/worldgen/foliage/WorldGenMelon.java @@ -2,7 +2,7 @@ package common.worldgen.foliage; import common.init.Blocks; import common.rng.Random; -import common.world.BlockPos; +import common.util.BlockPos; import common.world.WorldServer; import common.worldgen.FeatureGenerator; diff --git a/common/src/common/worldgen/foliage/WorldGenMushroom.java b/common/src/common/worldgen/foliage/WorldGenMushroom.java index a23509c..00d38a8 100755 --- a/common/src/common/worldgen/foliage/WorldGenMushroom.java +++ b/common/src/common/worldgen/foliage/WorldGenMushroom.java @@ -2,7 +2,7 @@ package common.worldgen.foliage; import common.block.BlockBush; import common.rng.Random; -import common.world.BlockPos; +import common.util.BlockPos; import common.world.WorldServer; import common.worldgen.FeatureGenerator; diff --git a/common/src/common/worldgen/foliage/WorldGenPumpkin.java b/common/src/common/worldgen/foliage/WorldGenPumpkin.java index e15fec5..45f3daf 100755 --- a/common/src/common/worldgen/foliage/WorldGenPumpkin.java +++ b/common/src/common/worldgen/foliage/WorldGenPumpkin.java @@ -3,8 +3,8 @@ package common.worldgen.foliage; import common.block.BlockPumpkin; import common.init.Blocks; import common.rng.Random; -import common.world.BlockPos; -import common.world.Facing; +import common.util.BlockPos; +import common.util.Facing; import common.world.WorldServer; import common.worldgen.FeatureGenerator; diff --git a/common/src/common/worldgen/foliage/WorldGenReed.java b/common/src/common/worldgen/foliage/WorldGenReed.java index 5162668..f85469c 100755 --- a/common/src/common/worldgen/foliage/WorldGenReed.java +++ b/common/src/common/worldgen/foliage/WorldGenReed.java @@ -3,7 +3,7 @@ package common.worldgen.foliage; import common.init.Blocks; import common.material.Material; import common.rng.Random; -import common.world.BlockPos; +import common.util.BlockPos; import common.world.WorldServer; import common.worldgen.FeatureGenerator; diff --git a/common/src/common/worldgen/foliage/WorldGenShrub.java b/common/src/common/worldgen/foliage/WorldGenShrub.java index 1ae5474..00b7d71 100755 --- a/common/src/common/worldgen/foliage/WorldGenShrub.java +++ b/common/src/common/worldgen/foliage/WorldGenShrub.java @@ -5,7 +5,7 @@ import common.block.BlockLeaves; import common.init.Blocks; import common.material.Material; import common.rng.Random; -import common.world.BlockPos; +import common.util.BlockPos; import common.world.State; import common.world.WorldServer; import common.worldgen.tree.WorldGenBaseTree; diff --git a/common/src/common/worldgen/foliage/WorldGenTallGrass.java b/common/src/common/worldgen/foliage/WorldGenTallGrass.java index 2bfeb28..52bf305 100755 --- a/common/src/common/worldgen/foliage/WorldGenTallGrass.java +++ b/common/src/common/worldgen/foliage/WorldGenTallGrass.java @@ -5,7 +5,7 @@ import common.block.BlockTallGrass; import common.init.Blocks; import common.material.Material; import common.rng.Random; -import common.world.BlockPos; +import common.util.BlockPos; import common.world.State; import common.world.WorldServer; import common.worldgen.FeatureGenerator; diff --git a/common/src/common/worldgen/foliage/WorldGenVines.java b/common/src/common/worldgen/foliage/WorldGenVines.java index 7b42cf0..eaf09b1 100755 --- a/common/src/common/worldgen/foliage/WorldGenVines.java +++ b/common/src/common/worldgen/foliage/WorldGenVines.java @@ -3,8 +3,8 @@ package common.worldgen.foliage; import common.block.BlockVine; import common.init.Blocks; import common.rng.Random; -import common.world.BlockPos; -import common.world.Facing; +import common.util.BlockPos; +import common.util.Facing; import common.world.State; import common.world.WorldServer; import common.worldgen.FeatureGenerator; diff --git a/common/src/common/worldgen/foliage/WorldGenWaterlily.java b/common/src/common/worldgen/foliage/WorldGenWaterlily.java index 333505f..c7496c9 100755 --- a/common/src/common/worldgen/foliage/WorldGenWaterlily.java +++ b/common/src/common/worldgen/foliage/WorldGenWaterlily.java @@ -3,8 +3,8 @@ package common.worldgen.foliage; import common.block.BlockDirectional; import common.init.Blocks; import common.rng.Random; -import common.world.BlockPos; -import common.world.Facing; +import common.util.BlockPos; +import common.util.Facing; import common.world.WorldServer; import common.worldgen.FeatureGenerator; diff --git a/common/src/common/worldgen/structure/MapGenScatteredFeature.java b/common/src/common/worldgen/structure/MapGenScatteredFeature.java index 16c54e2..8de6711 100755 --- a/common/src/common/worldgen/structure/MapGenScatteredFeature.java +++ b/common/src/common/worldgen/structure/MapGenScatteredFeature.java @@ -5,7 +5,7 @@ import java.util.List; import common.biome.Biome; import common.rng.Random; -import common.world.BlockPos; +import common.util.BlockPos; import common.world.WorldServer; public class MapGenScatteredFeature extends MapGenStructure diff --git a/common/src/common/worldgen/structure/MapGenStructure.java b/common/src/common/worldgen/structure/MapGenStructure.java index 5cd21bf..d339850 100755 --- a/common/src/common/worldgen/structure/MapGenStructure.java +++ b/common/src/common/worldgen/structure/MapGenStructure.java @@ -7,9 +7,9 @@ import common.collect.Maps; import common.nbt.NBTBase; import common.nbt.NBTTagCompound; import common.rng.Random; -import common.world.BlockPos; -import common.world.ChunkPos; -import common.world.LongHashMap; +import common.util.BlockPos; +import common.util.ChunkPos; +import common.util.LongHashMap; import common.world.World; import common.world.WorldServer; import common.world.WorldServer.WorldSavedData; diff --git a/common/src/common/worldgen/structure/StructureBoundingBox.java b/common/src/common/worldgen/structure/StructureBoundingBox.java index 418f011..482873c 100755 --- a/common/src/common/worldgen/structure/StructureBoundingBox.java +++ b/common/src/common/worldgen/structure/StructureBoundingBox.java @@ -1,9 +1,9 @@ package common.worldgen.structure; import common.nbt.NBTTagIntArray; -import common.world.BlockPos; -import common.world.Facing; -import common.world.Vec3i; +import common.util.BlockPos; +import common.util.Facing; +import common.util.Vec3i; public class StructureBoundingBox { diff --git a/common/src/common/worldgen/structure/StructureBridge.java b/common/src/common/worldgen/structure/StructureBridge.java index ab35d0e..0970247 100755 --- a/common/src/common/worldgen/structure/StructureBridge.java +++ b/common/src/common/worldgen/structure/StructureBridge.java @@ -8,8 +8,8 @@ import common.nbt.NBTTagCompound; import common.rng.Random; import common.tileentity.TileEntity; import common.tileentity.TileEntityMobSpawner; -import common.world.BlockPos; -import common.world.Facing; +import common.util.BlockPos; +import common.util.Facing; import common.world.WorldServer; import common.worldgen.LootConstants; diff --git a/common/src/common/worldgen/structure/StructureComponent.java b/common/src/common/worldgen/structure/StructureComponent.java index b01bff9..bd76ec3 100755 --- a/common/src/common/worldgen/structure/StructureComponent.java +++ b/common/src/common/worldgen/structure/StructureComponent.java @@ -15,8 +15,8 @@ import common.rng.WeightedList; import common.tileentity.TileEntity; import common.tileentity.TileEntityChest; import common.tileentity.TileEntityDispenser; -import common.world.BlockPos; -import common.world.Facing; +import common.util.BlockPos; +import common.util.Facing; import common.world.State; import common.world.WorldServer; diff --git a/common/src/common/worldgen/structure/StructureMineshaft.java b/common/src/common/worldgen/structure/StructureMineshaft.java index cadc388..21f5335 100755 --- a/common/src/common/worldgen/structure/StructureMineshaft.java +++ b/common/src/common/worldgen/structure/StructureMineshaft.java @@ -14,8 +14,8 @@ import common.rng.Random; import common.rng.WeightedList; import common.tileentity.TileEntity; import common.tileentity.TileEntityMobSpawner; -import common.world.BlockPos; -import common.world.Facing; +import common.util.BlockPos; +import common.util.Facing; import common.world.State; import common.world.WorldServer; import common.worldgen.LootConstants; diff --git a/common/src/common/worldgen/structure/StructureScattered.java b/common/src/common/worldgen/structure/StructureScattered.java index b031a72..e3b3bd4 100755 --- a/common/src/common/worldgen/structure/StructureScattered.java +++ b/common/src/common/worldgen/structure/StructureScattered.java @@ -15,8 +15,8 @@ import common.init.Items; import common.item.RngLoot; import common.nbt.NBTTagCompound; import common.rng.Random; -import common.world.BlockPos; -import common.world.Facing; +import common.util.BlockPos; +import common.util.Facing; import common.world.WorldServer; import common.worldgen.LootConstants; diff --git a/common/src/common/worldgen/structure/StructureStart.java b/common/src/common/worldgen/structure/StructureStart.java index 5cee450..bbf98f0 100755 --- a/common/src/common/worldgen/structure/StructureStart.java +++ b/common/src/common/worldgen/structure/StructureStart.java @@ -6,7 +6,7 @@ import java.util.LinkedList; import common.nbt.NBTTagCompound; import common.nbt.NBTTagList; import common.rng.Random; -import common.world.ChunkPos; +import common.util.ChunkPos; import common.world.WorldServer; public abstract class StructureStart diff --git a/common/src/common/worldgen/structure/StructureStronghold.java b/common/src/common/worldgen/structure/StructureStronghold.java index 3d10553..75f87c0 100755 --- a/common/src/common/worldgen/structure/StructureStronghold.java +++ b/common/src/common/worldgen/structure/StructureStronghold.java @@ -14,8 +14,8 @@ import common.nbt.NBTTagCompound; import common.rng.Random; import common.tileentity.TileEntity; import common.tileentity.TileEntityMobSpawner; -import common.world.BlockPos; -import common.world.Facing; +import common.util.BlockPos; +import common.util.Facing; import common.world.WorldServer; import common.worldgen.LootConstants; diff --git a/common/src/common/worldgen/structure/StructureVillage.java b/common/src/common/worldgen/structure/StructureVillage.java index aa850da..5d25145 100755 --- a/common/src/common/worldgen/structure/StructureVillage.java +++ b/common/src/common/worldgen/structure/StructureVillage.java @@ -19,8 +19,8 @@ import common.init.Config; import common.material.Material; import common.nbt.NBTTagCompound; import common.rng.Random; -import common.world.BlockPos; -import common.world.Facing; +import common.util.BlockPos; +import common.util.Facing; import common.world.State; import common.world.WorldServer; import common.worldgen.BiomeGenerator; diff --git a/common/src/common/worldgen/tree/WorldGenBaseTree.java b/common/src/common/worldgen/tree/WorldGenBaseTree.java index c1e3017..e3653c9 100755 --- a/common/src/common/worldgen/tree/WorldGenBaseTree.java +++ b/common/src/common/worldgen/tree/WorldGenBaseTree.java @@ -8,8 +8,8 @@ import common.init.Blocks; import common.material.Material; import common.properties.PropertyBool; import common.rng.Random; -import common.world.BlockPos; -import common.world.Facing; +import common.util.BlockPos; +import common.util.Facing; import common.world.State; import common.world.WorldServer; diff --git a/common/src/common/worldgen/tree/WorldGenBigTree.java b/common/src/common/worldgen/tree/WorldGenBigTree.java index 8a5580c..8f16b8a 100755 --- a/common/src/common/worldgen/tree/WorldGenBigTree.java +++ b/common/src/common/worldgen/tree/WorldGenBigTree.java @@ -9,8 +9,8 @@ import common.collect.Lists; import common.init.Blocks; import common.material.Material; import common.rng.Random; +import common.util.BlockPos; import common.util.ExtMath; -import common.world.BlockPos; import common.world.State; import common.world.WorldServer; diff --git a/common/src/common/worldgen/tree/WorldGenBirch.java b/common/src/common/worldgen/tree/WorldGenBirch.java index d0c4af8..9c4cebb 100755 --- a/common/src/common/worldgen/tree/WorldGenBirch.java +++ b/common/src/common/worldgen/tree/WorldGenBirch.java @@ -5,7 +5,7 @@ import common.block.BlockLeaves; import common.init.Blocks; import common.material.Material; import common.rng.Random; -import common.world.BlockPos; +import common.util.BlockPos; import common.world.State; import common.world.WorldServer; diff --git a/common/src/common/worldgen/tree/WorldGenDarkOak.java b/common/src/common/worldgen/tree/WorldGenDarkOak.java index 43cf4bc..75e40a9 100755 --- a/common/src/common/worldgen/tree/WorldGenDarkOak.java +++ b/common/src/common/worldgen/tree/WorldGenDarkOak.java @@ -5,8 +5,8 @@ import common.block.BlockLeaves; import common.init.Blocks; import common.material.Material; import common.rng.Random; -import common.world.BlockPos; -import common.world.Facing; +import common.util.BlockPos; +import common.util.Facing; import common.world.State; import common.world.WorldServer; diff --git a/common/src/common/worldgen/tree/WorldGenHugeTree.java b/common/src/common/worldgen/tree/WorldGenHugeTree.java index bd57382..2830025 100755 --- a/common/src/common/worldgen/tree/WorldGenHugeTree.java +++ b/common/src/common/worldgen/tree/WorldGenHugeTree.java @@ -5,7 +5,7 @@ import common.block.BlockLeaves; import common.init.Blocks; import common.material.Material; import common.rng.Random; -import common.world.BlockPos; +import common.util.BlockPos; import common.world.State; import common.world.WorldServer; diff --git a/common/src/common/worldgen/tree/WorldGenJungle.java b/common/src/common/worldgen/tree/WorldGenJungle.java index d9fef45..b034df5 100755 --- a/common/src/common/worldgen/tree/WorldGenJungle.java +++ b/common/src/common/worldgen/tree/WorldGenJungle.java @@ -4,8 +4,8 @@ import common.block.BlockVine; import common.init.Blocks; import common.properties.PropertyBool; import common.rng.Random; +import common.util.BlockPos; import common.util.ExtMath; -import common.world.BlockPos; import common.world.State; import common.world.WorldServer; diff --git a/common/src/common/worldgen/tree/WorldGenPine.java b/common/src/common/worldgen/tree/WorldGenPine.java index c7000ed..84552a5 100755 --- a/common/src/common/worldgen/tree/WorldGenPine.java +++ b/common/src/common/worldgen/tree/WorldGenPine.java @@ -5,8 +5,8 @@ import common.block.BlockDirt; import common.init.Blocks; import common.material.Material; import common.rng.Random; +import common.util.BlockPos; import common.util.ExtMath; -import common.world.BlockPos; import common.world.State; import common.world.WorldServer; diff --git a/common/src/common/worldgen/tree/WorldGenSavanna.java b/common/src/common/worldgen/tree/WorldGenSavanna.java index f4b98d2..068b0d7 100755 --- a/common/src/common/worldgen/tree/WorldGenSavanna.java +++ b/common/src/common/worldgen/tree/WorldGenSavanna.java @@ -5,8 +5,8 @@ import common.block.BlockLeaves; import common.init.Blocks; import common.material.Material; import common.rng.Random; -import common.world.BlockPos; -import common.world.Facing; +import common.util.BlockPos; +import common.util.Facing; import common.world.State; import common.world.WorldServer; diff --git a/common/src/common/worldgen/tree/WorldGenSwamp.java b/common/src/common/worldgen/tree/WorldGenSwamp.java index 264c763..cb4ebcb 100755 --- a/common/src/common/worldgen/tree/WorldGenSwamp.java +++ b/common/src/common/worldgen/tree/WorldGenSwamp.java @@ -7,7 +7,7 @@ import common.init.Blocks; import common.material.Material; import common.properties.PropertyBool; import common.rng.Random; -import common.world.BlockPos; +import common.util.BlockPos; import common.world.State; import common.world.WorldServer; diff --git a/common/src/common/worldgen/tree/WorldGenTaiga1.java b/common/src/common/worldgen/tree/WorldGenTaiga1.java index f5f6b85..f940439 100755 --- a/common/src/common/worldgen/tree/WorldGenTaiga1.java +++ b/common/src/common/worldgen/tree/WorldGenTaiga1.java @@ -5,7 +5,7 @@ import common.block.BlockLeaves; import common.init.Blocks; import common.material.Material; import common.rng.Random; -import common.world.BlockPos; +import common.util.BlockPos; import common.world.State; import common.world.WorldServer; diff --git a/common/src/common/worldgen/tree/WorldGenTaiga2.java b/common/src/common/worldgen/tree/WorldGenTaiga2.java index f085cdb..014bda7 100755 --- a/common/src/common/worldgen/tree/WorldGenTaiga2.java +++ b/common/src/common/worldgen/tree/WorldGenTaiga2.java @@ -5,7 +5,7 @@ import common.block.BlockLeaves; import common.init.Blocks; import common.material.Material; import common.rng.Random; -import common.world.BlockPos; +import common.util.BlockPos; import common.world.State; import common.world.WorldServer; diff --git a/common/src/common/worldgen/tree/WorldGenTree.java b/common/src/common/worldgen/tree/WorldGenTree.java index 1ea362b..82bf0fc 100755 --- a/common/src/common/worldgen/tree/WorldGenTree.java +++ b/common/src/common/worldgen/tree/WorldGenTree.java @@ -6,7 +6,7 @@ import common.block.BlockSapling; import common.init.Blocks; import common.material.Material; import common.rng.Random; -import common.world.BlockPos; +import common.util.BlockPos; import common.world.WorldServer; import common.worldgen.FeatureGenerator; diff --git a/server/src/server/Server.java b/server/src/server/Server.java index 7781080..728a53d 100755 --- a/server/src/server/Server.java +++ b/server/src/server/Server.java @@ -63,16 +63,16 @@ import common.packet.SPacketSkin; import common.packet.SPacketTimeUpdate; import common.packet.SPacketWorld; import common.potion.PotionEffect; +import common.util.BlockPos; import common.util.ExtMath; import common.util.LazyLoadBase; +import common.util.PortalType; +import common.util.Position; import common.util.Tuple; import common.util.Util; -import common.world.BlockPos; -import common.world.PortalType; -import common.world.Position; +import common.util.WorldPos; import common.world.Region; import common.world.World; -import common.world.WorldPos; import common.world.WorldServer; import common.world.Region.FolderInfo; import io.netty.bootstrap.ServerBootstrap; diff --git a/server/src/server/command/Command.java b/server/src/server/command/Command.java index 2598c0f..56750cc 100644 --- a/server/src/server/command/Command.java +++ b/server/src/server/command/Command.java @@ -7,7 +7,7 @@ import java.util.Map; import common.collect.Lists; import common.collect.Maps; -import common.world.Vec3; +import common.util.Vec3; import common.world.World; import server.command.DoubleParser.DefType; diff --git a/server/src/server/command/DimensionParser.java b/server/src/server/command/DimensionParser.java index 523f4b9..30f9121 100644 --- a/server/src/server/command/DimensionParser.java +++ b/server/src/server/command/DimensionParser.java @@ -4,7 +4,7 @@ import java.util.Collection; import common.dimension.Dimension; import common.init.UniverseRegistry; -import common.world.Position; +import common.util.Position; public class DimensionParser extends CompletingParser { private final boolean useSender; diff --git a/server/src/server/command/DoubleParser.java b/server/src/server/command/DoubleParser.java index cb071b4..353b4be 100644 --- a/server/src/server/command/DoubleParser.java +++ b/server/src/server/command/DoubleParser.java @@ -3,8 +3,8 @@ package server.command; import java.util.Collection; import common.collect.Lists; -import common.world.BlockPos; -import common.world.Position; +import common.util.BlockPos; +import common.util.Position; public class DoubleParser extends DefaultingParser { public static enum DefType { diff --git a/server/src/server/command/Executor.java b/server/src/server/command/Executor.java index 02207b4..d3888eb 100644 --- a/server/src/server/command/Executor.java +++ b/server/src/server/command/Executor.java @@ -1,8 +1,8 @@ package server.command; import common.entity.Entity; -import common.world.BlockPos; -import common.world.Position; +import common.util.BlockPos; +import common.util.Position; public interface Executor { void logConsole(String msg); diff --git a/server/src/server/command/FixedExecutor.java b/server/src/server/command/FixedExecutor.java index df9e3fb..5f7d2cf 100644 --- a/server/src/server/command/FixedExecutor.java +++ b/server/src/server/command/FixedExecutor.java @@ -1,8 +1,8 @@ package server.command; import common.entity.Entity; -import common.world.BlockPos; -import common.world.Position; +import common.util.BlockPos; +import common.util.Position; import server.Server; public class FixedExecutor implements Executor { diff --git a/server/src/server/command/commands/CommandOfflinetp.java b/server/src/server/command/commands/CommandOfflinetp.java index 6966524..7d3e339 100644 --- a/server/src/server/command/commands/CommandOfflinetp.java +++ b/server/src/server/command/commands/CommandOfflinetp.java @@ -6,7 +6,7 @@ import java.util.List; import common.collect.Lists; import common.entity.Entity; import common.init.UniverseRegistry; -import common.world.Position; +import common.util.Position; import server.command.Command; import server.command.CommandEnvironment; import server.command.Executor; diff --git a/server/src/server/command/commands/CommandSpawn.java b/server/src/server/command/commands/CommandSpawn.java index 93e522e..2534793 100644 --- a/server/src/server/command/commands/CommandSpawn.java +++ b/server/src/server/command/commands/CommandSpawn.java @@ -10,7 +10,7 @@ import common.entity.types.EntityLiving; import common.init.EntityRegistry; import common.nbt.NBTTagCompound; import common.util.Util; -import common.world.Vec3; +import common.util.Vec3; import common.world.WorldServer; import server.command.Command; import server.command.CommandEnvironment; diff --git a/server/src/server/command/commands/CommandTele.java b/server/src/server/command/commands/CommandTele.java index 19766bf..e2f735a 100644 --- a/server/src/server/command/commands/CommandTele.java +++ b/server/src/server/command/commands/CommandTele.java @@ -4,7 +4,7 @@ import java.util.List; import common.dimension.Dimension; import common.entity.Entity; -import common.world.Vec3; +import common.util.Vec3; import server.command.Command; import server.command.CommandEnvironment; import server.command.Executor; diff --git a/server/src/server/command/commands/CommandTime.java b/server/src/server/command/commands/CommandTime.java index 1a4676e..1f3561f 100644 --- a/server/src/server/command/commands/CommandTime.java +++ b/server/src/server/command/commands/CommandTime.java @@ -2,7 +2,7 @@ package server.command.commands; import common.dimension.Dimension; import common.item.ItemSpaceNavigator; -import common.world.Position; +import common.util.Position; import common.world.WorldServer; import server.command.Command; import server.command.CommandEnvironment; diff --git a/server/src/server/command/commands/CommandTp.java b/server/src/server/command/commands/CommandTp.java index e300ae7..f6a09f6 100644 --- a/server/src/server/command/commands/CommandTp.java +++ b/server/src/server/command/commands/CommandTp.java @@ -4,7 +4,7 @@ import java.util.List; import common.entity.Entity; import common.init.UniverseRegistry; -import common.world.Position; +import common.util.Position; import server.command.Command; import server.command.CommandEnvironment; import server.command.Executor; diff --git a/server/src/server/command/commands/CommandWarp.java b/server/src/server/command/commands/CommandWarp.java index 987e9de..e33dd3b 100644 --- a/server/src/server/command/commands/CommandWarp.java +++ b/server/src/server/command/commands/CommandWarp.java @@ -5,7 +5,7 @@ import java.util.List; import common.entity.Entity; import common.init.UniverseRegistry; -import common.world.Position; +import common.util.Position; import server.command.Command; import server.command.CommandEnvironment; import server.command.Executor; diff --git a/server/src/server/command/commands/CommandWorld.java b/server/src/server/command/commands/CommandWorld.java index 3b02edb..6257e46 100644 --- a/server/src/server/command/commands/CommandWorld.java +++ b/server/src/server/command/commands/CommandWorld.java @@ -3,7 +3,7 @@ package server.command.commands; import java.util.List; import common.entity.Entity; -import common.world.BlockPos; +import common.util.BlockPos; import common.world.WorldServer; import server.command.Command; import server.command.CommandEnvironment; diff --git a/server/src/server/network/Player.java b/server/src/server/network/Player.java index 544e4ef..6a418d3 100755 --- a/server/src/server/network/Player.java +++ b/server/src/server/network/Player.java @@ -114,21 +114,21 @@ import common.tileentity.ILockableContainer; import common.tileentity.TileEntity; import common.tileentity.TileEntityMachine; import common.tileentity.TileEntitySign; +import common.util.BlockPos; +import common.util.BoundingBox; +import common.util.ChunkPos; import common.util.ExtMath; +import common.util.Facing; +import common.util.IntHashMap; +import common.util.PortalType; +import common.util.Position; +import common.util.Vec3i; +import common.util.WorldPos; import common.village.MerchantRecipeList; -import common.world.BlockPos; -import common.world.BoundingBox; import common.world.Chunk; -import common.world.ChunkPos; -import common.world.Facing; -import common.world.IntHashMap; -import common.world.PortalType; -import common.world.Position; import common.world.Region; import common.world.State; -import common.world.Vec3i; import common.world.World; -import common.world.WorldPos; import common.world.WorldServer; import io.netty.util.concurrent.Future; import io.netty.util.concurrent.GenericFutureListener; From 193a12b00f9b22f502971494ccc7085753b5c726 Mon Sep 17 00:00:00 2001 From: Sen Date: Thu, 8 May 2025 13:00:17 +0200 Subject: [PATCH 010/200] net client --- client/src/client/Game.java | 46 ++++++++++++++- common/src/common/network/NetConnection.java | 62 -------------------- 2 files changed, 45 insertions(+), 63 deletions(-) diff --git a/client/src/client/Game.java b/client/src/client/Game.java index f754b50..abdb07b 100755 --- a/client/src/client/Game.java +++ b/client/src/client/Game.java @@ -109,6 +109,7 @@ import common.entity.types.IEntityFX; import common.future.Futures; import common.future.ListenableFuture; import common.future.ListenableFutureTask; +import common.future.ThreadFactoryBuilder; import common.init.BlockRegistry; import common.init.Config; import common.init.EntityRegistry; @@ -129,6 +130,10 @@ import common.model.ParticleType; import common.nbt.NBTTagCompound; import common.network.IThreadListener; import common.network.NetConnection; +import common.network.PacketDecoder; +import common.network.PacketEncoder; +import common.network.PacketPrepender; +import common.network.PacketSplitter; import common.network.NetHandler.ThreadQuickExitException; import common.packet.CPacketAction; import common.packet.CPacketCheat; @@ -151,6 +156,7 @@ import common.util.ExtMath; import common.util.Facing; import common.util.FileUtils; import common.util.HitPosition; +import common.util.LazyLoadBase; import common.util.Util; import common.util.HitPosition.ObjectType; import common.world.Chunk; @@ -159,6 +165,15 @@ import common.world.Region; import common.world.State; import common.world.World; import common.world.WorldClient; +import io.netty.bootstrap.Bootstrap; +import io.netty.channel.Channel; +import io.netty.channel.ChannelException; +import io.netty.channel.ChannelHandler; +import io.netty.channel.ChannelInitializer; +import io.netty.channel.ChannelOption; +import io.netty.channel.nio.NioEventLoopGroup; +import io.netty.channel.socket.nio.NioSocketChannel; +import io.netty.handler.timeout.ReadTimeoutHandler; /* Een net ganz funktionierndes Programm ... @@ -247,6 +262,13 @@ public class Game implements IThreadListener, IClient { } public static final int LOG_BUFFER = 32768; + private static final LazyLoadBase CLIENT_NIO_EVENTLOOP = new LazyLoadBase() + { + protected NioEventLoopGroup load() + { + return new NioEventLoopGroup(0, (new ThreadFactoryBuilder()).setNameFormat("Netty Client IO #%d").setDaemon(true).build()); + } + }; private final Queue> tasks = new ArrayDeque>(); private final Map bars = Maps.newTreeMap(); @@ -446,13 +468,35 @@ public class Game implements IThreadListener, IClient { return INSTANCE; } + private static NetConnection createNetworkManagerAndConnect(InetAddress address, int serverPort) + { + final NetConnection networkmanager = new NetConnection(); + ((Bootstrap)((Bootstrap)((Bootstrap)(new Bootstrap()).group(CLIENT_NIO_EVENTLOOP.getValue())).handler(new ChannelInitializer() + { + protected void initChannel(Channel p_initChannel_1_) throws Exception + { + try + { + p_initChannel_1_.config().setOption(ChannelOption.TCP_NODELAY, Boolean.valueOf(true)); + } + catch (ChannelException var3) + { + ; + } + + p_initChannel_1_.pipeline().addLast((String)"timeout", (ChannelHandler)(new ReadTimeoutHandler(30))).addLast((String)"splitter", (ChannelHandler)(new PacketSplitter())).addLast((String)"decoder", (ChannelHandler)(new PacketDecoder(false))).addLast((String)"prepender", (ChannelHandler)(new PacketPrepender())).addLast((String)"encoder", (ChannelHandler)(new PacketEncoder(true))).addLast((String)"packet_handler", (ChannelHandler)networkmanager); + } + })).channel(NioSocketChannel.class)).connect(address, serverPort).syncUninterruptibly(); + return networkmanager; + } + public void connect(String address, int port, String user, String pass, String access) { this.displayGuiScreen(GuiLoading.makeWaitTask("Verbinde zu " + (address == null ? "localhost" : address) + ":" + port + " ...")); Log.JNI.info("Verbinde zu " + (address == null ? "localhost" : address) + ":" + port); NetConnection connection = null; try { - connection = NetConnection.createNetworkManagerAndConnect(address == null ? InetAddress.getLoopbackAddress() : InetAddress.getByName(IDN.toASCII(address)), port); + connection = createNetworkManagerAndConnect(address == null ? InetAddress.getLoopbackAddress() : InetAddress.getByName(IDN.toASCII(address)), port); connection.setNetHandler(new ClientLoginHandler(connection, this)); connection.sendPacket(new HPacketHandshake(Config.PROTOCOL)); connection.sendPacket(new LPacketPasswordResponse(user, access, pass)); diff --git a/common/src/common/network/NetConnection.java b/common/src/common/network/NetConnection.java index 89c055a..a77835e 100755 --- a/common/src/common/network/NetConnection.java +++ b/common/src/common/network/NetConnection.java @@ -1,31 +1,18 @@ package common.network; -import java.net.InetAddress; import java.net.SocketAddress; import java.util.Queue; import java.util.concurrent.ConcurrentLinkedQueue; import java.util.concurrent.locks.ReentrantReadWriteLock; import java.util.regex.Pattern; -import common.future.ThreadFactoryBuilder; import common.log.Log; import common.network.NetHandler.ThreadQuickExitException; -import common.util.LazyLoadBase; -import io.netty.bootstrap.Bootstrap; import io.netty.channel.Channel; -import io.netty.channel.ChannelException; import io.netty.channel.ChannelFuture; import io.netty.channel.ChannelFutureListener; -import io.netty.channel.ChannelHandler; import io.netty.channel.ChannelHandlerContext; -import io.netty.channel.ChannelInitializer; -import io.netty.channel.ChannelOption; -import io.netty.channel.EventLoopGroup; import io.netty.channel.SimpleChannelInboundHandler; -import io.netty.channel.nio.NioEventLoopGroup; -import io.netty.channel.socket.SocketChannel; -import io.netty.channel.socket.nio.NioSocketChannel; -import io.netty.handler.timeout.ReadTimeoutHandler; import io.netty.handler.timeout.TimeoutException; import io.netty.util.AttributeKey; import io.netty.util.concurrent.Future; @@ -35,13 +22,6 @@ public class NetConnection extends SimpleChannelInboundHandler { private static final Pattern IP_REPLACER = Pattern.compile("([0-9]*)\\.([0-9]*)\\.[0-9]*\\.[0-9]*"); public static final AttributeKey ATTR_STATE = AttributeKey.valueOf("protocol"); - public static final LazyLoadBase CLIENT_NIO_EVENTLOOP = new LazyLoadBase() - { - protected NioEventLoopGroup load() - { - return new NioEventLoopGroup(0, (new ThreadFactoryBuilder()).setNameFormat("Netty Client IO #%d").setDaemon(true).build()); - } - }; private final Queue outboundPacketsQueue = new ConcurrentLinkedQueue(); private final ReentrantReadWriteLock readWriteLock = new ReentrantReadWriteLock(); @@ -290,48 +270,6 @@ public class NetConnection extends SimpleChannelInboundHandler this.terminationReason = message; } } - - /** - * Create a new NetworkManager from the server host and connect it to the server - * - * @param address The address of the server - * @param serverPort The server port - */ - public static NetConnection createNetworkManagerAndConnect(InetAddress address, int serverPort) - { - final NetConnection networkmanager = new NetConnection(); - Class oclass; - LazyLoadBase lazyloadbase; - -// if (Epoll.isAvailable()) -// { -// oclass = EpollSocketChannel.class; -// lazyloadbase = CLIENT_EPOLL_EVENTLOOP; -// } -// else -// { - oclass = NioSocketChannel.class; - lazyloadbase = CLIENT_NIO_EVENTLOOP; -// } - - ((Bootstrap)((Bootstrap)((Bootstrap)(new Bootstrap()).group((EventLoopGroup)lazyloadbase.getValue())).handler(new ChannelInitializer() - { - protected void initChannel(Channel p_initChannel_1_) throws Exception - { - try - { - p_initChannel_1_.config().setOption(ChannelOption.TCP_NODELAY, Boolean.valueOf(true)); - } - catch (ChannelException var3) - { - ; - } - - p_initChannel_1_.pipeline().addLast((String)"timeout", (ChannelHandler)(new ReadTimeoutHandler(30))).addLast((String)"splitter", (ChannelHandler)(new PacketSplitter())).addLast((String)"decoder", (ChannelHandler)(new PacketDecoder(false))).addLast((String)"prepender", (ChannelHandler)(new PacketPrepender())).addLast((String)"encoder", (ChannelHandler)(new PacketEncoder(true))).addLast((String)"packet_handler", (ChannelHandler)networkmanager); - } - })).channel(oclass)).connect(address, serverPort).syncUninterruptibly(); - return networkmanager; - } public boolean isChannelOpen() { From 812a981e4a54682ea3b3ce6f24f0043f20f4de12 Mon Sep 17 00:00:00 2001 From: Sen Date: Thu, 8 May 2025 13:03:36 +0200 Subject: [PATCH 011/200] rename Game -> Client --- client/src/client/{Game.java => Client.java} | 180 +++++++++--------- client/src/client/PlayerController.java | 4 +- client/src/client/audio/SoundManager.java | 6 +- client/src/client/audio/Volume.java | 6 +- client/src/client/gui/Gui.java | 4 +- client/src/client/gui/GuiConsole.java | 4 +- client/src/client/gui/GuiConvert.java | 2 +- client/src/client/gui/GuiLoading.java | 8 +- client/src/client/gui/character/GuiChar.java | 10 +- client/src/client/gui/container/GuiChest.java | 4 +- .../src/client/gui/container/GuiHopper.java | 4 +- client/src/client/gui/container/GuiHorse.java | 4 +- .../src/client/gui/container/GuiMachine.java | 4 +- .../src/client/gui/container/GuiRepair.java | 4 +- client/src/client/gui/element/Element.java | 4 +- client/src/client/gui/element/NavButton.java | 4 +- .../client/network/ClientLoginHandler.java | 6 +- client/src/client/network/ClientPlayer.java | 6 +- client/src/client/renderer/BlockRenderer.java | 8 +- client/src/client/renderer/Drawing.java | 6 +- .../src/client/renderer/EntityRenderer.java | 6 +- client/src/client/renderer/ItemRenderer.java | 6 +- client/src/client/renderer/RenderGlobal.java | 8 +- .../renderer/chunk/ChunkRenderDispatcher.java | 4 +- .../renderer/chunk/ChunkRenderWorker.java | 4 +- .../client/renderer/chunk/RenderChunk.java | 4 +- client/src/client/renderer/entity/Render.java | 4 +- .../renderer/entity/RenderBlockEntity.java | 4 +- .../src/client/renderer/entity/RenderDie.java | 4 +- .../renderer/entity/RenderFallingBlock.java | 4 +- .../renderer/entity/RenderFireball.java | 4 +- .../client/renderer/entity/RenderFish.java | 4 +- .../client/renderer/entity/RenderHorse.java | 4 +- .../client/renderer/entity/RenderManager.java | 6 +- .../renderer/entity/RenderMinecart.java | 4 +- .../renderer/entity/RenderTntMinecart.java | 4 +- .../renderer/entity/RenderTntPrimed.java | 4 +- .../client/renderer/layers/LayerExtra.java | 4 +- .../client/renderer/layers/LayerHeldItem.java | 4 +- .../layers/LayerMooshroomMushroom.java | 4 +- .../renderer/particle/EntityBreakingFX.java | 4 +- .../renderer/particle/EntityDiggingFX.java | 4 +- .../client/renderer/particle/EntityFX.java | 6 +- .../renderer/particle/EntityFirework.java | 6 +- .../renderer/particle/EntityFootStepFX.java | 4 +- .../particle/EntityLargeExplodeFX.java | 4 +- .../renderer/particle/EntityPickupFX.java | 4 +- .../renderer/texture/EntityTexManager.java | 26 +-- .../tileentity/TileEntityBannerRenderer.java | 6 +- .../TileEntityMobSpawnerRenderer.java | 4 +- .../tileentity/TileEntityPistonRenderer.java | 4 +- client/src/client/window/Bind.java | 14 +- client/src/client/window/Button.java | 4 +- client/src/client/window/Wheel.java | 4 +- client/src/client/world/Converter.java | 10 +- 55 files changed, 234 insertions(+), 238 deletions(-) rename client/src/client/{Game.java => Client.java} (95%) diff --git a/client/src/client/Game.java b/client/src/client/Client.java similarity index 95% rename from client/src/client/Game.java rename to client/src/client/Client.java index abdb07b..0bf4fb6 100755 --- a/client/src/client/Game.java +++ b/client/src/client/Client.java @@ -196,46 +196,46 @@ import io.netty.handler.timeout.ReadTimeoutHandler; [[oder einfach einen Toaster mit nem LCD und Maus]] */ -public class Game implements IThreadListener, IClient { +public class Client implements IThreadListener, IClient { public static class SyncFunction implements IntFunction { public void apply(IntVar cv, int value) { - Game.getGame().sync(value); + Client.CLIENT.sync(value); } } public static class TickFunction implements FloatFunction { public void apply(FloatVar cv, float value) { - Game.getGame().tick_target(value); + Client.CLIENT.tick_target(value); } } public static class ConsoleFunction implements IntFunction { public void apply(IntVar cv, int value) { - Game.getGame().resizeConsole(); + Client.CLIENT.resizeConsole(); } } public static class ChatFunction implements IntFunction { public void apply(IntVar cv, int value) { - Game.getGame().resizeChat(); + Client.CLIENT.resizeChat(); } } public static class FeedFunction implements IntFunction { public void apply(IntVar cv, int value) { - Game.getGame().resizeFeed(); + Client.CLIENT.resizeFeed(); } } public static class HotbarFunction implements IntFunction { public void apply(IntVar cv, int value) { - Game.getGame().resizeHotbar(); + Client.CLIENT.resizeHotbar(); } } public static class DistanceFunction implements IntFunction { public void apply(IntVar cv, int value) { - Game.getGame().distance(value); + Client.CLIENT.distance(value); } } @@ -455,20 +455,16 @@ public class Game implements IThreadListener, IClient { private long frameWait; private long startNanoTime = System.nanoTime(); - private static final Game INSTANCE = new Game(); + public static final Client CLIENT = new Client(); private final Bind[] keyBindsHotbar = new Bind[] { Bind.SELECT1, Bind.SELECT2, Bind.SELECT3, Bind.SELECT4, Bind.SELECT5, Bind.SELECT6, Bind.SELECT7, Bind.SELECT8, Bind.SELECT9 }; - private Game() { + private Client() { } - public static Game getGame() { - return INSTANCE; - } - - private static NetConnection createNetworkManagerAndConnect(InetAddress address, int serverPort) + private static NetConnection createNetworkManagerAndConnect(InetAddress address, int serverPort) { final NetConnection networkmanager = new NetConnection(); ((Bootstrap)((Bootstrap)((Bootstrap)(new Bootstrap()).group(CLIENT_NIO_EVENTLOOP.getValue())).handler(new ChannelInitializer() @@ -2308,18 +2304,18 @@ public class Game implements IThreadListener, IClient { GL11.glReadPixels(0, 0, this.fb_x, this.fb_y, GL11.GL_RGB, GL11.GL_UNSIGNED_BYTE, data); new Thread(new Runnable() { public void run() { - byte[] pixels = new byte[stride * Game.this.fb_y]; + byte[] pixels = new byte[stride * Client.this.fb_y]; data.get(pixels); - byte[] conv = new byte[Game.this.fb_x * Game.this.fb_y * 3]; - for(int l = 0; l < Game.this.fb_y; l++) { - System.arraycopy(pixels, l * stride, conv, (Game.this.fb_y - 1 - l) * Game.this.fb_x * 3, Game.this.fb_x * 3); + byte[] conv = new byte[Client.this.fb_x * Client.this.fb_y * 3]; + for(int l = 0; l < Client.this.fb_y; l++) { + System.arraycopy(pixels, l * stride, conv, (Client.this.fb_y - 1 - l) * Client.this.fb_x * 3, Client.this.fb_x * 3); } - BufferedImage image = new BufferedImage(Game.this.fb_x, Game.this.fb_y, BufferedImage.TYPE_INT_ARGB); - int[] img = new int[Game.this.fb_x * Game.this.fb_y]; + BufferedImage image = new BufferedImage(Client.this.fb_x, Client.this.fb_y, BufferedImage.TYPE_INT_ARGB); + int[] img = new int[Client.this.fb_x * Client.this.fb_y]; for(int z = 0; z < img.length; z++) { img[z] = (int)(conv[(z * 3) + 2] & 0xff) | ((int)(conv[(z * 3) + 1] & 0xff) << 8) | ((int)(conv[(z * 3) + 0] & 0xff) << 16) | 0xff000000; } - image.setRGB(0, 0, Game.this.fb_x, Game.this.fb_y, img, 0, Game.this.fb_x); + image.setRGB(0, 0, Client.this.fb_x, Client.this.fb_y, img, 0, Client.this.fb_x); File dir = new File("screenshots"); dir.mkdirs(); @@ -2336,18 +2332,18 @@ public class Game implements IThreadListener, IClient { ImageIO.write(image, "png", file); } catch(IOException e) { - Game.this.schedule(new Runnable() { + Client.this.schedule(new Runnable() { public void run() { - Game.this.saving = false; + Client.this.saving = false; Log.IO.error(e, "Konnte Textur '" + saved + "' nicht speichern"); } }); return; } - Game.this.schedule(new Runnable() { + Client.this.schedule(new Runnable() { public void run() { - Game.this.saving = false; - Game.this.logFeed("Bildschirmfoto als '%s' gespeichert", saved.getName()); + Client.this.saving = false; + Client.this.logFeed("Bildschirmfoto als '%s' gespeichert", saved.getName()); } }); } @@ -2422,12 +2418,12 @@ public class Game implements IThreadListener, IClient { } public void restartSound(boolean load) { - Game.this.logFeed("Lade Sound-System neu"); + Client.this.logFeed("Lade Sound-System neu"); this.soundManager.unload(); if(audio.end()) Log.SOUND.info("Audiogerät geschlossen"); this.startSound(load); - Game.this.logFeed("Das Sound-System wurde neu geladen"); + Client.this.logFeed("Das Sound-System wurde neu geladen"); } public AudioInterface getAudioInterface() { @@ -2449,124 +2445,124 @@ public class Game implements IThreadListener, IClient { this.registerDebug(Keysym.H, "Hilfe zu Tastenkombinationen anzeigen", new DebugRunner() { public void execute(Keysym key) { String bind = Bind.CHEAT.getInput() == null ? "n/a" : Bind.CHEAT.getInput().getDisplay(); - Game.this.displayGuiScreen(new GuiInfo("Hilfe zu Tastenkombinationen", TextColor.DGREEN + "" + Game.this.debug.size() + " Tastenkombinationen stehen zur Verfügung:\n" + + Client.this.displayGuiScreen(new GuiInfo("Hilfe zu Tastenkombinationen", TextColor.DGREEN + "" + Client.this.debug.size() + " Tastenkombinationen stehen zur Verfügung:\n" + Util.buildLines(new Function() { public String apply(DebugFunction func) { return TextColor.CYAN + bind + TextColor.RED + "+" + TextColor.GREEN + func.key.getDisplay() + TextColor.GRAY + " - " + TextColor.YELLOW + func.help; } - }, Game.this.debug.values()))); + }, Client.this.debug.values()))); } }); this.registerDebug(Keysym.N, "NoClip umschalten", new DebugRunner() { public void execute(Keysym key) { - Game.this.performAction(Action.NOCLIP); + Client.this.performAction(Action.NOCLIP); } }); this.registerDebug(Keysym.G, "Unsterblichkeit umschalten", new DebugRunner() { public void execute(Keysym key) { - Game.this.performAction(Action.GOD); + Client.this.performAction(Action.GOD); } }); this.registerDebug(Keysym.F, "Geschwindigkeit umschalten", new DebugRunner() { public void execute(Keysym key) { - Game.this.performAction(Action.SPEED); + Client.this.performAction(Action.SPEED); } }); this.registerDebug(Keysym.R, "Gegenstand reparieren und Stapel auffüllen", new DebugRunner() { public void execute(Keysym key) { - Game.this.performAction(Action.REPAIR); + Client.this.performAction(Action.REPAIR); } }); this.registerDebug(Keysym.E, "Gegenstands-Cheat-Menü umschalten", new DebugRunner() { public void execute(Keysym key) { - Game.this.logFeed("Cheat-Menü: %s", (Game.this.itemCheat ^= true) ? "an" : "aus"); - if(Game.this.open instanceof GuiContainer) - Game.this.open.init(); + Client.this.logFeed("Cheat-Menü: %s", (Client.this.itemCheat ^= true) ? "an" : "aus"); + if(Client.this.open instanceof GuiContainer) + Client.this.open.init(); } }); this.registerDebug(Keysym.L, "Maximale Helligkeit umschalten", new DebugRunner() { public void execute(Keysym key) { - Game.this.logFeed("Maximale Helligkeit: %s", (Game.this.setGamma ^= true) ? "an" : "aus"); + Client.this.logFeed("Maximale Helligkeit: %s", (Client.this.setGamma ^= true) ? "an" : "aus"); } }); this.registerDebug(Keysym.J, "JVM GC ausführen", new DebugRunner() { public void execute(Keysym key) { - Game.this.logFeed("Führe JVM GC aus"); + Client.this.logFeed("Führe JVM GC aus"); long mem = Runtime.getRuntime().freeMemory(); System.gc(); System.gc(); mem = Runtime.getRuntime().freeMemory() - mem; mem = mem < 0L ? 0L : mem; - Game.this.logFeed("JVM GC ausgeführt: %d MB freigegeben", (int)(mem / 1024L / 1024L)); + Client.this.logFeed("JVM GC ausgeführt: %d MB freigegeben", (int)(mem / 1024L / 1024L)); } }); this.registerDebug(Keysym.B, "Hitbox-Overlay umschalten", new DebugRunner() { public void execute(Keysym key) { - Game.this.getRenderManager().setDebugBoundingBox(!Game.this.getRenderManager().isDebugBoundingBox()); - Game.this.logFeed("Objekt-Grenzen: %s", Game.this.getRenderManager().isDebugBoundingBox() ? "an" : "aus"); + Client.this.getRenderManager().setDebugBoundingBox(!Client.this.getRenderManager().isDebugBoundingBox()); + Client.this.logFeed("Objekt-Grenzen: %s", Client.this.getRenderManager().isDebugBoundingBox() ? "an" : "aus"); } }); this.registerDebug(Keysym.K, "Debug-Kamera in 3. Person umschalten", new DebugRunner() { public void execute(Keysym key) { - Game.this.logFeed("Debug-Kamera 3. Person: %s", (Game.this.debugCamEnable ^= true) ? "an" : "aus"); + Client.this.logFeed("Debug-Kamera 3. Person: %s", (Client.this.debugCamEnable ^= true) ? "an" : "aus"); } }); this.registerDebug(Keysym.X, "Röntgenblick umschalten", new DebugRunner() { public void execute(Keysym key) { - Game.this.xrayActive ^= true; - Game.this.renderGlobal.loadRenderers(); - Game.this.logFeed("Röntgenblick: %s", Game.this.xrayActive ? "an" : "aus"); + Client.this.xrayActive ^= true; + Client.this.renderGlobal.loadRenderers(); + Client.this.logFeed("Röntgenblick: %s", Client.this.xrayActive ? "an" : "aus"); } }); this.registerDebug(Keysym.O, "Objekt-Overlay umschalten", new DebugRunner() { public void execute(Keysym key) { - Game.this.logFeed("Objekt-Umrahmung: %s", (Game.this.renderOutlines ^= true) ? "an" : "aus"); + Client.this.logFeed("Objekt-Umrahmung: %s", (Client.this.renderOutlines ^= true) ? "an" : "aus"); } }); this.registerDebug(Keysym.I, "Block-Objekt-Overlay umschalten", new DebugRunner() { public void execute(Keysym key) { - Game.this.logFeed("Block-Objekte anzeigen: %s", (Game.this.tileOverlay ^= true) ? "an" : "aus"); + Client.this.logFeed("Block-Objekte anzeigen: %s", (Client.this.tileOverlay ^= true) ? "an" : "aus"); } }); this.registerDebug(Keysym.Y, "Alle Chunks neu kompilieren", new DebugRunner() { public void execute(Keysym key) { - Game.this.logFeed("Kompiliere alle Chunks neu"); - Game.this.renderGlobal.loadRenderers(); - Game.this.logFeed("Alle Chunks wurden neu kompiliert"); + Client.this.logFeed("Kompiliere alle Chunks neu"); + Client.this.renderGlobal.loadRenderers(); + Client.this.logFeed("Alle Chunks wurden neu kompiliert"); } }); this.registerDebug(Keysym.T, "Alle Texturen neu laden", new DebugRunner() { public void execute(Keysym key) { - Game.this.logFeed("Lade Texturen neu"); - Game.this.refreshResources(); - Game.this.logFeed("Texturen wurden neu geladen"); + Client.this.logFeed("Lade Texturen neu"); + Client.this.refreshResources(); + Client.this.logFeed("Texturen wurden neu geladen"); } }); this.registerDebug(Keysym.S, "Alle Sounds neu laden", new DebugRunner() { public void execute(Keysym key) { - Game.this.logFeed("Lade Sounds neu"); - Game.this.restartSound(true); - Game.this.logFeed("Sounds wurden neu geladen"); + Client.this.logFeed("Lade Sounds neu"); + Client.this.restartSound(true); + Client.this.logFeed("Sounds wurden neu geladen"); } }); this.registerDebug(Keysym.W, "Server-Tick-Limit umschalten (Welt beschleunigen / Warpmodus)", new DebugRunner() { public void execute(Keysym key) { - Game.this.performAction(Action.WARP_MODE); + Client.this.performAction(Action.WARP_MODE); } }); this.registerDebug(Keysym.M, "Alle Gegenstände herbei ziehen (Magnetmodus)", new DebugRunner() { public void execute(Keysym key) { - Game.this.performAction(Action.MAGNET); + Client.this.performAction(Action.MAGNET); } }); this.registerDebug(Keysym.Z, "Den Spieler heilen", new DebugRunner() { public void execute(Keysym key) { - Game.this.performAction(Action.HEAL); + Client.this.performAction(Action.HEAL); } }); this.registerDebug(Keysym.P, "Server Performance-Anfrage senden", new DebugRunner() { public void execute(Keysym key) { - Game.this.performAction(Action.PERF); + Client.this.performAction(Action.PERF); } }); this.registerDebug(Keysym.C, "Debug-Crash auslösen (2x schnell hintereinander)", new DebugRunner() { @@ -2578,52 +2574,52 @@ public class Game implements IThreadListener, IClient { } else { this.lastUsed = System.currentTimeMillis(); - Game.this.logFeed(TextColor.RED + "VORSICHT: Debug-Absturz nach mehrmaligem Drücken innerhalb einer Sekunde"); + Client.this.logFeed(TextColor.RED + "VORSICHT: Debug-Absturz nach mehrmaligem Drücken innerhalb einer Sekunde"); } } }); this.registerDebug(Keysym.V, "Alle Sounds stoppen", new DebugRunner() { public void execute(Keysym key) { - Game.this.soundManager.stopSounds(); + Client.this.soundManager.stopSounds(); } }); this.registerDebug(Keysym.Q, "Programm sofort beenden und speichern", new DebugRunner() { public void execute(Keysym key) { - Game.this.interrupted = true; + Client.this.interrupted = true; } }); this.registerDebug(Keysym.A, "Bild-Synchonisation umschalten (VSync - begrenzt - unbegrenzt)", new DebugRunner() { public void execute(Keysym key) { - Game.this.getVar("win_sync").parse("" + (Game.this.vsync ? Game.this.syncLimit : (Game.this.syncLimited ? -1 : 0))); - Game.this.setDirty(); + Client.this.getVar("win_sync").parse("" + (Client.this.vsync ? Client.this.syncLimit : (Client.this.syncLimited ? -1 : 0))); + Client.this.setDirty(); } }); this.registerDebug(Keysym.D, "Konsole und Chat leeren", new DebugRunner() { public void execute(Keysym key) { GuiConsole.INSTANCE.reset(); - if(Game.this.open instanceof GuiConsole) - ((GuiConsole)Game.this.open).setLog(Game.this.buffer); + if(Client.this.open instanceof GuiConsole) + ((GuiConsole)Client.this.open).setLog(Client.this.buffer); } }); this.registerDebug(Keysym.U, "HUD umschalten", new DebugRunner() { public void execute(Keysym key) { - Game.this.showHud ^= true; + Client.this.showHud ^= true; } }); this.registerDebug(Keysym.UE, "Spieler in Overlay umschalten", new DebugRunner() { public void execute(Keysym key) { - Game.this.logFeed("Spieler-Info in Overlay: %s", (Game.this.debugPlayer ^= true) ? "an" : "aus"); + Client.this.logFeed("Spieler-Info in Overlay: %s", (Client.this.debugPlayer ^= true) ? "an" : "aus"); } }); this.registerDebug(Keysym.OE, "Tick-Profiler umschalten", new DebugRunner() { public void execute(Keysym key) { - if(Game.this.lastTickTime >= 0) { - Game.this.performAction(Action.STOP_PROFILING); - Game.this.lastTickTime = -1; + if(Client.this.lastTickTime >= 0) { + Client.this.performAction(Action.STOP_PROFILING); + Client.this.lastTickTime = -1; } else { - Game.this.performAction(Action.START_PROFILING); - Game.this.lastTickTime = 0; + Client.this.performAction(Action.START_PROFILING); + Client.this.lastTickTime = 0; } } }); @@ -2645,11 +2641,11 @@ public class Game implements IThreadListener, IClient { public static void main(String[] args) { Util.checkOs(); - Log.init(INSTANCE); + Log.init(CLIENT); Window.init(); ModelBlock.setAsProvider(); Registry.setup("Render thread"); - INSTANCE.run(); + CLIENT.run(); Window.end(); } @@ -3256,12 +3252,12 @@ public class Game implements IThreadListener, IClient { } catch(Throwable e) { Log.SYSTEM.error(e, "Konnte Zenity nicht starten"); - Game.this.logFeed(TextColor.RED + "Konnte Dateibrowser nicht öffnen"); - Game.this.waitingForFile = false; + Client.this.logFeed(TextColor.RED + "Konnte Dateibrowser nicht öffnen"); + Client.this.waitingForFile = false; return; } if(output == null) { - Game.this.waitingForFile = false; + Client.this.waitingForFile = false; return; } if(mode == FileMode.FILE_LOAD_MULTI) { @@ -3272,17 +3268,17 @@ public class Game implements IThreadListener, IClient { files.add(file); } if(files.isEmpty()) { - Game.this.waitingForFile = false; + Client.this.waitingForFile = false; return; } - Game.this.schedule(new Runnable() { + Client.this.schedule(new Runnable() { public void run() { - if(Game.this.waitingForFile) { + if(Client.this.waitingForFile) { for(File file : files) { callback.selected(file); } } - Game.this.waitingForFile = false; + Client.this.waitingForFile = false; } }); } @@ -3291,34 +3287,34 @@ public class Game implements IThreadListener, IClient { switch(mode) { case DIRECTORY_LOAD: if(!file.isDirectory()) { - Game.this.waitingForFile = false; + Client.this.waitingForFile = false; return; } break; case DIRECTORY_SAVE: if(file.exists() && !file.isDirectory()) { - Game.this.waitingForFile = false; + Client.this.waitingForFile = false; return; } break; case FILE_LOAD: if(!file.isFile()) { - Game.this.waitingForFile = false; + Client.this.waitingForFile = false; return; } break; case FILE_SAVE: if(file.exists() && !file.isFile()) { - Game.this.waitingForFile = false; + Client.this.waitingForFile = false; return; } break; } - Game.this.schedule(new Runnable() { + Client.this.schedule(new Runnable() { public void run() { - if(Game.this.waitingForFile) + if(Client.this.waitingForFile) callback.selected(file); - Game.this.waitingForFile = false; + Client.this.waitingForFile = false; } }); } diff --git a/client/src/client/PlayerController.java b/client/src/client/PlayerController.java index e6c48f4..a638839 100755 --- a/client/src/client/PlayerController.java +++ b/client/src/client/PlayerController.java @@ -24,7 +24,7 @@ import common.world.WorldClient; public class PlayerController { - private final Game gm; + private final Client gm; private final ClientPlayer netClientHandler; private BlockPos currentBlock = new BlockPos(-1, -1, -1); private ItemStack currentItemHittingBlock; @@ -36,7 +36,7 @@ public class PlayerController private int currentPlayerItem; private boolean interacting; - public PlayerController(Game gmIn, ClientPlayer netHandler) + public PlayerController(Client gmIn, ClientPlayer netHandler) { this.gm = gmIn; this.netClientHandler = netHandler; diff --git a/client/src/client/audio/SoundManager.java b/client/src/client/audio/SoundManager.java index 062682c..6942153 100755 --- a/client/src/client/audio/SoundManager.java +++ b/client/src/client/audio/SoundManager.java @@ -10,7 +10,7 @@ import java.util.List; import java.util.Map; import java.util.Map.Entry; -import client.Game; +import client.Client; import common.collect.BiMap; import common.collect.HashBiMap; import common.collect.Lists; @@ -85,7 +85,7 @@ public class SoundManager { private final Map playingSoundsStopTime = Maps.newHashMap(); private final Map sources = new HashMap(); private final String[] channels = new String[28]; - private final Game gm; + private final Client gm; private float listenerX; private float listenerY; @@ -94,7 +94,7 @@ public class SoundManager { private int playTime = 0; private int eventId = 0; - public SoundManager(Game gm) { + public SoundManager(Client gm) { this.gm = gm; } diff --git a/client/src/client/audio/Volume.java b/client/src/client/audio/Volume.java index a879b91..f402a3a 100644 --- a/client/src/client/audio/Volume.java +++ b/client/src/client/audio/Volume.java @@ -1,6 +1,6 @@ package client.audio; -import client.Game; +import client.Client; import client.gui.element.Slider; import client.vars.CVar; import client.vars.CVarCategory; @@ -91,8 +91,8 @@ public enum Volume implements CVar { } public void apply() { - if(Game.getGame().getAudioInterface() != null) - Game.getGame().getAudioInterface().alSetVolume(this, (short)(((float)this.value) / 100.0f * 32767.0f)); + if(Client.CLIENT.getAudioInterface() != null) + Client.CLIENT.getAudioInterface().alSetVolume(this, (short)(((float)this.value) / 100.0f * 32767.0f)); } public Slider selector(int x, int y, int w, int h) { diff --git a/client/src/client/gui/Gui.java b/client/src/client/gui/Gui.java index 36c7810..bad7a40 100644 --- a/client/src/client/gui/Gui.java +++ b/client/src/client/gui/Gui.java @@ -4,7 +4,7 @@ import java.util.List; import org.lwjgl.opengl.GL13; -import client.Game; +import client.Client; import client.gui.element.Dropdown; import client.gui.element.Dropdown.Handle; import client.gui.element.Element; @@ -20,7 +20,7 @@ public abstract class Gui { public static final int HOVER_COLOR = 0x288080ff; public static final int PRESS_COLOR = 0x30afafff; - protected final Game gm = Game.getGame(); + protected final Client gm = Client.CLIENT; public Element selected; private int min_x; diff --git a/client/src/client/gui/GuiConsole.java b/client/src/client/gui/GuiConsole.java index dafb2e7..4ff2c19 100644 --- a/client/src/client/gui/GuiConsole.java +++ b/client/src/client/gui/GuiConsole.java @@ -2,7 +2,7 @@ package client.gui; import java.util.List; -import client.Game; +import client.Client; import client.gui.element.ActButton; import client.gui.element.Fill; import client.gui.element.Textbox; @@ -142,7 +142,7 @@ public class GuiConsole extends Gui implements Textbox.Callback { private void addMessage(String msg) { String buffer = this.gm.getBuffer(); - if((buffer.length() + msg.length() + 2) > Game.LOG_BUFFER) { + if((buffer.length() + msg.length() + 2) > Client.LOG_BUFFER) { int offset = (msg.length() + 2) > 1024 ? (msg.length() + 2) : 1024; int nl = buffer.indexOf('\n', offset); buffer = nl >= 0 ? buffer.substring(nl + 1) : ""; diff --git a/client/src/client/gui/GuiConvert.java b/client/src/client/gui/GuiConvert.java index 8799b51..f45e633 100755 --- a/client/src/client/gui/GuiConvert.java +++ b/client/src/client/gui/GuiConvert.java @@ -6,7 +6,7 @@ import java.text.SimpleDateFormat; import java.util.Collections; import java.util.Date; -import client.Game.FileMode; +import client.Client.FileMode; import client.gui.element.ActButton; import client.gui.element.ActButton.Mode; import client.gui.element.GuiList; diff --git a/client/src/client/gui/GuiLoading.java b/client/src/client/gui/GuiLoading.java index d1750bd..f51592b 100644 --- a/client/src/client/gui/GuiLoading.java +++ b/client/src/client/gui/GuiLoading.java @@ -1,12 +1,12 @@ package client.gui; -import client.Game; +import client.Client; import client.gui.element.Bar; import client.gui.element.Label; public class GuiLoading extends Gui { public static interface Callback { - void poll(Game gm, GuiLoading gui); + void poll(Client gm, GuiLoading gui); } private final String message; @@ -19,7 +19,7 @@ public class GuiLoading extends Gui { public static GuiLoading makeServerTask(String message) { return new GuiLoading(message, new Callback() { - public void poll(Game gm, GuiLoading gui) { + public void poll(Client gm, GuiLoading gui) { int progress = gm.progress; if(progress < 0) { gui.resetBar(); @@ -35,7 +35,7 @@ public class GuiLoading extends Gui { public static GuiLoading makeWaitTask(String message) { return new GuiLoading(message, new Callback() { - public void poll(Game gm, GuiLoading gui) { + public void poll(Client gm, GuiLoading gui) { } }); } diff --git a/client/src/client/gui/character/GuiChar.java b/client/src/client/gui/character/GuiChar.java index 806ec6e..76daeb4 100755 --- a/client/src/client/gui/character/GuiChar.java +++ b/client/src/client/gui/character/GuiChar.java @@ -14,8 +14,8 @@ import javax.imageio.ImageIO; import org.lwjgl.opengl.GL11; import org.lwjgl.opengl.GL13; -import client.Game; -import client.Game.FileMode; +import client.Client; +import client.Client.FileMode; import client.SkinConverter; import client.gui.FileCallback; import client.gui.GuiLoading; @@ -237,8 +237,8 @@ public class GuiChar extends GuiList public static class FilterFunction implements EnumFunction { public void apply(EnumVar cv, FilterType value) { - if(Game.getGame().open instanceof GuiChar) - Game.getGame().displayGuiScreen(Game.getGame().open); + if(Client.CLIENT.open instanceof GuiChar) + Client.CLIENT.displayGuiScreen(Client.CLIENT.open); } } @@ -613,7 +613,7 @@ public class GuiChar extends GuiList ent.headYaw = ent.rotYaw; ent.prevHeadYaw = ent.rotYaw; GL11.glTranslatef(0.0F, -(ent.height / 2), 0.0F); - RenderManager rendermanager = Game.getGame().getRenderManager(); + RenderManager rendermanager = Client.CLIENT.getRenderManager(); rendermanager.setPlayerViewY(180.0F); rendermanager.renderEntity(ent, 0.0D, 0.0D, 0.0D, 1.0F); // GL11.glTranslatef(0.0F, 0.0F, 0.0F); diff --git a/client/src/client/gui/container/GuiChest.java b/client/src/client/gui/container/GuiChest.java index e2bea30..85c444f 100755 --- a/client/src/client/gui/container/GuiChest.java +++ b/client/src/client/gui/container/GuiChest.java @@ -1,6 +1,6 @@ package client.gui.container; -import client.Game; +import client.Client; import common.inventory.ContainerChest; import common.inventory.IInventory; @@ -19,7 +19,7 @@ public class GuiChest extends GuiContainer public GuiChest(IInventory upperInv, IInventory lowerInv) { - super(new ContainerChest(upperInv, lowerInv, Game.getGame().thePlayer)); + super(new ContainerChest(upperInv, lowerInv, Client.CLIENT.thePlayer)); this.upperChestInventory = upperInv; this.lowerChestInventory = lowerInv; // this.allowUserInput = false; diff --git a/client/src/client/gui/container/GuiHopper.java b/client/src/client/gui/container/GuiHopper.java index 400105a..c76579f 100755 --- a/client/src/client/gui/container/GuiHopper.java +++ b/client/src/client/gui/container/GuiHopper.java @@ -1,6 +1,6 @@ package client.gui.container; -import client.Game; +import client.Client; import common.inventory.ContainerHopper; import common.inventory.IInventory; import common.inventory.InventoryPlayer; @@ -19,7 +19,7 @@ public class GuiHopper extends GuiContainer public GuiHopper(InventoryPlayer playerInv, IInventory hopperInv) { - super(new ContainerHopper(playerInv, hopperInv, Game.getGame().thePlayer)); + super(new ContainerHopper(playerInv, hopperInv, Client.CLIENT.thePlayer)); this.playerInventory = playerInv; this.hopperInventory = hopperInv; // this.allowUserInput = false; diff --git a/client/src/client/gui/container/GuiHorse.java b/client/src/client/gui/container/GuiHorse.java index 966bf1e..dbb5ec9 100755 --- a/client/src/client/gui/container/GuiHorse.java +++ b/client/src/client/gui/container/GuiHorse.java @@ -1,6 +1,6 @@ package client.gui.container; -import client.Game; +import client.Client; import common.entity.animal.EntityHorse; import common.inventory.ContainerHorseInventory; import common.inventory.IInventory; @@ -27,7 +27,7 @@ public class GuiHorse extends GuiContainer public GuiHorse(IInventory playerInv, IInventory horseInv, EntityHorse horse) { - super(new ContainerHorseInventory(playerInv, horseInv, horse, Game.getGame().thePlayer)); + super(new ContainerHorseInventory(playerInv, horseInv, horse, Client.CLIENT.thePlayer)); this.playerInventory = playerInv; this.horseInventory = horseInv; // this.horseEntity = horse; diff --git a/client/src/client/gui/container/GuiMachine.java b/client/src/client/gui/container/GuiMachine.java index 679131a..82ed33f 100755 --- a/client/src/client/gui/container/GuiMachine.java +++ b/client/src/client/gui/container/GuiMachine.java @@ -1,6 +1,6 @@ package client.gui.container; -import client.Game; +import client.Client; import common.inventory.ContainerMachine; import common.inventory.IInventory; import common.inventory.InventoryPlayer; @@ -16,7 +16,7 @@ public class GuiMachine extends GuiContainer public GuiMachine(InventoryPlayer player, IInventory inv, TileEntityMachine machine) { - super(new ContainerMachine(player, machine, inv, Game.getGame().thePlayer)); + super(new ContainerMachine(player, machine, inv, Client.CLIENT.thePlayer)); this.playerInv = player; this.machineInv = machine; // this.allowUserInput = false; diff --git a/client/src/client/gui/container/GuiRepair.java b/client/src/client/gui/container/GuiRepair.java index 85e4099..8015977 100755 --- a/client/src/client/gui/container/GuiRepair.java +++ b/client/src/client/gui/container/GuiRepair.java @@ -2,7 +2,7 @@ package client.gui.container; import java.util.List; -import client.Game; +import client.Client; import common.inventory.Container; import common.inventory.ContainerRepair; import common.inventory.ICrafting; @@ -21,7 +21,7 @@ public class GuiRepair extends GuiContainer implements ICrafting public GuiRepair(InventoryPlayer inventoryIn, World worldIn) { - super(new ContainerRepair(inventoryIn, worldIn, Game.getGame().thePlayer)); + super(new ContainerRepair(inventoryIn, worldIn, Client.CLIENT.thePlayer)); this.playerInventory = inventoryIn; this.anvil = (ContainerRepair)this.inventorySlots; } diff --git a/client/src/client/gui/element/Element.java b/client/src/client/gui/element/Element.java index 86acf19..f5f8b88 100644 --- a/client/src/client/gui/element/Element.java +++ b/client/src/client/gui/element/Element.java @@ -2,7 +2,7 @@ package client.gui.element; import org.lwjgl.opengl.GL11; -import client.Game; +import client.Client; import client.gui.Formatter; import client.gui.Gui; import client.renderer.Drawing; @@ -15,7 +15,7 @@ import common.sound.PositionedSound; import common.util.Util; public abstract class Element { - protected final Game gm = Game.getGame(); + protected final Client gm = Client.CLIENT; protected Gui gui; protected Formatter format; diff --git a/client/src/client/gui/element/NavButton.java b/client/src/client/gui/element/NavButton.java index 2b16df9..f1722b8 100644 --- a/client/src/client/gui/element/NavButton.java +++ b/client/src/client/gui/element/NavButton.java @@ -1,6 +1,6 @@ package client.gui.element; -import client.Game; +import client.Client; import client.gui.Gui; import client.renderer.Drawing; import common.util.Util; @@ -11,7 +11,7 @@ public class NavButton extends ActButton { public NavButton(int x, int y, int w, int h, Gui gui, String text) { super(x, y, w, h, new Callback() { public void use(ActButton elem, Mode action) { - Game.getGame().displayGuiScreen(gui); + Client.CLIENT.displayGuiScreen(gui); } }, text); this.navGui = gui; diff --git a/client/src/client/network/ClientLoginHandler.java b/client/src/client/network/ClientLoginHandler.java index c7b66e8..47e9894 100755 --- a/client/src/client/network/ClientLoginHandler.java +++ b/client/src/client/network/ClientLoginHandler.java @@ -1,6 +1,6 @@ package client.network; -import client.Game; +import client.Client; import common.network.IClientLoginHandler; import common.network.NetConnection; import common.network.NetHandler; @@ -10,10 +10,10 @@ import common.packet.RPacketEnableCompression; import common.packet.RPacketLoginSuccess; public class ClientLoginHandler extends NetHandler implements IClientLoginHandler { - private final Game gm; + private final Client gm; private final NetConnection networkManager; - public ClientLoginHandler(NetConnection conn, Game gmIn) { + public ClientLoginHandler(NetConnection conn, Client gmIn) { this.networkManager = conn; this.gm = gmIn; } diff --git a/client/src/client/network/ClientPlayer.java b/client/src/client/network/ClientPlayer.java index 92b1b2e..e30af14 100755 --- a/client/src/client/network/ClientPlayer.java +++ b/client/src/client/network/ClientPlayer.java @@ -6,7 +6,7 @@ import java.util.Map; import java.util.Map.Entry; import java.util.Set; -import client.Game; +import client.Client; import client.PlayerController; import client.gui.Gui; import client.gui.GuiConsole; @@ -150,7 +150,7 @@ public class ClientPlayer extends NetHandler implements IClientPlayer /** * Reference to the Game instance, which many handler methods operate on */ - private Game gameController; + private Client gameController; /** * Reference to the current ClientWorld instance, which many handler methods operate on @@ -174,7 +174,7 @@ public class ClientPlayer extends NetHandler implements IClientPlayer */ private final Random avRandomizer = new Random(); - public ClientPlayer(Game gmIn, NetConnection p_i46300_3_) + public ClientPlayer(Client gmIn, NetConnection p_i46300_3_) { this.gameController = gmIn; this.netManager = p_i46300_3_; diff --git a/client/src/client/renderer/BlockRenderer.java b/client/src/client/renderer/BlockRenderer.java index 073fcd6..0288aaf 100755 --- a/client/src/client/renderer/BlockRenderer.java +++ b/client/src/client/renderer/BlockRenderer.java @@ -6,7 +6,7 @@ import java.util.Map; import org.lwjgl.opengl.GL11; -import client.Game; +import client.Client; import client.renderer.blockmodel.BakedModel; import client.renderer.blockmodel.BakedQuad; import client.renderer.blockmodel.IBakedModel; @@ -32,10 +32,10 @@ import common.world.State; public class BlockRenderer { private ModelManager manager; - private final Game gm; + private final Client gm; private final Map fluids = Maps.newHashMap(); - public BlockRenderer(ModelManager manager, Game gm) + public BlockRenderer(ModelManager manager, Client gm) { this.manager = manager; this.gm = gm; @@ -405,7 +405,7 @@ public class BlockRenderer private void initAtlasSprites() { - TextureMap texturemap = Game.getGame().getTextureMapBlocks(); + TextureMap texturemap = Client.CLIENT.getTextureMapBlocks(); for(int z = 0; z < FluidRegistry.getNumFluids(); z++) { BlockLiquid block = FluidRegistry.getStaticBlock(z); String name = BlockRegistry.REGISTRY.getNameForObject(block).toString(); diff --git a/client/src/client/renderer/Drawing.java b/client/src/client/renderer/Drawing.java index d4056c4..16c9962 100644 --- a/client/src/client/renderer/Drawing.java +++ b/client/src/client/renderer/Drawing.java @@ -2,7 +2,7 @@ package client.renderer; import org.lwjgl.opengl.GL11; -import client.Game; +import client.Client; import client.gui.Font; import client.gui.FontChar; import common.color.TextColor; @@ -543,11 +543,11 @@ public abstract class Drawing { drawText(str, x - size.xpos / 2, y - size.ypos, color); } - public static void drawScaled(Game gm, String texture) { + public static void drawScaled(Client gm, String texture) { drawScaled(gm, texture, 0, 0, gm.fb_x, gm.fb_y); } - public static void drawScaled(Game gm, String texture, double x, double y, double width, double height) { + public static void drawScaled(Client gm, String texture, double x, double y, double width, double height) { GlState.enableTexture2D(); GlState.disableLighting(); GlState.disableFog(); diff --git a/client/src/client/renderer/EntityRenderer.java b/client/src/client/renderer/EntityRenderer.java index 7f5d177..82efc10 100755 --- a/client/src/client/renderer/EntityRenderer.java +++ b/client/src/client/renderer/EntityRenderer.java @@ -9,7 +9,7 @@ import java.util.function.Predicate; import org.lwjgl.opengl.GL11; import org.lwjgl.opengl.GL13; -import client.Game; +import client.Client; import client.renderer.particle.EffectRenderer; import client.renderer.texture.DynamicTexture; import client.renderer.texture.TextureMap; @@ -44,7 +44,7 @@ public class EntityRenderer { private static final float FOG_DISTANCE = 0.4f; private static final float SQRT_2 = ExtMath.sqrtf(2.0F); - private Game gm; + private Client gm; private Random random = new Random(); private float farPlaneDistance; public final ItemRenderer itemRenderer; @@ -72,7 +72,7 @@ public class EntityRenderer { private double cameraPitch; private int frameCount; - public EntityRenderer(Game gmIn) + public EntityRenderer(Client gmIn) { this.frameCount = 0; this.gm = gmIn; diff --git a/client/src/client/renderer/ItemRenderer.java b/client/src/client/renderer/ItemRenderer.java index 1a24321..eff32d6 100755 --- a/client/src/client/renderer/ItemRenderer.java +++ b/client/src/client/renderer/ItemRenderer.java @@ -7,7 +7,7 @@ import java.nio.FloatBuffer; import org.lwjgl.opengl.GL11; import org.lwjgl.opengl.GL13; -import client.Game; +import client.Client; import client.renderer.entity.RenderItem; import client.renderer.entity.RenderManager; import client.renderer.entity.RenderNpc; @@ -35,7 +35,7 @@ public class ItemRenderer private static final Vec3 LIGHT1_POS = (new Vec3(-0.20000000298023224D, 1.0D, 0.699999988079071D)).normalize(); /** A reference to the Game object. */ - private final Game gm; + private final Client gm; private ItemStack itemToRender; /** @@ -98,7 +98,7 @@ public class ItemRenderer GlState.disableColorMaterial(); } - public ItemRenderer(Game gmIn) + public ItemRenderer(Client gmIn) { this.gm = gmIn; this.renderManager = gmIn.getRenderManager(); diff --git a/client/src/client/renderer/RenderGlobal.java b/client/src/client/renderer/RenderGlobal.java index 1dfe3a1..06c89ad 100755 --- a/client/src/client/renderer/RenderGlobal.java +++ b/client/src/client/renderer/RenderGlobal.java @@ -15,7 +15,7 @@ import org.lwjgl.opengl.GL11; import org.lwjgl.opengl.GL13; import org.lwjgl.opengl.GL15; -import client.Game; +import client.Client; import client.renderer.chunk.ChunkRenderDispatcher; import client.renderer.chunk.CompiledChunk; import client.renderer.chunk.RenderChunk; @@ -113,7 +113,7 @@ public class RenderGlobal private static final String SUN_TEX = "textures/world/sun.png"; private static final float[] SUN_COLOR = new float[4]; - private final Game gm; + private final Client gm; private final TextureManager renderEngine; private final RenderManager renderManager; private WorldClient theWorld; @@ -157,7 +157,7 @@ public class RenderGlobal private double prevRenderSortZ; private boolean displayListEntitiesDirty = true; - public RenderGlobal(Game gmIn) + public RenderGlobal(Client gmIn) { this.gm = gmIn; this.renderManager = gmIn.getRenderManager(); @@ -939,7 +939,7 @@ public class RenderGlobal float f = (float)((double)entityIn.prevPitch + (double)(entityIn.rotPitch - entityIn.prevPitch) * partialTicks); float f1 = (float)((double)entityIn.prevYaw + (double)(entityIn.rotYaw - entityIn.prevYaw) * partialTicks); - if (Game.getGame().thirdPersonView == 2) + if (Client.CLIENT.thirdPersonView == 2) { f += 180.0F; } diff --git a/client/src/client/renderer/chunk/ChunkRenderDispatcher.java b/client/src/client/renderer/chunk/ChunkRenderDispatcher.java index 0258888..735cadb 100755 --- a/client/src/client/renderer/chunk/ChunkRenderDispatcher.java +++ b/client/src/client/renderer/chunk/ChunkRenderDispatcher.java @@ -7,7 +7,7 @@ import java.util.concurrent.ArrayBlockingQueue; import java.util.concurrent.BlockingQueue; import java.util.concurrent.ThreadFactory; -import client.Game; +import client.Client; import client.renderer.RegionRenderCacheBuilder; import client.renderer.RenderBuffer; import client.renderer.VertexBuffer; @@ -227,7 +227,7 @@ public class ChunkRenderDispatcher public ListenableFuture uploadChunk(final BlockLayer player, final RenderBuffer p_178503_2_, final RenderChunk chunkRenderer, final CompiledChunk compiledChunkIn) { - if (Game.getGame().isMainThread()) + if (Client.CLIENT.isMainThread()) { p_178503_2_.reset(); chunkRenderer.getVertexBufferByLayer(player.ordinal()).bufferData(p_178503_2_.getByteBuffer()); diff --git a/client/src/client/renderer/chunk/ChunkRenderWorker.java b/client/src/client/renderer/chunk/ChunkRenderWorker.java index c140f7d..d685f68 100755 --- a/client/src/client/renderer/chunk/ChunkRenderWorker.java +++ b/client/src/client/renderer/chunk/ChunkRenderWorker.java @@ -4,7 +4,7 @@ import java.util.ArrayList; import java.util.List; import java.util.concurrent.CancellationException; -import client.Game; +import client.Client; import client.renderer.RegionRenderCacheBuilder; import common.collect.Lists; import common.entity.Entity; @@ -75,7 +75,7 @@ public class ChunkRenderWorker implements Runnable generator.getLock().unlock(); } - Entity lvt_2_1_ = Game.getGame().getRenderViewEntity(); + Entity lvt_2_1_ = Client.CLIENT.getRenderViewEntity(); if (lvt_2_1_ == null) { diff --git a/client/src/client/renderer/chunk/RenderChunk.java b/client/src/client/renderer/chunk/RenderChunk.java index 9e02136..8667584 100755 --- a/client/src/client/renderer/chunk/RenderChunk.java +++ b/client/src/client/renderer/chunk/RenderChunk.java @@ -10,7 +10,7 @@ import java.util.concurrent.locks.ReentrantLock; import org.lwjgl.opengl.GL11; -import client.Game; +import client.Client; import client.renderer.BlockRenderer; import client.renderer.DefaultVertexFormats; import client.renderer.RegionRenderCache; @@ -141,7 +141,7 @@ public class RenderChunk { ++renderChunksUpdated; boolean[] aboolean = new boolean[BlockLayer.values().length]; - BlockRenderer blockrendererdispatcher = Game.getGame().getBlockRendererDispatcher(); + BlockRenderer blockrendererdispatcher = Client.CLIENT.getBlockRendererDispatcher(); for (BlockPos.MutableBlockPos blockpos$mutableblockpos : BlockPos.getAllInBoxMutable(blockpos, blockpos1)) { diff --git a/client/src/client/renderer/entity/Render.java b/client/src/client/renderer/entity/Render.java index 7c2a5e0..4f29cae 100755 --- a/client/src/client/renderer/entity/Render.java +++ b/client/src/client/renderer/entity/Render.java @@ -2,7 +2,7 @@ package client.renderer.entity; import org.lwjgl.opengl.GL11; -import client.Game; +import client.Client; import client.renderer.DefaultVertexFormats; import client.renderer.Drawing; import client.renderer.Frustum; @@ -98,7 +98,7 @@ public abstract class Render private void renderEntityOnFire(Entity entity, double x, double y, double z, float partialTicks) { GlState.disableLighting(); - TextureMap texturemap = Game.getGame().getTextureMapBlocks(); + TextureMap texturemap = Client.CLIENT.getTextureMapBlocks(); TextureAtlasSprite textureatlassprite = texturemap.getAtlasSprite("blocks/fire_layer_0"); TextureAtlasSprite textureatlassprite1 = texturemap.getAtlasSprite("blocks/fire_layer_1"); GL11.glPushMatrix(); diff --git a/client/src/client/renderer/entity/RenderBlockEntity.java b/client/src/client/renderer/entity/RenderBlockEntity.java index 1adf24c..8d40d11 100755 --- a/client/src/client/renderer/entity/RenderBlockEntity.java +++ b/client/src/client/renderer/entity/RenderBlockEntity.java @@ -2,7 +2,7 @@ package client.renderer.entity; import org.lwjgl.opengl.GL11; -import client.Game; +import client.Client; import client.renderer.BlockRenderer; import client.renderer.texture.TextureMap; import common.entity.Entity; @@ -28,7 +28,7 @@ public class RenderBlockEntity extends Render // if(entity.isInvisible()) { // return; // } - BlockRenderer blockrendererdispatcher = Game.getGame().getBlockRendererDispatcher(); + BlockRenderer blockrendererdispatcher = Client.CLIENT.getBlockRendererDispatcher(); GL11.glPushMatrix(); GL11.glTranslatef((float)x, (float)y + 0.5F, (float)z); diff --git a/client/src/client/renderer/entity/RenderDie.java b/client/src/client/renderer/entity/RenderDie.java index 51a6cf1..38be9de 100755 --- a/client/src/client/renderer/entity/RenderDie.java +++ b/client/src/client/renderer/entity/RenderDie.java @@ -2,7 +2,7 @@ package client.renderer.entity; import org.lwjgl.opengl.GL11; -import client.Game; +import client.Client; import client.renderer.model.ModelDie; import client.renderer.texture.TextureMap; import common.entity.projectile.EntityDie; @@ -33,7 +33,7 @@ public class RenderDie extends Render GL11.glRotatef((float)((entity.ticksExisted % 10) * (360 / 10)), 0.3f, 0.4f, 0.1f); // GlState.translate(-0.05F, -0.05F, 0.05F); GL11.glScalef(0.5f, 0.5f, 0.5f); - Game.getGame().getRenderItem().renderItem(entity.getStack(), Camera.GROUND); + Client.CLIENT.getRenderItem().renderItem(entity.getStack(), Camera.GROUND); // blockrendererdispatcher.renderBlockBrightness(Blocks.planks.getDefaultState(), entity.getBrightness(partialTicks)); GL11.glPopMatrix(); super.doRender(entity, x, y, z, partialTicks); diff --git a/client/src/client/renderer/entity/RenderFallingBlock.java b/client/src/client/renderer/entity/RenderFallingBlock.java index b440c26..c004df8 100755 --- a/client/src/client/renderer/entity/RenderFallingBlock.java +++ b/client/src/client/renderer/entity/RenderFallingBlock.java @@ -2,7 +2,7 @@ package client.renderer.entity; import org.lwjgl.opengl.GL11; -import client.Game; +import client.Client; import client.renderer.BlockRenderer; import client.renderer.DefaultVertexFormats; import client.renderer.GlState; @@ -51,7 +51,7 @@ public class RenderFallingBlock extends Render int j = blockpos.getY(); int k = blockpos.getZ(); worldrenderer.setTranslation((double)((float)(-i) - 0.5F), (double)(-j), (double)((float)(-k) - 0.5F)); - BlockRenderer blockrendererdispatcher = Game.getGame().getBlockRendererDispatcher(); + BlockRenderer blockrendererdispatcher = Client.CLIENT.getBlockRendererDispatcher(); IBakedModel ibakedmodel = blockrendererdispatcher.getModelFromBlockState(iblockstate, world, (BlockPos)null); blockrendererdispatcher.renderModel(world, ibakedmodel, iblockstate, blockpos, worldrenderer, false); worldrenderer.setTranslation(0.0D, 0.0D, 0.0D); diff --git a/client/src/client/renderer/entity/RenderFireball.java b/client/src/client/renderer/entity/RenderFireball.java index 4431da3..0e68614 100755 --- a/client/src/client/renderer/entity/RenderFireball.java +++ b/client/src/client/renderer/entity/RenderFireball.java @@ -2,7 +2,7 @@ package client.renderer.entity; import org.lwjgl.opengl.GL11; -import client.Game; +import client.Client; import client.renderer.DefaultVertexFormats; import client.renderer.GlState; import client.renderer.RenderBuffer; @@ -33,7 +33,7 @@ public class RenderFireball extends Render GL11.glTranslatef((float)x, (float)y, (float)z); GlState.enableRescaleNormal(); GL11.glScalef(this.scale, this.scale, this.scale); - TextureAtlasSprite textureatlassprite = Game.getGame().getRenderItem().getItemModelMesher().getParticleIcon(Items.fire_charge); + TextureAtlasSprite textureatlassprite = Client.CLIENT.getRenderItem().getItemModelMesher().getParticleIcon(Items.fire_charge); // Tessellator tessellator = Tessellator.getInstance(); RenderBuffer worldrenderer = Tessellator.getBuffer(); float f = textureatlassprite.getMinU(); diff --git a/client/src/client/renderer/entity/RenderFish.java b/client/src/client/renderer/entity/RenderFish.java index a053261..4bac934 100755 --- a/client/src/client/renderer/entity/RenderFish.java +++ b/client/src/client/renderer/entity/RenderFish.java @@ -2,7 +2,7 @@ package client.renderer.entity; import org.lwjgl.opengl.GL11; -import client.Game; +import client.Client; import client.renderer.DefaultVertexFormats; import client.renderer.GlState; import client.renderer.RenderBuffer; @@ -65,7 +65,7 @@ public class RenderFish extends Render double d2 = entity.angler.prevZ + (entity.angler.posZ - entity.angler.prevZ) * (double)partialTicks + vec3.zCoord; double d3 = (double)entity.angler.getEyeHeight(); - if (this.renderManager.gm != null && this.renderManager.gm.thirdPersonView > 0 || entity.angler != Game.getGame().thePlayer) + if (this.renderManager.gm != null && this.renderManager.gm.thirdPersonView > 0 || entity.angler != Client.CLIENT.thePlayer) { float f9 = (entity.angler.prevYawOffset + (entity.angler.yawOffset - entity.angler.prevYawOffset) * partialTicks) * (float)Math.PI / 180.0F; double d4 = (double)ExtMath.sin(f9); diff --git a/client/src/client/renderer/entity/RenderHorse.java b/client/src/client/renderer/entity/RenderHorse.java index 46a3ff9..36656eb 100755 --- a/client/src/client/renderer/entity/RenderHorse.java +++ b/client/src/client/renderer/entity/RenderHorse.java @@ -4,7 +4,7 @@ import java.util.Set; import org.lwjgl.opengl.GL11; -import client.Game; +import client.Client; import client.renderer.model.ModelHorse; import client.renderer.texture.LayeredTexture; import common.collect.Sets; @@ -90,7 +90,7 @@ public class RenderHorse extends RenderLiving { if (!loaded.contains(s)) { - Game.getGame().getTextureManager().loadTexture(s, new LayeredTexture(horse.getVariantTexturePaths())); + Client.CLIENT.getTextureManager().loadTexture(s, new LayeredTexture(horse.getVariantTexturePaths())); loaded.add(s); } diff --git a/client/src/client/renderer/entity/RenderManager.java b/client/src/client/renderer/entity/RenderManager.java index 065cb0d..6a373ce 100755 --- a/client/src/client/renderer/entity/RenderManager.java +++ b/client/src/client/renderer/entity/RenderManager.java @@ -5,7 +5,7 @@ import java.util.Map; import org.lwjgl.opengl.GL11; import org.lwjgl.opengl.GL13; -import client.Game; +import client.Client; import client.init.RenderRegistry; import client.renderer.DefaultVertexFormats; import client.renderer.GlState; @@ -55,7 +55,7 @@ public class RenderManager public Entity pointedEntity; public float playerViewY; public float playerViewX; - public Game gm; + public Client gm; public double viewerPosX; public double viewerPosY; public double viewerPosZ; @@ -145,7 +145,7 @@ public class RenderManager return this.models.get(model); } - public void cacheActiveRenderInfo(World worldIn, Entity livingPlayerIn, Entity pointedEntityIn, Game optionsIn, float partialTicks) + public void cacheActiveRenderInfo(World worldIn, Entity livingPlayerIn, Entity pointedEntityIn, Client optionsIn, float partialTicks) { this.worldObj = worldIn; this.gm = optionsIn; diff --git a/client/src/client/renderer/entity/RenderMinecart.java b/client/src/client/renderer/entity/RenderMinecart.java index 050e8d2..6844f89 100755 --- a/client/src/client/renderer/entity/RenderMinecart.java +++ b/client/src/client/renderer/entity/RenderMinecart.java @@ -2,7 +2,7 @@ package client.renderer.entity; import org.lwjgl.opengl.GL11; -import client.Game; +import client.Client; import client.renderer.GlState; import client.renderer.model.ModelBase; import client.renderer.model.ModelMinecart; @@ -123,7 +123,7 @@ public class RenderMinecart extends Render protected void func_180560_a(T minecart, float partialTicks, State state) { GL11.glPushMatrix(); - Game.getGame().getBlockRendererDispatcher().renderBlockBrightness(state, minecart.getBrightness(partialTicks)); + Client.CLIENT.getBlockRendererDispatcher().renderBlockBrightness(state, minecart.getBrightness(partialTicks)); GL11.glPopMatrix(); } } diff --git a/client/src/client/renderer/entity/RenderTntMinecart.java b/client/src/client/renderer/entity/RenderTntMinecart.java index 2a9413e..9e48e44 100755 --- a/client/src/client/renderer/entity/RenderTntMinecart.java +++ b/client/src/client/renderer/entity/RenderTntMinecart.java @@ -2,7 +2,7 @@ package client.renderer.entity; import org.lwjgl.opengl.GL11; -import client.Game; +import client.Client; import client.renderer.BlockRenderer; import client.renderer.GlState; import common.entity.item.EntityTntCart; @@ -35,7 +35,7 @@ public class RenderTntMinecart extends RenderMinecart if (i > -1 && i / 5 % 2 == 0) { - BlockRenderer blockrendererdispatcher = Game.getGame().getBlockRendererDispatcher(); + BlockRenderer blockrendererdispatcher = Client.CLIENT.getBlockRendererDispatcher(); GlState.disableTexture2D(); GlState.disableLighting(); GlState.enableBlend(); diff --git a/client/src/client/renderer/entity/RenderTntPrimed.java b/client/src/client/renderer/entity/RenderTntPrimed.java index 0c339de..85aa3f8 100755 --- a/client/src/client/renderer/entity/RenderTntPrimed.java +++ b/client/src/client/renderer/entity/RenderTntPrimed.java @@ -2,7 +2,7 @@ package client.renderer.entity; import org.lwjgl.opengl.GL11; -import client.Game; +import client.Client; import client.renderer.BlockRenderer; import client.renderer.GlState; import client.renderer.texture.TextureMap; @@ -25,7 +25,7 @@ public class RenderTntPrimed extends Render */ public void doRender(EntityTnt entity, double x, double y, double z, float partialTicks) { - BlockRenderer blockrendererdispatcher = Game.getGame().getBlockRendererDispatcher(); + BlockRenderer blockrendererdispatcher = Client.CLIENT.getBlockRendererDispatcher(); GL11.glPushMatrix(); GL11.glTranslatef((float)x, (float)y + 0.5F, (float)z); diff --git a/client/src/client/renderer/layers/LayerExtra.java b/client/src/client/renderer/layers/LayerExtra.java index 0364213..ebfe2bb 100755 --- a/client/src/client/renderer/layers/LayerExtra.java +++ b/client/src/client/renderer/layers/LayerExtra.java @@ -4,7 +4,7 @@ import java.util.List; import org.lwjgl.opengl.GL11; -import client.Game; +import client.Client; import client.renderer.GlState; import client.renderer.blockmodel.ModelGenerator; import client.renderer.model.ModelBox; @@ -62,7 +62,7 @@ public class LayerExtra implements LayerRenderer // if (!entity.isInvisible()) // { GlState.color(1.0F, 1.0F, 1.0F, 1.0F); - Game.getGame().getTextureManager().bindTexture(EntityTexManager.getSkin(extended)); + Client.CLIENT.getTextureManager().bindTexture(EntityTexManager.getSkin(extended)); GL11.glPushMatrix(); if (entity.isSneakingVisually()) diff --git a/client/src/client/renderer/layers/LayerHeldItem.java b/client/src/client/renderer/layers/LayerHeldItem.java index 97dc2ad..00927e6 100755 --- a/client/src/client/renderer/layers/LayerHeldItem.java +++ b/client/src/client/renderer/layers/LayerHeldItem.java @@ -2,7 +2,7 @@ package client.renderer.layers; import org.lwjgl.opengl.GL11; -import client.Game; +import client.Client; import client.renderer.entity.RendererLivingEntity; import client.renderer.model.ModelBiped; import common.entity.npc.EntityNPC; @@ -53,7 +53,7 @@ public class LayerHeldItem implements LayerRenderer } Item item = itemstack.getItem(); - Game gm = Game.getGame(); + Client gm = Client.CLIENT; if (item instanceof ItemBlock && item.getBlock().getRenderType() == 2) { diff --git a/client/src/client/renderer/layers/LayerMooshroomMushroom.java b/client/src/client/renderer/layers/LayerMooshroomMushroom.java index cc5291f..424b294 100755 --- a/client/src/client/renderer/layers/LayerMooshroomMushroom.java +++ b/client/src/client/renderer/layers/LayerMooshroomMushroom.java @@ -2,7 +2,7 @@ package client.renderer.layers; import org.lwjgl.opengl.GL11; -import client.Game; +import client.Client; import client.renderer.BlockRenderer; import client.renderer.GlState; import client.renderer.entity.RenderMooshroom; @@ -24,7 +24,7 @@ public class LayerMooshroomMushroom implements LayerRenderer { if (!entitylivingbaseIn.isChild()) // && !entitylivingbaseIn.isInvisible()) { - BlockRenderer blockrendererdispatcher = Game.getGame().getBlockRendererDispatcher(); + BlockRenderer blockrendererdispatcher = Client.CLIENT.getBlockRendererDispatcher(); this.mooshroomRenderer.bindTexture(TextureMap.locationBlocksTexture); GlState.enableCull(); GlState.cullFace(GL11.GL_FRONT); diff --git a/client/src/client/renderer/particle/EntityBreakingFX.java b/client/src/client/renderer/particle/EntityBreakingFX.java index dbd35f0..fb19236 100755 --- a/client/src/client/renderer/particle/EntityBreakingFX.java +++ b/client/src/client/renderer/particle/EntityBreakingFX.java @@ -1,6 +1,6 @@ package client.renderer.particle; -import client.Game; +import client.Client; import client.renderer.RenderBuffer; import common.entity.Entity; import common.init.ItemRegistry; @@ -29,7 +29,7 @@ public class EntityBreakingFX extends EntityFX protected EntityBreakingFX(World worldIn, double posXIn, double posYIn, double posZIn, Item p_i1196_8_, int p_i1196_9_) { super(worldIn, posXIn, posYIn, posZIn, 0.0D, 0.0D, 0.0D); - this.setParticleIcon(Game.getGame().getRenderItem().getItemModelMesher().getParticleIcon(p_i1196_8_, p_i1196_9_)); + this.setParticleIcon(Client.CLIENT.getRenderItem().getItemModelMesher().getParticleIcon(p_i1196_8_, p_i1196_9_)); this.particleRed = this.particleGreen = this.particleBlue = 1.0F; this.particleGravity = 1.0F; // Blocks.snow.particleGravity; this.particleScale /= 2.0F; diff --git a/client/src/client/renderer/particle/EntityDiggingFX.java b/client/src/client/renderer/particle/EntityDiggingFX.java index 84ec999..9a6e753 100755 --- a/client/src/client/renderer/particle/EntityDiggingFX.java +++ b/client/src/client/renderer/particle/EntityDiggingFX.java @@ -1,6 +1,6 @@ package client.renderer.particle; -import client.Game; +import client.Client; import client.renderer.RenderBuffer; import common.block.Block; import common.entity.Entity; @@ -19,7 +19,7 @@ public class EntityDiggingFX extends EntityFX { super(worldIn, xCoordIn, yCoordIn, zCoordIn, xSpeedIn, ySpeedIn, zSpeedIn); this.sourceState = state; - this.setParticleIcon(Game.getGame().getBlockRendererDispatcher().getModelManager().getTexture(state)); + this.setParticleIcon(Client.CLIENT.getBlockRendererDispatcher().getModelManager().getTexture(state)); this.particleGravity = 1.0F; // state.getBlock().particleGravity; this.particleRed = this.particleGreen = this.particleBlue = 0.6F; this.particleScale /= 2.0F; diff --git a/client/src/client/renderer/particle/EntityFX.java b/client/src/client/renderer/particle/EntityFX.java index c3066fe..f0615ed 100755 --- a/client/src/client/renderer/particle/EntityFX.java +++ b/client/src/client/renderer/particle/EntityFX.java @@ -1,6 +1,6 @@ package client.renderer.particle; -import client.Game; +import client.Client; import client.renderer.RenderBuffer; import client.renderer.texture.TextureAtlasSprite; import common.entity.Entity; @@ -102,11 +102,11 @@ public class EntityFX extends Entity implements IEntityFX { if (this.particleAlpha == 1.0F && alpha < 1.0F) { - Game.getGame().effectRenderer.moveToAlphaLayer(this); + Client.CLIENT.effectRenderer.moveToAlphaLayer(this); } else if (this.particleAlpha < 1.0F && alpha == 1.0F) { - Game.getGame().effectRenderer.moveToNoAlphaLayer(this); + Client.CLIENT.effectRenderer.moveToNoAlphaLayer(this); } this.particleAlpha = alpha; diff --git a/client/src/client/renderer/particle/EntityFirework.java b/client/src/client/renderer/particle/EntityFirework.java index c34b444..da4bd91 100755 --- a/client/src/client/renderer/particle/EntityFirework.java +++ b/client/src/client/renderer/particle/EntityFirework.java @@ -1,6 +1,6 @@ package client.renderer.particle; -import client.Game; +import client.Client; import client.renderer.RenderBuffer; import common.entity.Entity; import common.init.SoundEvent; @@ -18,7 +18,7 @@ public class EntityFirework { public EntityFX getEntityFX(int particleID, World worldIn, double xCoordIn, double yCoordIn, double zCoordIn, double xSpeedIn, double ySpeedIn, double zSpeedIn, int... p_178902_15_) { - EntityFirework.SparkFX entityfirework$sparkfx = new EntityFirework.SparkFX(worldIn, xCoordIn, yCoordIn, zCoordIn, xSpeedIn, ySpeedIn, zSpeedIn, Game.getGame().effectRenderer); + EntityFirework.SparkFX entityfirework$sparkfx = new EntityFirework.SparkFX(worldIn, xCoordIn, yCoordIn, zCoordIn, xSpeedIn, ySpeedIn, zSpeedIn, Client.CLIENT.effectRenderer); entityfirework$sparkfx.setAlphaF(0.99F); return entityfirework$sparkfx; } @@ -333,7 +333,7 @@ public class EntityFirework private boolean isFarAway() { - Game gm = Game.getGame(); + Client gm = Client.CLIENT; return gm == null || gm.getRenderViewEntity() == null || gm.getRenderViewEntity().getDistanceSq(this.posX, this.posY, this.posZ) >= 256.0D; } diff --git a/client/src/client/renderer/particle/EntityFootStepFX.java b/client/src/client/renderer/particle/EntityFootStepFX.java index 5835284..2bad9a1 100755 --- a/client/src/client/renderer/particle/EntityFootStepFX.java +++ b/client/src/client/renderer/particle/EntityFootStepFX.java @@ -2,7 +2,7 @@ package client.renderer.particle; import org.lwjgl.opengl.GL11; -import client.Game; +import client.Client; import client.renderer.DefaultVertexFormats; import client.renderer.GlState; import client.renderer.RenderBuffer; @@ -88,7 +88,7 @@ public class EntityFootStepFX extends EntityFX { public EntityFX getEntityFX(int particleID, World worldIn, double xCoordIn, double yCoordIn, double zCoordIn, double xSpeedIn, double ySpeedIn, double zSpeedIn, int... p_178902_15_) { - return new EntityFootStepFX(Game.getGame().getTextureManager(), worldIn, xCoordIn, yCoordIn, zCoordIn); + return new EntityFootStepFX(Client.CLIENT.getTextureManager(), worldIn, xCoordIn, yCoordIn, zCoordIn); } } } diff --git a/client/src/client/renderer/particle/EntityLargeExplodeFX.java b/client/src/client/renderer/particle/EntityLargeExplodeFX.java index e4bdfd5..9dfe387 100755 --- a/client/src/client/renderer/particle/EntityLargeExplodeFX.java +++ b/client/src/client/renderer/particle/EntityLargeExplodeFX.java @@ -2,7 +2,7 @@ package client.renderer.particle; import org.lwjgl.opengl.GL11; -import client.Game; +import client.Client; import client.renderer.DefaultVertexFormats; import client.renderer.GlState; import client.renderer.ItemRenderer; @@ -95,7 +95,7 @@ public class EntityLargeExplodeFX extends EntityFX { public EntityFX getEntityFX(int particleID, World worldIn, double xCoordIn, double yCoordIn, double zCoordIn, double xSpeedIn, double ySpeedIn, double zSpeedIn, int... p_178902_15_) { - return new EntityLargeExplodeFX(Game.getGame().getTextureManager(), worldIn, xCoordIn, yCoordIn, zCoordIn, xSpeedIn, ySpeedIn, zSpeedIn); + return new EntityLargeExplodeFX(Client.CLIENT.getTextureManager(), worldIn, xCoordIn, yCoordIn, zCoordIn, xSpeedIn, ySpeedIn, zSpeedIn); } } } diff --git a/client/src/client/renderer/particle/EntityPickupFX.java b/client/src/client/renderer/particle/EntityPickupFX.java index a9b68b5..67a4bd8 100755 --- a/client/src/client/renderer/particle/EntityPickupFX.java +++ b/client/src/client/renderer/particle/EntityPickupFX.java @@ -2,7 +2,7 @@ package client.renderer.particle; import org.lwjgl.opengl.GL13; -import client.Game; +import client.Client; import client.renderer.GlState; import client.renderer.RenderBuffer; import client.renderer.entity.RenderManager; @@ -16,7 +16,7 @@ public class EntityPickupFX extends EntityFX private int age; private int maxAge; private float field_174841_aA; - private RenderManager field_174842_aB = Game.getGame().getRenderManager(); + private RenderManager field_174842_aB = Client.CLIENT.getRenderManager(); public EntityPickupFX(World worldIn, Entity p_i1233_2_, Entity p_i1233_3_, float p_i1233_4_) { diff --git a/client/src/client/renderer/texture/EntityTexManager.java b/client/src/client/renderer/texture/EntityTexManager.java index 91e1658..b273901 100755 --- a/client/src/client/renderer/texture/EntityTexManager.java +++ b/client/src/client/renderer/texture/EntityTexManager.java @@ -10,7 +10,7 @@ import java.util.Map; import java.util.Map.Entry; import java.util.Set; -import client.Game; +import client.Client; import client.renderer.entity.RenderNpc; import client.renderer.layers.LayerExtra; import common.collect.Lists; @@ -35,7 +35,7 @@ public abstract class EntityTexManager private static final Map DEF_LAYERS = Maps.newEnumMap(ModelType.class); public static void loadNpcTextures() { - TextureManager manager = Game.getGame().getTextureManager(); + TextureManager manager = Client.CLIENT.getTextureManager(); for(Entry entry : SpeciesRegistry.SKINS.entrySet()) { String skin = entry.getKey(); // skin = skin.startsWith("~") ? skin.substring(1) : skin; @@ -130,7 +130,7 @@ public abstract class EntityTexManager public static String getDefault(ModelType model) { String def = DEF_TEXTURES.get(model); if(def == null) - DEF_TEXTURES.put(model, def = Game.getGame().getRenderManager().getRenderObject(model).getDefaultTexture()); + DEF_TEXTURES.put(model, def = Client.CLIENT.getRenderManager().getRenderObject(model).getDefaultTexture()); return def; } @@ -149,21 +149,21 @@ public abstract class EntityTexManager public static LayerExtra getLayer(int id, String skin, ModelType model) { if(id == -1) - return Game.getGame().getTextureManager().getTexture(getNpcSkinLocation(skin)) != null ? NPC_LAYERS.get(skin.toLowerCase()) : DEF_LAYERS.get(model); - return altNpcLayer != null ? Game.getGame().getTextureManager().getTexture(getNpcSkinLocation(altNpcLayer)) != null ? - NPC_LAYERS.get(altNpcLayer.toLowerCase()) : DEF_LAYERS.get(model) : (altLayer != -1 ? USER_LAYERS.get(altLayer) : (USER_TEXTURES.contains(id) ? USER_LAYERS.get(id) : (skin != null && Game.getGame().getTextureManager().getTexture(getNpcSkinLocation(skin)) != null ? NPC_LAYERS.get(skin.toLowerCase()) : DEF_LAYERS.get(model)))); + return Client.CLIENT.getTextureManager().getTexture(getNpcSkinLocation(skin)) != null ? NPC_LAYERS.get(skin.toLowerCase()) : DEF_LAYERS.get(model); + return altNpcLayer != null ? Client.CLIENT.getTextureManager().getTexture(getNpcSkinLocation(altNpcLayer)) != null ? + NPC_LAYERS.get(altNpcLayer.toLowerCase()) : DEF_LAYERS.get(model) : (altLayer != -1 ? USER_LAYERS.get(altLayer) : (USER_TEXTURES.contains(id) ? USER_LAYERS.get(id) : (skin != null && Client.CLIENT.getTextureManager().getTexture(getNpcSkinLocation(skin)) != null ? NPC_LAYERS.get(skin.toLowerCase()) : DEF_LAYERS.get(model)))); } public static String getSkin(int id, String skin, ModelType model) { String loc = id != -1 ? (altTexture != null ? altTexture : getSkinLocation(id)) : getNpcSkinLocation(skin); - if(id != -1 && skin != null && Game.getGame().getTextureManager().getTexture(loc) == null) + if(id != -1 && skin != null && Client.CLIENT.getTextureManager().getTexture(loc) == null) loc = getNpcSkinLocation(skin); - return Game.getGame().getTextureManager().getTexture(loc) != null ? loc : getDefault(model); + return Client.CLIENT.getTextureManager().getTexture(loc) != null ? loc : getDefault(model); } public static boolean hasCustomSkin(int id) { - return Game.getGame().getTextureManager().getTexture(getSkinLocation(id)) != null; + return Client.CLIENT.getTextureManager().getTexture(getSkinLocation(id)) != null; } public static String getCape(String name) @@ -171,7 +171,7 @@ public abstract class EntityTexManager if(name == null || name.isEmpty()) return null; String loc = getCapeLocation(name); - return Game.getGame().getTextureManager().getTexture(loc) != null ? loc : null; + return Client.CLIENT.getTextureManager().getTexture(loc) != null ? loc : null; } public static void clearTextures() { @@ -185,7 +185,7 @@ public abstract class EntityTexManager if(comp == null && !USER_TEXTURES.contains(id)) return; // user = user.toLowerCase(); - TextureManager manager = Game.getGame().getTextureManager(); + TextureManager manager = Client.CLIENT.getTextureManager(); String loc = getSkinLocation(id); DynamicTexture dyntex = (DynamicTexture)manager.getTexture(loc); if(comp == null) { @@ -219,14 +219,14 @@ public abstract class EntityTexManager } public static void compToImage(byte[] comp, int[] img, ModelType model) { - RenderNpc render = Game.getGame().getRenderManager().getRenderObject(model); + RenderNpc render = Client.CLIENT.getRenderManager().getRenderObject(model); if(comp.length < render.getCompressedSize()) comp = new byte[render.getCompressedSize()]; render.compToImage(comp, img, model.texWidth); } public static byte[] imageToComp(int[] img, ModelType model) { - RenderNpc render = Game.getGame().getRenderManager().getRenderObject(model); + RenderNpc render = Client.CLIENT.getRenderManager().getRenderObject(model); byte[] comp = new byte[render.getCompressedSize()]; render.imageToComp(comp, img, model.texWidth); return comp; diff --git a/client/src/client/renderer/tileentity/TileEntityBannerRenderer.java b/client/src/client/renderer/tileentity/TileEntityBannerRenderer.java index bfa5ad0..c518892 100755 --- a/client/src/client/renderer/tileentity/TileEntityBannerRenderer.java +++ b/client/src/client/renderer/tileentity/TileEntityBannerRenderer.java @@ -6,7 +6,7 @@ import java.util.Map; import org.lwjgl.opengl.GL11; -import client.Game; +import client.Client; import client.renderer.GlState; import client.renderer.model.ModelBanner; import client.renderer.texture.LayeredColorMaskTexture; @@ -111,7 +111,7 @@ public class TileEntityBannerRenderer extends TileEntitySpecialRenderer 60000L) { - Game.getGame().getTextureManager().deleteTexture(tileentitybannerrenderer$timedbannertexture1.bannerTexture); + Client.CLIENT.getTextureManager().deleteTexture(tileentitybannerrenderer$timedbannertexture1.bannerTexture); iterator.remove(); } } @@ -133,7 +133,7 @@ public class TileEntityBannerRenderer extends TileEntitySpecialRenderer { - private final BlockRenderer blockRenderer = Game.getGame().getBlockRendererDispatcher(); + private final BlockRenderer blockRenderer = Client.CLIENT.getBlockRendererDispatcher(); public void renderTileEntityAt(TileEntityPiston te, double x, double y, double z, float partialTicks, int destroyStage) { diff --git a/client/src/client/window/Bind.java b/client/src/client/window/Bind.java index 2cbf390..1ab509f 100644 --- a/client/src/client/window/Bind.java +++ b/client/src/client/window/Bind.java @@ -1,6 +1,6 @@ package client.window; -import client.Game; +import client.Client; import client.gui.element.Element; import client.vars.CVar; import client.vars.CVarCategory; @@ -104,9 +104,9 @@ public enum Bind implements Identifyable, CVar { waitingFor.input = input; waitingFor = null; keyRelease = null; - Game.getGame().setDirty(); - if(Game.getGame().open != null) - Game.getGame().open.reformat(); + Client.CLIENT.setDirty(); + if(Client.CLIENT.open != null) + Client.CLIENT.open.reformat(); } } else if(keyRelease == null) { @@ -116,9 +116,9 @@ public enum Bind implements Identifyable, CVar { else { waitingFor.input = input; waitingFor = null; - Game.getGame().setDirty(); - if(Game.getGame().open != null) - Game.getGame().open.reformat(); + Client.CLIENT.setDirty(); + if(Client.CLIENT.open != null) + Client.CLIENT.open.reformat(); } } } diff --git a/client/src/client/window/Button.java b/client/src/client/window/Button.java index c5809e2..5286196 100644 --- a/client/src/client/window/Button.java +++ b/client/src/client/window/Button.java @@ -1,6 +1,6 @@ package client.window; -import client.Game; +import client.Client; public enum Button implements Input { MOUSE_LEFT("lmb", "Linke Maustaste"), @@ -37,7 +37,7 @@ public enum Button implements Input { } public boolean read() { - return Game.getGame().open == null && this.down; + return Client.CLIENT.open == null && this.down; } public void setDown(boolean down) { diff --git a/client/src/client/window/Wheel.java b/client/src/client/window/Wheel.java index 50cd5c3..3c4b6bd 100644 --- a/client/src/client/window/Wheel.java +++ b/client/src/client/window/Wheel.java @@ -1,6 +1,6 @@ package client.window; -import client.Game; +import client.Client; public enum Wheel implements Input { SCROLL_UP("scrup", "Mausrad aufwärts"), @@ -27,7 +27,7 @@ public enum Wheel implements Input { } public boolean read() { - return Game.getGame().open == null && this.used; + return Client.CLIENT.open == null && this.used; } public void setUsed() { diff --git a/client/src/client/world/Converter.java b/client/src/client/world/Converter.java index f89812d..33bf568 100644 --- a/client/src/client/world/Converter.java +++ b/client/src/client/world/Converter.java @@ -13,7 +13,7 @@ import java.util.Map.Entry; import java.util.zip.GZIPInputStream; import java.util.zip.InflaterInputStream; -import client.Game; +import client.Client; import client.gui.GuiConvert; import client.gui.GuiLoading; import client.gui.GuiLoading.Callback; @@ -1239,8 +1239,8 @@ public final class Converter { // if(nbt == null) // return false; final Converter conv = new Converter(); - Game.getGame().displayGuiScreen(new GuiLoading("Konvertiere Welt ...", new Callback() { - public void poll(Game gm, GuiLoading gui) { + Client.CLIENT.displayGuiScreen(new GuiLoading("Konvertiere Welt ...", new Callback() { + public void poll(Client gm, GuiLoading gui) { if(conv.totalRegions > 0) { gui.setBar(conv.task, "Regionen", conv.totalRegions); gui.setProgress(conv.doneRegions); @@ -1392,9 +1392,9 @@ public final class Converter { } } Log.IO.info("Welt '" + dir + "' wurde in %d Sekunden konvertiert", (System.currentTimeMillis() - cur) / 1000L); - Game.getGame().schedule(new Runnable() { + Client.CLIENT.schedule(new Runnable() { public void run() { - Game.getGame().displayGuiScreen(GuiConvert.INSTANCE); + Client.CLIENT.displayGuiScreen(GuiConvert.INSTANCE); } }); } From 49996f8116850c839cb8e43bd13ea16255f330aa Mon Sep 17 00:00:00 2001 From: Sen Date: Thu, 8 May 2025 13:04:57 +0200 Subject: [PATCH 012/200] fix gitignore --- .gitignore | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/.gitignore b/.gitignore index 0da720f..20170c0 100644 --- a/.gitignore +++ b/.gitignore @@ -1,8 +1,8 @@ -/common/dev -/common/bin -/client/bin -/client/run -/server/bin -/server/run -/export -/.metadata +common/dev +common/bin +client/bin +client/run +server/bin +server/run +export +.metadata From f1a13835a6e22766531819766260759e1d86115a Mon Sep 17 00:00:00 2001 From: Sen Date: Thu, 8 May 2025 13:05:44 +0200 Subject: [PATCH 013/200] revert gitignore --- .gitignore | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/.gitignore b/.gitignore index 20170c0..0da720f 100644 --- a/.gitignore +++ b/.gitignore @@ -1,8 +1,8 @@ -common/dev -common/bin -client/bin -client/run -server/bin -server/run -export -.metadata +/common/dev +/common/bin +/client/bin +/client/run +/server/bin +/server/run +/export +/.metadata From 6e5c9e842e65cddb2b2e374fa92d7f007618ed54 Mon Sep 17 00:00:00 2001 From: Sen Date: Fri, 9 May 2025 13:26:31 +0200 Subject: [PATCH 014/200] add windows support (untested) --- client/src/client/Client.java | 335 ++++++++++-------- client/src/client/PlayerController.java | 34 +- client/src/client/gui/Gui.java | 2 +- client/src/client/gui/GuiConfirm.java | 2 +- client/src/client/gui/GuiConsole.java | 12 +- client/src/client/gui/GuiConvert.java | 2 +- client/src/client/gui/GuiInfo.java | 2 +- client/src/client/gui/GuiMenu.java | 12 +- client/src/client/gui/GuiServer.java | 2 +- client/src/client/gui/character/GuiChar.java | 50 +-- .../client/gui/character/GuiCharacters.java | 2 +- client/src/client/gui/character/GuiClass.java | 12 +- .../src/client/gui/character/GuiSpecies.java | 8 +- client/src/client/gui/container/GuiChest.java | 2 +- .../client/gui/container/GuiContainer.java | 44 +-- .../src/client/gui/container/GuiEnchant.java | 6 +- .../src/client/gui/container/GuiHopper.java | 2 +- client/src/client/gui/container/GuiHorse.java | 2 +- .../src/client/gui/container/GuiMachine.java | 2 +- .../src/client/gui/container/GuiRepair.java | 2 +- client/src/client/gui/ingame/GuiGameOver.java | 4 +- client/src/client/network/ClientPlayer.java | 72 ++-- .../src/client/renderer/EntityRenderer.java | 56 +-- client/src/client/renderer/ItemRenderer.java | 20 +- client/src/client/renderer/RenderGlobal.java | 18 +- .../client/renderer/entity/RenderFish.java | 2 +- .../renderer/entity/RenderHumanoid.java | 4 +- common/src/common/log/Log.java | 10 +- common/src/common/util/Util.java | 11 +- 29 files changed, 380 insertions(+), 352 deletions(-) diff --git a/client/src/client/Client.java b/client/src/client/Client.java index 0bf4fb6..ddeec71 100755 --- a/client/src/client/Client.java +++ b/client/src/client/Client.java @@ -30,6 +30,7 @@ import java.util.concurrent.FutureTask; import java.util.function.Function; import javax.imageio.ImageIO; +import javax.swing.JFileChooser; import org.lwjgl.opengl.GL11; import org.lwjgl.opengl.GL13; @@ -342,8 +343,8 @@ public class Client implements IThreadListener, IClient { private BufferedImage skin; private Object popupTarget; public PlayerController controller; - public WorldClient theWorld; - public EntityNPC thePlayer; + public WorldClient world; + public EntityNPC player; public HitPosition pointed; @Variable(name = "chunk_view_distance", category = CVarCategory.RENDER, min = 2, max = 16 /* 128 */, callback = DistanceFunction.class, display = "Sichtweite", unit = "Chunks") @@ -520,8 +521,8 @@ public class Client implements IThreadListener, IClient { this.charEditor = false; this.viewEntity = null; this.connection = null; - this.theWorld = null; - this.thePlayer = null; + this.world = null; + this.player = null; this.serverInfo = null; this.lastTickTime = -1; this.soundManager.stopSounds(); @@ -574,7 +575,7 @@ public class Client implements IThreadListener, IClient { this.renderGlobal = new RenderGlobal(this); this.renderGlobal.onReload(); EntityTexManager.loadNpcTextures(); - this.effectRenderer = new EffectRenderer(this.theWorld, this.textureManager); + this.effectRenderer = new EffectRenderer(this.world, this.textureManager); } public void start() @@ -644,7 +645,7 @@ public class Client implements IThreadListener, IClient { if (this.keyBindsHotbar[l].isPressed()) { // if(!this.showDebugProfilerChart) { - this.thePlayer.inventory.currentItem = l; + this.player.inventory.currentItem = l; // } } } @@ -655,7 +656,7 @@ public class Client implements IThreadListener, IClient { if (Bind.THROW.isPressed()) { - this.thePlayer.dropOneItem(this.ctrl()); + this.player.dropOneItem(this.ctrl()); } this.primary |= Bind.PRIMARY.isPressed(); @@ -672,7 +673,7 @@ public class Client implements IThreadListener, IClient { } // this.ingameGui.updateTick(); this.entityRenderer.getMouseOver(1.0F); - if (/* !this.paused && */ this.theWorld != null) + if (/* !this.paused && */ this.world != null) { this.controller.updateController(); } @@ -682,9 +683,9 @@ public class Client implements IThreadListener, IClient { this.open.updateScreen(); } - if (this.open == null && this.thePlayer != null) + if (this.open == null && this.player != null) { - if (this.thePlayer.getHealth() <= 0) + if (this.player.getHealth() <= 0) { this.displayGuiScreen(null); } @@ -699,12 +700,12 @@ public class Client implements IThreadListener, IClient { --this.leftClickCounter; } - if (this.open == null && this.thePlayer != null) { - if (this.thePlayer.isUsingItem()) + if (this.open == null && this.player != null) { + if (this.player.isUsingItem()) { if (!Bind.SECONDARY.isDown()) { - this.controller.onStoppedUsingItem(this.thePlayer); + this.controller.onStoppedUsingItem(this.player); } } else @@ -730,7 +731,7 @@ public class Client implements IThreadListener, IClient { } } - if (Bind.SECONDARY.isDown() && this.rightClickTimer == 0 && !this.thePlayer.isUsingItem()) + if (Bind.SECONDARY.isDown() && this.rightClickTimer == 0 && !this.player.isUsingItem()) { this.secondary(); } @@ -740,30 +741,30 @@ public class Client implements IThreadListener, IClient { this.primary = this.secondary = this.tertiary = this.quarternary = false; - if (this.theWorld != null) + if (this.world != null) { - if (this.thePlayer != null) + if (this.player != null) { ++this.chunkLoadTimer; if (this.chunkLoadTimer == 30) { this.chunkLoadTimer = 0; - this.theWorld.ensureAreaLoaded(this.thePlayer); + this.world.ensureAreaLoaded(this.player); } } this.entityRenderer.updateRenderer(); this.renderGlobal.updateClouds(); - this.theWorld.decrLightning(); - this.theWorld.updateEntities(); + this.world.decrLightning(); + this.world.updateEntities(); } this.soundManager.update(); - if (this.theWorld != null) + if (this.world != null) { - this.theWorld.tick(); - if (/* !this.paused && */ this.theWorld != null) + this.world.tick(); + if (/* !this.paused && */ this.world != null) { - this.theWorld.displayTick(ExtMath.floord(this.thePlayer.posX), ExtMath.floord(this.thePlayer.posY), ExtMath.floord(this.thePlayer.posZ)); + this.world.displayTick(ExtMath.floord(this.player.posX), ExtMath.floord(this.player.posY), ExtMath.floord(this.player.posZ)); } this.effectRenderer.updateEffects(); } @@ -783,18 +784,18 @@ public class Client implements IThreadListener, IClient { GL11.glPolygonMode(GL11.GL_FRONT_AND_BACK, GL11.GL_LINE); // GL_FRONT_AND_BACK, GL_LINE } if(this.open == null) { - if(this.thePlayer != null) - this.thePlayer.setAngles(this.deltaX, this.deltaY); + if(this.player != null) + this.player.setAngles(this.deltaX, this.deltaY); this.deltaX = this.deltaY = 0.0f; } - if(this.thePlayer != null) - this.soundManager.setListener(this.thePlayer, (float)Timing.tick_fraction); - if(this.thePlayer != null && this.thePlayer.isEntityInsideOpaqueBlock()) + if(this.player != null) + this.soundManager.setListener(this.player, (float)Timing.tick_fraction); + if(this.player != null && this.player.isEntityInsideOpaqueBlock()) this.thirdPersonView = 0; GL11.glPushMatrix(); GL11.glClear(16640); GlState.enableTexture2D(); - if(this.theWorld != null) + if(this.world != null) this.entityRenderer.renderWorld((float)Timing.tick_fraction, System.nanoTime() - this.tickStart); GL11.glPopMatrix(); @@ -826,7 +827,7 @@ public class Client implements IThreadListener, IClient { public void renderHud() { this.setupOverlay(); - if(this.theWorld != null && this.open == null && this.thirdPersonView == 0 && this.viewEntity != null) { + if(this.world != null && this.open == null && this.thirdPersonView == 0 && this.viewEntity != null) { if(this.drawDebug) { this.renderWorldDirections((float)Timing.tick_fraction); } @@ -835,7 +836,7 @@ public class Client implements IThreadListener, IClient { Drawing.drawRect(this.fb_x / 2 - 16, this.fb_y / 2 - 1, 32, 2, this.pointed != null && this.pointed.type != ObjectType.MISS ? 0xffffffff : 0xffcfcfcf); } } - if(this.theWorld != null && this.open == null) { + if(this.world != null && this.open == null) { int selected = // this.getRenderViewEntity() != null && this.getRenderViewEntity().isPlayer() ? 9 : 0, this.getRenderViewEntity() != null && this.getRenderViewEntity().isPlayer() ? ((EntityNPC)this.getRenderViewEntity()).inventory.currentItem : -1; @@ -846,12 +847,12 @@ public class Client implements IThreadListener, IClient { Drawing.drawRectBorder(x - 1, y - 1, 36, 36, 0xff6f6f6f, selected == n ? 0xffffffff : 0xff000000, 0xffafafaf, 0xff4f4f4f); } - ItemStack itemstack = this.thePlayer != null ? this.thePlayer.inventory.getCurrentItem() : null; - String current = itemstack != null ? itemstack.getItem().getHotbarText(this.thePlayer, itemstack) : ""; + ItemStack itemstack = this.player != null ? this.player.inventory.getCurrentItem() : null; + String current = itemstack != null ? itemstack.getItem().getHotbarText(this.player, itemstack) : ""; if(!current.isEmpty()) Drawing.drawTextUpward(current, this.fb_x / 2, this.fb_y - 60, 0xffffffff); } - if(this.theWorld != null && !(this.open instanceof GuiConsole)) { + if(this.world != null && !(this.open instanceof GuiConsole)) { int x = this.fb_x / 2; int y = 0; Iterator> iter = this.bars.entrySet().iterator(); @@ -859,7 +860,7 @@ public class Client implements IThreadListener, IClient { while(iter.hasNext()) { Entry status = iter.next(); Entity ent; - if(this.thePlayer != null && now - status.getValue() < 10000L && (ent = this.thePlayer.worldObj.getEntityByID(status.getKey())) instanceof EntityLiving) { + if(this.player != null && now - status.getValue() < 10000L && (ent = this.player.worldObj.getEntityByID(status.getKey())) instanceof EntityLiving) { EntityLiving entity = (EntityLiving)ent; String s = entity.getName() + TextColor.GRAY + " [" + EntityLiving.getHealthColor(entity.getHealth(), entity.getMaxHealth()) + @@ -877,10 +878,10 @@ public class Client implements IThreadListener, IClient { } } - if(this.thePlayer != null && (!this.drawDebug || this.open != null)) { + if(this.player != null && (!this.drawDebug || this.open != null)) { x = 40; y = 40; - for(PotionEffect effect : this.thePlayer.getEffects()) { + for(PotionEffect effect : this.player.getEffects()) { Potion potion = effect.getPotion(); int color = potion.getColor(); String name = (potion.isBadEffect() ? TextColor.ORANGE : TextColor.ACID) + potion.getDisplay() + PotionHelper.getPotionPotency(effect.getAmplifier()); @@ -934,15 +935,15 @@ public class Client implements IThreadListener, IClient { } } - if(this.thePlayer != null) { + if(this.player != null) { x = 40; - y = this.fb_y - 40 - (this.thePlayer.isRidingHorse() && this.thePlayer.getHorseJumpPower() != 0.0f ? 2 : 1) * 40; - if(this.thePlayer.isRidingHorse() && this.thePlayer.getHorseJumpPower() != 0.0f) // { - y = bar(x, y, String.format(TextColor.NEON + "Sprungkraft: " + TextColor.CYAN + "%d %%", (int)(this.thePlayer.getHorseJumpPower() * 100.0f)), - this.thePlayer.getHorseJumpPower(), 0x4040ff); + y = this.fb_y - 40 - (this.player.isRidingHorse() && this.player.getHorseJumpPower() != 0.0f ? 2 : 1) * 40; + if(this.player.isRidingHorse() && this.player.getHorseJumpPower() != 0.0f) // { + y = bar(x, y, String.format(TextColor.NEON + "Sprungkraft: " + TextColor.CYAN + "%d %%", (int)(this.player.getHorseJumpPower() * 100.0f)), + this.player.getHorseJumpPower(), 0x4040ff); // } // else { - y = bar(x, y, String.format(TextColor.ACID + "EXP: " + TextColor.GREEN + "Level %d, %d/%d", this.thePlayer.experienceLevel, (int)((float)this.thePlayer.xpBarCap() * this.thePlayer.experience), this.thePlayer.xpBarCap()), this.thePlayer.experience, 0x40ff40); + y = bar(x, y, String.format(TextColor.ACID + "EXP: " + TextColor.GREEN + "Level %d, %d/%d", this.player.experienceLevel, (int)((float)this.player.xpBarCap() * this.player.experience), this.player.xpBarCap()), this.player.experience, 0x40ff40); // } } @@ -1013,7 +1014,7 @@ public class Client implements IThreadListener, IClient { } if(this.open != null) this.open.render(); - else if(this.theWorld == null || this.theWorld.hasNoChunks() || this.charEditor) + else if(this.world == null || this.world.hasNoChunks() || this.charEditor) Drawing.drawScaled(this, Gui.DIRT_BACKGROUND); if(Bind.INFO.isDown() && (this.open == null || !(this.open.selected instanceof Textbox))) this.drawInfo(); @@ -1112,8 +1113,8 @@ public class Client implements IThreadListener, IClient { } if(this.cameraUsed) { this.cameraUsed = false; - if(this.theWorld != null) - this.theWorld.setLastLightning(1, 0xffffff); + if(this.world != null) + this.world.setLastLightning(1, 0xffffff); } if(this.isDirty()) this.save(); @@ -1140,8 +1141,8 @@ public class Client implements IThreadListener, IClient { // } if(this.zooming) this.zoomLevel = ExtMath.clampf(this.zoomLevel + (dir < 0 ? -0.25f : 0.25f), 2.0f, 16.0f); - else if(this.thePlayer != null) - this.thePlayer.inventory.changeCurrentItem(dir); + else if(this.player != null) + this.player.inventory.changeCurrentItem(dir); } // public void resize(int width, int height) @@ -1180,8 +1181,8 @@ public class Client implements IThreadListener, IClient { { if(!this.refreshing) this.waitingForFile = false; - if(this.thePlayer != null) - this.thePlayer.setScreenClosed(); + if(this.player != null) + this.player.setScreenClosed(); if (this.open != null) { this.open.onGuiClosed(); @@ -1194,7 +1195,7 @@ public class Client implements IThreadListener, IClient { // guiScreenIn = new GuiMainMenu(); // } // else - if (gui == null && this.theWorld != null && this.thePlayer.getHealth() <= 0) + if (gui == null && this.world != null && this.player.getHealth() <= 0) { gui = GuiGameOver.INSTANCE; } @@ -1236,16 +1237,16 @@ public class Client implements IThreadListener, IClient { this.controller.resetInteraction(); } - if (this.leftClickCounter <= 0 && !this.thePlayer.isUsingItem()) + if (this.leftClickCounter <= 0 && !this.player.isUsingItem()) { if (leftClick && this.pointed != null && this.pointed.type == HitPosition.ObjectType.BLOCK) { BlockPos blockpos = this.pointed.block; - if (this.theWorld.getState(blockpos).getBlock().getMaterial() != Material.air && this.controller.onPlayerDamageBlock(blockpos, this.pointed.side)) + if (this.world.getState(blockpos).getBlock().getMaterial() != Material.air && this.controller.onPlayerDamageBlock(blockpos, this.pointed.side)) { this.effectRenderer.addBlockHitEffects(blockpos, this.pointed.side); - this.thePlayer.swingItem(); + this.player.swingItem(); } } else @@ -1261,17 +1262,17 @@ public class Client implements IThreadListener, IClient { { if (this.pointed == null) { - this.thePlayer.swingItem(); + this.player.swingItem(); Log.JNI.warn("Null zurückgegeben als 'hitResult', das sollte niemals passieren!"); this.leftClickCounter = 10; } else { - ItemStack itemstack = this.thePlayer.inventory.getCurrentItem(); - if ((this.pointed.type != ObjectType.BLOCK || this.theWorld.getState(this.pointed.block).getBlock().getMaterial() == Material.air) && itemstack != null && itemstack.getItem().onAction(itemstack, this.thePlayer, this.theWorld, ItemControl.PRIMARY, null)) + ItemStack itemstack = this.player.inventory.getCurrentItem(); + if ((this.pointed.type != ObjectType.BLOCK || this.world.getState(this.pointed.block).getBlock().getMaterial() == Material.air) && itemstack != null && itemstack.getItem().onAction(itemstack, this.player, this.world, ItemControl.PRIMARY, null)) { - this.thePlayer.swingItem(); - this.thePlayer.sendQueue.addToSendQueue(new CPacketAction(Action.ITEM_ACTION, ItemControl.PRIMARY.ordinal())); + this.player.swingItem(); + this.player.sendQueue.addToSendQueue(new CPacketAction(Action.ITEM_ACTION, ItemControl.PRIMARY.ordinal())); this.leftClickCounter = 10; return; } @@ -1279,13 +1280,13 @@ public class Client implements IThreadListener, IClient { switch (this.pointed.type) { case ENTITY: - this.thePlayer.swingItem(); - this.controller.attackEntity(this.thePlayer, this.pointed.entity); + this.player.swingItem(); + this.controller.attackEntity(this.player, this.pointed.entity); break; case BLOCK: - this.thePlayer.swingItem(); + this.player.swingItem(); BlockPos blockpos = this.pointed.block; - if (this.theWorld.getState(blockpos).getBlock().getMaterial() != Material.air) + if (this.world.getState(blockpos).getBlock().getMaterial() != Material.air) { this.controller.clickBlock(blockpos, this.pointed.side); break; @@ -1294,7 +1295,7 @@ public class Client implements IThreadListener, IClient { break; case MISS: default: - this.thePlayer.swingItem(); + this.player.swingItem(); this.leftClickCounter = 10; } } @@ -1307,7 +1308,7 @@ public class Client implements IThreadListener, IClient { { this.rightClickTimer = 4; boolean flag = true; - ItemStack itemstack = this.thePlayer.inventory.getCurrentItem(); + ItemStack itemstack = this.player.inventory.getCurrentItem(); if (itemstack != null && itemstack.getItem() == Items.camera && !this.saving) { @@ -1320,10 +1321,10 @@ public class Client implements IThreadListener, IClient { } else { - if ((this.pointed.type != ObjectType.BLOCK || this.theWorld.getState(this.pointed.block).getBlock().getMaterial() == Material.air) && itemstack != null && itemstack.getItem().onAction(itemstack, this.thePlayer, this.theWorld, ItemControl.SECONDARY, null)) + if ((this.pointed.type != ObjectType.BLOCK || this.world.getState(this.pointed.block).getBlock().getMaterial() == Material.air) && itemstack != null && itemstack.getItem().onAction(itemstack, this.player, this.world, ItemControl.SECONDARY, null)) { - this.thePlayer.swingItem(); - this.thePlayer.sendQueue.addToSendQueue(new CPacketAction(Action.ITEM_ACTION, ItemControl.SECONDARY.ordinal())); + this.player.swingItem(); + this.player.sendQueue.addToSendQueue(new CPacketAction(Action.ITEM_ACTION, ItemControl.SECONDARY.ordinal())); return; } @@ -1335,7 +1336,7 @@ public class Client implements IThreadListener, IClient { // flag = false; // } // else - if (this.controller.interactWithEntitySendPacket(this.thePlayer, this.pointed.entity)) + if (this.controller.interactWithEntitySendPacket(this.player, this.pointed.entity)) { flag = false; } @@ -1345,14 +1346,14 @@ public class Client implements IThreadListener, IClient { case BLOCK: BlockPos blockpos = this.pointed.block; - if (this.theWorld.getState(blockpos).getBlock().getMaterial() != Material.air) + if (this.world.getState(blockpos).getBlock().getMaterial() != Material.air) { int i = itemstack != null ? itemstack.stackSize : 0; - if (this.controller.onPlayerRightClick(this.thePlayer, this.theWorld, itemstack, blockpos, this.pointed.side, this.pointed.vec)) + if (this.controller.onPlayerRightClick(this.player, this.world, itemstack, blockpos, this.pointed.side, this.pointed.vec)) { flag = false; - this.thePlayer.swingItem(); + this.player.swingItem(); } if (itemstack == null) @@ -1362,7 +1363,7 @@ public class Client implements IThreadListener, IClient { if (itemstack.stackSize == 0) { - this.thePlayer.inventory.mainInventory[this.thePlayer.inventory.currentItem] = null; + this.player.inventory.mainInventory[this.player.inventory.currentItem] = null; } else if (itemstack.stackSize != i) // || this.controller.isCreative()) { @@ -1374,9 +1375,9 @@ public class Client implements IThreadListener, IClient { if (flag) { - ItemStack itemstack1 = this.thePlayer.inventory.getCurrentItem(); + ItemStack itemstack1 = this.player.inventory.getCurrentItem(); - if (itemstack1 != null && this.controller.sendUseItem(this.thePlayer, this.theWorld, itemstack1)) + if (itemstack1 != null && this.controller.sendUseItem(this.player, this.world, itemstack1)) { this.entityRenderer.itemRenderer.resetEquippedProgress2(); } @@ -1388,8 +1389,8 @@ public class Client implements IThreadListener, IClient { { if (this.pointed != null) { - if(this.thePlayer.getHeldItem() != null && this.thePlayer.getHeldItem().getItem().onAction(this.thePlayer.getHeldItem(), this.thePlayer, this.theWorld, ItemControl.TERTIARY, null)) { - this.thePlayer.sendQueue.addToSendQueue(new CPacketAction(Action.ITEM_ACTION, ItemControl.TERTIARY.ordinal())); + if(this.player.getHeldItem() != null && this.player.getHeldItem().getItem().onAction(this.player.getHeldItem(), this.player, this.world, ItemControl.TERTIARY, null)) { + this.player.sendQueue.addToSendQueue(new CPacketAction(Action.ITEM_ACTION, ItemControl.TERTIARY.ordinal())); return; } @@ -1403,14 +1404,14 @@ public class Client implements IThreadListener, IClient { if (this.pointed.type == HitPosition.ObjectType.BLOCK) { BlockPos blockpos = this.pointed.block; - Block block = this.theWorld.getState(blockpos).getBlock(); + Block block = this.world.getState(blockpos).getBlock(); if (block.getMaterial() == Material.air) { return; } - item = block.getItem(this.theWorld, blockpos); + item = block.getItem(this.world, blockpos); if (item == null) { @@ -1418,7 +1419,7 @@ public class Client implements IThreadListener, IClient { } Block block1 = item instanceof ItemBlock && !block.isPickStrict() ? item.getBlock() : block; - meta = block1.getDamageValue(this.theWorld, blockpos); + meta = block1.getDamageValue(this.world, blockpos); flag1 = item.getHasSubtypes(); } else @@ -1432,11 +1433,11 @@ public class Client implements IThreadListener, IClient { return; } - InventoryPlayer inventoryplayer = this.thePlayer.inventory; + InventoryPlayer inventoryplayer = this.player.inventory; inventoryplayer.setCurrentItem(item, meta, flag1); if(this.itemCheat) { - this.thePlayer.sendQueue.addToSendQueue(new CPacketCheat(new ItemStack(item, 1, meta), inventoryplayer.currentItem, this.ctrl())); + this.player.sendQueue.addToSendQueue(new CPacketCheat(new ItemStack(item, 1, meta), inventoryplayer.currentItem, this.ctrl())); } } } @@ -1445,8 +1446,8 @@ public class Client implements IThreadListener, IClient { { if (this.pointed != null) { - if(this.thePlayer.getHeldItem() != null && this.thePlayer.getHeldItem().getItem().onAction(this.thePlayer.getHeldItem(), this.thePlayer, this.theWorld, ItemControl.QUARTERNARY, null)) { - this.thePlayer.sendQueue.addToSendQueue(new CPacketAction(Action.ITEM_ACTION, ItemControl.QUARTERNARY.ordinal())); + if(this.player.getHeldItem() != null && this.player.getHeldItem().getItem().onAction(this.player.getHeldItem(), this.player, this.world, ItemControl.QUARTERNARY, null)) { + this.player.sendQueue.addToSendQueue(new CPacketAction(Action.ITEM_ACTION, ItemControl.QUARTERNARY.ordinal())); return; } } @@ -1466,7 +1467,7 @@ public class Client implements IThreadListener, IClient { this.viewEntity = null; this.connection = null; this.soundManager.stopSounds(); - this.theWorld = world; + this.world = world; if (this.renderGlobal != null) { @@ -1478,15 +1479,15 @@ public class Client implements IThreadListener, IClient { this.effectRenderer.clearEffects(world); } - if (this.thePlayer == null) + if (this.player == null) { - this.thePlayer = this.controller.createPlayerEntity(world, type); - this.thePlayer.rotYaw = -180.0F; + this.player = this.controller.createPlayerEntity(world, type); + this.player.rotYaw = -180.0F; } - this.thePlayer.preparePlayerToSpawn(); - world.spawnEntityInWorld(this.thePlayer); - this.viewEntity = this.thePlayer; + this.player.preparePlayerToSpawn(); + world.spawnEntityInWorld(this.player); + this.viewEntity = this.player; System.gc(); // SKC.loaded(true); @@ -1494,24 +1495,24 @@ public class Client implements IThreadListener, IClient { public void setDimensionAndSpawnPlayer(int dimension, int type) { - this.theWorld.removeAllEntities(); + this.world.removeAllEntities(); int i = 0; - if (this.thePlayer != null) + if (this.player != null) { - i = this.thePlayer.getId(); - this.theWorld.removeEntity(this.thePlayer); + i = this.player.getId(); + this.world.removeEntity(this.player); } this.viewEntity = null; - EntityNPC entityplayersp = this.thePlayer; - this.thePlayer = this.controller.createPlayerEntity(this.theWorld, type); - this.thePlayer.getDataWatcher().updateWatchedObjectsFromList(entityplayersp.getDataWatcher().getAllWatched()); - this.viewEntity = this.thePlayer; - this.thePlayer.preparePlayerToSpawn(); - this.theWorld.spawnEntityInWorld(this.thePlayer); - this.thePlayer.rotYaw = -180.0F; - this.thePlayer.setId(i); + EntityNPC entityplayersp = this.player; + this.player = this.controller.createPlayerEntity(this.world, type); + this.player.getDataWatcher().updateWatchedObjectsFromList(entityplayersp.getDataWatcher().getAllWatched()); + this.viewEntity = this.player; + this.player.preparePlayerToSpawn(); + this.world.spawnEntityInWorld(this.player); + this.player.rotYaw = -180.0F; + this.player.setId(i); // if (this.open instanceof GuiGameOver) // { @@ -1522,7 +1523,7 @@ public class Client implements IThreadListener, IClient { public ClientPlayer getNetHandler() { - return this.thePlayer != null ? (ClientPlayer)this.thePlayer.sendQueue : null; + return this.player != null ? (ClientPlayer)this.player.sendQueue : null; } // public void setSkin(BufferedImage skin, String id, ModelType model, boolean slim) @@ -1568,8 +1569,8 @@ public class Client implements IThreadListener, IClient { } public void performAction(Action action) { - if(this.thePlayer != null) - this.thePlayer.sendQueue.addToSendQueue(new CPacketAction(action)); + if(this.player != null) + this.player.sendQueue.addToSendQueue(new CPacketAction(action)); } public void setBossStatus(EntityLiving entity) { @@ -1709,7 +1710,7 @@ public class Client implements IThreadListener, IClient { String mem = String.format("JVM-Speicher: %d%% %d/%dMB", usedMem * 100L / maxMem, usedMem / 1024L / 1024L, maxMem / 1024L / 1024L) + "\n" + String.format("JVM-Reserviert: %d%% %dMB", totalMem * 100L / maxMem, totalMem / 1024L / 1024L); - if(this.theWorld == null) { + if(this.world == null) { return mem; } @@ -1737,27 +1738,27 @@ public class Client implements IThreadListener, IClient { Biome biome = null; String bline; String lline; - if(this.theWorld.isBlockLoaded(blockpos)) { - Chunk chunk = this.theWorld.getChunk(blockpos); + if(this.world.isBlockLoaded(blockpos)) { + Chunk chunk = this.world.getChunk(blockpos); biome = chunk.getBiome(blockpos, null); bline = "Biom: " + biome.display + " (" + biome.id + ")" + /* (this.debugHideInfo ? "" : */ (", D: " + - TextColor.stripCodes(this.theWorld.dimension.getFormattedName(false)) + - " (" + this.theWorld.dimension.getDimensionId() + ")"); + TextColor.stripCodes(this.world.dimension.getFormattedName(false)) + + " (" + this.world.dimension.getDimensionId() + ")"); lline = "Licht: " + chunk.getLightSub(blockpos, 0) + " (" + chunk.getLight(LightType.SKY, blockpos) + " Himmel, " + chunk.getLight(LightType.BLOCK, blockpos) + " Blöcke, " + String.format( - "%.1f", this.theWorld.getSunBrightness(1.0f) * 15.0f) + " Welt), A: " - + String.format("%.3f", this.theWorld.getCelestialAngle(1.0f)); + "%.1f", this.world.getSunBrightness(1.0f) * 15.0f) + " Welt), A: " + + String.format("%.3f", this.world.getCelestialAngle(1.0f)); } else { bline = "Biom: , D: " + - TextColor.stripCodes(this.theWorld.dimension.getFormattedName(false)) + - " (" + this.theWorld.dimension.getDimensionId() + ")"; + TextColor.stripCodes(this.world.dimension.getFormattedName(false)) + + " (" + this.world.dimension.getDimensionId() + ")"; lline = "Licht: " + String.format( - "%.1f", this.theWorld.getSunBrightness(1.0f) * 15.0f) + " Welt, A: " - + String.format("%.3f", this.theWorld.getCelestialAngle(1.0f)); + "%.1f", this.world.getSunBrightness(1.0f) * 15.0f) + " Welt, A: " + + String.format("%.3f", this.world.getCelestialAngle(1.0f)); } - float temp = this.theWorld.getTempOffset() + (biome != null ? biome.getTemperature(blockpos) : 0.0f); + float temp = this.world.getTempOffset() + (biome != null ? biome.getTemperature(blockpos) : 0.0f); long ticked = System.currentTimeMillis() - this.lastTicked; return @@ -1768,8 +1769,8 @@ public class Client implements IThreadListener, IClient { // this.connected != null ? this.connected : "[???]"))), this.renderGlobal.getDebugInfoRenders() + "\n" + this.renderGlobal.getDebugInfoEntities() + "\n" + - "Partikel: " + this.effectRenderer.getStatistics() + ". O: " + this.theWorld.getDebugLoadedEntities() + "\n" + - this.theWorld.getInfo() + "\n" + + "Partikel: " + this.effectRenderer.getStatistics() + ". O: " + this.world.getDebugLoadedEntities() + "\n" + + this.world.getInfo() + "\n" + // "", String.format("XYZ: %.3f / %.3f / %.3f", this.viewEntity.posX, this.viewEntity.getEntityBoundingBox().minY, this.viewEntity.posZ) + "\n" + @@ -1785,21 +1786,21 @@ public class Client implements IThreadListener, IClient { bline + "\n" + lline + "\n" + String.format("Zeit: %d T, R %d / %d T, U %d / %d T", - this.theWorld.getDayTime(), - this.theWorld.getDayTime() % this.theWorld.dimension.getRotationalPeriod(), - this.theWorld.dimension.getRotationalPeriod(), - this.theWorld.getDayTime() % this.theWorld.dimension.getOrbitalPeriod(), - this.theWorld.dimension.getOrbitalPeriod() + this.world.getDayTime(), + this.world.getDayTime() % this.world.dimension.getRotationalPeriod(), + this.world.dimension.getRotationalPeriod(), + this.world.getDayTime() % this.world.dimension.getOrbitalPeriod(), + this.world.dimension.getOrbitalPeriod() ) + "\n" + String.format("Laub: %s%s, T: %.2f K / %.2f °C, %s (R %.1f, %.1f)", - !this.theWorld.dimension.getType().days ? "*" : "", - this.theWorld.getLeavesGen(blockpos).getDisplayName(), + !this.world.dimension.getType().days ? "*" : "", + this.world.getLeavesGen(blockpos).getDisplayName(), temp, World.ABSOLUTE_ZERO + temp, - this.theWorld.getWeather().getDisplay(), this.theWorld.getRainStrength(), - this.theWorld.getDarkness() + this.world.getWeather().getDisplay(), this.world.getRainStrength(), + this.world.getDarkness() ) + "\n" + String.format("Zeitfaktor: %dx, Schwerkraft: %.2f m/s²", - this.timeFactor, this.theWorld.gravity * 10.0 + this.timeFactor, this.world.gravity * 10.0 ) + "\n" + String.format("Letzte Zeitsynch.: + %d.%d s", ticked / 1000L, (ticked / 100L) % 10L @@ -1812,17 +1813,17 @@ public class Client implements IThreadListener, IClient { } public String getRight(boolean showPlayerInfo) { - if(this.theWorld == null) { + if(this.world == null) { return null; } if(!showPlayerInfo && this.pointed != null && this.pointed.type == HitPosition.ObjectType.BLOCK && this.pointed.block != null) { BlockPos pos = this.pointed.block; - State block = this.theWorld.getState(pos); + State block = this.world.getState(pos); if(!this.debugWorld) { - block = block.getBlock().getActualState(block, this.theWorld, pos); + block = block.getBlock().getActualState(block, this.world, pos); } StringBuilder str = new StringBuilder( @@ -1842,7 +1843,7 @@ public class Client implements IThreadListener, IClient { } else if((this.pointed != null && this.pointed.type == HitPosition.ObjectType.ENTITY && this.pointed.entity != null) || showPlayerInfo) { - Entity entity = showPlayerInfo ? this.thePlayer : this.pointed.entity; + Entity entity = showPlayerInfo ? this.player : this.pointed.entity; ItemStack held = entity instanceof EntityLiving && ((EntityLiving)entity).getHeldItem() != null ? ((EntityLiving)entity).getHeldItem() : null; return @@ -2262,24 +2263,24 @@ public class Client implements IThreadListener, IClient { // if(this.theWorld != null && this.open == null && Bind.COMMAND.isPressed()) { // this.displayGuiScreen(GuiChat.INSTANCE); // } - if(this.theWorld != null && Bind.MENU.isPressed()) { + if(this.world != null && Bind.MENU.isPressed()) { if(this.open != (this.charEditor ? GuiChar.INSTANCE : null)) this.displayGuiScreen(this.charEditor ? GuiChar.INSTANCE : null); else this.displayGuiScreen(GuiMenu.INSTANCE); } - else if(this.theWorld == null && !(this.open instanceof GuiMenu) && Bind.MENU.isPressed()) { + else if(this.world == null && !(this.open instanceof GuiMenu) && Bind.MENU.isPressed()) { this.displayGuiScreen(GuiMenu.INSTANCE); } - if(this.theWorld != null && !this.charEditor && Bind.INVENTORY.isPressed()) { + if(this.world != null && !this.charEditor && Bind.INVENTORY.isPressed()) { if(this.open instanceof GuiContainer) { this.displayGuiScreen(null); } else if(this.open == null) { - if(this.thePlayer.isRiding() && this.thePlayer.vehicle instanceof EntityHorse) - this.thePlayer.sendHorseInventory(); + if(this.player.isRiding() && this.player.vehicle instanceof EntityHorse) + this.player.sendHorseInventory(); else - this.displayGuiScreen(/* this.itemCheat ? new GuiCheat() : */ new GuiInventory(this.thePlayer)); + this.displayGuiScreen(/* this.itemCheat ? new GuiCheat() : */ new GuiInventory(this.player)); } } } @@ -2394,7 +2395,7 @@ public class Client implements IThreadListener, IClient { } public void unload(boolean loading) { - if(this.theWorld != null) { + if(this.world != null) { if(this.getNetHandler() != null) this.getNetHandler().getNetworkManager().closeChannel("Quitting"); this.unloadWorld(); @@ -2906,7 +2907,7 @@ public class Client implements IThreadListener, IClient { return; } } - if(this.thePlayer != null && this.getNetHandler() != null) + if(this.player != null && this.getNetHandler() != null) this.getNetHandler().addToSendQueue(new CPacketMessage(line.startsWith("/") ? CPacketMessage.Type.COMMAND : CPacketMessage.Type.CHAT, line.startsWith("/") ? line.substring(1) : line)); // Log.CONSOLE.user("%s", line); // this.command(line); @@ -3216,8 +3217,11 @@ public class Client implements IThreadListener, IClient { this.waitingForFile = true; new Thread(new Runnable() { public void run() { - String output; + String output = null; + JFileChooser chooser = null; try { + if(Util.WINDOWS) + throw new RuntimeException("Windows wird von Zenity nicht unterstützt"); List list = Lists.newArrayList("zenity", "--file-selection"); switch(mode) { case DIRECTORY_SAVE: @@ -3251,21 +3255,40 @@ public class Client implements IThreadListener, IClient { } } catch(Throwable e) { - Log.SYSTEM.error(e, "Konnte Zenity nicht starten"); - Client.this.logFeed(TextColor.RED + "Konnte Dateibrowser nicht öffnen"); - Client.this.waitingForFile = false; - return; + Log.SYSTEM.error(e, "Konnte Dateibrowser nicht starten"); + chooser = new JFileChooser(def.isDirectory() ? def : def.getParentFile()); + chooser.setDialogTitle(title); + chooser.setMultiSelectionEnabled(mode == FileMode.FILE_LOAD_MULTI); + chooser.setFileSelectionMode(mode == FileMode.DIRECTORY_LOAD || mode == FileMode.DIRECTORY_SAVE ? JFileChooser.DIRECTORIES_ONLY : JFileChooser.FILES_ONLY); + int result; + if(mode == FileMode.FILE_SAVE || mode == FileMode.DIRECTORY_SAVE) + result = chooser.showSaveDialog(null); + else + result = chooser.showOpenDialog(null); + if(result != JFileChooser.APPROVE_OPTION) { +// Client.this.logFeed(TextColor.RED + "Konnte Dateibrowser nicht öffnen"); + Client.this.waitingForFile = false; + return; + } } - if(output == null) { + if(output == null && chooser == null) { Client.this.waitingForFile = false; return; } if(mode == FileMode.FILE_LOAD_MULTI) { final List files = Lists.newArrayList(); - for(String out : output.split(":")) { - File file = new File(out); - if(file.isFile()) - files.add(file); + if(chooser != null) { + for(File file : chooser.getSelectedFiles()) { + if(file.isFile()) + files.add(file); + } + } + else { + for(String out : output.split(":")) { + File file = new File(out); + if(file.isFile()) + files.add(file); + } } if(files.isEmpty()) { Client.this.waitingForFile = false; @@ -3283,7 +3306,7 @@ public class Client implements IThreadListener, IClient { }); } else { - File file = new File(output); + File file = chooser != null ? chooser.getSelectedFile() : new File(output); switch(mode) { case DIRECTORY_LOAD: if(!file.isDirectory()) { @@ -3319,12 +3342,12 @@ public class Client implements IThreadListener, IClient { }); } } - }, "Zenity listener").start(); + }, "File Browser listener").start(); } public void makeFireworks(double x, double y, double z, double motionX, double motionY, double motionZ, NBTTagCompound compund) { - this.effectRenderer.addEffect(new EntityFirework.StarterFX(this.theWorld, x, y, z, motionX, motionY, motionZ, this.effectRenderer, compund)); + this.effectRenderer.addEffect(new EntityFirework.StarterFX(this.world, x, y, z, motionX, motionY, motionZ, this.effectRenderer, compund)); } public int getRenderDistance() { @@ -3348,7 +3371,7 @@ public class Client implements IThreadListener, IClient { } public EntityNPC getPlayer() { - return this.thePlayer; + return this.player; } public IEntityFX spawnEffectParticle(int particleId, double xCoord, double yCoord, double zCoord, double xSpeed, double ySpeed, double zSpeed, diff --git a/client/src/client/PlayerController.java b/client/src/client/PlayerController.java index a638839..80017d3 100755 --- a/client/src/client/PlayerController.java +++ b/client/src/client/PlayerController.java @@ -113,7 +113,7 @@ public class PlayerController // } // else // { - World world = this.gm.theWorld; + World world = this.gm.world; State iblockstate = world.getState(pos); Block block1 = iblockstate.getBlock(); @@ -135,15 +135,15 @@ public class PlayerController // if (!this.creative) // { - ItemStack itemstack1 = this.gm.thePlayer.getCurrentEquippedItem(); + ItemStack itemstack1 = this.gm.player.getCurrentEquippedItem(); if (itemstack1 != null) { - itemstack1.onBlockDestroyed(world, block1, pos, this.gm.thePlayer); + itemstack1.onBlockDestroyed(world, block1, pos, this.gm.player); if (itemstack1.stackSize == 0) { - this.gm.thePlayer.destroyCurrentEquippedItem(); + this.gm.player.destroyCurrentEquippedItem(); } } // } @@ -188,8 +188,8 @@ public class PlayerController } else { - ItemStack stack = this.gm.thePlayer.getHeldItem(); - if(stack != null && stack.getItem().onAction(stack, this.gm.thePlayer, this.gm.theWorld, ItemControl.PRIMARY, loc)) { + ItemStack stack = this.gm.player.getHeldItem(); + if(stack != null && stack.getItem().onAction(stack, this.gm.player, this.gm.world, ItemControl.PRIMARY, loc)) { this.interacting = true; this.netClientHandler.addToSendQueue(new CPacketBreak(CPacketBreak.Action.START_DESTROY_BLOCK, loc, face)); return true; @@ -209,15 +209,15 @@ public class PlayerController } this.netClientHandler.addToSendQueue(new CPacketBreak(CPacketBreak.Action.START_DESTROY_BLOCK, loc, face)); - Block block1 = this.gm.theWorld.getState(loc).getBlock(); + Block block1 = this.gm.world.getState(loc).getBlock(); boolean flag = block1.getMaterial() != Material.air; if (flag && this.curBlockDamageMP == 0.0F) { - block1.onBlockClicked(this.gm.theWorld, loc, this.gm.thePlayer); + block1.onBlockClicked(this.gm.world, loc, this.gm.player); } - if (flag && block1.getPlayerRelativeBlockHardness(this.gm.thePlayer, this.gm.thePlayer.worldObj, loc) >= 1.0F) + if (flag && block1.getPlayerRelativeBlockHardness(this.gm.player, this.gm.player.worldObj, loc) >= 1.0F) { this.onPlayerDestroyBlock(loc, face); // if(this.cheat && block1.getPlayerRelativeBlockHardness(this.gm.thePlayer, this.gm.thePlayer.worldObj, loc) < 1.0F) @@ -227,10 +227,10 @@ public class PlayerController { this.isHittingBlock = true; this.currentBlock = loc; - this.currentItemHittingBlock = this.gm.thePlayer.getHeldItem(); + this.currentItemHittingBlock = this.gm.player.getHeldItem(); this.curBlockDamageMP = 0.0F; this.stepSoundTickCounter = 0.0F; - this.gm.theWorld.sendBlockBreakProgress(this.gm.thePlayer.getId(), this.currentBlock, (int)(this.curBlockDamageMP * 10.0F) - 1); + this.gm.world.sendBlockBreakProgress(this.gm.player.getId(), this.currentBlock, (int)(this.curBlockDamageMP * 10.0F) - 1); } } @@ -248,7 +248,7 @@ public class PlayerController this.netClientHandler.addToSendQueue(new CPacketBreak(CPacketBreak.Action.ABORT_DESTROY_BLOCK, this.currentBlock, Facing.DOWN)); this.isHittingBlock = false; this.curBlockDamageMP = 0.0F; - this.gm.theWorld.sendBlockBreakProgress(this.gm.thePlayer.getId(), this.currentBlock, -1); + this.gm.world.sendBlockBreakProgress(this.gm.player.getId(), this.currentBlock, -1); } } @@ -277,7 +277,7 @@ public class PlayerController // } else if (this.isHittingPosition(posBlock)) { - Block block = this.gm.theWorld.getState(posBlock).getBlock(); + Block block = this.gm.world.getState(posBlock).getBlock(); if (block.getMaterial() == Material.air) { @@ -286,7 +286,7 @@ public class PlayerController } else { - this.curBlockDamageMP += block.getPlayerRelativeBlockHardness(this.gm.thePlayer, this.gm.thePlayer.worldObj, posBlock); + this.curBlockDamageMP += block.getPlayerRelativeBlockHardness(this.gm.player, this.gm.player.worldObj, posBlock); if (this.stepSoundTickCounter % 4.0F == 0.0F && block.sound.getStepSound() != null) { @@ -305,7 +305,7 @@ public class PlayerController this.blockHitDelay = 5; } - this.gm.theWorld.sendBlockBreakProgress(this.gm.thePlayer.getId(), this.currentBlock, (int)(this.curBlockDamageMP * 10.0F) - 1); + this.gm.world.sendBlockBreakProgress(this.gm.player.getId(), this.currentBlock, (int)(this.curBlockDamageMP * 10.0F) - 1); return true; } } @@ -339,7 +339,7 @@ public class PlayerController private boolean isHittingPosition(BlockPos pos) { - ItemStack itemstack = this.gm.thePlayer.getHeldItem(); + ItemStack itemstack = this.gm.player.getHeldItem(); boolean flag = this.currentItemHittingBlock == null && itemstack == null; if (this.currentItemHittingBlock != null && itemstack != null) @@ -355,7 +355,7 @@ public class PlayerController */ private void syncCurrentPlayItem() { - int i = this.gm.thePlayer.inventory.currentItem; + int i = this.gm.player.inventory.currentItem; if (i != this.currentPlayerItem) { diff --git a/client/src/client/gui/Gui.java b/client/src/client/gui/Gui.java index bad7a40..73628a8 100644 --- a/client/src/client/gui/Gui.java +++ b/client/src/client/gui/Gui.java @@ -301,7 +301,7 @@ public abstract class Gui { // } public void drawMainBackground() { - if(this.gm.theWorld != null && !this.gm.charEditor) { + if(this.gm.world != null && !this.gm.charEditor) { // Drawing.drawGradient(0, 0, this.fb_x, this.fb_y, this.theWorld == null ? this.style.bg_top : 0x3f202020, // this.theWorld == null ? this.style.bg_btm : 0x3f000000); Drawing.drawGradient(0, 0, this.gm.fb_x, this.gm.fb_y, 0xc0101010, 0xd0101010); diff --git a/client/src/client/gui/GuiConfirm.java b/client/src/client/gui/GuiConfirm.java index 5a4a907..fb9b117 100755 --- a/client/src/client/gui/GuiConfirm.java +++ b/client/src/client/gui/GuiConfirm.java @@ -28,7 +28,7 @@ public class GuiConfirm extends Gui implements ActButton.Callback { public void init(int width, int height) { this.add(new Label(0, 0, 500, 24, this.messageLine1, true)); - this.add(new TransparentBox(0, 80, 500, 300, this.messageLine2, this.gm.theWorld != null && !this.gm.charEditor)); + this.add(new TransparentBox(0, 80, 500, 300, this.messageLine2, this.gm.world != null && !this.gm.charEditor)); this.confirmBtn = this.add(new ActButton(48, 500, 200, 24, this, this.confirmButtonText)); this.cancelBtn = this.add(new ActButton(252, 500, 200, 24, this, this.cancelButtonText)); this.shift(); diff --git a/client/src/client/gui/GuiConsole.java b/client/src/client/gui/GuiConsole.java index 4ff2c19..3ea6d44 100644 --- a/client/src/client/gui/GuiConsole.java +++ b/client/src/client/gui/GuiConsole.java @@ -55,7 +55,7 @@ public class GuiConsole extends Gui implements Textbox.Callback { } }, "Löschen")); } - this.logBox = this.add(new TransparentBox(0, this.full ? 24 : 0, width, height - (this.full ? 48 : 24), this.gm.getBuffer(), this.gm.theWorld != null && !this.gm.charEditor)); + this.logBox = this.add(new TransparentBox(0, this.full ? 24 : 0, width, height - (this.full ? 48 : 24), this.gm.getBuffer(), this.gm.world != null && !this.gm.charEditor)); if(this.full) this.add(new Fill(640, 0, width - 640, 24)); this.inputField = this.add(new Textbox(0, height - 24, width, 24, IPlayer.MAX_CMD_LENGTH, true, this, "")); @@ -79,7 +79,7 @@ public class GuiConsole extends Gui implements Textbox.Callback { } public void drawMainBackground() { - if(this.gm.theWorld == null || this.gm.charEditor) + if(this.gm.world == null || this.gm.charEditor) super.drawMainBackground(); } @@ -123,7 +123,7 @@ public class GuiConsole extends Gui implements Textbox.Callback { } this.inputField.setText(""); - if((this.gm.conAutoclose || !this.full) && this.gm.theWorld != null) + if((this.gm.conAutoclose || !this.full) && this.gm.world != null) this.gm.displayGuiScreen(null); } } @@ -215,7 +215,7 @@ public class GuiConsole extends Gui implements Textbox.Callback { s = argv[argv.length - 1]; Iterable res = pre.startsWith("#") ? (argv.length == 1 ? this.gm.getVars() : (argv.length == 2 ? getVarCompletion(argv[0].substring(1)) : Lists.newArrayList())) : - (this.gm.thePlayer == null ? Lists.newArrayList() : ((ClientPlayer)this.gm.thePlayer.sendQueue).getPlayerNames()); + (this.gm.player == null ? Lists.newArrayList() : ((ClientPlayer)this.gm.player.sendQueue).getPlayerNames()); if(argv.length == 1 && pre.startsWith("#")) s = s.substring(1); for(String s1 : res) { @@ -252,10 +252,10 @@ public class GuiConsole extends Gui implements Textbox.Callback { blockpos = new BlockPos(this.gm.pointed.entity); } if(currentText.startsWith("/")) { - if(this.gm.thePlayer != null) { + if(this.gm.player != null) { currentText = currentText.substring(1); this.prefixFirst = currentText.split(" ", -1).length == 1 ? "/" : null; - this.gm.thePlayer.sendQueue.addToSendQueue(new CPacketComplete(currentText, eid, blockpos)); + this.gm.player.sendQueue.addToSendQueue(new CPacketComplete(currentText, eid, blockpos)); this.waitingOnAutocomplete = true; } } diff --git a/client/src/client/gui/GuiConvert.java b/client/src/client/gui/GuiConvert.java index f45e633..e3e0a31 100755 --- a/client/src/client/gui/GuiConvert.java +++ b/client/src/client/gui/GuiConvert.java @@ -176,7 +176,7 @@ public class GuiConvert extends GuiList implements ActButto this.add(new ActButton(4, 4, 200, 24, new ActButton.Callback() { public void use(ActButton elem, ActButton.Mode action) { - if(GuiConvert.this.gm.theWorld != null) + if(GuiConvert.this.gm.world != null) return; GuiConvert.this.gm.showFileDialog(FileMode.DIRECTORY_LOAD, "Ordner wählen", GuiConvert.this.dir, new FileCallback() { public void selected(File file) { diff --git a/client/src/client/gui/GuiInfo.java b/client/src/client/gui/GuiInfo.java index eadf6dd..9b18880 100644 --- a/client/src/client/gui/GuiInfo.java +++ b/client/src/client/gui/GuiInfo.java @@ -125,7 +125,7 @@ public class GuiInfo extends Gui { } public void init(int width, int height) { - this.add(new TransparentBox(10, 10, width - 20, height - 44, this.info, this.gm.theWorld != null && !this.gm.charEditor)); + this.add(new TransparentBox(10, 10, width - 20, height - 44, this.info, this.gm.world != null && !this.gm.charEditor)); this.add(new NavButton(0, height - 24, width, 24, GuiMenu.INSTANCE, "Zurück")); } diff --git a/client/src/client/gui/GuiMenu.java b/client/src/client/gui/GuiMenu.java index 40002ad..17a9f4e 100644 --- a/client/src/client/gui/GuiMenu.java +++ b/client/src/client/gui/GuiMenu.java @@ -23,7 +23,7 @@ public class GuiMenu extends Gui { } public void drawMainBackground() { - if(this.gm.theWorld != null) + if(this.gm.world != null) super.drawMainBackground(); else this.gm.renderGlobal.renderStarField(this.gm.fb_x, this.gm.fb_y, 0x000000, 0xffffff, (float)this.ticks + (float)Timing.tick_fraction, this.rand); @@ -48,7 +48,7 @@ public class GuiMenu extends Gui { private boolean animStep; public void init(int width, int height) { - if(this.gm.theWorld == null) { + if(this.gm.world == null) { this.ticks = 0; this.hacked = 0; this.resetAnimation(); @@ -121,7 +121,7 @@ public class GuiMenu extends Gui { } public String getTitle() { - return this.gm.theWorld == null ? "Hauptmenü" : "Menü"; + return this.gm.world == null ? "Hauptmenü" : "Menü"; } private void pickSplash() { @@ -224,7 +224,7 @@ public class GuiMenu extends Gui { } public void updateScreen() { - if(this.gm.theWorld == null) { + if(this.gm.world == null) { this.ticks++; if(this.gm.shift() && !(this.selected instanceof Textbox)) this.pickSplash(); @@ -234,7 +234,7 @@ public class GuiMenu extends Gui { public void key(Keysym key, boolean ctrl, boolean shift) { super.key(key, ctrl, shift); - if(this.gm.theWorld == null) { + if(this.gm.world == null) { if((key == Keysym.UP || key == Keysym.W) && (this.hacked == 0 || this.hacked == 1)) this.hacked++; else if((key == Keysym.DOWN || key == Keysym.S) && (this.hacked == 2 || this.hacked == 3)) @@ -288,7 +288,7 @@ public class GuiMenu extends Gui { public void drawOverlays() { super.drawOverlays(); - if(this.gm.theWorld == null) { + if(this.gm.world == null) { int y = 164; int h = 16; int n = Drawing.getWidth(this.splashLabel.getText()); diff --git a/client/src/client/gui/GuiServer.java b/client/src/client/gui/GuiServer.java index ca80fa0..42dcdeb 100644 --- a/client/src/client/gui/GuiServer.java +++ b/client/src/client/gui/GuiServer.java @@ -74,7 +74,7 @@ public class GuiServer extends Gui implements Textbox.Callback { } private void connect() { - if(this.gm.theWorld != null) + if(this.gm.world != null) return; String name = null; if(this.server != null) { diff --git a/client/src/client/gui/character/GuiChar.java b/client/src/client/gui/character/GuiChar.java index 76daeb4..540c209 100755 --- a/client/src/client/gui/character/GuiChar.java +++ b/client/src/client/gui/character/GuiChar.java @@ -129,7 +129,7 @@ public class GuiChar extends GuiList EntityTexManager.altLayer = this.dynId; EntityTexManager.altNpcLayer = this.dynId == -1 && this.charinfo != null ? this.charinfo.skin : null; drawEntity(x + 32, y + 60, 28.0f - * Math.min(1.8f / GuiChar.this.gm.thePlayer.height, 1.5f / GuiChar.this.gm.thePlayer.width), -45.0f, -20.0f, GuiChar.this.gm.thePlayer); + * Math.min(1.8f / GuiChar.this.gm.player.height, 1.5f / GuiChar.this.gm.player.width), -45.0f, -20.0f, GuiChar.this.gm.player); GuiChar.this.gm.cameraUsed = flag; EntityTexManager.altTexture = null; EntityTexManager.altLayer = -1; @@ -271,8 +271,8 @@ public class GuiChar extends GuiList this.adjust = null; return; } - this.currentSkin = this.gm.thePlayer != null && !EntityTexManager.hasCustomSkin(this.gm.thePlayer.getId()) ? this.gm.thePlayer.getChar() : null; - this.load(this.gm.thePlayer == null ? ModelType.HUMANOID : this.gm.thePlayer.getModel(), this.gm.thePlayer != null ? this.gm.thePlayer.getSpecies() : SpeciesRegistry.CLASSES.get(EntityHuman.class)); + this.currentSkin = this.gm.player != null && !EntityTexManager.hasCustomSkin(this.gm.player.getId()) ? this.gm.player.getChar() : null; + this.load(this.gm.player == null ? ModelType.HUMANOID : this.gm.player.getModel(), this.gm.player != null ? this.gm.player.getSpecies() : SpeciesRegistry.CLASSES.get(EntityHuman.class)); this.add(new ActButton(4, 4, 194, 24, new ActButton.Callback() { public void use(ActButton elem, Mode action) { GuiChar.this.gm.showFileDialog(FileMode.FILE_LOAD_MULTI, "Skin konvertieren", TEXTURE_FOLDER, new FileCallback() { @@ -335,12 +335,12 @@ public class GuiChar extends GuiList }, "Vorlage kopieren")); this.adjust = this.add(new DragAdjust(width / 2 - 230, height - 64 - 640, 460, 640)); - this.add(new Label(width - 396, 36, 392, 20, "Spezies: " + (this.gm.thePlayer == null ? "" : this.gm.thePlayer.getSpecies().name), true)); + this.add(new Label(width - 396, 36, 392, 20, "Spezies: " + (this.gm.player == null ? "" : this.gm.player.getSpecies().name), true)); this.add(new NavButton(width - 396, 56, 392, 24, GuiSpecies.INSTANCE, "Spezies ändern")); - this.add(new Label(width - 396, 36 + 92, 392, 20, "Klasse: " + (this.gm.thePlayer == null || this.gm.thePlayer.getSpecies().classEnum == null || this.gm.thePlayer.getNpcClass() == null || this.gm.thePlayer.getNpcClass().toString().isEmpty() ? "" : this.gm.thePlayer.getNpcClass().toString()), true)) - .enabled = this.gm.thePlayer != null && this.gm.thePlayer.getSpecies().classEnum != null; + this.add(new Label(width - 396, 36 + 92, 392, 20, "Klasse: " + (this.gm.player == null || this.gm.player.getSpecies().classEnum == null || this.gm.player.getNpcClass() == null || this.gm.player.getNpcClass().toString().isEmpty() ? "" : this.gm.player.getNpcClass().toString()), true)) + .enabled = this.gm.player != null && this.gm.player.getSpecies().classEnum != null; this.add(new NavButton(width - 396, 56 + 92, 392, 24, GuiClass.INSTANCE, "Klasse ändern")) - .enabled = this.gm.thePlayer != null && this.gm.thePlayer.getSpecies().classEnum != null; + .enabled = this.gm.player != null && this.gm.player.getSpecies().classEnum != null; final ActButton[] alignBtns = new ActButton[Alignment.values().length]; for (int z = 0; z < Alignment.values().length; z++) @@ -348,25 +348,25 @@ public class GuiChar extends GuiList final Alignment align = Alignment.values()[z]; alignBtns[z] = this.add(new ActButton(width - 396 + (z % 3) * 132, height - 32 - 28 * 3 + 28 * (z / 3), 128, 24, new ActButton.Callback() { public void use(ActButton elem, Mode action) { - if(GuiChar.this.gm.thePlayer != null) { + if(GuiChar.this.gm.player != null) { GuiChar.this.waiting = false; - GuiChar.this.gm.thePlayer.sendQueue.addToSendQueue(new CPacketAction(CPacketAction.Action.SET_ALIGN, align.ordinal())); + GuiChar.this.gm.player.sendQueue.addToSendQueue(new CPacketAction(CPacketAction.Action.SET_ALIGN, align.ordinal())); for(ActButton btn : alignBtns) { btn.enabled = btn != elem; } } } }, align.color + align.display)); - alignBtns[z].enabled = this.gm.thePlayer == null || this.gm.thePlayer.getAlignment() != align; + alignBtns[z].enabled = this.gm.player == null || this.gm.player.getAlignment() != align; } - this.add(new Slider(width / 2 - 200, height - 28, 400, 24, 1, this.gm.thePlayer == null ? 120 : this.gm.thePlayer.getMinSize(), this.gm.thePlayer == null ? 320 : this.gm.thePlayer.getMaxSize(), this.gm.thePlayer == null ? 180 : this.gm.thePlayer.getDefaultSize(), this.gm.thePlayer == null ? 180 : this.gm.thePlayer.getCurrentSize(), new Slider.Callback() { + this.add(new Slider(width / 2 - 200, height - 28, 400, 24, 1, this.gm.player == null ? 120 : this.gm.player.getMinSize(), this.gm.player == null ? 320 : this.gm.player.getMaxSize(), this.gm.player == null ? 180 : this.gm.player.getDefaultSize(), this.gm.player == null ? 180 : this.gm.player.getCurrentSize(), new Slider.Callback() { public void use(Slider elem, int value) { - if(GuiChar.this.gm.thePlayer != null) { + if(GuiChar.this.gm.player != null) { GuiChar.this.waiting = false; - GuiChar.this.gm.thePlayer.sendQueue.addToSendQueue(new CPacketAction(CPacketAction.Action.SET_HEIGHT, value)); + GuiChar.this.gm.player.sendQueue.addToSendQueue(new CPacketAction(CPacketAction.Action.SET_HEIGHT, value)); } } - }, "Spieler-Größe", "cm")).enabled = this.gm.thePlayer == null || this.gm.thePlayer.getMinSize() != this.gm.thePlayer.getMaxSize(); + }, "Spieler-Größe", "cm")).enabled = this.gm.player == null || this.gm.player.getMinSize() != this.gm.player.getMaxSize(); this.add(new Label(width / 2 - 200, 36, 400, 20, "Name", true)); this.add(new Label(width - 396, height - 384, 392, 20, "Beschreibung", true)); final Textbox descField = this.add(new Textbox(width - 396, height - 364, 392, 130, IPlayer.MAX_INFO_LENGTH, new Textbox.Callback() { @@ -375,11 +375,11 @@ public class GuiChar extends GuiList }, "")); this.add(new ActButton(width - 198, height - 28, 194, 24, new ActButton.Callback() { public void use(ActButton elem, Mode action) { - if(GuiChar.this.gm.thePlayer != null) { + if(GuiChar.this.gm.player != null) { GuiChar.this.gm.displayGuiScreen(GuiLoading.makeWaitTask("Lade Welt ...")); Dimension dim = UniverseRegistry.getBaseDimensions().get(GuiChar.this.dimension); - GuiChar.this.gm.thePlayer.sendQueue.addToSendQueue(new CPacketMessage(CPacketMessage.Type.INFO, descField.getText())); - GuiChar.this.gm.thePlayer.sendQueue.addToSendQueue(new CPacketAction(CPacketAction.Action.CLOSE_EDITOR, dim.getDimensionId())); + GuiChar.this.gm.player.sendQueue.addToSendQueue(new CPacketMessage(CPacketMessage.Type.INFO, descField.getText())); + GuiChar.this.gm.player.sendQueue.addToSendQueue(new CPacketAction(CPacketAction.Action.CLOSE_EDITOR, dim.getDimensionId())); } } }, "Charakter erstellen")); @@ -388,17 +388,17 @@ public class GuiChar extends GuiList if(value == Action.SEND || value == Action.UNFOCUS) { String name = elem.getText(); if(name.isEmpty()) - elem.setText(GuiChar.this.gm.thePlayer == null ? "..." : GuiChar.this.gm.thePlayer.getCustomNameTag()); - else if(GuiChar.this.gm.thePlayer != null) { + elem.setText(GuiChar.this.gm.player == null ? "..." : GuiChar.this.gm.player.getCustomNameTag()); + else if(GuiChar.this.gm.player != null) { GuiChar.this.waiting = false; - GuiChar.this.gm.thePlayer.sendQueue.addToSendQueue(new CPacketMessage(CPacketMessage.Type.DISPLAY, name)); + GuiChar.this.gm.player.sendQueue.addToSendQueue(new CPacketMessage(CPacketMessage.Type.DISPLAY, name)); } } } - }, IPlayer.VALID_NICK, this.gm.thePlayer == null ? "" : this.gm.thePlayer.getCustomNameTag())); + }, IPlayer.VALID_NICK, this.gm.player == null ? "" : this.gm.player.getCustomNameTag())); this.templateButton.enabled = false; this.dimension = new Random().zrange(UniverseRegistry.getBaseDimensions().size()); - EntityEggInfo egg = EntityRegistry.SPAWN_EGGS.get(this.gm.thePlayer == null ? EntityRegistry.getEntityString(EntityHuman.class) : EntityRegistry.getEntityString(this.gm.thePlayer)); + EntityEggInfo egg = EntityRegistry.SPAWN_EGGS.get(this.gm.player == null ? EntityRegistry.getEntityString(EntityHuman.class) : EntityRegistry.getEntityString(this.gm.player)); if(egg != null && egg.origin != null) { Dimension dim = UniverseRegistry.getDimension(egg.origin); if(dim != null) { @@ -446,10 +446,10 @@ public class GuiChar extends GuiList public void drawOverlays() { if(this.adjust != null) { - float factor = this.gm.thePlayer.width > 2.15f ? 2.15f / this.gm.thePlayer.width : 1.0f; - factor = this.gm.thePlayer.height > 3.0f && 3.0f / this.gm.thePlayer.height < factor ? 3.0f / this.gm.thePlayer.height : factor; + float factor = this.gm.player.width > 2.15f ? 2.15f / this.gm.player.width : 1.0f; + factor = this.gm.player.height > 3.0f && 3.0f / this.gm.player.height < factor ? 3.0f / this.gm.player.height : factor; drawEntity(400 + (this.gm.fb_x - 400 - 400) / 2, this.gm.fb_y - 160, 160.0f * factor - , this.yaw, this.pitch, this.gm.thePlayer); + , this.yaw, this.pitch, this.gm.player); } } diff --git a/client/src/client/gui/character/GuiCharacters.java b/client/src/client/gui/character/GuiCharacters.java index cd94394..159e54f 100644 --- a/client/src/client/gui/character/GuiCharacters.java +++ b/client/src/client/gui/character/GuiCharacters.java @@ -73,7 +73,7 @@ public class GuiCharacters extends GuiList impleme if(this.gm.getNetHandler() != null) { int initialSelection = this.gm.getNetHandler().getSelectedCharacter(); for(PlayerCharacter character : this.gm.getNetHandler().getCharacterList()) { - this.elements.add(new CharacterEntry(initialSelection == this.elements.size() ? new PlayerCharacter(character.name, character.info, character.align, this.gm.thePlayer.worldObj.dimension.getFormattedName(false), this.gm.thePlayer.getPosition(), character.type, this.gm.thePlayer.experienceLevel) : character, initialSelection == this.elements.size())); + this.elements.add(new CharacterEntry(initialSelection == this.elements.size() ? new PlayerCharacter(character.name, character.info, character.align, this.gm.player.worldObj.dimension.getFormattedName(false), this.gm.player.getPosition(), character.type, this.gm.player.experienceLevel) : character, initialSelection == this.elements.size())); } this.elements.add(new CharacterEntry(null, false)); this.setSelected(initialSelection); diff --git a/client/src/client/gui/character/GuiClass.java b/client/src/client/gui/character/GuiClass.java index c1ca519..11a8805 100644 --- a/client/src/client/gui/character/GuiClass.java +++ b/client/src/client/gui/character/GuiClass.java @@ -21,14 +21,14 @@ public class GuiClass extends GuiList implements ActButton. public void draw(int x, int y, int mouseX, int mouseY, boolean hovered) { - if(GuiClass.this.gm.thePlayer != null && this.clazz == GuiClass.this.gm.thePlayer.getNpcClass()) + if(GuiClass.this.gm.player != null && this.clazz == GuiClass.this.gm.player.getNpcClass()) Drawing.drawRect(x, y, 1, 44, 0xffaf0000); Drawing.drawText(this.clazz.toString().isEmpty() ? "" : this.clazz.toString(), x + 3, y, 0xffffffff); } public void select(boolean dclick, int mx, int my) { - if((GuiClass.this.selectButton.enabled = GuiClass.this.gm.thePlayer == null || this.clazz != GuiClass.this.gm.thePlayer.getNpcClass()) && dclick) + if((GuiClass.this.selectButton.enabled = GuiClass.this.gm.player == null || this.clazz != GuiClass.this.gm.player.getNpcClass()) && dclick) GuiClass.this.use(GuiClass.this.selectButton, Mode.PRIMARY); } } @@ -45,8 +45,8 @@ public class GuiClass extends GuiList implements ActButton. super.init(width, height); this.setDimensions(400, height, 32, height - 32); this.elements.clear(); - if(this.gm.thePlayer != null && this.gm.thePlayer.getSpecies().classEnum != null) - for(Enum clazz : this.gm.thePlayer.getSpecies().classEnum.getEnumConstants()) { + if(this.gm.player != null && this.gm.player.getSpecies().classEnum != null) + for(Enum clazz : this.gm.player.getSpecies().classEnum.getEnumConstants()) { this.elements.add(new ClassEntry(clazz)); } this.add(new NavButton(width - 198 * 2, height - 28, 194, 24, GuiChar.INSTANCE, "Zurück")); @@ -69,8 +69,8 @@ public class GuiClass extends GuiList implements ActButton. public void use(ActButton elem, Mode action) { ClassEntry entry = this.getSelected(); - if(entry != null && GuiClass.this.gm.thePlayer != null) { - GuiClass.this.gm.thePlayer.sendQueue.addToSendQueue(new CPacketAction(CPacketAction.Action.SET_CLASS, entry.clazz.ordinal())); + if(entry != null && GuiClass.this.gm.player != null) { + GuiClass.this.gm.player.sendQueue.addToSendQueue(new CPacketAction(CPacketAction.Action.SET_CLASS, entry.clazz.ordinal())); this.gm.displayGuiScreen(GuiChar.INSTANCE); } } diff --git a/client/src/client/gui/character/GuiSpecies.java b/client/src/client/gui/character/GuiSpecies.java index af9b9bd..770d8a4 100644 --- a/client/src/client/gui/character/GuiSpecies.java +++ b/client/src/client/gui/character/GuiSpecies.java @@ -24,7 +24,7 @@ public class GuiSpecies extends GuiList implements ActB public void draw(int x, int y, int mouseX, int mouseY, boolean hovered) { - if(GuiSpecies.this.gm.thePlayer != null && this.species == GuiSpecies.this.gm.thePlayer.getSpecies()) + if(GuiSpecies.this.gm.player != null && this.species == GuiSpecies.this.gm.player.getSpecies()) Drawing.drawRect(x, y, 1, 44, 0xffaf0000); Drawing.drawText(this.species.name, x + 3, y, 0xff000000 | this.species.color1 | this.species.color2); if(this.species.classEnum != null) @@ -33,7 +33,7 @@ public class GuiSpecies extends GuiList implements ActB public void select(boolean dclick, int mx, int my) { - if((GuiSpecies.this.selectButton.enabled = GuiSpecies.this.gm.thePlayer == null || this.species != GuiSpecies.this.gm.thePlayer.getSpecies()) && dclick) + if((GuiSpecies.this.selectButton.enabled = GuiSpecies.this.gm.player == null || this.species != GuiSpecies.this.gm.player.getSpecies()) && dclick) GuiSpecies.this.use(GuiSpecies.this.selectButton, Mode.PRIMARY); } } @@ -73,7 +73,7 @@ public class GuiSpecies extends GuiList implements ActB public void use(ActButton elem, Mode action) { SpeciesEntry entry = this.getSelected(); - if(entry != null && GuiSpecies.this.gm.thePlayer != null) - GuiSpecies.this.gm.thePlayer.sendQueue.addToSendQueue(new CPacketAction(CPacketAction.Action.SET_SPECIES, EntityRegistry.getEntityID(entry.species.clazz))); + if(entry != null && GuiSpecies.this.gm.player != null) + GuiSpecies.this.gm.player.sendQueue.addToSendQueue(new CPacketAction(CPacketAction.Action.SET_SPECIES, EntityRegistry.getEntityID(entry.species.clazz))); } } diff --git a/client/src/client/gui/container/GuiChest.java b/client/src/client/gui/container/GuiChest.java index 85c444f..c9a56be 100755 --- a/client/src/client/gui/container/GuiChest.java +++ b/client/src/client/gui/container/GuiChest.java @@ -19,7 +19,7 @@ public class GuiChest extends GuiContainer public GuiChest(IInventory upperInv, IInventory lowerInv) { - super(new ContainerChest(upperInv, lowerInv, Client.CLIENT.thePlayer)); + super(new ContainerChest(upperInv, lowerInv, Client.CLIENT.player)); this.upperChestInventory = upperInv; this.lowerChestInventory = lowerInv; // this.allowUserInput = false; diff --git a/client/src/client/gui/container/GuiContainer.java b/client/src/client/gui/container/GuiContainer.java index 7f5051d..babe081 100755 --- a/client/src/client/gui/container/GuiContainer.java +++ b/client/src/client/gui/container/GuiContainer.java @@ -213,7 +213,7 @@ public abstract class GuiContainer extends Gui */ public void initGui() { - this.gm.thePlayer.openContainer = this.inventorySlots; + this.gm.player.openContainer = this.inventorySlots; // this.guiLeft = (this.width - this.xSize) / 2; // this.guiTop = (this.height - this.ySize) / 2; // this.addButtons(); @@ -360,7 +360,7 @@ public abstract class GuiContainer extends Gui ItemRenderer.disableStandardItemLighting(); // this.drawGuiContainerForegroundLayer(mouseX, mouseY); ItemRenderer.enableGUIStandardItemLighting(); - InventoryPlayer inventoryplayer = this.gm.thePlayer.inventory; + InventoryPlayer inventoryplayer = this.gm.player.inventory; ItemStack itemstack = this.draggedStack == null ? inventoryplayer.getItemStack() : this.draggedStack; if(this.gm.itemCheat) itemstack = itemstack == null ? this.cheatStack : itemstack; @@ -451,7 +451,7 @@ public abstract class GuiContainer extends Gui } protected void renderToolTip(ItemStack stack, int x, int y) { - List list = stack.getTooltip(this.gm.thePlayer); + List list = stack.getTooltip(this.gm.player); StringBuilder sb = new StringBuilder(); for(int i = 0; i < list.size(); ++i) { if(i != 0) @@ -512,7 +512,7 @@ public abstract class GuiContainer extends Gui ItemStack itemstack = slotIn.getStack(); boolean flag = false; boolean flag1 = slotIn == this.clickedSlot && this.draggedStack != null && !this.isRightMouseClick; - ItemStack itemstack1 = this.gm.thePlayer.inventory.getItemStack(); + ItemStack itemstack1 = this.gm.player.inventory.getItemStack(); String s = null; if (slotIn == this.clickedSlot && this.draggedStack != null && this.isRightMouseClick && itemstack != null) @@ -589,7 +589,7 @@ public abstract class GuiContainer extends Gui private void updateDragSplitting() { - ItemStack itemstack = this.gm.thePlayer.inventory.getItemStack(); + ItemStack itemstack = this.gm.player.inventory.getItemStack(); if (itemstack != null && this.dragSplitting) { @@ -643,8 +643,8 @@ public abstract class GuiContainer extends Gui return; if(this.cheatStack != null) { Slot slot = this.getSlotAtPosition(mouseX, mouseY); - if((mouseButton == 0 || mouseButton == 1) && slot != null && this.gm.thePlayer != null && slot.inventory == this.gm.thePlayer.inventory) - this.gm.thePlayer.sendQueue.addToSendQueue(new CPacketCheat(this.cheatStack, slot.getIndex(), mouseButton == 0 && this.cheatStack.stackSize > 1)); + if((mouseButton == 0 || mouseButton == 1) && slot != null && this.gm.player != null && slot.inventory == this.gm.player.inventory) + this.gm.player.sendQueue.addToSendQueue(new CPacketCheat(this.cheatStack, slot.getIndex(), mouseButton == 0 && this.cheatStack.stackSize > 1)); if(mouseButton != 1 && !this.gm.ctrl()) this.cheatStack = null; return; @@ -652,7 +652,7 @@ public abstract class GuiContainer extends Gui if((mouseButton == 0 || mouseButton == 1 || mouseButton == 2) && this.clickSide(mouseX, mouseY, -1, this.gm.shift() || mouseButton == 1, this.gm.ctrl() || mouseButton == 2)) return; if(mouseButton == 0) { - if(this.gm.itemCheat && this.gm.thePlayer != null && this.gm.thePlayer.inventory.getItemStack() == null) { + if(this.gm.itemCheat && this.gm.player != null && this.gm.player.inventory.getItemStack() == null) { for (CheatTab tab : CheatTab.values()) { if (this.isInsideTab(tab, mouseX, mouseY)) @@ -711,7 +711,7 @@ public abstract class GuiContainer extends Gui // else if (!this.dragSplitting) { - if (this.gm.thePlayer.inventory.getItemStack() == null) + if (this.gm.player.inventory.getItemStack() == null) { // if (mouseButton == this.gm.bindTertiary.getKeyCode() + 100) // { @@ -774,7 +774,7 @@ public abstract class GuiContainer extends Gui if(this.gm == null || this.cheatStack != null) return; Slot slot = this.getSlotAtPosition(mouseX, mouseY); - ItemStack itemstack = this.gm.thePlayer.inventory.getItemStack(); + ItemStack itemstack = this.gm.player.inventory.getItemStack(); // if (this.clickedSlot != null && this.gm.touchscreen) // { @@ -849,7 +849,7 @@ public abstract class GuiContainer extends Gui { for (Slot slot2 : this.inventorySlots.inventorySlots) { - if (slot2 != null && slot2.canTakeStack(this.gm.thePlayer) && slot2.getHasStack() && slot2.inventory == slot.inventory && Container.canAddItemToSlot(slot2, this.shiftClickedSlot, true)) + if (slot2 != null && slot2.canTakeStack(this.gm.player) && slot2.getHasStack() && slot2.inventory == slot.inventory && Container.canAddItemToSlot(slot2, this.shiftClickedSlot, true)) { this.handleMouseClick(slot2, slot2.slotNumber, state, 1); } @@ -935,7 +935,7 @@ public abstract class GuiContainer extends Gui this.handleMouseClick((Slot)null, -999, Container.getDragCode(2, this.dragSplittingLimit), 5); } - else if (this.gm.thePlayer.inventory.getItemStack() != null) + else if (this.gm.player.inventory.getItemStack() != null) { // if (state == this.gm.bindTertiary.getKeyCode() + 100) // { @@ -955,7 +955,7 @@ public abstract class GuiContainer extends Gui } } - if (this.gm.thePlayer.inventory.getItemStack() == null) + if (this.gm.player.inventory.getItemStack() == null) { this.lastClickTime = 0L; } @@ -994,11 +994,11 @@ public abstract class GuiContainer extends Gui slotId = slotIn.slotNumber; } - this.gm.controller.windowClick(this.inventorySlots.windowId, slotId, clickedButton, clickType, this.gm.thePlayer); + this.gm.controller.windowClick(this.inventorySlots.windowId, slotId, clickedButton, clickType, this.gm.player); } public void dropItem() { - if (this.gm != null && this.gm.thePlayer != null && this.theSlot != null && this.theSlot.getHasStack()) + if (this.gm != null && this.gm.player != null && this.theSlot != null && this.theSlot.getHasStack()) { // if (keyCode == this.gm.bindTertiary.getKeyCode()) // { @@ -1034,7 +1034,7 @@ public abstract class GuiContainer extends Gui */ public void useHotbar(int slot) { - if (!this.clickSide((this.gm.mouse_x - this.container_x) / 2, (this.gm.mouse_y - this.container_y) / 2, slot, this.gm.shift(), this.gm.ctrl()) && this.gm != null && this.gm.thePlayer != null && this.gm.thePlayer.inventory.getItemStack() == null && this.cheatStack == null && this.theSlot != null) + if (!this.clickSide((this.gm.mouse_x - this.container_x) / 2, (this.gm.mouse_y - this.container_y) / 2, slot, this.gm.shift(), this.gm.ctrl()) && this.gm != null && this.gm.player != null && this.gm.player.inventory.getItemStack() == null && this.cheatStack == null && this.theSlot != null) { // for (int i = 0; i < 9; ++i) // { @@ -1054,9 +1054,9 @@ public abstract class GuiContainer extends Gui */ public void onGuiClosed() { - if (this.gm != null && this.gm.thePlayer != null) + if (this.gm != null && this.gm.player != null) { - this.inventorySlots.onContainerClosed(this.gm.thePlayer); + this.inventorySlots.onContainerClosed(this.gm.player); } } @@ -1075,9 +1075,9 @@ public abstract class GuiContainer extends Gui { // super.updateScreen(); - if (this.gm != null && this.gm.thePlayer != null && (!this.gm.thePlayer.isEntityAlive() || this.gm.thePlayer.dead)) + if (this.gm != null && this.gm.player != null && (!this.gm.player.isEntityAlive() || this.gm.player.dead)) { - this.gm.thePlayer.closeScreen(); + this.gm.player.closeScreen(); } } @@ -1182,7 +1182,7 @@ public abstract class GuiContainer extends Gui } private boolean clickSide(int mouseX, int mouseY, int slot, boolean instant, boolean full) { - if(this.gm.itemCheat && this.isPointInRegion(this.xSize + 2, 0, 18 * 12, 18 * 9, mouseX, mouseY) && this.gm.thePlayer != null && this.gm.thePlayer.inventory.getItemStack() == null && this.cheatStack == null) { + if(this.gm.itemCheat && this.isPointInRegion(this.xSize + 2, 0, 18 * 12, 18 * 9, mouseX, mouseY) && this.gm.player != null && this.gm.player.inventory.getItemStack() == null && this.cheatStack == null) { int i = (ITEM_LIST.size() + 12 - 1) / 12 - 9; int j = (int)((double)(this.currentScroll * (float)i) + 0.5D); @@ -1197,7 +1197,7 @@ public abstract class GuiContainer extends Gui if(i1 >= 0 && i1 < ITEM_LIST.size()) { if(slot >= 0 || instant) { - this.gm.thePlayer.sendQueue.addToSendQueue(new CPacketCheat(ITEM_LIST.get(i1), slot, full)); + this.gm.player.sendQueue.addToSendQueue(new CPacketCheat(ITEM_LIST.get(i1), slot, full)); } else { this.cheatStack = ITEM_LIST.get(i1).copy(); diff --git a/client/src/client/gui/container/GuiEnchant.java b/client/src/client/gui/container/GuiEnchant.java index 5dce728..0b25ef3 100755 --- a/client/src/client/gui/container/GuiEnchant.java +++ b/client/src/client/gui/container/GuiEnchant.java @@ -70,7 +70,7 @@ public class GuiEnchant extends GuiContainer int l = mouseX - 60; int i1 = mouseY - (14 + 19 * k); - if (l >= 0 && i1 >= 0 && l < 108 && i1 < 19 && this.container.enchantItem(this.gm.thePlayer, k)) + if (l >= 0 && i1 >= 0 && l < 108 && i1 < 19 && this.container.enchantItem(this.gm.player, k)) { this.gm.controller.sendEnchantPacket(this.container.windowId, k); } @@ -107,7 +107,7 @@ public class GuiEnchant extends GuiContainer String s1 = "" + l1; int i2 = 6839882; - if (/* (k < l + 1 || */ this.gm.thePlayer.experienceLevel < l1) // && !this.gm.thePlayer.creative) + if (/* (k < l + 1 || */ this.gm.player.experienceLevel < l1) // && !this.gm.thePlayer.creative) { this.rect(i1, 14 + 19 * l, 108, 19, 0x400000); this.rect(i1 + 1, 15 + 19 * l, 16, 16, 0x200000); @@ -171,7 +171,7 @@ public class GuiEnchant extends GuiContainer // sb.append("\n"); // } - if (this.gm.thePlayer.experienceLevel < k) + if (this.gm.player.experienceLevel < k) { sb.append((sb.length() != 0 ? "\n" : "") + TextColor.RED + String.format("Erfahrungsstufe %d erforderlich", this.container.enchantLevels[j])); } diff --git a/client/src/client/gui/container/GuiHopper.java b/client/src/client/gui/container/GuiHopper.java index c76579f..c11362a 100755 --- a/client/src/client/gui/container/GuiHopper.java +++ b/client/src/client/gui/container/GuiHopper.java @@ -19,7 +19,7 @@ public class GuiHopper extends GuiContainer public GuiHopper(InventoryPlayer playerInv, IInventory hopperInv) { - super(new ContainerHopper(playerInv, hopperInv, Client.CLIENT.thePlayer)); + super(new ContainerHopper(playerInv, hopperInv, Client.CLIENT.player)); this.playerInventory = playerInv; this.hopperInventory = hopperInv; // this.allowUserInput = false; diff --git a/client/src/client/gui/container/GuiHorse.java b/client/src/client/gui/container/GuiHorse.java index dbb5ec9..ad5cf54 100755 --- a/client/src/client/gui/container/GuiHorse.java +++ b/client/src/client/gui/container/GuiHorse.java @@ -27,7 +27,7 @@ public class GuiHorse extends GuiContainer public GuiHorse(IInventory playerInv, IInventory horseInv, EntityHorse horse) { - super(new ContainerHorseInventory(playerInv, horseInv, horse, Client.CLIENT.thePlayer)); + super(new ContainerHorseInventory(playerInv, horseInv, horse, Client.CLIENT.player)); this.playerInventory = playerInv; this.horseInventory = horseInv; // this.horseEntity = horse; diff --git a/client/src/client/gui/container/GuiMachine.java b/client/src/client/gui/container/GuiMachine.java index 82ed33f..2467e18 100755 --- a/client/src/client/gui/container/GuiMachine.java +++ b/client/src/client/gui/container/GuiMachine.java @@ -16,7 +16,7 @@ public class GuiMachine extends GuiContainer public GuiMachine(InventoryPlayer player, IInventory inv, TileEntityMachine machine) { - super(new ContainerMachine(player, machine, inv, Client.CLIENT.thePlayer)); + super(new ContainerMachine(player, machine, inv, Client.CLIENT.player)); this.playerInv = player; this.machineInv = machine; // this.allowUserInput = false; diff --git a/client/src/client/gui/container/GuiRepair.java b/client/src/client/gui/container/GuiRepair.java index 8015977..2d7dfb7 100755 --- a/client/src/client/gui/container/GuiRepair.java +++ b/client/src/client/gui/container/GuiRepair.java @@ -21,7 +21,7 @@ public class GuiRepair extends GuiContainer implements ICrafting public GuiRepair(InventoryPlayer inventoryIn, World worldIn) { - super(new ContainerRepair(inventoryIn, worldIn, Client.CLIENT.thePlayer)); + super(new ContainerRepair(inventoryIn, worldIn, Client.CLIENT.player)); this.playerInventory = inventoryIn; this.anvil = (ContainerRepair)this.inventorySlots; } diff --git a/client/src/client/gui/ingame/GuiGameOver.java b/client/src/client/gui/ingame/GuiGameOver.java index 8b79563..d8ad0a9 100755 --- a/client/src/client/gui/ingame/GuiGameOver.java +++ b/client/src/client/gui/ingame/GuiGameOver.java @@ -18,10 +18,10 @@ public class GuiGameOver extends Gui { public void init(int width, int height) { this.timer = 0; this.add(new Label(0, 0, 200, 20, "Du bist gestorben!")); - this.add(new Label(0, 32, 200, 20, "Punktestand: " + TextColor.YELLOW + this.gm.thePlayer.experienceLevel)); + this.add(new Label(0, 32, 200, 20, "Punktestand: " + TextColor.YELLOW + this.gm.player.experienceLevel)); this.button = this.add(new ActButton(0, 100, 200, 24, new ActButton.Callback() { public void use(ActButton elem, Mode action) { - GuiGameOver.this.gm.thePlayer.respawnPlayer(); + GuiGameOver.this.gm.player.respawnPlayer(); GuiGameOver.this.gm.displayGuiScreen(null); } }, "Wiederbeleben")); diff --git a/client/src/client/network/ClientPlayer.java b/client/src/client/network/ClientPlayer.java index e30af14..e8d1e1f 100755 --- a/client/src/client/network/ClientPlayer.java +++ b/client/src/client/network/ClientPlayer.java @@ -202,7 +202,7 @@ public class ClientPlayer extends NetHandler implements IClientPlayer // this.gameController.gameSettings.difficulty = packetIn.getDifficulty(); this.gameController.loadWorld(this.clientWorldController, packetIn.getEntityType()); // this.gameController.thePlayer.dimension = this.clientWorldController.dimension.getDimensionId(); - this.gameController.thePlayer.setId(packetIn.getEntityId()); + this.gameController.player.setId(packetIn.getEntityId()); this.gameController.displayGuiScreen(this.gameController.charEditor ? GuiChar.INSTANCE : null); // this.currentServerMaxPlayers = packetIn.getMaxPlayers(); // this.gameController.controller.setCheat(packetIn.getCheat()); @@ -465,7 +465,7 @@ public class ClientPlayer extends NetHandler implements IClientPlayer { entity.getDataWatcher().updateWatchedObjectsFromList(packetIn.func_149376_c()); - if(entity == this.gameController.thePlayer && this.gameController.open instanceof GuiChar) + if(entity == this.gameController.player && this.gameController.open instanceof GuiChar) ((GuiChar)this.gameController.open).checkReopen(); } } @@ -481,7 +481,7 @@ public class ClientPlayer extends NetHandler implements IClientPlayer double z = (double)packetIn.getZ() / 32.0D; float yaw = packetIn.getYaw(); float pitch = packetIn.getPitch(); - EntityNPC player = (EntityNPC)EntityRegistry.createEntityByID(packetIn.getEntityType(), this.gameController.theWorld); // new EntityNPC(this.gameController.theWorld); // , /* this.getPlayerInfo( */ packetIn.getUser()); // ).getUser()); + EntityNPC player = (EntityNPC)EntityRegistry.createEntityByID(packetIn.getEntityType(), this.gameController.world); // new EntityNPC(this.gameController.theWorld); // , /* this.getPlayerInfo( */ packetIn.getUser()); // ).getUser()); player.setOtherPlayer(this.gameController); player.prevX = player.lastTickPosX = (double)(player.serverPosX = packetIn.getX()); player.prevY = player.lastTickPosY = (double)(player.serverPosY = packetIn.getY()); @@ -551,7 +551,7 @@ public class ClientPlayer extends NetHandler implements IClientPlayer if (packetIn.getHeldItemHotbarIndex() >= 0 && packetIn.getHeldItemHotbarIndex() < InventoryPlayer.getHotbarSize()) { - this.gameController.thePlayer.inventory.currentItem = packetIn.getHeldItemHotbarIndex(); + this.gameController.player.inventory.currentItem = packetIn.getHeldItemHotbarIndex(); } } @@ -620,7 +620,7 @@ public class ClientPlayer extends NetHandler implements IClientPlayer public void handlePlayerPosLook(SPacketPlayerPosLook packetIn) { NetHandler.checkThread(packetIn, this, this.gameController, this.clientWorldController); - EntityNPC entityplayer = this.gameController.thePlayer; + EntityNPC entityplayer = this.gameController.player; double d0 = packetIn.getX(); double d1 = packetIn.getY(); double d2 = packetIn.getZ(); @@ -669,9 +669,9 @@ public class ClientPlayer extends NetHandler implements IClientPlayer if (!this.doneLoadingTerrain) { - this.gameController.thePlayer.prevX = this.gameController.thePlayer.posX; - this.gameController.thePlayer.prevY = this.gameController.thePlayer.posY; - this.gameController.thePlayer.prevZ = this.gameController.thePlayer.posZ; + this.gameController.player.prevX = this.gameController.player.posX; + this.gameController.player.prevY = this.gameController.player.posY; + this.gameController.player.prevZ = this.gameController.player.posZ; this.doneLoadingTerrain = true; // this.gameController.displayGuiScreen(null); // if(this.travelSound) { @@ -769,7 +769,7 @@ public class ClientPlayer extends NetHandler implements IClientPlayer if (entitylivingbase == null) { - entitylivingbase = this.gameController.thePlayer; + entitylivingbase = this.gameController.player; } if (entity != null) @@ -907,7 +907,7 @@ public class ClientPlayer extends NetHandler implements IClientPlayer double d2 = (double)packetIn.getZ() / 32.0D; float f = (float)(packetIn.getYaw() * 360) / 256.0F; float f1 = (float)(packetIn.getPitch() * 360) / 256.0F; - EntityLiving entitylivingbase = (EntityLiving)EntityRegistry.createEntityByID(packetIn.getEntityType(), this.gameController.theWorld); + EntityLiving entitylivingbase = (EntityLiving)EntityRegistry.createEntityByID(packetIn.getEntityType(), this.gameController.world); entitylivingbase.serverPosX = packetIn.getX(); entitylivingbase.serverPosY = packetIn.getY(); entitylivingbase.serverPosZ = packetIn.getZ(); @@ -942,7 +942,7 @@ public class ClientPlayer extends NetHandler implements IClientPlayer { NetHandler.checkThread(packetIn, this, this.gameController, this.clientWorldController); // this.gameController.theWorld.getWorldInfo().setTime(packetIn.getTotalWorldTime()); - this.gameController.theWorld.setDayTime(packetIn.getWorldTime()); + this.gameController.world.setDayTime(packetIn.getWorldTime()); this.gameController.setTicked(packetIn.getServerinfo()); } @@ -968,9 +968,9 @@ public class ClientPlayer extends NetHandler implements IClientPlayer { // boolean flag = false; - if (packetIn.getEntityId() == this.gameController.thePlayer.getId()) + if (packetIn.getEntityId() == this.gameController.player.getId()) { - entity = this.gameController.thePlayer; + entity = this.gameController.player; if (entity1 instanceof EntityBoat) { @@ -1036,7 +1036,7 @@ public class ClientPlayer extends NetHandler implements IClientPlayer public void handleUpdateHealth(SPacketUpdateHealth packetIn) { NetHandler.checkThread(packetIn, this, this.gameController, this.clientWorldController); - this.gameController.thePlayer.setPlayerSPHealth(packetIn.getHealth()); + this.gameController.player.setPlayerSPHealth(packetIn.getHealth()); // this.gameController.thePlayer.getFoodStats().setFoodLevel(packetIn.getFoodLevel()); // this.gameController.thePlayer.getFoodStats().setFoodSaturationLevel(packetIn.getSaturationLevel()); } @@ -1044,7 +1044,7 @@ public class ClientPlayer extends NetHandler implements IClientPlayer public void handleSetExperience(SPacketSetExperience packetIn) { NetHandler.checkThread(packetIn, this, this.gameController, this.clientWorldController); - this.gameController.thePlayer.setXPStats(packetIn.getProgress(), packetIn.getTotalExperience(), packetIn.getLevel()); + this.gameController.player.setXPStats(packetIn.getProgress(), packetIn.getTotalExperience(), packetIn.getLevel()); } public void handleRespawn(SPacketRespawn packetIn) @@ -1080,11 +1080,11 @@ public class ClientPlayer extends NetHandler implements IClientPlayer public void handleExplosion(S27PacketExplosion packetIn) { NetHandler.checkThread(packetIn, this, this.gameController, this.clientWorldController); - Explosion explosion = new Explosion(this.gameController.theWorld, (Entity)null, packetIn.getX(), packetIn.getY(), packetIn.getZ(), packetIn.getStrength(), packetIn.getAffectedBlockPositions()); + Explosion explosion = new Explosion(this.gameController.world, (Entity)null, packetIn.getX(), packetIn.getY(), packetIn.getZ(), packetIn.getStrength(), packetIn.getAffectedBlockPositions()); explosion.doExplosionB(true, packetIn.hasAltSound()); - this.gameController.thePlayer.motionX += (double)packetIn.func_149149_c(); - this.gameController.thePlayer.motionY += (double)packetIn.func_149144_d(); - this.gameController.thePlayer.motionZ += (double)packetIn.func_149147_e(); + this.gameController.player.motionX += (double)packetIn.func_149149_c(); + this.gameController.player.motionY += (double)packetIn.func_149144_d(); + this.gameController.player.motionZ += (double)packetIn.func_149147_e(); } /** @@ -1094,7 +1094,7 @@ public class ClientPlayer extends NetHandler implements IClientPlayer public void handleOpenWindow(S2DPacketOpenWindow packetIn) { NetHandler.checkThread(packetIn, this, this.gameController, this.clientWorldController); - EntityNPC entityplayersp = this.gameController.thePlayer; + EntityNPC entityplayersp = this.gameController.player; if ("container".equals(packetIn.getGuiId())) { @@ -1128,7 +1128,7 @@ public class ClientPlayer extends NetHandler implements IClientPlayer { TileEntity machine = this.clientWorldController.getTileEntity(packetIn.getTilePos()); if(machine instanceof TileEntityMachine) - this.gameController.displayGuiScreen(new GuiMachine(this.gameController.thePlayer.inventory, containerlocalmenu, (TileEntityMachine)machine)); + this.gameController.displayGuiScreen(new GuiMachine(this.gameController.player.inventory, containerlocalmenu, (TileEntityMachine)machine)); } else { entityplayersp.displayGUIChest(containerlocalmenu); @@ -1143,7 +1143,7 @@ public class ClientPlayer extends NetHandler implements IClientPlayer public void handleSetSlot(S2FPacketSetSlot packetIn) { NetHandler.checkThread(packetIn, this, this.gameController, this.clientWorldController); - EntityNPC entityplayer = this.gameController.thePlayer; + EntityNPC entityplayer = this.gameController.player; if (packetIn.getWindowId() == -1) { @@ -1185,7 +1185,7 @@ public class ClientPlayer extends NetHandler implements IClientPlayer { NetHandler.checkThread(packetIn, this, this.gameController, this.clientWorldController); Container container = null; - EntityNPC entityplayer = this.gameController.thePlayer; + EntityNPC entityplayer = this.gameController.player; if (packetIn.getWindowId() == 0) { @@ -1208,7 +1208,7 @@ public class ClientPlayer extends NetHandler implements IClientPlayer public void handleWindowItems(S30PacketWindowItems packetIn) { NetHandler.checkThread(packetIn, this, this.gameController, this.clientWorldController); - EntityNPC entityplayer = this.gameController.thePlayer; + EntityNPC entityplayer = this.gameController.player; if (packetIn.func_148911_c() == 0) { @@ -1235,7 +1235,7 @@ public class ClientPlayer extends NetHandler implements IClientPlayer tileentity.setPos(packetIn.getSignPosition()); } - this.gameController.thePlayer.openEditSign((TileEntitySign)tileentity); + this.gameController.player.openEditSign((TileEntitySign)tileentity); } /** @@ -1246,9 +1246,9 @@ public class ClientPlayer extends NetHandler implements IClientPlayer NetHandler.checkThread(packetIn, this, this.gameController, this.clientWorldController); // boolean flag = false; - if (this.gameController.theWorld.isBlockLoaded(packetIn.getPos())) + if (this.gameController.world.isBlockLoaded(packetIn.getPos())) { - TileEntity tileentity = this.gameController.theWorld.getTileEntity(packetIn.getPos()); + TileEntity tileentity = this.gameController.world.getTileEntity(packetIn.getPos()); if (tileentity instanceof TileEntitySign) { @@ -1280,9 +1280,9 @@ public class ClientPlayer extends NetHandler implements IClientPlayer { NetHandler.checkThread(packetIn, this, this.gameController, this.clientWorldController); - if (this.gameController.theWorld.isBlockLoaded(packetIn.getPos())) + if (this.gameController.world.isBlockLoaded(packetIn.getPos())) { - TileEntity tileentity = this.gameController.theWorld.getTileEntity(packetIn.getPos()); + TileEntity tileentity = this.gameController.world.getTileEntity(packetIn.getPos()); // int i = packetIn.getTileEntityType(); if (tileentity != null && packetIn.isTileEntityType(tileentity)) // i == 1 && tileentity instanceof TileEntityMobSpawner || /* i == 2 && tileentity instanceof TileEntityCommandBlock || */ i == 3 && tileentity instanceof TileEntityBeacon || i == 4 && tileentity instanceof TileEntitySkull || /* i == 5 && tileentity instanceof TileEntityFlowerPot || */ i == 6 && tileentity instanceof TileEntityBanner || i == 7 && tileentity instanceof TileEntityMachine) @@ -1298,7 +1298,7 @@ public class ClientPlayer extends NetHandler implements IClientPlayer public void handleWindowProperty(S31PacketWindowProperty packetIn) { NetHandler.checkThread(packetIn, this, this.gameController, this.clientWorldController); - EntityNPC entityplayer = this.gameController.thePlayer; + EntityNPC entityplayer = this.gameController.player; if (entityplayer.openContainer != null && entityplayer.openContainer.windowId == packetIn.getWindowId()) { @@ -1335,7 +1335,7 @@ public class ClientPlayer extends NetHandler implements IClientPlayer public void handleBlockAction(SPacketBlockAction packetIn) { NetHandler.checkThread(packetIn, this, this.gameController, this.clientWorldController); - this.gameController.theWorld.addBlockEvent(packetIn.getBlockPosition(), packetIn.getBlockType(), packetIn.getData1(), packetIn.getData2()); + this.gameController.world.addBlockEvent(packetIn.getBlockPosition(), packetIn.getBlockType(), packetIn.getData1(), packetIn.getData2()); } /** @@ -1344,7 +1344,7 @@ public class ClientPlayer extends NetHandler implements IClientPlayer public void handleBlockBreakAnim(SPacketBlockBreakAnim packetIn) { NetHandler.checkThread(packetIn, this, this.gameController, this.clientWorldController); - this.gameController.theWorld.sendBlockBreakProgress(packetIn.getBreakerId(), packetIn.getPosition(), packetIn.getProgress()); + this.gameController.world.sendBlockBreakProgress(packetIn.getBreakerId(), packetIn.getPosition(), packetIn.getProgress()); } public void handleMapChunkBulk(SPacketMapChunkBulk packetIn) @@ -1403,7 +1403,7 @@ public class ClientPlayer extends NetHandler implements IClientPlayer // } // else // { - this.gameController.theWorld.playAuxSFX(packetIn.getSoundType(), packetIn.getSoundPos(), packetIn.getSoundData()); + this.gameController.world.playAuxSFX(packetIn.getSoundType(), packetIn.getSoundPos(), packetIn.getSoundData()); // } } @@ -1597,7 +1597,7 @@ public class ClientPlayer extends NetHandler implements IClientPlayer public void handlePlayerAbilities(S39PacketPlayerAbilities packetIn) { NetHandler.checkThread(packetIn, this, this.gameController, this.clientWorldController); - EntityNPC entityplayer = this.gameController.thePlayer; + EntityNPC entityplayer = this.gameController.player; entityplayer.flying = packetIn.isFlying(); entityplayer.noclip = packetIn.isNoclip(); // entityplayer.speed = packetIn.getSpeed(); @@ -1629,7 +1629,7 @@ public class ClientPlayer extends NetHandler implements IClientPlayer // else if(packetIn.getSoundName().startsWith("music#")) { // return; // } - this.gameController.theWorld.playSound(packetIn.getX(), packetIn.getY(), packetIn.getZ(), packetIn.getSound(), packetIn.getVolume()); + this.gameController.world.playSound(packetIn.getX(), packetIn.getY(), packetIn.getZ(), packetIn.getSound(), packetIn.getVolume()); } // public void handleDisplay(S48PacketDisplay packetIn) @@ -1901,7 +1901,7 @@ public class ClientPlayer extends NetHandler implements IClientPlayer int i = packetIn.getWindowId(); Gui gui = this.gameController.open; - if (gui != null && gui instanceof GuiMerchant && i == this.gameController.thePlayer.openContainer.windowId) + if (gui != null && gui instanceof GuiMerchant && i == this.gameController.player.openContainer.windowId) { // NpcMerchant imerchant = ((GuiMerchant)guiscreen).getMerchant(); MerchantRecipeList merchantrecipelist = packetIn.getTrades(); diff --git a/client/src/client/renderer/EntityRenderer.java b/client/src/client/renderer/EntityRenderer.java index 82efc10..d0b2f82 100755 --- a/client/src/client/renderer/EntityRenderer.java +++ b/client/src/client/renderer/EntityRenderer.java @@ -129,10 +129,10 @@ public class EntityRenderer { if (this.gm.getRenderViewEntity() == null) { - this.gm.setRenderViewEntity(this.gm.thePlayer); + this.gm.setRenderViewEntity(this.gm.player); } - float light = this.gm.theWorld.getLightBrightness(new BlockPos(this.gm.getRenderViewEntity())); + float light = this.gm.world.getLightBrightness(new BlockPos(this.gm.getRenderViewEntity())); // Log.info(String.format("%.3f", light)); float dist = (float)this.gm.renderDistance / 32.0F; float shift = light * (1.0F - dist) + dist; @@ -186,10 +186,10 @@ public class EntityRenderer { if (entity != null) { - if (this.gm.theWorld != null) + if (this.gm.world != null) { this.gm.setPointedEntity(null); - double max = this.gm.thePlayer != null ? this.gm.thePlayer.getReachDistance() : 5.0; + double max = this.gm.player != null ? this.gm.player.getReachDistance() : 5.0; this.gm.pointed = entity.rayTrace(max, partialTicks); double dist = max; Vec3 eye = entity.getPositionEyes(partialTicks); @@ -219,7 +219,7 @@ public class EntityRenderer { this.pointedEntity = null; Vec3 hit = null; float exp = 1.0F; - List list = this.gm.theWorld.getEntitiesInAABBexcluding(entity, entity.getEntityBoundingBox().addCoord(look.xCoord * max, look.yCoord * max, look.zCoord * max).expand((double)exp, (double)exp, (double)exp), new Predicate() + List list = this.gm.world.getEntitiesInAABBexcluding(entity, entity.getEntityBoundingBox().addCoord(look.xCoord * max, look.yCoord * max, look.zCoord * max).expand((double)exp, (double)exp, (double)exp), new Predicate() { public boolean test(Entity p_apply_1_) { @@ -502,7 +502,7 @@ public class EntityRenderer { f3 = f3 * 0.1F; f4 = f4 * 0.1F; f5 = f5 * 0.1F; - HitPosition movingobjectposition = this.gm.theWorld.rayTraceBlocks(new Vec3(d0 + (double)f3, d1 + (double)f4, d2 + (double)f5), new Vec3(d0 - d4 + (double)f3 + (double)f5, d1 - d6 + (double)f4, d2 - d5 + (double)f5)); + HitPosition movingobjectposition = this.gm.world.rayTraceBlocks(new Vec3(d0 + (double)f3, d1 + (double)f4, d2 + (double)f5), new Vec3(d0 - d4 + (double)f3 + (double)f5, d1 - d6 + (double)f4, d2 - d5 + (double)f5)); if (movingobjectposition != null) { @@ -749,7 +749,7 @@ public class EntityRenderer { { if (this.lightmapUpdateNeeded) { - WorldClient world = this.gm.theWorld; + WorldClient world = this.gm.world; if (world != null) { @@ -792,9 +792,9 @@ public class EntityRenderer { // f10 = 0.25F + f7 * 0.75F; // } - if (this.gm.thePlayer.hasEffect(Potion.NIGHT_VISION)) + if (this.gm.player.hasEffect(Potion.NIGHT_VISION)) { - float vis = this.getNightVisionBrightness(this.gm.thePlayer, partialTicks); + float vis = this.getNightVisionBrightness(this.gm.player, partialTicks); float mult = 1.0F / red; if (mult > 1.0F / green) @@ -926,7 +926,7 @@ public class EntityRenderer { if (this.gm.getRenderViewEntity() == null) { - this.gm.setRenderViewEntity(this.gm.thePlayer); + this.gm.setRenderViewEntity(this.gm.player); } this.getMouseOver(partialTicks); @@ -958,7 +958,7 @@ public class EntityRenderer { this.updateFogColor(partialTicks); GL11.glClear(16640); this.setupCameraTransform(partialTicks); - ActiveRenderInfo.updateRenderInfo(this.gm.thePlayer, this.gm.thirdPersonView == 2); + ActiveRenderInfo.updateRenderInfo(this.gm.player, this.gm.thirdPersonView == 2); Entity entity = this.gm.getRenderViewEntity(); double d0 = entity.lastTickPosX + (entity.posX - entity.lastTickPosX) * (double)partialTicks; double d1 = entity.lastTickPosY + (entity.posY - entity.lastTickPosY) * (double)partialTicks; @@ -981,14 +981,14 @@ public class EntityRenderer { this.setupFog(0, partialTicks); GlState.shadeModel(GL11.GL_SMOOTH); - if (entity.posY + (double)entity.getEyeHeight() < (double)this.gm.theWorld.dimension.getCloudHeight()) + if (entity.posY + (double)entity.getEyeHeight() < (double)this.gm.world.dimension.getCloudHeight()) { this.renderCloudsCheck(renderglobal, partialTicks); } this.setupFog(0, partialTicks); this.gm.getTextureManager().bindTexture(TextureMap.locationBlocksTexture); ItemRenderer.disableStandardItemLighting(); - renderglobal.setupTerrain(entity, (double)partialTicks, this.frameCount++, this.gm.thePlayer.noclip); + renderglobal.setupTerrain(entity, (double)partialTicks, this.frameCount++, this.gm.player.noclip); this.gm.renderGlobal.updateChunks(finishTimeNano); GL11.glMatrixMode(GL11.GL_MODELVIEW); GL11.glPushMatrix(); @@ -1073,7 +1073,7 @@ public class EntityRenderer { GlState.disableBlend(); GlState.disableFog(); - if (entity.posY + (double)entity.getEyeHeight() >= (double)this.gm.theWorld.dimension.getCloudHeight()) + if (entity.posY + (double)entity.getEyeHeight() >= (double)this.gm.world.dimension.getCloudHeight()) { this.renderCloudsCheck(renderglobal, partialTicks); } @@ -1096,7 +1096,7 @@ public class EntityRenderer { GL11.glPushMatrix(); this.setupFog(0, partialTicks); // renderGlobalIn.renderClouds(partialTicks); - if(this.gm.theWorld.dimension.getType().clouds) + if(this.gm.world.dimension.getType().clouds) renderGlobalIn.renderClouds(partialTicks); GlState.disableFog(); GL11.glPopMatrix(); @@ -1109,7 +1109,7 @@ public class EntityRenderer { private void addRainParticles() { - float f = this.gm.theWorld.getRainStrength(); + float f = this.gm.world.getRainStrength(); // if (this.gm.downfallSetting != 0) // { @@ -1120,7 +1120,7 @@ public class EntityRenderer { { this.random.setSeed((long)this.rendererUpdateCount * 312987231L); Entity entity = this.gm.getRenderViewEntity(); - World world = this.gm.theWorld; + World world = this.gm.world; BlockPos blockpos = new BlockPos(entity); int i = 10; double d0 = 0.0D; @@ -1166,7 +1166,7 @@ public class EntityRenderer { } } if(temp < 194.0f || this.random.chance(5)) - this.gm.theWorld.spawnParticle(temp >= 194.0f && this.random.chance(10) ? ParticleType.LAVA : ParticleType.SMOKE_NORMAL, (double)blockpos1.getX() + d3, (double)((float)blockpos1.getY() + 0.1F) - block.getBlockBoundsMinY(), (double)blockpos1.getZ() + d4, 0.0D, 0.0D, 0.0D); + this.gm.world.spawnParticle(temp >= 194.0f && this.random.chance(10) ? ParticleType.LAVA : ParticleType.SMOKE_NORMAL, (double)blockpos1.getX() + d3, (double)((float)blockpos1.getY() + 0.1F) - block.getBlockBoundsMinY(), (double)blockpos1.getZ() + d4, 0.0D, 0.0D, 0.0D); } else if (block.getMaterial() != Material.air) { @@ -1180,7 +1180,7 @@ public class EntityRenderer { d2 = (double)blockpos2.getZ() + d4; } - this.gm.theWorld.spawnParticle(temp <= 5.0f ? ParticleType.HAIL_CORN : ParticleType.WATER_DROP, (double)blockpos2.getX() + d3, (double)((float)blockpos2.getY() + 0.1F) + block.getBlockBoundsMaxY(), (double)blockpos2.getZ() + d4, 0.0D, 0.0D, 0.0D); + this.gm.world.spawnParticle(temp <= 5.0f ? ParticleType.HAIL_CORN : ParticleType.WATER_DROP, (double)blockpos2.getX() + d3, (double)((float)blockpos2.getY() + 0.1F) + block.getBlockBoundsMaxY(), (double)blockpos2.getZ() + d4, 0.0D, 0.0D, 0.0D); } } } @@ -1191,11 +1191,11 @@ public class EntityRenderer { if (d1 > (double)(blockpos.getY() + 1) && world.getPrecipitationHeight(blockpos).getY() > ExtMath.floorf((float)blockpos.getY())) { - this.gm.theWorld.playSound(d0, d1, d2, n >= j ? this.pickMoltenSound() : SoundEvent.RAIN, n >= j ? 0.2f : 0.1F); + this.gm.world.playSound(d0, d1, d2, n >= j ? this.pickMoltenSound() : SoundEvent.RAIN, n >= j ? 0.2f : 0.1F); } else { - this.gm.theWorld.playSound(d0, d1, d2, n >= j ? this.pickMoltenSound() : SoundEvent.RAIN, n >= j ? 0.4f : 0.2F); + this.gm.world.playSound(d0, d1, d2, n >= j ? this.pickMoltenSound() : SoundEvent.RAIN, n >= j ? 0.4f : 0.2F); } } } @@ -1210,13 +1210,13 @@ public class EntityRenderer { */ protected void renderRainSnow(float partialTicks) { - float f = this.gm.theWorld.getRainStrength(); + float f = this.gm.world.getRainStrength(); if (f > 0.0F) // && this.gm.downfallSetting < 2) { this.enableLightmap(); Entity entity = this.gm.getRenderViewEntity(); - World world = this.gm.theWorld; + World world = this.gm.world; int i = ExtMath.floord(entity.posX); int j = ExtMath.floord(entity.posY); int k = ExtMath.floord(entity.posZ); @@ -1411,7 +1411,7 @@ public class EntityRenderer { */ private void updateFogColor(float partial) { - WorldClient world = this.gm.theWorld; + WorldClient world = this.gm.world; Entity entity = this.gm.getRenderViewEntity(); float dist = 0.25F + 0.75F * (float)this.gm.renderDistance / 32.0F; dist = 1.0F - (float)Math.pow((double)dist, 0.25D); @@ -1473,7 +1473,7 @@ public class EntityRenderer { this.fogColorBlue *= mul; } - Block block = ActiveRenderInfo.getBlockAtEntityViewpoint(this.gm.theWorld, entity, partial); + Block block = ActiveRenderInfo.getBlockAtEntityViewpoint(this.gm.world, entity, partial); // if (this.cloudFog) // { @@ -1586,7 +1586,7 @@ public class EntityRenderer { private void setupFog(int start, float partial) { Entity entity = this.gm.getRenderViewEntity(); - float fog = this.gm.theWorld.getFogStrength(); + float fog = this.gm.world.getFogStrength(); float distance = Math.min(0.995f, Math.max(0.005f, FOG_DISTANCE - (0.3f * fog))); float density = 1.0f - Math.min(1.0f, FOG_DENSITY * (1.0f - fog * 0.1f)); // boolean flag = false; @@ -1599,7 +1599,7 @@ public class EntityRenderer { GL11.glFogfv(GL11.GL_FOG_COLOR, (FloatBuffer)this.setFogColorBuffer(this.fogColorRed, this.fogColorGreen, this.fogColorBlue, 1.0F)); GL11.glNormal3f(0.0F, -1.0F, 0.0F); GlState.color(1.0F, 1.0F, 1.0F, 1.0F); - Block block = ActiveRenderInfo.getBlockAtEntityViewpoint(this.gm.theWorld, entity, partial); + Block block = ActiveRenderInfo.getBlockAtEntityViewpoint(this.gm.world, entity, partial); if(distance >= 1.0f) { ; @@ -1676,7 +1676,7 @@ public class EntityRenderer { // SKC.glFogi(NVFogDistance.GL_FOG_DISTANCE_MODE_NV, NVFogDistance.GL_EYE_RADIAL_NV); // } - if (this.gm.theWorld.dimension.hasDenseFog()) + if (this.gm.world.dimension.hasDenseFog()) { GlState.setFogStart(far * ((distance / 0.75f) * 0.05F)); GlState.setFogEnd(Math.min(far, 192.0F) * Math.max(density * (distance / 0.75f), (distance / 0.75f) * 0.05F + 0.01f)); diff --git a/client/src/client/renderer/ItemRenderer.java b/client/src/client/renderer/ItemRenderer.java index eff32d6..0c310a6 100755 --- a/client/src/client/renderer/ItemRenderer.java +++ b/client/src/client/renderer/ItemRenderer.java @@ -163,7 +163,7 @@ public class ItemRenderer */ private void setLightMapFromPlayer(EntityNPC clientPlayer) { - int i = this.gm.theWorld.getCombinedLight(new BlockPos(clientPlayer.posX, clientPlayer.posY + (double)clientPlayer.getEyeHeight(), clientPlayer.posZ), 0); + int i = this.gm.world.getCombinedLight(new BlockPos(clientPlayer.posX, clientPlayer.posY + (double)clientPlayer.getEyeHeight(), clientPlayer.posZ), 0); float f = (float)(i & 65535); float f1 = (float)(i >> 16); GL13.glMultiTexCoord2f(GL13.GL_TEXTURE1, f, f1); @@ -299,9 +299,9 @@ public class ItemRenderer GL11.glRotatef(-135.0F, 0.0F, 1.0F, 0.0F); GL11.glScalef(1.0F, 1.0F, 1.0F); GL11.glTranslatef(5.6F, 0.0F, 0.0F); - RenderNpc render = this.renderManager.getRenderObject(this.gm.thePlayer.getModel()); + RenderNpc render = this.renderManager.getRenderObject(this.gm.player.getModel()); GlState.disableCull(); - render.renderPlayerArm(this.gm.thePlayer); + render.renderPlayerArm(this.gm.player); GlState.enableCull(); } @@ -407,7 +407,7 @@ public class ItemRenderer public void renderItemInFirstPerson(float partialTicks) { float f = 1.0F - (this.prevEquippedProgress + (this.equippedProgress - this.prevEquippedProgress) * partialTicks); - EntityNPC clientplayer = this.gm.thePlayer; + EntityNPC clientplayer = this.gm.player; float f1 = clientplayer.getSwingProgress(partialTicks); float f2 = clientplayer.prevPitch + (clientplayer.rotPitch - clientplayer.prevPitch) * partialTicks; float f3 = clientplayer.prevYaw + (clientplayer.rotYaw - clientplayer.prevYaw) * partialTicks; @@ -475,10 +475,10 @@ public class ItemRenderer { GlState.disableAlpha(); - if (this.gm.thePlayer.isEntityInsideOpaqueBlock()) + if (this.gm.player.isEntityInsideOpaqueBlock()) { - State iblockstate = this.gm.theWorld.getState(new BlockPos(this.gm.thePlayer)); - EntityNPC entityplayer = this.gm.thePlayer; + State iblockstate = this.gm.world.getState(new BlockPos(this.gm.player)); + EntityNPC entityplayer = this.gm.player; for (int i = 0; i < 8; ++i) { @@ -486,7 +486,7 @@ public class ItemRenderer double d1 = entityplayer.posY + (double)(((float)((i >> 1) % 2) - 0.5F) * 0.1F); double d2 = entityplayer.posZ + (double)(((float)((i >> 2) % 2) - 0.5F) * entityplayer.width * 0.8F); BlockPos blockpos = new BlockPos(d0, d1 + (double)entityplayer.getEyeHeight(), d2); - State iblockstate1 = this.gm.theWorld.getState(blockpos); + State iblockstate1 = this.gm.world.getState(blockpos); if (iblockstate1.getBlock().isVisuallyOpaque()) { @@ -500,7 +500,7 @@ public class ItemRenderer } } - if(this.gm.thePlayer.isBurning()) { + if(this.gm.player.isBurning()) { this.renderFireInFirstPerson(partialTicks); } @@ -590,7 +590,7 @@ public class ItemRenderer public void updateEquippedItem() { this.prevEquippedProgress = this.equippedProgress; - EntityNPC entityplayer = this.gm.thePlayer; + EntityNPC entityplayer = this.gm.player; ItemStack itemstack = entityplayer.inventory.getCurrentItem(); boolean flag = false; diff --git a/client/src/client/renderer/RenderGlobal.java b/client/src/client/renderer/RenderGlobal.java index 06c89ad..03a90a9 100755 --- a/client/src/client/renderer/RenderGlobal.java +++ b/client/src/client/renderer/RenderGlobal.java @@ -560,7 +560,7 @@ public class RenderGlobal GlState.enableAlpha(); } - if (this.gm.renderOutlines && this.gm.thePlayer != null) + if (this.gm.renderOutlines && this.gm.player != null) { GlState.depthFunc(GL11.GL_ALWAYS); GlState.disableFog(); @@ -575,7 +575,7 @@ public class RenderGlobal { Entity entity3 = list.get(j); if ((entity3 != this.gm.getRenderViewEntity() || this.gm.thirdPersonView != 0) && - entity3 instanceof EntityLiving && entity3.isInRangeToRender3d(d0, d1, d2) && (entity3.noFrustumCheck || Frustum.isInFrustum(entity3.getEntityBoundingBox()) || entity3.passenger == this.gm.thePlayer)) + entity3 instanceof EntityLiving && entity3.isInRangeToRender3d(d0, d1, d2) && (entity3.noFrustumCheck || Frustum.isInFrustum(entity3.getEntityBoundingBox()) || entity3.passenger == this.gm.player)) { // this.renderManager.renderEntity(entity3, partialTicks); int c = ((EntityLiving)entity3).getColor(); @@ -623,7 +623,7 @@ public class RenderGlobal } entity2 = (Entity)iterator.next(); - flag2 = this.renderManager.shouldRender(entity2, d0, d1, d2) || entity2.passenger == this.gm.thePlayer; + flag2 = this.renderManager.shouldRender(entity2, d0, d1, d2) || entity2.passenger == this.gm.player; if (!flag2) { @@ -1125,11 +1125,11 @@ public class RenderGlobal public void renderSky(float partialTicks) { - if (this.gm.theWorld.dimension.getSkyBoxTexture() != null) + if (this.gm.world.dimension.getSkyBoxTexture() != null) { - this.renderSkyBox(this.gm.theWorld.dimension.getSkyBoxTexture()); + this.renderSkyBox(this.gm.world.dimension.getSkyBoxTexture()); } - else if (this.gm.theWorld.dimension.getType().sky) + else if (this.gm.world.dimension.getType().sky) { GlState.disableTexture2D(); Vec3 vec3 = this.theWorld.getSkyColor(this.gm.getRenderViewEntity(), partialTicks); @@ -1223,7 +1223,7 @@ public class RenderGlobal GlState.color(1.0F, 1.0F, 1.0F, f16); GL11.glRotatef(-90.0F, 0.0F, 1.0F, 0.0F); GL11.glRotatef(this.theWorld.getCelestialAngle(partialTicks) * 360.0F, 1.0F, 0.0F, 0.0F); - if(this.gm.theWorld.dimension.getType().sun) { + if(this.gm.world.dimension.getType().sun) { float size = 30.0F; this.renderEngine.bindTexture(SUN_TEX); worldrenderer.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX); @@ -1233,7 +1233,7 @@ public class RenderGlobal worldrenderer.pos((double)(-size), 100.0D, (double)size).tex(0.0D, 1.0D).endVertex(); Tessellator.draw(); } - if(this.gm.theWorld.dimension.getType().moon) { + if(this.gm.world.dimension.getType().moon) { float size = 20.0F; this.renderEngine.bindTexture(MOON_TEX); int i = this.theWorld.getMoonPhase(); @@ -1332,7 +1332,7 @@ public class RenderGlobal int j = ExtMath.floord(d2 / 2048.0D); d1 = d1 - (double)(i * 2048); d2 = d2 - (double)(j * 2048); - this.renderEngine.bindTexture(this.gm.theWorld.dimension.getCloudTexture()); + this.renderEngine.bindTexture(this.gm.world.dimension.getCloudTexture()); GlState.enableBlend(); GlState.tryBlendFuncSeparate(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA, GL11.GL_ONE, GL11.GL_ZERO); Vec3 vec3 = this.theWorld.getCloudColour(this.gm.getRenderViewEntity(), partialTicks); diff --git a/client/src/client/renderer/entity/RenderFish.java b/client/src/client/renderer/entity/RenderFish.java index 4bac934..6782994 100755 --- a/client/src/client/renderer/entity/RenderFish.java +++ b/client/src/client/renderer/entity/RenderFish.java @@ -65,7 +65,7 @@ public class RenderFish extends Render double d2 = entity.angler.prevZ + (entity.angler.posZ - entity.angler.prevZ) * (double)partialTicks + vec3.zCoord; double d3 = (double)entity.angler.getEyeHeight(); - if (this.renderManager.gm != null && this.renderManager.gm.thirdPersonView > 0 || entity.angler != Client.CLIENT.thePlayer) + if (this.renderManager.gm != null && this.renderManager.gm.thirdPersonView > 0 || entity.angler != Client.CLIENT.player) { float f9 = (entity.angler.prevYawOffset + (entity.angler.yawOffset - entity.angler.prevYawOffset) * partialTicks) * (float)Math.PI / 180.0F; double d4 = (double)ExtMath.sin(f9); diff --git a/client/src/client/renderer/entity/RenderHumanoid.java b/client/src/client/renderer/entity/RenderHumanoid.java index 04e767e..42660a5 100755 --- a/client/src/client/renderer/entity/RenderHumanoid.java +++ b/client/src/client/renderer/entity/RenderHumanoid.java @@ -69,12 +69,12 @@ public class RenderHumanoid extends RenderNpc public void doRender(EntityNPC entity, double x, double y, double z, float partialTicks) { - if (entity != this.renderManager.gm.thePlayer || this.renderManager.livingPlayer == entity) + if (entity != this.renderManager.gm.player || this.renderManager.livingPlayer == entity) { // if(entity.isBoss()) // BossStatus.setBossStatus(entity); double d0 = y; - if(/* this.canSneak() && */ entity.isSneakingVisually() && entity != this.renderManager.gm.thePlayer) + if(/* this.canSneak() && */ entity.isSneakingVisually() && entity != this.renderManager.gm.player) d0 = y - 0.125D; this.setModelVisibilities(entity); super.doRender(entity, x, d0, z, partialTicks); diff --git a/common/src/common/log/Log.java b/common/src/common/log/Log.java index c6deea4..04aa56c 100644 --- a/common/src/common/log/Log.java +++ b/common/src/common/log/Log.java @@ -44,6 +44,7 @@ public enum Log { private static final List LOG = Lists.newArrayList(); private static LogLevel level = LogLevel.INFO; + private static boolean colors = true; private static IThreadListener sync = new IThreadListener() { public ListenableFuture schedule(Runnable run) { return null; @@ -71,14 +72,16 @@ public enum Log { if(pos - last != 0) System.err.print(str.substring(last, pos)); color = TextColor.getColor(c); // (c >= CHR_COLORS2) && (c <= CHR_COLORE2) ? aux_colors[c - CHR_COLORS2] : text_colors[c - CHR_COLORS1]; - System.err.printf("\u001b[38;2;%d;%d;%dm", (color >> 16) & 0xff, (color >> 8) & 0xff, color & 0xff); + if(colors) + System.err.printf("\u001b[38;2;%d;%d;%dm", (color >> 16) & 0xff, (color >> 8) & 0xff, color & 0xff); last = ++pos; continue; } else if(c == CHR_CRESET) { if(pos - last != 0) System.err.print(str.substring(last, pos)); - System.err.print("\u001b[0m"); + if(colors) + System.err.print("\u001b[0m"); last = ++pos; continue; } @@ -99,7 +102,7 @@ public enum Log { if(pos >= str.length() && pos - last != 0) System.err.print(str.substring(last, pos)); } - System.err.print("\u001b[0m\n"); + System.err.print(colors ? "\u001b[0m\n" : "\n"); } public static String str_time(long time) { @@ -112,6 +115,7 @@ public enum Log { public static void init(IThreadListener sync) { Log.sync = sync; + Log.colors = System.getProperty("log.nocolor") == null && !Util.WINDOWS; } public static void flushLog() { diff --git a/common/src/common/util/Util.java b/common/src/common/util/Util.java index e66fb25..fe4734b 100644 --- a/common/src/common/util/Util.java +++ b/common/src/common/util/Util.java @@ -12,7 +12,8 @@ import common.collect.Maps; import common.log.Log; public abstract class Util { - private static long start = getTime(); + public static final boolean WINDOWS = System.getProperty("os.name").startsWith("Windows"); + private static final long START = getTime(); public static String strip(String str, int offset, int len, char newl, char tab, char unk) { StringBuilder sb = new StringBuilder(); @@ -303,10 +304,10 @@ int utf_len(const char *str) { } public static void checkOs() { - if(System.getProperty("os.name").startsWith("Windows") || System.getProperty("os.name").startsWith("Mac")) { + if(System.getProperty("os.name").startsWith("Mac")) { String info = "Inkompatibles Betriebssystem"; - String msg = "Linux oder *BSD ist erforderlich, um dieses Programm auszuführen.\n" + - "Alle Versionen von Windows und Mac OS (X) sind nicht kompatibel."; + String msg = "Linux, *BSD oder Windows ist erforderlich, um dieses Programm\n" + + "auszuführen. Alle Versionen von Mac OS (X) sind nicht kompatibel."; System.err.println("#################################################################"); System.err.println("*** " + info + " ***"); System.err.println(msg); @@ -382,7 +383,7 @@ int utf_len(const char *str) { } public static long rtime() { - return Util.getTime() - start; + return Util.getTime() - START; } public static double ftime() { From 02c0bfcbf615300854d109206c7fdb5200abb44b Mon Sep 17 00:00:00 2001 From: Sen Date: Sat, 10 May 2025 00:02:02 +0200 Subject: [PATCH 015/200] split entity ai to server #1 --- common/src/common/ai/IEntityNode.java | 17 + common/src/common/entity/Entity.java | 8 - .../src/common/entity/animal/EntityHorse.java | 8 - .../common/entity/npc/EntityArachnoid.java | 5 - .../src/common/entity/npc/EntityHaunter.java | 5 - common/src/common/entity/npc/EntityNPC.java | 211 +-------- .../src/common/entity/types/EntityLiving.java | 424 +---------------- .../pathfinding/PathNavigateGround.java | 2 +- server/src/server/ai/EntityNPCNode.java | 224 +++++++++ server/src/server/ai/EntityNode.java | 436 ++++++++++++++++++ 10 files changed, 706 insertions(+), 634 deletions(-) create mode 100644 common/src/common/ai/IEntityNode.java create mode 100644 server/src/server/ai/EntityNPCNode.java create mode 100644 server/src/server/ai/EntityNode.java diff --git a/common/src/common/ai/IEntityNode.java b/common/src/common/ai/IEntityNode.java new file mode 100644 index 0000000..d4d89ee --- /dev/null +++ b/common/src/common/ai/IEntityNode.java @@ -0,0 +1,17 @@ +package common.ai; + +import common.entity.DamageSource; +import common.entity.types.EntityLiving; +import common.nbt.NBTTagCompound; + +public interface IEntityNode { + void update(); + void updateRenderAngles(); + void updateLeashedState(); + void setLeashTag(NBTTagCompound tag); + EntityLiving getAttacking(); + EntityLiving getAttackTarget(); + void resetCombat(); + void trackDamage(DamageSource source, int amount); + void sendDeathMessage(); +} diff --git a/common/src/common/entity/Entity.java b/common/src/common/entity/Entity.java index b142d3d..61d7871 100755 --- a/common/src/common/entity/Entity.java +++ b/common/src/common/entity/Entity.java @@ -2428,14 +2428,6 @@ public abstract class Entity return true; } - /** - * The maximum height from where the entity is alowed to jump (used in pathfinder) - */ - public int getMaxFallHeight() - { - return 3; - } - // public Vec3 getLastPortal() // { // return this.portalVec != null ? this.portalVec : new Vec3(0.0d, 0.0d, 0.0d); diff --git a/common/src/common/entity/animal/EntityHorse.java b/common/src/common/entity/animal/EntityHorse.java index ed9d625..66cb983 100755 --- a/common/src/common/entity/animal/EntityHorse.java +++ b/common/src/common/entity/animal/EntityHorse.java @@ -258,14 +258,6 @@ public class EntityHorse extends EntityAnimal implements IInvBasic return !this.isUndead() && super.allowLeashing(); } - protected void onUpdateLeashed(float distance) - { - if (distance > 6.0F && this.isEatingHaystack()) - { - this.setEatingHaystack(false); - } - } - public boolean isChested() { return this.getHorseWatchableBoolean(8); diff --git a/common/src/common/entity/npc/EntityArachnoid.java b/common/src/common/entity/npc/EntityArachnoid.java index becd804..0fcd081 100755 --- a/common/src/common/entity/npc/EntityArachnoid.java +++ b/common/src/common/entity/npc/EntityArachnoid.java @@ -35,11 +35,6 @@ public class EntityArachnoid extends EntityNPC // return 0.9375f * this.height / 1.6f; // } - protected PathNavigate getNewNavigator(World worldIn) - { - return new PathNavigateClimber(this, worldIn); - } - protected void entityInit() { super.entityInit(); diff --git a/common/src/common/entity/npc/EntityHaunter.java b/common/src/common/entity/npc/EntityHaunter.java index 4f1e389..ca79e08 100755 --- a/common/src/common/entity/npc/EntityHaunter.java +++ b/common/src/common/entity/npc/EntityHaunter.java @@ -30,11 +30,6 @@ public class EntityHaunter extends EntityNPC { super.applyEntityAttributes(); this.getEntityAttribute(Attributes.MOVEMENT_SPEED).setBaseValue(0.25D); } - - public int getMaxFallHeight() - { - return this.getAttackTarget() == null ? 3 : 3 + (this.getHealth() - 1); - } public void fall(float distance, float damageMultiplier) { diff --git a/common/src/common/entity/npc/EntityNPC.java b/common/src/common/entity/npc/EntityNPC.java index f261a8b..ffd5e7b 100755 --- a/common/src/common/entity/npc/EntityNPC.java +++ b/common/src/common/entity/npc/EntityNPC.java @@ -133,47 +133,11 @@ public abstract class EntityNPC extends EntityLiving // public static String getSpeciesName(String character) { // return (character.substring(0, 1).toUpperCase() + character.substring(1)).replace('_', ' ').replaceAll("( [a-z])", "$1"); // } - - protected final EntityAIAttackOnCollide aiMelee = new EntityAIAttackOnCollide(this, EntityLiving.class, 1.0D, true, true) { - public boolean shouldExecute() - { - return !EntityNPC.this.fleeing && super.shouldExecute(); - } - - public boolean continueExecuting() - { - return !EntityNPC.this.fleeing && super.shouldExecute(); - } - }; - protected final AIRangedAttack aiRanged = new AIRangedAttack(this, 1.0D, this.getAttackSpeed(), this.getAttackSpeed() * 3, 15.0F) { -// public void startExecuting() -// { -// super.startExecuting(); -// EntityNPC.this.setUsingItem(true); -// } -// -// public void resetTask() -// { -// super.resetTask(); -// EntityNPC.this.setUsingItem(false); -// } - - public boolean shouldExecute() - { - return !EntityNPC.this.fleeing && super.shouldExecute(); - } - - public boolean continueExecuting() - { - return !EntityNPC.this.fleeing && super.shouldExecute(); - } - }; protected final SpeciesInfo species; private EntityNPC talkingPlayer; private boolean isWilling; - private boolean fleeing; private boolean playing; protected boolean noPickup; private ItemStack[] equipment = new ItemStack[5]; @@ -255,120 +219,6 @@ public abstract class EntityNPC extends EntityLiving // this.setCharacter(""); if(this.species != null) this.setSize(this.getSpeciesBaseSize() * this.species.renderer.width / this.species.renderer.height, this.getSpeciesBaseSize()); // /* 0.6F, */ 1.8F); - if(this.getNavigator() instanceof PathNavigateGround) { - ((PathNavigateGround)this.getNavigator()).setBreakDoors(true); - ((PathNavigateGround)this.getNavigator()).setAvoidsWater(true); - } - this.tasks.addTask(0, new EntityAISwimming(this)); -// this.tasks.addTask(1, new EntityAIAttackOnCollide(this, EntityNPC.class, 0.6D, true, true)); -// this.tasks.addTask(1, new EntityAIAttackOnCollide(this, EntityLivingBase.class, 0.6D, true, true)); - this.tasks.addTask(1, new EntityAINpcMate(this)); - this.tasks.addTask(2, new EntityAIAvoidEntity(this, EntityLiving.class, new Predicate() { - public boolean test(EntityLiving entity) { - return entity != EntityNPC.this && EntityNPC.this.shouldFlee(entity); - } - }, 8.0F, 1.1D, 1.1D) { - { - this.setMutexBits(0); - } - - public void startExecuting() { - EntityNPC.this.setAttackTarget(null); - EntityNPC.this.fleeing = true; - } - - public boolean continueExecuting() { - return false; - } - - public void updateTask() - { - } - -// public void resetTask() { -// super.resetTask(); -// EntityNPC.this.isFleeing = false; -// } - }); - this.tasks.addTask(3, new EntityAIAvoidEntity(this, EntityLiving.class, new Predicate() { - public boolean test(EntityLiving entity) { - return entity != EntityNPC.this && EntityNPC.this.shouldFlee(entity); - } - }, 8.0F, 1.1D, 1.1D) { - public void startExecuting() { - super.startExecuting(); - EntityNPC.this.setAttackTarget(null); - EntityNPC.this.fleeing = true; - } - - public void resetTask() { - super.resetTask(); - EntityNPC.this.fleeing = false; - } - }); -// this.tasks.addTask(2, new EntityAITempt(this, 1.0D, Items.golden_apple, false)); - this.tasks.addTask(4, new EntityAIOpenDoor(this, true)); - this.tasks.addTask(5, new EntityAINagPlayer(this)); - this.tasks.addTask(5, new EntityAILookAtTalkingPlayer(this)); - this.tasks.addTask(6, new EntityAIWatchClosest2(this, null, 3.0F, 1.0F) { - private int sneakTime; - - public void updateTask() - { - super.updateTask(); - boolean flag = this.closestEntity.isPlayer() && this.closestEntity.isSneaking(); - if(this.sneakTime > 0) { - if(--this.sneakTime == 0) { - EntityNPC.this.setSneaking(false); - } - } - else if(EntityNPC.this.getAttackTarget() == null && EntityNPC.this.rand.chance(flag ? 5 : 200)) { - EntityNPC.this.setSneaking(true); - this.sneakTime = EntityNPC.this.rand.range(60, flag ? 160 : 120); - } - else if(EntityNPC.this.getAttackTarget() != null) { - EntityNPC.this.setSneaking(false); - this.sneakTime = 0; - } - } - - public void resetTask() - { - super.resetTask(); - EntityNPC.this.setSneaking(false); - } - }); - this.tasks.addTask(7, new EntityAINpcInteract(this)); - this.tasks.addTask(8, new EntityAIWander(this, 1.0D)); - this.tasks.addTask(8, new EntityAIPlay(this, 1.1D)); - this.tasks.addTask(9, new EntityAIWatchClosest(this, EntityLiving.class, 8.0F)); - this.targets.addTask(1, new EntityAIHurtByTarget(this, false, /* EntityNPC.class, */ EntityLiving.class) { - protected boolean isSuitableTarget(EntityLiving entity) { - if(entity != null && entity != EntityNPC.this && EntityNPC.this.shouldFlee(entity)) { - EntityNPC.this.setAttackTarget(null); - EntityNPC.this.fleeing = true; - return false; - } - return entity != null && entity != EntityNPC.this && (!(entity.isPlayer()) || EntityNPC.this.rand.chance(entity.getAttackedBy() == EntityNPC.this ? 2 : 4)) - && EntityNPC.this.canCounter(entity) && super.isSuitableTarget(entity); - } - }); - this.targets.addTask(2, new EntityAINearestAttackableTarget(this, EntityLiving.class, 10, true, false, new Predicate() { - public boolean test(EntityLiving entity) { - if(entity != null && entity != EntityNPC.this && EntityNPC.this.shouldFlee(entity)) { - EntityNPC.this.setAttackTarget(null); - EntityNPC.this.fleeing = true; - return false; - } - return entity != null && entity != EntityNPC.this && !EntityNPC.this.fleeing && EntityNPC.this.canAmbush(entity) && EntityNPC.this.canAttack(entity); - } - })); -// this.setCanPickUpLoot(true); - - if (worldIn != null && !worldIn.client) - { - this.setCombatTask(); - } } @@ -657,7 +507,7 @@ public abstract class EntityNPC extends EntityLiving } else if (!flag && !this.isPlayer() && this.isEntityAlive() && !this.isTalking()) { - if (!this.worldObj.client && this.canTrade() && this.getAttackTarget() == null) + if (!this.worldObj.client && this.canTrade() && this.node.getAttackTarget() == null) { this.setTalking(player); player.connection.displayTradeGui(this); @@ -1168,10 +1018,6 @@ public abstract class EntityNPC extends EntityLiving return this.playing; } - public boolean isFleeing() { - return this.fleeing; - } - // public boolean canPlay() { // return ; // } @@ -2032,7 +1878,8 @@ public abstract class EntityNPC extends EntityLiving { // float f1 = this.getHealth(); this.setHealth(this.getHealth() - damageAmount); - this.trackDamage(damageSrc, damageAmount); + if(this.node != null) + this.node.trackDamage(damageSrc, damageAmount); // if ((float)damageAmount < 3.4028235E37F) // { @@ -2835,7 +2682,7 @@ public abstract class EntityNPC extends EntityLiving else { this.setItemNoUpdate(slot, stack); if(!this.worldObj.client && slot == 0) - this.setCombatTask(); + this.node.setCombatTask(); } } @@ -3443,7 +3290,7 @@ public abstract class EntityNPC extends EntityLiving this.skin = tagCompund.getByteArray("Skin"); // this.setCanPickUpLoot(true); - this.setCombatTask(); + this.node.setCombatTask(); if(this.isPlayer()) { // this.entityUniqueID = getOfflineUUID(this.user); @@ -4461,16 +4308,6 @@ public abstract class EntityNPC extends EntityLiving { return !this.isPlayer() && super.interactFirst(playerIn); } - - public int getMaxFallHeight() - { - return this.isPlayer() ? 3 : super.getMaxFallHeight(); - } - - protected void updateLeashedState() { - if(!this.isPlayer()) - super.updateLeashedState(); - } public void setLeashedTo(Entity entity, boolean pkt) { if(!this.isPlayer()) @@ -4486,14 +4323,15 @@ public abstract class EntityNPC extends EntityLiving super.clearLeashed(pkt, dropLead); } - protected float updateDistance(float p_110146_1_, float p_110146_2_) + protected void updateDistance(float p_110146_1_, float p_110146_2_) { - if(!this.isPlayer()) - return super.updateDistance(p_110146_1_, p_110146_2_); + if(!this.isPlayer()) { + super.updateDistance(p_110146_1_, p_110146_2_); + return; + } float f = ExtMath.wrapf(p_110146_1_ - this.yawOffset); this.yawOffset += f * 0.3F; float f1 = ExtMath.wrapf(this.rotYaw - this.yawOffset); - boolean flag = f1 < -90.0F || f1 >= 90.0F; if (f1 < -75.0F) { @@ -4511,13 +4349,6 @@ public abstract class EntityNPC extends EntityLiving { this.yawOffset += f1 * 0.2F; } - - if (flag) - { - p_110146_2_ *= -1.0F; - } - - return p_110146_2_; } public boolean getCanSpawnHere() { @@ -4586,24 +4417,6 @@ public abstract class EntityNPC extends EntityLiving if(!this.isPlayer()) this.equipment[slot] = stack; } - - public void setCombatTask() - { - if(!this.isPlayer()) { - this.tasks.removeTask(this.aiMelee); - this.tasks.removeTask(this.aiRanged); - ItemStack itemstack = this.getHeldItem(); - - if (this.isRangedWeapon(itemstack)) - { - this.tasks.addTask(3, this.aiRanged); - } - else - { - this.tasks.addTask(3, this.aiMelee); - } - } - } public abstract int getBaseHealth(Random rand); // { // return 20; @@ -4649,10 +4462,6 @@ public abstract class EntityNPC extends EntityLiving public int getColor() { return this.isPlayer() ? 0xff00ff : 0x5000ad; } - - public void sendDeathMessage() { - this.sendDeathMessage(this.isPlayer(), true); - } protected boolean canRegenerateHealth() { return this.isPlayer(); diff --git a/common/src/common/entity/types/EntityLiving.java b/common/src/common/entity/types/EntityLiving.java index c99cbb5..96d6709 100755 --- a/common/src/common/entity/types/EntityLiving.java +++ b/common/src/common/entity/types/EntityLiving.java @@ -6,22 +6,14 @@ import java.util.List; import java.util.Map; import java.util.function.Predicate; -import common.ai.EntityAIBase; -import common.ai.EntityAIMoveTowardsRestriction; -import common.ai.EntityAITasks; -import common.ai.EntityJumpHelper; -import common.ai.EntityLookHelper; -import common.ai.EntityMoveHelper; -import common.ai.EntitySenses; +import common.ai.IEntityNode; import common.block.Block; import common.block.SoundType; -import common.collect.Lists; import common.collect.Maps; import common.color.TextColor; import common.enchantment.EnchantmentHelper; import common.entity.DamageSource; import common.entity.Entity; -import common.entity.EntityDamageSource; import common.entity.animal.EntityWolf; import common.entity.attributes.Attribute; import common.entity.attributes.AttributeInstance; @@ -50,12 +42,9 @@ import common.material.Material; import common.model.ParticleType; import common.nbt.NBTTagCompound; import common.nbt.NBTTagList; -import common.network.IPlayer; import common.packet.S1BPacketEntityAttach; import common.packet.SPacketAnimation; import common.packet.SPacketCollectItem; -import common.pathfinding.PathNavigate; -import common.pathfinding.PathNavigateGround; import common.potion.Potion; import common.potion.PotionEffect; import common.potion.PotionHelper; @@ -72,23 +61,13 @@ public abstract class EntityLiving extends Entity { private static final ItemStack[] EMPTY_INV = new ItemStack[5]; + protected IEntityNode node; private AttributeMap attributes; - private final List combat = Lists.newArrayList(); private final Map effects = Maps.newEnumMap(Potion.class); public int soundTimer; protected int xpValue; - private EntityLookHelper lookHelper; - protected EntityMoveHelper moveHelper; - protected EntityJumpHelper jumpHelper; - private EntityBodyHelper bodyHelper; - protected PathNavigate navigator; - protected final EntityAITasks tasks; - protected final EntityAITasks targets; - private EntityLiving target; - private EntitySenses senses; private boolean leashed; private Entity leashedTo; - private NBTTagCompound leashTag; public float prevCamPitch; public float camPitch; @@ -100,8 +79,6 @@ public abstract class EntityLiving extends Entity protected float landMovement; protected float prevGroundFactor; protected float groundFactor; - protected float movedDist; - protected float prevMovedDist; protected boolean jumping; public float moveStrafe; public float moveForward; @@ -135,18 +112,13 @@ public abstract class EntityLiving extends Entity private int lastAttacked; private EntityLiving attacker; private int lastAttackTime; - private int lastDamaged; // protected int entityAge; private int absorptionAmount; private boolean effectsDirty = true; protected boolean firstEffectUpdate = true; - private boolean attacked; - private boolean damaged; private String description; - - private String blockType; private float radiation; @@ -156,8 +128,6 @@ public abstract class EntityLiving extends Entity protected int growingAge; private float ageWidth = -1.0F; private float ageHeight; - private EntityAIBase aiBase = new EntityAIMoveTowardsRestriction(this, 1.0D); - private boolean isMovementAITaskSet; public EntityLiving(World worldIn) { @@ -171,15 +141,6 @@ public abstract class EntityLiving extends Entity this.rotYaw = (float)(Math.random() * Math.PI * 2.0D); this.headYaw = this.rotYaw; this.stepHeight = 0.6F; - - this.tasks = new EntityAITasks(); - this.targets = new EntityAITasks(); - this.lookHelper = new EntityLookHelper(this); - this.moveHelper = new EntityMoveHelper(this); - this.jumpHelper = new EntityJumpHelper(this); - this.bodyHelper = new EntityBodyHelper(this); - this.navigator = this.getNewNavigator(worldIn); - this.senses = new EntitySenses(this); } protected void entityInit() @@ -394,7 +355,6 @@ public abstract class EntityLiving extends Entity this.radiation = 0.0f; } this.updateEffects(); - this.prevMovedDist = this.movedDist; this.prevYawOffset = this.yawOffset; this.prevHeadYaw = this.headYaw; this.prevYaw = this.rotYaw; @@ -666,7 +626,7 @@ public abstract class EntityLiving extends Entity this.leashed = tagCompund.getBoolean("Leashed"); if(this.leashed && tagCompund.hasKey("Leash", 10)) { - this.leashTag = tagCompund.getCompoundTag("Leash"); + this.node.setLeashTag(tagCompund.getCompoundTag("Leash")); } } @@ -1109,11 +1069,12 @@ public abstract class EntityLiving extends Entity entity.onKillEntity(this); } - if(!this.worldObj.client) - this.sendDeathMessage(); + if(!this.worldObj.client) { + this.node.sendDeathMessage(); // this.noPickup = true; - this.resetCombat(); + this.node.resetCombat(); + } if (!this.worldObj.client) { @@ -1368,7 +1329,8 @@ public abstract class EntityLiving extends Entity { // float f1 = this.getHealth(); this.setHealth(this.getHealth() - damageAmount); - this.trackDamage(damageSrc, damageAmount); + if(this.node != null) + this.node.trackDamage(damageSrc, damageAmount); this.setAbsorptionAmount(this.getAbsorptionAmount() - damageAmount); } // } @@ -1376,7 +1338,7 @@ public abstract class EntityLiving extends Entity public EntityLiving getAttackingEntity() { - return (EntityLiving)(this.getAttacking() != null ? this.getAttacking() : (this.playerAttacker != null ? this.playerAttacker : (this.attackedBy != null ? this.attackedBy : null))); + return (EntityLiving)(this.node.getAttacking() != null ? this.node.getAttacking() : (this.playerAttacker != null ? this.playerAttacker : (this.attackedBy != null ? this.attackedBy : null))); } public final int getMaxHealth() @@ -1916,7 +1878,7 @@ public abstract class EntityLiving extends Entity if (this.ticksExisted % 20 == 0) { - this.resetCombat(); + this.node.resetCombat(); } } @@ -1948,7 +1910,7 @@ public abstract class EntityLiving extends Entity this.groundFactor += (f3 - this.groundFactor) * 0.3F; // this.worldObj.profiler.start("headTurn"); - f2 = this.updateDistance(f1, f2); + this.updateDistance(f1, f2); // this.worldObj.profiler.end(); // this.worldObj.profiler.start("rangeChecks"); @@ -1993,10 +1955,9 @@ public abstract class EntityLiving extends Entity } // this.worldObj.profiler.end(); - this.movedDist += f2; if(!this.worldObj.client) { - this.updateLeashedState(); + this.node.updateLeashedState(); } } @@ -2430,159 +2391,6 @@ public abstract class EntityLiving extends Entity public void clearRadiation() { this.radiation = 0.0f; } - - public void trackDamage(DamageSource source, int amount) { - this.resetCombat(); - this.blockType = null; - if(this.isOnLadder()) { - Block block = this.worldObj - .getState(new BlockPos(this.posX, this.getEntityBoundingBox().minY, this.posZ)).getBlock(); - if(block == Blocks.ladder) - this.blockType = "von einer Leiter"; - else if(block == Blocks.vine) - this.blockType = "von Ranken"; - } - else if(this.isInLiquid()) { - this.blockType = "aus dem Wasser"; - } - CombatEntry entry = new CombatEntry(source, amount, this.blockType, this.fallDistance); - this.combat.add(entry); - this.lastDamaged = this.ticksExisted; - this.damaged = true; - if(entry.getSource().getEntity() instanceof EntityLiving && !this.attacked && this.isEntityAlive()) - this.attacked = true; - } - - protected void sendDeathMessage() { - this.sendDeathMessage(false, false); - } - - protected void sendDeathMessage(boolean natural, boolean forAll) { - if(this.worldObj.client) - return; - String msg; - String kill; - IPlayer receiver = null; - if(this.combat.size() == 0) { - msg = kill = natural ? String.format("%s starb", this.getColoredName(TextColor.LGRAY)) : null; - } - else { - CombatEntry strong = null; - CombatEntry block = null; - int min = 0; - float max = 0.0F; - - for(int z = 0; z < this.combat.size(); ++z) { - CombatEntry entry = (CombatEntry)this.combat.get(z); - CombatEntry last = z > 0 ? (CombatEntry)this.combat.get(z - 1) : null; - - if((entry.getSource() == DamageSource.fall || entry.getSource() == DamageSource.outOfWorld) && - entry.getFallDistance() > 0.0F && (strong == null || entry.getFallDistance() > max)) { - if(z > 0) { - strong = last; - } - else { - strong = entry; - } - - max = entry.getFallDistance(); - } - - if(entry.getBlockType() != null && (block == null || entry.getDamage() > min)) { - block = entry; - } - } - CombatEntry fall = max > 5.0F && strong != null ? strong : (min > 5 && block != null ? block : null); - CombatEntry last = (CombatEntry)this.combat.get(this.combat.size() - 1); - Entity lastEnt = last.getSource().getEntity(); - - if(fall != null && last.getSource() == DamageSource.fall) { - if(fall.getSource() != DamageSource.fall && fall.getSource() != DamageSource.outOfWorld) { - Entity fallEnt = fall.getSource().getEntity(); - if(fallEnt != null && (lastEnt == null || fallEnt != lastEnt)) { - ItemStack fallItem = fallEnt instanceof EntityLiving ? ((EntityLiving)fallEnt).getHeldItem() : null; - receiver = fallEnt.isPlayer() ? ((EntityNPC)fallEnt).connection : null; - if(fallItem != null) { // && fallItem.hasDisplayName()) { - msg = String.format("%s wurde von %s mit %s zum Fallen verdammt", this.getColoredName(TextColor.CYAN), - fallEnt.getColoredName(TextColor.CYAN), fallItem.getColoredName(TextColor.CYAN)); - kill = String.format(TextColor.CYAN + "* %s mit %s zum Fallen verdammt", - this.getColoredName(TextColor.CYAN), fallItem.getColoredName(TextColor.CYAN)); - } - else { - msg = String.format("%s wurde von %s zum Fallen verdammt", this.getColoredName(TextColor.CYAN), - fallEnt.getColoredName(TextColor.CYAN)); - kill = String.format(TextColor.CYAN + "* %s zum Fallen verdammt", - this.getColoredName(TextColor.CYAN)); - } - } - else if(lastEnt != null) { - ItemStack lastItem = lastEnt instanceof EntityLiving ? ((EntityLiving)lastEnt).getHeldItem() : null; - receiver = lastEnt.isPlayer() ? ((EntityNPC)lastEnt).connection : null; - if(lastItem != null) { // && lastItem.hasDisplayName()) { - msg = String.format("%s fiel zu tief und wurde von %s mit %s erledigt", - this.getColoredName(TextColor.BLUE), - lastEnt.getColoredName(TextColor.BLUE), lastItem.getColoredName(TextColor.BLUE)); - kill = String.format(TextColor.BLUE + "* %s mit %s erledigt", - this.getColoredName(TextColor.BLUE), lastItem.getColoredName(TextColor.BLUE)); - } - else { - msg = String.format("%s fiel zu tief und wurde von %s erledigt", this.getColoredName(TextColor.BLUE), - lastEnt.getColoredName(TextColor.BLUE)); - kill = String.format(TextColor.BLUE + "%s erledigt", this.getColoredName(TextColor.BLUE)); - } - } - else { - msg = kill = natural ? String.format("%s wurde zum Fallen verdammt", this.getColoredName(TextColor.CYAN)) : null; - } - } - else { - msg = kill = natural ? String.format("%s fiel " + (fall.getBlockType() == null ? "aus zu großer Höhe" : fall.getBlockType()), - this.getColoredName(TextColor.NEON)) : null; - } - } - else { - receiver = last.getSource().getEntity() != null && last.getSource().getEntity().isPlayer() ? ((EntityNPC)last.getSource().getEntity()).connection : null; - msg = natural || (last.getSource() instanceof EntityDamageSource ? last.getSource().getEntity() != null : this.getAttackingEntity() != null) ? last.getSource().getDeathMessage(this) : null; - kill = msg == null ? null : last.getSource().getKillMessage(this); - } - } - if(msg == null) - return; - if(receiver != null) - receiver.addFeed(kill); - if(forAll) - for(IPlayer player : ((WorldServer)this.worldObj).getServer().getIPlayers()) { - if(player != receiver) - player.addFeed(msg); - } - } - - public EntityLiving getAttacking() { - EntityLiving entity = null; - EntityNPC player = null; - int edmg = 0; - int pdmg = 0; - for(CombatEntry entry : this.combat) { - if(entry.getSource().getEntity() != null && entry.getSource().getEntity().isPlayer() && (player == null || entry.getDamage() > pdmg)) { - pdmg = entry.getDamage(); - player = (EntityNPC)entry.getSource().getEntity(); - } - if(entry.getSource().getEntity() instanceof EntityLiving && (entity == null || entry.getDamage() > edmg)) { - edmg = entry.getDamage(); - entity = (EntityLiving)entry.getSource().getEntity(); - } - } - return player != null && pdmg >= edmg / 3 ? player : entity; - } - - public void resetCombat() { - int timeout = this.attacked ? 300 : 100; - if(this.damaged && (!this.isEntityAlive() || this.ticksExisted - this.lastDamaged > timeout)) { - this.damaged = false; - this.attacked = false; - this.combat.clear(); - } - } public boolean isSneakingVisually() { return this.isSneaking(); @@ -2804,22 +2612,6 @@ public abstract class EntityLiving extends Entity return 4; } - public int getMaxFallHeight() { - if(this.getAttackTarget() == null) { - return 3; - } - else { - int i = (int)((float)this.getHealth() - (float)this.getMaxHealth() * 0.33F); -// i = i - (3 - this.worldObj.getDifficulty().getId()) * 4; - - if(i < 0) { - i = 0; - } - - return i + 3; - } - } - // public boolean getCanSpawnHere() { // return true; // } @@ -2882,34 +2674,8 @@ public abstract class EntityLiving extends Entity } protected void updateEntityActionState() { -// ++this.entityAge; -// this.worldObj.profiler.start("checkDespawn"); -// this.despawnEntity(); -// this.worldObj.profiler.end(); -// this.worldObj.profiler.start("sensing"); - this.senses.clearSensingCache(); -// this.worldObj.profiler.end(); -// this.worldObj.profiler.start("targetSelector"); - this.targets.onUpdateTasks(); -// this.worldObj.profiler.end(); -// this.worldObj.profiler.start("goalSelector"); - this.tasks.onUpdateTasks(); -// this.worldObj.profiler.end(); -// this.worldObj.profiler.start("navigation"); - this.navigator.onUpdateNavigation(); -// this.worldObj.profiler.end(); -// this.worldObj.profiler.start("mob tick"); - this.updateAITasks(); -// this.worldObj.profiler.end(); -// this.worldObj.profiler.start("controls"); -// this.worldObj.profiler.start("move"); - this.moveHelper.onUpdateMoveHelper(); -// this.worldObj.profiler.next("look"); - this.lookHelper.onUpdateLook(); -// this.worldObj.profiler.next("jump"); - this.jumpHelper.doJump(); -// this.worldObj.profiler.end(); -// this.worldObj.profiler.end(); + if(this.node != null) + this.node.update(); } // protected void despawnEntity() { @@ -2967,123 +2733,12 @@ public abstract class EntityLiving extends Entity // super.applyEntityAttributes(); // this.getAttributeMap().registerAttribute(Attributes.FOLLOW_RANGE).setBaseValue(16.0D); // } - - protected PathNavigate getNewNavigator(World worldIn) { - return new PathNavigateGround(this, worldIn); - } - - public EntityLookHelper getLookHelper() { - return this.lookHelper; - } - - public EntityMoveHelper getMoveHelper() { - return this.moveHelper; - } - - public EntityJumpHelper getJumpHelper() { - return this.jumpHelper; - } - - public PathNavigate getNavigator() { - return this.navigator; - } - - public EntitySenses getEntitySenses() { - return this.senses; - } - - public EntityLiving getAttackTarget() { - return this.target; - } - - public void setAttackTarget(EntityLiving entitylivingbaseIn) { - this.target = entitylivingbaseIn; - } // public boolean canAttackClass(Class cls) { // return /* cls != EntityFireDemon.class && */ // ; // } - protected void updateLeashedState() { - if(this.leashTag != null) { - this.recreateLeash(); - } - - if(this.leashed) { - if(!this.isEntityAlive()) { - this.clearLeashed(true, true); - } - - if(this.leashedTo == null || this.leashedTo.dead) { - this.clearLeashed(true, true); - } - } - - if (this.getLeashed() && this.getLeashedTo() != null && this.getLeashedTo().worldObj == this.worldObj) - { - Entity entity = this.getLeashedTo(); - this.setHomePosAndDistance(new BlockPos((int)entity.posX, (int)entity.posY, (int)entity.posZ), 5); - float f = this.getDistanceToEntity(entity); - - if (this instanceof EntityTameable && ((EntityTameable)this).isSitting()) - { - if (f > 10.0F) - { - this.clearLeashed(true, true); - } - - return; - } - - if (!this.isMovementAITaskSet) - { - this.tasks.addTask(2, this.aiBase); - - if (this.getNavigator() instanceof PathNavigateGround) - { - ((PathNavigateGround)this.getNavigator()).setAvoidsWater(false); - } - - this.isMovementAITaskSet = true; - } - - this.onUpdateLeashed(f); - - if (f > 4.0F) - { - this.getNavigator().tryMoveToEntityLiving(entity, 1.0D); - } - - if (f > 6.0F) - { - double d0 = (entity.posX - this.posX) / (double)f; - double d1 = (entity.posY - this.posY) / (double)f; - double d2 = (entity.posZ - this.posZ) / (double)f; - this.motionX += d0 * Math.abs(d0) * 0.4D; - this.motionY += d1 * Math.abs(d1) * 0.4D; - this.motionZ += d2 * Math.abs(d2) * 0.4D; - } - - if (f > 10.0F) - { - this.clearLeashed(true, true); - } - } - else if (!this.getLeashed() && this.isMovementAITaskSet) - { - this.isMovementAITaskSet = false; - this.tasks.removeTask(this.aiBase); - - if (this.getNavigator() instanceof PathNavigateGround) - { - ((PathNavigateGround)this.getNavigator()).setAvoidsWater(true); - } - - this.detachHome(); - } - } - public void clearLeashed(boolean pkt, boolean dropLead) { if(this.leashed) { this.leashed = false; @@ -3120,43 +2775,9 @@ public abstract class EntityLiving extends Entity } } - private void recreateLeash() { - if(this.leashed && this.leashTag != null) { -// if(this.leashTag.hasKey("PlayerName", 8)) { -// String id = this.leashTag.getString("PlayerName"); -// if(!id.isEmpty()) { -// for(EntityNPC entitylivingbase : this.worldObj.getEntitiesWithinAABB(EntityNPC.class, -// this.getEntityBoundingBox().expand(10.0D, 10.0D, 10.0D))) { -// if(entitylivingbase.getUser().equals(id)) { -// this.leashedTo = entitylivingbase; -// break; -// } -// } -// } -// } -// else - if(this.leashTag.hasKey("X", 99) && this.leashTag.hasKey("Y", 99) && this.leashTag.hasKey("Z", 99)) { - BlockPos blockpos = new BlockPos(this.leashTag.getInteger("X"), this.leashTag.getInteger("Y"), - this.leashTag.getInteger("Z")); - EntityLeashKnot entityleashknot = EntityLeashKnot.getKnotForPosition(this.worldObj, blockpos); - - if(entityleashknot == null) { - entityleashknot = EntityLeashKnot.createKnot(this.worldObj, blockpos); - } - - this.leashedTo = entityleashknot; - } - else { - this.clearLeashed(false, true); - } - } - - this.leashTag = null; - } - - protected float updateDistance(float p_110146_1_, float p_110146_2_) { - this.bodyHelper.updateRenderAngles(); - return p_110146_2_; + protected void updateDistance(float p_110146_1_, float p_110146_2_) { + if(this.node != null) + this.node.updateRenderAngles(); } public ItemStack[] getInventory() { @@ -3287,11 +2908,6 @@ public abstract class EntityLiving extends Entity { return this.getBlockPathWeight(new BlockPos(this.posX, this.getEntityBoundingBox().minY, this.posZ)) >= 0.0F; } - - public boolean hasPath() - { - return !this.navigator.noPath(); - } public boolean isWithinHomeDistanceCurrentPosition() { @@ -3328,10 +2944,6 @@ public abstract class EntityLiving extends Entity { return this.maximumHomeDistance != -1.0F; } - - protected void onUpdateLeashed(float distance) - { - } protected void setSize(float width, float height) { diff --git a/common/src/common/pathfinding/PathNavigateGround.java b/common/src/common/pathfinding/PathNavigateGround.java index f12b1c8..c9631ee 100755 --- a/common/src/common/pathfinding/PathNavigateGround.java +++ b/common/src/common/pathfinding/PathNavigateGround.java @@ -11,7 +11,7 @@ import common.util.Vec3; import common.world.World; public class PathNavigateGround extends PathNavigate -{ +{ protected WalkNodeProcessor nodeProcessor; private boolean shouldAvoidSun; diff --git a/server/src/server/ai/EntityNPCNode.java b/server/src/server/ai/EntityNPCNode.java new file mode 100644 index 0000000..b314cdc --- /dev/null +++ b/server/src/server/ai/EntityNPCNode.java @@ -0,0 +1,224 @@ +package server.ai; + +import java.util.function.Predicate; + +import common.ai.AIRangedAttack; +import common.ai.EntityAIAttackOnCollide; +import common.ai.EntityAIAvoidEntity; +import common.ai.EntityAIHurtByTarget; +import common.ai.EntityAILookAtTalkingPlayer; +import common.ai.EntityAINagPlayer; +import common.ai.EntityAINearestAttackableTarget; +import common.ai.EntityAINpcInteract; +import common.ai.EntityAINpcMate; +import common.ai.EntityAIOpenDoor; +import common.ai.EntityAIPlay; +import common.ai.EntityAISwimming; +import common.ai.EntityAIWander; +import common.ai.EntityAIWatchClosest; +import common.ai.EntityAIWatchClosest2; +import common.entity.npc.EntityNPC; +import common.entity.types.EntityLiving; +import common.item.ItemStack; +import common.pathfinding.PathNavigateGround; + +public class EntityNPCNode extends EntityNode { + protected final EntityAIAttackOnCollide aiMelee; + protected final AIRangedAttack aiRanged; + private boolean fleeing; + + public EntityNPCNode(EntityNPC entity) { + super(entity); + this.aiMelee = new EntityAIAttackOnCollide(entity, EntityLiving.class, 1.0D, true, true) { + public boolean shouldExecute() + { + return !EntityNPCNode.this.fleeing && super.shouldExecute(); + } + + public boolean continueExecuting() + { + return !EntityNPCNode.this.fleeing && super.shouldExecute(); + } + }; + this.aiRanged = new AIRangedAttack(entity, 1.0D, entity.getAttackSpeed(), entity.getAttackSpeed() * 3, 15.0F) { +// public void startExecuting() +// { +// super.startExecuting(); +// EntityNPC.this.setUsingItem(true); +// } +// +// public void resetTask() +// { +// super.resetTask(); +// EntityNPC.this.setUsingItem(false); +// } + + public boolean shouldExecute() + { + return !EntityNPCNode.this.fleeing && super.shouldExecute(); + } + + public boolean continueExecuting() + { + return !EntityNPCNode.this.fleeing && super.shouldExecute(); + } + }; + } + + public EntityNPC getEntity() { + return (EntityNPC)this.entity; + } + + protected void registerTasks() { + if(this.getNavigator() instanceof PathNavigateGround) { + ((PathNavigateGround)this.getNavigator()).setBreakDoors(true); + ((PathNavigateGround)this.getNavigator()).setAvoidsWater(true); + } + this.tasks.addTask(0, new EntityAISwimming(this.getEntity())); +// this.tasks.addTask(1, new EntityAIAttackOnCollide(this, EntityNPC.class, 0.6D, true, true)); +// this.tasks.addTask(1, new EntityAIAttackOnCollide(this, EntityLivingBase.class, 0.6D, true, true)); + this.tasks.addTask(1, new EntityAINpcMate(this.getEntity())); + this.tasks.addTask(2, new EntityAIAvoidEntity(this.getEntity(), EntityLiving.class, new Predicate() { + public boolean test(EntityLiving entity) { + return entity != EntityNPCNode.this.entity && EntityNPC.this.shouldFlee(entity); + } + }, 8.0F, 1.1D, 1.1D) { + { + this.setMutexBits(0); + } + + public void startExecuting() { + EntityNPCNode.this.setAttackTarget(null); + EntityNPCNode.this.fleeing = true; + } + + public boolean continueExecuting() { + return false; + } + + public void updateTask() + { + } + +// public void resetTask() { +// super.resetTask(); +// EntityNPC.this.isFleeing = false; +// } + }); + this.tasks.addTask(3, new EntityAIAvoidEntity(this, EntityLiving.class, new Predicate() { + public boolean test(EntityLiving entity) { + return entity != EntityNPC.this && EntityNPC.this.shouldFlee(entity); + } + }, 8.0F, 1.1D, 1.1D) { + public void startExecuting() { + super.startExecuting(); + EntityNPC.this.setAttackTarget(null); + EntityNPC.this.fleeing = true; + } + + public void resetTask() { + super.resetTask(); + EntityNPC.this.fleeing = false; + } + }); +// this.tasks.addTask(2, new EntityAITempt(this, 1.0D, Items.golden_apple, false)); + this.tasks.addTask(4, new EntityAIOpenDoor(this, true)); + this.tasks.addTask(5, new EntityAINagPlayer(this)); + this.tasks.addTask(5, new EntityAILookAtTalkingPlayer(this)); + this.tasks.addTask(6, new EntityAIWatchClosest2(this, null, 3.0F, 1.0F) { + private int sneakTime; + + public void updateTask() + { + super.updateTask(); + boolean flag = this.closestEntity.isPlayer() && this.closestEntity.isSneaking(); + if(this.sneakTime > 0) { + if(--this.sneakTime == 0) { + EntityNPC.this.setSneaking(false); + } + } + else if(EntityNPC.this.getAttackTarget() == null && EntityNPC.this.rand.chance(flag ? 5 : 200)) { + EntityNPC.this.setSneaking(true); + this.sneakTime = EntityNPC.this.rand.range(60, flag ? 160 : 120); + } + else if(EntityNPC.this.getAttackTarget() != null) { + EntityNPC.this.setSneaking(false); + this.sneakTime = 0; + } + } + + public void resetTask() + { + super.resetTask(); + EntityNPC.this.setSneaking(false); + } + }); + this.tasks.addTask(7, new EntityAINpcInteract(this)); + this.tasks.addTask(8, new EntityAIWander(this, 1.0D)); + this.tasks.addTask(8, new EntityAIPlay(this, 1.1D)); + this.tasks.addTask(9, new EntityAIWatchClosest(this, EntityLiving.class, 8.0F)); + this.targets.addTask(1, new EntityAIHurtByTarget(this, false, /* EntityNPC.class, */ EntityLiving.class) { + protected boolean isSuitableTarget(EntityLiving entity) { + if(entity != null && entity != EntityNPC.this && EntityNPC.this.shouldFlee(entity)) { + EntityNPC.this.setAttackTarget(null); + EntityNPC.this.fleeing = true; + return false; + } + return entity != null && entity != EntityNPC.this && (!(entity.isPlayer()) || EntityNPC.this.rand.chance(entity.getAttackedBy() == EntityNPC.this ? 2 : 4)) + && EntityNPC.this.canCounter(entity) && super.isSuitableTarget(entity); + } + }); + this.targets.addTask(2, new EntityAINearestAttackableTarget(this, EntityLiving.class, 10, true, false, new Predicate() { + public boolean test(EntityLiving entity) { + if(entity != null && entity != EntityNPC.this && EntityNPC.this.shouldFlee(entity)) { + EntityNPC.this.setAttackTarget(null); + EntityNPC.this.fleeing = true; + return false; + } + return entity != null && entity != EntityNPC.this && !EntityNPC.this.fleeing && EntityNPC.this.canAmbush(entity) && EntityNPC.this.canAttack(entity); + } + })); +// this.setCanPickUpLoot(true); + + if (worldIn != null && !worldIn.client) + { + this.setCombatTask(); + } + } + + public void updateLeashedState() { + if(!this.player) + super.updateLeashedState(); + } + + public void sendDeathMessage() { + this.sendDeathMessage(this.player, true); + } + + public int getMaxFallHeight() + { + return this.player ? 3 : super.getMaxFallHeight(); + } + + public void setCombatTask() + { + if(!this.player) { + this.tasks.removeTask(this.aiMelee); + this.tasks.removeTask(this.aiRanged); + ItemStack itemstack = this.getEntity().getHeldItem(); + + if (this.getEntity().isRangedWeapon(itemstack)) + { + this.tasks.addTask(3, this.aiRanged); + } + else + { + this.tasks.addTask(3, this.aiMelee); + } + } + } + + public boolean isFleeing() { + return this.fleeing; + } +} diff --git a/server/src/server/ai/EntityNode.java b/server/src/server/ai/EntityNode.java new file mode 100644 index 0000000..2f4c0a7 --- /dev/null +++ b/server/src/server/ai/EntityNode.java @@ -0,0 +1,436 @@ +package server.ai; + +import java.util.List; + +import common.ai.EntityAIBase; +import common.ai.EntityAIMoveTowardsRestriction; +import common.ai.EntityAITasks; +import common.ai.EntityJumpHelper; +import common.ai.EntityLookHelper; +import common.ai.EntityMoveHelper; +import common.ai.EntitySenses; +import common.ai.IEntityNode; +import common.block.Block; +import common.collect.Lists; +import common.color.TextColor; +import common.entity.DamageSource; +import common.entity.Entity; +import common.entity.EntityDamageSource; +import common.entity.item.EntityLeashKnot; +import common.entity.npc.EntityNPC; +import common.entity.types.CombatEntry; +import common.entity.types.EntityBodyHelper; +import common.entity.types.EntityLiving; +import common.entity.types.EntityTameable; +import common.init.Blocks; +import common.item.ItemStack; +import common.nbt.NBTTagCompound; +import common.network.IPlayer; +import common.pathfinding.PathNavigate; +import common.pathfinding.PathNavigateGround; +import common.util.BlockPos; +import common.world.WorldServer; + +public abstract class EntityNode implements IEntityNode { + protected final EntityLiving entity; + protected final boolean player; + private final List combat = Lists.newArrayList(); + private EntityLookHelper lookHelper; + protected EntityMoveHelper moveHelper; + protected EntityJumpHelper jumpHelper; + private EntityBodyHelper bodyHelper; + protected PathNavigate navigator; + protected final EntityAITasks tasks; + protected final EntityAITasks targets; + private EntityLiving target; + private EntitySenses senses; + private Runnable tickFunc; + private NBTTagCompound leashTag; + private boolean isMovementAITaskSet; + private EntityAIBase aiBase; + private boolean attacked; + private boolean damaged; + private String blockType; + private int lastDamaged; + + public EntityNode(EntityLiving entity) { + this.entity = entity; + this.player = entity.isPlayer(); + this.tasks = new EntityAITasks(); + this.targets = new EntityAITasks(); + this.lookHelper = new EntityLookHelper(entity); + this.moveHelper = new EntityMoveHelper(entity); + this.jumpHelper = new EntityJumpHelper(entity); + this.bodyHelper = new EntityBodyHelper(entity); + this.navigator = this.getNewNavigator(); + this.senses = new EntitySenses(entity); + this.aiBase = new EntityAIMoveTowardsRestriction(entity, 1.0D); + this.registerTasks(); + } + + protected PathNavigate getNewNavigator() { + return new PathNavigateGround(this.entity, this.entity.worldObj); + } + +// protected PathNavigate getNewNavigator() { EntityArachnoid +// return new PathNavigateClimber(this.entity, this.entity.worldObj); +// } + + protected abstract void registerTasks(); + + public void setTickFunction(Runnable func) { + this.tickFunc = func; + } + + public EntityLookHelper getLookHelper() { + return this.lookHelper; + } + + public EntityMoveHelper getMoveHelper() { + return this.moveHelper; + } + + public EntityJumpHelper getJumpHelper() { + return this.jumpHelper; + } + + public PathNavigate getNavigator() { + return this.navigator; + } + + public EntitySenses getEntitySenses() { + return this.senses; + } + + public EntityLiving getAttackTarget() { + return this.target; + } + + public void setAttackTarget(EntityLiving entitylivingbaseIn) { + this.target = entitylivingbaseIn; + } + + public boolean hasPath() + { + return !this.navigator.noPath(); + } + + public void updateRenderAngles() { + this.bodyHelper.updateRenderAngles(); + } + + public void update() { + this.senses.clearSensingCache(); + this.targets.onUpdateTasks(); + this.tasks.onUpdateTasks(); + this.navigator.onUpdateNavigation(); + if(this.tickFunc != null) + this.tickFunc.run(); + this.moveHelper.onUpdateMoveHelper(); + this.lookHelper.onUpdateLook(); + this.jumpHelper.doJump(); + } + + public void setLeashTag(NBTTagCompound tag) { + this.leashTag = tag; + } + + private void recreateLeash() { + if(this.entity.getLeashed() && this.leashTag != null) { +// if(this.leashTag.hasKey("PlayerName", 8)) { +// String id = this.leashTag.getString("PlayerName"); +// if(!id.isEmpty()) { +// for(EntityNPC entitylivingbase : this.worldObj.getEntitiesWithinAABB(EntityNPC.class, +// this.getEntityBoundingBox().expand(10.0D, 10.0D, 10.0D))) { +// if(entitylivingbase.getUser().equals(id)) { +// this.leashedTo = entitylivingbase; +// break; +// } +// } +// } +// } +// else + if(this.leashTag.hasKey("X", 99) && this.leashTag.hasKey("Y", 99) && this.leashTag.hasKey("Z", 99)) { + BlockPos blockpos = new BlockPos(this.leashTag.getInteger("X"), this.leashTag.getInteger("Y"), + this.leashTag.getInteger("Z")); + EntityLeashKnot entityleashknot = EntityLeashKnot.getKnotForPosition(this.entity.worldObj, blockpos); + + if(entityleashknot == null) { + entityleashknot = EntityLeashKnot.createKnot(this.entity.worldObj, blockpos); + } + + this.entity.setLeashedTo(entityleashknot, false); + } + else { + this.entity.clearLeashed(false, true); + } + } + + this.leashTag = null; + } + + protected void onUpdateLeashed(float distance) + { + } + +// protected void onUpdateLeashed(float distance) EntityHorse +// { +// if (distance > 6.0F && this.entity.isEatingHaystack()) +// { +// this.entity.setEatingHaystack(false); +// } +// } + + public void updateLeashedState() { + if(this.leashTag != null) { + this.recreateLeash(); + } + + if(this.entity.getLeashed()) { + if(!this.entity.isEntityAlive()) { + this.entity.clearLeashed(true, true); + } + + if(this.entity.getLeashedTo() == null || this.entity.getLeashedTo().dead) { + this.entity.clearLeashed(true, true); + } + } + + if (this.entity.getLeashed() && this.entity.getLeashedTo() != null && this.entity.getLeashedTo().worldObj == this.entity.worldObj) + { + Entity entity = this.entity.getLeashedTo(); + this.entity.setHomePosAndDistance(new BlockPos((int)entity.posX, (int)entity.posY, (int)entity.posZ), 5); + float f = this.entity.getDistanceToEntity(entity); + + if (this.entity instanceof EntityTameable && ((EntityTameable)this.entity).isSitting()) + { + if (f > 10.0F) + { + this.entity.clearLeashed(true, true); + } + + return; + } + + if (!this.isMovementAITaskSet) + { + this.tasks.addTask(2, this.aiBase); + + if (this.getNavigator() instanceof PathNavigateGround) + { + ((PathNavigateGround)this.getNavigator()).setAvoidsWater(false); + } + + this.isMovementAITaskSet = true; + } + + this.onUpdateLeashed(f); + + if (f > 4.0F) + { + this.getNavigator().tryMoveToEntityLiving(entity, 1.0D); + } + + if (f > 6.0F) + { + double d0 = (entity.posX - this.entity.posX) / (double)f; + double d1 = (entity.posY - this.entity.posY) / (double)f; + double d2 = (entity.posZ - this.entity.posZ) / (double)f; + this.entity.motionX += d0 * Math.abs(d0) * 0.4D; + this.entity.motionY += d1 * Math.abs(d1) * 0.4D; + this.entity.motionZ += d2 * Math.abs(d2) * 0.4D; + } + + if (f > 10.0F) + { + this.entity.clearLeashed(true, true); + } + } + else if (!this.entity.getLeashed() && this.isMovementAITaskSet) + { + this.isMovementAITaskSet = false; + this.tasks.removeTask(this.aiBase); + + if (this.getNavigator() instanceof PathNavigateGround) + { + ((PathNavigateGround)this.getNavigator()).setAvoidsWater(true); + } + + this.entity.detachHome(); + } + } + + public void trackDamage(DamageSource source, int amount) { + this.resetCombat(); + this.blockType = null; + if(this.entity.isOnLadder()) { + Block block = this.entity.worldObj + .getState(new BlockPos(this.entity.posX, this.entity.getEntityBoundingBox().minY, this.entity.posZ)).getBlock(); + if(block == Blocks.ladder) + this.blockType = "von einer Leiter"; + else if(block == Blocks.vine) + this.blockType = "von Ranken"; + } + else if(this.entity.isInLiquid()) { + this.blockType = "aus dem Wasser"; + } + CombatEntry entry = new CombatEntry(source, amount, this.blockType, this.entity.fallDistance); + this.combat.add(entry); + this.lastDamaged = this.entity.ticksExisted; + this.damaged = true; + if(entry.getSource().getEntity() instanceof EntityLiving && !this.attacked && this.entity.isEntityAlive()) + this.attacked = true; + } + + public void sendDeathMessage() { + this.sendDeathMessage(false, false); + } + + protected void sendDeathMessage(boolean natural, boolean forAll) { +// if(this.entity.worldObj.client) +// return; + String msg; + String kill; + IPlayer receiver = null; + if(this.combat.size() == 0) { + msg = kill = natural ? String.format("%s starb", this.entity.getColoredName(TextColor.LGRAY)) : null; + } + else { + CombatEntry strong = null; + CombatEntry block = null; + int min = 0; + float max = 0.0F; + + for(int z = 0; z < this.combat.size(); ++z) { + CombatEntry entry = (CombatEntry)this.combat.get(z); + CombatEntry last = z > 0 ? (CombatEntry)this.combat.get(z - 1) : null; + + if((entry.getSource() == DamageSource.fall || entry.getSource() == DamageSource.outOfWorld) && + entry.getFallDistance() > 0.0F && (strong == null || entry.getFallDistance() > max)) { + if(z > 0) { + strong = last; + } + else { + strong = entry; + } + + max = entry.getFallDistance(); + } + + if(entry.getBlockType() != null && (block == null || entry.getDamage() > min)) { + block = entry; + } + } + CombatEntry fall = max > 5.0F && strong != null ? strong : (min > 5 && block != null ? block : null); + CombatEntry last = (CombatEntry)this.combat.get(this.combat.size() - 1); + Entity lastEnt = last.getSource().getEntity(); + + if(fall != null && last.getSource() == DamageSource.fall) { + if(fall.getSource() != DamageSource.fall && fall.getSource() != DamageSource.outOfWorld) { + Entity fallEnt = fall.getSource().getEntity(); + if(fallEnt != null && (lastEnt == null || fallEnt != lastEnt)) { + ItemStack fallItem = fallEnt instanceof EntityLiving ? ((EntityLiving)fallEnt).getHeldItem() : null; + receiver = fallEnt.isPlayer() ? ((EntityNPC)fallEnt).connection : null; + if(fallItem != null) { // && fallItem.hasDisplayName()) { + msg = String.format("%s wurde von %s mit %s zum Fallen verdammt", this.entity.getColoredName(TextColor.CYAN), + fallEnt.getColoredName(TextColor.CYAN), fallItem.getColoredName(TextColor.CYAN)); + kill = String.format(TextColor.CYAN + "* %s mit %s zum Fallen verdammt", + this.entity.getColoredName(TextColor.CYAN), fallItem.getColoredName(TextColor.CYAN)); + } + else { + msg = String.format("%s wurde von %s zum Fallen verdammt", this.entity.getColoredName(TextColor.CYAN), + fallEnt.getColoredName(TextColor.CYAN)); + kill = String.format(TextColor.CYAN + "* %s zum Fallen verdammt", + this.entity.getColoredName(TextColor.CYAN)); + } + } + else if(lastEnt != null) { + ItemStack lastItem = lastEnt instanceof EntityLiving ? ((EntityLiving)lastEnt).getHeldItem() : null; + receiver = lastEnt.isPlayer() ? ((EntityNPC)lastEnt).connection : null; + if(lastItem != null) { // && lastItem.hasDisplayName()) { + msg = String.format("%s fiel zu tief und wurde von %s mit %s erledigt", + this.entity.getColoredName(TextColor.BLUE), + lastEnt.getColoredName(TextColor.BLUE), lastItem.getColoredName(TextColor.BLUE)); + kill = String.format(TextColor.BLUE + "* %s mit %s erledigt", + this.entity.getColoredName(TextColor.BLUE), lastItem.getColoredName(TextColor.BLUE)); + } + else { + msg = String.format("%s fiel zu tief und wurde von %s erledigt", this.entity.getColoredName(TextColor.BLUE), + lastEnt.getColoredName(TextColor.BLUE)); + kill = String.format(TextColor.BLUE + "%s erledigt", this.entity.getColoredName(TextColor.BLUE)); + } + } + else { + msg = kill = natural ? String.format("%s wurde zum Fallen verdammt", this.entity.getColoredName(TextColor.CYAN)) : null; + } + } + else { + msg = kill = natural ? String.format("%s fiel " + (fall.getBlockType() == null ? "aus zu großer Höhe" : fall.getBlockType()), + this.entity.getColoredName(TextColor.NEON)) : null; + } + } + else { + receiver = last.getSource().getEntity() != null && last.getSource().getEntity().isPlayer() ? ((EntityNPC)last.getSource().getEntity()).connection : null; + msg = natural || (last.getSource() instanceof EntityDamageSource ? last.getSource().getEntity() != null : this.entity.getAttackingEntity() != null) ? last.getSource().getDeathMessage(this.entity) : null; + kill = msg == null ? null : last.getSource().getKillMessage(this.entity); + } + } + if(msg == null) + return; + if(receiver != null) + receiver.addFeed(kill); + if(forAll) + for(IPlayer player : ((WorldServer)this.entity.worldObj).getServer().getIPlayers()) { + if(player != receiver) + player.addFeed(msg); + } + } + + public EntityLiving getAttacking() { + EntityLiving entity = null; + EntityNPC player = null; + int edmg = 0; + int pdmg = 0; + for(CombatEntry entry : this.combat) { + if(entry.getSource().getEntity() != null && entry.getSource().getEntity().isPlayer() && (player == null || entry.getDamage() > pdmg)) { + pdmg = entry.getDamage(); + player = (EntityNPC)entry.getSource().getEntity(); + } + if(entry.getSource().getEntity() instanceof EntityLiving && (entity == null || entry.getDamage() > edmg)) { + edmg = entry.getDamage(); + entity = (EntityLiving)entry.getSource().getEntity(); + } + } + return player != null && pdmg >= edmg / 3 ? player : entity; + } + + public void resetCombat() { + int timeout = this.attacked ? 300 : 100; + if(this.damaged && (!this.entity.isEntityAlive() || this.entity.ticksExisted - this.lastDamaged > timeout)) { + this.damaged = false; + this.attacked = false; + this.combat.clear(); + } + } + + public int getMaxFallHeight() { + if(this.target == null) { + return 3; + } + else { + int i = (int)((float)this.entity.getHealth() - (float)this.entity.getMaxHealth() * 0.33F); +// i = i - (3 - this.worldObj.getDifficulty().getId()) * 4; + + if(i < 0) { + i = 0; + } + + return i + 3; + } + } + +// public int getMaxFallHeight() EntityHaunter +// { +// return this.getAttackTarget() == null ? 3 : 3 + (this.getHealth() - 1); +// } +} From ad828ec6b449201b7845b05bcf334423f43fea29 Mon Sep 17 00:00:00 2001 From: Sen Date: Mon, 12 May 2025 18:28:56 +0200 Subject: [PATCH 016/200] split entity ai to server #2+ --- client/src/client/Client.java | 8 +- client/src/client/gui/GuiConvert.java | 214 ------- client/src/client/gui/GuiMenu.java | 5 +- common/src/common/ai/AIFireballAttack.java | 6 +- .../common/ai/EntityAIControlledByPlayer.java | 2 +- common/src/common/ai/IEntityLivingNode.java | 21 + common/src/common/ai/IEntityMobNPCNode.java | 14 + common/src/common/ai/IEntityNPCNode.java | 9 + common/src/common/ai/IEntityNode.java | 15 +- common/src/common/entity/Entity.java | 19 +- .../common/entity/npc/AIHurtByAggressor.java | 22 + .../common/entity/npc/EntityChaosMarine.java | 2 +- .../src/common/entity/npc/EntityGargoyle.java | 4 - .../src/common/entity/npc/EntityMobNPC.java | 292 +--------- common/src/common/entity/npc/EntityNPC.java | 65 +-- .../common/entity/npc/EntitySpaceMarine.java | 2 +- .../src/common/entity/types/EntityLiving.java | 104 +--- common/src/common/util/Util.java | 8 + common/src/common/world/Region.java | 149 +---- common/src/common/world/WorldServer.java | 1 + server/src/server/Server.java | 70 ++- server/src/server/ai/EntityLivingNode.java | 537 ++++++++++++++++++ server/src/server/ai/EntityMobNPCNode.java | 84 +++ server/src/server/ai/EntityNPCNode.java | 128 +++-- server/src/server/ai/EntityNode.java | 427 +------------- server/src/server/init/NodeRegistry.java | 136 +++++ .../src/server}/world/Converter.java | 438 ++++---------- 27 files changed, 1160 insertions(+), 1622 deletions(-) delete mode 100755 client/src/client/gui/GuiConvert.java create mode 100644 common/src/common/ai/IEntityLivingNode.java create mode 100644 common/src/common/ai/IEntityMobNPCNode.java create mode 100644 common/src/common/ai/IEntityNPCNode.java create mode 100644 common/src/common/entity/npc/AIHurtByAggressor.java create mode 100644 server/src/server/ai/EntityLivingNode.java create mode 100644 server/src/server/ai/EntityMobNPCNode.java create mode 100644 server/src/server/init/NodeRegistry.java rename {client/src/client => server/src/server}/world/Converter.java (79%) diff --git a/client/src/client/Client.java b/client/src/client/Client.java index ddeec71..e0ab9f0 100755 --- a/client/src/client/Client.java +++ b/client/src/client/Client.java @@ -162,7 +162,6 @@ import common.util.Util; import common.util.HitPosition.ObjectType; import common.world.Chunk; import common.world.LightType; -import common.world.Region; import common.world.State; import common.world.World; import common.world.WorldClient; @@ -280,7 +279,7 @@ public class Client implements IThreadListener, IClient { private final List chat = Lists.newArrayList(); private final List feed = Lists.newArrayList(); private final List hotbar = Lists.newArrayList(); - private final File config = new File(System.getProperty("config.file", "game.cfg")); + private final File config = new File(System.getProperty("config.file", "client.cfg")); private boolean primary; private boolean secondary; @@ -1775,8 +1774,8 @@ public class Client implements IThreadListener, IClient { String.format("XYZ: %.3f / %.3f / %.3f", this.viewEntity.posX, this.viewEntity.getEntityBoundingBox().minY, this.viewEntity.posZ) + "\n" + String.format("Block: %d %d %d, R: '%s/%s'", blockpos.getX(), blockpos.getY(), blockpos.getZ(), - Region.getRegionFolder(blockpos.getX() >> 4, blockpos.getZ() >> 4), - Region.getRegionName(blockpos.getX() >> 4, blockpos.getZ() >> 4)) + "\n" + + Util.getRegionFolder(blockpos.getX() >> 4, blockpos.getZ() >> 4), + Util.getRegionName(blockpos.getX() >> 4, blockpos.getZ() >> 4)) + "\n" + String.format("Chunk: %d %d %d + %d %d %d, FOV: %.1f °%s", blockpos.getX() >> 4, blockpos.getY() >> 4, blockpos.getZ() >> 4, blockpos.getX() & 15, blockpos.getY() & 15, blockpos.getZ() & 15, this.zooming ? (this.fov / this.zoomLevel) : this.fov, this.zooming ? @@ -2217,7 +2216,6 @@ public class Client implements IThreadListener, IClient { Log.SYSTEM.info("Beende ..."); unload(false); this.getSoundManager().unload(); - Region.killIO(); this.renderGlobal.stopChunkBuilders(); if(audio.end()) Log.SOUND.info("Audiogerät geschlossen"); diff --git a/client/src/client/gui/GuiConvert.java b/client/src/client/gui/GuiConvert.java deleted file mode 100755 index e3e0a31..0000000 --- a/client/src/client/gui/GuiConvert.java +++ /dev/null @@ -1,214 +0,0 @@ -package client.gui; - -import java.io.File; -import java.io.FileFilter; -import java.text.SimpleDateFormat; -import java.util.Collections; -import java.util.Date; - -import client.Client.FileMode; -import client.gui.element.ActButton; -import client.gui.element.ActButton.Mode; -import client.gui.element.GuiList; -import client.gui.element.ListEntry; -import client.gui.element.NavButton; -import client.renderer.Drawing; -import client.world.Converter; -import common.color.TextColor; -import common.dimension.Space; -import common.log.Log; -import common.world.Region; -import common.world.World; -import common.world.Region.FolderInfo; -import common.world.Region.SaveVersion; - -public class GuiConvert extends GuiList implements ActButton.Callback -{ - protected class SaveInfo implements Comparable, ListEntry { - private final String file; - private final int dimensions; - private final int players; - private final long seed; - private final FolderInfo info; - - public SaveInfo(String file, int dimensions, int players, long seed, FolderInfo info) { - this.file = file; - this.dimensions = dimensions; - this.players = players; - this.seed = seed; - this.info = info; - } - - public String getFile() { - return this.file; - } - - public int getDimensions() { - return this.dimensions; - } - - public int getPlayers() { - return this.players; - } - - public boolean mustConvert() { - return this.info.legacy != null; - } - - public String getVersion() { - return this.info.legacy == null ? (this.info.version == null ? "" : this.info.version) : this.info.legacy.toString(); - } - - public boolean isIncompatible() { - return this.info.legacy == SaveVersion.RELEASE_1_13; - } - - public long getLastPlayed() { - return this.info.lastPlayed; - } - - public long getSeed() { - return this.seed; - } - - public int compareTo(SaveInfo comp) { - return this.info.lastPlayed < comp.info.lastPlayed ? 1 : (this.info.lastPlayed > comp.info.lastPlayed ? -1 : this.file.compareTo(comp.file)); - } - - public void select(boolean isDoubleClick, int mouseX, int mouseY) - { - boolean use = !this.isIncompatible() && this.mustConvert(); - GuiConvert.this.selectButton.enabled = use; - - if (isDoubleClick && use) - { - GuiConvert.this.use(GuiConvert.this.selectButton, Mode.PRIMARY); - } - } - - public void draw(int x, int y, int mouseXIn, int mouseYIn, boolean hover) - { - Drawing.drawText((this.isIncompatible() ? TextColor.DRED : "") + this.getFile() + (this.mustConvert() ? "" : - (TextColor.GRAY + " - " + TextColor.RESET + (this.getPlayers() > 0 ? this.getPlayers() + " Spieler" : "Keine Spieler"))), - x + 2, y, 0xffffffff); - Drawing.drawText((this.mustConvert() ? (this.isIncompatible() ? TextColor.CRIMSON : "") + this.getVersion() : (this.getDimensions() <= 0 ? "Keine Dimensionen" : this.getDimensions() + " Dimension" + (this.getDimensions() != 1 ? "en" : "") + " erschaffen")) - , x + 2, y + 18, 0xff808080); - Drawing.drawText(this.mustConvert() ? (this.isIncompatible() ? TextColor.CRIMSON + "Kann nicht konvertiert werden!" : - "Muss konvertiert werden!") : ( // "Kreativmodus: " + (info.isNoCreative() ? "Aus" : "An") + - "Zuletzt gespielt: " + DATE_FORMAT.format(new Date(this.getLastPlayed()))) + " " + TextColor.LGRAY + this.getVersion(), x + 2, y + 18 + 16, 0xff808080); - } - } - - public static final GuiConvert INSTANCE = new GuiConvert(); - private static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("dd.MM.yyyy HH:mm:ss"); - - private ActButton selectButton; - private File dir = null; - - private GuiConvert() - { - } - - private void load() { - this.elements.clear(); - if(this.dir == null || !this.dir.exists() || !this.dir.isDirectory()) - return; - try - { - File[] files = dir.listFiles(); - if(files == null) - throw new RuntimeException("Kann den Speicherordner für Welten nicht lesen oder öffnen!"); - for(File file : files) { - if(!file.isDirectory()) - continue; - FolderInfo info = Region.loadWorldInfo(file); - if(info == null) - info = Converter.convertMapFormat(file, false); - if(info == null) { - this.elements.add(new SaveInfo(file.getName(), -1, -1, - 0L, new FolderInfo(World.START_TIME, file.lastModified(), null, null))); - continue; - } - int dims = -1; - int players = -1; - if(info.legacy == null) { - dims = 0; - File[] folders = new File(new File(dir, file.getName()), "chunk").listFiles(new FileFilter() { - public boolean accept(File pathname) { - return pathname.isDirectory() && !pathname.getName().equals(Space.INSTANCE.getDimensionName()); - } - }); - if(folders != null) { - for(File sub : folders) { - File[] dim = sub.listFiles(); - if(dim != null && dim.length > 0) - dims++; - } - } - File[] plrs = new File(new File(dir, file.getName()), "players").listFiles(new FileFilter() { - public boolean accept(File pathname) { - return pathname.getName().endsWith(".nbt"); - } - }); - players = plrs == null ? 0 : plrs.length; - } - this.elements.add(new SaveInfo(file.getName(), dims, players, - 0L, info)); - } - Collections.sort(this.elements); - } - catch (Exception e) - { - Log.IO.error("Konnte Weltliste nicht laden", e); - this.elements.clear(); - } - } - - public void init(int width, int height) - { - super.init(width, height); - this.setDimensions(width, height, 32, height - 32); - - this.load(); - - this.add(this.selectButton = new ActButton(width / 2 - 383, height - 28, 150, 24, this, "Konvertieren")); - this.add(new NavButton(width / 2 + 233, height - 28, 150, 24, GuiMenu.INSTANCE, "Abbrechen")); - - this.add(new ActButton(4, 4, 200, 24, new ActButton.Callback() { - public void use(ActButton elem, ActButton.Mode action) { - if(GuiConvert.this.gm.world != null) - return; - GuiConvert.this.gm.showFileDialog(FileMode.DIRECTORY_LOAD, "Ordner wählen", GuiConvert.this.dir, new FileCallback() { - public void selected(File file) { - GuiConvert.this.dir = file; - GuiConvert.this.gm.displayGuiScreen(GuiConvert.this); - } - }); - } - }, "Ordner wählen ...")); - - this.selectButton.enabled = false; - } - - public String getTitle() { - return "Welt auswählen"; - } - - public int getListWidth() - { - return 660; - } - - public int getSlotHeight() - { - return 56; - } - - public void use(ActButton button, Mode mode) - { - String dir = this.getSelected().getFile(); - File folder = new File(this.dir, dir); - if(folder.isDirectory()) - Converter.convertMapFormat(folder, true); - } -} diff --git a/client/src/client/gui/GuiMenu.java b/client/src/client/gui/GuiMenu.java index 17a9f4e..54cbb34 100644 --- a/client/src/client/gui/GuiMenu.java +++ b/client/src/client/gui/GuiMenu.java @@ -94,12 +94,11 @@ public class GuiMenu extends Gui { } } }); - this.add(new NavButton(0, 102, 196, 24, GuiConvert.INSTANCE, "Welt konvertieren")); - this.add(new ActButton(204, 102, 196, 24, new ActButton.Callback() { + this.add(new ActButton(0, 102, 400, 24, new ActButton.Callback() { public void use(ActButton elem, ActButton.Mode action) { GuiMenu.this.gm.interrupted = true; } - }, "Spiel beenden")); + }, "Client schließen")); this.shift(); this.add(new Label(4, /* this.gm.fb_y - 2 */ 0, 200, 20, TextColor.VIOLET + Config.VERSION, true)); this.splashLabel = this.add(new Label(0, 160, width, 24, "")); diff --git a/common/src/common/ai/AIFireballAttack.java b/common/src/common/ai/AIFireballAttack.java index 87a3b8d..23b492c 100755 --- a/common/src/common/ai/AIFireballAttack.java +++ b/common/src/common/ai/AIFireballAttack.java @@ -30,7 +30,7 @@ public class AIFireballAttack extends EntityAIBase public boolean shouldExecute() { - return this.parentEntity.getAttackTarget() != null; + return this.parentEntity.getNode().getAttackTarget() != null; } public void startExecuting() @@ -45,7 +45,7 @@ public class AIFireballAttack extends EntityAIBase public void updateTask() { - EntityLiving target = this.parentEntity.getAttackTarget(); + EntityLiving target = this.parentEntity.getNode().getAttackTarget(); // double d0 = 64.0D; if (target.getDistanceSqToEntity(this.parentEntity) < this.distance * this.distance && this.parentEntity.canEntityBeSeen(target)) @@ -84,7 +84,7 @@ public class AIFireballAttack extends EntityAIBase world.spawnEntityInWorld(fireball); this.attackTimer = -this.delay * this.parentEntity.getRNG().range(1, 4); } - this.parentEntity.getLookHelper().setLookPositionWithEntity(target, 30.0f, 30.0f); + this.parentEntity.getNode().getLookHelper().setLookPositionWithEntity(target, 30.0f, 30.0f); } else if (this.attackTimer > 0) { diff --git a/common/src/common/ai/EntityAIControlledByPlayer.java b/common/src/common/ai/EntityAIControlledByPlayer.java index 320f4d1..1bee8cc 100755 --- a/common/src/common/ai/EntityAIControlledByPlayer.java +++ b/common/src/common/ai/EntityAIControlledByPlayer.java @@ -166,7 +166,7 @@ public class EntityAIControlledByPlayer extends EntityAIBase if (flag && 0 == WalkNodeProcessor.getColliding(this.thisEntity.worldObj, this.thisEntity, l, j, i1, j1, k1, l1, false, false, true) && 1 == WalkNodeProcessor.getColliding(this.thisEntity.worldObj, this.thisEntity, i, j + 1, k, j1, k1, l1, false, false, true) && 1 == WalkNodeProcessor.getColliding(this.thisEntity.worldObj, this.thisEntity, l, j + 1, i1, j1, k1, l1, false, false, true)) { - entitycreature.getJumpHelper().setJumping(); + entitycreature.getNode().getJumpHelper().setJumping(); } } diff --git a/common/src/common/ai/IEntityLivingNode.java b/common/src/common/ai/IEntityLivingNode.java new file mode 100644 index 0000000..6c10816 --- /dev/null +++ b/common/src/common/ai/IEntityLivingNode.java @@ -0,0 +1,21 @@ +package common.ai; + +import common.entity.DamageSource; +import common.entity.types.EntityLiving; +import common.nbt.NBTTagCompound; + +public interface IEntityLivingNode extends IEntityNode { + void update(); + void updateRenderAngles(); + void updateLeashedState(); + void setLeashTag(NBTTagCompound tag); + EntityLiving getAttacking(); + EntityLiving getAttackTarget(); + void resetCombat(); + void trackDamage(DamageSource source, int amount); + void sendDeathMessage(); + EntityJumpHelper getJumpHelper(); + EntityLookHelper getLookHelper(); + void updateAttacking(); + void dropExperience(); +} diff --git a/common/src/common/ai/IEntityMobNPCNode.java b/common/src/common/ai/IEntityMobNPCNode.java new file mode 100644 index 0000000..b913f8c --- /dev/null +++ b/common/src/common/ai/IEntityMobNPCNode.java @@ -0,0 +1,14 @@ +package common.ai; + +import common.entity.Entity; +import common.entity.types.EntityLiving; + +public interface IEntityMobNPCNode extends IEntityNPCNode { + + void becomeAngryAt(Entity entity); + + boolean isAngry(); + + void setAngerTarget(EntityLiving entity); + +} \ No newline at end of file diff --git a/common/src/common/ai/IEntityNPCNode.java b/common/src/common/ai/IEntityNPCNode.java new file mode 100644 index 0000000..f513d38 --- /dev/null +++ b/common/src/common/ai/IEntityNPCNode.java @@ -0,0 +1,9 @@ +package common.ai; + +import common.entity.types.EntityLiving; + +public interface IEntityNPCNode extends IEntityLivingNode { + void setCombatTask(); + boolean canCounter(EntityLiving entity); + boolean canAttack(EntityLiving entity); +} diff --git a/common/src/common/ai/IEntityNode.java b/common/src/common/ai/IEntityNode.java index d4d89ee..d38f988 100644 --- a/common/src/common/ai/IEntityNode.java +++ b/common/src/common/ai/IEntityNode.java @@ -1,17 +1,10 @@ package common.ai; -import common.entity.DamageSource; -import common.entity.types.EntityLiving; import common.nbt.NBTTagCompound; +import common.world.World; public interface IEntityNode { - void update(); - void updateRenderAngles(); - void updateLeashedState(); - void setLeashTag(NBTTagCompound tag); - EntityLiving getAttacking(); - EntityLiving getAttackTarget(); - void resetCombat(); - void trackDamage(DamageSource source, int amount); - void sendDeathMessage(); + void readNbt(NBTTagCompound tag); + void writeNbt(NBTTagCompound tag); + void setWorld(World world); } diff --git a/common/src/common/entity/Entity.java b/common/src/common/entity/Entity.java index 61d7871..8921c9a 100755 --- a/common/src/common/entity/Entity.java +++ b/common/src/common/entity/Entity.java @@ -2,6 +2,8 @@ package common.entity; import java.util.List; +import common.ai.IEntityLivingNode; +import common.ai.IEntityNode; import common.block.Block; import common.block.BlockFence; import common.block.BlockFenceGate; @@ -45,13 +47,14 @@ import common.world.State; import common.world.World; import common.world.WorldServer; -public abstract class Entity +public abstract class Entity { private static final BoundingBox ZERO_AABB = new BoundingBox(0.0D, 0.0D, 0.0D, 0.0D, 0.0D, 0.0D); private static int nextID; protected final DataWatcher dataWatcher; protected final Random rand; + protected T node; private int eid; public World worldObj; @@ -117,6 +120,14 @@ public abstract class Entity public boolean isAirBorne; protected PortalType inPortal; // private boolean invulnerable; + + public T getNode() { + return this.node; + } + + public void setNode(T node) { + this.node = node; + } public int getId() { @@ -1130,6 +1141,8 @@ public abstract class Entity public void setWorld(World worldIn) { this.worldObj = worldIn; + if(this.node != null) + this.node.setWorld(worldIn); } /** @@ -1523,6 +1536,8 @@ public abstract class Entity tagCompund.setBoolean("IgnoreFall", this.ignoreFall); this.writeEntityToNBT(tagCompund); + if(this.node != null) + this.node.writeNbt(tagCompund); if (this.vehicle != null && !(this.isPlayer())) { @@ -1592,6 +1607,8 @@ public abstract class Entity // this.setSilent(tagCompund.getBoolean("Silent")); this.ignoreFall = tagCompund.getBoolean("IgnoreFall"); this.readEntityFromNBT(tagCompund); + if(this.node != null) + this.node.readNbt(tagCompund); if (this.shouldSetPosAfterLoading()) { diff --git a/common/src/common/entity/npc/AIHurtByAggressor.java b/common/src/common/entity/npc/AIHurtByAggressor.java new file mode 100644 index 0000000..fe7838e --- /dev/null +++ b/common/src/common/entity/npc/AIHurtByAggressor.java @@ -0,0 +1,22 @@ +package common.entity.npc; + +import common.ai.EntityAIHurtByTarget; +import common.entity.types.EntityLiving; + +public class AIHurtByAggressor extends EntityAIHurtByTarget +{ + public AIHurtByAggressor(EntityMobNPC p_i45828_1_) + { + super(p_i45828_1_, true); + } + + protected void setEntityAttackTarget(EntityLiving creatureIn, EntityLiving entityLivingBaseIn) + { + super.setEntityAttackTarget(creatureIn, entityLivingBaseIn); + + if (creatureIn.getClass() == this.taskOwner.getClass()) + { + ((EntityMobNPC)creatureIn).getNode().becomeAngryAt(entityLivingBaseIn); + } + } +} \ No newline at end of file diff --git a/common/src/common/entity/npc/EntityChaosMarine.java b/common/src/common/entity/npc/EntityChaosMarine.java index cccb1b3..1e18b2a 100755 --- a/common/src/common/entity/npc/EntityChaosMarine.java +++ b/common/src/common/entity/npc/EntityChaosMarine.java @@ -108,7 +108,7 @@ public class EntityChaosMarine extends EntityNPC { return 20; } - protected int getAttackSpeed() { + public int getAttackSpeed() { return 5; } diff --git a/common/src/common/entity/npc/EntityGargoyle.java b/common/src/common/entity/npc/EntityGargoyle.java index 0f6b358..69914e3 100755 --- a/common/src/common/entity/npc/EntityGargoyle.java +++ b/common/src/common/entity/npc/EntityGargoyle.java @@ -141,10 +141,6 @@ public class EntityGargoyle extends EntityFlyingNPC // this.launchBoxToEntity(target); // } - public boolean isRangedWeapon(ItemStack stack) { - return false; - } - public boolean attackEntityFrom(DamageSource source, int amount) { // if (this.isEntityInvulnerable(source)) diff --git a/common/src/common/entity/npc/EntityMobNPC.java b/common/src/common/entity/npc/EntityMobNPC.java index e36c35f..c504d19 100755 --- a/common/src/common/entity/npc/EntityMobNPC.java +++ b/common/src/common/entity/npc/EntityMobNPC.java @@ -1,317 +1,45 @@ package common.entity.npc; -import common.ai.EntityAIHurtByTarget; +import common.ai.IEntityMobNPCNode; import common.entity.DamageSource; import common.entity.Entity; -import common.entity.attributes.AttributeInstance; -import common.entity.attributes.Attributes; import common.entity.types.EntityLiving; -import common.nbt.NBTTagCompound; import common.world.World; -public abstract class EntityMobNPC extends EntityNPC +public abstract class EntityMobNPC extends EntityNPC { - private int angerLevel; -// private int randomSoundDelay; - private int angerTarget; -// private Class angerClass; - + public T getNode() { + return this.node; + } + public EntityMobNPC(World worldIn) { super(worldIn); - this.targets.addTask(1, new AIHurtByAggressor(this)); -// this.targets.addTask(2, new AITargetAggressor(this)); } -// public boolean isImmuneToFire() -// { -// return true; -// } - public void setAttackedBy(EntityLiving livingBase) { super.setAttackedBy(livingBase); if (livingBase != null) { - this.angerTarget = livingBase.getId(); + this.node.setAngerTarget(livingBase); } } - -// protected void applyEntityAI() -// { -// this.targets.addTask(1, new EntityMobNPC.AIHurtByAggressor(this)); -// this.targets.addTask(2, new EntityMobNPC.AITargetAggressor(this)); -// } - -// protected void applyEntityAttributes() -// { -// super.applyEntityAttributes(); -// this.getEntityAttribute(Attributes.REINFORCEMENT_CHANCE).setBaseValue(0.0D); -// this.getEntityAttribute(Attributes.MOVEMENT_SPEED).setBaseValue(0.23000000417232513D); -// this.getEntityAttribute(Attributes.ATTACK_DAMAGE).setBaseValue(5.0D); -// } - -// /** -// * Called to update the entity's position/logic. -// */ -// public void onUpdate() -// { -// super.onUpdate(); -// } - - protected void updateAITasks() - { - AttributeInstance iattributeinstance = this.getEntityAttribute(Attributes.MOVEMENT_SPEED); - - if (this.isAngry()) - { - if (/* !this.isChild() && */ !iattributeinstance.hasModifier(Attributes.RUSHING_SPEED_MOD)) - { - iattributeinstance.applyModifier(Attributes.RUSHING_SPEED_MOD); - } - - --this.angerLevel; - } - else if (iattributeinstance.hasModifier(Attributes.RUSHING_SPEED_MOD)) - { - iattributeinstance.removeModifier(Attributes.RUSHING_SPEED_MOD); - } - -// if (this.randomSoundDelay > 0 && --this.randomSoundDelay == 0) -// { -// this.playSound("mob.zombiepig.zpigangry", this.getSoundVolume() * 2.0F, ((this.rand.floatv() - this.rand.floatv()) * 0.2F + 1.0F) * 1.8F); -// } - - if (this.angerLevel > 0 && this.angerTarget != 0 && this.getAttackedBy() == null) - { - Entity entity = this.worldObj.getEntityByID(this.angerTarget); - if(entity instanceof EntityLiving) - this.setAttackedBy((EntityLiving)entity); - if(entity != null && entity.isPlayer()) - this.playerAttacker = (EntityNPC)entity; - this.recentlyHit = this.getAttackedTime(); - } - - super.updateAITasks(); - } - -// /** -// * Checks if the entity's current position is a valid location to spawn this entity. -// */ -// public boolean getCanSpawnHere() -// { -// return this.worldObj.getDifficulty() != Difficulty.PEACEFUL; -// } - - /** - * (abstract) Protected helper method to write subclass entity data to NBT. - */ - public void writeEntityToNBT(NBTTagCompound tagCompound) - { - super.writeEntityToNBT(tagCompound); - tagCompound.setShort("Anger", (short)this.angerLevel); - -// if (this.angerTarget != null) -// { -// tagCompound.setString("HurtBy", this.angerTarget); -// } -// else -// { -// tagCompound.setString("HurtBy", ""); -// } - } - - /** - * (abstract) Protected helper method to read subclass entity data from NBT. - */ - public void readEntityFromNBT(NBTTagCompound tagCompund) - { - super.readEntityFromNBT(tagCompund); - this.angerLevel = tagCompund.getShort("Anger"); -// String s = tagCompund.getString("HurtBy"); -// -// if (s.length() > 0) -// { -// this.angerTarget = s; -// EntityNPC entityplayer = this.worldObj.getPlayer(this.angerTarget); -// this.setAttackedBy(entityplayer); -// -// if (entityplayer != null) -// { -// this.playerAttacker = entityplayer; -// this.recentlyHit = this.getAttackedTime(); -// } -// } - } - - /** - * Called when the entity is attacked. - */ + public boolean attackEntityFrom(DamageSource source, int amount) { -// if (this.isEntityInvulnerable(source)) -// { -// return false; -// } -// else -// { Entity entity = source.getEntity(); if (entity != null && entity instanceof EntityNPC) { - this.becomeAngryAt(entity); + this.node.becomeAngryAt(entity); } return super.attackEntityFrom(source, amount); -// } } - /** - * Causes this PigZombie to become angry at the supplied Entity (which will be a player). - */ - private void becomeAngryAt(Entity p_70835_1_) - { - this.angerLevel = this.rand.excl(400, 800); -// this.randomSoundDelay = this.rand.zrange(40); - - if (p_70835_1_ instanceof EntityLiving) - { - this.setAttackedBy((EntityLiving)p_70835_1_); - } - } - - public boolean isAngry() - { - return this.angerLevel > 0; - } - -// /** -// * Returns the sound this mob makes while it's alive. -// */ -// protected String getLivingSound() -// { -// return "mob.zombiepig.zpig"; -// } -// -// /** -// * Returns the sound this mob makes when it is hurt. -// */ -// protected String getHurtSound() -// { -// return "mob.zombiepig.zpighurt"; -// } -// -// /** -// * Returns the sound this mob makes on death. -// */ -// protected String getDeathSound() -// { -// return "mob.zombiepig.zpigdeath"; -// } - -// /** -// * Drop 0-2 items of this living's type -// * -// * @param wasRecentlyHit true if this this entity was recently hit by appropriate entity (generally only if player -// * or tameable) -// * @param lootingModifier level of enchanment to be applied to this drop -// */ -// protected void dropFewItems(boolean wasRecentlyHit, int lootingModifier) -// { -// int i = this.rand.zrange(2 + lootingModifier); -// -// for (int j = 0; j < i; ++j) -// { -// this.dropItem(Items.rotten_flesh, 1); -// } -// -// i = this.rand.zrange(2 + lootingModifier); -// -// for (int k = 0; k < i; ++k) -// { -// this.dropItem(Items.gold_nugget, 1); -// } -// } -// -// /** -// * Called when a player interacts with a mob. e.g. gets milk from a cow, gets into the saddle on a pig. -// */ -// public boolean interact(EntityNPC player) -// { -// return false; -// } -// -// /** -// * Causes this Entity to drop a random item. -// */ -// protected void addRandomDrop() -// { -// this.dropItem(Items.gold_ingot, 1); -// } -// -// /** -// * Gives armor or weapon for entity based on given DifficultyInstance -// */ -// protected void setEquipmentBasedOnDifficulty(DifficultyInstance difficulty) -// { -// this.setItem(0, new ItemStack(Items.golden_sword)); -// } -// -// /** -// * Called only once on an entity when first time spawned, via egg, mob spawner, natural spawning etc, but not called -// * when entity is reloaded from nbt. Mainly used for initializing attributes and inventory -// */ -// public IEntityLivingData onInitialSpawn(DifficultyInstance difficulty, IEntityLivingData livingdata) -// { -// super.onInitialSpawn(difficulty, livingdata); -//// this.setVillager(false); -// return livingdata; -// } - -// public int getColor() { -// return 0xff9494; -// } - -// public void onStruckByLightning(EntityLightning lightningBolt) { -// } - public boolean isAggressive(Class clazz) { - return this.isAngry() && clazz != this.getClass() && !this.isPeaceful(clazz); + return this.node.isAngry() && clazz != this.getClass() && !this.isPeaceful(clazz); } - - static class AIHurtByAggressor extends EntityAIHurtByTarget - { - public AIHurtByAggressor(EntityMobNPC p_i45828_1_) - { - super(p_i45828_1_, true); - } - - protected void setEntityAttackTarget(EntityLiving creatureIn, EntityLiving entityLivingBaseIn) - { - super.setEntityAttackTarget(creatureIn, entityLivingBaseIn); - - if (creatureIn.getClass() == this.taskOwner.getClass()) - { - ((EntityMobNPC)creatureIn).becomeAngryAt(entityLivingBaseIn); - } - } - } - -// static class AITargetAggressor extends EntityAINearestAttackableTarget -// { -// public AITargetAggressor(EntityMobNPC p_i45829_1_) -// { -// super(p_i45829_1_, EntityLiving.class, 10, true, false, new Predicate() { -// public boolean test(EntityLiving entity) { -// return entity.isPlayer(); // || entity instanceof EntityNPC; -// } -// }); -// } -// -// public boolean shouldExecute() -// { -// return ((EntityMobNPC)this.taskOwner).isAngry() && super.shouldExecute(); -// } -// } } diff --git a/common/src/common/entity/npc/EntityNPC.java b/common/src/common/entity/npc/EntityNPC.java index ffd5e7b..9eb5926 100755 --- a/common/src/common/entity/npc/EntityNPC.java +++ b/common/src/common/entity/npc/EntityNPC.java @@ -2,24 +2,8 @@ package common.entity.npc; import java.lang.reflect.InvocationTargetException; import java.util.List; -import java.util.function.Predicate; - import common.IClient; -import common.ai.AIRangedAttack; -import common.ai.EntityAIAttackOnCollide; -import common.ai.EntityAIAvoidEntity; -import common.ai.EntityAIHurtByTarget; -import common.ai.EntityAILookAtTalkingPlayer; -import common.ai.EntityAINagPlayer; -import common.ai.EntityAINearestAttackableTarget; -import common.ai.EntityAINpcInteract; -import common.ai.EntityAINpcMate; -import common.ai.EntityAIOpenDoor; -import common.ai.EntityAIPlay; -import common.ai.EntityAISwimming; -import common.ai.EntityAIWander; -import common.ai.EntityAIWatchClosest; -import common.ai.EntityAIWatchClosest2; +import common.ai.IEntityNPCNode; import common.block.Block; import common.block.BlockBed; import common.dimension.Space; @@ -78,7 +62,6 @@ import common.packet.CPacketInput; import common.packet.CPacketPlayer; import common.packet.SPacketEntityEquipment; import common.packet.SPacketEntityVelocity; -import common.pathfinding.PathNavigateGround; import common.potion.Potion; import common.potion.PotionEffect; import common.rng.Random; @@ -98,7 +81,7 @@ import common.world.World; import common.world.WorldClient; import common.world.WorldServer; -public abstract class EntityNPC extends EntityLiving +public abstract class EntityNPC extends EntityLiving { public static class CharacterTypeData { @@ -210,6 +193,10 @@ public abstract class EntityNPC extends EntityLiving private float horseJumpPower; // public float nausea; // public float prevNausea; + + public T getNode() { + return this.node; + } public EntityNPC(World worldIn) { @@ -260,53 +247,20 @@ public abstract class EntityNPC extends EntityLiving return this.connection != null || this.gm != null; } - - - public final boolean canInfight(Alignment align) { - return this.alignment.chaotic || (!this.alignment.lawful && - ((this.alignment.good && align.evil) || (this.alignment.evil && align.good))); - } - - public final boolean canMurder(Alignment align) { - return this.alignment.chaotic && ((this.alignment.good && align.evil) || (this.alignment.evil && align.good)); - } - - public boolean canCounter(EntityLiving entity) { - return !(entity instanceof EntityNPC) || - (this.getClass() == entity.getClass() ? this.canInfight(((EntityNPC)entity).alignment) : - !this.isPeaceful(((EntityNPC)entity).getClass())); - } - - public boolean canAttack(EntityLiving entity) { - return entity instanceof EntityNPC && (this.getClass() == entity.getClass() ? this.canMurder(((EntityNPC)entity).alignment) : - this.isAggressive(((EntityNPC)entity).getClass())); - } - public boolean canAmbush(EntityLiving entity) { return true; } - public boolean shouldFlee(EntityLiving entity) { - return (this.getHealth() <= (this.getMaxHealth() / 4) || !this.canCounter(entity)) && - ((entity instanceof EntityNPC && (((EntityNPC)entity).canAttack(this)) || - (entity == this.getAttackedBy() && ((EntityNPC)entity).canCounter(this)))); - } - // public void setCombatTask() // { // } - public boolean isRangedWeapon(ItemStack stack) { - return stack != null && (stack.getItem() == Items.bow || stack.getItem() instanceof ItemGunBase || - stack.getItem() == Items.snowball || stack.getItem() == Items.potion); - } - // public boolean isSneaking() // { // return true; // } - protected int getAttackSpeed() { + public int getAttackSpeed() { return 20; } @@ -724,6 +678,11 @@ public abstract class EntityNPC extends EntityLiving return Alignment.values()[this.dataWatcher.getWatchableObjectByte(18) % Alignment.values().length]; } + public Alignment getAlignmentCached() + { + return this.alignment; + } + public void setHeight(float height) { this.dataWatcher.updateObject(29, ExtMath.clampf(height, 0.2f, 10.0f)); diff --git a/common/src/common/entity/npc/EntitySpaceMarine.java b/common/src/common/entity/npc/EntitySpaceMarine.java index 9bc645f..ec25e30 100755 --- a/common/src/common/entity/npc/EntitySpaceMarine.java +++ b/common/src/common/entity/npc/EntitySpaceMarine.java @@ -108,7 +108,7 @@ public class EntitySpaceMarine extends EntityNPC { return 20; } - protected int getAttackSpeed() { + public int getAttackSpeed() { return 5; } diff --git a/common/src/common/entity/types/EntityLiving.java b/common/src/common/entity/types/EntityLiving.java index 96d6709..9e1ee6b 100755 --- a/common/src/common/entity/types/EntityLiving.java +++ b/common/src/common/entity/types/EntityLiving.java @@ -6,7 +6,7 @@ import java.util.List; import java.util.Map; import java.util.function.Predicate; -import common.ai.IEntityNode; +import common.ai.IEntityLivingNode; import common.block.Block; import common.block.SoundType; import common.collect.Maps; @@ -57,11 +57,10 @@ import common.world.State; import common.world.World; import common.world.WorldServer; -public abstract class EntityLiving extends Entity +public abstract class EntityLiving extends Entity { private static final ItemStack[] EMPTY_INV = new ItemStack[5]; - protected IEntityNode node; private AttributeMap attributes; private final Map effects = Maps.newEnumMap(Potion.class); public int soundTimer; @@ -105,13 +104,6 @@ public abstract class EntityLiving extends Entity public int maxHurtTime; public int deathTime; public int hurtCooldown = 20; - protected int lastDamage; - protected EntityNPC playerAttacker; - protected int recentlyHit; - private EntityLiving attackedBy; - private int lastAttacked; - private EntityLiving attacker; - private int lastAttackTime; // protected int entityAge; private int absorptionAmount; @@ -128,6 +120,10 @@ public abstract class EntityLiving extends Entity protected int growingAge; private float ageWidth = -1.0F; private float ageHeight; + + public T getNode() { + return this.node; + } public EntityLiving(World worldIn) { @@ -297,37 +293,9 @@ public abstract class EntityLiving extends Entity this.onDeathUpdate(); } - if (this.recentlyHit > 0) - { - --this.recentlyHit; - } - else - { - this.playerAttacker = null; - } - - if (this.attacker != null && !this.attacker.isEntityAlive()) - { - this.attacker = null; - } - -// if(this.attackedBy.isPlayer() && ((EntityNPC)this.attackedBy).capabilities.isCreativeMode) { -// this.attackedBy = null; // FIX Creative -// } - - if (this.attackedBy != null) - { - if (!this.attackedBy.isEntityAlive()) - { - this.setAttackedBy(null); - } - else if (this.ticksExisted - this.lastAttacked > 100) - { - this.setAttackedBy(null); - } - } - if(!this.worldObj.client) { + this.node.updateAttacking(); + if(!this.firstEffectUpdate && Config.radiation) { // && // (!(this.isPlayer()) || !((EntityNPCMP)this).creative)) { float radiation = this.radiation + (float)this.attributes.getAttributeInstance(Attributes.RADIATION).getAttributeValue(); @@ -389,16 +357,9 @@ public abstract class EntityLiving extends Entity if (this.deathTime == 20) { - if (!this.worldObj.client && (this.recentlyHit > 0 || this.isPlayer()) && this.canDropLoot() && Config.mobXP) + if (!this.worldObj.client) { - int i = this.getExperiencePoints(this.playerAttacker); - - while (i > 0) - { - int j = EntityXp.getXPSplit(i); - i -= j; - this.worldObj.spawnEntityInWorld(new EntityXp(this.worldObj, this.posX, this.posY, this.posZ, j)); - } + this.node.dropExperience(); } this.setDead(); @@ -452,46 +413,6 @@ public abstract class EntityLiving extends Entity return this.rand; } - public EntityLiving getAttackedBy() - { - return this.attackedBy; - } - - public int getAttackedTime() - { - return this.lastAttacked; - } - - public void setAttackedBy(EntityLiving livingBase) - { - this.attackedBy = livingBase; - this.lastAttacked = this.ticksExisted; - } - - public EntityLiving getLastAttack() - { - return this.attacker; - } - - public int getLastAttackTime() - { - return this.lastAttackTime; - } - - public void setLastAttack(Entity entity) - { - if (entity instanceof EntityLiving) - { - this.attacker = (EntityLiving)entity; - } - else - { - this.attacker = null; - } - - this.lastAttackTime = this.ticksExisted; - } - // public int getAge() // { // return this.entityAge; @@ -1336,11 +1257,6 @@ public abstract class EntityLiving extends Entity // } } - public EntityLiving getAttackingEntity() - { - return (EntityLiving)(this.node.getAttacking() != null ? this.node.getAttacking() : (this.playerAttacker != null ? this.playerAttacker : (this.attackedBy != null ? this.attackedBy : null))); - } - public final int getMaxHealth() { return (int)this.getEntityAttribute(Attributes.MAX_HEALTH).getAttributeValue(); diff --git a/common/src/common/util/Util.java b/common/src/common/util/Util.java index fe4734b..629ef96 100644 --- a/common/src/common/util/Util.java +++ b/common/src/common/util/Util.java @@ -389,4 +389,12 @@ int utf_len(const char *str) { public static double ftime() { return ((double)rtime()) / 1000000.0; } + + public static String getRegionFolder(int x, int z) { + return String.format("%c%03X%c%03X", x < 0 ? 'n' : 'p', ((x < 0) ? -x : x) >> 9, z < 0 ? 'n' : 'p', ((z < 0) ? -z : z) >> 9); + } + + public static String getRegionName(int x, int z) { + return String.format("r.%c%X%c%X.rgn", x < 0 ? 'n' : 'p', ((x < 0) ? -x : x) >> 3, z < 0 ? 'n' : 'p', ((z < 0) ? -z : z) >> 3); + } } diff --git a/common/src/common/world/Region.java b/common/src/common/world/Region.java index 06bbb84..ea0a6ae 100755 --- a/common/src/common/world/Region.java +++ b/common/src/common/world/Region.java @@ -22,9 +22,7 @@ import common.collect.Lists; import common.collect.Maps; import common.entity.Entity; import common.init.BlockRegistry; -import common.init.Config; import common.init.EntityRegistry; -import common.init.UniverseRegistry; import common.log.Log; import common.nbt.NBTLoader; import common.nbt.NBTTagCompound; @@ -33,39 +31,9 @@ import common.tileentity.TileEntity; import common.util.BlockPos; import common.util.NextTickListEntry; import common.util.NibbleArray; +import common.util.Util; public class Region { - public static enum SaveVersion { - ALPHA_1_0("Alpha 1.0 - Beta 1.2"), - BETA_1_3("Beta 1.3 - Release 1.8.9"), - RELEASE_1_9("Release 1.9 - Release 1.12.2"), - RELEASE_1_13("Release 1.13 +"); - - private final String name; - - private SaveVersion(String name) { - this.name = name; - } - - public String toString() { - return this.name; - } - } - - public static class FolderInfo { - public final long time; - public final long lastPlayed; - public final SaveVersion legacy; - public final String version; - - public FolderInfo(long time, long lastPlayed, SaveVersion legacy, String version) { - this.time = time; - this.lastPlayed = lastPlayed; - this.legacy = legacy; - this.version = version; - } - } - private static class ChunkBuffer extends ByteArrayOutputStream { public ChunkBuffer() { super(8096); @@ -90,10 +58,7 @@ public class Region { private static final Map CACHE = Maps.newHashMap(); private static final List QUEUE = Collections.synchronizedList(Lists.newArrayList()); - -// public static long lastPlayed; -// public static int version; -// public static String owner; + private static volatile long queued; private static volatile long saved; private static volatile boolean waiting; @@ -113,10 +78,10 @@ public class Region { private boolean modified; public Region(File dir, int x, int z) { - File sdir = new File(dir, getRegionFolder(x << 3, z << 3)); + File sdir = new File(dir, Util.getRegionFolder(x << 3, z << 3)); if(!sdir.exists()) sdir.mkdirs(); - this.regFile = new File(sdir, getRegionName(x << 3, z << 3)); + this.regFile = new File(sdir, Util.getRegionName(x << 3, z << 3)); this.folder = dir; this.xPos = x; this.zPos = z; @@ -313,13 +278,6 @@ public class Region { this.write(x, z, buf.getData(), buf.size()); } -// public NBTTagCompound readTag(int x, int z) throws IOException { -// byte[] data = this.read(x, z); -// if(data == null) -// return null; -// return CompressedStreamTools.read(new DataInputStream(new BufferedInputStream(new InflaterInputStream(new ByteArrayInputStream(data))))); -// } - public File getFile() { return this.regFile; } @@ -336,7 +294,7 @@ public class Region { } private static File getExpansionFile(File dir, int x, int z) { - File sdir = new File(dir, getRegionFolder(x, z)); + File sdir = new File(dir, Util.getRegionFolder(x, z)); if(!sdir.exists()) sdir.mkdirs(); return new File(sdir, String.format("c.%c%X%c%X.chk", x < 0 ? 'n' : 'p', (x < 0) ? -x : x, z < 0 ? 'n' : 'p', (z < 0) ? -z : z)); @@ -399,14 +357,6 @@ public class Region { // getRegionFile(dir, x >> 3, z >> 3).writeTag(x & 7, z & 7, tag); } - public static String getRegionFolder(int x, int z) { - return String.format("%c%03X%c%03X", x < 0 ? 'n' : 'p', ((x < 0) ? -x : x) >> 9, z < 0 ? 'n' : 'p', ((z < 0) ? -z : z) >> 9); - } - - public static String getRegionName(int x, int z) { - return String.format("r.%c%X%c%X.rgn", x < 0 ? 'n' : 'p', ((x < 0) ? -x : x) >> 3, z < 0 ? 'n' : 'p', ((z < 0) ? -z : z) >> 3); - } - public static Chunk readNbt(WorldServer world, int x, int z, NBTTagCompound tag) { // if(!tag.hasKey("Level", 10)) { // Log.error("Chunk-Datei bei " + x + "," + z + " hat keine Level-Daten, überspringe"); @@ -680,93 +630,4 @@ public class Region { public static void killIO() { killed = true; } - - public static void saveWorldInfo(File worldDir, long time) { - NBTTagCompound data = new NBTTagCompound(); - data.setLong("Time", time); - data.setLong("LastAccess", System.currentTimeMillis()); - data.setString("Version", Config.VERSION); - NBTTagCompound cfg = new NBTTagCompound(); - for(String cvar : Config.VARS.keySet()) { - cfg.setString(cvar, Config.VARS.get(cvar).getValue()); -// Config.Value value = Config.VARS.get(cvar); -// switch(value.getType()) { -// case BOOLEAN: -// cfg.setString(cvar, "" + value.getBoolean()); -// break; -// case INTEGER: -// cfg.setString(cvar, "" + value.getInt()); -// break; -// case FLOAT: -// cfg.setString(cvar, "" + value.getFloat()); -// break; -// case STRING: -// cfg.setString(cvar, value.getString()); -// break; -// } - } - data.setTag("Config", cfg); - data.setTag("Universe", UniverseRegistry.saveNbt()); - if(worldDir != null) - worldDir.mkdirs(); - File nfile = new File(worldDir, "level.nbt.tmp"); - File lfile = new File(worldDir, "level.nbt"); - try { -// File ofile = new File(worldDir, "level.nbt_old"); - NBTLoader.writeGZip(data, nfile); -// if(ofile.exists()) -// ofile.delete(); -// lfile.renameTo(ofile); - if(lfile.exists()) - lfile.delete(); - nfile.renameTo(lfile); -// if(nfile.exists()) -// nfile.delete(); - } - catch(Exception e) { - Log.JNI.error(e, "Fehler beim Schreiben von " + nfile); - } - } - - public static FolderInfo loadWorldInfo(File worldDir) { - Config.clear(); - UniverseRegistry.clear(); - File file = new File(worldDir, "level.nbt"); - if(!file.exists()) - file = new File(worldDir, "level.nbt.tmp"); - if(file.exists()) { - try { - NBTTagCompound tag = NBTLoader.readGZip(file); - NBTTagCompound cfg = tag.getCompoundTag("Config"); - for(String key : cfg.getKeySet()) { - Config.set(key, cfg.getString(key), null); - } - UniverseRegistry.loadNbt(tag.getCompoundTag("Universe")); - // tag.getInteger("Version"); - long lastPlayed = tag.getLong("LastAccess"); - String version = tag.hasKey("Version", 8) ? tag.getString("Version") : null; - version = version != null && version.isEmpty() ? null : version; - long time = tag.hasKey("Time", 4) ? tag.getLong("Time") : World.START_TIME; - return new FolderInfo(time, lastPlayed, null, version); - } - catch(Exception e) { - Log.JNI.error(e, "Fehler beim Lesen von " + file); - } - } - return null; - } - -// public static void reloadWorldInfo(File worldDir) { -// File file = new File(worldDir, "level.nbt"); -// if(file.exists()) { -// Config.clear(); -// try { -// Config.readFromNbt(NBTLoader.readGZip(file).getCompoundTag("Config"), true); -// } -// catch(Exception e) { -// Log.error("Fehler beim Lesen von " + file, e); -// return; -// } -// } -// } } diff --git a/common/src/common/world/WorldServer.java b/common/src/common/world/WorldServer.java index 934b9ee..e6edce1 100755 --- a/common/src/common/world/WorldServer.java +++ b/common/src/common/world/WorldServer.java @@ -962,6 +962,7 @@ public final class WorldServer extends World { } protected void onEntityAdded(Entity entityIn) { + // TODO: add node this.trackEntity(entityIn); this.entityIds.addKey(entityIn.getId(), entityIn); Entity[] aentity = entityIn.getParts(); diff --git a/server/src/server/Server.java b/server/src/server/Server.java index 728a53d..c69725b 100755 --- a/server/src/server/Server.java +++ b/server/src/server/Server.java @@ -6,9 +6,11 @@ import java.io.File; import java.io.IOException; import java.io.InputStreamReader; import java.net.InetAddress; +import java.text.SimpleDateFormat; import java.util.ArrayDeque; import java.util.ArrayList; import java.util.Collections; +import java.util.Date; import java.util.Iterator; import java.util.List; import java.util.Map; @@ -74,7 +76,6 @@ import common.util.WorldPos; import common.world.Region; import common.world.World; import common.world.WorldServer; -import common.world.Region.FolderInfo; import io.netty.bootstrap.ServerBootstrap; import io.netty.channel.Channel; import io.netty.channel.ChannelException; @@ -90,8 +91,10 @@ import io.netty.util.concurrent.Future; import io.netty.util.concurrent.GenericFutureListener; import server.command.CommandEnvironment; import server.command.FixedExecutor; +import server.init.NodeRegistry; import server.network.HandshakeHandler; import server.network.Player; +import server.world.Converter; public final class Server implements IThreadListener, IServer { private static final LazyLoadBase SERVER_NIO_EVENTLOOP = new LazyLoadBase() { @@ -141,6 +144,7 @@ public final class Server implements IThreadListener, IServer { public static void main(String[] args) { Util.checkOs(); Registry.setup("Server thread"); + NodeRegistry.register(); boolean debug = System.getProperty("server.debug", null) != null; boolean ipc = debug || System.getProperty("server.pipe", null) != null; int port = Integer.parseInt(System.getProperty("server.port", "" + Config.PORT)); @@ -155,6 +159,63 @@ public final class Server implements IThreadListener, IServer { Log.flushLog(); } + public static void saveServerConfig(long time) { + NBTTagCompound data = new NBTTagCompound(); + data.setLong("Time", time); + data.setLong("LastAccess", System.currentTimeMillis()); + data.setString("Version", Config.VERSION); + NBTTagCompound cfg = new NBTTagCompound(); + for(String cvar : Config.VARS.keySet()) { + cfg.setString(cvar, Config.VARS.get(cvar).getValue()); + } + data.setTag("Config", cfg); + data.setTag("Universe", UniverseRegistry.saveNbt()); + File nfile = new File("server.nbt.tmp"); + File lfile = new File("server.nbt"); + try { + NBTLoader.writeGZip(data, nfile); + if(lfile.exists()) + lfile.delete(); + nfile.renameTo(lfile); + } + catch(Exception e) { + Log.IO.error(e, "Fehler beim Schreiben von " + nfile); + } + } + + public static long loadServerConfig() { + Config.clear(); + UniverseRegistry.clear(); + File file = new File("server.nbt"); + if(!file.exists()) + file = new File("server.nbt.tmp"); + if(file.exists()) { + try { + NBTTagCompound tag = NBTLoader.readGZip(file); + NBTTagCompound cfg = tag.getCompoundTag("Config"); + for(String key : cfg.getKeySet()) { + Config.set(key, cfg.getString(key), null); + } + UniverseRegistry.loadNbt(tag.getCompoundTag("Universe")); + long lastPlayed = tag.getLong("LastAccess"); + String version = tag.hasKey("Version", 8) ? tag.getString("Version") : null; + version = version != null && version.isEmpty() ? "" : version; + long time = tag.hasKey("Time", 4) ? tag.getLong("Time") : World.START_TIME; + Log.IO.info("Version: %s", version); + Log.IO.info("Weltzeit: %d Ticks / %d Sekunden", time, time / 20L); + Log.IO.info("Zuletzt geladen: %s", new SimpleDateFormat("dd.MM.yyyy HH:mm:ss").format(new Date(lastPlayed))); + return time; + } + catch(Exception e) { + Log.IO.error(e, "Fehler beim Lesen von " + file); + Config.clear(); + UniverseRegistry.clear(); + } + } + Log.IO.info("Erstelle neue Welt und Konfiguration"); + return World.START_TIME; + } + private Server(boolean debug, boolean ipc) { this.debug = debug; this.ipcpipe = ipc; @@ -182,7 +243,7 @@ public final class Server implements IThreadListener, IServer { public void saveWorldInfo() { if(!this.debug) { - Region.saveWorldInfo(null, this.space.getDayTime()); + saveServerConfig(this.space.getDayTime()); WorldServer.saveWarps(this.warps); } } @@ -257,13 +318,14 @@ public final class Server implements IThreadListener, IServer { long time = System.currentTimeMillis(); Log.JNI.info("Starte Server Version " + Config.VERSION); if(!this.debug) { + Converter.convert(); this.setMessage("Welt wird erstellt und geladen"); - FolderInfo info = Region.loadWorldInfo(null); + long wtime = loadServerConfig(); // if(dtime == -1L) // { // dtime = World.START_TIME; //// Config.set("spawnDim", "1", null); //// } - this.worlds.add(this.space = new WorldServer(this, info == null ? World.START_TIME : info.time, + this.worlds.add(this.space = new WorldServer(this, wtime, Space.INSTANCE, false)); this.dimensions.put(this.space.dimension.getDimensionId(), this.space); new File("players").mkdirs(); diff --git a/server/src/server/ai/EntityLivingNode.java b/server/src/server/ai/EntityLivingNode.java new file mode 100644 index 0000000..584f859 --- /dev/null +++ b/server/src/server/ai/EntityLivingNode.java @@ -0,0 +1,537 @@ +package server.ai; + +import java.util.List; + +import common.ai.EntityAIBase; +import common.ai.EntityAIMoveTowardsRestriction; +import common.ai.EntityAITasks; +import common.ai.EntityJumpHelper; +import common.ai.EntityLookHelper; +import common.ai.EntityMoveHelper; +import common.ai.EntitySenses; +import common.ai.IEntityLivingNode; +import common.block.Block; +import common.collect.Lists; +import common.color.TextColor; +import common.entity.DamageSource; +import common.entity.Entity; +import common.entity.EntityDamageSource; +import common.entity.item.EntityLeashKnot; +import common.entity.item.EntityXp; +import common.entity.npc.EntityNPC; +import common.entity.types.CombatEntry; +import common.entity.types.EntityBodyHelper; +import common.entity.types.EntityLiving; +import common.entity.types.EntityTameable; +import common.init.Blocks; +import common.init.Config; +import common.item.ItemStack; +import common.nbt.NBTTagCompound; +import common.network.IPlayer; +import common.pathfinding.PathNavigate; +import common.pathfinding.PathNavigateGround; +import common.rng.Random; +import common.util.BlockPos; +import common.world.WorldServer; + +public abstract class EntityLivingNode extends EntityNode implements IEntityLivingNode { + protected final Random rand; + private final List combat = Lists.newArrayList(); + private EntityLookHelper lookHelper; + protected EntityMoveHelper moveHelper; + protected EntityJumpHelper jumpHelper; + private EntityBodyHelper bodyHelper; + protected PathNavigate navigator; + protected final EntityAITasks tasks; + protected final EntityAITasks targets; + private EntityLiving target; + private EntitySenses senses; + private NBTTagCompound leashTag; + private boolean isMovementAITaskSet; + private EntityAIBase aiBase; + private boolean attacked; + private boolean damaged; + private String blockType; + private int lastDamaged; + protected EntityNPC playerAttacker; + private EntityLiving attackedBy; + protected int lastDamage; + protected int recentlyHit; + private int lastAttacked; + private EntityLiving attacker; + private int lastAttackTime; + + public EntityLivingNode(T entity) { + super(entity); + this.rand = entity.getRNG(); + this.tasks = new EntityAITasks(); + this.targets = new EntityAITasks(); + this.lookHelper = new EntityLookHelper(entity); + this.moveHelper = new EntityMoveHelper(entity); + this.jumpHelper = new EntityJumpHelper(entity); + this.bodyHelper = new EntityBodyHelper(entity); + this.navigator = this.getNewNavigator(); + this.senses = new EntitySenses(entity); + this.aiBase = new EntityAIMoveTowardsRestriction(entity, 1.0D); + this.registerTasks(); + } + + public T getEntity() { + return this.entity; + } + + public EntityLiving getAttackingEntity() { + EntityLiving attacking = this.getAttacking(); + return attacking != null ? attacking : (this.playerAttacker != null ? this.playerAttacker : (this.attackedBy != null ? this.attackedBy : null)); + } + + protected PathNavigate getNewNavigator() { + return new PathNavigateGround(this.entity, this.entity.worldObj); + } + +// protected PathNavigate getNewNavigator() { EntityArachnoid +// return new PathNavigateClimber(this.entity, this.entity.worldObj); +// } + + protected abstract void registerTasks(); + + public EntityLookHelper getLookHelper() { + return this.lookHelper; + } + + public EntityMoveHelper getMoveHelper() { + return this.moveHelper; + } + + public EntityJumpHelper getJumpHelper() { + return this.jumpHelper; + } + + public PathNavigate getNavigator() { + return this.navigator; + } + + public EntitySenses getEntitySenses() { + return this.senses; + } + + public EntityLiving getAttackTarget() { + return this.target; + } + + public void setAttackTarget(EntityLiving entitylivingbaseIn) { + this.target = entitylivingbaseIn; + } + + public boolean hasPath() + { + return !this.navigator.noPath(); + } + + public void updateRenderAngles() { + this.bodyHelper.updateRenderAngles(); + } + + protected void updateAITasks() { + } + + public void update() { + this.senses.clearSensingCache(); + this.targets.onUpdateTasks(); + this.tasks.onUpdateTasks(); + this.navigator.onUpdateNavigation(); + this.updateAITasks(); + this.moveHelper.onUpdateMoveHelper(); + this.lookHelper.onUpdateLook(); + this.jumpHelper.doJump(); + } + + public void setLeashTag(NBTTagCompound tag) { + this.leashTag = tag; + } + + private void recreateLeash() { + if(this.entity.getLeashed() && this.leashTag != null) { +// if(this.leashTag.hasKey("PlayerName", 8)) { +// String id = this.leashTag.getString("PlayerName"); +// if(!id.isEmpty()) { +// for(EntityNPC entitylivingbase : this.worldObj.getEntitiesWithinAABB(EntityNPC.class, +// this.getEntityBoundingBox().expand(10.0D, 10.0D, 10.0D))) { +// if(entitylivingbase.getUser().equals(id)) { +// this.leashedTo = entitylivingbase; +// break; +// } +// } +// } +// } +// else + if(this.leashTag.hasKey("X", 99) && this.leashTag.hasKey("Y", 99) && this.leashTag.hasKey("Z", 99)) { + BlockPos blockpos = new BlockPos(this.leashTag.getInteger("X"), this.leashTag.getInteger("Y"), + this.leashTag.getInteger("Z")); + EntityLeashKnot entityleashknot = EntityLeashKnot.getKnotForPosition(this.entity.worldObj, blockpos); + + if(entityleashknot == null) { + entityleashknot = EntityLeashKnot.createKnot(this.entity.worldObj, blockpos); + } + + this.entity.setLeashedTo(entityleashknot, false); + } + else { + this.entity.clearLeashed(false, true); + } + } + + this.leashTag = null; + } + + protected void onUpdateLeashed(float distance) + { + } + +// protected void onUpdateLeashed(float distance) EntityHorse +// { +// if (distance > 6.0F && this.entity.isEatingHaystack()) +// { +// this.entity.setEatingHaystack(false); +// } +// } + + public void updateLeashedState() { + if(this.leashTag != null) { + this.recreateLeash(); + } + + if(this.entity.getLeashed()) { + if(!this.entity.isEntityAlive()) { + this.entity.clearLeashed(true, true); + } + + if(this.entity.getLeashedTo() == null || this.entity.getLeashedTo().dead) { + this.entity.clearLeashed(true, true); + } + } + + if (this.entity.getLeashed() && this.entity.getLeashedTo() != null && this.entity.getLeashedTo().worldObj == this.entity.worldObj) + { + Entity entity = this.entity.getLeashedTo(); + this.entity.setHomePosAndDistance(new BlockPos((int)entity.posX, (int)entity.posY, (int)entity.posZ), 5); + float f = this.entity.getDistanceToEntity(entity); + + if (this.entity instanceof EntityTameable && ((EntityTameable)this.entity).isSitting()) + { + if (f > 10.0F) + { + this.entity.clearLeashed(true, true); + } + + return; + } + + if (!this.isMovementAITaskSet) + { + this.tasks.addTask(2, this.aiBase); + + if (this.getNavigator() instanceof PathNavigateGround) + { + ((PathNavigateGround)this.getNavigator()).setAvoidsWater(false); + } + + this.isMovementAITaskSet = true; + } + + this.onUpdateLeashed(f); + + if (f > 4.0F) + { + this.getNavigator().tryMoveToEntityLiving(entity, 1.0D); + } + + if (f > 6.0F) + { + double d0 = (entity.posX - this.entity.posX) / (double)f; + double d1 = (entity.posY - this.entity.posY) / (double)f; + double d2 = (entity.posZ - this.entity.posZ) / (double)f; + this.entity.motionX += d0 * Math.abs(d0) * 0.4D; + this.entity.motionY += d1 * Math.abs(d1) * 0.4D; + this.entity.motionZ += d2 * Math.abs(d2) * 0.4D; + } + + if (f > 10.0F) + { + this.entity.clearLeashed(true, true); + } + } + else if (!this.entity.getLeashed() && this.isMovementAITaskSet) + { + this.isMovementAITaskSet = false; + this.tasks.removeTask(this.aiBase); + + if (this.getNavigator() instanceof PathNavigateGround) + { + ((PathNavigateGround)this.getNavigator()).setAvoidsWater(true); + } + + this.entity.detachHome(); + } + } + + public void trackDamage(DamageSource source, int amount) { + this.resetCombat(); + this.blockType = null; + if(this.entity.isOnLadder()) { + Block block = this.entity.worldObj + .getState(new BlockPos(this.entity.posX, this.entity.getEntityBoundingBox().minY, this.entity.posZ)).getBlock(); + if(block == Blocks.ladder) + this.blockType = "von einer Leiter"; + else if(block == Blocks.vine) + this.blockType = "von Ranken"; + } + else if(this.entity.isInLiquid()) { + this.blockType = "aus dem Wasser"; + } + CombatEntry entry = new CombatEntry(source, amount, this.blockType, this.entity.fallDistance); + this.combat.add(entry); + this.lastDamaged = this.entity.ticksExisted; + this.damaged = true; + if(entry.getSource().getEntity() instanceof EntityLiving && !this.attacked && this.entity.isEntityAlive()) + this.attacked = true; + } + + public void sendDeathMessage() { + this.sendDeathMessage(false, false); + } + + protected void sendDeathMessage(boolean natural, boolean forAll) { +// if(this.entity.worldObj.client) +// return; + String msg; + String kill; + IPlayer receiver = null; + if(this.combat.size() == 0) { + msg = kill = natural ? String.format("%s starb", this.entity.getColoredName(TextColor.LGRAY)) : null; + } + else { + CombatEntry strong = null; + CombatEntry block = null; + int min = 0; + float max = 0.0F; + + for(int z = 0; z < this.combat.size(); ++z) { + CombatEntry entry = (CombatEntry)this.combat.get(z); + CombatEntry last = z > 0 ? (CombatEntry)this.combat.get(z - 1) : null; + + if((entry.getSource() == DamageSource.fall || entry.getSource() == DamageSource.outOfWorld) && + entry.getFallDistance() > 0.0F && (strong == null || entry.getFallDistance() > max)) { + if(z > 0) { + strong = last; + } + else { + strong = entry; + } + + max = entry.getFallDistance(); + } + + if(entry.getBlockType() != null && (block == null || entry.getDamage() > min)) { + block = entry; + } + } + CombatEntry fall = max > 5.0F && strong != null ? strong : (min > 5 && block != null ? block : null); + CombatEntry last = (CombatEntry)this.combat.get(this.combat.size() - 1); + Entity lastEnt = last.getSource().getEntity(); + + if(fall != null && last.getSource() == DamageSource.fall) { + if(fall.getSource() != DamageSource.fall && fall.getSource() != DamageSource.outOfWorld) { + Entity fallEnt = fall.getSource().getEntity(); + if(fallEnt != null && (lastEnt == null || fallEnt != lastEnt)) { + ItemStack fallItem = fallEnt instanceof EntityLiving ? ((EntityLiving)fallEnt).getHeldItem() : null; + receiver = fallEnt.isPlayer() ? ((EntityNPC)fallEnt).connection : null; + if(fallItem != null) { // && fallItem.hasDisplayName()) { + msg = String.format("%s wurde von %s mit %s zum Fallen verdammt", this.entity.getColoredName(TextColor.CYAN), + fallEnt.getColoredName(TextColor.CYAN), fallItem.getColoredName(TextColor.CYAN)); + kill = String.format(TextColor.CYAN + "* %s mit %s zum Fallen verdammt", + this.entity.getColoredName(TextColor.CYAN), fallItem.getColoredName(TextColor.CYAN)); + } + else { + msg = String.format("%s wurde von %s zum Fallen verdammt", this.entity.getColoredName(TextColor.CYAN), + fallEnt.getColoredName(TextColor.CYAN)); + kill = String.format(TextColor.CYAN + "* %s zum Fallen verdammt", + this.entity.getColoredName(TextColor.CYAN)); + } + } + else if(lastEnt != null) { + ItemStack lastItem = lastEnt instanceof EntityLiving ? ((EntityLiving)lastEnt).getHeldItem() : null; + receiver = lastEnt.isPlayer() ? ((EntityNPC)lastEnt).connection : null; + if(lastItem != null) { // && lastItem.hasDisplayName()) { + msg = String.format("%s fiel zu tief und wurde von %s mit %s erledigt", + this.entity.getColoredName(TextColor.BLUE), + lastEnt.getColoredName(TextColor.BLUE), lastItem.getColoredName(TextColor.BLUE)); + kill = String.format(TextColor.BLUE + "* %s mit %s erledigt", + this.entity.getColoredName(TextColor.BLUE), lastItem.getColoredName(TextColor.BLUE)); + } + else { + msg = String.format("%s fiel zu tief und wurde von %s erledigt", this.entity.getColoredName(TextColor.BLUE), + lastEnt.getColoredName(TextColor.BLUE)); + kill = String.format(TextColor.BLUE + "%s erledigt", this.entity.getColoredName(TextColor.BLUE)); + } + } + else { + msg = kill = natural ? String.format("%s wurde zum Fallen verdammt", this.entity.getColoredName(TextColor.CYAN)) : null; + } + } + else { + msg = kill = natural ? String.format("%s fiel " + (fall.getBlockType() == null ? "aus zu großer Höhe" : fall.getBlockType()), + this.entity.getColoredName(TextColor.NEON)) : null; + } + } + else { + receiver = last.getSource().getEntity() != null && last.getSource().getEntity().isPlayer() ? ((EntityNPC)last.getSource().getEntity()).connection : null; + msg = natural || (last.getSource() instanceof EntityDamageSource ? last.getSource().getEntity() != null : this.entity.getAttackingEntity() != null) ? last.getSource().getDeathMessage(this.entity) : null; + kill = msg == null ? null : last.getSource().getKillMessage(this.entity); + } + } + if(msg == null) + return; + if(receiver != null) + receiver.addFeed(kill); + if(forAll) + for(IPlayer player : ((WorldServer)this.entity.worldObj).getServer().getIPlayers()) { + if(player != receiver) + player.addFeed(msg); + } + } + + public EntityLiving getAttacking() { + EntityLiving entity = null; + EntityNPC player = null; + int edmg = 0; + int pdmg = 0; + for(CombatEntry entry : this.combat) { + if(entry.getSource().getEntity() != null && entry.getSource().getEntity().isPlayer() && (player == null || entry.getDamage() > pdmg)) { + pdmg = entry.getDamage(); + player = (EntityNPC)entry.getSource().getEntity(); + } + if(entry.getSource().getEntity() instanceof EntityLiving && (entity == null || entry.getDamage() > edmg)) { + edmg = entry.getDamage(); + entity = (EntityLiving)entry.getSource().getEntity(); + } + } + return player != null && pdmg >= edmg / 3 ? player : entity; + } + + public void resetCombat() { + int timeout = this.attacked ? 300 : 100; + if(this.damaged && (!this.entity.isEntityAlive() || this.entity.ticksExisted - this.lastDamaged > timeout)) { + this.damaged = false; + this.attacked = false; + this.combat.clear(); + } + } + + public int getMaxFallHeight() { + if(this.target == null) { + return 3; + } + else { + int i = (int)((float)this.entity.getHealth() - (float)this.entity.getMaxHealth() * 0.33F); +// i = i - (3 - this.worldObj.getDifficulty().getId()) * 4; + + if(i < 0) { + i = 0; + } + + return i + 3; + } + } + +// public int getMaxFallHeight() EntityHaunter +// { +// return this.getAttackTarget() == null ? 3 : 3 + (this.getHealth() - 1); +// } + + public void updateAttacking() { + if (this.recentlyHit > 0) + { + --this.recentlyHit; + } + else + { + this.playerAttacker = null; + } + + if (this.attacker != null && !this.attacker.isEntityAlive()) + { + this.attacker = null; + } + +// if(this.attackedBy.isPlayer() && ((EntityNPC)this.attackedBy).capabilities.isCreativeMode) { +// this.attackedBy = null; // FIX Creative +// } + + if (this.attackedBy != null) + { + if (!this.attackedBy.isEntityAlive()) + { + this.setAttackedBy(null); + } + else if (this.entity.ticksExisted - this.lastAttacked > 100) + { + this.setAttackedBy(null); + } + } + } + + public void dropExperience() { + if ((this.recentlyHit > 0 || this.player) && this.entity.canDropLoot() && Config.mobXP) + { + int i = this.entity.getExperiencePoints(this.playerAttacker); + + while (i > 0) + { + int j = EntityXp.getXPSplit(i); + i -= j; + this.world.spawnEntityInWorld(new EntityXp(this.world, this.entity.posX, this.entity.posY, this.entity.posZ, j)); + } + } + } + + public EntityLiving getAttackedBy() + { + return this.attackedBy; + } + + public int getAttackedTime() + { + return this.lastAttacked; + } + + public void setAttackedBy(EntityLiving livingBase) + { + this.attackedBy = livingBase; + this.lastAttacked = this.entity.ticksExisted; + } + + public EntityLiving getLastAttack() + { + return this.attacker; + } + + public int getLastAttackTime() + { + return this.lastAttackTime; + } + + public void setLastAttack(Entity entity) + { + if (entity instanceof EntityLiving) + { + this.attacker = (EntityLiving)entity; + } + else + { + this.attacker = null; + } + + this.lastAttackTime = this.entity.ticksExisted; + } +} diff --git a/server/src/server/ai/EntityMobNPCNode.java b/server/src/server/ai/EntityMobNPCNode.java new file mode 100644 index 0000000..0779e52 --- /dev/null +++ b/server/src/server/ai/EntityMobNPCNode.java @@ -0,0 +1,84 @@ +package server.ai; + +import common.ai.IEntityMobNPCNode; +import common.entity.Entity; +import common.entity.attributes.AttributeInstance; +import common.entity.attributes.Attributes; +import common.entity.npc.AIHurtByAggressor; +import common.entity.npc.EntityMobNPC; +import common.entity.npc.EntityNPC; +import common.entity.types.EntityLiving; +import common.nbt.NBTTagCompound; + +public class EntityMobNPCNode extends EntityNPCNode implements IEntityMobNPCNode { + private int angerLevel; + private int angerTarget; + + public EntityMobNPCNode(T entity) { + super(entity); + } + + protected void registerTasks() { + super.registerTasks(); + this.targets.addTask(1, new AIHurtByAggressor(this.entity)); + } + + protected void updateAITasks() + { + AttributeInstance iattributeinstance = this.entity.getEntityAttribute(Attributes.MOVEMENT_SPEED); + + if (this.isAngry()) + { + if (!iattributeinstance.hasModifier(Attributes.RUSHING_SPEED_MOD)) + { + iattributeinstance.applyModifier(Attributes.RUSHING_SPEED_MOD); + } + + --this.angerLevel; + } + else if (iattributeinstance.hasModifier(Attributes.RUSHING_SPEED_MOD)) + { + iattributeinstance.removeModifier(Attributes.RUSHING_SPEED_MOD); + } + + if (this.angerLevel > 0 && this.angerTarget != 0 && this.entity.getAttackedBy() == null) + { + Entity entity = this.world.getEntityByID(this.angerTarget); + if(entity instanceof EntityLiving) + this.entity.setAttackedBy((EntityLiving)entity); + if(entity != null && entity.isPlayer()) + this.entity.playerAttacker = (EntityNPC)entity; + this.entity.recentlyHit = this.entity.getAttackedTime(); + } + + super.updateAITasks(); + } + + public void writeNbt(NBTTagCompound tagCompound) + { + super.writeNbt(tagCompound); + tagCompound.setShort("Anger", (short)this.angerLevel); + } + + public void readNbt(NBTTagCompound tagCompund) + { + super.readNbt(tagCompund); + this.angerLevel = tagCompund.getShort("Anger"); + } + + public void becomeAngryAt(Entity entity) + { + this.angerLevel = this.rand.excl(400, 800); + if(entity instanceof EntityLiving) + this.entity.setAttackedBy((EntityLiving)entity); + } + + public boolean isAngry() + { + return this.angerLevel > 0; + } + + public void setAngerTarget(EntityLiving entity) { + this.angerTarget = entity.getId(); + } +} diff --git a/server/src/server/ai/EntityNPCNode.java b/server/src/server/ai/EntityNPCNode.java index b314cdc..1c0f807 100644 --- a/server/src/server/ai/EntityNPCNode.java +++ b/server/src/server/ai/EntityNPCNode.java @@ -17,17 +17,21 @@ import common.ai.EntityAISwimming; import common.ai.EntityAIWander; import common.ai.EntityAIWatchClosest; import common.ai.EntityAIWatchClosest2; +import common.ai.IEntityNPCNode; +import common.entity.npc.Alignment; import common.entity.npc.EntityNPC; import common.entity.types.EntityLiving; +import common.init.Items; +import common.item.ItemGunBase; import common.item.ItemStack; import common.pathfinding.PathNavigateGround; -public class EntityNPCNode extends EntityNode { +public class EntityNPCNode extends EntityLivingNode implements IEntityNPCNode { protected final EntityAIAttackOnCollide aiMelee; protected final AIRangedAttack aiRanged; private boolean fleeing; - public EntityNPCNode(EntityNPC entity) { + public EntityNPCNode(T entity) { super(entity); this.aiMelee = new EntityAIAttackOnCollide(entity, EntityLiving.class, 1.0D, true, true) { public boolean shouldExecute() @@ -65,22 +69,18 @@ public class EntityNPCNode extends EntityNode { }; } - public EntityNPC getEntity() { - return (EntityNPC)this.entity; - } - protected void registerTasks() { if(this.getNavigator() instanceof PathNavigateGround) { ((PathNavigateGround)this.getNavigator()).setBreakDoors(true); ((PathNavigateGround)this.getNavigator()).setAvoidsWater(true); } - this.tasks.addTask(0, new EntityAISwimming(this.getEntity())); + this.tasks.addTask(0, new EntityAISwimming(this.entity)); // this.tasks.addTask(1, new EntityAIAttackOnCollide(this, EntityNPC.class, 0.6D, true, true)); // this.tasks.addTask(1, new EntityAIAttackOnCollide(this, EntityLivingBase.class, 0.6D, true, true)); - this.tasks.addTask(1, new EntityAINpcMate(this.getEntity())); - this.tasks.addTask(2, new EntityAIAvoidEntity(this.getEntity(), EntityLiving.class, new Predicate() { + this.tasks.addTask(1, new EntityAINpcMate(this.entity)); + this.tasks.addTask(2, new EntityAIAvoidEntity(this.entity, EntityLiving.class, new Predicate() { public boolean test(EntityLiving entity) { - return entity != EntityNPCNode.this.entity && EntityNPC.this.shouldFlee(entity); + return entity != EntityNPCNode.this.entity && EntityNPCNode.this.shouldFlee(entity); } }, 8.0F, 1.1D, 1.1D) { { @@ -105,27 +105,27 @@ public class EntityNPCNode extends EntityNode { // EntityNPC.this.isFleeing = false; // } }); - this.tasks.addTask(3, new EntityAIAvoidEntity(this, EntityLiving.class, new Predicate() { + this.tasks.addTask(3, new EntityAIAvoidEntity(this.entity, EntityLiving.class, new Predicate() { public boolean test(EntityLiving entity) { - return entity != EntityNPC.this && EntityNPC.this.shouldFlee(entity); + return entity != EntityNPCNode.this.entity && EntityNPCNode.this.shouldFlee(entity); } }, 8.0F, 1.1D, 1.1D) { public void startExecuting() { super.startExecuting(); - EntityNPC.this.setAttackTarget(null); - EntityNPC.this.fleeing = true; + EntityNPCNode.this.setAttackTarget(null); + EntityNPCNode.this.fleeing = true; } public void resetTask() { super.resetTask(); - EntityNPC.this.fleeing = false; + EntityNPCNode.this.fleeing = false; } }); // this.tasks.addTask(2, new EntityAITempt(this, 1.0D, Items.golden_apple, false)); - this.tasks.addTask(4, new EntityAIOpenDoor(this, true)); - this.tasks.addTask(5, new EntityAINagPlayer(this)); - this.tasks.addTask(5, new EntityAILookAtTalkingPlayer(this)); - this.tasks.addTask(6, new EntityAIWatchClosest2(this, null, 3.0F, 1.0F) { + this.tasks.addTask(4, new EntityAIOpenDoor(this.entity, true)); + this.tasks.addTask(5, new EntityAINagPlayer(this.entity)); + this.tasks.addTask(5, new EntityAILookAtTalkingPlayer(this.entity)); + this.tasks.addTask(6, new EntityAIWatchClosest2(this.entity, null, 3.0F, 1.0F) { private int sneakTime; public void updateTask() @@ -134,15 +134,15 @@ public class EntityNPCNode extends EntityNode { boolean flag = this.closestEntity.isPlayer() && this.closestEntity.isSneaking(); if(this.sneakTime > 0) { if(--this.sneakTime == 0) { - EntityNPC.this.setSneaking(false); + EntityNPCNode.this.entity.setSneaking(false); } } - else if(EntityNPC.this.getAttackTarget() == null && EntityNPC.this.rand.chance(flag ? 5 : 200)) { - EntityNPC.this.setSneaking(true); - this.sneakTime = EntityNPC.this.rand.range(60, flag ? 160 : 120); + else if(EntityNPCNode.this.getAttackTarget() == null && EntityNPCNode.this.rand.chance(flag ? 5 : 200)) { + EntityNPCNode.this.entity.setSneaking(true); + this.sneakTime = EntityNPCNode.this.rand.range(60, flag ? 160 : 120); } - else if(EntityNPC.this.getAttackTarget() != null) { - EntityNPC.this.setSneaking(false); + else if(EntityNPCNode.this.getAttackTarget() != null) { + EntityNPCNode.this.entity.setSneaking(false); this.sneakTime = 0; } } @@ -150,41 +150,75 @@ public class EntityNPCNode extends EntityNode { public void resetTask() { super.resetTask(); - EntityNPC.this.setSneaking(false); + EntityNPCNode.this.entity.setSneaking(false); } }); - this.tasks.addTask(7, new EntityAINpcInteract(this)); - this.tasks.addTask(8, new EntityAIWander(this, 1.0D)); - this.tasks.addTask(8, new EntityAIPlay(this, 1.1D)); - this.tasks.addTask(9, new EntityAIWatchClosest(this, EntityLiving.class, 8.0F)); - this.targets.addTask(1, new EntityAIHurtByTarget(this, false, /* EntityNPC.class, */ EntityLiving.class) { + this.tasks.addTask(7, new EntityAINpcInteract(this.entity)); + this.tasks.addTask(8, new EntityAIWander(this.entity, 1.0D)); + this.tasks.addTask(8, new EntityAIPlay(this.entity, 1.1D)); + this.tasks.addTask(9, new EntityAIWatchClosest(this.entity, EntityLiving.class, 8.0F)); + this.targets.addTask(1, new EntityAIHurtByTarget(this.entity, false, /* EntityNPC.class, */ EntityLiving.class) { protected boolean isSuitableTarget(EntityLiving entity) { - if(entity != null && entity != EntityNPC.this && EntityNPC.this.shouldFlee(entity)) { - EntityNPC.this.setAttackTarget(null); - EntityNPC.this.fleeing = true; + if(entity != null && entity != EntityNPCNode.this.entity && EntityNPCNode.this.shouldFlee(entity)) { + EntityNPCNode.this.setAttackTarget(null); + EntityNPCNode.this.fleeing = true; return false; } - return entity != null && entity != EntityNPC.this && (!(entity.isPlayer()) || EntityNPC.this.rand.chance(entity.getAttackedBy() == EntityNPC.this ? 2 : 4)) - && EntityNPC.this.canCounter(entity) && super.isSuitableTarget(entity); + return entity != null && entity != EntityNPCNode.this.entity && (!(entity.isPlayer()) || EntityNPCNode.this.rand.chance(entity.getAttackedBy() == EntityNPCNode.this.entity ? 2 : 4)) + && EntityNPCNode.this.canCounter(entity) && super.isSuitableTarget(entity); } }); - this.targets.addTask(2, new EntityAINearestAttackableTarget(this, EntityLiving.class, 10, true, false, new Predicate() { + this.targets.addTask(2, new EntityAINearestAttackableTarget(this.entity, EntityLiving.class, 10, true, false, new Predicate() { public boolean test(EntityLiving entity) { - if(entity != null && entity != EntityNPC.this && EntityNPC.this.shouldFlee(entity)) { - EntityNPC.this.setAttackTarget(null); - EntityNPC.this.fleeing = true; + if(entity != null && entity != EntityNPCNode.this.entity && EntityNPCNode.this.shouldFlee(entity)) { + EntityNPCNode.this.setAttackTarget(null); + EntityNPCNode.this.fleeing = true; return false; } - return entity != null && entity != EntityNPC.this && !EntityNPC.this.fleeing && EntityNPC.this.canAmbush(entity) && EntityNPC.this.canAttack(entity); + return entity != null && entity != EntityNPCNode.this.entity && !EntityNPCNode.this.fleeing && EntityNPCNode.this.entity.canAmbush(entity) && EntityNPCNode.this.canAttack(entity); } })); // this.setCanPickUpLoot(true); - if (worldIn != null && !worldIn.client) - { - this.setCombatTask(); - } + this.setCombatTask(); } + + public final boolean canInfight(Alignment align) { + Alignment alignment = this.entity.getAlignmentCached(); + return alignment.chaotic || (!alignment.lawful && + ((alignment.good && align.evil) || (alignment.evil && align.good))); + } + + public final boolean canMurder(Alignment align) { + Alignment alignment = this.entity.getAlignmentCached(); + return alignment.chaotic && ((alignment.good && align.evil) || (alignment.evil && align.good)); + } + + public boolean canCounter(EntityLiving entity) { + return !(entity instanceof EntityNPC) || + (this.entity.getClass() == entity.getClass() ? this.canInfight(((EntityNPC)entity).getAlignmentCached()) : + !this.entity.isPeaceful(((EntityNPC)entity).getClass())); + } + + public boolean canAttack(EntityLiving entity) { + return entity instanceof EntityNPC && (this.entity.getClass() == entity.getClass() ? this.canMurder(((EntityNPC)entity).getAlignmentCached()) : + this.entity.isAggressive(((EntityNPC)entity).getClass())); + } + + public boolean shouldFlee(EntityLiving entity) { + return (this.entity.getHealth() <= (this.entity.getMaxHealth() / 4) || !this.canCounter(entity)) && + ((entity instanceof EntityNPC && ((EntityNPC)entity).getNode().canAttack(this.entity) || + (entity == this.entity.getAttackedBy() && ((EntityNPC)entity).getNode().canCounter(this.entity)))); + } + + public boolean isRangedWeapon(ItemStack stack) { + return stack != null && (stack.getItem() == Items.bow || stack.getItem() instanceof ItemGunBase || + stack.getItem() == Items.snowball || stack.getItem() == Items.potion); + } + +// public boolean isRangedWeapon(ItemStack stack) { // EntityGargoyle +// return false; +// } public void updateLeashedState() { if(!this.player) @@ -205,9 +239,9 @@ public class EntityNPCNode extends EntityNode { if(!this.player) { this.tasks.removeTask(this.aiMelee); this.tasks.removeTask(this.aiRanged); - ItemStack itemstack = this.getEntity().getHeldItem(); + ItemStack itemstack = this.entity.getHeldItem(); - if (this.getEntity().isRangedWeapon(itemstack)) + if (this.isRangedWeapon(itemstack)) { this.tasks.addTask(3, this.aiRanged); } diff --git a/server/src/server/ai/EntityNode.java b/server/src/server/ai/EntityNode.java index 2f4c0a7..914b118 100644 --- a/server/src/server/ai/EntityNode.java +++ b/server/src/server/ai/EntityNode.java @@ -1,436 +1,29 @@ package server.ai; -import java.util.List; - -import common.ai.EntityAIBase; -import common.ai.EntityAIMoveTowardsRestriction; -import common.ai.EntityAITasks; -import common.ai.EntityJumpHelper; -import common.ai.EntityLookHelper; -import common.ai.EntityMoveHelper; -import common.ai.EntitySenses; import common.ai.IEntityNode; -import common.block.Block; -import common.collect.Lists; -import common.color.TextColor; -import common.entity.DamageSource; import common.entity.Entity; -import common.entity.EntityDamageSource; -import common.entity.item.EntityLeashKnot; -import common.entity.npc.EntityNPC; -import common.entity.types.CombatEntry; -import common.entity.types.EntityBodyHelper; -import common.entity.types.EntityLiving; -import common.entity.types.EntityTameable; -import common.init.Blocks; -import common.item.ItemStack; import common.nbt.NBTTagCompound; -import common.network.IPlayer; -import common.pathfinding.PathNavigate; -import common.pathfinding.PathNavigateGround; -import common.util.BlockPos; +import common.world.World; import common.world.WorldServer; -public abstract class EntityNode implements IEntityNode { - protected final EntityLiving entity; +public class EntityNode implements IEntityNode { + protected final T entity; protected final boolean player; - private final List combat = Lists.newArrayList(); - private EntityLookHelper lookHelper; - protected EntityMoveHelper moveHelper; - protected EntityJumpHelper jumpHelper; - private EntityBodyHelper bodyHelper; - protected PathNavigate navigator; - protected final EntityAITasks tasks; - protected final EntityAITasks targets; - private EntityLiving target; - private EntitySenses senses; - private Runnable tickFunc; - private NBTTagCompound leashTag; - private boolean isMovementAITaskSet; - private EntityAIBase aiBase; - private boolean attacked; - private boolean damaged; - private String blockType; - private int lastDamaged; + protected WorldServer world; - public EntityNode(EntityLiving entity) { + public EntityNode(T entity) { this.entity = entity; this.player = entity.isPlayer(); - this.tasks = new EntityAITasks(); - this.targets = new EntityAITasks(); - this.lookHelper = new EntityLookHelper(entity); - this.moveHelper = new EntityMoveHelper(entity); - this.jumpHelper = new EntityJumpHelper(entity); - this.bodyHelper = new EntityBodyHelper(entity); - this.navigator = this.getNewNavigator(); - this.senses = new EntitySenses(entity); - this.aiBase = new EntityAIMoveTowardsRestriction(entity, 1.0D); - this.registerTasks(); + this.world = (WorldServer)entity.worldObj; } - protected PathNavigate getNewNavigator() { - return new PathNavigateGround(this.entity, this.entity.worldObj); - } - -// protected PathNavigate getNewNavigator() { EntityArachnoid -// return new PathNavigateClimber(this.entity, this.entity.worldObj); -// } - - protected abstract void registerTasks(); - - public void setTickFunction(Runnable func) { - this.tickFunc = func; - } - - public EntityLookHelper getLookHelper() { - return this.lookHelper; - } - - public EntityMoveHelper getMoveHelper() { - return this.moveHelper; - } - - public EntityJumpHelper getJumpHelper() { - return this.jumpHelper; - } - - public PathNavigate getNavigator() { - return this.navigator; - } - - public EntitySenses getEntitySenses() { - return this.senses; - } - - public EntityLiving getAttackTarget() { - return this.target; - } - - public void setAttackTarget(EntityLiving entitylivingbaseIn) { - this.target = entitylivingbaseIn; - } - - public boolean hasPath() - { - return !this.navigator.noPath(); - } - - public void updateRenderAngles() { - this.bodyHelper.updateRenderAngles(); + public void setWorld(World world) { + this.world = (WorldServer)world; } - public void update() { - this.senses.clearSensingCache(); - this.targets.onUpdateTasks(); - this.tasks.onUpdateTasks(); - this.navigator.onUpdateNavigation(); - if(this.tickFunc != null) - this.tickFunc.run(); - this.moveHelper.onUpdateMoveHelper(); - this.lookHelper.onUpdateLook(); - this.jumpHelper.doJump(); + public void readNbt(NBTTagCompound tag) { } - public void setLeashTag(NBTTagCompound tag) { - this.leashTag = tag; + public void writeNbt(NBTTagCompound tag) { } - - private void recreateLeash() { - if(this.entity.getLeashed() && this.leashTag != null) { -// if(this.leashTag.hasKey("PlayerName", 8)) { -// String id = this.leashTag.getString("PlayerName"); -// if(!id.isEmpty()) { -// for(EntityNPC entitylivingbase : this.worldObj.getEntitiesWithinAABB(EntityNPC.class, -// this.getEntityBoundingBox().expand(10.0D, 10.0D, 10.0D))) { -// if(entitylivingbase.getUser().equals(id)) { -// this.leashedTo = entitylivingbase; -// break; -// } -// } -// } -// } -// else - if(this.leashTag.hasKey("X", 99) && this.leashTag.hasKey("Y", 99) && this.leashTag.hasKey("Z", 99)) { - BlockPos blockpos = new BlockPos(this.leashTag.getInteger("X"), this.leashTag.getInteger("Y"), - this.leashTag.getInteger("Z")); - EntityLeashKnot entityleashknot = EntityLeashKnot.getKnotForPosition(this.entity.worldObj, blockpos); - - if(entityleashknot == null) { - entityleashknot = EntityLeashKnot.createKnot(this.entity.worldObj, blockpos); - } - - this.entity.setLeashedTo(entityleashknot, false); - } - else { - this.entity.clearLeashed(false, true); - } - } - - this.leashTag = null; - } - - protected void onUpdateLeashed(float distance) - { - } - -// protected void onUpdateLeashed(float distance) EntityHorse -// { -// if (distance > 6.0F && this.entity.isEatingHaystack()) -// { -// this.entity.setEatingHaystack(false); -// } -// } - - public void updateLeashedState() { - if(this.leashTag != null) { - this.recreateLeash(); - } - - if(this.entity.getLeashed()) { - if(!this.entity.isEntityAlive()) { - this.entity.clearLeashed(true, true); - } - - if(this.entity.getLeashedTo() == null || this.entity.getLeashedTo().dead) { - this.entity.clearLeashed(true, true); - } - } - - if (this.entity.getLeashed() && this.entity.getLeashedTo() != null && this.entity.getLeashedTo().worldObj == this.entity.worldObj) - { - Entity entity = this.entity.getLeashedTo(); - this.entity.setHomePosAndDistance(new BlockPos((int)entity.posX, (int)entity.posY, (int)entity.posZ), 5); - float f = this.entity.getDistanceToEntity(entity); - - if (this.entity instanceof EntityTameable && ((EntityTameable)this.entity).isSitting()) - { - if (f > 10.0F) - { - this.entity.clearLeashed(true, true); - } - - return; - } - - if (!this.isMovementAITaskSet) - { - this.tasks.addTask(2, this.aiBase); - - if (this.getNavigator() instanceof PathNavigateGround) - { - ((PathNavigateGround)this.getNavigator()).setAvoidsWater(false); - } - - this.isMovementAITaskSet = true; - } - - this.onUpdateLeashed(f); - - if (f > 4.0F) - { - this.getNavigator().tryMoveToEntityLiving(entity, 1.0D); - } - - if (f > 6.0F) - { - double d0 = (entity.posX - this.entity.posX) / (double)f; - double d1 = (entity.posY - this.entity.posY) / (double)f; - double d2 = (entity.posZ - this.entity.posZ) / (double)f; - this.entity.motionX += d0 * Math.abs(d0) * 0.4D; - this.entity.motionY += d1 * Math.abs(d1) * 0.4D; - this.entity.motionZ += d2 * Math.abs(d2) * 0.4D; - } - - if (f > 10.0F) - { - this.entity.clearLeashed(true, true); - } - } - else if (!this.entity.getLeashed() && this.isMovementAITaskSet) - { - this.isMovementAITaskSet = false; - this.tasks.removeTask(this.aiBase); - - if (this.getNavigator() instanceof PathNavigateGround) - { - ((PathNavigateGround)this.getNavigator()).setAvoidsWater(true); - } - - this.entity.detachHome(); - } - } - - public void trackDamage(DamageSource source, int amount) { - this.resetCombat(); - this.blockType = null; - if(this.entity.isOnLadder()) { - Block block = this.entity.worldObj - .getState(new BlockPos(this.entity.posX, this.entity.getEntityBoundingBox().minY, this.entity.posZ)).getBlock(); - if(block == Blocks.ladder) - this.blockType = "von einer Leiter"; - else if(block == Blocks.vine) - this.blockType = "von Ranken"; - } - else if(this.entity.isInLiquid()) { - this.blockType = "aus dem Wasser"; - } - CombatEntry entry = new CombatEntry(source, amount, this.blockType, this.entity.fallDistance); - this.combat.add(entry); - this.lastDamaged = this.entity.ticksExisted; - this.damaged = true; - if(entry.getSource().getEntity() instanceof EntityLiving && !this.attacked && this.entity.isEntityAlive()) - this.attacked = true; - } - - public void sendDeathMessage() { - this.sendDeathMessage(false, false); - } - - protected void sendDeathMessage(boolean natural, boolean forAll) { -// if(this.entity.worldObj.client) -// return; - String msg; - String kill; - IPlayer receiver = null; - if(this.combat.size() == 0) { - msg = kill = natural ? String.format("%s starb", this.entity.getColoredName(TextColor.LGRAY)) : null; - } - else { - CombatEntry strong = null; - CombatEntry block = null; - int min = 0; - float max = 0.0F; - - for(int z = 0; z < this.combat.size(); ++z) { - CombatEntry entry = (CombatEntry)this.combat.get(z); - CombatEntry last = z > 0 ? (CombatEntry)this.combat.get(z - 1) : null; - - if((entry.getSource() == DamageSource.fall || entry.getSource() == DamageSource.outOfWorld) && - entry.getFallDistance() > 0.0F && (strong == null || entry.getFallDistance() > max)) { - if(z > 0) { - strong = last; - } - else { - strong = entry; - } - - max = entry.getFallDistance(); - } - - if(entry.getBlockType() != null && (block == null || entry.getDamage() > min)) { - block = entry; - } - } - CombatEntry fall = max > 5.0F && strong != null ? strong : (min > 5 && block != null ? block : null); - CombatEntry last = (CombatEntry)this.combat.get(this.combat.size() - 1); - Entity lastEnt = last.getSource().getEntity(); - - if(fall != null && last.getSource() == DamageSource.fall) { - if(fall.getSource() != DamageSource.fall && fall.getSource() != DamageSource.outOfWorld) { - Entity fallEnt = fall.getSource().getEntity(); - if(fallEnt != null && (lastEnt == null || fallEnt != lastEnt)) { - ItemStack fallItem = fallEnt instanceof EntityLiving ? ((EntityLiving)fallEnt).getHeldItem() : null; - receiver = fallEnt.isPlayer() ? ((EntityNPC)fallEnt).connection : null; - if(fallItem != null) { // && fallItem.hasDisplayName()) { - msg = String.format("%s wurde von %s mit %s zum Fallen verdammt", this.entity.getColoredName(TextColor.CYAN), - fallEnt.getColoredName(TextColor.CYAN), fallItem.getColoredName(TextColor.CYAN)); - kill = String.format(TextColor.CYAN + "* %s mit %s zum Fallen verdammt", - this.entity.getColoredName(TextColor.CYAN), fallItem.getColoredName(TextColor.CYAN)); - } - else { - msg = String.format("%s wurde von %s zum Fallen verdammt", this.entity.getColoredName(TextColor.CYAN), - fallEnt.getColoredName(TextColor.CYAN)); - kill = String.format(TextColor.CYAN + "* %s zum Fallen verdammt", - this.entity.getColoredName(TextColor.CYAN)); - } - } - else if(lastEnt != null) { - ItemStack lastItem = lastEnt instanceof EntityLiving ? ((EntityLiving)lastEnt).getHeldItem() : null; - receiver = lastEnt.isPlayer() ? ((EntityNPC)lastEnt).connection : null; - if(lastItem != null) { // && lastItem.hasDisplayName()) { - msg = String.format("%s fiel zu tief und wurde von %s mit %s erledigt", - this.entity.getColoredName(TextColor.BLUE), - lastEnt.getColoredName(TextColor.BLUE), lastItem.getColoredName(TextColor.BLUE)); - kill = String.format(TextColor.BLUE + "* %s mit %s erledigt", - this.entity.getColoredName(TextColor.BLUE), lastItem.getColoredName(TextColor.BLUE)); - } - else { - msg = String.format("%s fiel zu tief und wurde von %s erledigt", this.entity.getColoredName(TextColor.BLUE), - lastEnt.getColoredName(TextColor.BLUE)); - kill = String.format(TextColor.BLUE + "%s erledigt", this.entity.getColoredName(TextColor.BLUE)); - } - } - else { - msg = kill = natural ? String.format("%s wurde zum Fallen verdammt", this.entity.getColoredName(TextColor.CYAN)) : null; - } - } - else { - msg = kill = natural ? String.format("%s fiel " + (fall.getBlockType() == null ? "aus zu großer Höhe" : fall.getBlockType()), - this.entity.getColoredName(TextColor.NEON)) : null; - } - } - else { - receiver = last.getSource().getEntity() != null && last.getSource().getEntity().isPlayer() ? ((EntityNPC)last.getSource().getEntity()).connection : null; - msg = natural || (last.getSource() instanceof EntityDamageSource ? last.getSource().getEntity() != null : this.entity.getAttackingEntity() != null) ? last.getSource().getDeathMessage(this.entity) : null; - kill = msg == null ? null : last.getSource().getKillMessage(this.entity); - } - } - if(msg == null) - return; - if(receiver != null) - receiver.addFeed(kill); - if(forAll) - for(IPlayer player : ((WorldServer)this.entity.worldObj).getServer().getIPlayers()) { - if(player != receiver) - player.addFeed(msg); - } - } - - public EntityLiving getAttacking() { - EntityLiving entity = null; - EntityNPC player = null; - int edmg = 0; - int pdmg = 0; - for(CombatEntry entry : this.combat) { - if(entry.getSource().getEntity() != null && entry.getSource().getEntity().isPlayer() && (player == null || entry.getDamage() > pdmg)) { - pdmg = entry.getDamage(); - player = (EntityNPC)entry.getSource().getEntity(); - } - if(entry.getSource().getEntity() instanceof EntityLiving && (entity == null || entry.getDamage() > edmg)) { - edmg = entry.getDamage(); - entity = (EntityLiving)entry.getSource().getEntity(); - } - } - return player != null && pdmg >= edmg / 3 ? player : entity; - } - - public void resetCombat() { - int timeout = this.attacked ? 300 : 100; - if(this.damaged && (!this.entity.isEntityAlive() || this.entity.ticksExisted - this.lastDamaged > timeout)) { - this.damaged = false; - this.attacked = false; - this.combat.clear(); - } - } - - public int getMaxFallHeight() { - if(this.target == null) { - return 3; - } - else { - int i = (int)((float)this.entity.getHealth() - (float)this.entity.getMaxHealth() * 0.33F); -// i = i - (3 - this.worldObj.getDifficulty().getId()) * 4; - - if(i < 0) { - i = 0; - } - - return i + 3; - } - } - -// public int getMaxFallHeight() EntityHaunter -// { -// return this.getAttackTarget() == null ? 3 : 3 + (this.getHealth() - 1); -// } } diff --git a/server/src/server/init/NodeRegistry.java b/server/src/server/init/NodeRegistry.java new file mode 100644 index 0000000..e38b428 --- /dev/null +++ b/server/src/server/init/NodeRegistry.java @@ -0,0 +1,136 @@ +package server.init; + +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; +import java.util.Map; +import java.util.Set; + +import common.ai.IEntityNode; +import common.collect.Maps; +import common.entity.Entity; +import common.entity.animal.EntityBat; +import common.entity.animal.EntityChicken; +import common.entity.animal.EntityCow; +import common.entity.animal.EntityDragon; +import common.entity.animal.EntityHorse; +import common.entity.animal.EntityMooshroom; +import common.entity.animal.EntityMouse; +import common.entity.animal.EntityOcelot; +import common.entity.animal.EntityPig; +import common.entity.animal.EntityRabbit; +import common.entity.animal.EntitySheep; +import common.entity.animal.EntitySquid; +import common.entity.animal.EntityWolf; +import common.entity.item.EntityBoat; +import common.entity.item.EntityChestCart; +import common.entity.item.EntityCrystal; +import common.entity.item.EntityExplosion; +import common.entity.item.EntityFalling; +import common.entity.item.EntityFireworks; +import common.entity.item.EntityHopperCart; +import common.entity.item.EntityItem; +import common.entity.item.EntityLeashKnot; +import common.entity.item.EntityMinecart; +import common.entity.item.EntityNuke; +import common.entity.item.EntityOrb; +import common.entity.item.EntityTnt; +import common.entity.item.EntityTntCart; +import common.entity.item.EntityXp; +import common.entity.item.EntityXpBottle; +import common.entity.npc.SpeciesInfo; +import common.entity.projectile.EntityArrow; +import common.entity.projectile.EntityBox; +import common.entity.projectile.EntityBullet; +import common.entity.projectile.EntityDie; +import common.entity.projectile.EntityDynamite; +import common.entity.projectile.EntityEgg; +import common.entity.projectile.EntityFireCharge; +import common.entity.projectile.EntityFireball; +import common.entity.projectile.EntityHook; +import common.entity.projectile.EntityPotion; +import common.entity.projectile.EntitySnowball; +import common.entity.types.EntityLiving; +import common.entity.types.IObjectData; +import common.log.Log; +import common.nbt.NBTTagCompound; +import common.world.World; + +public abstract class NodeRegistry { + private static final Map, Class> NODES = Maps.newHashMap(); + + private static void registerNode(Class clazz, Class node) { + if(clazz == null) + throw new IllegalArgumentException("Kann keine null-Klasse registrieren"); + if(NODES.containsKey(clazz)) + throw new IllegalArgumentException("Klasse ist bereits registriert: " + clazz); + NODES.put(clazz, node); + } + + public static void addNode(Entity entity) { + IEntityNode node = null; + Class oclass = NODES.get(entity.getClass()); + Constructor[] consts = oclass.getConstructors(); + if(consts.length != 1) + throw new IllegalArgumentException("Klasse " + oclass + " hat mehr als einen Konstruktor"); + try { + node = (IEntityNode)consts[0].newInstance(entity); + } + catch(InstantiationException | IllegalAccessException | InvocationTargetException e) { + throw new RuntimeException(e); + } + entity.setNode(node); + } + + public static Class getNodeClass(Class clazz) { + return NODES.get(clazz); + } + + public static void register() { + registerNode(EntityItem.class, ); + registerNode(EntityXp.class, ); + registerNode(EntityEgg.class, ); + registerNode(EntityLeashKnot.class, ); + registerNode(EntityArrow.class, ); + registerNode(EntitySnowball.class, ); + registerNode(EntityFireball.class, ); + registerNode(EntityFireCharge.class, ); + registerNode(EntityOrb.class, ); + registerNode(EntityPotion.class, ); + registerNode(EntityXpBottle.class, ); + registerNode(EntityBox.class, ); + registerNode(EntityTnt.class, ); + registerNode(EntityFalling.class, ); + registerNode(EntityFireworks.class, ); + registerNode(EntityBoat.class, ); + registerNode(EntityMinecart.class, ); + registerNode(EntityChestCart.class, ); + registerNode(EntityTntCart.class, ); + registerNode(EntityHopperCart.class, ); + registerNode(EntityHook.class, ); + registerNode(EntityDynamite.class, ); + registerNode(EntityNuke.class, ); + registerNode(EntityDie.class, ); + registerNode(EntityExplosion.class, ); + registerNode(EntityCrystal.class, ); + registerNode(EntityBullet.class, ); + + registerNode(EntityDragon.class, ); + registerNode(EntityBat.class, ); + registerNode(EntityPig.class, ); + registerNode(EntitySheep.class, ); + registerNode(EntityCow.class, ); + registerNode(EntityChicken.class, ); + registerNode(EntitySquid.class, ); + registerNode(EntityWolf.class, ); + registerNode(EntityMooshroom.class, ); + registerNode(EntityOcelot.class, ); + registerNode(EntityHorse.class, ); + registerNode(EntityRabbit.class, ); + registerNode(EntityMouse.class, ); + + for(int z = 0; z < SpeciesRegistry.SPECIMEN.size(); z++) { + SpeciesInfo info = SpeciesRegistry.SPECIMEN.get(z); + registerNode(info.clazz, ); + } + } +} diff --git a/client/src/client/world/Converter.java b/server/src/server/world/Converter.java similarity index 79% rename from client/src/client/world/Converter.java rename to server/src/server/world/Converter.java index 33bf568..5bc9269 100644 --- a/client/src/client/world/Converter.java +++ b/server/src/server/world/Converter.java @@ -1,4 +1,4 @@ -package client.world; +package server.world; import java.io.BufferedInputStream; import java.io.ByteArrayInputStream; @@ -7,16 +7,14 @@ import java.io.File; import java.io.FilenameFilter; import java.io.IOException; import java.io.RandomAccessFile; +import java.text.SimpleDateFormat; import java.util.Arrays; +import java.util.Date; import java.util.Map; import java.util.Map.Entry; import java.util.zip.GZIPInputStream; import java.util.zip.InflaterInputStream; -import client.Client; -import client.gui.GuiConvert; -import client.gui.GuiLoading; -import client.gui.GuiLoading.Callback; import common.biome.Biome; import common.block.Block; import common.block.BlockCactus; @@ -92,15 +90,26 @@ import common.world.Region; import common.world.State; import common.world.Weather; import common.world.World; -import common.world.Region.FolderInfo; -import common.world.Region.SaveVersion; +import server.Server; + +public abstract class Converter { + private static enum SaveVersion { + ALPHA_1_0("Alpha 1.0 - Beta 1.2"), + BETA_1_3("Beta 1.3 - Release 1.8.9"), + RELEASE_1_9("Release 1.9 - Release 1.12.2"), + RELEASE_1_13("Release 1.13 +"); + + private final String name; + + private SaveVersion(String name) { + this.name = name; + } + + public String toString() { + return this.name; + } + } -public final class Converter { -// public static interface Callback { -// void postMessage(String msg); -// void postProgress(int progress); -// } - private static class AnvilRegion { private final int[] offsets = new int[1024]; @@ -182,11 +191,7 @@ public final class Converter { State getState(int id, int data); } - private Converter() { - } - - private long postProgress(long start, int progress) { -// SKC.info("... " + progress + "%"); + private static long postProgress(long start, int progress) { if(System.currentTimeMillis() - start >= 500L) { start = System.currentTimeMillis(); Log.JNI.info("... " + progress + "%"); @@ -198,16 +203,7 @@ public final class Converter { private static final Map ENTITY_MAP = Maps.newHashMap(); private static final Map TILE_MAP = Maps.newHashMap(); private static final char[] BLOCK_MAP = new char[65536]; -// private static final Map BLOCK_FUNCS = Maps.newHashMap(); private static final Map OLD_GAMERULES = Maps.newHashMap(); - - private String action; - private String task; - private String file; - private int totalRegions; - private int doneRegions; - private int totalChunks; - private int doneChunks; private static void mapEntity(Class clazz, String ... names) { String name = EntityRegistry.getEntityString(clazz); @@ -253,17 +249,6 @@ public final class Converter { } } -// private static void mapBlockDynamic(BlockFunction func, int id, int data) { -// BLOCK_MAP[(id << 4) | data] = (char)0x000f; -// BLOCK_FUNCS.put((char)((id << 4) | data), func); -// } -// -// private static void mapBlockDynamic(BlockFunction func, int id) { -// for(int z = 0; z < 16; z++) { -// mapBlockDynamic(func, id, z); -// } -// } - static { OLD_GAMERULES.put("doFireTick", "fireTick"); OLD_GAMERULES.put("mobGriefing", "mobGriefing"); @@ -273,7 +258,6 @@ public final class Converter { OLD_GAMERULES.put("doEntityDrops", "dropObjects"); OLD_GAMERULES.put("naturalRegeneration", "naturalRegeneration"); OLD_GAMERULES.put("doDaylightCycle", "daylightCycle"); -// OLD_GAMERULES.put("showDeathMessages", "deathMessages"); OLD_GAMERULES.put("keepInventory", "keepInventory"); OLD_GAMERULES.put("doWeatherCycle", "weatherChanges"); OLD_GAMERULES.put("randomTickSpeed", "randomTickSpeed"); @@ -306,7 +290,6 @@ public final class Converter { mapTile(TileEntityDaylightDetector.class, "DLDetector", "daylight_detector"); mapTile(TileEntityHopper.class, "Hopper", "hopper"); mapTile(TileEntityComparator.class, "Comparator", "comparator"); -// mapTile(TileEntityFlowerPot.class, "FlowerPot", "flower_pot"); mapTile(TileEntityBanner.class, "Banner", "banner"); mapBlock(Blocks.stone.getState(), 1); @@ -609,11 +592,6 @@ public final class Converter { mapBlockData(Blocks.stonebrick_stairs, 109); mapBlock(Blocks.mycelium, 110); mapBlockData(Blocks.waterlily, 111); -// mapBlockDynamic(new BlockFunction() { -// public IBlockState getState(int id, int data) { -// return Blocks.waterlily.getDefaultState().withProperty(BlockDirectional.FACING, Facing.randHorizontal(RANDOM)); -// } -// }, 111); mapBlock(Blocks.blood_brick, 112); mapBlockData(Blocks.blood_brick_fence, 113); mapBlockData(Blocks.blood_brick_stairs, 114); @@ -822,97 +800,7 @@ public final class Converter { return Blocks.stained_hardened_clay.getState().withProperty(BlockColored.COLOR, DyeColor.byMetadata(data)); } }, 252); - // 253, 254 mapBlock(Blocks.obsidian, 255); - -// addBlock(137, 49); // Command Block -// addBlock(166, 0); // Barrier -// addBlock(168, 98); // Prismarine -// // addBlock(169, 169); // Sea Lantern --> Lamp -// addBlock(179, 24); // Red Sandstone -// addBlock(180, 128); // Red Sandstone Stairs -// addBlock(181, 43, 1); // Red Sandstone Double Slab -// -// addBlock(198, 101); // End Rod -// addBlock(199, 102); // Chorus Plant -// addBlock(200, 102); // Chorus Flower -// addBlock(201, 155); // Purpur Block -// addBlock(203, 156); // Purpur Stairs -// addBlock(206, 98); // End Stone Bricks -// addBlock(207, 142); // Beetroot Block -// addBlock(208, 60); // Grass Path -// addBlock(209, 20); // End Gateway -// addBlock(210, 137); // Repeating Command Block -// addBlock(211, 137); // Chain Command Block -// addBlock(212, 79); // Frosted Ice -// addBlock(213, 87); // Magma Block -// addBlock(214, 100); // Nether Wart Block -// addBlock(215, 112); // Red Nether Brick -// addBlock(216, 155); // Bone Block -// addBlock(217, 20); // Structure Void -// addBlock(218, 158); // Observer -// addBlock(255, 49); // Structure Block -// addBlock(202, 155, 2); // Purpur Pillar -// addBlock(204, 43, 7); // Purpur Double Slab - -// if(block > 197 && adddata != null) -// adddata.set(cx, cy, cz, 0); -// if(block == 1 || block == 19) { // Stone, Sponge -// data.set(cx, cy, cz, 0); -// } -// else if(block == 29 || block == 33 || block == 34) { // Piston, Sticky Piston, Piston Head -// int dt = data.get(cx, cy, cz); -// if((dt & 7) == 6) -// data.set(cx, cy, cz, (dt & 8) | 1); -// } -// else if(block == 97) { // Monster Egg -// int dt = data.get(cx, cy, cz); -// switch(dt) { -// case 0: -// default: -// blocks[c] = (byte)1; -// data.set(cx, cy, cz, 0); -// break; -// case 1: -// blocks[c] = (byte)4; -// data.set(cx, cy, cz, 0); -// break; -// case 2: -// case 3: -// case 4: -// case 5: -// blocks[c] = (byte)98; -// data.set(cx, cy, cz, dt - 2); -// break; -// } -// } -// mapBlock(new BlockFunction() { -// public IBlockState getState(int id, int data) { -// return Blocks.waterlily.getDefaultState().withProperty(BlockDirectional.FACING, Facing.randHorizontal(RANDOM)); -// } -// }, 111); -// else if(block == 111) { // Water Lily -// data.set(cx, cy, cz, RANDOM.zrange(4)); -// } -// else if(block == 251 || block == 252) { // Concrete, Concrete Powder -// blocks[c] = (byte)159; -// } -// else if(block >= 235 && block <= 250) { // Glazed Terracotta -// blocks[c] = (byte)159; -// data.set(cx, cy, cz, block - 235); -// } -// else if(block >= 219 && block <= 234) { // Shulker Box -// blocks[c] = (byte)35; -// data.set(cx, cy, cz, block - 219); -// } -// else if(block == 205) { // Purpur Slab -// blocks[c] = (byte)44; -// data.set(cx, cy, cz, (data.get(cx, cy, cz) & 8) == 8 ? 15 : 7); -// } -// else if(block == 182) { // Red Sandstone Slab -// blocks[c] = (byte)44; -// data.set(cx, cy, cz, (data.get(cx, cy, cz) & 8) == 8 ? 9 : 1); -// } } private static void convertTile(NBTTagCompound ent) { @@ -1113,17 +1001,13 @@ public final class Converter { return tag; } - private long convertChunks(File dir, File file, long start, int progress, int total) { + private static long convertChunks(File dir, File file, long start, int progress, int total) { String name = file.getName(); - this.file = name; - this.totalChunks = 1024; boolean legacy = name.endsWith(".mcr"); int rx, rz; String[] reg = name.split("\\."); if(reg.length != 4) { Log.JNI.warn("Unbekannte Region " + file); - this.doneChunks = 0; - this.file = null; return start; } try { @@ -1132,8 +1016,6 @@ public final class Converter { } catch(NumberFormatException e) { Log.JNI.warn("Unbekannte Region " + file); - this.doneChunks = 0; - this.file = null; return start; } try { @@ -1146,7 +1028,6 @@ public final class Converter { for(int bx = 0; bx < 4; bx++) { for(int bz = 0; bz < 4; bz++) { if(!oldreg.hasRegion(bx, bz)) { - this.doneChunks += 64; continue; } areas++; @@ -1161,7 +1042,6 @@ public final class Converter { DataInputStream in = oldreg.getInputStream(x, z); if(in == null) { Log.JNI.warn("Konnte " + file.getPath() + "@" + x + "," + z + " nicht lesen"); - this.doneChunks += 1; continue; } NBTTagCompound tag = NBTLoader.read(in); @@ -1172,7 +1052,6 @@ public final class Converter { // out.close(); newreg.writeTag(nx, nz, tag); } - this.doneChunks += 1; } } newreg.close(false); @@ -1190,36 +1069,26 @@ public final class Converter { catch(IOException e) { e.printStackTrace(); } - this.doneChunks = 0; - this.file = null; return start; } - public static FolderInfo convertMapFormat(File dir, boolean load) { + public static boolean convert() { long cur = System.currentTimeMillis(); - if(load) - Log.JNI.info("Welt '" + dir + "' wird konvertiert"); - if(new File(dir, "level.nbt").exists()) { - if(load) - Log.JNI.error("Datei level.nbt existiert bereits"); - return null; - } - File ldat = new File(dir, "level.dat"); + if(new File("server.nbt").exists()) + return false; + File ldat = new File("level.dat"); if(!ldat.exists()) - ldat = new File(dir, "level.dat_old"); - if(!ldat.exists()) { - if(load) - Log.JNI.error("Datei level.dat und level.dat_old nicht gefunden"); - return null; - } + ldat = new File("level.dat_old"); + if(!ldat.exists()) + return false; + Log.JNI.info("Welt wird konvertiert"); NBTTagCompound nbt; try { nbt = NBTLoader.readGZip(ldat); } catch(Exception e) { - if(load) - Log.JNI.error(e, "Fehler beim Lesen von level.dat"); - return null; + Log.JNI.error(e, "Fehler beim Lesen von level.dat"); + return false; } nbt = nbt.getCompoundTag("Data"); int version = nbt.getInteger("version"); @@ -1227,182 +1096,77 @@ public final class Converter { // nbt.setBoolean("incompatible", data >= 1400); SaveVersion ver = data >= 1400 ? SaveVersion.RELEASE_1_13 : (data >= 100 ? SaveVersion.RELEASE_1_9 : (version == 19132 || version == 19133 ? SaveVersion.BETA_1_3 : (version == 0 ? SaveVersion.ALPHA_1_0 : null))); if(ver == null) { - if(load) - Log.IO.error("Version %d ist unbekannt", version); - return null; + Log.IO.error("Version %d ist unbekannt", version); + return false; } long wtime = nbt.getLong(nbt.hasKey("DayTime", 99) ? "DayTime" : "Time") + World.START_TIME; - if(!load) - return new FolderInfo(wtime, nbt.getLong("LastPlayed"), ver, null); -// nbt.setString("verdesc", ver); -// NBTTagCompound nbt = getLegacyWorldInfo(dir); -// if(nbt == null) -// return false; - final Converter conv = new Converter(); - Client.CLIENT.displayGuiScreen(new GuiLoading("Konvertiere Welt ...", new Callback() { - public void poll(Client gm, GuiLoading gui) { - if(conv.totalRegions > 0) { - gui.setBar(conv.task, "Regionen", conv.totalRegions); - gui.setProgress(conv.doneRegions); - } - else { - gui.resetBar(); - } - if(conv.totalChunks > 0) { - gui.setSub(conv.file, "Chunks", conv.totalChunks); - gui.setSubProgress(conv.doneChunks); - } - else { - gui.resetSub(); - } - gui.setTask(conv.action); - } - })); - final NBTTagCompound tag = nbt; - new Thread(new Runnable() { - public void run() { - Log.IO.info("Version: %s", ver); - if(ver != SaveVersion.RELEASE_1_13) { - conv.action = "Suche nach Chunk-Daten"; - Log.JNI.info("Konvertiere Chunk-Daten von region/*.mca,*.mcr"); - File regionDir = new File(dir, "region"); - if(regionDir.exists()) { - File chunkDir = new File(new File(dir, "chunk"), "terra"); - Log.JNI.info("Konvertiere Welt nach '" + chunkDir + "' ..."); - Log.JNI.info("Durchsuche Ordner unter '" + regionDir + "' nach .mca- und .mcr-Dateien ..."); - File[] files = regionDir.listFiles(new FilenameFilter() { - public boolean accept(File file, String name) { - return name.endsWith(".mca") || name.endsWith(".mcr"); - } - }); - if(files.length == 0) { - Log.JNI.info("Keine .mca- oder .mcr-Dateien gefunden."); - } - else { - conv.task = "Konvertiere Chunkdaten"; - conv.totalRegions = files.length; - Log.JNI.info("Ingesamt wurden " + files.length + " .mca-Dateien und .mcr-Dateien gefunden, konvertiere ..."); - if(ver == SaveVersion.RELEASE_1_9) - Log.JNI.info("Konvertiere von neuerer Version, dies wird Blöcke entfernen ..."); - chunkDir.mkdirs(); - int progress = 0; - long time = System.currentTimeMillis(); - long start = conv.postProgress(time, 0); - for(File file : files) { - int percent = (int)Math.round(100.0D * (double)progress / (double)files.length); - Log.JNI.info("Konvertiere Chunk-Daten: " + file.getName() + " (" + progress + "/" + files.length + ")"); - start = conv.convertChunks(chunkDir, file, start, progress, files.length); - ++progress; - start = conv.postProgress(start, percent); - conv.doneRegions += 1; - } - time = System.currentTimeMillis() - time; - Log.JNI.info("Fertig. Konversion dauerte " + ((time / 60000L) > 0 ? ((time / 60000L) + " Minuten und ") : "") + ((time / 1000L) % 60L) + " Sekunden."); - } - } - } - else { - Log.JNI.warn("Konvertiere keine Chunk-Daten, da Version zu neu"); - } - conv.doneRegions = 0; - conv.task = null; - conv.action = "Konvertiere level.dat"; - Log.JNI.info("Konvertiere Daten von level.dat"); - Config.clear(); - UniverseRegistry.clear(); - if(tag.hasKey("GameRules", 10)) { - NBTTagCompound rules = tag.getCompoundTag("GameRules"); - for(Entry rule : OLD_GAMERULES.entrySet()) { - if(rules.hasKey(rule.getKey(), 8)) - Config.set(rule.getValue(), rules.getString(rule.getKey()), null); - } - } - // Config.setVar("noRespawn", "" + nbt.getBoolean("hardcore"), false); - // int id = nbt.getInteger("GameType"); - // Config.set("defaultNoCreative", "" + (id == 2 || id == 0), false); - Log.JNI.info("Speichere neue level.nbt ..."); - Region.saveWorldInfo(dir, wtime); -// if(tag.hasKey("Player", 10)) { -// conv.action = "Konvertiere Spielerdaten"; -// NBTTagCompound player = tag.getCompoundTag("Player"); -// NBTTagList pos = player.getTagList("Pos", 6); -// NBTTagList motion = player.getTagList("Motion", 6); -// NBTTagList rotation = player.getTagList("Rotation", 5); -// boolean ground = player.getBoolean("OnGround"); -// BlockPos spawn = null; -// // boolean force = player.getBoolean("OnGround"); -// // int mode = -1; -// // if(player.hasKey("playerGameType", 99)) { -// // mode = player.getInteger("playerGameType"); -// // mode = mode == 0 || mode == 2 ? 0 : (mode == 1 || mode == 3 ? 1 : -1); -// // } -// if(player.hasKey("SpawnX", 99) && player.hasKey("SpawnY", 99) && player.hasKey("SpawnZ", 99)) { -// spawn = new BlockPos(player.getInteger("SpawnX"), player.getInteger("SpawnY"), -// player.getInteger("SpawnZ")); -// // force = player.getBoolean("SpawnForced"); -// } -// player.getKeySet().clear(); -// player.setTag("Pos", pos); -// player.setTag("Motion", motion); -// player.setTag("Rotation", rotation); -// player.setBoolean("OnGround", ground); -// player.setInteger("Dimension", 1); -// player.setString("id", EntityRegistry.getEntityString(EntityHuman.class)); -// if(spawn != null) { -// player.setInteger("SpawnX", spawn.getX()); -// player.setInteger("SpawnY", spawn.getY()); -// player.setInteger("SpawnZ", spawn.getZ()); -// player.setInteger("SpawnDim", 1); -// // player.setBoolean("SpawnForced", force); -// } -// player.setInteger("OriginX", tag.getInteger("SpawnX")); -// player.setInteger("OriginY", tag.getInteger("SpawnY")); -// player.setInteger("OriginZ", tag.getInteger("SpawnZ")); -// player.setInteger("OriginDim", 1); -// player.setString("CustomName", user.substring(0, 1).toUpperCase() + user.substring(1)); -// NBTTagCompound plr = new NBTTagCompound(); -// plr.setInteger("selected", 0); -// NBTTagList list = new NBTTagList(); -// list.appendTag(player); -// plr.setTag("characters", list); -// // if(mode >= 0) -// // player.setBoolean("creative", mode == 1); -// Log.JNI.info("Speichere neue Spielerdaten " + user.toLowerCase() + ".nbt ..."); -// File pdat = new File(new File(dir, "players"), user.toLowerCase() + ".nbt"); -// try { -// pdat.getParentFile().mkdirs(); -// NBTLoader.writeGZip(plr, pdat); -// } -// catch(Exception e) { -// Log.JNI.error(e, "Fehler beim Schreiben von " + pdat); -// } -// } - Weather weather = tag.getBoolean("thundering") ? Weather.THUNDER : (tag.getBoolean("raining") ? Weather.RAIN : Weather.CLEAR); - if(weather != Weather.CLEAR) { - conv.action = "Konvertiere Dimensionsdaten"; - NBTTagCompound dataTag = new NBTTagCompound(); - dataTag.setString("Weather", weather.getName()); - Log.JNI.info("Speichere neue data.nbt ..."); - File dataFile = new File(new File(new File(dir, "chunk"), "terra"), "data.nbt"); - try { - NBTLoader.writeGZip(dataTag, dataFile); - } - catch(Exception e) { - Log.JNI.error(e, "Konnte Weltdaten nicht speichern"); - } - } - Log.IO.info("Welt '" + dir + "' wurde in %d Sekunden konvertiert", (System.currentTimeMillis() - cur) / 1000L); - Client.CLIENT.schedule(new Runnable() { - public void run() { - Client.CLIENT.displayGuiScreen(GuiConvert.INSTANCE); + Log.IO.info("Version: %s", ver); + Log.IO.info("Weltzeit: %d Ticks / %d Sekunden", wtime, wtime / 20L); + Log.IO.info("Zuletzt geladen: %s", new SimpleDateFormat("dd.MM.yyyy HH:mm:ss").format(new Date(nbt.getLong("LastPlayed")))); + if(ver != SaveVersion.RELEASE_1_13) { + Log.JNI.info("Konvertiere Chunk-Daten von region/*.mca,*.mcr"); + File regionDir = new File("region"); + if(regionDir.exists()) { + File chunkDir = new File(new File("chunk"), "terra"); + Log.JNI.info("Konvertiere Welt nach '" + chunkDir + "' ..."); + Log.JNI.info("Durchsuche Ordner unter '" + regionDir + "' nach .mca- und .mcr-Dateien ..."); + File[] files = regionDir.listFiles(new FilenameFilter() { + public boolean accept(File file, String name) { + return name.endsWith(".mca") || name.endsWith(".mcr"); } }); + if(files.length == 0) { + Log.JNI.info("Keine .mca- oder .mcr-Dateien gefunden."); + } + else { + Log.JNI.info("Ingesamt wurden " + files.length + " .mca-Dateien und .mcr-Dateien gefunden, konvertiere ..."); + if(ver == SaveVersion.RELEASE_1_9) + Log.JNI.info("Konvertiere von neuerer Version, dies wird Blöcke entfernen ..."); + chunkDir.mkdirs(); + int progress = 0; + long time = System.currentTimeMillis(); + long start = postProgress(time, 0); + for(File file : files) { + int percent = (int)Math.round(100.0D * (double)progress / (double)files.length); + Log.JNI.info("Konvertiere Chunk-Daten: " + file.getName() + " (" + progress + "/" + files.length + ")"); + start = convertChunks(chunkDir, file, start, progress, files.length); + ++progress; + start = postProgress(start, percent); + } + time = System.currentTimeMillis() - time; + Log.JNI.info("Fertig. Konversion dauerte " + ((time / 60000L) > 0 ? ((time / 60000L) + " Minuten und ") : "") + ((time / 1000L) % 60L) + " Sekunden."); + } } - }, "Converter Thread").start(); - return new FolderInfo(wtime, System.currentTimeMillis(), null, Config.VERSION); + } + else { + Log.JNI.warn("Konvertiere keine Chunk-Daten, da Version zu neu"); + } + Log.JNI.info("Konvertiere Daten von level.dat"); + Config.clear(); + UniverseRegistry.clear(); + if(nbt.hasKey("GameRules", 10)) { + NBTTagCompound rules = nbt.getCompoundTag("GameRules"); + for(Entry rule : OLD_GAMERULES.entrySet()) { + if(rules.hasKey(rule.getKey(), 8)) + Config.set(rule.getValue(), rules.getString(rule.getKey()), null); + } + } + Log.JNI.info("Speichere neue server.nbt ..."); + Server.saveServerConfig(wtime); + Weather weather = nbt.getBoolean("thundering") ? Weather.THUNDER : (nbt.getBoolean("raining") ? Weather.RAIN : Weather.CLEAR); + if(weather != Weather.CLEAR) { + NBTTagCompound dataTag = new NBTTagCompound(); + dataTag.setString("Weather", weather.getName()); + Log.JNI.info("Speichere neue data.nbt ..."); + File dataFile = new File(new File(new File("chunk"), "terra"), "data.nbt"); + try { + NBTLoader.writeGZip(dataTag, dataFile); + } + catch(Exception e) { + Log.JNI.error(e, "Konnte Weltdaten nicht speichern"); + } + } + Log.IO.info("Welt wurde in %d Sekunden konvertiert", (System.currentTimeMillis() - cur) / 1000L); + return true; } - -// public static NBTTagCompound getLegacyWorldInfo(File worldDir) { -// return nbt; -// } } From 2158a700f4db2b865da348d8637761b273dd23e0 Mon Sep 17 00:00:00 2001 From: Sen Date: Mon, 12 May 2025 18:46:07 +0200 Subject: [PATCH 017/200] Revert "add windows support (untested)" This reverts commit 6e5c9e842e65cddb2b2e374fa92d7f007618ed54. --- client/src/client/Client.java | 335 ++++++++---------- client/src/client/PlayerController.java | 34 +- client/src/client/gui/Gui.java | 2 +- client/src/client/gui/GuiConfirm.java | 2 +- client/src/client/gui/GuiConsole.java | 12 +- client/src/client/gui/GuiInfo.java | 2 +- client/src/client/gui/GuiMenu.java | 12 +- client/src/client/gui/GuiServer.java | 2 +- client/src/client/gui/character/GuiChar.java | 50 +-- .../client/gui/character/GuiCharacters.java | 2 +- client/src/client/gui/character/GuiClass.java | 12 +- .../src/client/gui/character/GuiSpecies.java | 8 +- client/src/client/gui/container/GuiChest.java | 2 +- .../client/gui/container/GuiContainer.java | 44 +-- .../src/client/gui/container/GuiEnchant.java | 6 +- .../src/client/gui/container/GuiHopper.java | 2 +- client/src/client/gui/container/GuiHorse.java | 2 +- .../src/client/gui/container/GuiMachine.java | 2 +- .../src/client/gui/container/GuiRepair.java | 2 +- client/src/client/gui/ingame/GuiGameOver.java | 4 +- client/src/client/network/ClientPlayer.java | 72 ++-- .../src/client/renderer/EntityRenderer.java | 56 +-- client/src/client/renderer/ItemRenderer.java | 20 +- client/src/client/renderer/RenderGlobal.java | 18 +- .../client/renderer/entity/RenderFish.java | 2 +- .../renderer/entity/RenderHumanoid.java | 4 +- common/src/common/log/Log.java | 10 +- common/src/common/util/Util.java | 11 +- 28 files changed, 351 insertions(+), 379 deletions(-) diff --git a/client/src/client/Client.java b/client/src/client/Client.java index e0ab9f0..a9529d8 100755 --- a/client/src/client/Client.java +++ b/client/src/client/Client.java @@ -30,7 +30,6 @@ import java.util.concurrent.FutureTask; import java.util.function.Function; import javax.imageio.ImageIO; -import javax.swing.JFileChooser; import org.lwjgl.opengl.GL11; import org.lwjgl.opengl.GL13; @@ -342,8 +341,8 @@ public class Client implements IThreadListener, IClient { private BufferedImage skin; private Object popupTarget; public PlayerController controller; - public WorldClient world; - public EntityNPC player; + public WorldClient theWorld; + public EntityNPC thePlayer; public HitPosition pointed; @Variable(name = "chunk_view_distance", category = CVarCategory.RENDER, min = 2, max = 16 /* 128 */, callback = DistanceFunction.class, display = "Sichtweite", unit = "Chunks") @@ -520,8 +519,8 @@ public class Client implements IThreadListener, IClient { this.charEditor = false; this.viewEntity = null; this.connection = null; - this.world = null; - this.player = null; + this.theWorld = null; + this.thePlayer = null; this.serverInfo = null; this.lastTickTime = -1; this.soundManager.stopSounds(); @@ -574,7 +573,7 @@ public class Client implements IThreadListener, IClient { this.renderGlobal = new RenderGlobal(this); this.renderGlobal.onReload(); EntityTexManager.loadNpcTextures(); - this.effectRenderer = new EffectRenderer(this.world, this.textureManager); + this.effectRenderer = new EffectRenderer(this.theWorld, this.textureManager); } public void start() @@ -644,7 +643,7 @@ public class Client implements IThreadListener, IClient { if (this.keyBindsHotbar[l].isPressed()) { // if(!this.showDebugProfilerChart) { - this.player.inventory.currentItem = l; + this.thePlayer.inventory.currentItem = l; // } } } @@ -655,7 +654,7 @@ public class Client implements IThreadListener, IClient { if (Bind.THROW.isPressed()) { - this.player.dropOneItem(this.ctrl()); + this.thePlayer.dropOneItem(this.ctrl()); } this.primary |= Bind.PRIMARY.isPressed(); @@ -672,7 +671,7 @@ public class Client implements IThreadListener, IClient { } // this.ingameGui.updateTick(); this.entityRenderer.getMouseOver(1.0F); - if (/* !this.paused && */ this.world != null) + if (/* !this.paused && */ this.theWorld != null) { this.controller.updateController(); } @@ -682,9 +681,9 @@ public class Client implements IThreadListener, IClient { this.open.updateScreen(); } - if (this.open == null && this.player != null) + if (this.open == null && this.thePlayer != null) { - if (this.player.getHealth() <= 0) + if (this.thePlayer.getHealth() <= 0) { this.displayGuiScreen(null); } @@ -699,12 +698,12 @@ public class Client implements IThreadListener, IClient { --this.leftClickCounter; } - if (this.open == null && this.player != null) { - if (this.player.isUsingItem()) + if (this.open == null && this.thePlayer != null) { + if (this.thePlayer.isUsingItem()) { if (!Bind.SECONDARY.isDown()) { - this.controller.onStoppedUsingItem(this.player); + this.controller.onStoppedUsingItem(this.thePlayer); } } else @@ -730,7 +729,7 @@ public class Client implements IThreadListener, IClient { } } - if (Bind.SECONDARY.isDown() && this.rightClickTimer == 0 && !this.player.isUsingItem()) + if (Bind.SECONDARY.isDown() && this.rightClickTimer == 0 && !this.thePlayer.isUsingItem()) { this.secondary(); } @@ -740,30 +739,30 @@ public class Client implements IThreadListener, IClient { this.primary = this.secondary = this.tertiary = this.quarternary = false; - if (this.world != null) + if (this.theWorld != null) { - if (this.player != null) + if (this.thePlayer != null) { ++this.chunkLoadTimer; if (this.chunkLoadTimer == 30) { this.chunkLoadTimer = 0; - this.world.ensureAreaLoaded(this.player); + this.theWorld.ensureAreaLoaded(this.thePlayer); } } this.entityRenderer.updateRenderer(); this.renderGlobal.updateClouds(); - this.world.decrLightning(); - this.world.updateEntities(); + this.theWorld.decrLightning(); + this.theWorld.updateEntities(); } this.soundManager.update(); - if (this.world != null) + if (this.theWorld != null) { - this.world.tick(); - if (/* !this.paused && */ this.world != null) + this.theWorld.tick(); + if (/* !this.paused && */ this.theWorld != null) { - this.world.displayTick(ExtMath.floord(this.player.posX), ExtMath.floord(this.player.posY), ExtMath.floord(this.player.posZ)); + this.theWorld.displayTick(ExtMath.floord(this.thePlayer.posX), ExtMath.floord(this.thePlayer.posY), ExtMath.floord(this.thePlayer.posZ)); } this.effectRenderer.updateEffects(); } @@ -783,18 +782,18 @@ public class Client implements IThreadListener, IClient { GL11.glPolygonMode(GL11.GL_FRONT_AND_BACK, GL11.GL_LINE); // GL_FRONT_AND_BACK, GL_LINE } if(this.open == null) { - if(this.player != null) - this.player.setAngles(this.deltaX, this.deltaY); + if(this.thePlayer != null) + this.thePlayer.setAngles(this.deltaX, this.deltaY); this.deltaX = this.deltaY = 0.0f; } - if(this.player != null) - this.soundManager.setListener(this.player, (float)Timing.tick_fraction); - if(this.player != null && this.player.isEntityInsideOpaqueBlock()) + if(this.thePlayer != null) + this.soundManager.setListener(this.thePlayer, (float)Timing.tick_fraction); + if(this.thePlayer != null && this.thePlayer.isEntityInsideOpaqueBlock()) this.thirdPersonView = 0; GL11.glPushMatrix(); GL11.glClear(16640); GlState.enableTexture2D(); - if(this.world != null) + if(this.theWorld != null) this.entityRenderer.renderWorld((float)Timing.tick_fraction, System.nanoTime() - this.tickStart); GL11.glPopMatrix(); @@ -826,7 +825,7 @@ public class Client implements IThreadListener, IClient { public void renderHud() { this.setupOverlay(); - if(this.world != null && this.open == null && this.thirdPersonView == 0 && this.viewEntity != null) { + if(this.theWorld != null && this.open == null && this.thirdPersonView == 0 && this.viewEntity != null) { if(this.drawDebug) { this.renderWorldDirections((float)Timing.tick_fraction); } @@ -835,7 +834,7 @@ public class Client implements IThreadListener, IClient { Drawing.drawRect(this.fb_x / 2 - 16, this.fb_y / 2 - 1, 32, 2, this.pointed != null && this.pointed.type != ObjectType.MISS ? 0xffffffff : 0xffcfcfcf); } } - if(this.world != null && this.open == null) { + if(this.theWorld != null && this.open == null) { int selected = // this.getRenderViewEntity() != null && this.getRenderViewEntity().isPlayer() ? 9 : 0, this.getRenderViewEntity() != null && this.getRenderViewEntity().isPlayer() ? ((EntityNPC)this.getRenderViewEntity()).inventory.currentItem : -1; @@ -846,12 +845,12 @@ public class Client implements IThreadListener, IClient { Drawing.drawRectBorder(x - 1, y - 1, 36, 36, 0xff6f6f6f, selected == n ? 0xffffffff : 0xff000000, 0xffafafaf, 0xff4f4f4f); } - ItemStack itemstack = this.player != null ? this.player.inventory.getCurrentItem() : null; - String current = itemstack != null ? itemstack.getItem().getHotbarText(this.player, itemstack) : ""; + ItemStack itemstack = this.thePlayer != null ? this.thePlayer.inventory.getCurrentItem() : null; + String current = itemstack != null ? itemstack.getItem().getHotbarText(this.thePlayer, itemstack) : ""; if(!current.isEmpty()) Drawing.drawTextUpward(current, this.fb_x / 2, this.fb_y - 60, 0xffffffff); } - if(this.world != null && !(this.open instanceof GuiConsole)) { + if(this.theWorld != null && !(this.open instanceof GuiConsole)) { int x = this.fb_x / 2; int y = 0; Iterator> iter = this.bars.entrySet().iterator(); @@ -859,7 +858,7 @@ public class Client implements IThreadListener, IClient { while(iter.hasNext()) { Entry status = iter.next(); Entity ent; - if(this.player != null && now - status.getValue() < 10000L && (ent = this.player.worldObj.getEntityByID(status.getKey())) instanceof EntityLiving) { + if(this.thePlayer != null && now - status.getValue() < 10000L && (ent = this.thePlayer.worldObj.getEntityByID(status.getKey())) instanceof EntityLiving) { EntityLiving entity = (EntityLiving)ent; String s = entity.getName() + TextColor.GRAY + " [" + EntityLiving.getHealthColor(entity.getHealth(), entity.getMaxHealth()) + @@ -877,10 +876,10 @@ public class Client implements IThreadListener, IClient { } } - if(this.player != null && (!this.drawDebug || this.open != null)) { + if(this.thePlayer != null && (!this.drawDebug || this.open != null)) { x = 40; y = 40; - for(PotionEffect effect : this.player.getEffects()) { + for(PotionEffect effect : this.thePlayer.getEffects()) { Potion potion = effect.getPotion(); int color = potion.getColor(); String name = (potion.isBadEffect() ? TextColor.ORANGE : TextColor.ACID) + potion.getDisplay() + PotionHelper.getPotionPotency(effect.getAmplifier()); @@ -934,15 +933,15 @@ public class Client implements IThreadListener, IClient { } } - if(this.player != null) { + if(this.thePlayer != null) { x = 40; - y = this.fb_y - 40 - (this.player.isRidingHorse() && this.player.getHorseJumpPower() != 0.0f ? 2 : 1) * 40; - if(this.player.isRidingHorse() && this.player.getHorseJumpPower() != 0.0f) // { - y = bar(x, y, String.format(TextColor.NEON + "Sprungkraft: " + TextColor.CYAN + "%d %%", (int)(this.player.getHorseJumpPower() * 100.0f)), - this.player.getHorseJumpPower(), 0x4040ff); + y = this.fb_y - 40 - (this.thePlayer.isRidingHorse() && this.thePlayer.getHorseJumpPower() != 0.0f ? 2 : 1) * 40; + if(this.thePlayer.isRidingHorse() && this.thePlayer.getHorseJumpPower() != 0.0f) // { + y = bar(x, y, String.format(TextColor.NEON + "Sprungkraft: " + TextColor.CYAN + "%d %%", (int)(this.thePlayer.getHorseJumpPower() * 100.0f)), + this.thePlayer.getHorseJumpPower(), 0x4040ff); // } // else { - y = bar(x, y, String.format(TextColor.ACID + "EXP: " + TextColor.GREEN + "Level %d, %d/%d", this.player.experienceLevel, (int)((float)this.player.xpBarCap() * this.player.experience), this.player.xpBarCap()), this.player.experience, 0x40ff40); + y = bar(x, y, String.format(TextColor.ACID + "EXP: " + TextColor.GREEN + "Level %d, %d/%d", this.thePlayer.experienceLevel, (int)((float)this.thePlayer.xpBarCap() * this.thePlayer.experience), this.thePlayer.xpBarCap()), this.thePlayer.experience, 0x40ff40); // } } @@ -1013,7 +1012,7 @@ public class Client implements IThreadListener, IClient { } if(this.open != null) this.open.render(); - else if(this.world == null || this.world.hasNoChunks() || this.charEditor) + else if(this.theWorld == null || this.theWorld.hasNoChunks() || this.charEditor) Drawing.drawScaled(this, Gui.DIRT_BACKGROUND); if(Bind.INFO.isDown() && (this.open == null || !(this.open.selected instanceof Textbox))) this.drawInfo(); @@ -1112,8 +1111,8 @@ public class Client implements IThreadListener, IClient { } if(this.cameraUsed) { this.cameraUsed = false; - if(this.world != null) - this.world.setLastLightning(1, 0xffffff); + if(this.theWorld != null) + this.theWorld.setLastLightning(1, 0xffffff); } if(this.isDirty()) this.save(); @@ -1140,8 +1139,8 @@ public class Client implements IThreadListener, IClient { // } if(this.zooming) this.zoomLevel = ExtMath.clampf(this.zoomLevel + (dir < 0 ? -0.25f : 0.25f), 2.0f, 16.0f); - else if(this.player != null) - this.player.inventory.changeCurrentItem(dir); + else if(this.thePlayer != null) + this.thePlayer.inventory.changeCurrentItem(dir); } // public void resize(int width, int height) @@ -1180,8 +1179,8 @@ public class Client implements IThreadListener, IClient { { if(!this.refreshing) this.waitingForFile = false; - if(this.player != null) - this.player.setScreenClosed(); + if(this.thePlayer != null) + this.thePlayer.setScreenClosed(); if (this.open != null) { this.open.onGuiClosed(); @@ -1194,7 +1193,7 @@ public class Client implements IThreadListener, IClient { // guiScreenIn = new GuiMainMenu(); // } // else - if (gui == null && this.world != null && this.player.getHealth() <= 0) + if (gui == null && this.theWorld != null && this.thePlayer.getHealth() <= 0) { gui = GuiGameOver.INSTANCE; } @@ -1236,16 +1235,16 @@ public class Client implements IThreadListener, IClient { this.controller.resetInteraction(); } - if (this.leftClickCounter <= 0 && !this.player.isUsingItem()) + if (this.leftClickCounter <= 0 && !this.thePlayer.isUsingItem()) { if (leftClick && this.pointed != null && this.pointed.type == HitPosition.ObjectType.BLOCK) { BlockPos blockpos = this.pointed.block; - if (this.world.getState(blockpos).getBlock().getMaterial() != Material.air && this.controller.onPlayerDamageBlock(blockpos, this.pointed.side)) + if (this.theWorld.getState(blockpos).getBlock().getMaterial() != Material.air && this.controller.onPlayerDamageBlock(blockpos, this.pointed.side)) { this.effectRenderer.addBlockHitEffects(blockpos, this.pointed.side); - this.player.swingItem(); + this.thePlayer.swingItem(); } } else @@ -1261,17 +1260,17 @@ public class Client implements IThreadListener, IClient { { if (this.pointed == null) { - this.player.swingItem(); + this.thePlayer.swingItem(); Log.JNI.warn("Null zurückgegeben als 'hitResult', das sollte niemals passieren!"); this.leftClickCounter = 10; } else { - ItemStack itemstack = this.player.inventory.getCurrentItem(); - if ((this.pointed.type != ObjectType.BLOCK || this.world.getState(this.pointed.block).getBlock().getMaterial() == Material.air) && itemstack != null && itemstack.getItem().onAction(itemstack, this.player, this.world, ItemControl.PRIMARY, null)) + ItemStack itemstack = this.thePlayer.inventory.getCurrentItem(); + if ((this.pointed.type != ObjectType.BLOCK || this.theWorld.getState(this.pointed.block).getBlock().getMaterial() == Material.air) && itemstack != null && itemstack.getItem().onAction(itemstack, this.thePlayer, this.theWorld, ItemControl.PRIMARY, null)) { - this.player.swingItem(); - this.player.sendQueue.addToSendQueue(new CPacketAction(Action.ITEM_ACTION, ItemControl.PRIMARY.ordinal())); + this.thePlayer.swingItem(); + this.thePlayer.sendQueue.addToSendQueue(new CPacketAction(Action.ITEM_ACTION, ItemControl.PRIMARY.ordinal())); this.leftClickCounter = 10; return; } @@ -1279,13 +1278,13 @@ public class Client implements IThreadListener, IClient { switch (this.pointed.type) { case ENTITY: - this.player.swingItem(); - this.controller.attackEntity(this.player, this.pointed.entity); + this.thePlayer.swingItem(); + this.controller.attackEntity(this.thePlayer, this.pointed.entity); break; case BLOCK: - this.player.swingItem(); + this.thePlayer.swingItem(); BlockPos blockpos = this.pointed.block; - if (this.world.getState(blockpos).getBlock().getMaterial() != Material.air) + if (this.theWorld.getState(blockpos).getBlock().getMaterial() != Material.air) { this.controller.clickBlock(blockpos, this.pointed.side); break; @@ -1294,7 +1293,7 @@ public class Client implements IThreadListener, IClient { break; case MISS: default: - this.player.swingItem(); + this.thePlayer.swingItem(); this.leftClickCounter = 10; } } @@ -1307,7 +1306,7 @@ public class Client implements IThreadListener, IClient { { this.rightClickTimer = 4; boolean flag = true; - ItemStack itemstack = this.player.inventory.getCurrentItem(); + ItemStack itemstack = this.thePlayer.inventory.getCurrentItem(); if (itemstack != null && itemstack.getItem() == Items.camera && !this.saving) { @@ -1320,10 +1319,10 @@ public class Client implements IThreadListener, IClient { } else { - if ((this.pointed.type != ObjectType.BLOCK || this.world.getState(this.pointed.block).getBlock().getMaterial() == Material.air) && itemstack != null && itemstack.getItem().onAction(itemstack, this.player, this.world, ItemControl.SECONDARY, null)) + if ((this.pointed.type != ObjectType.BLOCK || this.theWorld.getState(this.pointed.block).getBlock().getMaterial() == Material.air) && itemstack != null && itemstack.getItem().onAction(itemstack, this.thePlayer, this.theWorld, ItemControl.SECONDARY, null)) { - this.player.swingItem(); - this.player.sendQueue.addToSendQueue(new CPacketAction(Action.ITEM_ACTION, ItemControl.SECONDARY.ordinal())); + this.thePlayer.swingItem(); + this.thePlayer.sendQueue.addToSendQueue(new CPacketAction(Action.ITEM_ACTION, ItemControl.SECONDARY.ordinal())); return; } @@ -1335,7 +1334,7 @@ public class Client implements IThreadListener, IClient { // flag = false; // } // else - if (this.controller.interactWithEntitySendPacket(this.player, this.pointed.entity)) + if (this.controller.interactWithEntitySendPacket(this.thePlayer, this.pointed.entity)) { flag = false; } @@ -1345,14 +1344,14 @@ public class Client implements IThreadListener, IClient { case BLOCK: BlockPos blockpos = this.pointed.block; - if (this.world.getState(blockpos).getBlock().getMaterial() != Material.air) + if (this.theWorld.getState(blockpos).getBlock().getMaterial() != Material.air) { int i = itemstack != null ? itemstack.stackSize : 0; - if (this.controller.onPlayerRightClick(this.player, this.world, itemstack, blockpos, this.pointed.side, this.pointed.vec)) + if (this.controller.onPlayerRightClick(this.thePlayer, this.theWorld, itemstack, blockpos, this.pointed.side, this.pointed.vec)) { flag = false; - this.player.swingItem(); + this.thePlayer.swingItem(); } if (itemstack == null) @@ -1362,7 +1361,7 @@ public class Client implements IThreadListener, IClient { if (itemstack.stackSize == 0) { - this.player.inventory.mainInventory[this.player.inventory.currentItem] = null; + this.thePlayer.inventory.mainInventory[this.thePlayer.inventory.currentItem] = null; } else if (itemstack.stackSize != i) // || this.controller.isCreative()) { @@ -1374,9 +1373,9 @@ public class Client implements IThreadListener, IClient { if (flag) { - ItemStack itemstack1 = this.player.inventory.getCurrentItem(); + ItemStack itemstack1 = this.thePlayer.inventory.getCurrentItem(); - if (itemstack1 != null && this.controller.sendUseItem(this.player, this.world, itemstack1)) + if (itemstack1 != null && this.controller.sendUseItem(this.thePlayer, this.theWorld, itemstack1)) { this.entityRenderer.itemRenderer.resetEquippedProgress2(); } @@ -1388,8 +1387,8 @@ public class Client implements IThreadListener, IClient { { if (this.pointed != null) { - if(this.player.getHeldItem() != null && this.player.getHeldItem().getItem().onAction(this.player.getHeldItem(), this.player, this.world, ItemControl.TERTIARY, null)) { - this.player.sendQueue.addToSendQueue(new CPacketAction(Action.ITEM_ACTION, ItemControl.TERTIARY.ordinal())); + if(this.thePlayer.getHeldItem() != null && this.thePlayer.getHeldItem().getItem().onAction(this.thePlayer.getHeldItem(), this.thePlayer, this.theWorld, ItemControl.TERTIARY, null)) { + this.thePlayer.sendQueue.addToSendQueue(new CPacketAction(Action.ITEM_ACTION, ItemControl.TERTIARY.ordinal())); return; } @@ -1403,14 +1402,14 @@ public class Client implements IThreadListener, IClient { if (this.pointed.type == HitPosition.ObjectType.BLOCK) { BlockPos blockpos = this.pointed.block; - Block block = this.world.getState(blockpos).getBlock(); + Block block = this.theWorld.getState(blockpos).getBlock(); if (block.getMaterial() == Material.air) { return; } - item = block.getItem(this.world, blockpos); + item = block.getItem(this.theWorld, blockpos); if (item == null) { @@ -1418,7 +1417,7 @@ public class Client implements IThreadListener, IClient { } Block block1 = item instanceof ItemBlock && !block.isPickStrict() ? item.getBlock() : block; - meta = block1.getDamageValue(this.world, blockpos); + meta = block1.getDamageValue(this.theWorld, blockpos); flag1 = item.getHasSubtypes(); } else @@ -1432,11 +1431,11 @@ public class Client implements IThreadListener, IClient { return; } - InventoryPlayer inventoryplayer = this.player.inventory; + InventoryPlayer inventoryplayer = this.thePlayer.inventory; inventoryplayer.setCurrentItem(item, meta, flag1); if(this.itemCheat) { - this.player.sendQueue.addToSendQueue(new CPacketCheat(new ItemStack(item, 1, meta), inventoryplayer.currentItem, this.ctrl())); + this.thePlayer.sendQueue.addToSendQueue(new CPacketCheat(new ItemStack(item, 1, meta), inventoryplayer.currentItem, this.ctrl())); } } } @@ -1445,8 +1444,8 @@ public class Client implements IThreadListener, IClient { { if (this.pointed != null) { - if(this.player.getHeldItem() != null && this.player.getHeldItem().getItem().onAction(this.player.getHeldItem(), this.player, this.world, ItemControl.QUARTERNARY, null)) { - this.player.sendQueue.addToSendQueue(new CPacketAction(Action.ITEM_ACTION, ItemControl.QUARTERNARY.ordinal())); + if(this.thePlayer.getHeldItem() != null && this.thePlayer.getHeldItem().getItem().onAction(this.thePlayer.getHeldItem(), this.thePlayer, this.theWorld, ItemControl.QUARTERNARY, null)) { + this.thePlayer.sendQueue.addToSendQueue(new CPacketAction(Action.ITEM_ACTION, ItemControl.QUARTERNARY.ordinal())); return; } } @@ -1466,7 +1465,7 @@ public class Client implements IThreadListener, IClient { this.viewEntity = null; this.connection = null; this.soundManager.stopSounds(); - this.world = world; + this.theWorld = world; if (this.renderGlobal != null) { @@ -1478,15 +1477,15 @@ public class Client implements IThreadListener, IClient { this.effectRenderer.clearEffects(world); } - if (this.player == null) + if (this.thePlayer == null) { - this.player = this.controller.createPlayerEntity(world, type); - this.player.rotYaw = -180.0F; + this.thePlayer = this.controller.createPlayerEntity(world, type); + this.thePlayer.rotYaw = -180.0F; } - this.player.preparePlayerToSpawn(); - world.spawnEntityInWorld(this.player); - this.viewEntity = this.player; + this.thePlayer.preparePlayerToSpawn(); + world.spawnEntityInWorld(this.thePlayer); + this.viewEntity = this.thePlayer; System.gc(); // SKC.loaded(true); @@ -1494,24 +1493,24 @@ public class Client implements IThreadListener, IClient { public void setDimensionAndSpawnPlayer(int dimension, int type) { - this.world.removeAllEntities(); + this.theWorld.removeAllEntities(); int i = 0; - if (this.player != null) + if (this.thePlayer != null) { - i = this.player.getId(); - this.world.removeEntity(this.player); + i = this.thePlayer.getId(); + this.theWorld.removeEntity(this.thePlayer); } this.viewEntity = null; - EntityNPC entityplayersp = this.player; - this.player = this.controller.createPlayerEntity(this.world, type); - this.player.getDataWatcher().updateWatchedObjectsFromList(entityplayersp.getDataWatcher().getAllWatched()); - this.viewEntity = this.player; - this.player.preparePlayerToSpawn(); - this.world.spawnEntityInWorld(this.player); - this.player.rotYaw = -180.0F; - this.player.setId(i); + EntityNPC entityplayersp = this.thePlayer; + this.thePlayer = this.controller.createPlayerEntity(this.theWorld, type); + this.thePlayer.getDataWatcher().updateWatchedObjectsFromList(entityplayersp.getDataWatcher().getAllWatched()); + this.viewEntity = this.thePlayer; + this.thePlayer.preparePlayerToSpawn(); + this.theWorld.spawnEntityInWorld(this.thePlayer); + this.thePlayer.rotYaw = -180.0F; + this.thePlayer.setId(i); // if (this.open instanceof GuiGameOver) // { @@ -1522,7 +1521,7 @@ public class Client implements IThreadListener, IClient { public ClientPlayer getNetHandler() { - return this.player != null ? (ClientPlayer)this.player.sendQueue : null; + return this.thePlayer != null ? (ClientPlayer)this.thePlayer.sendQueue : null; } // public void setSkin(BufferedImage skin, String id, ModelType model, boolean slim) @@ -1568,8 +1567,8 @@ public class Client implements IThreadListener, IClient { } public void performAction(Action action) { - if(this.player != null) - this.player.sendQueue.addToSendQueue(new CPacketAction(action)); + if(this.thePlayer != null) + this.thePlayer.sendQueue.addToSendQueue(new CPacketAction(action)); } public void setBossStatus(EntityLiving entity) { @@ -1709,7 +1708,7 @@ public class Client implements IThreadListener, IClient { String mem = String.format("JVM-Speicher: %d%% %d/%dMB", usedMem * 100L / maxMem, usedMem / 1024L / 1024L, maxMem / 1024L / 1024L) + "\n" + String.format("JVM-Reserviert: %d%% %dMB", totalMem * 100L / maxMem, totalMem / 1024L / 1024L); - if(this.world == null) { + if(this.theWorld == null) { return mem; } @@ -1737,27 +1736,27 @@ public class Client implements IThreadListener, IClient { Biome biome = null; String bline; String lline; - if(this.world.isBlockLoaded(blockpos)) { - Chunk chunk = this.world.getChunk(blockpos); + if(this.theWorld.isBlockLoaded(blockpos)) { + Chunk chunk = this.theWorld.getChunk(blockpos); biome = chunk.getBiome(blockpos, null); bline = "Biom: " + biome.display + " (" + biome.id + ")" + /* (this.debugHideInfo ? "" : */ (", D: " + - TextColor.stripCodes(this.world.dimension.getFormattedName(false)) + - " (" + this.world.dimension.getDimensionId() + ")"); + TextColor.stripCodes(this.theWorld.dimension.getFormattedName(false)) + + " (" + this.theWorld.dimension.getDimensionId() + ")"); lline = "Licht: " + chunk.getLightSub(blockpos, 0) + " (" + chunk.getLight(LightType.SKY, blockpos) + " Himmel, " + chunk.getLight(LightType.BLOCK, blockpos) + " Blöcke, " + String.format( - "%.1f", this.world.getSunBrightness(1.0f) * 15.0f) + " Welt), A: " - + String.format("%.3f", this.world.getCelestialAngle(1.0f)); + "%.1f", this.theWorld.getSunBrightness(1.0f) * 15.0f) + " Welt), A: " + + String.format("%.3f", this.theWorld.getCelestialAngle(1.0f)); } else { bline = "Biom: , D: " + - TextColor.stripCodes(this.world.dimension.getFormattedName(false)) + - " (" + this.world.dimension.getDimensionId() + ")"; + TextColor.stripCodes(this.theWorld.dimension.getFormattedName(false)) + + " (" + this.theWorld.dimension.getDimensionId() + ")"; lline = "Licht: " + String.format( - "%.1f", this.world.getSunBrightness(1.0f) * 15.0f) + " Welt, A: " - + String.format("%.3f", this.world.getCelestialAngle(1.0f)); + "%.1f", this.theWorld.getSunBrightness(1.0f) * 15.0f) + " Welt, A: " + + String.format("%.3f", this.theWorld.getCelestialAngle(1.0f)); } - float temp = this.world.getTempOffset() + (biome != null ? biome.getTemperature(blockpos) : 0.0f); + float temp = this.theWorld.getTempOffset() + (biome != null ? biome.getTemperature(blockpos) : 0.0f); long ticked = System.currentTimeMillis() - this.lastTicked; return @@ -1768,8 +1767,8 @@ public class Client implements IThreadListener, IClient { // this.connected != null ? this.connected : "[???]"))), this.renderGlobal.getDebugInfoRenders() + "\n" + this.renderGlobal.getDebugInfoEntities() + "\n" + - "Partikel: " + this.effectRenderer.getStatistics() + ". O: " + this.world.getDebugLoadedEntities() + "\n" + - this.world.getInfo() + "\n" + + "Partikel: " + this.effectRenderer.getStatistics() + ". O: " + this.theWorld.getDebugLoadedEntities() + "\n" + + this.theWorld.getInfo() + "\n" + // "", String.format("XYZ: %.3f / %.3f / %.3f", this.viewEntity.posX, this.viewEntity.getEntityBoundingBox().minY, this.viewEntity.posZ) + "\n" + @@ -1785,21 +1784,21 @@ public class Client implements IThreadListener, IClient { bline + "\n" + lline + "\n" + String.format("Zeit: %d T, R %d / %d T, U %d / %d T", - this.world.getDayTime(), - this.world.getDayTime() % this.world.dimension.getRotationalPeriod(), - this.world.dimension.getRotationalPeriod(), - this.world.getDayTime() % this.world.dimension.getOrbitalPeriod(), - this.world.dimension.getOrbitalPeriod() + this.theWorld.getDayTime(), + this.theWorld.getDayTime() % this.theWorld.dimension.getRotationalPeriod(), + this.theWorld.dimension.getRotationalPeriod(), + this.theWorld.getDayTime() % this.theWorld.dimension.getOrbitalPeriod(), + this.theWorld.dimension.getOrbitalPeriod() ) + "\n" + String.format("Laub: %s%s, T: %.2f K / %.2f °C, %s (R %.1f, %.1f)", - !this.world.dimension.getType().days ? "*" : "", - this.world.getLeavesGen(blockpos).getDisplayName(), + !this.theWorld.dimension.getType().days ? "*" : "", + this.theWorld.getLeavesGen(blockpos).getDisplayName(), temp, World.ABSOLUTE_ZERO + temp, - this.world.getWeather().getDisplay(), this.world.getRainStrength(), - this.world.getDarkness() + this.theWorld.getWeather().getDisplay(), this.theWorld.getRainStrength(), + this.theWorld.getDarkness() ) + "\n" + String.format("Zeitfaktor: %dx, Schwerkraft: %.2f m/s²", - this.timeFactor, this.world.gravity * 10.0 + this.timeFactor, this.theWorld.gravity * 10.0 ) + "\n" + String.format("Letzte Zeitsynch.: + %d.%d s", ticked / 1000L, (ticked / 100L) % 10L @@ -1812,17 +1811,17 @@ public class Client implements IThreadListener, IClient { } public String getRight(boolean showPlayerInfo) { - if(this.world == null) { + if(this.theWorld == null) { return null; } if(!showPlayerInfo && this.pointed != null && this.pointed.type == HitPosition.ObjectType.BLOCK && this.pointed.block != null) { BlockPos pos = this.pointed.block; - State block = this.world.getState(pos); + State block = this.theWorld.getState(pos); if(!this.debugWorld) { - block = block.getBlock().getActualState(block, this.world, pos); + block = block.getBlock().getActualState(block, this.theWorld, pos); } StringBuilder str = new StringBuilder( @@ -1842,7 +1841,7 @@ public class Client implements IThreadListener, IClient { } else if((this.pointed != null && this.pointed.type == HitPosition.ObjectType.ENTITY && this.pointed.entity != null) || showPlayerInfo) { - Entity entity = showPlayerInfo ? this.player : this.pointed.entity; + Entity entity = showPlayerInfo ? this.thePlayer : this.pointed.entity; ItemStack held = entity instanceof EntityLiving && ((EntityLiving)entity).getHeldItem() != null ? ((EntityLiving)entity).getHeldItem() : null; return @@ -2261,24 +2260,24 @@ public class Client implements IThreadListener, IClient { // if(this.theWorld != null && this.open == null && Bind.COMMAND.isPressed()) { // this.displayGuiScreen(GuiChat.INSTANCE); // } - if(this.world != null && Bind.MENU.isPressed()) { + if(this.theWorld != null && Bind.MENU.isPressed()) { if(this.open != (this.charEditor ? GuiChar.INSTANCE : null)) this.displayGuiScreen(this.charEditor ? GuiChar.INSTANCE : null); else this.displayGuiScreen(GuiMenu.INSTANCE); } - else if(this.world == null && !(this.open instanceof GuiMenu) && Bind.MENU.isPressed()) { + else if(this.theWorld == null && !(this.open instanceof GuiMenu) && Bind.MENU.isPressed()) { this.displayGuiScreen(GuiMenu.INSTANCE); } - if(this.world != null && !this.charEditor && Bind.INVENTORY.isPressed()) { + if(this.theWorld != null && !this.charEditor && Bind.INVENTORY.isPressed()) { if(this.open instanceof GuiContainer) { this.displayGuiScreen(null); } else if(this.open == null) { - if(this.player.isRiding() && this.player.vehicle instanceof EntityHorse) - this.player.sendHorseInventory(); + if(this.thePlayer.isRiding() && this.thePlayer.vehicle instanceof EntityHorse) + this.thePlayer.sendHorseInventory(); else - this.displayGuiScreen(/* this.itemCheat ? new GuiCheat() : */ new GuiInventory(this.player)); + this.displayGuiScreen(/* this.itemCheat ? new GuiCheat() : */ new GuiInventory(this.thePlayer)); } } } @@ -2393,7 +2392,7 @@ public class Client implements IThreadListener, IClient { } public void unload(boolean loading) { - if(this.world != null) { + if(this.theWorld != null) { if(this.getNetHandler() != null) this.getNetHandler().getNetworkManager().closeChannel("Quitting"); this.unloadWorld(); @@ -2905,7 +2904,7 @@ public class Client implements IThreadListener, IClient { return; } } - if(this.player != null && this.getNetHandler() != null) + if(this.thePlayer != null && this.getNetHandler() != null) this.getNetHandler().addToSendQueue(new CPacketMessage(line.startsWith("/") ? CPacketMessage.Type.COMMAND : CPacketMessage.Type.CHAT, line.startsWith("/") ? line.substring(1) : line)); // Log.CONSOLE.user("%s", line); // this.command(line); @@ -3215,11 +3214,8 @@ public class Client implements IThreadListener, IClient { this.waitingForFile = true; new Thread(new Runnable() { public void run() { - String output = null; - JFileChooser chooser = null; + String output; try { - if(Util.WINDOWS) - throw new RuntimeException("Windows wird von Zenity nicht unterstützt"); List list = Lists.newArrayList("zenity", "--file-selection"); switch(mode) { case DIRECTORY_SAVE: @@ -3253,40 +3249,21 @@ public class Client implements IThreadListener, IClient { } } catch(Throwable e) { - Log.SYSTEM.error(e, "Konnte Dateibrowser nicht starten"); - chooser = new JFileChooser(def.isDirectory() ? def : def.getParentFile()); - chooser.setDialogTitle(title); - chooser.setMultiSelectionEnabled(mode == FileMode.FILE_LOAD_MULTI); - chooser.setFileSelectionMode(mode == FileMode.DIRECTORY_LOAD || mode == FileMode.DIRECTORY_SAVE ? JFileChooser.DIRECTORIES_ONLY : JFileChooser.FILES_ONLY); - int result; - if(mode == FileMode.FILE_SAVE || mode == FileMode.DIRECTORY_SAVE) - result = chooser.showSaveDialog(null); - else - result = chooser.showOpenDialog(null); - if(result != JFileChooser.APPROVE_OPTION) { -// Client.this.logFeed(TextColor.RED + "Konnte Dateibrowser nicht öffnen"); - Client.this.waitingForFile = false; - return; - } + Log.SYSTEM.error(e, "Konnte Zenity nicht starten"); + Client.this.logFeed(TextColor.RED + "Konnte Dateibrowser nicht öffnen"); + Client.this.waitingForFile = false; + return; } - if(output == null && chooser == null) { + if(output == null) { Client.this.waitingForFile = false; return; } if(mode == FileMode.FILE_LOAD_MULTI) { final List files = Lists.newArrayList(); - if(chooser != null) { - for(File file : chooser.getSelectedFiles()) { - if(file.isFile()) - files.add(file); - } - } - else { - for(String out : output.split(":")) { - File file = new File(out); - if(file.isFile()) - files.add(file); - } + for(String out : output.split(":")) { + File file = new File(out); + if(file.isFile()) + files.add(file); } if(files.isEmpty()) { Client.this.waitingForFile = false; @@ -3304,7 +3281,7 @@ public class Client implements IThreadListener, IClient { }); } else { - File file = chooser != null ? chooser.getSelectedFile() : new File(output); + File file = new File(output); switch(mode) { case DIRECTORY_LOAD: if(!file.isDirectory()) { @@ -3340,12 +3317,12 @@ public class Client implements IThreadListener, IClient { }); } } - }, "File Browser listener").start(); + }, "Zenity listener").start(); } public void makeFireworks(double x, double y, double z, double motionX, double motionY, double motionZ, NBTTagCompound compund) { - this.effectRenderer.addEffect(new EntityFirework.StarterFX(this.world, x, y, z, motionX, motionY, motionZ, this.effectRenderer, compund)); + this.effectRenderer.addEffect(new EntityFirework.StarterFX(this.theWorld, x, y, z, motionX, motionY, motionZ, this.effectRenderer, compund)); } public int getRenderDistance() { @@ -3369,7 +3346,7 @@ public class Client implements IThreadListener, IClient { } public EntityNPC getPlayer() { - return this.player; + return this.thePlayer; } public IEntityFX spawnEffectParticle(int particleId, double xCoord, double yCoord, double zCoord, double xSpeed, double ySpeed, double zSpeed, diff --git a/client/src/client/PlayerController.java b/client/src/client/PlayerController.java index 80017d3..a638839 100755 --- a/client/src/client/PlayerController.java +++ b/client/src/client/PlayerController.java @@ -113,7 +113,7 @@ public class PlayerController // } // else // { - World world = this.gm.world; + World world = this.gm.theWorld; State iblockstate = world.getState(pos); Block block1 = iblockstate.getBlock(); @@ -135,15 +135,15 @@ public class PlayerController // if (!this.creative) // { - ItemStack itemstack1 = this.gm.player.getCurrentEquippedItem(); + ItemStack itemstack1 = this.gm.thePlayer.getCurrentEquippedItem(); if (itemstack1 != null) { - itemstack1.onBlockDestroyed(world, block1, pos, this.gm.player); + itemstack1.onBlockDestroyed(world, block1, pos, this.gm.thePlayer); if (itemstack1.stackSize == 0) { - this.gm.player.destroyCurrentEquippedItem(); + this.gm.thePlayer.destroyCurrentEquippedItem(); } } // } @@ -188,8 +188,8 @@ public class PlayerController } else { - ItemStack stack = this.gm.player.getHeldItem(); - if(stack != null && stack.getItem().onAction(stack, this.gm.player, this.gm.world, ItemControl.PRIMARY, loc)) { + ItemStack stack = this.gm.thePlayer.getHeldItem(); + if(stack != null && stack.getItem().onAction(stack, this.gm.thePlayer, this.gm.theWorld, ItemControl.PRIMARY, loc)) { this.interacting = true; this.netClientHandler.addToSendQueue(new CPacketBreak(CPacketBreak.Action.START_DESTROY_BLOCK, loc, face)); return true; @@ -209,15 +209,15 @@ public class PlayerController } this.netClientHandler.addToSendQueue(new CPacketBreak(CPacketBreak.Action.START_DESTROY_BLOCK, loc, face)); - Block block1 = this.gm.world.getState(loc).getBlock(); + Block block1 = this.gm.theWorld.getState(loc).getBlock(); boolean flag = block1.getMaterial() != Material.air; if (flag && this.curBlockDamageMP == 0.0F) { - block1.onBlockClicked(this.gm.world, loc, this.gm.player); + block1.onBlockClicked(this.gm.theWorld, loc, this.gm.thePlayer); } - if (flag && block1.getPlayerRelativeBlockHardness(this.gm.player, this.gm.player.worldObj, loc) >= 1.0F) + if (flag && block1.getPlayerRelativeBlockHardness(this.gm.thePlayer, this.gm.thePlayer.worldObj, loc) >= 1.0F) { this.onPlayerDestroyBlock(loc, face); // if(this.cheat && block1.getPlayerRelativeBlockHardness(this.gm.thePlayer, this.gm.thePlayer.worldObj, loc) < 1.0F) @@ -227,10 +227,10 @@ public class PlayerController { this.isHittingBlock = true; this.currentBlock = loc; - this.currentItemHittingBlock = this.gm.player.getHeldItem(); + this.currentItemHittingBlock = this.gm.thePlayer.getHeldItem(); this.curBlockDamageMP = 0.0F; this.stepSoundTickCounter = 0.0F; - this.gm.world.sendBlockBreakProgress(this.gm.player.getId(), this.currentBlock, (int)(this.curBlockDamageMP * 10.0F) - 1); + this.gm.theWorld.sendBlockBreakProgress(this.gm.thePlayer.getId(), this.currentBlock, (int)(this.curBlockDamageMP * 10.0F) - 1); } } @@ -248,7 +248,7 @@ public class PlayerController this.netClientHandler.addToSendQueue(new CPacketBreak(CPacketBreak.Action.ABORT_DESTROY_BLOCK, this.currentBlock, Facing.DOWN)); this.isHittingBlock = false; this.curBlockDamageMP = 0.0F; - this.gm.world.sendBlockBreakProgress(this.gm.player.getId(), this.currentBlock, -1); + this.gm.theWorld.sendBlockBreakProgress(this.gm.thePlayer.getId(), this.currentBlock, -1); } } @@ -277,7 +277,7 @@ public class PlayerController // } else if (this.isHittingPosition(posBlock)) { - Block block = this.gm.world.getState(posBlock).getBlock(); + Block block = this.gm.theWorld.getState(posBlock).getBlock(); if (block.getMaterial() == Material.air) { @@ -286,7 +286,7 @@ public class PlayerController } else { - this.curBlockDamageMP += block.getPlayerRelativeBlockHardness(this.gm.player, this.gm.player.worldObj, posBlock); + this.curBlockDamageMP += block.getPlayerRelativeBlockHardness(this.gm.thePlayer, this.gm.thePlayer.worldObj, posBlock); if (this.stepSoundTickCounter % 4.0F == 0.0F && block.sound.getStepSound() != null) { @@ -305,7 +305,7 @@ public class PlayerController this.blockHitDelay = 5; } - this.gm.world.sendBlockBreakProgress(this.gm.player.getId(), this.currentBlock, (int)(this.curBlockDamageMP * 10.0F) - 1); + this.gm.theWorld.sendBlockBreakProgress(this.gm.thePlayer.getId(), this.currentBlock, (int)(this.curBlockDamageMP * 10.0F) - 1); return true; } } @@ -339,7 +339,7 @@ public class PlayerController private boolean isHittingPosition(BlockPos pos) { - ItemStack itemstack = this.gm.player.getHeldItem(); + ItemStack itemstack = this.gm.thePlayer.getHeldItem(); boolean flag = this.currentItemHittingBlock == null && itemstack == null; if (this.currentItemHittingBlock != null && itemstack != null) @@ -355,7 +355,7 @@ public class PlayerController */ private void syncCurrentPlayItem() { - int i = this.gm.player.inventory.currentItem; + int i = this.gm.thePlayer.inventory.currentItem; if (i != this.currentPlayerItem) { diff --git a/client/src/client/gui/Gui.java b/client/src/client/gui/Gui.java index 73628a8..bad7a40 100644 --- a/client/src/client/gui/Gui.java +++ b/client/src/client/gui/Gui.java @@ -301,7 +301,7 @@ public abstract class Gui { // } public void drawMainBackground() { - if(this.gm.world != null && !this.gm.charEditor) { + if(this.gm.theWorld != null && !this.gm.charEditor) { // Drawing.drawGradient(0, 0, this.fb_x, this.fb_y, this.theWorld == null ? this.style.bg_top : 0x3f202020, // this.theWorld == null ? this.style.bg_btm : 0x3f000000); Drawing.drawGradient(0, 0, this.gm.fb_x, this.gm.fb_y, 0xc0101010, 0xd0101010); diff --git a/client/src/client/gui/GuiConfirm.java b/client/src/client/gui/GuiConfirm.java index fb9b117..5a4a907 100755 --- a/client/src/client/gui/GuiConfirm.java +++ b/client/src/client/gui/GuiConfirm.java @@ -28,7 +28,7 @@ public class GuiConfirm extends Gui implements ActButton.Callback { public void init(int width, int height) { this.add(new Label(0, 0, 500, 24, this.messageLine1, true)); - this.add(new TransparentBox(0, 80, 500, 300, this.messageLine2, this.gm.world != null && !this.gm.charEditor)); + this.add(new TransparentBox(0, 80, 500, 300, this.messageLine2, this.gm.theWorld != null && !this.gm.charEditor)); this.confirmBtn = this.add(new ActButton(48, 500, 200, 24, this, this.confirmButtonText)); this.cancelBtn = this.add(new ActButton(252, 500, 200, 24, this, this.cancelButtonText)); this.shift(); diff --git a/client/src/client/gui/GuiConsole.java b/client/src/client/gui/GuiConsole.java index 3ea6d44..4ff2c19 100644 --- a/client/src/client/gui/GuiConsole.java +++ b/client/src/client/gui/GuiConsole.java @@ -55,7 +55,7 @@ public class GuiConsole extends Gui implements Textbox.Callback { } }, "Löschen")); } - this.logBox = this.add(new TransparentBox(0, this.full ? 24 : 0, width, height - (this.full ? 48 : 24), this.gm.getBuffer(), this.gm.world != null && !this.gm.charEditor)); + this.logBox = this.add(new TransparentBox(0, this.full ? 24 : 0, width, height - (this.full ? 48 : 24), this.gm.getBuffer(), this.gm.theWorld != null && !this.gm.charEditor)); if(this.full) this.add(new Fill(640, 0, width - 640, 24)); this.inputField = this.add(new Textbox(0, height - 24, width, 24, IPlayer.MAX_CMD_LENGTH, true, this, "")); @@ -79,7 +79,7 @@ public class GuiConsole extends Gui implements Textbox.Callback { } public void drawMainBackground() { - if(this.gm.world == null || this.gm.charEditor) + if(this.gm.theWorld == null || this.gm.charEditor) super.drawMainBackground(); } @@ -123,7 +123,7 @@ public class GuiConsole extends Gui implements Textbox.Callback { } this.inputField.setText(""); - if((this.gm.conAutoclose || !this.full) && this.gm.world != null) + if((this.gm.conAutoclose || !this.full) && this.gm.theWorld != null) this.gm.displayGuiScreen(null); } } @@ -215,7 +215,7 @@ public class GuiConsole extends Gui implements Textbox.Callback { s = argv[argv.length - 1]; Iterable res = pre.startsWith("#") ? (argv.length == 1 ? this.gm.getVars() : (argv.length == 2 ? getVarCompletion(argv[0].substring(1)) : Lists.newArrayList())) : - (this.gm.player == null ? Lists.newArrayList() : ((ClientPlayer)this.gm.player.sendQueue).getPlayerNames()); + (this.gm.thePlayer == null ? Lists.newArrayList() : ((ClientPlayer)this.gm.thePlayer.sendQueue).getPlayerNames()); if(argv.length == 1 && pre.startsWith("#")) s = s.substring(1); for(String s1 : res) { @@ -252,10 +252,10 @@ public class GuiConsole extends Gui implements Textbox.Callback { blockpos = new BlockPos(this.gm.pointed.entity); } if(currentText.startsWith("/")) { - if(this.gm.player != null) { + if(this.gm.thePlayer != null) { currentText = currentText.substring(1); this.prefixFirst = currentText.split(" ", -1).length == 1 ? "/" : null; - this.gm.player.sendQueue.addToSendQueue(new CPacketComplete(currentText, eid, blockpos)); + this.gm.thePlayer.sendQueue.addToSendQueue(new CPacketComplete(currentText, eid, blockpos)); this.waitingOnAutocomplete = true; } } diff --git a/client/src/client/gui/GuiInfo.java b/client/src/client/gui/GuiInfo.java index 9b18880..eadf6dd 100644 --- a/client/src/client/gui/GuiInfo.java +++ b/client/src/client/gui/GuiInfo.java @@ -125,7 +125,7 @@ public class GuiInfo extends Gui { } public void init(int width, int height) { - this.add(new TransparentBox(10, 10, width - 20, height - 44, this.info, this.gm.world != null && !this.gm.charEditor)); + this.add(new TransparentBox(10, 10, width - 20, height - 44, this.info, this.gm.theWorld != null && !this.gm.charEditor)); this.add(new NavButton(0, height - 24, width, 24, GuiMenu.INSTANCE, "Zurück")); } diff --git a/client/src/client/gui/GuiMenu.java b/client/src/client/gui/GuiMenu.java index 54cbb34..d1f0062 100644 --- a/client/src/client/gui/GuiMenu.java +++ b/client/src/client/gui/GuiMenu.java @@ -23,7 +23,7 @@ public class GuiMenu extends Gui { } public void drawMainBackground() { - if(this.gm.world != null) + if(this.gm.theWorld != null) super.drawMainBackground(); else this.gm.renderGlobal.renderStarField(this.gm.fb_x, this.gm.fb_y, 0x000000, 0xffffff, (float)this.ticks + (float)Timing.tick_fraction, this.rand); @@ -48,7 +48,7 @@ public class GuiMenu extends Gui { private boolean animStep; public void init(int width, int height) { - if(this.gm.world == null) { + if(this.gm.theWorld == null) { this.ticks = 0; this.hacked = 0; this.resetAnimation(); @@ -120,7 +120,7 @@ public class GuiMenu extends Gui { } public String getTitle() { - return this.gm.world == null ? "Hauptmenü" : "Menü"; + return this.gm.theWorld == null ? "Hauptmenü" : "Menü"; } private void pickSplash() { @@ -223,7 +223,7 @@ public class GuiMenu extends Gui { } public void updateScreen() { - if(this.gm.world == null) { + if(this.gm.theWorld == null) { this.ticks++; if(this.gm.shift() && !(this.selected instanceof Textbox)) this.pickSplash(); @@ -233,7 +233,7 @@ public class GuiMenu extends Gui { public void key(Keysym key, boolean ctrl, boolean shift) { super.key(key, ctrl, shift); - if(this.gm.world == null) { + if(this.gm.theWorld == null) { if((key == Keysym.UP || key == Keysym.W) && (this.hacked == 0 || this.hacked == 1)) this.hacked++; else if((key == Keysym.DOWN || key == Keysym.S) && (this.hacked == 2 || this.hacked == 3)) @@ -287,7 +287,7 @@ public class GuiMenu extends Gui { public void drawOverlays() { super.drawOverlays(); - if(this.gm.world == null) { + if(this.gm.theWorld == null) { int y = 164; int h = 16; int n = Drawing.getWidth(this.splashLabel.getText()); diff --git a/client/src/client/gui/GuiServer.java b/client/src/client/gui/GuiServer.java index 42dcdeb..ca80fa0 100644 --- a/client/src/client/gui/GuiServer.java +++ b/client/src/client/gui/GuiServer.java @@ -74,7 +74,7 @@ public class GuiServer extends Gui implements Textbox.Callback { } private void connect() { - if(this.gm.world != null) + if(this.gm.theWorld != null) return; String name = null; if(this.server != null) { diff --git a/client/src/client/gui/character/GuiChar.java b/client/src/client/gui/character/GuiChar.java index 540c209..76daeb4 100755 --- a/client/src/client/gui/character/GuiChar.java +++ b/client/src/client/gui/character/GuiChar.java @@ -129,7 +129,7 @@ public class GuiChar extends GuiList EntityTexManager.altLayer = this.dynId; EntityTexManager.altNpcLayer = this.dynId == -1 && this.charinfo != null ? this.charinfo.skin : null; drawEntity(x + 32, y + 60, 28.0f - * Math.min(1.8f / GuiChar.this.gm.player.height, 1.5f / GuiChar.this.gm.player.width), -45.0f, -20.0f, GuiChar.this.gm.player); + * Math.min(1.8f / GuiChar.this.gm.thePlayer.height, 1.5f / GuiChar.this.gm.thePlayer.width), -45.0f, -20.0f, GuiChar.this.gm.thePlayer); GuiChar.this.gm.cameraUsed = flag; EntityTexManager.altTexture = null; EntityTexManager.altLayer = -1; @@ -271,8 +271,8 @@ public class GuiChar extends GuiList this.adjust = null; return; } - this.currentSkin = this.gm.player != null && !EntityTexManager.hasCustomSkin(this.gm.player.getId()) ? this.gm.player.getChar() : null; - this.load(this.gm.player == null ? ModelType.HUMANOID : this.gm.player.getModel(), this.gm.player != null ? this.gm.player.getSpecies() : SpeciesRegistry.CLASSES.get(EntityHuman.class)); + this.currentSkin = this.gm.thePlayer != null && !EntityTexManager.hasCustomSkin(this.gm.thePlayer.getId()) ? this.gm.thePlayer.getChar() : null; + this.load(this.gm.thePlayer == null ? ModelType.HUMANOID : this.gm.thePlayer.getModel(), this.gm.thePlayer != null ? this.gm.thePlayer.getSpecies() : SpeciesRegistry.CLASSES.get(EntityHuman.class)); this.add(new ActButton(4, 4, 194, 24, new ActButton.Callback() { public void use(ActButton elem, Mode action) { GuiChar.this.gm.showFileDialog(FileMode.FILE_LOAD_MULTI, "Skin konvertieren", TEXTURE_FOLDER, new FileCallback() { @@ -335,12 +335,12 @@ public class GuiChar extends GuiList }, "Vorlage kopieren")); this.adjust = this.add(new DragAdjust(width / 2 - 230, height - 64 - 640, 460, 640)); - this.add(new Label(width - 396, 36, 392, 20, "Spezies: " + (this.gm.player == null ? "" : this.gm.player.getSpecies().name), true)); + this.add(new Label(width - 396, 36, 392, 20, "Spezies: " + (this.gm.thePlayer == null ? "" : this.gm.thePlayer.getSpecies().name), true)); this.add(new NavButton(width - 396, 56, 392, 24, GuiSpecies.INSTANCE, "Spezies ändern")); - this.add(new Label(width - 396, 36 + 92, 392, 20, "Klasse: " + (this.gm.player == null || this.gm.player.getSpecies().classEnum == null || this.gm.player.getNpcClass() == null || this.gm.player.getNpcClass().toString().isEmpty() ? "" : this.gm.player.getNpcClass().toString()), true)) - .enabled = this.gm.player != null && this.gm.player.getSpecies().classEnum != null; + this.add(new Label(width - 396, 36 + 92, 392, 20, "Klasse: " + (this.gm.thePlayer == null || this.gm.thePlayer.getSpecies().classEnum == null || this.gm.thePlayer.getNpcClass() == null || this.gm.thePlayer.getNpcClass().toString().isEmpty() ? "" : this.gm.thePlayer.getNpcClass().toString()), true)) + .enabled = this.gm.thePlayer != null && this.gm.thePlayer.getSpecies().classEnum != null; this.add(new NavButton(width - 396, 56 + 92, 392, 24, GuiClass.INSTANCE, "Klasse ändern")) - .enabled = this.gm.player != null && this.gm.player.getSpecies().classEnum != null; + .enabled = this.gm.thePlayer != null && this.gm.thePlayer.getSpecies().classEnum != null; final ActButton[] alignBtns = new ActButton[Alignment.values().length]; for (int z = 0; z < Alignment.values().length; z++) @@ -348,25 +348,25 @@ public class GuiChar extends GuiList final Alignment align = Alignment.values()[z]; alignBtns[z] = this.add(new ActButton(width - 396 + (z % 3) * 132, height - 32 - 28 * 3 + 28 * (z / 3), 128, 24, new ActButton.Callback() { public void use(ActButton elem, Mode action) { - if(GuiChar.this.gm.player != null) { + if(GuiChar.this.gm.thePlayer != null) { GuiChar.this.waiting = false; - GuiChar.this.gm.player.sendQueue.addToSendQueue(new CPacketAction(CPacketAction.Action.SET_ALIGN, align.ordinal())); + GuiChar.this.gm.thePlayer.sendQueue.addToSendQueue(new CPacketAction(CPacketAction.Action.SET_ALIGN, align.ordinal())); for(ActButton btn : alignBtns) { btn.enabled = btn != elem; } } } }, align.color + align.display)); - alignBtns[z].enabled = this.gm.player == null || this.gm.player.getAlignment() != align; + alignBtns[z].enabled = this.gm.thePlayer == null || this.gm.thePlayer.getAlignment() != align; } - this.add(new Slider(width / 2 - 200, height - 28, 400, 24, 1, this.gm.player == null ? 120 : this.gm.player.getMinSize(), this.gm.player == null ? 320 : this.gm.player.getMaxSize(), this.gm.player == null ? 180 : this.gm.player.getDefaultSize(), this.gm.player == null ? 180 : this.gm.player.getCurrentSize(), new Slider.Callback() { + this.add(new Slider(width / 2 - 200, height - 28, 400, 24, 1, this.gm.thePlayer == null ? 120 : this.gm.thePlayer.getMinSize(), this.gm.thePlayer == null ? 320 : this.gm.thePlayer.getMaxSize(), this.gm.thePlayer == null ? 180 : this.gm.thePlayer.getDefaultSize(), this.gm.thePlayer == null ? 180 : this.gm.thePlayer.getCurrentSize(), new Slider.Callback() { public void use(Slider elem, int value) { - if(GuiChar.this.gm.player != null) { + if(GuiChar.this.gm.thePlayer != null) { GuiChar.this.waiting = false; - GuiChar.this.gm.player.sendQueue.addToSendQueue(new CPacketAction(CPacketAction.Action.SET_HEIGHT, value)); + GuiChar.this.gm.thePlayer.sendQueue.addToSendQueue(new CPacketAction(CPacketAction.Action.SET_HEIGHT, value)); } } - }, "Spieler-Größe", "cm")).enabled = this.gm.player == null || this.gm.player.getMinSize() != this.gm.player.getMaxSize(); + }, "Spieler-Größe", "cm")).enabled = this.gm.thePlayer == null || this.gm.thePlayer.getMinSize() != this.gm.thePlayer.getMaxSize(); this.add(new Label(width / 2 - 200, 36, 400, 20, "Name", true)); this.add(new Label(width - 396, height - 384, 392, 20, "Beschreibung", true)); final Textbox descField = this.add(new Textbox(width - 396, height - 364, 392, 130, IPlayer.MAX_INFO_LENGTH, new Textbox.Callback() { @@ -375,11 +375,11 @@ public class GuiChar extends GuiList }, "")); this.add(new ActButton(width - 198, height - 28, 194, 24, new ActButton.Callback() { public void use(ActButton elem, Mode action) { - if(GuiChar.this.gm.player != null) { + if(GuiChar.this.gm.thePlayer != null) { GuiChar.this.gm.displayGuiScreen(GuiLoading.makeWaitTask("Lade Welt ...")); Dimension dim = UniverseRegistry.getBaseDimensions().get(GuiChar.this.dimension); - GuiChar.this.gm.player.sendQueue.addToSendQueue(new CPacketMessage(CPacketMessage.Type.INFO, descField.getText())); - GuiChar.this.gm.player.sendQueue.addToSendQueue(new CPacketAction(CPacketAction.Action.CLOSE_EDITOR, dim.getDimensionId())); + GuiChar.this.gm.thePlayer.sendQueue.addToSendQueue(new CPacketMessage(CPacketMessage.Type.INFO, descField.getText())); + GuiChar.this.gm.thePlayer.sendQueue.addToSendQueue(new CPacketAction(CPacketAction.Action.CLOSE_EDITOR, dim.getDimensionId())); } } }, "Charakter erstellen")); @@ -388,17 +388,17 @@ public class GuiChar extends GuiList if(value == Action.SEND || value == Action.UNFOCUS) { String name = elem.getText(); if(name.isEmpty()) - elem.setText(GuiChar.this.gm.player == null ? "..." : GuiChar.this.gm.player.getCustomNameTag()); - else if(GuiChar.this.gm.player != null) { + elem.setText(GuiChar.this.gm.thePlayer == null ? "..." : GuiChar.this.gm.thePlayer.getCustomNameTag()); + else if(GuiChar.this.gm.thePlayer != null) { GuiChar.this.waiting = false; - GuiChar.this.gm.player.sendQueue.addToSendQueue(new CPacketMessage(CPacketMessage.Type.DISPLAY, name)); + GuiChar.this.gm.thePlayer.sendQueue.addToSendQueue(new CPacketMessage(CPacketMessage.Type.DISPLAY, name)); } } } - }, IPlayer.VALID_NICK, this.gm.player == null ? "" : this.gm.player.getCustomNameTag())); + }, IPlayer.VALID_NICK, this.gm.thePlayer == null ? "" : this.gm.thePlayer.getCustomNameTag())); this.templateButton.enabled = false; this.dimension = new Random().zrange(UniverseRegistry.getBaseDimensions().size()); - EntityEggInfo egg = EntityRegistry.SPAWN_EGGS.get(this.gm.player == null ? EntityRegistry.getEntityString(EntityHuman.class) : EntityRegistry.getEntityString(this.gm.player)); + EntityEggInfo egg = EntityRegistry.SPAWN_EGGS.get(this.gm.thePlayer == null ? EntityRegistry.getEntityString(EntityHuman.class) : EntityRegistry.getEntityString(this.gm.thePlayer)); if(egg != null && egg.origin != null) { Dimension dim = UniverseRegistry.getDimension(egg.origin); if(dim != null) { @@ -446,10 +446,10 @@ public class GuiChar extends GuiList public void drawOverlays() { if(this.adjust != null) { - float factor = this.gm.player.width > 2.15f ? 2.15f / this.gm.player.width : 1.0f; - factor = this.gm.player.height > 3.0f && 3.0f / this.gm.player.height < factor ? 3.0f / this.gm.player.height : factor; + float factor = this.gm.thePlayer.width > 2.15f ? 2.15f / this.gm.thePlayer.width : 1.0f; + factor = this.gm.thePlayer.height > 3.0f && 3.0f / this.gm.thePlayer.height < factor ? 3.0f / this.gm.thePlayer.height : factor; drawEntity(400 + (this.gm.fb_x - 400 - 400) / 2, this.gm.fb_y - 160, 160.0f * factor - , this.yaw, this.pitch, this.gm.player); + , this.yaw, this.pitch, this.gm.thePlayer); } } diff --git a/client/src/client/gui/character/GuiCharacters.java b/client/src/client/gui/character/GuiCharacters.java index 159e54f..cd94394 100644 --- a/client/src/client/gui/character/GuiCharacters.java +++ b/client/src/client/gui/character/GuiCharacters.java @@ -73,7 +73,7 @@ public class GuiCharacters extends GuiList impleme if(this.gm.getNetHandler() != null) { int initialSelection = this.gm.getNetHandler().getSelectedCharacter(); for(PlayerCharacter character : this.gm.getNetHandler().getCharacterList()) { - this.elements.add(new CharacterEntry(initialSelection == this.elements.size() ? new PlayerCharacter(character.name, character.info, character.align, this.gm.player.worldObj.dimension.getFormattedName(false), this.gm.player.getPosition(), character.type, this.gm.player.experienceLevel) : character, initialSelection == this.elements.size())); + this.elements.add(new CharacterEntry(initialSelection == this.elements.size() ? new PlayerCharacter(character.name, character.info, character.align, this.gm.thePlayer.worldObj.dimension.getFormattedName(false), this.gm.thePlayer.getPosition(), character.type, this.gm.thePlayer.experienceLevel) : character, initialSelection == this.elements.size())); } this.elements.add(new CharacterEntry(null, false)); this.setSelected(initialSelection); diff --git a/client/src/client/gui/character/GuiClass.java b/client/src/client/gui/character/GuiClass.java index 11a8805..c1ca519 100644 --- a/client/src/client/gui/character/GuiClass.java +++ b/client/src/client/gui/character/GuiClass.java @@ -21,14 +21,14 @@ public class GuiClass extends GuiList implements ActButton. public void draw(int x, int y, int mouseX, int mouseY, boolean hovered) { - if(GuiClass.this.gm.player != null && this.clazz == GuiClass.this.gm.player.getNpcClass()) + if(GuiClass.this.gm.thePlayer != null && this.clazz == GuiClass.this.gm.thePlayer.getNpcClass()) Drawing.drawRect(x, y, 1, 44, 0xffaf0000); Drawing.drawText(this.clazz.toString().isEmpty() ? "" : this.clazz.toString(), x + 3, y, 0xffffffff); } public void select(boolean dclick, int mx, int my) { - if((GuiClass.this.selectButton.enabled = GuiClass.this.gm.player == null || this.clazz != GuiClass.this.gm.player.getNpcClass()) && dclick) + if((GuiClass.this.selectButton.enabled = GuiClass.this.gm.thePlayer == null || this.clazz != GuiClass.this.gm.thePlayer.getNpcClass()) && dclick) GuiClass.this.use(GuiClass.this.selectButton, Mode.PRIMARY); } } @@ -45,8 +45,8 @@ public class GuiClass extends GuiList implements ActButton. super.init(width, height); this.setDimensions(400, height, 32, height - 32); this.elements.clear(); - if(this.gm.player != null && this.gm.player.getSpecies().classEnum != null) - for(Enum clazz : this.gm.player.getSpecies().classEnum.getEnumConstants()) { + if(this.gm.thePlayer != null && this.gm.thePlayer.getSpecies().classEnum != null) + for(Enum clazz : this.gm.thePlayer.getSpecies().classEnum.getEnumConstants()) { this.elements.add(new ClassEntry(clazz)); } this.add(new NavButton(width - 198 * 2, height - 28, 194, 24, GuiChar.INSTANCE, "Zurück")); @@ -69,8 +69,8 @@ public class GuiClass extends GuiList implements ActButton. public void use(ActButton elem, Mode action) { ClassEntry entry = this.getSelected(); - if(entry != null && GuiClass.this.gm.player != null) { - GuiClass.this.gm.player.sendQueue.addToSendQueue(new CPacketAction(CPacketAction.Action.SET_CLASS, entry.clazz.ordinal())); + if(entry != null && GuiClass.this.gm.thePlayer != null) { + GuiClass.this.gm.thePlayer.sendQueue.addToSendQueue(new CPacketAction(CPacketAction.Action.SET_CLASS, entry.clazz.ordinal())); this.gm.displayGuiScreen(GuiChar.INSTANCE); } } diff --git a/client/src/client/gui/character/GuiSpecies.java b/client/src/client/gui/character/GuiSpecies.java index 770d8a4..af9b9bd 100644 --- a/client/src/client/gui/character/GuiSpecies.java +++ b/client/src/client/gui/character/GuiSpecies.java @@ -24,7 +24,7 @@ public class GuiSpecies extends GuiList implements ActB public void draw(int x, int y, int mouseX, int mouseY, boolean hovered) { - if(GuiSpecies.this.gm.player != null && this.species == GuiSpecies.this.gm.player.getSpecies()) + if(GuiSpecies.this.gm.thePlayer != null && this.species == GuiSpecies.this.gm.thePlayer.getSpecies()) Drawing.drawRect(x, y, 1, 44, 0xffaf0000); Drawing.drawText(this.species.name, x + 3, y, 0xff000000 | this.species.color1 | this.species.color2); if(this.species.classEnum != null) @@ -33,7 +33,7 @@ public class GuiSpecies extends GuiList implements ActB public void select(boolean dclick, int mx, int my) { - if((GuiSpecies.this.selectButton.enabled = GuiSpecies.this.gm.player == null || this.species != GuiSpecies.this.gm.player.getSpecies()) && dclick) + if((GuiSpecies.this.selectButton.enabled = GuiSpecies.this.gm.thePlayer == null || this.species != GuiSpecies.this.gm.thePlayer.getSpecies()) && dclick) GuiSpecies.this.use(GuiSpecies.this.selectButton, Mode.PRIMARY); } } @@ -73,7 +73,7 @@ public class GuiSpecies extends GuiList implements ActB public void use(ActButton elem, Mode action) { SpeciesEntry entry = this.getSelected(); - if(entry != null && GuiSpecies.this.gm.player != null) - GuiSpecies.this.gm.player.sendQueue.addToSendQueue(new CPacketAction(CPacketAction.Action.SET_SPECIES, EntityRegistry.getEntityID(entry.species.clazz))); + if(entry != null && GuiSpecies.this.gm.thePlayer != null) + GuiSpecies.this.gm.thePlayer.sendQueue.addToSendQueue(new CPacketAction(CPacketAction.Action.SET_SPECIES, EntityRegistry.getEntityID(entry.species.clazz))); } } diff --git a/client/src/client/gui/container/GuiChest.java b/client/src/client/gui/container/GuiChest.java index c9a56be..85c444f 100755 --- a/client/src/client/gui/container/GuiChest.java +++ b/client/src/client/gui/container/GuiChest.java @@ -19,7 +19,7 @@ public class GuiChest extends GuiContainer public GuiChest(IInventory upperInv, IInventory lowerInv) { - super(new ContainerChest(upperInv, lowerInv, Client.CLIENT.player)); + super(new ContainerChest(upperInv, lowerInv, Client.CLIENT.thePlayer)); this.upperChestInventory = upperInv; this.lowerChestInventory = lowerInv; // this.allowUserInput = false; diff --git a/client/src/client/gui/container/GuiContainer.java b/client/src/client/gui/container/GuiContainer.java index babe081..7f5051d 100755 --- a/client/src/client/gui/container/GuiContainer.java +++ b/client/src/client/gui/container/GuiContainer.java @@ -213,7 +213,7 @@ public abstract class GuiContainer extends Gui */ public void initGui() { - this.gm.player.openContainer = this.inventorySlots; + this.gm.thePlayer.openContainer = this.inventorySlots; // this.guiLeft = (this.width - this.xSize) / 2; // this.guiTop = (this.height - this.ySize) / 2; // this.addButtons(); @@ -360,7 +360,7 @@ public abstract class GuiContainer extends Gui ItemRenderer.disableStandardItemLighting(); // this.drawGuiContainerForegroundLayer(mouseX, mouseY); ItemRenderer.enableGUIStandardItemLighting(); - InventoryPlayer inventoryplayer = this.gm.player.inventory; + InventoryPlayer inventoryplayer = this.gm.thePlayer.inventory; ItemStack itemstack = this.draggedStack == null ? inventoryplayer.getItemStack() : this.draggedStack; if(this.gm.itemCheat) itemstack = itemstack == null ? this.cheatStack : itemstack; @@ -451,7 +451,7 @@ public abstract class GuiContainer extends Gui } protected void renderToolTip(ItemStack stack, int x, int y) { - List list = stack.getTooltip(this.gm.player); + List list = stack.getTooltip(this.gm.thePlayer); StringBuilder sb = new StringBuilder(); for(int i = 0; i < list.size(); ++i) { if(i != 0) @@ -512,7 +512,7 @@ public abstract class GuiContainer extends Gui ItemStack itemstack = slotIn.getStack(); boolean flag = false; boolean flag1 = slotIn == this.clickedSlot && this.draggedStack != null && !this.isRightMouseClick; - ItemStack itemstack1 = this.gm.player.inventory.getItemStack(); + ItemStack itemstack1 = this.gm.thePlayer.inventory.getItemStack(); String s = null; if (slotIn == this.clickedSlot && this.draggedStack != null && this.isRightMouseClick && itemstack != null) @@ -589,7 +589,7 @@ public abstract class GuiContainer extends Gui private void updateDragSplitting() { - ItemStack itemstack = this.gm.player.inventory.getItemStack(); + ItemStack itemstack = this.gm.thePlayer.inventory.getItemStack(); if (itemstack != null && this.dragSplitting) { @@ -643,8 +643,8 @@ public abstract class GuiContainer extends Gui return; if(this.cheatStack != null) { Slot slot = this.getSlotAtPosition(mouseX, mouseY); - if((mouseButton == 0 || mouseButton == 1) && slot != null && this.gm.player != null && slot.inventory == this.gm.player.inventory) - this.gm.player.sendQueue.addToSendQueue(new CPacketCheat(this.cheatStack, slot.getIndex(), mouseButton == 0 && this.cheatStack.stackSize > 1)); + if((mouseButton == 0 || mouseButton == 1) && slot != null && this.gm.thePlayer != null && slot.inventory == this.gm.thePlayer.inventory) + this.gm.thePlayer.sendQueue.addToSendQueue(new CPacketCheat(this.cheatStack, slot.getIndex(), mouseButton == 0 && this.cheatStack.stackSize > 1)); if(mouseButton != 1 && !this.gm.ctrl()) this.cheatStack = null; return; @@ -652,7 +652,7 @@ public abstract class GuiContainer extends Gui if((mouseButton == 0 || mouseButton == 1 || mouseButton == 2) && this.clickSide(mouseX, mouseY, -1, this.gm.shift() || mouseButton == 1, this.gm.ctrl() || mouseButton == 2)) return; if(mouseButton == 0) { - if(this.gm.itemCheat && this.gm.player != null && this.gm.player.inventory.getItemStack() == null) { + if(this.gm.itemCheat && this.gm.thePlayer != null && this.gm.thePlayer.inventory.getItemStack() == null) { for (CheatTab tab : CheatTab.values()) { if (this.isInsideTab(tab, mouseX, mouseY)) @@ -711,7 +711,7 @@ public abstract class GuiContainer extends Gui // else if (!this.dragSplitting) { - if (this.gm.player.inventory.getItemStack() == null) + if (this.gm.thePlayer.inventory.getItemStack() == null) { // if (mouseButton == this.gm.bindTertiary.getKeyCode() + 100) // { @@ -774,7 +774,7 @@ public abstract class GuiContainer extends Gui if(this.gm == null || this.cheatStack != null) return; Slot slot = this.getSlotAtPosition(mouseX, mouseY); - ItemStack itemstack = this.gm.player.inventory.getItemStack(); + ItemStack itemstack = this.gm.thePlayer.inventory.getItemStack(); // if (this.clickedSlot != null && this.gm.touchscreen) // { @@ -849,7 +849,7 @@ public abstract class GuiContainer extends Gui { for (Slot slot2 : this.inventorySlots.inventorySlots) { - if (slot2 != null && slot2.canTakeStack(this.gm.player) && slot2.getHasStack() && slot2.inventory == slot.inventory && Container.canAddItemToSlot(slot2, this.shiftClickedSlot, true)) + if (slot2 != null && slot2.canTakeStack(this.gm.thePlayer) && slot2.getHasStack() && slot2.inventory == slot.inventory && Container.canAddItemToSlot(slot2, this.shiftClickedSlot, true)) { this.handleMouseClick(slot2, slot2.slotNumber, state, 1); } @@ -935,7 +935,7 @@ public abstract class GuiContainer extends Gui this.handleMouseClick((Slot)null, -999, Container.getDragCode(2, this.dragSplittingLimit), 5); } - else if (this.gm.player.inventory.getItemStack() != null) + else if (this.gm.thePlayer.inventory.getItemStack() != null) { // if (state == this.gm.bindTertiary.getKeyCode() + 100) // { @@ -955,7 +955,7 @@ public abstract class GuiContainer extends Gui } } - if (this.gm.player.inventory.getItemStack() == null) + if (this.gm.thePlayer.inventory.getItemStack() == null) { this.lastClickTime = 0L; } @@ -994,11 +994,11 @@ public abstract class GuiContainer extends Gui slotId = slotIn.slotNumber; } - this.gm.controller.windowClick(this.inventorySlots.windowId, slotId, clickedButton, clickType, this.gm.player); + this.gm.controller.windowClick(this.inventorySlots.windowId, slotId, clickedButton, clickType, this.gm.thePlayer); } public void dropItem() { - if (this.gm != null && this.gm.player != null && this.theSlot != null && this.theSlot.getHasStack()) + if (this.gm != null && this.gm.thePlayer != null && this.theSlot != null && this.theSlot.getHasStack()) { // if (keyCode == this.gm.bindTertiary.getKeyCode()) // { @@ -1034,7 +1034,7 @@ public abstract class GuiContainer extends Gui */ public void useHotbar(int slot) { - if (!this.clickSide((this.gm.mouse_x - this.container_x) / 2, (this.gm.mouse_y - this.container_y) / 2, slot, this.gm.shift(), this.gm.ctrl()) && this.gm != null && this.gm.player != null && this.gm.player.inventory.getItemStack() == null && this.cheatStack == null && this.theSlot != null) + if (!this.clickSide((this.gm.mouse_x - this.container_x) / 2, (this.gm.mouse_y - this.container_y) / 2, slot, this.gm.shift(), this.gm.ctrl()) && this.gm != null && this.gm.thePlayer != null && this.gm.thePlayer.inventory.getItemStack() == null && this.cheatStack == null && this.theSlot != null) { // for (int i = 0; i < 9; ++i) // { @@ -1054,9 +1054,9 @@ public abstract class GuiContainer extends Gui */ public void onGuiClosed() { - if (this.gm != null && this.gm.player != null) + if (this.gm != null && this.gm.thePlayer != null) { - this.inventorySlots.onContainerClosed(this.gm.player); + this.inventorySlots.onContainerClosed(this.gm.thePlayer); } } @@ -1075,9 +1075,9 @@ public abstract class GuiContainer extends Gui { // super.updateScreen(); - if (this.gm != null && this.gm.player != null && (!this.gm.player.isEntityAlive() || this.gm.player.dead)) + if (this.gm != null && this.gm.thePlayer != null && (!this.gm.thePlayer.isEntityAlive() || this.gm.thePlayer.dead)) { - this.gm.player.closeScreen(); + this.gm.thePlayer.closeScreen(); } } @@ -1182,7 +1182,7 @@ public abstract class GuiContainer extends Gui } private boolean clickSide(int mouseX, int mouseY, int slot, boolean instant, boolean full) { - if(this.gm.itemCheat && this.isPointInRegion(this.xSize + 2, 0, 18 * 12, 18 * 9, mouseX, mouseY) && this.gm.player != null && this.gm.player.inventory.getItemStack() == null && this.cheatStack == null) { + if(this.gm.itemCheat && this.isPointInRegion(this.xSize + 2, 0, 18 * 12, 18 * 9, mouseX, mouseY) && this.gm.thePlayer != null && this.gm.thePlayer.inventory.getItemStack() == null && this.cheatStack == null) { int i = (ITEM_LIST.size() + 12 - 1) / 12 - 9; int j = (int)((double)(this.currentScroll * (float)i) + 0.5D); @@ -1197,7 +1197,7 @@ public abstract class GuiContainer extends Gui if(i1 >= 0 && i1 < ITEM_LIST.size()) { if(slot >= 0 || instant) { - this.gm.player.sendQueue.addToSendQueue(new CPacketCheat(ITEM_LIST.get(i1), slot, full)); + this.gm.thePlayer.sendQueue.addToSendQueue(new CPacketCheat(ITEM_LIST.get(i1), slot, full)); } else { this.cheatStack = ITEM_LIST.get(i1).copy(); diff --git a/client/src/client/gui/container/GuiEnchant.java b/client/src/client/gui/container/GuiEnchant.java index 0b25ef3..5dce728 100755 --- a/client/src/client/gui/container/GuiEnchant.java +++ b/client/src/client/gui/container/GuiEnchant.java @@ -70,7 +70,7 @@ public class GuiEnchant extends GuiContainer int l = mouseX - 60; int i1 = mouseY - (14 + 19 * k); - if (l >= 0 && i1 >= 0 && l < 108 && i1 < 19 && this.container.enchantItem(this.gm.player, k)) + if (l >= 0 && i1 >= 0 && l < 108 && i1 < 19 && this.container.enchantItem(this.gm.thePlayer, k)) { this.gm.controller.sendEnchantPacket(this.container.windowId, k); } @@ -107,7 +107,7 @@ public class GuiEnchant extends GuiContainer String s1 = "" + l1; int i2 = 6839882; - if (/* (k < l + 1 || */ this.gm.player.experienceLevel < l1) // && !this.gm.thePlayer.creative) + if (/* (k < l + 1 || */ this.gm.thePlayer.experienceLevel < l1) // && !this.gm.thePlayer.creative) { this.rect(i1, 14 + 19 * l, 108, 19, 0x400000); this.rect(i1 + 1, 15 + 19 * l, 16, 16, 0x200000); @@ -171,7 +171,7 @@ public class GuiEnchant extends GuiContainer // sb.append("\n"); // } - if (this.gm.player.experienceLevel < k) + if (this.gm.thePlayer.experienceLevel < k) { sb.append((sb.length() != 0 ? "\n" : "") + TextColor.RED + String.format("Erfahrungsstufe %d erforderlich", this.container.enchantLevels[j])); } diff --git a/client/src/client/gui/container/GuiHopper.java b/client/src/client/gui/container/GuiHopper.java index c11362a..c76579f 100755 --- a/client/src/client/gui/container/GuiHopper.java +++ b/client/src/client/gui/container/GuiHopper.java @@ -19,7 +19,7 @@ public class GuiHopper extends GuiContainer public GuiHopper(InventoryPlayer playerInv, IInventory hopperInv) { - super(new ContainerHopper(playerInv, hopperInv, Client.CLIENT.player)); + super(new ContainerHopper(playerInv, hopperInv, Client.CLIENT.thePlayer)); this.playerInventory = playerInv; this.hopperInventory = hopperInv; // this.allowUserInput = false; diff --git a/client/src/client/gui/container/GuiHorse.java b/client/src/client/gui/container/GuiHorse.java index ad5cf54..dbb5ec9 100755 --- a/client/src/client/gui/container/GuiHorse.java +++ b/client/src/client/gui/container/GuiHorse.java @@ -27,7 +27,7 @@ public class GuiHorse extends GuiContainer public GuiHorse(IInventory playerInv, IInventory horseInv, EntityHorse horse) { - super(new ContainerHorseInventory(playerInv, horseInv, horse, Client.CLIENT.player)); + super(new ContainerHorseInventory(playerInv, horseInv, horse, Client.CLIENT.thePlayer)); this.playerInventory = playerInv; this.horseInventory = horseInv; // this.horseEntity = horse; diff --git a/client/src/client/gui/container/GuiMachine.java b/client/src/client/gui/container/GuiMachine.java index 2467e18..82ed33f 100755 --- a/client/src/client/gui/container/GuiMachine.java +++ b/client/src/client/gui/container/GuiMachine.java @@ -16,7 +16,7 @@ public class GuiMachine extends GuiContainer public GuiMachine(InventoryPlayer player, IInventory inv, TileEntityMachine machine) { - super(new ContainerMachine(player, machine, inv, Client.CLIENT.player)); + super(new ContainerMachine(player, machine, inv, Client.CLIENT.thePlayer)); this.playerInv = player; this.machineInv = machine; // this.allowUserInput = false; diff --git a/client/src/client/gui/container/GuiRepair.java b/client/src/client/gui/container/GuiRepair.java index 2d7dfb7..8015977 100755 --- a/client/src/client/gui/container/GuiRepair.java +++ b/client/src/client/gui/container/GuiRepair.java @@ -21,7 +21,7 @@ public class GuiRepair extends GuiContainer implements ICrafting public GuiRepair(InventoryPlayer inventoryIn, World worldIn) { - super(new ContainerRepair(inventoryIn, worldIn, Client.CLIENT.player)); + super(new ContainerRepair(inventoryIn, worldIn, Client.CLIENT.thePlayer)); this.playerInventory = inventoryIn; this.anvil = (ContainerRepair)this.inventorySlots; } diff --git a/client/src/client/gui/ingame/GuiGameOver.java b/client/src/client/gui/ingame/GuiGameOver.java index d8ad0a9..8b79563 100755 --- a/client/src/client/gui/ingame/GuiGameOver.java +++ b/client/src/client/gui/ingame/GuiGameOver.java @@ -18,10 +18,10 @@ public class GuiGameOver extends Gui { public void init(int width, int height) { this.timer = 0; this.add(new Label(0, 0, 200, 20, "Du bist gestorben!")); - this.add(new Label(0, 32, 200, 20, "Punktestand: " + TextColor.YELLOW + this.gm.player.experienceLevel)); + this.add(new Label(0, 32, 200, 20, "Punktestand: " + TextColor.YELLOW + this.gm.thePlayer.experienceLevel)); this.button = this.add(new ActButton(0, 100, 200, 24, new ActButton.Callback() { public void use(ActButton elem, Mode action) { - GuiGameOver.this.gm.player.respawnPlayer(); + GuiGameOver.this.gm.thePlayer.respawnPlayer(); GuiGameOver.this.gm.displayGuiScreen(null); } }, "Wiederbeleben")); diff --git a/client/src/client/network/ClientPlayer.java b/client/src/client/network/ClientPlayer.java index e8d1e1f..e30af14 100755 --- a/client/src/client/network/ClientPlayer.java +++ b/client/src/client/network/ClientPlayer.java @@ -202,7 +202,7 @@ public class ClientPlayer extends NetHandler implements IClientPlayer // this.gameController.gameSettings.difficulty = packetIn.getDifficulty(); this.gameController.loadWorld(this.clientWorldController, packetIn.getEntityType()); // this.gameController.thePlayer.dimension = this.clientWorldController.dimension.getDimensionId(); - this.gameController.player.setId(packetIn.getEntityId()); + this.gameController.thePlayer.setId(packetIn.getEntityId()); this.gameController.displayGuiScreen(this.gameController.charEditor ? GuiChar.INSTANCE : null); // this.currentServerMaxPlayers = packetIn.getMaxPlayers(); // this.gameController.controller.setCheat(packetIn.getCheat()); @@ -465,7 +465,7 @@ public class ClientPlayer extends NetHandler implements IClientPlayer { entity.getDataWatcher().updateWatchedObjectsFromList(packetIn.func_149376_c()); - if(entity == this.gameController.player && this.gameController.open instanceof GuiChar) + if(entity == this.gameController.thePlayer && this.gameController.open instanceof GuiChar) ((GuiChar)this.gameController.open).checkReopen(); } } @@ -481,7 +481,7 @@ public class ClientPlayer extends NetHandler implements IClientPlayer double z = (double)packetIn.getZ() / 32.0D; float yaw = packetIn.getYaw(); float pitch = packetIn.getPitch(); - EntityNPC player = (EntityNPC)EntityRegistry.createEntityByID(packetIn.getEntityType(), this.gameController.world); // new EntityNPC(this.gameController.theWorld); // , /* this.getPlayerInfo( */ packetIn.getUser()); // ).getUser()); + EntityNPC player = (EntityNPC)EntityRegistry.createEntityByID(packetIn.getEntityType(), this.gameController.theWorld); // new EntityNPC(this.gameController.theWorld); // , /* this.getPlayerInfo( */ packetIn.getUser()); // ).getUser()); player.setOtherPlayer(this.gameController); player.prevX = player.lastTickPosX = (double)(player.serverPosX = packetIn.getX()); player.prevY = player.lastTickPosY = (double)(player.serverPosY = packetIn.getY()); @@ -551,7 +551,7 @@ public class ClientPlayer extends NetHandler implements IClientPlayer if (packetIn.getHeldItemHotbarIndex() >= 0 && packetIn.getHeldItemHotbarIndex() < InventoryPlayer.getHotbarSize()) { - this.gameController.player.inventory.currentItem = packetIn.getHeldItemHotbarIndex(); + this.gameController.thePlayer.inventory.currentItem = packetIn.getHeldItemHotbarIndex(); } } @@ -620,7 +620,7 @@ public class ClientPlayer extends NetHandler implements IClientPlayer public void handlePlayerPosLook(SPacketPlayerPosLook packetIn) { NetHandler.checkThread(packetIn, this, this.gameController, this.clientWorldController); - EntityNPC entityplayer = this.gameController.player; + EntityNPC entityplayer = this.gameController.thePlayer; double d0 = packetIn.getX(); double d1 = packetIn.getY(); double d2 = packetIn.getZ(); @@ -669,9 +669,9 @@ public class ClientPlayer extends NetHandler implements IClientPlayer if (!this.doneLoadingTerrain) { - this.gameController.player.prevX = this.gameController.player.posX; - this.gameController.player.prevY = this.gameController.player.posY; - this.gameController.player.prevZ = this.gameController.player.posZ; + this.gameController.thePlayer.prevX = this.gameController.thePlayer.posX; + this.gameController.thePlayer.prevY = this.gameController.thePlayer.posY; + this.gameController.thePlayer.prevZ = this.gameController.thePlayer.posZ; this.doneLoadingTerrain = true; // this.gameController.displayGuiScreen(null); // if(this.travelSound) { @@ -769,7 +769,7 @@ public class ClientPlayer extends NetHandler implements IClientPlayer if (entitylivingbase == null) { - entitylivingbase = this.gameController.player; + entitylivingbase = this.gameController.thePlayer; } if (entity != null) @@ -907,7 +907,7 @@ public class ClientPlayer extends NetHandler implements IClientPlayer double d2 = (double)packetIn.getZ() / 32.0D; float f = (float)(packetIn.getYaw() * 360) / 256.0F; float f1 = (float)(packetIn.getPitch() * 360) / 256.0F; - EntityLiving entitylivingbase = (EntityLiving)EntityRegistry.createEntityByID(packetIn.getEntityType(), this.gameController.world); + EntityLiving entitylivingbase = (EntityLiving)EntityRegistry.createEntityByID(packetIn.getEntityType(), this.gameController.theWorld); entitylivingbase.serverPosX = packetIn.getX(); entitylivingbase.serverPosY = packetIn.getY(); entitylivingbase.serverPosZ = packetIn.getZ(); @@ -942,7 +942,7 @@ public class ClientPlayer extends NetHandler implements IClientPlayer { NetHandler.checkThread(packetIn, this, this.gameController, this.clientWorldController); // this.gameController.theWorld.getWorldInfo().setTime(packetIn.getTotalWorldTime()); - this.gameController.world.setDayTime(packetIn.getWorldTime()); + this.gameController.theWorld.setDayTime(packetIn.getWorldTime()); this.gameController.setTicked(packetIn.getServerinfo()); } @@ -968,9 +968,9 @@ public class ClientPlayer extends NetHandler implements IClientPlayer { // boolean flag = false; - if (packetIn.getEntityId() == this.gameController.player.getId()) + if (packetIn.getEntityId() == this.gameController.thePlayer.getId()) { - entity = this.gameController.player; + entity = this.gameController.thePlayer; if (entity1 instanceof EntityBoat) { @@ -1036,7 +1036,7 @@ public class ClientPlayer extends NetHandler implements IClientPlayer public void handleUpdateHealth(SPacketUpdateHealth packetIn) { NetHandler.checkThread(packetIn, this, this.gameController, this.clientWorldController); - this.gameController.player.setPlayerSPHealth(packetIn.getHealth()); + this.gameController.thePlayer.setPlayerSPHealth(packetIn.getHealth()); // this.gameController.thePlayer.getFoodStats().setFoodLevel(packetIn.getFoodLevel()); // this.gameController.thePlayer.getFoodStats().setFoodSaturationLevel(packetIn.getSaturationLevel()); } @@ -1044,7 +1044,7 @@ public class ClientPlayer extends NetHandler implements IClientPlayer public void handleSetExperience(SPacketSetExperience packetIn) { NetHandler.checkThread(packetIn, this, this.gameController, this.clientWorldController); - this.gameController.player.setXPStats(packetIn.getProgress(), packetIn.getTotalExperience(), packetIn.getLevel()); + this.gameController.thePlayer.setXPStats(packetIn.getProgress(), packetIn.getTotalExperience(), packetIn.getLevel()); } public void handleRespawn(SPacketRespawn packetIn) @@ -1080,11 +1080,11 @@ public class ClientPlayer extends NetHandler implements IClientPlayer public void handleExplosion(S27PacketExplosion packetIn) { NetHandler.checkThread(packetIn, this, this.gameController, this.clientWorldController); - Explosion explosion = new Explosion(this.gameController.world, (Entity)null, packetIn.getX(), packetIn.getY(), packetIn.getZ(), packetIn.getStrength(), packetIn.getAffectedBlockPositions()); + Explosion explosion = new Explosion(this.gameController.theWorld, (Entity)null, packetIn.getX(), packetIn.getY(), packetIn.getZ(), packetIn.getStrength(), packetIn.getAffectedBlockPositions()); explosion.doExplosionB(true, packetIn.hasAltSound()); - this.gameController.player.motionX += (double)packetIn.func_149149_c(); - this.gameController.player.motionY += (double)packetIn.func_149144_d(); - this.gameController.player.motionZ += (double)packetIn.func_149147_e(); + this.gameController.thePlayer.motionX += (double)packetIn.func_149149_c(); + this.gameController.thePlayer.motionY += (double)packetIn.func_149144_d(); + this.gameController.thePlayer.motionZ += (double)packetIn.func_149147_e(); } /** @@ -1094,7 +1094,7 @@ public class ClientPlayer extends NetHandler implements IClientPlayer public void handleOpenWindow(S2DPacketOpenWindow packetIn) { NetHandler.checkThread(packetIn, this, this.gameController, this.clientWorldController); - EntityNPC entityplayersp = this.gameController.player; + EntityNPC entityplayersp = this.gameController.thePlayer; if ("container".equals(packetIn.getGuiId())) { @@ -1128,7 +1128,7 @@ public class ClientPlayer extends NetHandler implements IClientPlayer { TileEntity machine = this.clientWorldController.getTileEntity(packetIn.getTilePos()); if(machine instanceof TileEntityMachine) - this.gameController.displayGuiScreen(new GuiMachine(this.gameController.player.inventory, containerlocalmenu, (TileEntityMachine)machine)); + this.gameController.displayGuiScreen(new GuiMachine(this.gameController.thePlayer.inventory, containerlocalmenu, (TileEntityMachine)machine)); } else { entityplayersp.displayGUIChest(containerlocalmenu); @@ -1143,7 +1143,7 @@ public class ClientPlayer extends NetHandler implements IClientPlayer public void handleSetSlot(S2FPacketSetSlot packetIn) { NetHandler.checkThread(packetIn, this, this.gameController, this.clientWorldController); - EntityNPC entityplayer = this.gameController.player; + EntityNPC entityplayer = this.gameController.thePlayer; if (packetIn.getWindowId() == -1) { @@ -1185,7 +1185,7 @@ public class ClientPlayer extends NetHandler implements IClientPlayer { NetHandler.checkThread(packetIn, this, this.gameController, this.clientWorldController); Container container = null; - EntityNPC entityplayer = this.gameController.player; + EntityNPC entityplayer = this.gameController.thePlayer; if (packetIn.getWindowId() == 0) { @@ -1208,7 +1208,7 @@ public class ClientPlayer extends NetHandler implements IClientPlayer public void handleWindowItems(S30PacketWindowItems packetIn) { NetHandler.checkThread(packetIn, this, this.gameController, this.clientWorldController); - EntityNPC entityplayer = this.gameController.player; + EntityNPC entityplayer = this.gameController.thePlayer; if (packetIn.func_148911_c() == 0) { @@ -1235,7 +1235,7 @@ public class ClientPlayer extends NetHandler implements IClientPlayer tileentity.setPos(packetIn.getSignPosition()); } - this.gameController.player.openEditSign((TileEntitySign)tileentity); + this.gameController.thePlayer.openEditSign((TileEntitySign)tileentity); } /** @@ -1246,9 +1246,9 @@ public class ClientPlayer extends NetHandler implements IClientPlayer NetHandler.checkThread(packetIn, this, this.gameController, this.clientWorldController); // boolean flag = false; - if (this.gameController.world.isBlockLoaded(packetIn.getPos())) + if (this.gameController.theWorld.isBlockLoaded(packetIn.getPos())) { - TileEntity tileentity = this.gameController.world.getTileEntity(packetIn.getPos()); + TileEntity tileentity = this.gameController.theWorld.getTileEntity(packetIn.getPos()); if (tileentity instanceof TileEntitySign) { @@ -1280,9 +1280,9 @@ public class ClientPlayer extends NetHandler implements IClientPlayer { NetHandler.checkThread(packetIn, this, this.gameController, this.clientWorldController); - if (this.gameController.world.isBlockLoaded(packetIn.getPos())) + if (this.gameController.theWorld.isBlockLoaded(packetIn.getPos())) { - TileEntity tileentity = this.gameController.world.getTileEntity(packetIn.getPos()); + TileEntity tileentity = this.gameController.theWorld.getTileEntity(packetIn.getPos()); // int i = packetIn.getTileEntityType(); if (tileentity != null && packetIn.isTileEntityType(tileentity)) // i == 1 && tileentity instanceof TileEntityMobSpawner || /* i == 2 && tileentity instanceof TileEntityCommandBlock || */ i == 3 && tileentity instanceof TileEntityBeacon || i == 4 && tileentity instanceof TileEntitySkull || /* i == 5 && tileentity instanceof TileEntityFlowerPot || */ i == 6 && tileentity instanceof TileEntityBanner || i == 7 && tileentity instanceof TileEntityMachine) @@ -1298,7 +1298,7 @@ public class ClientPlayer extends NetHandler implements IClientPlayer public void handleWindowProperty(S31PacketWindowProperty packetIn) { NetHandler.checkThread(packetIn, this, this.gameController, this.clientWorldController); - EntityNPC entityplayer = this.gameController.player; + EntityNPC entityplayer = this.gameController.thePlayer; if (entityplayer.openContainer != null && entityplayer.openContainer.windowId == packetIn.getWindowId()) { @@ -1335,7 +1335,7 @@ public class ClientPlayer extends NetHandler implements IClientPlayer public void handleBlockAction(SPacketBlockAction packetIn) { NetHandler.checkThread(packetIn, this, this.gameController, this.clientWorldController); - this.gameController.world.addBlockEvent(packetIn.getBlockPosition(), packetIn.getBlockType(), packetIn.getData1(), packetIn.getData2()); + this.gameController.theWorld.addBlockEvent(packetIn.getBlockPosition(), packetIn.getBlockType(), packetIn.getData1(), packetIn.getData2()); } /** @@ -1344,7 +1344,7 @@ public class ClientPlayer extends NetHandler implements IClientPlayer public void handleBlockBreakAnim(SPacketBlockBreakAnim packetIn) { NetHandler.checkThread(packetIn, this, this.gameController, this.clientWorldController); - this.gameController.world.sendBlockBreakProgress(packetIn.getBreakerId(), packetIn.getPosition(), packetIn.getProgress()); + this.gameController.theWorld.sendBlockBreakProgress(packetIn.getBreakerId(), packetIn.getPosition(), packetIn.getProgress()); } public void handleMapChunkBulk(SPacketMapChunkBulk packetIn) @@ -1403,7 +1403,7 @@ public class ClientPlayer extends NetHandler implements IClientPlayer // } // else // { - this.gameController.world.playAuxSFX(packetIn.getSoundType(), packetIn.getSoundPos(), packetIn.getSoundData()); + this.gameController.theWorld.playAuxSFX(packetIn.getSoundType(), packetIn.getSoundPos(), packetIn.getSoundData()); // } } @@ -1597,7 +1597,7 @@ public class ClientPlayer extends NetHandler implements IClientPlayer public void handlePlayerAbilities(S39PacketPlayerAbilities packetIn) { NetHandler.checkThread(packetIn, this, this.gameController, this.clientWorldController); - EntityNPC entityplayer = this.gameController.player; + EntityNPC entityplayer = this.gameController.thePlayer; entityplayer.flying = packetIn.isFlying(); entityplayer.noclip = packetIn.isNoclip(); // entityplayer.speed = packetIn.getSpeed(); @@ -1629,7 +1629,7 @@ public class ClientPlayer extends NetHandler implements IClientPlayer // else if(packetIn.getSoundName().startsWith("music#")) { // return; // } - this.gameController.world.playSound(packetIn.getX(), packetIn.getY(), packetIn.getZ(), packetIn.getSound(), packetIn.getVolume()); + this.gameController.theWorld.playSound(packetIn.getX(), packetIn.getY(), packetIn.getZ(), packetIn.getSound(), packetIn.getVolume()); } // public void handleDisplay(S48PacketDisplay packetIn) @@ -1901,7 +1901,7 @@ public class ClientPlayer extends NetHandler implements IClientPlayer int i = packetIn.getWindowId(); Gui gui = this.gameController.open; - if (gui != null && gui instanceof GuiMerchant && i == this.gameController.player.openContainer.windowId) + if (gui != null && gui instanceof GuiMerchant && i == this.gameController.thePlayer.openContainer.windowId) { // NpcMerchant imerchant = ((GuiMerchant)guiscreen).getMerchant(); MerchantRecipeList merchantrecipelist = packetIn.getTrades(); diff --git a/client/src/client/renderer/EntityRenderer.java b/client/src/client/renderer/EntityRenderer.java index d0b2f82..82efc10 100755 --- a/client/src/client/renderer/EntityRenderer.java +++ b/client/src/client/renderer/EntityRenderer.java @@ -129,10 +129,10 @@ public class EntityRenderer { if (this.gm.getRenderViewEntity() == null) { - this.gm.setRenderViewEntity(this.gm.player); + this.gm.setRenderViewEntity(this.gm.thePlayer); } - float light = this.gm.world.getLightBrightness(new BlockPos(this.gm.getRenderViewEntity())); + float light = this.gm.theWorld.getLightBrightness(new BlockPos(this.gm.getRenderViewEntity())); // Log.info(String.format("%.3f", light)); float dist = (float)this.gm.renderDistance / 32.0F; float shift = light * (1.0F - dist) + dist; @@ -186,10 +186,10 @@ public class EntityRenderer { if (entity != null) { - if (this.gm.world != null) + if (this.gm.theWorld != null) { this.gm.setPointedEntity(null); - double max = this.gm.player != null ? this.gm.player.getReachDistance() : 5.0; + double max = this.gm.thePlayer != null ? this.gm.thePlayer.getReachDistance() : 5.0; this.gm.pointed = entity.rayTrace(max, partialTicks); double dist = max; Vec3 eye = entity.getPositionEyes(partialTicks); @@ -219,7 +219,7 @@ public class EntityRenderer { this.pointedEntity = null; Vec3 hit = null; float exp = 1.0F; - List list = this.gm.world.getEntitiesInAABBexcluding(entity, entity.getEntityBoundingBox().addCoord(look.xCoord * max, look.yCoord * max, look.zCoord * max).expand((double)exp, (double)exp, (double)exp), new Predicate() + List list = this.gm.theWorld.getEntitiesInAABBexcluding(entity, entity.getEntityBoundingBox().addCoord(look.xCoord * max, look.yCoord * max, look.zCoord * max).expand((double)exp, (double)exp, (double)exp), new Predicate() { public boolean test(Entity p_apply_1_) { @@ -502,7 +502,7 @@ public class EntityRenderer { f3 = f3 * 0.1F; f4 = f4 * 0.1F; f5 = f5 * 0.1F; - HitPosition movingobjectposition = this.gm.world.rayTraceBlocks(new Vec3(d0 + (double)f3, d1 + (double)f4, d2 + (double)f5), new Vec3(d0 - d4 + (double)f3 + (double)f5, d1 - d6 + (double)f4, d2 - d5 + (double)f5)); + HitPosition movingobjectposition = this.gm.theWorld.rayTraceBlocks(new Vec3(d0 + (double)f3, d1 + (double)f4, d2 + (double)f5), new Vec3(d0 - d4 + (double)f3 + (double)f5, d1 - d6 + (double)f4, d2 - d5 + (double)f5)); if (movingobjectposition != null) { @@ -749,7 +749,7 @@ public class EntityRenderer { { if (this.lightmapUpdateNeeded) { - WorldClient world = this.gm.world; + WorldClient world = this.gm.theWorld; if (world != null) { @@ -792,9 +792,9 @@ public class EntityRenderer { // f10 = 0.25F + f7 * 0.75F; // } - if (this.gm.player.hasEffect(Potion.NIGHT_VISION)) + if (this.gm.thePlayer.hasEffect(Potion.NIGHT_VISION)) { - float vis = this.getNightVisionBrightness(this.gm.player, partialTicks); + float vis = this.getNightVisionBrightness(this.gm.thePlayer, partialTicks); float mult = 1.0F / red; if (mult > 1.0F / green) @@ -926,7 +926,7 @@ public class EntityRenderer { if (this.gm.getRenderViewEntity() == null) { - this.gm.setRenderViewEntity(this.gm.player); + this.gm.setRenderViewEntity(this.gm.thePlayer); } this.getMouseOver(partialTicks); @@ -958,7 +958,7 @@ public class EntityRenderer { this.updateFogColor(partialTicks); GL11.glClear(16640); this.setupCameraTransform(partialTicks); - ActiveRenderInfo.updateRenderInfo(this.gm.player, this.gm.thirdPersonView == 2); + ActiveRenderInfo.updateRenderInfo(this.gm.thePlayer, this.gm.thirdPersonView == 2); Entity entity = this.gm.getRenderViewEntity(); double d0 = entity.lastTickPosX + (entity.posX - entity.lastTickPosX) * (double)partialTicks; double d1 = entity.lastTickPosY + (entity.posY - entity.lastTickPosY) * (double)partialTicks; @@ -981,14 +981,14 @@ public class EntityRenderer { this.setupFog(0, partialTicks); GlState.shadeModel(GL11.GL_SMOOTH); - if (entity.posY + (double)entity.getEyeHeight() < (double)this.gm.world.dimension.getCloudHeight()) + if (entity.posY + (double)entity.getEyeHeight() < (double)this.gm.theWorld.dimension.getCloudHeight()) { this.renderCloudsCheck(renderglobal, partialTicks); } this.setupFog(0, partialTicks); this.gm.getTextureManager().bindTexture(TextureMap.locationBlocksTexture); ItemRenderer.disableStandardItemLighting(); - renderglobal.setupTerrain(entity, (double)partialTicks, this.frameCount++, this.gm.player.noclip); + renderglobal.setupTerrain(entity, (double)partialTicks, this.frameCount++, this.gm.thePlayer.noclip); this.gm.renderGlobal.updateChunks(finishTimeNano); GL11.glMatrixMode(GL11.GL_MODELVIEW); GL11.glPushMatrix(); @@ -1073,7 +1073,7 @@ public class EntityRenderer { GlState.disableBlend(); GlState.disableFog(); - if (entity.posY + (double)entity.getEyeHeight() >= (double)this.gm.world.dimension.getCloudHeight()) + if (entity.posY + (double)entity.getEyeHeight() >= (double)this.gm.theWorld.dimension.getCloudHeight()) { this.renderCloudsCheck(renderglobal, partialTicks); } @@ -1096,7 +1096,7 @@ public class EntityRenderer { GL11.glPushMatrix(); this.setupFog(0, partialTicks); // renderGlobalIn.renderClouds(partialTicks); - if(this.gm.world.dimension.getType().clouds) + if(this.gm.theWorld.dimension.getType().clouds) renderGlobalIn.renderClouds(partialTicks); GlState.disableFog(); GL11.glPopMatrix(); @@ -1109,7 +1109,7 @@ public class EntityRenderer { private void addRainParticles() { - float f = this.gm.world.getRainStrength(); + float f = this.gm.theWorld.getRainStrength(); // if (this.gm.downfallSetting != 0) // { @@ -1120,7 +1120,7 @@ public class EntityRenderer { { this.random.setSeed((long)this.rendererUpdateCount * 312987231L); Entity entity = this.gm.getRenderViewEntity(); - World world = this.gm.world; + World world = this.gm.theWorld; BlockPos blockpos = new BlockPos(entity); int i = 10; double d0 = 0.0D; @@ -1166,7 +1166,7 @@ public class EntityRenderer { } } if(temp < 194.0f || this.random.chance(5)) - this.gm.world.spawnParticle(temp >= 194.0f && this.random.chance(10) ? ParticleType.LAVA : ParticleType.SMOKE_NORMAL, (double)blockpos1.getX() + d3, (double)((float)blockpos1.getY() + 0.1F) - block.getBlockBoundsMinY(), (double)blockpos1.getZ() + d4, 0.0D, 0.0D, 0.0D); + this.gm.theWorld.spawnParticle(temp >= 194.0f && this.random.chance(10) ? ParticleType.LAVA : ParticleType.SMOKE_NORMAL, (double)blockpos1.getX() + d3, (double)((float)blockpos1.getY() + 0.1F) - block.getBlockBoundsMinY(), (double)blockpos1.getZ() + d4, 0.0D, 0.0D, 0.0D); } else if (block.getMaterial() != Material.air) { @@ -1180,7 +1180,7 @@ public class EntityRenderer { d2 = (double)blockpos2.getZ() + d4; } - this.gm.world.spawnParticle(temp <= 5.0f ? ParticleType.HAIL_CORN : ParticleType.WATER_DROP, (double)blockpos2.getX() + d3, (double)((float)blockpos2.getY() + 0.1F) + block.getBlockBoundsMaxY(), (double)blockpos2.getZ() + d4, 0.0D, 0.0D, 0.0D); + this.gm.theWorld.spawnParticle(temp <= 5.0f ? ParticleType.HAIL_CORN : ParticleType.WATER_DROP, (double)blockpos2.getX() + d3, (double)((float)blockpos2.getY() + 0.1F) + block.getBlockBoundsMaxY(), (double)blockpos2.getZ() + d4, 0.0D, 0.0D, 0.0D); } } } @@ -1191,11 +1191,11 @@ public class EntityRenderer { if (d1 > (double)(blockpos.getY() + 1) && world.getPrecipitationHeight(blockpos).getY() > ExtMath.floorf((float)blockpos.getY())) { - this.gm.world.playSound(d0, d1, d2, n >= j ? this.pickMoltenSound() : SoundEvent.RAIN, n >= j ? 0.2f : 0.1F); + this.gm.theWorld.playSound(d0, d1, d2, n >= j ? this.pickMoltenSound() : SoundEvent.RAIN, n >= j ? 0.2f : 0.1F); } else { - this.gm.world.playSound(d0, d1, d2, n >= j ? this.pickMoltenSound() : SoundEvent.RAIN, n >= j ? 0.4f : 0.2F); + this.gm.theWorld.playSound(d0, d1, d2, n >= j ? this.pickMoltenSound() : SoundEvent.RAIN, n >= j ? 0.4f : 0.2F); } } } @@ -1210,13 +1210,13 @@ public class EntityRenderer { */ protected void renderRainSnow(float partialTicks) { - float f = this.gm.world.getRainStrength(); + float f = this.gm.theWorld.getRainStrength(); if (f > 0.0F) // && this.gm.downfallSetting < 2) { this.enableLightmap(); Entity entity = this.gm.getRenderViewEntity(); - World world = this.gm.world; + World world = this.gm.theWorld; int i = ExtMath.floord(entity.posX); int j = ExtMath.floord(entity.posY); int k = ExtMath.floord(entity.posZ); @@ -1411,7 +1411,7 @@ public class EntityRenderer { */ private void updateFogColor(float partial) { - WorldClient world = this.gm.world; + WorldClient world = this.gm.theWorld; Entity entity = this.gm.getRenderViewEntity(); float dist = 0.25F + 0.75F * (float)this.gm.renderDistance / 32.0F; dist = 1.0F - (float)Math.pow((double)dist, 0.25D); @@ -1473,7 +1473,7 @@ public class EntityRenderer { this.fogColorBlue *= mul; } - Block block = ActiveRenderInfo.getBlockAtEntityViewpoint(this.gm.world, entity, partial); + Block block = ActiveRenderInfo.getBlockAtEntityViewpoint(this.gm.theWorld, entity, partial); // if (this.cloudFog) // { @@ -1586,7 +1586,7 @@ public class EntityRenderer { private void setupFog(int start, float partial) { Entity entity = this.gm.getRenderViewEntity(); - float fog = this.gm.world.getFogStrength(); + float fog = this.gm.theWorld.getFogStrength(); float distance = Math.min(0.995f, Math.max(0.005f, FOG_DISTANCE - (0.3f * fog))); float density = 1.0f - Math.min(1.0f, FOG_DENSITY * (1.0f - fog * 0.1f)); // boolean flag = false; @@ -1599,7 +1599,7 @@ public class EntityRenderer { GL11.glFogfv(GL11.GL_FOG_COLOR, (FloatBuffer)this.setFogColorBuffer(this.fogColorRed, this.fogColorGreen, this.fogColorBlue, 1.0F)); GL11.glNormal3f(0.0F, -1.0F, 0.0F); GlState.color(1.0F, 1.0F, 1.0F, 1.0F); - Block block = ActiveRenderInfo.getBlockAtEntityViewpoint(this.gm.world, entity, partial); + Block block = ActiveRenderInfo.getBlockAtEntityViewpoint(this.gm.theWorld, entity, partial); if(distance >= 1.0f) { ; @@ -1676,7 +1676,7 @@ public class EntityRenderer { // SKC.glFogi(NVFogDistance.GL_FOG_DISTANCE_MODE_NV, NVFogDistance.GL_EYE_RADIAL_NV); // } - if (this.gm.world.dimension.hasDenseFog()) + if (this.gm.theWorld.dimension.hasDenseFog()) { GlState.setFogStart(far * ((distance / 0.75f) * 0.05F)); GlState.setFogEnd(Math.min(far, 192.0F) * Math.max(density * (distance / 0.75f), (distance / 0.75f) * 0.05F + 0.01f)); diff --git a/client/src/client/renderer/ItemRenderer.java b/client/src/client/renderer/ItemRenderer.java index 0c310a6..eff32d6 100755 --- a/client/src/client/renderer/ItemRenderer.java +++ b/client/src/client/renderer/ItemRenderer.java @@ -163,7 +163,7 @@ public class ItemRenderer */ private void setLightMapFromPlayer(EntityNPC clientPlayer) { - int i = this.gm.world.getCombinedLight(new BlockPos(clientPlayer.posX, clientPlayer.posY + (double)clientPlayer.getEyeHeight(), clientPlayer.posZ), 0); + int i = this.gm.theWorld.getCombinedLight(new BlockPos(clientPlayer.posX, clientPlayer.posY + (double)clientPlayer.getEyeHeight(), clientPlayer.posZ), 0); float f = (float)(i & 65535); float f1 = (float)(i >> 16); GL13.glMultiTexCoord2f(GL13.GL_TEXTURE1, f, f1); @@ -299,9 +299,9 @@ public class ItemRenderer GL11.glRotatef(-135.0F, 0.0F, 1.0F, 0.0F); GL11.glScalef(1.0F, 1.0F, 1.0F); GL11.glTranslatef(5.6F, 0.0F, 0.0F); - RenderNpc render = this.renderManager.getRenderObject(this.gm.player.getModel()); + RenderNpc render = this.renderManager.getRenderObject(this.gm.thePlayer.getModel()); GlState.disableCull(); - render.renderPlayerArm(this.gm.player); + render.renderPlayerArm(this.gm.thePlayer); GlState.enableCull(); } @@ -407,7 +407,7 @@ public class ItemRenderer public void renderItemInFirstPerson(float partialTicks) { float f = 1.0F - (this.prevEquippedProgress + (this.equippedProgress - this.prevEquippedProgress) * partialTicks); - EntityNPC clientplayer = this.gm.player; + EntityNPC clientplayer = this.gm.thePlayer; float f1 = clientplayer.getSwingProgress(partialTicks); float f2 = clientplayer.prevPitch + (clientplayer.rotPitch - clientplayer.prevPitch) * partialTicks; float f3 = clientplayer.prevYaw + (clientplayer.rotYaw - clientplayer.prevYaw) * partialTicks; @@ -475,10 +475,10 @@ public class ItemRenderer { GlState.disableAlpha(); - if (this.gm.player.isEntityInsideOpaqueBlock()) + if (this.gm.thePlayer.isEntityInsideOpaqueBlock()) { - State iblockstate = this.gm.world.getState(new BlockPos(this.gm.player)); - EntityNPC entityplayer = this.gm.player; + State iblockstate = this.gm.theWorld.getState(new BlockPos(this.gm.thePlayer)); + EntityNPC entityplayer = this.gm.thePlayer; for (int i = 0; i < 8; ++i) { @@ -486,7 +486,7 @@ public class ItemRenderer double d1 = entityplayer.posY + (double)(((float)((i >> 1) % 2) - 0.5F) * 0.1F); double d2 = entityplayer.posZ + (double)(((float)((i >> 2) % 2) - 0.5F) * entityplayer.width * 0.8F); BlockPos blockpos = new BlockPos(d0, d1 + (double)entityplayer.getEyeHeight(), d2); - State iblockstate1 = this.gm.world.getState(blockpos); + State iblockstate1 = this.gm.theWorld.getState(blockpos); if (iblockstate1.getBlock().isVisuallyOpaque()) { @@ -500,7 +500,7 @@ public class ItemRenderer } } - if(this.gm.player.isBurning()) { + if(this.gm.thePlayer.isBurning()) { this.renderFireInFirstPerson(partialTicks); } @@ -590,7 +590,7 @@ public class ItemRenderer public void updateEquippedItem() { this.prevEquippedProgress = this.equippedProgress; - EntityNPC entityplayer = this.gm.player; + EntityNPC entityplayer = this.gm.thePlayer; ItemStack itemstack = entityplayer.inventory.getCurrentItem(); boolean flag = false; diff --git a/client/src/client/renderer/RenderGlobal.java b/client/src/client/renderer/RenderGlobal.java index 03a90a9..06c89ad 100755 --- a/client/src/client/renderer/RenderGlobal.java +++ b/client/src/client/renderer/RenderGlobal.java @@ -560,7 +560,7 @@ public class RenderGlobal GlState.enableAlpha(); } - if (this.gm.renderOutlines && this.gm.player != null) + if (this.gm.renderOutlines && this.gm.thePlayer != null) { GlState.depthFunc(GL11.GL_ALWAYS); GlState.disableFog(); @@ -575,7 +575,7 @@ public class RenderGlobal { Entity entity3 = list.get(j); if ((entity3 != this.gm.getRenderViewEntity() || this.gm.thirdPersonView != 0) && - entity3 instanceof EntityLiving && entity3.isInRangeToRender3d(d0, d1, d2) && (entity3.noFrustumCheck || Frustum.isInFrustum(entity3.getEntityBoundingBox()) || entity3.passenger == this.gm.player)) + entity3 instanceof EntityLiving && entity3.isInRangeToRender3d(d0, d1, d2) && (entity3.noFrustumCheck || Frustum.isInFrustum(entity3.getEntityBoundingBox()) || entity3.passenger == this.gm.thePlayer)) { // this.renderManager.renderEntity(entity3, partialTicks); int c = ((EntityLiving)entity3).getColor(); @@ -623,7 +623,7 @@ public class RenderGlobal } entity2 = (Entity)iterator.next(); - flag2 = this.renderManager.shouldRender(entity2, d0, d1, d2) || entity2.passenger == this.gm.player; + flag2 = this.renderManager.shouldRender(entity2, d0, d1, d2) || entity2.passenger == this.gm.thePlayer; if (!flag2) { @@ -1125,11 +1125,11 @@ public class RenderGlobal public void renderSky(float partialTicks) { - if (this.gm.world.dimension.getSkyBoxTexture() != null) + if (this.gm.theWorld.dimension.getSkyBoxTexture() != null) { - this.renderSkyBox(this.gm.world.dimension.getSkyBoxTexture()); + this.renderSkyBox(this.gm.theWorld.dimension.getSkyBoxTexture()); } - else if (this.gm.world.dimension.getType().sky) + else if (this.gm.theWorld.dimension.getType().sky) { GlState.disableTexture2D(); Vec3 vec3 = this.theWorld.getSkyColor(this.gm.getRenderViewEntity(), partialTicks); @@ -1223,7 +1223,7 @@ public class RenderGlobal GlState.color(1.0F, 1.0F, 1.0F, f16); GL11.glRotatef(-90.0F, 0.0F, 1.0F, 0.0F); GL11.glRotatef(this.theWorld.getCelestialAngle(partialTicks) * 360.0F, 1.0F, 0.0F, 0.0F); - if(this.gm.world.dimension.getType().sun) { + if(this.gm.theWorld.dimension.getType().sun) { float size = 30.0F; this.renderEngine.bindTexture(SUN_TEX); worldrenderer.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX); @@ -1233,7 +1233,7 @@ public class RenderGlobal worldrenderer.pos((double)(-size), 100.0D, (double)size).tex(0.0D, 1.0D).endVertex(); Tessellator.draw(); } - if(this.gm.world.dimension.getType().moon) { + if(this.gm.theWorld.dimension.getType().moon) { float size = 20.0F; this.renderEngine.bindTexture(MOON_TEX); int i = this.theWorld.getMoonPhase(); @@ -1332,7 +1332,7 @@ public class RenderGlobal int j = ExtMath.floord(d2 / 2048.0D); d1 = d1 - (double)(i * 2048); d2 = d2 - (double)(j * 2048); - this.renderEngine.bindTexture(this.gm.world.dimension.getCloudTexture()); + this.renderEngine.bindTexture(this.gm.theWorld.dimension.getCloudTexture()); GlState.enableBlend(); GlState.tryBlendFuncSeparate(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA, GL11.GL_ONE, GL11.GL_ZERO); Vec3 vec3 = this.theWorld.getCloudColour(this.gm.getRenderViewEntity(), partialTicks); diff --git a/client/src/client/renderer/entity/RenderFish.java b/client/src/client/renderer/entity/RenderFish.java index 6782994..4bac934 100755 --- a/client/src/client/renderer/entity/RenderFish.java +++ b/client/src/client/renderer/entity/RenderFish.java @@ -65,7 +65,7 @@ public class RenderFish extends Render double d2 = entity.angler.prevZ + (entity.angler.posZ - entity.angler.prevZ) * (double)partialTicks + vec3.zCoord; double d3 = (double)entity.angler.getEyeHeight(); - if (this.renderManager.gm != null && this.renderManager.gm.thirdPersonView > 0 || entity.angler != Client.CLIENT.player) + if (this.renderManager.gm != null && this.renderManager.gm.thirdPersonView > 0 || entity.angler != Client.CLIENT.thePlayer) { float f9 = (entity.angler.prevYawOffset + (entity.angler.yawOffset - entity.angler.prevYawOffset) * partialTicks) * (float)Math.PI / 180.0F; double d4 = (double)ExtMath.sin(f9); diff --git a/client/src/client/renderer/entity/RenderHumanoid.java b/client/src/client/renderer/entity/RenderHumanoid.java index 42660a5..04e767e 100755 --- a/client/src/client/renderer/entity/RenderHumanoid.java +++ b/client/src/client/renderer/entity/RenderHumanoid.java @@ -69,12 +69,12 @@ public class RenderHumanoid extends RenderNpc public void doRender(EntityNPC entity, double x, double y, double z, float partialTicks) { - if (entity != this.renderManager.gm.player || this.renderManager.livingPlayer == entity) + if (entity != this.renderManager.gm.thePlayer || this.renderManager.livingPlayer == entity) { // if(entity.isBoss()) // BossStatus.setBossStatus(entity); double d0 = y; - if(/* this.canSneak() && */ entity.isSneakingVisually() && entity != this.renderManager.gm.player) + if(/* this.canSneak() && */ entity.isSneakingVisually() && entity != this.renderManager.gm.thePlayer) d0 = y - 0.125D; this.setModelVisibilities(entity); super.doRender(entity, x, d0, z, partialTicks); diff --git a/common/src/common/log/Log.java b/common/src/common/log/Log.java index 04aa56c..c6deea4 100644 --- a/common/src/common/log/Log.java +++ b/common/src/common/log/Log.java @@ -44,7 +44,6 @@ public enum Log { private static final List LOG = Lists.newArrayList(); private static LogLevel level = LogLevel.INFO; - private static boolean colors = true; private static IThreadListener sync = new IThreadListener() { public ListenableFuture schedule(Runnable run) { return null; @@ -72,16 +71,14 @@ public enum Log { if(pos - last != 0) System.err.print(str.substring(last, pos)); color = TextColor.getColor(c); // (c >= CHR_COLORS2) && (c <= CHR_COLORE2) ? aux_colors[c - CHR_COLORS2] : text_colors[c - CHR_COLORS1]; - if(colors) - System.err.printf("\u001b[38;2;%d;%d;%dm", (color >> 16) & 0xff, (color >> 8) & 0xff, color & 0xff); + System.err.printf("\u001b[38;2;%d;%d;%dm", (color >> 16) & 0xff, (color >> 8) & 0xff, color & 0xff); last = ++pos; continue; } else if(c == CHR_CRESET) { if(pos - last != 0) System.err.print(str.substring(last, pos)); - if(colors) - System.err.print("\u001b[0m"); + System.err.print("\u001b[0m"); last = ++pos; continue; } @@ -102,7 +99,7 @@ public enum Log { if(pos >= str.length() && pos - last != 0) System.err.print(str.substring(last, pos)); } - System.err.print(colors ? "\u001b[0m\n" : "\n"); + System.err.print("\u001b[0m\n"); } public static String str_time(long time) { @@ -115,7 +112,6 @@ public enum Log { public static void init(IThreadListener sync) { Log.sync = sync; - Log.colors = System.getProperty("log.nocolor") == null && !Util.WINDOWS; } public static void flushLog() { diff --git a/common/src/common/util/Util.java b/common/src/common/util/Util.java index 629ef96..5d3a165 100644 --- a/common/src/common/util/Util.java +++ b/common/src/common/util/Util.java @@ -12,8 +12,7 @@ import common.collect.Maps; import common.log.Log; public abstract class Util { - public static final boolean WINDOWS = System.getProperty("os.name").startsWith("Windows"); - private static final long START = getTime(); + private static long start = getTime(); public static String strip(String str, int offset, int len, char newl, char tab, char unk) { StringBuilder sb = new StringBuilder(); @@ -304,10 +303,10 @@ int utf_len(const char *str) { } public static void checkOs() { - if(System.getProperty("os.name").startsWith("Mac")) { + if(System.getProperty("os.name").startsWith("Windows") || System.getProperty("os.name").startsWith("Mac")) { String info = "Inkompatibles Betriebssystem"; - String msg = "Linux, *BSD oder Windows ist erforderlich, um dieses Programm\n" + - "auszuführen. Alle Versionen von Mac OS (X) sind nicht kompatibel."; + String msg = "Linux oder *BSD ist erforderlich, um dieses Programm auszuführen.\n" + + "Alle Versionen von Windows und Mac OS (X) sind nicht kompatibel."; System.err.println("#################################################################"); System.err.println("*** " + info + " ***"); System.err.println(msg); @@ -383,7 +382,7 @@ int utf_len(const char *str) { } public static long rtime() { - return Util.getTime() - START; + return Util.getTime() - start; } public static double ftime() { From 541b9cc461b695818d457c07f1a7644258af57e5 Mon Sep 17 00:00:00 2001 From: Sen Date: Mon, 12 May 2025 18:47:43 +0200 Subject: [PATCH 018/200] Revert "Revert "add windows support (untested)"" This reverts commit 2158a700f4db2b865da348d8637761b273dd23e0. --- client/src/client/Client.java | 335 ++++++++++-------- client/src/client/PlayerController.java | 34 +- client/src/client/gui/Gui.java | 2 +- client/src/client/gui/GuiConfirm.java | 2 +- client/src/client/gui/GuiConsole.java | 12 +- client/src/client/gui/GuiInfo.java | 2 +- client/src/client/gui/GuiMenu.java | 12 +- client/src/client/gui/GuiServer.java | 2 +- client/src/client/gui/character/GuiChar.java | 50 +-- .../client/gui/character/GuiCharacters.java | 2 +- client/src/client/gui/character/GuiClass.java | 12 +- .../src/client/gui/character/GuiSpecies.java | 8 +- client/src/client/gui/container/GuiChest.java | 2 +- .../client/gui/container/GuiContainer.java | 44 +-- .../src/client/gui/container/GuiEnchant.java | 6 +- .../src/client/gui/container/GuiHopper.java | 2 +- client/src/client/gui/container/GuiHorse.java | 2 +- .../src/client/gui/container/GuiMachine.java | 2 +- .../src/client/gui/container/GuiRepair.java | 2 +- client/src/client/gui/ingame/GuiGameOver.java | 4 +- client/src/client/network/ClientPlayer.java | 72 ++-- .../src/client/renderer/EntityRenderer.java | 56 +-- client/src/client/renderer/ItemRenderer.java | 20 +- client/src/client/renderer/RenderGlobal.java | 18 +- .../client/renderer/entity/RenderFish.java | 2 +- .../renderer/entity/RenderHumanoid.java | 4 +- common/src/common/log/Log.java | 10 +- common/src/common/util/Util.java | 11 +- 28 files changed, 379 insertions(+), 351 deletions(-) diff --git a/client/src/client/Client.java b/client/src/client/Client.java index a9529d8..e0ab9f0 100755 --- a/client/src/client/Client.java +++ b/client/src/client/Client.java @@ -30,6 +30,7 @@ import java.util.concurrent.FutureTask; import java.util.function.Function; import javax.imageio.ImageIO; +import javax.swing.JFileChooser; import org.lwjgl.opengl.GL11; import org.lwjgl.opengl.GL13; @@ -341,8 +342,8 @@ public class Client implements IThreadListener, IClient { private BufferedImage skin; private Object popupTarget; public PlayerController controller; - public WorldClient theWorld; - public EntityNPC thePlayer; + public WorldClient world; + public EntityNPC player; public HitPosition pointed; @Variable(name = "chunk_view_distance", category = CVarCategory.RENDER, min = 2, max = 16 /* 128 */, callback = DistanceFunction.class, display = "Sichtweite", unit = "Chunks") @@ -519,8 +520,8 @@ public class Client implements IThreadListener, IClient { this.charEditor = false; this.viewEntity = null; this.connection = null; - this.theWorld = null; - this.thePlayer = null; + this.world = null; + this.player = null; this.serverInfo = null; this.lastTickTime = -1; this.soundManager.stopSounds(); @@ -573,7 +574,7 @@ public class Client implements IThreadListener, IClient { this.renderGlobal = new RenderGlobal(this); this.renderGlobal.onReload(); EntityTexManager.loadNpcTextures(); - this.effectRenderer = new EffectRenderer(this.theWorld, this.textureManager); + this.effectRenderer = new EffectRenderer(this.world, this.textureManager); } public void start() @@ -643,7 +644,7 @@ public class Client implements IThreadListener, IClient { if (this.keyBindsHotbar[l].isPressed()) { // if(!this.showDebugProfilerChart) { - this.thePlayer.inventory.currentItem = l; + this.player.inventory.currentItem = l; // } } } @@ -654,7 +655,7 @@ public class Client implements IThreadListener, IClient { if (Bind.THROW.isPressed()) { - this.thePlayer.dropOneItem(this.ctrl()); + this.player.dropOneItem(this.ctrl()); } this.primary |= Bind.PRIMARY.isPressed(); @@ -671,7 +672,7 @@ public class Client implements IThreadListener, IClient { } // this.ingameGui.updateTick(); this.entityRenderer.getMouseOver(1.0F); - if (/* !this.paused && */ this.theWorld != null) + if (/* !this.paused && */ this.world != null) { this.controller.updateController(); } @@ -681,9 +682,9 @@ public class Client implements IThreadListener, IClient { this.open.updateScreen(); } - if (this.open == null && this.thePlayer != null) + if (this.open == null && this.player != null) { - if (this.thePlayer.getHealth() <= 0) + if (this.player.getHealth() <= 0) { this.displayGuiScreen(null); } @@ -698,12 +699,12 @@ public class Client implements IThreadListener, IClient { --this.leftClickCounter; } - if (this.open == null && this.thePlayer != null) { - if (this.thePlayer.isUsingItem()) + if (this.open == null && this.player != null) { + if (this.player.isUsingItem()) { if (!Bind.SECONDARY.isDown()) { - this.controller.onStoppedUsingItem(this.thePlayer); + this.controller.onStoppedUsingItem(this.player); } } else @@ -729,7 +730,7 @@ public class Client implements IThreadListener, IClient { } } - if (Bind.SECONDARY.isDown() && this.rightClickTimer == 0 && !this.thePlayer.isUsingItem()) + if (Bind.SECONDARY.isDown() && this.rightClickTimer == 0 && !this.player.isUsingItem()) { this.secondary(); } @@ -739,30 +740,30 @@ public class Client implements IThreadListener, IClient { this.primary = this.secondary = this.tertiary = this.quarternary = false; - if (this.theWorld != null) + if (this.world != null) { - if (this.thePlayer != null) + if (this.player != null) { ++this.chunkLoadTimer; if (this.chunkLoadTimer == 30) { this.chunkLoadTimer = 0; - this.theWorld.ensureAreaLoaded(this.thePlayer); + this.world.ensureAreaLoaded(this.player); } } this.entityRenderer.updateRenderer(); this.renderGlobal.updateClouds(); - this.theWorld.decrLightning(); - this.theWorld.updateEntities(); + this.world.decrLightning(); + this.world.updateEntities(); } this.soundManager.update(); - if (this.theWorld != null) + if (this.world != null) { - this.theWorld.tick(); - if (/* !this.paused && */ this.theWorld != null) + this.world.tick(); + if (/* !this.paused && */ this.world != null) { - this.theWorld.displayTick(ExtMath.floord(this.thePlayer.posX), ExtMath.floord(this.thePlayer.posY), ExtMath.floord(this.thePlayer.posZ)); + this.world.displayTick(ExtMath.floord(this.player.posX), ExtMath.floord(this.player.posY), ExtMath.floord(this.player.posZ)); } this.effectRenderer.updateEffects(); } @@ -782,18 +783,18 @@ public class Client implements IThreadListener, IClient { GL11.glPolygonMode(GL11.GL_FRONT_AND_BACK, GL11.GL_LINE); // GL_FRONT_AND_BACK, GL_LINE } if(this.open == null) { - if(this.thePlayer != null) - this.thePlayer.setAngles(this.deltaX, this.deltaY); + if(this.player != null) + this.player.setAngles(this.deltaX, this.deltaY); this.deltaX = this.deltaY = 0.0f; } - if(this.thePlayer != null) - this.soundManager.setListener(this.thePlayer, (float)Timing.tick_fraction); - if(this.thePlayer != null && this.thePlayer.isEntityInsideOpaqueBlock()) + if(this.player != null) + this.soundManager.setListener(this.player, (float)Timing.tick_fraction); + if(this.player != null && this.player.isEntityInsideOpaqueBlock()) this.thirdPersonView = 0; GL11.glPushMatrix(); GL11.glClear(16640); GlState.enableTexture2D(); - if(this.theWorld != null) + if(this.world != null) this.entityRenderer.renderWorld((float)Timing.tick_fraction, System.nanoTime() - this.tickStart); GL11.glPopMatrix(); @@ -825,7 +826,7 @@ public class Client implements IThreadListener, IClient { public void renderHud() { this.setupOverlay(); - if(this.theWorld != null && this.open == null && this.thirdPersonView == 0 && this.viewEntity != null) { + if(this.world != null && this.open == null && this.thirdPersonView == 0 && this.viewEntity != null) { if(this.drawDebug) { this.renderWorldDirections((float)Timing.tick_fraction); } @@ -834,7 +835,7 @@ public class Client implements IThreadListener, IClient { Drawing.drawRect(this.fb_x / 2 - 16, this.fb_y / 2 - 1, 32, 2, this.pointed != null && this.pointed.type != ObjectType.MISS ? 0xffffffff : 0xffcfcfcf); } } - if(this.theWorld != null && this.open == null) { + if(this.world != null && this.open == null) { int selected = // this.getRenderViewEntity() != null && this.getRenderViewEntity().isPlayer() ? 9 : 0, this.getRenderViewEntity() != null && this.getRenderViewEntity().isPlayer() ? ((EntityNPC)this.getRenderViewEntity()).inventory.currentItem : -1; @@ -845,12 +846,12 @@ public class Client implements IThreadListener, IClient { Drawing.drawRectBorder(x - 1, y - 1, 36, 36, 0xff6f6f6f, selected == n ? 0xffffffff : 0xff000000, 0xffafafaf, 0xff4f4f4f); } - ItemStack itemstack = this.thePlayer != null ? this.thePlayer.inventory.getCurrentItem() : null; - String current = itemstack != null ? itemstack.getItem().getHotbarText(this.thePlayer, itemstack) : ""; + ItemStack itemstack = this.player != null ? this.player.inventory.getCurrentItem() : null; + String current = itemstack != null ? itemstack.getItem().getHotbarText(this.player, itemstack) : ""; if(!current.isEmpty()) Drawing.drawTextUpward(current, this.fb_x / 2, this.fb_y - 60, 0xffffffff); } - if(this.theWorld != null && !(this.open instanceof GuiConsole)) { + if(this.world != null && !(this.open instanceof GuiConsole)) { int x = this.fb_x / 2; int y = 0; Iterator> iter = this.bars.entrySet().iterator(); @@ -858,7 +859,7 @@ public class Client implements IThreadListener, IClient { while(iter.hasNext()) { Entry status = iter.next(); Entity ent; - if(this.thePlayer != null && now - status.getValue() < 10000L && (ent = this.thePlayer.worldObj.getEntityByID(status.getKey())) instanceof EntityLiving) { + if(this.player != null && now - status.getValue() < 10000L && (ent = this.player.worldObj.getEntityByID(status.getKey())) instanceof EntityLiving) { EntityLiving entity = (EntityLiving)ent; String s = entity.getName() + TextColor.GRAY + " [" + EntityLiving.getHealthColor(entity.getHealth(), entity.getMaxHealth()) + @@ -876,10 +877,10 @@ public class Client implements IThreadListener, IClient { } } - if(this.thePlayer != null && (!this.drawDebug || this.open != null)) { + if(this.player != null && (!this.drawDebug || this.open != null)) { x = 40; y = 40; - for(PotionEffect effect : this.thePlayer.getEffects()) { + for(PotionEffect effect : this.player.getEffects()) { Potion potion = effect.getPotion(); int color = potion.getColor(); String name = (potion.isBadEffect() ? TextColor.ORANGE : TextColor.ACID) + potion.getDisplay() + PotionHelper.getPotionPotency(effect.getAmplifier()); @@ -933,15 +934,15 @@ public class Client implements IThreadListener, IClient { } } - if(this.thePlayer != null) { + if(this.player != null) { x = 40; - y = this.fb_y - 40 - (this.thePlayer.isRidingHorse() && this.thePlayer.getHorseJumpPower() != 0.0f ? 2 : 1) * 40; - if(this.thePlayer.isRidingHorse() && this.thePlayer.getHorseJumpPower() != 0.0f) // { - y = bar(x, y, String.format(TextColor.NEON + "Sprungkraft: " + TextColor.CYAN + "%d %%", (int)(this.thePlayer.getHorseJumpPower() * 100.0f)), - this.thePlayer.getHorseJumpPower(), 0x4040ff); + y = this.fb_y - 40 - (this.player.isRidingHorse() && this.player.getHorseJumpPower() != 0.0f ? 2 : 1) * 40; + if(this.player.isRidingHorse() && this.player.getHorseJumpPower() != 0.0f) // { + y = bar(x, y, String.format(TextColor.NEON + "Sprungkraft: " + TextColor.CYAN + "%d %%", (int)(this.player.getHorseJumpPower() * 100.0f)), + this.player.getHorseJumpPower(), 0x4040ff); // } // else { - y = bar(x, y, String.format(TextColor.ACID + "EXP: " + TextColor.GREEN + "Level %d, %d/%d", this.thePlayer.experienceLevel, (int)((float)this.thePlayer.xpBarCap() * this.thePlayer.experience), this.thePlayer.xpBarCap()), this.thePlayer.experience, 0x40ff40); + y = bar(x, y, String.format(TextColor.ACID + "EXP: " + TextColor.GREEN + "Level %d, %d/%d", this.player.experienceLevel, (int)((float)this.player.xpBarCap() * this.player.experience), this.player.xpBarCap()), this.player.experience, 0x40ff40); // } } @@ -1012,7 +1013,7 @@ public class Client implements IThreadListener, IClient { } if(this.open != null) this.open.render(); - else if(this.theWorld == null || this.theWorld.hasNoChunks() || this.charEditor) + else if(this.world == null || this.world.hasNoChunks() || this.charEditor) Drawing.drawScaled(this, Gui.DIRT_BACKGROUND); if(Bind.INFO.isDown() && (this.open == null || !(this.open.selected instanceof Textbox))) this.drawInfo(); @@ -1111,8 +1112,8 @@ public class Client implements IThreadListener, IClient { } if(this.cameraUsed) { this.cameraUsed = false; - if(this.theWorld != null) - this.theWorld.setLastLightning(1, 0xffffff); + if(this.world != null) + this.world.setLastLightning(1, 0xffffff); } if(this.isDirty()) this.save(); @@ -1139,8 +1140,8 @@ public class Client implements IThreadListener, IClient { // } if(this.zooming) this.zoomLevel = ExtMath.clampf(this.zoomLevel + (dir < 0 ? -0.25f : 0.25f), 2.0f, 16.0f); - else if(this.thePlayer != null) - this.thePlayer.inventory.changeCurrentItem(dir); + else if(this.player != null) + this.player.inventory.changeCurrentItem(dir); } // public void resize(int width, int height) @@ -1179,8 +1180,8 @@ public class Client implements IThreadListener, IClient { { if(!this.refreshing) this.waitingForFile = false; - if(this.thePlayer != null) - this.thePlayer.setScreenClosed(); + if(this.player != null) + this.player.setScreenClosed(); if (this.open != null) { this.open.onGuiClosed(); @@ -1193,7 +1194,7 @@ public class Client implements IThreadListener, IClient { // guiScreenIn = new GuiMainMenu(); // } // else - if (gui == null && this.theWorld != null && this.thePlayer.getHealth() <= 0) + if (gui == null && this.world != null && this.player.getHealth() <= 0) { gui = GuiGameOver.INSTANCE; } @@ -1235,16 +1236,16 @@ public class Client implements IThreadListener, IClient { this.controller.resetInteraction(); } - if (this.leftClickCounter <= 0 && !this.thePlayer.isUsingItem()) + if (this.leftClickCounter <= 0 && !this.player.isUsingItem()) { if (leftClick && this.pointed != null && this.pointed.type == HitPosition.ObjectType.BLOCK) { BlockPos blockpos = this.pointed.block; - if (this.theWorld.getState(blockpos).getBlock().getMaterial() != Material.air && this.controller.onPlayerDamageBlock(blockpos, this.pointed.side)) + if (this.world.getState(blockpos).getBlock().getMaterial() != Material.air && this.controller.onPlayerDamageBlock(blockpos, this.pointed.side)) { this.effectRenderer.addBlockHitEffects(blockpos, this.pointed.side); - this.thePlayer.swingItem(); + this.player.swingItem(); } } else @@ -1260,17 +1261,17 @@ public class Client implements IThreadListener, IClient { { if (this.pointed == null) { - this.thePlayer.swingItem(); + this.player.swingItem(); Log.JNI.warn("Null zurückgegeben als 'hitResult', das sollte niemals passieren!"); this.leftClickCounter = 10; } else { - ItemStack itemstack = this.thePlayer.inventory.getCurrentItem(); - if ((this.pointed.type != ObjectType.BLOCK || this.theWorld.getState(this.pointed.block).getBlock().getMaterial() == Material.air) && itemstack != null && itemstack.getItem().onAction(itemstack, this.thePlayer, this.theWorld, ItemControl.PRIMARY, null)) + ItemStack itemstack = this.player.inventory.getCurrentItem(); + if ((this.pointed.type != ObjectType.BLOCK || this.world.getState(this.pointed.block).getBlock().getMaterial() == Material.air) && itemstack != null && itemstack.getItem().onAction(itemstack, this.player, this.world, ItemControl.PRIMARY, null)) { - this.thePlayer.swingItem(); - this.thePlayer.sendQueue.addToSendQueue(new CPacketAction(Action.ITEM_ACTION, ItemControl.PRIMARY.ordinal())); + this.player.swingItem(); + this.player.sendQueue.addToSendQueue(new CPacketAction(Action.ITEM_ACTION, ItemControl.PRIMARY.ordinal())); this.leftClickCounter = 10; return; } @@ -1278,13 +1279,13 @@ public class Client implements IThreadListener, IClient { switch (this.pointed.type) { case ENTITY: - this.thePlayer.swingItem(); - this.controller.attackEntity(this.thePlayer, this.pointed.entity); + this.player.swingItem(); + this.controller.attackEntity(this.player, this.pointed.entity); break; case BLOCK: - this.thePlayer.swingItem(); + this.player.swingItem(); BlockPos blockpos = this.pointed.block; - if (this.theWorld.getState(blockpos).getBlock().getMaterial() != Material.air) + if (this.world.getState(blockpos).getBlock().getMaterial() != Material.air) { this.controller.clickBlock(blockpos, this.pointed.side); break; @@ -1293,7 +1294,7 @@ public class Client implements IThreadListener, IClient { break; case MISS: default: - this.thePlayer.swingItem(); + this.player.swingItem(); this.leftClickCounter = 10; } } @@ -1306,7 +1307,7 @@ public class Client implements IThreadListener, IClient { { this.rightClickTimer = 4; boolean flag = true; - ItemStack itemstack = this.thePlayer.inventory.getCurrentItem(); + ItemStack itemstack = this.player.inventory.getCurrentItem(); if (itemstack != null && itemstack.getItem() == Items.camera && !this.saving) { @@ -1319,10 +1320,10 @@ public class Client implements IThreadListener, IClient { } else { - if ((this.pointed.type != ObjectType.BLOCK || this.theWorld.getState(this.pointed.block).getBlock().getMaterial() == Material.air) && itemstack != null && itemstack.getItem().onAction(itemstack, this.thePlayer, this.theWorld, ItemControl.SECONDARY, null)) + if ((this.pointed.type != ObjectType.BLOCK || this.world.getState(this.pointed.block).getBlock().getMaterial() == Material.air) && itemstack != null && itemstack.getItem().onAction(itemstack, this.player, this.world, ItemControl.SECONDARY, null)) { - this.thePlayer.swingItem(); - this.thePlayer.sendQueue.addToSendQueue(new CPacketAction(Action.ITEM_ACTION, ItemControl.SECONDARY.ordinal())); + this.player.swingItem(); + this.player.sendQueue.addToSendQueue(new CPacketAction(Action.ITEM_ACTION, ItemControl.SECONDARY.ordinal())); return; } @@ -1334,7 +1335,7 @@ public class Client implements IThreadListener, IClient { // flag = false; // } // else - if (this.controller.interactWithEntitySendPacket(this.thePlayer, this.pointed.entity)) + if (this.controller.interactWithEntitySendPacket(this.player, this.pointed.entity)) { flag = false; } @@ -1344,14 +1345,14 @@ public class Client implements IThreadListener, IClient { case BLOCK: BlockPos blockpos = this.pointed.block; - if (this.theWorld.getState(blockpos).getBlock().getMaterial() != Material.air) + if (this.world.getState(blockpos).getBlock().getMaterial() != Material.air) { int i = itemstack != null ? itemstack.stackSize : 0; - if (this.controller.onPlayerRightClick(this.thePlayer, this.theWorld, itemstack, blockpos, this.pointed.side, this.pointed.vec)) + if (this.controller.onPlayerRightClick(this.player, this.world, itemstack, blockpos, this.pointed.side, this.pointed.vec)) { flag = false; - this.thePlayer.swingItem(); + this.player.swingItem(); } if (itemstack == null) @@ -1361,7 +1362,7 @@ public class Client implements IThreadListener, IClient { if (itemstack.stackSize == 0) { - this.thePlayer.inventory.mainInventory[this.thePlayer.inventory.currentItem] = null; + this.player.inventory.mainInventory[this.player.inventory.currentItem] = null; } else if (itemstack.stackSize != i) // || this.controller.isCreative()) { @@ -1373,9 +1374,9 @@ public class Client implements IThreadListener, IClient { if (flag) { - ItemStack itemstack1 = this.thePlayer.inventory.getCurrentItem(); + ItemStack itemstack1 = this.player.inventory.getCurrentItem(); - if (itemstack1 != null && this.controller.sendUseItem(this.thePlayer, this.theWorld, itemstack1)) + if (itemstack1 != null && this.controller.sendUseItem(this.player, this.world, itemstack1)) { this.entityRenderer.itemRenderer.resetEquippedProgress2(); } @@ -1387,8 +1388,8 @@ public class Client implements IThreadListener, IClient { { if (this.pointed != null) { - if(this.thePlayer.getHeldItem() != null && this.thePlayer.getHeldItem().getItem().onAction(this.thePlayer.getHeldItem(), this.thePlayer, this.theWorld, ItemControl.TERTIARY, null)) { - this.thePlayer.sendQueue.addToSendQueue(new CPacketAction(Action.ITEM_ACTION, ItemControl.TERTIARY.ordinal())); + if(this.player.getHeldItem() != null && this.player.getHeldItem().getItem().onAction(this.player.getHeldItem(), this.player, this.world, ItemControl.TERTIARY, null)) { + this.player.sendQueue.addToSendQueue(new CPacketAction(Action.ITEM_ACTION, ItemControl.TERTIARY.ordinal())); return; } @@ -1402,14 +1403,14 @@ public class Client implements IThreadListener, IClient { if (this.pointed.type == HitPosition.ObjectType.BLOCK) { BlockPos blockpos = this.pointed.block; - Block block = this.theWorld.getState(blockpos).getBlock(); + Block block = this.world.getState(blockpos).getBlock(); if (block.getMaterial() == Material.air) { return; } - item = block.getItem(this.theWorld, blockpos); + item = block.getItem(this.world, blockpos); if (item == null) { @@ -1417,7 +1418,7 @@ public class Client implements IThreadListener, IClient { } Block block1 = item instanceof ItemBlock && !block.isPickStrict() ? item.getBlock() : block; - meta = block1.getDamageValue(this.theWorld, blockpos); + meta = block1.getDamageValue(this.world, blockpos); flag1 = item.getHasSubtypes(); } else @@ -1431,11 +1432,11 @@ public class Client implements IThreadListener, IClient { return; } - InventoryPlayer inventoryplayer = this.thePlayer.inventory; + InventoryPlayer inventoryplayer = this.player.inventory; inventoryplayer.setCurrentItem(item, meta, flag1); if(this.itemCheat) { - this.thePlayer.sendQueue.addToSendQueue(new CPacketCheat(new ItemStack(item, 1, meta), inventoryplayer.currentItem, this.ctrl())); + this.player.sendQueue.addToSendQueue(new CPacketCheat(new ItemStack(item, 1, meta), inventoryplayer.currentItem, this.ctrl())); } } } @@ -1444,8 +1445,8 @@ public class Client implements IThreadListener, IClient { { if (this.pointed != null) { - if(this.thePlayer.getHeldItem() != null && this.thePlayer.getHeldItem().getItem().onAction(this.thePlayer.getHeldItem(), this.thePlayer, this.theWorld, ItemControl.QUARTERNARY, null)) { - this.thePlayer.sendQueue.addToSendQueue(new CPacketAction(Action.ITEM_ACTION, ItemControl.QUARTERNARY.ordinal())); + if(this.player.getHeldItem() != null && this.player.getHeldItem().getItem().onAction(this.player.getHeldItem(), this.player, this.world, ItemControl.QUARTERNARY, null)) { + this.player.sendQueue.addToSendQueue(new CPacketAction(Action.ITEM_ACTION, ItemControl.QUARTERNARY.ordinal())); return; } } @@ -1465,7 +1466,7 @@ public class Client implements IThreadListener, IClient { this.viewEntity = null; this.connection = null; this.soundManager.stopSounds(); - this.theWorld = world; + this.world = world; if (this.renderGlobal != null) { @@ -1477,15 +1478,15 @@ public class Client implements IThreadListener, IClient { this.effectRenderer.clearEffects(world); } - if (this.thePlayer == null) + if (this.player == null) { - this.thePlayer = this.controller.createPlayerEntity(world, type); - this.thePlayer.rotYaw = -180.0F; + this.player = this.controller.createPlayerEntity(world, type); + this.player.rotYaw = -180.0F; } - this.thePlayer.preparePlayerToSpawn(); - world.spawnEntityInWorld(this.thePlayer); - this.viewEntity = this.thePlayer; + this.player.preparePlayerToSpawn(); + world.spawnEntityInWorld(this.player); + this.viewEntity = this.player; System.gc(); // SKC.loaded(true); @@ -1493,24 +1494,24 @@ public class Client implements IThreadListener, IClient { public void setDimensionAndSpawnPlayer(int dimension, int type) { - this.theWorld.removeAllEntities(); + this.world.removeAllEntities(); int i = 0; - if (this.thePlayer != null) + if (this.player != null) { - i = this.thePlayer.getId(); - this.theWorld.removeEntity(this.thePlayer); + i = this.player.getId(); + this.world.removeEntity(this.player); } this.viewEntity = null; - EntityNPC entityplayersp = this.thePlayer; - this.thePlayer = this.controller.createPlayerEntity(this.theWorld, type); - this.thePlayer.getDataWatcher().updateWatchedObjectsFromList(entityplayersp.getDataWatcher().getAllWatched()); - this.viewEntity = this.thePlayer; - this.thePlayer.preparePlayerToSpawn(); - this.theWorld.spawnEntityInWorld(this.thePlayer); - this.thePlayer.rotYaw = -180.0F; - this.thePlayer.setId(i); + EntityNPC entityplayersp = this.player; + this.player = this.controller.createPlayerEntity(this.world, type); + this.player.getDataWatcher().updateWatchedObjectsFromList(entityplayersp.getDataWatcher().getAllWatched()); + this.viewEntity = this.player; + this.player.preparePlayerToSpawn(); + this.world.spawnEntityInWorld(this.player); + this.player.rotYaw = -180.0F; + this.player.setId(i); // if (this.open instanceof GuiGameOver) // { @@ -1521,7 +1522,7 @@ public class Client implements IThreadListener, IClient { public ClientPlayer getNetHandler() { - return this.thePlayer != null ? (ClientPlayer)this.thePlayer.sendQueue : null; + return this.player != null ? (ClientPlayer)this.player.sendQueue : null; } // public void setSkin(BufferedImage skin, String id, ModelType model, boolean slim) @@ -1567,8 +1568,8 @@ public class Client implements IThreadListener, IClient { } public void performAction(Action action) { - if(this.thePlayer != null) - this.thePlayer.sendQueue.addToSendQueue(new CPacketAction(action)); + if(this.player != null) + this.player.sendQueue.addToSendQueue(new CPacketAction(action)); } public void setBossStatus(EntityLiving entity) { @@ -1708,7 +1709,7 @@ public class Client implements IThreadListener, IClient { String mem = String.format("JVM-Speicher: %d%% %d/%dMB", usedMem * 100L / maxMem, usedMem / 1024L / 1024L, maxMem / 1024L / 1024L) + "\n" + String.format("JVM-Reserviert: %d%% %dMB", totalMem * 100L / maxMem, totalMem / 1024L / 1024L); - if(this.theWorld == null) { + if(this.world == null) { return mem; } @@ -1736,27 +1737,27 @@ public class Client implements IThreadListener, IClient { Biome biome = null; String bline; String lline; - if(this.theWorld.isBlockLoaded(blockpos)) { - Chunk chunk = this.theWorld.getChunk(blockpos); + if(this.world.isBlockLoaded(blockpos)) { + Chunk chunk = this.world.getChunk(blockpos); biome = chunk.getBiome(blockpos, null); bline = "Biom: " + biome.display + " (" + biome.id + ")" + /* (this.debugHideInfo ? "" : */ (", D: " + - TextColor.stripCodes(this.theWorld.dimension.getFormattedName(false)) + - " (" + this.theWorld.dimension.getDimensionId() + ")"); + TextColor.stripCodes(this.world.dimension.getFormattedName(false)) + + " (" + this.world.dimension.getDimensionId() + ")"); lline = "Licht: " + chunk.getLightSub(blockpos, 0) + " (" + chunk.getLight(LightType.SKY, blockpos) + " Himmel, " + chunk.getLight(LightType.BLOCK, blockpos) + " Blöcke, " + String.format( - "%.1f", this.theWorld.getSunBrightness(1.0f) * 15.0f) + " Welt), A: " - + String.format("%.3f", this.theWorld.getCelestialAngle(1.0f)); + "%.1f", this.world.getSunBrightness(1.0f) * 15.0f) + " Welt), A: " + + String.format("%.3f", this.world.getCelestialAngle(1.0f)); } else { bline = "Biom: , D: " + - TextColor.stripCodes(this.theWorld.dimension.getFormattedName(false)) + - " (" + this.theWorld.dimension.getDimensionId() + ")"; + TextColor.stripCodes(this.world.dimension.getFormattedName(false)) + + " (" + this.world.dimension.getDimensionId() + ")"; lline = "Licht: " + String.format( - "%.1f", this.theWorld.getSunBrightness(1.0f) * 15.0f) + " Welt, A: " - + String.format("%.3f", this.theWorld.getCelestialAngle(1.0f)); + "%.1f", this.world.getSunBrightness(1.0f) * 15.0f) + " Welt, A: " + + String.format("%.3f", this.world.getCelestialAngle(1.0f)); } - float temp = this.theWorld.getTempOffset() + (biome != null ? biome.getTemperature(blockpos) : 0.0f); + float temp = this.world.getTempOffset() + (biome != null ? biome.getTemperature(blockpos) : 0.0f); long ticked = System.currentTimeMillis() - this.lastTicked; return @@ -1767,8 +1768,8 @@ public class Client implements IThreadListener, IClient { // this.connected != null ? this.connected : "[???]"))), this.renderGlobal.getDebugInfoRenders() + "\n" + this.renderGlobal.getDebugInfoEntities() + "\n" + - "Partikel: " + this.effectRenderer.getStatistics() + ". O: " + this.theWorld.getDebugLoadedEntities() + "\n" + - this.theWorld.getInfo() + "\n" + + "Partikel: " + this.effectRenderer.getStatistics() + ". O: " + this.world.getDebugLoadedEntities() + "\n" + + this.world.getInfo() + "\n" + // "", String.format("XYZ: %.3f / %.3f / %.3f", this.viewEntity.posX, this.viewEntity.getEntityBoundingBox().minY, this.viewEntity.posZ) + "\n" + @@ -1784,21 +1785,21 @@ public class Client implements IThreadListener, IClient { bline + "\n" + lline + "\n" + String.format("Zeit: %d T, R %d / %d T, U %d / %d T", - this.theWorld.getDayTime(), - this.theWorld.getDayTime() % this.theWorld.dimension.getRotationalPeriod(), - this.theWorld.dimension.getRotationalPeriod(), - this.theWorld.getDayTime() % this.theWorld.dimension.getOrbitalPeriod(), - this.theWorld.dimension.getOrbitalPeriod() + this.world.getDayTime(), + this.world.getDayTime() % this.world.dimension.getRotationalPeriod(), + this.world.dimension.getRotationalPeriod(), + this.world.getDayTime() % this.world.dimension.getOrbitalPeriod(), + this.world.dimension.getOrbitalPeriod() ) + "\n" + String.format("Laub: %s%s, T: %.2f K / %.2f °C, %s (R %.1f, %.1f)", - !this.theWorld.dimension.getType().days ? "*" : "", - this.theWorld.getLeavesGen(blockpos).getDisplayName(), + !this.world.dimension.getType().days ? "*" : "", + this.world.getLeavesGen(blockpos).getDisplayName(), temp, World.ABSOLUTE_ZERO + temp, - this.theWorld.getWeather().getDisplay(), this.theWorld.getRainStrength(), - this.theWorld.getDarkness() + this.world.getWeather().getDisplay(), this.world.getRainStrength(), + this.world.getDarkness() ) + "\n" + String.format("Zeitfaktor: %dx, Schwerkraft: %.2f m/s²", - this.timeFactor, this.theWorld.gravity * 10.0 + this.timeFactor, this.world.gravity * 10.0 ) + "\n" + String.format("Letzte Zeitsynch.: + %d.%d s", ticked / 1000L, (ticked / 100L) % 10L @@ -1811,17 +1812,17 @@ public class Client implements IThreadListener, IClient { } public String getRight(boolean showPlayerInfo) { - if(this.theWorld == null) { + if(this.world == null) { return null; } if(!showPlayerInfo && this.pointed != null && this.pointed.type == HitPosition.ObjectType.BLOCK && this.pointed.block != null) { BlockPos pos = this.pointed.block; - State block = this.theWorld.getState(pos); + State block = this.world.getState(pos); if(!this.debugWorld) { - block = block.getBlock().getActualState(block, this.theWorld, pos); + block = block.getBlock().getActualState(block, this.world, pos); } StringBuilder str = new StringBuilder( @@ -1841,7 +1842,7 @@ public class Client implements IThreadListener, IClient { } else if((this.pointed != null && this.pointed.type == HitPosition.ObjectType.ENTITY && this.pointed.entity != null) || showPlayerInfo) { - Entity entity = showPlayerInfo ? this.thePlayer : this.pointed.entity; + Entity entity = showPlayerInfo ? this.player : this.pointed.entity; ItemStack held = entity instanceof EntityLiving && ((EntityLiving)entity).getHeldItem() != null ? ((EntityLiving)entity).getHeldItem() : null; return @@ -2260,24 +2261,24 @@ public class Client implements IThreadListener, IClient { // if(this.theWorld != null && this.open == null && Bind.COMMAND.isPressed()) { // this.displayGuiScreen(GuiChat.INSTANCE); // } - if(this.theWorld != null && Bind.MENU.isPressed()) { + if(this.world != null && Bind.MENU.isPressed()) { if(this.open != (this.charEditor ? GuiChar.INSTANCE : null)) this.displayGuiScreen(this.charEditor ? GuiChar.INSTANCE : null); else this.displayGuiScreen(GuiMenu.INSTANCE); } - else if(this.theWorld == null && !(this.open instanceof GuiMenu) && Bind.MENU.isPressed()) { + else if(this.world == null && !(this.open instanceof GuiMenu) && Bind.MENU.isPressed()) { this.displayGuiScreen(GuiMenu.INSTANCE); } - if(this.theWorld != null && !this.charEditor && Bind.INVENTORY.isPressed()) { + if(this.world != null && !this.charEditor && Bind.INVENTORY.isPressed()) { if(this.open instanceof GuiContainer) { this.displayGuiScreen(null); } else if(this.open == null) { - if(this.thePlayer.isRiding() && this.thePlayer.vehicle instanceof EntityHorse) - this.thePlayer.sendHorseInventory(); + if(this.player.isRiding() && this.player.vehicle instanceof EntityHorse) + this.player.sendHorseInventory(); else - this.displayGuiScreen(/* this.itemCheat ? new GuiCheat() : */ new GuiInventory(this.thePlayer)); + this.displayGuiScreen(/* this.itemCheat ? new GuiCheat() : */ new GuiInventory(this.player)); } } } @@ -2392,7 +2393,7 @@ public class Client implements IThreadListener, IClient { } public void unload(boolean loading) { - if(this.theWorld != null) { + if(this.world != null) { if(this.getNetHandler() != null) this.getNetHandler().getNetworkManager().closeChannel("Quitting"); this.unloadWorld(); @@ -2904,7 +2905,7 @@ public class Client implements IThreadListener, IClient { return; } } - if(this.thePlayer != null && this.getNetHandler() != null) + if(this.player != null && this.getNetHandler() != null) this.getNetHandler().addToSendQueue(new CPacketMessage(line.startsWith("/") ? CPacketMessage.Type.COMMAND : CPacketMessage.Type.CHAT, line.startsWith("/") ? line.substring(1) : line)); // Log.CONSOLE.user("%s", line); // this.command(line); @@ -3214,8 +3215,11 @@ public class Client implements IThreadListener, IClient { this.waitingForFile = true; new Thread(new Runnable() { public void run() { - String output; + String output = null; + JFileChooser chooser = null; try { + if(Util.WINDOWS) + throw new RuntimeException("Windows wird von Zenity nicht unterstützt"); List list = Lists.newArrayList("zenity", "--file-selection"); switch(mode) { case DIRECTORY_SAVE: @@ -3249,21 +3253,40 @@ public class Client implements IThreadListener, IClient { } } catch(Throwable e) { - Log.SYSTEM.error(e, "Konnte Zenity nicht starten"); - Client.this.logFeed(TextColor.RED + "Konnte Dateibrowser nicht öffnen"); - Client.this.waitingForFile = false; - return; + Log.SYSTEM.error(e, "Konnte Dateibrowser nicht starten"); + chooser = new JFileChooser(def.isDirectory() ? def : def.getParentFile()); + chooser.setDialogTitle(title); + chooser.setMultiSelectionEnabled(mode == FileMode.FILE_LOAD_MULTI); + chooser.setFileSelectionMode(mode == FileMode.DIRECTORY_LOAD || mode == FileMode.DIRECTORY_SAVE ? JFileChooser.DIRECTORIES_ONLY : JFileChooser.FILES_ONLY); + int result; + if(mode == FileMode.FILE_SAVE || mode == FileMode.DIRECTORY_SAVE) + result = chooser.showSaveDialog(null); + else + result = chooser.showOpenDialog(null); + if(result != JFileChooser.APPROVE_OPTION) { +// Client.this.logFeed(TextColor.RED + "Konnte Dateibrowser nicht öffnen"); + Client.this.waitingForFile = false; + return; + } } - if(output == null) { + if(output == null && chooser == null) { Client.this.waitingForFile = false; return; } if(mode == FileMode.FILE_LOAD_MULTI) { final List files = Lists.newArrayList(); - for(String out : output.split(":")) { - File file = new File(out); - if(file.isFile()) - files.add(file); + if(chooser != null) { + for(File file : chooser.getSelectedFiles()) { + if(file.isFile()) + files.add(file); + } + } + else { + for(String out : output.split(":")) { + File file = new File(out); + if(file.isFile()) + files.add(file); + } } if(files.isEmpty()) { Client.this.waitingForFile = false; @@ -3281,7 +3304,7 @@ public class Client implements IThreadListener, IClient { }); } else { - File file = new File(output); + File file = chooser != null ? chooser.getSelectedFile() : new File(output); switch(mode) { case DIRECTORY_LOAD: if(!file.isDirectory()) { @@ -3317,12 +3340,12 @@ public class Client implements IThreadListener, IClient { }); } } - }, "Zenity listener").start(); + }, "File Browser listener").start(); } public void makeFireworks(double x, double y, double z, double motionX, double motionY, double motionZ, NBTTagCompound compund) { - this.effectRenderer.addEffect(new EntityFirework.StarterFX(this.theWorld, x, y, z, motionX, motionY, motionZ, this.effectRenderer, compund)); + this.effectRenderer.addEffect(new EntityFirework.StarterFX(this.world, x, y, z, motionX, motionY, motionZ, this.effectRenderer, compund)); } public int getRenderDistance() { @@ -3346,7 +3369,7 @@ public class Client implements IThreadListener, IClient { } public EntityNPC getPlayer() { - return this.thePlayer; + return this.player; } public IEntityFX spawnEffectParticle(int particleId, double xCoord, double yCoord, double zCoord, double xSpeed, double ySpeed, double zSpeed, diff --git a/client/src/client/PlayerController.java b/client/src/client/PlayerController.java index a638839..80017d3 100755 --- a/client/src/client/PlayerController.java +++ b/client/src/client/PlayerController.java @@ -113,7 +113,7 @@ public class PlayerController // } // else // { - World world = this.gm.theWorld; + World world = this.gm.world; State iblockstate = world.getState(pos); Block block1 = iblockstate.getBlock(); @@ -135,15 +135,15 @@ public class PlayerController // if (!this.creative) // { - ItemStack itemstack1 = this.gm.thePlayer.getCurrentEquippedItem(); + ItemStack itemstack1 = this.gm.player.getCurrentEquippedItem(); if (itemstack1 != null) { - itemstack1.onBlockDestroyed(world, block1, pos, this.gm.thePlayer); + itemstack1.onBlockDestroyed(world, block1, pos, this.gm.player); if (itemstack1.stackSize == 0) { - this.gm.thePlayer.destroyCurrentEquippedItem(); + this.gm.player.destroyCurrentEquippedItem(); } } // } @@ -188,8 +188,8 @@ public class PlayerController } else { - ItemStack stack = this.gm.thePlayer.getHeldItem(); - if(stack != null && stack.getItem().onAction(stack, this.gm.thePlayer, this.gm.theWorld, ItemControl.PRIMARY, loc)) { + ItemStack stack = this.gm.player.getHeldItem(); + if(stack != null && stack.getItem().onAction(stack, this.gm.player, this.gm.world, ItemControl.PRIMARY, loc)) { this.interacting = true; this.netClientHandler.addToSendQueue(new CPacketBreak(CPacketBreak.Action.START_DESTROY_BLOCK, loc, face)); return true; @@ -209,15 +209,15 @@ public class PlayerController } this.netClientHandler.addToSendQueue(new CPacketBreak(CPacketBreak.Action.START_DESTROY_BLOCK, loc, face)); - Block block1 = this.gm.theWorld.getState(loc).getBlock(); + Block block1 = this.gm.world.getState(loc).getBlock(); boolean flag = block1.getMaterial() != Material.air; if (flag && this.curBlockDamageMP == 0.0F) { - block1.onBlockClicked(this.gm.theWorld, loc, this.gm.thePlayer); + block1.onBlockClicked(this.gm.world, loc, this.gm.player); } - if (flag && block1.getPlayerRelativeBlockHardness(this.gm.thePlayer, this.gm.thePlayer.worldObj, loc) >= 1.0F) + if (flag && block1.getPlayerRelativeBlockHardness(this.gm.player, this.gm.player.worldObj, loc) >= 1.0F) { this.onPlayerDestroyBlock(loc, face); // if(this.cheat && block1.getPlayerRelativeBlockHardness(this.gm.thePlayer, this.gm.thePlayer.worldObj, loc) < 1.0F) @@ -227,10 +227,10 @@ public class PlayerController { this.isHittingBlock = true; this.currentBlock = loc; - this.currentItemHittingBlock = this.gm.thePlayer.getHeldItem(); + this.currentItemHittingBlock = this.gm.player.getHeldItem(); this.curBlockDamageMP = 0.0F; this.stepSoundTickCounter = 0.0F; - this.gm.theWorld.sendBlockBreakProgress(this.gm.thePlayer.getId(), this.currentBlock, (int)(this.curBlockDamageMP * 10.0F) - 1); + this.gm.world.sendBlockBreakProgress(this.gm.player.getId(), this.currentBlock, (int)(this.curBlockDamageMP * 10.0F) - 1); } } @@ -248,7 +248,7 @@ public class PlayerController this.netClientHandler.addToSendQueue(new CPacketBreak(CPacketBreak.Action.ABORT_DESTROY_BLOCK, this.currentBlock, Facing.DOWN)); this.isHittingBlock = false; this.curBlockDamageMP = 0.0F; - this.gm.theWorld.sendBlockBreakProgress(this.gm.thePlayer.getId(), this.currentBlock, -1); + this.gm.world.sendBlockBreakProgress(this.gm.player.getId(), this.currentBlock, -1); } } @@ -277,7 +277,7 @@ public class PlayerController // } else if (this.isHittingPosition(posBlock)) { - Block block = this.gm.theWorld.getState(posBlock).getBlock(); + Block block = this.gm.world.getState(posBlock).getBlock(); if (block.getMaterial() == Material.air) { @@ -286,7 +286,7 @@ public class PlayerController } else { - this.curBlockDamageMP += block.getPlayerRelativeBlockHardness(this.gm.thePlayer, this.gm.thePlayer.worldObj, posBlock); + this.curBlockDamageMP += block.getPlayerRelativeBlockHardness(this.gm.player, this.gm.player.worldObj, posBlock); if (this.stepSoundTickCounter % 4.0F == 0.0F && block.sound.getStepSound() != null) { @@ -305,7 +305,7 @@ public class PlayerController this.blockHitDelay = 5; } - this.gm.theWorld.sendBlockBreakProgress(this.gm.thePlayer.getId(), this.currentBlock, (int)(this.curBlockDamageMP * 10.0F) - 1); + this.gm.world.sendBlockBreakProgress(this.gm.player.getId(), this.currentBlock, (int)(this.curBlockDamageMP * 10.0F) - 1); return true; } } @@ -339,7 +339,7 @@ public class PlayerController private boolean isHittingPosition(BlockPos pos) { - ItemStack itemstack = this.gm.thePlayer.getHeldItem(); + ItemStack itemstack = this.gm.player.getHeldItem(); boolean flag = this.currentItemHittingBlock == null && itemstack == null; if (this.currentItemHittingBlock != null && itemstack != null) @@ -355,7 +355,7 @@ public class PlayerController */ private void syncCurrentPlayItem() { - int i = this.gm.thePlayer.inventory.currentItem; + int i = this.gm.player.inventory.currentItem; if (i != this.currentPlayerItem) { diff --git a/client/src/client/gui/Gui.java b/client/src/client/gui/Gui.java index bad7a40..73628a8 100644 --- a/client/src/client/gui/Gui.java +++ b/client/src/client/gui/Gui.java @@ -301,7 +301,7 @@ public abstract class Gui { // } public void drawMainBackground() { - if(this.gm.theWorld != null && !this.gm.charEditor) { + if(this.gm.world != null && !this.gm.charEditor) { // Drawing.drawGradient(0, 0, this.fb_x, this.fb_y, this.theWorld == null ? this.style.bg_top : 0x3f202020, // this.theWorld == null ? this.style.bg_btm : 0x3f000000); Drawing.drawGradient(0, 0, this.gm.fb_x, this.gm.fb_y, 0xc0101010, 0xd0101010); diff --git a/client/src/client/gui/GuiConfirm.java b/client/src/client/gui/GuiConfirm.java index 5a4a907..fb9b117 100755 --- a/client/src/client/gui/GuiConfirm.java +++ b/client/src/client/gui/GuiConfirm.java @@ -28,7 +28,7 @@ public class GuiConfirm extends Gui implements ActButton.Callback { public void init(int width, int height) { this.add(new Label(0, 0, 500, 24, this.messageLine1, true)); - this.add(new TransparentBox(0, 80, 500, 300, this.messageLine2, this.gm.theWorld != null && !this.gm.charEditor)); + this.add(new TransparentBox(0, 80, 500, 300, this.messageLine2, this.gm.world != null && !this.gm.charEditor)); this.confirmBtn = this.add(new ActButton(48, 500, 200, 24, this, this.confirmButtonText)); this.cancelBtn = this.add(new ActButton(252, 500, 200, 24, this, this.cancelButtonText)); this.shift(); diff --git a/client/src/client/gui/GuiConsole.java b/client/src/client/gui/GuiConsole.java index 4ff2c19..3ea6d44 100644 --- a/client/src/client/gui/GuiConsole.java +++ b/client/src/client/gui/GuiConsole.java @@ -55,7 +55,7 @@ public class GuiConsole extends Gui implements Textbox.Callback { } }, "Löschen")); } - this.logBox = this.add(new TransparentBox(0, this.full ? 24 : 0, width, height - (this.full ? 48 : 24), this.gm.getBuffer(), this.gm.theWorld != null && !this.gm.charEditor)); + this.logBox = this.add(new TransparentBox(0, this.full ? 24 : 0, width, height - (this.full ? 48 : 24), this.gm.getBuffer(), this.gm.world != null && !this.gm.charEditor)); if(this.full) this.add(new Fill(640, 0, width - 640, 24)); this.inputField = this.add(new Textbox(0, height - 24, width, 24, IPlayer.MAX_CMD_LENGTH, true, this, "")); @@ -79,7 +79,7 @@ public class GuiConsole extends Gui implements Textbox.Callback { } public void drawMainBackground() { - if(this.gm.theWorld == null || this.gm.charEditor) + if(this.gm.world == null || this.gm.charEditor) super.drawMainBackground(); } @@ -123,7 +123,7 @@ public class GuiConsole extends Gui implements Textbox.Callback { } this.inputField.setText(""); - if((this.gm.conAutoclose || !this.full) && this.gm.theWorld != null) + if((this.gm.conAutoclose || !this.full) && this.gm.world != null) this.gm.displayGuiScreen(null); } } @@ -215,7 +215,7 @@ public class GuiConsole extends Gui implements Textbox.Callback { s = argv[argv.length - 1]; Iterable res = pre.startsWith("#") ? (argv.length == 1 ? this.gm.getVars() : (argv.length == 2 ? getVarCompletion(argv[0].substring(1)) : Lists.newArrayList())) : - (this.gm.thePlayer == null ? Lists.newArrayList() : ((ClientPlayer)this.gm.thePlayer.sendQueue).getPlayerNames()); + (this.gm.player == null ? Lists.newArrayList() : ((ClientPlayer)this.gm.player.sendQueue).getPlayerNames()); if(argv.length == 1 && pre.startsWith("#")) s = s.substring(1); for(String s1 : res) { @@ -252,10 +252,10 @@ public class GuiConsole extends Gui implements Textbox.Callback { blockpos = new BlockPos(this.gm.pointed.entity); } if(currentText.startsWith("/")) { - if(this.gm.thePlayer != null) { + if(this.gm.player != null) { currentText = currentText.substring(1); this.prefixFirst = currentText.split(" ", -1).length == 1 ? "/" : null; - this.gm.thePlayer.sendQueue.addToSendQueue(new CPacketComplete(currentText, eid, blockpos)); + this.gm.player.sendQueue.addToSendQueue(new CPacketComplete(currentText, eid, blockpos)); this.waitingOnAutocomplete = true; } } diff --git a/client/src/client/gui/GuiInfo.java b/client/src/client/gui/GuiInfo.java index eadf6dd..9b18880 100644 --- a/client/src/client/gui/GuiInfo.java +++ b/client/src/client/gui/GuiInfo.java @@ -125,7 +125,7 @@ public class GuiInfo extends Gui { } public void init(int width, int height) { - this.add(new TransparentBox(10, 10, width - 20, height - 44, this.info, this.gm.theWorld != null && !this.gm.charEditor)); + this.add(new TransparentBox(10, 10, width - 20, height - 44, this.info, this.gm.world != null && !this.gm.charEditor)); this.add(new NavButton(0, height - 24, width, 24, GuiMenu.INSTANCE, "Zurück")); } diff --git a/client/src/client/gui/GuiMenu.java b/client/src/client/gui/GuiMenu.java index d1f0062..54cbb34 100644 --- a/client/src/client/gui/GuiMenu.java +++ b/client/src/client/gui/GuiMenu.java @@ -23,7 +23,7 @@ public class GuiMenu extends Gui { } public void drawMainBackground() { - if(this.gm.theWorld != null) + if(this.gm.world != null) super.drawMainBackground(); else this.gm.renderGlobal.renderStarField(this.gm.fb_x, this.gm.fb_y, 0x000000, 0xffffff, (float)this.ticks + (float)Timing.tick_fraction, this.rand); @@ -48,7 +48,7 @@ public class GuiMenu extends Gui { private boolean animStep; public void init(int width, int height) { - if(this.gm.theWorld == null) { + if(this.gm.world == null) { this.ticks = 0; this.hacked = 0; this.resetAnimation(); @@ -120,7 +120,7 @@ public class GuiMenu extends Gui { } public String getTitle() { - return this.gm.theWorld == null ? "Hauptmenü" : "Menü"; + return this.gm.world == null ? "Hauptmenü" : "Menü"; } private void pickSplash() { @@ -223,7 +223,7 @@ public class GuiMenu extends Gui { } public void updateScreen() { - if(this.gm.theWorld == null) { + if(this.gm.world == null) { this.ticks++; if(this.gm.shift() && !(this.selected instanceof Textbox)) this.pickSplash(); @@ -233,7 +233,7 @@ public class GuiMenu extends Gui { public void key(Keysym key, boolean ctrl, boolean shift) { super.key(key, ctrl, shift); - if(this.gm.theWorld == null) { + if(this.gm.world == null) { if((key == Keysym.UP || key == Keysym.W) && (this.hacked == 0 || this.hacked == 1)) this.hacked++; else if((key == Keysym.DOWN || key == Keysym.S) && (this.hacked == 2 || this.hacked == 3)) @@ -287,7 +287,7 @@ public class GuiMenu extends Gui { public void drawOverlays() { super.drawOverlays(); - if(this.gm.theWorld == null) { + if(this.gm.world == null) { int y = 164; int h = 16; int n = Drawing.getWidth(this.splashLabel.getText()); diff --git a/client/src/client/gui/GuiServer.java b/client/src/client/gui/GuiServer.java index ca80fa0..42dcdeb 100644 --- a/client/src/client/gui/GuiServer.java +++ b/client/src/client/gui/GuiServer.java @@ -74,7 +74,7 @@ public class GuiServer extends Gui implements Textbox.Callback { } private void connect() { - if(this.gm.theWorld != null) + if(this.gm.world != null) return; String name = null; if(this.server != null) { diff --git a/client/src/client/gui/character/GuiChar.java b/client/src/client/gui/character/GuiChar.java index 76daeb4..540c209 100755 --- a/client/src/client/gui/character/GuiChar.java +++ b/client/src/client/gui/character/GuiChar.java @@ -129,7 +129,7 @@ public class GuiChar extends GuiList EntityTexManager.altLayer = this.dynId; EntityTexManager.altNpcLayer = this.dynId == -1 && this.charinfo != null ? this.charinfo.skin : null; drawEntity(x + 32, y + 60, 28.0f - * Math.min(1.8f / GuiChar.this.gm.thePlayer.height, 1.5f / GuiChar.this.gm.thePlayer.width), -45.0f, -20.0f, GuiChar.this.gm.thePlayer); + * Math.min(1.8f / GuiChar.this.gm.player.height, 1.5f / GuiChar.this.gm.player.width), -45.0f, -20.0f, GuiChar.this.gm.player); GuiChar.this.gm.cameraUsed = flag; EntityTexManager.altTexture = null; EntityTexManager.altLayer = -1; @@ -271,8 +271,8 @@ public class GuiChar extends GuiList this.adjust = null; return; } - this.currentSkin = this.gm.thePlayer != null && !EntityTexManager.hasCustomSkin(this.gm.thePlayer.getId()) ? this.gm.thePlayer.getChar() : null; - this.load(this.gm.thePlayer == null ? ModelType.HUMANOID : this.gm.thePlayer.getModel(), this.gm.thePlayer != null ? this.gm.thePlayer.getSpecies() : SpeciesRegistry.CLASSES.get(EntityHuman.class)); + this.currentSkin = this.gm.player != null && !EntityTexManager.hasCustomSkin(this.gm.player.getId()) ? this.gm.player.getChar() : null; + this.load(this.gm.player == null ? ModelType.HUMANOID : this.gm.player.getModel(), this.gm.player != null ? this.gm.player.getSpecies() : SpeciesRegistry.CLASSES.get(EntityHuman.class)); this.add(new ActButton(4, 4, 194, 24, new ActButton.Callback() { public void use(ActButton elem, Mode action) { GuiChar.this.gm.showFileDialog(FileMode.FILE_LOAD_MULTI, "Skin konvertieren", TEXTURE_FOLDER, new FileCallback() { @@ -335,12 +335,12 @@ public class GuiChar extends GuiList }, "Vorlage kopieren")); this.adjust = this.add(new DragAdjust(width / 2 - 230, height - 64 - 640, 460, 640)); - this.add(new Label(width - 396, 36, 392, 20, "Spezies: " + (this.gm.thePlayer == null ? "" : this.gm.thePlayer.getSpecies().name), true)); + this.add(new Label(width - 396, 36, 392, 20, "Spezies: " + (this.gm.player == null ? "" : this.gm.player.getSpecies().name), true)); this.add(new NavButton(width - 396, 56, 392, 24, GuiSpecies.INSTANCE, "Spezies ändern")); - this.add(new Label(width - 396, 36 + 92, 392, 20, "Klasse: " + (this.gm.thePlayer == null || this.gm.thePlayer.getSpecies().classEnum == null || this.gm.thePlayer.getNpcClass() == null || this.gm.thePlayer.getNpcClass().toString().isEmpty() ? "" : this.gm.thePlayer.getNpcClass().toString()), true)) - .enabled = this.gm.thePlayer != null && this.gm.thePlayer.getSpecies().classEnum != null; + this.add(new Label(width - 396, 36 + 92, 392, 20, "Klasse: " + (this.gm.player == null || this.gm.player.getSpecies().classEnum == null || this.gm.player.getNpcClass() == null || this.gm.player.getNpcClass().toString().isEmpty() ? "" : this.gm.player.getNpcClass().toString()), true)) + .enabled = this.gm.player != null && this.gm.player.getSpecies().classEnum != null; this.add(new NavButton(width - 396, 56 + 92, 392, 24, GuiClass.INSTANCE, "Klasse ändern")) - .enabled = this.gm.thePlayer != null && this.gm.thePlayer.getSpecies().classEnum != null; + .enabled = this.gm.player != null && this.gm.player.getSpecies().classEnum != null; final ActButton[] alignBtns = new ActButton[Alignment.values().length]; for (int z = 0; z < Alignment.values().length; z++) @@ -348,25 +348,25 @@ public class GuiChar extends GuiList final Alignment align = Alignment.values()[z]; alignBtns[z] = this.add(new ActButton(width - 396 + (z % 3) * 132, height - 32 - 28 * 3 + 28 * (z / 3), 128, 24, new ActButton.Callback() { public void use(ActButton elem, Mode action) { - if(GuiChar.this.gm.thePlayer != null) { + if(GuiChar.this.gm.player != null) { GuiChar.this.waiting = false; - GuiChar.this.gm.thePlayer.sendQueue.addToSendQueue(new CPacketAction(CPacketAction.Action.SET_ALIGN, align.ordinal())); + GuiChar.this.gm.player.sendQueue.addToSendQueue(new CPacketAction(CPacketAction.Action.SET_ALIGN, align.ordinal())); for(ActButton btn : alignBtns) { btn.enabled = btn != elem; } } } }, align.color + align.display)); - alignBtns[z].enabled = this.gm.thePlayer == null || this.gm.thePlayer.getAlignment() != align; + alignBtns[z].enabled = this.gm.player == null || this.gm.player.getAlignment() != align; } - this.add(new Slider(width / 2 - 200, height - 28, 400, 24, 1, this.gm.thePlayer == null ? 120 : this.gm.thePlayer.getMinSize(), this.gm.thePlayer == null ? 320 : this.gm.thePlayer.getMaxSize(), this.gm.thePlayer == null ? 180 : this.gm.thePlayer.getDefaultSize(), this.gm.thePlayer == null ? 180 : this.gm.thePlayer.getCurrentSize(), new Slider.Callback() { + this.add(new Slider(width / 2 - 200, height - 28, 400, 24, 1, this.gm.player == null ? 120 : this.gm.player.getMinSize(), this.gm.player == null ? 320 : this.gm.player.getMaxSize(), this.gm.player == null ? 180 : this.gm.player.getDefaultSize(), this.gm.player == null ? 180 : this.gm.player.getCurrentSize(), new Slider.Callback() { public void use(Slider elem, int value) { - if(GuiChar.this.gm.thePlayer != null) { + if(GuiChar.this.gm.player != null) { GuiChar.this.waiting = false; - GuiChar.this.gm.thePlayer.sendQueue.addToSendQueue(new CPacketAction(CPacketAction.Action.SET_HEIGHT, value)); + GuiChar.this.gm.player.sendQueue.addToSendQueue(new CPacketAction(CPacketAction.Action.SET_HEIGHT, value)); } } - }, "Spieler-Größe", "cm")).enabled = this.gm.thePlayer == null || this.gm.thePlayer.getMinSize() != this.gm.thePlayer.getMaxSize(); + }, "Spieler-Größe", "cm")).enabled = this.gm.player == null || this.gm.player.getMinSize() != this.gm.player.getMaxSize(); this.add(new Label(width / 2 - 200, 36, 400, 20, "Name", true)); this.add(new Label(width - 396, height - 384, 392, 20, "Beschreibung", true)); final Textbox descField = this.add(new Textbox(width - 396, height - 364, 392, 130, IPlayer.MAX_INFO_LENGTH, new Textbox.Callback() { @@ -375,11 +375,11 @@ public class GuiChar extends GuiList }, "")); this.add(new ActButton(width - 198, height - 28, 194, 24, new ActButton.Callback() { public void use(ActButton elem, Mode action) { - if(GuiChar.this.gm.thePlayer != null) { + if(GuiChar.this.gm.player != null) { GuiChar.this.gm.displayGuiScreen(GuiLoading.makeWaitTask("Lade Welt ...")); Dimension dim = UniverseRegistry.getBaseDimensions().get(GuiChar.this.dimension); - GuiChar.this.gm.thePlayer.sendQueue.addToSendQueue(new CPacketMessage(CPacketMessage.Type.INFO, descField.getText())); - GuiChar.this.gm.thePlayer.sendQueue.addToSendQueue(new CPacketAction(CPacketAction.Action.CLOSE_EDITOR, dim.getDimensionId())); + GuiChar.this.gm.player.sendQueue.addToSendQueue(new CPacketMessage(CPacketMessage.Type.INFO, descField.getText())); + GuiChar.this.gm.player.sendQueue.addToSendQueue(new CPacketAction(CPacketAction.Action.CLOSE_EDITOR, dim.getDimensionId())); } } }, "Charakter erstellen")); @@ -388,17 +388,17 @@ public class GuiChar extends GuiList if(value == Action.SEND || value == Action.UNFOCUS) { String name = elem.getText(); if(name.isEmpty()) - elem.setText(GuiChar.this.gm.thePlayer == null ? "..." : GuiChar.this.gm.thePlayer.getCustomNameTag()); - else if(GuiChar.this.gm.thePlayer != null) { + elem.setText(GuiChar.this.gm.player == null ? "..." : GuiChar.this.gm.player.getCustomNameTag()); + else if(GuiChar.this.gm.player != null) { GuiChar.this.waiting = false; - GuiChar.this.gm.thePlayer.sendQueue.addToSendQueue(new CPacketMessage(CPacketMessage.Type.DISPLAY, name)); + GuiChar.this.gm.player.sendQueue.addToSendQueue(new CPacketMessage(CPacketMessage.Type.DISPLAY, name)); } } } - }, IPlayer.VALID_NICK, this.gm.thePlayer == null ? "" : this.gm.thePlayer.getCustomNameTag())); + }, IPlayer.VALID_NICK, this.gm.player == null ? "" : this.gm.player.getCustomNameTag())); this.templateButton.enabled = false; this.dimension = new Random().zrange(UniverseRegistry.getBaseDimensions().size()); - EntityEggInfo egg = EntityRegistry.SPAWN_EGGS.get(this.gm.thePlayer == null ? EntityRegistry.getEntityString(EntityHuman.class) : EntityRegistry.getEntityString(this.gm.thePlayer)); + EntityEggInfo egg = EntityRegistry.SPAWN_EGGS.get(this.gm.player == null ? EntityRegistry.getEntityString(EntityHuman.class) : EntityRegistry.getEntityString(this.gm.player)); if(egg != null && egg.origin != null) { Dimension dim = UniverseRegistry.getDimension(egg.origin); if(dim != null) { @@ -446,10 +446,10 @@ public class GuiChar extends GuiList public void drawOverlays() { if(this.adjust != null) { - float factor = this.gm.thePlayer.width > 2.15f ? 2.15f / this.gm.thePlayer.width : 1.0f; - factor = this.gm.thePlayer.height > 3.0f && 3.0f / this.gm.thePlayer.height < factor ? 3.0f / this.gm.thePlayer.height : factor; + float factor = this.gm.player.width > 2.15f ? 2.15f / this.gm.player.width : 1.0f; + factor = this.gm.player.height > 3.0f && 3.0f / this.gm.player.height < factor ? 3.0f / this.gm.player.height : factor; drawEntity(400 + (this.gm.fb_x - 400 - 400) / 2, this.gm.fb_y - 160, 160.0f * factor - , this.yaw, this.pitch, this.gm.thePlayer); + , this.yaw, this.pitch, this.gm.player); } } diff --git a/client/src/client/gui/character/GuiCharacters.java b/client/src/client/gui/character/GuiCharacters.java index cd94394..159e54f 100644 --- a/client/src/client/gui/character/GuiCharacters.java +++ b/client/src/client/gui/character/GuiCharacters.java @@ -73,7 +73,7 @@ public class GuiCharacters extends GuiList impleme if(this.gm.getNetHandler() != null) { int initialSelection = this.gm.getNetHandler().getSelectedCharacter(); for(PlayerCharacter character : this.gm.getNetHandler().getCharacterList()) { - this.elements.add(new CharacterEntry(initialSelection == this.elements.size() ? new PlayerCharacter(character.name, character.info, character.align, this.gm.thePlayer.worldObj.dimension.getFormattedName(false), this.gm.thePlayer.getPosition(), character.type, this.gm.thePlayer.experienceLevel) : character, initialSelection == this.elements.size())); + this.elements.add(new CharacterEntry(initialSelection == this.elements.size() ? new PlayerCharacter(character.name, character.info, character.align, this.gm.player.worldObj.dimension.getFormattedName(false), this.gm.player.getPosition(), character.type, this.gm.player.experienceLevel) : character, initialSelection == this.elements.size())); } this.elements.add(new CharacterEntry(null, false)); this.setSelected(initialSelection); diff --git a/client/src/client/gui/character/GuiClass.java b/client/src/client/gui/character/GuiClass.java index c1ca519..11a8805 100644 --- a/client/src/client/gui/character/GuiClass.java +++ b/client/src/client/gui/character/GuiClass.java @@ -21,14 +21,14 @@ public class GuiClass extends GuiList implements ActButton. public void draw(int x, int y, int mouseX, int mouseY, boolean hovered) { - if(GuiClass.this.gm.thePlayer != null && this.clazz == GuiClass.this.gm.thePlayer.getNpcClass()) + if(GuiClass.this.gm.player != null && this.clazz == GuiClass.this.gm.player.getNpcClass()) Drawing.drawRect(x, y, 1, 44, 0xffaf0000); Drawing.drawText(this.clazz.toString().isEmpty() ? "" : this.clazz.toString(), x + 3, y, 0xffffffff); } public void select(boolean dclick, int mx, int my) { - if((GuiClass.this.selectButton.enabled = GuiClass.this.gm.thePlayer == null || this.clazz != GuiClass.this.gm.thePlayer.getNpcClass()) && dclick) + if((GuiClass.this.selectButton.enabled = GuiClass.this.gm.player == null || this.clazz != GuiClass.this.gm.player.getNpcClass()) && dclick) GuiClass.this.use(GuiClass.this.selectButton, Mode.PRIMARY); } } @@ -45,8 +45,8 @@ public class GuiClass extends GuiList implements ActButton. super.init(width, height); this.setDimensions(400, height, 32, height - 32); this.elements.clear(); - if(this.gm.thePlayer != null && this.gm.thePlayer.getSpecies().classEnum != null) - for(Enum clazz : this.gm.thePlayer.getSpecies().classEnum.getEnumConstants()) { + if(this.gm.player != null && this.gm.player.getSpecies().classEnum != null) + for(Enum clazz : this.gm.player.getSpecies().classEnum.getEnumConstants()) { this.elements.add(new ClassEntry(clazz)); } this.add(new NavButton(width - 198 * 2, height - 28, 194, 24, GuiChar.INSTANCE, "Zurück")); @@ -69,8 +69,8 @@ public class GuiClass extends GuiList implements ActButton. public void use(ActButton elem, Mode action) { ClassEntry entry = this.getSelected(); - if(entry != null && GuiClass.this.gm.thePlayer != null) { - GuiClass.this.gm.thePlayer.sendQueue.addToSendQueue(new CPacketAction(CPacketAction.Action.SET_CLASS, entry.clazz.ordinal())); + if(entry != null && GuiClass.this.gm.player != null) { + GuiClass.this.gm.player.sendQueue.addToSendQueue(new CPacketAction(CPacketAction.Action.SET_CLASS, entry.clazz.ordinal())); this.gm.displayGuiScreen(GuiChar.INSTANCE); } } diff --git a/client/src/client/gui/character/GuiSpecies.java b/client/src/client/gui/character/GuiSpecies.java index af9b9bd..770d8a4 100644 --- a/client/src/client/gui/character/GuiSpecies.java +++ b/client/src/client/gui/character/GuiSpecies.java @@ -24,7 +24,7 @@ public class GuiSpecies extends GuiList implements ActB public void draw(int x, int y, int mouseX, int mouseY, boolean hovered) { - if(GuiSpecies.this.gm.thePlayer != null && this.species == GuiSpecies.this.gm.thePlayer.getSpecies()) + if(GuiSpecies.this.gm.player != null && this.species == GuiSpecies.this.gm.player.getSpecies()) Drawing.drawRect(x, y, 1, 44, 0xffaf0000); Drawing.drawText(this.species.name, x + 3, y, 0xff000000 | this.species.color1 | this.species.color2); if(this.species.classEnum != null) @@ -33,7 +33,7 @@ public class GuiSpecies extends GuiList implements ActB public void select(boolean dclick, int mx, int my) { - if((GuiSpecies.this.selectButton.enabled = GuiSpecies.this.gm.thePlayer == null || this.species != GuiSpecies.this.gm.thePlayer.getSpecies()) && dclick) + if((GuiSpecies.this.selectButton.enabled = GuiSpecies.this.gm.player == null || this.species != GuiSpecies.this.gm.player.getSpecies()) && dclick) GuiSpecies.this.use(GuiSpecies.this.selectButton, Mode.PRIMARY); } } @@ -73,7 +73,7 @@ public class GuiSpecies extends GuiList implements ActB public void use(ActButton elem, Mode action) { SpeciesEntry entry = this.getSelected(); - if(entry != null && GuiSpecies.this.gm.thePlayer != null) - GuiSpecies.this.gm.thePlayer.sendQueue.addToSendQueue(new CPacketAction(CPacketAction.Action.SET_SPECIES, EntityRegistry.getEntityID(entry.species.clazz))); + if(entry != null && GuiSpecies.this.gm.player != null) + GuiSpecies.this.gm.player.sendQueue.addToSendQueue(new CPacketAction(CPacketAction.Action.SET_SPECIES, EntityRegistry.getEntityID(entry.species.clazz))); } } diff --git a/client/src/client/gui/container/GuiChest.java b/client/src/client/gui/container/GuiChest.java index 85c444f..c9a56be 100755 --- a/client/src/client/gui/container/GuiChest.java +++ b/client/src/client/gui/container/GuiChest.java @@ -19,7 +19,7 @@ public class GuiChest extends GuiContainer public GuiChest(IInventory upperInv, IInventory lowerInv) { - super(new ContainerChest(upperInv, lowerInv, Client.CLIENT.thePlayer)); + super(new ContainerChest(upperInv, lowerInv, Client.CLIENT.player)); this.upperChestInventory = upperInv; this.lowerChestInventory = lowerInv; // this.allowUserInput = false; diff --git a/client/src/client/gui/container/GuiContainer.java b/client/src/client/gui/container/GuiContainer.java index 7f5051d..babe081 100755 --- a/client/src/client/gui/container/GuiContainer.java +++ b/client/src/client/gui/container/GuiContainer.java @@ -213,7 +213,7 @@ public abstract class GuiContainer extends Gui */ public void initGui() { - this.gm.thePlayer.openContainer = this.inventorySlots; + this.gm.player.openContainer = this.inventorySlots; // this.guiLeft = (this.width - this.xSize) / 2; // this.guiTop = (this.height - this.ySize) / 2; // this.addButtons(); @@ -360,7 +360,7 @@ public abstract class GuiContainer extends Gui ItemRenderer.disableStandardItemLighting(); // this.drawGuiContainerForegroundLayer(mouseX, mouseY); ItemRenderer.enableGUIStandardItemLighting(); - InventoryPlayer inventoryplayer = this.gm.thePlayer.inventory; + InventoryPlayer inventoryplayer = this.gm.player.inventory; ItemStack itemstack = this.draggedStack == null ? inventoryplayer.getItemStack() : this.draggedStack; if(this.gm.itemCheat) itemstack = itemstack == null ? this.cheatStack : itemstack; @@ -451,7 +451,7 @@ public abstract class GuiContainer extends Gui } protected void renderToolTip(ItemStack stack, int x, int y) { - List list = stack.getTooltip(this.gm.thePlayer); + List list = stack.getTooltip(this.gm.player); StringBuilder sb = new StringBuilder(); for(int i = 0; i < list.size(); ++i) { if(i != 0) @@ -512,7 +512,7 @@ public abstract class GuiContainer extends Gui ItemStack itemstack = slotIn.getStack(); boolean flag = false; boolean flag1 = slotIn == this.clickedSlot && this.draggedStack != null && !this.isRightMouseClick; - ItemStack itemstack1 = this.gm.thePlayer.inventory.getItemStack(); + ItemStack itemstack1 = this.gm.player.inventory.getItemStack(); String s = null; if (slotIn == this.clickedSlot && this.draggedStack != null && this.isRightMouseClick && itemstack != null) @@ -589,7 +589,7 @@ public abstract class GuiContainer extends Gui private void updateDragSplitting() { - ItemStack itemstack = this.gm.thePlayer.inventory.getItemStack(); + ItemStack itemstack = this.gm.player.inventory.getItemStack(); if (itemstack != null && this.dragSplitting) { @@ -643,8 +643,8 @@ public abstract class GuiContainer extends Gui return; if(this.cheatStack != null) { Slot slot = this.getSlotAtPosition(mouseX, mouseY); - if((mouseButton == 0 || mouseButton == 1) && slot != null && this.gm.thePlayer != null && slot.inventory == this.gm.thePlayer.inventory) - this.gm.thePlayer.sendQueue.addToSendQueue(new CPacketCheat(this.cheatStack, slot.getIndex(), mouseButton == 0 && this.cheatStack.stackSize > 1)); + if((mouseButton == 0 || mouseButton == 1) && slot != null && this.gm.player != null && slot.inventory == this.gm.player.inventory) + this.gm.player.sendQueue.addToSendQueue(new CPacketCheat(this.cheatStack, slot.getIndex(), mouseButton == 0 && this.cheatStack.stackSize > 1)); if(mouseButton != 1 && !this.gm.ctrl()) this.cheatStack = null; return; @@ -652,7 +652,7 @@ public abstract class GuiContainer extends Gui if((mouseButton == 0 || mouseButton == 1 || mouseButton == 2) && this.clickSide(mouseX, mouseY, -1, this.gm.shift() || mouseButton == 1, this.gm.ctrl() || mouseButton == 2)) return; if(mouseButton == 0) { - if(this.gm.itemCheat && this.gm.thePlayer != null && this.gm.thePlayer.inventory.getItemStack() == null) { + if(this.gm.itemCheat && this.gm.player != null && this.gm.player.inventory.getItemStack() == null) { for (CheatTab tab : CheatTab.values()) { if (this.isInsideTab(tab, mouseX, mouseY)) @@ -711,7 +711,7 @@ public abstract class GuiContainer extends Gui // else if (!this.dragSplitting) { - if (this.gm.thePlayer.inventory.getItemStack() == null) + if (this.gm.player.inventory.getItemStack() == null) { // if (mouseButton == this.gm.bindTertiary.getKeyCode() + 100) // { @@ -774,7 +774,7 @@ public abstract class GuiContainer extends Gui if(this.gm == null || this.cheatStack != null) return; Slot slot = this.getSlotAtPosition(mouseX, mouseY); - ItemStack itemstack = this.gm.thePlayer.inventory.getItemStack(); + ItemStack itemstack = this.gm.player.inventory.getItemStack(); // if (this.clickedSlot != null && this.gm.touchscreen) // { @@ -849,7 +849,7 @@ public abstract class GuiContainer extends Gui { for (Slot slot2 : this.inventorySlots.inventorySlots) { - if (slot2 != null && slot2.canTakeStack(this.gm.thePlayer) && slot2.getHasStack() && slot2.inventory == slot.inventory && Container.canAddItemToSlot(slot2, this.shiftClickedSlot, true)) + if (slot2 != null && slot2.canTakeStack(this.gm.player) && slot2.getHasStack() && slot2.inventory == slot.inventory && Container.canAddItemToSlot(slot2, this.shiftClickedSlot, true)) { this.handleMouseClick(slot2, slot2.slotNumber, state, 1); } @@ -935,7 +935,7 @@ public abstract class GuiContainer extends Gui this.handleMouseClick((Slot)null, -999, Container.getDragCode(2, this.dragSplittingLimit), 5); } - else if (this.gm.thePlayer.inventory.getItemStack() != null) + else if (this.gm.player.inventory.getItemStack() != null) { // if (state == this.gm.bindTertiary.getKeyCode() + 100) // { @@ -955,7 +955,7 @@ public abstract class GuiContainer extends Gui } } - if (this.gm.thePlayer.inventory.getItemStack() == null) + if (this.gm.player.inventory.getItemStack() == null) { this.lastClickTime = 0L; } @@ -994,11 +994,11 @@ public abstract class GuiContainer extends Gui slotId = slotIn.slotNumber; } - this.gm.controller.windowClick(this.inventorySlots.windowId, slotId, clickedButton, clickType, this.gm.thePlayer); + this.gm.controller.windowClick(this.inventorySlots.windowId, slotId, clickedButton, clickType, this.gm.player); } public void dropItem() { - if (this.gm != null && this.gm.thePlayer != null && this.theSlot != null && this.theSlot.getHasStack()) + if (this.gm != null && this.gm.player != null && this.theSlot != null && this.theSlot.getHasStack()) { // if (keyCode == this.gm.bindTertiary.getKeyCode()) // { @@ -1034,7 +1034,7 @@ public abstract class GuiContainer extends Gui */ public void useHotbar(int slot) { - if (!this.clickSide((this.gm.mouse_x - this.container_x) / 2, (this.gm.mouse_y - this.container_y) / 2, slot, this.gm.shift(), this.gm.ctrl()) && this.gm != null && this.gm.thePlayer != null && this.gm.thePlayer.inventory.getItemStack() == null && this.cheatStack == null && this.theSlot != null) + if (!this.clickSide((this.gm.mouse_x - this.container_x) / 2, (this.gm.mouse_y - this.container_y) / 2, slot, this.gm.shift(), this.gm.ctrl()) && this.gm != null && this.gm.player != null && this.gm.player.inventory.getItemStack() == null && this.cheatStack == null && this.theSlot != null) { // for (int i = 0; i < 9; ++i) // { @@ -1054,9 +1054,9 @@ public abstract class GuiContainer extends Gui */ public void onGuiClosed() { - if (this.gm != null && this.gm.thePlayer != null) + if (this.gm != null && this.gm.player != null) { - this.inventorySlots.onContainerClosed(this.gm.thePlayer); + this.inventorySlots.onContainerClosed(this.gm.player); } } @@ -1075,9 +1075,9 @@ public abstract class GuiContainer extends Gui { // super.updateScreen(); - if (this.gm != null && this.gm.thePlayer != null && (!this.gm.thePlayer.isEntityAlive() || this.gm.thePlayer.dead)) + if (this.gm != null && this.gm.player != null && (!this.gm.player.isEntityAlive() || this.gm.player.dead)) { - this.gm.thePlayer.closeScreen(); + this.gm.player.closeScreen(); } } @@ -1182,7 +1182,7 @@ public abstract class GuiContainer extends Gui } private boolean clickSide(int mouseX, int mouseY, int slot, boolean instant, boolean full) { - if(this.gm.itemCheat && this.isPointInRegion(this.xSize + 2, 0, 18 * 12, 18 * 9, mouseX, mouseY) && this.gm.thePlayer != null && this.gm.thePlayer.inventory.getItemStack() == null && this.cheatStack == null) { + if(this.gm.itemCheat && this.isPointInRegion(this.xSize + 2, 0, 18 * 12, 18 * 9, mouseX, mouseY) && this.gm.player != null && this.gm.player.inventory.getItemStack() == null && this.cheatStack == null) { int i = (ITEM_LIST.size() + 12 - 1) / 12 - 9; int j = (int)((double)(this.currentScroll * (float)i) + 0.5D); @@ -1197,7 +1197,7 @@ public abstract class GuiContainer extends Gui if(i1 >= 0 && i1 < ITEM_LIST.size()) { if(slot >= 0 || instant) { - this.gm.thePlayer.sendQueue.addToSendQueue(new CPacketCheat(ITEM_LIST.get(i1), slot, full)); + this.gm.player.sendQueue.addToSendQueue(new CPacketCheat(ITEM_LIST.get(i1), slot, full)); } else { this.cheatStack = ITEM_LIST.get(i1).copy(); diff --git a/client/src/client/gui/container/GuiEnchant.java b/client/src/client/gui/container/GuiEnchant.java index 5dce728..0b25ef3 100755 --- a/client/src/client/gui/container/GuiEnchant.java +++ b/client/src/client/gui/container/GuiEnchant.java @@ -70,7 +70,7 @@ public class GuiEnchant extends GuiContainer int l = mouseX - 60; int i1 = mouseY - (14 + 19 * k); - if (l >= 0 && i1 >= 0 && l < 108 && i1 < 19 && this.container.enchantItem(this.gm.thePlayer, k)) + if (l >= 0 && i1 >= 0 && l < 108 && i1 < 19 && this.container.enchantItem(this.gm.player, k)) { this.gm.controller.sendEnchantPacket(this.container.windowId, k); } @@ -107,7 +107,7 @@ public class GuiEnchant extends GuiContainer String s1 = "" + l1; int i2 = 6839882; - if (/* (k < l + 1 || */ this.gm.thePlayer.experienceLevel < l1) // && !this.gm.thePlayer.creative) + if (/* (k < l + 1 || */ this.gm.player.experienceLevel < l1) // && !this.gm.thePlayer.creative) { this.rect(i1, 14 + 19 * l, 108, 19, 0x400000); this.rect(i1 + 1, 15 + 19 * l, 16, 16, 0x200000); @@ -171,7 +171,7 @@ public class GuiEnchant extends GuiContainer // sb.append("\n"); // } - if (this.gm.thePlayer.experienceLevel < k) + if (this.gm.player.experienceLevel < k) { sb.append((sb.length() != 0 ? "\n" : "") + TextColor.RED + String.format("Erfahrungsstufe %d erforderlich", this.container.enchantLevels[j])); } diff --git a/client/src/client/gui/container/GuiHopper.java b/client/src/client/gui/container/GuiHopper.java index c76579f..c11362a 100755 --- a/client/src/client/gui/container/GuiHopper.java +++ b/client/src/client/gui/container/GuiHopper.java @@ -19,7 +19,7 @@ public class GuiHopper extends GuiContainer public GuiHopper(InventoryPlayer playerInv, IInventory hopperInv) { - super(new ContainerHopper(playerInv, hopperInv, Client.CLIENT.thePlayer)); + super(new ContainerHopper(playerInv, hopperInv, Client.CLIENT.player)); this.playerInventory = playerInv; this.hopperInventory = hopperInv; // this.allowUserInput = false; diff --git a/client/src/client/gui/container/GuiHorse.java b/client/src/client/gui/container/GuiHorse.java index dbb5ec9..ad5cf54 100755 --- a/client/src/client/gui/container/GuiHorse.java +++ b/client/src/client/gui/container/GuiHorse.java @@ -27,7 +27,7 @@ public class GuiHorse extends GuiContainer public GuiHorse(IInventory playerInv, IInventory horseInv, EntityHorse horse) { - super(new ContainerHorseInventory(playerInv, horseInv, horse, Client.CLIENT.thePlayer)); + super(new ContainerHorseInventory(playerInv, horseInv, horse, Client.CLIENT.player)); this.playerInventory = playerInv; this.horseInventory = horseInv; // this.horseEntity = horse; diff --git a/client/src/client/gui/container/GuiMachine.java b/client/src/client/gui/container/GuiMachine.java index 82ed33f..2467e18 100755 --- a/client/src/client/gui/container/GuiMachine.java +++ b/client/src/client/gui/container/GuiMachine.java @@ -16,7 +16,7 @@ public class GuiMachine extends GuiContainer public GuiMachine(InventoryPlayer player, IInventory inv, TileEntityMachine machine) { - super(new ContainerMachine(player, machine, inv, Client.CLIENT.thePlayer)); + super(new ContainerMachine(player, machine, inv, Client.CLIENT.player)); this.playerInv = player; this.machineInv = machine; // this.allowUserInput = false; diff --git a/client/src/client/gui/container/GuiRepair.java b/client/src/client/gui/container/GuiRepair.java index 8015977..2d7dfb7 100755 --- a/client/src/client/gui/container/GuiRepair.java +++ b/client/src/client/gui/container/GuiRepair.java @@ -21,7 +21,7 @@ public class GuiRepair extends GuiContainer implements ICrafting public GuiRepair(InventoryPlayer inventoryIn, World worldIn) { - super(new ContainerRepair(inventoryIn, worldIn, Client.CLIENT.thePlayer)); + super(new ContainerRepair(inventoryIn, worldIn, Client.CLIENT.player)); this.playerInventory = inventoryIn; this.anvil = (ContainerRepair)this.inventorySlots; } diff --git a/client/src/client/gui/ingame/GuiGameOver.java b/client/src/client/gui/ingame/GuiGameOver.java index 8b79563..d8ad0a9 100755 --- a/client/src/client/gui/ingame/GuiGameOver.java +++ b/client/src/client/gui/ingame/GuiGameOver.java @@ -18,10 +18,10 @@ public class GuiGameOver extends Gui { public void init(int width, int height) { this.timer = 0; this.add(new Label(0, 0, 200, 20, "Du bist gestorben!")); - this.add(new Label(0, 32, 200, 20, "Punktestand: " + TextColor.YELLOW + this.gm.thePlayer.experienceLevel)); + this.add(new Label(0, 32, 200, 20, "Punktestand: " + TextColor.YELLOW + this.gm.player.experienceLevel)); this.button = this.add(new ActButton(0, 100, 200, 24, new ActButton.Callback() { public void use(ActButton elem, Mode action) { - GuiGameOver.this.gm.thePlayer.respawnPlayer(); + GuiGameOver.this.gm.player.respawnPlayer(); GuiGameOver.this.gm.displayGuiScreen(null); } }, "Wiederbeleben")); diff --git a/client/src/client/network/ClientPlayer.java b/client/src/client/network/ClientPlayer.java index e30af14..e8d1e1f 100755 --- a/client/src/client/network/ClientPlayer.java +++ b/client/src/client/network/ClientPlayer.java @@ -202,7 +202,7 @@ public class ClientPlayer extends NetHandler implements IClientPlayer // this.gameController.gameSettings.difficulty = packetIn.getDifficulty(); this.gameController.loadWorld(this.clientWorldController, packetIn.getEntityType()); // this.gameController.thePlayer.dimension = this.clientWorldController.dimension.getDimensionId(); - this.gameController.thePlayer.setId(packetIn.getEntityId()); + this.gameController.player.setId(packetIn.getEntityId()); this.gameController.displayGuiScreen(this.gameController.charEditor ? GuiChar.INSTANCE : null); // this.currentServerMaxPlayers = packetIn.getMaxPlayers(); // this.gameController.controller.setCheat(packetIn.getCheat()); @@ -465,7 +465,7 @@ public class ClientPlayer extends NetHandler implements IClientPlayer { entity.getDataWatcher().updateWatchedObjectsFromList(packetIn.func_149376_c()); - if(entity == this.gameController.thePlayer && this.gameController.open instanceof GuiChar) + if(entity == this.gameController.player && this.gameController.open instanceof GuiChar) ((GuiChar)this.gameController.open).checkReopen(); } } @@ -481,7 +481,7 @@ public class ClientPlayer extends NetHandler implements IClientPlayer double z = (double)packetIn.getZ() / 32.0D; float yaw = packetIn.getYaw(); float pitch = packetIn.getPitch(); - EntityNPC player = (EntityNPC)EntityRegistry.createEntityByID(packetIn.getEntityType(), this.gameController.theWorld); // new EntityNPC(this.gameController.theWorld); // , /* this.getPlayerInfo( */ packetIn.getUser()); // ).getUser()); + EntityNPC player = (EntityNPC)EntityRegistry.createEntityByID(packetIn.getEntityType(), this.gameController.world); // new EntityNPC(this.gameController.theWorld); // , /* this.getPlayerInfo( */ packetIn.getUser()); // ).getUser()); player.setOtherPlayer(this.gameController); player.prevX = player.lastTickPosX = (double)(player.serverPosX = packetIn.getX()); player.prevY = player.lastTickPosY = (double)(player.serverPosY = packetIn.getY()); @@ -551,7 +551,7 @@ public class ClientPlayer extends NetHandler implements IClientPlayer if (packetIn.getHeldItemHotbarIndex() >= 0 && packetIn.getHeldItemHotbarIndex() < InventoryPlayer.getHotbarSize()) { - this.gameController.thePlayer.inventory.currentItem = packetIn.getHeldItemHotbarIndex(); + this.gameController.player.inventory.currentItem = packetIn.getHeldItemHotbarIndex(); } } @@ -620,7 +620,7 @@ public class ClientPlayer extends NetHandler implements IClientPlayer public void handlePlayerPosLook(SPacketPlayerPosLook packetIn) { NetHandler.checkThread(packetIn, this, this.gameController, this.clientWorldController); - EntityNPC entityplayer = this.gameController.thePlayer; + EntityNPC entityplayer = this.gameController.player; double d0 = packetIn.getX(); double d1 = packetIn.getY(); double d2 = packetIn.getZ(); @@ -669,9 +669,9 @@ public class ClientPlayer extends NetHandler implements IClientPlayer if (!this.doneLoadingTerrain) { - this.gameController.thePlayer.prevX = this.gameController.thePlayer.posX; - this.gameController.thePlayer.prevY = this.gameController.thePlayer.posY; - this.gameController.thePlayer.prevZ = this.gameController.thePlayer.posZ; + this.gameController.player.prevX = this.gameController.player.posX; + this.gameController.player.prevY = this.gameController.player.posY; + this.gameController.player.prevZ = this.gameController.player.posZ; this.doneLoadingTerrain = true; // this.gameController.displayGuiScreen(null); // if(this.travelSound) { @@ -769,7 +769,7 @@ public class ClientPlayer extends NetHandler implements IClientPlayer if (entitylivingbase == null) { - entitylivingbase = this.gameController.thePlayer; + entitylivingbase = this.gameController.player; } if (entity != null) @@ -907,7 +907,7 @@ public class ClientPlayer extends NetHandler implements IClientPlayer double d2 = (double)packetIn.getZ() / 32.0D; float f = (float)(packetIn.getYaw() * 360) / 256.0F; float f1 = (float)(packetIn.getPitch() * 360) / 256.0F; - EntityLiving entitylivingbase = (EntityLiving)EntityRegistry.createEntityByID(packetIn.getEntityType(), this.gameController.theWorld); + EntityLiving entitylivingbase = (EntityLiving)EntityRegistry.createEntityByID(packetIn.getEntityType(), this.gameController.world); entitylivingbase.serverPosX = packetIn.getX(); entitylivingbase.serverPosY = packetIn.getY(); entitylivingbase.serverPosZ = packetIn.getZ(); @@ -942,7 +942,7 @@ public class ClientPlayer extends NetHandler implements IClientPlayer { NetHandler.checkThread(packetIn, this, this.gameController, this.clientWorldController); // this.gameController.theWorld.getWorldInfo().setTime(packetIn.getTotalWorldTime()); - this.gameController.theWorld.setDayTime(packetIn.getWorldTime()); + this.gameController.world.setDayTime(packetIn.getWorldTime()); this.gameController.setTicked(packetIn.getServerinfo()); } @@ -968,9 +968,9 @@ public class ClientPlayer extends NetHandler implements IClientPlayer { // boolean flag = false; - if (packetIn.getEntityId() == this.gameController.thePlayer.getId()) + if (packetIn.getEntityId() == this.gameController.player.getId()) { - entity = this.gameController.thePlayer; + entity = this.gameController.player; if (entity1 instanceof EntityBoat) { @@ -1036,7 +1036,7 @@ public class ClientPlayer extends NetHandler implements IClientPlayer public void handleUpdateHealth(SPacketUpdateHealth packetIn) { NetHandler.checkThread(packetIn, this, this.gameController, this.clientWorldController); - this.gameController.thePlayer.setPlayerSPHealth(packetIn.getHealth()); + this.gameController.player.setPlayerSPHealth(packetIn.getHealth()); // this.gameController.thePlayer.getFoodStats().setFoodLevel(packetIn.getFoodLevel()); // this.gameController.thePlayer.getFoodStats().setFoodSaturationLevel(packetIn.getSaturationLevel()); } @@ -1044,7 +1044,7 @@ public class ClientPlayer extends NetHandler implements IClientPlayer public void handleSetExperience(SPacketSetExperience packetIn) { NetHandler.checkThread(packetIn, this, this.gameController, this.clientWorldController); - this.gameController.thePlayer.setXPStats(packetIn.getProgress(), packetIn.getTotalExperience(), packetIn.getLevel()); + this.gameController.player.setXPStats(packetIn.getProgress(), packetIn.getTotalExperience(), packetIn.getLevel()); } public void handleRespawn(SPacketRespawn packetIn) @@ -1080,11 +1080,11 @@ public class ClientPlayer extends NetHandler implements IClientPlayer public void handleExplosion(S27PacketExplosion packetIn) { NetHandler.checkThread(packetIn, this, this.gameController, this.clientWorldController); - Explosion explosion = new Explosion(this.gameController.theWorld, (Entity)null, packetIn.getX(), packetIn.getY(), packetIn.getZ(), packetIn.getStrength(), packetIn.getAffectedBlockPositions()); + Explosion explosion = new Explosion(this.gameController.world, (Entity)null, packetIn.getX(), packetIn.getY(), packetIn.getZ(), packetIn.getStrength(), packetIn.getAffectedBlockPositions()); explosion.doExplosionB(true, packetIn.hasAltSound()); - this.gameController.thePlayer.motionX += (double)packetIn.func_149149_c(); - this.gameController.thePlayer.motionY += (double)packetIn.func_149144_d(); - this.gameController.thePlayer.motionZ += (double)packetIn.func_149147_e(); + this.gameController.player.motionX += (double)packetIn.func_149149_c(); + this.gameController.player.motionY += (double)packetIn.func_149144_d(); + this.gameController.player.motionZ += (double)packetIn.func_149147_e(); } /** @@ -1094,7 +1094,7 @@ public class ClientPlayer extends NetHandler implements IClientPlayer public void handleOpenWindow(S2DPacketOpenWindow packetIn) { NetHandler.checkThread(packetIn, this, this.gameController, this.clientWorldController); - EntityNPC entityplayersp = this.gameController.thePlayer; + EntityNPC entityplayersp = this.gameController.player; if ("container".equals(packetIn.getGuiId())) { @@ -1128,7 +1128,7 @@ public class ClientPlayer extends NetHandler implements IClientPlayer { TileEntity machine = this.clientWorldController.getTileEntity(packetIn.getTilePos()); if(machine instanceof TileEntityMachine) - this.gameController.displayGuiScreen(new GuiMachine(this.gameController.thePlayer.inventory, containerlocalmenu, (TileEntityMachine)machine)); + this.gameController.displayGuiScreen(new GuiMachine(this.gameController.player.inventory, containerlocalmenu, (TileEntityMachine)machine)); } else { entityplayersp.displayGUIChest(containerlocalmenu); @@ -1143,7 +1143,7 @@ public class ClientPlayer extends NetHandler implements IClientPlayer public void handleSetSlot(S2FPacketSetSlot packetIn) { NetHandler.checkThread(packetIn, this, this.gameController, this.clientWorldController); - EntityNPC entityplayer = this.gameController.thePlayer; + EntityNPC entityplayer = this.gameController.player; if (packetIn.getWindowId() == -1) { @@ -1185,7 +1185,7 @@ public class ClientPlayer extends NetHandler implements IClientPlayer { NetHandler.checkThread(packetIn, this, this.gameController, this.clientWorldController); Container container = null; - EntityNPC entityplayer = this.gameController.thePlayer; + EntityNPC entityplayer = this.gameController.player; if (packetIn.getWindowId() == 0) { @@ -1208,7 +1208,7 @@ public class ClientPlayer extends NetHandler implements IClientPlayer public void handleWindowItems(S30PacketWindowItems packetIn) { NetHandler.checkThread(packetIn, this, this.gameController, this.clientWorldController); - EntityNPC entityplayer = this.gameController.thePlayer; + EntityNPC entityplayer = this.gameController.player; if (packetIn.func_148911_c() == 0) { @@ -1235,7 +1235,7 @@ public class ClientPlayer extends NetHandler implements IClientPlayer tileentity.setPos(packetIn.getSignPosition()); } - this.gameController.thePlayer.openEditSign((TileEntitySign)tileentity); + this.gameController.player.openEditSign((TileEntitySign)tileentity); } /** @@ -1246,9 +1246,9 @@ public class ClientPlayer extends NetHandler implements IClientPlayer NetHandler.checkThread(packetIn, this, this.gameController, this.clientWorldController); // boolean flag = false; - if (this.gameController.theWorld.isBlockLoaded(packetIn.getPos())) + if (this.gameController.world.isBlockLoaded(packetIn.getPos())) { - TileEntity tileentity = this.gameController.theWorld.getTileEntity(packetIn.getPos()); + TileEntity tileentity = this.gameController.world.getTileEntity(packetIn.getPos()); if (tileentity instanceof TileEntitySign) { @@ -1280,9 +1280,9 @@ public class ClientPlayer extends NetHandler implements IClientPlayer { NetHandler.checkThread(packetIn, this, this.gameController, this.clientWorldController); - if (this.gameController.theWorld.isBlockLoaded(packetIn.getPos())) + if (this.gameController.world.isBlockLoaded(packetIn.getPos())) { - TileEntity tileentity = this.gameController.theWorld.getTileEntity(packetIn.getPos()); + TileEntity tileentity = this.gameController.world.getTileEntity(packetIn.getPos()); // int i = packetIn.getTileEntityType(); if (tileentity != null && packetIn.isTileEntityType(tileentity)) // i == 1 && tileentity instanceof TileEntityMobSpawner || /* i == 2 && tileentity instanceof TileEntityCommandBlock || */ i == 3 && tileentity instanceof TileEntityBeacon || i == 4 && tileentity instanceof TileEntitySkull || /* i == 5 && tileentity instanceof TileEntityFlowerPot || */ i == 6 && tileentity instanceof TileEntityBanner || i == 7 && tileentity instanceof TileEntityMachine) @@ -1298,7 +1298,7 @@ public class ClientPlayer extends NetHandler implements IClientPlayer public void handleWindowProperty(S31PacketWindowProperty packetIn) { NetHandler.checkThread(packetIn, this, this.gameController, this.clientWorldController); - EntityNPC entityplayer = this.gameController.thePlayer; + EntityNPC entityplayer = this.gameController.player; if (entityplayer.openContainer != null && entityplayer.openContainer.windowId == packetIn.getWindowId()) { @@ -1335,7 +1335,7 @@ public class ClientPlayer extends NetHandler implements IClientPlayer public void handleBlockAction(SPacketBlockAction packetIn) { NetHandler.checkThread(packetIn, this, this.gameController, this.clientWorldController); - this.gameController.theWorld.addBlockEvent(packetIn.getBlockPosition(), packetIn.getBlockType(), packetIn.getData1(), packetIn.getData2()); + this.gameController.world.addBlockEvent(packetIn.getBlockPosition(), packetIn.getBlockType(), packetIn.getData1(), packetIn.getData2()); } /** @@ -1344,7 +1344,7 @@ public class ClientPlayer extends NetHandler implements IClientPlayer public void handleBlockBreakAnim(SPacketBlockBreakAnim packetIn) { NetHandler.checkThread(packetIn, this, this.gameController, this.clientWorldController); - this.gameController.theWorld.sendBlockBreakProgress(packetIn.getBreakerId(), packetIn.getPosition(), packetIn.getProgress()); + this.gameController.world.sendBlockBreakProgress(packetIn.getBreakerId(), packetIn.getPosition(), packetIn.getProgress()); } public void handleMapChunkBulk(SPacketMapChunkBulk packetIn) @@ -1403,7 +1403,7 @@ public class ClientPlayer extends NetHandler implements IClientPlayer // } // else // { - this.gameController.theWorld.playAuxSFX(packetIn.getSoundType(), packetIn.getSoundPos(), packetIn.getSoundData()); + this.gameController.world.playAuxSFX(packetIn.getSoundType(), packetIn.getSoundPos(), packetIn.getSoundData()); // } } @@ -1597,7 +1597,7 @@ public class ClientPlayer extends NetHandler implements IClientPlayer public void handlePlayerAbilities(S39PacketPlayerAbilities packetIn) { NetHandler.checkThread(packetIn, this, this.gameController, this.clientWorldController); - EntityNPC entityplayer = this.gameController.thePlayer; + EntityNPC entityplayer = this.gameController.player; entityplayer.flying = packetIn.isFlying(); entityplayer.noclip = packetIn.isNoclip(); // entityplayer.speed = packetIn.getSpeed(); @@ -1629,7 +1629,7 @@ public class ClientPlayer extends NetHandler implements IClientPlayer // else if(packetIn.getSoundName().startsWith("music#")) { // return; // } - this.gameController.theWorld.playSound(packetIn.getX(), packetIn.getY(), packetIn.getZ(), packetIn.getSound(), packetIn.getVolume()); + this.gameController.world.playSound(packetIn.getX(), packetIn.getY(), packetIn.getZ(), packetIn.getSound(), packetIn.getVolume()); } // public void handleDisplay(S48PacketDisplay packetIn) @@ -1901,7 +1901,7 @@ public class ClientPlayer extends NetHandler implements IClientPlayer int i = packetIn.getWindowId(); Gui gui = this.gameController.open; - if (gui != null && gui instanceof GuiMerchant && i == this.gameController.thePlayer.openContainer.windowId) + if (gui != null && gui instanceof GuiMerchant && i == this.gameController.player.openContainer.windowId) { // NpcMerchant imerchant = ((GuiMerchant)guiscreen).getMerchant(); MerchantRecipeList merchantrecipelist = packetIn.getTrades(); diff --git a/client/src/client/renderer/EntityRenderer.java b/client/src/client/renderer/EntityRenderer.java index 82efc10..d0b2f82 100755 --- a/client/src/client/renderer/EntityRenderer.java +++ b/client/src/client/renderer/EntityRenderer.java @@ -129,10 +129,10 @@ public class EntityRenderer { if (this.gm.getRenderViewEntity() == null) { - this.gm.setRenderViewEntity(this.gm.thePlayer); + this.gm.setRenderViewEntity(this.gm.player); } - float light = this.gm.theWorld.getLightBrightness(new BlockPos(this.gm.getRenderViewEntity())); + float light = this.gm.world.getLightBrightness(new BlockPos(this.gm.getRenderViewEntity())); // Log.info(String.format("%.3f", light)); float dist = (float)this.gm.renderDistance / 32.0F; float shift = light * (1.0F - dist) + dist; @@ -186,10 +186,10 @@ public class EntityRenderer { if (entity != null) { - if (this.gm.theWorld != null) + if (this.gm.world != null) { this.gm.setPointedEntity(null); - double max = this.gm.thePlayer != null ? this.gm.thePlayer.getReachDistance() : 5.0; + double max = this.gm.player != null ? this.gm.player.getReachDistance() : 5.0; this.gm.pointed = entity.rayTrace(max, partialTicks); double dist = max; Vec3 eye = entity.getPositionEyes(partialTicks); @@ -219,7 +219,7 @@ public class EntityRenderer { this.pointedEntity = null; Vec3 hit = null; float exp = 1.0F; - List list = this.gm.theWorld.getEntitiesInAABBexcluding(entity, entity.getEntityBoundingBox().addCoord(look.xCoord * max, look.yCoord * max, look.zCoord * max).expand((double)exp, (double)exp, (double)exp), new Predicate() + List list = this.gm.world.getEntitiesInAABBexcluding(entity, entity.getEntityBoundingBox().addCoord(look.xCoord * max, look.yCoord * max, look.zCoord * max).expand((double)exp, (double)exp, (double)exp), new Predicate() { public boolean test(Entity p_apply_1_) { @@ -502,7 +502,7 @@ public class EntityRenderer { f3 = f3 * 0.1F; f4 = f4 * 0.1F; f5 = f5 * 0.1F; - HitPosition movingobjectposition = this.gm.theWorld.rayTraceBlocks(new Vec3(d0 + (double)f3, d1 + (double)f4, d2 + (double)f5), new Vec3(d0 - d4 + (double)f3 + (double)f5, d1 - d6 + (double)f4, d2 - d5 + (double)f5)); + HitPosition movingobjectposition = this.gm.world.rayTraceBlocks(new Vec3(d0 + (double)f3, d1 + (double)f4, d2 + (double)f5), new Vec3(d0 - d4 + (double)f3 + (double)f5, d1 - d6 + (double)f4, d2 - d5 + (double)f5)); if (movingobjectposition != null) { @@ -749,7 +749,7 @@ public class EntityRenderer { { if (this.lightmapUpdateNeeded) { - WorldClient world = this.gm.theWorld; + WorldClient world = this.gm.world; if (world != null) { @@ -792,9 +792,9 @@ public class EntityRenderer { // f10 = 0.25F + f7 * 0.75F; // } - if (this.gm.thePlayer.hasEffect(Potion.NIGHT_VISION)) + if (this.gm.player.hasEffect(Potion.NIGHT_VISION)) { - float vis = this.getNightVisionBrightness(this.gm.thePlayer, partialTicks); + float vis = this.getNightVisionBrightness(this.gm.player, partialTicks); float mult = 1.0F / red; if (mult > 1.0F / green) @@ -926,7 +926,7 @@ public class EntityRenderer { if (this.gm.getRenderViewEntity() == null) { - this.gm.setRenderViewEntity(this.gm.thePlayer); + this.gm.setRenderViewEntity(this.gm.player); } this.getMouseOver(partialTicks); @@ -958,7 +958,7 @@ public class EntityRenderer { this.updateFogColor(partialTicks); GL11.glClear(16640); this.setupCameraTransform(partialTicks); - ActiveRenderInfo.updateRenderInfo(this.gm.thePlayer, this.gm.thirdPersonView == 2); + ActiveRenderInfo.updateRenderInfo(this.gm.player, this.gm.thirdPersonView == 2); Entity entity = this.gm.getRenderViewEntity(); double d0 = entity.lastTickPosX + (entity.posX - entity.lastTickPosX) * (double)partialTicks; double d1 = entity.lastTickPosY + (entity.posY - entity.lastTickPosY) * (double)partialTicks; @@ -981,14 +981,14 @@ public class EntityRenderer { this.setupFog(0, partialTicks); GlState.shadeModel(GL11.GL_SMOOTH); - if (entity.posY + (double)entity.getEyeHeight() < (double)this.gm.theWorld.dimension.getCloudHeight()) + if (entity.posY + (double)entity.getEyeHeight() < (double)this.gm.world.dimension.getCloudHeight()) { this.renderCloudsCheck(renderglobal, partialTicks); } this.setupFog(0, partialTicks); this.gm.getTextureManager().bindTexture(TextureMap.locationBlocksTexture); ItemRenderer.disableStandardItemLighting(); - renderglobal.setupTerrain(entity, (double)partialTicks, this.frameCount++, this.gm.thePlayer.noclip); + renderglobal.setupTerrain(entity, (double)partialTicks, this.frameCount++, this.gm.player.noclip); this.gm.renderGlobal.updateChunks(finishTimeNano); GL11.glMatrixMode(GL11.GL_MODELVIEW); GL11.glPushMatrix(); @@ -1073,7 +1073,7 @@ public class EntityRenderer { GlState.disableBlend(); GlState.disableFog(); - if (entity.posY + (double)entity.getEyeHeight() >= (double)this.gm.theWorld.dimension.getCloudHeight()) + if (entity.posY + (double)entity.getEyeHeight() >= (double)this.gm.world.dimension.getCloudHeight()) { this.renderCloudsCheck(renderglobal, partialTicks); } @@ -1096,7 +1096,7 @@ public class EntityRenderer { GL11.glPushMatrix(); this.setupFog(0, partialTicks); // renderGlobalIn.renderClouds(partialTicks); - if(this.gm.theWorld.dimension.getType().clouds) + if(this.gm.world.dimension.getType().clouds) renderGlobalIn.renderClouds(partialTicks); GlState.disableFog(); GL11.glPopMatrix(); @@ -1109,7 +1109,7 @@ public class EntityRenderer { private void addRainParticles() { - float f = this.gm.theWorld.getRainStrength(); + float f = this.gm.world.getRainStrength(); // if (this.gm.downfallSetting != 0) // { @@ -1120,7 +1120,7 @@ public class EntityRenderer { { this.random.setSeed((long)this.rendererUpdateCount * 312987231L); Entity entity = this.gm.getRenderViewEntity(); - World world = this.gm.theWorld; + World world = this.gm.world; BlockPos blockpos = new BlockPos(entity); int i = 10; double d0 = 0.0D; @@ -1166,7 +1166,7 @@ public class EntityRenderer { } } if(temp < 194.0f || this.random.chance(5)) - this.gm.theWorld.spawnParticle(temp >= 194.0f && this.random.chance(10) ? ParticleType.LAVA : ParticleType.SMOKE_NORMAL, (double)blockpos1.getX() + d3, (double)((float)blockpos1.getY() + 0.1F) - block.getBlockBoundsMinY(), (double)blockpos1.getZ() + d4, 0.0D, 0.0D, 0.0D); + this.gm.world.spawnParticle(temp >= 194.0f && this.random.chance(10) ? ParticleType.LAVA : ParticleType.SMOKE_NORMAL, (double)blockpos1.getX() + d3, (double)((float)blockpos1.getY() + 0.1F) - block.getBlockBoundsMinY(), (double)blockpos1.getZ() + d4, 0.0D, 0.0D, 0.0D); } else if (block.getMaterial() != Material.air) { @@ -1180,7 +1180,7 @@ public class EntityRenderer { d2 = (double)blockpos2.getZ() + d4; } - this.gm.theWorld.spawnParticle(temp <= 5.0f ? ParticleType.HAIL_CORN : ParticleType.WATER_DROP, (double)blockpos2.getX() + d3, (double)((float)blockpos2.getY() + 0.1F) + block.getBlockBoundsMaxY(), (double)blockpos2.getZ() + d4, 0.0D, 0.0D, 0.0D); + this.gm.world.spawnParticle(temp <= 5.0f ? ParticleType.HAIL_CORN : ParticleType.WATER_DROP, (double)blockpos2.getX() + d3, (double)((float)blockpos2.getY() + 0.1F) + block.getBlockBoundsMaxY(), (double)blockpos2.getZ() + d4, 0.0D, 0.0D, 0.0D); } } } @@ -1191,11 +1191,11 @@ public class EntityRenderer { if (d1 > (double)(blockpos.getY() + 1) && world.getPrecipitationHeight(blockpos).getY() > ExtMath.floorf((float)blockpos.getY())) { - this.gm.theWorld.playSound(d0, d1, d2, n >= j ? this.pickMoltenSound() : SoundEvent.RAIN, n >= j ? 0.2f : 0.1F); + this.gm.world.playSound(d0, d1, d2, n >= j ? this.pickMoltenSound() : SoundEvent.RAIN, n >= j ? 0.2f : 0.1F); } else { - this.gm.theWorld.playSound(d0, d1, d2, n >= j ? this.pickMoltenSound() : SoundEvent.RAIN, n >= j ? 0.4f : 0.2F); + this.gm.world.playSound(d0, d1, d2, n >= j ? this.pickMoltenSound() : SoundEvent.RAIN, n >= j ? 0.4f : 0.2F); } } } @@ -1210,13 +1210,13 @@ public class EntityRenderer { */ protected void renderRainSnow(float partialTicks) { - float f = this.gm.theWorld.getRainStrength(); + float f = this.gm.world.getRainStrength(); if (f > 0.0F) // && this.gm.downfallSetting < 2) { this.enableLightmap(); Entity entity = this.gm.getRenderViewEntity(); - World world = this.gm.theWorld; + World world = this.gm.world; int i = ExtMath.floord(entity.posX); int j = ExtMath.floord(entity.posY); int k = ExtMath.floord(entity.posZ); @@ -1411,7 +1411,7 @@ public class EntityRenderer { */ private void updateFogColor(float partial) { - WorldClient world = this.gm.theWorld; + WorldClient world = this.gm.world; Entity entity = this.gm.getRenderViewEntity(); float dist = 0.25F + 0.75F * (float)this.gm.renderDistance / 32.0F; dist = 1.0F - (float)Math.pow((double)dist, 0.25D); @@ -1473,7 +1473,7 @@ public class EntityRenderer { this.fogColorBlue *= mul; } - Block block = ActiveRenderInfo.getBlockAtEntityViewpoint(this.gm.theWorld, entity, partial); + Block block = ActiveRenderInfo.getBlockAtEntityViewpoint(this.gm.world, entity, partial); // if (this.cloudFog) // { @@ -1586,7 +1586,7 @@ public class EntityRenderer { private void setupFog(int start, float partial) { Entity entity = this.gm.getRenderViewEntity(); - float fog = this.gm.theWorld.getFogStrength(); + float fog = this.gm.world.getFogStrength(); float distance = Math.min(0.995f, Math.max(0.005f, FOG_DISTANCE - (0.3f * fog))); float density = 1.0f - Math.min(1.0f, FOG_DENSITY * (1.0f - fog * 0.1f)); // boolean flag = false; @@ -1599,7 +1599,7 @@ public class EntityRenderer { GL11.glFogfv(GL11.GL_FOG_COLOR, (FloatBuffer)this.setFogColorBuffer(this.fogColorRed, this.fogColorGreen, this.fogColorBlue, 1.0F)); GL11.glNormal3f(0.0F, -1.0F, 0.0F); GlState.color(1.0F, 1.0F, 1.0F, 1.0F); - Block block = ActiveRenderInfo.getBlockAtEntityViewpoint(this.gm.theWorld, entity, partial); + Block block = ActiveRenderInfo.getBlockAtEntityViewpoint(this.gm.world, entity, partial); if(distance >= 1.0f) { ; @@ -1676,7 +1676,7 @@ public class EntityRenderer { // SKC.glFogi(NVFogDistance.GL_FOG_DISTANCE_MODE_NV, NVFogDistance.GL_EYE_RADIAL_NV); // } - if (this.gm.theWorld.dimension.hasDenseFog()) + if (this.gm.world.dimension.hasDenseFog()) { GlState.setFogStart(far * ((distance / 0.75f) * 0.05F)); GlState.setFogEnd(Math.min(far, 192.0F) * Math.max(density * (distance / 0.75f), (distance / 0.75f) * 0.05F + 0.01f)); diff --git a/client/src/client/renderer/ItemRenderer.java b/client/src/client/renderer/ItemRenderer.java index eff32d6..0c310a6 100755 --- a/client/src/client/renderer/ItemRenderer.java +++ b/client/src/client/renderer/ItemRenderer.java @@ -163,7 +163,7 @@ public class ItemRenderer */ private void setLightMapFromPlayer(EntityNPC clientPlayer) { - int i = this.gm.theWorld.getCombinedLight(new BlockPos(clientPlayer.posX, clientPlayer.posY + (double)clientPlayer.getEyeHeight(), clientPlayer.posZ), 0); + int i = this.gm.world.getCombinedLight(new BlockPos(clientPlayer.posX, clientPlayer.posY + (double)clientPlayer.getEyeHeight(), clientPlayer.posZ), 0); float f = (float)(i & 65535); float f1 = (float)(i >> 16); GL13.glMultiTexCoord2f(GL13.GL_TEXTURE1, f, f1); @@ -299,9 +299,9 @@ public class ItemRenderer GL11.glRotatef(-135.0F, 0.0F, 1.0F, 0.0F); GL11.glScalef(1.0F, 1.0F, 1.0F); GL11.glTranslatef(5.6F, 0.0F, 0.0F); - RenderNpc render = this.renderManager.getRenderObject(this.gm.thePlayer.getModel()); + RenderNpc render = this.renderManager.getRenderObject(this.gm.player.getModel()); GlState.disableCull(); - render.renderPlayerArm(this.gm.thePlayer); + render.renderPlayerArm(this.gm.player); GlState.enableCull(); } @@ -407,7 +407,7 @@ public class ItemRenderer public void renderItemInFirstPerson(float partialTicks) { float f = 1.0F - (this.prevEquippedProgress + (this.equippedProgress - this.prevEquippedProgress) * partialTicks); - EntityNPC clientplayer = this.gm.thePlayer; + EntityNPC clientplayer = this.gm.player; float f1 = clientplayer.getSwingProgress(partialTicks); float f2 = clientplayer.prevPitch + (clientplayer.rotPitch - clientplayer.prevPitch) * partialTicks; float f3 = clientplayer.prevYaw + (clientplayer.rotYaw - clientplayer.prevYaw) * partialTicks; @@ -475,10 +475,10 @@ public class ItemRenderer { GlState.disableAlpha(); - if (this.gm.thePlayer.isEntityInsideOpaqueBlock()) + if (this.gm.player.isEntityInsideOpaqueBlock()) { - State iblockstate = this.gm.theWorld.getState(new BlockPos(this.gm.thePlayer)); - EntityNPC entityplayer = this.gm.thePlayer; + State iblockstate = this.gm.world.getState(new BlockPos(this.gm.player)); + EntityNPC entityplayer = this.gm.player; for (int i = 0; i < 8; ++i) { @@ -486,7 +486,7 @@ public class ItemRenderer double d1 = entityplayer.posY + (double)(((float)((i >> 1) % 2) - 0.5F) * 0.1F); double d2 = entityplayer.posZ + (double)(((float)((i >> 2) % 2) - 0.5F) * entityplayer.width * 0.8F); BlockPos blockpos = new BlockPos(d0, d1 + (double)entityplayer.getEyeHeight(), d2); - State iblockstate1 = this.gm.theWorld.getState(blockpos); + State iblockstate1 = this.gm.world.getState(blockpos); if (iblockstate1.getBlock().isVisuallyOpaque()) { @@ -500,7 +500,7 @@ public class ItemRenderer } } - if(this.gm.thePlayer.isBurning()) { + if(this.gm.player.isBurning()) { this.renderFireInFirstPerson(partialTicks); } @@ -590,7 +590,7 @@ public class ItemRenderer public void updateEquippedItem() { this.prevEquippedProgress = this.equippedProgress; - EntityNPC entityplayer = this.gm.thePlayer; + EntityNPC entityplayer = this.gm.player; ItemStack itemstack = entityplayer.inventory.getCurrentItem(); boolean flag = false; diff --git a/client/src/client/renderer/RenderGlobal.java b/client/src/client/renderer/RenderGlobal.java index 06c89ad..03a90a9 100755 --- a/client/src/client/renderer/RenderGlobal.java +++ b/client/src/client/renderer/RenderGlobal.java @@ -560,7 +560,7 @@ public class RenderGlobal GlState.enableAlpha(); } - if (this.gm.renderOutlines && this.gm.thePlayer != null) + if (this.gm.renderOutlines && this.gm.player != null) { GlState.depthFunc(GL11.GL_ALWAYS); GlState.disableFog(); @@ -575,7 +575,7 @@ public class RenderGlobal { Entity entity3 = list.get(j); if ((entity3 != this.gm.getRenderViewEntity() || this.gm.thirdPersonView != 0) && - entity3 instanceof EntityLiving && entity3.isInRangeToRender3d(d0, d1, d2) && (entity3.noFrustumCheck || Frustum.isInFrustum(entity3.getEntityBoundingBox()) || entity3.passenger == this.gm.thePlayer)) + entity3 instanceof EntityLiving && entity3.isInRangeToRender3d(d0, d1, d2) && (entity3.noFrustumCheck || Frustum.isInFrustum(entity3.getEntityBoundingBox()) || entity3.passenger == this.gm.player)) { // this.renderManager.renderEntity(entity3, partialTicks); int c = ((EntityLiving)entity3).getColor(); @@ -623,7 +623,7 @@ public class RenderGlobal } entity2 = (Entity)iterator.next(); - flag2 = this.renderManager.shouldRender(entity2, d0, d1, d2) || entity2.passenger == this.gm.thePlayer; + flag2 = this.renderManager.shouldRender(entity2, d0, d1, d2) || entity2.passenger == this.gm.player; if (!flag2) { @@ -1125,11 +1125,11 @@ public class RenderGlobal public void renderSky(float partialTicks) { - if (this.gm.theWorld.dimension.getSkyBoxTexture() != null) + if (this.gm.world.dimension.getSkyBoxTexture() != null) { - this.renderSkyBox(this.gm.theWorld.dimension.getSkyBoxTexture()); + this.renderSkyBox(this.gm.world.dimension.getSkyBoxTexture()); } - else if (this.gm.theWorld.dimension.getType().sky) + else if (this.gm.world.dimension.getType().sky) { GlState.disableTexture2D(); Vec3 vec3 = this.theWorld.getSkyColor(this.gm.getRenderViewEntity(), partialTicks); @@ -1223,7 +1223,7 @@ public class RenderGlobal GlState.color(1.0F, 1.0F, 1.0F, f16); GL11.glRotatef(-90.0F, 0.0F, 1.0F, 0.0F); GL11.glRotatef(this.theWorld.getCelestialAngle(partialTicks) * 360.0F, 1.0F, 0.0F, 0.0F); - if(this.gm.theWorld.dimension.getType().sun) { + if(this.gm.world.dimension.getType().sun) { float size = 30.0F; this.renderEngine.bindTexture(SUN_TEX); worldrenderer.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX); @@ -1233,7 +1233,7 @@ public class RenderGlobal worldrenderer.pos((double)(-size), 100.0D, (double)size).tex(0.0D, 1.0D).endVertex(); Tessellator.draw(); } - if(this.gm.theWorld.dimension.getType().moon) { + if(this.gm.world.dimension.getType().moon) { float size = 20.0F; this.renderEngine.bindTexture(MOON_TEX); int i = this.theWorld.getMoonPhase(); @@ -1332,7 +1332,7 @@ public class RenderGlobal int j = ExtMath.floord(d2 / 2048.0D); d1 = d1 - (double)(i * 2048); d2 = d2 - (double)(j * 2048); - this.renderEngine.bindTexture(this.gm.theWorld.dimension.getCloudTexture()); + this.renderEngine.bindTexture(this.gm.world.dimension.getCloudTexture()); GlState.enableBlend(); GlState.tryBlendFuncSeparate(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA, GL11.GL_ONE, GL11.GL_ZERO); Vec3 vec3 = this.theWorld.getCloudColour(this.gm.getRenderViewEntity(), partialTicks); diff --git a/client/src/client/renderer/entity/RenderFish.java b/client/src/client/renderer/entity/RenderFish.java index 4bac934..6782994 100755 --- a/client/src/client/renderer/entity/RenderFish.java +++ b/client/src/client/renderer/entity/RenderFish.java @@ -65,7 +65,7 @@ public class RenderFish extends Render double d2 = entity.angler.prevZ + (entity.angler.posZ - entity.angler.prevZ) * (double)partialTicks + vec3.zCoord; double d3 = (double)entity.angler.getEyeHeight(); - if (this.renderManager.gm != null && this.renderManager.gm.thirdPersonView > 0 || entity.angler != Client.CLIENT.thePlayer) + if (this.renderManager.gm != null && this.renderManager.gm.thirdPersonView > 0 || entity.angler != Client.CLIENT.player) { float f9 = (entity.angler.prevYawOffset + (entity.angler.yawOffset - entity.angler.prevYawOffset) * partialTicks) * (float)Math.PI / 180.0F; double d4 = (double)ExtMath.sin(f9); diff --git a/client/src/client/renderer/entity/RenderHumanoid.java b/client/src/client/renderer/entity/RenderHumanoid.java index 04e767e..42660a5 100755 --- a/client/src/client/renderer/entity/RenderHumanoid.java +++ b/client/src/client/renderer/entity/RenderHumanoid.java @@ -69,12 +69,12 @@ public class RenderHumanoid extends RenderNpc public void doRender(EntityNPC entity, double x, double y, double z, float partialTicks) { - if (entity != this.renderManager.gm.thePlayer || this.renderManager.livingPlayer == entity) + if (entity != this.renderManager.gm.player || this.renderManager.livingPlayer == entity) { // if(entity.isBoss()) // BossStatus.setBossStatus(entity); double d0 = y; - if(/* this.canSneak() && */ entity.isSneakingVisually() && entity != this.renderManager.gm.thePlayer) + if(/* this.canSneak() && */ entity.isSneakingVisually() && entity != this.renderManager.gm.player) d0 = y - 0.125D; this.setModelVisibilities(entity); super.doRender(entity, x, d0, z, partialTicks); diff --git a/common/src/common/log/Log.java b/common/src/common/log/Log.java index c6deea4..04aa56c 100644 --- a/common/src/common/log/Log.java +++ b/common/src/common/log/Log.java @@ -44,6 +44,7 @@ public enum Log { private static final List LOG = Lists.newArrayList(); private static LogLevel level = LogLevel.INFO; + private static boolean colors = true; private static IThreadListener sync = new IThreadListener() { public ListenableFuture schedule(Runnable run) { return null; @@ -71,14 +72,16 @@ public enum Log { if(pos - last != 0) System.err.print(str.substring(last, pos)); color = TextColor.getColor(c); // (c >= CHR_COLORS2) && (c <= CHR_COLORE2) ? aux_colors[c - CHR_COLORS2] : text_colors[c - CHR_COLORS1]; - System.err.printf("\u001b[38;2;%d;%d;%dm", (color >> 16) & 0xff, (color >> 8) & 0xff, color & 0xff); + if(colors) + System.err.printf("\u001b[38;2;%d;%d;%dm", (color >> 16) & 0xff, (color >> 8) & 0xff, color & 0xff); last = ++pos; continue; } else if(c == CHR_CRESET) { if(pos - last != 0) System.err.print(str.substring(last, pos)); - System.err.print("\u001b[0m"); + if(colors) + System.err.print("\u001b[0m"); last = ++pos; continue; } @@ -99,7 +102,7 @@ public enum Log { if(pos >= str.length() && pos - last != 0) System.err.print(str.substring(last, pos)); } - System.err.print("\u001b[0m\n"); + System.err.print(colors ? "\u001b[0m\n" : "\n"); } public static String str_time(long time) { @@ -112,6 +115,7 @@ public enum Log { public static void init(IThreadListener sync) { Log.sync = sync; + Log.colors = System.getProperty("log.nocolor") == null && !Util.WINDOWS; } public static void flushLog() { diff --git a/common/src/common/util/Util.java b/common/src/common/util/Util.java index 5d3a165..629ef96 100644 --- a/common/src/common/util/Util.java +++ b/common/src/common/util/Util.java @@ -12,7 +12,8 @@ import common.collect.Maps; import common.log.Log; public abstract class Util { - private static long start = getTime(); + public static final boolean WINDOWS = System.getProperty("os.name").startsWith("Windows"); + private static final long START = getTime(); public static String strip(String str, int offset, int len, char newl, char tab, char unk) { StringBuilder sb = new StringBuilder(); @@ -303,10 +304,10 @@ int utf_len(const char *str) { } public static void checkOs() { - if(System.getProperty("os.name").startsWith("Windows") || System.getProperty("os.name").startsWith("Mac")) { + if(System.getProperty("os.name").startsWith("Mac")) { String info = "Inkompatibles Betriebssystem"; - String msg = "Linux oder *BSD ist erforderlich, um dieses Programm auszuführen.\n" + - "Alle Versionen von Windows und Mac OS (X) sind nicht kompatibel."; + String msg = "Linux, *BSD oder Windows ist erforderlich, um dieses Programm\n" + + "auszuführen. Alle Versionen von Mac OS (X) sind nicht kompatibel."; System.err.println("#################################################################"); System.err.println("*** " + info + " ***"); System.err.println(msg); @@ -382,7 +383,7 @@ int utf_len(const char *str) { } public static long rtime() { - return Util.getTime() - start; + return Util.getTime() - START; } public static double ftime() { From d8e54d4d69281e6de7fbf016fed53552dba3f229 Mon Sep 17 00:00:00 2001 From: Sen Date: Mon, 12 May 2025 18:48:05 +0200 Subject: [PATCH 019/200] Revert "split entity ai to server #2+" This reverts commit ad828ec6b449201b7845b05bcf334423f43fea29. --- client/src/client/Client.java | 8 +- client/src/client/gui/GuiConvert.java | 214 +++++++ client/src/client/gui/GuiMenu.java | 5 +- .../src/client}/world/Converter.java | 434 ++++++++++---- common/src/common/ai/AIFireballAttack.java | 6 +- .../common/ai/EntityAIControlledByPlayer.java | 2 +- common/src/common/ai/IEntityLivingNode.java | 21 - common/src/common/ai/IEntityMobNPCNode.java | 14 - common/src/common/ai/IEntityNPCNode.java | 9 - common/src/common/ai/IEntityNode.java | 15 +- common/src/common/entity/Entity.java | 19 +- .../common/entity/npc/AIHurtByAggressor.java | 22 - .../common/entity/npc/EntityChaosMarine.java | 2 +- .../src/common/entity/npc/EntityGargoyle.java | 4 + .../src/common/entity/npc/EntityMobNPC.java | 294 +++++++++- common/src/common/entity/npc/EntityNPC.java | 65 ++- .../common/entity/npc/EntitySpaceMarine.java | 2 +- .../src/common/entity/types/EntityLiving.java | 104 +++- common/src/common/util/Util.java | 8 - common/src/common/world/Region.java | 149 ++++- common/src/common/world/WorldServer.java | 1 - server/src/server/Server.java | 70 +-- server/src/server/ai/EntityLivingNode.java | 537 ------------------ server/src/server/ai/EntityMobNPCNode.java | 84 --- server/src/server/ai/EntityNPCNode.java | 128 ++--- server/src/server/ai/EntityNode.java | 427 +++++++++++++- server/src/server/init/NodeRegistry.java | 136 ----- 27 files changed, 1621 insertions(+), 1159 deletions(-) create mode 100755 client/src/client/gui/GuiConvert.java rename {server/src/server => client/src/client}/world/Converter.java (79%) delete mode 100644 common/src/common/ai/IEntityLivingNode.java delete mode 100644 common/src/common/ai/IEntityMobNPCNode.java delete mode 100644 common/src/common/ai/IEntityNPCNode.java delete mode 100644 common/src/common/entity/npc/AIHurtByAggressor.java delete mode 100644 server/src/server/ai/EntityLivingNode.java delete mode 100644 server/src/server/ai/EntityMobNPCNode.java delete mode 100644 server/src/server/init/NodeRegistry.java diff --git a/client/src/client/Client.java b/client/src/client/Client.java index e0ab9f0..ddeec71 100755 --- a/client/src/client/Client.java +++ b/client/src/client/Client.java @@ -162,6 +162,7 @@ import common.util.Util; import common.util.HitPosition.ObjectType; import common.world.Chunk; import common.world.LightType; +import common.world.Region; import common.world.State; import common.world.World; import common.world.WorldClient; @@ -279,7 +280,7 @@ public class Client implements IThreadListener, IClient { private final List chat = Lists.newArrayList(); private final List feed = Lists.newArrayList(); private final List hotbar = Lists.newArrayList(); - private final File config = new File(System.getProperty("config.file", "client.cfg")); + private final File config = new File(System.getProperty("config.file", "game.cfg")); private boolean primary; private boolean secondary; @@ -1774,8 +1775,8 @@ public class Client implements IThreadListener, IClient { String.format("XYZ: %.3f / %.3f / %.3f", this.viewEntity.posX, this.viewEntity.getEntityBoundingBox().minY, this.viewEntity.posZ) + "\n" + String.format("Block: %d %d %d, R: '%s/%s'", blockpos.getX(), blockpos.getY(), blockpos.getZ(), - Util.getRegionFolder(blockpos.getX() >> 4, blockpos.getZ() >> 4), - Util.getRegionName(blockpos.getX() >> 4, blockpos.getZ() >> 4)) + "\n" + + Region.getRegionFolder(blockpos.getX() >> 4, blockpos.getZ() >> 4), + Region.getRegionName(blockpos.getX() >> 4, blockpos.getZ() >> 4)) + "\n" + String.format("Chunk: %d %d %d + %d %d %d, FOV: %.1f °%s", blockpos.getX() >> 4, blockpos.getY() >> 4, blockpos.getZ() >> 4, blockpos.getX() & 15, blockpos.getY() & 15, blockpos.getZ() & 15, this.zooming ? (this.fov / this.zoomLevel) : this.fov, this.zooming ? @@ -2216,6 +2217,7 @@ public class Client implements IThreadListener, IClient { Log.SYSTEM.info("Beende ..."); unload(false); this.getSoundManager().unload(); + Region.killIO(); this.renderGlobal.stopChunkBuilders(); if(audio.end()) Log.SOUND.info("Audiogerät geschlossen"); diff --git a/client/src/client/gui/GuiConvert.java b/client/src/client/gui/GuiConvert.java new file mode 100755 index 0000000..e3e0a31 --- /dev/null +++ b/client/src/client/gui/GuiConvert.java @@ -0,0 +1,214 @@ +package client.gui; + +import java.io.File; +import java.io.FileFilter; +import java.text.SimpleDateFormat; +import java.util.Collections; +import java.util.Date; + +import client.Client.FileMode; +import client.gui.element.ActButton; +import client.gui.element.ActButton.Mode; +import client.gui.element.GuiList; +import client.gui.element.ListEntry; +import client.gui.element.NavButton; +import client.renderer.Drawing; +import client.world.Converter; +import common.color.TextColor; +import common.dimension.Space; +import common.log.Log; +import common.world.Region; +import common.world.World; +import common.world.Region.FolderInfo; +import common.world.Region.SaveVersion; + +public class GuiConvert extends GuiList implements ActButton.Callback +{ + protected class SaveInfo implements Comparable, ListEntry { + private final String file; + private final int dimensions; + private final int players; + private final long seed; + private final FolderInfo info; + + public SaveInfo(String file, int dimensions, int players, long seed, FolderInfo info) { + this.file = file; + this.dimensions = dimensions; + this.players = players; + this.seed = seed; + this.info = info; + } + + public String getFile() { + return this.file; + } + + public int getDimensions() { + return this.dimensions; + } + + public int getPlayers() { + return this.players; + } + + public boolean mustConvert() { + return this.info.legacy != null; + } + + public String getVersion() { + return this.info.legacy == null ? (this.info.version == null ? "" : this.info.version) : this.info.legacy.toString(); + } + + public boolean isIncompatible() { + return this.info.legacy == SaveVersion.RELEASE_1_13; + } + + public long getLastPlayed() { + return this.info.lastPlayed; + } + + public long getSeed() { + return this.seed; + } + + public int compareTo(SaveInfo comp) { + return this.info.lastPlayed < comp.info.lastPlayed ? 1 : (this.info.lastPlayed > comp.info.lastPlayed ? -1 : this.file.compareTo(comp.file)); + } + + public void select(boolean isDoubleClick, int mouseX, int mouseY) + { + boolean use = !this.isIncompatible() && this.mustConvert(); + GuiConvert.this.selectButton.enabled = use; + + if (isDoubleClick && use) + { + GuiConvert.this.use(GuiConvert.this.selectButton, Mode.PRIMARY); + } + } + + public void draw(int x, int y, int mouseXIn, int mouseYIn, boolean hover) + { + Drawing.drawText((this.isIncompatible() ? TextColor.DRED : "") + this.getFile() + (this.mustConvert() ? "" : + (TextColor.GRAY + " - " + TextColor.RESET + (this.getPlayers() > 0 ? this.getPlayers() + " Spieler" : "Keine Spieler"))), + x + 2, y, 0xffffffff); + Drawing.drawText((this.mustConvert() ? (this.isIncompatible() ? TextColor.CRIMSON : "") + this.getVersion() : (this.getDimensions() <= 0 ? "Keine Dimensionen" : this.getDimensions() + " Dimension" + (this.getDimensions() != 1 ? "en" : "") + " erschaffen")) + , x + 2, y + 18, 0xff808080); + Drawing.drawText(this.mustConvert() ? (this.isIncompatible() ? TextColor.CRIMSON + "Kann nicht konvertiert werden!" : + "Muss konvertiert werden!") : ( // "Kreativmodus: " + (info.isNoCreative() ? "Aus" : "An") + + "Zuletzt gespielt: " + DATE_FORMAT.format(new Date(this.getLastPlayed()))) + " " + TextColor.LGRAY + this.getVersion(), x + 2, y + 18 + 16, 0xff808080); + } + } + + public static final GuiConvert INSTANCE = new GuiConvert(); + private static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("dd.MM.yyyy HH:mm:ss"); + + private ActButton selectButton; + private File dir = null; + + private GuiConvert() + { + } + + private void load() { + this.elements.clear(); + if(this.dir == null || !this.dir.exists() || !this.dir.isDirectory()) + return; + try + { + File[] files = dir.listFiles(); + if(files == null) + throw new RuntimeException("Kann den Speicherordner für Welten nicht lesen oder öffnen!"); + for(File file : files) { + if(!file.isDirectory()) + continue; + FolderInfo info = Region.loadWorldInfo(file); + if(info == null) + info = Converter.convertMapFormat(file, false); + if(info == null) { + this.elements.add(new SaveInfo(file.getName(), -1, -1, + 0L, new FolderInfo(World.START_TIME, file.lastModified(), null, null))); + continue; + } + int dims = -1; + int players = -1; + if(info.legacy == null) { + dims = 0; + File[] folders = new File(new File(dir, file.getName()), "chunk").listFiles(new FileFilter() { + public boolean accept(File pathname) { + return pathname.isDirectory() && !pathname.getName().equals(Space.INSTANCE.getDimensionName()); + } + }); + if(folders != null) { + for(File sub : folders) { + File[] dim = sub.listFiles(); + if(dim != null && dim.length > 0) + dims++; + } + } + File[] plrs = new File(new File(dir, file.getName()), "players").listFiles(new FileFilter() { + public boolean accept(File pathname) { + return pathname.getName().endsWith(".nbt"); + } + }); + players = plrs == null ? 0 : plrs.length; + } + this.elements.add(new SaveInfo(file.getName(), dims, players, + 0L, info)); + } + Collections.sort(this.elements); + } + catch (Exception e) + { + Log.IO.error("Konnte Weltliste nicht laden", e); + this.elements.clear(); + } + } + + public void init(int width, int height) + { + super.init(width, height); + this.setDimensions(width, height, 32, height - 32); + + this.load(); + + this.add(this.selectButton = new ActButton(width / 2 - 383, height - 28, 150, 24, this, "Konvertieren")); + this.add(new NavButton(width / 2 + 233, height - 28, 150, 24, GuiMenu.INSTANCE, "Abbrechen")); + + this.add(new ActButton(4, 4, 200, 24, new ActButton.Callback() { + public void use(ActButton elem, ActButton.Mode action) { + if(GuiConvert.this.gm.world != null) + return; + GuiConvert.this.gm.showFileDialog(FileMode.DIRECTORY_LOAD, "Ordner wählen", GuiConvert.this.dir, new FileCallback() { + public void selected(File file) { + GuiConvert.this.dir = file; + GuiConvert.this.gm.displayGuiScreen(GuiConvert.this); + } + }); + } + }, "Ordner wählen ...")); + + this.selectButton.enabled = false; + } + + public String getTitle() { + return "Welt auswählen"; + } + + public int getListWidth() + { + return 660; + } + + public int getSlotHeight() + { + return 56; + } + + public void use(ActButton button, Mode mode) + { + String dir = this.getSelected().getFile(); + File folder = new File(this.dir, dir); + if(folder.isDirectory()) + Converter.convertMapFormat(folder, true); + } +} diff --git a/client/src/client/gui/GuiMenu.java b/client/src/client/gui/GuiMenu.java index 54cbb34..17a9f4e 100644 --- a/client/src/client/gui/GuiMenu.java +++ b/client/src/client/gui/GuiMenu.java @@ -94,11 +94,12 @@ public class GuiMenu extends Gui { } } }); - this.add(new ActButton(0, 102, 400, 24, new ActButton.Callback() { + this.add(new NavButton(0, 102, 196, 24, GuiConvert.INSTANCE, "Welt konvertieren")); + this.add(new ActButton(204, 102, 196, 24, new ActButton.Callback() { public void use(ActButton elem, ActButton.Mode action) { GuiMenu.this.gm.interrupted = true; } - }, "Client schließen")); + }, "Spiel beenden")); this.shift(); this.add(new Label(4, /* this.gm.fb_y - 2 */ 0, 200, 20, TextColor.VIOLET + Config.VERSION, true)); this.splashLabel = this.add(new Label(0, 160, width, 24, "")); diff --git a/server/src/server/world/Converter.java b/client/src/client/world/Converter.java similarity index 79% rename from server/src/server/world/Converter.java rename to client/src/client/world/Converter.java index 5bc9269..33bf568 100644 --- a/server/src/server/world/Converter.java +++ b/client/src/client/world/Converter.java @@ -1,4 +1,4 @@ -package server.world; +package client.world; import java.io.BufferedInputStream; import java.io.ByteArrayInputStream; @@ -7,14 +7,16 @@ import java.io.File; import java.io.FilenameFilter; import java.io.IOException; import java.io.RandomAccessFile; -import java.text.SimpleDateFormat; import java.util.Arrays; -import java.util.Date; import java.util.Map; import java.util.Map.Entry; import java.util.zip.GZIPInputStream; import java.util.zip.InflaterInputStream; +import client.Client; +import client.gui.GuiConvert; +import client.gui.GuiLoading; +import client.gui.GuiLoading.Callback; import common.biome.Biome; import common.block.Block; import common.block.BlockCactus; @@ -90,26 +92,15 @@ import common.world.Region; import common.world.State; import common.world.Weather; import common.world.World; -import server.Server; - -public abstract class Converter { - private static enum SaveVersion { - ALPHA_1_0("Alpha 1.0 - Beta 1.2"), - BETA_1_3("Beta 1.3 - Release 1.8.9"), - RELEASE_1_9("Release 1.9 - Release 1.12.2"), - RELEASE_1_13("Release 1.13 +"); - - private final String name; - - private SaveVersion(String name) { - this.name = name; - } - - public String toString() { - return this.name; - } - } +import common.world.Region.FolderInfo; +import common.world.Region.SaveVersion; +public final class Converter { +// public static interface Callback { +// void postMessage(String msg); +// void postProgress(int progress); +// } + private static class AnvilRegion { private final int[] offsets = new int[1024]; @@ -191,7 +182,11 @@ public abstract class Converter { State getState(int id, int data); } - private static long postProgress(long start, int progress) { + private Converter() { + } + + private long postProgress(long start, int progress) { +// SKC.info("... " + progress + "%"); if(System.currentTimeMillis() - start >= 500L) { start = System.currentTimeMillis(); Log.JNI.info("... " + progress + "%"); @@ -203,7 +198,16 @@ public abstract class Converter { private static final Map ENTITY_MAP = Maps.newHashMap(); private static final Map TILE_MAP = Maps.newHashMap(); private static final char[] BLOCK_MAP = new char[65536]; +// private static final Map BLOCK_FUNCS = Maps.newHashMap(); private static final Map OLD_GAMERULES = Maps.newHashMap(); + + private String action; + private String task; + private String file; + private int totalRegions; + private int doneRegions; + private int totalChunks; + private int doneChunks; private static void mapEntity(Class clazz, String ... names) { String name = EntityRegistry.getEntityString(clazz); @@ -249,6 +253,17 @@ public abstract class Converter { } } +// private static void mapBlockDynamic(BlockFunction func, int id, int data) { +// BLOCK_MAP[(id << 4) | data] = (char)0x000f; +// BLOCK_FUNCS.put((char)((id << 4) | data), func); +// } +// +// private static void mapBlockDynamic(BlockFunction func, int id) { +// for(int z = 0; z < 16; z++) { +// mapBlockDynamic(func, id, z); +// } +// } + static { OLD_GAMERULES.put("doFireTick", "fireTick"); OLD_GAMERULES.put("mobGriefing", "mobGriefing"); @@ -258,6 +273,7 @@ public abstract class Converter { OLD_GAMERULES.put("doEntityDrops", "dropObjects"); OLD_GAMERULES.put("naturalRegeneration", "naturalRegeneration"); OLD_GAMERULES.put("doDaylightCycle", "daylightCycle"); +// OLD_GAMERULES.put("showDeathMessages", "deathMessages"); OLD_GAMERULES.put("keepInventory", "keepInventory"); OLD_GAMERULES.put("doWeatherCycle", "weatherChanges"); OLD_GAMERULES.put("randomTickSpeed", "randomTickSpeed"); @@ -290,6 +306,7 @@ public abstract class Converter { mapTile(TileEntityDaylightDetector.class, "DLDetector", "daylight_detector"); mapTile(TileEntityHopper.class, "Hopper", "hopper"); mapTile(TileEntityComparator.class, "Comparator", "comparator"); +// mapTile(TileEntityFlowerPot.class, "FlowerPot", "flower_pot"); mapTile(TileEntityBanner.class, "Banner", "banner"); mapBlock(Blocks.stone.getState(), 1); @@ -592,6 +609,11 @@ public abstract class Converter { mapBlockData(Blocks.stonebrick_stairs, 109); mapBlock(Blocks.mycelium, 110); mapBlockData(Blocks.waterlily, 111); +// mapBlockDynamic(new BlockFunction() { +// public IBlockState getState(int id, int data) { +// return Blocks.waterlily.getDefaultState().withProperty(BlockDirectional.FACING, Facing.randHorizontal(RANDOM)); +// } +// }, 111); mapBlock(Blocks.blood_brick, 112); mapBlockData(Blocks.blood_brick_fence, 113); mapBlockData(Blocks.blood_brick_stairs, 114); @@ -800,7 +822,97 @@ public abstract class Converter { return Blocks.stained_hardened_clay.getState().withProperty(BlockColored.COLOR, DyeColor.byMetadata(data)); } }, 252); + // 253, 254 mapBlock(Blocks.obsidian, 255); + +// addBlock(137, 49); // Command Block +// addBlock(166, 0); // Barrier +// addBlock(168, 98); // Prismarine +// // addBlock(169, 169); // Sea Lantern --> Lamp +// addBlock(179, 24); // Red Sandstone +// addBlock(180, 128); // Red Sandstone Stairs +// addBlock(181, 43, 1); // Red Sandstone Double Slab +// +// addBlock(198, 101); // End Rod +// addBlock(199, 102); // Chorus Plant +// addBlock(200, 102); // Chorus Flower +// addBlock(201, 155); // Purpur Block +// addBlock(203, 156); // Purpur Stairs +// addBlock(206, 98); // End Stone Bricks +// addBlock(207, 142); // Beetroot Block +// addBlock(208, 60); // Grass Path +// addBlock(209, 20); // End Gateway +// addBlock(210, 137); // Repeating Command Block +// addBlock(211, 137); // Chain Command Block +// addBlock(212, 79); // Frosted Ice +// addBlock(213, 87); // Magma Block +// addBlock(214, 100); // Nether Wart Block +// addBlock(215, 112); // Red Nether Brick +// addBlock(216, 155); // Bone Block +// addBlock(217, 20); // Structure Void +// addBlock(218, 158); // Observer +// addBlock(255, 49); // Structure Block +// addBlock(202, 155, 2); // Purpur Pillar +// addBlock(204, 43, 7); // Purpur Double Slab + +// if(block > 197 && adddata != null) +// adddata.set(cx, cy, cz, 0); +// if(block == 1 || block == 19) { // Stone, Sponge +// data.set(cx, cy, cz, 0); +// } +// else if(block == 29 || block == 33 || block == 34) { // Piston, Sticky Piston, Piston Head +// int dt = data.get(cx, cy, cz); +// if((dt & 7) == 6) +// data.set(cx, cy, cz, (dt & 8) | 1); +// } +// else if(block == 97) { // Monster Egg +// int dt = data.get(cx, cy, cz); +// switch(dt) { +// case 0: +// default: +// blocks[c] = (byte)1; +// data.set(cx, cy, cz, 0); +// break; +// case 1: +// blocks[c] = (byte)4; +// data.set(cx, cy, cz, 0); +// break; +// case 2: +// case 3: +// case 4: +// case 5: +// blocks[c] = (byte)98; +// data.set(cx, cy, cz, dt - 2); +// break; +// } +// } +// mapBlock(new BlockFunction() { +// public IBlockState getState(int id, int data) { +// return Blocks.waterlily.getDefaultState().withProperty(BlockDirectional.FACING, Facing.randHorizontal(RANDOM)); +// } +// }, 111); +// else if(block == 111) { // Water Lily +// data.set(cx, cy, cz, RANDOM.zrange(4)); +// } +// else if(block == 251 || block == 252) { // Concrete, Concrete Powder +// blocks[c] = (byte)159; +// } +// else if(block >= 235 && block <= 250) { // Glazed Terracotta +// blocks[c] = (byte)159; +// data.set(cx, cy, cz, block - 235); +// } +// else if(block >= 219 && block <= 234) { // Shulker Box +// blocks[c] = (byte)35; +// data.set(cx, cy, cz, block - 219); +// } +// else if(block == 205) { // Purpur Slab +// blocks[c] = (byte)44; +// data.set(cx, cy, cz, (data.get(cx, cy, cz) & 8) == 8 ? 15 : 7); +// } +// else if(block == 182) { // Red Sandstone Slab +// blocks[c] = (byte)44; +// data.set(cx, cy, cz, (data.get(cx, cy, cz) & 8) == 8 ? 9 : 1); +// } } private static void convertTile(NBTTagCompound ent) { @@ -1001,13 +1113,17 @@ public abstract class Converter { return tag; } - private static long convertChunks(File dir, File file, long start, int progress, int total) { + private long convertChunks(File dir, File file, long start, int progress, int total) { String name = file.getName(); + this.file = name; + this.totalChunks = 1024; boolean legacy = name.endsWith(".mcr"); int rx, rz; String[] reg = name.split("\\."); if(reg.length != 4) { Log.JNI.warn("Unbekannte Region " + file); + this.doneChunks = 0; + this.file = null; return start; } try { @@ -1016,6 +1132,8 @@ public abstract class Converter { } catch(NumberFormatException e) { Log.JNI.warn("Unbekannte Region " + file); + this.doneChunks = 0; + this.file = null; return start; } try { @@ -1028,6 +1146,7 @@ public abstract class Converter { for(int bx = 0; bx < 4; bx++) { for(int bz = 0; bz < 4; bz++) { if(!oldreg.hasRegion(bx, bz)) { + this.doneChunks += 64; continue; } areas++; @@ -1042,6 +1161,7 @@ public abstract class Converter { DataInputStream in = oldreg.getInputStream(x, z); if(in == null) { Log.JNI.warn("Konnte " + file.getPath() + "@" + x + "," + z + " nicht lesen"); + this.doneChunks += 1; continue; } NBTTagCompound tag = NBTLoader.read(in); @@ -1052,6 +1172,7 @@ public abstract class Converter { // out.close(); newreg.writeTag(nx, nz, tag); } + this.doneChunks += 1; } } newreg.close(false); @@ -1069,26 +1190,36 @@ public abstract class Converter { catch(IOException e) { e.printStackTrace(); } + this.doneChunks = 0; + this.file = null; return start; } - public static boolean convert() { + public static FolderInfo convertMapFormat(File dir, boolean load) { long cur = System.currentTimeMillis(); - if(new File("server.nbt").exists()) - return false; - File ldat = new File("level.dat"); + if(load) + Log.JNI.info("Welt '" + dir + "' wird konvertiert"); + if(new File(dir, "level.nbt").exists()) { + if(load) + Log.JNI.error("Datei level.nbt existiert bereits"); + return null; + } + File ldat = new File(dir, "level.dat"); if(!ldat.exists()) - ldat = new File("level.dat_old"); - if(!ldat.exists()) - return false; - Log.JNI.info("Welt wird konvertiert"); + ldat = new File(dir, "level.dat_old"); + if(!ldat.exists()) { + if(load) + Log.JNI.error("Datei level.dat und level.dat_old nicht gefunden"); + return null; + } NBTTagCompound nbt; try { nbt = NBTLoader.readGZip(ldat); } catch(Exception e) { - Log.JNI.error(e, "Fehler beim Lesen von level.dat"); - return false; + if(load) + Log.JNI.error(e, "Fehler beim Lesen von level.dat"); + return null; } nbt = nbt.getCompoundTag("Data"); int version = nbt.getInteger("version"); @@ -1096,77 +1227,182 @@ public abstract class Converter { // nbt.setBoolean("incompatible", data >= 1400); SaveVersion ver = data >= 1400 ? SaveVersion.RELEASE_1_13 : (data >= 100 ? SaveVersion.RELEASE_1_9 : (version == 19132 || version == 19133 ? SaveVersion.BETA_1_3 : (version == 0 ? SaveVersion.ALPHA_1_0 : null))); if(ver == null) { - Log.IO.error("Version %d ist unbekannt", version); - return false; + if(load) + Log.IO.error("Version %d ist unbekannt", version); + return null; } long wtime = nbt.getLong(nbt.hasKey("DayTime", 99) ? "DayTime" : "Time") + World.START_TIME; - Log.IO.info("Version: %s", ver); - Log.IO.info("Weltzeit: %d Ticks / %d Sekunden", wtime, wtime / 20L); - Log.IO.info("Zuletzt geladen: %s", new SimpleDateFormat("dd.MM.yyyy HH:mm:ss").format(new Date(nbt.getLong("LastPlayed")))); - if(ver != SaveVersion.RELEASE_1_13) { - Log.JNI.info("Konvertiere Chunk-Daten von region/*.mca,*.mcr"); - File regionDir = new File("region"); - if(regionDir.exists()) { - File chunkDir = new File(new File("chunk"), "terra"); - Log.JNI.info("Konvertiere Welt nach '" + chunkDir + "' ..."); - Log.JNI.info("Durchsuche Ordner unter '" + regionDir + "' nach .mca- und .mcr-Dateien ..."); - File[] files = regionDir.listFiles(new FilenameFilter() { - public boolean accept(File file, String name) { - return name.endsWith(".mca") || name.endsWith(".mcr"); - } - }); - if(files.length == 0) { - Log.JNI.info("Keine .mca- oder .mcr-Dateien gefunden."); + if(!load) + return new FolderInfo(wtime, nbt.getLong("LastPlayed"), ver, null); +// nbt.setString("verdesc", ver); +// NBTTagCompound nbt = getLegacyWorldInfo(dir); +// if(nbt == null) +// return false; + final Converter conv = new Converter(); + Client.CLIENT.displayGuiScreen(new GuiLoading("Konvertiere Welt ...", new Callback() { + public void poll(Client gm, GuiLoading gui) { + if(conv.totalRegions > 0) { + gui.setBar(conv.task, "Regionen", conv.totalRegions); + gui.setProgress(conv.doneRegions); } else { - Log.JNI.info("Ingesamt wurden " + files.length + " .mca-Dateien und .mcr-Dateien gefunden, konvertiere ..."); - if(ver == SaveVersion.RELEASE_1_9) - Log.JNI.info("Konvertiere von neuerer Version, dies wird Blöcke entfernen ..."); - chunkDir.mkdirs(); - int progress = 0; - long time = System.currentTimeMillis(); - long start = postProgress(time, 0); - for(File file : files) { - int percent = (int)Math.round(100.0D * (double)progress / (double)files.length); - Log.JNI.info("Konvertiere Chunk-Daten: " + file.getName() + " (" + progress + "/" + files.length + ")"); - start = convertChunks(chunkDir, file, start, progress, files.length); - ++progress; - start = postProgress(start, percent); - } - time = System.currentTimeMillis() - time; - Log.JNI.info("Fertig. Konversion dauerte " + ((time / 60000L) > 0 ? ((time / 60000L) + " Minuten und ") : "") + ((time / 1000L) % 60L) + " Sekunden."); + gui.resetBar(); } + if(conv.totalChunks > 0) { + gui.setSub(conv.file, "Chunks", conv.totalChunks); + gui.setSubProgress(conv.doneChunks); + } + else { + gui.resetSub(); + } + gui.setTask(conv.action); } - } - else { - Log.JNI.warn("Konvertiere keine Chunk-Daten, da Version zu neu"); - } - Log.JNI.info("Konvertiere Daten von level.dat"); - Config.clear(); - UniverseRegistry.clear(); - if(nbt.hasKey("GameRules", 10)) { - NBTTagCompound rules = nbt.getCompoundTag("GameRules"); - for(Entry rule : OLD_GAMERULES.entrySet()) { - if(rules.hasKey(rule.getKey(), 8)) - Config.set(rule.getValue(), rules.getString(rule.getKey()), null); + })); + final NBTTagCompound tag = nbt; + new Thread(new Runnable() { + public void run() { + Log.IO.info("Version: %s", ver); + if(ver != SaveVersion.RELEASE_1_13) { + conv.action = "Suche nach Chunk-Daten"; + Log.JNI.info("Konvertiere Chunk-Daten von region/*.mca,*.mcr"); + File regionDir = new File(dir, "region"); + if(regionDir.exists()) { + File chunkDir = new File(new File(dir, "chunk"), "terra"); + Log.JNI.info("Konvertiere Welt nach '" + chunkDir + "' ..."); + Log.JNI.info("Durchsuche Ordner unter '" + regionDir + "' nach .mca- und .mcr-Dateien ..."); + File[] files = regionDir.listFiles(new FilenameFilter() { + public boolean accept(File file, String name) { + return name.endsWith(".mca") || name.endsWith(".mcr"); + } + }); + if(files.length == 0) { + Log.JNI.info("Keine .mca- oder .mcr-Dateien gefunden."); + } + else { + conv.task = "Konvertiere Chunkdaten"; + conv.totalRegions = files.length; + Log.JNI.info("Ingesamt wurden " + files.length + " .mca-Dateien und .mcr-Dateien gefunden, konvertiere ..."); + if(ver == SaveVersion.RELEASE_1_9) + Log.JNI.info("Konvertiere von neuerer Version, dies wird Blöcke entfernen ..."); + chunkDir.mkdirs(); + int progress = 0; + long time = System.currentTimeMillis(); + long start = conv.postProgress(time, 0); + for(File file : files) { + int percent = (int)Math.round(100.0D * (double)progress / (double)files.length); + Log.JNI.info("Konvertiere Chunk-Daten: " + file.getName() + " (" + progress + "/" + files.length + ")"); + start = conv.convertChunks(chunkDir, file, start, progress, files.length); + ++progress; + start = conv.postProgress(start, percent); + conv.doneRegions += 1; + } + time = System.currentTimeMillis() - time; + Log.JNI.info("Fertig. Konversion dauerte " + ((time / 60000L) > 0 ? ((time / 60000L) + " Minuten und ") : "") + ((time / 1000L) % 60L) + " Sekunden."); + } + } + } + else { + Log.JNI.warn("Konvertiere keine Chunk-Daten, da Version zu neu"); + } + conv.doneRegions = 0; + conv.task = null; + conv.action = "Konvertiere level.dat"; + Log.JNI.info("Konvertiere Daten von level.dat"); + Config.clear(); + UniverseRegistry.clear(); + if(tag.hasKey("GameRules", 10)) { + NBTTagCompound rules = tag.getCompoundTag("GameRules"); + for(Entry rule : OLD_GAMERULES.entrySet()) { + if(rules.hasKey(rule.getKey(), 8)) + Config.set(rule.getValue(), rules.getString(rule.getKey()), null); + } + } + // Config.setVar("noRespawn", "" + nbt.getBoolean("hardcore"), false); + // int id = nbt.getInteger("GameType"); + // Config.set("defaultNoCreative", "" + (id == 2 || id == 0), false); + Log.JNI.info("Speichere neue level.nbt ..."); + Region.saveWorldInfo(dir, wtime); +// if(tag.hasKey("Player", 10)) { +// conv.action = "Konvertiere Spielerdaten"; +// NBTTagCompound player = tag.getCompoundTag("Player"); +// NBTTagList pos = player.getTagList("Pos", 6); +// NBTTagList motion = player.getTagList("Motion", 6); +// NBTTagList rotation = player.getTagList("Rotation", 5); +// boolean ground = player.getBoolean("OnGround"); +// BlockPos spawn = null; +// // boolean force = player.getBoolean("OnGround"); +// // int mode = -1; +// // if(player.hasKey("playerGameType", 99)) { +// // mode = player.getInteger("playerGameType"); +// // mode = mode == 0 || mode == 2 ? 0 : (mode == 1 || mode == 3 ? 1 : -1); +// // } +// if(player.hasKey("SpawnX", 99) && player.hasKey("SpawnY", 99) && player.hasKey("SpawnZ", 99)) { +// spawn = new BlockPos(player.getInteger("SpawnX"), player.getInteger("SpawnY"), +// player.getInteger("SpawnZ")); +// // force = player.getBoolean("SpawnForced"); +// } +// player.getKeySet().clear(); +// player.setTag("Pos", pos); +// player.setTag("Motion", motion); +// player.setTag("Rotation", rotation); +// player.setBoolean("OnGround", ground); +// player.setInteger("Dimension", 1); +// player.setString("id", EntityRegistry.getEntityString(EntityHuman.class)); +// if(spawn != null) { +// player.setInteger("SpawnX", spawn.getX()); +// player.setInteger("SpawnY", spawn.getY()); +// player.setInteger("SpawnZ", spawn.getZ()); +// player.setInteger("SpawnDim", 1); +// // player.setBoolean("SpawnForced", force); +// } +// player.setInteger("OriginX", tag.getInteger("SpawnX")); +// player.setInteger("OriginY", tag.getInteger("SpawnY")); +// player.setInteger("OriginZ", tag.getInteger("SpawnZ")); +// player.setInteger("OriginDim", 1); +// player.setString("CustomName", user.substring(0, 1).toUpperCase() + user.substring(1)); +// NBTTagCompound plr = new NBTTagCompound(); +// plr.setInteger("selected", 0); +// NBTTagList list = new NBTTagList(); +// list.appendTag(player); +// plr.setTag("characters", list); +// // if(mode >= 0) +// // player.setBoolean("creative", mode == 1); +// Log.JNI.info("Speichere neue Spielerdaten " + user.toLowerCase() + ".nbt ..."); +// File pdat = new File(new File(dir, "players"), user.toLowerCase() + ".nbt"); +// try { +// pdat.getParentFile().mkdirs(); +// NBTLoader.writeGZip(plr, pdat); +// } +// catch(Exception e) { +// Log.JNI.error(e, "Fehler beim Schreiben von " + pdat); +// } +// } + Weather weather = tag.getBoolean("thundering") ? Weather.THUNDER : (tag.getBoolean("raining") ? Weather.RAIN : Weather.CLEAR); + if(weather != Weather.CLEAR) { + conv.action = "Konvertiere Dimensionsdaten"; + NBTTagCompound dataTag = new NBTTagCompound(); + dataTag.setString("Weather", weather.getName()); + Log.JNI.info("Speichere neue data.nbt ..."); + File dataFile = new File(new File(new File(dir, "chunk"), "terra"), "data.nbt"); + try { + NBTLoader.writeGZip(dataTag, dataFile); + } + catch(Exception e) { + Log.JNI.error(e, "Konnte Weltdaten nicht speichern"); + } + } + Log.IO.info("Welt '" + dir + "' wurde in %d Sekunden konvertiert", (System.currentTimeMillis() - cur) / 1000L); + Client.CLIENT.schedule(new Runnable() { + public void run() { + Client.CLIENT.displayGuiScreen(GuiConvert.INSTANCE); + } + }); } - } - Log.JNI.info("Speichere neue server.nbt ..."); - Server.saveServerConfig(wtime); - Weather weather = nbt.getBoolean("thundering") ? Weather.THUNDER : (nbt.getBoolean("raining") ? Weather.RAIN : Weather.CLEAR); - if(weather != Weather.CLEAR) { - NBTTagCompound dataTag = new NBTTagCompound(); - dataTag.setString("Weather", weather.getName()); - Log.JNI.info("Speichere neue data.nbt ..."); - File dataFile = new File(new File(new File("chunk"), "terra"), "data.nbt"); - try { - NBTLoader.writeGZip(dataTag, dataFile); - } - catch(Exception e) { - Log.JNI.error(e, "Konnte Weltdaten nicht speichern"); - } - } - Log.IO.info("Welt wurde in %d Sekunden konvertiert", (System.currentTimeMillis() - cur) / 1000L); - return true; + }, "Converter Thread").start(); + return new FolderInfo(wtime, System.currentTimeMillis(), null, Config.VERSION); } + +// public static NBTTagCompound getLegacyWorldInfo(File worldDir) { +// return nbt; +// } } diff --git a/common/src/common/ai/AIFireballAttack.java b/common/src/common/ai/AIFireballAttack.java index 23b492c..87a3b8d 100755 --- a/common/src/common/ai/AIFireballAttack.java +++ b/common/src/common/ai/AIFireballAttack.java @@ -30,7 +30,7 @@ public class AIFireballAttack extends EntityAIBase public boolean shouldExecute() { - return this.parentEntity.getNode().getAttackTarget() != null; + return this.parentEntity.getAttackTarget() != null; } public void startExecuting() @@ -45,7 +45,7 @@ public class AIFireballAttack extends EntityAIBase public void updateTask() { - EntityLiving target = this.parentEntity.getNode().getAttackTarget(); + EntityLiving target = this.parentEntity.getAttackTarget(); // double d0 = 64.0D; if (target.getDistanceSqToEntity(this.parentEntity) < this.distance * this.distance && this.parentEntity.canEntityBeSeen(target)) @@ -84,7 +84,7 @@ public class AIFireballAttack extends EntityAIBase world.spawnEntityInWorld(fireball); this.attackTimer = -this.delay * this.parentEntity.getRNG().range(1, 4); } - this.parentEntity.getNode().getLookHelper().setLookPositionWithEntity(target, 30.0f, 30.0f); + this.parentEntity.getLookHelper().setLookPositionWithEntity(target, 30.0f, 30.0f); } else if (this.attackTimer > 0) { diff --git a/common/src/common/ai/EntityAIControlledByPlayer.java b/common/src/common/ai/EntityAIControlledByPlayer.java index 1bee8cc..320f4d1 100755 --- a/common/src/common/ai/EntityAIControlledByPlayer.java +++ b/common/src/common/ai/EntityAIControlledByPlayer.java @@ -166,7 +166,7 @@ public class EntityAIControlledByPlayer extends EntityAIBase if (flag && 0 == WalkNodeProcessor.getColliding(this.thisEntity.worldObj, this.thisEntity, l, j, i1, j1, k1, l1, false, false, true) && 1 == WalkNodeProcessor.getColliding(this.thisEntity.worldObj, this.thisEntity, i, j + 1, k, j1, k1, l1, false, false, true) && 1 == WalkNodeProcessor.getColliding(this.thisEntity.worldObj, this.thisEntity, l, j + 1, i1, j1, k1, l1, false, false, true)) { - entitycreature.getNode().getJumpHelper().setJumping(); + entitycreature.getJumpHelper().setJumping(); } } diff --git a/common/src/common/ai/IEntityLivingNode.java b/common/src/common/ai/IEntityLivingNode.java deleted file mode 100644 index 6c10816..0000000 --- a/common/src/common/ai/IEntityLivingNode.java +++ /dev/null @@ -1,21 +0,0 @@ -package common.ai; - -import common.entity.DamageSource; -import common.entity.types.EntityLiving; -import common.nbt.NBTTagCompound; - -public interface IEntityLivingNode extends IEntityNode { - void update(); - void updateRenderAngles(); - void updateLeashedState(); - void setLeashTag(NBTTagCompound tag); - EntityLiving getAttacking(); - EntityLiving getAttackTarget(); - void resetCombat(); - void trackDamage(DamageSource source, int amount); - void sendDeathMessage(); - EntityJumpHelper getJumpHelper(); - EntityLookHelper getLookHelper(); - void updateAttacking(); - void dropExperience(); -} diff --git a/common/src/common/ai/IEntityMobNPCNode.java b/common/src/common/ai/IEntityMobNPCNode.java deleted file mode 100644 index b913f8c..0000000 --- a/common/src/common/ai/IEntityMobNPCNode.java +++ /dev/null @@ -1,14 +0,0 @@ -package common.ai; - -import common.entity.Entity; -import common.entity.types.EntityLiving; - -public interface IEntityMobNPCNode extends IEntityNPCNode { - - void becomeAngryAt(Entity entity); - - boolean isAngry(); - - void setAngerTarget(EntityLiving entity); - -} \ No newline at end of file diff --git a/common/src/common/ai/IEntityNPCNode.java b/common/src/common/ai/IEntityNPCNode.java deleted file mode 100644 index f513d38..0000000 --- a/common/src/common/ai/IEntityNPCNode.java +++ /dev/null @@ -1,9 +0,0 @@ -package common.ai; - -import common.entity.types.EntityLiving; - -public interface IEntityNPCNode extends IEntityLivingNode { - void setCombatTask(); - boolean canCounter(EntityLiving entity); - boolean canAttack(EntityLiving entity); -} diff --git a/common/src/common/ai/IEntityNode.java b/common/src/common/ai/IEntityNode.java index d38f988..d4d89ee 100644 --- a/common/src/common/ai/IEntityNode.java +++ b/common/src/common/ai/IEntityNode.java @@ -1,10 +1,17 @@ package common.ai; +import common.entity.DamageSource; +import common.entity.types.EntityLiving; import common.nbt.NBTTagCompound; -import common.world.World; public interface IEntityNode { - void readNbt(NBTTagCompound tag); - void writeNbt(NBTTagCompound tag); - void setWorld(World world); + void update(); + void updateRenderAngles(); + void updateLeashedState(); + void setLeashTag(NBTTagCompound tag); + EntityLiving getAttacking(); + EntityLiving getAttackTarget(); + void resetCombat(); + void trackDamage(DamageSource source, int amount); + void sendDeathMessage(); } diff --git a/common/src/common/entity/Entity.java b/common/src/common/entity/Entity.java index 8921c9a..61d7871 100755 --- a/common/src/common/entity/Entity.java +++ b/common/src/common/entity/Entity.java @@ -2,8 +2,6 @@ package common.entity; import java.util.List; -import common.ai.IEntityLivingNode; -import common.ai.IEntityNode; import common.block.Block; import common.block.BlockFence; import common.block.BlockFenceGate; @@ -47,14 +45,13 @@ import common.world.State; import common.world.World; import common.world.WorldServer; -public abstract class Entity +public abstract class Entity { private static final BoundingBox ZERO_AABB = new BoundingBox(0.0D, 0.0D, 0.0D, 0.0D, 0.0D, 0.0D); private static int nextID; protected final DataWatcher dataWatcher; protected final Random rand; - protected T node; private int eid; public World worldObj; @@ -120,14 +117,6 @@ public abstract class Entity public boolean isAirBorne; protected PortalType inPortal; // private boolean invulnerable; - - public T getNode() { - return this.node; - } - - public void setNode(T node) { - this.node = node; - } public int getId() { @@ -1141,8 +1130,6 @@ public abstract class Entity public void setWorld(World worldIn) { this.worldObj = worldIn; - if(this.node != null) - this.node.setWorld(worldIn); } /** @@ -1536,8 +1523,6 @@ public abstract class Entity tagCompund.setBoolean("IgnoreFall", this.ignoreFall); this.writeEntityToNBT(tagCompund); - if(this.node != null) - this.node.writeNbt(tagCompund); if (this.vehicle != null && !(this.isPlayer())) { @@ -1607,8 +1592,6 @@ public abstract class Entity // this.setSilent(tagCompund.getBoolean("Silent")); this.ignoreFall = tagCompund.getBoolean("IgnoreFall"); this.readEntityFromNBT(tagCompund); - if(this.node != null) - this.node.readNbt(tagCompund); if (this.shouldSetPosAfterLoading()) { diff --git a/common/src/common/entity/npc/AIHurtByAggressor.java b/common/src/common/entity/npc/AIHurtByAggressor.java deleted file mode 100644 index fe7838e..0000000 --- a/common/src/common/entity/npc/AIHurtByAggressor.java +++ /dev/null @@ -1,22 +0,0 @@ -package common.entity.npc; - -import common.ai.EntityAIHurtByTarget; -import common.entity.types.EntityLiving; - -public class AIHurtByAggressor extends EntityAIHurtByTarget -{ - public AIHurtByAggressor(EntityMobNPC p_i45828_1_) - { - super(p_i45828_1_, true); - } - - protected void setEntityAttackTarget(EntityLiving creatureIn, EntityLiving entityLivingBaseIn) - { - super.setEntityAttackTarget(creatureIn, entityLivingBaseIn); - - if (creatureIn.getClass() == this.taskOwner.getClass()) - { - ((EntityMobNPC)creatureIn).getNode().becomeAngryAt(entityLivingBaseIn); - } - } -} \ No newline at end of file diff --git a/common/src/common/entity/npc/EntityChaosMarine.java b/common/src/common/entity/npc/EntityChaosMarine.java index 1e18b2a..cccb1b3 100755 --- a/common/src/common/entity/npc/EntityChaosMarine.java +++ b/common/src/common/entity/npc/EntityChaosMarine.java @@ -108,7 +108,7 @@ public class EntityChaosMarine extends EntityNPC { return 20; } - public int getAttackSpeed() { + protected int getAttackSpeed() { return 5; } diff --git a/common/src/common/entity/npc/EntityGargoyle.java b/common/src/common/entity/npc/EntityGargoyle.java index 69914e3..0f6b358 100755 --- a/common/src/common/entity/npc/EntityGargoyle.java +++ b/common/src/common/entity/npc/EntityGargoyle.java @@ -141,6 +141,10 @@ public class EntityGargoyle extends EntityFlyingNPC // this.launchBoxToEntity(target); // } + public boolean isRangedWeapon(ItemStack stack) { + return false; + } + public boolean attackEntityFrom(DamageSource source, int amount) { // if (this.isEntityInvulnerable(source)) diff --git a/common/src/common/entity/npc/EntityMobNPC.java b/common/src/common/entity/npc/EntityMobNPC.java index c504d19..e36c35f 100755 --- a/common/src/common/entity/npc/EntityMobNPC.java +++ b/common/src/common/entity/npc/EntityMobNPC.java @@ -1,45 +1,317 @@ package common.entity.npc; -import common.ai.IEntityMobNPCNode; +import common.ai.EntityAIHurtByTarget; import common.entity.DamageSource; import common.entity.Entity; +import common.entity.attributes.AttributeInstance; +import common.entity.attributes.Attributes; import common.entity.types.EntityLiving; +import common.nbt.NBTTagCompound; import common.world.World; -public abstract class EntityMobNPC extends EntityNPC +public abstract class EntityMobNPC extends EntityNPC { - public T getNode() { - return this.node; - } - + private int angerLevel; +// private int randomSoundDelay; + private int angerTarget; +// private Class angerClass; + public EntityMobNPC(World worldIn) { super(worldIn); + this.targets.addTask(1, new AIHurtByAggressor(this)); +// this.targets.addTask(2, new AITargetAggressor(this)); } +// public boolean isImmuneToFire() +// { +// return true; +// } + public void setAttackedBy(EntityLiving livingBase) { super.setAttackedBy(livingBase); if (livingBase != null) { - this.node.setAngerTarget(livingBase); + this.angerTarget = livingBase.getId(); } } - + +// protected void applyEntityAI() +// { +// this.targets.addTask(1, new EntityMobNPC.AIHurtByAggressor(this)); +// this.targets.addTask(2, new EntityMobNPC.AITargetAggressor(this)); +// } + +// protected void applyEntityAttributes() +// { +// super.applyEntityAttributes(); +// this.getEntityAttribute(Attributes.REINFORCEMENT_CHANCE).setBaseValue(0.0D); +// this.getEntityAttribute(Attributes.MOVEMENT_SPEED).setBaseValue(0.23000000417232513D); +// this.getEntityAttribute(Attributes.ATTACK_DAMAGE).setBaseValue(5.0D); +// } + +// /** +// * Called to update the entity's position/logic. +// */ +// public void onUpdate() +// { +// super.onUpdate(); +// } + + protected void updateAITasks() + { + AttributeInstance iattributeinstance = this.getEntityAttribute(Attributes.MOVEMENT_SPEED); + + if (this.isAngry()) + { + if (/* !this.isChild() && */ !iattributeinstance.hasModifier(Attributes.RUSHING_SPEED_MOD)) + { + iattributeinstance.applyModifier(Attributes.RUSHING_SPEED_MOD); + } + + --this.angerLevel; + } + else if (iattributeinstance.hasModifier(Attributes.RUSHING_SPEED_MOD)) + { + iattributeinstance.removeModifier(Attributes.RUSHING_SPEED_MOD); + } + +// if (this.randomSoundDelay > 0 && --this.randomSoundDelay == 0) +// { +// this.playSound("mob.zombiepig.zpigangry", this.getSoundVolume() * 2.0F, ((this.rand.floatv() - this.rand.floatv()) * 0.2F + 1.0F) * 1.8F); +// } + + if (this.angerLevel > 0 && this.angerTarget != 0 && this.getAttackedBy() == null) + { + Entity entity = this.worldObj.getEntityByID(this.angerTarget); + if(entity instanceof EntityLiving) + this.setAttackedBy((EntityLiving)entity); + if(entity != null && entity.isPlayer()) + this.playerAttacker = (EntityNPC)entity; + this.recentlyHit = this.getAttackedTime(); + } + + super.updateAITasks(); + } + +// /** +// * Checks if the entity's current position is a valid location to spawn this entity. +// */ +// public boolean getCanSpawnHere() +// { +// return this.worldObj.getDifficulty() != Difficulty.PEACEFUL; +// } + + /** + * (abstract) Protected helper method to write subclass entity data to NBT. + */ + public void writeEntityToNBT(NBTTagCompound tagCompound) + { + super.writeEntityToNBT(tagCompound); + tagCompound.setShort("Anger", (short)this.angerLevel); + +// if (this.angerTarget != null) +// { +// tagCompound.setString("HurtBy", this.angerTarget); +// } +// else +// { +// tagCompound.setString("HurtBy", ""); +// } + } + + /** + * (abstract) Protected helper method to read subclass entity data from NBT. + */ + public void readEntityFromNBT(NBTTagCompound tagCompund) + { + super.readEntityFromNBT(tagCompund); + this.angerLevel = tagCompund.getShort("Anger"); +// String s = tagCompund.getString("HurtBy"); +// +// if (s.length() > 0) +// { +// this.angerTarget = s; +// EntityNPC entityplayer = this.worldObj.getPlayer(this.angerTarget); +// this.setAttackedBy(entityplayer); +// +// if (entityplayer != null) +// { +// this.playerAttacker = entityplayer; +// this.recentlyHit = this.getAttackedTime(); +// } +// } + } + + /** + * Called when the entity is attacked. + */ public boolean attackEntityFrom(DamageSource source, int amount) { +// if (this.isEntityInvulnerable(source)) +// { +// return false; +// } +// else +// { Entity entity = source.getEntity(); if (entity != null && entity instanceof EntityNPC) { - this.node.becomeAngryAt(entity); + this.becomeAngryAt(entity); } return super.attackEntityFrom(source, amount); +// } } - public boolean isAggressive(Class clazz) { - return this.node.isAngry() && clazz != this.getClass() && !this.isPeaceful(clazz); + /** + * Causes this PigZombie to become angry at the supplied Entity (which will be a player). + */ + private void becomeAngryAt(Entity p_70835_1_) + { + this.angerLevel = this.rand.excl(400, 800); +// this.randomSoundDelay = this.rand.zrange(40); + + if (p_70835_1_ instanceof EntityLiving) + { + this.setAttackedBy((EntityLiving)p_70835_1_); + } } + + public boolean isAngry() + { + return this.angerLevel > 0; + } + +// /** +// * Returns the sound this mob makes while it's alive. +// */ +// protected String getLivingSound() +// { +// return "mob.zombiepig.zpig"; +// } +// +// /** +// * Returns the sound this mob makes when it is hurt. +// */ +// protected String getHurtSound() +// { +// return "mob.zombiepig.zpighurt"; +// } +// +// /** +// * Returns the sound this mob makes on death. +// */ +// protected String getDeathSound() +// { +// return "mob.zombiepig.zpigdeath"; +// } + +// /** +// * Drop 0-2 items of this living's type +// * +// * @param wasRecentlyHit true if this this entity was recently hit by appropriate entity (generally only if player +// * or tameable) +// * @param lootingModifier level of enchanment to be applied to this drop +// */ +// protected void dropFewItems(boolean wasRecentlyHit, int lootingModifier) +// { +// int i = this.rand.zrange(2 + lootingModifier); +// +// for (int j = 0; j < i; ++j) +// { +// this.dropItem(Items.rotten_flesh, 1); +// } +// +// i = this.rand.zrange(2 + lootingModifier); +// +// for (int k = 0; k < i; ++k) +// { +// this.dropItem(Items.gold_nugget, 1); +// } +// } +// +// /** +// * Called when a player interacts with a mob. e.g. gets milk from a cow, gets into the saddle on a pig. +// */ +// public boolean interact(EntityNPC player) +// { +// return false; +// } +// +// /** +// * Causes this Entity to drop a random item. +// */ +// protected void addRandomDrop() +// { +// this.dropItem(Items.gold_ingot, 1); +// } +// +// /** +// * Gives armor or weapon for entity based on given DifficultyInstance +// */ +// protected void setEquipmentBasedOnDifficulty(DifficultyInstance difficulty) +// { +// this.setItem(0, new ItemStack(Items.golden_sword)); +// } +// +// /** +// * Called only once on an entity when first time spawned, via egg, mob spawner, natural spawning etc, but not called +// * when entity is reloaded from nbt. Mainly used for initializing attributes and inventory +// */ +// public IEntityLivingData onInitialSpawn(DifficultyInstance difficulty, IEntityLivingData livingdata) +// { +// super.onInitialSpawn(difficulty, livingdata); +//// this.setVillager(false); +// return livingdata; +// } + +// public int getColor() { +// return 0xff9494; +// } + +// public void onStruckByLightning(EntityLightning lightningBolt) { +// } + + public boolean isAggressive(Class clazz) { + return this.isAngry() && clazz != this.getClass() && !this.isPeaceful(clazz); + } + + static class AIHurtByAggressor extends EntityAIHurtByTarget + { + public AIHurtByAggressor(EntityMobNPC p_i45828_1_) + { + super(p_i45828_1_, true); + } + + protected void setEntityAttackTarget(EntityLiving creatureIn, EntityLiving entityLivingBaseIn) + { + super.setEntityAttackTarget(creatureIn, entityLivingBaseIn); + + if (creatureIn.getClass() == this.taskOwner.getClass()) + { + ((EntityMobNPC)creatureIn).becomeAngryAt(entityLivingBaseIn); + } + } + } + +// static class AITargetAggressor extends EntityAINearestAttackableTarget +// { +// public AITargetAggressor(EntityMobNPC p_i45829_1_) +// { +// super(p_i45829_1_, EntityLiving.class, 10, true, false, new Predicate() { +// public boolean test(EntityLiving entity) { +// return entity.isPlayer(); // || entity instanceof EntityNPC; +// } +// }); +// } +// +// public boolean shouldExecute() +// { +// return ((EntityMobNPC)this.taskOwner).isAngry() && super.shouldExecute(); +// } +// } } diff --git a/common/src/common/entity/npc/EntityNPC.java b/common/src/common/entity/npc/EntityNPC.java index 9eb5926..ffd5e7b 100755 --- a/common/src/common/entity/npc/EntityNPC.java +++ b/common/src/common/entity/npc/EntityNPC.java @@ -2,8 +2,24 @@ package common.entity.npc; import java.lang.reflect.InvocationTargetException; import java.util.List; +import java.util.function.Predicate; + import common.IClient; -import common.ai.IEntityNPCNode; +import common.ai.AIRangedAttack; +import common.ai.EntityAIAttackOnCollide; +import common.ai.EntityAIAvoidEntity; +import common.ai.EntityAIHurtByTarget; +import common.ai.EntityAILookAtTalkingPlayer; +import common.ai.EntityAINagPlayer; +import common.ai.EntityAINearestAttackableTarget; +import common.ai.EntityAINpcInteract; +import common.ai.EntityAINpcMate; +import common.ai.EntityAIOpenDoor; +import common.ai.EntityAIPlay; +import common.ai.EntityAISwimming; +import common.ai.EntityAIWander; +import common.ai.EntityAIWatchClosest; +import common.ai.EntityAIWatchClosest2; import common.block.Block; import common.block.BlockBed; import common.dimension.Space; @@ -62,6 +78,7 @@ import common.packet.CPacketInput; import common.packet.CPacketPlayer; import common.packet.SPacketEntityEquipment; import common.packet.SPacketEntityVelocity; +import common.pathfinding.PathNavigateGround; import common.potion.Potion; import common.potion.PotionEffect; import common.rng.Random; @@ -81,7 +98,7 @@ import common.world.World; import common.world.WorldClient; import common.world.WorldServer; -public abstract class EntityNPC extends EntityLiving +public abstract class EntityNPC extends EntityLiving { public static class CharacterTypeData { @@ -193,10 +210,6 @@ public abstract class EntityNPC extends EntityLiving extends EntityLiving extends EntityLiving extends Entity +public abstract class EntityLiving extends Entity { private static final ItemStack[] EMPTY_INV = new ItemStack[5]; + protected IEntityNode node; private AttributeMap attributes; private final Map effects = Maps.newEnumMap(Potion.class); public int soundTimer; @@ -104,6 +105,13 @@ public abstract class EntityLiving extends Entity extends Entity extends Entity 0) + { + --this.recentlyHit; + } + else + { + this.playerAttacker = null; + } + + if (this.attacker != null && !this.attacker.isEntityAlive()) + { + this.attacker = null; + } + +// if(this.attackedBy.isPlayer() && ((EntityNPC)this.attackedBy).capabilities.isCreativeMode) { +// this.attackedBy = null; // FIX Creative +// } + + if (this.attackedBy != null) + { + if (!this.attackedBy.isEntityAlive()) + { + this.setAttackedBy(null); + } + else if (this.ticksExisted - this.lastAttacked > 100) + { + this.setAttackedBy(null); + } + } + if(!this.worldObj.client) { - this.node.updateAttacking(); - if(!this.firstEffectUpdate && Config.radiation) { // && // (!(this.isPlayer()) || !((EntityNPCMP)this).creative)) { float radiation = this.radiation + (float)this.attributes.getAttributeInstance(Attributes.RADIATION).getAttributeValue(); @@ -357,9 +389,16 @@ public abstract class EntityLiving extends Entity 0 || this.isPlayer()) && this.canDropLoot() && Config.mobXP) { - this.node.dropExperience(); + int i = this.getExperiencePoints(this.playerAttacker); + + while (i > 0) + { + int j = EntityXp.getXPSplit(i); + i -= j; + this.worldObj.spawnEntityInWorld(new EntityXp(this.worldObj, this.posX, this.posY, this.posZ, j)); + } } this.setDead(); @@ -413,6 +452,46 @@ public abstract class EntityLiving extends Entity extends Entity> 9, z < 0 ? 'n' : 'p', ((z < 0) ? -z : z) >> 9); - } - - public static String getRegionName(int x, int z) { - return String.format("r.%c%X%c%X.rgn", x < 0 ? 'n' : 'p', ((x < 0) ? -x : x) >> 3, z < 0 ? 'n' : 'p', ((z < 0) ? -z : z) >> 3); - } } diff --git a/common/src/common/world/Region.java b/common/src/common/world/Region.java index ea0a6ae..06bbb84 100755 --- a/common/src/common/world/Region.java +++ b/common/src/common/world/Region.java @@ -22,7 +22,9 @@ import common.collect.Lists; import common.collect.Maps; import common.entity.Entity; import common.init.BlockRegistry; +import common.init.Config; import common.init.EntityRegistry; +import common.init.UniverseRegistry; import common.log.Log; import common.nbt.NBTLoader; import common.nbt.NBTTagCompound; @@ -31,9 +33,39 @@ import common.tileentity.TileEntity; import common.util.BlockPos; import common.util.NextTickListEntry; import common.util.NibbleArray; -import common.util.Util; public class Region { + public static enum SaveVersion { + ALPHA_1_0("Alpha 1.0 - Beta 1.2"), + BETA_1_3("Beta 1.3 - Release 1.8.9"), + RELEASE_1_9("Release 1.9 - Release 1.12.2"), + RELEASE_1_13("Release 1.13 +"); + + private final String name; + + private SaveVersion(String name) { + this.name = name; + } + + public String toString() { + return this.name; + } + } + + public static class FolderInfo { + public final long time; + public final long lastPlayed; + public final SaveVersion legacy; + public final String version; + + public FolderInfo(long time, long lastPlayed, SaveVersion legacy, String version) { + this.time = time; + this.lastPlayed = lastPlayed; + this.legacy = legacy; + this.version = version; + } + } + private static class ChunkBuffer extends ByteArrayOutputStream { public ChunkBuffer() { super(8096); @@ -58,7 +90,10 @@ public class Region { private static final Map CACHE = Maps.newHashMap(); private static final List QUEUE = Collections.synchronizedList(Lists.newArrayList()); - + +// public static long lastPlayed; +// public static int version; +// public static String owner; private static volatile long queued; private static volatile long saved; private static volatile boolean waiting; @@ -78,10 +113,10 @@ public class Region { private boolean modified; public Region(File dir, int x, int z) { - File sdir = new File(dir, Util.getRegionFolder(x << 3, z << 3)); + File sdir = new File(dir, getRegionFolder(x << 3, z << 3)); if(!sdir.exists()) sdir.mkdirs(); - this.regFile = new File(sdir, Util.getRegionName(x << 3, z << 3)); + this.regFile = new File(sdir, getRegionName(x << 3, z << 3)); this.folder = dir; this.xPos = x; this.zPos = z; @@ -278,6 +313,13 @@ public class Region { this.write(x, z, buf.getData(), buf.size()); } +// public NBTTagCompound readTag(int x, int z) throws IOException { +// byte[] data = this.read(x, z); +// if(data == null) +// return null; +// return CompressedStreamTools.read(new DataInputStream(new BufferedInputStream(new InflaterInputStream(new ByteArrayInputStream(data))))); +// } + public File getFile() { return this.regFile; } @@ -294,7 +336,7 @@ public class Region { } private static File getExpansionFile(File dir, int x, int z) { - File sdir = new File(dir, Util.getRegionFolder(x, z)); + File sdir = new File(dir, getRegionFolder(x, z)); if(!sdir.exists()) sdir.mkdirs(); return new File(sdir, String.format("c.%c%X%c%X.chk", x < 0 ? 'n' : 'p', (x < 0) ? -x : x, z < 0 ? 'n' : 'p', (z < 0) ? -z : z)); @@ -357,6 +399,14 @@ public class Region { // getRegionFile(dir, x >> 3, z >> 3).writeTag(x & 7, z & 7, tag); } + public static String getRegionFolder(int x, int z) { + return String.format("%c%03X%c%03X", x < 0 ? 'n' : 'p', ((x < 0) ? -x : x) >> 9, z < 0 ? 'n' : 'p', ((z < 0) ? -z : z) >> 9); + } + + public static String getRegionName(int x, int z) { + return String.format("r.%c%X%c%X.rgn", x < 0 ? 'n' : 'p', ((x < 0) ? -x : x) >> 3, z < 0 ? 'n' : 'p', ((z < 0) ? -z : z) >> 3); + } + public static Chunk readNbt(WorldServer world, int x, int z, NBTTagCompound tag) { // if(!tag.hasKey("Level", 10)) { // Log.error("Chunk-Datei bei " + x + "," + z + " hat keine Level-Daten, überspringe"); @@ -630,4 +680,93 @@ public class Region { public static void killIO() { killed = true; } + + public static void saveWorldInfo(File worldDir, long time) { + NBTTagCompound data = new NBTTagCompound(); + data.setLong("Time", time); + data.setLong("LastAccess", System.currentTimeMillis()); + data.setString("Version", Config.VERSION); + NBTTagCompound cfg = new NBTTagCompound(); + for(String cvar : Config.VARS.keySet()) { + cfg.setString(cvar, Config.VARS.get(cvar).getValue()); +// Config.Value value = Config.VARS.get(cvar); +// switch(value.getType()) { +// case BOOLEAN: +// cfg.setString(cvar, "" + value.getBoolean()); +// break; +// case INTEGER: +// cfg.setString(cvar, "" + value.getInt()); +// break; +// case FLOAT: +// cfg.setString(cvar, "" + value.getFloat()); +// break; +// case STRING: +// cfg.setString(cvar, value.getString()); +// break; +// } + } + data.setTag("Config", cfg); + data.setTag("Universe", UniverseRegistry.saveNbt()); + if(worldDir != null) + worldDir.mkdirs(); + File nfile = new File(worldDir, "level.nbt.tmp"); + File lfile = new File(worldDir, "level.nbt"); + try { +// File ofile = new File(worldDir, "level.nbt_old"); + NBTLoader.writeGZip(data, nfile); +// if(ofile.exists()) +// ofile.delete(); +// lfile.renameTo(ofile); + if(lfile.exists()) + lfile.delete(); + nfile.renameTo(lfile); +// if(nfile.exists()) +// nfile.delete(); + } + catch(Exception e) { + Log.JNI.error(e, "Fehler beim Schreiben von " + nfile); + } + } + + public static FolderInfo loadWorldInfo(File worldDir) { + Config.clear(); + UniverseRegistry.clear(); + File file = new File(worldDir, "level.nbt"); + if(!file.exists()) + file = new File(worldDir, "level.nbt.tmp"); + if(file.exists()) { + try { + NBTTagCompound tag = NBTLoader.readGZip(file); + NBTTagCompound cfg = tag.getCompoundTag("Config"); + for(String key : cfg.getKeySet()) { + Config.set(key, cfg.getString(key), null); + } + UniverseRegistry.loadNbt(tag.getCompoundTag("Universe")); + // tag.getInteger("Version"); + long lastPlayed = tag.getLong("LastAccess"); + String version = tag.hasKey("Version", 8) ? tag.getString("Version") : null; + version = version != null && version.isEmpty() ? null : version; + long time = tag.hasKey("Time", 4) ? tag.getLong("Time") : World.START_TIME; + return new FolderInfo(time, lastPlayed, null, version); + } + catch(Exception e) { + Log.JNI.error(e, "Fehler beim Lesen von " + file); + } + } + return null; + } + +// public static void reloadWorldInfo(File worldDir) { +// File file = new File(worldDir, "level.nbt"); +// if(file.exists()) { +// Config.clear(); +// try { +// Config.readFromNbt(NBTLoader.readGZip(file).getCompoundTag("Config"), true); +// } +// catch(Exception e) { +// Log.error("Fehler beim Lesen von " + file, e); +// return; +// } +// } +// } } diff --git a/common/src/common/world/WorldServer.java b/common/src/common/world/WorldServer.java index e6edce1..934b9ee 100755 --- a/common/src/common/world/WorldServer.java +++ b/common/src/common/world/WorldServer.java @@ -962,7 +962,6 @@ public final class WorldServer extends World { } protected void onEntityAdded(Entity entityIn) { - // TODO: add node this.trackEntity(entityIn); this.entityIds.addKey(entityIn.getId(), entityIn); Entity[] aentity = entityIn.getParts(); diff --git a/server/src/server/Server.java b/server/src/server/Server.java index c69725b..728a53d 100755 --- a/server/src/server/Server.java +++ b/server/src/server/Server.java @@ -6,11 +6,9 @@ import java.io.File; import java.io.IOException; import java.io.InputStreamReader; import java.net.InetAddress; -import java.text.SimpleDateFormat; import java.util.ArrayDeque; import java.util.ArrayList; import java.util.Collections; -import java.util.Date; import java.util.Iterator; import java.util.List; import java.util.Map; @@ -76,6 +74,7 @@ import common.util.WorldPos; import common.world.Region; import common.world.World; import common.world.WorldServer; +import common.world.Region.FolderInfo; import io.netty.bootstrap.ServerBootstrap; import io.netty.channel.Channel; import io.netty.channel.ChannelException; @@ -91,10 +90,8 @@ import io.netty.util.concurrent.Future; import io.netty.util.concurrent.GenericFutureListener; import server.command.CommandEnvironment; import server.command.FixedExecutor; -import server.init.NodeRegistry; import server.network.HandshakeHandler; import server.network.Player; -import server.world.Converter; public final class Server implements IThreadListener, IServer { private static final LazyLoadBase SERVER_NIO_EVENTLOOP = new LazyLoadBase() { @@ -144,7 +141,6 @@ public final class Server implements IThreadListener, IServer { public static void main(String[] args) { Util.checkOs(); Registry.setup("Server thread"); - NodeRegistry.register(); boolean debug = System.getProperty("server.debug", null) != null; boolean ipc = debug || System.getProperty("server.pipe", null) != null; int port = Integer.parseInt(System.getProperty("server.port", "" + Config.PORT)); @@ -159,63 +155,6 @@ public final class Server implements IThreadListener, IServer { Log.flushLog(); } - public static void saveServerConfig(long time) { - NBTTagCompound data = new NBTTagCompound(); - data.setLong("Time", time); - data.setLong("LastAccess", System.currentTimeMillis()); - data.setString("Version", Config.VERSION); - NBTTagCompound cfg = new NBTTagCompound(); - for(String cvar : Config.VARS.keySet()) { - cfg.setString(cvar, Config.VARS.get(cvar).getValue()); - } - data.setTag("Config", cfg); - data.setTag("Universe", UniverseRegistry.saveNbt()); - File nfile = new File("server.nbt.tmp"); - File lfile = new File("server.nbt"); - try { - NBTLoader.writeGZip(data, nfile); - if(lfile.exists()) - lfile.delete(); - nfile.renameTo(lfile); - } - catch(Exception e) { - Log.IO.error(e, "Fehler beim Schreiben von " + nfile); - } - } - - public static long loadServerConfig() { - Config.clear(); - UniverseRegistry.clear(); - File file = new File("server.nbt"); - if(!file.exists()) - file = new File("server.nbt.tmp"); - if(file.exists()) { - try { - NBTTagCompound tag = NBTLoader.readGZip(file); - NBTTagCompound cfg = tag.getCompoundTag("Config"); - for(String key : cfg.getKeySet()) { - Config.set(key, cfg.getString(key), null); - } - UniverseRegistry.loadNbt(tag.getCompoundTag("Universe")); - long lastPlayed = tag.getLong("LastAccess"); - String version = tag.hasKey("Version", 8) ? tag.getString("Version") : null; - version = version != null && version.isEmpty() ? "" : version; - long time = tag.hasKey("Time", 4) ? tag.getLong("Time") : World.START_TIME; - Log.IO.info("Version: %s", version); - Log.IO.info("Weltzeit: %d Ticks / %d Sekunden", time, time / 20L); - Log.IO.info("Zuletzt geladen: %s", new SimpleDateFormat("dd.MM.yyyy HH:mm:ss").format(new Date(lastPlayed))); - return time; - } - catch(Exception e) { - Log.IO.error(e, "Fehler beim Lesen von " + file); - Config.clear(); - UniverseRegistry.clear(); - } - } - Log.IO.info("Erstelle neue Welt und Konfiguration"); - return World.START_TIME; - } - private Server(boolean debug, boolean ipc) { this.debug = debug; this.ipcpipe = ipc; @@ -243,7 +182,7 @@ public final class Server implements IThreadListener, IServer { public void saveWorldInfo() { if(!this.debug) { - saveServerConfig(this.space.getDayTime()); + Region.saveWorldInfo(null, this.space.getDayTime()); WorldServer.saveWarps(this.warps); } } @@ -318,14 +257,13 @@ public final class Server implements IThreadListener, IServer { long time = System.currentTimeMillis(); Log.JNI.info("Starte Server Version " + Config.VERSION); if(!this.debug) { - Converter.convert(); this.setMessage("Welt wird erstellt und geladen"); - long wtime = loadServerConfig(); + FolderInfo info = Region.loadWorldInfo(null); // if(dtime == -1L) // { // dtime = World.START_TIME; //// Config.set("spawnDim", "1", null); //// } - this.worlds.add(this.space = new WorldServer(this, wtime, + this.worlds.add(this.space = new WorldServer(this, info == null ? World.START_TIME : info.time, Space.INSTANCE, false)); this.dimensions.put(this.space.dimension.getDimensionId(), this.space); new File("players").mkdirs(); diff --git a/server/src/server/ai/EntityLivingNode.java b/server/src/server/ai/EntityLivingNode.java deleted file mode 100644 index 584f859..0000000 --- a/server/src/server/ai/EntityLivingNode.java +++ /dev/null @@ -1,537 +0,0 @@ -package server.ai; - -import java.util.List; - -import common.ai.EntityAIBase; -import common.ai.EntityAIMoveTowardsRestriction; -import common.ai.EntityAITasks; -import common.ai.EntityJumpHelper; -import common.ai.EntityLookHelper; -import common.ai.EntityMoveHelper; -import common.ai.EntitySenses; -import common.ai.IEntityLivingNode; -import common.block.Block; -import common.collect.Lists; -import common.color.TextColor; -import common.entity.DamageSource; -import common.entity.Entity; -import common.entity.EntityDamageSource; -import common.entity.item.EntityLeashKnot; -import common.entity.item.EntityXp; -import common.entity.npc.EntityNPC; -import common.entity.types.CombatEntry; -import common.entity.types.EntityBodyHelper; -import common.entity.types.EntityLiving; -import common.entity.types.EntityTameable; -import common.init.Blocks; -import common.init.Config; -import common.item.ItemStack; -import common.nbt.NBTTagCompound; -import common.network.IPlayer; -import common.pathfinding.PathNavigate; -import common.pathfinding.PathNavigateGround; -import common.rng.Random; -import common.util.BlockPos; -import common.world.WorldServer; - -public abstract class EntityLivingNode extends EntityNode implements IEntityLivingNode { - protected final Random rand; - private final List combat = Lists.newArrayList(); - private EntityLookHelper lookHelper; - protected EntityMoveHelper moveHelper; - protected EntityJumpHelper jumpHelper; - private EntityBodyHelper bodyHelper; - protected PathNavigate navigator; - protected final EntityAITasks tasks; - protected final EntityAITasks targets; - private EntityLiving target; - private EntitySenses senses; - private NBTTagCompound leashTag; - private boolean isMovementAITaskSet; - private EntityAIBase aiBase; - private boolean attacked; - private boolean damaged; - private String blockType; - private int lastDamaged; - protected EntityNPC playerAttacker; - private EntityLiving attackedBy; - protected int lastDamage; - protected int recentlyHit; - private int lastAttacked; - private EntityLiving attacker; - private int lastAttackTime; - - public EntityLivingNode(T entity) { - super(entity); - this.rand = entity.getRNG(); - this.tasks = new EntityAITasks(); - this.targets = new EntityAITasks(); - this.lookHelper = new EntityLookHelper(entity); - this.moveHelper = new EntityMoveHelper(entity); - this.jumpHelper = new EntityJumpHelper(entity); - this.bodyHelper = new EntityBodyHelper(entity); - this.navigator = this.getNewNavigator(); - this.senses = new EntitySenses(entity); - this.aiBase = new EntityAIMoveTowardsRestriction(entity, 1.0D); - this.registerTasks(); - } - - public T getEntity() { - return this.entity; - } - - public EntityLiving getAttackingEntity() { - EntityLiving attacking = this.getAttacking(); - return attacking != null ? attacking : (this.playerAttacker != null ? this.playerAttacker : (this.attackedBy != null ? this.attackedBy : null)); - } - - protected PathNavigate getNewNavigator() { - return new PathNavigateGround(this.entity, this.entity.worldObj); - } - -// protected PathNavigate getNewNavigator() { EntityArachnoid -// return new PathNavigateClimber(this.entity, this.entity.worldObj); -// } - - protected abstract void registerTasks(); - - public EntityLookHelper getLookHelper() { - return this.lookHelper; - } - - public EntityMoveHelper getMoveHelper() { - return this.moveHelper; - } - - public EntityJumpHelper getJumpHelper() { - return this.jumpHelper; - } - - public PathNavigate getNavigator() { - return this.navigator; - } - - public EntitySenses getEntitySenses() { - return this.senses; - } - - public EntityLiving getAttackTarget() { - return this.target; - } - - public void setAttackTarget(EntityLiving entitylivingbaseIn) { - this.target = entitylivingbaseIn; - } - - public boolean hasPath() - { - return !this.navigator.noPath(); - } - - public void updateRenderAngles() { - this.bodyHelper.updateRenderAngles(); - } - - protected void updateAITasks() { - } - - public void update() { - this.senses.clearSensingCache(); - this.targets.onUpdateTasks(); - this.tasks.onUpdateTasks(); - this.navigator.onUpdateNavigation(); - this.updateAITasks(); - this.moveHelper.onUpdateMoveHelper(); - this.lookHelper.onUpdateLook(); - this.jumpHelper.doJump(); - } - - public void setLeashTag(NBTTagCompound tag) { - this.leashTag = tag; - } - - private void recreateLeash() { - if(this.entity.getLeashed() && this.leashTag != null) { -// if(this.leashTag.hasKey("PlayerName", 8)) { -// String id = this.leashTag.getString("PlayerName"); -// if(!id.isEmpty()) { -// for(EntityNPC entitylivingbase : this.worldObj.getEntitiesWithinAABB(EntityNPC.class, -// this.getEntityBoundingBox().expand(10.0D, 10.0D, 10.0D))) { -// if(entitylivingbase.getUser().equals(id)) { -// this.leashedTo = entitylivingbase; -// break; -// } -// } -// } -// } -// else - if(this.leashTag.hasKey("X", 99) && this.leashTag.hasKey("Y", 99) && this.leashTag.hasKey("Z", 99)) { - BlockPos blockpos = new BlockPos(this.leashTag.getInteger("X"), this.leashTag.getInteger("Y"), - this.leashTag.getInteger("Z")); - EntityLeashKnot entityleashknot = EntityLeashKnot.getKnotForPosition(this.entity.worldObj, blockpos); - - if(entityleashknot == null) { - entityleashknot = EntityLeashKnot.createKnot(this.entity.worldObj, blockpos); - } - - this.entity.setLeashedTo(entityleashknot, false); - } - else { - this.entity.clearLeashed(false, true); - } - } - - this.leashTag = null; - } - - protected void onUpdateLeashed(float distance) - { - } - -// protected void onUpdateLeashed(float distance) EntityHorse -// { -// if (distance > 6.0F && this.entity.isEatingHaystack()) -// { -// this.entity.setEatingHaystack(false); -// } -// } - - public void updateLeashedState() { - if(this.leashTag != null) { - this.recreateLeash(); - } - - if(this.entity.getLeashed()) { - if(!this.entity.isEntityAlive()) { - this.entity.clearLeashed(true, true); - } - - if(this.entity.getLeashedTo() == null || this.entity.getLeashedTo().dead) { - this.entity.clearLeashed(true, true); - } - } - - if (this.entity.getLeashed() && this.entity.getLeashedTo() != null && this.entity.getLeashedTo().worldObj == this.entity.worldObj) - { - Entity entity = this.entity.getLeashedTo(); - this.entity.setHomePosAndDistance(new BlockPos((int)entity.posX, (int)entity.posY, (int)entity.posZ), 5); - float f = this.entity.getDistanceToEntity(entity); - - if (this.entity instanceof EntityTameable && ((EntityTameable)this.entity).isSitting()) - { - if (f > 10.0F) - { - this.entity.clearLeashed(true, true); - } - - return; - } - - if (!this.isMovementAITaskSet) - { - this.tasks.addTask(2, this.aiBase); - - if (this.getNavigator() instanceof PathNavigateGround) - { - ((PathNavigateGround)this.getNavigator()).setAvoidsWater(false); - } - - this.isMovementAITaskSet = true; - } - - this.onUpdateLeashed(f); - - if (f > 4.0F) - { - this.getNavigator().tryMoveToEntityLiving(entity, 1.0D); - } - - if (f > 6.0F) - { - double d0 = (entity.posX - this.entity.posX) / (double)f; - double d1 = (entity.posY - this.entity.posY) / (double)f; - double d2 = (entity.posZ - this.entity.posZ) / (double)f; - this.entity.motionX += d0 * Math.abs(d0) * 0.4D; - this.entity.motionY += d1 * Math.abs(d1) * 0.4D; - this.entity.motionZ += d2 * Math.abs(d2) * 0.4D; - } - - if (f > 10.0F) - { - this.entity.clearLeashed(true, true); - } - } - else if (!this.entity.getLeashed() && this.isMovementAITaskSet) - { - this.isMovementAITaskSet = false; - this.tasks.removeTask(this.aiBase); - - if (this.getNavigator() instanceof PathNavigateGround) - { - ((PathNavigateGround)this.getNavigator()).setAvoidsWater(true); - } - - this.entity.detachHome(); - } - } - - public void trackDamage(DamageSource source, int amount) { - this.resetCombat(); - this.blockType = null; - if(this.entity.isOnLadder()) { - Block block = this.entity.worldObj - .getState(new BlockPos(this.entity.posX, this.entity.getEntityBoundingBox().minY, this.entity.posZ)).getBlock(); - if(block == Blocks.ladder) - this.blockType = "von einer Leiter"; - else if(block == Blocks.vine) - this.blockType = "von Ranken"; - } - else if(this.entity.isInLiquid()) { - this.blockType = "aus dem Wasser"; - } - CombatEntry entry = new CombatEntry(source, amount, this.blockType, this.entity.fallDistance); - this.combat.add(entry); - this.lastDamaged = this.entity.ticksExisted; - this.damaged = true; - if(entry.getSource().getEntity() instanceof EntityLiving && !this.attacked && this.entity.isEntityAlive()) - this.attacked = true; - } - - public void sendDeathMessage() { - this.sendDeathMessage(false, false); - } - - protected void sendDeathMessage(boolean natural, boolean forAll) { -// if(this.entity.worldObj.client) -// return; - String msg; - String kill; - IPlayer receiver = null; - if(this.combat.size() == 0) { - msg = kill = natural ? String.format("%s starb", this.entity.getColoredName(TextColor.LGRAY)) : null; - } - else { - CombatEntry strong = null; - CombatEntry block = null; - int min = 0; - float max = 0.0F; - - for(int z = 0; z < this.combat.size(); ++z) { - CombatEntry entry = (CombatEntry)this.combat.get(z); - CombatEntry last = z > 0 ? (CombatEntry)this.combat.get(z - 1) : null; - - if((entry.getSource() == DamageSource.fall || entry.getSource() == DamageSource.outOfWorld) && - entry.getFallDistance() > 0.0F && (strong == null || entry.getFallDistance() > max)) { - if(z > 0) { - strong = last; - } - else { - strong = entry; - } - - max = entry.getFallDistance(); - } - - if(entry.getBlockType() != null && (block == null || entry.getDamage() > min)) { - block = entry; - } - } - CombatEntry fall = max > 5.0F && strong != null ? strong : (min > 5 && block != null ? block : null); - CombatEntry last = (CombatEntry)this.combat.get(this.combat.size() - 1); - Entity lastEnt = last.getSource().getEntity(); - - if(fall != null && last.getSource() == DamageSource.fall) { - if(fall.getSource() != DamageSource.fall && fall.getSource() != DamageSource.outOfWorld) { - Entity fallEnt = fall.getSource().getEntity(); - if(fallEnt != null && (lastEnt == null || fallEnt != lastEnt)) { - ItemStack fallItem = fallEnt instanceof EntityLiving ? ((EntityLiving)fallEnt).getHeldItem() : null; - receiver = fallEnt.isPlayer() ? ((EntityNPC)fallEnt).connection : null; - if(fallItem != null) { // && fallItem.hasDisplayName()) { - msg = String.format("%s wurde von %s mit %s zum Fallen verdammt", this.entity.getColoredName(TextColor.CYAN), - fallEnt.getColoredName(TextColor.CYAN), fallItem.getColoredName(TextColor.CYAN)); - kill = String.format(TextColor.CYAN + "* %s mit %s zum Fallen verdammt", - this.entity.getColoredName(TextColor.CYAN), fallItem.getColoredName(TextColor.CYAN)); - } - else { - msg = String.format("%s wurde von %s zum Fallen verdammt", this.entity.getColoredName(TextColor.CYAN), - fallEnt.getColoredName(TextColor.CYAN)); - kill = String.format(TextColor.CYAN + "* %s zum Fallen verdammt", - this.entity.getColoredName(TextColor.CYAN)); - } - } - else if(lastEnt != null) { - ItemStack lastItem = lastEnt instanceof EntityLiving ? ((EntityLiving)lastEnt).getHeldItem() : null; - receiver = lastEnt.isPlayer() ? ((EntityNPC)lastEnt).connection : null; - if(lastItem != null) { // && lastItem.hasDisplayName()) { - msg = String.format("%s fiel zu tief und wurde von %s mit %s erledigt", - this.entity.getColoredName(TextColor.BLUE), - lastEnt.getColoredName(TextColor.BLUE), lastItem.getColoredName(TextColor.BLUE)); - kill = String.format(TextColor.BLUE + "* %s mit %s erledigt", - this.entity.getColoredName(TextColor.BLUE), lastItem.getColoredName(TextColor.BLUE)); - } - else { - msg = String.format("%s fiel zu tief und wurde von %s erledigt", this.entity.getColoredName(TextColor.BLUE), - lastEnt.getColoredName(TextColor.BLUE)); - kill = String.format(TextColor.BLUE + "%s erledigt", this.entity.getColoredName(TextColor.BLUE)); - } - } - else { - msg = kill = natural ? String.format("%s wurde zum Fallen verdammt", this.entity.getColoredName(TextColor.CYAN)) : null; - } - } - else { - msg = kill = natural ? String.format("%s fiel " + (fall.getBlockType() == null ? "aus zu großer Höhe" : fall.getBlockType()), - this.entity.getColoredName(TextColor.NEON)) : null; - } - } - else { - receiver = last.getSource().getEntity() != null && last.getSource().getEntity().isPlayer() ? ((EntityNPC)last.getSource().getEntity()).connection : null; - msg = natural || (last.getSource() instanceof EntityDamageSource ? last.getSource().getEntity() != null : this.entity.getAttackingEntity() != null) ? last.getSource().getDeathMessage(this.entity) : null; - kill = msg == null ? null : last.getSource().getKillMessage(this.entity); - } - } - if(msg == null) - return; - if(receiver != null) - receiver.addFeed(kill); - if(forAll) - for(IPlayer player : ((WorldServer)this.entity.worldObj).getServer().getIPlayers()) { - if(player != receiver) - player.addFeed(msg); - } - } - - public EntityLiving getAttacking() { - EntityLiving entity = null; - EntityNPC player = null; - int edmg = 0; - int pdmg = 0; - for(CombatEntry entry : this.combat) { - if(entry.getSource().getEntity() != null && entry.getSource().getEntity().isPlayer() && (player == null || entry.getDamage() > pdmg)) { - pdmg = entry.getDamage(); - player = (EntityNPC)entry.getSource().getEntity(); - } - if(entry.getSource().getEntity() instanceof EntityLiving && (entity == null || entry.getDamage() > edmg)) { - edmg = entry.getDamage(); - entity = (EntityLiving)entry.getSource().getEntity(); - } - } - return player != null && pdmg >= edmg / 3 ? player : entity; - } - - public void resetCombat() { - int timeout = this.attacked ? 300 : 100; - if(this.damaged && (!this.entity.isEntityAlive() || this.entity.ticksExisted - this.lastDamaged > timeout)) { - this.damaged = false; - this.attacked = false; - this.combat.clear(); - } - } - - public int getMaxFallHeight() { - if(this.target == null) { - return 3; - } - else { - int i = (int)((float)this.entity.getHealth() - (float)this.entity.getMaxHealth() * 0.33F); -// i = i - (3 - this.worldObj.getDifficulty().getId()) * 4; - - if(i < 0) { - i = 0; - } - - return i + 3; - } - } - -// public int getMaxFallHeight() EntityHaunter -// { -// return this.getAttackTarget() == null ? 3 : 3 + (this.getHealth() - 1); -// } - - public void updateAttacking() { - if (this.recentlyHit > 0) - { - --this.recentlyHit; - } - else - { - this.playerAttacker = null; - } - - if (this.attacker != null && !this.attacker.isEntityAlive()) - { - this.attacker = null; - } - -// if(this.attackedBy.isPlayer() && ((EntityNPC)this.attackedBy).capabilities.isCreativeMode) { -// this.attackedBy = null; // FIX Creative -// } - - if (this.attackedBy != null) - { - if (!this.attackedBy.isEntityAlive()) - { - this.setAttackedBy(null); - } - else if (this.entity.ticksExisted - this.lastAttacked > 100) - { - this.setAttackedBy(null); - } - } - } - - public void dropExperience() { - if ((this.recentlyHit > 0 || this.player) && this.entity.canDropLoot() && Config.mobXP) - { - int i = this.entity.getExperiencePoints(this.playerAttacker); - - while (i > 0) - { - int j = EntityXp.getXPSplit(i); - i -= j; - this.world.spawnEntityInWorld(new EntityXp(this.world, this.entity.posX, this.entity.posY, this.entity.posZ, j)); - } - } - } - - public EntityLiving getAttackedBy() - { - return this.attackedBy; - } - - public int getAttackedTime() - { - return this.lastAttacked; - } - - public void setAttackedBy(EntityLiving livingBase) - { - this.attackedBy = livingBase; - this.lastAttacked = this.entity.ticksExisted; - } - - public EntityLiving getLastAttack() - { - return this.attacker; - } - - public int getLastAttackTime() - { - return this.lastAttackTime; - } - - public void setLastAttack(Entity entity) - { - if (entity instanceof EntityLiving) - { - this.attacker = (EntityLiving)entity; - } - else - { - this.attacker = null; - } - - this.lastAttackTime = this.entity.ticksExisted; - } -} diff --git a/server/src/server/ai/EntityMobNPCNode.java b/server/src/server/ai/EntityMobNPCNode.java deleted file mode 100644 index 0779e52..0000000 --- a/server/src/server/ai/EntityMobNPCNode.java +++ /dev/null @@ -1,84 +0,0 @@ -package server.ai; - -import common.ai.IEntityMobNPCNode; -import common.entity.Entity; -import common.entity.attributes.AttributeInstance; -import common.entity.attributes.Attributes; -import common.entity.npc.AIHurtByAggressor; -import common.entity.npc.EntityMobNPC; -import common.entity.npc.EntityNPC; -import common.entity.types.EntityLiving; -import common.nbt.NBTTagCompound; - -public class EntityMobNPCNode extends EntityNPCNode implements IEntityMobNPCNode { - private int angerLevel; - private int angerTarget; - - public EntityMobNPCNode(T entity) { - super(entity); - } - - protected void registerTasks() { - super.registerTasks(); - this.targets.addTask(1, new AIHurtByAggressor(this.entity)); - } - - protected void updateAITasks() - { - AttributeInstance iattributeinstance = this.entity.getEntityAttribute(Attributes.MOVEMENT_SPEED); - - if (this.isAngry()) - { - if (!iattributeinstance.hasModifier(Attributes.RUSHING_SPEED_MOD)) - { - iattributeinstance.applyModifier(Attributes.RUSHING_SPEED_MOD); - } - - --this.angerLevel; - } - else if (iattributeinstance.hasModifier(Attributes.RUSHING_SPEED_MOD)) - { - iattributeinstance.removeModifier(Attributes.RUSHING_SPEED_MOD); - } - - if (this.angerLevel > 0 && this.angerTarget != 0 && this.entity.getAttackedBy() == null) - { - Entity entity = this.world.getEntityByID(this.angerTarget); - if(entity instanceof EntityLiving) - this.entity.setAttackedBy((EntityLiving)entity); - if(entity != null && entity.isPlayer()) - this.entity.playerAttacker = (EntityNPC)entity; - this.entity.recentlyHit = this.entity.getAttackedTime(); - } - - super.updateAITasks(); - } - - public void writeNbt(NBTTagCompound tagCompound) - { - super.writeNbt(tagCompound); - tagCompound.setShort("Anger", (short)this.angerLevel); - } - - public void readNbt(NBTTagCompound tagCompund) - { - super.readNbt(tagCompund); - this.angerLevel = tagCompund.getShort("Anger"); - } - - public void becomeAngryAt(Entity entity) - { - this.angerLevel = this.rand.excl(400, 800); - if(entity instanceof EntityLiving) - this.entity.setAttackedBy((EntityLiving)entity); - } - - public boolean isAngry() - { - return this.angerLevel > 0; - } - - public void setAngerTarget(EntityLiving entity) { - this.angerTarget = entity.getId(); - } -} diff --git a/server/src/server/ai/EntityNPCNode.java b/server/src/server/ai/EntityNPCNode.java index 1c0f807..b314cdc 100644 --- a/server/src/server/ai/EntityNPCNode.java +++ b/server/src/server/ai/EntityNPCNode.java @@ -17,21 +17,17 @@ import common.ai.EntityAISwimming; import common.ai.EntityAIWander; import common.ai.EntityAIWatchClosest; import common.ai.EntityAIWatchClosest2; -import common.ai.IEntityNPCNode; -import common.entity.npc.Alignment; import common.entity.npc.EntityNPC; import common.entity.types.EntityLiving; -import common.init.Items; -import common.item.ItemGunBase; import common.item.ItemStack; import common.pathfinding.PathNavigateGround; -public class EntityNPCNode extends EntityLivingNode implements IEntityNPCNode { +public class EntityNPCNode extends EntityNode { protected final EntityAIAttackOnCollide aiMelee; protected final AIRangedAttack aiRanged; private boolean fleeing; - public EntityNPCNode(T entity) { + public EntityNPCNode(EntityNPC entity) { super(entity); this.aiMelee = new EntityAIAttackOnCollide(entity, EntityLiving.class, 1.0D, true, true) { public boolean shouldExecute() @@ -69,18 +65,22 @@ public class EntityNPCNode extends EntityLivingNode impl }; } + public EntityNPC getEntity() { + return (EntityNPC)this.entity; + } + protected void registerTasks() { if(this.getNavigator() instanceof PathNavigateGround) { ((PathNavigateGround)this.getNavigator()).setBreakDoors(true); ((PathNavigateGround)this.getNavigator()).setAvoidsWater(true); } - this.tasks.addTask(0, new EntityAISwimming(this.entity)); + this.tasks.addTask(0, new EntityAISwimming(this.getEntity())); // this.tasks.addTask(1, new EntityAIAttackOnCollide(this, EntityNPC.class, 0.6D, true, true)); // this.tasks.addTask(1, new EntityAIAttackOnCollide(this, EntityLivingBase.class, 0.6D, true, true)); - this.tasks.addTask(1, new EntityAINpcMate(this.entity)); - this.tasks.addTask(2, new EntityAIAvoidEntity(this.entity, EntityLiving.class, new Predicate() { + this.tasks.addTask(1, new EntityAINpcMate(this.getEntity())); + this.tasks.addTask(2, new EntityAIAvoidEntity(this.getEntity(), EntityLiving.class, new Predicate() { public boolean test(EntityLiving entity) { - return entity != EntityNPCNode.this.entity && EntityNPCNode.this.shouldFlee(entity); + return entity != EntityNPCNode.this.entity && EntityNPC.this.shouldFlee(entity); } }, 8.0F, 1.1D, 1.1D) { { @@ -105,27 +105,27 @@ public class EntityNPCNode extends EntityLivingNode impl // EntityNPC.this.isFleeing = false; // } }); - this.tasks.addTask(3, new EntityAIAvoidEntity(this.entity, EntityLiving.class, new Predicate() { + this.tasks.addTask(3, new EntityAIAvoidEntity(this, EntityLiving.class, new Predicate() { public boolean test(EntityLiving entity) { - return entity != EntityNPCNode.this.entity && EntityNPCNode.this.shouldFlee(entity); + return entity != EntityNPC.this && EntityNPC.this.shouldFlee(entity); } }, 8.0F, 1.1D, 1.1D) { public void startExecuting() { super.startExecuting(); - EntityNPCNode.this.setAttackTarget(null); - EntityNPCNode.this.fleeing = true; + EntityNPC.this.setAttackTarget(null); + EntityNPC.this.fleeing = true; } public void resetTask() { super.resetTask(); - EntityNPCNode.this.fleeing = false; + EntityNPC.this.fleeing = false; } }); // this.tasks.addTask(2, new EntityAITempt(this, 1.0D, Items.golden_apple, false)); - this.tasks.addTask(4, new EntityAIOpenDoor(this.entity, true)); - this.tasks.addTask(5, new EntityAINagPlayer(this.entity)); - this.tasks.addTask(5, new EntityAILookAtTalkingPlayer(this.entity)); - this.tasks.addTask(6, new EntityAIWatchClosest2(this.entity, null, 3.0F, 1.0F) { + this.tasks.addTask(4, new EntityAIOpenDoor(this, true)); + this.tasks.addTask(5, new EntityAINagPlayer(this)); + this.tasks.addTask(5, new EntityAILookAtTalkingPlayer(this)); + this.tasks.addTask(6, new EntityAIWatchClosest2(this, null, 3.0F, 1.0F) { private int sneakTime; public void updateTask() @@ -134,15 +134,15 @@ public class EntityNPCNode extends EntityLivingNode impl boolean flag = this.closestEntity.isPlayer() && this.closestEntity.isSneaking(); if(this.sneakTime > 0) { if(--this.sneakTime == 0) { - EntityNPCNode.this.entity.setSneaking(false); + EntityNPC.this.setSneaking(false); } } - else if(EntityNPCNode.this.getAttackTarget() == null && EntityNPCNode.this.rand.chance(flag ? 5 : 200)) { - EntityNPCNode.this.entity.setSneaking(true); - this.sneakTime = EntityNPCNode.this.rand.range(60, flag ? 160 : 120); + else if(EntityNPC.this.getAttackTarget() == null && EntityNPC.this.rand.chance(flag ? 5 : 200)) { + EntityNPC.this.setSneaking(true); + this.sneakTime = EntityNPC.this.rand.range(60, flag ? 160 : 120); } - else if(EntityNPCNode.this.getAttackTarget() != null) { - EntityNPCNode.this.entity.setSneaking(false); + else if(EntityNPC.this.getAttackTarget() != null) { + EntityNPC.this.setSneaking(false); this.sneakTime = 0; } } @@ -150,75 +150,41 @@ public class EntityNPCNode extends EntityLivingNode impl public void resetTask() { super.resetTask(); - EntityNPCNode.this.entity.setSneaking(false); + EntityNPC.this.setSneaking(false); } }); - this.tasks.addTask(7, new EntityAINpcInteract(this.entity)); - this.tasks.addTask(8, new EntityAIWander(this.entity, 1.0D)); - this.tasks.addTask(8, new EntityAIPlay(this.entity, 1.1D)); - this.tasks.addTask(9, new EntityAIWatchClosest(this.entity, EntityLiving.class, 8.0F)); - this.targets.addTask(1, new EntityAIHurtByTarget(this.entity, false, /* EntityNPC.class, */ EntityLiving.class) { + this.tasks.addTask(7, new EntityAINpcInteract(this)); + this.tasks.addTask(8, new EntityAIWander(this, 1.0D)); + this.tasks.addTask(8, new EntityAIPlay(this, 1.1D)); + this.tasks.addTask(9, new EntityAIWatchClosest(this, EntityLiving.class, 8.0F)); + this.targets.addTask(1, new EntityAIHurtByTarget(this, false, /* EntityNPC.class, */ EntityLiving.class) { protected boolean isSuitableTarget(EntityLiving entity) { - if(entity != null && entity != EntityNPCNode.this.entity && EntityNPCNode.this.shouldFlee(entity)) { - EntityNPCNode.this.setAttackTarget(null); - EntityNPCNode.this.fleeing = true; + if(entity != null && entity != EntityNPC.this && EntityNPC.this.shouldFlee(entity)) { + EntityNPC.this.setAttackTarget(null); + EntityNPC.this.fleeing = true; return false; } - return entity != null && entity != EntityNPCNode.this.entity && (!(entity.isPlayer()) || EntityNPCNode.this.rand.chance(entity.getAttackedBy() == EntityNPCNode.this.entity ? 2 : 4)) - && EntityNPCNode.this.canCounter(entity) && super.isSuitableTarget(entity); + return entity != null && entity != EntityNPC.this && (!(entity.isPlayer()) || EntityNPC.this.rand.chance(entity.getAttackedBy() == EntityNPC.this ? 2 : 4)) + && EntityNPC.this.canCounter(entity) && super.isSuitableTarget(entity); } }); - this.targets.addTask(2, new EntityAINearestAttackableTarget(this.entity, EntityLiving.class, 10, true, false, new Predicate() { + this.targets.addTask(2, new EntityAINearestAttackableTarget(this, EntityLiving.class, 10, true, false, new Predicate() { public boolean test(EntityLiving entity) { - if(entity != null && entity != EntityNPCNode.this.entity && EntityNPCNode.this.shouldFlee(entity)) { - EntityNPCNode.this.setAttackTarget(null); - EntityNPCNode.this.fleeing = true; + if(entity != null && entity != EntityNPC.this && EntityNPC.this.shouldFlee(entity)) { + EntityNPC.this.setAttackTarget(null); + EntityNPC.this.fleeing = true; return false; } - return entity != null && entity != EntityNPCNode.this.entity && !EntityNPCNode.this.fleeing && EntityNPCNode.this.entity.canAmbush(entity) && EntityNPCNode.this.canAttack(entity); + return entity != null && entity != EntityNPC.this && !EntityNPC.this.fleeing && EntityNPC.this.canAmbush(entity) && EntityNPC.this.canAttack(entity); } })); // this.setCanPickUpLoot(true); - this.setCombatTask(); + if (worldIn != null && !worldIn.client) + { + this.setCombatTask(); + } } - - public final boolean canInfight(Alignment align) { - Alignment alignment = this.entity.getAlignmentCached(); - return alignment.chaotic || (!alignment.lawful && - ((alignment.good && align.evil) || (alignment.evil && align.good))); - } - - public final boolean canMurder(Alignment align) { - Alignment alignment = this.entity.getAlignmentCached(); - return alignment.chaotic && ((alignment.good && align.evil) || (alignment.evil && align.good)); - } - - public boolean canCounter(EntityLiving entity) { - return !(entity instanceof EntityNPC) || - (this.entity.getClass() == entity.getClass() ? this.canInfight(((EntityNPC)entity).getAlignmentCached()) : - !this.entity.isPeaceful(((EntityNPC)entity).getClass())); - } - - public boolean canAttack(EntityLiving entity) { - return entity instanceof EntityNPC && (this.entity.getClass() == entity.getClass() ? this.canMurder(((EntityNPC)entity).getAlignmentCached()) : - this.entity.isAggressive(((EntityNPC)entity).getClass())); - } - - public boolean shouldFlee(EntityLiving entity) { - return (this.entity.getHealth() <= (this.entity.getMaxHealth() / 4) || !this.canCounter(entity)) && - ((entity instanceof EntityNPC && ((EntityNPC)entity).getNode().canAttack(this.entity) || - (entity == this.entity.getAttackedBy() && ((EntityNPC)entity).getNode().canCounter(this.entity)))); - } - - public boolean isRangedWeapon(ItemStack stack) { - return stack != null && (stack.getItem() == Items.bow || stack.getItem() instanceof ItemGunBase || - stack.getItem() == Items.snowball || stack.getItem() == Items.potion); - } - -// public boolean isRangedWeapon(ItemStack stack) { // EntityGargoyle -// return false; -// } public void updateLeashedState() { if(!this.player) @@ -239,9 +205,9 @@ public class EntityNPCNode extends EntityLivingNode impl if(!this.player) { this.tasks.removeTask(this.aiMelee); this.tasks.removeTask(this.aiRanged); - ItemStack itemstack = this.entity.getHeldItem(); + ItemStack itemstack = this.getEntity().getHeldItem(); - if (this.isRangedWeapon(itemstack)) + if (this.getEntity().isRangedWeapon(itemstack)) { this.tasks.addTask(3, this.aiRanged); } diff --git a/server/src/server/ai/EntityNode.java b/server/src/server/ai/EntityNode.java index 914b118..2f4c0a7 100644 --- a/server/src/server/ai/EntityNode.java +++ b/server/src/server/ai/EntityNode.java @@ -1,29 +1,436 @@ package server.ai; +import java.util.List; + +import common.ai.EntityAIBase; +import common.ai.EntityAIMoveTowardsRestriction; +import common.ai.EntityAITasks; +import common.ai.EntityJumpHelper; +import common.ai.EntityLookHelper; +import common.ai.EntityMoveHelper; +import common.ai.EntitySenses; import common.ai.IEntityNode; +import common.block.Block; +import common.collect.Lists; +import common.color.TextColor; +import common.entity.DamageSource; import common.entity.Entity; +import common.entity.EntityDamageSource; +import common.entity.item.EntityLeashKnot; +import common.entity.npc.EntityNPC; +import common.entity.types.CombatEntry; +import common.entity.types.EntityBodyHelper; +import common.entity.types.EntityLiving; +import common.entity.types.EntityTameable; +import common.init.Blocks; +import common.item.ItemStack; import common.nbt.NBTTagCompound; -import common.world.World; +import common.network.IPlayer; +import common.pathfinding.PathNavigate; +import common.pathfinding.PathNavigateGround; +import common.util.BlockPos; import common.world.WorldServer; -public class EntityNode implements IEntityNode { - protected final T entity; +public abstract class EntityNode implements IEntityNode { + protected final EntityLiving entity; protected final boolean player; - protected WorldServer world; + private final List combat = Lists.newArrayList(); + private EntityLookHelper lookHelper; + protected EntityMoveHelper moveHelper; + protected EntityJumpHelper jumpHelper; + private EntityBodyHelper bodyHelper; + protected PathNavigate navigator; + protected final EntityAITasks tasks; + protected final EntityAITasks targets; + private EntityLiving target; + private EntitySenses senses; + private Runnable tickFunc; + private NBTTagCompound leashTag; + private boolean isMovementAITaskSet; + private EntityAIBase aiBase; + private boolean attacked; + private boolean damaged; + private String blockType; + private int lastDamaged; - public EntityNode(T entity) { + public EntityNode(EntityLiving entity) { this.entity = entity; this.player = entity.isPlayer(); - this.world = (WorldServer)entity.worldObj; + this.tasks = new EntityAITasks(); + this.targets = new EntityAITasks(); + this.lookHelper = new EntityLookHelper(entity); + this.moveHelper = new EntityMoveHelper(entity); + this.jumpHelper = new EntityJumpHelper(entity); + this.bodyHelper = new EntityBodyHelper(entity); + this.navigator = this.getNewNavigator(); + this.senses = new EntitySenses(entity); + this.aiBase = new EntityAIMoveTowardsRestriction(entity, 1.0D); + this.registerTasks(); } - public void setWorld(World world) { - this.world = (WorldServer)world; + protected PathNavigate getNewNavigator() { + return new PathNavigateGround(this.entity, this.entity.worldObj); + } + +// protected PathNavigate getNewNavigator() { EntityArachnoid +// return new PathNavigateClimber(this.entity, this.entity.worldObj); +// } + + protected abstract void registerTasks(); + + public void setTickFunction(Runnable func) { + this.tickFunc = func; + } + + public EntityLookHelper getLookHelper() { + return this.lookHelper; + } + + public EntityMoveHelper getMoveHelper() { + return this.moveHelper; + } + + public EntityJumpHelper getJumpHelper() { + return this.jumpHelper; + } + + public PathNavigate getNavigator() { + return this.navigator; + } + + public EntitySenses getEntitySenses() { + return this.senses; + } + + public EntityLiving getAttackTarget() { + return this.target; + } + + public void setAttackTarget(EntityLiving entitylivingbaseIn) { + this.target = entitylivingbaseIn; + } + + public boolean hasPath() + { + return !this.navigator.noPath(); + } + + public void updateRenderAngles() { + this.bodyHelper.updateRenderAngles(); } - public void readNbt(NBTTagCompound tag) { + public void update() { + this.senses.clearSensingCache(); + this.targets.onUpdateTasks(); + this.tasks.onUpdateTasks(); + this.navigator.onUpdateNavigation(); + if(this.tickFunc != null) + this.tickFunc.run(); + this.moveHelper.onUpdateMoveHelper(); + this.lookHelper.onUpdateLook(); + this.jumpHelper.doJump(); } - public void writeNbt(NBTTagCompound tag) { + public void setLeashTag(NBTTagCompound tag) { + this.leashTag = tag; } + + private void recreateLeash() { + if(this.entity.getLeashed() && this.leashTag != null) { +// if(this.leashTag.hasKey("PlayerName", 8)) { +// String id = this.leashTag.getString("PlayerName"); +// if(!id.isEmpty()) { +// for(EntityNPC entitylivingbase : this.worldObj.getEntitiesWithinAABB(EntityNPC.class, +// this.getEntityBoundingBox().expand(10.0D, 10.0D, 10.0D))) { +// if(entitylivingbase.getUser().equals(id)) { +// this.leashedTo = entitylivingbase; +// break; +// } +// } +// } +// } +// else + if(this.leashTag.hasKey("X", 99) && this.leashTag.hasKey("Y", 99) && this.leashTag.hasKey("Z", 99)) { + BlockPos blockpos = new BlockPos(this.leashTag.getInteger("X"), this.leashTag.getInteger("Y"), + this.leashTag.getInteger("Z")); + EntityLeashKnot entityleashknot = EntityLeashKnot.getKnotForPosition(this.entity.worldObj, blockpos); + + if(entityleashknot == null) { + entityleashknot = EntityLeashKnot.createKnot(this.entity.worldObj, blockpos); + } + + this.entity.setLeashedTo(entityleashknot, false); + } + else { + this.entity.clearLeashed(false, true); + } + } + + this.leashTag = null; + } + + protected void onUpdateLeashed(float distance) + { + } + +// protected void onUpdateLeashed(float distance) EntityHorse +// { +// if (distance > 6.0F && this.entity.isEatingHaystack()) +// { +// this.entity.setEatingHaystack(false); +// } +// } + + public void updateLeashedState() { + if(this.leashTag != null) { + this.recreateLeash(); + } + + if(this.entity.getLeashed()) { + if(!this.entity.isEntityAlive()) { + this.entity.clearLeashed(true, true); + } + + if(this.entity.getLeashedTo() == null || this.entity.getLeashedTo().dead) { + this.entity.clearLeashed(true, true); + } + } + + if (this.entity.getLeashed() && this.entity.getLeashedTo() != null && this.entity.getLeashedTo().worldObj == this.entity.worldObj) + { + Entity entity = this.entity.getLeashedTo(); + this.entity.setHomePosAndDistance(new BlockPos((int)entity.posX, (int)entity.posY, (int)entity.posZ), 5); + float f = this.entity.getDistanceToEntity(entity); + + if (this.entity instanceof EntityTameable && ((EntityTameable)this.entity).isSitting()) + { + if (f > 10.0F) + { + this.entity.clearLeashed(true, true); + } + + return; + } + + if (!this.isMovementAITaskSet) + { + this.tasks.addTask(2, this.aiBase); + + if (this.getNavigator() instanceof PathNavigateGround) + { + ((PathNavigateGround)this.getNavigator()).setAvoidsWater(false); + } + + this.isMovementAITaskSet = true; + } + + this.onUpdateLeashed(f); + + if (f > 4.0F) + { + this.getNavigator().tryMoveToEntityLiving(entity, 1.0D); + } + + if (f > 6.0F) + { + double d0 = (entity.posX - this.entity.posX) / (double)f; + double d1 = (entity.posY - this.entity.posY) / (double)f; + double d2 = (entity.posZ - this.entity.posZ) / (double)f; + this.entity.motionX += d0 * Math.abs(d0) * 0.4D; + this.entity.motionY += d1 * Math.abs(d1) * 0.4D; + this.entity.motionZ += d2 * Math.abs(d2) * 0.4D; + } + + if (f > 10.0F) + { + this.entity.clearLeashed(true, true); + } + } + else if (!this.entity.getLeashed() && this.isMovementAITaskSet) + { + this.isMovementAITaskSet = false; + this.tasks.removeTask(this.aiBase); + + if (this.getNavigator() instanceof PathNavigateGround) + { + ((PathNavigateGround)this.getNavigator()).setAvoidsWater(true); + } + + this.entity.detachHome(); + } + } + + public void trackDamage(DamageSource source, int amount) { + this.resetCombat(); + this.blockType = null; + if(this.entity.isOnLadder()) { + Block block = this.entity.worldObj + .getState(new BlockPos(this.entity.posX, this.entity.getEntityBoundingBox().minY, this.entity.posZ)).getBlock(); + if(block == Blocks.ladder) + this.blockType = "von einer Leiter"; + else if(block == Blocks.vine) + this.blockType = "von Ranken"; + } + else if(this.entity.isInLiquid()) { + this.blockType = "aus dem Wasser"; + } + CombatEntry entry = new CombatEntry(source, amount, this.blockType, this.entity.fallDistance); + this.combat.add(entry); + this.lastDamaged = this.entity.ticksExisted; + this.damaged = true; + if(entry.getSource().getEntity() instanceof EntityLiving && !this.attacked && this.entity.isEntityAlive()) + this.attacked = true; + } + + public void sendDeathMessage() { + this.sendDeathMessage(false, false); + } + + protected void sendDeathMessage(boolean natural, boolean forAll) { +// if(this.entity.worldObj.client) +// return; + String msg; + String kill; + IPlayer receiver = null; + if(this.combat.size() == 0) { + msg = kill = natural ? String.format("%s starb", this.entity.getColoredName(TextColor.LGRAY)) : null; + } + else { + CombatEntry strong = null; + CombatEntry block = null; + int min = 0; + float max = 0.0F; + + for(int z = 0; z < this.combat.size(); ++z) { + CombatEntry entry = (CombatEntry)this.combat.get(z); + CombatEntry last = z > 0 ? (CombatEntry)this.combat.get(z - 1) : null; + + if((entry.getSource() == DamageSource.fall || entry.getSource() == DamageSource.outOfWorld) && + entry.getFallDistance() > 0.0F && (strong == null || entry.getFallDistance() > max)) { + if(z > 0) { + strong = last; + } + else { + strong = entry; + } + + max = entry.getFallDistance(); + } + + if(entry.getBlockType() != null && (block == null || entry.getDamage() > min)) { + block = entry; + } + } + CombatEntry fall = max > 5.0F && strong != null ? strong : (min > 5 && block != null ? block : null); + CombatEntry last = (CombatEntry)this.combat.get(this.combat.size() - 1); + Entity lastEnt = last.getSource().getEntity(); + + if(fall != null && last.getSource() == DamageSource.fall) { + if(fall.getSource() != DamageSource.fall && fall.getSource() != DamageSource.outOfWorld) { + Entity fallEnt = fall.getSource().getEntity(); + if(fallEnt != null && (lastEnt == null || fallEnt != lastEnt)) { + ItemStack fallItem = fallEnt instanceof EntityLiving ? ((EntityLiving)fallEnt).getHeldItem() : null; + receiver = fallEnt.isPlayer() ? ((EntityNPC)fallEnt).connection : null; + if(fallItem != null) { // && fallItem.hasDisplayName()) { + msg = String.format("%s wurde von %s mit %s zum Fallen verdammt", this.entity.getColoredName(TextColor.CYAN), + fallEnt.getColoredName(TextColor.CYAN), fallItem.getColoredName(TextColor.CYAN)); + kill = String.format(TextColor.CYAN + "* %s mit %s zum Fallen verdammt", + this.entity.getColoredName(TextColor.CYAN), fallItem.getColoredName(TextColor.CYAN)); + } + else { + msg = String.format("%s wurde von %s zum Fallen verdammt", this.entity.getColoredName(TextColor.CYAN), + fallEnt.getColoredName(TextColor.CYAN)); + kill = String.format(TextColor.CYAN + "* %s zum Fallen verdammt", + this.entity.getColoredName(TextColor.CYAN)); + } + } + else if(lastEnt != null) { + ItemStack lastItem = lastEnt instanceof EntityLiving ? ((EntityLiving)lastEnt).getHeldItem() : null; + receiver = lastEnt.isPlayer() ? ((EntityNPC)lastEnt).connection : null; + if(lastItem != null) { // && lastItem.hasDisplayName()) { + msg = String.format("%s fiel zu tief und wurde von %s mit %s erledigt", + this.entity.getColoredName(TextColor.BLUE), + lastEnt.getColoredName(TextColor.BLUE), lastItem.getColoredName(TextColor.BLUE)); + kill = String.format(TextColor.BLUE + "* %s mit %s erledigt", + this.entity.getColoredName(TextColor.BLUE), lastItem.getColoredName(TextColor.BLUE)); + } + else { + msg = String.format("%s fiel zu tief und wurde von %s erledigt", this.entity.getColoredName(TextColor.BLUE), + lastEnt.getColoredName(TextColor.BLUE)); + kill = String.format(TextColor.BLUE + "%s erledigt", this.entity.getColoredName(TextColor.BLUE)); + } + } + else { + msg = kill = natural ? String.format("%s wurde zum Fallen verdammt", this.entity.getColoredName(TextColor.CYAN)) : null; + } + } + else { + msg = kill = natural ? String.format("%s fiel " + (fall.getBlockType() == null ? "aus zu großer Höhe" : fall.getBlockType()), + this.entity.getColoredName(TextColor.NEON)) : null; + } + } + else { + receiver = last.getSource().getEntity() != null && last.getSource().getEntity().isPlayer() ? ((EntityNPC)last.getSource().getEntity()).connection : null; + msg = natural || (last.getSource() instanceof EntityDamageSource ? last.getSource().getEntity() != null : this.entity.getAttackingEntity() != null) ? last.getSource().getDeathMessage(this.entity) : null; + kill = msg == null ? null : last.getSource().getKillMessage(this.entity); + } + } + if(msg == null) + return; + if(receiver != null) + receiver.addFeed(kill); + if(forAll) + for(IPlayer player : ((WorldServer)this.entity.worldObj).getServer().getIPlayers()) { + if(player != receiver) + player.addFeed(msg); + } + } + + public EntityLiving getAttacking() { + EntityLiving entity = null; + EntityNPC player = null; + int edmg = 0; + int pdmg = 0; + for(CombatEntry entry : this.combat) { + if(entry.getSource().getEntity() != null && entry.getSource().getEntity().isPlayer() && (player == null || entry.getDamage() > pdmg)) { + pdmg = entry.getDamage(); + player = (EntityNPC)entry.getSource().getEntity(); + } + if(entry.getSource().getEntity() instanceof EntityLiving && (entity == null || entry.getDamage() > edmg)) { + edmg = entry.getDamage(); + entity = (EntityLiving)entry.getSource().getEntity(); + } + } + return player != null && pdmg >= edmg / 3 ? player : entity; + } + + public void resetCombat() { + int timeout = this.attacked ? 300 : 100; + if(this.damaged && (!this.entity.isEntityAlive() || this.entity.ticksExisted - this.lastDamaged > timeout)) { + this.damaged = false; + this.attacked = false; + this.combat.clear(); + } + } + + public int getMaxFallHeight() { + if(this.target == null) { + return 3; + } + else { + int i = (int)((float)this.entity.getHealth() - (float)this.entity.getMaxHealth() * 0.33F); +// i = i - (3 - this.worldObj.getDifficulty().getId()) * 4; + + if(i < 0) { + i = 0; + } + + return i + 3; + } + } + +// public int getMaxFallHeight() EntityHaunter +// { +// return this.getAttackTarget() == null ? 3 : 3 + (this.getHealth() - 1); +// } } diff --git a/server/src/server/init/NodeRegistry.java b/server/src/server/init/NodeRegistry.java deleted file mode 100644 index e38b428..0000000 --- a/server/src/server/init/NodeRegistry.java +++ /dev/null @@ -1,136 +0,0 @@ -package server.init; - -import java.lang.reflect.Constructor; -import java.lang.reflect.InvocationTargetException; -import java.util.Map; -import java.util.Set; - -import common.ai.IEntityNode; -import common.collect.Maps; -import common.entity.Entity; -import common.entity.animal.EntityBat; -import common.entity.animal.EntityChicken; -import common.entity.animal.EntityCow; -import common.entity.animal.EntityDragon; -import common.entity.animal.EntityHorse; -import common.entity.animal.EntityMooshroom; -import common.entity.animal.EntityMouse; -import common.entity.animal.EntityOcelot; -import common.entity.animal.EntityPig; -import common.entity.animal.EntityRabbit; -import common.entity.animal.EntitySheep; -import common.entity.animal.EntitySquid; -import common.entity.animal.EntityWolf; -import common.entity.item.EntityBoat; -import common.entity.item.EntityChestCart; -import common.entity.item.EntityCrystal; -import common.entity.item.EntityExplosion; -import common.entity.item.EntityFalling; -import common.entity.item.EntityFireworks; -import common.entity.item.EntityHopperCart; -import common.entity.item.EntityItem; -import common.entity.item.EntityLeashKnot; -import common.entity.item.EntityMinecart; -import common.entity.item.EntityNuke; -import common.entity.item.EntityOrb; -import common.entity.item.EntityTnt; -import common.entity.item.EntityTntCart; -import common.entity.item.EntityXp; -import common.entity.item.EntityXpBottle; -import common.entity.npc.SpeciesInfo; -import common.entity.projectile.EntityArrow; -import common.entity.projectile.EntityBox; -import common.entity.projectile.EntityBullet; -import common.entity.projectile.EntityDie; -import common.entity.projectile.EntityDynamite; -import common.entity.projectile.EntityEgg; -import common.entity.projectile.EntityFireCharge; -import common.entity.projectile.EntityFireball; -import common.entity.projectile.EntityHook; -import common.entity.projectile.EntityPotion; -import common.entity.projectile.EntitySnowball; -import common.entity.types.EntityLiving; -import common.entity.types.IObjectData; -import common.log.Log; -import common.nbt.NBTTagCompound; -import common.world.World; - -public abstract class NodeRegistry { - private static final Map, Class> NODES = Maps.newHashMap(); - - private static void registerNode(Class clazz, Class node) { - if(clazz == null) - throw new IllegalArgumentException("Kann keine null-Klasse registrieren"); - if(NODES.containsKey(clazz)) - throw new IllegalArgumentException("Klasse ist bereits registriert: " + clazz); - NODES.put(clazz, node); - } - - public static void addNode(Entity entity) { - IEntityNode node = null; - Class oclass = NODES.get(entity.getClass()); - Constructor[] consts = oclass.getConstructors(); - if(consts.length != 1) - throw new IllegalArgumentException("Klasse " + oclass + " hat mehr als einen Konstruktor"); - try { - node = (IEntityNode)consts[0].newInstance(entity); - } - catch(InstantiationException | IllegalAccessException | InvocationTargetException e) { - throw new RuntimeException(e); - } - entity.setNode(node); - } - - public static Class getNodeClass(Class clazz) { - return NODES.get(clazz); - } - - public static void register() { - registerNode(EntityItem.class, ); - registerNode(EntityXp.class, ); - registerNode(EntityEgg.class, ); - registerNode(EntityLeashKnot.class, ); - registerNode(EntityArrow.class, ); - registerNode(EntitySnowball.class, ); - registerNode(EntityFireball.class, ); - registerNode(EntityFireCharge.class, ); - registerNode(EntityOrb.class, ); - registerNode(EntityPotion.class, ); - registerNode(EntityXpBottle.class, ); - registerNode(EntityBox.class, ); - registerNode(EntityTnt.class, ); - registerNode(EntityFalling.class, ); - registerNode(EntityFireworks.class, ); - registerNode(EntityBoat.class, ); - registerNode(EntityMinecart.class, ); - registerNode(EntityChestCart.class, ); - registerNode(EntityTntCart.class, ); - registerNode(EntityHopperCart.class, ); - registerNode(EntityHook.class, ); - registerNode(EntityDynamite.class, ); - registerNode(EntityNuke.class, ); - registerNode(EntityDie.class, ); - registerNode(EntityExplosion.class, ); - registerNode(EntityCrystal.class, ); - registerNode(EntityBullet.class, ); - - registerNode(EntityDragon.class, ); - registerNode(EntityBat.class, ); - registerNode(EntityPig.class, ); - registerNode(EntitySheep.class, ); - registerNode(EntityCow.class, ); - registerNode(EntityChicken.class, ); - registerNode(EntitySquid.class, ); - registerNode(EntityWolf.class, ); - registerNode(EntityMooshroom.class, ); - registerNode(EntityOcelot.class, ); - registerNode(EntityHorse.class, ); - registerNode(EntityRabbit.class, ); - registerNode(EntityMouse.class, ); - - for(int z = 0; z < SpeciesRegistry.SPECIMEN.size(); z++) { - SpeciesInfo info = SpeciesRegistry.SPECIMEN.get(z); - registerNode(info.clazz, ); - } - } -} From f89724e2aa59f17241c654afbdc23e9e41539c86 Mon Sep 17 00:00:00 2001 From: Sen Date: Mon, 12 May 2025 18:48:16 +0200 Subject: [PATCH 020/200] Revert "split entity ai to server #1" This reverts commit 02c0bfcbf615300854d109206c7fdb5200abb44b. --- common/src/common/ai/IEntityNode.java | 17 - common/src/common/entity/Entity.java | 8 + .../src/common/entity/animal/EntityHorse.java | 8 + .../common/entity/npc/EntityArachnoid.java | 5 + .../src/common/entity/npc/EntityHaunter.java | 5 + common/src/common/entity/npc/EntityNPC.java | 211 ++++++++- .../src/common/entity/types/EntityLiving.java | 424 ++++++++++++++++- .../pathfinding/PathNavigateGround.java | 2 +- server/src/server/ai/EntityNPCNode.java | 224 --------- server/src/server/ai/EntityNode.java | 436 ------------------ 10 files changed, 634 insertions(+), 706 deletions(-) delete mode 100644 common/src/common/ai/IEntityNode.java delete mode 100644 server/src/server/ai/EntityNPCNode.java delete mode 100644 server/src/server/ai/EntityNode.java diff --git a/common/src/common/ai/IEntityNode.java b/common/src/common/ai/IEntityNode.java deleted file mode 100644 index d4d89ee..0000000 --- a/common/src/common/ai/IEntityNode.java +++ /dev/null @@ -1,17 +0,0 @@ -package common.ai; - -import common.entity.DamageSource; -import common.entity.types.EntityLiving; -import common.nbt.NBTTagCompound; - -public interface IEntityNode { - void update(); - void updateRenderAngles(); - void updateLeashedState(); - void setLeashTag(NBTTagCompound tag); - EntityLiving getAttacking(); - EntityLiving getAttackTarget(); - void resetCombat(); - void trackDamage(DamageSource source, int amount); - void sendDeathMessage(); -} diff --git a/common/src/common/entity/Entity.java b/common/src/common/entity/Entity.java index 61d7871..b142d3d 100755 --- a/common/src/common/entity/Entity.java +++ b/common/src/common/entity/Entity.java @@ -2428,6 +2428,14 @@ public abstract class Entity return true; } + /** + * The maximum height from where the entity is alowed to jump (used in pathfinder) + */ + public int getMaxFallHeight() + { + return 3; + } + // public Vec3 getLastPortal() // { // return this.portalVec != null ? this.portalVec : new Vec3(0.0d, 0.0d, 0.0d); diff --git a/common/src/common/entity/animal/EntityHorse.java b/common/src/common/entity/animal/EntityHorse.java index 66cb983..ed9d625 100755 --- a/common/src/common/entity/animal/EntityHorse.java +++ b/common/src/common/entity/animal/EntityHorse.java @@ -258,6 +258,14 @@ public class EntityHorse extends EntityAnimal implements IInvBasic return !this.isUndead() && super.allowLeashing(); } + protected void onUpdateLeashed(float distance) + { + if (distance > 6.0F && this.isEatingHaystack()) + { + this.setEatingHaystack(false); + } + } + public boolean isChested() { return this.getHorseWatchableBoolean(8); diff --git a/common/src/common/entity/npc/EntityArachnoid.java b/common/src/common/entity/npc/EntityArachnoid.java index 0fcd081..becd804 100755 --- a/common/src/common/entity/npc/EntityArachnoid.java +++ b/common/src/common/entity/npc/EntityArachnoid.java @@ -35,6 +35,11 @@ public class EntityArachnoid extends EntityNPC // return 0.9375f * this.height / 1.6f; // } + protected PathNavigate getNewNavigator(World worldIn) + { + return new PathNavigateClimber(this, worldIn); + } + protected void entityInit() { super.entityInit(); diff --git a/common/src/common/entity/npc/EntityHaunter.java b/common/src/common/entity/npc/EntityHaunter.java index ca79e08..4f1e389 100755 --- a/common/src/common/entity/npc/EntityHaunter.java +++ b/common/src/common/entity/npc/EntityHaunter.java @@ -30,6 +30,11 @@ public class EntityHaunter extends EntityNPC { super.applyEntityAttributes(); this.getEntityAttribute(Attributes.MOVEMENT_SPEED).setBaseValue(0.25D); } + + public int getMaxFallHeight() + { + return this.getAttackTarget() == null ? 3 : 3 + (this.getHealth() - 1); + } public void fall(float distance, float damageMultiplier) { diff --git a/common/src/common/entity/npc/EntityNPC.java b/common/src/common/entity/npc/EntityNPC.java index ffd5e7b..f261a8b 100755 --- a/common/src/common/entity/npc/EntityNPC.java +++ b/common/src/common/entity/npc/EntityNPC.java @@ -133,11 +133,47 @@ public abstract class EntityNPC extends EntityLiving // public static String getSpeciesName(String character) { // return (character.substring(0, 1).toUpperCase() + character.substring(1)).replace('_', ' ').replaceAll("( [a-z])", "$1"); // } + + protected final EntityAIAttackOnCollide aiMelee = new EntityAIAttackOnCollide(this, EntityLiving.class, 1.0D, true, true) { + public boolean shouldExecute() + { + return !EntityNPC.this.fleeing && super.shouldExecute(); + } + + public boolean continueExecuting() + { + return !EntityNPC.this.fleeing && super.shouldExecute(); + } + }; + protected final AIRangedAttack aiRanged = new AIRangedAttack(this, 1.0D, this.getAttackSpeed(), this.getAttackSpeed() * 3, 15.0F) { +// public void startExecuting() +// { +// super.startExecuting(); +// EntityNPC.this.setUsingItem(true); +// } +// +// public void resetTask() +// { +// super.resetTask(); +// EntityNPC.this.setUsingItem(false); +// } + + public boolean shouldExecute() + { + return !EntityNPC.this.fleeing && super.shouldExecute(); + } + + public boolean continueExecuting() + { + return !EntityNPC.this.fleeing && super.shouldExecute(); + } + }; protected final SpeciesInfo species; private EntityNPC talkingPlayer; private boolean isWilling; + private boolean fleeing; private boolean playing; protected boolean noPickup; private ItemStack[] equipment = new ItemStack[5]; @@ -219,6 +255,120 @@ public abstract class EntityNPC extends EntityLiving // this.setCharacter(""); if(this.species != null) this.setSize(this.getSpeciesBaseSize() * this.species.renderer.width / this.species.renderer.height, this.getSpeciesBaseSize()); // /* 0.6F, */ 1.8F); + if(this.getNavigator() instanceof PathNavigateGround) { + ((PathNavigateGround)this.getNavigator()).setBreakDoors(true); + ((PathNavigateGround)this.getNavigator()).setAvoidsWater(true); + } + this.tasks.addTask(0, new EntityAISwimming(this)); +// this.tasks.addTask(1, new EntityAIAttackOnCollide(this, EntityNPC.class, 0.6D, true, true)); +// this.tasks.addTask(1, new EntityAIAttackOnCollide(this, EntityLivingBase.class, 0.6D, true, true)); + this.tasks.addTask(1, new EntityAINpcMate(this)); + this.tasks.addTask(2, new EntityAIAvoidEntity(this, EntityLiving.class, new Predicate() { + public boolean test(EntityLiving entity) { + return entity != EntityNPC.this && EntityNPC.this.shouldFlee(entity); + } + }, 8.0F, 1.1D, 1.1D) { + { + this.setMutexBits(0); + } + + public void startExecuting() { + EntityNPC.this.setAttackTarget(null); + EntityNPC.this.fleeing = true; + } + + public boolean continueExecuting() { + return false; + } + + public void updateTask() + { + } + +// public void resetTask() { +// super.resetTask(); +// EntityNPC.this.isFleeing = false; +// } + }); + this.tasks.addTask(3, new EntityAIAvoidEntity(this, EntityLiving.class, new Predicate() { + public boolean test(EntityLiving entity) { + return entity != EntityNPC.this && EntityNPC.this.shouldFlee(entity); + } + }, 8.0F, 1.1D, 1.1D) { + public void startExecuting() { + super.startExecuting(); + EntityNPC.this.setAttackTarget(null); + EntityNPC.this.fleeing = true; + } + + public void resetTask() { + super.resetTask(); + EntityNPC.this.fleeing = false; + } + }); +// this.tasks.addTask(2, new EntityAITempt(this, 1.0D, Items.golden_apple, false)); + this.tasks.addTask(4, new EntityAIOpenDoor(this, true)); + this.tasks.addTask(5, new EntityAINagPlayer(this)); + this.tasks.addTask(5, new EntityAILookAtTalkingPlayer(this)); + this.tasks.addTask(6, new EntityAIWatchClosest2(this, null, 3.0F, 1.0F) { + private int sneakTime; + + public void updateTask() + { + super.updateTask(); + boolean flag = this.closestEntity.isPlayer() && this.closestEntity.isSneaking(); + if(this.sneakTime > 0) { + if(--this.sneakTime == 0) { + EntityNPC.this.setSneaking(false); + } + } + else if(EntityNPC.this.getAttackTarget() == null && EntityNPC.this.rand.chance(flag ? 5 : 200)) { + EntityNPC.this.setSneaking(true); + this.sneakTime = EntityNPC.this.rand.range(60, flag ? 160 : 120); + } + else if(EntityNPC.this.getAttackTarget() != null) { + EntityNPC.this.setSneaking(false); + this.sneakTime = 0; + } + } + + public void resetTask() + { + super.resetTask(); + EntityNPC.this.setSneaking(false); + } + }); + this.tasks.addTask(7, new EntityAINpcInteract(this)); + this.tasks.addTask(8, new EntityAIWander(this, 1.0D)); + this.tasks.addTask(8, new EntityAIPlay(this, 1.1D)); + this.tasks.addTask(9, new EntityAIWatchClosest(this, EntityLiving.class, 8.0F)); + this.targets.addTask(1, new EntityAIHurtByTarget(this, false, /* EntityNPC.class, */ EntityLiving.class) { + protected boolean isSuitableTarget(EntityLiving entity) { + if(entity != null && entity != EntityNPC.this && EntityNPC.this.shouldFlee(entity)) { + EntityNPC.this.setAttackTarget(null); + EntityNPC.this.fleeing = true; + return false; + } + return entity != null && entity != EntityNPC.this && (!(entity.isPlayer()) || EntityNPC.this.rand.chance(entity.getAttackedBy() == EntityNPC.this ? 2 : 4)) + && EntityNPC.this.canCounter(entity) && super.isSuitableTarget(entity); + } + }); + this.targets.addTask(2, new EntityAINearestAttackableTarget(this, EntityLiving.class, 10, true, false, new Predicate() { + public boolean test(EntityLiving entity) { + if(entity != null && entity != EntityNPC.this && EntityNPC.this.shouldFlee(entity)) { + EntityNPC.this.setAttackTarget(null); + EntityNPC.this.fleeing = true; + return false; + } + return entity != null && entity != EntityNPC.this && !EntityNPC.this.fleeing && EntityNPC.this.canAmbush(entity) && EntityNPC.this.canAttack(entity); + } + })); +// this.setCanPickUpLoot(true); + + if (worldIn != null && !worldIn.client) + { + this.setCombatTask(); + } } @@ -507,7 +657,7 @@ public abstract class EntityNPC extends EntityLiving } else if (!flag && !this.isPlayer() && this.isEntityAlive() && !this.isTalking()) { - if (!this.worldObj.client && this.canTrade() && this.node.getAttackTarget() == null) + if (!this.worldObj.client && this.canTrade() && this.getAttackTarget() == null) { this.setTalking(player); player.connection.displayTradeGui(this); @@ -1018,6 +1168,10 @@ public abstract class EntityNPC extends EntityLiving return this.playing; } + public boolean isFleeing() { + return this.fleeing; + } + // public boolean canPlay() { // return ; // } @@ -1878,8 +2032,7 @@ public abstract class EntityNPC extends EntityLiving { // float f1 = this.getHealth(); this.setHealth(this.getHealth() - damageAmount); - if(this.node != null) - this.node.trackDamage(damageSrc, damageAmount); + this.trackDamage(damageSrc, damageAmount); // if ((float)damageAmount < 3.4028235E37F) // { @@ -2682,7 +2835,7 @@ public abstract class EntityNPC extends EntityLiving else { this.setItemNoUpdate(slot, stack); if(!this.worldObj.client && slot == 0) - this.node.setCombatTask(); + this.setCombatTask(); } } @@ -3290,7 +3443,7 @@ public abstract class EntityNPC extends EntityLiving this.skin = tagCompund.getByteArray("Skin"); // this.setCanPickUpLoot(true); - this.node.setCombatTask(); + this.setCombatTask(); if(this.isPlayer()) { // this.entityUniqueID = getOfflineUUID(this.user); @@ -4308,6 +4461,16 @@ public abstract class EntityNPC extends EntityLiving { return !this.isPlayer() && super.interactFirst(playerIn); } + + public int getMaxFallHeight() + { + return this.isPlayer() ? 3 : super.getMaxFallHeight(); + } + + protected void updateLeashedState() { + if(!this.isPlayer()) + super.updateLeashedState(); + } public void setLeashedTo(Entity entity, boolean pkt) { if(!this.isPlayer()) @@ -4323,15 +4486,14 @@ public abstract class EntityNPC extends EntityLiving super.clearLeashed(pkt, dropLead); } - protected void updateDistance(float p_110146_1_, float p_110146_2_) + protected float updateDistance(float p_110146_1_, float p_110146_2_) { - if(!this.isPlayer()) { - super.updateDistance(p_110146_1_, p_110146_2_); - return; - } + if(!this.isPlayer()) + return super.updateDistance(p_110146_1_, p_110146_2_); float f = ExtMath.wrapf(p_110146_1_ - this.yawOffset); this.yawOffset += f * 0.3F; float f1 = ExtMath.wrapf(this.rotYaw - this.yawOffset); + boolean flag = f1 < -90.0F || f1 >= 90.0F; if (f1 < -75.0F) { @@ -4349,6 +4511,13 @@ public abstract class EntityNPC extends EntityLiving { this.yawOffset += f1 * 0.2F; } + + if (flag) + { + p_110146_2_ *= -1.0F; + } + + return p_110146_2_; } public boolean getCanSpawnHere() { @@ -4417,6 +4586,24 @@ public abstract class EntityNPC extends EntityLiving if(!this.isPlayer()) this.equipment[slot] = stack; } + + public void setCombatTask() + { + if(!this.isPlayer()) { + this.tasks.removeTask(this.aiMelee); + this.tasks.removeTask(this.aiRanged); + ItemStack itemstack = this.getHeldItem(); + + if (this.isRangedWeapon(itemstack)) + { + this.tasks.addTask(3, this.aiRanged); + } + else + { + this.tasks.addTask(3, this.aiMelee); + } + } + } public abstract int getBaseHealth(Random rand); // { // return 20; @@ -4462,6 +4649,10 @@ public abstract class EntityNPC extends EntityLiving public int getColor() { return this.isPlayer() ? 0xff00ff : 0x5000ad; } + + public void sendDeathMessage() { + this.sendDeathMessage(this.isPlayer(), true); + } protected boolean canRegenerateHealth() { return this.isPlayer(); diff --git a/common/src/common/entity/types/EntityLiving.java b/common/src/common/entity/types/EntityLiving.java index 96d6709..c99cbb5 100755 --- a/common/src/common/entity/types/EntityLiving.java +++ b/common/src/common/entity/types/EntityLiving.java @@ -6,14 +6,22 @@ import java.util.List; import java.util.Map; import java.util.function.Predicate; -import common.ai.IEntityNode; +import common.ai.EntityAIBase; +import common.ai.EntityAIMoveTowardsRestriction; +import common.ai.EntityAITasks; +import common.ai.EntityJumpHelper; +import common.ai.EntityLookHelper; +import common.ai.EntityMoveHelper; +import common.ai.EntitySenses; import common.block.Block; import common.block.SoundType; +import common.collect.Lists; import common.collect.Maps; import common.color.TextColor; import common.enchantment.EnchantmentHelper; import common.entity.DamageSource; import common.entity.Entity; +import common.entity.EntityDamageSource; import common.entity.animal.EntityWolf; import common.entity.attributes.Attribute; import common.entity.attributes.AttributeInstance; @@ -42,9 +50,12 @@ import common.material.Material; import common.model.ParticleType; import common.nbt.NBTTagCompound; import common.nbt.NBTTagList; +import common.network.IPlayer; import common.packet.S1BPacketEntityAttach; import common.packet.SPacketAnimation; import common.packet.SPacketCollectItem; +import common.pathfinding.PathNavigate; +import common.pathfinding.PathNavigateGround; import common.potion.Potion; import common.potion.PotionEffect; import common.potion.PotionHelper; @@ -61,13 +72,23 @@ public abstract class EntityLiving extends Entity { private static final ItemStack[] EMPTY_INV = new ItemStack[5]; - protected IEntityNode node; private AttributeMap attributes; + private final List combat = Lists.newArrayList(); private final Map effects = Maps.newEnumMap(Potion.class); public int soundTimer; protected int xpValue; + private EntityLookHelper lookHelper; + protected EntityMoveHelper moveHelper; + protected EntityJumpHelper jumpHelper; + private EntityBodyHelper bodyHelper; + protected PathNavigate navigator; + protected final EntityAITasks tasks; + protected final EntityAITasks targets; + private EntityLiving target; + private EntitySenses senses; private boolean leashed; private Entity leashedTo; + private NBTTagCompound leashTag; public float prevCamPitch; public float camPitch; @@ -79,6 +100,8 @@ public abstract class EntityLiving extends Entity protected float landMovement; protected float prevGroundFactor; protected float groundFactor; + protected float movedDist; + protected float prevMovedDist; protected boolean jumping; public float moveStrafe; public float moveForward; @@ -112,13 +135,18 @@ public abstract class EntityLiving extends Entity private int lastAttacked; private EntityLiving attacker; private int lastAttackTime; + private int lastDamaged; // protected int entityAge; private int absorptionAmount; private boolean effectsDirty = true; protected boolean firstEffectUpdate = true; + private boolean attacked; + private boolean damaged; private String description; + + private String blockType; private float radiation; @@ -128,6 +156,8 @@ public abstract class EntityLiving extends Entity protected int growingAge; private float ageWidth = -1.0F; private float ageHeight; + private EntityAIBase aiBase = new EntityAIMoveTowardsRestriction(this, 1.0D); + private boolean isMovementAITaskSet; public EntityLiving(World worldIn) { @@ -141,6 +171,15 @@ public abstract class EntityLiving extends Entity this.rotYaw = (float)(Math.random() * Math.PI * 2.0D); this.headYaw = this.rotYaw; this.stepHeight = 0.6F; + + this.tasks = new EntityAITasks(); + this.targets = new EntityAITasks(); + this.lookHelper = new EntityLookHelper(this); + this.moveHelper = new EntityMoveHelper(this); + this.jumpHelper = new EntityJumpHelper(this); + this.bodyHelper = new EntityBodyHelper(this); + this.navigator = this.getNewNavigator(worldIn); + this.senses = new EntitySenses(this); } protected void entityInit() @@ -355,6 +394,7 @@ public abstract class EntityLiving extends Entity this.radiation = 0.0f; } this.updateEffects(); + this.prevMovedDist = this.movedDist; this.prevYawOffset = this.yawOffset; this.prevHeadYaw = this.headYaw; this.prevYaw = this.rotYaw; @@ -626,7 +666,7 @@ public abstract class EntityLiving extends Entity this.leashed = tagCompund.getBoolean("Leashed"); if(this.leashed && tagCompund.hasKey("Leash", 10)) { - this.node.setLeashTag(tagCompund.getCompoundTag("Leash")); + this.leashTag = tagCompund.getCompoundTag("Leash"); } } @@ -1069,12 +1109,11 @@ public abstract class EntityLiving extends Entity entity.onKillEntity(this); } - if(!this.worldObj.client) { - this.node.sendDeathMessage(); + if(!this.worldObj.client) + this.sendDeathMessage(); // this.noPickup = true; - this.node.resetCombat(); - } + this.resetCombat(); if (!this.worldObj.client) { @@ -1329,8 +1368,7 @@ public abstract class EntityLiving extends Entity { // float f1 = this.getHealth(); this.setHealth(this.getHealth() - damageAmount); - if(this.node != null) - this.node.trackDamage(damageSrc, damageAmount); + this.trackDamage(damageSrc, damageAmount); this.setAbsorptionAmount(this.getAbsorptionAmount() - damageAmount); } // } @@ -1338,7 +1376,7 @@ public abstract class EntityLiving extends Entity public EntityLiving getAttackingEntity() { - return (EntityLiving)(this.node.getAttacking() != null ? this.node.getAttacking() : (this.playerAttacker != null ? this.playerAttacker : (this.attackedBy != null ? this.attackedBy : null))); + return (EntityLiving)(this.getAttacking() != null ? this.getAttacking() : (this.playerAttacker != null ? this.playerAttacker : (this.attackedBy != null ? this.attackedBy : null))); } public final int getMaxHealth() @@ -1878,7 +1916,7 @@ public abstract class EntityLiving extends Entity if (this.ticksExisted % 20 == 0) { - this.node.resetCombat(); + this.resetCombat(); } } @@ -1910,7 +1948,7 @@ public abstract class EntityLiving extends Entity this.groundFactor += (f3 - this.groundFactor) * 0.3F; // this.worldObj.profiler.start("headTurn"); - this.updateDistance(f1, f2); + f2 = this.updateDistance(f1, f2); // this.worldObj.profiler.end(); // this.worldObj.profiler.start("rangeChecks"); @@ -1955,9 +1993,10 @@ public abstract class EntityLiving extends Entity } // this.worldObj.profiler.end(); + this.movedDist += f2; if(!this.worldObj.client) { - this.node.updateLeashedState(); + this.updateLeashedState(); } } @@ -2391,6 +2430,159 @@ public abstract class EntityLiving extends Entity public void clearRadiation() { this.radiation = 0.0f; } + + public void trackDamage(DamageSource source, int amount) { + this.resetCombat(); + this.blockType = null; + if(this.isOnLadder()) { + Block block = this.worldObj + .getState(new BlockPos(this.posX, this.getEntityBoundingBox().minY, this.posZ)).getBlock(); + if(block == Blocks.ladder) + this.blockType = "von einer Leiter"; + else if(block == Blocks.vine) + this.blockType = "von Ranken"; + } + else if(this.isInLiquid()) { + this.blockType = "aus dem Wasser"; + } + CombatEntry entry = new CombatEntry(source, amount, this.blockType, this.fallDistance); + this.combat.add(entry); + this.lastDamaged = this.ticksExisted; + this.damaged = true; + if(entry.getSource().getEntity() instanceof EntityLiving && !this.attacked && this.isEntityAlive()) + this.attacked = true; + } + + protected void sendDeathMessage() { + this.sendDeathMessage(false, false); + } + + protected void sendDeathMessage(boolean natural, boolean forAll) { + if(this.worldObj.client) + return; + String msg; + String kill; + IPlayer receiver = null; + if(this.combat.size() == 0) { + msg = kill = natural ? String.format("%s starb", this.getColoredName(TextColor.LGRAY)) : null; + } + else { + CombatEntry strong = null; + CombatEntry block = null; + int min = 0; + float max = 0.0F; + + for(int z = 0; z < this.combat.size(); ++z) { + CombatEntry entry = (CombatEntry)this.combat.get(z); + CombatEntry last = z > 0 ? (CombatEntry)this.combat.get(z - 1) : null; + + if((entry.getSource() == DamageSource.fall || entry.getSource() == DamageSource.outOfWorld) && + entry.getFallDistance() > 0.0F && (strong == null || entry.getFallDistance() > max)) { + if(z > 0) { + strong = last; + } + else { + strong = entry; + } + + max = entry.getFallDistance(); + } + + if(entry.getBlockType() != null && (block == null || entry.getDamage() > min)) { + block = entry; + } + } + CombatEntry fall = max > 5.0F && strong != null ? strong : (min > 5 && block != null ? block : null); + CombatEntry last = (CombatEntry)this.combat.get(this.combat.size() - 1); + Entity lastEnt = last.getSource().getEntity(); + + if(fall != null && last.getSource() == DamageSource.fall) { + if(fall.getSource() != DamageSource.fall && fall.getSource() != DamageSource.outOfWorld) { + Entity fallEnt = fall.getSource().getEntity(); + if(fallEnt != null && (lastEnt == null || fallEnt != lastEnt)) { + ItemStack fallItem = fallEnt instanceof EntityLiving ? ((EntityLiving)fallEnt).getHeldItem() : null; + receiver = fallEnt.isPlayer() ? ((EntityNPC)fallEnt).connection : null; + if(fallItem != null) { // && fallItem.hasDisplayName()) { + msg = String.format("%s wurde von %s mit %s zum Fallen verdammt", this.getColoredName(TextColor.CYAN), + fallEnt.getColoredName(TextColor.CYAN), fallItem.getColoredName(TextColor.CYAN)); + kill = String.format(TextColor.CYAN + "* %s mit %s zum Fallen verdammt", + this.getColoredName(TextColor.CYAN), fallItem.getColoredName(TextColor.CYAN)); + } + else { + msg = String.format("%s wurde von %s zum Fallen verdammt", this.getColoredName(TextColor.CYAN), + fallEnt.getColoredName(TextColor.CYAN)); + kill = String.format(TextColor.CYAN + "* %s zum Fallen verdammt", + this.getColoredName(TextColor.CYAN)); + } + } + else if(lastEnt != null) { + ItemStack lastItem = lastEnt instanceof EntityLiving ? ((EntityLiving)lastEnt).getHeldItem() : null; + receiver = lastEnt.isPlayer() ? ((EntityNPC)lastEnt).connection : null; + if(lastItem != null) { // && lastItem.hasDisplayName()) { + msg = String.format("%s fiel zu tief und wurde von %s mit %s erledigt", + this.getColoredName(TextColor.BLUE), + lastEnt.getColoredName(TextColor.BLUE), lastItem.getColoredName(TextColor.BLUE)); + kill = String.format(TextColor.BLUE + "* %s mit %s erledigt", + this.getColoredName(TextColor.BLUE), lastItem.getColoredName(TextColor.BLUE)); + } + else { + msg = String.format("%s fiel zu tief und wurde von %s erledigt", this.getColoredName(TextColor.BLUE), + lastEnt.getColoredName(TextColor.BLUE)); + kill = String.format(TextColor.BLUE + "%s erledigt", this.getColoredName(TextColor.BLUE)); + } + } + else { + msg = kill = natural ? String.format("%s wurde zum Fallen verdammt", this.getColoredName(TextColor.CYAN)) : null; + } + } + else { + msg = kill = natural ? String.format("%s fiel " + (fall.getBlockType() == null ? "aus zu großer Höhe" : fall.getBlockType()), + this.getColoredName(TextColor.NEON)) : null; + } + } + else { + receiver = last.getSource().getEntity() != null && last.getSource().getEntity().isPlayer() ? ((EntityNPC)last.getSource().getEntity()).connection : null; + msg = natural || (last.getSource() instanceof EntityDamageSource ? last.getSource().getEntity() != null : this.getAttackingEntity() != null) ? last.getSource().getDeathMessage(this) : null; + kill = msg == null ? null : last.getSource().getKillMessage(this); + } + } + if(msg == null) + return; + if(receiver != null) + receiver.addFeed(kill); + if(forAll) + for(IPlayer player : ((WorldServer)this.worldObj).getServer().getIPlayers()) { + if(player != receiver) + player.addFeed(msg); + } + } + + public EntityLiving getAttacking() { + EntityLiving entity = null; + EntityNPC player = null; + int edmg = 0; + int pdmg = 0; + for(CombatEntry entry : this.combat) { + if(entry.getSource().getEntity() != null && entry.getSource().getEntity().isPlayer() && (player == null || entry.getDamage() > pdmg)) { + pdmg = entry.getDamage(); + player = (EntityNPC)entry.getSource().getEntity(); + } + if(entry.getSource().getEntity() instanceof EntityLiving && (entity == null || entry.getDamage() > edmg)) { + edmg = entry.getDamage(); + entity = (EntityLiving)entry.getSource().getEntity(); + } + } + return player != null && pdmg >= edmg / 3 ? player : entity; + } + + public void resetCombat() { + int timeout = this.attacked ? 300 : 100; + if(this.damaged && (!this.isEntityAlive() || this.ticksExisted - this.lastDamaged > timeout)) { + this.damaged = false; + this.attacked = false; + this.combat.clear(); + } + } public boolean isSneakingVisually() { return this.isSneaking(); @@ -2612,6 +2804,22 @@ public abstract class EntityLiving extends Entity return 4; } + public int getMaxFallHeight() { + if(this.getAttackTarget() == null) { + return 3; + } + else { + int i = (int)((float)this.getHealth() - (float)this.getMaxHealth() * 0.33F); +// i = i - (3 - this.worldObj.getDifficulty().getId()) * 4; + + if(i < 0) { + i = 0; + } + + return i + 3; + } + } + // public boolean getCanSpawnHere() { // return true; // } @@ -2674,8 +2882,34 @@ public abstract class EntityLiving extends Entity } protected void updateEntityActionState() { - if(this.node != null) - this.node.update(); +// ++this.entityAge; +// this.worldObj.profiler.start("checkDespawn"); +// this.despawnEntity(); +// this.worldObj.profiler.end(); +// this.worldObj.profiler.start("sensing"); + this.senses.clearSensingCache(); +// this.worldObj.profiler.end(); +// this.worldObj.profiler.start("targetSelector"); + this.targets.onUpdateTasks(); +// this.worldObj.profiler.end(); +// this.worldObj.profiler.start("goalSelector"); + this.tasks.onUpdateTasks(); +// this.worldObj.profiler.end(); +// this.worldObj.profiler.start("navigation"); + this.navigator.onUpdateNavigation(); +// this.worldObj.profiler.end(); +// this.worldObj.profiler.start("mob tick"); + this.updateAITasks(); +// this.worldObj.profiler.end(); +// this.worldObj.profiler.start("controls"); +// this.worldObj.profiler.start("move"); + this.moveHelper.onUpdateMoveHelper(); +// this.worldObj.profiler.next("look"); + this.lookHelper.onUpdateLook(); +// this.worldObj.profiler.next("jump"); + this.jumpHelper.doJump(); +// this.worldObj.profiler.end(); +// this.worldObj.profiler.end(); } // protected void despawnEntity() { @@ -2733,12 +2967,123 @@ public abstract class EntityLiving extends Entity // super.applyEntityAttributes(); // this.getAttributeMap().registerAttribute(Attributes.FOLLOW_RANGE).setBaseValue(16.0D); // } + + protected PathNavigate getNewNavigator(World worldIn) { + return new PathNavigateGround(this, worldIn); + } + + public EntityLookHelper getLookHelper() { + return this.lookHelper; + } + + public EntityMoveHelper getMoveHelper() { + return this.moveHelper; + } + + public EntityJumpHelper getJumpHelper() { + return this.jumpHelper; + } + + public PathNavigate getNavigator() { + return this.navigator; + } + + public EntitySenses getEntitySenses() { + return this.senses; + } + + public EntityLiving getAttackTarget() { + return this.target; + } + + public void setAttackTarget(EntityLiving entitylivingbaseIn) { + this.target = entitylivingbaseIn; + } // public boolean canAttackClass(Class cls) { // return /* cls != EntityFireDemon.class && */ // ; // } + protected void updateLeashedState() { + if(this.leashTag != null) { + this.recreateLeash(); + } + + if(this.leashed) { + if(!this.isEntityAlive()) { + this.clearLeashed(true, true); + } + + if(this.leashedTo == null || this.leashedTo.dead) { + this.clearLeashed(true, true); + } + } + + if (this.getLeashed() && this.getLeashedTo() != null && this.getLeashedTo().worldObj == this.worldObj) + { + Entity entity = this.getLeashedTo(); + this.setHomePosAndDistance(new BlockPos((int)entity.posX, (int)entity.posY, (int)entity.posZ), 5); + float f = this.getDistanceToEntity(entity); + + if (this instanceof EntityTameable && ((EntityTameable)this).isSitting()) + { + if (f > 10.0F) + { + this.clearLeashed(true, true); + } + + return; + } + + if (!this.isMovementAITaskSet) + { + this.tasks.addTask(2, this.aiBase); + + if (this.getNavigator() instanceof PathNavigateGround) + { + ((PathNavigateGround)this.getNavigator()).setAvoidsWater(false); + } + + this.isMovementAITaskSet = true; + } + + this.onUpdateLeashed(f); + + if (f > 4.0F) + { + this.getNavigator().tryMoveToEntityLiving(entity, 1.0D); + } + + if (f > 6.0F) + { + double d0 = (entity.posX - this.posX) / (double)f; + double d1 = (entity.posY - this.posY) / (double)f; + double d2 = (entity.posZ - this.posZ) / (double)f; + this.motionX += d0 * Math.abs(d0) * 0.4D; + this.motionY += d1 * Math.abs(d1) * 0.4D; + this.motionZ += d2 * Math.abs(d2) * 0.4D; + } + + if (f > 10.0F) + { + this.clearLeashed(true, true); + } + } + else if (!this.getLeashed() && this.isMovementAITaskSet) + { + this.isMovementAITaskSet = false; + this.tasks.removeTask(this.aiBase); + + if (this.getNavigator() instanceof PathNavigateGround) + { + ((PathNavigateGround)this.getNavigator()).setAvoidsWater(true); + } + + this.detachHome(); + } + } + public void clearLeashed(boolean pkt, boolean dropLead) { if(this.leashed) { this.leashed = false; @@ -2775,9 +3120,43 @@ public abstract class EntityLiving extends Entity } } - protected void updateDistance(float p_110146_1_, float p_110146_2_) { - if(this.node != null) - this.node.updateRenderAngles(); + private void recreateLeash() { + if(this.leashed && this.leashTag != null) { +// if(this.leashTag.hasKey("PlayerName", 8)) { +// String id = this.leashTag.getString("PlayerName"); +// if(!id.isEmpty()) { +// for(EntityNPC entitylivingbase : this.worldObj.getEntitiesWithinAABB(EntityNPC.class, +// this.getEntityBoundingBox().expand(10.0D, 10.0D, 10.0D))) { +// if(entitylivingbase.getUser().equals(id)) { +// this.leashedTo = entitylivingbase; +// break; +// } +// } +// } +// } +// else + if(this.leashTag.hasKey("X", 99) && this.leashTag.hasKey("Y", 99) && this.leashTag.hasKey("Z", 99)) { + BlockPos blockpos = new BlockPos(this.leashTag.getInteger("X"), this.leashTag.getInteger("Y"), + this.leashTag.getInteger("Z")); + EntityLeashKnot entityleashknot = EntityLeashKnot.getKnotForPosition(this.worldObj, blockpos); + + if(entityleashknot == null) { + entityleashknot = EntityLeashKnot.createKnot(this.worldObj, blockpos); + } + + this.leashedTo = entityleashknot; + } + else { + this.clearLeashed(false, true); + } + } + + this.leashTag = null; + } + + protected float updateDistance(float p_110146_1_, float p_110146_2_) { + this.bodyHelper.updateRenderAngles(); + return p_110146_2_; } public ItemStack[] getInventory() { @@ -2908,6 +3287,11 @@ public abstract class EntityLiving extends Entity { return this.getBlockPathWeight(new BlockPos(this.posX, this.getEntityBoundingBox().minY, this.posZ)) >= 0.0F; } + + public boolean hasPath() + { + return !this.navigator.noPath(); + } public boolean isWithinHomeDistanceCurrentPosition() { @@ -2944,6 +3328,10 @@ public abstract class EntityLiving extends Entity { return this.maximumHomeDistance != -1.0F; } + + protected void onUpdateLeashed(float distance) + { + } protected void setSize(float width, float height) { diff --git a/common/src/common/pathfinding/PathNavigateGround.java b/common/src/common/pathfinding/PathNavigateGround.java index c9631ee..f12b1c8 100755 --- a/common/src/common/pathfinding/PathNavigateGround.java +++ b/common/src/common/pathfinding/PathNavigateGround.java @@ -11,7 +11,7 @@ import common.util.Vec3; import common.world.World; public class PathNavigateGround extends PathNavigate -{ +{ protected WalkNodeProcessor nodeProcessor; private boolean shouldAvoidSun; diff --git a/server/src/server/ai/EntityNPCNode.java b/server/src/server/ai/EntityNPCNode.java deleted file mode 100644 index b314cdc..0000000 --- a/server/src/server/ai/EntityNPCNode.java +++ /dev/null @@ -1,224 +0,0 @@ -package server.ai; - -import java.util.function.Predicate; - -import common.ai.AIRangedAttack; -import common.ai.EntityAIAttackOnCollide; -import common.ai.EntityAIAvoidEntity; -import common.ai.EntityAIHurtByTarget; -import common.ai.EntityAILookAtTalkingPlayer; -import common.ai.EntityAINagPlayer; -import common.ai.EntityAINearestAttackableTarget; -import common.ai.EntityAINpcInteract; -import common.ai.EntityAINpcMate; -import common.ai.EntityAIOpenDoor; -import common.ai.EntityAIPlay; -import common.ai.EntityAISwimming; -import common.ai.EntityAIWander; -import common.ai.EntityAIWatchClosest; -import common.ai.EntityAIWatchClosest2; -import common.entity.npc.EntityNPC; -import common.entity.types.EntityLiving; -import common.item.ItemStack; -import common.pathfinding.PathNavigateGround; - -public class EntityNPCNode extends EntityNode { - protected final EntityAIAttackOnCollide aiMelee; - protected final AIRangedAttack aiRanged; - private boolean fleeing; - - public EntityNPCNode(EntityNPC entity) { - super(entity); - this.aiMelee = new EntityAIAttackOnCollide(entity, EntityLiving.class, 1.0D, true, true) { - public boolean shouldExecute() - { - return !EntityNPCNode.this.fleeing && super.shouldExecute(); - } - - public boolean continueExecuting() - { - return !EntityNPCNode.this.fleeing && super.shouldExecute(); - } - }; - this.aiRanged = new AIRangedAttack(entity, 1.0D, entity.getAttackSpeed(), entity.getAttackSpeed() * 3, 15.0F) { -// public void startExecuting() -// { -// super.startExecuting(); -// EntityNPC.this.setUsingItem(true); -// } -// -// public void resetTask() -// { -// super.resetTask(); -// EntityNPC.this.setUsingItem(false); -// } - - public boolean shouldExecute() - { - return !EntityNPCNode.this.fleeing && super.shouldExecute(); - } - - public boolean continueExecuting() - { - return !EntityNPCNode.this.fleeing && super.shouldExecute(); - } - }; - } - - public EntityNPC getEntity() { - return (EntityNPC)this.entity; - } - - protected void registerTasks() { - if(this.getNavigator() instanceof PathNavigateGround) { - ((PathNavigateGround)this.getNavigator()).setBreakDoors(true); - ((PathNavigateGround)this.getNavigator()).setAvoidsWater(true); - } - this.tasks.addTask(0, new EntityAISwimming(this.getEntity())); -// this.tasks.addTask(1, new EntityAIAttackOnCollide(this, EntityNPC.class, 0.6D, true, true)); -// this.tasks.addTask(1, new EntityAIAttackOnCollide(this, EntityLivingBase.class, 0.6D, true, true)); - this.tasks.addTask(1, new EntityAINpcMate(this.getEntity())); - this.tasks.addTask(2, new EntityAIAvoidEntity(this.getEntity(), EntityLiving.class, new Predicate() { - public boolean test(EntityLiving entity) { - return entity != EntityNPCNode.this.entity && EntityNPC.this.shouldFlee(entity); - } - }, 8.0F, 1.1D, 1.1D) { - { - this.setMutexBits(0); - } - - public void startExecuting() { - EntityNPCNode.this.setAttackTarget(null); - EntityNPCNode.this.fleeing = true; - } - - public boolean continueExecuting() { - return false; - } - - public void updateTask() - { - } - -// public void resetTask() { -// super.resetTask(); -// EntityNPC.this.isFleeing = false; -// } - }); - this.tasks.addTask(3, new EntityAIAvoidEntity(this, EntityLiving.class, new Predicate() { - public boolean test(EntityLiving entity) { - return entity != EntityNPC.this && EntityNPC.this.shouldFlee(entity); - } - }, 8.0F, 1.1D, 1.1D) { - public void startExecuting() { - super.startExecuting(); - EntityNPC.this.setAttackTarget(null); - EntityNPC.this.fleeing = true; - } - - public void resetTask() { - super.resetTask(); - EntityNPC.this.fleeing = false; - } - }); -// this.tasks.addTask(2, new EntityAITempt(this, 1.0D, Items.golden_apple, false)); - this.tasks.addTask(4, new EntityAIOpenDoor(this, true)); - this.tasks.addTask(5, new EntityAINagPlayer(this)); - this.tasks.addTask(5, new EntityAILookAtTalkingPlayer(this)); - this.tasks.addTask(6, new EntityAIWatchClosest2(this, null, 3.0F, 1.0F) { - private int sneakTime; - - public void updateTask() - { - super.updateTask(); - boolean flag = this.closestEntity.isPlayer() && this.closestEntity.isSneaking(); - if(this.sneakTime > 0) { - if(--this.sneakTime == 0) { - EntityNPC.this.setSneaking(false); - } - } - else if(EntityNPC.this.getAttackTarget() == null && EntityNPC.this.rand.chance(flag ? 5 : 200)) { - EntityNPC.this.setSneaking(true); - this.sneakTime = EntityNPC.this.rand.range(60, flag ? 160 : 120); - } - else if(EntityNPC.this.getAttackTarget() != null) { - EntityNPC.this.setSneaking(false); - this.sneakTime = 0; - } - } - - public void resetTask() - { - super.resetTask(); - EntityNPC.this.setSneaking(false); - } - }); - this.tasks.addTask(7, new EntityAINpcInteract(this)); - this.tasks.addTask(8, new EntityAIWander(this, 1.0D)); - this.tasks.addTask(8, new EntityAIPlay(this, 1.1D)); - this.tasks.addTask(9, new EntityAIWatchClosest(this, EntityLiving.class, 8.0F)); - this.targets.addTask(1, new EntityAIHurtByTarget(this, false, /* EntityNPC.class, */ EntityLiving.class) { - protected boolean isSuitableTarget(EntityLiving entity) { - if(entity != null && entity != EntityNPC.this && EntityNPC.this.shouldFlee(entity)) { - EntityNPC.this.setAttackTarget(null); - EntityNPC.this.fleeing = true; - return false; - } - return entity != null && entity != EntityNPC.this && (!(entity.isPlayer()) || EntityNPC.this.rand.chance(entity.getAttackedBy() == EntityNPC.this ? 2 : 4)) - && EntityNPC.this.canCounter(entity) && super.isSuitableTarget(entity); - } - }); - this.targets.addTask(2, new EntityAINearestAttackableTarget(this, EntityLiving.class, 10, true, false, new Predicate() { - public boolean test(EntityLiving entity) { - if(entity != null && entity != EntityNPC.this && EntityNPC.this.shouldFlee(entity)) { - EntityNPC.this.setAttackTarget(null); - EntityNPC.this.fleeing = true; - return false; - } - return entity != null && entity != EntityNPC.this && !EntityNPC.this.fleeing && EntityNPC.this.canAmbush(entity) && EntityNPC.this.canAttack(entity); - } - })); -// this.setCanPickUpLoot(true); - - if (worldIn != null && !worldIn.client) - { - this.setCombatTask(); - } - } - - public void updateLeashedState() { - if(!this.player) - super.updateLeashedState(); - } - - public void sendDeathMessage() { - this.sendDeathMessage(this.player, true); - } - - public int getMaxFallHeight() - { - return this.player ? 3 : super.getMaxFallHeight(); - } - - public void setCombatTask() - { - if(!this.player) { - this.tasks.removeTask(this.aiMelee); - this.tasks.removeTask(this.aiRanged); - ItemStack itemstack = this.getEntity().getHeldItem(); - - if (this.getEntity().isRangedWeapon(itemstack)) - { - this.tasks.addTask(3, this.aiRanged); - } - else - { - this.tasks.addTask(3, this.aiMelee); - } - } - } - - public boolean isFleeing() { - return this.fleeing; - } -} diff --git a/server/src/server/ai/EntityNode.java b/server/src/server/ai/EntityNode.java deleted file mode 100644 index 2f4c0a7..0000000 --- a/server/src/server/ai/EntityNode.java +++ /dev/null @@ -1,436 +0,0 @@ -package server.ai; - -import java.util.List; - -import common.ai.EntityAIBase; -import common.ai.EntityAIMoveTowardsRestriction; -import common.ai.EntityAITasks; -import common.ai.EntityJumpHelper; -import common.ai.EntityLookHelper; -import common.ai.EntityMoveHelper; -import common.ai.EntitySenses; -import common.ai.IEntityNode; -import common.block.Block; -import common.collect.Lists; -import common.color.TextColor; -import common.entity.DamageSource; -import common.entity.Entity; -import common.entity.EntityDamageSource; -import common.entity.item.EntityLeashKnot; -import common.entity.npc.EntityNPC; -import common.entity.types.CombatEntry; -import common.entity.types.EntityBodyHelper; -import common.entity.types.EntityLiving; -import common.entity.types.EntityTameable; -import common.init.Blocks; -import common.item.ItemStack; -import common.nbt.NBTTagCompound; -import common.network.IPlayer; -import common.pathfinding.PathNavigate; -import common.pathfinding.PathNavigateGround; -import common.util.BlockPos; -import common.world.WorldServer; - -public abstract class EntityNode implements IEntityNode { - protected final EntityLiving entity; - protected final boolean player; - private final List combat = Lists.newArrayList(); - private EntityLookHelper lookHelper; - protected EntityMoveHelper moveHelper; - protected EntityJumpHelper jumpHelper; - private EntityBodyHelper bodyHelper; - protected PathNavigate navigator; - protected final EntityAITasks tasks; - protected final EntityAITasks targets; - private EntityLiving target; - private EntitySenses senses; - private Runnable tickFunc; - private NBTTagCompound leashTag; - private boolean isMovementAITaskSet; - private EntityAIBase aiBase; - private boolean attacked; - private boolean damaged; - private String blockType; - private int lastDamaged; - - public EntityNode(EntityLiving entity) { - this.entity = entity; - this.player = entity.isPlayer(); - this.tasks = new EntityAITasks(); - this.targets = new EntityAITasks(); - this.lookHelper = new EntityLookHelper(entity); - this.moveHelper = new EntityMoveHelper(entity); - this.jumpHelper = new EntityJumpHelper(entity); - this.bodyHelper = new EntityBodyHelper(entity); - this.navigator = this.getNewNavigator(); - this.senses = new EntitySenses(entity); - this.aiBase = new EntityAIMoveTowardsRestriction(entity, 1.0D); - this.registerTasks(); - } - - protected PathNavigate getNewNavigator() { - return new PathNavigateGround(this.entity, this.entity.worldObj); - } - -// protected PathNavigate getNewNavigator() { EntityArachnoid -// return new PathNavigateClimber(this.entity, this.entity.worldObj); -// } - - protected abstract void registerTasks(); - - public void setTickFunction(Runnable func) { - this.tickFunc = func; - } - - public EntityLookHelper getLookHelper() { - return this.lookHelper; - } - - public EntityMoveHelper getMoveHelper() { - return this.moveHelper; - } - - public EntityJumpHelper getJumpHelper() { - return this.jumpHelper; - } - - public PathNavigate getNavigator() { - return this.navigator; - } - - public EntitySenses getEntitySenses() { - return this.senses; - } - - public EntityLiving getAttackTarget() { - return this.target; - } - - public void setAttackTarget(EntityLiving entitylivingbaseIn) { - this.target = entitylivingbaseIn; - } - - public boolean hasPath() - { - return !this.navigator.noPath(); - } - - public void updateRenderAngles() { - this.bodyHelper.updateRenderAngles(); - } - - public void update() { - this.senses.clearSensingCache(); - this.targets.onUpdateTasks(); - this.tasks.onUpdateTasks(); - this.navigator.onUpdateNavigation(); - if(this.tickFunc != null) - this.tickFunc.run(); - this.moveHelper.onUpdateMoveHelper(); - this.lookHelper.onUpdateLook(); - this.jumpHelper.doJump(); - } - - public void setLeashTag(NBTTagCompound tag) { - this.leashTag = tag; - } - - private void recreateLeash() { - if(this.entity.getLeashed() && this.leashTag != null) { -// if(this.leashTag.hasKey("PlayerName", 8)) { -// String id = this.leashTag.getString("PlayerName"); -// if(!id.isEmpty()) { -// for(EntityNPC entitylivingbase : this.worldObj.getEntitiesWithinAABB(EntityNPC.class, -// this.getEntityBoundingBox().expand(10.0D, 10.0D, 10.0D))) { -// if(entitylivingbase.getUser().equals(id)) { -// this.leashedTo = entitylivingbase; -// break; -// } -// } -// } -// } -// else - if(this.leashTag.hasKey("X", 99) && this.leashTag.hasKey("Y", 99) && this.leashTag.hasKey("Z", 99)) { - BlockPos blockpos = new BlockPos(this.leashTag.getInteger("X"), this.leashTag.getInteger("Y"), - this.leashTag.getInteger("Z")); - EntityLeashKnot entityleashknot = EntityLeashKnot.getKnotForPosition(this.entity.worldObj, blockpos); - - if(entityleashknot == null) { - entityleashknot = EntityLeashKnot.createKnot(this.entity.worldObj, blockpos); - } - - this.entity.setLeashedTo(entityleashknot, false); - } - else { - this.entity.clearLeashed(false, true); - } - } - - this.leashTag = null; - } - - protected void onUpdateLeashed(float distance) - { - } - -// protected void onUpdateLeashed(float distance) EntityHorse -// { -// if (distance > 6.0F && this.entity.isEatingHaystack()) -// { -// this.entity.setEatingHaystack(false); -// } -// } - - public void updateLeashedState() { - if(this.leashTag != null) { - this.recreateLeash(); - } - - if(this.entity.getLeashed()) { - if(!this.entity.isEntityAlive()) { - this.entity.clearLeashed(true, true); - } - - if(this.entity.getLeashedTo() == null || this.entity.getLeashedTo().dead) { - this.entity.clearLeashed(true, true); - } - } - - if (this.entity.getLeashed() && this.entity.getLeashedTo() != null && this.entity.getLeashedTo().worldObj == this.entity.worldObj) - { - Entity entity = this.entity.getLeashedTo(); - this.entity.setHomePosAndDistance(new BlockPos((int)entity.posX, (int)entity.posY, (int)entity.posZ), 5); - float f = this.entity.getDistanceToEntity(entity); - - if (this.entity instanceof EntityTameable && ((EntityTameable)this.entity).isSitting()) - { - if (f > 10.0F) - { - this.entity.clearLeashed(true, true); - } - - return; - } - - if (!this.isMovementAITaskSet) - { - this.tasks.addTask(2, this.aiBase); - - if (this.getNavigator() instanceof PathNavigateGround) - { - ((PathNavigateGround)this.getNavigator()).setAvoidsWater(false); - } - - this.isMovementAITaskSet = true; - } - - this.onUpdateLeashed(f); - - if (f > 4.0F) - { - this.getNavigator().tryMoveToEntityLiving(entity, 1.0D); - } - - if (f > 6.0F) - { - double d0 = (entity.posX - this.entity.posX) / (double)f; - double d1 = (entity.posY - this.entity.posY) / (double)f; - double d2 = (entity.posZ - this.entity.posZ) / (double)f; - this.entity.motionX += d0 * Math.abs(d0) * 0.4D; - this.entity.motionY += d1 * Math.abs(d1) * 0.4D; - this.entity.motionZ += d2 * Math.abs(d2) * 0.4D; - } - - if (f > 10.0F) - { - this.entity.clearLeashed(true, true); - } - } - else if (!this.entity.getLeashed() && this.isMovementAITaskSet) - { - this.isMovementAITaskSet = false; - this.tasks.removeTask(this.aiBase); - - if (this.getNavigator() instanceof PathNavigateGround) - { - ((PathNavigateGround)this.getNavigator()).setAvoidsWater(true); - } - - this.entity.detachHome(); - } - } - - public void trackDamage(DamageSource source, int amount) { - this.resetCombat(); - this.blockType = null; - if(this.entity.isOnLadder()) { - Block block = this.entity.worldObj - .getState(new BlockPos(this.entity.posX, this.entity.getEntityBoundingBox().minY, this.entity.posZ)).getBlock(); - if(block == Blocks.ladder) - this.blockType = "von einer Leiter"; - else if(block == Blocks.vine) - this.blockType = "von Ranken"; - } - else if(this.entity.isInLiquid()) { - this.blockType = "aus dem Wasser"; - } - CombatEntry entry = new CombatEntry(source, amount, this.blockType, this.entity.fallDistance); - this.combat.add(entry); - this.lastDamaged = this.entity.ticksExisted; - this.damaged = true; - if(entry.getSource().getEntity() instanceof EntityLiving && !this.attacked && this.entity.isEntityAlive()) - this.attacked = true; - } - - public void sendDeathMessage() { - this.sendDeathMessage(false, false); - } - - protected void sendDeathMessage(boolean natural, boolean forAll) { -// if(this.entity.worldObj.client) -// return; - String msg; - String kill; - IPlayer receiver = null; - if(this.combat.size() == 0) { - msg = kill = natural ? String.format("%s starb", this.entity.getColoredName(TextColor.LGRAY)) : null; - } - else { - CombatEntry strong = null; - CombatEntry block = null; - int min = 0; - float max = 0.0F; - - for(int z = 0; z < this.combat.size(); ++z) { - CombatEntry entry = (CombatEntry)this.combat.get(z); - CombatEntry last = z > 0 ? (CombatEntry)this.combat.get(z - 1) : null; - - if((entry.getSource() == DamageSource.fall || entry.getSource() == DamageSource.outOfWorld) && - entry.getFallDistance() > 0.0F && (strong == null || entry.getFallDistance() > max)) { - if(z > 0) { - strong = last; - } - else { - strong = entry; - } - - max = entry.getFallDistance(); - } - - if(entry.getBlockType() != null && (block == null || entry.getDamage() > min)) { - block = entry; - } - } - CombatEntry fall = max > 5.0F && strong != null ? strong : (min > 5 && block != null ? block : null); - CombatEntry last = (CombatEntry)this.combat.get(this.combat.size() - 1); - Entity lastEnt = last.getSource().getEntity(); - - if(fall != null && last.getSource() == DamageSource.fall) { - if(fall.getSource() != DamageSource.fall && fall.getSource() != DamageSource.outOfWorld) { - Entity fallEnt = fall.getSource().getEntity(); - if(fallEnt != null && (lastEnt == null || fallEnt != lastEnt)) { - ItemStack fallItem = fallEnt instanceof EntityLiving ? ((EntityLiving)fallEnt).getHeldItem() : null; - receiver = fallEnt.isPlayer() ? ((EntityNPC)fallEnt).connection : null; - if(fallItem != null) { // && fallItem.hasDisplayName()) { - msg = String.format("%s wurde von %s mit %s zum Fallen verdammt", this.entity.getColoredName(TextColor.CYAN), - fallEnt.getColoredName(TextColor.CYAN), fallItem.getColoredName(TextColor.CYAN)); - kill = String.format(TextColor.CYAN + "* %s mit %s zum Fallen verdammt", - this.entity.getColoredName(TextColor.CYAN), fallItem.getColoredName(TextColor.CYAN)); - } - else { - msg = String.format("%s wurde von %s zum Fallen verdammt", this.entity.getColoredName(TextColor.CYAN), - fallEnt.getColoredName(TextColor.CYAN)); - kill = String.format(TextColor.CYAN + "* %s zum Fallen verdammt", - this.entity.getColoredName(TextColor.CYAN)); - } - } - else if(lastEnt != null) { - ItemStack lastItem = lastEnt instanceof EntityLiving ? ((EntityLiving)lastEnt).getHeldItem() : null; - receiver = lastEnt.isPlayer() ? ((EntityNPC)lastEnt).connection : null; - if(lastItem != null) { // && lastItem.hasDisplayName()) { - msg = String.format("%s fiel zu tief und wurde von %s mit %s erledigt", - this.entity.getColoredName(TextColor.BLUE), - lastEnt.getColoredName(TextColor.BLUE), lastItem.getColoredName(TextColor.BLUE)); - kill = String.format(TextColor.BLUE + "* %s mit %s erledigt", - this.entity.getColoredName(TextColor.BLUE), lastItem.getColoredName(TextColor.BLUE)); - } - else { - msg = String.format("%s fiel zu tief und wurde von %s erledigt", this.entity.getColoredName(TextColor.BLUE), - lastEnt.getColoredName(TextColor.BLUE)); - kill = String.format(TextColor.BLUE + "%s erledigt", this.entity.getColoredName(TextColor.BLUE)); - } - } - else { - msg = kill = natural ? String.format("%s wurde zum Fallen verdammt", this.entity.getColoredName(TextColor.CYAN)) : null; - } - } - else { - msg = kill = natural ? String.format("%s fiel " + (fall.getBlockType() == null ? "aus zu großer Höhe" : fall.getBlockType()), - this.entity.getColoredName(TextColor.NEON)) : null; - } - } - else { - receiver = last.getSource().getEntity() != null && last.getSource().getEntity().isPlayer() ? ((EntityNPC)last.getSource().getEntity()).connection : null; - msg = natural || (last.getSource() instanceof EntityDamageSource ? last.getSource().getEntity() != null : this.entity.getAttackingEntity() != null) ? last.getSource().getDeathMessage(this.entity) : null; - kill = msg == null ? null : last.getSource().getKillMessage(this.entity); - } - } - if(msg == null) - return; - if(receiver != null) - receiver.addFeed(kill); - if(forAll) - for(IPlayer player : ((WorldServer)this.entity.worldObj).getServer().getIPlayers()) { - if(player != receiver) - player.addFeed(msg); - } - } - - public EntityLiving getAttacking() { - EntityLiving entity = null; - EntityNPC player = null; - int edmg = 0; - int pdmg = 0; - for(CombatEntry entry : this.combat) { - if(entry.getSource().getEntity() != null && entry.getSource().getEntity().isPlayer() && (player == null || entry.getDamage() > pdmg)) { - pdmg = entry.getDamage(); - player = (EntityNPC)entry.getSource().getEntity(); - } - if(entry.getSource().getEntity() instanceof EntityLiving && (entity == null || entry.getDamage() > edmg)) { - edmg = entry.getDamage(); - entity = (EntityLiving)entry.getSource().getEntity(); - } - } - return player != null && pdmg >= edmg / 3 ? player : entity; - } - - public void resetCombat() { - int timeout = this.attacked ? 300 : 100; - if(this.damaged && (!this.entity.isEntityAlive() || this.entity.ticksExisted - this.lastDamaged > timeout)) { - this.damaged = false; - this.attacked = false; - this.combat.clear(); - } - } - - public int getMaxFallHeight() { - if(this.target == null) { - return 3; - } - else { - int i = (int)((float)this.entity.getHealth() - (float)this.entity.getMaxHealth() * 0.33F); -// i = i - (3 - this.worldObj.getDifficulty().getId()) * 4; - - if(i < 0) { - i = 0; - } - - return i + 3; - } - } - -// public int getMaxFallHeight() EntityHaunter -// { -// return this.getAttackTarget() == null ? 3 : 3 + (this.getHealth() - 1); -// } -} From 95b5d0e3e3c22908771fb36a42e283eef84527e2 Mon Sep 17 00:00:00 2001 From: Sen Date: Mon, 12 May 2025 18:52:03 +0200 Subject: [PATCH 021/200] move converter to server --- client/src/client/Client.java | 8 +- client/src/client/gui/GuiConvert.java | 214 --------- client/src/client/gui/GuiMenu.java | 5 +- common/src/common/util/Util.java | 8 + common/src/common/world/Region.java | 149 +----- server/src/server/Server.java | 68 ++- .../src/server}/world/Converter.java | 438 ++++-------------- 7 files changed, 183 insertions(+), 707 deletions(-) delete mode 100755 client/src/client/gui/GuiConvert.java rename {client/src/client => server/src/server}/world/Converter.java (79%) diff --git a/client/src/client/Client.java b/client/src/client/Client.java index ddeec71..e0ab9f0 100755 --- a/client/src/client/Client.java +++ b/client/src/client/Client.java @@ -162,7 +162,6 @@ import common.util.Util; import common.util.HitPosition.ObjectType; import common.world.Chunk; import common.world.LightType; -import common.world.Region; import common.world.State; import common.world.World; import common.world.WorldClient; @@ -280,7 +279,7 @@ public class Client implements IThreadListener, IClient { private final List chat = Lists.newArrayList(); private final List feed = Lists.newArrayList(); private final List hotbar = Lists.newArrayList(); - private final File config = new File(System.getProperty("config.file", "game.cfg")); + private final File config = new File(System.getProperty("config.file", "client.cfg")); private boolean primary; private boolean secondary; @@ -1775,8 +1774,8 @@ public class Client implements IThreadListener, IClient { String.format("XYZ: %.3f / %.3f / %.3f", this.viewEntity.posX, this.viewEntity.getEntityBoundingBox().minY, this.viewEntity.posZ) + "\n" + String.format("Block: %d %d %d, R: '%s/%s'", blockpos.getX(), blockpos.getY(), blockpos.getZ(), - Region.getRegionFolder(blockpos.getX() >> 4, blockpos.getZ() >> 4), - Region.getRegionName(blockpos.getX() >> 4, blockpos.getZ() >> 4)) + "\n" + + Util.getRegionFolder(blockpos.getX() >> 4, blockpos.getZ() >> 4), + Util.getRegionName(blockpos.getX() >> 4, blockpos.getZ() >> 4)) + "\n" + String.format("Chunk: %d %d %d + %d %d %d, FOV: %.1f °%s", blockpos.getX() >> 4, blockpos.getY() >> 4, blockpos.getZ() >> 4, blockpos.getX() & 15, blockpos.getY() & 15, blockpos.getZ() & 15, this.zooming ? (this.fov / this.zoomLevel) : this.fov, this.zooming ? @@ -2217,7 +2216,6 @@ public class Client implements IThreadListener, IClient { Log.SYSTEM.info("Beende ..."); unload(false); this.getSoundManager().unload(); - Region.killIO(); this.renderGlobal.stopChunkBuilders(); if(audio.end()) Log.SOUND.info("Audiogerät geschlossen"); diff --git a/client/src/client/gui/GuiConvert.java b/client/src/client/gui/GuiConvert.java deleted file mode 100755 index e3e0a31..0000000 --- a/client/src/client/gui/GuiConvert.java +++ /dev/null @@ -1,214 +0,0 @@ -package client.gui; - -import java.io.File; -import java.io.FileFilter; -import java.text.SimpleDateFormat; -import java.util.Collections; -import java.util.Date; - -import client.Client.FileMode; -import client.gui.element.ActButton; -import client.gui.element.ActButton.Mode; -import client.gui.element.GuiList; -import client.gui.element.ListEntry; -import client.gui.element.NavButton; -import client.renderer.Drawing; -import client.world.Converter; -import common.color.TextColor; -import common.dimension.Space; -import common.log.Log; -import common.world.Region; -import common.world.World; -import common.world.Region.FolderInfo; -import common.world.Region.SaveVersion; - -public class GuiConvert extends GuiList implements ActButton.Callback -{ - protected class SaveInfo implements Comparable, ListEntry { - private final String file; - private final int dimensions; - private final int players; - private final long seed; - private final FolderInfo info; - - public SaveInfo(String file, int dimensions, int players, long seed, FolderInfo info) { - this.file = file; - this.dimensions = dimensions; - this.players = players; - this.seed = seed; - this.info = info; - } - - public String getFile() { - return this.file; - } - - public int getDimensions() { - return this.dimensions; - } - - public int getPlayers() { - return this.players; - } - - public boolean mustConvert() { - return this.info.legacy != null; - } - - public String getVersion() { - return this.info.legacy == null ? (this.info.version == null ? "" : this.info.version) : this.info.legacy.toString(); - } - - public boolean isIncompatible() { - return this.info.legacy == SaveVersion.RELEASE_1_13; - } - - public long getLastPlayed() { - return this.info.lastPlayed; - } - - public long getSeed() { - return this.seed; - } - - public int compareTo(SaveInfo comp) { - return this.info.lastPlayed < comp.info.lastPlayed ? 1 : (this.info.lastPlayed > comp.info.lastPlayed ? -1 : this.file.compareTo(comp.file)); - } - - public void select(boolean isDoubleClick, int mouseX, int mouseY) - { - boolean use = !this.isIncompatible() && this.mustConvert(); - GuiConvert.this.selectButton.enabled = use; - - if (isDoubleClick && use) - { - GuiConvert.this.use(GuiConvert.this.selectButton, Mode.PRIMARY); - } - } - - public void draw(int x, int y, int mouseXIn, int mouseYIn, boolean hover) - { - Drawing.drawText((this.isIncompatible() ? TextColor.DRED : "") + this.getFile() + (this.mustConvert() ? "" : - (TextColor.GRAY + " - " + TextColor.RESET + (this.getPlayers() > 0 ? this.getPlayers() + " Spieler" : "Keine Spieler"))), - x + 2, y, 0xffffffff); - Drawing.drawText((this.mustConvert() ? (this.isIncompatible() ? TextColor.CRIMSON : "") + this.getVersion() : (this.getDimensions() <= 0 ? "Keine Dimensionen" : this.getDimensions() + " Dimension" + (this.getDimensions() != 1 ? "en" : "") + " erschaffen")) - , x + 2, y + 18, 0xff808080); - Drawing.drawText(this.mustConvert() ? (this.isIncompatible() ? TextColor.CRIMSON + "Kann nicht konvertiert werden!" : - "Muss konvertiert werden!") : ( // "Kreativmodus: " + (info.isNoCreative() ? "Aus" : "An") + - "Zuletzt gespielt: " + DATE_FORMAT.format(new Date(this.getLastPlayed()))) + " " + TextColor.LGRAY + this.getVersion(), x + 2, y + 18 + 16, 0xff808080); - } - } - - public static final GuiConvert INSTANCE = new GuiConvert(); - private static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("dd.MM.yyyy HH:mm:ss"); - - private ActButton selectButton; - private File dir = null; - - private GuiConvert() - { - } - - private void load() { - this.elements.clear(); - if(this.dir == null || !this.dir.exists() || !this.dir.isDirectory()) - return; - try - { - File[] files = dir.listFiles(); - if(files == null) - throw new RuntimeException("Kann den Speicherordner für Welten nicht lesen oder öffnen!"); - for(File file : files) { - if(!file.isDirectory()) - continue; - FolderInfo info = Region.loadWorldInfo(file); - if(info == null) - info = Converter.convertMapFormat(file, false); - if(info == null) { - this.elements.add(new SaveInfo(file.getName(), -1, -1, - 0L, new FolderInfo(World.START_TIME, file.lastModified(), null, null))); - continue; - } - int dims = -1; - int players = -1; - if(info.legacy == null) { - dims = 0; - File[] folders = new File(new File(dir, file.getName()), "chunk").listFiles(new FileFilter() { - public boolean accept(File pathname) { - return pathname.isDirectory() && !pathname.getName().equals(Space.INSTANCE.getDimensionName()); - } - }); - if(folders != null) { - for(File sub : folders) { - File[] dim = sub.listFiles(); - if(dim != null && dim.length > 0) - dims++; - } - } - File[] plrs = new File(new File(dir, file.getName()), "players").listFiles(new FileFilter() { - public boolean accept(File pathname) { - return pathname.getName().endsWith(".nbt"); - } - }); - players = plrs == null ? 0 : plrs.length; - } - this.elements.add(new SaveInfo(file.getName(), dims, players, - 0L, info)); - } - Collections.sort(this.elements); - } - catch (Exception e) - { - Log.IO.error("Konnte Weltliste nicht laden", e); - this.elements.clear(); - } - } - - public void init(int width, int height) - { - super.init(width, height); - this.setDimensions(width, height, 32, height - 32); - - this.load(); - - this.add(this.selectButton = new ActButton(width / 2 - 383, height - 28, 150, 24, this, "Konvertieren")); - this.add(new NavButton(width / 2 + 233, height - 28, 150, 24, GuiMenu.INSTANCE, "Abbrechen")); - - this.add(new ActButton(4, 4, 200, 24, new ActButton.Callback() { - public void use(ActButton elem, ActButton.Mode action) { - if(GuiConvert.this.gm.world != null) - return; - GuiConvert.this.gm.showFileDialog(FileMode.DIRECTORY_LOAD, "Ordner wählen", GuiConvert.this.dir, new FileCallback() { - public void selected(File file) { - GuiConvert.this.dir = file; - GuiConvert.this.gm.displayGuiScreen(GuiConvert.this); - } - }); - } - }, "Ordner wählen ...")); - - this.selectButton.enabled = false; - } - - public String getTitle() { - return "Welt auswählen"; - } - - public int getListWidth() - { - return 660; - } - - public int getSlotHeight() - { - return 56; - } - - public void use(ActButton button, Mode mode) - { - String dir = this.getSelected().getFile(); - File folder = new File(this.dir, dir); - if(folder.isDirectory()) - Converter.convertMapFormat(folder, true); - } -} diff --git a/client/src/client/gui/GuiMenu.java b/client/src/client/gui/GuiMenu.java index 17a9f4e..54cbb34 100644 --- a/client/src/client/gui/GuiMenu.java +++ b/client/src/client/gui/GuiMenu.java @@ -94,12 +94,11 @@ public class GuiMenu extends Gui { } } }); - this.add(new NavButton(0, 102, 196, 24, GuiConvert.INSTANCE, "Welt konvertieren")); - this.add(new ActButton(204, 102, 196, 24, new ActButton.Callback() { + this.add(new ActButton(0, 102, 400, 24, new ActButton.Callback() { public void use(ActButton elem, ActButton.Mode action) { GuiMenu.this.gm.interrupted = true; } - }, "Spiel beenden")); + }, "Client schließen")); this.shift(); this.add(new Label(4, /* this.gm.fb_y - 2 */ 0, 200, 20, TextColor.VIOLET + Config.VERSION, true)); this.splashLabel = this.add(new Label(0, 160, width, 24, "")); diff --git a/common/src/common/util/Util.java b/common/src/common/util/Util.java index fe4734b..629ef96 100644 --- a/common/src/common/util/Util.java +++ b/common/src/common/util/Util.java @@ -389,4 +389,12 @@ int utf_len(const char *str) { public static double ftime() { return ((double)rtime()) / 1000000.0; } + + public static String getRegionFolder(int x, int z) { + return String.format("%c%03X%c%03X", x < 0 ? 'n' : 'p', ((x < 0) ? -x : x) >> 9, z < 0 ? 'n' : 'p', ((z < 0) ? -z : z) >> 9); + } + + public static String getRegionName(int x, int z) { + return String.format("r.%c%X%c%X.rgn", x < 0 ? 'n' : 'p', ((x < 0) ? -x : x) >> 3, z < 0 ? 'n' : 'p', ((z < 0) ? -z : z) >> 3); + } } diff --git a/common/src/common/world/Region.java b/common/src/common/world/Region.java index 06bbb84..ea0a6ae 100755 --- a/common/src/common/world/Region.java +++ b/common/src/common/world/Region.java @@ -22,9 +22,7 @@ import common.collect.Lists; import common.collect.Maps; import common.entity.Entity; import common.init.BlockRegistry; -import common.init.Config; import common.init.EntityRegistry; -import common.init.UniverseRegistry; import common.log.Log; import common.nbt.NBTLoader; import common.nbt.NBTTagCompound; @@ -33,39 +31,9 @@ import common.tileentity.TileEntity; import common.util.BlockPos; import common.util.NextTickListEntry; import common.util.NibbleArray; +import common.util.Util; public class Region { - public static enum SaveVersion { - ALPHA_1_0("Alpha 1.0 - Beta 1.2"), - BETA_1_3("Beta 1.3 - Release 1.8.9"), - RELEASE_1_9("Release 1.9 - Release 1.12.2"), - RELEASE_1_13("Release 1.13 +"); - - private final String name; - - private SaveVersion(String name) { - this.name = name; - } - - public String toString() { - return this.name; - } - } - - public static class FolderInfo { - public final long time; - public final long lastPlayed; - public final SaveVersion legacy; - public final String version; - - public FolderInfo(long time, long lastPlayed, SaveVersion legacy, String version) { - this.time = time; - this.lastPlayed = lastPlayed; - this.legacy = legacy; - this.version = version; - } - } - private static class ChunkBuffer extends ByteArrayOutputStream { public ChunkBuffer() { super(8096); @@ -90,10 +58,7 @@ public class Region { private static final Map CACHE = Maps.newHashMap(); private static final List QUEUE = Collections.synchronizedList(Lists.newArrayList()); - -// public static long lastPlayed; -// public static int version; -// public static String owner; + private static volatile long queued; private static volatile long saved; private static volatile boolean waiting; @@ -113,10 +78,10 @@ public class Region { private boolean modified; public Region(File dir, int x, int z) { - File sdir = new File(dir, getRegionFolder(x << 3, z << 3)); + File sdir = new File(dir, Util.getRegionFolder(x << 3, z << 3)); if(!sdir.exists()) sdir.mkdirs(); - this.regFile = new File(sdir, getRegionName(x << 3, z << 3)); + this.regFile = new File(sdir, Util.getRegionName(x << 3, z << 3)); this.folder = dir; this.xPos = x; this.zPos = z; @@ -313,13 +278,6 @@ public class Region { this.write(x, z, buf.getData(), buf.size()); } -// public NBTTagCompound readTag(int x, int z) throws IOException { -// byte[] data = this.read(x, z); -// if(data == null) -// return null; -// return CompressedStreamTools.read(new DataInputStream(new BufferedInputStream(new InflaterInputStream(new ByteArrayInputStream(data))))); -// } - public File getFile() { return this.regFile; } @@ -336,7 +294,7 @@ public class Region { } private static File getExpansionFile(File dir, int x, int z) { - File sdir = new File(dir, getRegionFolder(x, z)); + File sdir = new File(dir, Util.getRegionFolder(x, z)); if(!sdir.exists()) sdir.mkdirs(); return new File(sdir, String.format("c.%c%X%c%X.chk", x < 0 ? 'n' : 'p', (x < 0) ? -x : x, z < 0 ? 'n' : 'p', (z < 0) ? -z : z)); @@ -399,14 +357,6 @@ public class Region { // getRegionFile(dir, x >> 3, z >> 3).writeTag(x & 7, z & 7, tag); } - public static String getRegionFolder(int x, int z) { - return String.format("%c%03X%c%03X", x < 0 ? 'n' : 'p', ((x < 0) ? -x : x) >> 9, z < 0 ? 'n' : 'p', ((z < 0) ? -z : z) >> 9); - } - - public static String getRegionName(int x, int z) { - return String.format("r.%c%X%c%X.rgn", x < 0 ? 'n' : 'p', ((x < 0) ? -x : x) >> 3, z < 0 ? 'n' : 'p', ((z < 0) ? -z : z) >> 3); - } - public static Chunk readNbt(WorldServer world, int x, int z, NBTTagCompound tag) { // if(!tag.hasKey("Level", 10)) { // Log.error("Chunk-Datei bei " + x + "," + z + " hat keine Level-Daten, überspringe"); @@ -680,93 +630,4 @@ public class Region { public static void killIO() { killed = true; } - - public static void saveWorldInfo(File worldDir, long time) { - NBTTagCompound data = new NBTTagCompound(); - data.setLong("Time", time); - data.setLong("LastAccess", System.currentTimeMillis()); - data.setString("Version", Config.VERSION); - NBTTagCompound cfg = new NBTTagCompound(); - for(String cvar : Config.VARS.keySet()) { - cfg.setString(cvar, Config.VARS.get(cvar).getValue()); -// Config.Value value = Config.VARS.get(cvar); -// switch(value.getType()) { -// case BOOLEAN: -// cfg.setString(cvar, "" + value.getBoolean()); -// break; -// case INTEGER: -// cfg.setString(cvar, "" + value.getInt()); -// break; -// case FLOAT: -// cfg.setString(cvar, "" + value.getFloat()); -// break; -// case STRING: -// cfg.setString(cvar, value.getString()); -// break; -// } - } - data.setTag("Config", cfg); - data.setTag("Universe", UniverseRegistry.saveNbt()); - if(worldDir != null) - worldDir.mkdirs(); - File nfile = new File(worldDir, "level.nbt.tmp"); - File lfile = new File(worldDir, "level.nbt"); - try { -// File ofile = new File(worldDir, "level.nbt_old"); - NBTLoader.writeGZip(data, nfile); -// if(ofile.exists()) -// ofile.delete(); -// lfile.renameTo(ofile); - if(lfile.exists()) - lfile.delete(); - nfile.renameTo(lfile); -// if(nfile.exists()) -// nfile.delete(); - } - catch(Exception e) { - Log.JNI.error(e, "Fehler beim Schreiben von " + nfile); - } - } - - public static FolderInfo loadWorldInfo(File worldDir) { - Config.clear(); - UniverseRegistry.clear(); - File file = new File(worldDir, "level.nbt"); - if(!file.exists()) - file = new File(worldDir, "level.nbt.tmp"); - if(file.exists()) { - try { - NBTTagCompound tag = NBTLoader.readGZip(file); - NBTTagCompound cfg = tag.getCompoundTag("Config"); - for(String key : cfg.getKeySet()) { - Config.set(key, cfg.getString(key), null); - } - UniverseRegistry.loadNbt(tag.getCompoundTag("Universe")); - // tag.getInteger("Version"); - long lastPlayed = tag.getLong("LastAccess"); - String version = tag.hasKey("Version", 8) ? tag.getString("Version") : null; - version = version != null && version.isEmpty() ? null : version; - long time = tag.hasKey("Time", 4) ? tag.getLong("Time") : World.START_TIME; - return new FolderInfo(time, lastPlayed, null, version); - } - catch(Exception e) { - Log.JNI.error(e, "Fehler beim Lesen von " + file); - } - } - return null; - } - -// public static void reloadWorldInfo(File worldDir) { -// File file = new File(worldDir, "level.nbt"); -// if(file.exists()) { -// Config.clear(); -// try { -// Config.readFromNbt(NBTLoader.readGZip(file).getCompoundTag("Config"), true); -// } -// catch(Exception e) { -// Log.error("Fehler beim Lesen von " + file, e); -// return; -// } -// } -// } } diff --git a/server/src/server/Server.java b/server/src/server/Server.java index 728a53d..5fb29ea 100755 --- a/server/src/server/Server.java +++ b/server/src/server/Server.java @@ -6,9 +6,11 @@ import java.io.File; import java.io.IOException; import java.io.InputStreamReader; import java.net.InetAddress; +import java.text.SimpleDateFormat; import java.util.ArrayDeque; import java.util.ArrayList; import java.util.Collections; +import java.util.Date; import java.util.Iterator; import java.util.List; import java.util.Map; @@ -74,7 +76,6 @@ import common.util.WorldPos; import common.world.Region; import common.world.World; import common.world.WorldServer; -import common.world.Region.FolderInfo; import io.netty.bootstrap.ServerBootstrap; import io.netty.channel.Channel; import io.netty.channel.ChannelException; @@ -92,6 +93,7 @@ import server.command.CommandEnvironment; import server.command.FixedExecutor; import server.network.HandshakeHandler; import server.network.Player; +import server.world.Converter; public final class Server implements IThreadListener, IServer { private static final LazyLoadBase SERVER_NIO_EVENTLOOP = new LazyLoadBase() { @@ -155,6 +157,63 @@ public final class Server implements IThreadListener, IServer { Log.flushLog(); } + public static void saveServerConfig(long time) { + NBTTagCompound data = new NBTTagCompound(); + data.setLong("Time", time); + data.setLong("LastAccess", System.currentTimeMillis()); + data.setString("Version", Config.VERSION); + NBTTagCompound cfg = new NBTTagCompound(); + for(String cvar : Config.VARS.keySet()) { + cfg.setString(cvar, Config.VARS.get(cvar).getValue()); + } + data.setTag("Config", cfg); + data.setTag("Universe", UniverseRegistry.saveNbt()); + File nfile = new File("server.nbt.tmp"); + File lfile = new File("server.nbt"); + try { + NBTLoader.writeGZip(data, nfile); + if(lfile.exists()) + lfile.delete(); + nfile.renameTo(lfile); + } + catch(Exception e) { + Log.IO.error(e, "Fehler beim Schreiben von " + nfile); + } + } + + public static long loadServerConfig() { + Config.clear(); + UniverseRegistry.clear(); + File file = new File("server.nbt"); + if(!file.exists()) + file = new File("server.nbt.tmp"); + if(file.exists()) { + try { + NBTTagCompound tag = NBTLoader.readGZip(file); + NBTTagCompound cfg = tag.getCompoundTag("Config"); + for(String key : cfg.getKeySet()) { + Config.set(key, cfg.getString(key), null); + } + UniverseRegistry.loadNbt(tag.getCompoundTag("Universe")); + long lastPlayed = tag.getLong("LastAccess"); + String version = tag.hasKey("Version", 8) ? tag.getString("Version") : null; + version = version != null && version.isEmpty() ? "" : version; + long time = tag.hasKey("Time", 4) ? tag.getLong("Time") : World.START_TIME; + Log.IO.info("Version: %s", version); + Log.IO.info("Weltzeit: %d Ticks / %d Sekunden", time, time / 20L); + Log.IO.info("Zuletzt geladen: %s", new SimpleDateFormat("dd.MM.yyyy HH:mm:ss").format(new Date(lastPlayed))); + return time; + } + catch(Exception e) { + Log.IO.error(e, "Fehler beim Lesen von " + file); + Config.clear(); + UniverseRegistry.clear(); + } + } + Log.IO.info("Erstelle neue Welt und Konfiguration"); + return World.START_TIME; + } + private Server(boolean debug, boolean ipc) { this.debug = debug; this.ipcpipe = ipc; @@ -182,7 +241,7 @@ public final class Server implements IThreadListener, IServer { public void saveWorldInfo() { if(!this.debug) { - Region.saveWorldInfo(null, this.space.getDayTime()); + saveServerConfig(this.space.getDayTime()); WorldServer.saveWarps(this.warps); } } @@ -257,13 +316,14 @@ public final class Server implements IThreadListener, IServer { long time = System.currentTimeMillis(); Log.JNI.info("Starte Server Version " + Config.VERSION); if(!this.debug) { + Converter.convert(); this.setMessage("Welt wird erstellt und geladen"); - FolderInfo info = Region.loadWorldInfo(null); + long wtime = loadServerConfig(); // if(dtime == -1L) // { // dtime = World.START_TIME; //// Config.set("spawnDim", "1", null); //// } - this.worlds.add(this.space = new WorldServer(this, info == null ? World.START_TIME : info.time, + this.worlds.add(this.space = new WorldServer(this, wtime, Space.INSTANCE, false)); this.dimensions.put(this.space.dimension.getDimensionId(), this.space); new File("players").mkdirs(); diff --git a/client/src/client/world/Converter.java b/server/src/server/world/Converter.java similarity index 79% rename from client/src/client/world/Converter.java rename to server/src/server/world/Converter.java index 33bf568..5bc9269 100644 --- a/client/src/client/world/Converter.java +++ b/server/src/server/world/Converter.java @@ -1,4 +1,4 @@ -package client.world; +package server.world; import java.io.BufferedInputStream; import java.io.ByteArrayInputStream; @@ -7,16 +7,14 @@ import java.io.File; import java.io.FilenameFilter; import java.io.IOException; import java.io.RandomAccessFile; +import java.text.SimpleDateFormat; import java.util.Arrays; +import java.util.Date; import java.util.Map; import java.util.Map.Entry; import java.util.zip.GZIPInputStream; import java.util.zip.InflaterInputStream; -import client.Client; -import client.gui.GuiConvert; -import client.gui.GuiLoading; -import client.gui.GuiLoading.Callback; import common.biome.Biome; import common.block.Block; import common.block.BlockCactus; @@ -92,15 +90,26 @@ import common.world.Region; import common.world.State; import common.world.Weather; import common.world.World; -import common.world.Region.FolderInfo; -import common.world.Region.SaveVersion; +import server.Server; + +public abstract class Converter { + private static enum SaveVersion { + ALPHA_1_0("Alpha 1.0 - Beta 1.2"), + BETA_1_3("Beta 1.3 - Release 1.8.9"), + RELEASE_1_9("Release 1.9 - Release 1.12.2"), + RELEASE_1_13("Release 1.13 +"); + + private final String name; + + private SaveVersion(String name) { + this.name = name; + } + + public String toString() { + return this.name; + } + } -public final class Converter { -// public static interface Callback { -// void postMessage(String msg); -// void postProgress(int progress); -// } - private static class AnvilRegion { private final int[] offsets = new int[1024]; @@ -182,11 +191,7 @@ public final class Converter { State getState(int id, int data); } - private Converter() { - } - - private long postProgress(long start, int progress) { -// SKC.info("... " + progress + "%"); + private static long postProgress(long start, int progress) { if(System.currentTimeMillis() - start >= 500L) { start = System.currentTimeMillis(); Log.JNI.info("... " + progress + "%"); @@ -198,16 +203,7 @@ public final class Converter { private static final Map ENTITY_MAP = Maps.newHashMap(); private static final Map TILE_MAP = Maps.newHashMap(); private static final char[] BLOCK_MAP = new char[65536]; -// private static final Map BLOCK_FUNCS = Maps.newHashMap(); private static final Map OLD_GAMERULES = Maps.newHashMap(); - - private String action; - private String task; - private String file; - private int totalRegions; - private int doneRegions; - private int totalChunks; - private int doneChunks; private static void mapEntity(Class clazz, String ... names) { String name = EntityRegistry.getEntityString(clazz); @@ -253,17 +249,6 @@ public final class Converter { } } -// private static void mapBlockDynamic(BlockFunction func, int id, int data) { -// BLOCK_MAP[(id << 4) | data] = (char)0x000f; -// BLOCK_FUNCS.put((char)((id << 4) | data), func); -// } -// -// private static void mapBlockDynamic(BlockFunction func, int id) { -// for(int z = 0; z < 16; z++) { -// mapBlockDynamic(func, id, z); -// } -// } - static { OLD_GAMERULES.put("doFireTick", "fireTick"); OLD_GAMERULES.put("mobGriefing", "mobGriefing"); @@ -273,7 +258,6 @@ public final class Converter { OLD_GAMERULES.put("doEntityDrops", "dropObjects"); OLD_GAMERULES.put("naturalRegeneration", "naturalRegeneration"); OLD_GAMERULES.put("doDaylightCycle", "daylightCycle"); -// OLD_GAMERULES.put("showDeathMessages", "deathMessages"); OLD_GAMERULES.put("keepInventory", "keepInventory"); OLD_GAMERULES.put("doWeatherCycle", "weatherChanges"); OLD_GAMERULES.put("randomTickSpeed", "randomTickSpeed"); @@ -306,7 +290,6 @@ public final class Converter { mapTile(TileEntityDaylightDetector.class, "DLDetector", "daylight_detector"); mapTile(TileEntityHopper.class, "Hopper", "hopper"); mapTile(TileEntityComparator.class, "Comparator", "comparator"); -// mapTile(TileEntityFlowerPot.class, "FlowerPot", "flower_pot"); mapTile(TileEntityBanner.class, "Banner", "banner"); mapBlock(Blocks.stone.getState(), 1); @@ -609,11 +592,6 @@ public final class Converter { mapBlockData(Blocks.stonebrick_stairs, 109); mapBlock(Blocks.mycelium, 110); mapBlockData(Blocks.waterlily, 111); -// mapBlockDynamic(new BlockFunction() { -// public IBlockState getState(int id, int data) { -// return Blocks.waterlily.getDefaultState().withProperty(BlockDirectional.FACING, Facing.randHorizontal(RANDOM)); -// } -// }, 111); mapBlock(Blocks.blood_brick, 112); mapBlockData(Blocks.blood_brick_fence, 113); mapBlockData(Blocks.blood_brick_stairs, 114); @@ -822,97 +800,7 @@ public final class Converter { return Blocks.stained_hardened_clay.getState().withProperty(BlockColored.COLOR, DyeColor.byMetadata(data)); } }, 252); - // 253, 254 mapBlock(Blocks.obsidian, 255); - -// addBlock(137, 49); // Command Block -// addBlock(166, 0); // Barrier -// addBlock(168, 98); // Prismarine -// // addBlock(169, 169); // Sea Lantern --> Lamp -// addBlock(179, 24); // Red Sandstone -// addBlock(180, 128); // Red Sandstone Stairs -// addBlock(181, 43, 1); // Red Sandstone Double Slab -// -// addBlock(198, 101); // End Rod -// addBlock(199, 102); // Chorus Plant -// addBlock(200, 102); // Chorus Flower -// addBlock(201, 155); // Purpur Block -// addBlock(203, 156); // Purpur Stairs -// addBlock(206, 98); // End Stone Bricks -// addBlock(207, 142); // Beetroot Block -// addBlock(208, 60); // Grass Path -// addBlock(209, 20); // End Gateway -// addBlock(210, 137); // Repeating Command Block -// addBlock(211, 137); // Chain Command Block -// addBlock(212, 79); // Frosted Ice -// addBlock(213, 87); // Magma Block -// addBlock(214, 100); // Nether Wart Block -// addBlock(215, 112); // Red Nether Brick -// addBlock(216, 155); // Bone Block -// addBlock(217, 20); // Structure Void -// addBlock(218, 158); // Observer -// addBlock(255, 49); // Structure Block -// addBlock(202, 155, 2); // Purpur Pillar -// addBlock(204, 43, 7); // Purpur Double Slab - -// if(block > 197 && adddata != null) -// adddata.set(cx, cy, cz, 0); -// if(block == 1 || block == 19) { // Stone, Sponge -// data.set(cx, cy, cz, 0); -// } -// else if(block == 29 || block == 33 || block == 34) { // Piston, Sticky Piston, Piston Head -// int dt = data.get(cx, cy, cz); -// if((dt & 7) == 6) -// data.set(cx, cy, cz, (dt & 8) | 1); -// } -// else if(block == 97) { // Monster Egg -// int dt = data.get(cx, cy, cz); -// switch(dt) { -// case 0: -// default: -// blocks[c] = (byte)1; -// data.set(cx, cy, cz, 0); -// break; -// case 1: -// blocks[c] = (byte)4; -// data.set(cx, cy, cz, 0); -// break; -// case 2: -// case 3: -// case 4: -// case 5: -// blocks[c] = (byte)98; -// data.set(cx, cy, cz, dt - 2); -// break; -// } -// } -// mapBlock(new BlockFunction() { -// public IBlockState getState(int id, int data) { -// return Blocks.waterlily.getDefaultState().withProperty(BlockDirectional.FACING, Facing.randHorizontal(RANDOM)); -// } -// }, 111); -// else if(block == 111) { // Water Lily -// data.set(cx, cy, cz, RANDOM.zrange(4)); -// } -// else if(block == 251 || block == 252) { // Concrete, Concrete Powder -// blocks[c] = (byte)159; -// } -// else if(block >= 235 && block <= 250) { // Glazed Terracotta -// blocks[c] = (byte)159; -// data.set(cx, cy, cz, block - 235); -// } -// else if(block >= 219 && block <= 234) { // Shulker Box -// blocks[c] = (byte)35; -// data.set(cx, cy, cz, block - 219); -// } -// else if(block == 205) { // Purpur Slab -// blocks[c] = (byte)44; -// data.set(cx, cy, cz, (data.get(cx, cy, cz) & 8) == 8 ? 15 : 7); -// } -// else if(block == 182) { // Red Sandstone Slab -// blocks[c] = (byte)44; -// data.set(cx, cy, cz, (data.get(cx, cy, cz) & 8) == 8 ? 9 : 1); -// } } private static void convertTile(NBTTagCompound ent) { @@ -1113,17 +1001,13 @@ public final class Converter { return tag; } - private long convertChunks(File dir, File file, long start, int progress, int total) { + private static long convertChunks(File dir, File file, long start, int progress, int total) { String name = file.getName(); - this.file = name; - this.totalChunks = 1024; boolean legacy = name.endsWith(".mcr"); int rx, rz; String[] reg = name.split("\\."); if(reg.length != 4) { Log.JNI.warn("Unbekannte Region " + file); - this.doneChunks = 0; - this.file = null; return start; } try { @@ -1132,8 +1016,6 @@ public final class Converter { } catch(NumberFormatException e) { Log.JNI.warn("Unbekannte Region " + file); - this.doneChunks = 0; - this.file = null; return start; } try { @@ -1146,7 +1028,6 @@ public final class Converter { for(int bx = 0; bx < 4; bx++) { for(int bz = 0; bz < 4; bz++) { if(!oldreg.hasRegion(bx, bz)) { - this.doneChunks += 64; continue; } areas++; @@ -1161,7 +1042,6 @@ public final class Converter { DataInputStream in = oldreg.getInputStream(x, z); if(in == null) { Log.JNI.warn("Konnte " + file.getPath() + "@" + x + "," + z + " nicht lesen"); - this.doneChunks += 1; continue; } NBTTagCompound tag = NBTLoader.read(in); @@ -1172,7 +1052,6 @@ public final class Converter { // out.close(); newreg.writeTag(nx, nz, tag); } - this.doneChunks += 1; } } newreg.close(false); @@ -1190,36 +1069,26 @@ public final class Converter { catch(IOException e) { e.printStackTrace(); } - this.doneChunks = 0; - this.file = null; return start; } - public static FolderInfo convertMapFormat(File dir, boolean load) { + public static boolean convert() { long cur = System.currentTimeMillis(); - if(load) - Log.JNI.info("Welt '" + dir + "' wird konvertiert"); - if(new File(dir, "level.nbt").exists()) { - if(load) - Log.JNI.error("Datei level.nbt existiert bereits"); - return null; - } - File ldat = new File(dir, "level.dat"); + if(new File("server.nbt").exists()) + return false; + File ldat = new File("level.dat"); if(!ldat.exists()) - ldat = new File(dir, "level.dat_old"); - if(!ldat.exists()) { - if(load) - Log.JNI.error("Datei level.dat und level.dat_old nicht gefunden"); - return null; - } + ldat = new File("level.dat_old"); + if(!ldat.exists()) + return false; + Log.JNI.info("Welt wird konvertiert"); NBTTagCompound nbt; try { nbt = NBTLoader.readGZip(ldat); } catch(Exception e) { - if(load) - Log.JNI.error(e, "Fehler beim Lesen von level.dat"); - return null; + Log.JNI.error(e, "Fehler beim Lesen von level.dat"); + return false; } nbt = nbt.getCompoundTag("Data"); int version = nbt.getInteger("version"); @@ -1227,182 +1096,77 @@ public final class Converter { // nbt.setBoolean("incompatible", data >= 1400); SaveVersion ver = data >= 1400 ? SaveVersion.RELEASE_1_13 : (data >= 100 ? SaveVersion.RELEASE_1_9 : (version == 19132 || version == 19133 ? SaveVersion.BETA_1_3 : (version == 0 ? SaveVersion.ALPHA_1_0 : null))); if(ver == null) { - if(load) - Log.IO.error("Version %d ist unbekannt", version); - return null; + Log.IO.error("Version %d ist unbekannt", version); + return false; } long wtime = nbt.getLong(nbt.hasKey("DayTime", 99) ? "DayTime" : "Time") + World.START_TIME; - if(!load) - return new FolderInfo(wtime, nbt.getLong("LastPlayed"), ver, null); -// nbt.setString("verdesc", ver); -// NBTTagCompound nbt = getLegacyWorldInfo(dir); -// if(nbt == null) -// return false; - final Converter conv = new Converter(); - Client.CLIENT.displayGuiScreen(new GuiLoading("Konvertiere Welt ...", new Callback() { - public void poll(Client gm, GuiLoading gui) { - if(conv.totalRegions > 0) { - gui.setBar(conv.task, "Regionen", conv.totalRegions); - gui.setProgress(conv.doneRegions); - } - else { - gui.resetBar(); - } - if(conv.totalChunks > 0) { - gui.setSub(conv.file, "Chunks", conv.totalChunks); - gui.setSubProgress(conv.doneChunks); - } - else { - gui.resetSub(); - } - gui.setTask(conv.action); - } - })); - final NBTTagCompound tag = nbt; - new Thread(new Runnable() { - public void run() { - Log.IO.info("Version: %s", ver); - if(ver != SaveVersion.RELEASE_1_13) { - conv.action = "Suche nach Chunk-Daten"; - Log.JNI.info("Konvertiere Chunk-Daten von region/*.mca,*.mcr"); - File regionDir = new File(dir, "region"); - if(regionDir.exists()) { - File chunkDir = new File(new File(dir, "chunk"), "terra"); - Log.JNI.info("Konvertiere Welt nach '" + chunkDir + "' ..."); - Log.JNI.info("Durchsuche Ordner unter '" + regionDir + "' nach .mca- und .mcr-Dateien ..."); - File[] files = regionDir.listFiles(new FilenameFilter() { - public boolean accept(File file, String name) { - return name.endsWith(".mca") || name.endsWith(".mcr"); - } - }); - if(files.length == 0) { - Log.JNI.info("Keine .mca- oder .mcr-Dateien gefunden."); - } - else { - conv.task = "Konvertiere Chunkdaten"; - conv.totalRegions = files.length; - Log.JNI.info("Ingesamt wurden " + files.length + " .mca-Dateien und .mcr-Dateien gefunden, konvertiere ..."); - if(ver == SaveVersion.RELEASE_1_9) - Log.JNI.info("Konvertiere von neuerer Version, dies wird Blöcke entfernen ..."); - chunkDir.mkdirs(); - int progress = 0; - long time = System.currentTimeMillis(); - long start = conv.postProgress(time, 0); - for(File file : files) { - int percent = (int)Math.round(100.0D * (double)progress / (double)files.length); - Log.JNI.info("Konvertiere Chunk-Daten: " + file.getName() + " (" + progress + "/" + files.length + ")"); - start = conv.convertChunks(chunkDir, file, start, progress, files.length); - ++progress; - start = conv.postProgress(start, percent); - conv.doneRegions += 1; - } - time = System.currentTimeMillis() - time; - Log.JNI.info("Fertig. Konversion dauerte " + ((time / 60000L) > 0 ? ((time / 60000L) + " Minuten und ") : "") + ((time / 1000L) % 60L) + " Sekunden."); - } - } - } - else { - Log.JNI.warn("Konvertiere keine Chunk-Daten, da Version zu neu"); - } - conv.doneRegions = 0; - conv.task = null; - conv.action = "Konvertiere level.dat"; - Log.JNI.info("Konvertiere Daten von level.dat"); - Config.clear(); - UniverseRegistry.clear(); - if(tag.hasKey("GameRules", 10)) { - NBTTagCompound rules = tag.getCompoundTag("GameRules"); - for(Entry rule : OLD_GAMERULES.entrySet()) { - if(rules.hasKey(rule.getKey(), 8)) - Config.set(rule.getValue(), rules.getString(rule.getKey()), null); - } - } - // Config.setVar("noRespawn", "" + nbt.getBoolean("hardcore"), false); - // int id = nbt.getInteger("GameType"); - // Config.set("defaultNoCreative", "" + (id == 2 || id == 0), false); - Log.JNI.info("Speichere neue level.nbt ..."); - Region.saveWorldInfo(dir, wtime); -// if(tag.hasKey("Player", 10)) { -// conv.action = "Konvertiere Spielerdaten"; -// NBTTagCompound player = tag.getCompoundTag("Player"); -// NBTTagList pos = player.getTagList("Pos", 6); -// NBTTagList motion = player.getTagList("Motion", 6); -// NBTTagList rotation = player.getTagList("Rotation", 5); -// boolean ground = player.getBoolean("OnGround"); -// BlockPos spawn = null; -// // boolean force = player.getBoolean("OnGround"); -// // int mode = -1; -// // if(player.hasKey("playerGameType", 99)) { -// // mode = player.getInteger("playerGameType"); -// // mode = mode == 0 || mode == 2 ? 0 : (mode == 1 || mode == 3 ? 1 : -1); -// // } -// if(player.hasKey("SpawnX", 99) && player.hasKey("SpawnY", 99) && player.hasKey("SpawnZ", 99)) { -// spawn = new BlockPos(player.getInteger("SpawnX"), player.getInteger("SpawnY"), -// player.getInteger("SpawnZ")); -// // force = player.getBoolean("SpawnForced"); -// } -// player.getKeySet().clear(); -// player.setTag("Pos", pos); -// player.setTag("Motion", motion); -// player.setTag("Rotation", rotation); -// player.setBoolean("OnGround", ground); -// player.setInteger("Dimension", 1); -// player.setString("id", EntityRegistry.getEntityString(EntityHuman.class)); -// if(spawn != null) { -// player.setInteger("SpawnX", spawn.getX()); -// player.setInteger("SpawnY", spawn.getY()); -// player.setInteger("SpawnZ", spawn.getZ()); -// player.setInteger("SpawnDim", 1); -// // player.setBoolean("SpawnForced", force); -// } -// player.setInteger("OriginX", tag.getInteger("SpawnX")); -// player.setInteger("OriginY", tag.getInteger("SpawnY")); -// player.setInteger("OriginZ", tag.getInteger("SpawnZ")); -// player.setInteger("OriginDim", 1); -// player.setString("CustomName", user.substring(0, 1).toUpperCase() + user.substring(1)); -// NBTTagCompound plr = new NBTTagCompound(); -// plr.setInteger("selected", 0); -// NBTTagList list = new NBTTagList(); -// list.appendTag(player); -// plr.setTag("characters", list); -// // if(mode >= 0) -// // player.setBoolean("creative", mode == 1); -// Log.JNI.info("Speichere neue Spielerdaten " + user.toLowerCase() + ".nbt ..."); -// File pdat = new File(new File(dir, "players"), user.toLowerCase() + ".nbt"); -// try { -// pdat.getParentFile().mkdirs(); -// NBTLoader.writeGZip(plr, pdat); -// } -// catch(Exception e) { -// Log.JNI.error(e, "Fehler beim Schreiben von " + pdat); -// } -// } - Weather weather = tag.getBoolean("thundering") ? Weather.THUNDER : (tag.getBoolean("raining") ? Weather.RAIN : Weather.CLEAR); - if(weather != Weather.CLEAR) { - conv.action = "Konvertiere Dimensionsdaten"; - NBTTagCompound dataTag = new NBTTagCompound(); - dataTag.setString("Weather", weather.getName()); - Log.JNI.info("Speichere neue data.nbt ..."); - File dataFile = new File(new File(new File(dir, "chunk"), "terra"), "data.nbt"); - try { - NBTLoader.writeGZip(dataTag, dataFile); - } - catch(Exception e) { - Log.JNI.error(e, "Konnte Weltdaten nicht speichern"); - } - } - Log.IO.info("Welt '" + dir + "' wurde in %d Sekunden konvertiert", (System.currentTimeMillis() - cur) / 1000L); - Client.CLIENT.schedule(new Runnable() { - public void run() { - Client.CLIENT.displayGuiScreen(GuiConvert.INSTANCE); + Log.IO.info("Version: %s", ver); + Log.IO.info("Weltzeit: %d Ticks / %d Sekunden", wtime, wtime / 20L); + Log.IO.info("Zuletzt geladen: %s", new SimpleDateFormat("dd.MM.yyyy HH:mm:ss").format(new Date(nbt.getLong("LastPlayed")))); + if(ver != SaveVersion.RELEASE_1_13) { + Log.JNI.info("Konvertiere Chunk-Daten von region/*.mca,*.mcr"); + File regionDir = new File("region"); + if(regionDir.exists()) { + File chunkDir = new File(new File("chunk"), "terra"); + Log.JNI.info("Konvertiere Welt nach '" + chunkDir + "' ..."); + Log.JNI.info("Durchsuche Ordner unter '" + regionDir + "' nach .mca- und .mcr-Dateien ..."); + File[] files = regionDir.listFiles(new FilenameFilter() { + public boolean accept(File file, String name) { + return name.endsWith(".mca") || name.endsWith(".mcr"); } }); + if(files.length == 0) { + Log.JNI.info("Keine .mca- oder .mcr-Dateien gefunden."); + } + else { + Log.JNI.info("Ingesamt wurden " + files.length + " .mca-Dateien und .mcr-Dateien gefunden, konvertiere ..."); + if(ver == SaveVersion.RELEASE_1_9) + Log.JNI.info("Konvertiere von neuerer Version, dies wird Blöcke entfernen ..."); + chunkDir.mkdirs(); + int progress = 0; + long time = System.currentTimeMillis(); + long start = postProgress(time, 0); + for(File file : files) { + int percent = (int)Math.round(100.0D * (double)progress / (double)files.length); + Log.JNI.info("Konvertiere Chunk-Daten: " + file.getName() + " (" + progress + "/" + files.length + ")"); + start = convertChunks(chunkDir, file, start, progress, files.length); + ++progress; + start = postProgress(start, percent); + } + time = System.currentTimeMillis() - time; + Log.JNI.info("Fertig. Konversion dauerte " + ((time / 60000L) > 0 ? ((time / 60000L) + " Minuten und ") : "") + ((time / 1000L) % 60L) + " Sekunden."); + } } - }, "Converter Thread").start(); - return new FolderInfo(wtime, System.currentTimeMillis(), null, Config.VERSION); + } + else { + Log.JNI.warn("Konvertiere keine Chunk-Daten, da Version zu neu"); + } + Log.JNI.info("Konvertiere Daten von level.dat"); + Config.clear(); + UniverseRegistry.clear(); + if(nbt.hasKey("GameRules", 10)) { + NBTTagCompound rules = nbt.getCompoundTag("GameRules"); + for(Entry rule : OLD_GAMERULES.entrySet()) { + if(rules.hasKey(rule.getKey(), 8)) + Config.set(rule.getValue(), rules.getString(rule.getKey()), null); + } + } + Log.JNI.info("Speichere neue server.nbt ..."); + Server.saveServerConfig(wtime); + Weather weather = nbt.getBoolean("thundering") ? Weather.THUNDER : (nbt.getBoolean("raining") ? Weather.RAIN : Weather.CLEAR); + if(weather != Weather.CLEAR) { + NBTTagCompound dataTag = new NBTTagCompound(); + dataTag.setString("Weather", weather.getName()); + Log.JNI.info("Speichere neue data.nbt ..."); + File dataFile = new File(new File(new File("chunk"), "terra"), "data.nbt"); + try { + NBTLoader.writeGZip(dataTag, dataFile); + } + catch(Exception e) { + Log.JNI.error(e, "Konnte Weltdaten nicht speichern"); + } + } + Log.IO.info("Welt wurde in %d Sekunden konvertiert", (System.currentTimeMillis() - cur) / 1000L); + return true; } - -// public static NBTTagCompound getLegacyWorldInfo(File worldDir) { -// return nbt; -// } } From 1578d22e4660afa662bb776ba7ba433e6ef105c9 Mon Sep 17 00:00:00 2001 From: Sen Date: Mon, 12 May 2025 19:13:37 +0200 Subject: [PATCH 022/200] specify client and server --- client/src/client/Client.java | 10 +++++----- client/src/client/gui/GuiConnect.java | 1 - client/src/client/gui/GuiInfo.java | 2 +- client/src/client/gui/GuiMenu.java | 5 +++-- client/src/client/gui/GuiServer.java | 2 +- common/src/common/init/Config.java | 2 ++ server/src/server/Server.java | 2 +- 7 files changed, 13 insertions(+), 11 deletions(-) diff --git a/client/src/client/Client.java b/client/src/client/Client.java index e0ab9f0..33f7fc3 100755 --- a/client/src/client/Client.java +++ b/client/src/client/Client.java @@ -1216,14 +1216,14 @@ public class Client implements IThreadListener, IClient { // SKC.setGuiMenu(); // else // SKC.setGuiAny(); - Window.setTitle(String.format("%s - %s", Config.VERSION, gui.getTitle())); + Window.setTitle(String.format("%s - %s", Config.CLIENT_VERSION, gui.getTitle())); } else { this.menu(false); this.leftClickCounter = 10000; Bind.disableMouse(); - Window.setTitle(String.format("%s - %s%s", Config.VERSION, "Welt / Render", this.nograb ? "" : " (Maus gefangen)")); + Window.setTitle(String.format("%s - %s%s", Config.CLIENT_VERSION, "Welt / Render", this.nograb ? "" : " (Maus gefangen)")); // SKC.setGuiNone(); } } @@ -2139,8 +2139,8 @@ public class Client implements IThreadListener, IClient { public void run() { Log.SYSTEM.info("Java " + System.getProperty("java.version")); - Log.SYSTEM.info(Config.VERSION); - if(!Window.createWindow(Config.VERSION, System.getProperty("opengl.debug") != null)) + Log.SYSTEM.info(Config.CLIENT_VERSION); + if(!Window.createWindow(Config.CLIENT_VERSION, System.getProperty("opengl.debug") != null)) System.exit(1); Log.SYSTEM.info("OpenGL %s", GL11.glGetString(GL11.GL_VERSION)); Log.SYSTEM.info("GL_VENDOR: %s", GL11.glGetString(GL11.GL_VENDOR)); @@ -2912,7 +2912,7 @@ public class Client implements IThreadListener, IClient { } public void reset() { - this.buffer = TextColor.NEON + "*** " + Config.VERSION + " ***"; + this.buffer = TextColor.NEON + "*** " + Config.CLIENT_VERSION + " ***"; this.console.clear(); this.chat.clear(); this.feed.clear(); diff --git a/client/src/client/gui/GuiConnect.java b/client/src/client/gui/GuiConnect.java index 339a92e..9d0eb3e 100644 --- a/client/src/client/gui/GuiConnect.java +++ b/client/src/client/gui/GuiConnect.java @@ -181,7 +181,6 @@ public class GuiConnect extends GuiList implements ActBut this.add(this.deleteButton = new ActButton(width / 2 - 75, height - 28, 150, 24, this, "Löschen")); this.add(this.editButton = new ActButton(width / 2 + 79, height - 28, 150, 24, this, "Bearbeiten")); this.add(this.copyButton = new ActButton(width / 2 - 229, height - 28, 150, 24, this, "Kopieren")); - this.add(new NavButton(4, 4, 200, 24, GuiServer.INSTANCE, "Schnellverbindung ...")); this.add(new NavButton(width / 2 + 233, height - 28, 150, 24, GuiMenu.INSTANCE, "Abbrechen")); this.selectButton.enabled = false; diff --git a/client/src/client/gui/GuiInfo.java b/client/src/client/gui/GuiInfo.java index 9b18880..7d64ac4 100644 --- a/client/src/client/gui/GuiInfo.java +++ b/client/src/client/gui/GuiInfo.java @@ -8,7 +8,7 @@ import common.log.Log; public class GuiInfo extends Gui { private static final String VER = - TextColor.GREEN + "" + TextColor.BUG + "" + TextColor.BUG + "" + TextColor.BUG + " " + TextColor.VIOLET + "" + Config.VERSION + "" + + TextColor.GREEN + "" + TextColor.BUG + "" + TextColor.BUG + "" + TextColor.BUG + " " + TextColor.VIOLET + "" + Config.CLIENT_VERSION + "" + TextColor.GREEN + " " + TextColor.BUG + "" + TextColor.BUG + "" + TextColor.BUG; private static final String INFO = "Ein Spiel zur Simulation, zum Testen, für Rollenspiele, Mehrspieler und vieles mehr." + "\n" + diff --git a/client/src/client/gui/GuiMenu.java b/client/src/client/gui/GuiMenu.java index 54cbb34..e562003 100644 --- a/client/src/client/gui/GuiMenu.java +++ b/client/src/client/gui/GuiMenu.java @@ -52,7 +52,7 @@ public class GuiMenu extends Gui { this.ticks = 0; this.hacked = 0; this.resetAnimation(); - this.add(new ActButton(0, 0, 400, 24, new ActButton.Callback() { + this.add(new ActButton(0, -28, 400, 24, new ActButton.Callback() { public void use(ActButton elem, Mode action) { if(GuiMenu.this.hacked == 9) { GuiMenu.this.hacked++; @@ -63,6 +63,7 @@ public class GuiMenu extends Gui { } } }, "Server beitreten")); + this.add(new NavButton(0, 0, 400, 24, GuiServer.INSTANCE, "Schnellverbindung")); this.add(new ActButton(0, 28, 400, 24, new ActButton.Callback() { public void use(ActButton elem, Mode action) { if(GuiMenu.this.hacked == 8) @@ -100,7 +101,7 @@ public class GuiMenu extends Gui { } }, "Client schließen")); this.shift(); - this.add(new Label(4, /* this.gm.fb_y - 2 */ 0, 200, 20, TextColor.VIOLET + Config.VERSION, true)); + this.add(new Label(4, /* this.gm.fb_y - 2 */ 0, 200, 20, TextColor.VIOLET + Config.CLIENT_VERSION, true)); this.splashLabel = this.add(new Label(0, 160, width, 24, "")); this.pickSplash(); } diff --git a/client/src/client/gui/GuiServer.java b/client/src/client/gui/GuiServer.java index 42dcdeb..6fc3495 100644 --- a/client/src/client/gui/GuiServer.java +++ b/client/src/client/gui/GuiServer.java @@ -58,7 +58,7 @@ public class GuiServer extends Gui implements Textbox.Callback { GuiServer.this.connect(); } }, this.server == null ? "Verbinden" : (this.server.getName().isEmpty() ? "Hinzufügen" : "Übernehmen"))); - this.add(new NavButton(0, 250, 480, 24, GuiConnect.INSTANCE, "Zurück")); + this.add(new NavButton(0, 250, 480, 24, this.server != null ? GuiConnect.INSTANCE : GuiMenu.INSTANCE, "Zurück")); if(this.server != null) this.nameLabel = this.add(new Label(0, -70, 410, 20, "Name", true)); this.addrLabel = this.add(new Label(0, 0, 410, 20, "Adresse", true)); diff --git a/common/src/common/init/Config.java b/common/src/common/init/Config.java index 5415de3..ca82a82 100755 --- a/common/src/common/init/Config.java +++ b/common/src/common/init/Config.java @@ -129,7 +129,9 @@ public abstract class Config { public static final int PROTOCOL = 666; public static final int PORT = 26666; + public static final String NAME = "TCR"; public static final String VERSION = "v2.2.1-alpha"; + public static final String CLIENT_VERSION = NAME + " Client " + VERSION; public static final Map VARS = new TreeMap(); diff --git a/server/src/server/Server.java b/server/src/server/Server.java index 5fb29ea..52675ce 100755 --- a/server/src/server/Server.java +++ b/server/src/server/Server.java @@ -314,7 +314,7 @@ public final class Server implements IThreadListener, IServer { public void run(int port) { long time = System.currentTimeMillis(); - Log.JNI.info("Starte Server Version " + Config.VERSION); + Log.JNI.info("Starte " + Config.NAME + " Server Version " + Config.VERSION); if(!this.debug) { Converter.convert(); this.setMessage("Welt wird erstellt und geladen"); From 66e9f68eeecf11cbb3575862e000de5fd56ebe3d Mon Sep 17 00:00:00 2001 From: Sen Date: Tue, 13 May 2025 14:39:09 +0200 Subject: [PATCH 023/200] move attributes --- client/src/client/network/ClientPlayer.java | 8 ++++---- common/src/common/ai/EntityAIFindEntityNearest.java | 4 ++-- common/src/common/ai/EntityAITarget.java | 4 ++-- common/src/common/ai/EntityMoveHelper.java | 2 +- .../src/common/{entity => }/attributes/Attribute.java | 2 +- .../{entity => }/attributes/AttributeInstance.java | 2 +- .../common/{entity => }/attributes/AttributeMap.java | 3 ++- .../{entity => }/attributes/AttributeModifier.java | 2 +- .../src/common/{entity => }/attributes/Attributes.java | 2 +- common/src/common/entity/EntityTrackerEntry.java | 4 ++-- common/src/common/entity/animal/EntityChicken.java | 2 +- common/src/common/entity/animal/EntityCow.java | 2 +- common/src/common/entity/animal/EntityHorse.java | 4 ++-- common/src/common/entity/animal/EntityMouse.java | 4 ++-- common/src/common/entity/animal/EntityOcelot.java | 2 +- common/src/common/entity/animal/EntityPig.java | 2 +- common/src/common/entity/animal/EntityRabbit.java | 2 +- common/src/common/entity/animal/EntitySheep.java | 2 +- common/src/common/entity/animal/EntityWolf.java | 2 +- common/src/common/entity/npc/EntityChaosMarine.java | 2 +- common/src/common/entity/npc/EntityFlyingNPC.java | 2 +- common/src/common/entity/npc/EntityGargoyle.java | 2 +- common/src/common/entity/npc/EntityGoblin.java | 2 +- common/src/common/entity/npc/EntityHaunter.java | 2 +- common/src/common/entity/npc/EntityHoveringNPC.java | 2 +- common/src/common/entity/npc/EntityMage.java | 4 ++-- common/src/common/entity/npc/EntityMobNPC.java | 4 ++-- common/src/common/entity/npc/EntityNPC.java | 4 ++-- common/src/common/entity/npc/EntityOrc.java | 2 +- common/src/common/entity/npc/EntityPrimarch.java | 2 +- common/src/common/entity/npc/EntitySlime.java | 2 +- common/src/common/entity/npc/EntitySpaceMarine.java | 2 +- common/src/common/entity/npc/EntityTiefling.java | 2 +- common/src/common/entity/npc/EntityUndead.java | 2 +- common/src/common/entity/npc/EntityVampire.java | 2 +- common/src/common/entity/npc/EntityZombie.java | 4 ++-- common/src/common/entity/types/EntityLiving.java | 10 +++++----- common/src/common/inventory/ContainerPlayer.java | 2 +- common/src/common/item/Item.java | 4 ++-- common/src/common/item/ItemArmor.java | 6 +++--- common/src/common/item/ItemBucketMilk.java | 6 +++--- common/src/common/item/ItemMetal.java | 6 +++--- common/src/common/item/ItemMetalBlock.java | 6 +++--- common/src/common/item/ItemPotion.java | 4 ++-- common/src/common/item/ItemStack.java | 6 +++--- common/src/common/item/ItemSword.java | 6 +++--- common/src/common/item/ItemTool.java | 6 +++--- .../src/common/packet/S20PacketEntityProperties.java | 4 ++-- common/src/common/pathfinding/PathNavigate.java | 4 ++-- common/src/common/potion/Potion.java | 10 +++++----- .../{entity/attributes => util}/LowerStringMap.java | 2 +- 51 files changed, 90 insertions(+), 89 deletions(-) rename common/src/common/{entity => }/attributes/Attribute.java (98%) rename common/src/common/{entity => }/attributes/AttributeInstance.java (99%) rename common/src/common/{entity => }/attributes/AttributeMap.java (98%) rename common/src/common/{entity => }/attributes/AttributeModifier.java (99%) rename common/src/common/{entity => }/attributes/Attributes.java (99%) rename common/src/common/{entity/attributes => util}/LowerStringMap.java (98%) diff --git a/client/src/client/network/ClientPlayer.java b/client/src/client/network/ClientPlayer.java index e8d1e1f..217ff52 100755 --- a/client/src/client/network/ClientPlayer.java +++ b/client/src/client/network/ClientPlayer.java @@ -27,16 +27,16 @@ import client.gui.container.GuiRepair; import client.gui.ingame.GuiSign; import client.renderer.particle.EntityPickupFX; import client.renderer.texture.EntityTexManager; +import common.attributes.Attribute; +import common.attributes.AttributeInstance; +import common.attributes.AttributeMap; +import common.attributes.AttributeModifier; import common.collect.Lists; import common.collect.Maps; import common.dimension.Dimension; import common.entity.DataWatcher; import common.entity.Entity; import common.entity.animal.EntityHorse; -import common.entity.attributes.Attribute; -import common.entity.attributes.AttributeInstance; -import common.entity.attributes.AttributeMap; -import common.entity.attributes.AttributeModifier; import common.entity.effect.EntityLightning; import common.entity.item.EntityBoat; import common.entity.item.EntityXp; diff --git a/common/src/common/ai/EntityAIFindEntityNearest.java b/common/src/common/ai/EntityAIFindEntityNearest.java index ee34588..87eb994 100755 --- a/common/src/common/ai/EntityAIFindEntityNearest.java +++ b/common/src/common/ai/EntityAIFindEntityNearest.java @@ -4,8 +4,8 @@ import java.util.Collections; import java.util.List; import java.util.function.Predicate; -import common.entity.attributes.AttributeInstance; -import common.entity.attributes.Attributes; +import common.attributes.AttributeInstance; +import common.attributes.Attributes; import common.entity.types.EntityLiving; public class EntityAIFindEntityNearest extends EntityAIBase diff --git a/common/src/common/ai/EntityAITarget.java b/common/src/common/ai/EntityAITarget.java index 2c6b33b..58d7769 100755 --- a/common/src/common/ai/EntityAITarget.java +++ b/common/src/common/ai/EntityAITarget.java @@ -1,7 +1,7 @@ package common.ai; -import common.entity.attributes.AttributeInstance; -import common.entity.attributes.Attributes; +import common.attributes.AttributeInstance; +import common.attributes.Attributes; import common.entity.types.EntityLiving; import common.entity.types.IEntityOwnable; import common.init.Config; diff --git a/common/src/common/ai/EntityMoveHelper.java b/common/src/common/ai/EntityMoveHelper.java index 1528c0e..74f4f40 100755 --- a/common/src/common/ai/EntityMoveHelper.java +++ b/common/src/common/ai/EntityMoveHelper.java @@ -1,6 +1,6 @@ package common.ai; -import common.entity.attributes.Attributes; +import common.attributes.Attributes; import common.entity.types.EntityLiving; import common.util.ExtMath; diff --git a/common/src/common/entity/attributes/Attribute.java b/common/src/common/attributes/Attribute.java similarity index 98% rename from common/src/common/entity/attributes/Attribute.java rename to common/src/common/attributes/Attribute.java index 3e56630..ed6c7e9 100755 --- a/common/src/common/entity/attributes/Attribute.java +++ b/common/src/common/attributes/Attribute.java @@ -1,4 +1,4 @@ -package common.entity.attributes; +package common.attributes; import java.util.Map; diff --git a/common/src/common/entity/attributes/AttributeInstance.java b/common/src/common/attributes/AttributeInstance.java similarity index 99% rename from common/src/common/entity/attributes/AttributeInstance.java rename to common/src/common/attributes/AttributeInstance.java index 7204633..299161b 100755 --- a/common/src/common/entity/attributes/AttributeInstance.java +++ b/common/src/common/attributes/AttributeInstance.java @@ -1,4 +1,4 @@ -package common.entity.attributes; +package common.attributes; import java.util.Collection; import java.util.Map; diff --git a/common/src/common/entity/attributes/AttributeMap.java b/common/src/common/attributes/AttributeMap.java similarity index 98% rename from common/src/common/entity/attributes/AttributeMap.java rename to common/src/common/attributes/AttributeMap.java index a19fcba..c859fd3 100755 --- a/common/src/common/entity/attributes/AttributeMap.java +++ b/common/src/common/attributes/AttributeMap.java @@ -1,4 +1,4 @@ -package common.entity.attributes; +package common.attributes; import java.util.Collection; import java.util.Map; @@ -6,6 +6,7 @@ import java.util.Map.Entry; import common.collect.Maps; import common.collect.Sets; +import common.util.LowerStringMap; import java.util.Set; diff --git a/common/src/common/entity/attributes/AttributeModifier.java b/common/src/common/attributes/AttributeModifier.java similarity index 99% rename from common/src/common/entity/attributes/AttributeModifier.java rename to common/src/common/attributes/AttributeModifier.java index 9081bd1..ba4d937 100755 --- a/common/src/common/entity/attributes/AttributeModifier.java +++ b/common/src/common/attributes/AttributeModifier.java @@ -1,4 +1,4 @@ -package common.entity.attributes; +package common.attributes; import common.rng.Random; diff --git a/common/src/common/entity/attributes/Attributes.java b/common/src/common/attributes/Attributes.java similarity index 99% rename from common/src/common/entity/attributes/Attributes.java rename to common/src/common/attributes/Attributes.java index c23c629..6a1ccc6 100755 --- a/common/src/common/entity/attributes/Attributes.java +++ b/common/src/common/attributes/Attributes.java @@ -1,4 +1,4 @@ -package common.entity.attributes; +package common.attributes; import java.util.Collection; diff --git a/common/src/common/entity/EntityTrackerEntry.java b/common/src/common/entity/EntityTrackerEntry.java index f70867f..9b3a96f 100755 --- a/common/src/common/entity/EntityTrackerEntry.java +++ b/common/src/common/entity/EntityTrackerEntry.java @@ -4,9 +4,9 @@ import java.util.Collection; import java.util.List; import java.util.Set; +import common.attributes.AttributeInstance; +import common.attributes.AttributeMap; import common.collect.Sets; -import common.entity.attributes.AttributeInstance; -import common.entity.attributes.AttributeMap; import common.entity.npc.EntityNPC; import common.entity.projectile.EntityArrow; import common.entity.types.EntityLiving; diff --git a/common/src/common/entity/animal/EntityChicken.java b/common/src/common/entity/animal/EntityChicken.java index c809c9f..aaec6ab 100755 --- a/common/src/common/entity/animal/EntityChicken.java +++ b/common/src/common/entity/animal/EntityChicken.java @@ -8,7 +8,7 @@ import common.ai.EntityAISwimming; import common.ai.EntityAITempt; import common.ai.EntityAIWander; import common.ai.EntityAIWatchClosest; -import common.entity.attributes.Attributes; +import common.attributes.Attributes; import common.entity.npc.EntityNPC; import common.entity.types.EntityAnimal; import common.entity.types.EntityLiving; diff --git a/common/src/common/entity/animal/EntityCow.java b/common/src/common/entity/animal/EntityCow.java index cadd0a3..4d3df31 100755 --- a/common/src/common/entity/animal/EntityCow.java +++ b/common/src/common/entity/animal/EntityCow.java @@ -8,7 +8,7 @@ import common.ai.EntityAISwimming; import common.ai.EntityAITempt; import common.ai.EntityAIWander; import common.ai.EntityAIWatchClosest; -import common.entity.attributes.Attributes; +import common.attributes.Attributes; import common.entity.npc.EntityNPC; import common.entity.types.EntityAnimal; import common.entity.types.EntityLiving; diff --git a/common/src/common/entity/animal/EntityHorse.java b/common/src/common/entity/animal/EntityHorse.java index ed9d625..7352c24 100755 --- a/common/src/common/entity/animal/EntityHorse.java +++ b/common/src/common/entity/animal/EntityHorse.java @@ -10,12 +10,12 @@ import common.ai.EntityAIRunAroundLikeCrazy; import common.ai.EntityAISwimming; import common.ai.EntityAIWander; import common.ai.EntityAIWatchClosest; +import common.attributes.AttributeInstance; +import common.attributes.Attributes; import common.block.Block; import common.block.SoundType; import common.entity.DamageSource; import common.entity.Entity; -import common.entity.attributes.AttributeInstance; -import common.entity.attributes.Attributes; import common.entity.npc.EntityNPC; import common.entity.types.EntityAnimal; import common.entity.types.EntityLiving; diff --git a/common/src/common/entity/animal/EntityMouse.java b/common/src/common/entity/animal/EntityMouse.java index 8456057..e304a0f 100755 --- a/common/src/common/entity/animal/EntityMouse.java +++ b/common/src/common/entity/animal/EntityMouse.java @@ -10,9 +10,9 @@ import common.ai.EntityAISwimming; import common.ai.EntityAITempt; import common.ai.EntityAIWander; import common.ai.EntityAIWatchClosest; +import common.attributes.AttributeInstance; +import common.attributes.Attributes; import common.block.Block; -import common.entity.attributes.AttributeInstance; -import common.entity.attributes.Attributes; import common.entity.npc.EntityNPC; import common.entity.types.EntityAnimal; import common.entity.types.EntityLiving; diff --git a/common/src/common/entity/animal/EntityOcelot.java b/common/src/common/entity/animal/EntityOcelot.java index 78acf63..12d53c2 100755 --- a/common/src/common/entity/animal/EntityOcelot.java +++ b/common/src/common/entity/animal/EntityOcelot.java @@ -13,9 +13,9 @@ import common.ai.EntityAITargetNonTamed; import common.ai.EntityAITempt; import common.ai.EntityAIWander; import common.ai.EntityAIWatchClosest; +import common.attributes.Attributes; import common.entity.DamageSource; import common.entity.Entity; -import common.entity.attributes.Attributes; import common.entity.npc.Alignment; import common.entity.npc.EntityNPC; import common.entity.types.EntityAnimal; diff --git a/common/src/common/entity/animal/EntityPig.java b/common/src/common/entity/animal/EntityPig.java index b094e99..52e04b3 100755 --- a/common/src/common/entity/animal/EntityPig.java +++ b/common/src/common/entity/animal/EntityPig.java @@ -9,7 +9,7 @@ import common.ai.EntityAISwimming; import common.ai.EntityAITempt; import common.ai.EntityAIWander; import common.ai.EntityAIWatchClosest; -import common.entity.attributes.Attributes; +import common.attributes.Attributes; import common.entity.npc.EntityNPC; import common.entity.types.EntityAnimal; import common.entity.types.EntityLiving; diff --git a/common/src/common/entity/animal/EntityRabbit.java b/common/src/common/entity/animal/EntityRabbit.java index a8f319a..93ce36f 100755 --- a/common/src/common/entity/animal/EntityRabbit.java +++ b/common/src/common/entity/animal/EntityRabbit.java @@ -15,11 +15,11 @@ import common.ai.EntityAIWander; import common.ai.EntityAIWatchClosest; import common.ai.EntityJumpHelper; import common.ai.EntityMoveHelper; +import common.attributes.Attributes; import common.block.Block; import common.block.BlockTallGrass; import common.entity.DamageSource; import common.entity.Entity; -import common.entity.attributes.Attributes; import common.entity.npc.Alignment; import common.entity.npc.EntityNPC; import common.entity.types.EntityAnimal; diff --git a/common/src/common/entity/animal/EntitySheep.java b/common/src/common/entity/animal/EntitySheep.java index 2c2ab93..cf4ee54 100755 --- a/common/src/common/entity/animal/EntitySheep.java +++ b/common/src/common/entity/animal/EntitySheep.java @@ -11,10 +11,10 @@ import common.ai.EntityAISwimming; import common.ai.EntityAITempt; import common.ai.EntityAIWander; import common.ai.EntityAIWatchClosest; +import common.attributes.Attributes; import common.biome.Biome; import common.collect.Maps; import common.color.DyeColor; -import common.entity.attributes.Attributes; import common.entity.item.EntityItem; import common.entity.npc.EntityNPC; import common.entity.types.EntityAnimal; diff --git a/common/src/common/entity/animal/EntityWolf.java b/common/src/common/entity/animal/EntityWolf.java index c99ffad..caa4b4a 100755 --- a/common/src/common/entity/animal/EntityWolf.java +++ b/common/src/common/entity/animal/EntityWolf.java @@ -15,10 +15,10 @@ import common.ai.EntityAISwimming; import common.ai.EntityAITargetNonTamed; import common.ai.EntityAIWander; import common.ai.EntityAIWatchClosest; +import common.attributes.Attributes; import common.color.DyeColor; import common.entity.DamageSource; import common.entity.Entity; -import common.entity.attributes.Attributes; import common.entity.npc.Alignment; import common.entity.npc.EntityNPC; import common.entity.types.EntityAnimal; diff --git a/common/src/common/entity/npc/EntityChaosMarine.java b/common/src/common/entity/npc/EntityChaosMarine.java index cccb1b3..13790fa 100755 --- a/common/src/common/entity/npc/EntityChaosMarine.java +++ b/common/src/common/entity/npc/EntityChaosMarine.java @@ -2,8 +2,8 @@ package common.entity.npc; import java.util.List; +import common.attributes.Attributes; import common.collect.Lists; -import common.entity.attributes.Attributes; import common.init.Items; import common.init.SpeciesRegistry; import common.item.ItemStack; diff --git a/common/src/common/entity/npc/EntityFlyingNPC.java b/common/src/common/entity/npc/EntityFlyingNPC.java index 9827f40..c83c3ab 100755 --- a/common/src/common/entity/npc/EntityFlyingNPC.java +++ b/common/src/common/entity/npc/EntityFlyingNPC.java @@ -2,8 +2,8 @@ package common.entity.npc; import common.ai.EntityAIBase; import common.ai.EntityMoveHelper; +import common.attributes.Attributes; import common.block.Block; -import common.entity.attributes.Attributes; import common.entity.types.EntityLiving; import common.potion.Potion; import common.rng.Random; diff --git a/common/src/common/entity/npc/EntityGargoyle.java b/common/src/common/entity/npc/EntityGargoyle.java index 0f6b358..6b5e72a 100755 --- a/common/src/common/entity/npc/EntityGargoyle.java +++ b/common/src/common/entity/npc/EntityGargoyle.java @@ -1,8 +1,8 @@ package common.entity.npc; import common.ai.AIFlyingBoxAttack; +import common.attributes.Attributes; import common.entity.DamageSource; -import common.entity.attributes.Attributes; import common.init.Config; import common.item.ItemStack; import common.model.ParticleType; diff --git a/common/src/common/entity/npc/EntityGoblin.java b/common/src/common/entity/npc/EntityGoblin.java index 3b0db10..b80ef9a 100755 --- a/common/src/common/entity/npc/EntityGoblin.java +++ b/common/src/common/entity/npc/EntityGoblin.java @@ -1,6 +1,6 @@ package common.entity.npc; -import common.entity.attributes.Attributes; +import common.attributes.Attributes; import common.entity.types.EntityLiving; import common.rng.Random; import common.world.World; diff --git a/common/src/common/entity/npc/EntityHaunter.java b/common/src/common/entity/npc/EntityHaunter.java index 4f1e389..e076393 100755 --- a/common/src/common/entity/npc/EntityHaunter.java +++ b/common/src/common/entity/npc/EntityHaunter.java @@ -1,8 +1,8 @@ package common.entity.npc; import common.ai.EntityAIExplode; +import common.attributes.Attributes; import common.entity.Entity; -import common.entity.attributes.Attributes; import common.entity.effect.EntityLightning; import common.entity.types.EntityLiving; import common.init.Config; diff --git a/common/src/common/entity/npc/EntityHoveringNPC.java b/common/src/common/entity/npc/EntityHoveringNPC.java index d35b423..0d8390f 100755 --- a/common/src/common/entity/npc/EntityHoveringNPC.java +++ b/common/src/common/entity/npc/EntityHoveringNPC.java @@ -1,6 +1,6 @@ package common.entity.npc; -import common.entity.attributes.Attributes; +import common.attributes.Attributes; import common.entity.types.EntityLiving; import common.packet.CPacketAction; import common.world.World; diff --git a/common/src/common/entity/npc/EntityMage.java b/common/src/common/entity/npc/EntityMage.java index 09c4134..4abe982 100755 --- a/common/src/common/entity/npc/EntityMage.java +++ b/common/src/common/entity/npc/EntityMage.java @@ -2,8 +2,8 @@ package common.entity.npc; import java.util.List; -import common.entity.attributes.AttributeInstance; -import common.entity.attributes.Attributes; +import common.attributes.AttributeInstance; +import common.attributes.Attributes; import common.entity.effect.EntityLightning; import common.entity.types.EntityLiving; import common.init.Items; diff --git a/common/src/common/entity/npc/EntityMobNPC.java b/common/src/common/entity/npc/EntityMobNPC.java index e36c35f..4504a52 100755 --- a/common/src/common/entity/npc/EntityMobNPC.java +++ b/common/src/common/entity/npc/EntityMobNPC.java @@ -1,10 +1,10 @@ package common.entity.npc; import common.ai.EntityAIHurtByTarget; +import common.attributes.AttributeInstance; +import common.attributes.Attributes; import common.entity.DamageSource; import common.entity.Entity; -import common.entity.attributes.AttributeInstance; -import common.entity.attributes.Attributes; import common.entity.types.EntityLiving; import common.nbt.NBTTagCompound; import common.world.World; diff --git a/common/src/common/entity/npc/EntityNPC.java b/common/src/common/entity/npc/EntityNPC.java index f261a8b..cf4e573 100755 --- a/common/src/common/entity/npc/EntityNPC.java +++ b/common/src/common/entity/npc/EntityNPC.java @@ -20,6 +20,8 @@ import common.ai.EntityAISwimming; import common.ai.EntityAIWander; import common.ai.EntityAIWatchClosest; import common.ai.EntityAIWatchClosest2; +import common.attributes.AttributeInstance; +import common.attributes.Attributes; import common.block.Block; import common.block.BlockBed; import common.dimension.Space; @@ -31,8 +33,6 @@ import common.entity.EntityType; import common.entity.animal.EntityDragonPart; import common.entity.animal.EntityHorse; import common.entity.animal.EntityPig; -import common.entity.attributes.AttributeInstance; -import common.entity.attributes.Attributes; import common.entity.item.EntityBoat; import common.entity.item.EntityCart; import common.entity.item.EntityItem; diff --git a/common/src/common/entity/npc/EntityOrc.java b/common/src/common/entity/npc/EntityOrc.java index e6cc4c0..96cdb66 100755 --- a/common/src/common/entity/npc/EntityOrc.java +++ b/common/src/common/entity/npc/EntityOrc.java @@ -1,6 +1,6 @@ package common.entity.npc; -import common.entity.attributes.Attributes; +import common.attributes.Attributes; import common.rng.Random; import common.world.World; diff --git a/common/src/common/entity/npc/EntityPrimarch.java b/common/src/common/entity/npc/EntityPrimarch.java index b20a047..e4c29f8 100755 --- a/common/src/common/entity/npc/EntityPrimarch.java +++ b/common/src/common/entity/npc/EntityPrimarch.java @@ -2,8 +2,8 @@ package common.entity.npc; import java.util.List; +import common.attributes.Attributes; import common.collect.Lists; -import common.entity.attributes.Attributes; import common.rng.Random; import common.util.Identifyable; import common.world.World; diff --git a/common/src/common/entity/npc/EntitySlime.java b/common/src/common/entity/npc/EntitySlime.java index da31cab..ee08d9c 100755 --- a/common/src/common/entity/npc/EntitySlime.java +++ b/common/src/common/entity/npc/EntitySlime.java @@ -2,10 +2,10 @@ package common.entity.npc; import common.ai.EntityAIBase; import common.ai.EntityMoveHelper; +import common.attributes.Attributes; import common.biome.Biome; import common.entity.DamageSource; import common.entity.Entity; -import common.entity.attributes.Attributes; import common.entity.types.EntityLiving; import common.init.Config; import common.init.SoundEvent; diff --git a/common/src/common/entity/npc/EntitySpaceMarine.java b/common/src/common/entity/npc/EntitySpaceMarine.java index 9bc645f..566360c 100755 --- a/common/src/common/entity/npc/EntitySpaceMarine.java +++ b/common/src/common/entity/npc/EntitySpaceMarine.java @@ -2,8 +2,8 @@ package common.entity.npc; import java.util.List; +import common.attributes.Attributes; import common.collect.Lists; -import common.entity.attributes.Attributes; import common.init.Items; import common.init.SpeciesRegistry; import common.item.ItemStack; diff --git a/common/src/common/entity/npc/EntityTiefling.java b/common/src/common/entity/npc/EntityTiefling.java index 7a075df..f3134f1 100755 --- a/common/src/common/entity/npc/EntityTiefling.java +++ b/common/src/common/entity/npc/EntityTiefling.java @@ -1,6 +1,6 @@ package common.entity.npc; -import common.entity.attributes.Attributes; +import common.attributes.Attributes; import common.rng.Random; import common.world.World; diff --git a/common/src/common/entity/npc/EntityUndead.java b/common/src/common/entity/npc/EntityUndead.java index d35adeb..c87135b 100755 --- a/common/src/common/entity/npc/EntityUndead.java +++ b/common/src/common/entity/npc/EntityUndead.java @@ -1,8 +1,8 @@ package common.entity.npc; import common.ai.EntityAIAvoidEntity; +import common.attributes.Attributes; import common.entity.animal.EntityWolf; -import common.entity.attributes.Attributes; import common.entity.types.EntityLiving; import common.init.Items; import common.item.ItemStack; diff --git a/common/src/common/entity/npc/EntityVampire.java b/common/src/common/entity/npc/EntityVampire.java index 374a691..0733ab9 100755 --- a/common/src/common/entity/npc/EntityVampire.java +++ b/common/src/common/entity/npc/EntityVampire.java @@ -1,6 +1,6 @@ package common.entity.npc; -import common.entity.attributes.Attributes; +import common.attributes.Attributes; import common.entity.effect.EntityLightning; import common.rng.Random; import common.world.World; diff --git a/common/src/common/entity/npc/EntityZombie.java b/common/src/common/entity/npc/EntityZombie.java index bdd5734..5d8b152 100755 --- a/common/src/common/entity/npc/EntityZombie.java +++ b/common/src/common/entity/npc/EntityZombie.java @@ -4,10 +4,10 @@ import java.util.List; import java.util.function.Predicate; import common.ai.EntityAIMoveThroughVillage; +import common.attributes.AttributeModifier; +import common.attributes.Attributes; import common.entity.DamageSource; import common.entity.animal.EntityChicken; -import common.entity.attributes.AttributeModifier; -import common.entity.attributes.Attributes; import common.entity.types.EntityLiving; import common.init.Config; import common.rng.Random; diff --git a/common/src/common/entity/types/EntityLiving.java b/common/src/common/entity/types/EntityLiving.java index c99cbb5..58347ac 100755 --- a/common/src/common/entity/types/EntityLiving.java +++ b/common/src/common/entity/types/EntityLiving.java @@ -13,6 +13,11 @@ import common.ai.EntityJumpHelper; import common.ai.EntityLookHelper; import common.ai.EntityMoveHelper; import common.ai.EntitySenses; +import common.attributes.Attribute; +import common.attributes.AttributeInstance; +import common.attributes.AttributeMap; +import common.attributes.AttributeModifier; +import common.attributes.Attributes; import common.block.Block; import common.block.SoundType; import common.collect.Lists; @@ -23,11 +28,6 @@ import common.entity.DamageSource; import common.entity.Entity; import common.entity.EntityDamageSource; import common.entity.animal.EntityWolf; -import common.entity.attributes.Attribute; -import common.entity.attributes.AttributeInstance; -import common.entity.attributes.AttributeMap; -import common.entity.attributes.AttributeModifier; -import common.entity.attributes.Attributes; import common.entity.item.EntityItem; import common.entity.item.EntityLeashKnot; import common.entity.item.EntityXp; diff --git a/common/src/common/inventory/ContainerPlayer.java b/common/src/common/inventory/ContainerPlayer.java index 2a1253d..1512068 100755 --- a/common/src/common/inventory/ContainerPlayer.java +++ b/common/src/common/inventory/ContainerPlayer.java @@ -2,8 +2,8 @@ package common.inventory; import java.util.List; +import common.attributes.AttributeMap; import common.collect.Lists; -import common.entity.attributes.AttributeMap; import common.entity.npc.EntityNPC; import common.init.CraftingRegistry; import common.item.ItemArmor; diff --git a/common/src/common/item/Item.java b/common/src/common/item/Item.java index 9212ab5..f968ee9 100755 --- a/common/src/common/item/Item.java +++ b/common/src/common/item/Item.java @@ -4,12 +4,12 @@ import java.util.List; import java.util.Map; import java.util.Set; +import common.attributes.Attribute; +import common.attributes.AttributeModifier; import common.block.Block; import common.collect.Maps; import common.collect.Sets; import common.color.TextColor; -import common.entity.attributes.Attribute; -import common.entity.attributes.AttributeModifier; import common.entity.npc.EntityNPC; import common.entity.types.EntityLiving; import common.model.ItemMeshDefinition; diff --git a/common/src/common/item/ItemArmor.java b/common/src/common/item/ItemArmor.java index 0529e9a..4fc425c 100755 --- a/common/src/common/item/ItemArmor.java +++ b/common/src/common/item/ItemArmor.java @@ -5,14 +5,14 @@ import java.util.Map; import java.util.Set; import java.util.function.Predicate; +import common.attributes.Attribute; +import common.attributes.AttributeModifier; +import common.attributes.Attributes; import common.block.BlockDispenser; import common.collect.Sets; import common.dispenser.BehaviorDefaultDispenseItem; import common.dispenser.IBehaviorDispenseItem; import common.dispenser.IBlockSource; -import common.entity.attributes.Attribute; -import common.entity.attributes.AttributeModifier; -import common.entity.attributes.Attributes; import common.entity.npc.EntityNPC; import common.entity.types.EntityLiving; import common.init.DispenserRegistry; diff --git a/common/src/common/item/ItemBucketMilk.java b/common/src/common/item/ItemBucketMilk.java index ada9fb5..7eaecfa 100755 --- a/common/src/common/item/ItemBucketMilk.java +++ b/common/src/common/item/ItemBucketMilk.java @@ -3,10 +3,10 @@ package common.item; import java.util.Map; import java.util.Set; +import common.attributes.Attribute; +import common.attributes.AttributeModifier; +import common.attributes.Attributes; import common.collect.Sets; -import common.entity.attributes.Attribute; -import common.entity.attributes.AttributeModifier; -import common.entity.attributes.Attributes; import common.entity.npc.EntityNPC; import common.init.Items; import common.world.World; diff --git a/common/src/common/item/ItemMetal.java b/common/src/common/item/ItemMetal.java index 9d798b3..9962259 100755 --- a/common/src/common/item/ItemMetal.java +++ b/common/src/common/item/ItemMetal.java @@ -4,11 +4,11 @@ import java.util.List; import java.util.Map; import java.util.Set; +import common.attributes.Attribute; +import common.attributes.AttributeModifier; +import common.attributes.Attributes; import common.collect.Sets; import common.color.TextColor; -import common.entity.attributes.Attribute; -import common.entity.attributes.AttributeModifier; -import common.entity.attributes.Attributes; import common.entity.npc.EntityNPC; import common.init.MetalType; diff --git a/common/src/common/item/ItemMetalBlock.java b/common/src/common/item/ItemMetalBlock.java index 4a6a37e..c43e4f2 100755 --- a/common/src/common/item/ItemMetalBlock.java +++ b/common/src/common/item/ItemMetalBlock.java @@ -4,12 +4,12 @@ import java.util.List; import java.util.Map; import java.util.Set; +import common.attributes.Attribute; +import common.attributes.AttributeModifier; +import common.attributes.Attributes; import common.block.Block; import common.collect.Sets; import common.color.TextColor; -import common.entity.attributes.Attribute; -import common.entity.attributes.AttributeModifier; -import common.entity.attributes.Attributes; import common.entity.npc.EntityNPC; import common.init.MetalType; diff --git a/common/src/common/item/ItemPotion.java b/common/src/common/item/ItemPotion.java index 40aa95f..a254127 100755 --- a/common/src/common/item/ItemPotion.java +++ b/common/src/common/item/ItemPotion.java @@ -5,11 +5,11 @@ import java.util.List; import java.util.Map; import java.util.Map.Entry; +import common.attributes.Attribute; +import common.attributes.AttributeModifier; import common.collect.Maps; import common.collect.Sets; import common.color.TextColor; -import common.entity.attributes.Attribute; -import common.entity.attributes.AttributeModifier; import common.entity.npc.EntityNPC; import common.entity.projectile.EntityPotion; import common.init.Items; diff --git a/common/src/common/item/ItemStack.java b/common/src/common/item/ItemStack.java index a25e49c..0088c3c 100755 --- a/common/src/common/item/ItemStack.java +++ b/common/src/common/item/ItemStack.java @@ -5,6 +5,9 @@ import java.util.List; import java.util.Map; import java.util.Map.Entry; +import common.attributes.Attribute; +import common.attributes.AttributeModifier; +import common.attributes.Attributes; import common.block.Block; import common.collect.Lists; import common.collect.Maps; @@ -12,9 +15,6 @@ import common.color.TextColor; import common.enchantment.Enchantment; import common.enchantment.EnchantmentDurability; import common.enchantment.EnchantmentHelper; -import common.entity.attributes.Attribute; -import common.entity.attributes.AttributeModifier; -import common.entity.attributes.Attributes; import common.entity.npc.EntityNPC; import common.entity.types.EntityLiving; import common.init.BlockRegistry; diff --git a/common/src/common/item/ItemSword.java b/common/src/common/item/ItemSword.java index 9ae7bc8..0c616a2 100755 --- a/common/src/common/item/ItemSword.java +++ b/common/src/common/item/ItemSword.java @@ -3,11 +3,11 @@ package common.item; import java.util.Map; import java.util.Set; +import common.attributes.Attribute; +import common.attributes.AttributeModifier; +import common.attributes.Attributes; import common.block.Block; import common.collect.Sets; -import common.entity.attributes.Attribute; -import common.entity.attributes.AttributeModifier; -import common.entity.attributes.Attributes; import common.entity.npc.EntityNPC; import common.entity.types.EntityLiving; import common.init.Blocks; diff --git a/common/src/common/item/ItemTool.java b/common/src/common/item/ItemTool.java index 4c58202..2970a58 100755 --- a/common/src/common/item/ItemTool.java +++ b/common/src/common/item/ItemTool.java @@ -3,11 +3,11 @@ package common.item; import java.util.Map; import java.util.Set; +import common.attributes.Attribute; +import common.attributes.AttributeModifier; +import common.attributes.Attributes; import common.block.Block; import common.collect.Sets; -import common.entity.attributes.Attribute; -import common.entity.attributes.AttributeModifier; -import common.entity.attributes.Attributes; import common.entity.types.EntityLiving; import common.init.ToolMaterial; import common.model.Transforms; diff --git a/common/src/common/packet/S20PacketEntityProperties.java b/common/src/common/packet/S20PacketEntityProperties.java index 0d0a1f0..f3ca49a 100755 --- a/common/src/common/packet/S20PacketEntityProperties.java +++ b/common/src/common/packet/S20PacketEntityProperties.java @@ -4,9 +4,9 @@ import java.io.IOException; import java.util.Collection; import java.util.List; +import common.attributes.AttributeInstance; +import common.attributes.AttributeModifier; import common.collect.Lists; -import common.entity.attributes.AttributeInstance; -import common.entity.attributes.AttributeModifier; import common.network.IClientPlayer; import common.network.Packet; import common.network.PacketBuffer; diff --git a/common/src/common/pathfinding/PathNavigate.java b/common/src/common/pathfinding/PathNavigate.java index ee406dd..0d8fb09 100755 --- a/common/src/common/pathfinding/PathNavigate.java +++ b/common/src/common/pathfinding/PathNavigate.java @@ -2,9 +2,9 @@ package common.pathfinding; import java.util.List; +import common.attributes.AttributeInstance; +import common.attributes.Attributes; import common.entity.Entity; -import common.entity.attributes.AttributeInstance; -import common.entity.attributes.Attributes; import common.entity.types.EntityLiving; import common.util.BlockPos; import common.util.BoundingBox; diff --git a/common/src/common/potion/Potion.java b/common/src/common/potion/Potion.java index cf03a29..c2eab2f 100755 --- a/common/src/common/potion/Potion.java +++ b/common/src/common/potion/Potion.java @@ -3,13 +3,13 @@ package common.potion; import java.util.Map; import java.util.Map.Entry; +import common.attributes.Attribute; +import common.attributes.AttributeInstance; +import common.attributes.AttributeMap; +import common.attributes.AttributeModifier; +import common.attributes.Attributes; import common.collect.Maps; import common.entity.DamageSource; -import common.entity.attributes.Attribute; -import common.entity.attributes.AttributeInstance; -import common.entity.attributes.AttributeMap; -import common.entity.attributes.AttributeModifier; -import common.entity.attributes.Attributes; import common.entity.projectile.EntityPotion; import common.entity.types.EntityLiving; import common.init.Config; diff --git a/common/src/common/entity/attributes/LowerStringMap.java b/common/src/common/util/LowerStringMap.java similarity index 98% rename from common/src/common/entity/attributes/LowerStringMap.java rename to common/src/common/util/LowerStringMap.java index 091cc27..b445a3d 100755 --- a/common/src/common/entity/attributes/LowerStringMap.java +++ b/common/src/common/util/LowerStringMap.java @@ -1,4 +1,4 @@ -package common.entity.attributes; +package common.util; import java.util.Collection; import java.util.Map; From 6e77090c5b56bf3c3b4aa1fcc1c053e1a086399b Mon Sep 17 00:00:00 2001 From: Sen Date: Tue, 13 May 2025 17:02:57 +0200 Subject: [PATCH 024/200] server client split world classes --- client/src/client/Client.java | 104 +------ client/src/client/PlayerController.java | 4 +- client/src/client/gui/GuiConsole.java | 4 +- client/src/client/gui/character/GuiChar.java | 10 +- client/src/client/gui/character/GuiClass.java | 2 +- .../src/client/gui/character/GuiSpecies.java | 2 +- .../client/gui/container/GuiContainer.java | 4 +- .../client/network/ClientLoginHandler.java | 1 + client/src/client/network/ClientPlayer.java | 51 +++- .../src/client/renderer/EntityRenderer.java | 2 +- client/src/client/renderer/RenderGlobal.java | 2 +- .../client/renderer/particle/EntityFX.java | 3 +- .../renderer/particle/EntityFirework.java | 2 +- .../particle/EntityParticleEmitter.java | 2 +- .../src/client}/world/EmptyChunk.java | 4 +- .../src/client}/world/WorldClient.java | 54 ++-- common/src/common/IClient.java | 34 --- common/src/common/IServer.java | 25 -- common/src/common/ai/EntityAIFleeSun.java | 4 +- common/src/common/ai/EntityAIMoveIndoors.java | 6 +- .../common/ai/EntityAIMoveThroughVillage.java | 6 +- common/src/common/ai/EntityAINpcMate.java | 4 +- .../common/ai/EntityAIRestrictOpenDoor.java | 8 +- common/src/common/ai/EntityAIRestrictSun.java | 4 +- .../src/common/ai/EntityAIWatchClosest.java | 4 +- common/src/common/biome/Biome.java | 8 +- common/src/common/biome/BiomeChaos.java | 4 +- common/src/common/biome/BiomeDesert.java | 4 +- .../src/common/biome/BiomeExterminated.java | 4 +- common/src/common/biome/BiomeForest.java | 6 +- common/src/common/biome/BiomeHell.java | 4 +- common/src/common/biome/BiomeHills.java | 6 +- common/src/common/biome/BiomeJungle.java | 4 +- common/src/common/biome/BiomeMesa.java | 6 +- common/src/common/biome/BiomeMoon.java | 4 +- common/src/common/biome/BiomeMutated.java | 8 +- common/src/common/biome/BiomeNone.java | 6 +- common/src/common/biome/BiomePlains.java | 4 +- common/src/common/biome/BiomeSavanna.java | 8 +- common/src/common/biome/BiomeSnow.java | 4 +- common/src/common/biome/BiomeSpace.java | 4 +- common/src/common/biome/BiomeSwamp.java | 4 +- common/src/common/biome/BiomeTaiga.java | 6 +- common/src/common/biome/BiomeTian.java | 4 +- common/src/common/block/Block.java | 16 +- .../common/block/BlockBasePressurePlate.java | 8 +- common/src/common/block/BlockBedrock.java | 4 +- .../src/common/block/BlockBlackenedDirt.java | 4 +- .../src/common/block/BlockBlackenedSoil.java | 4 +- common/src/common/block/BlockBlueShroom.java | 4 +- .../src/common/block/BlockBrewingStand.java | 8 +- common/src/common/block/BlockBush.java | 4 +- common/src/common/block/BlockButton.java | 8 +- common/src/common/block/BlockCactus.java | 4 +- common/src/common/block/BlockChest.java | 6 +- common/src/common/block/BlockCocoa.java | 6 +- common/src/common/block/BlockContainer.java | 4 +- common/src/common/block/BlockCore.java | 6 +- common/src/common/block/BlockCrops.java | 6 +- .../common/block/BlockDaylightDetector.java | 8 +- common/src/common/block/BlockDispenser.java | 8 +- common/src/common/block/BlockDoublePlant.java | 6 +- common/src/common/block/BlockDragonEgg.java | 6 +- .../src/common/block/BlockDynamicLiquid.java | 6 +- .../common/block/BlockEnchantmentTable.java | 4 +- common/src/common/block/BlockFalling.java | 6 +- common/src/common/block/BlockFarmland.java | 4 +- common/src/common/block/BlockFire.java | 10 +- common/src/common/block/BlockFloorPortal.java | 4 +- common/src/common/block/BlockFlower.java | 4 +- common/src/common/block/BlockFlowerPot.java | 4 +- common/src/common/block/BlockFurnace.java | 10 +- common/src/common/block/BlockGrass.java | 6 +- common/src/common/block/BlockHopper.java | 6 +- common/src/common/block/BlockIce.java | 4 +- common/src/common/block/BlockLeaves.java | 10 +- common/src/common/block/BlockLever.java | 4 +- common/src/common/block/BlockLiquid.java | 8 +- common/src/common/block/BlockLog.java | 4 +- common/src/common/block/BlockMachine.java | 6 +- common/src/common/block/BlockMushroom.java | 8 +- common/src/common/block/BlockMycelium.java | 8 +- common/src/common/block/BlockNuke.java | 4 +- common/src/common/block/BlockPistonBase.java | 4 +- common/src/common/block/BlockPistonHead.java | 4 +- .../src/common/block/BlockPistonMoving.java | 4 +- common/src/common/block/BlockPortal.java | 6 +- common/src/common/block/BlockPumpkin.java | 2 +- common/src/common/block/BlockRailBase.java | 6 +- .../src/common/block/BlockRailDetector.java | 8 +- .../common/block/BlockRedstoneComparator.java | 14 +- .../src/common/block/BlockRedstoneDiode.java | 12 +- .../src/common/block/BlockRedstoneLight.java | 6 +- common/src/common/block/BlockRedstoneOre.java | 8 +- .../common/block/BlockRedstoneRepeater.java | 8 +- .../src/common/block/BlockRedstoneTorch.java | 16 +- .../src/common/block/BlockRedstoneWire.java | 10 +- common/src/common/block/BlockReed.java | 4 +- common/src/common/block/BlockSapling.java | 10 +- common/src/common/block/BlockSign.java | 2 +- common/src/common/block/BlockSkull.java | 4 +- common/src/common/block/BlockSnow.java | 4 +- common/src/common/block/BlockSnowBlock.java | 4 +- .../src/common/block/BlockStainedGlass.java | 4 +- .../common/block/BlockStainedGlassPane.java | 4 +- common/src/common/block/BlockStairs.java | 12 +- .../src/common/block/BlockStaticLiquid.java | 4 +- common/src/common/block/BlockStem.java | 6 +- common/src/common/block/BlockTNT.java | 4 +- common/src/common/block/BlockTallGrass.java | 6 +- common/src/common/block/BlockTorch.java | 8 +- common/src/common/block/BlockTripWire.java | 10 +- .../src/common/block/BlockTripWireHook.java | 8 +- common/src/common/block/BlockVine.java | 4 +- common/src/common/block/BlockWarpChest.java | 4 +- common/src/common/block/BlockWart.java | 4 +- common/src/common/block/IGrowable.java | 4 +- common/src/common/entity/Entity.java | 8 +- .../common/entity/animal/EntityDragon.java | 4 +- .../common/entity/effect/EntityLightning.java | 4 +- .../common/entity/item/EntityFireworks.java | 4 +- common/src/common/entity/item/EntityItem.java | 4 +- .../common/entity/npc/EntityArachnoid.java | 2 +- .../src/common/entity/npc/EntityDarkMage.java | 4 +- .../src/common/entity/npc/EntityHaunter.java | 4 +- .../common/entity/npc/EntityHoveringNPC.java | 10 +- common/src/common/entity/npc/EntityHuman.java | 8 +- common/src/common/entity/npc/EntityNPC.java | 200 ++++++------- common/src/common/entity/npc/EntitySlime.java | 6 +- .../src/common/entity/npc/EntityUndead.java | 4 +- .../src/common/entity/npc/EntityZombie.java | 4 +- .../common/entity/projectile/EntityHook.java | 4 +- .../src/common/entity/types/EntityLiving.java | 22 +- .../common/entity/types/EntityThrowable.java | 4 +- common/src/common/entity/types/IEntityFX.java | 9 - common/src/common/init/Config.java | 72 ++--- common/src/common/item/ItemBanHammer.java | 4 +- common/src/common/item/ItemBucket.java | 10 +- common/src/common/item/ItemDye.java | 4 +- common/src/common/item/ItemExterminator.java | 4 +- common/src/common/item/ItemInfoWand.java | 4 +- common/src/common/item/ItemLightning.java | 4 +- common/src/common/item/ItemWand.java | 12 +- common/src/common/item/ItemWeatherToken.java | 4 +- common/src/common/network/IClientPlayer.java | 199 +------------ common/src/common/packet/APacketEmpty.java | 14 - .../common/packet/RPacketLoginSuccess.java | 37 ++- .../common/tileentity/TileEntityBeacon.java | 4 +- .../TileEntityDaylightDetector.java | 6 +- common/src/common/village/Village.java | 10 +- common/src/common/world/AWorldClient.java | 15 + common/src/common/world/AWorldServer.java | 62 ++++ common/src/common/world/Chunk.java | 4 +- common/src/common/world/Explosion.java | 2 +- common/src/common/world/IWorld.java | 279 ++++++++++++++++++ common/src/common/world/World.java | 2 +- common/src/common/worldgen/BlockReplacer.java | 4 +- .../src/common/worldgen/ChunkGenerator.java | 4 +- .../src/common/worldgen/FeatureDungeons.java | 6 +- .../src/common/worldgen/FeatureGenerator.java | 6 +- common/src/common/worldgen/FeatureLakes.java | 6 +- .../src/common/worldgen/FeatureLiquids.java | 6 +- common/src/common/worldgen/FeatureOres.java | 6 +- .../src/common/worldgen/GeneratorCavern.java | 4 +- .../src/common/worldgen/GeneratorDebug.java | 4 +- .../common/worldgen/GeneratorDestroyed.java | 4 +- common/src/common/worldgen/GeneratorFlat.java | 4 +- .../src/common/worldgen/GeneratorIsland.java | 4 +- .../src/common/worldgen/GeneratorPerlin.java | 4 +- .../src/common/worldgen/GeneratorSimple.java | 4 +- .../src/common/worldgen/ReplacerAltBiome.java | 4 +- .../common/worldgen/ReplacerAltSurface.java | 4 +- common/src/common/worldgen/ReplacerBiome.java | 4 +- .../src/common/worldgen/ReplacerTopLayer.java | 4 +- .../src/common/worldgen/caves/MapGenBase.java | 8 +- .../common/worldgen/caves/MapGenBigCaves.java | 4 +- .../common/worldgen/caves/MapGenCaves.java | 4 +- .../common/worldgen/caves/MapGenRavine.java | 4 +- .../feature/WorldGenAbandonedChest.java | 4 +- .../worldgen/feature/WorldGenAsteroid.java | 4 +- .../worldgen/feature/WorldGenBlockBlob.java | 4 +- .../common/worldgen/feature/WorldGenClay.java | 4 +- .../worldgen/feature/WorldGenClayExt.java | 4 +- .../worldgen/feature/WorldGenDesertWells.java | 4 +- .../common/worldgen/feature/WorldGenFire.java | 4 +- .../worldgen/feature/WorldGenGlowStone.java | 4 +- .../worldgen/feature/WorldGenHellLava.java | 4 +- .../worldgen/feature/WorldGenIcePath.java | 4 +- .../worldgen/feature/WorldGenIceSpike.java | 4 +- .../common/worldgen/feature/WorldGenSand.java | 4 +- .../worldgen/feature/WorldGenSpikes.java | 4 +- .../worldgen/foliage/FeatureDoublePlant.java | 4 +- .../worldgen/foliage/WorldGenBigMushroom.java | 4 +- .../worldgen/foliage/WorldGenCactus.java | 4 +- .../worldgen/foliage/WorldGenDeadBush.java | 4 +- .../worldgen/foliage/WorldGenFlowers.java | 4 +- .../worldgen/foliage/WorldGenMelon.java | 4 +- .../worldgen/foliage/WorldGenMushroom.java | 4 +- .../worldgen/foliage/WorldGenPumpkin.java | 4 +- .../common/worldgen/foliage/WorldGenReed.java | 4 +- .../worldgen/foliage/WorldGenShrub.java | 4 +- .../worldgen/foliage/WorldGenTallGrass.java | 4 +- .../worldgen/foliage/WorldGenVines.java | 4 +- .../worldgen/foliage/WorldGenWaterlily.java | 4 +- .../worldgen/tree/WorldGenBaseTree.java | 10 +- .../common/worldgen/tree/WorldGenBigTree.java | 6 +- .../common/worldgen/tree/WorldGenBirch.java | 4 +- .../common/worldgen/tree/WorldGenDarkOak.java | 10 +- .../worldgen/tree/WorldGenHugeTree.java | 12 +- .../common/worldgen/tree/WorldGenJungle.java | 8 +- .../common/worldgen/tree/WorldGenPine.java | 12 +- .../common/worldgen/tree/WorldGenSavanna.java | 8 +- .../common/worldgen/tree/WorldGenSwamp.java | 6 +- .../common/worldgen/tree/WorldGenTaiga1.java | 4 +- .../common/worldgen/tree/WorldGenTaiga2.java | 4 +- .../common/worldgen/tree/WorldGenTree.java | 6 +- server/src/server/Server.java | 50 ++-- .../server}/clipboard/ClipboardPlacer.java | 5 +- .../src/server/command/EntityListParser.java | 2 +- server/src/server/command/EntityParser.java | 2 +- server/src/server/command/WorldParser.java | 2 +- .../server/command/commands/CommandSpawn.java | 2 +- .../server/command/commands/CommandTime.java | 2 +- .../command/commands/CommandWeather.java | 2 +- .../server/command/commands/CommandWorld.java | 2 +- server/src/server/network/Player.java | 26 +- .../server}/village/VillageCollection.java | 6 +- server/src/server/world/Converter.java | 3 +- .../src/server}/world/Region.java | 4 +- .../src/server}/world/Spawner.java | 4 +- .../src/server}/world/WorldServer.java | 59 ++-- .../worldgen/structure/MapGenBridge.java | 4 +- .../worldgen/structure/MapGenMineshaft.java | 2 +- .../structure/MapGenScatteredFeature.java | 4 +- .../worldgen/structure/MapGenStronghold.java | 4 +- .../worldgen/structure/MapGenStructure.java | 14 +- .../worldgen/structure/MapGenStructureIO.java | 4 +- .../worldgen/structure/MapGenVillage.java | 4 +- .../structure/StructureBoundingBox.java | 2 +- .../worldgen/structure/StructureBridge.java | 4 +- .../structure/StructureComponent.java | 4 +- .../structure/StructureMineshaft.java | 4 +- .../structure/StructureMineshaftStart.java | 4 +- .../structure/StructureScattered.java | 4 +- .../worldgen/structure/StructureStart.java | 4 +- .../structure/StructureStronghold.java | 4 +- .../worldgen/structure/StructureVillage.java | 4 +- 247 files changed, 1309 insertions(+), 1187 deletions(-) rename {common/src/common => client/src/client}/world/EmptyChunk.java (95%) rename {common/src/common => client/src/client}/world/WorldClient.java (92%) delete mode 100644 common/src/common/IClient.java delete mode 100644 common/src/common/IServer.java delete mode 100644 common/src/common/entity/types/IEntityFX.java delete mode 100755 common/src/common/packet/APacketEmpty.java create mode 100644 common/src/common/world/AWorldClient.java create mode 100644 common/src/common/world/AWorldServer.java create mode 100644 common/src/common/world/IWorld.java rename {common/src/common => server/src/server}/clipboard/ClipboardPlacer.java (98%) rename {common/src/common => server/src/server}/village/VillageCollection.java (98%) rename {common/src/common => server/src/server}/world/Region.java (99%) rename {common/src/common => server/src/server}/world/Spawner.java (98%) rename {common/src/common => server/src/server}/world/WorldServer.java (98%) rename {common/src/common => server/src/server}/worldgen/structure/MapGenBridge.java (96%) rename {common/src/common => server/src/server}/worldgen/structure/MapGenMineshaft.java (96%) rename {common/src/common => server/src/server}/worldgen/structure/MapGenScatteredFeature.java (98%) rename {common/src/common => server/src/server}/worldgen/structure/MapGenStronghold.java (98%) rename {common/src/common => server/src/server}/worldgen/structure/MapGenStructure.java (95%) rename {common/src/common => server/src/server}/worldgen/structure/MapGenStructureIO.java (98%) rename {common/src/common => server/src/server}/worldgen/structure/MapGenVillage.java (98%) rename {common/src/common => server/src/server}/worldgen/structure/StructureBoundingBox.java (99%) rename {common/src/common => server/src/server}/worldgen/structure/StructureBridge.java (99%) rename {common/src/common => server/src/server}/worldgen/structure/StructureComponent.java (99%) rename {common/src/common => server/src/server}/worldgen/structure/StructureMineshaft.java (99%) rename {common/src/common => server/src/server}/worldgen/structure/StructureMineshaftStart.java (90%) rename {common/src/common => server/src/server}/worldgen/structure/StructureScattered.java (99%) rename {common/src/common => server/src/server}/worldgen/structure/StructureStart.java (98%) rename {common/src/common => server/src/server}/worldgen/structure/StructureStronghold.java (99%) rename {common/src/common => server/src/server}/worldgen/structure/StructureVillage.java (99%) diff --git a/client/src/client/Client.java b/client/src/client/Client.java index 33f7fc3..e1b1490 100755 --- a/client/src/client/Client.java +++ b/client/src/client/Client.java @@ -66,7 +66,6 @@ import client.renderer.chunk.RenderChunk; import client.renderer.entity.RenderItem; import client.renderer.entity.RenderManager; import client.renderer.particle.EffectRenderer; -import client.renderer.particle.EntityFirework; import client.renderer.texture.ColormapLoader; import client.renderer.texture.EntityTexManager; import client.renderer.texture.TextureManager; @@ -95,7 +94,7 @@ import client.window.Keysym; import client.window.Wheel; import client.window.Window; import client.window.WindowEvent; -import common.IClient; +import client.world.WorldClient; import common.biome.Biome; import common.block.Block; import common.collect.Lists; @@ -106,7 +105,6 @@ import common.entity.animal.EntityHorse; import common.entity.npc.Energy; import common.entity.npc.EntityNPC; import common.entity.types.EntityLiving; -import common.entity.types.IEntityFX; import common.future.Futures; import common.future.ListenableFuture; import common.future.ListenableFutureTask; @@ -127,8 +125,6 @@ import common.log.Log; import common.log.LogLevel; import common.log.Message; import common.material.Material; -import common.model.ParticleType; -import common.nbt.NBTTagCompound; import common.network.IThreadListener; import common.network.NetConnection; import common.network.PacketDecoder; @@ -149,7 +145,6 @@ import common.properties.IProperty; import common.rng.Random; import common.sound.EventType; import common.sound.PositionedSound; -import common.sound.Sound; import common.util.BlockPos; import common.util.BoundingBox; import common.util.CharValidator; @@ -164,7 +159,6 @@ import common.world.Chunk; import common.world.LightType; import common.world.State; import common.world.World; -import common.world.WorldClient; import io.netty.bootstrap.Bootstrap; import io.netty.channel.Channel; import io.netty.channel.ChannelException; @@ -196,7 +190,7 @@ import io.netty.handler.timeout.ReadTimeoutHandler; [[oder einfach einen Toaster mit nem LCD und Maus]] */ -public class Client implements IThreadListener, IClient { +public class Client implements IThreadListener { public static class SyncFunction implements IntFunction { public void apply(IntVar cv, int value) { Client.CLIENT.sync(value); @@ -1271,7 +1265,7 @@ public class Client implements IThreadListener, IClient { if ((this.pointed.type != ObjectType.BLOCK || this.world.getState(this.pointed.block).getBlock().getMaterial() == Material.air) && itemstack != null && itemstack.getItem().onAction(itemstack, this.player, this.world, ItemControl.PRIMARY, null)) { this.player.swingItem(); - this.player.sendQueue.addToSendQueue(new CPacketAction(Action.ITEM_ACTION, ItemControl.PRIMARY.ordinal())); + this.player.client.addToSendQueue(new CPacketAction(Action.ITEM_ACTION, ItemControl.PRIMARY.ordinal())); this.leftClickCounter = 10; return; } @@ -1323,7 +1317,7 @@ public class Client implements IThreadListener, IClient { if ((this.pointed.type != ObjectType.BLOCK || this.world.getState(this.pointed.block).getBlock().getMaterial() == Material.air) && itemstack != null && itemstack.getItem().onAction(itemstack, this.player, this.world, ItemControl.SECONDARY, null)) { this.player.swingItem(); - this.player.sendQueue.addToSendQueue(new CPacketAction(Action.ITEM_ACTION, ItemControl.SECONDARY.ordinal())); + this.player.client.addToSendQueue(new CPacketAction(Action.ITEM_ACTION, ItemControl.SECONDARY.ordinal())); return; } @@ -1389,7 +1383,7 @@ public class Client implements IThreadListener, IClient { if (this.pointed != null) { if(this.player.getHeldItem() != null && this.player.getHeldItem().getItem().onAction(this.player.getHeldItem(), this.player, this.world, ItemControl.TERTIARY, null)) { - this.player.sendQueue.addToSendQueue(new CPacketAction(Action.ITEM_ACTION, ItemControl.TERTIARY.ordinal())); + this.player.client.addToSendQueue(new CPacketAction(Action.ITEM_ACTION, ItemControl.TERTIARY.ordinal())); return; } @@ -1436,7 +1430,7 @@ public class Client implements IThreadListener, IClient { inventoryplayer.setCurrentItem(item, meta, flag1); if(this.itemCheat) { - this.player.sendQueue.addToSendQueue(new CPacketCheat(new ItemStack(item, 1, meta), inventoryplayer.currentItem, this.ctrl())); + this.player.client.addToSendQueue(new CPacketCheat(new ItemStack(item, 1, meta), inventoryplayer.currentItem, this.ctrl())); } } } @@ -1446,7 +1440,7 @@ public class Client implements IThreadListener, IClient { if (this.pointed != null) { if(this.player.getHeldItem() != null && this.player.getHeldItem().getItem().onAction(this.player.getHeldItem(), this.player, this.world, ItemControl.QUARTERNARY, null)) { - this.player.sendQueue.addToSendQueue(new CPacketAction(Action.ITEM_ACTION, ItemControl.QUARTERNARY.ordinal())); + this.player.client.addToSendQueue(new CPacketAction(Action.ITEM_ACTION, ItemControl.QUARTERNARY.ordinal())); return; } } @@ -1522,7 +1516,7 @@ public class Client implements IThreadListener, IClient { public ClientPlayer getNetHandler() { - return this.player != null ? (ClientPlayer)this.player.sendQueue : null; + return this.player != null ? (ClientPlayer)this.player.client : null; } // public void setSkin(BufferedImage skin, String id, ModelType model, boolean slim) @@ -1569,7 +1563,7 @@ public class Client implements IThreadListener, IClient { public void performAction(Action action) { if(this.player != null) - this.player.sendQueue.addToSendQueue(new CPacketAction(action)); + this.player.client.addToSendQueue(new CPacketAction(action)); } public void setBossStatus(EntityLiving entity) { @@ -1805,7 +1799,7 @@ public class Client implements IThreadListener, IClient { ticked / 1000L, (ticked / 100L) % 10L ) + (this.serverInfo != null ? "\n" + this.serverInfo : "") -// WorldServer world = this.server.getWorld(this.theWorld.dimension.getDimensionId()); +// IWorldServer world = this.server.getWorld(this.theWorld.dimension.getDimensionId()); // if(world != null) // list.add("Seed: " + world.getSeed()); ; @@ -3342,82 +3336,4 @@ public class Client implements IThreadListener, IClient { } }, "File Browser listener").start(); } - - public void makeFireworks(double x, double y, double z, double motionX, double motionY, double motionZ, NBTTagCompound compund) - { - this.effectRenderer.addEffect(new EntityFirework.StarterFX(this.world, x, y, z, motionX, motionY, motionZ, this.effectRenderer, compund)); - } - - public int getRenderDistance() { - return this.renderDistance; - } - - public float getGravity() { - return this.gravity; - } - - public int getTimeFactor() { - return this.timeFactor; - } - - public boolean hasDayCycle() { - return this.dayCycle; - } - - public void playSound(Sound sound) { - this.soundManager.playSound(sound); - } - - public EntityNPC getPlayer() { - return this.player; - } - - public IEntityFX spawnEffectParticle(int particleId, double xCoord, double yCoord, double zCoord, double xSpeed, double ySpeed, double zSpeed, - int[] parameters) { - return this.effectRenderer.spawnEffectParticle(particleId, xCoord, yCoord, zCoord, xSpeed, ySpeed, zSpeed, parameters); - } - - public void addBlockDestroyEffects(BlockPos pos, State state) { - this.effectRenderer.addBlockDestroyEffects(pos, state); - } - - public void sendBlockBreakProgress(int breakerId, BlockPos pos, int progress) { - this.renderGlobal.sendBlockBreakProgress(breakerId, pos, progress); - } - - public void markBlocksForUpdate(int x1, int y1, int z1, int x2, int y2, int z2) { - this.renderGlobal.markBlocksForUpdate(x1, y1, z1, x2, y2, z2); - } - - public void emitParticleAtEntity(Entity entityIn, ParticleType particleTypes) { - this.effectRenderer.emitParticleAtEntity(entityIn, particleTypes); - } - - public boolean isJumping() { - return this.jump; - } - - public boolean isSprinting() { - return this.sprint; - } - - public boolean isSneaking() { - return this.sneak; - } - - public float getMoveForward() { - return this.moveForward; - } - - public float getMoveStrafe() { - return this.moveStrafe; - } - - public void setMoveForward(float value) { - this.moveForward = value; - } - - public void setMoveStrafe(float value) { - this.moveStrafe = value; - } } diff --git a/client/src/client/PlayerController.java b/client/src/client/PlayerController.java index 80017d3..a06986e 100755 --- a/client/src/client/PlayerController.java +++ b/client/src/client/PlayerController.java @@ -1,6 +1,7 @@ package client; import client.network.ClientPlayer; +import client.world.WorldClient; import common.block.Block; import common.entity.Entity; import common.entity.npc.EntityNPC; @@ -20,7 +21,6 @@ import common.util.Facing; import common.util.Vec3; import common.world.State; import common.world.World; -import common.world.WorldClient; public class PlayerController { @@ -471,7 +471,7 @@ public class PlayerController public EntityNPC createPlayerEntity(WorldClient worldIn, int type) { EntityNPC player = (EntityNPC)EntityRegistry.createEntityByID(type, worldIn); - player.setClientPlayer(this.gm, this.netClientHandler); + player.setClientPlayer(this.netClientHandler); return player; } diff --git a/client/src/client/gui/GuiConsole.java b/client/src/client/gui/GuiConsole.java index 3ea6d44..52f1501 100644 --- a/client/src/client/gui/GuiConsole.java +++ b/client/src/client/gui/GuiConsole.java @@ -215,7 +215,7 @@ public class GuiConsole extends Gui implements Textbox.Callback { s = argv[argv.length - 1]; Iterable res = pre.startsWith("#") ? (argv.length == 1 ? this.gm.getVars() : (argv.length == 2 ? getVarCompletion(argv[0].substring(1)) : Lists.newArrayList())) : - (this.gm.player == null ? Lists.newArrayList() : ((ClientPlayer)this.gm.player.sendQueue).getPlayerNames()); + (this.gm.player == null ? Lists.newArrayList() : ((ClientPlayer)this.gm.player.client).getPlayerNames()); if(argv.length == 1 && pre.startsWith("#")) s = s.substring(1); for(String s1 : res) { @@ -255,7 +255,7 @@ public class GuiConsole extends Gui implements Textbox.Callback { if(this.gm.player != null) { currentText = currentText.substring(1); this.prefixFirst = currentText.split(" ", -1).length == 1 ? "/" : null; - this.gm.player.sendQueue.addToSendQueue(new CPacketComplete(currentText, eid, blockpos)); + this.gm.player.client.addToSendQueue(new CPacketComplete(currentText, eid, blockpos)); this.waitingOnAutocomplete = true; } } diff --git a/client/src/client/gui/character/GuiChar.java b/client/src/client/gui/character/GuiChar.java index 540c209..25c3593 100755 --- a/client/src/client/gui/character/GuiChar.java +++ b/client/src/client/gui/character/GuiChar.java @@ -350,7 +350,7 @@ public class GuiChar extends GuiList public void use(ActButton elem, Mode action) { if(GuiChar.this.gm.player != null) { GuiChar.this.waiting = false; - GuiChar.this.gm.player.sendQueue.addToSendQueue(new CPacketAction(CPacketAction.Action.SET_ALIGN, align.ordinal())); + GuiChar.this.gm.player.client.addToSendQueue(new CPacketAction(CPacketAction.Action.SET_ALIGN, align.ordinal())); for(ActButton btn : alignBtns) { btn.enabled = btn != elem; } @@ -363,7 +363,7 @@ public class GuiChar extends GuiList public void use(Slider elem, int value) { if(GuiChar.this.gm.player != null) { GuiChar.this.waiting = false; - GuiChar.this.gm.player.sendQueue.addToSendQueue(new CPacketAction(CPacketAction.Action.SET_HEIGHT, value)); + GuiChar.this.gm.player.client.addToSendQueue(new CPacketAction(CPacketAction.Action.SET_HEIGHT, value)); } } }, "Spieler-Größe", "cm")).enabled = this.gm.player == null || this.gm.player.getMinSize() != this.gm.player.getMaxSize(); @@ -378,8 +378,8 @@ public class GuiChar extends GuiList if(GuiChar.this.gm.player != null) { GuiChar.this.gm.displayGuiScreen(GuiLoading.makeWaitTask("Lade Welt ...")); Dimension dim = UniverseRegistry.getBaseDimensions().get(GuiChar.this.dimension); - GuiChar.this.gm.player.sendQueue.addToSendQueue(new CPacketMessage(CPacketMessage.Type.INFO, descField.getText())); - GuiChar.this.gm.player.sendQueue.addToSendQueue(new CPacketAction(CPacketAction.Action.CLOSE_EDITOR, dim.getDimensionId())); + GuiChar.this.gm.player.client.addToSendQueue(new CPacketMessage(CPacketMessage.Type.INFO, descField.getText())); + GuiChar.this.gm.player.client.addToSendQueue(new CPacketAction(CPacketAction.Action.CLOSE_EDITOR, dim.getDimensionId())); } } }, "Charakter erstellen")); @@ -391,7 +391,7 @@ public class GuiChar extends GuiList elem.setText(GuiChar.this.gm.player == null ? "..." : GuiChar.this.gm.player.getCustomNameTag()); else if(GuiChar.this.gm.player != null) { GuiChar.this.waiting = false; - GuiChar.this.gm.player.sendQueue.addToSendQueue(new CPacketMessage(CPacketMessage.Type.DISPLAY, name)); + GuiChar.this.gm.player.client.addToSendQueue(new CPacketMessage(CPacketMessage.Type.DISPLAY, name)); } } } diff --git a/client/src/client/gui/character/GuiClass.java b/client/src/client/gui/character/GuiClass.java index 11a8805..e25e5f5 100644 --- a/client/src/client/gui/character/GuiClass.java +++ b/client/src/client/gui/character/GuiClass.java @@ -70,7 +70,7 @@ public class GuiClass extends GuiList implements ActButton. public void use(ActButton elem, Mode action) { ClassEntry entry = this.getSelected(); if(entry != null && GuiClass.this.gm.player != null) { - GuiClass.this.gm.player.sendQueue.addToSendQueue(new CPacketAction(CPacketAction.Action.SET_CLASS, entry.clazz.ordinal())); + GuiClass.this.gm.player.client.addToSendQueue(new CPacketAction(CPacketAction.Action.SET_CLASS, entry.clazz.ordinal())); this.gm.displayGuiScreen(GuiChar.INSTANCE); } } diff --git a/client/src/client/gui/character/GuiSpecies.java b/client/src/client/gui/character/GuiSpecies.java index 770d8a4..47a9ec7 100644 --- a/client/src/client/gui/character/GuiSpecies.java +++ b/client/src/client/gui/character/GuiSpecies.java @@ -74,6 +74,6 @@ public class GuiSpecies extends GuiList implements ActB public void use(ActButton elem, Mode action) { SpeciesEntry entry = this.getSelected(); if(entry != null && GuiSpecies.this.gm.player != null) - GuiSpecies.this.gm.player.sendQueue.addToSendQueue(new CPacketAction(CPacketAction.Action.SET_SPECIES, EntityRegistry.getEntityID(entry.species.clazz))); + GuiSpecies.this.gm.player.client.addToSendQueue(new CPacketAction(CPacketAction.Action.SET_SPECIES, EntityRegistry.getEntityID(entry.species.clazz))); } } diff --git a/client/src/client/gui/container/GuiContainer.java b/client/src/client/gui/container/GuiContainer.java index babe081..7ae0eb8 100755 --- a/client/src/client/gui/container/GuiContainer.java +++ b/client/src/client/gui/container/GuiContainer.java @@ -644,7 +644,7 @@ public abstract class GuiContainer extends Gui if(this.cheatStack != null) { Slot slot = this.getSlotAtPosition(mouseX, mouseY); if((mouseButton == 0 || mouseButton == 1) && slot != null && this.gm.player != null && slot.inventory == this.gm.player.inventory) - this.gm.player.sendQueue.addToSendQueue(new CPacketCheat(this.cheatStack, slot.getIndex(), mouseButton == 0 && this.cheatStack.stackSize > 1)); + this.gm.player.client.addToSendQueue(new CPacketCheat(this.cheatStack, slot.getIndex(), mouseButton == 0 && this.cheatStack.stackSize > 1)); if(mouseButton != 1 && !this.gm.ctrl()) this.cheatStack = null; return; @@ -1197,7 +1197,7 @@ public abstract class GuiContainer extends Gui if(i1 >= 0 && i1 < ITEM_LIST.size()) { if(slot >= 0 || instant) { - this.gm.player.sendQueue.addToSendQueue(new CPacketCheat(ITEM_LIST.get(i1), slot, full)); + this.gm.player.client.addToSendQueue(new CPacketCheat(ITEM_LIST.get(i1), slot, full)); } else { this.cheatStack = ITEM_LIST.get(i1).copy(); diff --git a/client/src/client/network/ClientLoginHandler.java b/client/src/client/network/ClientLoginHandler.java index 47e9894..c17ab44 100755 --- a/client/src/client/network/ClientLoginHandler.java +++ b/client/src/client/network/ClientLoginHandler.java @@ -30,6 +30,7 @@ public class ClientLoginHandler extends NetHandler implements IClientLoginHandle public void handleLoginSuccess(RPacketLoginSuccess packetIn) { + this.gm.debugWorld = packetIn.isDebug(); this.networkManager.setConnectionState(PacketRegistry.PLAY); this.networkManager.setNetHandler(new ClientPlayer(this.gm, this.networkManager)); } diff --git a/client/src/client/network/ClientPlayer.java b/client/src/client/network/ClientPlayer.java index 217ff52..eb1cbc1 100755 --- a/client/src/client/network/ClientPlayer.java +++ b/client/src/client/network/ClientPlayer.java @@ -27,6 +27,7 @@ import client.gui.container.GuiRepair; import client.gui.ingame.GuiSign; import client.renderer.particle.EntityPickupFX; import client.renderer.texture.EntityTexManager; +import client.world.WorldClient; import common.attributes.Attribute; import common.attributes.AttributeInstance; import common.attributes.AttributeMap; @@ -126,6 +127,7 @@ import common.packet.SPacketUpdateHealth; import common.packet.SPacketWorld; import common.potion.PotionEffect; import common.rng.Random; +import common.sound.Sound; import common.tileentity.IInteractionObject; import common.tileentity.LocalBlockIntercommunication; import common.tileentity.TileEntity; @@ -137,7 +139,6 @@ import common.world.Chunk; import common.world.Explosion; import common.world.Weather; import common.world.World; -import common.world.WorldClient; public class ClientPlayer extends NetHandler implements IClientPlayer { @@ -180,6 +181,52 @@ public class ClientPlayer extends NetHandler implements IClientPlayer this.netManager = p_i46300_3_; } + + public void playSound(Sound sound) { + this.gameController.getSoundManager().playSound(sound); + } + + public void emitParticleAtEntity(Entity entityIn, ParticleType particleTypes) { + this.gameController.effectRenderer.emitParticleAtEntity(entityIn, particleTypes); + } + + public boolean isJumping() { + return this.gameController.jump; + } + + public boolean isSprinting() { + return this.gameController.sprint; + } + + public boolean isSneaking() { + return this.gameController.sneak; + } + + public float getMoveForward() { + return this.gameController.moveForward; + } + + public float getMoveStrafe() { + return this.gameController.moveStrafe; + } + + public void setMoveForward(float value) { + this.gameController.moveForward = value; + } + + public void setMoveStrafe(float value) { + this.gameController.moveStrafe = value; + } + + public boolean isRenderViewEntity(Entity entity) { + return this.gameController.getRenderViewEntity() == entity; + } + + public void updatePlayerMoveState() { + this.gameController.updatePlayerMoveState(); + } + + /** * Clears the WorldClient instance associated with this NetHandlerPlayClient */ @@ -482,7 +529,7 @@ public class ClientPlayer extends NetHandler implements IClientPlayer float yaw = packetIn.getYaw(); float pitch = packetIn.getPitch(); EntityNPC player = (EntityNPC)EntityRegistry.createEntityByID(packetIn.getEntityType(), this.gameController.world); // new EntityNPC(this.gameController.theWorld); // , /* this.getPlayerInfo( */ packetIn.getUser()); // ).getUser()); - player.setOtherPlayer(this.gameController); + player.setOtherPlayer(); player.prevX = player.lastTickPosX = (double)(player.serverPosX = packetIn.getX()); player.prevY = player.lastTickPosY = (double)(player.serverPosY = packetIn.getY()); player.prevZ = player.lastTickPosZ = (double)(player.serverPosZ = packetIn.getZ()); diff --git a/client/src/client/renderer/EntityRenderer.java b/client/src/client/renderer/EntityRenderer.java index d0b2f82..9e5bf48 100755 --- a/client/src/client/renderer/EntityRenderer.java +++ b/client/src/client/renderer/EntityRenderer.java @@ -13,6 +13,7 @@ import client.Client; import client.renderer.particle.EffectRenderer; import client.renderer.texture.DynamicTexture; import client.renderer.texture.TextureMap; +import client.world.WorldClient; import common.biome.Biome; import common.block.Block; import common.entity.Entity; @@ -32,7 +33,6 @@ import common.util.ExtMath; import common.util.HitPosition; import common.util.Vec3; import common.world.World; -import common.world.WorldClient; public class EntityRenderer { private static final String locationMoltenPng = "textures/world/molten.png"; diff --git a/client/src/client/renderer/RenderGlobal.java b/client/src/client/renderer/RenderGlobal.java index 03a90a9..f1ad4b3 100755 --- a/client/src/client/renderer/RenderGlobal.java +++ b/client/src/client/renderer/RenderGlobal.java @@ -25,6 +25,7 @@ import client.renderer.texture.TextureAtlasSprite; import client.renderer.texture.TextureManager; import client.renderer.texture.TextureMap; import client.renderer.tileentity.TileEntityRendererDispatcher; +import client.world.WorldClient; import common.block.Block; import common.block.BlockChest; import common.block.BlockSign; @@ -52,7 +53,6 @@ import common.util.Vec3; import common.util.Vector3f; import common.world.Chunk; import common.world.State; -import common.world.WorldClient; public class RenderGlobal { diff --git a/client/src/client/renderer/particle/EntityFX.java b/client/src/client/renderer/particle/EntityFX.java index f0615ed..67c53bd 100755 --- a/client/src/client/renderer/particle/EntityFX.java +++ b/client/src/client/renderer/particle/EntityFX.java @@ -5,12 +5,11 @@ import client.renderer.RenderBuffer; import client.renderer.texture.TextureAtlasSprite; import common.entity.Entity; import common.entity.EntityType; -import common.entity.types.IEntityFX; import common.nbt.NBTTagCompound; import common.util.ExtMath; import common.world.World; -public class EntityFX extends Entity implements IEntityFX +public class EntityFX extends Entity { protected int particleTextureIndexX; protected int particleTextureIndexY; diff --git a/client/src/client/renderer/particle/EntityFirework.java b/client/src/client/renderer/particle/EntityFirework.java index da4bd91..b3f3072 100755 --- a/client/src/client/renderer/particle/EntityFirework.java +++ b/client/src/client/renderer/particle/EntityFirework.java @@ -2,6 +2,7 @@ package client.renderer.particle; import client.Client; import client.renderer.RenderBuffer; +import client.world.WorldClient; import common.entity.Entity; import common.init.SoundEvent; import common.item.ItemDye; @@ -10,7 +11,6 @@ import common.nbt.NBTTagList; import common.util.BoundingBox; import common.util.ExtMath; import common.world.World; -import common.world.WorldClient; public class EntityFirework { diff --git a/client/src/client/renderer/particle/EntityParticleEmitter.java b/client/src/client/renderer/particle/EntityParticleEmitter.java index 262871b..42f18a8 100755 --- a/client/src/client/renderer/particle/EntityParticleEmitter.java +++ b/client/src/client/renderer/particle/EntityParticleEmitter.java @@ -1,10 +1,10 @@ package client.renderer.particle; import client.renderer.RenderBuffer; +import client.world.WorldClient; import common.entity.Entity; import common.model.ParticleType; import common.world.World; -import common.world.WorldClient; public class EntityParticleEmitter extends EntityFX { diff --git a/common/src/common/world/EmptyChunk.java b/client/src/client/world/EmptyChunk.java similarity index 95% rename from common/src/common/world/EmptyChunk.java rename to client/src/client/world/EmptyChunk.java index 66ef16f..190c2d7 100755 --- a/common/src/common/world/EmptyChunk.java +++ b/client/src/client/world/EmptyChunk.java @@ -1,4 +1,4 @@ -package common.world; +package client.world; import java.util.List; import java.util.function.Predicate; @@ -9,6 +9,8 @@ import common.init.Blocks; import common.tileentity.TileEntity; import common.util.BlockPos; import common.util.BoundingBox; +import common.world.Chunk; +import common.world.LightType; public class EmptyChunk extends Chunk { public EmptyChunk(WorldClient world) { diff --git a/common/src/common/world/WorldClient.java b/client/src/client/world/WorldClient.java similarity index 92% rename from common/src/common/world/WorldClient.java rename to client/src/client/world/WorldClient.java index 998a254..a38b356 100755 --- a/common/src/common/world/WorldClient.java +++ b/client/src/client/world/WorldClient.java @@ -1,9 +1,11 @@ -package common.world; +package client.world; import java.util.List; import java.util.Set; -import common.IClient; +import client.Client; +import client.renderer.particle.EntityFX; +import client.renderer.particle.EntityFirework; import common.biome.Biome; import common.block.Block; import common.collect.Lists; @@ -12,7 +14,6 @@ import common.dimension.Dimension; import common.entity.Entity; import common.entity.item.EntityCart; import common.entity.npc.EntityNPC; -import common.entity.types.IEntityFX; import common.init.BlockRegistry; import common.init.ItemRegistry; import common.init.Items; @@ -32,12 +33,15 @@ import common.util.ExtMath; import common.util.LongHashMap; import common.util.Vec3; import common.util.BlockPos.MutableBlockPos; +import common.world.Chunk; +import common.world.AWorldClient; +import common.world.State; -public class WorldClient extends World +public class WorldClient extends AWorldClient { private static final int DISPLAY_RANGE = 16; - private final IClient gm; + private final Client gm; private final Set entityList = Sets.newHashSet(); private final Set spawnQueue = Sets.newHashSet(); private final Set previousActive = Sets.newHashSet(); @@ -48,14 +52,14 @@ public class WorldClient extends World protected int lastLightning; protected Vec3 lightColor = new Vec3(0xffffff); - public WorldClient(IClient gm, boolean debug, Dimension dim) + public WorldClient(Client gm, boolean debug, Dimension dim) { - super(dim, true, debug); + super(dim, debug); this.gm = gm; this.calculateInitialSkylight(); this.calculateInitialWeather(); - this.setGravity(this.gm.getGravity()); - this.setTimeFactor(this.gm.getTimeFactor()); + this.setGravity(this.gm.gravity); + this.setTimeFactor(this.gm.timeFactor); // this.setDifficulty(this.gm.difficulty); } @@ -63,7 +67,7 @@ public class WorldClient extends World { // this.info.tick(); - if (this.gm.hasDayCycle()) + if (this.gm.dayCycle) { this.daytime += this.timeFactor; } @@ -92,7 +96,7 @@ public class WorldClient extends World protected void updateBlocks() { - this.setActivePlayerChunksAndCheckLight(this.gm.getRenderDistance()); + this.setActivePlayerChunksAndCheckLight(this.gm.renderDistance); this.previousActive.retainAll(this.active); if (this.previousActive.size() == this.active.size()) @@ -160,7 +164,7 @@ public class WorldClient extends World } else if (entityIn instanceof EntityCart) { - this.gm.playSound(new MovingSoundMinecart((EntityCart)entityIn)); + this.gm.getSoundManager().playSound(new MovingSoundMinecart((EntityCart)entityIn)); } return flag; @@ -220,7 +224,7 @@ public class WorldClient extends World public Entity getEntityByID(int id) { - return (Entity)(id == this.gm.getPlayer().getId() ? this.gm.getPlayer() : super.getEntityByID(id)); + return (Entity)(id == this.gm.player.getId() ? this.gm.player : super.getEntityByID(id)); } public Entity removeEntityFromWorld(int entityID) @@ -338,13 +342,13 @@ public class WorldClient extends World // } // else // { - this.gm.playSound(positionedsoundrecord); + this.gm.getSoundManager().playSound(positionedsoundrecord); // } } public void makeFireworks(double x, double y, double z, double motionX, double motionY, double motionZ, NBTTagCompound compund) { - this.gm.makeFireworks(x, y, z, motionX, motionY, motionZ, compund); + this.gm.effectRenderer.addEffect(new EntityFirework.StarterFX(this.gm.world, x, y, z, motionX, motionY, motionZ, this.gm.effectRenderer, compund)); } public Chunk getChunk(int x, int z) @@ -373,7 +377,7 @@ public class WorldClient extends World this.spawnEntityFX(particleType, particleType.getShouldIgnoreRange(), xCoord, yCoord, zCoord, xOffset, yOffset, zOffset, data); } - public IEntityFX spawnEntityFX(ParticleType particle, boolean ignoreRange, double xCoord, double yCoord, double zCoord, double xOffset, double yOffset, double zOffset, int[] parameters) + public EntityFX spawnEntityFX(ParticleType particle, boolean ignoreRange, double xCoord, double yCoord, double zCoord, double xOffset, double yOffset, double zOffset, int[] parameters) { if (this.gm.getRenderViewEntity() != null) { @@ -391,14 +395,14 @@ public class WorldClient extends World if (ignoreRange) { - return this.gm.spawnEffectParticle(particleID, xCoord, yCoord, zCoord, xOffset, yOffset, zOffset, parameters); + return this.gm.effectRenderer.spawnEffectParticle(particleID, xCoord, yCoord, zCoord, xOffset, yOffset, zOffset, parameters); } else { double d3 = 16.0D; if(d0 * d0 + d1 * d1 + d2 * d2 > 256.0D) return null; - return this.gm.spawnEffectParticle(particleID, xCoord, yCoord, zCoord, xOffset, yOffset, zOffset, parameters); + return this.gm.effectRenderer.spawnEffectParticle(particleID, xCoord, yCoord, zCoord, xOffset, yOffset, zOffset, parameters); } } return null; @@ -585,10 +589,10 @@ public class WorldClient extends World if (block.getMaterial() != Material.air) { - this.gm.playSound(new PositionedSound(block.sound.getBreakSound(), 1.0F, /* block.sound.getFrequency() * 0.8F, */ (float)blockPosIn.getX() + 0.5F, (float)blockPosIn.getY() + 0.5F, (float)blockPosIn.getZ() + 0.5F)); + this.gm.getSoundManager().playSound(new PositionedSound(block.sound.getBreakSound(), 1.0F, /* block.sound.getFrequency() * 0.8F, */ (float)blockPosIn.getX() + 0.5F, (float)blockPosIn.getY() + 0.5F, (float)blockPosIn.getZ() + 0.5F)); } - this.gm.addBlockDestroyEffects(blockPosIn, block.getStateFromMeta(data >> 12 & 255)); + this.gm.effectRenderer.addBlockDestroyEffects(blockPosIn, block.getStateFromMeta(data >> 12 & 255)); break; case 2002: @@ -625,7 +629,7 @@ public class WorldClient extends World double d24 = Math.cos(d23) * d22; double d9 = 0.01D + this.rand.doublev() * 0.5D; double d11 = Math.sin(d23) * d22; - IEntityFX entityfx = this.spawnEntityFX(enumparticletypes, enumparticletypes.getShouldIgnoreRange(), d13 + d24 * 0.1D, d14 + 0.3D, d16 + d11 * 0.1D, d24, d9, d11, new int[0]); + EntityFX entityfx = this.spawnEntityFX(enumparticletypes, enumparticletypes.getShouldIgnoreRange(), d13 + d24 * 0.1D, d14 + 0.3D, d16 + d11 * 0.1D, d24, d9, d11, new int[0]); if (entityfx != null) { @@ -662,7 +666,7 @@ public class WorldClient extends World int i = pos.getX(); int j = pos.getY(); int k = pos.getZ(); - this.gm.markBlocksForUpdate(i - 1, j - 1, k - 1, i + 1, j + 1, k + 1); + this.gm.renderGlobal.markBlocksForUpdate(i - 1, j - 1, k - 1, i + 1, j + 1, k + 1); } public void notifyLightSet(BlockPos pos) @@ -670,17 +674,17 @@ public class WorldClient extends World int i = pos.getX(); int j = pos.getY(); int k = pos.getZ(); - this.gm.markBlocksForUpdate(i - 1, j - 1, k - 1, i + 1, j + 1, k + 1); + this.gm.renderGlobal.markBlocksForUpdate(i - 1, j - 1, k - 1, i + 1, j + 1, k + 1); } public void markBlockRangeForRenderUpdate(int x1, int y1, int z1, int x2, int y2, int z2) { - this.gm.markBlocksForUpdate(x1 - 1, y1 - 1, z1 - 1, x2 + 1, y2 + 1, z2 + 1); + this.gm.renderGlobal.markBlocksForUpdate(x1 - 1, y1 - 1, z1 - 1, x2 + 1, y2 + 1, z2 + 1); } public void sendBlockBreakProgress(int breakerId, BlockPos pos, int progress) { - this.gm.sendBlockBreakProgress(breakerId, pos, progress); + this.gm.renderGlobal.sendBlockBreakProgress(breakerId, pos, progress); } public float getSunBrightness(float p_72971_1_) { diff --git a/common/src/common/IClient.java b/common/src/common/IClient.java deleted file mode 100644 index 6d050f4..0000000 --- a/common/src/common/IClient.java +++ /dev/null @@ -1,34 +0,0 @@ -package common; - -import common.entity.Entity; -import common.entity.npc.EntityNPC; -import common.entity.types.IEntityFX; -import common.model.ParticleType; -import common.nbt.NBTTagCompound; -import common.sound.Sound; -import common.util.BlockPos; -import common.world.State; - -public interface IClient { - int getRenderDistance(); - float getGravity(); - int getTimeFactor(); - boolean hasDayCycle(); - void playSound(Sound sound); - EntityNPC getPlayer(); - Entity getRenderViewEntity(); - void makeFireworks(double x, double y, double z, double motionX, double motionY, double motionZ, NBTTagCompound compund); - IEntityFX spawnEffectParticle(int particleId, double xCoord, double yCoord, double zCoord, double xSpeed, double ySpeed, double zSpeed, int[] parameters); - void addBlockDestroyEffects(BlockPos pos, State state); - void sendBlockBreakProgress(int breakerId, BlockPos pos, int progress); - void markBlocksForUpdate(int x1, int y1, int z1, int x2, int y2, int z2); - void updatePlayerMoveState(); - void emitParticleAtEntity(Entity entityIn, ParticleType particleTypes); - boolean isJumping(); - boolean isSprinting(); - boolean isSneaking(); - float getMoveForward(); - float getMoveStrafe(); - void setMoveForward(float value); - void setMoveStrafe(float value); -} diff --git a/common/src/common/IServer.java b/common/src/common/IServer.java deleted file mode 100644 index c3fc135..0000000 --- a/common/src/common/IServer.java +++ /dev/null @@ -1,25 +0,0 @@ -package common; - -import java.util.List; -import java.util.Map; - -import common.entity.Entity; -import common.entity.npc.EntityNPC; -import common.network.IPlayer; -import common.network.Packet; -import common.util.BlockPos; -import common.util.PortalType; -import common.util.Position; -import common.world.WorldServer; - -public interface IServer { - List getIPlayers(); - void sendPacket(Packet packet); - void sendPacket(Packet packet, int dimension); - void sendNear(double x, double y, double z, double radius, int dimension, Packet packet); - void sendNearExcept(EntityNPC except, double x, double y, double z, double radius, int dimension, Packet packet); - Map getWarps(); - List getWorlds(); - WorldServer getWorld(int dimension); - void placeInDimension(Entity entity, WorldServer oldWorld, WorldServer world, BlockPos pos, PortalType portal); -} \ No newline at end of file diff --git a/common/src/common/ai/EntityAIFleeSun.java b/common/src/common/ai/EntityAIFleeSun.java index 0347580..85c8c7e 100755 --- a/common/src/common/ai/EntityAIFleeSun.java +++ b/common/src/common/ai/EntityAIFleeSun.java @@ -5,7 +5,7 @@ import common.rng.Random; import common.util.BlockPos; import common.util.Vec3; import common.world.World; -import common.world.WorldServer; +import common.world.AWorldServer; public class EntityAIFleeSun extends EntityAIBase { @@ -29,7 +29,7 @@ public class EntityAIFleeSun extends EntityAIBase */ public boolean shouldExecute() { - if (!((WorldServer)this.theWorld).isDaytime()) + if (!((AWorldServer)this.theWorld).isDaytime()) { return false; } diff --git a/common/src/common/ai/EntityAIMoveIndoors.java b/common/src/common/ai/EntityAIMoveIndoors.java index 0348347..a5294db 100755 --- a/common/src/common/ai/EntityAIMoveIndoors.java +++ b/common/src/common/ai/EntityAIMoveIndoors.java @@ -5,7 +5,7 @@ import common.util.BlockPos; import common.util.Vec3; import common.village.Village; import common.village.VillageDoorInfo; -import common.world.WorldServer; +import common.world.AWorldServer; public class EntityAIMoveIndoors extends EntityAIBase { @@ -27,7 +27,7 @@ public class EntityAIMoveIndoors extends EntityAIBase { BlockPos blockpos = new BlockPos(this.entityObj); - if ((!((WorldServer)this.entityObj.worldObj).isDaytime() /* || this.entityObj.worldObj.isRaining() && !this.entityObj.worldObj.getBiomeGenForCoords(blockpos).canRain() */) && !this.entityObj.worldObj.dimension.hasNoLight()) + if ((!((AWorldServer)this.entityObj.worldObj).isDaytime() /* || this.entityObj.worldObj.isRaining() && !this.entityObj.worldObj.getBiomeGenForCoords(blockpos).canRain() */) && !this.entityObj.worldObj.dimension.hasNoLight()) { if (this.entityObj.getRNG().zrange(50) != 0) { @@ -39,7 +39,7 @@ public class EntityAIMoveIndoors extends EntityAIBase } else { - Village village = ((WorldServer)this.entityObj.worldObj).getNearestVillage(blockpos, 14); + Village village = ((AWorldServer)this.entityObj.worldObj).getNearestVillage(blockpos, 14); if (village == null) { diff --git a/common/src/common/ai/EntityAIMoveThroughVillage.java b/common/src/common/ai/EntityAIMoveThroughVillage.java index be583f8..2ebfcb6 100755 --- a/common/src/common/ai/EntityAIMoveThroughVillage.java +++ b/common/src/common/ai/EntityAIMoveThroughVillage.java @@ -11,7 +11,7 @@ import common.util.ExtMath; import common.util.Vec3; import common.village.Village; import common.village.VillageDoorInfo; -import common.world.WorldServer; +import common.world.AWorldServer; public class EntityAIMoveThroughVillage extends EntityAIBase { @@ -44,13 +44,13 @@ public class EntityAIMoveThroughVillage extends EntityAIBase { this.resizeDoorList(); - if (this.isNocturnal && ((WorldServer)this.theEntity.worldObj).isDaytime()) + if (this.isNocturnal && ((AWorldServer)this.theEntity.worldObj).isDaytime()) { return false; } else { - Village village = ((WorldServer)this.theEntity.worldObj).getNearestVillage(new BlockPos(this.theEntity), 0); + Village village = ((AWorldServer)this.theEntity.worldObj).getNearestVillage(new BlockPos(this.theEntity), 0); if (village == null) { diff --git a/common/src/common/ai/EntityAINpcMate.java b/common/src/common/ai/EntityAINpcMate.java index 654af34..639566c 100755 --- a/common/src/common/ai/EntityAINpcMate.java +++ b/common/src/common/ai/EntityAINpcMate.java @@ -3,7 +3,7 @@ package common.ai; import common.entity.Entity; import common.entity.npc.EntityNPC; import common.world.World; -import common.world.WorldServer; +import common.world.AWorldServer; public class EntityAINpcMate extends EntityAIBase { @@ -33,7 +33,7 @@ public class EntityAINpcMate extends EntityAIBase { if (this.npc.getIsWillingToMate(true)) { - Entity entity = ((WorldServer)this.worldObj).findNearestEntityWithinAABB(EntityNPC.class, this.npc.getEntityBoundingBox().expand(8.0D, 3.0D, 8.0D), this.npc); + Entity entity = ((AWorldServer)this.worldObj).findNearestEntityWithinAABB(EntityNPC.class, this.npc.getEntityBoundingBox().expand(8.0D, 3.0D, 8.0D), this.npc); if (entity == null) { diff --git a/common/src/common/ai/EntityAIRestrictOpenDoor.java b/common/src/common/ai/EntityAIRestrictOpenDoor.java index d7a94c4..15235cb 100755 --- a/common/src/common/ai/EntityAIRestrictOpenDoor.java +++ b/common/src/common/ai/EntityAIRestrictOpenDoor.java @@ -5,7 +5,7 @@ import common.pathfinding.PathNavigateGround; import common.util.BlockPos; import common.village.Village; import common.village.VillageDoorInfo; -import common.world.WorldServer; +import common.world.AWorldServer; public class EntityAIRestrictOpenDoor extends EntityAIBase { @@ -27,14 +27,14 @@ public class EntityAIRestrictOpenDoor extends EntityAIBase */ public boolean shouldExecute() { - if (((WorldServer)this.entityObj.worldObj).isDaytime()) + if (((AWorldServer)this.entityObj.worldObj).isDaytime()) { return false; } else { BlockPos blockpos = new BlockPos(this.entityObj); - Village village = ((WorldServer)this.entityObj.worldObj).getNearestVillage(blockpos, 16); + Village village = ((AWorldServer)this.entityObj.worldObj).getNearestVillage(blockpos, 16); if (village == null) { @@ -53,7 +53,7 @@ public class EntityAIRestrictOpenDoor extends EntityAIBase */ public boolean continueExecuting() { - return ((WorldServer)this.entityObj.worldObj).isDaytime() ? false : !this.frontDoor.getIsDetachedFromVillageFlag() && this.frontDoor.isIndoorSide(new BlockPos(this.entityObj)); + return ((AWorldServer)this.entityObj.worldObj).isDaytime() ? false : !this.frontDoor.getIsDetachedFromVillageFlag() && this.frontDoor.isIndoorSide(new BlockPos(this.entityObj)); } /** diff --git a/common/src/common/ai/EntityAIRestrictSun.java b/common/src/common/ai/EntityAIRestrictSun.java index 2734f28..50e2901 100755 --- a/common/src/common/ai/EntityAIRestrictSun.java +++ b/common/src/common/ai/EntityAIRestrictSun.java @@ -2,7 +2,7 @@ package common.ai; import common.entity.types.EntityLiving; import common.pathfinding.PathNavigateGround; -import common.world.WorldServer; +import common.world.AWorldServer; public class EntityAIRestrictSun extends EntityAIBase { @@ -18,7 +18,7 @@ public class EntityAIRestrictSun extends EntityAIBase */ public boolean shouldExecute() { - return ((WorldServer)this.theEntity.worldObj).isDaytime(); + return ((AWorldServer)this.theEntity.worldObj).isDaytime(); } /** diff --git a/common/src/common/ai/EntityAIWatchClosest.java b/common/src/common/ai/EntityAIWatchClosest.java index 81b0a9e..43c1703 100755 --- a/common/src/common/ai/EntityAIWatchClosest.java +++ b/common/src/common/ai/EntityAIWatchClosest.java @@ -2,7 +2,7 @@ package common.ai; import common.entity.Entity; import common.entity.types.EntityLiving; -import common.world.WorldServer; +import common.world.AWorldServer; public class EntityAIWatchClosest extends EntityAIBase { @@ -57,7 +57,7 @@ public class EntityAIWatchClosest extends EntityAIBase } else { - this.closestEntity = ((WorldServer)this.theWatcher.worldObj).findNearestEntityWithinAABB(this.watchedClass, this.theWatcher.getEntityBoundingBox().expand((double)this.maxDistanceForPlayer, 3.0D, (double)this.maxDistanceForPlayer), this.theWatcher); + this.closestEntity = ((AWorldServer)this.theWatcher.worldObj).findNearestEntityWithinAABB(this.watchedClass, this.theWatcher.getEntityBoundingBox().expand((double)this.maxDistanceForPlayer, 3.0D, (double)this.maxDistanceForPlayer), this.theWatcher); } return this.closestEntity != null; diff --git a/common/src/common/biome/Biome.java b/common/src/common/biome/Biome.java index bfb66bb..b4d4ea8 100755 --- a/common/src/common/biome/Biome.java +++ b/common/src/common/biome/Biome.java @@ -36,7 +36,7 @@ import common.util.BlockPos; import common.util.ExtMath; import common.world.State; import common.world.World; -import common.world.WorldServer; +import common.world.AWorldServer; import common.worldgen.ChunkPrimer; import common.worldgen.FeatureGenerator; import common.worldgen.feature.WorldGenClay; @@ -315,7 +315,7 @@ public abstract class Biome { } } - public void decorate(WorldServer world, Random rand, BlockPos pos) + public void decorate(AWorldServer world, Random rand, BlockPos pos) { for (int i = 0; i < this.sandPerChunk2; ++i) { @@ -564,7 +564,7 @@ public abstract class Biome { return Colorizer.getFoliageColor(d0, d1); } - public void genTerrainBlocks(WorldServer worldIn, Random rand, ChunkPrimer chunkPrimerIn, int x, int z, double noiseVal) + public void genTerrainBlocks(AWorldServer worldIn, Random rand, ChunkPrimer chunkPrimerIn, int x, int z, double noiseVal) { this.generateBiomeTerrain(worldIn, rand, chunkPrimerIn, x, z, noiseVal); } @@ -579,7 +579,7 @@ public abstract class Biome { * * If this.fillerBlock is red sand, we replace some of that with red sandstone. */ - public final void generateBiomeTerrain(WorldServer worldIn, Random rand, ChunkPrimer chunkPrimerIn, int x, int z, double noiseVal) + public final void generateBiomeTerrain(AWorldServer worldIn, Random rand, ChunkPrimer chunkPrimerIn, int x, int z, double noiseVal) { int i = worldIn.getSeaLevel(); State worldState = worldIn.dimension.getFiller(); diff --git a/common/src/common/biome/BiomeChaos.java b/common/src/common/biome/BiomeChaos.java index d2353c7..79ee8c1 100755 --- a/common/src/common/biome/BiomeChaos.java +++ b/common/src/common/biome/BiomeChaos.java @@ -7,7 +7,7 @@ import common.init.EntityRegistry; import common.rng.Random; import common.rng.WeightedList; import common.util.BlockPos; -import common.world.WorldServer; +import common.world.AWorldServer; import common.worldgen.FeatureGenerator; import common.worldgen.foliage.WorldGenMushroom; @@ -29,7 +29,7 @@ public class BiomeChaos extends Biome } } - public void decorate(WorldServer worldIn, Random rand, BlockPos pos) + public void decorate(AWorldServer worldIn, Random rand, BlockPos pos) { super.decorate(worldIn, rand, pos); diff --git a/common/src/common/biome/BiomeDesert.java b/common/src/common/biome/BiomeDesert.java index 0890481..b95ad41 100755 --- a/common/src/common/biome/BiomeDesert.java +++ b/common/src/common/biome/BiomeDesert.java @@ -4,7 +4,7 @@ import common.init.Blocks; import common.rng.Random; import common.rng.WeightedList; import common.util.BlockPos; -import common.world.WorldServer; +import common.world.AWorldServer; import common.worldgen.feature.WorldGenDesertWells; public class BiomeDesert extends Biome @@ -24,7 +24,7 @@ public class BiomeDesert extends Biome protected void addMobs(WeightedList mobs) { } - public void decorate(WorldServer worldIn, Random rand, BlockPos pos) + public void decorate(AWorldServer worldIn, Random rand, BlockPos pos) { super.decorate(worldIn, rand, pos); diff --git a/common/src/common/biome/BiomeExterminated.java b/common/src/common/biome/BiomeExterminated.java index 1ca72d5..f944a55 100755 --- a/common/src/common/biome/BiomeExterminated.java +++ b/common/src/common/biome/BiomeExterminated.java @@ -4,7 +4,7 @@ import common.init.Blocks; import common.rng.Random; import common.rng.WeightedList; import common.util.BlockPos; -import common.world.WorldServer; +import common.world.AWorldServer; public class BiomeExterminated extends Biome { public BiomeExterminated(int id) { @@ -16,7 +16,7 @@ public class BiomeExterminated extends Biome { protected void addMobs(WeightedList mobs) { } - public void decorate(WorldServer worldIn, Random rand, BlockPos pos) { + public void decorate(AWorldServer worldIn, Random rand, BlockPos pos) { } public int getSkyColor() { diff --git a/common/src/common/biome/BiomeForest.java b/common/src/common/biome/BiomeForest.java index 9c30b45..b699026 100755 --- a/common/src/common/biome/BiomeForest.java +++ b/common/src/common/biome/BiomeForest.java @@ -10,7 +10,7 @@ import common.init.Blocks; import common.rng.Random; import common.util.BlockPos; import common.util.ExtMath; -import common.world.WorldServer; +import common.world.AWorldServer; import common.worldgen.foliage.WorldGenBigMushroom; import common.worldgen.tree.WorldGenBaseTree; import common.worldgen.tree.WorldGenBigTree; @@ -120,7 +120,7 @@ public class BiomeForest extends Biome } } - public void decorate(WorldServer worldIn, Random rand, BlockPos pos) + public void decorate(AWorldServer worldIn, Random rand, BlockPos pos) { // if(worldIn.getLeavesGen() != this.leavesType) { // this.leavesType = worldIn.getLeavesGen(); @@ -229,7 +229,7 @@ public class BiomeForest extends Biome { return this.id != Biome.birchForest.id && this.id != Biome.birchForestHills.id ? new BiomeMutated(id, this) { - public void decorate(WorldServer worldIn, Random rand, BlockPos pos) + public void decorate(AWorldServer worldIn, Random rand, BlockPos pos) { this.baseBiome.decorate(worldIn, rand, pos); } diff --git a/common/src/common/biome/BiomeHell.java b/common/src/common/biome/BiomeHell.java index d19e23c..1e4b4dc 100755 --- a/common/src/common/biome/BiomeHell.java +++ b/common/src/common/biome/BiomeHell.java @@ -10,7 +10,7 @@ import common.init.Blocks; import common.rng.Random; import common.rng.WeightedList; import common.util.BlockPos; -import common.world.WorldServer; +import common.world.AWorldServer; import common.worldgen.FeatureOres; import common.worldgen.feature.WorldGenFire; import common.worldgen.feature.WorldGenGlowStone; @@ -73,7 +73,7 @@ public class BiomeHell extends Biome mobs.add(new RngSpawn(EntityMagma.class, 1, 4, 4)); } - public void decorate(WorldServer worldIn, Random rand, BlockPos pos) + public void decorate(AWorldServer worldIn, Random rand, BlockPos pos) { if(this.subtype == 0) { for (int i = 0; i < 8; ++i) diff --git a/common/src/common/biome/BiomeHills.java b/common/src/common/biome/BiomeHills.java index 578fcab..7ea7137 100755 --- a/common/src/common/biome/BiomeHills.java +++ b/common/src/common/biome/BiomeHills.java @@ -3,7 +3,7 @@ package common.biome; import common.init.Blocks; import common.rng.Random; import common.util.BlockPos; -import common.world.WorldServer; +import common.world.AWorldServer; import common.worldgen.ChunkPrimer; import common.worldgen.FeatureOres; import common.worldgen.tree.WorldGenTaiga2; @@ -36,7 +36,7 @@ public class BiomeHills extends Biome return (WorldGenTree)(rand.rarity(3) ? this.field_150634_aD : super.genBigTreeChance(rand)); } - public void decorate(WorldServer worldIn, Random rand, BlockPos pos) + public void decorate(AWorldServer worldIn, Random rand, BlockPos pos) { super.decorate(worldIn, rand, pos); // int i = 3 + rand.nextInt(6); @@ -64,7 +64,7 @@ public class BiomeHills extends Biome // } } - public void genTerrainBlocks(WorldServer worldIn, Random rand, ChunkPrimer chunkPrimerIn, int x, int z, double noiseVal) + public void genTerrainBlocks(AWorldServer worldIn, Random rand, ChunkPrimer chunkPrimerIn, int x, int z, double noiseVal) { this.topBlock = Blocks.grass.getState(); this.fillerBlock = Blocks.dirt.getState(); diff --git a/common/src/common/biome/BiomeJungle.java b/common/src/common/biome/BiomeJungle.java index 09c52dc..71737c7 100755 --- a/common/src/common/biome/BiomeJungle.java +++ b/common/src/common/biome/BiomeJungle.java @@ -7,7 +7,7 @@ import common.init.Blocks; import common.rng.Random; import common.util.BlockPos; import common.world.State; -import common.world.WorldServer; +import common.world.AWorldServer; import common.worldgen.FeatureGenerator; import common.worldgen.foliage.WorldGenMelon; import common.worldgen.foliage.WorldGenShrub; @@ -63,7 +63,7 @@ public class BiomeJungle extends Biome return rand.chance(4) ? new WorldGenTallGrass(BlockTallGrass.EnumType.FERN) : new WorldGenTallGrass(BlockTallGrass.EnumType.GRASS); } - public void decorate(WorldServer worldIn, Random rand, BlockPos pos) + public void decorate(AWorldServer worldIn, Random rand, BlockPos pos) { super.decorate(worldIn, rand, pos); int i = rand.chOffset(); diff --git a/common/src/common/biome/BiomeMesa.java b/common/src/common/biome/BiomeMesa.java index a42e388..eb9fd70 100755 --- a/common/src/common/biome/BiomeMesa.java +++ b/common/src/common/biome/BiomeMesa.java @@ -14,7 +14,7 @@ import common.rng.Random; import common.rng.WeightedList; import common.util.BlockPos; import common.world.State; -import common.world.WorldServer; +import common.world.AWorldServer; import common.worldgen.ChunkPrimer; import common.worldgen.tree.WorldGenTree; @@ -71,12 +71,12 @@ public class BiomeMesa extends Biome return 9470285; } - public void decorate(WorldServer worldIn, Random rand, BlockPos pos) + public void decorate(AWorldServer worldIn, Random rand, BlockPos pos) { super.decorate(worldIn, rand, pos); } - public void genTerrainBlocks(WorldServer worldIn, Random rand, ChunkPrimer chunkPrimerIn, int x, int z, double noiseVal) + public void genTerrainBlocks(AWorldServer worldIn, Random rand, ChunkPrimer chunkPrimerIn, int x, int z, double noiseVal) { if (this.layers == null || this.layerSeed != worldIn.getSeed()) { diff --git a/common/src/common/biome/BiomeMoon.java b/common/src/common/biome/BiomeMoon.java index ded8deb..49ccfb8 100755 --- a/common/src/common/biome/BiomeMoon.java +++ b/common/src/common/biome/BiomeMoon.java @@ -4,7 +4,7 @@ import common.init.Blocks; import common.rng.Random; import common.rng.WeightedList; import common.util.BlockPos; -import common.world.WorldServer; +import common.world.AWorldServer; import common.worldgen.FeatureOres; public class BiomeMoon extends Biome { @@ -19,7 +19,7 @@ public class BiomeMoon extends Biome { protected void addMobs(WeightedList mobs) { } - public void decorate(WorldServer worldIn, Random rand, BlockPos pos) { + public void decorate(AWorldServer worldIn, Random rand, BlockPos pos) { this.cheeseGenerator.generate(worldIn, rand, pos); } } diff --git a/common/src/common/biome/BiomeMutated.java b/common/src/common/biome/BiomeMutated.java index 630b885..2f90e23 100755 --- a/common/src/common/biome/BiomeMutated.java +++ b/common/src/common/biome/BiomeMutated.java @@ -3,7 +3,7 @@ package common.biome; import common.rng.Random; import common.rng.WeightedList; import common.util.BlockPos; -import common.world.WorldServer; +import common.world.AWorldServer; import common.worldgen.ChunkPrimer; import common.worldgen.tree.WorldGenTree; @@ -43,17 +43,17 @@ public class BiomeMutated extends Biome protected void addMobs(WeightedList mobs) { } - public void decorate(WorldServer worldIn, Random rand, BlockPos pos) + public void decorate(AWorldServer worldIn, Random rand, BlockPos pos) { this.baseBiome.decorate(worldIn, rand, pos); // TODO: check } - public void decorateNormal(WorldServer worldIn, Random rand, BlockPos pos) + public void decorateNormal(AWorldServer worldIn, Random rand, BlockPos pos) { super.decorate(worldIn, rand, pos); } - public void genTerrainBlocks(WorldServer worldIn, Random rand, ChunkPrimer chunkPrimerIn, int x, int z, double noiseVal) + public void genTerrainBlocks(AWorldServer worldIn, Random rand, ChunkPrimer chunkPrimerIn, int x, int z, double noiseVal) { this.baseBiome.genTerrainBlocks(worldIn, rand, chunkPrimerIn, x, z, noiseVal); } diff --git a/common/src/common/biome/BiomeNone.java b/common/src/common/biome/BiomeNone.java index 27b2a97..00a5ef4 100755 --- a/common/src/common/biome/BiomeNone.java +++ b/common/src/common/biome/BiomeNone.java @@ -4,7 +4,7 @@ import common.init.Blocks; import common.rng.Random; import common.rng.WeightedList; import common.util.BlockPos; -import common.world.WorldServer; +import common.world.AWorldServer; import common.worldgen.ChunkPrimer; public class BiomeNone extends Biome { @@ -17,10 +17,10 @@ public class BiomeNone extends Biome { protected void addMobs(WeightedList mobs) { } - public void genTerrainBlocks(WorldServer worldIn, Random rand, ChunkPrimer chunkPrimerIn, int x, int z, double noiseVal) { + public void genTerrainBlocks(AWorldServer worldIn, Random rand, ChunkPrimer chunkPrimerIn, int x, int z, double noiseVal) { } - public void decorate(WorldServer worldIn, Random rand, BlockPos pos) { + public void decorate(AWorldServer worldIn, Random rand, BlockPos pos) { } public Temperature getTempCategory() { diff --git a/common/src/common/biome/BiomePlains.java b/common/src/common/biome/BiomePlains.java index d74d85a..6aace9a 100755 --- a/common/src/common/biome/BiomePlains.java +++ b/common/src/common/biome/BiomePlains.java @@ -5,7 +5,7 @@ import common.block.BlockFlower; import common.entity.animal.EntityHorse; import common.rng.Random; import common.util.BlockPos; -import common.world.WorldServer; +import common.world.AWorldServer; public class BiomePlains extends Biome { @@ -68,7 +68,7 @@ public class BiomePlains extends Biome } } - public void decorate(WorldServer worldIn, Random rand, BlockPos pos) + public void decorate(AWorldServer worldIn, Random rand, BlockPos pos) { double d0 = GRASS_NOISE.generate((double)(pos.getX() + 8) / 200.0D, (double)(pos.getZ() + 8) / 200.0D); diff --git a/common/src/common/biome/BiomeSavanna.java b/common/src/common/biome/BiomeSavanna.java index fe9f069..c456f4e 100755 --- a/common/src/common/biome/BiomeSavanna.java +++ b/common/src/common/biome/BiomeSavanna.java @@ -6,7 +6,7 @@ import common.entity.animal.EntityHorse; import common.init.Blocks; import common.rng.Random; import common.util.BlockPos; -import common.world.WorldServer; +import common.world.AWorldServer; import common.worldgen.ChunkPrimer; import common.worldgen.tree.WorldGenSavanna; import common.worldgen.tree.WorldGenTree; @@ -38,7 +38,7 @@ public class BiomeSavanna extends Biome return biomegenbase; } - public void decorate(WorldServer worldIn, Random rand, BlockPos pos) + public void decorate(AWorldServer worldIn, Random rand, BlockPos pos) { DOUBLE_PLANT_GEN.setPlantType(BlockDoublePlant.EnumPlantType.GRASS); @@ -63,7 +63,7 @@ public class BiomeSavanna extends Biome this.grassPerChunk = 5; } - public void genTerrainBlocks(WorldServer worldIn, Random rand, ChunkPrimer chunkPrimerIn, int x, int z, double noiseVal) + public void genTerrainBlocks(AWorldServer worldIn, Random rand, ChunkPrimer chunkPrimerIn, int x, int z, double noiseVal) { this.topBlock = Blocks.grass.getState(); this.fillerBlock = Blocks.dirt.getState(); @@ -81,7 +81,7 @@ public class BiomeSavanna extends Biome this.generateBiomeTerrain(worldIn, rand, chunkPrimerIn, x, z, noiseVal); } - public void decorate(WorldServer worldIn, Random rand, BlockPos pos) + public void decorate(AWorldServer worldIn, Random rand, BlockPos pos) { this.decorateNormal(worldIn, rand, pos); } diff --git a/common/src/common/biome/BiomeSnow.java b/common/src/common/biome/BiomeSnow.java index 695ac5d..d1440e8 100755 --- a/common/src/common/biome/BiomeSnow.java +++ b/common/src/common/biome/BiomeSnow.java @@ -4,7 +4,7 @@ import common.init.Blocks; import common.rng.Random; import common.rng.WeightedList; import common.util.BlockPos; -import common.world.WorldServer; +import common.world.AWorldServer; import common.worldgen.feature.WorldGenIcePath; import common.worldgen.feature.WorldGenIceSpike; import common.worldgen.tree.WorldGenTaiga2; @@ -27,7 +27,7 @@ public class BiomeSnow extends Biome protected void addMobs(WeightedList mobs) { } - public void decorate(WorldServer worldIn, Random rand, BlockPos pos) + public void decorate(AWorldServer worldIn, Random rand, BlockPos pos) { if (this.spiky) { diff --git a/common/src/common/biome/BiomeSpace.java b/common/src/common/biome/BiomeSpace.java index a2ebccb..550c865 100755 --- a/common/src/common/biome/BiomeSpace.java +++ b/common/src/common/biome/BiomeSpace.java @@ -5,7 +5,7 @@ import common.init.Blocks; import common.rng.Random; import common.rng.WeightedList; import common.util.BlockPos; -import common.world.WorldServer; +import common.world.AWorldServer; import common.worldgen.FeatureGenerator; import common.worldgen.feature.WorldGenAsteroid; @@ -26,7 +26,7 @@ public class BiomeSpace extends Biome protected void addMobs(WeightedList mobs) { } - public void decorate(WorldServer worldIn, Random rand, BlockPos pos) + public void decorate(AWorldServer worldIn, Random rand, BlockPos pos) { if(rand.chance(5)) { int x = rand.chOffset(); diff --git a/common/src/common/biome/BiomeSwamp.java b/common/src/common/biome/BiomeSwamp.java index b708632..d726a13 100755 --- a/common/src/common/biome/BiomeSwamp.java +++ b/common/src/common/biome/BiomeSwamp.java @@ -8,7 +8,7 @@ import common.material.Material; import common.rng.Random; import common.util.BlockPos; import common.util.Facing; -import common.world.WorldServer; +import common.world.AWorldServer; import common.worldgen.ChunkPrimer; import common.worldgen.tree.WorldGenTree; @@ -53,7 +53,7 @@ public class BiomeSwamp extends Biome return BlockFlower.EnumFlowerType.BLUE_ORCHID; } - public void genTerrainBlocks(WorldServer worldIn, Random rand, ChunkPrimer chunkPrimerIn, int x, int z, double noiseVal) + public void genTerrainBlocks(AWorldServer worldIn, Random rand, ChunkPrimer chunkPrimerIn, int x, int z, double noiseVal) { double d0 = GRASS_NOISE.generate((double)x * 0.25D, (double)z * 0.25D); diff --git a/common/src/common/biome/BiomeTaiga.java b/common/src/common/biome/BiomeTaiga.java index 5680a75..440fc02 100755 --- a/common/src/common/biome/BiomeTaiga.java +++ b/common/src/common/biome/BiomeTaiga.java @@ -7,7 +7,7 @@ import common.entity.animal.EntityWolf; import common.init.Blocks; import common.rng.Random; import common.util.BlockPos; -import common.world.WorldServer; +import common.world.AWorldServer; import common.worldgen.ChunkPrimer; import common.worldgen.FeatureGenerator; import common.worldgen.feature.WorldGenBlockBlob; @@ -59,7 +59,7 @@ public class BiomeTaiga extends Biome return rand.rarity(5) ? new WorldGenTallGrass(BlockTallGrass.EnumType.FERN) : new WorldGenTallGrass(BlockTallGrass.EnumType.GRASS); } - public void decorate(WorldServer worldIn, Random rand, BlockPos pos) + public void decorate(AWorldServer worldIn, Random rand, BlockPos pos) { if (this.field_150644_aH == 1 || this.field_150644_aH == 2) { @@ -87,7 +87,7 @@ public class BiomeTaiga extends Biome super.decorate(worldIn, rand, pos); } - public void genTerrainBlocks(WorldServer worldIn, Random rand, ChunkPrimer chunkPrimerIn, int x, int z, double noiseVal) + public void genTerrainBlocks(AWorldServer worldIn, Random rand, ChunkPrimer chunkPrimerIn, int x, int z, double noiseVal) { if (this.field_150644_aH == 1 || this.field_150644_aH == 2) { diff --git a/common/src/common/biome/BiomeTian.java b/common/src/common/biome/BiomeTian.java index eae35ef..6f8b5bf 100755 --- a/common/src/common/biome/BiomeTian.java +++ b/common/src/common/biome/BiomeTian.java @@ -9,7 +9,7 @@ import common.init.Blocks; import common.rng.Random; import common.rng.WeightedList; import common.util.BlockPos; -import common.world.WorldServer; +import common.world.AWorldServer; import common.worldgen.FeatureGenerator; import common.worldgen.feature.WorldGenSpikes; import common.worldgen.foliage.WorldGenMushroom; @@ -57,7 +57,7 @@ public class BiomeTian extends Biome return rand.pick(rand.chance(this.treeGen2, this.treeGen1, 4), rand.chance(this.treeGen3, this.treeGen4, 15)); } - public void decorate(WorldServer worldIn, Random rand, BlockPos pos) + public void decorate(AWorldServer worldIn, Random rand, BlockPos pos) { super.decorate(worldIn, rand, pos); diff --git a/common/src/common/block/Block.java b/common/src/common/block/Block.java index 484a05f..d1c321a 100755 --- a/common/src/common/block/Block.java +++ b/common/src/common/block/Block.java @@ -46,10 +46,10 @@ import common.util.HitPosition.ObjectType; import common.world.Explosion; import common.world.IBlockAccess; import common.world.IWorldAccess; +import common.world.AWorldClient; import common.world.State; import common.world.World; -import common.world.WorldClient; -import common.world.WorldServer; +import common.world.AWorldServer; public class Block { @@ -698,14 +698,14 @@ public class Block /** * Called randomly when setTickRandomly is set to true (used by e.g. crops to grow, etc.) */ - public void randomTick(WorldServer worldIn, BlockPos pos, State state, Random random) + public void randomTick(AWorldServer worldIn, BlockPos pos, State state, Random random) { this.updateTick(worldIn, pos, state, random); if(this.radiation > 0.0f && /* worldIn.getTime() % 5L == 0L && */ random.chance(Config.randomTick / 3)) this.affectEntities(worldIn, pos, state, this.radiation * 8.0f * 0.25f); } - private void affectEntities(WorldServer worldIn, BlockPos pos, State state, float rad) + private void affectEntities(AWorldServer worldIn, BlockPos pos, State state, float rad) { float r = ExtMath.clampf(rad * 2.0f, 0.0f, 25.0f); BoundingBox box = this.getCollisionBoundingBox(worldIn, pos, state); @@ -719,11 +719,11 @@ public class Block } } - public void updateTick(WorldServer worldIn, BlockPos pos, State state, Random rand) + public void updateTick(AWorldServer worldIn, BlockPos pos, State state, Random rand) { } - public void randomDisplayTick(WorldClient worldIn, BlockPos pos, State state, Random rand) + public void randomDisplayTick(AWorldClient worldIn, BlockPos pos, State state, Random rand) { } @@ -749,11 +749,11 @@ public class Block return 10; } - public void onBlockAdded(WorldServer world, BlockPos pos, State state) + public void onBlockAdded(AWorldServer world, BlockPos pos, State state) { } - public void onBlockRemoved(WorldServer world, BlockPos pos, State state) + public void onBlockRemoved(AWorldServer world, BlockPos pos, State state) { } diff --git a/common/src/common/block/BlockBasePressurePlate.java b/common/src/common/block/BlockBasePressurePlate.java index d8e1366..b19329d 100755 --- a/common/src/common/block/BlockBasePressurePlate.java +++ b/common/src/common/block/BlockBasePressurePlate.java @@ -14,7 +14,7 @@ import common.world.IBlockAccess; import common.world.IWorldAccess; import common.world.State; import common.world.World; -import common.world.WorldServer; +import common.world.AWorldServer; public abstract class BlockBasePressurePlate extends Block { @@ -109,11 +109,11 @@ public abstract class BlockBasePressurePlate extends Block /** * Called randomly when setTickRandomly is set to true (used by e.g. crops to grow, etc.) */ - public void randomTick(WorldServer worldIn, BlockPos pos, State state, Random random) + public void randomTick(AWorldServer worldIn, BlockPos pos, State state, Random random) { } - public void updateTick(WorldServer worldIn, BlockPos pos, State state, Random rand) + public void updateTick(AWorldServer worldIn, BlockPos pos, State state, Random rand) { // if (!worldIn.client) // { @@ -183,7 +183,7 @@ public abstract class BlockBasePressurePlate extends Block return new BoundingBox((double)((float)pos.getX() + 0.125F), (double)pos.getY(), (double)((float)pos.getZ() + 0.125F), (double)((float)(pos.getX() + 1) - 0.125F), (double)pos.getY() + 0.25D, (double)((float)(pos.getZ() + 1) - 0.125F)); } - public void onBlockRemoved(WorldServer worldIn, BlockPos pos, State state) + public void onBlockRemoved(AWorldServer worldIn, BlockPos pos, State state) { if (this.getRedstoneStrength(state) > 0) { diff --git a/common/src/common/block/BlockBedrock.java b/common/src/common/block/BlockBedrock.java index 0ea00ba..71ec977 100755 --- a/common/src/common/block/BlockBedrock.java +++ b/common/src/common/block/BlockBedrock.java @@ -4,15 +4,15 @@ import common.material.Material; import common.model.ParticleType; import common.rng.Random; import common.util.BlockPos; +import common.world.AWorldClient; import common.world.State; -import common.world.WorldClient; public class BlockBedrock extends Block { public BlockBedrock() { super(Material.rock); } - public void randomDisplayTick(WorldClient worldIn, BlockPos pos, State state, Random rand) + public void randomDisplayTick(AWorldClient worldIn, BlockPos pos, State state, Random rand) { if(/* worldIn.canShowVoidParticles() && */ pos.getY() <= 5 && rand.chance(8)) { worldIn.spawnParticle(ParticleType.SUSPENDED_DEPTH, (double)pos.getX() + rand.floatv(), (double)(pos.getY()+1) + (rand.floatv() * 0.5f), diff --git a/common/src/common/block/BlockBlackenedDirt.java b/common/src/common/block/BlockBlackenedDirt.java index ac5909c..361c7cb 100644 --- a/common/src/common/block/BlockBlackenedDirt.java +++ b/common/src/common/block/BlockBlackenedDirt.java @@ -7,7 +7,7 @@ import common.material.Material; import common.rng.Random; import common.util.BlockPos; import common.world.State; -import common.world.WorldServer; +import common.world.AWorldServer; public class BlockBlackenedDirt extends Block { @@ -18,7 +18,7 @@ public class BlockBlackenedDirt extends Block this.setTab(CheatTab.tabNature); } - public void updateTick(WorldServer worldIn, BlockPos pos, State state, Random rand) + public void updateTick(AWorldServer worldIn, BlockPos pos, State state, Random rand) { if (Config.darkDirtSpread) { diff --git a/common/src/common/block/BlockBlackenedSoil.java b/common/src/common/block/BlockBlackenedSoil.java index a77664e..3e122f6 100644 --- a/common/src/common/block/BlockBlackenedSoil.java +++ b/common/src/common/block/BlockBlackenedSoil.java @@ -10,7 +10,7 @@ import common.model.ModelProvider; import common.rng.Random; import common.util.BlockPos; import common.world.State; -import common.world.WorldServer; +import common.world.AWorldServer; public class BlockBlackenedSoil extends Block { @@ -21,7 +21,7 @@ public class BlockBlackenedSoil extends Block this.setTab(CheatTab.tabNature); } - public void updateTick(WorldServer worldIn, BlockPos pos, State state, Random rand) + public void updateTick(AWorldServer worldIn, BlockPos pos, State state, Random rand) { if (worldIn.getLightFromNeighbors(pos.up()) < 2 && worldIn.getState(pos.up()).getBlock().getLightOpacity() > 6) { diff --git a/common/src/common/block/BlockBlueShroom.java b/common/src/common/block/BlockBlueShroom.java index d0097d9..648fadf 100755 --- a/common/src/common/block/BlockBlueShroom.java +++ b/common/src/common/block/BlockBlueShroom.java @@ -8,7 +8,7 @@ import common.rng.Random; import common.util.BlockPos; import common.world.State; import common.world.World; -import common.world.WorldServer; +import common.world.AWorldServer; public class BlockBlueShroom extends BlockBush { @@ -19,7 +19,7 @@ public class BlockBlueShroom extends BlockBush this.setTickRandomly(); } - public void updateTick(WorldServer worldIn, BlockPos pos, State state, Random rand) + public void updateTick(AWorldServer worldIn, BlockPos pos, State state, Random rand) { if (Config.blueShroomGrowth > 0 && rand.chance(Config.blueShroomGrowth)) { diff --git a/common/src/common/block/BlockBrewingStand.java b/common/src/common/block/BlockBrewingStand.java index beb51cd..dcd6dc6 100755 --- a/common/src/common/block/BlockBrewingStand.java +++ b/common/src/common/block/BlockBrewingStand.java @@ -23,10 +23,10 @@ import common.tileentity.TileEntityBrewingStand; import common.util.BlockPos; import common.util.BoundingBox; import common.util.Facing; +import common.world.AWorldClient; import common.world.State; import common.world.World; -import common.world.WorldClient; -import common.world.WorldServer; +import common.world.AWorldServer; public class BlockBrewingStand extends BlockContainer { @@ -447,7 +447,7 @@ public class BlockBrewingStand extends BlockContainer } } - public void randomDisplayTick(WorldClient worldIn, BlockPos pos, State state, Random rand) + public void randomDisplayTick(AWorldClient worldIn, BlockPos pos, State state, Random rand) { double d0 = (double)((float)pos.getX() + 0.4F + rand.floatv() * 0.2F); double d1 = (double)((float)pos.getY() + 0.7F + rand.floatv() * 0.3F); @@ -455,7 +455,7 @@ public class BlockBrewingStand extends BlockContainer worldIn.spawnParticle(ParticleType.SMOKE_NORMAL, d0, d1, d2, 0.0D, 0.0D, 0.0D); } - public void onBlockRemoved(WorldServer worldIn, BlockPos pos, State state) + public void onBlockRemoved(AWorldServer worldIn, BlockPos pos, State state) { TileEntity tileentity = worldIn.getTileEntity(pos); diff --git a/common/src/common/block/BlockBush.java b/common/src/common/block/BlockBush.java index 94ff784..4ff09d6 100755 --- a/common/src/common/block/BlockBush.java +++ b/common/src/common/block/BlockBush.java @@ -9,7 +9,7 @@ import common.util.BlockPos; import common.util.BoundingBox; import common.world.State; import common.world.World; -import common.world.WorldServer; +import common.world.AWorldServer; public class BlockBush extends Block { @@ -49,7 +49,7 @@ public class BlockBush extends Block this.checkAndDropBlock(worldIn, pos, state); } - public void updateTick(WorldServer worldIn, BlockPos pos, State state, Random rand) + public void updateTick(AWorldServer worldIn, BlockPos pos, State state, Random rand) { this.checkAndDropBlock(worldIn, pos, state); } diff --git a/common/src/common/block/BlockButton.java b/common/src/common/block/BlockButton.java index 4c655c0..28b690c 100755 --- a/common/src/common/block/BlockButton.java +++ b/common/src/common/block/BlockButton.java @@ -24,7 +24,7 @@ import common.util.Facing; import common.world.IWorldAccess; import common.world.State; import common.world.World; -import common.world.WorldServer; +import common.world.AWorldServer; public class BlockButton extends Block { @@ -195,7 +195,7 @@ public class BlockButton extends Block } } - public void onBlockRemoved(WorldServer worldIn, BlockPos pos, State state) + public void onBlockRemoved(AWorldServer worldIn, BlockPos pos, State state) { if (((Boolean)state.getValue(POWERED)).booleanValue()) { @@ -226,11 +226,11 @@ public class BlockButton extends Block /** * Called randomly when setTickRandomly is set to true (used by e.g. crops to grow, etc.) */ - public void randomTick(WorldServer worldIn, BlockPos pos, State state, Random random) + public void randomTick(AWorldServer worldIn, BlockPos pos, State state, Random random) { } - public void updateTick(WorldServer worldIn, BlockPos pos, State state, Random rand) + public void updateTick(AWorldServer worldIn, BlockPos pos, State state, Random rand) { // if (!worldIn.client) // { diff --git a/common/src/common/block/BlockCactus.java b/common/src/common/block/BlockCactus.java index 1ab3926..92db3ca 100755 --- a/common/src/common/block/BlockCactus.java +++ b/common/src/common/block/BlockCactus.java @@ -17,7 +17,7 @@ import common.util.BoundingBox; import common.util.Facing; import common.world.State; import common.world.World; -import common.world.WorldServer; +import common.world.AWorldServer; public class BlockCactus extends Block { @@ -43,7 +43,7 @@ public class BlockCactus extends Block this.setTab(CheatTab.tabPlants); } - public void updateTick(WorldServer worldIn, BlockPos pos, State state, Random rand) + public void updateTick(AWorldServer worldIn, BlockPos pos, State state, Random rand) { BlockPos blockpos = pos.up(); diff --git a/common/src/common/block/BlockChest.java b/common/src/common/block/BlockChest.java index 99af70f..a195e29 100755 --- a/common/src/common/block/BlockChest.java +++ b/common/src/common/block/BlockChest.java @@ -29,7 +29,7 @@ import common.util.Facing; import common.world.IWorldAccess; import common.world.State; import common.world.World; -import common.world.WorldServer; +import common.world.AWorldServer; public class BlockChest extends BlockContainer { @@ -92,7 +92,7 @@ public class BlockChest extends BlockContainer } } - public void onBlockAdded(WorldServer worldIn, BlockPos pos, State state) + public void onBlockAdded(AWorldServer worldIn, BlockPos pos, State state) { this.checkForSurroundingChests(worldIn, pos, state); @@ -416,7 +416,7 @@ public class BlockChest extends BlockContainer } } - public void onBlockRemoved(WorldServer worldIn, BlockPos pos, State state) + public void onBlockRemoved(AWorldServer worldIn, BlockPos pos, State state) { TileEntity tileentity = worldIn.getTileEntity(pos); diff --git a/common/src/common/block/BlockCocoa.java b/common/src/common/block/BlockCocoa.java index 2d5cff9..7eff652 100755 --- a/common/src/common/block/BlockCocoa.java +++ b/common/src/common/block/BlockCocoa.java @@ -21,7 +21,7 @@ import common.util.Facing; import common.world.IWorldAccess; import common.world.State; import common.world.World; -import common.world.WorldServer; +import common.world.AWorldServer; public class BlockCocoa extends BlockDirectional implements IGrowable { @@ -34,7 +34,7 @@ public class BlockCocoa extends BlockDirectional implements IGrowable this.setTickRandomly(); } - public void updateTick(WorldServer worldIn, BlockPos pos, State state, Random rand) + public void updateTick(AWorldServer worldIn, BlockPos pos, State state, Random rand) { if (!this.canBlockStay(worldIn, pos, state)) { @@ -197,7 +197,7 @@ public class BlockCocoa extends BlockDirectional implements IGrowable return true; } - public void grow(WorldServer worldIn, Random rand, BlockPos pos, State state) + public void grow(AWorldServer worldIn, Random rand, BlockPos pos, State state) { worldIn.setState(pos, state.withProperty(AGE, Integer.valueOf(((Integer)state.getValue(AGE)).intValue() + 1)), 2); } diff --git a/common/src/common/block/BlockContainer.java b/common/src/common/block/BlockContainer.java index 8443549..78a927b 100755 --- a/common/src/common/block/BlockContainer.java +++ b/common/src/common/block/BlockContainer.java @@ -6,7 +6,7 @@ import common.util.BlockPos; import common.util.Facing; import common.world.State; import common.world.World; -import common.world.WorldServer; +import common.world.AWorldServer; public abstract class BlockContainer extends Block implements ITileEntityProvider { @@ -34,7 +34,7 @@ public abstract class BlockContainer extends Block implements ITileEntityProvide return -1; } - public void onBlockRemoved(WorldServer worldIn, BlockPos pos, State state) + public void onBlockRemoved(AWorldServer worldIn, BlockPos pos, State state) { super.onBlockRemoved(worldIn, pos, state); worldIn.removeTileEntity(pos); diff --git a/common/src/common/block/BlockCore.java b/common/src/common/block/BlockCore.java index 68bf08a..d23bada 100755 --- a/common/src/common/block/BlockCore.java +++ b/common/src/common/block/BlockCore.java @@ -5,7 +5,7 @@ import common.item.CheatTab; import common.material.Material; import common.util.BlockPos; import common.world.State; -import common.world.WorldServer; +import common.world.AWorldServer; public class BlockCore extends Block { public BlockCore() { @@ -13,13 +13,13 @@ public class BlockCore extends Block { this.setTab(CheatTab.tabTech); } - public void onBlockRemoved(WorldServer world, BlockPos pos, State state) + public void onBlockRemoved(AWorldServer world, BlockPos pos, State state) { if(Config.loaders) world.removeLoader(pos); } - public void onBlockAdded(WorldServer world, BlockPos pos, State state) + public void onBlockAdded(AWorldServer world, BlockPos pos, State state) { if(Config.loaders) world.addLoader(pos); diff --git a/common/src/common/block/BlockCrops.java b/common/src/common/block/BlockCrops.java index a67fb61..fee8af4 100755 --- a/common/src/common/block/BlockCrops.java +++ b/common/src/common/block/BlockCrops.java @@ -14,7 +14,7 @@ import common.rng.Random; import common.util.BlockPos; import common.world.State; import common.world.World; -import common.world.WorldServer; +import common.world.AWorldServer; public class BlockCrops extends BlockBush implements IGrowable { @@ -40,7 +40,7 @@ public class BlockCrops extends BlockBush implements IGrowable return ground == Blocks.farmland; } - public void updateTick(WorldServer worldIn, BlockPos pos, State state, Random rand) + public void updateTick(AWorldServer worldIn, BlockPos pos, State state, Random rand) { super.updateTick(worldIn, pos, state, rand); @@ -194,7 +194,7 @@ public class BlockCrops extends BlockBush implements IGrowable return true; } - public void grow(WorldServer worldIn, Random rand, BlockPos pos, State state) + public void grow(AWorldServer worldIn, Random rand, BlockPos pos, State state) { this.grow(worldIn, pos, state); } diff --git a/common/src/common/block/BlockDaylightDetector.java b/common/src/common/block/BlockDaylightDetector.java index 9e3110a..f213c1f 100755 --- a/common/src/common/block/BlockDaylightDetector.java +++ b/common/src/common/block/BlockDaylightDetector.java @@ -24,7 +24,7 @@ import common.world.IWorldAccess; import common.world.LightType; import common.world.State; import common.world.World; -import common.world.WorldServer; +import common.world.AWorldServer; public class BlockDaylightDetector extends BlockContainer { @@ -53,7 +53,7 @@ public class BlockDaylightDetector extends BlockContainer return ((Integer)state.getValue(POWER)).intValue(); } - public void updatePower(WorldServer worldIn, BlockPos pos) + public void updatePower(AWorldServer worldIn, BlockPos pos) { if (!worldIn.dimension.hasNoLight()) { @@ -90,12 +90,12 @@ public class BlockDaylightDetector extends BlockContainer if (this.inverted) { worldIn.setState(pos, Blocks.daylight_detector.getState().withProperty(POWER, state.getValue(POWER)), 4); - Blocks.daylight_detector.updatePower((WorldServer)worldIn, pos); + Blocks.daylight_detector.updatePower((AWorldServer)worldIn, pos); } else { worldIn.setState(pos, Blocks.daylight_detector_inverted.getState().withProperty(POWER, state.getValue(POWER)), 4); - Blocks.daylight_detector_inverted.updatePower((WorldServer)worldIn, pos); + Blocks.daylight_detector_inverted.updatePower((AWorldServer)worldIn, pos); } return true; diff --git a/common/src/common/block/BlockDispenser.java b/common/src/common/block/BlockDispenser.java index 6f0fd6c..98595fe 100755 --- a/common/src/common/block/BlockDispenser.java +++ b/common/src/common/block/BlockDispenser.java @@ -28,7 +28,7 @@ import common.util.BlockPos; import common.util.Facing; import common.world.State; import common.world.World; -import common.world.WorldServer; +import common.world.AWorldServer; public class BlockDispenser extends BlockContainer { @@ -52,7 +52,7 @@ public class BlockDispenser extends BlockContainer return 4; } - public void onBlockAdded(WorldServer worldIn, BlockPos pos, State state) + public void onBlockAdded(AWorldServer worldIn, BlockPos pos, State state) { super.onBlockAdded(worldIn, pos, state); this.setDefaultDirection(worldIn, pos, state); @@ -172,7 +172,7 @@ public class BlockDispenser extends BlockContainer } } - public void updateTick(WorldServer worldIn, BlockPos pos, State state, Random rand) + public void updateTick(AWorldServer worldIn, BlockPos pos, State state, Random rand) { // if (!worldIn.client) // { @@ -215,7 +215,7 @@ public class BlockDispenser extends BlockContainer } } - public void onBlockRemoved(WorldServer worldIn, BlockPos pos, State state) + public void onBlockRemoved(AWorldServer worldIn, BlockPos pos, State state) { TileEntity tileentity = worldIn.getTileEntity(pos); diff --git a/common/src/common/block/BlockDoublePlant.java b/common/src/common/block/BlockDoublePlant.java index 3164ea6..2e835f5 100755 --- a/common/src/common/block/BlockDoublePlant.java +++ b/common/src/common/block/BlockDoublePlant.java @@ -27,7 +27,7 @@ import common.util.Facing.Axis; import common.world.IWorldAccess; import common.world.State; import common.world.World; -import common.world.WorldServer; +import common.world.AWorldServer; public class BlockDoublePlant extends BlockBush implements IGrowable { @@ -45,7 +45,7 @@ public class BlockDoublePlant extends BlockBush implements IGrowable // this.setTickRandomly(); } - public void updateTick(WorldServer worldIn, BlockPos pos, State state, Random rand) + public void updateTick(AWorldServer worldIn, BlockPos pos, State state, Random rand) { if(Config.plantDry && worldIn.getTemperatureC(pos) >= 50.0f) { @@ -295,7 +295,7 @@ public class BlockDoublePlant extends BlockBush implements IGrowable return true; } - public void grow(WorldServer worldIn, Random rand, BlockPos pos, State state) + public void grow(AWorldServer worldIn, Random rand, BlockPos pos, State state) { spawnAsEntity(worldIn, pos, new ItemStack(this, 1, this.getVariant(worldIn, pos).getMeta())); } diff --git a/common/src/common/block/BlockDragonEgg.java b/common/src/common/block/BlockDragonEgg.java index 15dc5e2..2d90ee8 100755 --- a/common/src/common/block/BlockDragonEgg.java +++ b/common/src/common/block/BlockDragonEgg.java @@ -13,7 +13,7 @@ import common.util.Facing; import common.world.IWorldAccess; import common.world.State; import common.world.World; -import common.world.WorldServer; +import common.world.AWorldServer; public class BlockDragonEgg extends Block { @@ -82,7 +82,7 @@ public class BlockDragonEgg extends Block this.setBlockBounds(0.0625F, 0.0F, 0.0625F, 0.9375F, 1.0F, 0.9375F); } - public void onBlockAdded(WorldServer worldIn, BlockPos pos, State state) + public void onBlockAdded(AWorldServer worldIn, BlockPos pos, State state) { worldIn.scheduleUpdate(pos, this, this.tickRate(worldIn, pos)); } @@ -95,7 +95,7 @@ public class BlockDragonEgg extends Block worldIn.scheduleUpdate(pos, this, this.tickRate(worldIn, pos)); } - public void updateTick(WorldServer worldIn, BlockPos pos, State state, Random rand) + public void updateTick(AWorldServer worldIn, BlockPos pos, State state, Random rand) { if(Config.blockGravity) this.checkFall(worldIn, pos); diff --git a/common/src/common/block/BlockDynamicLiquid.java b/common/src/common/block/BlockDynamicLiquid.java index 48534b4..e9a1eda 100755 --- a/common/src/common/block/BlockDynamicLiquid.java +++ b/common/src/common/block/BlockDynamicLiquid.java @@ -11,7 +11,7 @@ import common.util.BlockPos; import common.util.Facing; import common.world.State; import common.world.World; -import common.world.WorldServer; +import common.world.AWorldServer; public class BlockDynamicLiquid extends BlockLiquid { @@ -29,7 +29,7 @@ public class BlockDynamicLiquid extends BlockLiquid worldIn.setState(pos, getStaticBlock(this).getState().withProperty(LEVEL, currentState.getValue(LEVEL)), 2); } - public void updateTick(WorldServer worldIn, BlockPos pos, State state, Random rand) + public void updateTick(AWorldServer worldIn, BlockPos pos, State state, Random rand) { if(!Config.liquidPhysics) return; @@ -293,7 +293,7 @@ public class BlockDynamicLiquid extends BlockLiquid return material != this.material && material != Material.lava && !this.isBlocked(worldIn, pos, state); } - public void onBlockAdded(WorldServer worldIn, BlockPos pos, State state) + public void onBlockAdded(AWorldServer worldIn, BlockPos pos, State state) { if (!this.checkForMixing(worldIn, pos, state)) { diff --git a/common/src/common/block/BlockEnchantmentTable.java b/common/src/common/block/BlockEnchantmentTable.java index 4dfc2d3..c27dbab 100755 --- a/common/src/common/block/BlockEnchantmentTable.java +++ b/common/src/common/block/BlockEnchantmentTable.java @@ -14,9 +14,9 @@ import common.tileentity.TileEntity; import common.tileentity.TileEntityEnchantmentTable; import common.util.BlockPos; import common.util.Facing; +import common.world.AWorldClient; import common.world.State; import common.world.World; -import common.world.WorldClient; public class BlockEnchantmentTable extends BlockContainer { @@ -43,7 +43,7 @@ public class BlockEnchantmentTable extends BlockContainer return false; } - public void randomDisplayTick(WorldClient worldIn, BlockPos pos, State state, Random rand) + public void randomDisplayTick(AWorldClient worldIn, BlockPos pos, State state, Random rand) { super.randomDisplayTick(worldIn, pos, state, rand); diff --git a/common/src/common/block/BlockFalling.java b/common/src/common/block/BlockFalling.java index 6ce696b..e483126 100755 --- a/common/src/common/block/BlockFalling.java +++ b/common/src/common/block/BlockFalling.java @@ -9,7 +9,7 @@ import common.rng.Random; import common.util.BlockPos; import common.world.State; import common.world.World; -import common.world.WorldServer; +import common.world.AWorldServer; public class BlockFalling extends Block { @@ -26,7 +26,7 @@ public class BlockFalling extends Block super(materialIn); } - public void onBlockAdded(WorldServer worldIn, BlockPos pos, State state) + public void onBlockAdded(AWorldServer worldIn, BlockPos pos, State state) { worldIn.scheduleUpdate(pos, this, this.tickRate(worldIn, pos)); } @@ -39,7 +39,7 @@ public class BlockFalling extends Block worldIn.scheduleUpdate(pos, this, this.tickRate(worldIn, pos)); } - public void updateTick(WorldServer worldIn, BlockPos pos, State state, Random rand) + public void updateTick(AWorldServer worldIn, BlockPos pos, State state, Random rand) { if(/* !worldIn.client && */ Config.blockGravity) this.checkFallable(worldIn, pos); diff --git a/common/src/common/block/BlockFarmland.java b/common/src/common/block/BlockFarmland.java index 66cf24a..7367cf4 100755 --- a/common/src/common/block/BlockFarmland.java +++ b/common/src/common/block/BlockFarmland.java @@ -18,7 +18,7 @@ import common.util.Facing; import common.world.IWorldAccess; import common.world.State; import common.world.World; -import common.world.WorldServer; +import common.world.AWorldServer; public class BlockFarmland extends Block { @@ -51,7 +51,7 @@ public class BlockFarmland extends Block return false; } - public void updateTick(WorldServer worldIn, BlockPos pos, State state, Random rand) + public void updateTick(AWorldServer worldIn, BlockPos pos, State state, Random rand) { int i = ((Integer)state.getValue(MOISTURE)).intValue(); diff --git a/common/src/common/block/BlockFire.java b/common/src/common/block/BlockFire.java index b2afa60..e0bc2f7 100755 --- a/common/src/common/block/BlockFire.java +++ b/common/src/common/block/BlockFire.java @@ -21,10 +21,10 @@ import common.util.BoundingBox; import common.util.Facing; import common.world.IBlockAccess; import common.world.IWorldAccess; +import common.world.AWorldClient; import common.world.State; import common.world.World; -import common.world.WorldClient; -import common.world.WorldServer; +import common.world.AWorldServer; public class BlockFire extends Block { @@ -115,7 +115,7 @@ public class BlockFire extends Block return 30; } - public void updateTick(WorldServer worldIn, BlockPos pos, State state, Random rand) + public void updateTick(AWorldServer worldIn, BlockPos pos, State state, Random rand) { if (Config.fire) { @@ -350,7 +350,7 @@ public class BlockFire extends Block } } - public void onBlockAdded(WorldServer worldIn, BlockPos pos, State state) + public void onBlockAdded(AWorldServer worldIn, BlockPos pos, State state) { if ( // (worldIn.dimension.getDimensionId() < -1 || worldIn.dimension.getDimensionId() > 0) || !Blocks.portal.tryIgnitePortal(worldIn, pos, worldIn.rand.zrange(8))) @@ -366,7 +366,7 @@ public class BlockFire extends Block } } - public void randomDisplayTick(WorldClient worldIn, BlockPos pos, State state, Random rand) + public void randomDisplayTick(AWorldClient worldIn, BlockPos pos, State state, Random rand) { if (rand.chance(24)) { diff --git a/common/src/common/block/BlockFloorPortal.java b/common/src/common/block/BlockFloorPortal.java index 18b87df..a365a47 100755 --- a/common/src/common/block/BlockFloorPortal.java +++ b/common/src/common/block/BlockFloorPortal.java @@ -16,9 +16,9 @@ import common.util.BlockPos; import common.util.BoundingBox; import common.util.Facing; import common.world.IWorldAccess; +import common.world.AWorldClient; import common.world.State; import common.world.World; -import common.world.WorldClient; public class BlockFloorPortal extends Block { @@ -90,7 +90,7 @@ public class BlockFloorPortal extends Block entityIn.setFlatPortal(); } - public void randomDisplayTick(WorldClient worldIn, BlockPos pos, State state, Random rand) + public void randomDisplayTick(AWorldClient worldIn, BlockPos pos, State state, Random rand) { double d0 = (double)((float)pos.getX() + rand.floatv()); double d1 = (double)((float)pos.getY() + 0.8F); diff --git a/common/src/common/block/BlockFlower.java b/common/src/common/block/BlockFlower.java index dcdebbb..2b2091f 100755 --- a/common/src/common/block/BlockFlower.java +++ b/common/src/common/block/BlockFlower.java @@ -19,7 +19,7 @@ import common.rng.Random; import common.util.BlockPos; import common.util.Identifyable; import common.world.State; -import common.world.WorldServer; +import common.world.AWorldServer; public abstract class BlockFlower extends BlockBush { @@ -31,7 +31,7 @@ public abstract class BlockFlower extends BlockBush // this.setTickRandomly(); } - public void updateTick(WorldServer worldIn, BlockPos pos, State state, Random rand) + public void updateTick(AWorldServer worldIn, BlockPos pos, State state, Random rand) { if(Config.flowerDry && worldIn.getTemperatureC(pos) >= 50.0f) { diff --git a/common/src/common/block/BlockFlowerPot.java b/common/src/common/block/BlockFlowerPot.java index da6046a..d25970a 100755 --- a/common/src/common/block/BlockFlowerPot.java +++ b/common/src/common/block/BlockFlowerPot.java @@ -18,7 +18,7 @@ import common.util.BlockPos; import common.util.Facing; import common.world.State; import common.world.World; -import common.world.WorldServer; +import common.world.AWorldServer; public class BlockFlowerPot extends Block // Container { @@ -242,7 +242,7 @@ public class BlockFlowerPot extends Block // Container } } - public void onBlockRemoved(WorldServer worldIn, BlockPos pos, State state) + public void onBlockRemoved(AWorldServer worldIn, BlockPos pos, State state) { int type = state.getValue(CONTENTS); if(type > 0) diff --git a/common/src/common/block/BlockFurnace.java b/common/src/common/block/BlockFurnace.java index 8d4572d..73731a1 100755 --- a/common/src/common/block/BlockFurnace.java +++ b/common/src/common/block/BlockFurnace.java @@ -20,10 +20,10 @@ import common.tileentity.TileEntity; import common.tileentity.TileEntityFurnace; import common.util.BlockPos; import common.util.Facing; +import common.world.AWorldClient; import common.world.State; import common.world.World; -import common.world.WorldClient; -import common.world.WorldServer; +import common.world.AWorldServer; public class BlockFurnace extends BlockContainer { @@ -46,7 +46,7 @@ public class BlockFurnace extends BlockContainer return ItemRegistry.getItemFromBlock(Blocks.furnace); } - public void onBlockAdded(WorldServer worldIn, BlockPos pos, State state) + public void onBlockAdded(AWorldServer worldIn, BlockPos pos, State state) { this.setDefaultFacing(worldIn, pos, state); } @@ -83,7 +83,7 @@ public class BlockFurnace extends BlockContainer } - public void randomDisplayTick(WorldClient worldIn, BlockPos pos, State state, Random rand) + public void randomDisplayTick(AWorldClient worldIn, BlockPos pos, State state, Random rand) { if (this.isBurning) { @@ -199,7 +199,7 @@ public class BlockFurnace extends BlockContainer } } - public void onBlockRemoved(WorldServer worldIn, BlockPos pos, State state) + public void onBlockRemoved(AWorldServer worldIn, BlockPos pos, State state) { if (!keepInventory) { diff --git a/common/src/common/block/BlockGrass.java b/common/src/common/block/BlockGrass.java index dbf04d5..440a2b0 100755 --- a/common/src/common/block/BlockGrass.java +++ b/common/src/common/block/BlockGrass.java @@ -16,7 +16,7 @@ import common.util.BlockPos; import common.world.IWorldAccess; import common.world.State; import common.world.World; -import common.world.WorldServer; +import common.world.AWorldServer; public class BlockGrass extends Block implements IGrowable { @@ -56,7 +56,7 @@ public class BlockGrass extends Block implements IGrowable return Colorizer.getGrassColor(worldIn, pos); } - public void updateTick(WorldServer worldIn, BlockPos pos, State state, Random rand) + public void updateTick(AWorldServer worldIn, BlockPos pos, State state, Random rand) { // if (!worldIn.client) // { @@ -111,7 +111,7 @@ public class BlockGrass extends Block implements IGrowable return true; } - public void grow(WorldServer worldIn, Random rand, BlockPos pos, State state) + public void grow(AWorldServer worldIn, Random rand, BlockPos pos, State state) { BlockPos blockpos = pos.up(); diff --git a/common/src/common/block/BlockHopper.java b/common/src/common/block/BlockHopper.java index 70438d2..88832e8 100755 --- a/common/src/common/block/BlockHopper.java +++ b/common/src/common/block/BlockHopper.java @@ -26,7 +26,7 @@ import common.util.Facing; import common.world.IWorldAccess; import common.world.State; import common.world.World; -import common.world.WorldServer; +import common.world.AWorldServer; public class BlockHopper extends BlockContainer { @@ -165,7 +165,7 @@ public class BlockHopper extends BlockContainer } } - public void onBlockAdded(WorldServer worldIn, BlockPos pos, State state) + public void onBlockAdded(AWorldServer worldIn, BlockPos pos, State state) { this.updateState(worldIn, pos, state); } @@ -208,7 +208,7 @@ public class BlockHopper extends BlockContainer } } - public void onBlockRemoved(WorldServer worldIn, BlockPos pos, State state) + public void onBlockRemoved(AWorldServer worldIn, BlockPos pos, State state) { TileEntity tileentity = worldIn.getTileEntity(pos); diff --git a/common/src/common/block/BlockIce.java b/common/src/common/block/BlockIce.java index fae0c6c..a1e5981 100755 --- a/common/src/common/block/BlockIce.java +++ b/common/src/common/block/BlockIce.java @@ -14,7 +14,7 @@ import common.util.BlockPos; import common.world.LightType; import common.world.State; import common.world.World; -import common.world.WorldServer; +import common.world.AWorldServer; public class BlockIce extends BlockBreakable { @@ -71,7 +71,7 @@ public class BlockIce extends BlockBreakable return 0; } - public void updateTick(WorldServer worldIn, BlockPos pos, State state, Random rand) + public void updateTick(AWorldServer worldIn, BlockPos pos, State state, Random rand) { if (Config.iceMelt && ((worldIn.getLightFor(LightType.BLOCK, pos) > 11 - this.getLightOpacity()) || !worldIn.canFreezeAt(pos))) { diff --git a/common/src/common/block/BlockLeaves.java b/common/src/common/block/BlockLeaves.java index bfe3d39..8c2014a 100755 --- a/common/src/common/block/BlockLeaves.java +++ b/common/src/common/block/BlockLeaves.java @@ -24,10 +24,10 @@ import common.rng.Random; import common.tileentity.TileEntity; import common.util.BlockPos; import common.world.IWorldAccess; +import common.world.AWorldClient; import common.world.State; import common.world.World; -import common.world.WorldClient; -import common.world.WorldServer; +import common.world.AWorldServer; public class BlockLeaves extends BlockLeavesBase { @@ -67,7 +67,7 @@ public class BlockLeaves extends BlockLeavesBase // return BiomeColorHelper.getFoliageColorAtPos(worldIn, pos); // } - public void onBlockRemoved(WorldServer worldIn, BlockPos pos, State state) + public void onBlockRemoved(AWorldServer worldIn, BlockPos pos, State state) { int i = 1; int j = i + 1; @@ -96,7 +96,7 @@ public class BlockLeaves extends BlockLeavesBase } } - public void updateTick(WorldServer worldIn, BlockPos pos, State state, Random rand) + public void updateTick(AWorldServer worldIn, BlockPos pos, State state, Random rand) { if(Config.seasonLeaves && state.getValue(TYPE) != worldIn.getLeavesGen(pos)) { worldIn.setState(pos, state.withProperty(TYPE, worldIn.getLeavesGen(pos)), 2); @@ -213,7 +213,7 @@ public class BlockLeaves extends BlockLeavesBase // } } - public void randomDisplayTick(WorldClient worldIn, BlockPos pos, State state, Random rand) + public void randomDisplayTick(AWorldClient worldIn, BlockPos pos, State state, Random rand) { if (worldIn.isRainingAt(pos.up(), true) && !worldIn.isBlockSolid(pos.down()) && rand.chance(15)) // == 1 { diff --git a/common/src/common/block/BlockLever.java b/common/src/common/block/BlockLever.java index a48cb6d..3e33154 100755 --- a/common/src/common/block/BlockLever.java +++ b/common/src/common/block/BlockLever.java @@ -18,7 +18,7 @@ import common.util.Identifyable; import common.world.IWorldAccess; import common.world.State; import common.world.World; -import common.world.WorldServer; +import common.world.AWorldServer; public class BlockLever extends Block { @@ -215,7 +215,7 @@ public class BlockLever extends Block } } - public void onBlockRemoved(WorldServer worldIn, BlockPos pos, State state) + public void onBlockRemoved(AWorldServer worldIn, BlockPos pos, State state) { if (((Boolean)state.getValue(POWERED)).booleanValue()) { diff --git a/common/src/common/block/BlockLiquid.java b/common/src/common/block/BlockLiquid.java index ef20f41..9f036fd 100755 --- a/common/src/common/block/BlockLiquid.java +++ b/common/src/common/block/BlockLiquid.java @@ -20,10 +20,10 @@ import common.util.Facing; import common.util.Vec3; import common.world.IBlockAccess; import common.world.IWorldAccess; +import common.world.AWorldClient; import common.world.State; import common.world.World; -import common.world.WorldClient; -import common.world.WorldServer; +import common.world.AWorldServer; public abstract class BlockLiquid extends Block { @@ -234,7 +234,7 @@ public abstract class BlockLiquid extends Block return this.opaque ? BlockLayer.SOLID : BlockLayer.TRANSLUCENT; } - public void randomDisplayTick(WorldClient worldIn, BlockPos pos, State state, Random rand) + public void randomDisplayTick(AWorldClient worldIn, BlockPos pos, State state, Random rand) { double d0 = (double)pos.getX(); double d1 = (double)pos.getY(); @@ -302,7 +302,7 @@ public abstract class BlockLiquid extends Block return vec3.xCoord == 0.0D && vec3.zCoord == 0.0D ? -1000.0D : ExtMath.atan2(vec3.zCoord, vec3.xCoord) - (Math.PI / 2D); } - public void onBlockAdded(WorldServer worldIn, BlockPos pos, State state) + public void onBlockAdded(AWorldServer worldIn, BlockPos pos, State state) { this.checkForMixing(worldIn, pos, state); } diff --git a/common/src/common/block/BlockLog.java b/common/src/common/block/BlockLog.java index 234583e..1646cf3 100755 --- a/common/src/common/block/BlockLog.java +++ b/common/src/common/block/BlockLog.java @@ -13,7 +13,7 @@ import common.util.Facing; import common.util.Identifyable; import common.world.State; import common.world.World; -import common.world.WorldServer; +import common.world.AWorldServer; public class BlockLog extends BlockRotatedPillar { @@ -28,7 +28,7 @@ public class BlockLog extends BlockRotatedPillar this.setStepSound(SoundType.WOOD); } - public void onBlockRemoved(WorldServer worldIn, BlockPos pos, State state) + public void onBlockRemoved(AWorldServer worldIn, BlockPos pos, State state) { int i = 4; int j = i + 1; diff --git a/common/src/common/block/BlockMachine.java b/common/src/common/block/BlockMachine.java index d65db95..782ab21 100755 --- a/common/src/common/block/BlockMachine.java +++ b/common/src/common/block/BlockMachine.java @@ -13,7 +13,7 @@ import common.util.BlockPos; import common.util.Facing; import common.world.State; import common.world.World; -import common.world.WorldServer; +import common.world.AWorldServer; public abstract class BlockMachine extends BlockDirectional implements ITileEntityProvider { public BlockMachine() { @@ -25,7 +25,7 @@ public abstract class BlockMachine extends BlockDirectional implements ITileEnti public abstract TileEntity createNewTileEntity(World worldIn, int meta); - public void onBlockAdded(WorldServer worldIn, BlockPos pos, State state) { + public void onBlockAdded(AWorldServer worldIn, BlockPos pos, State state) { this.updateState(worldIn, pos, state); } @@ -54,7 +54,7 @@ public abstract class BlockMachine extends BlockDirectional implements ITileEnti // } } - public void onBlockRemoved(WorldServer worldIn, BlockPos pos, State state) { + public void onBlockRemoved(AWorldServer worldIn, BlockPos pos, State state) { TileEntity tileentity = worldIn.getTileEntity(pos); if(tileentity instanceof TileEntityMachine) { InventoryHelper.dropInventoryItems(worldIn, pos, (TileEntityMachine)tileentity); diff --git a/common/src/common/block/BlockMushroom.java b/common/src/common/block/BlockMushroom.java index 3e45fab..0f11d22 100755 --- a/common/src/common/block/BlockMushroom.java +++ b/common/src/common/block/BlockMushroom.java @@ -8,7 +8,7 @@ import common.rng.Random; import common.util.BlockPos; import common.world.State; import common.world.World; -import common.world.WorldServer; +import common.world.AWorldServer; import common.worldgen.FeatureGenerator; import common.worldgen.foliage.WorldGenBigMushroom; @@ -21,7 +21,7 @@ public class BlockMushroom extends BlockBush implements IGrowable this.setTickRandomly(); } - public void updateTick(WorldServer worldIn, BlockPos pos, State state, Random rand) + public void updateTick(AWorldServer worldIn, BlockPos pos, State state, Random rand) { if (Config.shroomGrowth > 0 && rand.chance(Config.shroomGrowth)) { @@ -86,7 +86,7 @@ public class BlockMushroom extends BlockBush implements IGrowable } } - public boolean generateBigMushroom(WorldServer worldIn, BlockPos pos, State state, Random rand) + public boolean generateBigMushroom(AWorldServer worldIn, BlockPos pos, State state, Random rand) { worldIn.setBlockToAir(pos); FeatureGenerator worldgenerator = null; @@ -124,7 +124,7 @@ public class BlockMushroom extends BlockBush implements IGrowable return (double)rand.floatv() < 0.4D; } - public void grow(WorldServer worldIn, Random rand, BlockPos pos, State state) + public void grow(AWorldServer worldIn, Random rand, BlockPos pos, State state) { this.generateBigMushroom(worldIn, pos, state, rand); } diff --git a/common/src/common/block/BlockMycelium.java b/common/src/common/block/BlockMycelium.java index a883235..977c979 100755 --- a/common/src/common/block/BlockMycelium.java +++ b/common/src/common/block/BlockMycelium.java @@ -13,9 +13,9 @@ import common.properties.PropertyBool; import common.rng.Random; import common.util.BlockPos; import common.world.IWorldAccess; +import common.world.AWorldClient; import common.world.State; -import common.world.WorldClient; -import common.world.WorldServer; +import common.world.AWorldServer; public class BlockMycelium extends Block { @@ -39,7 +39,7 @@ public class BlockMycelium extends Block return state.withProperty(SNOWY, Boolean.valueOf(block == Blocks.snow || block == Blocks.snow_layer)); } - public void updateTick(WorldServer worldIn, BlockPos pos, State state, Random rand) + public void updateTick(AWorldServer worldIn, BlockPos pos, State state, Random rand) { // if (!worldIn.client) // { @@ -68,7 +68,7 @@ public class BlockMycelium extends Block // } } - public void randomDisplayTick(WorldClient worldIn, BlockPos pos, State state, Random rand) + public void randomDisplayTick(AWorldClient worldIn, BlockPos pos, State state, Random rand) { super.randomDisplayTick(worldIn, pos, state, rand); diff --git a/common/src/common/block/BlockNuke.java b/common/src/common/block/BlockNuke.java index 70e4c0e..7f70ced 100755 --- a/common/src/common/block/BlockNuke.java +++ b/common/src/common/block/BlockNuke.java @@ -11,7 +11,7 @@ import common.util.BlockPos; import common.world.Explosion; import common.world.State; import common.world.World; -import common.world.WorldServer; +import common.world.AWorldServer; public class BlockNuke extends Block { @@ -21,7 +21,7 @@ public class BlockNuke extends Block this.setTab(CheatTab.tabTech); } - public void onBlockAdded(WorldServer worldIn, BlockPos pos, State state) + public void onBlockAdded(AWorldServer worldIn, BlockPos pos, State state) { super.onBlockAdded(worldIn, pos, state); diff --git a/common/src/common/block/BlockPistonBase.java b/common/src/common/block/BlockPistonBase.java index 5fe919c..e09a0e3 100755 --- a/common/src/common/block/BlockPistonBase.java +++ b/common/src/common/block/BlockPistonBase.java @@ -26,7 +26,7 @@ import common.util.Facing; import common.world.IWorldAccess; import common.world.State; import common.world.World; -import common.world.WorldServer; +import common.world.AWorldServer; public class BlockPistonBase extends Block { @@ -291,7 +291,7 @@ public class BlockPistonBase extends Block } } - public void onBlockAdded(WorldServer worldIn, BlockPos pos, State state) + public void onBlockAdded(AWorldServer worldIn, BlockPos pos, State state) { if (!worldIn.client && worldIn.getTileEntity(pos) == null) { diff --git a/common/src/common/block/BlockPistonHead.java b/common/src/common/block/BlockPistonHead.java index 07c783e..fff8415 100755 --- a/common/src/common/block/BlockPistonHead.java +++ b/common/src/common/block/BlockPistonHead.java @@ -22,7 +22,7 @@ import common.util.Identifyable; import common.world.IWorldAccess; import common.world.State; import common.world.World; -import common.world.WorldServer; +import common.world.AWorldServer; public class BlockPistonHead extends Block { @@ -59,7 +59,7 @@ public class BlockPistonHead extends Block // super.onBlockHarvested(worldIn, pos, state, player); // } - public void onBlockRemoved(WorldServer worldIn, BlockPos pos, State state) + public void onBlockRemoved(AWorldServer worldIn, BlockPos pos, State state) { super.onBlockRemoved(worldIn, pos, state); Facing enumfacing = ((Facing)state.getValue(FACING)).getOpposite(); diff --git a/common/src/common/block/BlockPistonMoving.java b/common/src/common/block/BlockPistonMoving.java index 50fddc2..8047a3c 100755 --- a/common/src/common/block/BlockPistonMoving.java +++ b/common/src/common/block/BlockPistonMoving.java @@ -18,7 +18,7 @@ import common.util.Vec3; import common.world.IWorldAccess; import common.world.State; import common.world.World; -import common.world.WorldServer; +import common.world.AWorldServer; public class BlockPistonMoving extends BlockContainer { @@ -45,7 +45,7 @@ public class BlockPistonMoving extends BlockContainer return new TileEntityPiston(state, facing, extending, renderHead); } - public void onBlockRemoved(WorldServer worldIn, BlockPos pos, State state) + public void onBlockRemoved(AWorldServer worldIn, BlockPos pos, State state) { TileEntity tileentity = worldIn.getTileEntity(pos); diff --git a/common/src/common/block/BlockPortal.java b/common/src/common/block/BlockPortal.java index 14112ba..190f899 100755 --- a/common/src/common/block/BlockPortal.java +++ b/common/src/common/block/BlockPortal.java @@ -19,9 +19,9 @@ import common.util.BoundingBox; import common.util.Facing; import common.util.Facing.Axis; import common.world.IWorldAccess; +import common.world.AWorldClient; import common.world.State; import common.world.World; -import common.world.WorldClient; public class BlockPortal extends BlockBreakable { @@ -37,7 +37,7 @@ public class BlockPortal extends BlockBreakable // this.setTickRandomly(); } -// public void updateTick(WorldServer worldIn, BlockPos pos, IBlockState state, Random rand) +// public void updateTick(IWorldServer worldIn, BlockPos pos, IBlockState state, Random rand) // { //// super.updateTick(worldIn, pos, state, rand); // @@ -208,7 +208,7 @@ public class BlockPortal extends BlockBreakable } } - public void randomDisplayTick(WorldClient worldIn, BlockPos pos, State state, Random rand) + public void randomDisplayTick(AWorldClient worldIn, BlockPos pos, State state, Random rand) { // if (rand.chance(100)) // { diff --git a/common/src/common/block/BlockPumpkin.java b/common/src/common/block/BlockPumpkin.java index caf602a..53866ad 100755 --- a/common/src/common/block/BlockPumpkin.java +++ b/common/src/common/block/BlockPumpkin.java @@ -34,7 +34,7 @@ public class BlockPumpkin extends BlockDirectional this.setTab(CheatTab.tabPlants); } -// public void onBlockAdded(WorldServer worldIn, BlockPos pos, IBlockState state) +// public void onBlockAdded(IWorldServer worldIn, BlockPos pos, IBlockState state) // { // super.onBlockAdded(worldIn, pos, state); // this.trySpawnGolem(worldIn, pos); diff --git a/common/src/common/block/BlockRailBase.java b/common/src/common/block/BlockRailBase.java index ebcab36..01c0256 100755 --- a/common/src/common/block/BlockRailBase.java +++ b/common/src/common/block/BlockRailBase.java @@ -20,7 +20,7 @@ import common.util.Vec3; import common.world.IWorldAccess; import common.world.State; import common.world.World; -import common.world.WorldServer; +import common.world.AWorldServer; public abstract class BlockRailBase extends Block { @@ -92,7 +92,7 @@ public abstract class BlockRailBase extends Block return worldIn.isBlockSolid(pos.down()); } - public void onBlockAdded(WorldServer worldIn, BlockPos pos, State state) + public void onBlockAdded(AWorldServer worldIn, BlockPos pos, State state) { if (!worldIn.client) { @@ -168,7 +168,7 @@ public abstract class BlockRailBase extends Block return BlockLayer.CUTOUT; } - public void onBlockRemoved(WorldServer worldIn, BlockPos pos, State state) + public void onBlockRemoved(AWorldServer worldIn, BlockPos pos, State state) { super.onBlockRemoved(worldIn, pos, state); diff --git a/common/src/common/block/BlockRailDetector.java b/common/src/common/block/BlockRailDetector.java index 7579307..1c2fbd6 100755 --- a/common/src/common/block/BlockRailDetector.java +++ b/common/src/common/block/BlockRailDetector.java @@ -19,7 +19,7 @@ import common.util.Facing; import common.world.IWorldAccess; import common.world.State; import common.world.World; -import common.world.WorldServer; +import common.world.AWorldServer; public class BlockRailDetector extends BlockRailBase { @@ -72,11 +72,11 @@ public class BlockRailDetector extends BlockRailBase /** * Called randomly when setTickRandomly is set to true (used by e.g. crops to grow, etc.) */ - public void randomTick(WorldServer worldIn, BlockPos pos, State state, Random random) + public void randomTick(AWorldServer worldIn, BlockPos pos, State state, Random random) { } - public void updateTick(WorldServer worldIn, BlockPos pos, State state, Random rand) + public void updateTick(AWorldServer worldIn, BlockPos pos, State state, Random rand) { if (/* !worldIn.client && */ ((Boolean)state.getValue(POWERED)).booleanValue()) { @@ -129,7 +129,7 @@ public class BlockRailDetector extends BlockRailBase worldIn.updateComparatorOutputLevel(pos, this); } - public void onBlockAdded(WorldServer worldIn, BlockPos pos, State state) + public void onBlockAdded(AWorldServer worldIn, BlockPos pos, State state) { super.onBlockAdded(worldIn, pos, state); this.updatePoweredState(worldIn, pos, state); diff --git a/common/src/common/block/BlockRedstoneComparator.java b/common/src/common/block/BlockRedstoneComparator.java index 9f6b9d2..b44b3dc 100755 --- a/common/src/common/block/BlockRedstoneComparator.java +++ b/common/src/common/block/BlockRedstoneComparator.java @@ -21,7 +21,7 @@ import common.util.Identifyable; import common.world.IWorldAccess; import common.world.State; import common.world.World; -import common.world.WorldServer; +import common.world.AWorldServer; public class BlockRedstoneComparator extends BlockRedstoneDiode implements ITileEntityProvider { @@ -176,7 +176,7 @@ public class BlockRedstoneComparator extends BlockRedstoneDiode implements ITile protected void updateState(World worldIn, BlockPos pos, State state) { - if (worldIn.client || !((WorldServer)worldIn).isBlockTickPending(pos, this)) + if (worldIn.client || !((AWorldServer)worldIn).isBlockTickPending(pos, this)) { int i = this.calculateOutput(worldIn, pos, state); TileEntity tileentity = worldIn.getTileEntity(pos); @@ -187,12 +187,12 @@ public class BlockRedstoneComparator extends BlockRedstoneDiode implements ITile if (this.isFacingTowardsRepeater(worldIn, pos, state)) { if(!worldIn.client) - ((WorldServer)worldIn).updateBlockTick(pos, this, 2, -1); + ((AWorldServer)worldIn).updateBlockTick(pos, this, 2, -1); } else { if(!worldIn.client) - ((WorldServer)worldIn).updateBlockTick(pos, this, 2, 0); + ((AWorldServer)worldIn).updateBlockTick(pos, this, 2, 0); } } } @@ -229,7 +229,7 @@ public class BlockRedstoneComparator extends BlockRedstoneDiode implements ITile } } - public void updateTick(WorldServer worldIn, BlockPos pos, State state, Random rand) + public void updateTick(AWorldServer worldIn, BlockPos pos, State state, Random rand) { if (this.isRepeaterPowered) { @@ -239,13 +239,13 @@ public class BlockRedstoneComparator extends BlockRedstoneDiode implements ITile this.onStateChange(worldIn, pos, state); } - public void onBlockAdded(WorldServer worldIn, BlockPos pos, State state) + public void onBlockAdded(AWorldServer worldIn, BlockPos pos, State state) { super.onBlockAdded(worldIn, pos, state); worldIn.setTileEntity(pos, this.createNewTileEntity(worldIn, 0)); } - public void onBlockRemoved(WorldServer worldIn, BlockPos pos, State state) + public void onBlockRemoved(AWorldServer worldIn, BlockPos pos, State state) { super.onBlockRemoved(worldIn, pos, state); worldIn.removeTileEntity(pos); diff --git a/common/src/common/block/BlockRedstoneDiode.java b/common/src/common/block/BlockRedstoneDiode.java index 4b0c3d3..7be2128 100755 --- a/common/src/common/block/BlockRedstoneDiode.java +++ b/common/src/common/block/BlockRedstoneDiode.java @@ -11,7 +11,7 @@ import common.util.Facing; import common.world.IWorldAccess; import common.world.State; import common.world.World; -import common.world.WorldServer; +import common.world.AWorldServer; public abstract class BlockRedstoneDiode extends BlockDirectional { @@ -43,11 +43,11 @@ public abstract class BlockRedstoneDiode extends BlockDirectional /** * Called randomly when setTickRandomly is set to true (used by e.g. crops to grow, etc.) */ - public void randomTick(WorldServer worldIn, BlockPos pos, State state, Random random) + public void randomTick(AWorldServer worldIn, BlockPos pos, State state, Random random) { } - public void updateTick(WorldServer worldIn, BlockPos pos, State state, Random rand) + public void updateTick(AWorldServer worldIn, BlockPos pos, State state, Random rand) { if (!this.isLocked(worldIn, pos, state)) { @@ -116,7 +116,7 @@ public abstract class BlockRedstoneDiode extends BlockDirectional { boolean flag = this.shouldBePowered(worldIn, pos, state); - if ((this.isRepeaterPowered && !flag || !this.isRepeaterPowered && flag) && (worldIn.client || !((WorldServer)worldIn).isBlockTickPending(pos, this))) + if ((this.isRepeaterPowered && !flag || !this.isRepeaterPowered && flag) && (worldIn.client || !((AWorldServer)worldIn).isBlockTickPending(pos, this))) { int i = -1; @@ -130,7 +130,7 @@ public abstract class BlockRedstoneDiode extends BlockDirectional } if(!worldIn.client) - ((WorldServer)worldIn).updateBlockTick(pos, this, this.getDelay(state), i); + ((AWorldServer)worldIn).updateBlockTick(pos, this, this.getDelay(state), i); } } } @@ -205,7 +205,7 @@ public abstract class BlockRedstoneDiode extends BlockDirectional } } - public void onBlockAdded(WorldServer worldIn, BlockPos pos, State state) + public void onBlockAdded(AWorldServer worldIn, BlockPos pos, State state) { this.notifyNeighbors(worldIn, pos, state); } diff --git a/common/src/common/block/BlockRedstoneLight.java b/common/src/common/block/BlockRedstoneLight.java index 017346b..579156b 100755 --- a/common/src/common/block/BlockRedstoneLight.java +++ b/common/src/common/block/BlockRedstoneLight.java @@ -9,7 +9,7 @@ import common.rng.Random; import common.util.BlockPos; import common.world.State; import common.world.World; -import common.world.WorldServer; +import common.world.AWorldServer; public class BlockRedstoneLight extends Block { @@ -26,7 +26,7 @@ public class BlockRedstoneLight extends Block } } - public void onBlockAdded(WorldServer worldIn, BlockPos pos, State state) + public void onBlockAdded(AWorldServer worldIn, BlockPos pos, State state) { if (!worldIn.client) { @@ -59,7 +59,7 @@ public class BlockRedstoneLight extends Block } } - public void updateTick(WorldServer worldIn, BlockPos pos, State state, Random rand) + public void updateTick(AWorldServer worldIn, BlockPos pos, State state, Random rand) { // if (!worldIn.client) // { diff --git a/common/src/common/block/BlockRedstoneOre.java b/common/src/common/block/BlockRedstoneOre.java index 9d7f947..13eb609 100755 --- a/common/src/common/block/BlockRedstoneOre.java +++ b/common/src/common/block/BlockRedstoneOre.java @@ -14,10 +14,10 @@ import common.model.ParticleType; import common.rng.Random; import common.util.BlockPos; import common.util.Facing; +import common.world.AWorldClient; import common.world.State; import common.world.World; -import common.world.WorldClient; -import common.world.WorldServer; +import common.world.AWorldServer; public class BlockRedstoneOre extends Block { @@ -74,7 +74,7 @@ public class BlockRedstoneOre extends Block } } - public void updateTick(WorldServer worldIn, BlockPos pos, State state, Random rand) + public void updateTick(AWorldServer worldIn, BlockPos pos, State state, Random rand) { if (this == Blocks.lit_redstone_ore) { @@ -120,7 +120,7 @@ public class BlockRedstoneOre extends Block } } - public void randomDisplayTick(WorldClient worldIn, BlockPos pos, State state, Random rand) + public void randomDisplayTick(AWorldClient worldIn, BlockPos pos, State state, Random rand) { if (this.isOn) { diff --git a/common/src/common/block/BlockRedstoneRepeater.java b/common/src/common/block/BlockRedstoneRepeater.java index 208e723..a98316f 100755 --- a/common/src/common/block/BlockRedstoneRepeater.java +++ b/common/src/common/block/BlockRedstoneRepeater.java @@ -15,10 +15,10 @@ import common.rng.Random; import common.util.BlockPos; import common.util.Facing; import common.world.IWorldAccess; +import common.world.AWorldClient; import common.world.State; import common.world.World; -import common.world.WorldClient; -import common.world.WorldServer; +import common.world.AWorldServer; public class BlockRedstoneRepeater extends BlockRedstoneDiode { @@ -105,7 +105,7 @@ public class BlockRedstoneRepeater extends BlockRedstoneDiode return isRedstoneRepeaterBlockID(blockIn); } - public void randomDisplayTick(WorldClient worldIn, BlockPos pos, State state, Random rand) + public void randomDisplayTick(AWorldClient worldIn, BlockPos pos, State state, Random rand) { if (this.isRepeaterPowered) { @@ -127,7 +127,7 @@ public class BlockRedstoneRepeater extends BlockRedstoneDiode } } - public void onBlockRemoved(WorldServer worldIn, BlockPos pos, State state) + public void onBlockRemoved(AWorldServer worldIn, BlockPos pos, State state) { super.onBlockRemoved(worldIn, pos, state); this.notifyNeighbors(worldIn, pos, state); diff --git a/common/src/common/block/BlockRedstoneTorch.java b/common/src/common/block/BlockRedstoneTorch.java index 5e6bbdc..1de1741 100755 --- a/common/src/common/block/BlockRedstoneTorch.java +++ b/common/src/common/block/BlockRedstoneTorch.java @@ -15,17 +15,17 @@ import common.rng.Random; import common.util.BlockPos; import common.util.Facing; import common.world.IWorldAccess; +import common.world.AWorldClient; import common.world.State; import common.world.World; -import common.world.WorldClient; -import common.world.WorldServer; +import common.world.AWorldServer; public class BlockRedstoneTorch extends BlockTorch { private static Map> toggles = Maps.>newHashMap(); private final boolean isOn; - private boolean isBurnedOut(WorldServer worldIn, BlockPos pos, boolean turnOff) + private boolean isBurnedOut(AWorldServer worldIn, BlockPos pos, boolean turnOff) { if (!toggles.containsKey(worldIn)) { @@ -74,7 +74,7 @@ public class BlockRedstoneTorch extends BlockTorch return 2; } - public void onBlockAdded(WorldServer worldIn, BlockPos pos, State state) + public void onBlockAdded(AWorldServer worldIn, BlockPos pos, State state) { if (this.isOn) { @@ -85,7 +85,7 @@ public class BlockRedstoneTorch extends BlockTorch } } - public void onBlockRemoved(WorldServer worldIn, BlockPos pos, State state) + public void onBlockRemoved(AWorldServer worldIn, BlockPos pos, State state) { if (this.isOn) { @@ -110,11 +110,11 @@ public class BlockRedstoneTorch extends BlockTorch /** * Called randomly when setTickRandomly is set to true (used by e.g. crops to grow, etc.) */ - public void randomTick(WorldServer worldIn, BlockPos pos, State state, Random random) + public void randomTick(AWorldServer worldIn, BlockPos pos, State state, Random random) { } - public void updateTick(WorldServer worldIn, BlockPos pos, State state, Random rand) + public void updateTick(AWorldServer worldIn, BlockPos pos, State state, Random rand) { boolean flag = this.shouldBeOff(worldIn, pos, state); List list = (List)toggles.get(worldIn); @@ -187,7 +187,7 @@ public class BlockRedstoneTorch extends BlockTorch return true; } - public void randomDisplayTick(WorldClient worldIn, BlockPos pos, State state, Random rand) + public void randomDisplayTick(AWorldClient worldIn, BlockPos pos, State state, Random rand) { if (this.isOn) { diff --git a/common/src/common/block/BlockRedstoneWire.java b/common/src/common/block/BlockRedstoneWire.java index e023983..a77e77a 100755 --- a/common/src/common/block/BlockRedstoneWire.java +++ b/common/src/common/block/BlockRedstoneWire.java @@ -26,10 +26,10 @@ import common.util.Facing; import common.util.Identifyable; import common.world.IBlockAccess; import common.world.IWorldAccess; +import common.world.AWorldClient; import common.world.State; import common.world.World; -import common.world.WorldClient; -import common.world.WorldServer; +import common.world.AWorldServer; public class BlockRedstoneWire extends Block { @@ -540,7 +540,7 @@ public class BlockRedstoneWire extends Block } } - public void onBlockAdded(WorldServer worldIn, BlockPos pos, State state) + public void onBlockAdded(AWorldServer worldIn, BlockPos pos, State state) { if (!worldIn.client) { @@ -572,7 +572,7 @@ public class BlockRedstoneWire extends Block } } - public void onBlockRemoved(WorldServer worldIn, BlockPos pos, State state) + public void onBlockRemoved(AWorldServer worldIn, BlockPos pos, State state) { super.onBlockRemoved(worldIn, pos, state); @@ -773,7 +773,7 @@ public class BlockRedstoneWire extends Block return -16777216 | i << 16 | j << 8 | k; } - public void randomDisplayTick(WorldClient worldIn, BlockPos pos, State state, Random rand) + public void randomDisplayTick(AWorldClient worldIn, BlockPos pos, State state, Random rand) { int i = ((Integer)state.getValue(POWER)).intValue(); diff --git a/common/src/common/block/BlockReed.java b/common/src/common/block/BlockReed.java index 8ac6c66..8d7b151 100755 --- a/common/src/common/block/BlockReed.java +++ b/common/src/common/block/BlockReed.java @@ -17,7 +17,7 @@ import common.util.Facing; import common.world.IWorldAccess; import common.world.State; import common.world.World; -import common.world.WorldServer; +import common.world.AWorldServer; public class BlockReed extends Block { @@ -32,7 +32,7 @@ public class BlockReed extends Block this.setTickRandomly(); } - public void updateTick(WorldServer worldIn, BlockPos pos, State state, Random rand) + public void updateTick(AWorldServer worldIn, BlockPos pos, State state, Random rand) { if(Config.reedDry && worldIn.getTemperatureC(pos) >= 50.0f) { diff --git a/common/src/common/block/BlockSapling.java b/common/src/common/block/BlockSapling.java index 3a8edb1..d612805 100755 --- a/common/src/common/block/BlockSapling.java +++ b/common/src/common/block/BlockSapling.java @@ -15,7 +15,7 @@ import common.rng.Random; import common.util.BlockPos; import common.world.State; import common.world.World; -import common.world.WorldServer; +import common.world.AWorldServer; import common.worldgen.FeatureGenerator; import common.worldgen.tree.WorldGenBaseTree; import common.worldgen.tree.WorldGenBigTree; @@ -52,7 +52,7 @@ public class BlockSapling extends BlockBush implements IGrowable // return I18n.translate(this.getUnlocalizedName() + "." + BlockPlanks.EnumType.OAK.getUnlocalizedName() + ".name"); // } - public void updateTick(WorldServer worldIn, BlockPos pos, State state, Random rand) + public void updateTick(AWorldServer worldIn, BlockPos pos, State state, Random rand) { if(Config.saplingDry && worldIn.getTemperatureC(pos) >= 50.0f) { @@ -71,7 +71,7 @@ public class BlockSapling extends BlockBush implements IGrowable // } } - public void grow(WorldServer worldIn, BlockPos pos, State state, Random rand) + public void grow(AWorldServer worldIn, BlockPos pos, State state, Random rand) { if (((Integer)state.getValue(STAGE)).intValue() == 0) { @@ -83,7 +83,7 @@ public class BlockSapling extends BlockBush implements IGrowable } } - public void generateTree(WorldServer worldIn, BlockPos pos, State state, Random rand) + public void generateTree(AWorldServer worldIn, BlockPos pos, State state, Random rand) { WoodType type = state.getBlock() instanceof BlockSapling ? ((BlockSapling)state.getBlock()).type : WoodType.OAK; State log = type == WoodType.CHERRY ? Blocks.cherry_log.getState() : // .withProperty(BlockNewLog.VARIANT, BlockPlanks.EnumType.CHERRY) : @@ -264,7 +264,7 @@ public class BlockSapling extends BlockBush implements IGrowable return (double)worldIn.rand.floatv() < 0.45D; } - public void grow(WorldServer worldIn, Random rand, BlockPos pos, State state) + public void grow(AWorldServer worldIn, Random rand, BlockPos pos, State state) { this.grow(worldIn, pos, state, rand); } diff --git a/common/src/common/block/BlockSign.java b/common/src/common/block/BlockSign.java index a440937..70691aa 100755 --- a/common/src/common/block/BlockSign.java +++ b/common/src/common/block/BlockSign.java @@ -94,7 +94,7 @@ public class BlockSign extends BlockContainer // return true; // } -// public void onBlockRemoved(WorldServer worldIn, BlockPos pos, State state) +// public void onBlockRemoved(IWorldServer worldIn, BlockPos pos, State state) // { // if(!worldIn.client) { // TileEntity tileentity = worldIn.getTileEntity(pos); diff --git a/common/src/common/block/BlockSkull.java b/common/src/common/block/BlockSkull.java index d73ccae..97d44ec 100755 --- a/common/src/common/block/BlockSkull.java +++ b/common/src/common/block/BlockSkull.java @@ -17,7 +17,7 @@ import common.util.Facing; import common.world.IWorldAccess; import common.world.State; import common.world.World; -import common.world.WorldServer; +import common.world.AWorldServer; public class BlockSkull extends BlockContainer { @@ -102,7 +102,7 @@ public class BlockSkull extends BlockContainer // super.onBlockHarvested(worldIn, pos, state, player); // } - public void onBlockRemoved(WorldServer worldIn, BlockPos pos, State state) + public void onBlockRemoved(AWorldServer worldIn, BlockPos pos, State state) { if (!worldIn.client) { diff --git a/common/src/common/block/BlockSnow.java b/common/src/common/block/BlockSnow.java index 489585c..3647804 100755 --- a/common/src/common/block/BlockSnow.java +++ b/common/src/common/block/BlockSnow.java @@ -23,7 +23,7 @@ import common.world.IWorldAccess; import common.world.LightType; import common.world.State; import common.world.World; -import common.world.WorldServer; +import common.world.AWorldServer; public class BlockSnow extends Block { @@ -135,7 +135,7 @@ public class BlockSnow extends Block return 0; } - public void updateTick(WorldServer worldIn, BlockPos pos, State state, Random rand) + public void updateTick(AWorldServer worldIn, BlockPos pos, State state, Random rand) { if (Config.snowMelt && ((worldIn.getLightFor(LightType.BLOCK, pos) > 11) || !worldIn.canFreezeAt(pos))) { diff --git a/common/src/common/block/BlockSnowBlock.java b/common/src/common/block/BlockSnowBlock.java index a85f7cb..0e4a60e 100755 --- a/common/src/common/block/BlockSnowBlock.java +++ b/common/src/common/block/BlockSnowBlock.java @@ -9,7 +9,7 @@ import common.rng.Random; import common.util.BlockPos; import common.world.LightType; import common.world.State; -import common.world.WorldServer; +import common.world.AWorldServer; public class BlockSnowBlock extends Block { @@ -36,7 +36,7 @@ public class BlockSnowBlock extends Block return 4; } - public void updateTick(WorldServer worldIn, BlockPos pos, State state, Random rand) + public void updateTick(AWorldServer worldIn, BlockPos pos, State state, Random rand) { if (Config.snowFullMelt && worldIn.getLightFor(LightType.BLOCK, pos) > 11) { diff --git a/common/src/common/block/BlockStainedGlass.java b/common/src/common/block/BlockStainedGlass.java index 47ae319..de0f6a2 100755 --- a/common/src/common/block/BlockStainedGlass.java +++ b/common/src/common/block/BlockStainedGlass.java @@ -85,7 +85,7 @@ public class BlockStainedGlass extends BlockBreakable return this.getState().withProperty(COLOR, DyeColor.byMetadata(meta)); } -// public void onBlockAdded(WorldServer worldIn, BlockPos pos, State state) +// public void onBlockAdded(IWorldServer worldIn, BlockPos pos, State state) // { // if (!worldIn.client) // { @@ -93,7 +93,7 @@ public class BlockStainedGlass extends BlockBreakable // } // } // -// public void onBlockRemoved(WorldServer worldIn, BlockPos pos, State state) +// public void onBlockRemoved(IWorldServer worldIn, BlockPos pos, State state) // { // if (!worldIn.client) // { diff --git a/common/src/common/block/BlockStainedGlassPane.java b/common/src/common/block/BlockStainedGlassPane.java index eb50a9e..254d120 100755 --- a/common/src/common/block/BlockStainedGlassPane.java +++ b/common/src/common/block/BlockStainedGlassPane.java @@ -77,7 +77,7 @@ public class BlockStainedGlassPane extends BlockPane return new IProperty[] {NORTH, EAST, WEST, SOUTH, COLOR}; } -// public void onBlockAdded(WorldServer worldIn, BlockPos pos, State state) +// public void onBlockAdded(IWorldServer worldIn, BlockPos pos, State state) // { // if (!worldIn.client) // { @@ -85,7 +85,7 @@ public class BlockStainedGlassPane extends BlockPane // } // } // -// public void onBlockRemoved(WorldServer worldIn, BlockPos pos, State state) +// public void onBlockRemoved(IWorldServer worldIn, BlockPos pos, State state) // { // if (!worldIn.client) // { diff --git a/common/src/common/block/BlockStairs.java b/common/src/common/block/BlockStairs.java index cb917cf..8c6f5d9 100755 --- a/common/src/common/block/BlockStairs.java +++ b/common/src/common/block/BlockStairs.java @@ -27,10 +27,10 @@ import common.util.Vec3; import common.world.Explosion; import common.world.IBlockAccess; import common.world.IWorldAccess; +import common.world.AWorldClient; import common.world.State; import common.world.World; -import common.world.WorldClient; -import common.world.WorldServer; +import common.world.AWorldServer; public class BlockStairs extends Block { @@ -561,7 +561,7 @@ public class BlockStairs extends Block this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F); } - public void randomDisplayTick(WorldClient worldIn, BlockPos pos, State state, Random rand) + public void randomDisplayTick(AWorldClient worldIn, BlockPos pos, State state, Random rand) { this.modelBlock.randomDisplayTick(worldIn, pos, state, rand); } @@ -633,13 +633,13 @@ public class BlockStairs extends Block return this.modelBlock.canPlaceBlockAt(worldIn, pos); } - public void onBlockAdded(WorldServer worldIn, BlockPos pos, State state) + public void onBlockAdded(AWorldServer worldIn, BlockPos pos, State state) { this.onNeighborBlockChange(worldIn, pos, this.modelState, Blocks.air); this.modelBlock.onBlockAdded(worldIn, pos, this.modelState); } - public void onBlockRemoved(WorldServer worldIn, BlockPos pos, State state) + public void onBlockRemoved(AWorldServer worldIn, BlockPos pos, State state) { this.modelBlock.onBlockRemoved(worldIn, pos, this.modelState); } @@ -652,7 +652,7 @@ public class BlockStairs extends Block this.modelBlock.onEntityCollidedWithBlock(worldIn, pos, entityIn); } - public void updateTick(WorldServer worldIn, BlockPos pos, State state, Random rand) + public void updateTick(AWorldServer worldIn, BlockPos pos, State state, Random rand) { this.modelBlock.updateTick(worldIn, pos, state, rand); } diff --git a/common/src/common/block/BlockStaticLiquid.java b/common/src/common/block/BlockStaticLiquid.java index b087f92..5b5b29f 100755 --- a/common/src/common/block/BlockStaticLiquid.java +++ b/common/src/common/block/BlockStaticLiquid.java @@ -8,7 +8,7 @@ import common.util.BlockPos; import common.util.Facing; import common.world.State; import common.world.World; -import common.world.WorldServer; +import common.world.AWorldServer; public class BlockStaticLiquid extends BlockLiquid { @@ -41,7 +41,7 @@ public class BlockStaticLiquid extends BlockLiquid worldIn.scheduleUpdate(pos, blockdynamicliquid, this.tickRate(worldIn, pos)); } - public void updateTick(WorldServer worldIn, BlockPos pos, State state, Random rand) + public void updateTick(AWorldServer worldIn, BlockPos pos, State state, Random rand) { if (Config.lavaFire && this.material == Material.lava) { diff --git a/common/src/common/block/BlockStem.java b/common/src/common/block/BlockStem.java index 171047a..d42ae2b 100755 --- a/common/src/common/block/BlockStem.java +++ b/common/src/common/block/BlockStem.java @@ -21,7 +21,7 @@ import common.util.Facing; import common.world.IWorldAccess; import common.world.State; import common.world.World; -import common.world.WorldServer; +import common.world.AWorldServer; public class BlockStem extends BlockBush implements IGrowable { @@ -73,7 +73,7 @@ public class BlockStem extends BlockBush implements IGrowable return ground == Blocks.farmland; } - public void updateTick(WorldServer worldIn, BlockPos pos, State state, Random rand) + public void updateTick(AWorldServer worldIn, BlockPos pos, State state, Random rand) { super.updateTick(worldIn, pos, state, rand); @@ -213,7 +213,7 @@ public class BlockStem extends BlockBush implements IGrowable return true; } - public void grow(WorldServer worldIn, Random rand, BlockPos pos, State state) + public void grow(AWorldServer worldIn, Random rand, BlockPos pos, State state) { this.growStem(worldIn, pos, state); } diff --git a/common/src/common/block/BlockTNT.java b/common/src/common/block/BlockTNT.java index 7f121a1..1dfc2a3 100755 --- a/common/src/common/block/BlockTNT.java +++ b/common/src/common/block/BlockTNT.java @@ -23,7 +23,7 @@ import common.util.Facing; import common.world.Explosion; import common.world.State; import common.world.World; -import common.world.WorldServer; +import common.world.AWorldServer; public class BlockTNT extends Block { @@ -37,7 +37,7 @@ public class BlockTNT extends Block this.setTab(CheatTab.tabTech); } - public void onBlockAdded(WorldServer worldIn, BlockPos pos, State state) + public void onBlockAdded(AWorldServer worldIn, BlockPos pos, State state) { super.onBlockAdded(worldIn, pos, state); diff --git a/common/src/common/block/BlockTallGrass.java b/common/src/common/block/BlockTallGrass.java index aa2e686..a527f19 100755 --- a/common/src/common/block/BlockTallGrass.java +++ b/common/src/common/block/BlockTallGrass.java @@ -23,7 +23,7 @@ import common.util.Identifyable; import common.world.IWorldAccess; import common.world.State; import common.world.World; -import common.world.WorldServer; +import common.world.AWorldServer; public class BlockTallGrass extends BlockBush implements IGrowable { @@ -38,7 +38,7 @@ public class BlockTallGrass extends BlockBush implements IGrowable // this.setTickRandomly(); } - public void updateTick(WorldServer worldIn, BlockPos pos, State state, Random rand) + public void updateTick(AWorldServer worldIn, BlockPos pos, State state, Random rand) { if(Config.tallgrassDry && worldIn.getTemperatureC(pos) >= 50.0f && state.getValue(TYPE) != EnumType.DEAD_BUSH) { @@ -147,7 +147,7 @@ public class BlockTallGrass extends BlockBush implements IGrowable return true; } - public void grow(WorldServer worldIn, Random rand, BlockPos pos, State state) + public void grow(AWorldServer worldIn, Random rand, BlockPos pos, State state) { BlockDoublePlant.EnumPlantType blockdoubleplant$enumplanttype = BlockDoublePlant.EnumPlantType.GRASS; diff --git a/common/src/common/block/BlockTorch.java b/common/src/common/block/BlockTorch.java index 53d5940..a249b7e 100755 --- a/common/src/common/block/BlockTorch.java +++ b/common/src/common/block/BlockTorch.java @@ -20,10 +20,10 @@ import common.util.Facing; import common.util.HitPosition; import common.util.Vec3; import common.world.Chunk; +import common.world.AWorldClient; import common.world.State; import common.world.World; -import common.world.WorldClient; -import common.world.WorldServer; +import common.world.AWorldServer; public class BlockTorch extends Block { @@ -135,7 +135,7 @@ public class BlockTorch extends Block } } - public void onBlockAdded(WorldServer worldIn, BlockPos pos, State state) + public void onBlockAdded(AWorldServer worldIn, BlockPos pos, State state) { this.checkForDrop(worldIn, pos, state); } @@ -234,7 +234,7 @@ public class BlockTorch extends Block return super.collisionRayTrace(worldIn, pos, start, end); } - public void randomDisplayTick(WorldClient worldIn, BlockPos pos, State state, Random rand) + public void randomDisplayTick(AWorldClient worldIn, BlockPos pos, State state, Random rand) { Facing enumfacing = (Facing)state.getValue(FACING); double d0 = (double)pos.getX() + 0.5D; diff --git a/common/src/common/block/BlockTripWire.java b/common/src/common/block/BlockTripWire.java index 7512125..e02e941 100755 --- a/common/src/common/block/BlockTripWire.java +++ b/common/src/common/block/BlockTripWire.java @@ -23,7 +23,7 @@ import common.world.IBlockAccess; import common.world.IWorldAccess; import common.world.State; import common.world.World; -import common.world.WorldServer; +import common.world.AWorldServer; public class BlockTripWire extends Block { @@ -124,14 +124,14 @@ public class BlockTripWire extends Block } } - public void onBlockAdded(WorldServer worldIn, BlockPos pos, State state) + public void onBlockAdded(AWorldServer worldIn, BlockPos pos, State state) { state = state.withProperty(SUSPENDED, Boolean.valueOf(!worldIn.isBlockSolid(pos.down()))); worldIn.setState(pos, state, 3); this.notifyHook(worldIn, pos, state); } - public void onBlockRemoved(WorldServer worldIn, BlockPos pos, State state) + public void onBlockRemoved(AWorldServer worldIn, BlockPos pos, State state) { this.notifyHook(worldIn, pos, state.withProperty(POWERED, Boolean.valueOf(true))); } @@ -191,11 +191,11 @@ public class BlockTripWire extends Block /** * Called randomly when setTickRandomly is set to true (used by e.g. crops to grow, etc.) */ - public void randomTick(WorldServer worldIn, BlockPos pos, State state, Random random) + public void randomTick(AWorldServer worldIn, BlockPos pos, State state, Random random) { } - public void updateTick(WorldServer worldIn, BlockPos pos, State state, Random rand) + public void updateTick(AWorldServer worldIn, BlockPos pos, State state, Random rand) { // if (!worldIn.client) // { diff --git a/common/src/common/block/BlockTripWireHook.java b/common/src/common/block/BlockTripWireHook.java index 0c8afda..778de6c 100755 --- a/common/src/common/block/BlockTripWireHook.java +++ b/common/src/common/block/BlockTripWireHook.java @@ -20,7 +20,7 @@ import common.util.Facing; import common.world.IWorldAccess; import common.world.State; import common.world.World; -import common.world.WorldServer; +import common.world.AWorldServer; public class BlockTripWireHook extends Block { @@ -225,11 +225,11 @@ public class BlockTripWireHook extends Block /** * Called randomly when setTickRandomly is set to true (used by e.g. crops to grow, etc.) */ - public void randomTick(WorldServer worldIn, BlockPos pos, State state, Random random) + public void randomTick(AWorldServer worldIn, BlockPos pos, State state, Random random) { } - public void updateTick(WorldServer worldIn, BlockPos pos, State state, Random rand) + public void updateTick(AWorldServer worldIn, BlockPos pos, State state, Random rand) { this.triggerHookAt(worldIn, pos, state, false, true, -1, (State)null); } @@ -298,7 +298,7 @@ public class BlockTripWireHook extends Block } } - public void onBlockRemoved(WorldServer worldIn, BlockPos pos, State state) + public void onBlockRemoved(AWorldServer worldIn, BlockPos pos, State state) { boolean flag = ((Boolean)state.getValue(ATTACHED)).booleanValue(); boolean flag1 = ((Boolean)state.getValue(POWERED)).booleanValue(); diff --git a/common/src/common/block/BlockVine.java b/common/src/common/block/BlockVine.java index 8e82dcc..ed6f33b 100755 --- a/common/src/common/block/BlockVine.java +++ b/common/src/common/block/BlockVine.java @@ -24,7 +24,7 @@ import common.util.Facing; import common.world.IWorldAccess; import common.world.State; import common.world.World; -import common.world.WorldServer; +import common.world.AWorldServer; public class BlockVine extends Block { @@ -241,7 +241,7 @@ public class BlockVine extends Block } } - public void updateTick(WorldServer worldIn, BlockPos pos, State state, Random rand) + public void updateTick(AWorldServer worldIn, BlockPos pos, State state, Random rand) { if(Config.vineDry && worldIn.getTemperatureC(pos) >= 50.0f) { diff --git a/common/src/common/block/BlockWarpChest.java b/common/src/common/block/BlockWarpChest.java index 32b40c9..f3aab50 100755 --- a/common/src/common/block/BlockWarpChest.java +++ b/common/src/common/block/BlockWarpChest.java @@ -18,9 +18,9 @@ import common.properties.PropertyDirection; import common.rng.Random; import common.util.BlockPos; import common.util.Facing; +import common.world.AWorldClient; import common.world.State; import common.world.World; -import common.world.WorldClient; public class BlockWarpChest extends Block { @@ -117,7 +117,7 @@ public class BlockWarpChest extends Block // return new TileEntityWarpChest(); // } - public void randomDisplayTick(WorldClient worldIn, BlockPos pos, State state, Random rand) + public void randomDisplayTick(AWorldClient worldIn, BlockPos pos, State state, Random rand) { for (int i = 0; i < 3; ++i) { diff --git a/common/src/common/block/BlockWart.java b/common/src/common/block/BlockWart.java index 3c576a8..3937dbe 100755 --- a/common/src/common/block/BlockWart.java +++ b/common/src/common/block/BlockWart.java @@ -15,7 +15,7 @@ import common.rng.Random; import common.util.BlockPos; import common.world.State; import common.world.World; -import common.world.WorldServer; +import common.world.AWorldServer; public class BlockWart extends BlockBush { @@ -44,7 +44,7 @@ public class BlockWart extends BlockBush return this.canPlaceBlockOn(worldIn.getState(pos.down()).getBlock()); } - public void updateTick(WorldServer worldIn, BlockPos pos, State state, Random rand) + public void updateTick(AWorldServer worldIn, BlockPos pos, State state, Random rand) { if(Config.wartGrowth > 0) { int i = ((Integer)state.getValue(AGE)).intValue(); diff --git a/common/src/common/block/IGrowable.java b/common/src/common/block/IGrowable.java index a3c9ca0..9bb72c7 100755 --- a/common/src/common/block/IGrowable.java +++ b/common/src/common/block/IGrowable.java @@ -4,7 +4,7 @@ import common.rng.Random; import common.util.BlockPos; import common.world.State; import common.world.World; -import common.world.WorldServer; +import common.world.AWorldServer; public interface IGrowable { @@ -12,5 +12,5 @@ public interface IGrowable boolean canUseBonemeal(World worldIn, Random rand, BlockPos pos, State state); - void grow(WorldServer worldIn, Random rand, BlockPos pos, State state); + void grow(AWorldServer worldIn, Random rand, BlockPos pos, State state); } diff --git a/common/src/common/entity/Entity.java b/common/src/common/entity/Entity.java index b142d3d..59c59a1 100755 --- a/common/src/common/entity/Entity.java +++ b/common/src/common/entity/Entity.java @@ -43,7 +43,7 @@ import common.util.Vec3; import common.world.Explosion; import common.world.State; import common.world.World; -import common.world.WorldServer; +import common.world.AWorldServer; public abstract class Entity { @@ -2370,8 +2370,8 @@ public abstract class Entity // this.worldObj.profiler.start("changeDimension"); // Server server = Server.getServer(); // int oldDim = this.dimension; - WorldServer worldserver = (WorldServer)this.worldObj; // server.getWorld(oldDim); - WorldServer worldserver1 = worldserver.getServer().getWorld(dimensionId); + AWorldServer worldserver = (AWorldServer)this.worldObj; // server.getWorld(oldDim); + AWorldServer worldserver1 = worldserver.getOtherWorld(dimensionId); // this.dimension = dimensionId; // if (i == 1 && dimensionId == 1) @@ -2383,7 +2383,7 @@ public abstract class Entity this.worldObj.removeEntity(this); this.dead = false; // this.worldObj.profiler.start("reposition"); - worldserver.getServer().placeInDimension(this, worldserver, worldserver1, pos, portal); + worldserver.placeInDimension(this, worldserver, worldserver1, pos, portal); if(this.isEntityAlive()) worldserver1.updateEntity(this, false); // this.worldObj.profiler.next("reloading"); diff --git a/common/src/common/entity/animal/EntityDragon.java b/common/src/common/entity/animal/EntityDragon.java index 4b97778..b02ea8e 100755 --- a/common/src/common/entity/animal/EntityDragon.java +++ b/common/src/common/entity/animal/EntityDragon.java @@ -15,8 +15,8 @@ import common.init.SoundEvent; import common.model.ParticleType; import common.util.ExtMath; import common.util.Vec3; +import common.world.AWorldClient; import common.world.World; -import common.world.WorldClient; public class EntityDragon extends EntityLiving implements IEntityMultiPart { @@ -105,7 +105,7 @@ public class EntityDragon extends EntityLiving implements IEntityMultiPart if (f1 <= -0.3F && f >= -0.3F) // && !this.isSilent()) { - ((WorldClient)this.worldObj).playSound(this.posX, this.posY, this.posZ, SoundEvent.DRAGON_WINGS, 5.0F); + ((AWorldClient)this.worldObj).playSound(this.posX, this.posY, this.posZ, SoundEvent.DRAGON_WINGS, 5.0F); } } diff --git a/common/src/common/entity/effect/EntityLightning.java b/common/src/common/entity/effect/EntityLightning.java index e966314..4de8d0f 100755 --- a/common/src/common/entity/effect/EntityLightning.java +++ b/common/src/common/entity/effect/EntityLightning.java @@ -11,8 +11,8 @@ import common.init.SoundEvent; import common.material.Material; import common.util.BlockPos; import common.util.BoundingBox; +import common.world.AWorldClient; import common.world.World; -import common.world.WorldClient; public class EntityLightning extends EntityWeatherEffect { @@ -77,7 +77,7 @@ public class EntityLightning extends EntityWeatherEffect { if (this.worldObj.client) { - ((WorldClient)this.worldObj).setLastLightning(2, this.color); + ((AWorldClient)this.worldObj).setLastLightning(2, this.color); } else // if(this.damage > 0) { diff --git a/common/src/common/entity/item/EntityFireworks.java b/common/src/common/entity/item/EntityFireworks.java index 1e1e2eb..56951a5 100755 --- a/common/src/common/entity/item/EntityFireworks.java +++ b/common/src/common/entity/item/EntityFireworks.java @@ -7,8 +7,8 @@ import common.item.ItemStack; import common.model.ParticleType; import common.nbt.NBTTagCompound; import common.util.ExtMath; +import common.world.AWorldClient; import common.world.World; -import common.world.WorldClient; public class EntityFireworks extends Entity { @@ -158,7 +158,7 @@ public class EntityFireworks extends Entity nbttagcompound = itemstack.getTagCompound().getCompoundTag("Fireworks"); } - ((WorldClient)this.worldObj).makeFireworks(this.posX, this.posY, this.posZ, this.motionX, this.motionY, this.motionZ, nbttagcompound); + ((AWorldClient)this.worldObj).makeFireworks(this.posX, this.posY, this.posZ, this.motionX, this.motionY, this.motionZ, nbttagcompound); } super.handleStatusUpdate(id); diff --git a/common/src/common/entity/item/EntityItem.java b/common/src/common/entity/item/EntityItem.java index 1647b97..6b7abf7 100755 --- a/common/src/common/entity/item/EntityItem.java +++ b/common/src/common/entity/item/EntityItem.java @@ -19,7 +19,7 @@ import common.util.BlockPos; import common.util.ExtMath; import common.util.PortalType; import common.world.World; -import common.world.WorldServer; +import common.world.AWorldServer; public class EntityItem extends Entity { @@ -65,7 +65,7 @@ public class EntityItem extends Entity { if(!this.worldObj.client && Config.itemFallDamage && distance >= 1.0f && this.getEntityItem().getItem().isFragile()) { // for(int z = 0; z < 8; z++) { - ((WorldServer)this.worldObj).spawnParticle(ParticleType.ITEM_CRACK, this.posX, this.posY, this.posZ, + ((AWorldServer)this.worldObj).spawnParticle(ParticleType.ITEM_CRACK, this.posX, this.posY, this.posZ, 8, this.rand.gaussian() * 0.15D, this.rand.doublev() * 0.2D, this.rand.gaussian() * 0.15D, 0.1f, ItemRegistry.getIdFromItem(this.getEntityItem().getItem()), this.getEntityItem().getMetadata()); // } diff --git a/common/src/common/entity/npc/EntityArachnoid.java b/common/src/common/entity/npc/EntityArachnoid.java index becd804..990e649 100755 --- a/common/src/common/entity/npc/EntityArachnoid.java +++ b/common/src/common/entity/npc/EntityArachnoid.java @@ -69,7 +69,7 @@ public class EntityArachnoid extends EntityNPC public boolean isOnLadder() { - return super.isOnLadder() || (this.sendQueue != null ? this.collidedHorizontally && !this.noclip : this.isBesideClimbableBlock()); + return super.isOnLadder() || (this.client != null ? this.collidedHorizontally && !this.noclip : this.isBesideClimbableBlock()); } public void setInWeb() diff --git a/common/src/common/entity/npc/EntityDarkMage.java b/common/src/common/entity/npc/EntityDarkMage.java index 5d5712b..5f0476f 100755 --- a/common/src/common/entity/npc/EntityDarkMage.java +++ b/common/src/common/entity/npc/EntityDarkMage.java @@ -4,8 +4,8 @@ import common.ai.AISmallFireballAttack; import common.init.SoundEvent; import common.model.ParticleType; import common.rng.Random; +import common.world.AWorldClient; import common.world.World; -import common.world.WorldClient; public class EntityDarkMage extends EntityHoveringNPC { public EntityDarkMage(World worldIn) { @@ -85,7 +85,7 @@ public class EntityDarkMage extends EntityHoveringNPC { { if(this.worldObj.client && this.isAttacking()) { if(this.rand.chance(24)) { // && !this.isSilent()) { - ((WorldClient)this.worldObj).playSound(this.posX + 0.5D, this.posY + 0.5D, this.posZ + 0.5D, SoundEvent.FIRE, + ((AWorldClient)this.worldObj).playSound(this.posX + 0.5D, this.posY + 0.5D, this.posZ + 0.5D, SoundEvent.FIRE, 1.0F + this.rand.floatv()); } for(int i = 0; i < 2; ++i) { diff --git a/common/src/common/entity/npc/EntityHaunter.java b/common/src/common/entity/npc/EntityHaunter.java index e076393..4f5165d 100755 --- a/common/src/common/entity/npc/EntityHaunter.java +++ b/common/src/common/entity/npc/EntityHaunter.java @@ -12,7 +12,7 @@ import common.item.ItemStack; import common.nbt.NBTTagCompound; import common.rng.Random; import common.world.World; -import common.world.WorldServer; +import common.world.AWorldServer; public class EntityHaunter extends EntityNPC { // private int lastActiveTime; @@ -346,7 +346,7 @@ public class EntityHaunter extends EntityNPC { } public boolean getCanSpawnHere() { - return !((WorldServer)this.worldObj).isDaytime(); + return !((AWorldServer)this.worldObj).isDaytime(); } // public boolean canAmbush(EntityLiving entity) { diff --git a/common/src/common/entity/npc/EntityHoveringNPC.java b/common/src/common/entity/npc/EntityHoveringNPC.java index 0d8390f..3c823c8 100755 --- a/common/src/common/entity/npc/EntityHoveringNPC.java +++ b/common/src/common/entity/npc/EntityHoveringNPC.java @@ -98,11 +98,11 @@ public abstract class EntityHoveringNPC extends EntityNPC { if (flag) { - this.sendQueue.addToSendQueue(new CPacketAction(CPacketAction.Action.START_HOVER)); + this.client.addToSendQueue(new CPacketAction(CPacketAction.Action.START_HOVER)); } else { - this.sendQueue.addToSendQueue(new CPacketAction(CPacketAction.Action.STOP_HOVER)); + this.client.addToSendQueue(new CPacketAction(CPacketAction.Action.STOP_HOVER)); } this.serverHoverState = flag; @@ -113,10 +113,10 @@ public abstract class EntityHoveringNPC extends EntityNPC public void onLivingUpdate() { - if(this.sendQueue != null) { - if(this.gm.isJumping() && this.gm.isSprinting() && this.gm.getMoveForward() == 0.0f && this.gm.getMoveStrafe() == 0.0f) + if(this.client != null) { + if(this.client.isJumping() && this.client.isSprinting() && this.client.getMoveForward() == 0.0f && this.client.getMoveStrafe() == 0.0f) this.setHovering(true); - if(this.isFlying() || (!this.gm.isJumping() && this.gm.isSneaking() && this.onGround)) + if(this.isFlying() || (!this.client.isJumping() && this.client.isSneaking() && this.onGround)) this.setHovering(false); } if (!this.onGround && this.motionY < 0.0D && (!this.isPlayer() || (!this.isFlying() && this.isHovering() && !this.jumping))) diff --git a/common/src/common/entity/npc/EntityHuman.java b/common/src/common/entity/npc/EntityHuman.java index cedc14b..77a4d3d 100755 --- a/common/src/common/entity/npc/EntityHuman.java +++ b/common/src/common/entity/npc/EntityHuman.java @@ -8,7 +8,7 @@ import common.util.BlockPos; import common.util.Identifyable; import common.village.Village; import common.world.World; -import common.world.WorldServer; +import common.world.AWorldServer; public class EntityHuman extends EntityNPC { public static enum ClassType implements Identifyable { @@ -111,10 +111,10 @@ public class EntityHuman extends EntityNPC { protected void updateAITasks() { if(--this.checkTimer <= 0) { BlockPos blockpos = new BlockPos(this); -// if(((WorldServer)this.worldObj).isPrimary()) - ((WorldServer)this.worldObj).addToVillagerPositionList(blockpos); +// if(((IWorldServer)this.worldObj).isPrimary()) + ((AWorldServer)this.worldObj).addToVillagerPositionList(blockpos); this.checkTimer = this.rand.excl(70, 120); - this.village = ((WorldServer)this.worldObj).getNearestVillage(blockpos, 32); + this.village = ((AWorldServer)this.worldObj).getNearestVillage(blockpos, 32); if(this.village == null) { this.detachHome(); diff --git a/common/src/common/entity/npc/EntityNPC.java b/common/src/common/entity/npc/EntityNPC.java index cf4e573..9bd5118 100755 --- a/common/src/common/entity/npc/EntityNPC.java +++ b/common/src/common/entity/npc/EntityNPC.java @@ -4,7 +4,6 @@ import java.lang.reflect.InvocationTargetException; import java.util.List; import java.util.function.Predicate; -import common.IClient; import common.ai.AIRangedAttack; import common.ai.EntityAIAttackOnCollide; import common.ai.EntityAIAvoidEntity; @@ -94,9 +93,9 @@ import common.util.PortalType; import common.util.Vec3; import common.util.WorldPos; import common.village.MerchantRecipeList; +import common.world.AWorldClient; import common.world.World; -import common.world.WorldClient; -import common.world.WorldServer; +import common.world.AWorldServer; public abstract class EntityNPC extends EntityLiving { @@ -186,8 +185,8 @@ public abstract class EntityNPC extends EntityLiving private byte[] skin; public IPlayer connection; - public IClientPlayer sendQueue; - protected IClient gm; + public IClientPlayer client; + protected boolean slave; public InventoryPlayer inventory; protected InventoryWarpChest warpChest; @@ -392,22 +391,22 @@ public abstract class EntityNPC extends EntityLiving this.stepHeight = 0.0F; } - public final void setClientPlayer(IClient gm, IClientPlayer connection) { + public final void setClientPlayer(IClientPlayer connection) { this.initPlayer(); - this.gm = gm; - this.sendQueue = connection; + this.slave = true; + this.client = connection; } - public final void setOtherPlayer(IClient gm) { + public final void setOtherPlayer() { this.initPlayer(); - this.gm = gm; + this.slave = true; this.stepHeight = 0.0F; this.noClip = true; this.renderDistWeight = 10.0D; } public final boolean isPlayer() { - return this.connection != null || this.gm != null; + return this.connection != null || this.slave; } @@ -1275,14 +1274,14 @@ public abstract class EntityNPC extends EntityLiving } else { this.worldObj.playAuxSFX(1013, new BlockPos(ox, oy, oz), 0); - ((WorldServer)this.worldObj).spawnParticle(ParticleType.PORTAL, + ((AWorldServer)this.worldObj).spawnParticle(ParticleType.PORTAL, ox + (this.rand.doublev() - 0.5D) * (double)this.width * 2.0D, oy + this.rand.doublev() * (double)this.height, oz + (this.rand.doublev() - 0.5D) * (double)this.width * 2.0D, 8, (this.rand.floatv() - 0.5F) * 0.2F, (this.rand.floatv() - 0.5F) * 0.2F, (this.rand.floatv() - 0.5F) * 0.2F, 0.15D); this.worldObj.playAuxSFX(1005, this.getPosition(), 0); - ((WorldServer)this.worldObj).spawnParticle(ParticleType.PORTAL, + ((AWorldServer)this.worldObj).spawnParticle(ParticleType.PORTAL, this.posX + (this.rand.doublev() - 0.5D) * (double)this.width * 2.0D, this.posY + this.rand.doublev() * (double)this.height, this.posZ + (this.rand.doublev() - 0.5D) * (double)this.width * 2.0D, 8, @@ -1678,7 +1677,7 @@ public abstract class EntityNPC extends EntityLiving if (!ItemStack.areItemStacksEqual(itemstack1, itemstack)) { - ((WorldServer)this.worldObj).sendToAllTrackingEntity(this, new SPacketEntityEquipment(this.getId(), j, itemstack1)); + ((AWorldServer)this.worldObj).sendToAllTrackingEntity(this, new SPacketEntityEquipment(this.getId(), j, itemstack1)); if (itemstack != null) { @@ -1736,8 +1735,8 @@ public abstract class EntityNPC extends EntityLiving public boolean attackEntityFrom(DamageSource source, int amount) { - if(this.gm != null) - return this.sendQueue == null; + if(this.slave) + return this.client == null; // if(this.isEntityInvulnerable(source)) // return false; if(this.connection != null) { @@ -1760,13 +1759,13 @@ public abstract class EntityNPC extends EntityLiving */ public void heal(int healAmount) { - if(this.sendQueue == null) + if(this.client == null) super.heal(healAmount); } public void healMana(int amount) { - if(this.sendQueue == null) + if(this.client == null) super.healMana(amount); } @@ -1781,9 +1780,9 @@ public abstract class EntityNPC extends EntityLiving this.connection.mountEntity(entityIn); // super.mountEntity(entityIn); - if (this.sendQueue != null && entityIn instanceof EntityCart) + if (this.client != null && entityIn instanceof EntityCart) { - this.gm.playSound(new MovingSoundMinecartRiding(this, (EntityCart)entityIn)); + this.client.playSound(new MovingSoundMinecartRiding(this, (EntityCart)entityIn)); } } @@ -1792,7 +1791,7 @@ public abstract class EntityNPC extends EntityLiving */ public void onUpdate() { - if(this.sendQueue != null) { + if(this.client != null) { if (this.worldObj.isBlockLoaded(new BlockPos(this.posX, 0.0D, this.posZ))) { // super.onUpdate(); @@ -1800,8 +1799,8 @@ public abstract class EntityNPC extends EntityLiving if (this.isRiding()) { - this.sendQueue.addToSendQueue(new CPacketPlayer.C05PacketPlayerLook(this.rotYaw, this.rotPitch, this.onGround)); - this.sendQueue.addToSendQueue(new CPacketInput(this.moveStrafe, this.moveForward, this.gm.isJumping(), this.gm.isSneaking())); + this.client.addToSendQueue(new CPacketPlayer.C05PacketPlayerLook(this.rotYaw, this.rotPitch, this.onGround)); + this.client.addToSendQueue(new CPacketInput(this.moveStrafe, this.moveForward, this.client.isJumping(), this.client.isSneaking())); } else { @@ -1816,7 +1815,7 @@ public abstract class EntityNPC extends EntityLiving return; } - if(this.gm != null) { + if(this.slave) { // this.renderOffsetY = 0.0F; // super.onUpdate(); this.updatePlayer(); @@ -1966,9 +1965,9 @@ public abstract class EntityNPC extends EntityLiving */ public EntityItem dropOneItem(boolean dropAll) { - if(this.sendQueue != null) { + if(this.client != null) { CPacketBreak.Action c07packetplayerdigging$action = dropAll ? CPacketBreak.Action.DROP_ALL_ITEMS : CPacketBreak.Action.DROP_ITEM; - this.sendQueue.addToSendQueue(new CPacketBreak(c07packetplayerdigging$action, BlockPos.ORIGIN, Facing.DOWN)); + this.client.addToSendQueue(new CPacketBreak(c07packetplayerdigging$action, BlockPos.ORIGIN, Facing.DOWN)); return null; } return this.dropItem(this.inventory.decrStackSize(this.inventory.currentItem, dropAll && this.inventory.getCurrentItem() != null ? this.inventory.getCurrentItem().stackSize : 1), false, true); @@ -1979,13 +1978,13 @@ public abstract class EntityNPC extends EntityLiving */ protected void joinEntityItemWithWorld(EntityItem itemIn) { - if(this.sendQueue == null) + if(this.client == null) this.worldObj.spawnEntityInWorld(itemIn); } protected void changeSize(float width, float height) { super.changeSize(width, height); - if(this.sendQueue != null) + if(this.client != null) this.stepHeight = height / 3.0f; } @@ -1995,8 +1994,8 @@ public abstract class EntityNPC extends EntityLiving public void swingItem() { super.swingItem(); - if(this.sendQueue != null) - this.sendQueue.addToSendQueue(new CPacketAction(CPacketAction.Action.SWING_ARM)); + if(this.client != null) + this.client.addToSendQueue(new CPacketAction(CPacketAction.Action.SWING_ARM)); } /** @@ -2005,7 +2004,7 @@ public abstract class EntityNPC extends EntityLiving */ protected void damageEntity(DamageSource damageSrc, int damageAmount) { - if(this.sendQueue != null) { + if(this.client != null) { // if(!this.isEntityInvulnerable(damageSrc)) this.setHealth(this.getHealth() - damageAmount); return; @@ -2050,19 +2049,19 @@ public abstract class EntityNPC extends EntityLiving { if(this.connection != null) this.connection.closeScreen(); - else if(this.sendQueue != null) { + else if(this.client != null) { // this.setScreenClosed(); // this.sendQueue.addToSendQueue(new CPacketAction(CPacketAction.Action.CLOSE_CONTAINER)); // , this.openContainer.windowId)); // this.closeScreenAndDropStack(); - this.sendQueue.closeGui(); + this.client.closeGui(); } else this.openContainer = this.inventoryContainer; } public void setScreenClosed() { - if(this.sendQueue != null) { - this.sendQueue.addToSendQueue(new CPacketAction(CPacketAction.Action.CLOSE_CONTAINER, this.openContainer.windowId)); + if(this.client != null) { + this.client.addToSendQueue(new CPacketAction(CPacketAction.Action.CLOSE_CONTAINER, this.openContainer.windowId)); this.inventory.setItemStack((ItemStack)null); this.openContainer = this.inventoryContainer; } @@ -2070,7 +2069,7 @@ public abstract class EntityNPC extends EntityLiving protected boolean pushOutOfBlocks(double x, double y, double z) { - if(this.sendQueue == null) + if(this.client == null) return super.pushOutOfBlocks(x, y, z); if (this.noClip) { @@ -2144,7 +2143,7 @@ public abstract class EntityNPC extends EntityLiving public void setSprinting(boolean sprinting) { super.setSprinting(sprinting); - if(this.sendQueue != null) + if(this.client != null) this.sprintingTicksLeft = sprinting ? 600 : 0; } @@ -2152,23 +2151,23 @@ public abstract class EntityNPC extends EntityLiving { if(this.connection != null) this.connection.playSound(name, volume); - else if(this.sendQueue != null) - ((WorldClient)this.worldObj).playSound(this.posX, this.posY, this.posZ, name, volume); - else if(this.gm == null) + else if(this.client != null) + ((AWorldClient)this.worldObj).playSound(this.posX, this.posY, this.posZ, name, volume); + else if(!this.slave) super.playSound(name, volume); } public boolean isTicked() { - return (!this.worldObj.client && (Config.mobTick || this.connection != null)) || this.sendQueue != null; + return (!this.worldObj.client && (Config.mobTick || this.connection != null)) || this.client != null; } public void openEditSign(TileEntitySign signTile) { if(this.connection != null) this.connection.openEditSign(signTile); - else if(this.sendQueue != null) - this.sendQueue.displayGuiSign(signTile.getPos(), signTile.signText); + else if(this.client != null) + this.client.displayGuiSign(signTile.getPos(), signTile.signText); } /** @@ -2195,8 +2194,8 @@ public abstract class EntityNPC extends EntityLiving { if(this.connection != null) this.connection.displayGUIChest(chestInventory); - else if(this.sendQueue != null) { - this.sendQueue.displayGUIChest(chestInventory, this.inventory); + else if(this.client != null) { + this.client.displayGUIChest(chestInventory, this.inventory); } } @@ -2204,16 +2203,16 @@ public abstract class EntityNPC extends EntityLiving { if(this.connection != null) this.connection.displayGUIHorse(horse, horseInventory); - else if(this.sendQueue != null) - this.sendQueue.displayGuiHorse(horse, this.inventory, horseInventory); + else if(this.client != null) + this.client.displayGuiHorse(horse, this.inventory, horseInventory); } public void displayGui(IInteractionObject guiOwner) { if(this.connection != null) this.connection.displayGui(guiOwner); - else if(this.sendQueue != null) { - this.sendQueue.displayGui(guiOwner, this.inventory, this.worldObj); + else if(this.client != null) { + this.client.displayGui(guiOwner, this.inventory, this.worldObj); } } @@ -2224,16 +2223,16 @@ public abstract class EntityNPC extends EntityLiving { if(this.connection != null) this.connection.onCriticalHit(entityHit); - else if(this.sendQueue != null) - this.gm.emitParticleAtEntity(entityHit, ParticleType.CRIT); + else if(this.client != null) + this.client.emitParticleAtEntity(entityHit, ParticleType.CRIT); } public void onEnchantmentCritical(Entity entityHit) { if(this.connection != null) this.connection.onEnchantmentCritical(entityHit); - else if(this.sendQueue != null) - this.gm.emitParticleAtEntity(entityHit, ParticleType.CRIT_MAGIC); + else if(this.client != null) + this.client.emitParticleAtEntity(entityHit, ParticleType.CRIT_MAGIC); } /** @@ -2241,7 +2240,7 @@ public abstract class EntityNPC extends EntityLiving */ public boolean isSneaking() { - return this.sendQueue != null ? this.gm.isSneaking() : super.isSneaking(); + return this.client != null ? this.client.isSneaking() : super.isSneaking(); } public void updateEntityActionState() @@ -2254,11 +2253,11 @@ public abstract class EntityNPC extends EntityLiving this.headYaw = this.rotYaw; // super.updateEntityActionState(); - if (this.sendQueue != null && this.isCurrentViewEntity()) + if (this.client != null && this.client.isRenderViewEntity(this)) { - this.moveStrafe = this.gm.getMoveStrafe(); - this.moveForward = this.gm.getMoveForward(); - this.jumping = this.gm.isJumping(); + this.moveStrafe = this.client.getMoveStrafe(); + this.moveForward = this.client.getMoveForward(); + this.jumping = this.client.isJumping(); this.prevRenderArmYaw = this.renderArmYaw; this.prevRenderArmPitch = this.renderArmPitch; this.renderArmPitch = (float)((double)this.renderArmPitch + (double)(this.rotPitch - this.renderArmPitch) * 0.5D); @@ -2272,7 +2271,7 @@ public abstract class EntityNPC extends EntityLiving */ public void onLivingUpdate() { - if(this.sendQueue != null) { + if(this.client != null) { if (this.sprintingTicksLeft > 0) { --this.sprintingTicksLeft; @@ -2338,16 +2337,16 @@ public abstract class EntityNPC extends EntityLiving // --this.portalTimer; // } - boolean flag = this.gm.isJumping(); - boolean flag1 = this.gm.isSneaking(); + boolean flag = this.client.isJumping(); + boolean flag1 = this.client.isSneaking(); float f = 0.8F; - boolean flag2 = this.gm.getMoveForward() >= f; - this.gm.updatePlayerMoveState(); + boolean flag2 = this.client.getMoveForward() >= f; + this.client.updatePlayerMoveState(); if (this.isUsingItem() && !this.isRiding()) { - this.gm.setMoveStrafe(this.gm.getMoveStrafe() * 0.2F); - this.gm.setMoveForward(this.gm.getMoveForward() * 0.2F); + this.client.setMoveStrafe(this.client.getMoveStrafe() * 0.2F); + this.client.setMoveForward(this.client.getMoveForward() * 0.2F); this.sprintToggleTimer = 0; } @@ -2357,9 +2356,9 @@ public abstract class EntityNPC extends EntityLiving this.pushOutOfBlocks(this.posX + (double)this.width * 0.35D, this.getEntityBoundingBox().minY + 0.5D, this.posZ + (double)this.width * 0.35D); boolean canSprint = true; // (float)this.getFoodStats().getFoodLevel() > 6.0F || this.allowFlying; - if (this.onGround && !flag1 && !flag2 && this.gm.getMoveForward() >= f && !this.isSprinting() && canSprint && !this.isUsingItem() && !this.hasEffect(Potion.BLINDNESS)) + if (this.onGround && !flag1 && !flag2 && this.client.getMoveForward() >= f && !this.isSprinting() && canSprint && !this.isUsingItem() && !this.hasEffect(Potion.BLINDNESS)) { - if (this.sprintToggleTimer <= 0 && !this.gm.isSprinting()) + if (this.sprintToggleTimer <= 0 && !this.client.isSprinting()) { this.sprintToggleTimer = 7; } @@ -2369,12 +2368,12 @@ public abstract class EntityNPC extends EntityLiving } } - if (!this.isSprinting() && this.gm.getMoveForward() >= f && canSprint && !this.isUsingItem() && !this.hasEffect(Potion.BLINDNESS) && this.gm.isSprinting()) + if (!this.isSprinting() && this.client.getMoveForward() >= f && canSprint && !this.isUsingItem() && !this.hasEffect(Potion.BLINDNESS) && this.client.isSprinting()) { this.setSprinting(true); } - if (this.isSprinting() && (this.gm.getMoveForward() < f || this.collidedHorizontally || !canSprint)) + if (this.isSprinting() && (this.client.getMoveForward() < f || this.collidedHorizontally || !canSprint)) { this.setSprinting(false); } @@ -2386,10 +2385,10 @@ public abstract class EntityNPC extends EntityLiving if (!this.flying) { this.flying = true; - this.sendQueue.addToSendQueue(new CPacketAction(CPacketAction.Action.START_FLYING)); + this.client.addToSendQueue(new CPacketAction(CPacketAction.Action.START_FLYING)); } } - else if (!flag && this.gm.isJumping()) + else if (!flag && this.client.isJumping()) { if (this.flyToggleTimer == 0) { @@ -2398,7 +2397,7 @@ public abstract class EntityNPC extends EntityLiving else { this.flying = !this.flying; - this.sendQueue.addToSendQueue(new CPacketAction(this.flying ? + this.client.addToSendQueue(new CPacketAction(this.flying ? CPacketAction.Action.START_FLYING : CPacketAction.Action.STOP_FLYING)); this.flyToggleTimer = 0; } @@ -2409,15 +2408,15 @@ public abstract class EntityNPC extends EntityLiving } // this.firstEffectUpdate = false; - if (this.isFlying() && this.isCurrentViewEntity()) + if (this.isFlying() && this.client.isRenderViewEntity(this)) { - if (this.gm.isSneaking()) + if (this.client.isSneaking()) { this.motionY -= (double)( this.landMovement * 0.5f * (this.canFlyFullSpeed() ? 3.0F : 1.0F)); } - if (this.gm.isJumping()) + if (this.client.isJumping()) { this.motionY += (double)( this.landMovement * 0.5f * (this.canFlyFullSpeed() ? 3.0F : 1.0F)); @@ -2436,12 +2435,12 @@ public abstract class EntityNPC extends EntityLiving } } - if (flag && !this.gm.isJumping()) + if (flag && !this.client.isJumping()) { this.horseJumpPowerCounter = -10; this.sendHorseJump(); } - else if (!flag && this.gm.isJumping()) + else if (!flag && this.client.isJumping()) { this.horseJumpPowerCounter = 0; this.horseJumpPower = 0.0F; @@ -2471,12 +2470,12 @@ public abstract class EntityNPC extends EntityLiving if (this.onGround && this.flying && !this.noclip) { this.flying = false; - this.sendQueue.addToSendQueue(new CPacketAction(CPacketAction.Action.STOP_FLYING)); + this.client.addToSendQueue(new CPacketAction(CPacketAction.Action.STOP_FLYING)); } return; } - if(this.gm != null) { + if(this.slave) { if (this.otherPlayerMPPosRotationIncrements > 0) { double d0 = this.posX + (this.otherPlayerMPX - this.posX) / (double)this.otherPlayerMPPosRotationIncrements; @@ -2628,11 +2627,11 @@ public abstract class EntityNPC extends EntityLiving { if (flag) { - this.sendQueue.addToSendQueue(new CPacketAction(CPacketAction.Action.START_SPRINTING)); + this.client.addToSendQueue(new CPacketAction(CPacketAction.Action.START_SPRINTING)); } else { - this.sendQueue.addToSendQueue(new CPacketAction(CPacketAction.Action.STOP_SPRINTING)); + this.client.addToSendQueue(new CPacketAction(CPacketAction.Action.STOP_SPRINTING)); } this.serverSprintState = flag; @@ -2644,17 +2643,17 @@ public abstract class EntityNPC extends EntityLiving { if (flag1) { - this.sendQueue.addToSendQueue(new CPacketAction(CPacketAction.Action.START_SNEAKING)); + this.client.addToSendQueue(new CPacketAction(CPacketAction.Action.START_SNEAKING)); } else { - this.sendQueue.addToSendQueue(new CPacketAction(CPacketAction.Action.STOP_SNEAKING)); + this.client.addToSendQueue(new CPacketAction(CPacketAction.Action.STOP_SNEAKING)); } this.serverSneakState = flag1; } - if (this.isCurrentViewEntity()) + if (this.client.isRenderViewEntity(this)) { double d0 = this.posX - this.lastReportedPosX; double d1 = this.getEntityBoundingBox().minY - this.lastReportedPosY; @@ -2668,24 +2667,24 @@ public abstract class EntityNPC extends EntityLiving { if (flag2 && flag3) { - this.sendQueue.addToSendQueue(new CPacketPlayer.C06PacketPlayerPosLook(this.posX, this.getEntityBoundingBox().minY, this.posZ, this.rotYaw, this.rotPitch, this.onGround)); + this.client.addToSendQueue(new CPacketPlayer.C06PacketPlayerPosLook(this.posX, this.getEntityBoundingBox().minY, this.posZ, this.rotYaw, this.rotPitch, this.onGround)); } else if (flag2) { - this.sendQueue.addToSendQueue(new CPacketPlayer.C04PacketPlayerPosition(this.posX, this.getEntityBoundingBox().minY, this.posZ, this.onGround)); + this.client.addToSendQueue(new CPacketPlayer.C04PacketPlayerPosition(this.posX, this.getEntityBoundingBox().minY, this.posZ, this.onGround)); } else if (flag3) { - this.sendQueue.addToSendQueue(new CPacketPlayer.C05PacketPlayerLook(this.rotYaw, this.rotPitch, this.onGround)); + this.client.addToSendQueue(new CPacketPlayer.C05PacketPlayerLook(this.rotYaw, this.rotPitch, this.onGround)); } else { - this.sendQueue.addToSendQueue(new CPacketPlayer(this.onGround)); + this.client.addToSendQueue(new CPacketPlayer(this.onGround)); } } else { - this.sendQueue.addToSendQueue(new CPacketPlayer.C06PacketPlayerPosLook(this.motionX, -999.0D, this.motionZ, this.rotYaw, this.rotPitch, this.onGround)); + this.client.addToSendQueue(new CPacketPlayer.C06PacketPlayerPosLook(this.motionX, -999.0D, this.motionZ, this.rotYaw, this.rotPitch, this.onGround)); flag2 = false; } @@ -2709,7 +2708,7 @@ public abstract class EntityNPC extends EntityLiving public void respawnPlayer() { - this.sendQueue.addToSendQueue(new CPacketAction(CPacketAction.Action.PERFORM_RESPAWN)); + this.client.addToSendQueue(new CPacketAction(CPacketAction.Action.PERFORM_RESPAWN)); } // public void closeScreenAndDropStack() @@ -2756,12 +2755,12 @@ public abstract class EntityNPC extends EntityLiving protected void sendHorseJump() { - this.sendQueue.addToSendQueue(new CPacketAction(CPacketAction.Action.RIDING_JUMP, (int)(this.getHorseJumpPower() * 100.0F))); + this.client.addToSendQueue(new CPacketAction(CPacketAction.Action.RIDING_JUMP, (int)(this.getHorseJumpPower() * 100.0F))); } public void sendHorseInventory() { - this.sendQueue.addToSendQueue(new CPacketAction(CPacketAction.Action.OPEN_INVENTORY)); + this.client.addToSendQueue(new CPacketAction(CPacketAction.Action.OPEN_INVENTORY)); } /** @@ -2794,13 +2793,10 @@ public abstract class EntityNPC extends EntityLiving public void displayTradeGui(String title) { - this.sendQueue.displayGuiMerchant(title, this.inventory, this.worldObj); + this.client.displayGuiMerchant(title, this.inventory, this.worldObj); } - protected boolean isCurrentViewEntity() - { - return this.gm.getRenderViewEntity() == this; - } + // END SP SPEC @@ -2808,7 +2804,7 @@ public abstract class EntityNPC extends EntityLiving public void setPositionAndRotation2(double x, double y, double z, float yaw, float pitch, int posRotationIncrements, boolean p_180426_10_) { - if(this.gm != null && this.sendQueue == null) { + if(this.slave && this.client == null) { this.otherPlayerMPX = x; this.otherPlayerMPY = y; this.otherPlayerMPZ = z; @@ -2823,7 +2819,7 @@ public abstract class EntityNPC extends EntityLiving public void setItem(int slot, ItemStack stack) { - if(this.gm != null && this.sendQueue == null) { + if(this.slave && this.client == null) { if (slot == 0) this.inventory.mainInventory[this.inventory.currentItem] = stack; else @@ -2893,7 +2889,7 @@ public abstract class EntityNPC extends EntityLiving this.noPickup = true; super.onDeath(cause); - if(this.gm != null) { + if(this.slave) { this.changeSize(0.2F, 0.2F); this.setPosition(this.posX, this.posY, this.posZ); this.motionY = 0.10000000149011612D; @@ -3010,8 +3006,8 @@ public abstract class EntityNPC extends EntityLiving this.connection.updateEffectMeta(); } - public final WorldServer getServerWorld() { - return (WorldServer)this.worldObj; + public final AWorldServer getServerWorld() { + return (AWorldServer)this.worldObj; } public void onUpdateEntity() { diff --git a/common/src/common/entity/npc/EntitySlime.java b/common/src/common/entity/npc/EntitySlime.java index ee08d9c..5a8dcf1 100755 --- a/common/src/common/entity/npc/EntitySlime.java +++ b/common/src/common/entity/npc/EntitySlime.java @@ -17,7 +17,7 @@ import common.util.BlockPos; import common.util.ExtMath; import common.world.Chunk; import common.world.World; -import common.world.WorldServer; +import common.world.AWorldServer; public class EntitySlime extends EntityNPC { @@ -373,7 +373,7 @@ public class EntitySlime extends EntityNPC // } - public static Random getRandomWithSeed(WorldServer world, int xPosition, int zPosition, long seed) + public static Random getRandomWithSeed(AWorldServer world, int xPosition, int zPosition, long seed) { return new Random(world.getSeed() + (long)(xPosition * xPosition * 4987142) + (long)(xPosition * 5947611) + @@ -403,7 +403,7 @@ public class EntitySlime extends EntityNPC return super.getCanSpawnHere(); } - if (this.rand.zrange(10) == 0 && getRandomWithSeed((WorldServer)this.worldObj, chunk.xPos, chunk.zPos, 987234911L).zrange(10) == 0 && this.posY < 40.0D) + if (this.rand.zrange(10) == 0 && getRandomWithSeed((AWorldServer)this.worldObj, chunk.xPos, chunk.zPos, 987234911L).zrange(10) == 0 && this.posY < 40.0D) { return super.getCanSpawnHere(); } diff --git a/common/src/common/entity/npc/EntityUndead.java b/common/src/common/entity/npc/EntityUndead.java index c87135b..af39d58 100755 --- a/common/src/common/entity/npc/EntityUndead.java +++ b/common/src/common/entity/npc/EntityUndead.java @@ -8,7 +8,7 @@ import common.init.Items; import common.item.ItemStack; import common.rng.Random; import common.world.World; -import common.world.WorldServer; +import common.world.AWorldServer; public class EntityUndead extends EntityNPC { @@ -107,7 +107,7 @@ public class EntityUndead extends EntityNPC } public boolean getCanSpawnHere() { - return !((WorldServer)this.worldObj).isDaytime(); + return !((AWorldServer)this.worldObj).isDaytime(); } // public boolean canAmbush(EntityLiving entity) { diff --git a/common/src/common/entity/npc/EntityZombie.java b/common/src/common/entity/npc/EntityZombie.java index 5d8b152..a38a61f 100755 --- a/common/src/common/entity/npc/EntityZombie.java +++ b/common/src/common/entity/npc/EntityZombie.java @@ -14,7 +14,7 @@ import common.rng.Random; import common.util.BlockPos; import common.util.ExtMath; import common.world.World; -import common.world.WorldServer; +import common.world.AWorldServer; public class EntityZombie extends EntityNPC { @@ -325,7 +325,7 @@ public class EntityZombie extends EntityNPC } public boolean getCanSpawnHere() { - return !((WorldServer)this.worldObj).isDaytime(); + return !((AWorldServer)this.worldObj).isDaytime(); } // public boolean canAmbush(EntityLiving entity) { diff --git a/common/src/common/entity/projectile/EntityHook.java b/common/src/common/entity/projectile/EntityHook.java index 318976c..8c811aa 100755 --- a/common/src/common/entity/projectile/EntityHook.java +++ b/common/src/common/entity/projectile/EntityHook.java @@ -25,7 +25,7 @@ import common.util.ExtMath; import common.util.HitPosition; import common.util.Vec3; import common.world.World; -import common.world.WorldServer; +import common.world.AWorldServer; import common.worldgen.LootConstants; public class EntityHook extends Entity implements IObjectData @@ -385,7 +385,7 @@ public class EntityHook extends Entity implements IObjectData if (!this.worldObj.client && d10 > 0.0D) { - WorldServer worldserver = (WorldServer)this.worldObj; + AWorldServer worldserver = (AWorldServer)this.worldObj; int l = 1; BlockPos blockpos = (new BlockPos(this)).up(); diff --git a/common/src/common/entity/types/EntityLiving.java b/common/src/common/entity/types/EntityLiving.java index 58347ac..117a3fd 100755 --- a/common/src/common/entity/types/EntityLiving.java +++ b/common/src/common/entity/types/EntityLiving.java @@ -66,7 +66,7 @@ import common.util.ExtMath; import common.util.Vec3; import common.world.State; import common.world.World; -import common.world.WorldServer; +import common.world.AWorldServer; public abstract class EntityLiving extends Entity { @@ -234,7 +234,7 @@ public abstract class EntityLiving extends Entity } int i = (int)(150.0D * d0); - ((WorldServer)this.worldObj).spawnParticle(ParticleType.BLOCK_DUST, this.posX, this.posY, this.posZ, i, 0.0D, 0.0D, 0.0D, 0.15000000596046448D, BlockRegistry.getStateId(iblockstate)); + ((AWorldServer)this.worldObj).spawnParticle(ParticleType.BLOCK_DUST, this.posX, this.posY, this.posZ, i, 0.0D, 0.0D, 0.0D, 0.15000000596046448D, BlockRegistry.getStateId(iblockstate)); } } @@ -1433,9 +1433,9 @@ public abstract class EntityLiving extends Entity this.swingTimer = -1; this.swingingItem = true; - if (this.worldObj instanceof WorldServer) + if (this.worldObj instanceof AWorldServer) { - ((WorldServer)this.worldObj).sendToAllTrackingEntity(this, new SPacketAnimation(this, 0)); + ((AWorldServer)this.worldObj).sendToAllTrackingEntity(this, new SPacketAnimation(this, 0)); } } } @@ -1898,7 +1898,7 @@ public abstract class EntityLiving extends Entity // // if (!ItemStack.areItemStacksEqual(itemstack1, itemstack)) // { -// ((WorldServer)this.worldObj).sendToAllTrackingEntity(this, new SPacketEntityEquipment(this.getId(), j, itemstack1)); +// ((IWorldServer)this.worldObj).sendToAllTrackingEntity(this, new SPacketEntityEquipment(this.getId(), j, itemstack1)); // // if (itemstack != null) // { @@ -2219,7 +2219,7 @@ public abstract class EntityLiving extends Entity { if (!entity.dead && !this.worldObj.client) { - WorldServer world = ((WorldServer)this.worldObj); + AWorldServer world = ((AWorldServer)this.worldObj); if (entity instanceof EntityItem) { @@ -2551,7 +2551,7 @@ public abstract class EntityLiving extends Entity if(receiver != null) receiver.addFeed(kill); if(forAll) - for(IPlayer player : ((WorldServer)this.worldObj).getServer().getIPlayers()) { + for(IPlayer player : ((AWorldServer)this.worldObj).getAllPlayers()) { if(player != receiver) player.addFeed(msg); } @@ -3093,8 +3093,8 @@ public abstract class EntityLiving extends Entity this.dropItem(Items.lead, 1); } - if(!this.worldObj.client && pkt && this.worldObj instanceof WorldServer) { - ((WorldServer)this.worldObj).sendToAllTrackingEntity(this, new S1BPacketEntityAttach(1, this, (Entity)null)); + if(!this.worldObj.client && pkt && this.worldObj instanceof AWorldServer) { + ((AWorldServer)this.worldObj).sendToAllTrackingEntity(this, new S1BPacketEntityAttach(1, this, (Entity)null)); } } } @@ -3115,8 +3115,8 @@ public abstract class EntityLiving extends Entity this.leashed = true; this.leashedTo = entity; - if(!this.worldObj.client && pkt && this.worldObj instanceof WorldServer) { - ((WorldServer)this.worldObj).sendToAllTrackingEntity(this, new S1BPacketEntityAttach(1, this, this.leashedTo)); + if(!this.worldObj.client && pkt && this.worldObj instanceof AWorldServer) { + ((AWorldServer)this.worldObj).sendToAllTrackingEntity(this, new S1BPacketEntityAttach(1, this, this.leashedTo)); } } diff --git a/common/src/common/entity/types/EntityThrowable.java b/common/src/common/entity/types/EntityThrowable.java index 2833d82..e325a29 100755 --- a/common/src/common/entity/types/EntityThrowable.java +++ b/common/src/common/entity/types/EntityThrowable.java @@ -358,11 +358,11 @@ public abstract class EntityThrowable extends Entity implements IProjectile // { // this.thrower = this.worldObj.getPlayer(this.throwerName); -// if (this.thrower == null && this.worldObj instanceof WorldServer) +// if (this.thrower == null && this.worldObj instanceof IWorldServer) // { // try // { -// Entity entity = ((WorldServer)this.worldObj).getEntityFromUuid(UUID.fromString(this.throwerName)); +// Entity entity = ((IWorldServer)this.worldObj).getEntityFromUuid(UUID.fromString(this.throwerName)); // // if (entity instanceof EntityLivingBase) // { diff --git a/common/src/common/entity/types/IEntityFX.java b/common/src/common/entity/types/IEntityFX.java deleted file mode 100644 index 2676179..0000000 --- a/common/src/common/entity/types/IEntityFX.java +++ /dev/null @@ -1,9 +0,0 @@ -package common.entity.types; - -public interface IEntityFX { - - IEntityFX multiplyVelocity(float multiplier); - - void setRBGColorF(float particleRedIn, float particleGreenIn, float particleBlueIn); - -} \ No newline at end of file diff --git a/common/src/common/init/Config.java b/common/src/common/init/Config.java index ca82a82..3393db2 100755 --- a/common/src/common/init/Config.java +++ b/common/src/common/init/Config.java @@ -6,30 +6,21 @@ import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; import java.lang.reflect.Field; -import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Modifier; import java.util.Map; import java.util.TreeMap; -import common.IServer; -import common.packet.SPacketWorld; import common.util.ExtMath; -import common.world.WorldServer; public abstract class Config { public static enum ValueType { STRING, BOOLEAN, INTEGER, FLOAT; } - private static interface Callback { - void run(IServer server); - } - @Target(FIELD) @Retention(value = RetentionPolicy.RUNTIME) private static @interface Var { String name(); - Class callback() default Callback.class; float min() default (float)Integer.MIN_VALUE; float max() default (float)Integer.MAX_VALUE; } @@ -40,7 +31,8 @@ public abstract class Config { private final Field field; private final float min; private final float max; - private final Callback callback; + + private Runnable callback; private Value(Field field, Var value) { this.type = field.getType() == int.class ? ValueType.INTEGER : (field.getType() == boolean.class ? ValueType.BOOLEAN : @@ -55,18 +47,18 @@ public abstract class Config { this.max = (this.type == ValueType.INTEGER || this.type == ValueType.FLOAT) ? value.max() : (this.type == ValueType.BOOLEAN ? 1 : 0); // Update update = this.field.getAnnotation(Update.class); - if(value.callback() == Callback.class) { - this.callback = null; - } - else { - try { - this.callback = value.callback().getConstructor().newInstance(); - } - catch(InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException - | NoSuchMethodException e) { - throw new RuntimeException(e); - } - } +// if(value.callback() == Callback.class) { +// this.callback = null; +// } +// else { +// try { +// this.callback = value.callback().getConstructor().newInstance(); +// } +// catch(InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException +// | NoSuchMethodException e) { +// throw new RuntimeException(e); +// } +// } this.setValue(this.def); } @@ -181,7 +173,7 @@ public abstract class Config { public static boolean objectDrop = true; @Var(name = "naturalRegeneration") public static boolean regeneration = true; - @Var(name = "daylightCycle", callback = WorldCallback.class) + @Var(name = "daylightCycle") public static boolean dayCycle = true; @Var(name = "weatherChanges") public static boolean weather = true; @@ -410,7 +402,7 @@ public abstract class Config { public static int pistonLimit = 16; @Var(name = "gravelFlintChance") public static int flintChance = 10; - @Var(name = "timeFlow", callback = WorldCallback.class) + @Var(name = "timeFlow") public static int timeFlow = 1; @Var(name = "emptyTicks") public static int unloadTicks = 1200; @@ -446,7 +438,7 @@ public abstract class Config { public static int orbDamageOther = 0; @Var(name = "weatherChance") public static int weatherChance = 48000; - @Var(name = "viewDistance", min = 2, max = 128, callback = DistanceCallback.class) + @Var(name = "viewDistance", min = 2, max = 128) public static int distance = 10; @Var(name = "healChance") public static int healChance = 5; @@ -472,7 +464,7 @@ public abstract class Config { // @Var(name = "spawnDim") // public static int spawnDim = 0; - @Var(name = "gravity", callback = WorldCallback.class) + @Var(name = "gravity") public static float gravity = 1.0f; @Var(name = "knockback") public static float knockback = 1.0f; @@ -505,29 +497,19 @@ public abstract class Config { value.setValue(value.def); } } + + public static void setCallback(Runnable callback, String ... vars) { + for(String key : vars) { + VARS.get(key).callback = callback; + } + } - public static void set(String key, String value, IServer server) { + public static void set(String key, String value, boolean update) { Config.Value vl = VARS.get(key); if(vl != null) { vl.setValue(value); - if(server != null && vl.callback != null) - vl.callback.run(server); - } - } - - public static class WorldCallback implements Callback { - public void run(IServer server) { - for(WorldServer world : server.getWorlds()) { - world.updatePhysics(); - } - server.sendPacket(new SPacketWorld(WorldServer.clampGravity(), Config.dayCycle, Config.timeFlow)); - } - } - public static class DistanceCallback implements Callback { - public void run(IServer server) { - for(WorldServer world : server.getWorlds()) { - world.updateViewRadius(); - } + if(update && vl.callback != null) + vl.callback.run(); } } } diff --git a/common/src/common/item/ItemBanHammer.java b/common/src/common/item/ItemBanHammer.java index e9c61ff..17d20c1 100755 --- a/common/src/common/item/ItemBanHammer.java +++ b/common/src/common/item/ItemBanHammer.java @@ -8,14 +8,14 @@ import common.entity.npc.EntityNPC; import common.entity.types.EntityLiving; import common.util.BoundingBox; import common.util.Vec3; -import common.world.WorldServer; +import common.world.AWorldServer; public class ItemBanHammer extends ItemWand { public ItemBanHammer() { this.setColor(TextColor.DRED); } - public void onUse(ItemStack stack, EntityNPC player, WorldServer world, Vec3 vec) { + public void onUse(ItemStack stack, EntityNPC player, AWorldServer world, Vec3 vec) { List list = world.getEntitiesWithinAABB(EntityLiving.class, new BoundingBox( vec.xCoord - 3.5, vec.yCoord - 3.5, vec.zCoord - 3.5, vec.xCoord + 3.5, vec.yCoord + 3.5, vec.zCoord + 3.5)); for(EntityLiving entity : list) { diff --git a/common/src/common/item/ItemBucket.java b/common/src/common/item/ItemBucket.java index b718e5b..2cd1821 100755 --- a/common/src/common/item/ItemBucket.java +++ b/common/src/common/item/ItemBucket.java @@ -28,14 +28,14 @@ import common.util.HitPosition; import common.util.Vec3i; import common.world.State; import common.world.World; -import common.world.WorldServer; +import common.world.AWorldServer; public class ItemBucket extends Item { private final boolean recursive; private final BlockDynamicLiquid liquid; - private static boolean test(WorldServer world, BlockPos pos, Set blocks, int max, BlockPos origin, int radius) { + private static boolean test(AWorldServer world, BlockPos pos, Set blocks, int max, BlockPos origin, int radius) { if(pos.getY() < 0 || pos.getY() > max) return false; if(pos.getX() < origin.getX() - radius || pos.getX() > origin.getX() + radius) @@ -48,7 +48,7 @@ public class ItemBucket extends Item return blocks == null ? block instanceof BlockLiquid : blocks.contains(block); } - private static void setRecursive(WorldServer world, BlockPos origin, int radius, BlockStaticLiquid liquid) { + private static void setRecursive(AWorldServer world, BlockPos origin, int radius, BlockStaticLiquid liquid) { Queue queue = new ArrayDeque(); Set visited = new HashSet(); List dirs = new ArrayList(); @@ -162,7 +162,7 @@ public class ItemBucket extends Item if(this.recursive) { if (material.isLiquid()) { if(!worldIn.client) - setRecursive((WorldServer)worldIn, blockpos, 4, null); + setRecursive((AWorldServer)worldIn, blockpos, 4, null); // playerIn.triggerAchievement(StatRegistry.objectUseStats[ItemRegistry.getIdFromItem(this)]); // if(!playerIn.creative) --itemStackIn.stackSize; @@ -272,7 +272,7 @@ public class ItemBucket extends Item if(this.recursive) { if(!worldIn.client) - setRecursive((WorldServer)worldIn, pos, 4, FluidRegistry.getStaticBlock(this.liquid)); + setRecursive((AWorldServer)worldIn, pos, 4, FluidRegistry.getStaticBlock(this.liquid)); } else { worldIn.setState(pos, this.liquid.getState(), 3); diff --git a/common/src/common/item/ItemDye.java b/common/src/common/item/ItemDye.java index 0849a20..c42120e 100755 --- a/common/src/common/item/ItemDye.java +++ b/common/src/common/item/ItemDye.java @@ -21,7 +21,7 @@ import common.util.BlockPos; import common.util.Facing; import common.world.State; import common.world.World; -import common.world.WorldServer; +import common.world.AWorldServer; public class ItemDye extends Item { @@ -159,7 +159,7 @@ public class ItemDye extends Item { if (igrowable.canUseBonemeal(worldIn, worldIn.rand, target, iblockstate)) { - igrowable.grow((WorldServer)worldIn, worldIn.rand, target, iblockstate); + igrowable.grow((AWorldServer)worldIn, worldIn.rand, target, iblockstate); } --stack.stackSize; diff --git a/common/src/common/item/ItemExterminator.java b/common/src/common/item/ItemExterminator.java index 6892a5d..cd5287d 100755 --- a/common/src/common/item/ItemExterminator.java +++ b/common/src/common/item/ItemExterminator.java @@ -5,7 +5,7 @@ import common.dimension.Space; import common.entity.npc.EntityNPC; import common.init.SoundEvent; import common.world.World; -import common.world.WorldServer; +import common.world.AWorldServer; public class ItemExterminator extends ItemMagnetic { public ItemExterminator() { @@ -22,7 +22,7 @@ public class ItemExterminator extends ItemMagnetic { world.playSoundAtEntity(player, SoundEvent.CLICK, 1.0F); if(world.dimension == Space.INSTANCE) player.connection.addHotbar(TextColor.RED + "Der Weltraum kann nicht zerstört werden (lol)"); - else if(!((WorldServer)world).exterminate()) + else if(!((AWorldServer)world).exterminate()) player.connection.addHotbar(TextColor.YELLOW + "Die Welt %s ist bereits zerstört", world.dimension.getFormattedName(false)); else player.connection.addHotbar(TextColor.CRIMSON + "Die Welt %s wurde vernichtet >:)-", world.dimension.getFormattedName(false)); diff --git a/common/src/common/item/ItemInfoWand.java b/common/src/common/item/ItemInfoWand.java index 8cf4c33..6370462 100755 --- a/common/src/common/item/ItemInfoWand.java +++ b/common/src/common/item/ItemInfoWand.java @@ -5,14 +5,14 @@ import common.color.TextColor; import common.entity.npc.EntityNPC; import common.util.BlockPos; import common.util.Vec3; -import common.world.WorldServer; +import common.world.AWorldServer; public class ItemInfoWand extends ItemWand { public ItemInfoWand() { this.setColor(TextColor.BLUE); } - public void onUse(ItemStack stack, EntityNPC player, WorldServer world, Vec3 vec) + public void onUse(ItemStack stack, EntityNPC player, AWorldServer world, Vec3 vec) { Biome biome = world.getBiomeGenForCoords(new BlockPos(vec.xCoord, 0, vec.zCoord)); player.connection.addHotbar(TextColor.NEON + "* Position bei Level %d: %.3f %.3f %.3f, %s [%d], %.2f °C", world.dimension.getDimensionId(), diff --git a/common/src/common/item/ItemLightning.java b/common/src/common/item/ItemLightning.java index 68a4779..5e2e23b 100755 --- a/common/src/common/item/ItemLightning.java +++ b/common/src/common/item/ItemLightning.java @@ -3,14 +3,14 @@ package common.item; import common.color.TextColor; import common.entity.npc.EntityNPC; import common.util.Vec3; -import common.world.WorldServer; +import common.world.AWorldServer; public class ItemLightning extends ItemWand { public ItemLightning() { this.setColor(TextColor.NEON); } - public void onUse(ItemStack stack, EntityNPC player, WorldServer world, Vec3 vec) + public void onUse(ItemStack stack, EntityNPC player, AWorldServer world, Vec3 vec) { if(player.useMana(5)) world.strikeLightning(vec.xCoord - 0.5, vec.yCoord, vec.zCoord - 0.5, 0x532380, 230, true, player); diff --git a/common/src/common/item/ItemWand.java b/common/src/common/item/ItemWand.java index 880f6c8..8b69b69 100755 --- a/common/src/common/item/ItemWand.java +++ b/common/src/common/item/ItemWand.java @@ -10,7 +10,7 @@ import common.util.ExtMath; import common.util.Facing; import common.util.Vec3; import common.world.World; -import common.world.WorldServer; +import common.world.AWorldServer; public abstract class ItemWand extends Item { public ItemWand() { @@ -38,7 +38,7 @@ public abstract class ItemWand extends Item { // { // if(playerIn.worldObj.client) // return true; -// this.onUse(stack, (EntityNPCMP)playerIn, (WorldServer)playerIn.worldObj, new Vec3(target.posX, target.posY + target.height / 2.0, target.posZ)); +// this.onUse(stack, (EntityNPCMP)playerIn, (IWorldServer)playerIn.worldObj, new Vec3(target.posX, target.posY + target.height / 2.0, target.posZ)); // return true; // } @@ -46,7 +46,7 @@ public abstract class ItemWand extends Item { if(control == ItemControl.SECONDARY && !world.client && block == null) { BlockPos vec = world.getBlockTrace(player, this.getRange(stack, player)); if(vec != null) - this.onUse(stack, player, (WorldServer)world, new Vec3( + this.onUse(stack, player, (AWorldServer)world, new Vec3( ExtMath.floord(vec.getX()) + 0.5, ExtMath.floord(vec.getY()) + 1.0, ExtMath.floord(vec.getZ()) + 0.5)); } return control == ItemControl.SECONDARY; @@ -58,7 +58,7 @@ public abstract class ItemWand extends Item { // EntityNPCMP entity = (EntityNPCMP)player; if(pos != null) { // pos = side.getAxisDirection() == AxisDirection.NEGATIVE ? pos.offset(side) : pos; - this.onUse(stack, player, (WorldServer)world, new Vec3(pos.getX() + hitX, pos.getY() + hitY, pos.getZ() + hitZ)); + this.onUse(stack, player, (AWorldServer)world, new Vec3(pos.getX() + hitX, pos.getY() + hitY, pos.getZ() + hitZ)); } return true; } @@ -71,12 +71,12 @@ public abstract class ItemWand extends Item { // public boolean hitEntity(ItemStack stack, EntityLivingBase target, EntityLivingBase attacker) { // if(attacker.worldObj.client) // return true; -// this.onUse(stack, (EntityNPCMP)attacker, (WorldServer)attacker.worldObj, new Vec3(target.posX, target.posY + target.height / 2.0, target.posZ)); +// this.onUse(stack, (EntityNPCMP)attacker, (IWorldServer)attacker.worldObj, new Vec3(target.posX, target.posY + target.height / 2.0, target.posZ)); // return true; // } public abstract int getRange(ItemStack stack, EntityNPC player); - public abstract void onUse(ItemStack stack, EntityNPC player, WorldServer world, Vec3 vec); + public abstract void onUse(ItemStack stack, EntityNPC player, AWorldServer world, Vec3 vec); public Transforms getTransform() { return Transforms.TOOL; diff --git a/common/src/common/item/ItemWeatherToken.java b/common/src/common/item/ItemWeatherToken.java index 50ddb53..ccb48e4 100755 --- a/common/src/common/item/ItemWeatherToken.java +++ b/common/src/common/item/ItemWeatherToken.java @@ -5,7 +5,7 @@ import common.entity.npc.EntityNPC; import common.init.SoundEvent; import common.world.Weather; import common.world.World; -import common.world.WorldServer; +import common.world.AWorldServer; public class ItemWeatherToken extends ItemMagnetic { private final Weather weather; @@ -24,7 +24,7 @@ public class ItemWeatherToken extends ItemMagnetic { worldIn.playSoundAtEntity(playerIn, SoundEvent.SPELL, 0.5F); if (!worldIn.client) { - WorldServer world = (WorldServer)worldIn; + AWorldServer world = (AWorldServer)worldIn; if(!world.isExterminated()) { world.setWeather(this.weather); world.resetWeather(); diff --git a/common/src/common/network/IClientPlayer.java b/common/src/common/network/IClientPlayer.java index c5ff27d..fc6ac1d 100644 --- a/common/src/common/network/IClientPlayer.java +++ b/common/src/common/network/IClientPlayer.java @@ -1,8 +1,10 @@ package common.network; +import common.entity.Entity; import common.entity.animal.EntityHorse; import common.inventory.IInventory; import common.inventory.InventoryPlayer; +import common.model.ParticleType; import common.packet.S14PacketEntity; import common.packet.S18PacketEntityTeleport; import common.packet.S19PacketEntityHeadLook; @@ -64,258 +66,85 @@ import common.packet.SPacketTimeUpdate; import common.packet.SPacketTrades; import common.packet.SPacketUpdateHealth; import common.packet.SPacketWorld; +import common.sound.Sound; import common.tileentity.IInteractionObject; import common.util.BlockPos; import common.world.World; public interface IClientPlayer { + void playSound(Sound sound); + boolean isRenderViewEntity(Entity entity); + void updatePlayerMoveState(); + void emitParticleAtEntity(Entity entityIn, ParticleType particleTypes); + boolean isJumping(); + boolean isSprinting(); + boolean isSneaking(); + float getMoveForward(); + float getMoveStrafe(); + void setMoveForward(float value); + void setMoveStrafe(float value); void addToSendQueue(Packet packet); void handleJoinGame(SPacketJoinGame packetIn); - - /** - * Spawns an instance of the objecttype indicated by the packet and sets its position and momentum - */ void handleSpawnObject(SPacketSpawnObject packetIn); - - /** - * Handles globally visible entities. Used in vanilla for lightning bolts - */ void handleSpawnGlobalEntity(S2CPacketSpawnGlobalEntity packetIn); - - /** - * Sets the velocity of the specified entity to the specified value - */ void handleEntityVelocity(SPacketEntityVelocity packetIn); - - /** - * Invoked when the server registers new proximate objects in your watchlist or when objects in your watchlist have - * changed -> Registers any changes locally - */ void handleEntityMetadata(S1CPacketEntityMetadata packetIn); - - /** - * Handles the creation of a nearby player entity, sets the position and held item - */ void handleSpawnPlayer(SPacketSpawnPlayer packetIn); - - /** - * Updates an entity's position and rotation as specified by the packet - */ void handleEntityTeleport(S18PacketEntityTeleport packetIn); - - /** - * Updates which hotbar slot of the player is currently selected - */ void handleHeldItemChange(SPacketHeldItemChange packetIn); - - /** - * Updates the specified entity's position by the specified relative moment and absolute rotation. Note that - * subclassing of the packet allows for the specification of a subset of this data (e.g. only rel. position, abs. - * rotation or both). - */ void handleEntityMovement(S14PacketEntity packetIn); - - /** - * Updates the direction in which the specified entity is looking, normally this head rotation is independent of the - * rotation of the entity itself - */ void handleEntityHeadLook(S19PacketEntityHeadLook packetIn); - - /** - * Locally eliminates the entities. Invoked by the server when the items are in fact destroyed, or the player is no - * longer registered as required to monitor them. The latter happens when distance between the player and item - * increases beyond a certain treshold (typically the viewing distance) - */ void handleDestroyEntities(SPacketDestroyEntities packetIn); - - /** - * Handles changes in player positioning and rotation such as when travelling to a new dimension, (re)spawning, - * mounting horses etc. Seems to immediately reply to the server with the clients post-processing perspective on the - * player positioning - */ void handlePlayerPosLook(SPacketPlayerPosLook packetIn); - - /** - * Received from the servers PlayerManager if between 1 and 64 blocks in a chunk are changed. If only one block - * requires an update, the server sends S23PacketBlockChange and if 64 or more blocks are changed, the server sends - * S21PacketChunkData - */ void handleMultiBlockChange(SPacketMultiBlockChange packetIn); - - /** - * Updates the specified chunk with the supplied data, marks it for re-rendering and lighting recalculation - */ void handleChunkData(SPacketChunkData packetIn); - void handleBiomes(SPacketBiomes packetIn); - - /** - * Updates the block and metadata and generates a blockupdate (and notify the clients) - */ void handleBlockChange(SPacketBlockChange packetIn); - - /** - * Closes the network channel - */ void handleDisconnect(SPacketDisconnect packetIn); - void handleCollectItem(SPacketCollectItem packetIn); - - /** - * Prints a chatmessage in the chat GUI - */ void handleMessage(SPacketMessage packetIn); - void handleLoading(SPacketLoading packet); - - /** - * Renders a specified animation: Waking up a player, a living entity swinging its currently held item, being hurt - * or receiving a critical hit by normal or magical means - */ void handleAnimation(SPacketAnimation packetIn); - - /** - * Spawns the mob entity at the specified location, with the specified rotation, momentum and type. Updates the - * entities Datawatchers with the entity metadata specified in the packet - */ void handleSpawnMob(SPacketSpawnMob packetIn); - void handleTimeUpdate(SPacketTimeUpdate packetIn); - void handleServerTick(SPacketServerTick packet); - void handleEntityAttach(S1BPacketEntityAttach packetIn); - - /** - * Invokes the entities' handleUpdateHealth method which is implemented in LivingBase (hurt/death), - * MinecartMobSpawner (spawn delay), FireworkRocket & MinecartTNT (explosion), IronGolem (throwing,...), Witch - * (spawn particles), Zombie (villager transformation), Animal (breeding mode particles), Horse (breeding/smoke - * particles), Sheep (...), Tameable (...), Villager (particles for breeding mode, angry and happy), Wolf (...) - */ void handleEntityStatus(S1APacketEntityStatus packetIn); - void handleUpdateHealth(SPacketUpdateHealth packetIn); - void handleSetExperience(SPacketSetExperience packetIn); - void handleRespawn(SPacketRespawn packetIn); - - /** - * Initiates a new explosion (sound, particles, drop spawn) for the affected blocks indicated by the packet. - */ void handleExplosion(S27PacketExplosion packetIn); - - /** - * Displays a GUI by ID. In order starting from id 0: Chest, Workbench, Furnace, Dispenser, Enchanting table, - * Brewing stand, Villager merchant, Beacon, Anvil, Hopper, Dropper, Horse - */ void handleOpenWindow(S2DPacketOpenWindow packetIn); - - /** - * Handles pickin up an ItemStack or dropping one in your inventory or an open container - */ void handleSetSlot(S2FPacketSetSlot packetIn); - - /** - * Verifies that the server and client are synchronized with respect to the inventory/container opened by the player - * and confirms if it is the case. - */ void handleConfirmTransaction(S32PacketConfirmTransaction packetIn); - - /** - * Handles the placement of a specified ItemStack in a specified container/inventory slot - */ void handleWindowItems(S30PacketWindowItems packetIn); - - /** - * Creates a sign in the specified location if it didn't exist and opens the GUI to edit its text - */ void handleSignEditorOpen(S36PacketSignEditorOpen packetIn); - - /** - * Updates a specified sign with the specified text lines - */ void handleUpdateSign(S33PacketUpdateSign packetIn); - - /** - * Updates the NBTTagCompound metadata of instances of the following entitytypes: Mob spawners, command blocks, - * beacons, skulls, flowerpot - */ void handleUpdateTileEntity(S35PacketUpdateTileEntity packetIn); - - /** - * Sets the progressbar of the opened window to the specified value - */ void handleWindowProperty(S31PacketWindowProperty packetIn); - void handleEntityEquipment(SPacketEntityEquipment packetIn); - - /** - * Resets the ItemStack held in hand and closes the window that is opened - */ void handleCloseWindow(S2EPacketCloseWindow packetIn); - - /** - * Triggers Block.onBlockEventReceived, which is implemented in BlockPistonBase for extension/retraction, BlockNote - * for setting the instrument (including audiovisual feedback) and in BlockContainer to set the number of players - * accessing a (Ender)Chest - */ void handleBlockAction(SPacketBlockAction packetIn); - - /** - * Updates all registered IWorldAccess instances with destroyBlockInWorldPartially - */ void handleBlockBreakAnim(SPacketBlockBreakAnim packetIn); - void handleMapChunkBulk(SPacketMapChunkBulk packetIn); - void handleChangeGameState(S2BPacketChangeGameState packetIn); - void handleEffect(S28PacketEffect packetIn); - void handleEntityEffect(S1DPacketEntityEffect packetIn); - void handleCamera(SPacketCamera packetIn); - void handleRemoveEntityEffect(S1EPacketRemoveEntityEffect packetIn); - void handlePlayerListItem(S38PacketPlayerListItem packetIn); - void handleCharacterList(SPacketCharacterList packet); - void handleKeepAlive(SPacketKeepAlive packetIn); - void handlePlayerAbilities(S39PacketPlayerAbilities packetIn); - - /** - * Displays the available command-completion options the server knows of - */ void handleTabComplete(S3APacketTabComplete packetIn); - void handleSoundEffect(S29PacketSoundEffect packetIn); - void handleEntityNBT(S43PacketUpdateEntityNBT packetIn); - - /** - * Spawns a specified number of particles at the specified location with a randomized displacement according to - * specified bounds - */ void handleParticles(S2APacketParticles packetIn); - - /** - * Updates en entity's attributes and their respective modifiers, which are used for speed bonusses (player - * sprinting, animals fleeing, baby speed), weapon/tool attackDamage, hostiles followRange randomization, zombie - * maxHealth and knockback resistance as well as reinforcement spawning chance. - */ void handleEntityProperties(S20PacketEntityProperties packetIn); - void handleSkin(SPacketSkin packetIn); - void handleTrades(SPacketTrades packetIn); - void handleWorld(SPacketWorld packetIn); - void handleDimName(SPacketDimensionName packetIn); void displayGUIChest(IInventory chestInventory, InventoryPlayer inventory); diff --git a/common/src/common/packet/APacketEmpty.java b/common/src/common/packet/APacketEmpty.java deleted file mode 100755 index dfc7ceb..0000000 --- a/common/src/common/packet/APacketEmpty.java +++ /dev/null @@ -1,14 +0,0 @@ -package common.packet; - -import java.io.IOException; - -import common.network.Packet; -import common.network.PacketBuffer; - -public abstract class APacketEmpty implements Packet { - public final void readPacketData(PacketBuffer buf) throws IOException { - } - - public final void writePacketData(PacketBuffer buf) throws IOException { - } -} diff --git a/common/src/common/packet/RPacketLoginSuccess.java b/common/src/common/packet/RPacketLoginSuccess.java index 6e46fa0..a8b7837 100755 --- a/common/src/common/packet/RPacketLoginSuccess.java +++ b/common/src/common/packet/RPacketLoginSuccess.java @@ -1,11 +1,34 @@ package common.packet; -import common.network.IClientLoginHandler; +import java.io.IOException; -public class RPacketLoginSuccess extends APacketEmpty -{ - public void processPacket(IClientLoginHandler handler) - { - handler.handleLoginSuccess(this); - } +import common.network.IClientLoginHandler; +import common.network.Packet; +import common.network.PacketBuffer; + +public class RPacketLoginSuccess implements Packet { + private boolean debug; + + public RPacketLoginSuccess() { + } + + public RPacketLoginSuccess(boolean debug) { + this.debug = debug; + } + + public final void readPacketData(PacketBuffer buf) throws IOException { + this.debug = buf.readBoolean(); + } + + public final void writePacketData(PacketBuffer buf) throws IOException { + buf.writeBoolean(this.debug); + } + + public void processPacket(IClientLoginHandler handler) { + handler.handleLoginSuccess(this); + } + + public boolean isDebug() { + return this.debug; + } } diff --git a/common/src/common/tileentity/TileEntityBeacon.java b/common/src/common/tileentity/TileEntityBeacon.java index 97ffe57..e8dc19f 100755 --- a/common/src/common/tileentity/TileEntityBeacon.java +++ b/common/src/common/tileentity/TileEntityBeacon.java @@ -15,7 +15,7 @@ import common.util.BlockPos; import common.util.BoundingBox; import common.world.State; import common.world.World; -import common.world.WorldServer; +import common.world.AWorldServer; public class TileEntityBeacon extends TileEntity implements ITickable { @@ -45,7 +45,7 @@ public class TileEntityBeacon extends TileEntity implements ITickable */ public void update() { - if (!this.worldObj.client && ((WorldServer)this.worldObj).getTime() % 80L == 0L) + if (!this.worldObj.client && ((AWorldServer)this.worldObj).getTime() % 80L == 0L) { this.updateBeacon(); } diff --git a/common/src/common/tileentity/TileEntityDaylightDetector.java b/common/src/common/tileentity/TileEntityDaylightDetector.java index 02ca54d..a3518e2 100755 --- a/common/src/common/tileentity/TileEntityDaylightDetector.java +++ b/common/src/common/tileentity/TileEntityDaylightDetector.java @@ -1,7 +1,7 @@ package common.tileentity; import common.block.BlockDaylightDetector; -import common.world.WorldServer; +import common.world.AWorldServer; public class TileEntityDaylightDetector extends TileEntity implements ITickable { @@ -10,13 +10,13 @@ public class TileEntityDaylightDetector extends TileEntity implements ITickable */ public void update() { - if (this.worldObj != null && !this.worldObj.client && ((WorldServer)this.worldObj).getTime() % 20L == 0L) + if (this.worldObj != null && !this.worldObj.client && ((AWorldServer)this.worldObj).getTime() % 20L == 0L) { this.blockType = this.getBlockType(); if (this.blockType instanceof BlockDaylightDetector) { - ((BlockDaylightDetector)this.blockType).updatePower((WorldServer)this.worldObj, this.pos); + ((BlockDaylightDetector)this.blockType).updatePower((AWorldServer)this.worldObj, this.pos); } } } diff --git a/common/src/common/village/Village.java b/common/src/common/village/Village.java index adc573f..7ecc458 100755 --- a/common/src/common/village/Village.java +++ b/common/src/common/village/Village.java @@ -10,7 +10,7 @@ import common.material.Material; import common.nbt.NBTTagCompound; import common.nbt.NBTTagList; import common.util.BlockPos; -import common.world.WorldServer; +import common.world.AWorldServer; public class Village { @@ -24,17 +24,17 @@ public class Village // { // } // -// public Village(WorldServer worldIn) +// public Village(IWorldServer worldIn) // { // this.worldObj = worldIn; // } // -// public void setWorld(WorldServer worldIn) +// public void setWorld(IWorldServer worldIn) // { // this.worldObj = worldIn; // } - public void tick(WorldServer world, int counter) + public void tick(AWorldServer world, int counter) { // this.tickCounter = counter; boolean mod = false; @@ -180,7 +180,7 @@ public class Village return this.doors.isEmpty(); } - private boolean isWoodDoor(WorldServer world, BlockPos pos) + private boolean isWoodDoor(AWorldServer world, BlockPos pos) { Block block = world.getState(pos).getBlock(); return block instanceof BlockDoor ? block.getMaterial() == Material.wood : false; diff --git a/common/src/common/world/AWorldClient.java b/common/src/common/world/AWorldClient.java new file mode 100644 index 0000000..c7189f0 --- /dev/null +++ b/common/src/common/world/AWorldClient.java @@ -0,0 +1,15 @@ +package common.world; + +import common.dimension.Dimension; +import common.init.SoundEvent; +import common.nbt.NBTTagCompound; + +public abstract class AWorldClient extends World { + protected AWorldClient(Dimension dim, boolean debug) { + super(dim, true, debug); + } + + public abstract void playSound(double x, double y, double z, SoundEvent sound, float volume); + public abstract void makeFireworks(double x, double y, double z, double motionX, double motionY, double motionZ, NBTTagCompound compund); + public abstract void setLastLightning(int last, int color); +} diff --git a/common/src/common/world/AWorldServer.java b/common/src/common/world/AWorldServer.java new file mode 100644 index 0000000..5135f32 --- /dev/null +++ b/common/src/common/world/AWorldServer.java @@ -0,0 +1,62 @@ +package common.world; + +import java.util.List; + +import common.block.Block; +import common.dimension.Dimension; +import common.entity.Entity; +import common.entity.npc.EntityNPC; +import common.entity.types.EntityLiving; +import common.model.ParticleType; +import common.network.IPlayer; +import common.network.Packet; +import common.rng.Random; +import common.util.BlockPos; +import common.util.BoundingBox; +import common.util.PortalType; +import common.village.Village; +import common.worldgen.BiomeGenerator; + +public abstract class AWorldServer extends World { + protected AWorldServer(Dimension dim, boolean debug) { + super(dim, false, debug); + } + + public abstract List getAllPlayers(); + public abstract AWorldServer getOtherWorld(int dimension); + public abstract void placeInDimension(Entity entity, AWorldServer oldWorld, AWorldServer world, BlockPos pos, PortalType portal); + public abstract State getSurfaceLiquid(); + public abstract boolean addLoader(BlockPos pos); + public abstract boolean removeLoader(BlockPos pos); + public abstract BiomeGenerator getBiomeGenerator(); + public abstract boolean isBlockTickPending(BlockPos pos, Block blockType); + public abstract void updateBlockTick(BlockPos pos, Block blockIn, int delay, int priority); + public abstract void resetUpdateEntityTick(); + public abstract void strikeLightning(double x, double y, double z, int color, int damage, boolean fire, EntityLiving summoner); + public abstract void resetWeather(); + public abstract void spawnParticle(ParticleType particleType, double xCoord, double yCoord, double zCoord, int numberOfParticles, double xOffset, double yOffset, + double zOffset, double particleSpeed, int... particleArguments); + public abstract long getSeed(); + public abstract boolean isExterminated(); + public abstract boolean exterminate(); + public abstract void forceBlockUpdateTick(Block blockType, BlockPos pos, Random random); + public abstract Village getNearestVillage(BlockPos doorBlock, int radius); + public abstract void addToVillagerPositionList(BlockPos blockpos); + public abstract void removePlayer(EntityNPC player); + public abstract void updateMountedMovingPlayer(EntityNPC player); + public abstract boolean isPlayerWatchingChunk(EntityNPC player, int chunkX, int chunkZ); + public abstract void untrackEntity(Entity entityIn); + public abstract void updateTrackedPlayer(EntityNPC player); + public abstract void sendToAllTrackingEntity(Entity entityIn, Packet packet); + public abstract void sendToAllTrackingAndSelf(Entity entityIn, Packet packet); + public abstract void removePlayerFromTrackers(EntityNPC player); + public abstract void updateChunksForPlayer(EntityNPC player, Chunk chunk); + public abstract boolean isDaytime(); + public abstract int getSkylightSubtracted(); + public abstract boolean isBlockinHighHumidity(BlockPos pos); + public abstract T findNearestEntityWithinAABB(Class entityType, BoundingBox aabb, T closestTo); + public abstract boolean canBlockFreeze(BlockPos pos, boolean noWaterAdj); + public abstract BlockPos getTopSolidOrLiquidBlock(BlockPos pos); + public abstract void removePlayerEntityDangerously(Entity entityIn); + public abstract long getTime(); +} diff --git a/common/src/common/world/Chunk.java b/common/src/common/world/Chunk.java index 68f14f5..484292c 100755 --- a/common/src/common/world/Chunk.java +++ b/common/src/common/world/Chunk.java @@ -482,7 +482,7 @@ public class Chunk { if(oldb != block) { if(!this.world.client) { - oldb.onBlockRemoved((WorldServer)this.world, pos, old); + oldb.onBlockRemoved((AWorldServer)this.world, pos, old); } else if(oldb instanceof ITileEntityProvider) { this.world.removeTileEntity(pos); @@ -523,7 +523,7 @@ public class Chunk { } if(!this.world.client && oldb != block) { - block.onBlockAdded((WorldServer)this.world, pos, state); + block.onBlockAdded((AWorldServer)this.world, pos, state); } if(block instanceof ITileEntityProvider) { diff --git a/common/src/common/world/Explosion.java b/common/src/common/world/Explosion.java index c2830a2..f3c1e2f 100755 --- a/common/src/common/world/Explosion.java +++ b/common/src/common/world/Explosion.java @@ -172,7 +172,7 @@ public class Explosion worldObj.setState(blockpos, Blocks.air.getState(), 3); if(rand.chance(1000)) { worldObj.playSound(SoundEvent.EXPLODE, explosionX + x, explosionY + y, explosionZ + z, 4.0F); - ((WorldServer)worldObj).spawnParticle(ParticleType.EXPLOSION_HUGE, explosionX + x, explosionY + y, explosionZ + z, 0, rand.gaussian() * 0.02D, rand.gaussian() * 0.02D, rand.gaussian() * 0.02D, 1.0); + ((AWorldServer)worldObj).spawnParticle(ParticleType.EXPLOSION_HUGE, explosionX + x, explosionY + y, explosionZ + z, 0, rand.gaussian() * 0.02D, rand.gaussian() * 0.02D, rand.gaussian() * 0.02D, 1.0); } } } diff --git a/common/src/common/world/IWorld.java b/common/src/common/world/IWorld.java new file mode 100644 index 0000000..ef161f4 --- /dev/null +++ b/common/src/common/world/IWorld.java @@ -0,0 +1,279 @@ +package common.world; + +import java.util.Collection; +import java.util.List; +import java.util.function.Predicate; + +import common.biome.Biome; +import common.block.Block; +import common.block.LeavesType; +import common.entity.Entity; +import common.entity.item.EntityExplosion; +import common.entity.npc.EntityNPC; +import common.init.SoundEvent; +import common.item.ItemStack; +import common.model.ParticleType; +import common.tileentity.TileEntity; +import common.util.BlockPos; +import common.util.BoundingBox; +import common.util.Facing; +import common.util.HitPosition; +import common.util.Vec3; + +public interface IWorld { + + boolean isBlockSolid(BlockPos pos); + + void setGravity(float gravity); + + Biome getBiomeGenForCoords(BlockPos pos); + + boolean isAirBlock(BlockPos pos); + + boolean isBlockLoaded(BlockPos pos); + + boolean isBlockLoaded(BlockPos pos, boolean allowEmpty); + + boolean isAreaLoaded(BlockPos center, int radius); + + boolean isAreaLoaded(BlockPos center, int radius, boolean allowEmpty); + + boolean isAreaLoaded(BlockPos from, BlockPos to); + + boolean isAreaLoaded(BlockPos from, BlockPos to, boolean allowEmpty); + + Chunk getChunk(BlockPos pos); + + boolean setState(BlockPos pos, State newState, int flags); + + boolean setState(BlockPos pos, State state); + + boolean setBlockToAir(BlockPos pos); + + boolean destroyBlock(BlockPos pos, boolean dropBlock); + + void notifyNeighborsRespectDebug(BlockPos pos, Block blockType); + + void markBlocksDirtyVertical(int x1, int z1, int x2, int z2); + + void markBlockRangeForRenderUpdate(BlockPos rangeMin, BlockPos rangeMax); + + void notifyNeighborsOfStateChange(BlockPos pos, Block blockType); + + void notifyNeighborsOfStateExcept(BlockPos pos, Block blockType, Facing skipSide); + + void notifyBlockOfStateChange(BlockPos pos, Block blockIn); + + boolean canSeeSky(BlockPos pos); + + int getLight(BlockPos pos); + + int getLightFromNeighbors(BlockPos pos); + + BlockPos getHeight(BlockPos pos); + + int getChunksLowestHorizon(int x, int z); + + int getLightFromNeighborsFor(LightType type, BlockPos pos); + + int getLightFor(LightType type, BlockPos pos); + + void setLightFor(LightType type, BlockPos pos, int lightValue); + + int getCombinedLight(BlockPos pos, int lightValue); + + float getLightBrightness(BlockPos pos); + + State getState(BlockPos pos); + + BlockPos getBlockTrace(Entity entity, int distance); + + HitPosition rayTraceBlocks(Vec3 p_72933_1_, Vec3 p_72933_2_); + + HitPosition rayTraceBlocks(Vec3 start, Vec3 end, boolean stopOnLiquid); + + HitPosition rayTraceBlocks(Vec3 vec31, Vec3 vec32, boolean stopOnLiquid, boolean ignoreBlockWithoutBoundingBox, + boolean returnLastUncollidableBlock); + + void playSoundAtEntity(Entity entityIn, SoundEvent name, float volume); + + boolean spawnEntityInWorld(Entity entityIn); + + void removeEntity(Entity entityIn); + + List getCollidingBoundingBoxes(Entity entityIn, BoundingBox bb); + + List getCollisionBoxes(BoundingBox bb); + + int calculateSkylightSubtracted(boolean current); + + float getCelestialAngle(float partialTicks); + + int getMoonPhase(); + + float getCurrentMoonPhaseFactor(); + + float getCelestialAngleRadians(float partialTicks); + + BlockPos getPrecipitationHeight(BlockPos pos); + + void updateEntities(); + + boolean addTileEntity(TileEntity tile); + + void addTileEntities(Collection tileEntityCollection); + + void updateEntity(Entity entityIn, boolean forceUpdate); + + boolean checkNoEntityCollision(BoundingBox bb); + + boolean checkNoEntityCollision(BoundingBox bb, Entity entityIn); + + boolean isAnyLiquid(BoundingBox bb); + + boolean isFlammableWithin(BoundingBox bb); + + boolean handleLiquidAcceleration(BoundingBox bb, Entity entityIn); + + boolean isMaterialInMolten(BoundingBox bb); + + boolean isAABBInLiquid(BoundingBox bb); + + Explosion createExplosion(Entity entityIn, double x, double y, double z, float strength, boolean isSmoking); + + Explosion createAltExplosion(Entity entityIn, double x, double y, double z, float strength, boolean isSmoking); + + Explosion newExplosion(Entity entityIn, double x, double y, double z, float strength, boolean isFlaming, boolean isSmoking, boolean altSound); + + EntityExplosion newExplosion(double x, double y, double z, int strength); + + float getBlockDensity(Vec3 vec, BoundingBox bb); + + boolean extinguishFire(EntityNPC player, BlockPos pos, Facing side); + + TileEntity getTileEntity(BlockPos pos); + + void setTileEntity(BlockPos pos, TileEntity tileEntityIn); + + void removeTileEntity(BlockPos pos); + + void markTileEntityForRemoval(TileEntity tileEntityIn); + + float getTempOffset(); + + LeavesType getLeavesGen(BlockPos pos); + + float getTemperatureK(BlockPos pos); + + float getTemperatureC(BlockPos pos); + + boolean canFreezeAt(BlockPos pos); + + boolean canBurnAt(BlockPos pos); + + boolean doesWaterVaporize(BlockPos pos); + + boolean isLavaFaster(BlockPos pos); + + boolean canSnowAt(BlockPos pos, boolean checkLight, boolean allowLayers); + + boolean checkLight(BlockPos pos); + + boolean checkLightFor(LightType lightType, BlockPos pos); + + List getEntitiesWithinAABBExcludingEntity(Entity entityIn, BoundingBox bb); + + List getEntitiesInAABBexcluding(Entity entityIn, BoundingBox boundingBox, Predicate predicate); + + List getEntitiesWithinAABB(Class classEntity, BoundingBox bb); + + List getEntitiesWithinAABB(Class clazz, BoundingBox aabb, Predicate filter); + + Entity getEntityByID(int id); + + void markChunkDirty(BlockPos pos, TileEntity unusedTileEntity); + + void loadEntities(Collection entityCollection); + + void unloadEntities(Collection entityCollection); + + boolean canBlockBePlaced(Block blockIn, BlockPos pos, boolean p_175716_3_, Facing side, Entity entityIn, ItemStack itemStackIn); + + int getSeaLevel(); + + int getStrongPower(BlockPos pos); + + boolean isSidePowered(BlockPos pos, Facing side); + + int getRedstonePower(BlockPos pos, Facing facing); + + boolean isBlockPowered(BlockPos pos); + + int isBlockIndirectlyGettingPowered(BlockPos pos); + + EntityNPC getClosestPlayerToEntity(Entity entityIn, double distance); + + EntityNPC getClosestPlayer(double x, double y, double z, double distance); + + boolean isAnyPlayerWithinRangeAt(double x, double y, double z, double range); + + void setTimeFactor(int factor); + + void setEntityState(Entity entityIn, byte state); + + void addBlockEvent(BlockPos pos, Block blockIn, int eventID, int eventParam); + + Weather getWeather(); + + long getDayTime(); + + void setWeather(Weather weather); + + void setDayTime(long time); + + float getDarkness(); + + void setDarkness(float dark); + + float getRainStrength(); + + void setRainStrength(float strength); + + float getFogStrength(); + + void setFogStrength(float strength); + + void setTemperature(float temp); + + boolean isDark(); + + boolean isThundering(); + + boolean hasDownfall(); + + boolean isRaining(); + + boolean isRainingAt(BlockPos strikePosition, boolean wet); + + void playAuxSFX(int type, BlockPos pos, int data); + + void updateComparatorOutputLevel(BlockPos pos, Block blockIn); + + void scheduleUpdate(BlockPos pos, Block blockIn, int delay); + + void spawnParticle(ParticleType particleType, double xCoord, double yCoord, double zCoord, double xOffset, double yOffset, double zOffset, + int... data); + + Chunk getChunk(int x, int z); + + void markBlockForUpdate(BlockPos pos); + + void markBlockRangeForRenderUpdate(int x1, int y1, int z1, int x2, int y2, int z2); + + void playSound(SoundEvent sound, double x, double y, double z, float volume); + + void playAuxSFX(EntityNPC player, int sfxType, BlockPos blockPosIn, int data); + + void sendBlockBreakProgress(int breakerId, BlockPos pos, int progress); + +} \ No newline at end of file diff --git a/common/src/common/world/World.java b/common/src/common/world/World.java index 519dc36..7b66e16 100755 --- a/common/src/common/world/World.java +++ b/common/src/common/world/World.java @@ -38,7 +38,7 @@ import common.util.HitPosition; import common.util.IntHashMap; import common.util.Vec3; -public abstract class World implements IWorldAccess { +public abstract class World implements IWorldAccess, IWorld { public static final float[][] BRIGHTNESS = new float[16][16]; static { for(int l = 0; l < 16; l++) { diff --git a/common/src/common/worldgen/BlockReplacer.java b/common/src/common/worldgen/BlockReplacer.java index e45c63b..f94bab7 100755 --- a/common/src/common/worldgen/BlockReplacer.java +++ b/common/src/common/worldgen/BlockReplacer.java @@ -2,8 +2,8 @@ package common.worldgen; import common.biome.Biome; import common.rng.Random; -import common.world.WorldServer; +import common.world.AWorldServer; public interface BlockReplacer { - public void replaceBlocks(WorldServer world, int x, int z, ChunkPrimer primer, Random rand, Biome[] biomes); + public void replaceBlocks(AWorldServer world, int x, int z, ChunkPrimer primer, Random rand, Biome[] biomes); } diff --git a/common/src/common/worldgen/ChunkGenerator.java b/common/src/common/worldgen/ChunkGenerator.java index df3ae2d..6e149f1 100755 --- a/common/src/common/worldgen/ChunkGenerator.java +++ b/common/src/common/worldgen/ChunkGenerator.java @@ -1,8 +1,8 @@ package common.worldgen; -import common.world.WorldServer; +import common.world.AWorldServer; public interface ChunkGenerator { - public void generateChunk(WorldServer world, int x, int z, ChunkPrimer primer); + public void generateChunk(AWorldServer world, int x, int z, ChunkPrimer primer); public int getMaximumHeight(); } diff --git a/common/src/common/worldgen/FeatureDungeons.java b/common/src/common/worldgen/FeatureDungeons.java index 5e01ee4..cb04f19 100755 --- a/common/src/common/worldgen/FeatureDungeons.java +++ b/common/src/common/worldgen/FeatureDungeons.java @@ -12,7 +12,7 @@ import common.tileentity.TileEntityChest; import common.tileentity.TileEntityMobSpawner; import common.util.BlockPos; import common.util.Facing; -import common.world.WorldServer; +import common.world.AWorldServer; public class FeatureDungeons { @@ -25,7 +25,7 @@ public class FeatureDungeons } - public boolean generate(WorldServer worldIn, Random rand, BlockPos position) { + public boolean generate(AWorldServer worldIn, Random rand, BlockPos position) { boolean flag = false; for(int z = 0; z < this.chance; z++) { flag |= this.generateDungeon(worldIn, rand, position.add(rand.chOffset(), rand.zrange(256), rand.chOffset())); @@ -33,7 +33,7 @@ public class FeatureDungeons return flag; } - private boolean generateDungeon(WorldServer worldIn, Random rand, BlockPos position) + private boolean generateDungeon(AWorldServer worldIn, Random rand, BlockPos position) { int i = 3; int j = rand.zrange(2) + 2; diff --git a/common/src/common/worldgen/FeatureGenerator.java b/common/src/common/worldgen/FeatureGenerator.java index 19beb30..6854bce 100755 --- a/common/src/common/worldgen/FeatureGenerator.java +++ b/common/src/common/worldgen/FeatureGenerator.java @@ -3,7 +3,7 @@ package common.worldgen; import common.rng.Random; import common.util.BlockPos; import common.world.State; -import common.world.WorldServer; +import common.world.AWorldServer; public abstract class FeatureGenerator { @@ -19,9 +19,9 @@ public abstract class FeatureGenerator this.doBlockNotify = notify; } - public abstract boolean generate(WorldServer worldIn, Random rand, BlockPos position); + public abstract boolean generate(AWorldServer worldIn, Random rand, BlockPos position); - protected void setBlockAndNotifyAdequately(WorldServer worldIn, BlockPos pos, State state) + protected void setBlockAndNotifyAdequately(AWorldServer worldIn, BlockPos pos, State state) { if (this.doBlockNotify) { diff --git a/common/src/common/worldgen/FeatureLakes.java b/common/src/common/worldgen/FeatureLakes.java index 658d7d0..47f5f97 100755 --- a/common/src/common/worldgen/FeatureLakes.java +++ b/common/src/common/worldgen/FeatureLakes.java @@ -8,7 +8,7 @@ import common.rng.Random; import common.util.BlockPos; import common.world.LightType; import common.world.State; -import common.world.WorldServer; +import common.world.AWorldServer; public class FeatureLakes { @@ -47,7 +47,7 @@ public class FeatureLakes // this(block, block == Blocks.lava ? Blocks.stone.getDefaultState() : null, Blocks.dirt, Blocks.grass.getDefaultState()); // } - public boolean generate(WorldServer worldIn, Random rand, BlockPos position) { + public boolean generate(AWorldServer worldIn, Random rand, BlockPos position) { if(this.ratiod) { if(this.chance >= 1 && rand.chance(this.chance)) { int y = rand.range(this.minHeight, this.maxHeight); // rand.zrange(rand.zrange(248) + 8); @@ -63,7 +63,7 @@ public class FeatureLakes return false; } - private boolean generateLake(WorldServer worldIn, Random rand, BlockPos position) + private boolean generateLake(AWorldServer worldIn, Random rand, BlockPos position) { for (position = position.add(-8, 0, -8); position.getY() > 5 && worldIn.isAirBlock(position); position = position.down()) { diff --git a/common/src/common/worldgen/FeatureLiquids.java b/common/src/common/worldgen/FeatureLiquids.java index 900c594..e0c0e26 100755 --- a/common/src/common/worldgen/FeatureLiquids.java +++ b/common/src/common/worldgen/FeatureLiquids.java @@ -5,7 +5,7 @@ import common.material.Material; import common.rng.Random; import common.util.BlockPos; import common.world.State; -import common.world.WorldServer; +import common.world.AWorldServer; public class FeatureLiquids { @@ -40,7 +40,7 @@ public class FeatureLiquids } - public boolean generate(WorldServer worldIn, Random rand, BlockPos position) { + public boolean generate(AWorldServer worldIn, Random rand, BlockPos position) { Block replace = worldIn.dimension.getFiller().getBlock(); boolean flag = false; for(int z = 0; z < this.chance; z++) { @@ -56,7 +56,7 @@ public class FeatureLiquids return flag; } - private boolean generateLiquid(WorldServer worldIn, Random rand, BlockPos position, Block replace) + private boolean generateLiquid(AWorldServer worldIn, Random rand, BlockPos position, Block replace) { if (worldIn.getState(position.up()).getBlock() != replace) { diff --git a/common/src/common/worldgen/FeatureOres.java b/common/src/common/worldgen/FeatureOres.java index 091d34b..0786e0c 100755 --- a/common/src/common/worldgen/FeatureOres.java +++ b/common/src/common/worldgen/FeatureOres.java @@ -5,7 +5,7 @@ import common.rng.Random; import common.util.BlockPos; import common.util.ExtMath; import common.world.State; -import common.world.WorldServer; +import common.world.AWorldServer; public class FeatureOres { @@ -80,7 +80,7 @@ public class FeatureOres // this.replace = replace; } - public boolean generate(WorldServer worldIn, Random rand, BlockPos position) { + public boolean generate(AWorldServer worldIn, Random rand, BlockPos position) { Block replace = /* this.replace != null ? this.replace : */ worldIn.dimension.getFiller().getBlock(); int tries = this.spawnTries == 0 ? (rand.zrange(this.moreTries) == 0 ? 1 : 0) : @@ -106,7 +106,7 @@ public class FeatureOres return true; } - private void generateVein(WorldServer worldIn, Random rand, BlockPos position, Block replace) + private void generateVein(AWorldServer worldIn, Random rand, BlockPos position, Block replace) { float f = rand.floatv() * (float)Math.PI; double d0 = (double)(/* (float)(position.getX() + 8) */ 8.0f + ExtMath.sin(f) * (float)this.numberOfBlocks / 8.0F); diff --git a/common/src/common/worldgen/GeneratorCavern.java b/common/src/common/worldgen/GeneratorCavern.java index 0aed076..a3e164e 100755 --- a/common/src/common/worldgen/GeneratorCavern.java +++ b/common/src/common/worldgen/GeneratorCavern.java @@ -4,7 +4,7 @@ import common.rng.OctaveGen; import common.rng.Random; import common.util.ExtMath; import common.world.State; -import common.world.WorldServer; +import common.world.AWorldServer; public class GeneratorCavern implements ChunkGenerator { @@ -43,7 +43,7 @@ public class GeneratorCavern implements ChunkGenerator return 128; } - public void generateChunk(WorldServer world, int x, int z, ChunkPrimer primer) + public void generateChunk(AWorldServer world, int x, int z, ChunkPrimer primer) { int range = 4; int lh = world.getSeaLevel() / 2 + 1; diff --git a/common/src/common/worldgen/GeneratorDebug.java b/common/src/common/worldgen/GeneratorDebug.java index 58ca6c1..5833d49 100755 --- a/common/src/common/worldgen/GeneratorDebug.java +++ b/common/src/common/worldgen/GeneratorDebug.java @@ -7,7 +7,7 @@ import common.collect.Lists; import common.init.BlockRegistry; import common.util.ExtMath; import common.world.State; -import common.world.WorldServer; +import common.world.AWorldServer; public class GeneratorDebug implements ChunkGenerator { @@ -42,7 +42,7 @@ public class GeneratorDebug implements ChunkGenerator return 72; } - public void generateChunk(WorldServer world, int x, int z, ChunkPrimer primer) + public void generateChunk(AWorldServer world, int x, int z, ChunkPrimer primer) { for(int bx = 0; bx < 16; ++bx) { for(int bz = 0; bz < 16; ++bz) { diff --git a/common/src/common/worldgen/GeneratorDestroyed.java b/common/src/common/worldgen/GeneratorDestroyed.java index 5eea1c5..2d7b188 100755 --- a/common/src/common/worldgen/GeneratorDestroyed.java +++ b/common/src/common/worldgen/GeneratorDestroyed.java @@ -3,7 +3,7 @@ package common.worldgen; import common.init.Blocks; import common.rng.Random; import common.world.State; -import common.world.WorldServer; +import common.world.AWorldServer; public class GeneratorDestroyed implements ChunkGenerator { @@ -23,7 +23,7 @@ public class GeneratorDestroyed implements ChunkGenerator return this.height; } - public void generateChunk(WorldServer world, int x, int z, ChunkPrimer primer) + public void generateChunk(AWorldServer world, int x, int z, ChunkPrimer primer) { for(int by = 0; by < this.height; ++by) { for(int bx = 0; bx < 16; ++bx) { diff --git a/common/src/common/worldgen/GeneratorFlat.java b/common/src/common/worldgen/GeneratorFlat.java index 2c0071b..bb97868 100755 --- a/common/src/common/worldgen/GeneratorFlat.java +++ b/common/src/common/worldgen/GeneratorFlat.java @@ -3,7 +3,7 @@ package common.worldgen; import java.util.Arrays; import common.world.State; -import common.world.WorldServer; +import common.world.AWorldServer; public class GeneratorFlat implements ChunkGenerator { private final State[] layers; @@ -37,7 +37,7 @@ public class GeneratorFlat implements ChunkGenerator { return this.layers.length; } - public void generateChunk(WorldServer world, int x, int z, ChunkPrimer primer) { + public void generateChunk(AWorldServer world, int x, int z, ChunkPrimer primer) { for(int by = 0; by < this.layers.length; by++) { State state = this.layers[by]; for(int bx = 0; bx < 16; bx++) { diff --git a/common/src/common/worldgen/GeneratorIsland.java b/common/src/common/worldgen/GeneratorIsland.java index 14c3b81..ffb42f9 100755 --- a/common/src/common/worldgen/GeneratorIsland.java +++ b/common/src/common/worldgen/GeneratorIsland.java @@ -4,7 +4,7 @@ import common.rng.OctaveGen; import common.rng.Random; import common.util.ExtMath; import common.world.State; -import common.world.WorldServer; +import common.world.AWorldServer; public class GeneratorIsland implements ChunkGenerator { @@ -41,7 +41,7 @@ public class GeneratorIsland implements ChunkGenerator return 128; } - public void generateChunk(WorldServer world, int x, int z, ChunkPrimer primer) + public void generateChunk(AWorldServer world, int x, int z, ChunkPrimer primer) { int range = 2; int xr = range + 1; diff --git a/common/src/common/worldgen/GeneratorPerlin.java b/common/src/common/worldgen/GeneratorPerlin.java index f9156a9..7269142 100755 --- a/common/src/common/worldgen/GeneratorPerlin.java +++ b/common/src/common/worldgen/GeneratorPerlin.java @@ -7,7 +7,7 @@ import common.rng.OctaveGen; import common.rng.Random; import common.util.ExtMath; import common.world.State; -import common.world.WorldServer; +import common.world.AWorldServer; public class GeneratorPerlin implements ChunkGenerator { @@ -105,7 +105,7 @@ public class GeneratorPerlin implements ChunkGenerator return 256; } - public void generateChunk(WorldServer world, int x, int z, ChunkPrimer primer) + public void generateChunk(AWorldServer world, int x, int z, ChunkPrimer primer) { int sea = world.getSeaLevel(); world.getBiomeGenerator().getGenBiomes(this.biomes, x * 4 - 2, z * 4 - 2, 10, 10); diff --git a/common/src/common/worldgen/GeneratorSimple.java b/common/src/common/worldgen/GeneratorSimple.java index 3ba0303..fb940fc 100755 --- a/common/src/common/worldgen/GeneratorSimple.java +++ b/common/src/common/worldgen/GeneratorSimple.java @@ -4,7 +4,7 @@ import common.rng.NoiseGen; import common.rng.OctaveGen; import common.rng.Random; import common.world.State; -import common.world.WorldServer; +import common.world.AWorldServer; public class GeneratorSimple implements ChunkGenerator { @@ -54,7 +54,7 @@ public class GeneratorSimple implements ChunkGenerator return 128; } - public void generateChunk(WorldServer world, int x, int z, ChunkPrimer primer) + public void generateChunk(AWorldServer world, int x, int z, ChunkPrimer primer) { if(this.biomeGen == null) world.getBiomeGenerator().genFactors(this.factors, x * 16, z * 16, 16, 16); diff --git a/common/src/common/worldgen/ReplacerAltBiome.java b/common/src/common/worldgen/ReplacerAltBiome.java index 549d8c9..f312858 100755 --- a/common/src/common/worldgen/ReplacerAltBiome.java +++ b/common/src/common/worldgen/ReplacerAltBiome.java @@ -7,7 +7,7 @@ import common.rng.NoiseGen; import common.rng.OctaveGen; import common.rng.Random; import common.world.State; -import common.world.WorldServer; +import common.world.AWorldServer; public class ReplacerAltBiome implements BlockReplacer { @@ -46,7 +46,7 @@ public class ReplacerAltBiome implements BlockReplacer this.block = filler.getBlock(); } - public void replaceBlocks(WorldServer world, int x, int z, ChunkPrimer primer, Random rand, Biome[] biomes) + public void replaceBlocks(AWorldServer world, int x, int z, ChunkPrimer primer, Random rand, Biome[] biomes) { int seaLevel = world.getSeaLevel(); double scale = 0.03125D; diff --git a/common/src/common/worldgen/ReplacerAltSurface.java b/common/src/common/worldgen/ReplacerAltSurface.java index 3dc3c58..1911633 100755 --- a/common/src/common/worldgen/ReplacerAltSurface.java +++ b/common/src/common/worldgen/ReplacerAltSurface.java @@ -6,7 +6,7 @@ import common.material.Material; import common.rng.OctaveGen; import common.rng.Random; import common.world.State; -import common.world.WorldServer; +import common.world.AWorldServer; public class ReplacerAltSurface implements BlockReplacer { @@ -38,7 +38,7 @@ public class ReplacerAltSurface implements BlockReplacer this.fillerBlock = filler.getBlock(); } - public void replaceBlocks(WorldServer world, int x, int z, ChunkPrimer primer, Random rand, Biome[] biomes) + public void replaceBlocks(AWorldServer world, int x, int z, ChunkPrimer primer, Random rand, Biome[] biomes) { int i = world.getSeaLevel() + 1; double d0 = 0.03125D; diff --git a/common/src/common/worldgen/ReplacerBiome.java b/common/src/common/worldgen/ReplacerBiome.java index aa3d70a..c483418 100755 --- a/common/src/common/worldgen/ReplacerBiome.java +++ b/common/src/common/worldgen/ReplacerBiome.java @@ -3,7 +3,7 @@ package common.worldgen; import common.biome.Biome; import common.rng.PerlinGen; import common.rng.Random; -import common.world.WorldServer; +import common.world.AWorldServer; public class ReplacerBiome implements BlockReplacer { @@ -15,7 +15,7 @@ public class ReplacerBiome implements BlockReplacer this.stoneNoiseGen = new PerlinGen(rand, 4); } - public void replaceBlocks(WorldServer world, int x, int z, ChunkPrimer primer, Random rand, Biome[] biomes) + public void replaceBlocks(AWorldServer world, int x, int z, ChunkPrimer primer, Random rand, Biome[] biomes) { double d0 = 0.03125D; this.stoneNoiseGen.generate(this.stoneNoise, (double)(x * 16), (double)(z * 16), 16, 16, d0 * 2.0D, d0 * 2.0D, 1.0D); diff --git a/common/src/common/worldgen/ReplacerTopLayer.java b/common/src/common/worldgen/ReplacerTopLayer.java index d27dc7e..2a1804e 100755 --- a/common/src/common/worldgen/ReplacerTopLayer.java +++ b/common/src/common/worldgen/ReplacerTopLayer.java @@ -6,7 +6,7 @@ import common.init.Blocks; import common.material.Material; import common.rng.Random; import common.world.State; -import common.world.WorldServer; +import common.world.AWorldServer; public class ReplacerTopLayer implements BlockReplacer { @@ -22,7 +22,7 @@ public class ReplacerTopLayer implements BlockReplacer this.replace = replace; } - public void replaceBlocks(WorldServer world, int x, int z, ChunkPrimer primer, Random rand, Biome[] biomes) + public void replaceBlocks(AWorldServer world, int x, int z, ChunkPrimer primer, Random rand, Biome[] biomes) { for (int i = 0; i < 16; ++i) { diff --git a/common/src/common/worldgen/caves/MapGenBase.java b/common/src/common/worldgen/caves/MapGenBase.java index 82fb296..f2c9b08 100755 --- a/common/src/common/worldgen/caves/MapGenBase.java +++ b/common/src/common/worldgen/caves/MapGenBase.java @@ -1,7 +1,7 @@ package common.worldgen.caves; import common.rng.Random; -import common.world.WorldServer; +import common.world.AWorldServer; import common.worldgen.ChunkPrimer; public class MapGenBase @@ -13,9 +13,9 @@ public class MapGenBase protected Random rand = new Random(); /** This world object. */ - protected WorldServer worldObj; + protected AWorldServer worldObj; - public void generate(WorldServer worldIn, int x, int z, ChunkPrimer chunkPrimerIn) + public void generate(AWorldServer worldIn, int x, int z, ChunkPrimer chunkPrimerIn) { int i = this.range; this.worldObj = worldIn; @@ -38,7 +38,7 @@ public class MapGenBase /** * Recursively called by generate() */ - protected void recursiveGenerate(WorldServer worldIn, int chunkX, int chunkZ, int p_180701_4_, int p_180701_5_, ChunkPrimer chunkPrimerIn) + protected void recursiveGenerate(AWorldServer worldIn, int chunkX, int chunkZ, int p_180701_4_, int p_180701_5_, ChunkPrimer chunkPrimerIn) { } } diff --git a/common/src/common/worldgen/caves/MapGenBigCaves.java b/common/src/common/worldgen/caves/MapGenBigCaves.java index c04c80b..9fb133e 100755 --- a/common/src/common/worldgen/caves/MapGenBigCaves.java +++ b/common/src/common/worldgen/caves/MapGenBigCaves.java @@ -5,7 +5,7 @@ import common.init.Blocks; import common.rng.Random; import common.util.ExtMath; import common.world.State; -import common.world.WorldServer; +import common.world.AWorldServer; import common.worldgen.ChunkPrimer; public class MapGenBigCaves extends MapGenBase @@ -199,7 +199,7 @@ public class MapGenBigCaves extends MapGenBase /** * Recursively called by generate() */ - protected void recursiveGenerate(WorldServer worldIn, int chunkX, int chunkZ, int p_180701_4_, int p_180701_5_, ChunkPrimer chunkPrimerIn) + protected void recursiveGenerate(AWorldServer worldIn, int chunkX, int chunkZ, int p_180701_4_, int p_180701_5_, ChunkPrimer chunkPrimerIn) { int i = this.rand.zrange(this.rand.zrange(this.rand.zrange(10) + 1) + 1); diff --git a/common/src/common/worldgen/caves/MapGenCaves.java b/common/src/common/worldgen/caves/MapGenCaves.java index 405603b..ec0d0c7 100755 --- a/common/src/common/worldgen/caves/MapGenCaves.java +++ b/common/src/common/worldgen/caves/MapGenCaves.java @@ -9,7 +9,7 @@ import common.rng.Random; import common.util.BlockPos; import common.util.ExtMath; import common.world.State; -import common.world.WorldServer; +import common.world.AWorldServer; import common.worldgen.ChunkPrimer; public class MapGenCaves extends MapGenBase @@ -245,7 +245,7 @@ public class MapGenCaves extends MapGenBase /** * Recursively called by generate() */ - protected void recursiveGenerate(WorldServer worldIn, int chunkX, int chunkZ, int p_180701_4_, int p_180701_5_, ChunkPrimer chunkPrimerIn) + protected void recursiveGenerate(AWorldServer worldIn, int chunkX, int chunkZ, int p_180701_4_, int p_180701_5_, ChunkPrimer chunkPrimerIn) { int i = this.rand.zrange(this.rand.zrange(this.rand.zrange(15) + 1) + 1); diff --git a/common/src/common/worldgen/caves/MapGenRavine.java b/common/src/common/worldgen/caves/MapGenRavine.java index 02646d1..cbe9256 100755 --- a/common/src/common/worldgen/caves/MapGenRavine.java +++ b/common/src/common/worldgen/caves/MapGenRavine.java @@ -6,7 +6,7 @@ import common.rng.Random; import common.util.BlockPos; import common.util.ExtMath; import common.world.State; -import common.world.WorldServer; +import common.world.AWorldServer; import common.worldgen.ChunkPrimer; public class MapGenRavine extends MapGenBase @@ -219,7 +219,7 @@ public class MapGenRavine extends MapGenBase /** * Recursively called by generate() */ - protected void recursiveGenerate(WorldServer worldIn, int chunkX, int chunkZ, int p_180701_4_, int p_180701_5_, ChunkPrimer chunkPrimerIn) + protected void recursiveGenerate(AWorldServer worldIn, int chunkX, int chunkZ, int p_180701_4_, int p_180701_5_, ChunkPrimer chunkPrimerIn) { if (this.rand.zrange(50) == 0) { diff --git a/common/src/common/worldgen/feature/WorldGenAbandonedChest.java b/common/src/common/worldgen/feature/WorldGenAbandonedChest.java index c724150..61d7574 100755 --- a/common/src/common/worldgen/feature/WorldGenAbandonedChest.java +++ b/common/src/common/worldgen/feature/WorldGenAbandonedChest.java @@ -9,7 +9,7 @@ import common.rng.WeightedList; import common.tileentity.TileEntity; import common.tileentity.TileEntityChest; import common.util.BlockPos; -import common.world.WorldServer; +import common.world.AWorldServer; import common.worldgen.FeatureGenerator; import common.worldgen.LootConstants; @@ -30,7 +30,7 @@ public class WorldGenAbandonedChest extends FeatureGenerator this(LootConstants.ABANDONED_ITEMS, 10); } - public boolean generate(WorldServer worldIn, Random rand, BlockPos position) + public boolean generate(AWorldServer worldIn, Random rand, BlockPos position) { Block block; while (((block = worldIn.getState(position).getBlock()).getMaterial() == Material.air || block.getMaterial() == Material.leaves) && position.getY() > 1) diff --git a/common/src/common/worldgen/feature/WorldGenAsteroid.java b/common/src/common/worldgen/feature/WorldGenAsteroid.java index fdc1eef..c1459c6 100755 --- a/common/src/common/worldgen/feature/WorldGenAsteroid.java +++ b/common/src/common/worldgen/feature/WorldGenAsteroid.java @@ -3,7 +3,7 @@ package common.worldgen.feature; import common.rng.Random; import common.util.BlockPos; import common.world.State; -import common.world.WorldServer; +import common.world.AWorldServer; import common.worldgen.FeatureGenerator; public class WorldGenAsteroid extends FeatureGenerator { @@ -13,7 +13,7 @@ public class WorldGenAsteroid extends FeatureGenerator { this.blocks = blocks; } - public boolean generate(WorldServer world, Random rand, BlockPos pos) { + public boolean generate(AWorldServer world, Random rand, BlockPos pos) { for(pos = pos.add(-8, 0, -8); pos.getY() > 9 && !world.isAirBlock(pos); pos = pos.down()) { ; } diff --git a/common/src/common/worldgen/feature/WorldGenBlockBlob.java b/common/src/common/worldgen/feature/WorldGenBlockBlob.java index 06929da..5de76f4 100755 --- a/common/src/common/worldgen/feature/WorldGenBlockBlob.java +++ b/common/src/common/worldgen/feature/WorldGenBlockBlob.java @@ -4,7 +4,7 @@ import common.block.Block; import common.init.Blocks; import common.rng.Random; import common.util.BlockPos; -import common.world.WorldServer; +import common.world.AWorldServer; import common.worldgen.FeatureGenerator; public class WorldGenBlockBlob extends FeatureGenerator @@ -19,7 +19,7 @@ public class WorldGenBlockBlob extends FeatureGenerator this.field_150544_b = p_i45450_2_; } - public boolean generate(WorldServer worldIn, Random rand, BlockPos position) + public boolean generate(AWorldServer worldIn, Random rand, BlockPos position) { while (true) { diff --git a/common/src/common/worldgen/feature/WorldGenClay.java b/common/src/common/worldgen/feature/WorldGenClay.java index 9888fbc..6dc622f 100755 --- a/common/src/common/worldgen/feature/WorldGenClay.java +++ b/common/src/common/worldgen/feature/WorldGenClay.java @@ -4,7 +4,7 @@ import common.block.Block; import common.init.Blocks; import common.rng.Random; import common.util.BlockPos; -import common.world.WorldServer; +import common.world.AWorldServer; import common.worldgen.FeatureGenerator; public class WorldGenClay extends FeatureGenerator @@ -19,7 +19,7 @@ public class WorldGenClay extends FeatureGenerator this.numberOfBlocks = blocks; } - public boolean generate(WorldServer worldIn, Random rand, BlockPos position) + public boolean generate(AWorldServer worldIn, Random rand, BlockPos position) { if (!worldIn.getState(position).getBlock().getMaterial().isColdLiquid()) { diff --git a/common/src/common/worldgen/feature/WorldGenClayExt.java b/common/src/common/worldgen/feature/WorldGenClayExt.java index c7fc80e..c9e5ce0 100755 --- a/common/src/common/worldgen/feature/WorldGenClayExt.java +++ b/common/src/common/worldgen/feature/WorldGenClayExt.java @@ -5,14 +5,14 @@ import common.init.Blocks; import common.rng.Random; import common.util.BlockPos; import common.util.ExtMath; -import common.world.WorldServer; +import common.world.AWorldServer; public class WorldGenClayExt extends WorldGenClay { public WorldGenClayExt(int blocks) { super(blocks); } - public boolean generate(WorldServer worldIn, Random rand, BlockPos position) { + public boolean generate(AWorldServer worldIn, Random rand, BlockPos position) { if(!worldIn.getState(position).getBlock().getMaterial().isColdLiquid()) { return false; } diff --git a/common/src/common/worldgen/feature/WorldGenDesertWells.java b/common/src/common/worldgen/feature/WorldGenDesertWells.java index 75fab6b..55a49c8 100755 --- a/common/src/common/worldgen/feature/WorldGenDesertWells.java +++ b/common/src/common/worldgen/feature/WorldGenDesertWells.java @@ -9,7 +9,7 @@ import common.util.BlockPos; import common.util.Facing; import common.util.Predicates; import common.world.State; -import common.world.WorldServer; +import common.world.AWorldServer; import common.worldgen.FeatureGenerator; public class WorldGenDesertWells extends FeatureGenerator @@ -19,7 +19,7 @@ public class WorldGenDesertWells extends FeatureGenerator private final State field_175912_c = Blocks.sandstone.getState(); private final State field_175910_d = Blocks.flowing_water.getState(); - public boolean generate(WorldServer worldIn, Random rand, BlockPos position) + public boolean generate(AWorldServer worldIn, Random rand, BlockPos position) { while (worldIn.isAirBlock(position) && position.getY() > 2) { diff --git a/common/src/common/worldgen/feature/WorldGenFire.java b/common/src/common/worldgen/feature/WorldGenFire.java index 4623f68..d5ffd52 100755 --- a/common/src/common/worldgen/feature/WorldGenFire.java +++ b/common/src/common/worldgen/feature/WorldGenFire.java @@ -3,12 +3,12 @@ package common.worldgen.feature; import common.init.Blocks; import common.rng.Random; import common.util.BlockPos; -import common.world.WorldServer; +import common.world.AWorldServer; import common.worldgen.FeatureGenerator; public class WorldGenFire extends FeatureGenerator { - public boolean generate(WorldServer worldIn, Random rand, BlockPos position) + public boolean generate(AWorldServer worldIn, Random rand, BlockPos position) { for (int i = 0; i < 64; ++i) { diff --git a/common/src/common/worldgen/feature/WorldGenGlowStone.java b/common/src/common/worldgen/feature/WorldGenGlowStone.java index a87146c..7f8e92b 100755 --- a/common/src/common/worldgen/feature/WorldGenGlowStone.java +++ b/common/src/common/worldgen/feature/WorldGenGlowStone.java @@ -5,12 +5,12 @@ import common.material.Material; import common.rng.Random; import common.util.BlockPos; import common.util.Facing; -import common.world.WorldServer; +import common.world.AWorldServer; import common.worldgen.FeatureGenerator; public class WorldGenGlowStone extends FeatureGenerator { - public boolean generate(WorldServer worldIn, Random rand, BlockPos position) + public boolean generate(AWorldServer worldIn, Random rand, BlockPos position) { if (!worldIn.isAirBlock(position)) { diff --git a/common/src/common/worldgen/feature/WorldGenHellLava.java b/common/src/common/worldgen/feature/WorldGenHellLava.java index 7aee1b8..202ab9f 100755 --- a/common/src/common/worldgen/feature/WorldGenHellLava.java +++ b/common/src/common/worldgen/feature/WorldGenHellLava.java @@ -5,7 +5,7 @@ import common.init.Blocks; import common.material.Material; import common.rng.Random; import common.util.BlockPos; -import common.world.WorldServer; +import common.world.AWorldServer; import common.worldgen.FeatureGenerator; public class WorldGenHellLava extends FeatureGenerator @@ -19,7 +19,7 @@ public class WorldGenHellLava extends FeatureGenerator this.field_94524_b = p_i45453_2_; } - public boolean generate(WorldServer worldIn, Random rand, BlockPos position) + public boolean generate(AWorldServer worldIn, Random rand, BlockPos position) { if (worldIn.getState(position.up()).getBlock() != Blocks.hellrock) { diff --git a/common/src/common/worldgen/feature/WorldGenIcePath.java b/common/src/common/worldgen/feature/WorldGenIcePath.java index 69b9aac..b06b13d 100755 --- a/common/src/common/worldgen/feature/WorldGenIcePath.java +++ b/common/src/common/worldgen/feature/WorldGenIcePath.java @@ -4,7 +4,7 @@ import common.block.Block; import common.init.Blocks; import common.rng.Random; import common.util.BlockPos; -import common.world.WorldServer; +import common.world.AWorldServer; import common.worldgen.FeatureGenerator; public class WorldGenIcePath extends FeatureGenerator @@ -17,7 +17,7 @@ public class WorldGenIcePath extends FeatureGenerator this.basePathWidth = p_i45454_1_; } - public boolean generate(WorldServer worldIn, Random rand, BlockPos position) + public boolean generate(AWorldServer worldIn, Random rand, BlockPos position) { while (worldIn.isAirBlock(position) && position.getY() > 2) { diff --git a/common/src/common/worldgen/feature/WorldGenIceSpike.java b/common/src/common/worldgen/feature/WorldGenIceSpike.java index 8d7aaf1..03f5388 100755 --- a/common/src/common/worldgen/feature/WorldGenIceSpike.java +++ b/common/src/common/worldgen/feature/WorldGenIceSpike.java @@ -6,12 +6,12 @@ import common.material.Material; import common.rng.Random; import common.util.BlockPos; import common.util.ExtMath; -import common.world.WorldServer; +import common.world.AWorldServer; import common.worldgen.FeatureGenerator; public class WorldGenIceSpike extends FeatureGenerator { - public boolean generate(WorldServer worldIn, Random rand, BlockPos position) + public boolean generate(AWorldServer worldIn, Random rand, BlockPos position) { while (worldIn.isAirBlock(position) && position.getY() > 2) { diff --git a/common/src/common/worldgen/feature/WorldGenSand.java b/common/src/common/worldgen/feature/WorldGenSand.java index 657a276..1e750bf 100755 --- a/common/src/common/worldgen/feature/WorldGenSand.java +++ b/common/src/common/worldgen/feature/WorldGenSand.java @@ -4,7 +4,7 @@ import common.block.Block; import common.init.Blocks; import common.rng.Random; import common.util.BlockPos; -import common.world.WorldServer; +import common.world.AWorldServer; import common.worldgen.FeatureGenerator; public class WorldGenSand extends FeatureGenerator @@ -20,7 +20,7 @@ public class WorldGenSand extends FeatureGenerator this.radius = p_i45462_2_; } - public boolean generate(WorldServer worldIn, Random rand, BlockPos position) + public boolean generate(AWorldServer worldIn, Random rand, BlockPos position) { if (!worldIn.getState(position).getBlock().getMaterial().isColdLiquid()) { diff --git a/common/src/common/worldgen/feature/WorldGenSpikes.java b/common/src/common/worldgen/feature/WorldGenSpikes.java index 76b6f07..736f13b 100755 --- a/common/src/common/worldgen/feature/WorldGenSpikes.java +++ b/common/src/common/worldgen/feature/WorldGenSpikes.java @@ -6,7 +6,7 @@ import common.entity.item.EntityCrystal; import common.rng.Random; import common.util.BlockPos; import common.world.State; -import common.world.WorldServer; +import common.world.AWorldServer; import common.worldgen.FeatureGenerator; public class WorldGenSpikes extends FeatureGenerator @@ -28,7 +28,7 @@ public class WorldGenSpikes extends FeatureGenerator this.crystals = crystals; } - public boolean generate(WorldServer worldIn, Random rand, BlockPos position) + public boolean generate(AWorldServer worldIn, Random rand, BlockPos position) { if (worldIn.isAirBlock(position) && worldIn.getState(position.down()).getBlock() == this.base) { diff --git a/common/src/common/worldgen/foliage/FeatureDoublePlant.java b/common/src/common/worldgen/foliage/FeatureDoublePlant.java index 2e00419..7dbfdcb 100755 --- a/common/src/common/worldgen/foliage/FeatureDoublePlant.java +++ b/common/src/common/worldgen/foliage/FeatureDoublePlant.java @@ -4,7 +4,7 @@ import common.block.BlockDoublePlant; import common.init.Blocks; import common.rng.Random; import common.util.BlockPos; -import common.world.WorldServer; +import common.world.AWorldServer; public class FeatureDoublePlant { @@ -15,7 +15,7 @@ public class FeatureDoublePlant this.type = type; } - public boolean generate(WorldServer worldIn, Random rand, BlockPos position) + public boolean generate(AWorldServer worldIn, Random rand, BlockPos position) { boolean flag = false; diff --git a/common/src/common/worldgen/foliage/WorldGenBigMushroom.java b/common/src/common/worldgen/foliage/WorldGenBigMushroom.java index 96005ec..dac6cef 100755 --- a/common/src/common/worldgen/foliage/WorldGenBigMushroom.java +++ b/common/src/common/worldgen/foliage/WorldGenBigMushroom.java @@ -6,7 +6,7 @@ import common.init.Blocks; import common.material.Material; import common.rng.Random; import common.util.BlockPos; -import common.world.WorldServer; +import common.world.AWorldServer; import common.worldgen.FeatureGenerator; public class WorldGenBigMushroom extends FeatureGenerator @@ -25,7 +25,7 @@ public class WorldGenBigMushroom extends FeatureGenerator super(false); } - public boolean generate(WorldServer worldIn, Random rand, BlockPos position) + public boolean generate(AWorldServer worldIn, Random rand, BlockPos position) { // if (this.mushroomType == null) // { diff --git a/common/src/common/worldgen/foliage/WorldGenCactus.java b/common/src/common/worldgen/foliage/WorldGenCactus.java index 500a5ea..f14ef17 100755 --- a/common/src/common/worldgen/foliage/WorldGenCactus.java +++ b/common/src/common/worldgen/foliage/WorldGenCactus.java @@ -3,12 +3,12 @@ package common.worldgen.foliage; import common.init.Blocks; import common.rng.Random; import common.util.BlockPos; -import common.world.WorldServer; +import common.world.AWorldServer; import common.worldgen.FeatureGenerator; public class WorldGenCactus extends FeatureGenerator { - public boolean generate(WorldServer worldIn, Random rand, BlockPos position) + public boolean generate(AWorldServer worldIn, Random rand, BlockPos position) { for (int i = 0; i < 10; ++i) { diff --git a/common/src/common/worldgen/foliage/WorldGenDeadBush.java b/common/src/common/worldgen/foliage/WorldGenDeadBush.java index 6e7bb2d..5b84123 100755 --- a/common/src/common/worldgen/foliage/WorldGenDeadBush.java +++ b/common/src/common/worldgen/foliage/WorldGenDeadBush.java @@ -5,12 +5,12 @@ import common.init.Blocks; import common.material.Material; import common.rng.Random; import common.util.BlockPos; -import common.world.WorldServer; +import common.world.AWorldServer; import common.worldgen.FeatureGenerator; public class WorldGenDeadBush extends FeatureGenerator { - public boolean generate(WorldServer worldIn, Random rand, BlockPos position) + public boolean generate(AWorldServer worldIn, Random rand, BlockPos position) { Block block; diff --git a/common/src/common/worldgen/foliage/WorldGenFlowers.java b/common/src/common/worldgen/foliage/WorldGenFlowers.java index 9adc8b2..f29cbb7 100755 --- a/common/src/common/worldgen/foliage/WorldGenFlowers.java +++ b/common/src/common/worldgen/foliage/WorldGenFlowers.java @@ -4,7 +4,7 @@ import common.block.BlockFlower; import common.rng.Random; import common.util.BlockPos; import common.world.State; -import common.world.WorldServer; +import common.world.AWorldServer; import common.worldgen.FeatureGenerator; public class WorldGenFlowers extends FeatureGenerator @@ -23,7 +23,7 @@ public class WorldGenFlowers extends FeatureGenerator this.field_175915_b = p_175914_1_.getState().withProperty(p_175914_1_.getTypeProperty(), p_175914_2_); } - public boolean generate(WorldServer worldIn, Random rand, BlockPos position) + public boolean generate(AWorldServer worldIn, Random rand, BlockPos position) { for (int i = 0; i < 64; ++i) { diff --git a/common/src/common/worldgen/foliage/WorldGenMelon.java b/common/src/common/worldgen/foliage/WorldGenMelon.java index fff25dc..7ae8427 100755 --- a/common/src/common/worldgen/foliage/WorldGenMelon.java +++ b/common/src/common/worldgen/foliage/WorldGenMelon.java @@ -3,12 +3,12 @@ package common.worldgen.foliage; import common.init.Blocks; import common.rng.Random; import common.util.BlockPos; -import common.world.WorldServer; +import common.world.AWorldServer; import common.worldgen.FeatureGenerator; public class WorldGenMelon extends FeatureGenerator { - public boolean generate(WorldServer worldIn, Random rand, BlockPos position) + public boolean generate(AWorldServer worldIn, Random rand, BlockPos position) { for (int i = 0; i < 64; ++i) { diff --git a/common/src/common/worldgen/foliage/WorldGenMushroom.java b/common/src/common/worldgen/foliage/WorldGenMushroom.java index 00d38a8..f989bb2 100755 --- a/common/src/common/worldgen/foliage/WorldGenMushroom.java +++ b/common/src/common/worldgen/foliage/WorldGenMushroom.java @@ -3,7 +3,7 @@ package common.worldgen.foliage; import common.block.BlockBush; import common.rng.Random; import common.util.BlockPos; -import common.world.WorldServer; +import common.world.AWorldServer; import common.worldgen.FeatureGenerator; public class WorldGenMushroom extends FeatureGenerator @@ -15,7 +15,7 @@ public class WorldGenMushroom extends FeatureGenerator this.field_175908_a = p_i45633_1_; } - public boolean generate(WorldServer worldIn, Random rand, BlockPos position) + public boolean generate(AWorldServer worldIn, Random rand, BlockPos position) { for (int i = 0; i < 64; ++i) { diff --git a/common/src/common/worldgen/foliage/WorldGenPumpkin.java b/common/src/common/worldgen/foliage/WorldGenPumpkin.java index 45f3daf..8a9c2e6 100755 --- a/common/src/common/worldgen/foliage/WorldGenPumpkin.java +++ b/common/src/common/worldgen/foliage/WorldGenPumpkin.java @@ -5,12 +5,12 @@ import common.init.Blocks; import common.rng.Random; import common.util.BlockPos; import common.util.Facing; -import common.world.WorldServer; +import common.world.AWorldServer; import common.worldgen.FeatureGenerator; public class WorldGenPumpkin extends FeatureGenerator { - public boolean generate(WorldServer worldIn, Random rand, BlockPos position) + public boolean generate(AWorldServer worldIn, Random rand, BlockPos position) { for (int i = 0; i < 64; ++i) { diff --git a/common/src/common/worldgen/foliage/WorldGenReed.java b/common/src/common/worldgen/foliage/WorldGenReed.java index f85469c..1c55cbd 100755 --- a/common/src/common/worldgen/foliage/WorldGenReed.java +++ b/common/src/common/worldgen/foliage/WorldGenReed.java @@ -4,12 +4,12 @@ import common.init.Blocks; import common.material.Material; import common.rng.Random; import common.util.BlockPos; -import common.world.WorldServer; +import common.world.AWorldServer; import common.worldgen.FeatureGenerator; public class WorldGenReed extends FeatureGenerator { - public boolean generate(WorldServer worldIn, Random rand, BlockPos position) + public boolean generate(AWorldServer worldIn, Random rand, BlockPos position) { for (int i = 0; i < 20; ++i) { diff --git a/common/src/common/worldgen/foliage/WorldGenShrub.java b/common/src/common/worldgen/foliage/WorldGenShrub.java index 00b7d71..860c885 100755 --- a/common/src/common/worldgen/foliage/WorldGenShrub.java +++ b/common/src/common/worldgen/foliage/WorldGenShrub.java @@ -7,7 +7,7 @@ import common.material.Material; import common.rng.Random; import common.util.BlockPos; import common.world.State; -import common.world.WorldServer; +import common.world.AWorldServer; import common.worldgen.tree.WorldGenBaseTree; public class WorldGenShrub extends WorldGenBaseTree @@ -22,7 +22,7 @@ public class WorldGenShrub extends WorldGenBaseTree this.leavesMetadata = leaves.withProperty(BlockLeaves.DECAY, Boolean.valueOf(false)); } - public boolean generate(WorldServer worldIn, Random rand, BlockPos position) + public boolean generate(AWorldServer worldIn, Random rand, BlockPos position) { Block block; diff --git a/common/src/common/worldgen/foliage/WorldGenTallGrass.java b/common/src/common/worldgen/foliage/WorldGenTallGrass.java index 52bf305..9adca0d 100755 --- a/common/src/common/worldgen/foliage/WorldGenTallGrass.java +++ b/common/src/common/worldgen/foliage/WorldGenTallGrass.java @@ -7,7 +7,7 @@ import common.material.Material; import common.rng.Random; import common.util.BlockPos; import common.world.State; -import common.world.WorldServer; +import common.world.AWorldServer; import common.worldgen.FeatureGenerator; public class WorldGenTallGrass extends FeatureGenerator @@ -19,7 +19,7 @@ public class WorldGenTallGrass extends FeatureGenerator this.tallGrassState = Blocks.tallgrass.getState().withProperty(BlockTallGrass.TYPE, p_i45629_1_); } - public boolean generate(WorldServer worldIn, Random rand, BlockPos position) + public boolean generate(AWorldServer worldIn, Random rand, BlockPos position) { Block block; diff --git a/common/src/common/worldgen/foliage/WorldGenVines.java b/common/src/common/worldgen/foliage/WorldGenVines.java index eaf09b1..dfeb2bd 100755 --- a/common/src/common/worldgen/foliage/WorldGenVines.java +++ b/common/src/common/worldgen/foliage/WorldGenVines.java @@ -6,12 +6,12 @@ import common.rng.Random; import common.util.BlockPos; import common.util.Facing; import common.world.State; -import common.world.WorldServer; +import common.world.AWorldServer; import common.worldgen.FeatureGenerator; public class WorldGenVines extends FeatureGenerator { - public boolean generate(WorldServer worldIn, Random rand, BlockPos position) + public boolean generate(AWorldServer worldIn, Random rand, BlockPos position) { for (; position.getY() < 128; position = position.up()) { diff --git a/common/src/common/worldgen/foliage/WorldGenWaterlily.java b/common/src/common/worldgen/foliage/WorldGenWaterlily.java index c7496c9..a60117b 100755 --- a/common/src/common/worldgen/foliage/WorldGenWaterlily.java +++ b/common/src/common/worldgen/foliage/WorldGenWaterlily.java @@ -5,12 +5,12 @@ import common.init.Blocks; import common.rng.Random; import common.util.BlockPos; import common.util.Facing; -import common.world.WorldServer; +import common.world.AWorldServer; import common.worldgen.FeatureGenerator; public class WorldGenWaterlily extends FeatureGenerator { - public boolean generate(WorldServer worldIn, Random rand, BlockPos position) + public boolean generate(AWorldServer worldIn, Random rand, BlockPos position) { for (int i = 0; i < 10; ++i) { diff --git a/common/src/common/worldgen/tree/WorldGenBaseTree.java b/common/src/common/worldgen/tree/WorldGenBaseTree.java index e3653c9..83768cc 100755 --- a/common/src/common/worldgen/tree/WorldGenBaseTree.java +++ b/common/src/common/worldgen/tree/WorldGenBaseTree.java @@ -11,7 +11,7 @@ import common.rng.Random; import common.util.BlockPos; import common.util.Facing; import common.world.State; -import common.world.WorldServer; +import common.world.AWorldServer; public class WorldGenBaseTree extends WorldGenTree { @@ -42,7 +42,7 @@ public class WorldGenBaseTree extends WorldGenTree this.vinesGrow = vines; } - public boolean generate(WorldServer worldIn, Random rand, BlockPos position) + public boolean generate(AWorldServer worldIn, Random rand, BlockPos position) { int i = rand.zrange(3) + this.minTreeHeight; boolean flag = true; @@ -233,17 +233,17 @@ public class WorldGenBaseTree extends WorldGenTree } } - private void func_181652_a(WorldServer p_181652_1_, int p_181652_2_, BlockPos p_181652_3_, Facing p_181652_4_) + private void func_181652_a(AWorldServer p_181652_1_, int p_181652_2_, BlockPos p_181652_3_, Facing p_181652_4_) { this.setBlockAndNotifyAdequately(p_181652_1_, p_181652_3_, Blocks.cocoa.getState().withProperty(BlockCocoa.AGE, p_181652_2_).withProperty(BlockCocoa.FACING, p_181652_4_)); } - private void func_181651_a(WorldServer p_181651_1_, BlockPos p_181651_2_, PropertyBool p_181651_3_) + private void func_181651_a(AWorldServer p_181651_1_, BlockPos p_181651_2_, PropertyBool p_181651_3_) { this.setBlockAndNotifyAdequately(p_181651_1_, p_181651_2_, Blocks.vine.getState().withProperty(p_181651_3_, Boolean.valueOf(true))); } - private void func_181650_b(WorldServer p_181650_1_, BlockPos p_181650_2_, PropertyBool p_181650_3_) + private void func_181650_b(AWorldServer p_181650_1_, BlockPos p_181650_2_, PropertyBool p_181650_3_) { this.func_181651_a(p_181650_1_, p_181650_2_, p_181650_3_); int i = 4; diff --git a/common/src/common/worldgen/tree/WorldGenBigTree.java b/common/src/common/worldgen/tree/WorldGenBigTree.java index 8f16b8a..91f5588 100755 --- a/common/src/common/worldgen/tree/WorldGenBigTree.java +++ b/common/src/common/worldgen/tree/WorldGenBigTree.java @@ -12,7 +12,7 @@ import common.rng.Random; import common.util.BlockPos; import common.util.ExtMath; import common.world.State; -import common.world.WorldServer; +import common.world.AWorldServer; public class WorldGenBigTree extends WorldGenTree { @@ -20,7 +20,7 @@ public class WorldGenBigTree extends WorldGenTree private final State logBase; private Random rand; - private WorldServer world; + private AWorldServer world; private BlockPos basePos = BlockPos.ORIGIN; private int heightLimit; private int height; @@ -322,7 +322,7 @@ public class WorldGenBigTree extends WorldGenTree this.leafDistanceLimit = 5; } - public boolean generate(WorldServer worldIn, Random rand, BlockPos position) + public boolean generate(AWorldServer worldIn, Random rand, BlockPos position) { this.world = worldIn; this.basePos = position; diff --git a/common/src/common/worldgen/tree/WorldGenBirch.java b/common/src/common/worldgen/tree/WorldGenBirch.java index 9c4cebb..eb4da07 100755 --- a/common/src/common/worldgen/tree/WorldGenBirch.java +++ b/common/src/common/worldgen/tree/WorldGenBirch.java @@ -7,7 +7,7 @@ import common.material.Material; import common.rng.Random; import common.util.BlockPos; import common.world.State; -import common.world.WorldServer; +import common.world.AWorldServer; public class WorldGenBirch extends WorldGenTree { @@ -23,7 +23,7 @@ public class WorldGenBirch extends WorldGenTree this.useExtraRandomHeight = extra; } - public boolean generate(WorldServer worldIn, Random rand, BlockPos position) + public boolean generate(AWorldServer worldIn, Random rand, BlockPos position) { int i = rand.zrange(3) + 5; diff --git a/common/src/common/worldgen/tree/WorldGenDarkOak.java b/common/src/common/worldgen/tree/WorldGenDarkOak.java index 75e40a9..27d5298 100755 --- a/common/src/common/worldgen/tree/WorldGenDarkOak.java +++ b/common/src/common/worldgen/tree/WorldGenDarkOak.java @@ -8,7 +8,7 @@ import common.rng.Random; import common.util.BlockPos; import common.util.Facing; import common.world.State; -import common.world.WorldServer; +import common.world.AWorldServer; public class WorldGenDarkOak extends WorldGenTree { @@ -22,7 +22,7 @@ public class WorldGenDarkOak extends WorldGenTree super(notify); } - public boolean generate(WorldServer worldIn, Random rand, BlockPos position) + public boolean generate(AWorldServer worldIn, Random rand, BlockPos position) { int i = rand.zrange(3) + rand.zrange(2) + 6; int j = position.getX(); @@ -161,7 +161,7 @@ public class WorldGenDarkOak extends WorldGenTree } } - private boolean func_181638_a(WorldServer p_181638_1_, BlockPos p_181638_2_, int p_181638_3_) + private boolean func_181638_a(AWorldServer p_181638_1_, BlockPos p_181638_2_, int p_181638_3_) { int i = p_181638_2_.getX(); int j = p_181638_2_.getY(); @@ -197,7 +197,7 @@ public class WorldGenDarkOak extends WorldGenTree return true; } - private void func_181639_b(WorldServer p_181639_1_, BlockPos p_181639_2_) + private void func_181639_b(AWorldServer p_181639_1_, BlockPos p_181639_2_) { if (this.canBeReplaced(p_181639_1_.getState(p_181639_2_).getBlock())) { @@ -205,7 +205,7 @@ public class WorldGenDarkOak extends WorldGenTree } } - private void func_150526_a(WorldServer worldIn, int p_150526_2_, int p_150526_3_, int p_150526_4_) + private void func_150526_a(AWorldServer worldIn, int p_150526_2_, int p_150526_3_, int p_150526_4_) { BlockPos blockpos = new BlockPos(p_150526_2_, p_150526_3_, p_150526_4_); Block block = worldIn.getState(blockpos).getBlock(); diff --git a/common/src/common/worldgen/tree/WorldGenHugeTree.java b/common/src/common/worldgen/tree/WorldGenHugeTree.java index 2830025..d13cdf6 100755 --- a/common/src/common/worldgen/tree/WorldGenHugeTree.java +++ b/common/src/common/worldgen/tree/WorldGenHugeTree.java @@ -7,7 +7,7 @@ import common.material.Material; import common.rng.Random; import common.util.BlockPos; import common.world.State; -import common.world.WorldServer; +import common.world.AWorldServer; public abstract class WorldGenHugeTree extends WorldGenTree { @@ -42,7 +42,7 @@ public abstract class WorldGenHugeTree extends WorldGenTree return i; } - private boolean func_175926_c(WorldServer worldIn, BlockPos p_175926_2_, int p_175926_3_) + private boolean func_175926_c(AWorldServer worldIn, BlockPos p_175926_2_, int p_175926_3_) { boolean flag = true; @@ -81,7 +81,7 @@ public abstract class WorldGenHugeTree extends WorldGenTree } } - private boolean func_175927_a(BlockPos p_175927_1_, WorldServer worldIn) + private boolean func_175927_a(BlockPos p_175927_1_, AWorldServer worldIn) { BlockPos blockpos = p_175927_1_.down(); Block block = worldIn.getState(blockpos).getBlock(); @@ -100,12 +100,12 @@ public abstract class WorldGenHugeTree extends WorldGenTree } } - protected boolean func_175929_a(WorldServer worldIn, Random p_175929_2_, BlockPos p_175929_3_, int p_175929_4_) + protected boolean func_175929_a(AWorldServer worldIn, Random p_175929_2_, BlockPos p_175929_3_, int p_175929_4_) { return this.func_175926_c(worldIn, p_175929_3_, p_175929_4_) && this.func_175927_a(p_175929_3_, worldIn); } - protected void func_175925_a(WorldServer worldIn, BlockPos p_175925_2_, int p_175925_3_) + protected void func_175925_a(AWorldServer worldIn, BlockPos p_175925_2_, int p_175925_3_) { int i = p_175925_3_ * p_175925_3_; @@ -130,7 +130,7 @@ public abstract class WorldGenHugeTree extends WorldGenTree } } - protected void func_175928_b(WorldServer worldIn, BlockPos p_175928_2_, int p_175928_3_) + protected void func_175928_b(AWorldServer worldIn, BlockPos p_175928_2_, int p_175928_3_) { int i = p_175928_3_ * p_175928_3_; diff --git a/common/src/common/worldgen/tree/WorldGenJungle.java b/common/src/common/worldgen/tree/WorldGenJungle.java index b034df5..cd68e7a 100755 --- a/common/src/common/worldgen/tree/WorldGenJungle.java +++ b/common/src/common/worldgen/tree/WorldGenJungle.java @@ -7,7 +7,7 @@ import common.rng.Random; import common.util.BlockPos; import common.util.ExtMath; import common.world.State; -import common.world.WorldServer; +import common.world.AWorldServer; public class WorldGenJungle extends WorldGenHugeTree { @@ -16,7 +16,7 @@ public class WorldGenJungle extends WorldGenHugeTree super(p_i46448_1_, p_i46448_2_, p_i46448_3_, p_i46448_4_, p_i46448_5_); } - public boolean generate(WorldServer worldIn, Random rand, BlockPos position) + public boolean generate(AWorldServer worldIn, Random rand, BlockPos position) { int i = this.func_150533_a(rand); @@ -113,7 +113,7 @@ public class WorldGenJungle extends WorldGenHugeTree } } - private void func_181632_a(WorldServer p_181632_1_, Random p_181632_2_, BlockPos p_181632_3_, PropertyBool p_181632_4_) + private void func_181632_a(AWorldServer p_181632_1_, Random p_181632_2_, BlockPos p_181632_3_, PropertyBool p_181632_4_) { if (p_181632_2_.zrange(3) > 0 && p_181632_1_.isAirBlock(p_181632_3_)) { @@ -121,7 +121,7 @@ public class WorldGenJungle extends WorldGenHugeTree } } - private void func_175930_c(WorldServer worldIn, BlockPos p_175930_2_, int p_175930_3_) + private void func_175930_c(AWorldServer worldIn, BlockPos p_175930_2_, int p_175930_3_) { int i = 2; diff --git a/common/src/common/worldgen/tree/WorldGenPine.java b/common/src/common/worldgen/tree/WorldGenPine.java index 84552a5..b4ffb5c 100755 --- a/common/src/common/worldgen/tree/WorldGenPine.java +++ b/common/src/common/worldgen/tree/WorldGenPine.java @@ -8,7 +8,7 @@ import common.rng.Random; import common.util.BlockPos; import common.util.ExtMath; import common.world.State; -import common.world.WorldServer; +import common.world.AWorldServer; public class WorldGenPine extends WorldGenHugeTree { @@ -23,7 +23,7 @@ public class WorldGenPine extends WorldGenHugeTree this.useBaseHeight = p_i45457_2_; } - public boolean generate(WorldServer worldIn, Random rand, BlockPos position) + public boolean generate(AWorldServer worldIn, Random rand, BlockPos position) { int i = this.func_150533_a(rand); @@ -73,7 +73,7 @@ public class WorldGenPine extends WorldGenHugeTree } } - private void func_150541_c(WorldServer worldIn, int p_150541_2_, int p_150541_3_, int p_150541_4_, int p_150541_5_, Random p_150541_6_) + private void func_150541_c(AWorldServer worldIn, int p_150541_2_, int p_150541_3_, int p_150541_4_, int p_150541_5_, Random p_150541_6_) { int i = p_150541_6_.zrange(5) + (this.useBaseHeight ? this.baseHeight : 3); int j = 0; @@ -87,7 +87,7 @@ public class WorldGenPine extends WorldGenHugeTree } } - public void finish(WorldServer worldIn, Random p_180711_2_, BlockPos p_180711_3_) + public void finish(AWorldServer worldIn, Random p_180711_2_, BlockPos p_180711_3_) { this.func_175933_b(worldIn, p_180711_3_.west().north()); this.func_175933_b(worldIn, p_180711_3_.east(2).north()); @@ -107,7 +107,7 @@ public class WorldGenPine extends WorldGenHugeTree } } - private void func_175933_b(WorldServer worldIn, BlockPos p_175933_2_) + private void func_175933_b(AWorldServer worldIn, BlockPos p_175933_2_) { for (int i = -2; i <= 2; ++i) { @@ -121,7 +121,7 @@ public class WorldGenPine extends WorldGenHugeTree } } - private void func_175934_c(WorldServer worldIn, BlockPos p_175934_2_) + private void func_175934_c(AWorldServer worldIn, BlockPos p_175934_2_) { for (int i = 2; i >= -3; --i) { diff --git a/common/src/common/worldgen/tree/WorldGenSavanna.java b/common/src/common/worldgen/tree/WorldGenSavanna.java index 068b0d7..c9f37cd 100755 --- a/common/src/common/worldgen/tree/WorldGenSavanna.java +++ b/common/src/common/worldgen/tree/WorldGenSavanna.java @@ -8,7 +8,7 @@ import common.rng.Random; import common.util.BlockPos; import common.util.Facing; import common.world.State; -import common.world.WorldServer; +import common.world.AWorldServer; public class WorldGenSavanna extends WorldGenTree { @@ -23,7 +23,7 @@ public class WorldGenSavanna extends WorldGenTree super(p_i45463_1_); } - public boolean generate(WorldServer worldIn, Random rand, BlockPos position) + public boolean generate(AWorldServer worldIn, Random rand, BlockPos position) { int i = rand.zrange(3) + rand.zrange(3) + 5; boolean flag = true; @@ -202,12 +202,12 @@ public class WorldGenSavanna extends WorldGenTree } } - private void func_181642_b(WorldServer p_181642_1_, BlockPos p_181642_2_) + private void func_181642_b(AWorldServer p_181642_1_, BlockPos p_181642_2_) { this.setBlockAndNotifyAdequately(p_181642_1_, p_181642_2_, field_181643_a); } - private void func_175924_b(WorldServer worldIn, BlockPos p_175924_2_) + private void func_175924_b(AWorldServer worldIn, BlockPos p_175924_2_) { Material material = worldIn.getState(p_175924_2_).getBlock().getMaterial(); diff --git a/common/src/common/worldgen/tree/WorldGenSwamp.java b/common/src/common/worldgen/tree/WorldGenSwamp.java index cb4ebcb..ea77f4c 100755 --- a/common/src/common/worldgen/tree/WorldGenSwamp.java +++ b/common/src/common/worldgen/tree/WorldGenSwamp.java @@ -9,7 +9,7 @@ import common.properties.PropertyBool; import common.rng.Random; import common.util.BlockPos; import common.world.State; -import common.world.WorldServer; +import common.world.AWorldServer; public class WorldGenSwamp extends WorldGenTree { @@ -24,7 +24,7 @@ public class WorldGenSwamp extends WorldGenTree super(false); } - public boolean generate(WorldServer worldIn, Random rand, BlockPos position) + public boolean generate(AWorldServer worldIn, Random rand, BlockPos position) { int i; @@ -186,7 +186,7 @@ public class WorldGenSwamp extends WorldGenTree } } - private void func_181647_a(WorldServer p_181647_1_, BlockPos p_181647_2_, PropertyBool p_181647_3_) + private void func_181647_a(AWorldServer p_181647_1_, BlockPos p_181647_2_, PropertyBool p_181647_3_) { State iblockstate = Blocks.vine.getState().withProperty(p_181647_3_, Boolean.valueOf(true)); this.setBlockAndNotifyAdequately(p_181647_1_, p_181647_2_, iblockstate); diff --git a/common/src/common/worldgen/tree/WorldGenTaiga1.java b/common/src/common/worldgen/tree/WorldGenTaiga1.java index f940439..c9a2b45 100755 --- a/common/src/common/worldgen/tree/WorldGenTaiga1.java +++ b/common/src/common/worldgen/tree/WorldGenTaiga1.java @@ -7,7 +7,7 @@ import common.material.Material; import common.rng.Random; import common.util.BlockPos; import common.world.State; -import common.world.WorldServer; +import common.world.AWorldServer; public class WorldGenTaiga1 extends WorldGenTree { @@ -22,7 +22,7 @@ public class WorldGenTaiga1 extends WorldGenTree super(false); } - public boolean generate(WorldServer worldIn, Random rand, BlockPos position) + public boolean generate(AWorldServer worldIn, Random rand, BlockPos position) { int i = rand.zrange(5) + 7; int j = i - rand.zrange(2) - 3; diff --git a/common/src/common/worldgen/tree/WorldGenTaiga2.java b/common/src/common/worldgen/tree/WorldGenTaiga2.java index 014bda7..10f3ec1 100755 --- a/common/src/common/worldgen/tree/WorldGenTaiga2.java +++ b/common/src/common/worldgen/tree/WorldGenTaiga2.java @@ -7,7 +7,7 @@ import common.material.Material; import common.rng.Random; import common.util.BlockPos; import common.world.State; -import common.world.WorldServer; +import common.world.AWorldServer; public class WorldGenTaiga2 extends WorldGenTree { @@ -22,7 +22,7 @@ public class WorldGenTaiga2 extends WorldGenTree super(p_i2025_1_); } - public boolean generate(WorldServer worldIn, Random rand, BlockPos position) + public boolean generate(AWorldServer worldIn, Random rand, BlockPos position) { int i = rand.zrange(4) + 6; int j = 1 + rand.zrange(2); diff --git a/common/src/common/worldgen/tree/WorldGenTree.java b/common/src/common/worldgen/tree/WorldGenTree.java index 82bf0fc..4ea8b65 100755 --- a/common/src/common/worldgen/tree/WorldGenTree.java +++ b/common/src/common/worldgen/tree/WorldGenTree.java @@ -7,7 +7,7 @@ import common.init.Blocks; import common.material.Material; import common.rng.Random; import common.util.BlockPos; -import common.world.WorldServer; +import common.world.AWorldServer; import common.worldgen.FeatureGenerator; public abstract class WorldGenTree extends FeatureGenerator @@ -27,11 +27,11 @@ public abstract class WorldGenTree extends FeatureGenerator { } - public void finish(WorldServer worldIn, Random random, BlockPos pos) + public void finish(AWorldServer worldIn, Random random, BlockPos pos) { } - protected void setBaseBlock(WorldServer worldIn, BlockPos pos) + protected void setBaseBlock(AWorldServer worldIn, BlockPos pos) { if (worldIn.getState(pos) != worldIn.dimension.getTop()) { diff --git a/server/src/server/Server.java b/server/src/server/Server.java index 52675ce..8cd6b84 100755 --- a/server/src/server/Server.java +++ b/server/src/server/Server.java @@ -20,7 +20,6 @@ import java.util.concurrent.ExecutionException; import java.util.concurrent.Executors; import java.util.concurrent.FutureTask; -import common.IServer; import common.collect.Lists; import common.collect.Maps; import common.color.TextColor; @@ -73,9 +72,7 @@ import common.util.Position; import common.util.Tuple; import common.util.Util; import common.util.WorldPos; -import common.world.Region; import common.world.World; -import common.world.WorldServer; import io.netty.bootstrap.ServerBootstrap; import io.netty.channel.Channel; import io.netty.channel.ChannelException; @@ -94,8 +91,10 @@ import server.command.FixedExecutor; import server.network.HandshakeHandler; import server.network.Player; import server.world.Converter; +import server.world.Region; +import server.world.WorldServer; -public final class Server implements IThreadListener, IServer { +public final class Server implements IThreadListener { private static final LazyLoadBase SERVER_NIO_EVENTLOOP = new LazyLoadBase() { protected NioEventLoopGroup load() { return new NioEventLoopGroup(0, (new ThreadFactoryBuilder()).setNameFormat("Netty Server IO #%d").setDaemon(true).build()); @@ -144,7 +143,7 @@ public final class Server implements IThreadListener, IServer { Util.checkOs(); Registry.setup("Server thread"); boolean debug = System.getProperty("server.debug", null) != null; - boolean ipc = debug || System.getProperty("server.pipe", null) != null; + boolean ipc = System.getProperty("server.pipe", null) != null; int port = Integer.parseInt(System.getProperty("server.port", "" + Config.PORT)); final Server server = new Server(debug, ipc); Registry.addShutdownHook(new Runnable() { @@ -192,7 +191,7 @@ public final class Server implements IThreadListener, IServer { NBTTagCompound tag = NBTLoader.readGZip(file); NBTTagCompound cfg = tag.getCompoundTag("Config"); for(String key : cfg.getKeySet()) { - Config.set(key, cfg.getString(key), null); + Config.set(key, cfg.getString(key), false); } UniverseRegistry.loadNbt(tag.getCompoundTag("Universe")); long lastPlayed = tag.getLong("LastAccess"); @@ -217,6 +216,21 @@ public final class Server implements IThreadListener, IServer { private Server(boolean debug, boolean ipc) { this.debug = debug; this.ipcpipe = ipc; + Config.setCallback(new Runnable() { + public void run() { + for(WorldServer world : Server.this.getWorlds()) { + world.updatePhysics(); + } + Server.this.sendPacket(new SPacketWorld(WorldServer.clampGravity(), Config.dayCycle, Config.timeFlow)); + } + }, "daylightCycle", "timeFlow", "gravity"); + Config.setCallback(new Runnable() { + public void run() { + for(WorldServer world : Server.this.getWorlds()) { + world.updateViewRadius(); + } + } + }, "viewDistance"); } public CommandEnvironment getScriptEnvironment() { @@ -353,10 +367,10 @@ public final class Server implements IThreadListener, IServer { else { Config.clear(); UniverseRegistry.clear(); - Config.set("daylightCycle", "false", null); - Config.set("weatherChanges", "false", null); - Config.set("mobSpawning", "false", null); - Config.set("spawnRadius", "0", null); + Config.set("daylightCycle", "false", false); + Config.set("weatherChanges", "false", false); + Config.set("mobSpawning", "false", false); + Config.set("spawnRadius", "0", false); this.worlds.add(this.space = new WorldServer(this, World.START_TIME, Space.INSTANCE, true)); this.dimensions.put(this.space.dimension.getDimensionId(), this.space); @@ -565,7 +579,7 @@ public final class Server implements IThreadListener, IServer { } this.networkTick(); if(++this.pingTimer > 600) { - this.sendPacket(new S38PacketPlayerListItem(this.getIPlayers())); + this.sendPacket(new S38PacketPlayerListItem((List)this.getPlayers())); this.pingTimer = 0; } if(Config.saveInterval > 0 && ++this.saveTimer >= Config.saveInterval) { @@ -653,10 +667,6 @@ public final class Server implements IThreadListener, IServer { return this.players; } - public List getIPlayers() { - return (List)this.players; - } - public Player getPlayer(String user) { return this.usermap.get(user); } @@ -676,7 +686,7 @@ public final class Server implements IThreadListener, IServer { public void setVar(String cv, String value) { this.schedule(new Runnable() { public void run() { - Config.set(cv, value, Server.this); + Config.set(cv, value, true); } }); } @@ -773,7 +783,7 @@ public final class Server implements IThreadListener, IServer { } }); } - connection.sendPacket(new RPacketLoginSuccess()); + connection.sendPacket(new RPacketLoginSuccess(this.debug)); connection.setNetHandler(conn); this.players.add(conn); this.usermap.put(loginUser, conn); @@ -827,7 +837,7 @@ public final class Server implements IThreadListener, IServer { EntityNPC player = conn.getEntity(); player.unmount(); this.writePlayer(conn); - WorldServer world = player.getServerWorld(); + WorldServer world = (WorldServer)player.getServerWorld(); world.removeEntity(player); world.removePlayer(player); this.players.remove(conn); @@ -836,7 +846,7 @@ public final class Server implements IThreadListener, IServer { } private void preparePlayer(EntityNPC player, WorldServer oldWorld) { - WorldServer newWorld = player.getServerWorld(); + WorldServer newWorld = (WorldServer)player.getServerWorld(); if(oldWorld != null) { oldWorld.removePlayer(player); } @@ -1000,7 +1010,7 @@ public final class Server implements IThreadListener, IServer { } public void transferToDimension(EntityNPC player, int dimension, BlockPos pos, float yaw, float pitch, PortalType portal) { - WorldServer oldWorld = player.getServerWorld(); // this.getWorld(player.dimension); + WorldServer oldWorld = (WorldServer)player.getServerWorld(); // this.getWorld(player.dimension); // player.dimension = dimension; WorldServer newWorld = this.getWorld(dimension); player.connection.sendPacket(new SPacketRespawn(newWorld.dimension, EntityRegistry.getEntityID(player), player.connection.isInEditor())); diff --git a/common/src/common/clipboard/ClipboardPlacer.java b/server/src/server/clipboard/ClipboardPlacer.java similarity index 98% rename from common/src/common/clipboard/ClipboardPlacer.java rename to server/src/server/clipboard/ClipboardPlacer.java index b2dc5a7..a6e93e5 100755 --- a/common/src/common/clipboard/ClipboardPlacer.java +++ b/server/src/server/clipboard/ClipboardPlacer.java @@ -1,4 +1,4 @@ -package common.clipboard; +package server.clipboard; import java.util.Deque; import java.util.HashMap; @@ -12,6 +12,7 @@ import common.block.Block; import common.block.BlockDoor; import common.block.BlockRailBase; import common.block.ITileEntityProvider; +import common.clipboard.ClipboardBlock; import common.collect.Lists; import common.init.Blocks; import common.init.ReorderRegistry; @@ -19,7 +20,7 @@ import common.inventory.IInventory; import common.tileentity.TileEntity; import common.util.BlockPos; import common.util.Vec3i; -import common.world.WorldServer; +import server.world.WorldServer; public class ClipboardPlacer { private static class BlockEntry { diff --git a/server/src/server/command/EntityListParser.java b/server/src/server/command/EntityListParser.java index c62aeaf..130ebbb 100644 --- a/server/src/server/command/EntityListParser.java +++ b/server/src/server/command/EntityListParser.java @@ -11,8 +11,8 @@ import common.entity.Entity; import common.entity.EntityType; import common.entity.types.EntityLiving; import common.init.EntityRegistry; -import common.world.WorldServer; import server.network.Player; +import server.world.WorldServer; public class EntityListParser extends EntityParser { public EntityListParser(String name, boolean useSender, boolean livingOnly) { diff --git a/server/src/server/command/EntityParser.java b/server/src/server/command/EntityParser.java index 3b5ff7a..09a88dd 100644 --- a/server/src/server/command/EntityParser.java +++ b/server/src/server/command/EntityParser.java @@ -6,7 +6,7 @@ import java.util.List; import common.collect.Lists; import common.entity.Entity; import common.entity.types.EntityLiving; -import common.world.WorldServer; +import server.world.WorldServer; public class EntityParser extends PlayerEntityParser { protected final boolean livingOnly; diff --git a/server/src/server/command/WorldParser.java b/server/src/server/command/WorldParser.java index 87c9d43..c76e27c 100644 --- a/server/src/server/command/WorldParser.java +++ b/server/src/server/command/WorldParser.java @@ -5,7 +5,7 @@ import java.util.List; import common.collect.Lists; import common.dimension.Dimension; -import common.world.WorldServer; +import server.world.WorldServer; public class WorldParser extends DimensionParser { private final boolean loadedOnly; diff --git a/server/src/server/command/commands/CommandSpawn.java b/server/src/server/command/commands/CommandSpawn.java index 2534793..053ff75 100644 --- a/server/src/server/command/commands/CommandSpawn.java +++ b/server/src/server/command/commands/CommandSpawn.java @@ -11,12 +11,12 @@ import common.init.EntityRegistry; import common.nbt.NBTTagCompound; import common.util.Util; import common.util.Vec3; -import common.world.WorldServer; import server.command.Command; import server.command.CommandEnvironment; import server.command.Executor; import server.command.RunException; import server.network.Player; +import server.world.WorldServer; public class CommandSpawn extends Command { public CommandSpawn() { diff --git a/server/src/server/command/commands/CommandTime.java b/server/src/server/command/commands/CommandTime.java index 1f3561f..97f59d2 100644 --- a/server/src/server/command/commands/CommandTime.java +++ b/server/src/server/command/commands/CommandTime.java @@ -3,11 +3,11 @@ package server.command.commands; import common.dimension.Dimension; import common.item.ItemSpaceNavigator; import common.util.Position; -import common.world.WorldServer; import server.command.Command; import server.command.CommandEnvironment; import server.command.Executor; import server.command.RunException; +import server.world.WorldServer; public class CommandTime extends Command { public CommandTime() { diff --git a/server/src/server/command/commands/CommandWeather.java b/server/src/server/command/commands/CommandWeather.java index ea62180..2a45a62 100644 --- a/server/src/server/command/commands/CommandWeather.java +++ b/server/src/server/command/commands/CommandWeather.java @@ -1,11 +1,11 @@ package server.command.commands; import common.world.Weather; -import common.world.WorldServer; import server.command.Command; import server.command.CommandEnvironment; import server.command.Executor; import server.command.RunException; +import server.world.WorldServer; public class CommandWeather extends Command { public CommandWeather() { diff --git a/server/src/server/command/commands/CommandWorld.java b/server/src/server/command/commands/CommandWorld.java index 6257e46..5ce211c 100644 --- a/server/src/server/command/commands/CommandWorld.java +++ b/server/src/server/command/commands/CommandWorld.java @@ -4,10 +4,10 @@ import java.util.List; import common.entity.Entity; import common.util.BlockPos; -import common.world.WorldServer; import server.command.Command; import server.command.CommandEnvironment; import server.command.Executor; +import server.world.WorldServer; public class CommandWorld extends Command { public CommandWorld() { diff --git a/server/src/server/network/Player.java b/server/src/server/network/Player.java index 6a418d3..97c6f93 100755 --- a/server/src/server/network/Player.java +++ b/server/src/server/network/Player.java @@ -14,7 +14,6 @@ import common.block.BlockFenceGate; import common.block.BlockWall; import common.clipboard.BlockTransform; import common.clipboard.ClipboardBlock; -import common.clipboard.ClipboardPlacer; import common.clipboard.Rotation; import common.clipboard.RotationValue; import common.clipboard.Vector; @@ -126,14 +125,15 @@ import common.util.Vec3i; import common.util.WorldPos; import common.village.MerchantRecipeList; import common.world.Chunk; -import common.world.Region; import common.world.State; import common.world.World; -import common.world.WorldServer; import io.netty.util.concurrent.Future; import io.netty.util.concurrent.GenericFutureListener; import server.Server; +import server.clipboard.ClipboardPlacer; import server.command.Executor; +import server.world.Region; +import server.world.WorldServer; public class Player extends NetHandler implements ICrafting, Executor, IPlayer { @@ -580,6 +580,10 @@ public class Player extends NetHandler implements ICrafting, Executor, IPlayer this.sendPacket(new SPacketMessage(String.format(format, args), Type.HOTBAR)); } + private WorldServer getEntityWorld() { + return (WorldServer)this.entity.getServerWorld(); + } + public void sendPickupMessage(Entity entity, int amount) { if(entity instanceof EntityItem) if(amount == 1) @@ -1363,7 +1367,7 @@ public class Player extends NetHandler implements ICrafting, Executor, IPlayer int ny = this.clipboard[0].length; int nz = this.clipboard[0][0].length; BlockPos to = this.entity.getPosition(); - ClipboardPlacer placer = new ClipboardPlacer(this.entity.getServerWorld()); + ClipboardPlacer placer = new ClipboardPlacer((WorldServer)this.entity.getServerWorld()); BlockTransform transform = null; if(this.rotation != 0 || this.flipX || this.flipZ) { transform = new BlockTransform(); @@ -1448,7 +1452,7 @@ public class Player extends NetHandler implements ICrafting, Executor, IPlayer if(this.selectionDim == Integer.MIN_VALUE || this.selectionDim != this.entity.worldObj.dimension.getDimensionId() || this.selPos1 == null || this.selPos2 == null) return false; - WorldServer source = this.entity.getServerWorld(); + WorldServer source = this.getEntityWorld(); int mx = Math.min(this.selPos1.getX(), this.selPos2.getX()); int my = Math.min(this.selPos1.getY(), this.selPos2.getY()); int mz = Math.min(this.selPos1.getZ(), this.selPos2.getZ()); @@ -1749,7 +1753,7 @@ public class Player extends NetHandler implements ICrafting, Executor, IPlayer return true; } } - Config.set(args[0], value, this.server); + Config.set(args[0], value, true); this.addConsole(TextColor.YELLOW + "%s" + TextColor.GRAY + " -> " + ((cv.type == ValueType.BOOLEAN ? (cv.getValue().equals("true") ? TextColor.GREEN : TextColor.RED) : (cv.type == ValueType.STRING ? TextColor.NEON : TextColor.BLUE))) + "%s", args[0], cv.type == ValueType.STRING ? ("'" + cv.getValue() + "'") : cv.getValue()); } return true; @@ -2071,7 +2075,7 @@ public class Player extends NetHandler implements ICrafting, Executor, IPlayer } else { - WorldServer worldserver = this.entity.getServerWorld(); // this.serverController.getWorld(this.playerEntity.dimension); + WorldServer worldserver = this.getEntityWorld(); // this.serverController.getWorld(this.playerEntity.dimension); // this.updated = true; double d0 = this.entity.posX; @@ -2308,7 +2312,7 @@ public class Player extends NetHandler implements ICrafting, Executor, IPlayer NetHandler.checkThread(packetIn, this, this.server); if(this.charEditor) return; - WorldServer worldserver = this.entity.getServerWorld(); // this.serverController.getWorld(this.playerEntity.dimension); + WorldServer worldserver = this.getEntityWorld(); // this.serverController.getWorld(this.playerEntity.dimension); BlockPos blockpos = packetIn.getPosition(); switch (packetIn.getStatus()) @@ -2394,7 +2398,7 @@ public class Player extends NetHandler implements ICrafting, Executor, IPlayer NetHandler.checkThread(packetIn, this, this.server); if(this.charEditor) return; - WorldServer worldserver = this.entity.getServerWorld(); // this.serverController.getWorld(this.playerEntity.dimension); + WorldServer worldserver = this.getEntityWorld(); // this.serverController.getWorld(this.playerEntity.dimension); ItemStack itemstack = this.entity.inventory.getCurrentItem(); boolean flag = false; BlockPos blockpos = packetIn.getPosition(); @@ -2461,7 +2465,7 @@ public class Player extends NetHandler implements ICrafting, Executor, IPlayer private void useEntity(int entityId, boolean interact) { - WorldServer worldserver = this.entity.getServerWorld(); // this.serverController.getWorld(this.playerEntity.dimension); + WorldServer worldserver = this.getEntityWorld(); // this.serverController.getWorld(this.playerEntity.dimension); Entity entity = worldserver.getEntityByID(entityId); if (entity != null) { @@ -3041,7 +3045,7 @@ public class Player extends NetHandler implements ICrafting, Executor, IPlayer if(this.charEditor) return; - WorldServer worldserver = this.entity.getServerWorld(); // this.serverController.getWorld(this.playerEntity.dimension); + WorldServer worldserver = this.getEntityWorld(); // this.serverController.getWorld(this.playerEntity.dimension); BlockPos blockpos = packetIn.getPosition(); if (worldserver.isBlockLoaded(blockpos)) diff --git a/common/src/common/village/VillageCollection.java b/server/src/server/village/VillageCollection.java similarity index 98% rename from common/src/common/village/VillageCollection.java rename to server/src/server/village/VillageCollection.java index ecc2d9f..53ad125 100755 --- a/common/src/common/village/VillageCollection.java +++ b/server/src/server/village/VillageCollection.java @@ -1,4 +1,4 @@ -package common.village; +package server.village; import java.util.Iterator; import java.util.List; @@ -11,7 +11,9 @@ import common.nbt.NBTTagCompound; import common.nbt.NBTTagList; import common.util.BlockPos; import common.util.Facing; -import common.world.WorldServer; +import common.village.Village; +import common.village.VillageDoorInfo; +import server.world.WorldServer; public class VillageCollection { diff --git a/server/src/server/world/Converter.java b/server/src/server/world/Converter.java index 5bc9269..34001e7 100644 --- a/server/src/server/world/Converter.java +++ b/server/src/server/world/Converter.java @@ -86,7 +86,6 @@ import common.tileentity.TileEntitySign; import common.tileentity.TileEntitySkull; import common.util.Facing; import common.util.NibbleArray; -import common.world.Region; import common.world.State; import common.world.Weather; import common.world.World; @@ -1148,7 +1147,7 @@ public abstract class Converter { NBTTagCompound rules = nbt.getCompoundTag("GameRules"); for(Entry rule : OLD_GAMERULES.entrySet()) { if(rules.hasKey(rule.getKey(), 8)) - Config.set(rule.getValue(), rules.getString(rule.getKey()), null); + Config.set(rule.getValue(), rules.getString(rule.getKey()), false); } } Log.JNI.info("Speichere neue server.nbt ..."); diff --git a/common/src/common/world/Region.java b/server/src/server/world/Region.java similarity index 99% rename from common/src/common/world/Region.java rename to server/src/server/world/Region.java index ea0a6ae..fcf1367 100755 --- a/common/src/common/world/Region.java +++ b/server/src/server/world/Region.java @@ -1,4 +1,4 @@ -package common.world; +package server.world; import java.io.BufferedInputStream; import java.io.ByteArrayInputStream; @@ -32,6 +32,8 @@ import common.util.BlockPos; import common.util.NextTickListEntry; import common.util.NibbleArray; import common.util.Util; +import common.world.BlockArray; +import common.world.Chunk; public class Region { private static class ChunkBuffer extends ByteArrayOutputStream { diff --git a/common/src/common/world/Spawner.java b/server/src/server/world/Spawner.java similarity index 98% rename from common/src/common/world/Spawner.java rename to server/src/server/world/Spawner.java index b4a5468..5a4255b 100755 --- a/common/src/common/world/Spawner.java +++ b/server/src/server/world/Spawner.java @@ -1,4 +1,4 @@ -package common.world; +package server.world; import java.util.Set; @@ -16,6 +16,8 @@ import common.rng.WeightedList; import common.util.BlockPos; import common.util.ChunkPos; import common.util.ExtMath; +import common.world.Chunk; +import common.world.World; public abstract class Spawner { private static final int MOB_COUNT_DIV = (int)Math.pow(17.0D, 2.0D); diff --git a/common/src/common/world/WorldServer.java b/server/src/server/world/WorldServer.java similarity index 98% rename from common/src/common/world/WorldServer.java rename to server/src/server/world/WorldServer.java index 934b9ee..494458d 100755 --- a/common/src/common/world/WorldServer.java +++ b/server/src/server/world/WorldServer.java @@ -1,4 +1,4 @@ -package common.world; +package server.world; import java.io.File; import java.io.FileFilter; @@ -13,7 +13,6 @@ import java.util.TreeSet; import java.util.concurrent.ConcurrentHashMap; import java.util.function.Predicate; -import common.IServer; import common.biome.Biome; import common.biome.RngSpawn; import common.block.Block; @@ -75,7 +74,14 @@ import common.util.PortalType; import common.util.Position; import common.util.Vec3; import common.village.Village; -import common.village.VillageCollection; +import common.world.BlockArray; +import common.world.Chunk; +import common.world.Explosion; +import common.world.AWorldServer; +import common.world.LightType; +import common.world.State; +import common.world.Weather; +import common.world.World; import common.worldgen.BiomeGenSingle; import common.worldgen.BiomeGenerator; import common.worldgen.BlockReplacer; @@ -91,16 +97,19 @@ import common.worldgen.LootConstants; import common.worldgen.caves.MapGenBigCaves; import common.worldgen.caves.MapGenCaves; import common.worldgen.caves.MapGenRavine; -import common.worldgen.structure.MapGenBridge; -import common.worldgen.structure.MapGenMineshaft; -import common.worldgen.structure.MapGenScatteredFeature; -import common.worldgen.structure.MapGenStronghold; -import common.worldgen.structure.MapGenVillage; +import server.Server; +import server.network.Player; +import server.village.VillageCollection; +import server.worldgen.structure.MapGenBridge; +import server.worldgen.structure.MapGenMineshaft; +import server.worldgen.structure.MapGenScatteredFeature; +import server.worldgen.structure.MapGenStronghold; +import server.worldgen.structure.MapGenVillage; -public final class WorldServer extends World { +public final class WorldServer extends AWorldServer { private static final int[][] XZ_DIRS = new int[][] {{1, 0}, {0, 1}, {-1, 0}, {0, -1}}; - private final IServer server; + private final Server server; private final File chunkDir; private final Random grng; private final Set ticks = Sets.newHashSet(); @@ -162,9 +171,13 @@ public final class WorldServer extends World { private int updateLCG = this.rand.intv(); private long prevUpdate; private long time; + + public static float clampGravity() { + return ExtMath.clampf(Config.gravity, -10.0f, 10.0f); + } - public WorldServer(IServer server, long dtime, Dimension dim, boolean debug) { - super(dim, false, debug); + public WorldServer(Server server, long dtime, Dimension dim, boolean debug) { + super(dim, debug); this.server = server; // this.time = time; this.daytime = dtime; @@ -366,11 +379,7 @@ public final class WorldServer extends World { } } - public static float clampGravity() { - return ExtMath.clampf(Config.gravity, -10.0f, 10.0f); - } - - public IServer getServer() { + public Server getServer() { return this.server; } @@ -1632,7 +1641,7 @@ public final class WorldServer extends World { this.dungeons = null; } - public static String getLoadedInfo(IServer server) { + public static String getLoadedInfo(Server server) { int chunks = 0; int entities = 0; int tiles = 0; @@ -1698,7 +1707,7 @@ public final class WorldServer extends World { public void sendBlockBreakProgress(int breakerId, BlockPos pos, int progress) { - for (IPlayer conn : this.server.getIPlayers()) + for (Player conn : this.server.getPlayers()) { EntityNPC player = conn.getPresentEntity(); if (player != null && player.worldObj == this && player.getId() != breakerId) @@ -2643,6 +2652,18 @@ public final class WorldServer extends World { // return true; } + public List getAllPlayers() { + return (List)this.server.getPlayers(); + } + + public void placeInDimension(Entity entity, AWorldServer oldWorld, AWorldServer world, BlockPos pos, PortalType portal) { + this.server.placeInDimension(entity, (WorldServer)oldWorld, (WorldServer)world, pos, portal); + } + + public AWorldServer getOtherWorld(int dimension) { + return this.server.getWorld(dimension); + } + private static class EventList extends ArrayList { private EventList() { } diff --git a/common/src/common/worldgen/structure/MapGenBridge.java b/server/src/server/worldgen/structure/MapGenBridge.java similarity index 96% rename from common/src/common/worldgen/structure/MapGenBridge.java rename to server/src/server/worldgen/structure/MapGenBridge.java index 3a428b4..0a998ba 100755 --- a/common/src/common/worldgen/structure/MapGenBridge.java +++ b/server/src/server/worldgen/structure/MapGenBridge.java @@ -1,9 +1,9 @@ -package common.worldgen.structure; +package server.worldgen.structure; import java.util.List; import common.rng.Random; -import common.world.WorldServer; +import server.world.WorldServer; public class MapGenBridge extends MapGenStructure { diff --git a/common/src/common/worldgen/structure/MapGenMineshaft.java b/server/src/server/worldgen/structure/MapGenMineshaft.java similarity index 96% rename from common/src/common/worldgen/structure/MapGenMineshaft.java rename to server/src/server/worldgen/structure/MapGenMineshaft.java index e464c18..2fee1e7 100755 --- a/common/src/common/worldgen/structure/MapGenMineshaft.java +++ b/server/src/server/worldgen/structure/MapGenMineshaft.java @@ -1,4 +1,4 @@ -package common.worldgen.structure; +package server.worldgen.structure; public class MapGenMineshaft extends MapGenStructure { diff --git a/common/src/common/worldgen/structure/MapGenScatteredFeature.java b/server/src/server/worldgen/structure/MapGenScatteredFeature.java similarity index 98% rename from common/src/common/worldgen/structure/MapGenScatteredFeature.java rename to server/src/server/worldgen/structure/MapGenScatteredFeature.java index 8de6711..e8caba9 100755 --- a/common/src/common/worldgen/structure/MapGenScatteredFeature.java +++ b/server/src/server/worldgen/structure/MapGenScatteredFeature.java @@ -1,4 +1,4 @@ -package common.worldgen.structure; +package server.worldgen.structure; import java.util.Arrays; import java.util.List; @@ -6,7 +6,7 @@ import java.util.List; import common.biome.Biome; import common.rng.Random; import common.util.BlockPos; -import common.world.WorldServer; +import server.world.WorldServer; public class MapGenScatteredFeature extends MapGenStructure { diff --git a/common/src/common/worldgen/structure/MapGenStronghold.java b/server/src/server/worldgen/structure/MapGenStronghold.java similarity index 98% rename from common/src/common/worldgen/structure/MapGenStronghold.java rename to server/src/server/worldgen/structure/MapGenStronghold.java index 10d7f64..cefc2f3 100755 --- a/common/src/common/worldgen/structure/MapGenStronghold.java +++ b/server/src/server/worldgen/structure/MapGenStronghold.java @@ -1,9 +1,9 @@ -package common.worldgen.structure; +package server.worldgen.structure; import java.util.List; import common.rng.Random; -import common.world.WorldServer; +import server.world.WorldServer; public class MapGenStronghold extends MapGenStructure { diff --git a/common/src/common/worldgen/structure/MapGenStructure.java b/server/src/server/worldgen/structure/MapGenStructure.java similarity index 95% rename from common/src/common/worldgen/structure/MapGenStructure.java rename to server/src/server/worldgen/structure/MapGenStructure.java index d339850..82aca60 100755 --- a/common/src/common/worldgen/structure/MapGenStructure.java +++ b/server/src/server/worldgen/structure/MapGenStructure.java @@ -1,4 +1,4 @@ -package common.worldgen.structure; +package server.worldgen.structure; import java.util.Iterator; import java.util.Map; @@ -10,16 +10,24 @@ import common.rng.Random; import common.util.BlockPos; import common.util.ChunkPos; import common.util.LongHashMap; +import common.world.AWorldServer; import common.world.World; -import common.world.WorldServer; -import common.world.WorldServer.WorldSavedData; import common.worldgen.ChunkPrimer; import common.worldgen.caves.MapGenBase; +import server.world.WorldServer; +import server.world.WorldServer.WorldSavedData; public abstract class MapGenStructure extends MapGenBase { private WorldSavedData structureData; protected Map structureMap = Maps.newHashMap(); + protected WorldServer worldObj; + + public void generate(AWorldServer worldIn, int x, int z, ChunkPrimer chunkPrimerIn) + { + this.worldObj = (WorldServer)worldIn; + super.generate(worldIn, x, z, chunkPrimerIn); + } public abstract String getStructureName(); diff --git a/common/src/common/worldgen/structure/MapGenStructureIO.java b/server/src/server/worldgen/structure/MapGenStructureIO.java similarity index 98% rename from common/src/common/worldgen/structure/MapGenStructureIO.java rename to server/src/server/worldgen/structure/MapGenStructureIO.java index 2556af7..7418618 100755 --- a/common/src/common/worldgen/structure/MapGenStructureIO.java +++ b/server/src/server/worldgen/structure/MapGenStructureIO.java @@ -1,11 +1,11 @@ -package common.worldgen.structure; +package server.worldgen.structure; import java.util.Map; import common.collect.Maps; import common.log.Log; import common.nbt.NBTTagCompound; -import common.world.WorldServer; +import server.world.WorldServer; public class MapGenStructureIO { diff --git a/common/src/common/worldgen/structure/MapGenVillage.java b/server/src/server/worldgen/structure/MapGenVillage.java similarity index 98% rename from common/src/common/worldgen/structure/MapGenVillage.java rename to server/src/server/worldgen/structure/MapGenVillage.java index b907379..e6119f8 100755 --- a/common/src/common/worldgen/structure/MapGenVillage.java +++ b/server/src/server/worldgen/structure/MapGenVillage.java @@ -1,4 +1,4 @@ -package common.worldgen.structure; +package server.worldgen.structure; import java.util.List; import java.util.Set; @@ -7,7 +7,7 @@ import common.biome.Biome; import common.collect.Sets; import common.nbt.NBTTagCompound; import common.rng.Random; -import common.world.WorldServer; +import server.world.WorldServer; public class MapGenVillage extends MapGenStructure { diff --git a/common/src/common/worldgen/structure/StructureBoundingBox.java b/server/src/server/worldgen/structure/StructureBoundingBox.java similarity index 99% rename from common/src/common/worldgen/structure/StructureBoundingBox.java rename to server/src/server/worldgen/structure/StructureBoundingBox.java index 482873c..70ddf56 100755 --- a/common/src/common/worldgen/structure/StructureBoundingBox.java +++ b/server/src/server/worldgen/structure/StructureBoundingBox.java @@ -1,4 +1,4 @@ -package common.worldgen.structure; +package server.worldgen.structure; import common.nbt.NBTTagIntArray; import common.util.BlockPos; diff --git a/common/src/common/worldgen/structure/StructureBridge.java b/server/src/server/worldgen/structure/StructureBridge.java similarity index 99% rename from common/src/common/worldgen/structure/StructureBridge.java rename to server/src/server/worldgen/structure/StructureBridge.java index 0970247..4dc4aa8 100755 --- a/common/src/common/worldgen/structure/StructureBridge.java +++ b/server/src/server/worldgen/structure/StructureBridge.java @@ -1,4 +1,4 @@ -package common.worldgen.structure; +package server.worldgen.structure; import java.util.List; @@ -10,8 +10,8 @@ import common.tileentity.TileEntity; import common.tileentity.TileEntityMobSpawner; import common.util.BlockPos; import common.util.Facing; -import common.world.WorldServer; import common.worldgen.LootConstants; +import server.world.WorldServer; public class StructureBridge diff --git a/common/src/common/worldgen/structure/StructureComponent.java b/server/src/server/worldgen/structure/StructureComponent.java similarity index 99% rename from common/src/common/worldgen/structure/StructureComponent.java rename to server/src/server/worldgen/structure/StructureComponent.java index bd76ec3..54d9af1 100755 --- a/common/src/common/worldgen/structure/StructureComponent.java +++ b/server/src/server/worldgen/structure/StructureComponent.java @@ -1,4 +1,4 @@ -package common.worldgen.structure; +package server.worldgen.structure; import java.util.List; @@ -18,7 +18,7 @@ import common.tileentity.TileEntityDispenser; import common.util.BlockPos; import common.util.Facing; import common.world.State; -import common.world.WorldServer; +import server.world.WorldServer; public abstract class StructureComponent { diff --git a/common/src/common/worldgen/structure/StructureMineshaft.java b/server/src/server/worldgen/structure/StructureMineshaft.java similarity index 99% rename from common/src/common/worldgen/structure/StructureMineshaft.java rename to server/src/server/worldgen/structure/StructureMineshaft.java index 21f5335..e3a08d5 100755 --- a/common/src/common/worldgen/structure/StructureMineshaft.java +++ b/server/src/server/worldgen/structure/StructureMineshaft.java @@ -1,4 +1,4 @@ -package common.worldgen.structure; +package server.worldgen.structure; import java.util.LinkedList; import java.util.List; @@ -17,8 +17,8 @@ import common.tileentity.TileEntityMobSpawner; import common.util.BlockPos; import common.util.Facing; import common.world.State; -import common.world.WorldServer; import common.worldgen.LootConstants; +import server.world.WorldServer; public class StructureMineshaft diff --git a/common/src/common/worldgen/structure/StructureMineshaftStart.java b/server/src/server/worldgen/structure/StructureMineshaftStart.java similarity index 90% rename from common/src/common/worldgen/structure/StructureMineshaftStart.java rename to server/src/server/worldgen/structure/StructureMineshaftStart.java index 72dc9b0..789b500 100755 --- a/common/src/common/worldgen/structure/StructureMineshaftStart.java +++ b/server/src/server/worldgen/structure/StructureMineshaftStart.java @@ -1,7 +1,7 @@ -package common.worldgen.structure; +package server.worldgen.structure; import common.rng.Random; -import common.world.WorldServer; +import server.world.WorldServer; public class StructureMineshaftStart extends StructureStart { diff --git a/common/src/common/worldgen/structure/StructureScattered.java b/server/src/server/worldgen/structure/StructureScattered.java similarity index 99% rename from common/src/common/worldgen/structure/StructureScattered.java rename to server/src/server/worldgen/structure/StructureScattered.java index e3b3bd4..6a667d2 100755 --- a/common/src/common/worldgen/structure/StructureScattered.java +++ b/server/src/server/worldgen/structure/StructureScattered.java @@ -1,4 +1,4 @@ -package common.worldgen.structure; +package server.worldgen.structure; import common.block.BlockFlower; import common.block.BlockFlowerPot; @@ -17,8 +17,8 @@ import common.nbt.NBTTagCompound; import common.rng.Random; import common.util.BlockPos; import common.util.Facing; -import common.world.WorldServer; import common.worldgen.LootConstants; +import server.world.WorldServer; public class StructureScattered { diff --git a/common/src/common/worldgen/structure/StructureStart.java b/server/src/server/worldgen/structure/StructureStart.java similarity index 98% rename from common/src/common/worldgen/structure/StructureStart.java rename to server/src/server/worldgen/structure/StructureStart.java index bbf98f0..bc06008 100755 --- a/common/src/common/worldgen/structure/StructureStart.java +++ b/server/src/server/worldgen/structure/StructureStart.java @@ -1,4 +1,4 @@ -package common.worldgen.structure; +package server.worldgen.structure; import java.util.Iterator; import java.util.LinkedList; @@ -7,7 +7,7 @@ import common.nbt.NBTTagCompound; import common.nbt.NBTTagList; import common.rng.Random; import common.util.ChunkPos; -import common.world.WorldServer; +import server.world.WorldServer; public abstract class StructureStart { diff --git a/common/src/common/worldgen/structure/StructureStronghold.java b/server/src/server/worldgen/structure/StructureStronghold.java similarity index 99% rename from common/src/common/worldgen/structure/StructureStronghold.java rename to server/src/server/worldgen/structure/StructureStronghold.java index 75f87c0..ad13933 100755 --- a/common/src/common/worldgen/structure/StructureStronghold.java +++ b/server/src/server/worldgen/structure/StructureStronghold.java @@ -1,4 +1,4 @@ -package common.worldgen.structure; +package server.worldgen.structure; import java.util.List; import java.util.Map; @@ -16,8 +16,8 @@ import common.tileentity.TileEntity; import common.tileentity.TileEntityMobSpawner; import common.util.BlockPos; import common.util.Facing; -import common.world.WorldServer; import common.worldgen.LootConstants; +import server.world.WorldServer; public class StructureStronghold diff --git a/common/src/common/worldgen/structure/StructureVillage.java b/server/src/server/worldgen/structure/StructureVillage.java similarity index 99% rename from common/src/common/worldgen/structure/StructureVillage.java rename to server/src/server/worldgen/structure/StructureVillage.java index 5d25145..810a4f6 100755 --- a/common/src/common/worldgen/structure/StructureVillage.java +++ b/server/src/server/worldgen/structure/StructureVillage.java @@ -1,4 +1,4 @@ -package common.worldgen.structure; +package server.worldgen.structure; import java.util.Iterator; import java.util.List; @@ -22,9 +22,9 @@ import common.rng.Random; import common.util.BlockPos; import common.util.Facing; import common.world.State; -import common.world.WorldServer; import common.worldgen.BiomeGenerator; import common.worldgen.LootConstants; +import server.world.WorldServer; public class StructureVillage From a3e8566ca2855169ea05036763528b23e56c679d Mon Sep 17 00:00:00 2001 From: Sen Date: Tue, 13 May 2025 17:19:40 +0200 Subject: [PATCH 025/200] move clipboard classes --- common/src/common/init/Registry.java | 2 -- server/src/server/Server.java | 4 ++++ .../src/server}/clipboard/BlockTransform.java | 2 +- .../src/server}/clipboard/ClipboardBlock.java | 2 +- server/src/server/clipboard/ClipboardPlacer.java | 2 -- .../src/server/clipboard}/ReorderRegistry.java | 7 +++++-- .../src/server}/clipboard/Rotation.java | 2 +- .../src/server/clipboard}/RotationRegistry.java | 7 ++----- .../src/server}/clipboard/RotationValue.java | 2 +- .../src/server}/clipboard/Vector.java | 2 +- server/src/server/network/Player.java | 12 ++++++------ server/src/server/world/WorldServer.java | 2 +- 12 files changed, 23 insertions(+), 23 deletions(-) rename {common/src/common => server/src/server}/clipboard/BlockTransform.java (99%) rename {common/src/common => server/src/server}/clipboard/ClipboardBlock.java (96%) rename {common/src/common/init => server/src/server/clipboard}/ReorderRegistry.java (98%) rename {common/src/common => server/src/server}/clipboard/Rotation.java (97%) rename {common/src/common/init => server/src/server/clipboard}/RotationRegistry.java (96%) rename {common/src/common => server/src/server}/clipboard/RotationValue.java (95%) rename {common/src/common => server/src/server}/clipboard/Vector.java (99%) diff --git a/common/src/common/init/Registry.java b/common/src/common/init/Registry.java index 43ddaf4..c6a34ff 100755 --- a/common/src/common/init/Registry.java +++ b/common/src/common/init/Registry.java @@ -32,8 +32,6 @@ public abstract class Registry { EntityRegistry.register(); DispenserRegistry.register(); UniverseRegistry.register(); - RotationRegistry.register(); - ReorderRegistry.register(); } public static void setup(String thread) { diff --git a/server/src/server/Server.java b/server/src/server/Server.java index 8cd6b84..738d227 100755 --- a/server/src/server/Server.java +++ b/server/src/server/Server.java @@ -86,6 +86,8 @@ import io.netty.channel.socket.nio.NioServerSocketChannel; import io.netty.handler.timeout.ReadTimeoutHandler; import io.netty.util.concurrent.Future; import io.netty.util.concurrent.GenericFutureListener; +import server.clipboard.ReorderRegistry; +import server.clipboard.RotationRegistry; import server.command.CommandEnvironment; import server.command.FixedExecutor; import server.network.HandshakeHandler; @@ -142,6 +144,8 @@ public final class Server implements IThreadListener { public static void main(String[] args) { Util.checkOs(); Registry.setup("Server thread"); + RotationRegistry.register(); + ReorderRegistry.register(); boolean debug = System.getProperty("server.debug", null) != null; boolean ipc = System.getProperty("server.pipe", null) != null; int port = Integer.parseInt(System.getProperty("server.port", "" + Config.PORT)); diff --git a/common/src/common/clipboard/BlockTransform.java b/server/src/server/clipboard/BlockTransform.java similarity index 99% rename from common/src/common/clipboard/BlockTransform.java rename to server/src/server/clipboard/BlockTransform.java index 62ae4b2..94a5c87 100755 --- a/common/src/common/clipboard/BlockTransform.java +++ b/server/src/server/clipboard/BlockTransform.java @@ -1,4 +1,4 @@ -package common.clipboard; +package server.clipboard; public class BlockTransform { private double m00, m01, m02, m03; diff --git a/common/src/common/clipboard/ClipboardBlock.java b/server/src/server/clipboard/ClipboardBlock.java similarity index 96% rename from common/src/common/clipboard/ClipboardBlock.java rename to server/src/server/clipboard/ClipboardBlock.java index 8ed9ea5..abb7c34 100755 --- a/common/src/common/clipboard/ClipboardBlock.java +++ b/server/src/server/clipboard/ClipboardBlock.java @@ -1,4 +1,4 @@ -package common.clipboard; +package server.clipboard; import common.nbt.NBTTagCompound; import common.tileentity.TileEntity; diff --git a/server/src/server/clipboard/ClipboardPlacer.java b/server/src/server/clipboard/ClipboardPlacer.java index a6e93e5..24d9db5 100755 --- a/server/src/server/clipboard/ClipboardPlacer.java +++ b/server/src/server/clipboard/ClipboardPlacer.java @@ -12,10 +12,8 @@ import common.block.Block; import common.block.BlockDoor; import common.block.BlockRailBase; import common.block.ITileEntityProvider; -import common.clipboard.ClipboardBlock; import common.collect.Lists; import common.init.Blocks; -import common.init.ReorderRegistry; import common.inventory.IInventory; import common.tileentity.TileEntity; import common.util.BlockPos; diff --git a/common/src/common/init/ReorderRegistry.java b/server/src/server/clipboard/ReorderRegistry.java similarity index 98% rename from common/src/common/init/ReorderRegistry.java rename to server/src/server/clipboard/ReorderRegistry.java index b5796fa..8e872b9 100755 --- a/common/src/common/init/ReorderRegistry.java +++ b/server/src/server/clipboard/ReorderRegistry.java @@ -1,4 +1,4 @@ -package common.init; +package server.clipboard; import java.util.HashMap; import java.util.HashSet; @@ -9,6 +9,9 @@ import common.block.Block; import common.block.BlockBed; import common.block.BlockDoor; import common.color.DyeColor; +import common.init.BlockRegistry; +import common.init.Blocks; +import common.init.WoodType; import common.util.Facing; import common.util.Vec3i; import common.world.State; @@ -33,7 +36,7 @@ public abstract class ReorderRegistry { return STATE_ATTACH.get(state); } - static void register() { + public static void register() { for(WoodType wood : WoodType.values()) { PLACE_LAST.add(BlockRegistry.getRegisteredBlock(wood.getName() + "_sapling")); } diff --git a/common/src/common/clipboard/Rotation.java b/server/src/server/clipboard/Rotation.java similarity index 97% rename from common/src/common/clipboard/Rotation.java rename to server/src/server/clipboard/Rotation.java index 51e4d1b..bf66507 100755 --- a/common/src/common/clipboard/Rotation.java +++ b/server/src/server/clipboard/Rotation.java @@ -1,4 +1,4 @@ -package common.clipboard; +package server.clipboard; import java.util.function.Predicate; diff --git a/common/src/common/init/RotationRegistry.java b/server/src/server/clipboard/RotationRegistry.java similarity index 96% rename from common/src/common/init/RotationRegistry.java rename to server/src/server/clipboard/RotationRegistry.java index 3c6eb32..38bc0c7 100755 --- a/common/src/common/init/RotationRegistry.java +++ b/server/src/server/clipboard/RotationRegistry.java @@ -1,4 +1,4 @@ -package common.init; +package server.clipboard; import java.util.HashMap; import java.util.List; @@ -16,9 +16,6 @@ import common.block.BlockRailBase; import common.block.BlockRailDetector; import common.block.BlockRailPowered; import common.block.BlockRotatedPillar; -import common.clipboard.Rotation; -import common.clipboard.RotationValue; -import common.clipboard.Vector; import common.collect.Lists; import common.collect.Maps; import common.properties.IProperty; @@ -30,7 +27,7 @@ import common.world.State; public abstract class RotationRegistry { private static final Map MAP = new HashMap(); - static void register() { + public static void register() { for(Block block : common.init.BlockRegistry.REGISTRY) { for(IProperty prop : block.getPropertyMap()) { Predicate predicate = null; diff --git a/common/src/common/clipboard/RotationValue.java b/server/src/server/clipboard/RotationValue.java similarity index 95% rename from common/src/common/clipboard/RotationValue.java rename to server/src/server/clipboard/RotationValue.java index 46319c6..29870cf 100755 --- a/common/src/common/clipboard/RotationValue.java +++ b/server/src/server/clipboard/RotationValue.java @@ -1,4 +1,4 @@ -package common.clipboard; +package server.clipboard; public class RotationValue { public final byte mask; diff --git a/common/src/common/clipboard/Vector.java b/server/src/server/clipboard/Vector.java similarity index 99% rename from common/src/common/clipboard/Vector.java rename to server/src/server/clipboard/Vector.java index 71fdb4d..ef94edd 100755 --- a/common/src/common/clipboard/Vector.java +++ b/server/src/server/clipboard/Vector.java @@ -1,4 +1,4 @@ -package common.clipboard; +package server.clipboard; public class Vector implements Comparable { public static final Vector ZERO = new Vector(0, 0, 0); diff --git a/server/src/server/network/Player.java b/server/src/server/network/Player.java index 97c6f93..e975817 100755 --- a/server/src/server/network/Player.java +++ b/server/src/server/network/Player.java @@ -12,11 +12,6 @@ import common.block.Block; import common.block.BlockFence; import common.block.BlockFenceGate; import common.block.BlockWall; -import common.clipboard.BlockTransform; -import common.clipboard.ClipboardBlock; -import common.clipboard.Rotation; -import common.clipboard.RotationValue; -import common.clipboard.Vector; import common.collect.Lists; import common.color.TextColor; import common.dimension.Dimension; @@ -35,7 +30,6 @@ import common.init.BlockRegistry; import common.init.Config; import common.init.EntityRegistry; import common.init.Items; -import common.init.RotationRegistry; import common.init.SoundEvent; import common.init.UniverseRegistry; import common.init.Config.ValueType; @@ -130,7 +124,13 @@ import common.world.World; import io.netty.util.concurrent.Future; import io.netty.util.concurrent.GenericFutureListener; import server.Server; +import server.clipboard.BlockTransform; +import server.clipboard.ClipboardBlock; import server.clipboard.ClipboardPlacer; +import server.clipboard.Rotation; +import server.clipboard.RotationRegistry; +import server.clipboard.RotationValue; +import server.clipboard.Vector; import server.command.Executor; import server.world.Region; import server.world.WorldServer; diff --git a/server/src/server/world/WorldServer.java b/server/src/server/world/WorldServer.java index 494458d..145c86c 100755 --- a/server/src/server/world/WorldServer.java +++ b/server/src/server/world/WorldServer.java @@ -21,7 +21,6 @@ import common.block.BlockEventData; import common.block.BlockFalling; import common.block.BlockLiquid; import common.block.BlockSnow; -import common.clipboard.ClipboardBlock; import common.collect.Lists; import common.collect.Maps; import common.collect.Sets; @@ -98,6 +97,7 @@ import common.worldgen.caves.MapGenBigCaves; import common.worldgen.caves.MapGenCaves; import common.worldgen.caves.MapGenRavine; import server.Server; +import server.clipboard.ClipboardBlock; import server.network.Player; import server.village.VillageCollection; import server.worldgen.structure.MapGenBridge; From 6d1e00ddef9504b2d3fe64d62284b6ee37c6b281 Mon Sep 17 00:00:00 2001 From: Sen Date: Tue, 13 May 2025 17:34:21 +0200 Subject: [PATCH 026/200] fix server copy password --- client/src/client/gui/GuiConnect.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/src/client/gui/GuiConnect.java b/client/src/client/gui/GuiConnect.java index 9d0eb3e..9303c20 100644 --- a/client/src/client/gui/GuiConnect.java +++ b/client/src/client/gui/GuiConnect.java @@ -260,7 +260,7 @@ public class GuiConnect extends GuiList implements ActBut ServerInfo server = this.getSelected(); if(server != null) { this.setSelected(-1); - this.gm.displayGuiScreen(new GuiServer(new ServerInfo(server.name, server.address, server.port, server.user, server.address, server.access, -1L))); + this.gm.displayGuiScreen(new GuiServer(new ServerInfo(server.name, server.address, server.port, server.user, server.password, server.access, -1L))); } } } From e26938ee772ee26de8a218cd29d88e57f5dc5278 Mon Sep 17 00:00:00 2001 From: Sen Date: Tue, 13 May 2025 18:31:28 +0200 Subject: [PATCH 027/200] biome split temp commit --- common/src/common/biome/BaseBiome.java | 47 ++++++++++++++++++++++++++ common/src/common/biome/Biome.java | 8 +++-- 2 files changed, 52 insertions(+), 3 deletions(-) create mode 100644 common/src/common/biome/BaseBiome.java diff --git a/common/src/common/biome/BaseBiome.java b/common/src/common/biome/BaseBiome.java new file mode 100644 index 0000000..91c6a43 --- /dev/null +++ b/common/src/common/biome/BaseBiome.java @@ -0,0 +1,47 @@ +package common.biome; + +public abstract class BaseBiome { + public final int id; + public final String name; + public final String display; + public final int color; + public final float temperature; + public final float humidity; + public final int waterColor; + public final int skyColor; + public final int fogColor; + public final int cloudColor; + + private BaseBiome(int id, String name, String display, int color, float temperature, float humidity, int waterColor, int skyColor, int fogColor, int cloudColor) { + this.id = id; + this.name = name; + this.display = display; + this.temperature = temperature; + this.humidity = humidity; + this.color = color; + this.waterColor = waterColor; + this.skyColor = skyColor; + this.fogColor = fogColor; + this.cloudColor = cloudColor; + } + + private BaseBiome(int id, String name, String display, int color, float temperature, float humidity, int waterColor) { + this(id, name, display, color, temperature, humidity, waterColor, 0xffffffff, 0xffffffff, 0xffffffff); + } + + private BaseBiome(int id, String name, String display, int color, float temperature, float humidity, int skyColor, int fogColor, int cloudColor) { + this(id, name, display, color, temperature, humidity, 0xffffff, skyColor, fogColor, cloudColor); + } + + private BaseBiome(int id, String name, String display, int color, float temperature, float humidity) { + this(id, name, display, color, temperature, humidity, 0xffffff, 0xffffffff, 0xffffffff, 0xffffffff); + } + + private BaseBiome(int id, String name, String display, int color, float temperature) { + this(id, name, display, color, temperature, 50.0f, 0xffffff, 0xffffffff, 0xffffffff, 0xffffffff); + } + + private BaseBiome(int id, String name, String display, int color) { + this(id, name, display, color, 0.0f, 50.0f, 0xffffff, 0xffffffff, 0xffffffff, 0xffffffff); + } +} diff --git a/common/src/common/biome/Biome.java b/common/src/common/biome/Biome.java index b4d4ea8..e37576a 100755 --- a/common/src/common/biome/Biome.java +++ b/common/src/common/biome/Biome.java @@ -145,13 +145,14 @@ public abstract class Biome { public String name = null; public String display = ""; public int color = 0x000000; + protected float temperature = 0.0f; + protected float humidity = 50.0f; + public int waterColor = 0xffffff; + public State topBlock = Blocks.grass.getState(); public State fillerBlock = Blocks.dirt.getState(); public float depth = Scaling.VARYING_LOW.depth; public float scale = Scaling.VARYING_LOW.scale; - protected float temperature = 0.0f; - protected float humidity = 50.0f; - public int waterColor = 0xffffff; public boolean generateLakes = true; public boolean generateLiquids = true; public boolean allowColdBeach = false; @@ -765,6 +766,7 @@ public abstract class Biome { throw new IllegalStateException("Biom \"" + biome.name + "\" ist als ID " + LOOKUP.get(biome.name.toLowerCase()).id + " und " + biome.id + " definiert"); LOOKUP.put(biome.name.toLowerCase(), biome); LIST.add(biome); + System.out.printf("%s(%d, \"%s\", \"%s\", 0x%06x, %.1ff, %.1ff),\n", biome.name.toUpperCase(), biome.id, biome.name, biome.display, biome.color, biome.temperature, biome.humidity); } } } From 111226fe28a2fbafa2f00b04522349b37330f35e Mon Sep 17 00:00:00 2001 From: Sen Date: Wed, 14 May 2025 00:37:46 +0200 Subject: [PATCH 028/200] move worldgen to server --- client/src/client/Client.java | 6 +- .../src/client/renderer/EntityRenderer.java | 6 +- .../client/renderer/RegionRenderCache.java | 4 +- client/src/client/world/WorldClient.java | 20 +- common/src/common/biome/BaseBiome.java | 210 +++++- .../src/common/biome/BiomeExterminated.java | 33 - common/src/common/biome/IBiome.java | 47 ++ common/src/common/block/BlockGrass.java | 50 +- common/src/common/block/BlockMushroom.java | 30 +- common/src/common/block/BlockSapling.java | 164 +---- common/src/common/color/Colorizer.java | 10 +- common/src/common/dimension/Dimension.java | 328 ++++----- common/src/common/dimension/Space.java | 4 +- .../src/common/entity/animal/EntitySheep.java | 6 +- common/src/common/entity/npc/EntitySlime.java | 6 +- .../common/entity/projectile/EntityHook.java | 7 +- .../entity/projectile/FishConstants.java | 29 + common/src/common/init/Registry.java | 1 - common/src/common/init/UniverseRegistry.java | 68 +- common/src/common/item/ItemInfoWand.java | 4 +- common/src/common/world/AWorldServer.java | 15 - common/src/common/world/Chunk.java | 31 +- common/src/common/world/IWorld.java | 279 -------- common/src/common/world/IWorldAccess.java | 4 +- common/src/common/world/World.java | 8 +- .../src/common/worldgen/BiomeGenerator.java | 12 +- common/src/common/worldgen/BlockReplacer.java | 9 - .../src/common/worldgen/ChunkGenerator.java | 8 - .../{GeneratorDebug.java => DebugStates.java} | 95 ++- common/src/common/worldgen/FeatureLake.java | 23 + common/src/common/worldgen/FeatureLiquid.java | 19 + common/src/common/worldgen/FeatureOre.java | 23 + server/src/server/Server.java | 23 +- .../src/server}/biome/Biome.java | 623 ++++++++++-------- .../src/server}/biome/BiomeBeach.java | 7 +- .../src/server}/biome/BiomeBlackened.java | 11 +- .../src/server}/biome/BiomeChaos.java | 15 +- .../src/server}/biome/BiomeDesert.java | 13 +- .../src/server/biome/BiomeExterminated.java | 22 + .../src/server}/biome/BiomeForest.java | 58 +- .../src/server}/biome/BiomeHell.java | 31 +- .../src/server}/biome/BiomeHills.java | 31 +- .../src/server}/biome/BiomeJungle.java | 27 +- .../src/server}/biome/BiomeMesa.java | 40 +- .../src/server}/biome/BiomeMoon.java | 13 +- .../src/server}/biome/BiomeMushroom.java | 7 +- .../src/server}/biome/BiomeMutated.java | 37 +- .../src/server}/biome/BiomeNone.java | 15 +- .../src/server}/biome/BiomePlains.java | 12 +- .../src/server}/biome/BiomeSavanna.java | 30 +- .../src/server}/biome/BiomeSnow.java | 23 +- .../src/server}/biome/BiomeSnowLand.java | 7 +- .../src/server}/biome/BiomeSpace.java | 15 +- .../src/server}/biome/BiomeStoneBeach.java | 7 +- .../src/server}/biome/BiomeSwamp.java | 27 +- .../src/server}/biome/BiomeTaiga.java | 33 +- .../src/server}/biome/BiomeTian.java | 23 +- .../src/server}/biome/BiomeWater.java | 7 +- .../src/server}/biome/RngSpawn.java | 2 +- .../src/server}/biome/Scaling.java | 2 +- .../src/server}/biome/Temperature.java | 2 +- server/src/server/network/Player.java | 14 +- server/src/server/world/Converter.java | 4 +- server/src/server/world/Spawner.java | 4 +- server/src/server/world/WorldServer.java | 194 ++++-- .../src/server}/worldgen/BiomeGenLayered.java | 77 +-- .../src/server}/worldgen/BiomeGenPerlin.java | 2 +- .../src/server}/worldgen/BiomeGenSingle.java | 19 +- server/src/server/worldgen/BlockReplacer.java | 9 + .../src/server/worldgen/ChunkGenerator.java | 8 + .../src/server}/worldgen/ChunkPrimer.java | 6 +- .../src/server}/worldgen/FeatureDungeons.java | 8 +- .../server}/worldgen/FeatureGenerator.java | 8 +- .../src/server}/worldgen/FeatureLakes.java | 12 +- .../src/server}/worldgen/FeatureLiquids.java | 8 +- .../src/server}/worldgen/FeatureOres.java | 8 +- .../src/server}/worldgen/GeneratorCavern.java | 6 +- .../src/server/worldgen/GeneratorDebug.java | 27 + .../server}/worldgen/GeneratorDestroyed.java | 6 +- .../src/server}/worldgen/GeneratorFlat.java | 6 +- .../src/server}/worldgen/GeneratorIsland.java | 6 +- .../src/server}/worldgen/GeneratorPerlin.java | 15 +- .../src/server}/worldgen/GeneratorSimple.java | 6 +- .../src/server}/worldgen/LootConstants.java | 33 +- server/src/server/worldgen/MobConstants.java | 16 + .../server}/worldgen/ReplacerAltBiome.java | 11 +- .../server}/worldgen/ReplacerAltSurface.java | 8 +- .../src/server}/worldgen/ReplacerBiome.java | 11 +- .../server}/worldgen/ReplacerTopLayer.java | 8 +- .../server}/worldgen/caves/MapGenBase.java | 12 +- .../worldgen/caves/MapGenBigCaves.java | 8 +- .../server}/worldgen/caves/MapGenCaves.java | 11 +- .../server}/worldgen/caves/MapGenRavine.java | 11 +- .../feature/WorldGenAbandonedChest.java | 10 +- .../worldgen/feature/WorldGenAsteroid.java | 8 +- .../worldgen/feature/WorldGenBlockBlob.java | 8 +- .../worldgen/feature/WorldGenClay.java | 8 +- .../worldgen/feature/WorldGenClayExt.java | 6 +- .../worldgen/feature/WorldGenDesertWells.java | 8 +- .../worldgen/feature/WorldGenFire.java | 8 +- .../worldgen/feature/WorldGenGlowStone.java | 8 +- .../worldgen/feature/WorldGenHellLava.java | 8 +- .../worldgen/feature/WorldGenIcePath.java | 8 +- .../worldgen/feature/WorldGenIceSpike.java | 8 +- .../worldgen/feature/WorldGenSand.java | 8 +- .../worldgen/feature/WorldGenSpikes.java | 8 +- .../worldgen/foliage/FeatureDoublePlant.java | 6 +- .../worldgen/foliage/WorldGenBigMushroom.java | 8 +- .../worldgen/foliage/WorldGenCactus.java | 8 +- .../worldgen/foliage/WorldGenDeadBush.java | 8 +- .../worldgen/foliage/WorldGenFlowers.java | 8 +- .../worldgen/foliage/WorldGenMelon.java | 8 +- .../worldgen/foliage/WorldGenMushroom.java | 8 +- .../worldgen/foliage/WorldGenPumpkin.java | 8 +- .../worldgen/foliage/WorldGenReed.java | 8 +- .../worldgen/foliage/WorldGenShrub.java | 8 +- .../worldgen/foliage/WorldGenTallGrass.java | 8 +- .../worldgen/foliage/WorldGenVines.java | 8 +- .../worldgen/foliage/WorldGenWaterlily.java | 8 +- .../src/server}/worldgen/layer/GenLayer.java | 7 +- .../worldgen/layer/GenLayerAddAreas.java | 2 +- .../worldgen/layer/GenLayerAddExtra.java | 6 +- .../worldgen/layer/GenLayerAddSea.java | 6 +- .../worldgen/layer/GenLayerAddSnow.java | 2 +- .../server}/worldgen/layer/GenLayerBase.java | 2 +- .../server}/worldgen/layer/GenLayerBiome.java | 14 +- .../worldgen/layer/GenLayerBiomeEdge.java | 25 +- .../server}/worldgen/layer/GenLayerEdge.java | 2 +- .../worldgen/layer/GenLayerFuzzyZoom.java | 2 +- .../server}/worldgen/layer/GenLayerHills.java | 68 +- .../worldgen/layer/GenLayerRemoveEmpty.java | 2 +- .../server}/worldgen/layer/GenLayerRiver.java | 6 +- .../worldgen/layer/GenLayerRiverInit.java | 2 +- .../worldgen/layer/GenLayerRiverMix.java | 18 +- .../server}/worldgen/layer/GenLayerShore.java | 22 +- .../worldgen/layer/GenLayerSmooth.java | 2 +- .../worldgen/layer/GenLayerVoronoiZoom.java | 2 +- .../server}/worldgen/layer/GenLayerZoom.java | 2 +- .../src/server}/worldgen/layer/IntCache.java | 2 +- .../structure/MapGenScatteredFeature.java | 16 +- .../worldgen/structure/MapGenStructure.java | 12 +- .../worldgen/structure/MapGenVillage.java | 4 +- .../worldgen/structure/StructureBridge.java | 2 +- .../structure/StructureMineshaft.java | 2 +- .../structure/StructureScattered.java | 2 +- .../structure/StructureStronghold.java | 2 +- .../worldgen/structure/StructureVillage.java | 8 +- .../worldgen/tree/WorldGenBaseTree.java | 12 +- .../worldgen/tree/WorldGenBigTree.java | 8 +- .../server}/worldgen/tree/WorldGenBirch.java | 6 +- .../worldgen/tree/WorldGenDarkOak.java | 12 +- .../worldgen/tree/WorldGenHugeTree.java | 14 +- .../server}/worldgen/tree/WorldGenJungle.java | 10 +- .../server}/worldgen/tree/WorldGenPine.java | 14 +- .../worldgen/tree/WorldGenSavanna.java | 10 +- .../server}/worldgen/tree/WorldGenSwamp.java | 8 +- .../server}/worldgen/tree/WorldGenTaiga1.java | 6 +- .../server}/worldgen/tree/WorldGenTaiga2.java | 6 +- .../server}/worldgen/tree/WorldGenTree.java | 10 +- 159 files changed, 1917 insertions(+), 1951 deletions(-) delete mode 100755 common/src/common/biome/BiomeExterminated.java create mode 100644 common/src/common/biome/IBiome.java create mode 100644 common/src/common/entity/projectile/FishConstants.java delete mode 100644 common/src/common/world/IWorld.java delete mode 100755 common/src/common/worldgen/BlockReplacer.java delete mode 100755 common/src/common/worldgen/ChunkGenerator.java rename common/src/common/worldgen/{GeneratorDebug.java => DebugStates.java} (60%) mode change 100755 => 100644 create mode 100644 common/src/common/worldgen/FeatureLake.java create mode 100644 common/src/common/worldgen/FeatureLiquid.java create mode 100644 common/src/common/worldgen/FeatureOre.java rename {common/src/common => server/src/server}/biome/Biome.java (51%) rename {common/src/common => server/src/server}/biome/BiomeBeach.java (73%) rename {common/src/common => server/src/server}/biome/BiomeBlackened.java (81%) rename {common/src/common => server/src/server}/biome/BiomeChaos.java (78%) rename {common/src/common => server/src/server}/biome/BiomeDesert.java (72%) create mode 100755 server/src/server/biome/BiomeExterminated.java rename {common/src/common => server/src/server}/biome/BiomeForest.java (83%) rename {common/src/common => server/src/server}/biome/BiomeHell.java (88%) rename {common/src/common => server/src/server}/biome/BiomeHills.java (76%) rename {common/src/common => server/src/server}/biome/BiomeJungle.java (80%) rename {common/src/common => server/src/server}/biome/BiomeMesa.java (91%) rename {common/src/common => server/src/server}/biome/BiomeMoon.java (67%) rename {common/src/common => server/src/server}/biome/BiomeMushroom.java (81%) rename {common/src/common => server/src/server}/biome/BiomeMutated.java (66%) rename {common/src/common => server/src/server}/biome/BiomeNone.java (51%) rename {common/src/common => server/src/server}/biome/BiomePlains.java (94%) rename {common/src/common => server/src/server}/biome/BiomeSavanna.java (71%) rename {common/src/common => server/src/server}/biome/BiomeSnow.java (66%) rename {common/src/common => server/src/server}/biome/BiomeSnowLand.java (82%) rename {common/src/common => server/src/server}/biome/BiomeSpace.java (74%) rename {common/src/common => server/src/server}/biome/BiomeStoneBeach.java (79%) rename {common/src/common => server/src/server}/biome/BiomeSwamp.java (75%) rename {common/src/common => server/src/server}/biome/BiomeTaiga.java (76%) rename {common/src/common => server/src/server}/biome/BiomeTian.java (85%) rename {common/src/common => server/src/server}/biome/BiomeWater.java (77%) rename {common/src/common => server/src/server}/biome/RngSpawn.java (94%) rename {common/src/common => server/src/server}/biome/Scaling.java (96%) rename {common/src/common => server/src/server}/biome/Temperature.java (71%) rename {common/src/common => server/src/server}/worldgen/BiomeGenLayered.java (78%) rename {common/src/common => server/src/server}/worldgen/BiomeGenPerlin.java (96%) rename {common/src/common => server/src/server}/worldgen/BiomeGenSingle.java (59%) create mode 100755 server/src/server/worldgen/BlockReplacer.java create mode 100755 server/src/server/worldgen/ChunkGenerator.java rename {common/src/common => server/src/server}/worldgen/ChunkPrimer.java (88%) rename {common/src/common => server/src/server}/worldgen/FeatureDungeons.java (96%) rename {common/src/common => server/src/server}/worldgen/FeatureGenerator.java (67%) rename {common/src/common => server/src/server}/worldgen/FeatureLakes.java (95%) rename {common/src/common => server/src/server}/worldgen/FeatureLiquids.java (93%) rename {common/src/common => server/src/server}/worldgen/FeatureOres.java (96%) rename {common/src/common => server/src/server}/worldgen/GeneratorCavern.java (97%) create mode 100755 server/src/server/worldgen/GeneratorDebug.java rename {common/src/common => server/src/server}/worldgen/GeneratorDestroyed.java (86%) rename {common/src/common => server/src/server}/worldgen/GeneratorFlat.java (86%) rename {common/src/common => server/src/server}/worldgen/GeneratorIsland.java (97%) rename {common/src/common => server/src/server}/worldgen/GeneratorPerlin.java (95%) rename {common/src/common => server/src/server}/worldgen/GeneratorSimple.java (96%) rename {common/src/common => server/src/server}/worldgen/LootConstants.java (73%) create mode 100644 server/src/server/worldgen/MobConstants.java rename {common/src/common => server/src/server}/worldgen/ReplacerAltBiome.java (92%) rename {common/src/common => server/src/server}/worldgen/ReplacerAltSurface.java (95%) rename {common/src/common => server/src/server}/worldgen/ReplacerBiome.java (69%) rename {common/src/common => server/src/server}/worldgen/ReplacerTopLayer.java (91%) rename {common/src/common => server/src/server}/worldgen/caves/MapGenBase.java (70%) rename {common/src/common => server/src/server}/worldgen/caves/MapGenBigCaves.java (97%) rename {common/src/common => server/src/server}/worldgen/caves/MapGenCaves.java (96%) rename {common/src/common => server/src/server}/worldgen/caves/MapGenRavine.java (96%) rename {common/src/common => server/src/server}/worldgen/feature/WorldGenAbandonedChest.java (89%) rename {common/src/common => server/src/server}/worldgen/feature/WorldGenAsteroid.java (91%) rename {common/src/common => server/src/server}/worldgen/feature/WorldGenBlockBlob.java (91%) rename {common/src/common => server/src/server}/worldgen/feature/WorldGenClay.java (89%) rename {common/src/common => server/src/server}/worldgen/feature/WorldGenClayExt.java (93%) rename {common/src/common => server/src/server}/worldgen/feature/WorldGenDesertWells.java (94%) rename {common/src/common => server/src/server}/worldgen/feature/WorldGenFire.java (75%) rename {common/src/common => server/src/server}/worldgen/feature/WorldGenGlowStone.java (88%) rename {common/src/common => server/src/server}/worldgen/feature/WorldGenHellLava.java (92%) rename {common/src/common => server/src/server}/worldgen/feature/WorldGenIcePath.java (89%) rename {common/src/common => server/src/server}/worldgen/feature/WorldGenIceSpike.java (95%) rename {common/src/common => server/src/server}/worldgen/feature/WorldGenSand.java (89%) rename {common/src/common => server/src/server}/worldgen/feature/WorldGenSpikes.java (93%) rename {common/src/common => server/src/server}/worldgen/foliage/FeatureDoublePlant.java (85%) rename {common/src/common => server/src/server}/worldgen/foliage/WorldGenBigMushroom.java (97%) rename {common/src/common => server/src/server}/worldgen/foliage/WorldGenCactus.java (80%) rename {common/src/common => server/src/server}/worldgen/foliage/WorldGenDeadBush.java (82%) rename {common/src/common => server/src/server}/worldgen/foliage/WorldGenFlowers.java (86%) rename {common/src/common => server/src/server}/worldgen/foliage/WorldGenMelon.java (76%) rename {common/src/common => server/src/server}/worldgen/foliage/WorldGenMushroom.java (81%) rename {common/src/common => server/src/server}/worldgen/foliage/WorldGenPumpkin.java (80%) rename {common/src/common => server/src/server}/worldgen/foliage/WorldGenReed.java (86%) rename {common/src/common => server/src/server}/worldgen/foliage/WorldGenShrub.java (91%) rename {common/src/common => server/src/server}/worldgen/foliage/WorldGenTallGrass.java (86%) rename {common/src/common => server/src/server}/worldgen/foliage/WorldGenVines.java (87%) rename {common/src/common => server/src/server}/worldgen/foliage/WorldGenWaterlily.java (81%) rename {common/src/common => server/src/server}/worldgen/layer/GenLayer.java (94%) rename {common/src/common => server/src/server}/worldgen/layer/GenLayerAddAreas.java (99%) rename {common/src/common => server/src/server}/worldgen/layer/GenLayerAddExtra.java (90%) rename {common/src/common => server/src/server}/worldgen/layer/GenLayerAddSea.java (92%) rename {common/src/common => server/src/server}/worldgen/layer/GenLayerAddSnow.java (98%) rename {common/src/common => server/src/server}/worldgen/layer/GenLayerBase.java (95%) rename {common/src/common => server/src/server}/worldgen/layer/GenLayerBiome.java (83%) rename {common/src/common => server/src/server}/worldgen/layer/GenLayerBiomeEdge.java (79%) rename {common/src/common => server/src/server}/worldgen/layer/GenLayerEdge.java (99%) rename {common/src/common => server/src/server}/worldgen/layer/GenLayerFuzzyZoom.java (94%) rename {common/src/common => server/src/server}/worldgen/layer/GenLayerHills.java (72%) rename {common/src/common => server/src/server}/worldgen/layer/GenLayerRemoveEmpty.java (98%) rename {common/src/common => server/src/server}/worldgen/layer/GenLayerRiver.java (92%) rename {common/src/common => server/src/server}/worldgen/layer/GenLayerRiverInit.java (96%) rename {common/src/common => server/src/server}/worldgen/layer/GenLayerRiverMix.java (81%) rename {common/src/common => server/src/server}/worldgen/layer/GenLayerShore.java (86%) rename {common/src/common => server/src/server}/worldgen/layer/GenLayerSmooth.java (98%) rename {common/src/common => server/src/server}/worldgen/layer/GenLayerVoronoiZoom.java (99%) rename {common/src/common => server/src/server}/worldgen/layer/GenLayerZoom.java (98%) rename {common/src/common => server/src/server}/worldgen/layer/IntCache.java (98%) rename {common/src/common => server/src/server}/worldgen/tree/WorldGenBaseTree.java (95%) rename {common/src/common => server/src/server}/worldgen/tree/WorldGenBigTree.java (98%) rename {common/src/common => server/src/server}/worldgen/tree/WorldGenBirch.java (96%) rename {common/src/common => server/src/server}/worldgen/tree/WorldGenDarkOak.java (94%) rename {common/src/common => server/src/server}/worldgen/tree/WorldGenHugeTree.java (89%) rename {common/src/common => server/src/server}/worldgen/tree/WorldGenJungle.java (92%) rename {common/src/common => server/src/server}/worldgen/tree/WorldGenPine.java (89%) rename {common/src/common => server/src/server}/worldgen/tree/WorldGenSavanna.java (96%) rename {common/src/common => server/src/server}/worldgen/tree/WorldGenSwamp.java (96%) rename {common/src/common => server/src/server}/worldgen/tree/WorldGenTaiga1.java (96%) rename {common/src/common => server/src/server}/worldgen/tree/WorldGenTaiga2.java (97%) rename {common/src/common => server/src/server}/worldgen/tree/WorldGenTree.java (79%) diff --git a/client/src/client/Client.java b/client/src/client/Client.java index e1b1490..3547751 100755 --- a/client/src/client/Client.java +++ b/client/src/client/Client.java @@ -95,7 +95,7 @@ import client.window.Wheel; import client.window.Window; import client.window.WindowEvent; import client.world.WorldClient; -import common.biome.Biome; +import common.biome.BaseBiome; import common.block.Block; import common.collect.Lists; import common.collect.Maps; @@ -116,6 +116,7 @@ import common.init.ItemRegistry; import common.init.Items; import common.init.Registry; import common.init.SoundEvent; +import common.init.UniverseRegistry; import common.inventory.InventoryPlayer; import common.item.Item; import common.item.ItemBlock; @@ -1728,7 +1729,7 @@ public class Client implements IThreadListener { break; } - Biome biome = null; + BaseBiome biome = null; String bline; String lline; if(this.world.isBlockLoaded(blockpos)) { @@ -2638,6 +2639,7 @@ public class Client implements IThreadListener { Window.init(); ModelBlock.setAsProvider(); Registry.setup("Render thread"); + UniverseRegistry.register(); CLIENT.run(); Window.end(); } diff --git a/client/src/client/renderer/EntityRenderer.java b/client/src/client/renderer/EntityRenderer.java index 9e5bf48..0e7be20 100755 --- a/client/src/client/renderer/EntityRenderer.java +++ b/client/src/client/renderer/EntityRenderer.java @@ -14,7 +14,7 @@ import client.renderer.particle.EffectRenderer; import client.renderer.texture.DynamicTexture; import client.renderer.texture.TextureMap; import client.world.WorldClient; -import common.biome.Biome; +import common.biome.BaseBiome; import common.block.Block; import common.entity.Entity; import common.entity.npc.EntityNPC; @@ -1144,7 +1144,7 @@ public class EntityRenderer { for (int l = 0; l < k; ++l) { BlockPos blockpos1 = world.getPrecipitationHeight(blockpos.add(this.random.zrange(i) - this.random.zrange(i), 0, this.random.zrange(i) - this.random.zrange(i))); - Biome biomegenbase = world.getBiomeGenForCoords(blockpos1); + BaseBiome biomegenbase = world.getBiomeGenForCoords(blockpos1); BlockPos blockpos2 = blockpos1.down(); Block block = world.getState(blockpos2).getBlock(); float temp = World.ABSOLUTE_ZERO + world.getTempOffset() + biomegenbase.getTemperature(blockpos1); @@ -1253,7 +1253,7 @@ public class EntityRenderer { double d3 = (double)this.rainXCoords[i2] * 0.5D; double d4 = (double)this.rainYCoords[i2] * 0.5D; blockpos$mutableblockpos.set(l1, 0, k1); - Biome biomegenbase = world.getBiomeGenForCoords(blockpos$mutableblockpos); + BaseBiome biomegenbase = world.getBiomeGenForCoords(blockpos$mutableblockpos); // if (biomegenbase.canRain() || biomegenbase.isSnowyBiome()) // { diff --git a/client/src/client/renderer/RegionRenderCache.java b/client/src/client/renderer/RegionRenderCache.java index 635a77a..f5157cc 100755 --- a/client/src/client/renderer/RegionRenderCache.java +++ b/client/src/client/renderer/RegionRenderCache.java @@ -2,7 +2,7 @@ package client.renderer; import java.util.Arrays; -import common.biome.Biome; +import common.biome.BaseBiome; import common.init.Blocks; import common.tileentity.TileEntity; import common.util.BlockPos; @@ -125,7 +125,7 @@ public class RegionRenderCache extends ChunkCache implements IWorldAccess return i << 20 | j << 4; } - public Biome getBiomeGenForCoords(BlockPos pos) + public BaseBiome getBiomeGenForCoords(BlockPos pos) { return this.worldObj.getBiomeGenForCoords(pos); } diff --git a/client/src/client/world/WorldClient.java b/client/src/client/world/WorldClient.java index a38b356..497f744 100755 --- a/client/src/client/world/WorldClient.java +++ b/client/src/client/world/WorldClient.java @@ -6,7 +6,7 @@ import java.util.Set; import client.Client; import client.renderer.particle.EntityFX; import client.renderer.particle.EntityFirework; -import common.biome.Biome; +import common.biome.BaseBiome; import common.block.Block; import common.collect.Lists; import common.collect.Sets; @@ -759,10 +759,10 @@ public class WorldClient extends AWorldClient public Vec3 getSkyColor(Entity entity, float partial) { BlockPos pos = new BlockPos(ExtMath.floord(entity.posX), ExtMath.floord(entity.posY), ExtMath.floord(entity.posZ)); - Biome biome = this.getBiomeGenForCoords(pos); + BaseBiome biome = this.getBiomeGenForCoords(pos); Vec3 vec; - if(biome.getSkyColor() != 0xffffffff) - vec = new Vec3(biome.getSkyColor()); + if(biome.skyColor != 0xffffffff) + vec = new Vec3(biome.skyColor); else vec = new Vec3(this.dimension.getSkyColor()); if(this.dimension.getType().days) { @@ -815,10 +815,10 @@ public class WorldClient extends AWorldClient public Vec3 getCloudColour(Entity entity, float partialTicks) { Vec3 color = new Vec3(this.dimension.getCloudColor()); - Biome biome = this.getBiomeGenForCoords(new BlockPos(ExtMath.floord(entity.posX), ExtMath.floord(entity.posY), + BaseBiome biome = this.getBiomeGenForCoords(new BlockPos(ExtMath.floord(entity.posX), ExtMath.floord(entity.posY), ExtMath.floord(entity.posZ))); - if(biome.getCloudColor() != 0xffffffff) - color = new Vec3(biome.getCloudColor()); + if(biome.cloudColor != 0xffffffff) + color = new Vec3(biome.cloudColor); float r = (float)color.xCoord; float g = (float)color.yCoord; float b = (float)color.zCoord; @@ -854,10 +854,10 @@ public class WorldClient extends AWorldClient public Vec3 getFogColor(Entity entity, float partialTicks) { Vec3 color = new Vec3(this.dimension.getFogColor()); - Biome biome = this.getBiomeGenForCoords(new BlockPos(ExtMath.floord(entity.posX), ExtMath.floord(entity.posY), + BaseBiome biome = this.getBiomeGenForCoords(new BlockPos(ExtMath.floord(entity.posX), ExtMath.floord(entity.posY), ExtMath.floord(entity.posZ))); - if(biome.getFogColor() != 0xffffffff) - color = new Vec3(biome.getFogColor()); + if(biome.fogColor != 0xffffffff) + color = new Vec3(biome.fogColor); if(!this.dimension.getType().days) return color; float sun = ExtMath.clampf(ExtMath.cos(this.getCelestialAngle(partialTicks) * (float)Math.PI * 2.0F) * 2.0F + 0.5F, diff --git a/common/src/common/biome/BaseBiome.java b/common/src/common/biome/BaseBiome.java index 91c6a43..c2de8dd 100644 --- a/common/src/common/biome/BaseBiome.java +++ b/common/src/common/biome/BaseBiome.java @@ -1,6 +1,96 @@ package common.biome; -public abstract class BaseBiome { +import java.util.List; +import java.util.Map; + +import common.collect.Lists; +import common.collect.Maps; +import common.color.Colorizer; +import common.log.Log; +import common.rng.PerlinGen; +import common.rng.Random; +import common.util.BlockPos; +import common.util.ExtMath; + +public enum BaseBiome { + NONE(0, "none", "", 0x000000), + PLAINS(1, "plains", "Ebene", 0x8db360, 12.0f, 40.0f), + DESERT(2, "desert", "Wüste", 0xfa9418, 60.0f, 0.0f), + EXTREMEHILLS(3, "extremeHills", "Extremes Bergland", 0x606060, -12.0f, 30.0f), + FOREST(4, "forest", "Wald", 0x056621, 8.0f, 80.0f), + TAIGA(5, "taiga", "Taiga", 0x0b6659, -10.0f, 80.0f), + SWAMPLAND(6, "swampland", "Sumpf", 0x07f9b2, 12.0f, 90.0f, 0xe0ffae, 0xffffffff, 6975545), + RIVER(7, "river", "Fluss", 0x0000ff), + EXTERMINATED(8, "exterminated", "Ausgelöscht", 0x000000, 150.0f, 0.0f, 0x202020, 0x303030, 0x303030, 0x101010, 0x303030, 0x000000), + SPACE(9, "space", "Leere des Weltraums", 0x000000, 0.0f, 0.0f), + FROZENSEA(10, "frozenSea", "Vereister See", 0x9090a0, -20.0f), + FROZENRIVER(11, "frozenRiver", "Vereister Fluss", 0xa0a0ff, -20.0f), + ICEPLAINS(12, "icePlains", "Eisebene", 0xffffff, -20.0f), + ICEMOUNTAINS(13, "iceMountains", "Vereistes Bergland", 0xa0a0a0, -20.0f), + MUSHROOMPLAINS(14, "mushroomPlains", "Pilzland", 0xff00ff, 16.0f, 100.0f), + BLACKENED(15, "blackened", "Schwarz", 0x000000, 0.0f, 0.0f), + BEACH(16, "beach", "Strand", 0xfade55, 12.0f, 40.0f), + DESERTHILLS(17, "desertHills", "Wüsten-Bergland", 0xd25f12, 60.0f, 0.0f), + FORESTHILLS(18, "forestHills", "Wald-Bergland", 0x22551c, 8.0f, 80.0f), + TAIGAHILLS(19, "taigaHills", "Taiga-Bergland", 0x163933, -10.0f, 80.0f), + EXTREMEHILLSEDGE(20, "extremeHillsEdge", "Extremes Bergland Gr.", 0x72789a, -12.0f, 30.0f), + JUNGLE(21, "jungle", "Urwald", 0x537b09, 18.0f, 90.0f), + JUNGLEHILLS(22, "jungleHills", "Urwald-Bergland", 0x2c4205, 18.0f, 90.0f), + JUNGLEEDGE(23, "jungleEdge", "Urwald Gr.", 0x628b17, 18.0f, 80.0f), + SEA(24, "sea", "See", 0x000070), + STONEBEACH(25, "stoneBeach", "Steinstrand", 0xa2a284, -12.0f, 30.0f), + COLDBEACH(26, "coldBeach", "Vereister Strand", 0xfaf0c0, -18.0f, 30.0f), + BIRCHFOREST(27, "birchForest", "Birkenwald", 0x307444, 4.0f, 60.0f), + BIRCHFORESTHILLS(28, "birchForestHills", "Birkenwald-Bergland", 0x1f5f32, 4.0f, 60.0f), + ROOFEDFOREST(29, "roofedForest", "Dichter Wald", 0x40511a, 8.0f, 80.0f), + COLDTAIGA(30, "coldTaiga", "Vereiste Taiga", 0x31554a, -40.0f, 40.0f), + COLDTAIGAHILLS(31, "coldTaigaHills", "Vereistes Taiga-Bergland", 0x243f36, -40.0f, 40.0f), + MEGATAIGA(32, "megaTaiga", "Hohe Taiga", 0x596651, -8.0f, 80.0f), + MEGATAIGAHILLS(33, "megaTaigaHills", "Hohes Taiga-Bergland", 0x454f3e, -8.0f, 80.0f), + EXTREMEHILLSPLUS(34, "extremeHillsPlus", "Extremes Bergland +", 0x507050, -12.0f, 30.0f), + SAVANNA(35, "savanna", "Savanne", 0xbdb25f, 28.0f, 0.0f), + SAVANNAPLATEAU(36, "savannaPlateau", "Savannen-Plateau", 0xa79d64, 20.0f, 0.0f), + MESA(37, "mesa", "Mesa", 0xd94515, 0.0f, 0.0f, 0xffffff, 9470285, 10387789), + MESAPLATEAUF(38, "mesaPlateauF", "Mesa-Waldplateau", 0xb09765, 0.0f, 0.0f, 0xffffff, 9470285, 10387789), + MESAPLATEAU(39, "mesaPlateau", "Mesa-Plateau", 0xca8c65, 0.0f, 0.0f, 0xffffff, 9470285, 10387789), + SNOWLAND(40, "snowLand", "Eisland", 0xffffff, 0.0f, 100.0f), + TIAN(41, "tian", "Tian", 0x808080, 0.0f, 80.0f), + ELVENFOREST(42, "elvenForest", "Elbenwald", 0x059821, 8.0f, 90.0f), + UPPERHELL(43, "upperHell", "Übergang in die Hölle", 0xff0000, 0.0f, 0.0f, 0x000000, 0x000000, 0x000000), + LOWERHELL(44, "lowerHell", "Abgrund der Hölle", 0xff0000, 0.0f, 0.0f, 0x000000, 0x000000, 0x000000), + HELLHILLS(45, "hellHills", "Bergland der Hölle", 0xff0000, 0.0f, 0.0f, 0x000000, 0x000000, 0x000000), + SOULPLAINS(46, "soulPlains", "Seelenland", 0xff0000, 0.0f, 0.0f, 0x000000, 0x000000, 0x000000), + ASHLAND(47, "ashLand", "Verbrannt", 0xff0000, 0.0f, 0.0f, 0x000000, 0x000000, 0x000000), + MOON(48, "moon", "Mondoberfläche", 0xa0a0a0, 0.0f, 0.0f), + CHAOS(49, "chaos", "Chaos", 0xff00ff), + + DESERTM(130, "desertM", "Wüste M", 0xfa9418, 60.0f, 0.0f), + EXTREMEHILLSM(131, "extremeHillsM", "Extremes Bergland M", 0x606060, -12.0f, 30.0f), + FLOWERFOREST(132, "flowerForest", "Blumenwald", 0x6a7425, 8.0f, 80.0f), + TAIGAM(133, "taigaM", "Taiga M", 0x0b6659, -10.0f, 80.0f), + SWAMPLANDM(134, "swamplandM", "Sumpf M", 0x07f9b2, 12.0f, 90.0f, 0xe0ffae, 0xffffffff, 6975545), + ICEPLAINSSPIKES(140, "icePlainsSpikes", "Eisebene + Spitzen", 0xd2ffff, -20.0f), + JUNGLEM(149, "jungleM", "Urwald M", 0x537b09, 18.0f, 90.0f), + JUNGLEEDGEM(151, "jungleEdgeM", "Urwald Gr. M", 0x628b17, 18.0f, 80.0f), + BIRCHFORESTM(155, "birchForestM", "Birkenwald M", 0x307444, 4.0f, 60.0f), + BIRCHFORESTHILLSM(156, "birchForestHillsM", "Birkenwald-Bergland M", 0x1f5f32, 4.0f, 60.0f), + ROOFEDFORESTM(157, "roofedForestM", "Dichter Wald M", 0x40511a, 8.0f, 80.0f), + COLDTAIGAM(158, "coldTaigaM", "Vereiste Taiga M", 0x31554a, -40.0f, 40.0f), + MEGASPRUCETAIGA(160, "megaSpruceTaiga", "Hohe Fichtentaiga", 0x596651, -10.0f, 80.0f), + REDWOODTAIGAHILLSM(161, "redwoodTaigaHillsM", "Mammutbaumtaiga", 0x596651, -10.0f, 80.0f), + EXTREMEHILLSPLUSM(162, "extremeHillsPlusM", "Extremes Bergland + M", 0x507050, -12.0f, 30.0f), + SAVANNAM(163, "savannaM", "Savanne M", 0xbdb25f, 24.0f, 0.0f), + SAVANNAPLATEAUM(164, "savannaPlateauM", "Savannen-Plateau M", 0xa79d64, 20.0f, 0.0f), + MESABRYCE(165, "mesaBryce", "Mesa (Bryce)", 0xd94515, 0.0f, 0.0f, 0xffffff, 9470285, 10387789), + MESAPLATEAUFM(166, "mesaPlateauFM", "Mesa-Waldplateau M", 0xb09765, 0.0f, 0.0f, 0xffffff, 9470285, 10387789), + MESAPLATEAUM(167, "mesaPlateauM", "Mesa-Plateau M", 0xca8c65, 0.0f, 0.0f, 0xffffff, 9470285, 10387789); + + public static final BaseBiome DEF_BIOME = FOREST; + private static final PerlinGen TEMP_NOISE = new PerlinGen(new Random(1234L), 1); + private static final PerlinGen COLOR_NOISE = new PerlinGen(new Random(2345L), 1); + private static final BaseBiome[] BIOMES = new BaseBiome[256]; + private static final Map LOOKUP = Maps.newTreeMap(); + public final int id; public final String name; public final String display; @@ -8,11 +98,68 @@ public abstract class BaseBiome { public final float temperature; public final float humidity; public final int waterColor; + public final int grassColor; + public final int foliageColor; public final int skyColor; public final int fogColor; public final int cloudColor; + + static { + for(BaseBiome biome : values()) { + BIOMES[biome.id] = biome; + if(LOOKUP.containsKey(biome.name.toLowerCase())) + throw new IllegalStateException("Biom \"" + biome.name + "\" ist als ID " + LOOKUP.get(biome.name.toLowerCase()).id + " und " + biome.id + " definiert"); + LOOKUP.put(biome.name.toLowerCase(), biome); + } + } + + public static BaseBiome getBiome(int id) + { + if (id >= 0 && id < BIOMES.length) + { + return BIOMES[id]; + } + else + { + Log.JNI.warn("Biom-ID ist nicht im Bereich: " + id + ", verwende " + DEF_BIOME.id + " (" + DEF_BIOME.name + ")"); + return DEF_BIOME; + } + } - private BaseBiome(int id, String name, String display, int color, float temperature, float humidity, int waterColor, int skyColor, int fogColor, int cloudColor) { + public static BaseBiome getBiomeDef(int id) + { + if (id >= 0 && id < BIOMES.length) + { + BaseBiome biome = BIOMES[id]; + return biome == null ? DEF_BIOME : biome; + } + else + { + Log.JNI.warn("Biom-ID ist nicht im Bereich: " + id + ", verwende " + DEF_BIOME.id + " (" + DEF_BIOME.name + ")"); + return DEF_BIOME; + } + } + + public static List getBiomeNames() { + return Lists.newArrayList(LOOKUP.keySet()); + } + + public static BaseBiome findByName(String name) { + BaseBiome biome = LOOKUP.get(name.toLowerCase().replace(" ", "").replace("_", "")); + if(biome == null) { + int z; + try { + z = Integer.parseInt(name); + } + catch(NumberFormatException e) { + return DEF_BIOME; + } + return z < 0 || z >= BIOMES.length || BIOMES[z] == null ? DEF_BIOME : BIOMES[z]; + } + return biome; + } + + private BaseBiome(int id, String name, String display, int color, float temperature, float humidity, int waterColor, int grassColor, int foliageColor, int skyColor, int fogColor, int cloudColor) { this.id = id; this.name = name; this.display = display; @@ -20,28 +167,69 @@ public abstract class BaseBiome { this.humidity = humidity; this.color = color; this.waterColor = waterColor; + this.grassColor = grassColor; + this.foliageColor = foliageColor; this.skyColor = skyColor; this.fogColor = fogColor; this.cloudColor = cloudColor; } - private BaseBiome(int id, String name, String display, int color, float temperature, float humidity, int waterColor) { - this(id, name, display, color, temperature, humidity, waterColor, 0xffffffff, 0xffffffff, 0xffffffff); - } - - private BaseBiome(int id, String name, String display, int color, float temperature, float humidity, int skyColor, int fogColor, int cloudColor) { - this(id, name, display, color, temperature, humidity, 0xffffff, skyColor, fogColor, cloudColor); + private BaseBiome(int id, String name, String display, int color, float temperature, float humidity, int waterColor, int grassColor, int foliageColor) { + this(id, name, display, color, temperature, humidity, waterColor, grassColor, foliageColor, 0xffffffff, 0xffffffff, 0xffffffff); } private BaseBiome(int id, String name, String display, int color, float temperature, float humidity) { - this(id, name, display, color, temperature, humidity, 0xffffff, 0xffffffff, 0xffffffff, 0xffffffff); + this(id, name, display, color, temperature, humidity, 0xffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff); } private BaseBiome(int id, String name, String display, int color, float temperature) { - this(id, name, display, color, temperature, 50.0f, 0xffffff, 0xffffffff, 0xffffffff, 0xffffffff); + this(id, name, display, color, temperature, 50.0f, 0xffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff); } private BaseBiome(int id, String name, String display, int color) { - this(id, name, display, color, 0.0f, 50.0f, 0xffffff, 0xffffffff, 0xffffffff, 0xffffffff); + this(id, name, display, color, 0.0f, 50.0f, 0xffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff); + } + + public final float getTemperature(BlockPos pos) { + if(pos.getY() > 64) { + float f = (float)(TEMP_NOISE.generate((double)pos.getX() * 1.0D / 8.0D, (double)pos.getZ() * 1.0D / 8.0D) * 4.0D); + return this.temperature - (f + (float)pos.getY() - 64.0F) / 15.0f; + } + return this.temperature; + } + + public float getFactor() { + float f = this.humidity * 0.01f * ((this.temperature + 14.0f) / 40.0f + 0.15f); + return f > 1.0f ? 1.0f : f; + } + + public boolean isHighHumidity() { + return this.humidity > 85.0f; + } + + // skycolor = ((temp + 14) / 40 + 0.15) / 3 + + public int getGrassColorAtPos(BlockPos pos) { + if(this.grassColor != 0xffffffff) + return this.grassColor; + if(this == SWAMPLAND || this == SWAMPLANDM) { + double d0 = COLOR_NOISE.generate((double)pos.getX() * 0.0225D, (double)pos.getZ() * 0.0225D); + return d0 < -0.1D ? 5011004 : 6975545; + } + if(this == ELVENFOREST) + return Colorizer.getGrassColor(1.0f, this.humidity * 0.01f); + double d0 = (double)ExtMath.clampf((this.getTemperature(pos) + 14.0f) / 40.0f + 0.15f, 0.0F, 1.0F); + double d1 = (double)ExtMath.clampf(this.humidity * 0.01f, 0.0F, 1.0F); + return this == ROOFEDFOREST || this == ROOFEDFORESTM ? (Colorizer.getGrassColor(d0, d1) & 16711422) + 2634762 >> 1 : Colorizer.getGrassColor(d0, d1); + } + + public int getFoliageColorAtPos(BlockPos pos) { + if(this.foliageColor != 0xffffffff) + return this.foliageColor; + if(this == ELVENFOREST) + return Colorizer.getFoliageColor(1.0f, this.humidity * 0.01f); + double d0 = (double)ExtMath.clampf((this.getTemperature(pos) + 14.0f) / 40.0f + 0.15f, 0.0F, 1.0F); + double d1 = (double)ExtMath.clampf(this.humidity * 0.01f, 0.0F, 1.0F); + return Colorizer.getFoliageColor(d0, d1); } } diff --git a/common/src/common/biome/BiomeExterminated.java b/common/src/common/biome/BiomeExterminated.java deleted file mode 100755 index f944a55..0000000 --- a/common/src/common/biome/BiomeExterminated.java +++ /dev/null @@ -1,33 +0,0 @@ -package common.biome; - -import common.init.Blocks; -import common.rng.Random; -import common.rng.WeightedList; -import common.util.BlockPos; -import common.world.AWorldServer; - -public class BiomeExterminated extends Biome { - public BiomeExterminated(int id) { - super(id); - this.topBlock = Blocks.air.getState(); - this.fillerBlock = Blocks.air.getState(); - } - - protected void addMobs(WeightedList mobs) { - } - - public void decorate(AWorldServer worldIn, Random rand, BlockPos pos) { - } - - public int getSkyColor() { - return 0x101010; - } - - public int getFogColor() { - return 0x303030; - } - - public int getCloudColor() { - return 0x000000; - } -} diff --git a/common/src/common/biome/IBiome.java b/common/src/common/biome/IBiome.java new file mode 100644 index 0000000..c46503f --- /dev/null +++ b/common/src/common/biome/IBiome.java @@ -0,0 +1,47 @@ +package common.biome; + +import common.init.BlockRegistry; +import common.rng.Random; +import common.util.BlockPos; +import common.world.AWorldServer; +import common.world.State; + +public interface IBiome { + public static abstract class BiomeProvider { + private static BiomeProvider provider = new BiomeProvider() { + public IBiome getBiome(BaseBiome base) { + return new IBiome() { + public State getFiller() { + return BlockRegistry.getRegisteredBlock("air").getState(); + } + public State getTop() { + return BlockRegistry.getRegisteredBlock("air").getState(); + } + public void growGrass(AWorldServer worldIn, BlockPos pos, State state, Random rand) { + } + public boolean generateBigMushroom(AWorldServer worldIn, BlockPos pos, State state, Random rand) { + return false; + } + public void generateTree(AWorldServer worldIn, BlockPos pos, State state, Random rand) { + } + }; + } + }; + + public abstract IBiome getBiome(BaseBiome base); + } + + public static void setProvider(BiomeProvider provider) { + BiomeProvider.provider = provider; + } + + public static IBiome getBiome(BaseBiome base) { + return BiomeProvider.provider.getBiome(base); + } + + void growGrass(AWorldServer worldIn, BlockPos pos, State state, Random rand); + boolean generateBigMushroom(AWorldServer worldIn, BlockPos pos, State state, Random rand); + void generateTree(AWorldServer worldIn, BlockPos pos, State state, Random rand); + State getFiller(); + State getTop(); +} \ No newline at end of file diff --git a/common/src/common/block/BlockGrass.java b/common/src/common/block/BlockGrass.java index 440a2b0..2f1ddcf 100755 --- a/common/src/common/block/BlockGrass.java +++ b/common/src/common/block/BlockGrass.java @@ -1,5 +1,6 @@ package common.block; +import common.biome.IBiome; import common.color.Colorizer; import common.init.Blocks; import common.init.Config; @@ -113,54 +114,7 @@ public class BlockGrass extends Block implements IGrowable public void grow(AWorldServer worldIn, Random rand, BlockPos pos, State state) { - BlockPos blockpos = pos.up(); - - for (int i = 0; i < 128; ++i) - { - BlockPos blockpos1 = blockpos; - int j = 0; - - while (true) - { - if (j >= i / 16) - { - if (worldIn.getState(blockpos1).getBlock().material == Material.air) - { - if (rand.chance(8)) - { - BlockFlower.EnumFlowerType blockflower$enumflowertype = worldIn.getBiomeGenForCoords(blockpos1).pickRandomFlower(rand, blockpos1); - BlockFlower blockflower = blockflower$enumflowertype.getBlockType().getBlock(); - State iblockstate = blockflower.getState().withProperty(blockflower.getTypeProperty(), blockflower$enumflowertype); - - if (blockflower.canBlockStay(worldIn, blockpos1, iblockstate)) - { - worldIn.setState(blockpos1, iblockstate, 3); - } - } - else - { - State iblockstate1 = Blocks.tallgrass.getState().withProperty(BlockTallGrass.TYPE, BlockTallGrass.EnumType.GRASS); - - if (Blocks.tallgrass.canBlockStay(worldIn, blockpos1, iblockstate1)) - { - worldIn.setState(blockpos1, iblockstate1, 3); - } - } - } - - break; - } - - blockpos1 = blockpos1.add(rand.zrange(3) - 1, (rand.zrange(3) - 1) * rand.zrange(3) / 2, rand.zrange(3) - 1); - - if (worldIn.getState(blockpos1.down()).getBlock() != Blocks.grass || worldIn.getState(blockpos1).getBlock().isNormalCube()) - { - break; - } - - ++j; - } - } + IBiome.getBiome(worldIn.getBiomeGenForCoords(pos)).growGrass(worldIn, pos, state, rand); } public BlockLayer getBlockLayer() diff --git a/common/src/common/block/BlockMushroom.java b/common/src/common/block/BlockMushroom.java index 0f11d22..aedd4e5 100755 --- a/common/src/common/block/BlockMushroom.java +++ b/common/src/common/block/BlockMushroom.java @@ -1,5 +1,6 @@ package common.block; +import common.biome.IBiome; import common.init.Blocks; import common.init.Config; import common.model.Model; @@ -9,8 +10,6 @@ import common.util.BlockPos; import common.world.State; import common.world.World; import common.world.AWorldServer; -import common.worldgen.FeatureGenerator; -import common.worldgen.foliage.WorldGenBigMushroom; public class BlockMushroom extends BlockBush implements IGrowable { @@ -86,31 +85,6 @@ public class BlockMushroom extends BlockBush implements IGrowable } } - public boolean generateBigMushroom(AWorldServer worldIn, BlockPos pos, State state, Random rand) - { - worldIn.setBlockToAir(pos); - FeatureGenerator worldgenerator = null; - - if (this == Blocks.brown_mushroom) - { - worldgenerator = new WorldGenBigMushroom(Blocks.brown_mushroom_block); - } - else if (this == Blocks.red_mushroom) - { - worldgenerator = new WorldGenBigMushroom(Blocks.red_mushroom_block); - } - - if (worldgenerator != null && worldgenerator.generate(worldIn, rand, pos)) - { - return true; - } - else - { - worldIn.setState(pos, state, 3); - return false; - } - } - /** * Whether this IGrowable can grow */ @@ -126,7 +100,7 @@ public class BlockMushroom extends BlockBush implements IGrowable public void grow(AWorldServer worldIn, Random rand, BlockPos pos, State state) { - this.generateBigMushroom(worldIn, pos, state, rand); + IBiome.getBiome(worldIn.getBiomeGenForCoords(pos)).generateBigMushroom(worldIn, pos, state, rand); } public Model getModel(ModelProvider provider, String name, State state) { diff --git a/common/src/common/block/BlockSapling.java b/common/src/common/block/BlockSapling.java index d612805..f03ba37 100755 --- a/common/src/common/block/BlockSapling.java +++ b/common/src/common/block/BlockSapling.java @@ -2,6 +2,7 @@ package common.block; import java.util.List; +import common.biome.IBiome; import common.collect.Lists; import common.init.Blocks; import common.init.Config; @@ -16,15 +17,6 @@ import common.util.BlockPos; import common.world.State; import common.world.World; import common.world.AWorldServer; -import common.worldgen.FeatureGenerator; -import common.worldgen.tree.WorldGenBaseTree; -import common.worldgen.tree.WorldGenBigTree; -import common.worldgen.tree.WorldGenBirch; -import common.worldgen.tree.WorldGenDarkOak; -import common.worldgen.tree.WorldGenJungle; -import common.worldgen.tree.WorldGenPine; -import common.worldgen.tree.WorldGenSavanna; -import common.worldgen.tree.WorldGenTaiga2; public class BlockSapling extends BlockBush implements IGrowable { @@ -79,158 +71,10 @@ public class BlockSapling extends BlockBush implements IGrowable } else { - this.generateTree(worldIn, pos, state, rand); + IBiome.getBiome(worldIn.getBiomeGenForCoords(pos)).generateTree(worldIn, pos, state, rand); } } - public void generateTree(AWorldServer worldIn, BlockPos pos, State state, Random rand) - { - WoodType type = state.getBlock() instanceof BlockSapling ? ((BlockSapling)state.getBlock()).type : WoodType.OAK; - State log = type == WoodType.CHERRY ? Blocks.cherry_log.getState() : // .withProperty(BlockNewLog.VARIANT, BlockPlanks.EnumType.CHERRY) : - (type == WoodType.MAPLE ? Blocks.maple_log.getState() /* .withProperty(BlockNewLog.VARIANT, BlockPlanks.EnumType.MAPLE) */ : Blocks.oak_log.getState()); - State leaves = type == WoodType.CHERRY ? Blocks.cherry_leaves.getState() : - (type == WoodType.MAPLE ? Blocks.maple_leaves.getState() : Blocks.oak_leaves.getState()); - FeatureGenerator worldgenerator = (FeatureGenerator)(rand.chance(10) ? new WorldGenBigTree(true, log, leaves) : new WorldGenBaseTree(true, log, leaves)); - int i = 0; - int j = 0; - boolean flag = false; -// leaves = leaves.withProperty(BlockLeaves.TYPE, worldIn.getLeavesGen()); - - switch (type) - { - case SPRUCE: - label114: - for (i = 0; i >= -1; --i) - { - for (j = 0; j >= -1; --j) - { - if (this.isSameSaplingTypeIn(worldIn, pos, i, j, WoodType.SPRUCE)) - { - worldgenerator = new WorldGenPine(false, rand.chance()); - flag = true; - break label114; - } - } - } - - if (!flag) - { - j = 0; - i = 0; - worldgenerator = new WorldGenTaiga2(true); - } - - break; - - case BIRCH: - worldgenerator = new WorldGenBirch(true, false); - break; - - case TIAN: - worldgenerator = new WorldGenBigTree(true, Blocks.tian_log.getState(), Blocks.tian_leaves.getState()) - .setHeightLimit(6, 20); - break; - - case JUNGLE: - State iblockstate = Blocks.jungle_log.getState(); // .withProperty(BlockOldLog.VARIANT, BlockPlanks.EnumType.JUNGLE); - State iblockstate1 = Blocks.jungle_leaves.getState(); // .withProperty(BlockOldLeaf.VARIANT, BlockPlanks.EnumType.JUNGLE); // .withProperty(BlockLeaves.CHECK_DECAY, Boolean.valueOf(false)); - label269: - - for (i = 0; i >= -1; --i) - { - for (j = 0; j >= -1; --j) - { - if (this.isSameSaplingTypeIn(worldIn, pos, i, j, WoodType.JUNGLE)) - { - worldgenerator = new WorldGenJungle(true, 10, 20, iblockstate, iblockstate1); - flag = true; - break label269; - } - } - } - - if (!flag) - { - j = 0; - i = 0; - worldgenerator = new WorldGenBaseTree(true, rand.range(4, 10), iblockstate, iblockstate1, false); - } - - break; - - case ACACIA: - worldgenerator = new WorldGenSavanna(true); - break; - - case DARK_OAK: - label390: - for (i = 0; i >= -1; --i) - { - for (j = 0; j >= -1; --j) - { - if (this.isSameSaplingTypeIn(worldIn, pos, i, j, WoodType.DARK_OAK)) - { - worldgenerator = new WorldGenDarkOak(true); - flag = true; - break label390; - } - } - } - - if (!flag) - { - return; - } - - case OAK: - case CHERRY: - case MAPLE: - } - - State iblockstate2 = Blocks.air.getState(); - - if (flag) - { - worldIn.setState(pos.add(i, 0, j), iblockstate2, 4); - worldIn.setState(pos.add(i + 1, 0, j), iblockstate2, 4); - worldIn.setState(pos.add(i, 0, j + 1), iblockstate2, 4); - worldIn.setState(pos.add(i + 1, 0, j + 1), iblockstate2, 4); - } - else - { - worldIn.setState(pos, iblockstate2, 4); - } - - if (!worldgenerator.generate(worldIn, rand, pos.add(i, 0, j))) - { - if (flag) - { - worldIn.setState(pos.add(i, 0, j), state, 4); - worldIn.setState(pos.add(i + 1, 0, j), state, 4); - worldIn.setState(pos.add(i, 0, j + 1), state, 4); - worldIn.setState(pos.add(i + 1, 0, j + 1), state, 4); - } - else - { - worldIn.setState(pos, state, 4); - } - } - } - - private boolean isSameSaplingTypeIn(World worldIn, BlockPos pos, int xOff, int yOff, WoodType type) - { - return this.isTypeAt(worldIn, pos.add(xOff, 0, yOff), type) && this.isTypeAt(worldIn, pos.add(xOff + 1, 0, yOff), type) && this.isTypeAt(worldIn, pos.add(xOff, 0, yOff + 1), type) && this.isTypeAt(worldIn, pos.add(xOff + 1, 0, yOff + 1), type); - } - - /** - * Check whether the given BlockPos has a Sapling of the given type - */ - public boolean isTypeAt(World worldIn, BlockPos pos, WoodType type) - { - State iblockstate = worldIn.getState(pos); - return iblockstate.getBlock() instanceof BlockSapling && ((BlockSapling)iblockstate.getBlock()).type == type; - } - // /** // * Gets the metadata of the item this Block can drop. This method is called when the block gets destroyed. It // * returns the metadata of the dropped item based on the old metadata of the block. @@ -296,4 +140,8 @@ public class BlockSapling extends BlockBush implements IGrowable public Model getModel(ModelProvider provider, String name, State state) { return provider.getModel(name).cross(); } + + public WoodType getWoodType() { + return this.type; + } } diff --git a/common/src/common/color/Colorizer.java b/common/src/common/color/Colorizer.java index dcae2c9..468793a 100755 --- a/common/src/common/color/Colorizer.java +++ b/common/src/common/color/Colorizer.java @@ -1,6 +1,6 @@ package common.color; -import common.biome.Biome; +import common.biome.BaseBiome; import common.util.BlockPos; import common.world.IWorldAccess; @@ -8,21 +8,21 @@ public enum Colorizer { NONE(0xffffff), BASIC(0x37b500), PINE(0x3f993f), BIRCH(0x68a723); private interface ColorResolver { - int getColorAtPos(Biome biome, BlockPos pos); + int getColorAtPos(BaseBiome biome, BlockPos pos); } private static final ColorResolver GRASS_COLOR = new ColorResolver() { - public int getColorAtPos(Biome biome, BlockPos pos) { + public int getColorAtPos(BaseBiome biome, BlockPos pos) { return biome.getGrassColorAtPos(pos); } }; private static final ColorResolver FOLIAGE_COLOR = new ColorResolver() { - public int getColorAtPos(Biome biome, BlockPos pos) { + public int getColorAtPos(BaseBiome biome, BlockPos pos) { return biome.getFoliageColorAtPos(pos); } }; private static final ColorResolver WATER_COLOR_MULTIPLIER = new ColorResolver() { - public int getColorAtPos(Biome biome, BlockPos pos) { + public int getColorAtPos(BaseBiome biome, BlockPos pos) { return biome.waterColor; } }; diff --git a/common/src/common/dimension/Dimension.java b/common/src/common/dimension/Dimension.java index 32c7520..b3ef389 100755 --- a/common/src/common/dimension/Dimension.java +++ b/common/src/common/dimension/Dimension.java @@ -4,7 +4,8 @@ import java.util.List; import java.util.Map; import java.util.Set; -import common.biome.Biome; +import common.biome.BaseBiome; +import common.biome.IBiome; import common.block.LeavesType; import common.collect.Lists; import common.collect.Maps; @@ -16,34 +17,13 @@ import common.init.UniverseRegistry; import common.nbt.NBTTagCompound; import common.nbt.NBTTagList; import common.nbt.NBTTagString; -import common.rng.Random; import common.util.ExtMath; import common.util.Vec3; import common.world.State; import common.world.Weather; -import common.worldgen.BiomeGenLayered; -import common.worldgen.BiomeGenPerlin; -import common.worldgen.BiomeGenSingle; -import common.worldgen.BiomeGenerator; -import common.worldgen.BlockReplacer; -import common.worldgen.ChunkGenerator; -import common.worldgen.FeatureDungeons; -import common.worldgen.FeatureLakes; -import common.worldgen.FeatureLiquids; -import common.worldgen.FeatureOres; -import common.worldgen.GeneratorCavern; -import common.worldgen.GeneratorDestroyed; -import common.worldgen.GeneratorFlat; -import common.worldgen.GeneratorIsland; -import common.worldgen.GeneratorPerlin; -import common.worldgen.GeneratorSimple; -import common.worldgen.ReplacerAltBiome; -import common.worldgen.ReplacerAltSurface; -import common.worldgen.ReplacerBiome; -import common.worldgen.ReplacerTopLayer; -import common.worldgen.caves.MapGenBigCaves; -import common.worldgen.caves.MapGenCaves; -import common.worldgen.caves.MapGenRavine; +import common.worldgen.FeatureLake; +import common.worldgen.FeatureLiquid; +import common.worldgen.FeatureOre; public abstract class Dimension extends Nameable implements Comparable { public class GeneratorSettings { @@ -290,7 +270,7 @@ public abstract class Dimension extends Nameable implements Comparable ores = Lists.newArrayList(); - private final List lakes = Lists.newArrayList(); - private final List liquids = Lists.newArrayList(); + private final List ores = Lists.newArrayList(); + private final List lakes = Lists.newArrayList(); + private final List liquids = Lists.newArrayList(); private long seed = 0L; @@ -482,15 +462,16 @@ public abstract class Dimension extends Nameable implements Comparable 0 ? new BiomeGenLayered(rand.longv(), this.defaultBiome, this.semiFixed, this.biomeSize, this.riverSize, - this.snowRarity, this.seaRarity, this.addBiomes == null ? new Biome[0] : this.addBiomes, this.addRarity, - this.hotBiomes == null ? new Biome[] {this.defaultBiome} : this.hotBiomes, - this.mediumBiomes == null ? new Biome[] {this.defaultBiome} : this.mediumBiomes, - this.coldBiomes == null ? new Biome[] {this.defaultBiome} : this.coldBiomes, - this.frostBiomes == null ? new Biome[] {this.defaultBiome} : this.frostBiomes) : new BiomeGenSingle(this.defaultBiome); - } - - public final ChunkGenerator createChunkGenerator(Random rand) { - switch(this.generatorType) { - case FLAT: - return this.layers == null ? new GeneratorFlat(this.seaLevel, this.filler) : new GeneratorFlat(this.layers); - case PERLIN: - default: - return new GeneratorPerlin(rand, this.filler, this.liquid, this.noiseGen); - case SIMPLE: - return new GeneratorSimple(rand, this.filler, this.liquid, - this.biomeSize > 0 ? null : new BiomeGenPerlin(rand.longv())); - case ISLAND: - return new GeneratorIsland(rand, this.filler); - case CAVERN: - return new GeneratorCavern(rand, this.filler, this.liquid); - case DESTROYED: - return new GeneratorDestroyed(this.seaLevel); - } - } - - public final BlockReplacer createBlockReplacer(Random rand) { - switch(this.replacerType) { - case BIOMES: - default: - return new ReplacerBiome(rand); - case SIMPLE: - return new ReplacerAltBiome(rand, this.filler, this.liquid, this.alt2, this.alt1); - case ALTERNATE: - return new ReplacerAltSurface(rand, this.filler, this.alt1, this.alt2, this.liquid); - case TOPLAYER: - return new ReplacerTopLayer(this.surface, this.filler.getBlock()); - case NONE: - return null; - } - } - - public final FeatureDungeons createDungeonGenerator() { - return this.dungeons > 0 ? new FeatureDungeons(this.dungeons) : null; - } - - public final MapGenCaves createCaveGenerator() { - return this.caves ? - (new MapGenCaves(this.caveFiller, this.filler.getBlock(), this.top.getBlock(), - this.surface.getBlock(), this.alt1.getBlock())) : null; - } - - public final MapGenRavine createRavineGenerator() { - return this.ravines ? - (new MapGenRavine(this.caveFiller, this.filler.getBlock(), - this.top.getBlock(), this.surface.getBlock())) : null; - } - - public final MapGenBigCaves createBigCaveGenerator() { - return this.strideCaves ? - (new MapGenBigCaves(this.filler.getBlock(), - this.top.getBlock(), this.surface.getBlock())) : null; - } - - public final FeatureOres[] getOres() { - return this.ores.isEmpty() ? null : this.ores.toArray(new FeatureOres[this.ores.size()]); - } - - public final FeatureLakes[] getLakes() { - return this.lakes.isEmpty() ? null : this.lakes.toArray(new FeatureLakes[this.lakes.size()]); - } - - public final FeatureLiquids[] getLiquids() { - return this.liquids.isEmpty() ? null : this.liquids.toArray(new FeatureLiquids[this.liquids.size()]); - } - public final long getSeed() { return this.seed; } @@ -1108,8 +1010,7 @@ public abstract class Dimension extends Nameable implements Comparable getOres() { + return this.ores; + } + + public List getLakes() { + return this.lakes; + } + + public List getLiquids() { + return this.liquids; + } } diff --git a/common/src/common/dimension/Space.java b/common/src/common/dimension/Space.java index 3eac115..268ad58 100755 --- a/common/src/common/dimension/Space.java +++ b/common/src/common/dimension/Space.java @@ -1,6 +1,6 @@ package common.dimension; -import common.biome.Biome; +import common.biome.BaseBiome; public final class Space extends Dimension { public static final Space INSTANCE = new Space(); @@ -8,7 +8,7 @@ public final class Space extends Dimension { private Space() { super(0, "space"); this.setPhysics(1L, 1L, 0.0f, 0.0f, 2.7f, 15).setTimeQualifier(8); - this.setBiome(Biome.space).setStarBrightness(1.0f).setDeepStarBrightness(1.0f); + this.setBiome(BaseBiome.SPACE).setStarBrightness(1.0f).setDeepStarBrightness(1.0f); this.setCustomName("Der Weltraum"); } diff --git a/common/src/common/entity/animal/EntitySheep.java b/common/src/common/entity/animal/EntitySheep.java index cf4ee54..78cb9ac 100755 --- a/common/src/common/entity/animal/EntitySheep.java +++ b/common/src/common/entity/animal/EntitySheep.java @@ -12,7 +12,7 @@ import common.ai.EntityAITempt; import common.ai.EntityAIWander; import common.ai.EntityAIWatchClosest; import common.attributes.Attributes; -import common.biome.Biome; +import common.biome.BaseBiome; import common.collect.Maps; import common.color.DyeColor; import common.entity.item.EntityItem; @@ -303,9 +303,9 @@ public class EntitySheep extends EntityAnimal DyeColor.MAGENTA, DyeColor.ORANGE, DyeColor.PINK, DyeColor.PURPLE, DyeColor.RED }; - public static DyeColor getRandomSheepColor(Random random, Biome biome) + public static DyeColor getRandomSheepColor(Random random, BaseBiome biome) { - if(biome == Biome.snowLand) + if(biome == BaseBiome.SNOWLAND) return DyeColor.WHITE; int i = random.zrange(140); return i < 20 ? DyeColor.BLACK : diff --git a/common/src/common/entity/npc/EntitySlime.java b/common/src/common/entity/npc/EntitySlime.java index 5a8dcf1..406b2b7 100755 --- a/common/src/common/entity/npc/EntitySlime.java +++ b/common/src/common/entity/npc/EntitySlime.java @@ -3,7 +3,7 @@ package common.entity.npc; import common.ai.EntityAIBase; import common.ai.EntityMoveHelper; import common.attributes.Attributes; -import common.biome.Biome; +import common.biome.BaseBiome; import common.entity.DamageSource; import common.entity.Entity; import common.entity.types.EntityLiving; @@ -396,9 +396,9 @@ public class EntitySlime extends EntityNPC // { // if (this.worldObj.getDifficulty() != Difficulty.PEACEFUL) // { - Biome biomegenbase = this.worldObj.getBiomeGenForCoords(blockpos); + BaseBiome biomegenbase = this.worldObj.getBiomeGenForCoords(blockpos); - if (biomegenbase == Biome.swampland && this.posY > 50.0D && this.posY < 70.0D && this.rand.floatv() < 0.5F && this.rand.floatv() < this.worldObj.getCurrentMoonPhaseFactor() && this.worldObj.getLightFromNeighbors(new BlockPos(this)) <= this.rand.zrange(8)) + if (biomegenbase == BaseBiome.SWAMPLAND && this.posY > 50.0D && this.posY < 70.0D && this.rand.floatv() < 0.5F && this.rand.floatv() < this.worldObj.getCurrentMoonPhaseFactor() && this.worldObj.getLightFromNeighbors(new BlockPos(this)) <= this.rand.zrange(8)) { return super.getCanSpawnHere(); } diff --git a/common/src/common/entity/projectile/EntityHook.java b/common/src/common/entity/projectile/EntityHook.java index 8c811aa..8e51dd4 100755 --- a/common/src/common/entity/projectile/EntityHook.java +++ b/common/src/common/entity/projectile/EntityHook.java @@ -26,7 +26,6 @@ import common.util.HitPosition; import common.util.Vec3; import common.world.World; import common.world.AWorldServer; -import common.worldgen.LootConstants; public class EntityHook extends Entity implements IObjectData { @@ -614,7 +613,7 @@ public class EntityHook extends Entity implements IObjectData if (f < f1) { // this.angler.triggerAchievement(StatRegistry.junkFishedStat); - return ((RngFishable)LootConstants.FISHING_JUNK.pick(this.rand)).getItemStack(this.rand); + return ((RngFishable)FishConstants.FISHING_JUNK.pick(this.rand)).getItemStack(this.rand); } else { @@ -623,13 +622,13 @@ public class EntityHook extends Entity implements IObjectData if (f < f2) { // this.angler.triggerAchievement(StatRegistry.treasureFishedStat); - return ((RngFishable)LootConstants.FISHING_TREASURE.pick(this.rand)).getItemStack(this.rand); + return ((RngFishable)FishConstants.FISHING_TREASURE.pick(this.rand)).getItemStack(this.rand); } else { float f3 = f - f2; // this.angler.triggerAchievement(StatRegistry.fishCaughtStat); - return ((RngFishable)LootConstants.FISH_TYPES.pick(this.rand)).getItemStack(this.rand); + return ((RngFishable)FishConstants.FISH_TYPES.pick(this.rand)).getItemStack(this.rand); } } } diff --git a/common/src/common/entity/projectile/FishConstants.java b/common/src/common/entity/projectile/FishConstants.java new file mode 100644 index 0000000..890d8c7 --- /dev/null +++ b/common/src/common/entity/projectile/FishConstants.java @@ -0,0 +1,29 @@ +package common.entity.projectile; + +import common.color.DyeColor; +import common.init.Blocks; +import common.init.Items; +import common.item.ItemFishFood; +import common.item.ItemStack; +import common.rng.WeightedList; + +public abstract class FishConstants { + public static final WeightedList FISHING_JUNK = new WeightedList( + (new RngFishable(new ItemStack(Items.leather_boots), 10)).setMaxDamagePercent(0.9F), new RngFishable(new ItemStack(Items.leather), 10), + new RngFishable(new ItemStack(Items.bone), 10), new RngFishable(new ItemStack(Items.potion), 10), + new RngFishable(new ItemStack(Items.string), 5), (new RngFishable(new ItemStack(Items.fishing_rod), 2)).setMaxDamagePercent(0.9F), + new RngFishable(new ItemStack(Items.bowl), 10), new RngFishable(new ItemStack(Items.stick), 5), + new RngFishable(new ItemStack(Items.dye, 10, DyeColor.BLACK.getDyeDamage()), 1), + new RngFishable(new ItemStack(Blocks.tripwire_hook), 10), new RngFishable(new ItemStack(Items.rotten_flesh), 10)); + public static final WeightedList FISHING_TREASURE = new WeightedList( + new RngFishable(new ItemStack(Blocks.waterlily), 1), new RngFishable(new ItemStack(Items.name_tag), 1), + new RngFishable(new ItemStack(Items.saddle), 1), + (new RngFishable(new ItemStack(Items.bow), 1)).setMaxDamagePercent(0.25F).setEnchantable(), + (new RngFishable(new ItemStack(Items.fishing_rod), 1)).setMaxDamagePercent(0.25F).setEnchantable(), + (new RngFishable(new ItemStack(Items.book), 1)).setEnchantable()); + public static final WeightedList FISH_TYPES = new WeightedList( + new RngFishable(new ItemStack(Items.fish, 1, ItemFishFood.FishType.COD.getMetadata()), 60), + new RngFishable(new ItemStack(Items.fish, 1, ItemFishFood.FishType.SALMON.getMetadata()), 25), + new RngFishable(new ItemStack(Items.fish, 1, ItemFishFood.FishType.CLOWNFISH.getMetadata()), 2), + new RngFishable(new ItemStack(Items.fish, 1, ItemFishFood.FishType.PUFFERFISH.getMetadata()), 13)); +} diff --git a/common/src/common/init/Registry.java b/common/src/common/init/Registry.java index c6a34ff..4880af1 100755 --- a/common/src/common/init/Registry.java +++ b/common/src/common/init/Registry.java @@ -31,7 +31,6 @@ public abstract class Registry { SmeltingRegistry.register(); EntityRegistry.register(); DispenserRegistry.register(); - UniverseRegistry.register(); } public static void setup(String thread) { diff --git a/common/src/common/init/UniverseRegistry.java b/common/src/common/init/UniverseRegistry.java index 4986d28..dd02b2c 100755 --- a/common/src/common/init/UniverseRegistry.java +++ b/common/src/common/init/UniverseRegistry.java @@ -4,7 +4,7 @@ import java.util.List; import java.util.Map; import java.util.Map.Entry; -import common.biome.Biome; +import common.biome.BaseBiome; import common.block.BlockColored; import common.block.BlockSand; import common.block.LeavesType; @@ -518,7 +518,7 @@ public abstract class UniverseRegistry { PORTALS.put(portal.ordinal() | 0x7ff00000, BASE_ALIASES.get(dest).getDimensionId()); } - static void register() { + public static void register() { registerGalaxy("Milchstraße", "milkyway"); registerSector("Solar", "solar", "milkyway"); registerDimension("Sol", new Star(2, "sol", 0xff7f00, 274.0f, 5778.0f, Blocks.lava.getState(), 128).setTimeQualifier(1), "solar"); @@ -526,12 +526,12 @@ public abstract class UniverseRegistry { 259.15f).setTimeQualifier(0) .setPerlinGen(Blocks.stone.getState(), Blocks.water.getState(), 63) .setBiomeReplacer(Blocks.gravel.getState()) - .setBiomeGen(Biome.forest, false, 4, 4, 6, 50, 50, Biome.mushroomPlains).enableMobs().enableSnow() - .setFrostBiomes(Biome.icePlains, Biome.icePlains, Biome.icePlains, Biome.coldTaiga, Biome.megaTaiga) - .setColdBiomes(Biome.forest, Biome.extremeHills, Biome.taiga, Biome.plains, Biome.blackened) - .setMediumBiomes(Biome.forest, Biome.roofedForest, Biome.extremeHills, Biome.plains, Biome.birchForest, - Biome.swampland, Biome.jungle, Biome.blackened) - .setHotBiomes(Biome.desert, Biome.desert, Biome.desert, Biome.savanna, Biome.savanna, Biome.plains) + .setBiomeGen(BaseBiome.FOREST, false, 4, 4, 6, 50, 50, BaseBiome.MUSHROOMPLAINS).enableMobs().enableSnow() + .setFrostBiomes(BaseBiome.ICEPLAINS, BaseBiome.ICEPLAINS, BaseBiome.ICEPLAINS, BaseBiome.COLDTAIGA, BaseBiome.MEGATAIGA) + .setColdBiomes(BaseBiome.FOREST, BaseBiome.EXTREMEHILLS, BaseBiome.TAIGA, BaseBiome.PLAINS, BaseBiome.BLACKENED) + .setMediumBiomes(BaseBiome.FOREST, BaseBiome.ROOFEDFOREST, BaseBiome.EXTREMEHILLS, BaseBiome.PLAINS, BaseBiome.BIRCHFOREST, + BaseBiome.SWAMPLAND, BaseBiome.JUNGLE, BaseBiome.BLACKENED) + .setHotBiomes(BaseBiome.DESERT, BaseBiome.DESERT, BaseBiome.DESERT, BaseBiome.SAVANNA, BaseBiome.SAVANNA, BaseBiome.PLAINS) .enableCavesRavines(Blocks.lava.getState()).setDungeons(8).setWorldFloor(Blocks.bedrock.getState()) .addLake(Blocks.water.getState(), null, Blocks.grass.getState(), 4, 0, 255, false) .addLake(Blocks.lava.getState(), Blocks.stone.getState(), null, 8, 8, 255, true) @@ -549,7 +549,7 @@ public abstract class UniverseRegistry { .addOre(Blocks.cinnabar_ore.getState(), 1, 0, 11, 0, 24, false) .enableVillages().enableMineshafts().enableScattered().enableStrongholds(), "sol"); registerDimension("Luna", new Moon(3, "luna", 0x333333, 0x333333, 655728L, 655728L, 1.62f, 210.0f, 8) - .setPerlinGen(Blocks.moon_rock.getState(), Blocks.air.getState(), 63).setBiome(Biome.moon) + .setPerlinGen(Blocks.moon_rock.getState(), Blocks.air.getState(), 63).setBiome(BaseBiome.MOON) .setTimeQualifier(1), "terra"); registerDimension("Merkur", new Planet(4, "mercury", 0x666666, 0x535353, 0x858585, 2111297L, 1407509L, 3.7f, 440.0f) @@ -592,7 +592,7 @@ public abstract class UniverseRegistry { registerDimension("Gi'rok", new Star(100, "girok", 0xff8f00, 232.0f, 5220.0f, Blocks.lava.getState(), 112).setTimeQualifier(2), "solar"); registerDimension("'Elbenplanet Gharoth'", new Planet(101, "gharoth", 0xffffffff, 0xc0d8ff, 0xffffff, 4837386L, 52960L, 30.0f, 10.0f, 257.3f) .setTimeQualifier(2).setSimpleGen(Blocks.dirt.getState(), Blocks.water.getState(), 64) - .setSimpleReplacer(Blocks.gravel.getState(), Blocks.sand.getState()).setBiome(Biome.elvenForest) + .setSimpleReplacer(Blocks.gravel.getState(), Blocks.sand.getState()).setBiome(BaseBiome.ELVENFOREST) .enableCaves(Blocks.air.getState()).setDungeons(4).enableMobs().enableSnow() .setWorldFloor(Blocks.bedrock.getState()) .addLake(Blocks.water.getState(), null, Blocks.grass.getState(), 4, 0, 255, false) @@ -603,7 +603,7 @@ public abstract class UniverseRegistry { .addOre(Blocks.gyriyn_ore.getState(), 0, 2, 3, 0, 12, false), "girok"); registerDimension("'Vampirplanet Transsylvanien'", new Planet(102, "transylvania", 0xffffffff, 0xc0d8ff, 0xffffff, 33850466L, 49760L, 20.0f, 10.0f, 255.5f) .setTimeQualifier(5).setPerlinGen(Blocks.rock.getState(), Blocks.water.getState(), 63) - .setBiomeReplacer(Blocks.gravel.getState()).setBiomeGen(Biome.forest, true, 5, 3, 3, 30) + .setBiomeReplacer(Blocks.gravel.getState()).setBiomeGen(BaseBiome.FOREST, true, 5, 3, 3, 30) .enableCavesRavines(Blocks.lava.getState()).setDungeons(10).enableMobs().enableSnow() .setWorldFloor(Blocks.bedrock.getState()) .addLake(Blocks.water.getState(), null, Blocks.grass.getState(), 4, 0, 255, false) @@ -615,12 +615,12 @@ public abstract class UniverseRegistry { .addOre(Blocks.ardite_ore.getState(), 0, 2, 3, 0, 12, false) .addOre(Blocks.nichun_ore.getState(), 0, 10, 1, 0, 10, false), "girok"); registerDimension("'Eismond Yrdinath'", new Moon(103, "yrdinath", 0xccccff, 0xccccff, 46743637L, 17460L, 2.5f, 239.15f, 8).setTimeQualifier(4) - .setPerlinGen(Blocks.snow.getState(), Blocks.ice.getState(), 63).setBiome(Biome.snowLand) + .setPerlinGen(Blocks.snow.getState(), Blocks.ice.getState(), 63).setBiome(BaseBiome.SNOWLAND) .setWorldFloor(Blocks.air.getState()).enableMobs().enableSnow().setWeather(Weather.SNOW), "transylvania"); registerDimension("'Wüstenplanet Me'sar'", new Planet(104, "mesar", 0xff7f3f, 0xff6022, 0xff6f00, 56643366L, 87340L, 11.0f, 333.15f) .setTimeQualifier(5).setPerlinGen(Blocks.rock.getState(), Blocks.air.getState(), 63) .setBiomeReplacer(Blocks.sand.getState().withProperty(BlockSand.VARIANT, BlockSand.EnumType.RED_SAND)) - .setBiomeGen(Biome.mesa, true, 3, 1000, 100000, 100000) + .setBiomeGen(BaseBiome.MESA, true, 3, 1000, 100000, 100000) .enableCavesRavines(Blocks.lava.getState()).enableMobs() .setWorldFloor(Blocks.bedrock.getState()) .addLake(Blocks.lava.getState(), null, null, 8, 8, 255, true) @@ -637,7 +637,7 @@ public abstract class UniverseRegistry { registerDimension("Ov'rol", new Star(120, "ovrol", 0x000000, 302.0f, 12666.0f, Blocks.goo.getState(), 192), "blvck"); registerDimension("'Schwarzplanet'", new Planet(121, "blackplanet", 0x000000, 0x000000, 0x000000, 4632918508L, 204556L, 12.0f, 0.0f) .setPerlinGen(Blocks.blackened_stone.getState(), Blocks.goo.getState(), 63) - .setBiomeReplacer(Blocks.blackened_cobble.getState()).setBiome(Biome.blackened) + .setBiomeReplacer(Blocks.blackened_cobble.getState()).setBiome(BaseBiome.BLACKENED) .enableCaves(Blocks.air.getState()).setDungeons(4).enableMobs() .setWorldFloor(Blocks.bedrock.getState()) .addLake(Blocks.goo.getState(), null, null, 8, 8, 255, true) @@ -646,7 +646,7 @@ public abstract class UniverseRegistry { registerDimension("Der Warp", new Semi(-1, "warp", 0x0c001f, 0x0c001f, 0x190033, 285.0f, 3).setCloudTexture("clouds_dense").setCloudHeight(238.0f) .setPerlinGen(Blocks.obsidian.getState(), Blocks.lava.getState(), 63) - .setBiome(Biome.chaos).enableCavesRavines(Blocks.air.getState()).enableLongCaves().enableMobs().enableSnow() + .setBiome(BaseBiome.CHAOS).enableCavesRavines(Blocks.air.getState()).enableLongCaves().enableMobs().enableSnow() .addLake(Blocks.water.getState(), null, Blocks.obsidian.getState(), 8, 0, 255, false) .addLake(Blocks.lava.getState(), null, null, 1, 8, 255, false) .addLiquid(Blocks.flowing_water.getState(), 1, 8, 255, false) @@ -656,7 +656,7 @@ public abstract class UniverseRegistry { registerDomain("Tian'Xin", "tianxin"); registerDimension("Ni'enrath", new Area(-2, "nienrath", 0x7f00ff, 0x7f00ff, 276.15f, 1) - .setPerlinGen(Blocks.tian.getState(), Blocks.water.getState(), 63).setBiome(Biome.tian) + .setPerlinGen(Blocks.tian.getState(), Blocks.water.getState(), 63).setBiome(BaseBiome.TIAN) .setBiomeReplacer(Blocks.tian.getState()).enableLongCaves().enableMobs().enableSnow() .addLake(Blocks.water.getState(), Blocks.tian.getState(), Blocks.tian.getState(), 4, 0, 255, false) .addLiquid(Blocks.flowing_water.getState(), 50, 8, 255, false), "tianxin"); @@ -670,32 +670,32 @@ public abstract class UniverseRegistry { .setWorldFloor(Blocks.air.getState()).setWorldCeiling(Blocks.bedrock.getState()).enableDenseFog() .setCavernGen(Blocks.hellrock.getState(), Blocks.lava.getState(), 63) .setSurfaceReplacer(Blocks.gravel.getState(), Blocks.soul_sand.getState()) - .setBiome(Biome.upperHell), "hell"); + .setBiome(BaseBiome.UPPERHELL), "hell"); registerDimension("Kreis Kyroth", new Area(-1002, "kyroth", 0x990000, 0x990000, 387.15f, 3).enableLongCaves().enableMobs() .setWorldFloor(Blocks.air.getState()) .setSimpleGen(Blocks.hellrock.getState(), Blocks.lava.getState(), 64) .setSimpleReplacer(Blocks.obsidian.getState(), Blocks.soul_sand.getState()) - .setBiome(Biome.lowerHell) + .setBiome(BaseBiome.LOWERHELL) .addLake(Blocks.lava.getState(), null, null, 4, 8, 255, false) .addLiquid(Blocks.flowing_lava.getState(), 40, 8, 255, true), "hell"); registerDimension("Kreis Ahrd", new Area(-1003, "ahrd", 0xcc0000, 0xcc0000, 467.15f, 15).enableLongCaves().enableMobs() .setWorldFloor(Blocks.air.getState()) .setPerlinGen(Blocks.hellrock.getState(), Blocks.lava.getState(), 63) - .setBiomeReplacer(Blocks.soul_sand.getState()).setBiome(Biome.hellHills) + .setBiomeReplacer(Blocks.soul_sand.getState()).setBiome(BaseBiome.HELLHILLS) .addLake(Blocks.lava.getState(), Blocks.soul_sand.getState(), Blocks.soul_sand.getState(), 2, 8, 255, false).addLiquid(Blocks.flowing_lava.getState(), 80, 8, 255, true), "hell"); registerDimension("Kreis Mizorath", new Area(-1004, "mizorath", 0xff0000, 0xff0000, 1067.15f, 15).enableMobs() .setWorldFloor(Blocks.air.getState()) .setPerlinGen(Blocks.hellrock.getState(), Blocks.blood.getState(), 63) - .setBiomeReplacer(Blocks.soul_sand.getState()).setBiome(Biome.soulPlains), "hell"); + .setBiomeReplacer(Blocks.soul_sand.getState()).setBiome(BaseBiome.SOULPLAINS), "hell"); registerDimension("Kreis Dargoth", new Area(-1005, "dargoth", 0xff3f0c, 0xff3f0c, 1707.15f, 15).enableMobs() .setWorldFloor(Blocks.air.getState()) .setPerlinGen(Blocks.hellrock.getState(), Blocks.magma.getState(), 63) - .setBiomeReplacer(Blocks.soul_sand.getState()).setBiome(Biome.soulPlains), "hell"); + .setBiomeReplacer(Blocks.soul_sand.getState()).setBiome(BaseBiome.SOULPLAINS), "hell"); registerDimension("Kreis Aasirith", new Area(-1006, "aasirith", 0x191919, 0x191919, 2482.0f, 1).enableLongCaves().enableMobs() .setWorldFloor(Blocks.air.getState()) .setPerlinGen(Blocks.rock.getState(), Blocks.magma.getState(), 63) - .setBiomeReplacer(Blocks.ash.getState()).setBiome(Biome.ashLand) + .setBiomeReplacer(Blocks.ash.getState()).setBiome(BaseBiome.ASHLAND) .addLake(Blocks.lava.getState(), Blocks.rock.getState(), Blocks.rock.getState(), 2, 8, 255, false).addLiquid(Blocks.flowing_lava.getState(), 80, 8, 255, true), "hell"); @@ -749,7 +749,7 @@ public abstract class UniverseRegistry { dtag.setInteger("SeaRarity", 50); dtag.setInteger("AddRarity", 50); dtag.setInteger("SeaLevel", 0); - dtag.setString("DefaultBiome", Biome.none.name.toLowerCase()); + dtag.setString("DefaultBiome", BaseBiome.NONE.name.toLowerCase()); dtag.setBoolean("SemiFixed", false); // dtag.setString("DefaultWeather", Weather.CLEAR.getName()); dtag.setString("DefaultLeaves", LeavesType.SPRING.getName()); @@ -768,11 +768,11 @@ public abstract class UniverseRegistry { return dim; } - private static Dimension addFlatPreset(String name, Biome biome, boolean populate, State main, Object ... layers) { + private static Dimension addFlatPreset(String name, BaseBiome biome, boolean populate, State main, Object ... layers) { return addFlatPreset(name, "terra", biome, populate, main, layers); } - private static Dimension addFlatPreset(String name, String base, Biome biome, boolean populate, State main, Object ... layers) { + private static Dimension addFlatPreset(String name, String base, BaseBiome biome, boolean populate, State main, Object ... layers) { Dimension dim = addPreset("Flach - " + name, base, "ClearGenerator:1b" + (populate ? "" : ",NoPopulation:1b")); dim.setBiome(biome); if(main != null) @@ -795,33 +795,33 @@ public abstract class UniverseRegistry { addPreset("Chaotische Höhlen", "UpperLmtScale:2.0,LowerLmtScale:64.0,SeaLevel:6"); addPreset("Viel Glück", "LiquidBlock:lava,SeaLevel:40"); - addFlatPreset("Klassisch", Biome.plains, false, Blocks.dirt.getState(), Blocks.bedrock.getState(), 2, Blocks.dirt.getState(), + addFlatPreset("Klassisch", BaseBiome.PLAINS, false, Blocks.dirt.getState(), Blocks.bedrock.getState(), 2, Blocks.dirt.getState(), Blocks.grass.getState()).enableVillages(); - addFlatPreset("Abbauwelt", Biome.extremeHills, true, Blocks.stone.getState(), Blocks.bedrock.getState(), 230, Blocks.stone.getState(), + addFlatPreset("Abbauwelt", BaseBiome.EXTREMEHILLS, true, Blocks.stone.getState(), Blocks.bedrock.getState(), 230, Blocks.stone.getState(), 5, Blocks.dirt.getState(), Blocks.grass.getState()).enableStrongholds().enableMineshafts().setDungeons(8); - addFlatPreset("Wasserwelt", Biome.sea, false, Blocks.stone.getState(), Blocks.bedrock.getState(), 5, Blocks.stone.getState(), + addFlatPreset("Wasserwelt", BaseBiome.SEA, false, Blocks.stone.getState(), Blocks.bedrock.getState(), 5, Blocks.stone.getState(), 52, Blocks.dirt.getState(), 5, Blocks.sand.getState(), 90, Blocks.water.getState()); - addFlatPreset("Oberfläche", Biome.plains, true, Blocks.stone.getState(), Blocks.bedrock.getState(), 59, Blocks.stone.getState(), + addFlatPreset("Oberfläche", BaseBiome.PLAINS, true, Blocks.stone.getState(), Blocks.bedrock.getState(), 59, Blocks.stone.getState(), 3, Blocks.dirt.getState(), Blocks.grass.getState()).setBiomeReplacer(Blocks.gravel.getState()).enableVillages().enableStrongholds().enableMineshafts().setDungeons(8) .addLake(Blocks.water.getState(), null, Blocks.grass.getState(), 4, 0, 255, false).addLake(Blocks.lava.getState(), Blocks.stone.getState(), null, 8, 8, 255, true); - addFlatPreset("Verschneites Königreich", Biome.icePlains, false, Blocks.stone.getState(), Blocks.bedrock.getState(), 59, Blocks.stone.getState(), + addFlatPreset("Verschneites Königreich", BaseBiome.ICEPLAINS, false, Blocks.stone.getState(), Blocks.bedrock.getState(), 59, Blocks.stone.getState(), 3, Blocks.dirt.getState(), Blocks.grass.getState(), Blocks.snow_layer.getState()).enableVillages(); - addFlatPreset("Verschneites Königreich +", Biome.icePlains, true, Blocks.stone.getState(), Blocks.bedrock.getState(), 59, Blocks.stone.getState(), + addFlatPreset("Verschneites Königreich +", BaseBiome.ICEPLAINS, true, Blocks.stone.getState(), Blocks.bedrock.getState(), 59, Blocks.stone.getState(), 3, Blocks.dirt.getState(), Blocks.grass.getState(), Blocks.snow_layer.getState()).setBiomeReplacer(Blocks.gravel.getState()).enableVillages() .addLake(Blocks.water.getState(), null, Blocks.grass.getState(), 4, 0, 255, false); - addFlatPreset("Unendliche Grube", Biome.plains, false, Blocks.dirt.getState(), 2, Blocks.cobblestone.getState(), 3, Blocks.dirt.getState(), Blocks.grass.getState()) + addFlatPreset("Unendliche Grube", BaseBiome.PLAINS, false, Blocks.dirt.getState(), 2, Blocks.cobblestone.getState(), 3, Blocks.dirt.getState(), Blocks.grass.getState()) .setBiomeReplacer(Blocks.gravel.getState()).enableVillages(); - addFlatPreset("Wüste", Biome.desert, false, Blocks.stone.getState(), Blocks.bedrock.getState(), 3, Blocks.stone.getState(), 52, Blocks.sandstone.getState()) + addFlatPreset("Wüste", BaseBiome.DESERT, false, Blocks.stone.getState(), Blocks.bedrock.getState(), 3, Blocks.stone.getState(), 52, Blocks.sandstone.getState()) .enableVillages().enableScattered(); - addFlatPreset("Redstonewelt", Biome.desert, false, Blocks.sandstone.getState(), Blocks.bedrock.getState(), 3, Blocks.stone.getState(), + addFlatPreset("Redstonewelt", BaseBiome.DESERT, false, Blocks.sandstone.getState(), Blocks.bedrock.getState(), 3, Blocks.stone.getState(), 52, Blocks.sandstone.getState()); addPreset("Leer", "ClearGenerator:1b"); diff --git a/common/src/common/item/ItemInfoWand.java b/common/src/common/item/ItemInfoWand.java index 6370462..a0250f0 100755 --- a/common/src/common/item/ItemInfoWand.java +++ b/common/src/common/item/ItemInfoWand.java @@ -1,6 +1,6 @@ package common.item; -import common.biome.Biome; +import common.biome.BaseBiome; import common.color.TextColor; import common.entity.npc.EntityNPC; import common.util.BlockPos; @@ -14,7 +14,7 @@ public class ItemInfoWand extends ItemWand { public void onUse(ItemStack stack, EntityNPC player, AWorldServer world, Vec3 vec) { - Biome biome = world.getBiomeGenForCoords(new BlockPos(vec.xCoord, 0, vec.zCoord)); + BaseBiome biome = world.getBiomeGenForCoords(new BlockPos(vec.xCoord, 0, vec.zCoord)); player.connection.addHotbar(TextColor.NEON + "* Position bei Level %d: %.3f %.3f %.3f, %s [%d], %.2f °C", world.dimension.getDimensionId(), vec.xCoord, vec.yCoord, vec.zCoord, biome.display, biome.id, world.getTemperatureC(new BlockPos(vec))); diff --git a/common/src/common/world/AWorldServer.java b/common/src/common/world/AWorldServer.java index 5135f32..3ab7b11 100644 --- a/common/src/common/world/AWorldServer.java +++ b/common/src/common/world/AWorldServer.java @@ -10,12 +10,10 @@ import common.entity.types.EntityLiving; import common.model.ParticleType; import common.network.IPlayer; import common.network.Packet; -import common.rng.Random; import common.util.BlockPos; import common.util.BoundingBox; import common.util.PortalType; import common.village.Village; -import common.worldgen.BiomeGenerator; public abstract class AWorldServer extends World { protected AWorldServer(Dimension dim, boolean debug) { @@ -25,10 +23,8 @@ public abstract class AWorldServer extends World { public abstract List getAllPlayers(); public abstract AWorldServer getOtherWorld(int dimension); public abstract void placeInDimension(Entity entity, AWorldServer oldWorld, AWorldServer world, BlockPos pos, PortalType portal); - public abstract State getSurfaceLiquid(); public abstract boolean addLoader(BlockPos pos); public abstract boolean removeLoader(BlockPos pos); - public abstract BiomeGenerator getBiomeGenerator(); public abstract boolean isBlockTickPending(BlockPos pos, Block blockType); public abstract void updateBlockTick(BlockPos pos, Block blockIn, int delay, int priority); public abstract void resetUpdateEntityTick(); @@ -39,24 +35,13 @@ public abstract class AWorldServer extends World { public abstract long getSeed(); public abstract boolean isExterminated(); public abstract boolean exterminate(); - public abstract void forceBlockUpdateTick(Block blockType, BlockPos pos, Random random); public abstract Village getNearestVillage(BlockPos doorBlock, int radius); public abstract void addToVillagerPositionList(BlockPos blockpos); - public abstract void removePlayer(EntityNPC player); - public abstract void updateMountedMovingPlayer(EntityNPC player); public abstract boolean isPlayerWatchingChunk(EntityNPC player, int chunkX, int chunkZ); - public abstract void untrackEntity(Entity entityIn); - public abstract void updateTrackedPlayer(EntityNPC player); public abstract void sendToAllTrackingEntity(Entity entityIn, Packet packet); - public abstract void sendToAllTrackingAndSelf(Entity entityIn, Packet packet); - public abstract void removePlayerFromTrackers(EntityNPC player); - public abstract void updateChunksForPlayer(EntityNPC player, Chunk chunk); public abstract boolean isDaytime(); public abstract int getSkylightSubtracted(); public abstract boolean isBlockinHighHumidity(BlockPos pos); public abstract T findNearestEntityWithinAABB(Class entityType, BoundingBox aabb, T closestTo); - public abstract boolean canBlockFreeze(BlockPos pos, boolean noWaterAdj); - public abstract BlockPos getTopSolidOrLiquidBlock(BlockPos pos); - public abstract void removePlayerEntityDangerously(Entity entityIn); public abstract long getTime(); } diff --git a/common/src/common/world/Chunk.java b/common/src/common/world/Chunk.java index 484292c..84ed58c 100755 --- a/common/src/common/world/Chunk.java +++ b/common/src/common/world/Chunk.java @@ -6,11 +6,12 @@ import java.util.Map; import java.util.concurrent.ConcurrentLinkedQueue; import java.util.function.Predicate; -import common.biome.Biome; +import common.biome.BaseBiome; import common.block.Block; import common.block.ITileEntityProvider; import common.collect.Maps; import common.entity.Entity; +import common.init.BlockRegistry; import common.init.Blocks; import common.log.Log; import common.material.Material; @@ -24,8 +25,7 @@ import common.util.ExtMath; import common.util.Facing; import common.util.NibbleArray; import common.worldgen.BiomeGenerator; -import common.worldgen.ChunkPrimer; -import common.worldgen.GeneratorDebug; +import common.worldgen.DebugStates; public class Chunk { public final int xPos; @@ -63,14 +63,14 @@ public class Chunk { Arrays.fill(this.biomes, (byte)-1); } - public Chunk(World world, ChunkPrimer primer, State base, State ceil, Random rand, Biome[] biomes, int x, int z) { + public Chunk(World world, short[] data, int height, State base, State ceil, Random rand, BaseBiome[] biomes, int x, int z) { this(world, x, z); boolean sky = !world.dimension.hasNoLight(); for(int bx = 0; bx < 16; ++bx) { for(int bz = 0; bz < 16; ++bz) { - for(int by = 0; by < primer.height; ++by) { - State state = primer.get(bx, by, bz); - if(state.getBlock().getMaterial() != Material.air) { + for(int by = 0; by < height; ++by) { + State state = BlockRegistry.STATEMAP.getByValue(data[bx << 4 | bz | by << 8]); + if(state != null && state.getBlock().getMaterial() != Material.air) { int y = by >> 4; if(this.blocks[y] == null) this.blocks[y] = new BlockArray(y << 4, sky); @@ -92,16 +92,16 @@ public class Chunk { } } if(ceil != null) { - int y = (primer.height - 1) >> 4; + int y = (height - 1) >> 4; if(this.blocks[y] == null) this.blocks[y] = new BlockArray(y << 4, sky); - y = (primer.height - 5) >> 4; + y = (height - 5) >> 4; if(this.blocks[y] == null) this.blocks[y] = new BlockArray(y << 4, sky); for(int bx = 0; bx < 16; ++bx) { for(int bz = 0; bz < 16; ++bz) { - for(int by = primer.height - 1; by >= primer.height - 5; --by) { - if(by >= (primer.height - 1) - rand.zrange(5)) + for(int by = height - 1; by >= height - 5; --by) { + if(by >= (height - 1) - rand.zrange(5)) this.blocks[by >> 4].set(bx, by & 15, bz, ceil); } } @@ -412,7 +412,7 @@ public class Chunk { // } if(pos.getY() == 1) { - state = GeneratorDebug.getState(pos.getX(), pos.getZ()); + state = DebugStates.getState(pos.getX(), pos.getZ()); } return state == null ? Blocks.air.getState() : state; @@ -956,19 +956,18 @@ public class Chunk { } } - public Biome getBiome(BlockPos pos, BiomeGenerator gen) { + public BaseBiome getBiome(BlockPos pos, BiomeGenerator gen) { int x = pos.getX() & 15; int z = pos.getZ() & 15; int o = this.biomes[z << 4 | x] & 255; if(o == 255) { - Biome biome = gen == null ? Biome.DEF_BIOME : gen.getBiomeGenerator(pos, Biome.DEF_BIOME); + BaseBiome biome = gen == null ? BaseBiome.DEF_BIOME : gen.getBiomeGenerator(pos, BaseBiome.DEF_BIOME); o = biome.id; this.biomes[z << 4 | x] = (byte)(o & 255); } - Biome biome = Biome.getBiome(o); - return biome == null ? Biome.DEF_BIOME : biome; + return BaseBiome.getBiomeDef(o); } public byte[] getBiomes() { diff --git a/common/src/common/world/IWorld.java b/common/src/common/world/IWorld.java deleted file mode 100644 index ef161f4..0000000 --- a/common/src/common/world/IWorld.java +++ /dev/null @@ -1,279 +0,0 @@ -package common.world; - -import java.util.Collection; -import java.util.List; -import java.util.function.Predicate; - -import common.biome.Biome; -import common.block.Block; -import common.block.LeavesType; -import common.entity.Entity; -import common.entity.item.EntityExplosion; -import common.entity.npc.EntityNPC; -import common.init.SoundEvent; -import common.item.ItemStack; -import common.model.ParticleType; -import common.tileentity.TileEntity; -import common.util.BlockPos; -import common.util.BoundingBox; -import common.util.Facing; -import common.util.HitPosition; -import common.util.Vec3; - -public interface IWorld { - - boolean isBlockSolid(BlockPos pos); - - void setGravity(float gravity); - - Biome getBiomeGenForCoords(BlockPos pos); - - boolean isAirBlock(BlockPos pos); - - boolean isBlockLoaded(BlockPos pos); - - boolean isBlockLoaded(BlockPos pos, boolean allowEmpty); - - boolean isAreaLoaded(BlockPos center, int radius); - - boolean isAreaLoaded(BlockPos center, int radius, boolean allowEmpty); - - boolean isAreaLoaded(BlockPos from, BlockPos to); - - boolean isAreaLoaded(BlockPos from, BlockPos to, boolean allowEmpty); - - Chunk getChunk(BlockPos pos); - - boolean setState(BlockPos pos, State newState, int flags); - - boolean setState(BlockPos pos, State state); - - boolean setBlockToAir(BlockPos pos); - - boolean destroyBlock(BlockPos pos, boolean dropBlock); - - void notifyNeighborsRespectDebug(BlockPos pos, Block blockType); - - void markBlocksDirtyVertical(int x1, int z1, int x2, int z2); - - void markBlockRangeForRenderUpdate(BlockPos rangeMin, BlockPos rangeMax); - - void notifyNeighborsOfStateChange(BlockPos pos, Block blockType); - - void notifyNeighborsOfStateExcept(BlockPos pos, Block blockType, Facing skipSide); - - void notifyBlockOfStateChange(BlockPos pos, Block blockIn); - - boolean canSeeSky(BlockPos pos); - - int getLight(BlockPos pos); - - int getLightFromNeighbors(BlockPos pos); - - BlockPos getHeight(BlockPos pos); - - int getChunksLowestHorizon(int x, int z); - - int getLightFromNeighborsFor(LightType type, BlockPos pos); - - int getLightFor(LightType type, BlockPos pos); - - void setLightFor(LightType type, BlockPos pos, int lightValue); - - int getCombinedLight(BlockPos pos, int lightValue); - - float getLightBrightness(BlockPos pos); - - State getState(BlockPos pos); - - BlockPos getBlockTrace(Entity entity, int distance); - - HitPosition rayTraceBlocks(Vec3 p_72933_1_, Vec3 p_72933_2_); - - HitPosition rayTraceBlocks(Vec3 start, Vec3 end, boolean stopOnLiquid); - - HitPosition rayTraceBlocks(Vec3 vec31, Vec3 vec32, boolean stopOnLiquid, boolean ignoreBlockWithoutBoundingBox, - boolean returnLastUncollidableBlock); - - void playSoundAtEntity(Entity entityIn, SoundEvent name, float volume); - - boolean spawnEntityInWorld(Entity entityIn); - - void removeEntity(Entity entityIn); - - List getCollidingBoundingBoxes(Entity entityIn, BoundingBox bb); - - List getCollisionBoxes(BoundingBox bb); - - int calculateSkylightSubtracted(boolean current); - - float getCelestialAngle(float partialTicks); - - int getMoonPhase(); - - float getCurrentMoonPhaseFactor(); - - float getCelestialAngleRadians(float partialTicks); - - BlockPos getPrecipitationHeight(BlockPos pos); - - void updateEntities(); - - boolean addTileEntity(TileEntity tile); - - void addTileEntities(Collection tileEntityCollection); - - void updateEntity(Entity entityIn, boolean forceUpdate); - - boolean checkNoEntityCollision(BoundingBox bb); - - boolean checkNoEntityCollision(BoundingBox bb, Entity entityIn); - - boolean isAnyLiquid(BoundingBox bb); - - boolean isFlammableWithin(BoundingBox bb); - - boolean handleLiquidAcceleration(BoundingBox bb, Entity entityIn); - - boolean isMaterialInMolten(BoundingBox bb); - - boolean isAABBInLiquid(BoundingBox bb); - - Explosion createExplosion(Entity entityIn, double x, double y, double z, float strength, boolean isSmoking); - - Explosion createAltExplosion(Entity entityIn, double x, double y, double z, float strength, boolean isSmoking); - - Explosion newExplosion(Entity entityIn, double x, double y, double z, float strength, boolean isFlaming, boolean isSmoking, boolean altSound); - - EntityExplosion newExplosion(double x, double y, double z, int strength); - - float getBlockDensity(Vec3 vec, BoundingBox bb); - - boolean extinguishFire(EntityNPC player, BlockPos pos, Facing side); - - TileEntity getTileEntity(BlockPos pos); - - void setTileEntity(BlockPos pos, TileEntity tileEntityIn); - - void removeTileEntity(BlockPos pos); - - void markTileEntityForRemoval(TileEntity tileEntityIn); - - float getTempOffset(); - - LeavesType getLeavesGen(BlockPos pos); - - float getTemperatureK(BlockPos pos); - - float getTemperatureC(BlockPos pos); - - boolean canFreezeAt(BlockPos pos); - - boolean canBurnAt(BlockPos pos); - - boolean doesWaterVaporize(BlockPos pos); - - boolean isLavaFaster(BlockPos pos); - - boolean canSnowAt(BlockPos pos, boolean checkLight, boolean allowLayers); - - boolean checkLight(BlockPos pos); - - boolean checkLightFor(LightType lightType, BlockPos pos); - - List getEntitiesWithinAABBExcludingEntity(Entity entityIn, BoundingBox bb); - - List getEntitiesInAABBexcluding(Entity entityIn, BoundingBox boundingBox, Predicate predicate); - - List getEntitiesWithinAABB(Class classEntity, BoundingBox bb); - - List getEntitiesWithinAABB(Class clazz, BoundingBox aabb, Predicate filter); - - Entity getEntityByID(int id); - - void markChunkDirty(BlockPos pos, TileEntity unusedTileEntity); - - void loadEntities(Collection entityCollection); - - void unloadEntities(Collection entityCollection); - - boolean canBlockBePlaced(Block blockIn, BlockPos pos, boolean p_175716_3_, Facing side, Entity entityIn, ItemStack itemStackIn); - - int getSeaLevel(); - - int getStrongPower(BlockPos pos); - - boolean isSidePowered(BlockPos pos, Facing side); - - int getRedstonePower(BlockPos pos, Facing facing); - - boolean isBlockPowered(BlockPos pos); - - int isBlockIndirectlyGettingPowered(BlockPos pos); - - EntityNPC getClosestPlayerToEntity(Entity entityIn, double distance); - - EntityNPC getClosestPlayer(double x, double y, double z, double distance); - - boolean isAnyPlayerWithinRangeAt(double x, double y, double z, double range); - - void setTimeFactor(int factor); - - void setEntityState(Entity entityIn, byte state); - - void addBlockEvent(BlockPos pos, Block blockIn, int eventID, int eventParam); - - Weather getWeather(); - - long getDayTime(); - - void setWeather(Weather weather); - - void setDayTime(long time); - - float getDarkness(); - - void setDarkness(float dark); - - float getRainStrength(); - - void setRainStrength(float strength); - - float getFogStrength(); - - void setFogStrength(float strength); - - void setTemperature(float temp); - - boolean isDark(); - - boolean isThundering(); - - boolean hasDownfall(); - - boolean isRaining(); - - boolean isRainingAt(BlockPos strikePosition, boolean wet); - - void playAuxSFX(int type, BlockPos pos, int data); - - void updateComparatorOutputLevel(BlockPos pos, Block blockIn); - - void scheduleUpdate(BlockPos pos, Block blockIn, int delay); - - void spawnParticle(ParticleType particleType, double xCoord, double yCoord, double zCoord, double xOffset, double yOffset, double zOffset, - int... data); - - Chunk getChunk(int x, int z); - - void markBlockForUpdate(BlockPos pos); - - void markBlockRangeForRenderUpdate(int x1, int y1, int z1, int x2, int y2, int z2); - - void playSound(SoundEvent sound, double x, double y, double z, float volume); - - void playAuxSFX(EntityNPC player, int sfxType, BlockPos blockPosIn, int data); - - void sendBlockBreakProgress(int breakerId, BlockPos pos, int progress); - -} \ No newline at end of file diff --git a/common/src/common/world/IWorldAccess.java b/common/src/common/world/IWorldAccess.java index b798152..e90b74f 100755 --- a/common/src/common/world/IWorldAccess.java +++ b/common/src/common/world/IWorldAccess.java @@ -1,6 +1,6 @@ package common.world; -import common.biome.Biome; +import common.biome.BaseBiome; import common.tileentity.TileEntity; import common.util.BlockPos; @@ -8,5 +8,5 @@ public interface IWorldAccess extends IBlockAccess { TileEntity getTileEntity(BlockPos pos); int getCombinedLight(BlockPos pos, int lightValue); - Biome getBiomeGenForCoords(BlockPos pos); + BaseBiome getBiomeGenForCoords(BlockPos pos); } diff --git a/common/src/common/world/World.java b/common/src/common/world/World.java index 7b66e16..7597092 100755 --- a/common/src/common/world/World.java +++ b/common/src/common/world/World.java @@ -6,7 +6,7 @@ import java.util.List; import java.util.Set; import java.util.function.Predicate; -import common.biome.Biome; +import common.biome.BaseBiome; import common.block.Block; import common.block.BlockHopper; import common.block.BlockLiquid; @@ -38,7 +38,7 @@ import common.util.HitPosition; import common.util.IntHashMap; import common.util.Vec3; -public abstract class World implements IWorldAccess, IWorld { +public abstract class World implements IWorldAccess { public static final float[][] BRIGHTNESS = new float[16][16]; static { for(int l = 0; l < 16; l++) { @@ -133,11 +133,11 @@ public abstract class World implements IWorldAccess, IWorld { this.gravity = Math.signum(this.gravity) * 0.075; } - public Biome getBiomeGenForCoords(final BlockPos pos) { + public BaseBiome getBiomeGenForCoords(final BlockPos pos) { if(this.isBlockLoaded(pos)) return this.getChunk(pos).getBiome(pos, null); else - return Biome.DEF_BIOME; + return BaseBiome.DEF_BIOME; } public boolean isAirBlock(BlockPos pos) { diff --git a/common/src/common/worldgen/BiomeGenerator.java b/common/src/common/worldgen/BiomeGenerator.java index b6ef4e9..c8db4d7 100755 --- a/common/src/common/worldgen/BiomeGenerator.java +++ b/common/src/common/worldgen/BiomeGenerator.java @@ -2,15 +2,15 @@ package common.worldgen; import java.util.Set; -import common.biome.Biome; +import common.biome.BaseBiome; import common.util.BlockPos; public interface BiomeGenerator { public void genFactors(double[] factors, int xPos, int zPos, int sizeX, int sizeZ); - public Biome getBiomeGenerator(BlockPos pos, Biome def); - public void getGenBiomes(Biome[] biomes, int x, int z, int width, int height); - public void getChunkBiomes(Biome[] oldBiomeList, int x, int z, int width, int depth); - public void getBiomes(Biome[] listToReuse, int x, int z, int width, int length, boolean cacheFlag); - public boolean areBiomesViable(int x, int z, int size, Set allowed); + public BaseBiome getBiomeGenerator(BlockPos pos, BaseBiome def); + public void getGenBiomes(BaseBiome[] biomes, int x, int z, int width, int height); + public void getChunkBiomes(BaseBiome[] oldBiomeList, int x, int z, int width, int depth); + public void getBiomes(BaseBiome[] listToReuse, int x, int z, int width, int length, boolean cacheFlag); + public boolean areBiomesViable(int x, int z, int size, Set allowed); public void cleanupCache(); } diff --git a/common/src/common/worldgen/BlockReplacer.java b/common/src/common/worldgen/BlockReplacer.java deleted file mode 100755 index f94bab7..0000000 --- a/common/src/common/worldgen/BlockReplacer.java +++ /dev/null @@ -1,9 +0,0 @@ -package common.worldgen; - -import common.biome.Biome; -import common.rng.Random; -import common.world.AWorldServer; - -public interface BlockReplacer { - public void replaceBlocks(AWorldServer world, int x, int z, ChunkPrimer primer, Random rand, Biome[] biomes); -} diff --git a/common/src/common/worldgen/ChunkGenerator.java b/common/src/common/worldgen/ChunkGenerator.java deleted file mode 100755 index 6e149f1..0000000 --- a/common/src/common/worldgen/ChunkGenerator.java +++ /dev/null @@ -1,8 +0,0 @@ -package common.worldgen; - -import common.world.AWorldServer; - -public interface ChunkGenerator { - public void generateChunk(AWorldServer world, int x, int z, ChunkPrimer primer); - public int getMaximumHeight(); -} diff --git a/common/src/common/worldgen/GeneratorDebug.java b/common/src/common/worldgen/DebugStates.java old mode 100755 new mode 100644 similarity index 60% rename from common/src/common/worldgen/GeneratorDebug.java rename to common/src/common/worldgen/DebugStates.java index 5833d49..7487eb7 --- a/common/src/common/worldgen/GeneratorDebug.java +++ b/common/src/common/worldgen/DebugStates.java @@ -1,59 +1,38 @@ -package common.worldgen; - -import java.util.List; - -import common.block.Block; -import common.collect.Lists; -import common.init.BlockRegistry; -import common.util.ExtMath; -import common.world.State; -import common.world.AWorldServer; - -public class GeneratorDebug implements ChunkGenerator -{ - private static final List STATES = Lists.newArrayList(); - private static final int XSTRETCH; - private static final int ZSTRETCH; - - static { - for(Block block : BlockRegistry.REGISTRY) { - STATES.addAll(block.getValidStates()); - } - XSTRETCH = ExtMath.ceilf(ExtMath.sqrtf((float)STATES.size())); - ZSTRETCH = ExtMath.ceilf((float)STATES.size() / (float)XSTRETCH); - } - - public static State getState(int x, int z) { - State state = null; - if(x > 0 && z > 0 && x % 2 != 0 && z % 2 != 0) { - x = x / 2; - z = z / 2; - if(x <= XSTRETCH && z <= ZSTRETCH) { - int idx = ExtMath.absi(x * XSTRETCH + z); - if(idx < STATES.size()) { - state = STATES.get(idx); - } - } - } - return state; - } - - public int getMaximumHeight() { - return 72; - } - - public void generateChunk(AWorldServer world, int x, int z, ChunkPrimer primer) - { - for(int bx = 0; bx < 16; ++bx) { - for(int bz = 0; bz < 16; ++bz) { - int sx = x * 16 + bx; - int sz = z * 16 + bz; -// primer.set(bx, 60, bz, Blocks.glass.getDefaultState()); - State state = getState(sx, sz); - if(state != null) { - primer.set(bx, 1, bz, state); - } - } +package common.worldgen; + +import java.util.List; + +import common.block.Block; +import common.collect.Lists; +import common.init.BlockRegistry; +import common.util.ExtMath; +import common.world.State; + +public class DebugStates { + private static final List STATES = Lists.newArrayList(); + private static final int XSTRETCH; + private static final int ZSTRETCH; + + static { + for(Block block : BlockRegistry.REGISTRY) { + STATES.addAll(block.getValidStates()); } - } -} + XSTRETCH = ExtMath.ceilf(ExtMath.sqrtf((float)STATES.size())); + ZSTRETCH = ExtMath.ceilf((float)STATES.size() / (float)XSTRETCH); + } + + public static State getState(int x, int z) { + State state = null; + if(x > 0 && z > 0 && x % 2 != 0 && z % 2 != 0) { + x = x / 2; + z = z / 2; + if(x <= XSTRETCH && z <= ZSTRETCH) { + int idx = ExtMath.absi(x * XSTRETCH + z); + if(idx < STATES.size()) { + state = STATES.get(idx); + } + } + } + return state; + } +} diff --git a/common/src/common/worldgen/FeatureLake.java b/common/src/common/worldgen/FeatureLake.java new file mode 100644 index 0000000..b279e52 --- /dev/null +++ b/common/src/common/worldgen/FeatureLake.java @@ -0,0 +1,23 @@ +package common.worldgen; + +import common.world.State; + +public class FeatureLake { + public final State state; + public final State filler; + public final State top; + public final int chance; + public final int minHeight; + public final int maxHeight; + public final boolean ratiod; + + public FeatureLake(State state, State filler, State top, int chance, int minHeight, int maxHeight, boolean ratiod) { + this.state = state; + this.filler = filler; + this.top = top; + this.chance = chance; + this.minHeight = minHeight; + this.maxHeight = maxHeight; + this.ratiod = ratiod; + } +} diff --git a/common/src/common/worldgen/FeatureLiquid.java b/common/src/common/worldgen/FeatureLiquid.java new file mode 100644 index 0000000..d2794c0 --- /dev/null +++ b/common/src/common/worldgen/FeatureLiquid.java @@ -0,0 +1,19 @@ +package common.worldgen; + +import common.world.State; + +public class FeatureLiquid { + public final State state; + public final int chance; + public final int minHeight; + public final int maxHeight; + public final boolean lower; + + public FeatureLiquid(State state, int chance, int minHeight, int maxHeight, boolean lower) { + this.state = state; + this.chance = chance; + this.minHeight = minHeight; + this.maxHeight = maxHeight; + this.lower = lower; + } +} diff --git a/common/src/common/worldgen/FeatureOre.java b/common/src/common/worldgen/FeatureOre.java new file mode 100644 index 0000000..38237ff --- /dev/null +++ b/common/src/common/worldgen/FeatureOre.java @@ -0,0 +1,23 @@ +package common.worldgen; + +import common.world.State; + +public class FeatureOre { + public final State state; + public final int count; + public final int more; + public final int size; + public final int min; + public final int max; + public final boolean dist; + + public FeatureOre(State state, int count, int more, int size, int min, int max, boolean dist) { + this.state = state; + this.count = count; + this.more = more; + this.size = size; + this.min = min; + this.max = max; + this.dist = dist; + } +} diff --git a/server/src/server/Server.java b/server/src/server/Server.java index 738d227..4e33741 100755 --- a/server/src/server/Server.java +++ b/server/src/server/Server.java @@ -86,6 +86,7 @@ import io.netty.channel.socket.nio.NioServerSocketChannel; import io.netty.handler.timeout.ReadTimeoutHandler; import io.netty.util.concurrent.Future; import io.netty.util.concurrent.GenericFutureListener; +import server.biome.Biome; import server.clipboard.ReorderRegistry; import server.clipboard.RotationRegistry; import server.command.CommandEnvironment; @@ -144,6 +145,8 @@ public final class Server implements IThreadListener { public static void main(String[] args) { Util.checkOs(); Registry.setup("Server thread"); + Biome.setAsProvider(); + UniverseRegistry.register(); RotationRegistry.register(); ReorderRegistry.register(); boolean debug = System.getProperty("server.debug", null) != null; @@ -907,10 +910,11 @@ public final class Server implements IThreadListener { public void recreatePlayer(Player conn) { EntityNPC old = conn.getEntity(); BlockPos pos = old.getPosition(); - old.getServerWorld().removePlayerFromTrackers(old); - old.getServerWorld().untrackEntity(old); - old.getServerWorld().removePlayer(old); - old.getServerWorld().removePlayerEntityDangerously(old); + WorldServer oldWorld = (WorldServer)old.getServerWorld(); + oldWorld.removePlayerFromTrackers(old); + oldWorld.untrackEntity(old); + oldWorld.removePlayer(old); + oldWorld.removePlayerEntityDangerously(old); WorldPos bed = old.getSpawnPoint(); WorldPos origin = old.getOrigin(); BlockPos spawn = null; @@ -975,11 +979,12 @@ public final class Server implements IThreadListener { old.writeToNBT(oldTag); oldTag.setInteger("Dimension", old.worldObj.dimension.getDimensionId()); oldTag.setString("id", EntityRegistry.getEntityString(old)); - - old.getServerWorld().removePlayerFromTrackers(old); - old.getServerWorld().untrackEntity(old); - old.getServerWorld().removePlayer(old); - old.getServerWorld().removePlayerEntityDangerously(old); + + WorldServer oldWorld = (WorldServer)old.getServerWorld(); + oldWorld.removePlayerFromTrackers(old); + oldWorld.untrackEntity(old); + oldWorld.removePlayer(old); + oldWorld.removePlayerEntityDangerously(old); // old.dead = false; WorldServer world = tag == null ? this.space : this.getWorld(tag.getInteger("Dimension")); diff --git a/common/src/common/biome/Biome.java b/server/src/server/biome/Biome.java similarity index 51% rename from common/src/common/biome/Biome.java rename to server/src/server/biome/Biome.java index e37576a..a8564f4 100755 --- a/common/src/common/biome/Biome.java +++ b/server/src/server/biome/Biome.java @@ -1,16 +1,13 @@ -package common.biome; - -import java.util.List; -import java.util.Map; +package server.biome; +import common.biome.BaseBiome; +import common.biome.IBiome; import common.block.Block; import common.block.BlockColored; import common.block.BlockFlower; import common.block.BlockSand; +import common.block.BlockSapling; import common.block.BlockTallGrass; -import common.collect.Lists; -import common.collect.Maps; -import common.color.Colorizer; import common.color.DyeColor; import common.entity.animal.EntityBat; import common.entity.animal.EntityChicken; @@ -27,104 +24,107 @@ import common.entity.npc.EntitySlime; import common.entity.npc.EntityUndead; import common.entity.npc.EntityZombie; import common.init.Blocks; +import common.init.WoodType; import common.log.Log; import common.material.Material; import common.rng.PerlinGen; import common.rng.Random; import common.rng.WeightedList; import common.util.BlockPos; -import common.util.ExtMath; +import common.world.AWorldServer; import common.world.State; import common.world.World; -import common.world.AWorldServer; -import common.worldgen.ChunkPrimer; -import common.worldgen.FeatureGenerator; -import common.worldgen.feature.WorldGenClay; -import common.worldgen.feature.WorldGenClayExt; -import common.worldgen.feature.WorldGenSand; -import common.worldgen.foliage.FeatureDoublePlant; -import common.worldgen.foliage.WorldGenBigMushroom; -import common.worldgen.foliage.WorldGenCactus; -import common.worldgen.foliage.WorldGenDeadBush; -import common.worldgen.foliage.WorldGenFlowers; -import common.worldgen.foliage.WorldGenMushroom; -import common.worldgen.foliage.WorldGenPumpkin; -import common.worldgen.foliage.WorldGenReed; -import common.worldgen.foliage.WorldGenTallGrass; -import common.worldgen.foliage.WorldGenWaterlily; -import common.worldgen.tree.WorldGenBaseTree; -import common.worldgen.tree.WorldGenBigTree; -import common.worldgen.tree.WorldGenSwamp; -import common.worldgen.tree.WorldGenTree; +import server.world.WorldServer; +import server.worldgen.ChunkPrimer; +import server.worldgen.FeatureGenerator; +import server.worldgen.feature.WorldGenClay; +import server.worldgen.feature.WorldGenClayExt; +import server.worldgen.feature.WorldGenSand; +import server.worldgen.foliage.FeatureDoublePlant; +import server.worldgen.foliage.WorldGenBigMushroom; +import server.worldgen.foliage.WorldGenCactus; +import server.worldgen.foliage.WorldGenDeadBush; +import server.worldgen.foliage.WorldGenFlowers; +import server.worldgen.foliage.WorldGenMushroom; +import server.worldgen.foliage.WorldGenPumpkin; +import server.worldgen.foliage.WorldGenReed; +import server.worldgen.foliage.WorldGenTallGrass; +import server.worldgen.foliage.WorldGenWaterlily; +import server.worldgen.tree.WorldGenBaseTree; +import server.worldgen.tree.WorldGenBigTree; +import server.worldgen.tree.WorldGenBirch; +import server.worldgen.tree.WorldGenDarkOak; +import server.worldgen.tree.WorldGenJungle; +import server.worldgen.tree.WorldGenPine; +import server.worldgen.tree.WorldGenSavanna; +import server.worldgen.tree.WorldGenSwamp; +import server.worldgen.tree.WorldGenTaiga2; +import server.worldgen.tree.WorldGenTree; -public abstract class Biome { - private static final Biome[] BIOMES = new Biome[256]; +public abstract class Biome implements IBiome { + public static final Biome[] BIOMES = new Biome[256]; - public static final Biome none = (new BiomeNone(0)).setBiomeName("none", ""); + public static final Biome none = (new BiomeNone()); - public static final Biome plains = (new BiomePlains(1)).setColor(9286496).setBiomeName("plains", "Ebene"); - public static final Biome desert = (new BiomeDesert(2)).setColor(16421912).setBiomeName("desert", "Wüste").setTemperature(60.0f).setHumidity(0.0f).setScaling(Scaling.PLAINS_LOW); - public static final Biome extremeHills = (new BiomeHills(3, false)).setColor(6316128).setBiomeName("extremeHills", "Extremes Bergland").setScaling(Scaling.HILLS_LARGE).setTemperature(-12.0f).setHumidity(30.0f); - public static final Biome forest = (new BiomeForest(4, 0)).setColor(353825).setBiomeName("forest", "Wald"); - public static final Biome taiga = (new BiomeTaiga(5, 0)).setColor(747097).setBiomeName("taiga", "Taiga").setTemperature(-10.0f).setHumidity(80.0f).setScaling(Scaling.PLAINS_MEDIUM); - public static final Biome swampland = (new BiomeSwamp(6)).setColor(522674).setBiomeName("swampland", "Sumpf").setScaling(Scaling.SEA_POND).setTemperature(12.0f).setHumidity(90.0f); - public static final Biome river = (new BiomeWater(7, true)).setColor(255).setBiomeName("river", "Fluss").setScaling(Scaling.SEA_SHALLOW); + public static final Biome plains = (new BiomePlains()); + public static final Biome desert = (new BiomeDesert(false)).setScaling(Scaling.PLAINS_LOW); + public static final Biome extremeHills = (new BiomeHills(BaseBiome.EXTREMEHILLS, false)).setScaling(Scaling.HILLS_LARGE); + public static final Biome forest = (new BiomeForest(BaseBiome.FOREST, 0)); + public static final Biome taiga = (new BiomeTaiga(BaseBiome.TAIGA, 0)).setScaling(Scaling.PLAINS_MEDIUM); + public static final Biome swampland = (new BiomeSwamp()).setScaling(Scaling.SEA_POND); + public static final Biome river = (new BiomeWater(BaseBiome.RIVER, true)).setScaling(Scaling.SEA_SHALLOW); - public static final Biome exterminated = (new BiomeExterminated(8)).setColor(0x000000).setBiomeName("exterminated", "Ausgelöscht").setHumidity(0.0f).setTemperature(150.0f); - public static final Biome space = (new BiomeSpace(9)).setColor(0x000000).setBiomeName("space", "Leere des Weltraums").setHumidity(0.0f); + public static final Biome exterminated = (new BiomeExterminated()); + public static final Biome space = (new BiomeSpace()); - public static final Biome frozenSea = (new BiomeWater(10, false)).setColor(9474208).setBiomeName("frozenSea", "Vereister See").enableColdBeach().setScaling(Scaling.SEA_MEDIUM).setTemperature(-20.0f).setHumidity(50.0f); - public static final Biome frozenRiver = (new BiomeWater(11, true)).setColor(10526975).setBiomeName("frozenRiver", "Vereister Fluss").enableColdBeach().setScaling(Scaling.SEA_SHALLOW).setTemperature(-20.0f).setHumidity(50.0f); - public static final Biome icePlains = (new BiomeSnow(12, false)).setColor(16777215).setBiomeName("icePlains", "Eisebene").enableColdBeach().setTemperature(-20.0f).setHumidity(50.0f).setScaling(Scaling.PLAINS_LOW); - public static final Biome iceMountains = (new BiomeSnow(13, false)).setColor(10526880).setBiomeName("iceMountains", "Vereistes Bergland").enableColdBeach().setScaling(Scaling.HILLS_LOW).setTemperature(-20.0f).setHumidity(50.0f); - public static final Biome mushroomPlains = (new BiomeMushroom(14)).setColor(16711935).setBiomeName("mushroomPlains", "Pilzland").setTemperature(16.0f).setHumidity(100.0f).setScaling(Scaling.PLAINS_VARYING); - public static final Biome blackened = (new BiomeBlackened(15)).setColor(0x000000).setBiomeName("blackened", "Schwarz").setHumidity(0.0f); - public static final Biome beach = (new BiomeBeach(16)).setColor(16440917).setBiomeName("beach", "Strand").setTemperature(12.0f).setHumidity(40.0f).setScaling(Scaling.SEA_SHORE); - public static final Biome desertHills = (new BiomeDesert(17)).setColor(13786898).setBiomeName("desertHills", "Wüsten-Bergland").setTemperature(60.0f).setHumidity(0.0f).setScaling(Scaling.HILLS_LOW); - public static final Biome forestHills = (new BiomeForest(18, 0)).setColor(2250012).setBiomeName("forestHills", "Wald-Bergland").setScaling(Scaling.HILLS_LOW); - public static final Biome taigaHills = (new BiomeTaiga(19, 0)).setColor(1456435).setBiomeName("taigaHills", "Taiga-Bergland").setTemperature(-10.0f).setHumidity(80.0f).setScaling(Scaling.HILLS_LOW); - public static final Biome extremeHillsEdge = (new BiomeHills(20, true)).setColor(7501978).setBiomeName("extremeHillsEdge", "Extremes Bergland Gr.").setScaling(Scaling.HILLS_MEDIUM).setTemperature(-12.0f).setHumidity(30.0f); - public static final Biome jungle = (new BiomeJungle(21, false)).setColor(5470985).setBiomeName("jungle", "Urwald").setTemperature(18.0f).setHumidity(90.0f); - public static final Biome jungleHills = (new BiomeJungle(22, false)).setColor(2900485).setBiomeName("jungleHills", "Urwald-Bergland").setTemperature(18.0f).setHumidity(90.0f).setScaling(Scaling.HILLS_LOW); - public static final Biome jungleEdge = (new BiomeJungle(23, true)).setColor(6458135).setBiomeName("jungleEdge", "Urwald Gr.").setTemperature(18.0f).setHumidity(80.0f); - public static final Biome sea = (new BiomeWater(24, false)).setColor(112).setBiomeName("sea", "See").setScaling(Scaling.SEA_MEDIUM); - public static final Biome stoneBeach = (new BiomeStoneBeach(25)).setColor(10658436).setBiomeName("stoneBeach", "Steinstrand").setTemperature(-12.0f).setHumidity(30.0f).setScaling(Scaling.SEA_VARYING); - public static final Biome coldBeach = (new BiomeBeach(26)).setColor(16445632).setBiomeName("coldBeach", "Vereister Strand").setTemperature(-18.0f).setHumidity(30.0f).setScaling(Scaling.SEA_SHORE).enableColdBeach(); - public static final Biome birchForest = (new BiomeForest(27, 2)).setBiomeName("birchForest", "Birkenwald").setColor(3175492); - public static final Biome birchForestHills = (new BiomeForest(28, 2)).setBiomeName("birchForestHills", "Birkenwald-Bergland").setColor(2055986).setScaling(Scaling.HILLS_LOW); - public static final Biome roofedForest = (new BiomeForest(29, 3)).setColor(4215066).setBiomeName("roofedForest", "Dichter Wald"); - public static final Biome coldTaiga = (new BiomeTaiga(30, 0)).setColor(3233098).setBiomeName("coldTaiga", "Vereiste Taiga").enableColdBeach().setTemperature(-40.0f).setHumidity(40.0f).setScaling(Scaling.PLAINS_MEDIUM); - public static final Biome coldTaigaHills = (new BiomeTaiga(31, 0)).setColor(2375478).setBiomeName("coldTaigaHills", "Vereistes Taiga-Bergland").enableColdBeach().setTemperature(-40.0f).setHumidity(40.0f).setScaling(Scaling.HILLS_LOW); - public static final Biome megaTaiga = (new BiomeTaiga(32, 1)).setColor(5858897).setBiomeName("megaTaiga", "Hohe Taiga").setTemperature(-8.0f).setHumidity(80.0f).setScaling(Scaling.PLAINS_MEDIUM); - public static final Biome megaTaigaHills = (new BiomeTaiga(33, 1)).setColor(4542270).setBiomeName("megaTaigaHills", "Hohes Taiga-Bergland").setTemperature(-8.0f).setHumidity(80.0f).setScaling(Scaling.HILLS_LOW); - public static final Biome extremeHillsPlus = (new BiomeHills(34, true)).setColor(5271632).setBiomeName("extremeHillsPlus", "Extremes Bergland +").setScaling(Scaling.HILLS_LARGE).setTemperature(-12.0f).setHumidity(30.0f); - public static final Biome savanna = (new BiomeSavanna(35)).setColor(12431967).setBiomeName("savanna", "Savanne").setTemperature(28.0F).setHumidity(0.0f).setScaling(Scaling.PLAINS_LOW); - public static final Biome savannaPlateau = (new BiomeSavanna(36)).setColor(10984804).setBiomeName("savannaPlateau", "Savannen-Plateau").setTemperature(20.0F).setHumidity(0.0f).setScaling(Scaling.HILLS_PLATEAU); + public static final Biome frozenSea = (new BiomeWater(BaseBiome.FROZENSEA, false)).enableColdBeach().setScaling(Scaling.SEA_MEDIUM); + public static final Biome frozenRiver = (new BiomeWater(BaseBiome.FROZENRIVER, true)).enableColdBeach().setScaling(Scaling.SEA_SHALLOW); + public static final Biome icePlains = (new BiomeSnow(BaseBiome.ICEPLAINS, false)).enableColdBeach().setScaling(Scaling.PLAINS_LOW); + public static final Biome iceMountains = (new BiomeSnow(BaseBiome.ICEMOUNTAINS, false)).enableColdBeach().setScaling(Scaling.HILLS_LOW); + public static final Biome mushroomPlains = (new BiomeMushroom()).setScaling(Scaling.PLAINS_VARYING); + public static final Biome blackened = (new BiomeBlackened()); + public static final Biome beach = (new BiomeBeach(false)).setScaling(Scaling.SEA_SHORE); + public static final Biome desertHills = (new BiomeDesert(true)).setScaling(Scaling.HILLS_LOW); + public static final Biome forestHills = (new BiomeForest(BaseBiome.FORESTHILLS, 0)).setScaling(Scaling.HILLS_LOW); + public static final Biome taigaHills = (new BiomeTaiga(BaseBiome.TAIGAHILLS, 0)).setScaling(Scaling.HILLS_LOW); + public static final Biome extremeHillsEdge = (new BiomeHills(BaseBiome.EXTREMEHILLSEDGE, true)).setScaling(Scaling.HILLS_MEDIUM); + public static final Biome jungle = (new BiomeJungle(BaseBiome.JUNGLE, false)); + public static final Biome jungleHills = (new BiomeJungle(BaseBiome.JUNGLEHILLS, false)).setScaling(Scaling.HILLS_LOW); + public static final Biome jungleEdge = (new BiomeJungle(BaseBiome.JUNGLEEDGE, true)); + public static final Biome sea = (new BiomeWater(BaseBiome.SEA, false)).setScaling(Scaling.SEA_MEDIUM); + public static final Biome stoneBeach = (new BiomeStoneBeach()).setScaling(Scaling.SEA_VARYING); + public static final Biome coldBeach = (new BiomeBeach(true)).setScaling(Scaling.SEA_SHORE).enableColdBeach(); + public static final Biome birchForest = (new BiomeForest(BaseBiome.BIRCHFOREST, 2)); + public static final Biome birchForestHills = (new BiomeForest(BaseBiome.BIRCHFORESTHILLS, 2)).setScaling(Scaling.HILLS_LOW); + public static final Biome roofedForest = (new BiomeForest(BaseBiome.ROOFEDFOREST, 3)); + public static final Biome coldTaiga = (new BiomeTaiga(BaseBiome.COLDTAIGA, 0)).enableColdBeach().setScaling(Scaling.PLAINS_MEDIUM); + public static final Biome coldTaigaHills = (new BiomeTaiga(BaseBiome.COLDTAIGAHILLS, 0)).enableColdBeach().setScaling(Scaling.HILLS_LOW); + public static final Biome megaTaiga = (new BiomeTaiga(BaseBiome.MEGATAIGA, 1)).setScaling(Scaling.PLAINS_MEDIUM); + public static final Biome megaTaigaHills = (new BiomeTaiga(BaseBiome.MEGATAIGAHILLS, 1)).setScaling(Scaling.HILLS_LOW); + public static final Biome extremeHillsPlus = (new BiomeHills(BaseBiome.EXTREMEHILLSPLUS, true)).setScaling(Scaling.HILLS_LARGE); + public static final Biome savanna = (new BiomeSavanna(false)).setScaling(Scaling.PLAINS_LOW); + public static final Biome savannaPlateau = (new BiomeSavanna(true)).setScaling(Scaling.HILLS_PLATEAU); - public static final Biome mesa = (new BiomeMesa(37, false, false)).setColor(14238997).setBiomeName("mesa", "Mesa"); - public static final Biome mesaPlateau_F = (new BiomeMesa(38, false, true)).setColor(11573093).setBiomeName("mesaPlateauF", "Mesa-Waldplateau").setScaling(Scaling.HILLS_PLATEAU); - public static final Biome mesaPlateau = (new BiomeMesa(39, false, false)).setColor(13274213).setBiomeName("mesaPlateau", "Mesa-Plateau").setScaling(Scaling.HILLS_PLATEAU); + public static final Biome mesa = (new BiomeMesa(BaseBiome.MESA, false, false)); + public static final Biome mesaPlateau_F = (new BiomeMesa(BaseBiome.MESAPLATEAUF, false, true)).setScaling(Scaling.HILLS_PLATEAU); + public static final Biome mesaPlateau = (new BiomeMesa(BaseBiome.MESAPLATEAU, false, false)).setScaling(Scaling.HILLS_PLATEAU); - public static final Biome snowLand = (new BiomeSnowLand(40)).setColor(0xffffff).setBiomeName("snowLand", "Eisland").enableColdBeach().setHumidity(100.0f); - public static final Biome tian = (new BiomeTian(41)).setColor(0x808080).setBiomeName("tian", "Tian").setHumidity(80.0f).setScaling(Scaling.VARYING_MEDIUM); - public static final Biome elvenForest = (new BiomeForest(42, 4)).setColor(0x059821).setBiomeName("elvenForest", "Elbenwald").setHumidity(90.0f); - public static final Biome upperHell = (new BiomeHell(43, 0)).setColor(16711680).setBiomeName("upperHell", "Übergang in die Hölle").setHumidity(0.0f); - public static final Biome lowerHell = (new BiomeHell(44, 1)).setColor(16711680).setBiomeName("lowerHell", "Abgrund der Hölle").setHumidity(0.0f); - public static final Biome hellHills = (new BiomeHell(45, 1)).setColor(16711680).setBiomeName("hellHills", "Bergland der Hölle").setHumidity(0.0f).setScaling(Scaling.HILLS_LARGE); - public static final Biome soulPlains = (new BiomeHell(46, 1)).setColor(16711680).setBiomeName("soulPlains", "Seelenland").setHumidity(0.0f).setScaling(Scaling.SEA_POND); - public static final Biome ashLand = (new BiomeHell(47, 2)).setColor(16711680).setBiomeName("ashLand", "Verbrannt").setHumidity(0.0f).setScaling(Scaling.PLAINS_LOW); - public static final Biome moon = (new BiomeMoon(48)).setColor(0xa0a0a0).setBiomeName("moon", "Mondoberfläche").setHumidity(0.0f).setScaling(Scaling.PLAINS_LOW); - public static final Biome chaos = (new BiomeChaos(49)).setColor(0xff00ff).setBiomeName("chaos", "Chaos").setHumidity(50.0f).setScaling(Scaling.VARYING_CHAOTIC); + public static final Biome snowLand = (new BiomeSnowLand()).enableColdBeach(); + public static final Biome tian = (new BiomeTian()).setScaling(Scaling.VARYING_MEDIUM); + public static final Biome elvenForest = (new BiomeForest(BaseBiome.ELVENFOREST, 4)); + public static final Biome upperHell = (new BiomeHell(BaseBiome.UPPERHELL, 0)); + public static final Biome lowerHell = (new BiomeHell(BaseBiome.LOWERHELL, 1)); + public static final Biome hellHills = (new BiomeHell(BaseBiome.HELLHILLS, 1)).setScaling(Scaling.HILLS_LARGE); + public static final Biome soulPlains = (new BiomeHell(BaseBiome.SOULPLAINS, 1)).setScaling(Scaling.SEA_POND); + public static final Biome ashLand = (new BiomeHell(BaseBiome.ASHLAND, 2)).setScaling(Scaling.PLAINS_LOW); + public static final Biome moon = (new BiomeMoon()).setScaling(Scaling.PLAINS_LOW); + public static final Biome chaos = (new BiomeChaos()).setScaling(Scaling.VARYING_CHAOTIC); - public static final Biome DEF_BIOME = forest; - protected static final PerlinGen TEMP_NOISE; protected static final PerlinGen TREE_NOISE; protected static final PerlinGen GRASS_NOISE; protected static final FeatureDoublePlant DOUBLE_PLANT_GEN; - private static final Map LOOKUP = Maps.newTreeMap(); - private static final List LIST = Lists.newArrayList(); - public final int id; + public final BaseBiome base; protected final WeightedList mobs = new WeightedList(); protected final WorldGenBaseTree worldGeneratorTrees = new WorldGenBaseTree(false); @@ -142,13 +142,6 @@ public abstract class Biome { private final FeatureGenerator waterlilyGen = new WorldGenWaterlily(); private final FeatureGenerator clayGenExt = new WorldGenClayExt(32); - public String name = null; - public String display = ""; - public int color = 0x000000; - protected float temperature = 0.0f; - protected float humidity = 50.0f; - public int waterColor = 0xffffff; - public State topBlock = Blocks.grass.getState(); public State fillerBlock = Blocks.dirt.getState(); public float depth = Scaling.VARYING_LOW.depth; @@ -171,10 +164,31 @@ public abstract class Biome { protected int clayPerChunk = 1; protected int clayExtPerChunk = 0; // 10 protected int bigMushroomsPerChunk = 0; + + public static Biome getBiome(int id) + { + if (id >= 0 && id < BIOMES.length) + { + return BIOMES[id]; + } + else + { + Log.JNI.warn("Biom-ID ist nicht im Bereich: " + id + ", verwende " + BaseBiome.DEF_BIOME.id + " (" + BaseBiome.DEF_BIOME.name + ")"); + return BIOMES[BaseBiome.DEF_BIOME.id]; + } + } + + public static void setAsProvider() { + IBiome.setProvider(new IBiome.BiomeProvider() { + public final IBiome getBiome(BaseBiome base) { + return BIOMES[base.id]; + } + }); + } - protected Biome(int id) { - this.id = id; - BIOMES[id] = this; + protected Biome(BaseBiome base) { + BIOMES[base.id] = this; + this.base = base; this.addMobs(this.mobs); } @@ -196,36 +210,6 @@ public abstract class Biome { mobs.add(new RngSpawn(EntityMouse.class, 10, 8, 8)); } - public int getSkyColor() { - return 0xffffffff; - } - - public int getFogColor() { - return 0xffffffff; - } - - public int getCloudColor() { - return 0xffffffff; - } - - public float getFactor() { - float f = this.humidity * 0.01f * ((this.temperature + 14.0f) / 40.0f + 0.15f); - return f > 1.0f ? 1.0f : f; - } - - // skycolor = ((temp + 14) / 40 + 0.15) / 3 - protected Biome setTemperature(float temp) - { - this.temperature = temp; - return this; - } - - protected Biome setHumidity(float humidity) - { - this.humidity = humidity; - return this; - } - protected final Biome setScaling(Scaling scaling) { return this.setScaling(scaling.depth, scaling.scale); @@ -246,13 +230,10 @@ public abstract class Biome { public WorldGenTree genBigTreeLegacy(Random rand, BlockPos pos) { int noise = (int)((TREE_NOISE.generate((double)pos.getX() * 0.5D, (double)pos.getZ() * 0.5D) / 8D + rand.doublev() * 4D + 4D) / 3D); - return (noise > 0 && rand.chance(noise)) || (this.isHighHumidity() && rand.chance(3)) ? this.worldGeneratorBigTree : + return (noise > 0 && rand.chance(noise)) || (this.base.isHighHumidity() && rand.chance(3)) ? this.worldGeneratorBigTree : this.worldGeneratorTrees; } - - /** - * Gets a WorldGen appropriate for this biome. - */ + public FeatureGenerator getRandomWorldGenForGrass(Random rand) { return new WorldGenTallGrass(BlockTallGrass.EnumType.GRASS); @@ -263,6 +244,14 @@ public abstract class Biome { return rand.rarity(3) ? BlockFlower.EnumFlowerType.DANDELION : BlockFlower.EnumFlowerType.ROSE; } + public State getFiller() { + return this.fillerBlock; + } + + public State getTop() { + return this.topBlock; + } + protected Biome enableColdBeach() { this.allowColdBeach = true; @@ -275,48 +264,17 @@ public abstract class Biome { return this; } - protected Biome setBiomeName(String name, String display) - { - this.name = name; - this.display = display; - return this; - } - - protected Biome setColor(int colorIn) - { - this.color = colorIn; - return this; - } - public WeightedList getMobs() { return this.mobs; } - public boolean isHighHumidity() - { - return this.humidity > 85.0f; - } - public float getMobGenChance() { return 0.1F; } - public final float getTemperature(BlockPos pos) - { - if (pos.getY() > 64) - { - float f = (float)(TEMP_NOISE.generate((double)pos.getX() * 1.0D / 8.0D, (double)pos.getZ() * 1.0D / 8.0D) * 4.0D); - return this.temperature - (f + (float)pos.getY() - 64.0F) / 15.0f; - } - else - { - return this.temperature; - } - } - - public void decorate(AWorldServer world, Random rand, BlockPos pos) + public void decorate(WorldServer world, Random rand, BlockPos pos) { for (int i = 0; i < this.sandPerChunk2; ++i) { @@ -550,22 +508,8 @@ public abstract class Biome { } } } - - public int getGrassColorAtPos(BlockPos pos) - { - double d0 = (double)ExtMath.clampf((this.getTemperature(pos) + 14.0f) / 40.0f + 0.15f, 0.0F, 1.0F); - double d1 = (double)ExtMath.clampf(this.humidity * 0.01f, 0.0F, 1.0F); - return Colorizer.getGrassColor(d0, d1); - } - - public int getFoliageColorAtPos(BlockPos pos) - { - double d0 = (double)ExtMath.clampf((this.getTemperature(pos) + 14.0f) / 40.0f + 0.15f, 0.0F, 1.0F); - double d1 = (double)ExtMath.clampf(this.humidity * 0.01f, 0.0F, 1.0F); - return Colorizer.getFoliageColor(d0, d1); - } - public void genTerrainBlocks(AWorldServer worldIn, Random rand, ChunkPrimer chunkPrimerIn, int x, int z, double noiseVal) + public void genTerrainBlocks(WorldServer worldIn, Random rand, ChunkPrimer chunkPrimerIn, int x, int z, double noiseVal) { this.generateBiomeTerrain(worldIn, rand, chunkPrimerIn, x, z, noiseVal); } @@ -580,7 +524,7 @@ public abstract class Biome { * * If this.fillerBlock is red sand, we replace some of that with red sandstone. */ - public final void generateBiomeTerrain(AWorldServer worldIn, Random rand, ChunkPrimer chunkPrimerIn, int x, int z, double noiseVal) + public final void generateBiomeTerrain(WorldServer worldIn, Random rand, ChunkPrimer chunkPrimerIn, int x, int z, double noiseVal) { int i = worldIn.getSeaLevel(); State worldState = worldIn.dimension.getFiller(); @@ -621,7 +565,7 @@ public abstract class Biome { if (j1 < i && (iblockstate == null || iblockstate.getBlock().getMaterial() == Material.air)) { - if (freeze && World.ABSOLUTE_ZERO + worldIn.getTempOffset() + this.getTemperature(blockpos$mutableblockpos.set(x, j1, z)) <= 0.0F) + if (freeze && World.ABSOLUTE_ZERO + worldIn.getTempOffset() + this.base.getTemperature(blockpos$mutableblockpos.set(x, j1, z)) <= 0.0F) { iblockstate = Blocks.ice.getState(); } @@ -663,14 +607,231 @@ public abstract class Biome { } } - protected Biome createMutation() + public boolean generateBigMushroom(AWorldServer worldIn, BlockPos pos, State state, Random rand) { - return this.createMutatedBiome(this.id + 128); + worldIn.setBlockToAir(pos); + FeatureGenerator worldgenerator = null; + + if (state.getBlock() == Blocks.brown_mushroom) + { + worldgenerator = new WorldGenBigMushroom(Blocks.brown_mushroom_block); + } + else if (state.getBlock() == Blocks.red_mushroom) + { + worldgenerator = new WorldGenBigMushroom(Blocks.red_mushroom_block); + } + + if (worldgenerator != null && worldgenerator.generate((WorldServer)worldIn, rand, pos)) + { + return true; + } + else + { + worldIn.setState(pos, state, 3); + return false; + } } - protected Biome createMutatedBiome(int p_180277_1_) + private boolean isTypeAt(World worldIn, BlockPos pos, WoodType type) { - return new BiomeMutated(p_180277_1_, this); + State iblockstate = worldIn.getState(pos); + return iblockstate.getBlock() instanceof BlockSapling && ((BlockSapling)iblockstate.getBlock()).getWoodType() == type; + } + + private boolean isSameSaplingTypeIn(World worldIn, BlockPos pos, int xOff, int yOff, WoodType type) + { + return this.isTypeAt(worldIn, pos.add(xOff, 0, yOff), type) && this.isTypeAt(worldIn, pos.add(xOff + 1, 0, yOff), type) && this.isTypeAt(worldIn, pos.add(xOff, 0, yOff + 1), type) && this.isTypeAt(worldIn, pos.add(xOff + 1, 0, yOff + 1), type); + } + + public void generateTree(AWorldServer worldIn, BlockPos pos, State state, Random rand) + { + WoodType type = state.getBlock() instanceof BlockSapling ? ((BlockSapling)state.getBlock()).getWoodType() : WoodType.OAK; + State log = type == WoodType.CHERRY ? Blocks.cherry_log.getState() : // .withProperty(BlockNewLog.VARIANT, BlockPlanks.EnumType.CHERRY) : + (type == WoodType.MAPLE ? Blocks.maple_log.getState() /* .withProperty(BlockNewLog.VARIANT, BlockPlanks.EnumType.MAPLE) */ : Blocks.oak_log.getState()); + State leaves = type == WoodType.CHERRY ? Blocks.cherry_leaves.getState() : + (type == WoodType.MAPLE ? Blocks.maple_leaves.getState() : Blocks.oak_leaves.getState()); + FeatureGenerator worldgenerator = (FeatureGenerator)(rand.chance(10) ? new WorldGenBigTree(true, log, leaves) : new WorldGenBaseTree(true, log, leaves)); + int i = 0; + int j = 0; + boolean flag = false; +// leaves = leaves.withProperty(BlockLeaves.TYPE, worldIn.getLeavesGen()); + + switch (type) + { + case SPRUCE: + label114: + for (i = 0; i >= -1; --i) + { + for (j = 0; j >= -1; --j) + { + if (this.isSameSaplingTypeIn(worldIn, pos, i, j, WoodType.SPRUCE)) + { + worldgenerator = new WorldGenPine(false, rand.chance()); + flag = true; + break label114; + } + } + } + + if (!flag) + { + j = 0; + i = 0; + worldgenerator = new WorldGenTaiga2(true); + } + + break; + + case BIRCH: + worldgenerator = new WorldGenBirch(true, false); + break; + + case TIAN: + worldgenerator = new WorldGenBigTree(true, Blocks.tian_log.getState(), Blocks.tian_leaves.getState()) + .setHeightLimit(6, 20); + break; + + case JUNGLE: + State iblockstate = Blocks.jungle_log.getState(); // .withProperty(BlockOldLog.VARIANT, BlockPlanks.EnumType.JUNGLE); + State iblockstate1 = Blocks.jungle_leaves.getState(); // .withProperty(BlockOldLeaf.VARIANT, BlockPlanks.EnumType.JUNGLE); // .withProperty(BlockLeaves.CHECK_DECAY, Boolean.valueOf(false)); + label269: + + for (i = 0; i >= -1; --i) + { + for (j = 0; j >= -1; --j) + { + if (this.isSameSaplingTypeIn(worldIn, pos, i, j, WoodType.JUNGLE)) + { + worldgenerator = new WorldGenJungle(true, 10, 20, iblockstate, iblockstate1); + flag = true; + break label269; + } + } + } + + if (!flag) + { + j = 0; + i = 0; + worldgenerator = new WorldGenBaseTree(true, rand.range(4, 10), iblockstate, iblockstate1, false); + } + + break; + + case ACACIA: + worldgenerator = new WorldGenSavanna(true); + break; + + case DARK_OAK: + label390: + for (i = 0; i >= -1; --i) + { + for (j = 0; j >= -1; --j) + { + if (this.isSameSaplingTypeIn(worldIn, pos, i, j, WoodType.DARK_OAK)) + { + worldgenerator = new WorldGenDarkOak(true); + flag = true; + break label390; + } + } + } + + if (!flag) + { + return; + } + + case OAK: + case CHERRY: + case MAPLE: + } + + State iblockstate2 = Blocks.air.getState(); + + if (flag) + { + worldIn.setState(pos.add(i, 0, j), iblockstate2, 4); + worldIn.setState(pos.add(i + 1, 0, j), iblockstate2, 4); + worldIn.setState(pos.add(i, 0, j + 1), iblockstate2, 4); + worldIn.setState(pos.add(i + 1, 0, j + 1), iblockstate2, 4); + } + else + { + worldIn.setState(pos, iblockstate2, 4); + } + + if (!worldgenerator.generate((WorldServer)worldIn, rand, pos.add(i, 0, j))) + { + if (flag) + { + worldIn.setState(pos.add(i, 0, j), state, 4); + worldIn.setState(pos.add(i + 1, 0, j), state, 4); + worldIn.setState(pos.add(i, 0, j + 1), state, 4); + worldIn.setState(pos.add(i + 1, 0, j + 1), state, 4); + } + else + { + worldIn.setState(pos, state, 4); + } + } + } + + public void growGrass(AWorldServer worldIn, BlockPos pos, State state, Random rand) + { + BlockPos blockpos = pos.up(); + + for (int i = 0; i < 128; ++i) + { + BlockPos blockpos1 = blockpos; + int j = 0; + + while (true) + { + if (j >= i / 16) + { + if (worldIn.getState(blockpos1).getBlock().getMaterial() == Material.air) + { + if (rand.chance(8)) + { + BlockFlower.EnumFlowerType blockflower$enumflowertype = BIOMES[worldIn.getBiomeGenForCoords(blockpos1).id].pickRandomFlower(rand, blockpos1); + BlockFlower blockflower = blockflower$enumflowertype.getBlockType().getBlock(); + State iblockstate = blockflower.getState().withProperty(blockflower.getTypeProperty(), blockflower$enumflowertype); + + if (blockflower.canBlockStay(worldIn, blockpos1, iblockstate)) + { + worldIn.setState(blockpos1, iblockstate, 3); + } + } + else + { + State iblockstate1 = Blocks.tallgrass.getState().withProperty(BlockTallGrass.TYPE, BlockTallGrass.EnumType.GRASS); + + if (Blocks.tallgrass.canBlockStay(worldIn, blockpos1, iblockstate1)) + { + worldIn.setState(blockpos1, iblockstate1, 3); + } + } + } + + break; + } + + blockpos1 = blockpos1.add(rand.zrange(3) - 1, (rand.zrange(3) - 1) * rand.zrange(3) / 2, rand.zrange(3) - 1); + + if (worldIn.getState(blockpos1.down()).getBlock() != Blocks.grass || worldIn.getState(blockpos1).getBlock().isNormalCube()) + { + break; + } + + ++j; + } + } + } + + protected Biome createMutatedBiome(BaseBiome base) + { + return new BiomeMutated(base, this); } public Class getBiomeClass() @@ -685,88 +846,34 @@ public abstract class Biome { public Temperature getTempCategory() { - return this.temperature < -12.0f ? Temperature.COLD : (this.temperature < 20.0f ? Temperature.MEDIUM : Temperature.WARM); + return this.base.temperature < -12.0f ? Temperature.COLD : (this.base.temperature < 20.0f ? Temperature.MEDIUM : Temperature.WARM); } - - public static Biome getBiome(int id) - { - return getBiome(id, null); - } - - public static Biome getBiome(int id, Biome def) - { - if (id >= 0 && id < BIOMES.length) - { - Biome biome = BIOMES[id]; - return biome == null ? def : biome; - } - else - { - Log.JNI.warn("Biom-ID ist nicht im Bereich: " + id + ", verwende " + DEF_BIOME.id + " (" + DEF_BIOME.name + ")"); - return DEF_BIOME; - } - } - - public static List getBiomes() { - return LIST; - } - - public static List getBiomeNames() { - return Lists.newArrayList(LOOKUP.keySet()); - } - - public static Biome findByName(String name) { - Biome biome = LOOKUP.get(name.toLowerCase().replace(" ", "").replace("_", "")); - if(biome == null) { - int z; - try { - z = Integer.parseInt(name); - } - catch(NumberFormatException e) { - return null; - } - return z < 0 || z >= BIOMES.length ? null : BIOMES[z]; - } - return biome; - } static { -// plains.createMutation(); - desert.createMutation(); - forest.createMutation(); - taiga.createMutation(); - swampland.createMutation(); - icePlains.createMutation(); - jungle.createMutation(); - jungleEdge.createMutation(); - coldTaiga.createMutation(); - savanna.createMutation(); - savannaPlateau.createMutation(); - mesa.createMutation(); - mesaPlateau_F.createMutation(); - mesaPlateau.createMutation(); - birchForest.createMutation(); - birchForestHills.createMutation(); - roofedForest.createMutation(); - megaTaiga.createMutation(); - extremeHills.createMutation(); - extremeHillsPlus.createMutation(); - megaTaiga.createMutatedBiome(megaTaigaHills.id + 128).setBiomeName("redwoodTaigaHillsM", "Mammutbaumtaiga"); + desert.createMutatedBiome(BaseBiome.DESERTM); + forest.createMutatedBiome(BaseBiome.FLOWERFOREST); + taiga.createMutatedBiome(BaseBiome.TAIGAM); + swampland.createMutatedBiome(BaseBiome.SWAMPLANDM); + icePlains.createMutatedBiome(BaseBiome.ICEPLAINSSPIKES); + jungle.createMutatedBiome(BaseBiome.JUNGLEM); + jungleEdge.createMutatedBiome(BaseBiome.JUNGLEEDGEM); + coldTaiga.createMutatedBiome(BaseBiome.COLDTAIGAM); + savanna.createMutatedBiome(BaseBiome.SAVANNAM); + savannaPlateau.createMutatedBiome(BaseBiome.SAVANNAPLATEAUM); + mesa.createMutatedBiome(BaseBiome.MESABRYCE); + mesaPlateau_F.createMutatedBiome(BaseBiome.MESAPLATEAUFM); + mesaPlateau.createMutatedBiome(BaseBiome.MESAPLATEAUM); + birchForest.createMutatedBiome(BaseBiome.BIRCHFORESTM); + birchForestHills.createMutatedBiome(BaseBiome.BIRCHFORESTHILLSM); + roofedForest.createMutatedBiome(BaseBiome.ROOFEDFORESTM); + megaTaiga.createMutatedBiome(BaseBiome.MEGASPRUCETAIGA); + extremeHills.createMutatedBiome(BaseBiome.EXTREMEHILLSM); + extremeHillsPlus.createMutatedBiome(BaseBiome.EXTREMEHILLSPLUSM); + megaTaiga.createMutatedBiome(BaseBiome.REDWOODTAIGAHILLSM); - TEMP_NOISE = new PerlinGen(new Random(1234L), 1); TREE_NOISE = new PerlinGen(new Random(667L), 8); GRASS_NOISE = new PerlinGen(new Random(2345L), 1); DOUBLE_PLANT_GEN = new FeatureDoublePlant(); - - for(Biome biome : BIOMES) { - if(biome == null) - continue; - if(LOOKUP.containsKey(biome.name.toLowerCase())) - throw new IllegalStateException("Biom \"" + biome.name + "\" ist als ID " + LOOKUP.get(biome.name.toLowerCase()).id + " und " + biome.id + " definiert"); - LOOKUP.put(biome.name.toLowerCase(), biome); - LIST.add(biome); - System.out.printf("%s(%d, \"%s\", \"%s\", 0x%06x, %.1ff, %.1ff),\n", biome.name.toUpperCase(), biome.id, biome.name, biome.display, biome.color, biome.temperature, biome.humidity); - } } } diff --git a/common/src/common/biome/BiomeBeach.java b/server/src/server/biome/BiomeBeach.java similarity index 73% rename from common/src/common/biome/BiomeBeach.java rename to server/src/server/biome/BiomeBeach.java index f73c715..e6fac04 100755 --- a/common/src/common/biome/BiomeBeach.java +++ b/server/src/server/biome/BiomeBeach.java @@ -1,13 +1,14 @@ -package common.biome; +package server.biome; +import common.biome.BaseBiome; import common.init.Blocks; import common.rng.WeightedList; public class BiomeBeach extends Biome { - public BiomeBeach(int id) + public BiomeBeach(boolean cold) { - super(id); + super(cold ? BaseBiome.COLDBEACH : BaseBiome.BEACH); this.topBlock = Blocks.sand.getState(); this.fillerBlock = Blocks.sand.getState(); this.treesPerChunk = -999; diff --git a/common/src/common/biome/BiomeBlackened.java b/server/src/server/biome/BiomeBlackened.java similarity index 81% rename from common/src/common/biome/BiomeBlackened.java rename to server/src/server/biome/BiomeBlackened.java index ffe2256..c917b39 100644 --- a/common/src/common/biome/BiomeBlackened.java +++ b/server/src/server/biome/BiomeBlackened.java @@ -1,19 +1,20 @@ -package common.biome; +package server.biome; +import common.biome.BaseBiome; import common.block.BlockFlower; import common.entity.npc.EntityMetalhead; import common.init.Blocks; import common.rng.Random; import common.rng.WeightedList; import common.util.BlockPos; -import common.worldgen.tree.WorldGenBaseTree; -import common.worldgen.tree.WorldGenTree; +import server.worldgen.tree.WorldGenBaseTree; +import server.worldgen.tree.WorldGenTree; public class BiomeBlackened extends Biome { protected final WorldGenTree treeGen = new WorldGenBaseTree(false, Blocks.blackwood_log.getState(), Blocks.blackwood_leaves.getState()); - public BiomeBlackened(int id) { - super(id); + public BiomeBlackened() { + super(BaseBiome.BLACKENED); this.topBlock = Blocks.blackened_soil.getState(); this.fillerBlock = Blocks.blackened_dirt.getState(); this.treesPerChunk = 3; diff --git a/common/src/common/biome/BiomeChaos.java b/server/src/server/biome/BiomeChaos.java similarity index 78% rename from common/src/common/biome/BiomeChaos.java rename to server/src/server/biome/BiomeChaos.java index 79ee8c1..7613c41 100755 --- a/common/src/common/biome/BiomeChaos.java +++ b/server/src/server/biome/BiomeChaos.java @@ -1,5 +1,6 @@ -package common.biome; +package server.biome; +import common.biome.BaseBiome; import common.entity.Entity; import common.entity.types.EntityLiving; import common.init.Blocks; @@ -7,17 +8,17 @@ import common.init.EntityRegistry; import common.rng.Random; import common.rng.WeightedList; import common.util.BlockPos; -import common.world.AWorldServer; -import common.worldgen.FeatureGenerator; -import common.worldgen.foliage.WorldGenMushroom; +import server.world.WorldServer; +import server.worldgen.FeatureGenerator; +import server.worldgen.foliage.WorldGenMushroom; public class BiomeChaos extends Biome { protected FeatureGenerator mushroomBlueGen = new WorldGenMushroom(Blocks.blue_mushroom); - public BiomeChaos(int id) + public BiomeChaos() { - super(id); + super(BaseBiome.CHAOS); this.topBlock = Blocks.obsidian.getState(); this.fillerBlock = Blocks.obsidian.getState(); } @@ -29,7 +30,7 @@ public class BiomeChaos extends Biome } } - public void decorate(AWorldServer worldIn, Random rand, BlockPos pos) + public void decorate(WorldServer worldIn, Random rand, BlockPos pos) { super.decorate(worldIn, rand, pos); diff --git a/common/src/common/biome/BiomeDesert.java b/server/src/server/biome/BiomeDesert.java similarity index 72% rename from common/src/common/biome/BiomeDesert.java rename to server/src/server/biome/BiomeDesert.java index b95ad41..e6b445d 100755 --- a/common/src/common/biome/BiomeDesert.java +++ b/server/src/server/biome/BiomeDesert.java @@ -1,17 +1,18 @@ -package common.biome; +package server.biome; +import common.biome.BaseBiome; import common.init.Blocks; import common.rng.Random; import common.rng.WeightedList; import common.util.BlockPos; -import common.world.AWorldServer; -import common.worldgen.feature.WorldGenDesertWells; +import server.world.WorldServer; +import server.worldgen.feature.WorldGenDesertWells; public class BiomeDesert extends Biome { - public BiomeDesert(int id) + public BiomeDesert(boolean hills) { - super(id); + super(hills ? BaseBiome.DESERTHILLS : BaseBiome.DESERT); this.topBlock = Blocks.sand.getState(); this.fillerBlock = Blocks.sand.getState(); this.treesPerChunk = -999; @@ -24,7 +25,7 @@ public class BiomeDesert extends Biome protected void addMobs(WeightedList mobs) { } - public void decorate(AWorldServer worldIn, Random rand, BlockPos pos) + public void decorate(WorldServer worldIn, Random rand, BlockPos pos) { super.decorate(worldIn, rand, pos); diff --git a/server/src/server/biome/BiomeExterminated.java b/server/src/server/biome/BiomeExterminated.java new file mode 100755 index 0000000..cf386f8 --- /dev/null +++ b/server/src/server/biome/BiomeExterminated.java @@ -0,0 +1,22 @@ +package server.biome; + +import common.biome.BaseBiome; +import common.init.Blocks; +import common.rng.Random; +import common.rng.WeightedList; +import common.util.BlockPos; +import server.world.WorldServer; + +public class BiomeExterminated extends Biome { + public BiomeExterminated() { + super(BaseBiome.EXTERMINATED); + this.topBlock = Blocks.air.getState(); + this.fillerBlock = Blocks.air.getState(); + } + + protected void addMobs(WeightedList mobs) { + } + + public void decorate(WorldServer worldIn, Random rand, BlockPos pos) { + } +} diff --git a/common/src/common/biome/BiomeForest.java b/server/src/server/biome/BiomeForest.java similarity index 83% rename from common/src/common/biome/BiomeForest.java rename to server/src/server/biome/BiomeForest.java index b699026..e77f451 100755 --- a/common/src/common/biome/BiomeForest.java +++ b/server/src/server/biome/BiomeForest.java @@ -1,8 +1,8 @@ -package common.biome; +package server.biome; +import common.biome.BaseBiome; import common.block.BlockDoublePlant; import common.block.BlockFlower; -import common.color.Colorizer; import common.entity.animal.EntityWolf; import common.entity.npc.EntityElf; import common.entity.npc.EntityWoodElf; @@ -10,13 +10,13 @@ import common.init.Blocks; import common.rng.Random; import common.util.BlockPos; import common.util.ExtMath; -import common.world.AWorldServer; -import common.worldgen.foliage.WorldGenBigMushroom; -import common.worldgen.tree.WorldGenBaseTree; -import common.worldgen.tree.WorldGenBigTree; -import common.worldgen.tree.WorldGenBirch; -import common.worldgen.tree.WorldGenDarkOak; -import common.worldgen.tree.WorldGenTree; +import server.world.WorldServer; +import server.worldgen.foliage.WorldGenBigMushroom; +import server.worldgen.tree.WorldGenBaseTree; +import server.worldgen.tree.WorldGenBigTree; +import server.worldgen.tree.WorldGenBirch; +import server.worldgen.tree.WorldGenDarkOak; +import server.worldgen.tree.WorldGenTree; public class BiomeForest extends Biome { @@ -42,9 +42,9 @@ public class BiomeForest extends Biome protected WorldGenBigTree mapleBig = new WorldGenBigTree(false, Blocks.maple_log.getState(), // .withProperty(BlockNewLog.VARIANT, BlockPlanks.EnumType.MAPLE), Blocks.maple_leaves.getState()); // .withProperty(BlockLeaves.TYPE, worldIn.getLeavesGen())); - public BiomeForest(int id, int type) + public BiomeForest(BaseBiome base, int type) { - super(id); + super(base); this.subType = type; this.treesPerChunk = 10; this.grassPerChunk = 2; @@ -65,14 +65,6 @@ public class BiomeForest extends Biome this.waterlilyPerChunk = 4; } - this.setTemperature(8.0f).setHumidity(80.0f); - - if (this.subType == 2) - { - this.setColor(3175492); - this.setTemperature(4.0f).setHumidity(60.0f); - } - if (this.subType == 0) { this.mobs.add(new RngSpawn(EntityWolf.class, 5, 4, 4)); @@ -120,7 +112,7 @@ public class BiomeForest extends Biome } } - public void decorate(AWorldServer worldIn, Random rand, BlockPos pos) + public void decorate(WorldServer worldIn, Random rand, BlockPos pos) { // if(worldIn.getLeavesGen() != this.leavesType) { // this.leavesType = worldIn.getLeavesGen(); @@ -203,37 +195,23 @@ public class BiomeForest extends Biome super.decorate(worldIn, rand, pos); } - public int getGrassColorAtPos(BlockPos pos) + protected Biome createMutatedBiome(BaseBiome base) { - return this.subType == 4 ? Colorizer.getGrassColor(1.0f, this.humidity * 0.01f) : - (this.subType == 3 ? (super.getGrassColorAtPos(pos) & 16711422) + 2634762 >> 1 : - super.getGrassColorAtPos(pos)); - } - - public int getFoliageColorAtPos(BlockPos pos) - { - return this.subType == 4 ? Colorizer.getFoliageColor(1.0f, this.humidity * 0.01f) : super.getFoliageColorAtPos(pos); - } - - protected Biome createMutatedBiome(final int id) - { - if (this.id == Biome.forest.id) + if (this.base == BaseBiome.FOREST) { - BiomeForest biomegenforest = new BiomeForest(id, 1); + BiomeForest biomegenforest = new BiomeForest(base, 1); biomegenforest.setScaling(this.depth, this.scale + 0.2F); - biomegenforest.setBiomeName("flowerForest", "Blumenwald"); - biomegenforest.setColor(6976549); return biomegenforest; } else { - return this.id != Biome.birchForest.id && this.id != Biome.birchForestHills.id ? new BiomeMutated(id, this) + return this.base != BaseBiome.BIRCHFOREST && this.base != BaseBiome.BIRCHFORESTHILLS ? new BiomeMutated(base, this) { - public void decorate(AWorldServer worldIn, Random rand, BlockPos pos) + public void decorate(WorldServer worldIn, Random rand, BlockPos pos) { this.baseBiome.decorate(worldIn, rand, pos); } - }: new BiomeMutated(id, this) + }: new BiomeMutated(base, this) { public WorldGenTree genBigTreeChance(Random rand) { diff --git a/common/src/common/biome/BiomeHell.java b/server/src/server/biome/BiomeHell.java similarity index 88% rename from common/src/common/biome/BiomeHell.java rename to server/src/server/biome/BiomeHell.java index 1e4b4dc..39fc07e 100755 --- a/common/src/common/biome/BiomeHell.java +++ b/server/src/server/biome/BiomeHell.java @@ -1,5 +1,6 @@ -package common.biome; +package server.biome; +import common.biome.BaseBiome; import common.entity.npc.EntityBloodElf; import common.entity.npc.EntityCultivator; import common.entity.npc.EntityFireDemon; @@ -10,12 +11,12 @@ import common.init.Blocks; import common.rng.Random; import common.rng.WeightedList; import common.util.BlockPos; -import common.world.AWorldServer; -import common.worldgen.FeatureOres; -import common.worldgen.feature.WorldGenFire; -import common.worldgen.feature.WorldGenGlowStone; -import common.worldgen.feature.WorldGenHellLava; -import common.worldgen.foliage.WorldGenMushroom; +import server.world.WorldServer; +import server.worldgen.FeatureOres; +import server.worldgen.feature.WorldGenFire; +import server.worldgen.feature.WorldGenGlowStone; +import server.worldgen.feature.WorldGenHellLava; +import server.worldgen.foliage.WorldGenMushroom; public class BiomeHell extends Biome { @@ -29,9 +30,9 @@ public class BiomeHell extends Biome private final WorldGenMushroom brownMushroomGen; private final WorldGenMushroom redMushroomGen; - public BiomeHell(int id, int subtype) + public BiomeHell(BaseBiome base, int subtype) { - super(id); + super(base); this.subtype = subtype; if(this.subtype == 0) { this.mobs.add(new RngSpawn(EntityBloodElf.class, 10, 1, 2)); @@ -73,7 +74,7 @@ public class BiomeHell extends Biome mobs.add(new RngSpawn(EntityMagma.class, 1, 4, 4)); } - public void decorate(AWorldServer worldIn, Random rand, BlockPos pos) + public void decorate(WorldServer worldIn, Random rand, BlockPos pos) { if(this.subtype == 0) { for (int i = 0; i < 8; ++i) @@ -125,14 +126,4 @@ public class BiomeHell extends Biome // { // return this.subtype == 0 ? new DecoratorHell() : super.createBiomeDecorator(); // } - - public int getGrassColorAtPos(BlockPos pos) - { - return 0; - } - - public int getFoliageColorAtPos(BlockPos pos) - { - return 0; - } } diff --git a/common/src/common/biome/BiomeHills.java b/server/src/server/biome/BiomeHills.java similarity index 76% rename from common/src/common/biome/BiomeHills.java rename to server/src/server/biome/BiomeHills.java index 7ea7137..dacd5c1 100755 --- a/common/src/common/biome/BiomeHills.java +++ b/server/src/server/biome/BiomeHills.java @@ -1,13 +1,14 @@ -package common.biome; +package server.biome; +import common.biome.BaseBiome; import common.init.Blocks; import common.rng.Random; import common.util.BlockPos; -import common.world.AWorldServer; -import common.worldgen.ChunkPrimer; -import common.worldgen.FeatureOres; -import common.worldgen.tree.WorldGenTaiga2; -import common.worldgen.tree.WorldGenTree; +import server.world.WorldServer; +import server.worldgen.ChunkPrimer; +import server.worldgen.FeatureOres; +import server.worldgen.tree.WorldGenTaiga2; +import server.worldgen.tree.WorldGenTree; public class BiomeHills extends Biome { @@ -19,12 +20,12 @@ public class BiomeHills extends Biome private int field_150637_aG = 2; private int field_150638_aH; - protected BiomeHills(int id, boolean p_i45373_2_) + protected BiomeHills(BaseBiome base, boolean large) { - super(id); + super(base); this.field_150638_aH = this.field_150635_aE; - if (p_i45373_2_) + if (large) { this.treesPerChunk = 3; this.field_150638_aH = this.field_150636_aF; @@ -36,7 +37,7 @@ public class BiomeHills extends Biome return (WorldGenTree)(rand.rarity(3) ? this.field_150634_aD : super.genBigTreeChance(rand)); } - public void decorate(AWorldServer worldIn, Random rand, BlockPos pos) + public void decorate(WorldServer worldIn, Random rand, BlockPos pos) { super.decorate(worldIn, rand, pos); // int i = 3 + rand.nextInt(6); @@ -64,7 +65,7 @@ public class BiomeHills extends Biome // } } - public void genTerrainBlocks(AWorldServer worldIn, Random rand, ChunkPrimer chunkPrimerIn, int x, int z, double noiseVal) + public void genTerrainBlocks(WorldServer worldIn, Random rand, ChunkPrimer chunkPrimerIn, int x, int z, double noiseVal) { this.topBlock = Blocks.grass.getState(); this.fillerBlock = Blocks.dirt.getState(); @@ -89,16 +90,12 @@ public class BiomeHills extends Biome private BiomeHills mutateHills(Biome p_150633_1_) { this.field_150638_aH = this.field_150637_aG; - this.setColor(p_150633_1_.color); - this.setBiomeName(p_150633_1_.name + "M", p_150633_1_.display + " M"); this.setScaling(p_150633_1_.depth, p_150633_1_.scale); - this.setTemperature(p_150633_1_.temperature); - this.setHumidity(p_150633_1_.humidity); return this; } - protected Biome createMutatedBiome(int p_180277_1_) + protected Biome createMutatedBiome(BaseBiome base) { - return (new BiomeHills(p_180277_1_, false)).mutateHills(this); + return (new BiomeHills(base, false)).mutateHills(this); } } diff --git a/common/src/common/biome/BiomeJungle.java b/server/src/server/biome/BiomeJungle.java similarity index 80% rename from common/src/common/biome/BiomeJungle.java rename to server/src/server/biome/BiomeJungle.java index 71737c7..84517f2 100755 --- a/common/src/common/biome/BiomeJungle.java +++ b/server/src/server/biome/BiomeJungle.java @@ -1,5 +1,6 @@ -package common.biome; +package server.biome; +import common.biome.BaseBiome; import common.block.BlockTallGrass; import common.entity.animal.EntityChicken; import common.entity.animal.EntityOcelot; @@ -7,15 +8,15 @@ import common.init.Blocks; import common.rng.Random; import common.util.BlockPos; import common.world.State; -import common.world.AWorldServer; -import common.worldgen.FeatureGenerator; -import common.worldgen.foliage.WorldGenMelon; -import common.worldgen.foliage.WorldGenShrub; -import common.worldgen.foliage.WorldGenTallGrass; -import common.worldgen.foliage.WorldGenVines; -import common.worldgen.tree.WorldGenBaseTree; -import common.worldgen.tree.WorldGenJungle; -import common.worldgen.tree.WorldGenTree; +import server.world.WorldServer; +import server.worldgen.FeatureGenerator; +import server.worldgen.foliage.WorldGenMelon; +import server.worldgen.foliage.WorldGenShrub; +import server.worldgen.foliage.WorldGenTallGrass; +import server.worldgen.foliage.WorldGenVines; +import server.worldgen.tree.WorldGenBaseTree; +import server.worldgen.tree.WorldGenJungle; +import server.worldgen.tree.WorldGenTree; public class BiomeJungle extends Biome { @@ -25,9 +26,9 @@ public class BiomeJungle extends Biome private final boolean edge; - public BiomeJungle(int id, boolean edge) + public BiomeJungle(BaseBiome base, boolean edge) { - super(id); + super(base); this.edge = edge; if (edge) @@ -63,7 +64,7 @@ public class BiomeJungle extends Biome return rand.chance(4) ? new WorldGenTallGrass(BlockTallGrass.EnumType.FERN) : new WorldGenTallGrass(BlockTallGrass.EnumType.GRASS); } - public void decorate(AWorldServer worldIn, Random rand, BlockPos pos) + public void decorate(WorldServer worldIn, Random rand, BlockPos pos) { super.decorate(worldIn, rand, pos); int i = rand.chOffset(); diff --git a/common/src/common/biome/BiomeMesa.java b/server/src/server/biome/BiomeMesa.java similarity index 91% rename from common/src/common/biome/BiomeMesa.java rename to server/src/server/biome/BiomeMesa.java index eb9fd70..90dca55 100755 --- a/common/src/common/biome/BiomeMesa.java +++ b/server/src/server/biome/BiomeMesa.java @@ -1,7 +1,8 @@ -package common.biome; +package server.biome; import java.util.Arrays; +import common.biome.BaseBiome; import common.block.Block; import common.block.BlockColored; import common.block.BlockDirt; @@ -14,9 +15,9 @@ import common.rng.Random; import common.rng.WeightedList; import common.util.BlockPos; import common.world.State; -import common.world.AWorldServer; -import common.worldgen.ChunkPrimer; -import common.worldgen.tree.WorldGenTree; +import server.world.WorldServer; +import server.worldgen.ChunkPrimer; +import server.worldgen.tree.WorldGenTree; public class BiomeMesa extends Biome { @@ -29,14 +30,13 @@ public class BiomeMesa extends Biome private PerlinGen highBryceGen; private PerlinGen clayColorGen; - public BiomeMesa(int id, boolean bryce, boolean soil) + public BiomeMesa(BaseBiome base, boolean bryce, boolean soil) { - super(id); + super(base); this.bryce = bryce; this.soil = soil; // this.setDisableRain(); // this.setTemperatureLegacy(2.0F).setHumidity(0.0F); - this.setHumidity(0.0f); // this.mobs.clear(); this.topBlock = Blocks.sand.getState().withProperty(BlockSand.VARIANT, BlockSand.EnumType.RED_SAND); this.fillerBlock = Blocks.stained_hardened_clay.getState(); @@ -61,22 +61,12 @@ public class BiomeMesa extends Biome return this.worldGeneratorTrees; } - public int getFoliageColorAtPos(BlockPos pos) - { - return 10387789; - } - - public int getGrassColorAtPos(BlockPos pos) - { - return 9470285; - } - - public void decorate(AWorldServer worldIn, Random rand, BlockPos pos) + public void decorate(WorldServer worldIn, Random rand, BlockPos pos) { super.decorate(worldIn, rand, pos); } - public void genTerrainBlocks(AWorldServer worldIn, Random rand, ChunkPrimer chunkPrimerIn, int x, int z, double noiseVal) + public void genTerrainBlocks(WorldServer worldIn, Random rand, ChunkPrimer chunkPrimerIn, int x, int z, double noiseVal) { if (this.layers == null || this.layerSeed != worldIn.getSeed()) { @@ -327,22 +317,16 @@ public class BiomeMesa extends Biome return this.layers[(y + i + 64) % 64]; } - protected Biome createMutatedBiome(int id) + protected Biome createMutatedBiome(BaseBiome base) { - boolean bryce = this.id == Biome.mesa.id; - BiomeMesa mesa = new BiomeMesa(id, bryce, this.soil); + boolean bryce = this.base == BaseBiome.MESA; + BiomeMesa mesa = new BiomeMesa(base, bryce, this.soil); if (!bryce) { mesa.setScaling(Scaling.HILLS_LOW); - mesa.setBiomeName(this.name + "M", this.display + " M"); - } - else - { - mesa.setBiomeName(this.name + "Bryce", this.display + " (Bryce)"); } - mesa.setColor(this.color); return mesa; } } diff --git a/common/src/common/biome/BiomeMoon.java b/server/src/server/biome/BiomeMoon.java similarity index 67% rename from common/src/common/biome/BiomeMoon.java rename to server/src/server/biome/BiomeMoon.java index 49ccfb8..2263900 100755 --- a/common/src/common/biome/BiomeMoon.java +++ b/server/src/server/biome/BiomeMoon.java @@ -1,17 +1,18 @@ -package common.biome; +package server.biome; +import common.biome.BaseBiome; import common.init.Blocks; import common.rng.Random; import common.rng.WeightedList; import common.util.BlockPos; -import common.world.AWorldServer; -import common.worldgen.FeatureOres; +import server.world.WorldServer; +import server.worldgen.FeatureOres; public class BiomeMoon extends Biome { private FeatureOres cheeseGenerator = new FeatureOres(Blocks.moon_cheese.getState(), 8, 8, 12, 24, 52, false); - public BiomeMoon(int id) { - super(id); + public BiomeMoon() { + super(BaseBiome.MOON); this.topBlock = Blocks.moon_rock.getState(); this.fillerBlock = Blocks.moon_rock.getState(); } @@ -19,7 +20,7 @@ public class BiomeMoon extends Biome { protected void addMobs(WeightedList mobs) { } - public void decorate(AWorldServer worldIn, Random rand, BlockPos pos) { + public void decorate(WorldServer worldIn, Random rand, BlockPos pos) { this.cheeseGenerator.generate(worldIn, rand, pos); } } diff --git a/common/src/common/biome/BiomeMushroom.java b/server/src/server/biome/BiomeMushroom.java similarity index 81% rename from common/src/common/biome/BiomeMushroom.java rename to server/src/server/biome/BiomeMushroom.java index 5133daa..755e52b 100755 --- a/common/src/common/biome/BiomeMushroom.java +++ b/server/src/server/biome/BiomeMushroom.java @@ -1,14 +1,15 @@ -package common.biome; +package server.biome; +import common.biome.BaseBiome; import common.entity.animal.EntityMooshroom; import common.init.Blocks; import common.rng.WeightedList; public class BiomeMushroom extends Biome { - public BiomeMushroom(int id) + public BiomeMushroom() { - super(id); + super(BaseBiome.MUSHROOMPLAINS); this.treesPerChunk = -100; this.flowersPerChunk = -100; this.grassPerChunk = -100; diff --git a/common/src/common/biome/BiomeMutated.java b/server/src/server/biome/BiomeMutated.java similarity index 66% rename from common/src/common/biome/BiomeMutated.java rename to server/src/server/biome/BiomeMutated.java index 2f90e23..a422fda 100755 --- a/common/src/common/biome/BiomeMutated.java +++ b/server/src/server/biome/BiomeMutated.java @@ -1,30 +1,25 @@ -package common.biome; +package server.biome; +import common.biome.BaseBiome; import common.rng.Random; import common.rng.WeightedList; import common.util.BlockPos; -import common.world.AWorldServer; -import common.worldgen.ChunkPrimer; -import common.worldgen.tree.WorldGenTree; +import server.world.WorldServer; +import server.worldgen.ChunkPrimer; +import server.worldgen.tree.WorldGenTree; public class BiomeMutated extends Biome { protected Biome baseBiome; - public BiomeMutated(int id, Biome biome) + public BiomeMutated(BaseBiome base, Biome biome) { - super(id); + super(base); this.baseBiome = biome; - this.setColor(biome.color); - this.name = biome.name + "M"; - this.display = biome.display + " M"; this.topBlock = biome.topBlock; this.fillerBlock = biome.fillerBlock; // this.minHeight = biome.minHeight; // this.maxHeight = biome.maxHeight; - this.temperature = biome.temperature; - this.humidity = biome.humidity; - this.waterColor = biome.waterColor; this.allowColdBeach = biome.allowColdBeach; // this.enableRain = biome.enableRain; // this.mobs.clear(); @@ -43,17 +38,17 @@ public class BiomeMutated extends Biome protected void addMobs(WeightedList mobs) { } - public void decorate(AWorldServer worldIn, Random rand, BlockPos pos) + public void decorate(WorldServer worldIn, Random rand, BlockPos pos) { this.baseBiome.decorate(worldIn, rand, pos); // TODO: check } - public void decorateNormal(AWorldServer worldIn, Random rand, BlockPos pos) + public void decorateNormal(WorldServer worldIn, Random rand, BlockPos pos) { super.decorate(worldIn, rand, pos); } - public void genTerrainBlocks(AWorldServer worldIn, Random rand, ChunkPrimer chunkPrimerIn, int x, int z, double noiseVal) + public void genTerrainBlocks(WorldServer worldIn, Random rand, ChunkPrimer chunkPrimerIn, int x, int z, double noiseVal) { this.baseBiome.genTerrainBlocks(worldIn, rand, chunkPrimerIn, x, z, noiseVal); } @@ -67,17 +62,7 @@ public class BiomeMutated extends Biome { return this.baseBiome.genBigTreeChance(rand); } - - public int getFoliageColorAtPos(BlockPos pos) - { - return this.baseBiome.getFoliageColorAtPos(pos); - } - - public int getGrassColorAtPos(BlockPos pos) - { - return this.baseBiome.getGrassColorAtPos(pos); - } - + public Class getBiomeClass() { return this.baseBiome.getBiomeClass(); diff --git a/common/src/common/biome/BiomeNone.java b/server/src/server/biome/BiomeNone.java similarity index 51% rename from common/src/common/biome/BiomeNone.java rename to server/src/server/biome/BiomeNone.java index 00a5ef4..4ae060c 100755 --- a/common/src/common/biome/BiomeNone.java +++ b/server/src/server/biome/BiomeNone.java @@ -1,15 +1,16 @@ -package common.biome; +package server.biome; +import common.biome.BaseBiome; import common.init.Blocks; import common.rng.Random; import common.rng.WeightedList; import common.util.BlockPos; -import common.world.AWorldServer; -import common.worldgen.ChunkPrimer; +import server.world.WorldServer; +import server.worldgen.ChunkPrimer; public class BiomeNone extends Biome { - public BiomeNone(int id) { - super(id); + public BiomeNone() { + super(BaseBiome.NONE); this.topBlock = Blocks.air.getState(); this.fillerBlock = Blocks.air.getState(); } @@ -17,10 +18,10 @@ public class BiomeNone extends Biome { protected void addMobs(WeightedList mobs) { } - public void genTerrainBlocks(AWorldServer worldIn, Random rand, ChunkPrimer chunkPrimerIn, int x, int z, double noiseVal) { + public void genTerrainBlocks(WorldServer worldIn, Random rand, ChunkPrimer chunkPrimerIn, int x, int z, double noiseVal) { } - public void decorate(AWorldServer worldIn, Random rand, BlockPos pos) { + public void decorate(WorldServer worldIn, Random rand, BlockPos pos) { } public Temperature getTempCategory() { diff --git a/common/src/common/biome/BiomePlains.java b/server/src/server/biome/BiomePlains.java similarity index 94% rename from common/src/common/biome/BiomePlains.java rename to server/src/server/biome/BiomePlains.java index 6aace9a..d9b1c03 100755 --- a/common/src/common/biome/BiomePlains.java +++ b/server/src/server/biome/BiomePlains.java @@ -1,11 +1,12 @@ -package common.biome; +package server.biome; +import common.biome.BaseBiome; import common.block.BlockDoublePlant; import common.block.BlockFlower; import common.entity.animal.EntityHorse; import common.rng.Random; import common.util.BlockPos; -import common.world.AWorldServer; +import server.world.WorldServer; public class BiomePlains extends Biome { @@ -20,10 +21,9 @@ public class BiomePlains extends Biome // protected boolean field_150628_aC; - protected BiomePlains(int id) + protected BiomePlains() { - super(id); - this.setTemperature(12.0f).setHumidity(40.0f); + super(BaseBiome.PLAINS); this.setScaling(Scaling.PLAINS_LOW); this.mobs.add(new RngSpawn(EntityHorse.class, 5, 2, 6)); this.treesPerChunk = -999; @@ -68,7 +68,7 @@ public class BiomePlains extends Biome } } - public void decorate(AWorldServer worldIn, Random rand, BlockPos pos) + public void decorate(WorldServer worldIn, Random rand, BlockPos pos) { double d0 = GRASS_NOISE.generate((double)(pos.getX() + 8) / 200.0D, (double)(pos.getZ() + 8) / 200.0D); diff --git a/common/src/common/biome/BiomeSavanna.java b/server/src/server/biome/BiomeSavanna.java similarity index 71% rename from common/src/common/biome/BiomeSavanna.java rename to server/src/server/biome/BiomeSavanna.java index c456f4e..d35f6d9 100755 --- a/common/src/common/biome/BiomeSavanna.java +++ b/server/src/server/biome/BiomeSavanna.java @@ -1,23 +1,24 @@ -package common.biome; +package server.biome; +import common.biome.BaseBiome; import common.block.BlockDirt; import common.block.BlockDoublePlant; import common.entity.animal.EntityHorse; import common.init.Blocks; import common.rng.Random; import common.util.BlockPos; -import common.world.AWorldServer; -import common.worldgen.ChunkPrimer; -import common.worldgen.tree.WorldGenSavanna; -import common.worldgen.tree.WorldGenTree; +import server.world.WorldServer; +import server.worldgen.ChunkPrimer; +import server.worldgen.tree.WorldGenSavanna; +import server.worldgen.tree.WorldGenTree; public class BiomeSavanna extends Biome { private static final WorldGenSavanna field_150627_aC = new WorldGenSavanna(false); - protected BiomeSavanna(int id) + protected BiomeSavanna(boolean plateau) { - super(id); + super(plateau ? BaseBiome.SAVANNAPLATEAU : BaseBiome.SAVANNA); this.mobs.add(new RngSpawn(EntityHorse.class, 1, 2, 6)); this.treesPerChunk = 1; this.flowersPerChunk = 4; @@ -29,16 +30,15 @@ public class BiomeSavanna extends Biome return (WorldGenTree)(rand.rarity(5) ? field_150627_aC : this.worldGeneratorTrees); } - protected Biome createMutatedBiome(int p_180277_1_) + protected Biome createMutatedBiome(BaseBiome base) { - Biome biomegenbase = new BiomeSavanna.Mutated(p_180277_1_, this); - biomegenbase.temperature = this.temperature == 28.0f ? 24.0f : 20.0f; + Biome biomegenbase = new BiomeSavanna.Mutated(base, this); biomegenbase.depth = this.depth * 0.5F + 0.3F; biomegenbase.scale = this.scale * 0.5F + 1.2F; return biomegenbase; } - public void decorate(AWorldServer worldIn, Random rand, BlockPos pos) + public void decorate(WorldServer worldIn, Random rand, BlockPos pos) { DOUBLE_PLANT_GEN.setPlantType(BlockDoublePlant.EnumPlantType.GRASS); @@ -55,15 +55,15 @@ public class BiomeSavanna extends Biome public static class Mutated extends BiomeMutated { - public Mutated(int p_i45382_1_, Biome p_i45382_2_) + public Mutated(BaseBiome base, Biome p_i45382_2_) { - super(p_i45382_1_, p_i45382_2_); + super(base, p_i45382_2_); this.treesPerChunk = 2; this.flowersPerChunk = 2; this.grassPerChunk = 5; } - public void genTerrainBlocks(AWorldServer worldIn, Random rand, ChunkPrimer chunkPrimerIn, int x, int z, double noiseVal) + public void genTerrainBlocks(WorldServer worldIn, Random rand, ChunkPrimer chunkPrimerIn, int x, int z, double noiseVal) { this.topBlock = Blocks.grass.getState(); this.fillerBlock = Blocks.dirt.getState(); @@ -81,7 +81,7 @@ public class BiomeSavanna extends Biome this.generateBiomeTerrain(worldIn, rand, chunkPrimerIn, x, z, noiseVal); } - public void decorate(AWorldServer worldIn, Random rand, BlockPos pos) + public void decorate(WorldServer worldIn, Random rand, BlockPos pos) { this.decorateNormal(worldIn, rand, pos); } diff --git a/common/src/common/biome/BiomeSnow.java b/server/src/server/biome/BiomeSnow.java similarity index 66% rename from common/src/common/biome/BiomeSnow.java rename to server/src/server/biome/BiomeSnow.java index d1440e8..134f190 100755 --- a/common/src/common/biome/BiomeSnow.java +++ b/server/src/server/biome/BiomeSnow.java @@ -1,14 +1,15 @@ -package common.biome; +package server.biome; +import common.biome.BaseBiome; import common.init.Blocks; import common.rng.Random; import common.rng.WeightedList; import common.util.BlockPos; -import common.world.AWorldServer; -import common.worldgen.feature.WorldGenIcePath; -import common.worldgen.feature.WorldGenIceSpike; -import common.worldgen.tree.WorldGenTaiga2; -import common.worldgen.tree.WorldGenTree; +import server.world.WorldServer; +import server.worldgen.feature.WorldGenIcePath; +import server.worldgen.feature.WorldGenIceSpike; +import server.worldgen.tree.WorldGenTaiga2; +import server.worldgen.tree.WorldGenTree; public class BiomeSnow extends Biome { @@ -16,9 +17,9 @@ public class BiomeSnow extends Biome private final WorldGenIcePath pathGen = new WorldGenIcePath(4); private final boolean spiky; - public BiomeSnow(int id, boolean spiky) + public BiomeSnow(BaseBiome base, boolean spiky) { - super(id); + super(base); this.spiky = spiky; if(spiky) this.topBlock = Blocks.snow.getState(); @@ -27,7 +28,7 @@ public class BiomeSnow extends Biome protected void addMobs(WeightedList mobs) { } - public void decorate(AWorldServer worldIn, Random rand, BlockPos pos) + public void decorate(WorldServer worldIn, Random rand, BlockPos pos) { if (this.spiky) { @@ -54,9 +55,9 @@ public class BiomeSnow extends Biome return new WorldGenTaiga2(false); } - protected Biome createMutatedBiome(int p_180277_1_) + protected Biome createMutatedBiome(BaseBiome base) { - Biome biomegenbase = (new BiomeSnow(p_180277_1_, true)).setColor(13828095).setBiomeName(this.name + "Spikes", this.display + " + Spitzen").enableColdBeach().setTemperature(-20.0f).setHumidity(50.0f).setScaling(this.depth + 0.1F, this.scale + 0.1F); + Biome biomegenbase = (new BiomeSnow(base, true)).enableColdBeach().setScaling(this.depth + 0.1F, this.scale + 0.1F); biomegenbase.depth = this.depth + 0.3F; biomegenbase.scale = this.scale + 0.4F; return biomegenbase; diff --git a/common/src/common/biome/BiomeSnowLand.java b/server/src/server/biome/BiomeSnowLand.java similarity index 82% rename from common/src/common/biome/BiomeSnowLand.java rename to server/src/server/biome/BiomeSnowLand.java index 5699886..0ba4b65 100755 --- a/common/src/common/biome/BiomeSnowLand.java +++ b/server/src/server/biome/BiomeSnowLand.java @@ -1,5 +1,6 @@ -package common.biome; +package server.biome; +import common.biome.BaseBiome; import common.entity.animal.EntitySheep; import common.entity.npc.EntitySpirit; import common.init.Blocks; @@ -7,9 +8,9 @@ import common.rng.WeightedList; public class BiomeSnowLand extends Biome { - public BiomeSnowLand(int id) + public BiomeSnowLand() { - super(id); + super(BaseBiome.SNOWLAND); this.topBlock = Blocks.snow.getState(); this.fillerBlock = Blocks.snow.getState(); this.mushroomsPerChunk = -1; diff --git a/common/src/common/biome/BiomeSpace.java b/server/src/server/biome/BiomeSpace.java similarity index 74% rename from common/src/common/biome/BiomeSpace.java rename to server/src/server/biome/BiomeSpace.java index 550c865..ad2708a 100755 --- a/common/src/common/biome/BiomeSpace.java +++ b/server/src/server/biome/BiomeSpace.java @@ -1,13 +1,14 @@ -package common.biome; +package server.biome; +import common.biome.BaseBiome; import common.block.BlockDirt; import common.init.Blocks; import common.rng.Random; import common.rng.WeightedList; import common.util.BlockPos; -import common.world.AWorldServer; -import common.worldgen.FeatureGenerator; -import common.worldgen.feature.WorldGenAsteroid; +import server.world.WorldServer; +import server.worldgen.FeatureGenerator; +import server.worldgen.feature.WorldGenAsteroid; public class BiomeSpace extends Biome { @@ -16,9 +17,9 @@ public class BiomeSpace extends Biome protected FeatureGenerator asteroidGen2 = new WorldGenAsteroid(Blocks.dirt.getState(), Blocks.dirt.getState().withProperty(BlockDirt.VARIANT, BlockDirt.DirtType.COARSE_DIRT)); - public BiomeSpace(int id) + public BiomeSpace() { - super(id); + super(BaseBiome.SPACE); this.topBlock = Blocks.air.getState(); this.fillerBlock = Blocks.air.getState(); } @@ -26,7 +27,7 @@ public class BiomeSpace extends Biome protected void addMobs(WeightedList mobs) { } - public void decorate(AWorldServer worldIn, Random rand, BlockPos pos) + public void decorate(WorldServer worldIn, Random rand, BlockPos pos) { if(rand.chance(5)) { int x = rand.chOffset(); diff --git a/common/src/common/biome/BiomeStoneBeach.java b/server/src/server/biome/BiomeStoneBeach.java similarity index 79% rename from common/src/common/biome/BiomeStoneBeach.java rename to server/src/server/biome/BiomeStoneBeach.java index 41c1926..9c6fa69 100755 --- a/common/src/common/biome/BiomeStoneBeach.java +++ b/server/src/server/biome/BiomeStoneBeach.java @@ -1,13 +1,14 @@ -package common.biome; +package server.biome; +import common.biome.BaseBiome; import common.init.Blocks; import common.rng.WeightedList; public class BiomeStoneBeach extends Biome { - public BiomeStoneBeach(int id) + public BiomeStoneBeach() { - super(id); + super(BaseBiome.STONEBEACH); // this.mobs.clear(); this.topBlock = Blocks.stone.getState(); this.fillerBlock = Blocks.stone.getState(); diff --git a/common/src/common/biome/BiomeSwamp.java b/server/src/server/biome/BiomeSwamp.java similarity index 75% rename from common/src/common/biome/BiomeSwamp.java rename to server/src/server/biome/BiomeSwamp.java index d726a13..6b10c37 100755 --- a/common/src/common/biome/BiomeSwamp.java +++ b/server/src/server/biome/BiomeSwamp.java @@ -1,5 +1,6 @@ -package common.biome; +package server.biome; +import common.biome.BaseBiome; import common.block.BlockDirectional; import common.block.BlockFlower; import common.entity.npc.EntitySlime; @@ -8,15 +9,15 @@ import common.material.Material; import common.rng.Random; import common.util.BlockPos; import common.util.Facing; -import common.world.AWorldServer; -import common.worldgen.ChunkPrimer; -import common.worldgen.tree.WorldGenTree; +import server.world.WorldServer; +import server.worldgen.ChunkPrimer; +import server.worldgen.tree.WorldGenTree; public class BiomeSwamp extends Biome { - protected BiomeSwamp(int id) + protected BiomeSwamp() { - super(id); + super(BaseBiome.SWAMPLAND); this.treesPerChunk = 2; this.flowersPerChunk = 1; this.deadBushPerChunk = 1; @@ -27,7 +28,6 @@ public class BiomeSwamp extends Biome this.sandPerChunk2 = 0; this.sandPerChunk = 0; this.grassPerChunk = 5; - this.waterColor = 0xe0ffae; this.mobs.add(new RngSpawn(EntitySlime.class, 1, 1, 1)); this.disableBeach(); } @@ -37,23 +37,12 @@ public class BiomeSwamp extends Biome return this.worldGeneratorSwamp; } - public int getGrassColorAtPos(BlockPos pos) - { - double d0 = GRASS_NOISE.generate((double)pos.getX() * 0.0225D, (double)pos.getZ() * 0.0225D); - return d0 < -0.1D ? 5011004 : 6975545; - } - - public int getFoliageColorAtPos(BlockPos pos) - { - return 6975545; - } - public BlockFlower.EnumFlowerType pickRandomFlower(Random rand, BlockPos pos) { return BlockFlower.EnumFlowerType.BLUE_ORCHID; } - public void genTerrainBlocks(AWorldServer worldIn, Random rand, ChunkPrimer chunkPrimerIn, int x, int z, double noiseVal) + public void genTerrainBlocks(WorldServer worldIn, Random rand, ChunkPrimer chunkPrimerIn, int x, int z, double noiseVal) { double d0 = GRASS_NOISE.generate((double)x * 0.25D, (double)z * 0.25D); diff --git a/common/src/common/biome/BiomeTaiga.java b/server/src/server/biome/BiomeTaiga.java similarity index 76% rename from common/src/common/biome/BiomeTaiga.java rename to server/src/server/biome/BiomeTaiga.java index 440fc02..e892d05 100755 --- a/common/src/common/biome/BiomeTaiga.java +++ b/server/src/server/biome/BiomeTaiga.java @@ -1,5 +1,6 @@ -package common.biome; +package server.biome; +import common.biome.BaseBiome; import common.block.BlockDirt; import common.block.BlockDoublePlant; import common.block.BlockTallGrass; @@ -7,15 +8,15 @@ import common.entity.animal.EntityWolf; import common.init.Blocks; import common.rng.Random; import common.util.BlockPos; -import common.world.AWorldServer; -import common.worldgen.ChunkPrimer; -import common.worldgen.FeatureGenerator; -import common.worldgen.feature.WorldGenBlockBlob; -import common.worldgen.foliage.WorldGenTallGrass; -import common.worldgen.tree.WorldGenPine; -import common.worldgen.tree.WorldGenTaiga1; -import common.worldgen.tree.WorldGenTaiga2; -import common.worldgen.tree.WorldGenTree; +import server.world.WorldServer; +import server.worldgen.ChunkPrimer; +import server.worldgen.FeatureGenerator; +import server.worldgen.feature.WorldGenBlockBlob; +import server.worldgen.foliage.WorldGenTallGrass; +import server.worldgen.tree.WorldGenPine; +import server.worldgen.tree.WorldGenTaiga1; +import server.worldgen.tree.WorldGenTaiga2; +import server.worldgen.tree.WorldGenTree; public class BiomeTaiga extends Biome { @@ -26,9 +27,9 @@ public class BiomeTaiga extends Biome private static final WorldGenBlockBlob field_150643_aG = new WorldGenBlockBlob(Blocks.mossy_cobblestone, 0); private int field_150644_aH; - public BiomeTaiga(int id, int p_i45385_2_) + public BiomeTaiga(BaseBiome base, int p_i45385_2_) { - super(id); + super(base); this.field_150644_aH = p_i45385_2_; this.mobs.add(new RngSpawn(EntityWolf.class, 8, 4, 4)); this.treesPerChunk = 10; @@ -59,7 +60,7 @@ public class BiomeTaiga extends Biome return rand.rarity(5) ? new WorldGenTallGrass(BlockTallGrass.EnumType.FERN) : new WorldGenTallGrass(BlockTallGrass.EnumType.GRASS); } - public void decorate(AWorldServer worldIn, Random rand, BlockPos pos) + public void decorate(WorldServer worldIn, Random rand, BlockPos pos) { if (this.field_150644_aH == 1 || this.field_150644_aH == 2) { @@ -87,7 +88,7 @@ public class BiomeTaiga extends Biome super.decorate(worldIn, rand, pos); } - public void genTerrainBlocks(AWorldServer worldIn, Random rand, ChunkPrimer chunkPrimerIn, int x, int z, double noiseVal) + public void genTerrainBlocks(WorldServer worldIn, Random rand, ChunkPrimer chunkPrimerIn, int x, int z, double noiseVal) { if (this.field_150644_aH == 1 || this.field_150644_aH == 2) { @@ -107,8 +108,8 @@ public class BiomeTaiga extends Biome this.generateBiomeTerrain(worldIn, rand, chunkPrimerIn, x, z, noiseVal); } - protected Biome createMutatedBiome(int p_180277_1_) + protected Biome createMutatedBiome(BaseBiome base) { - return this.id == Biome.megaTaiga.id ? (new BiomeTaiga(p_180277_1_, 2)).setColor(5858897).setBiomeName("megaSpruceTaiga", "Hohe Fichtentaiga").setTemperature(-10.0f).setHumidity(80.0f).setScaling(this.depth, this.scale) : super.createMutatedBiome(p_180277_1_); + return this.base == BaseBiome.MEGATAIGA ? (new BiomeTaiga(base, 2)).setScaling(this.depth, this.scale) : super.createMutatedBiome(base); } } diff --git a/common/src/common/biome/BiomeTian.java b/server/src/server/biome/BiomeTian.java similarity index 85% rename from common/src/common/biome/BiomeTian.java rename to server/src/server/biome/BiomeTian.java index 6f8b5bf..c7a52c3 100755 --- a/common/src/common/biome/BiomeTian.java +++ b/server/src/server/biome/BiomeTian.java @@ -1,5 +1,6 @@ -package common.biome; +package server.biome; +import common.biome.BaseBiome; import common.block.BlockFlower; import common.entity.animal.EntityBat; import common.entity.animal.EntityMouse; @@ -9,13 +10,13 @@ import common.init.Blocks; import common.rng.Random; import common.rng.WeightedList; import common.util.BlockPos; -import common.world.AWorldServer; -import common.worldgen.FeatureGenerator; -import common.worldgen.feature.WorldGenSpikes; -import common.worldgen.foliage.WorldGenMushroom; -import common.worldgen.tree.WorldGenBaseTree; -import common.worldgen.tree.WorldGenBigTree; -import common.worldgen.tree.WorldGenTree; +import server.world.WorldServer; +import server.worldgen.FeatureGenerator; +import server.worldgen.feature.WorldGenSpikes; +import server.worldgen.foliage.WorldGenMushroom; +import server.worldgen.tree.WorldGenBaseTree; +import server.worldgen.tree.WorldGenBigTree; +import server.worldgen.tree.WorldGenTree; public class BiomeTian extends Biome { @@ -29,9 +30,9 @@ public class BiomeTian extends Biome protected WorldGenTree treeGen4 = new WorldGenBigTree(false, Blocks.tian_log.getState(), Blocks.tian_leaves.getState()) .setHeightLimit(12, 15); - public BiomeTian(int id) + public BiomeTian() { - super(id); + super(BaseBiome.TIAN); this.topBlock = Blocks.tian_soil.getState(); this.fillerBlock = Blocks.tian.getState(); this.mushroomsPerChunk = -1; @@ -57,7 +58,7 @@ public class BiomeTian extends Biome return rand.pick(rand.chance(this.treeGen2, this.treeGen1, 4), rand.chance(this.treeGen3, this.treeGen4, 15)); } - public void decorate(AWorldServer worldIn, Random rand, BlockPos pos) + public void decorate(WorldServer worldIn, Random rand, BlockPos pos) { super.decorate(worldIn, rand, pos); diff --git a/common/src/common/biome/BiomeWater.java b/server/src/server/biome/BiomeWater.java similarity index 77% rename from common/src/common/biome/BiomeWater.java rename to server/src/server/biome/BiomeWater.java index af521da..acf45c1 100755 --- a/common/src/common/biome/BiomeWater.java +++ b/server/src/server/biome/BiomeWater.java @@ -1,13 +1,14 @@ -package common.biome; +package server.biome; +import common.biome.BaseBiome; import common.entity.animal.EntitySquid; import common.rng.WeightedList; public class BiomeWater extends Biome { private final boolean river; - public BiomeWater(int id, boolean river) { - super(id); + public BiomeWater(BaseBiome base, boolean river) { + super(base); this.river = river; this.disableBeach(); } diff --git a/common/src/common/biome/RngSpawn.java b/server/src/server/biome/RngSpawn.java similarity index 94% rename from common/src/common/biome/RngSpawn.java rename to server/src/server/biome/RngSpawn.java index 969bdca..140c20b 100644 --- a/common/src/common/biome/RngSpawn.java +++ b/server/src/server/biome/RngSpawn.java @@ -1,4 +1,4 @@ -package common.biome; +package server.biome; import common.entity.types.EntityLiving; import common.rng.RngItem; diff --git a/common/src/common/biome/Scaling.java b/server/src/server/biome/Scaling.java similarity index 96% rename from common/src/common/biome/Scaling.java rename to server/src/server/biome/Scaling.java index 1518b57..1dadf62 100644 --- a/common/src/common/biome/Scaling.java +++ b/server/src/server/biome/Scaling.java @@ -1,4 +1,4 @@ -package common.biome; +package server.biome; public enum Scaling { VARYING_LOW(0.1F, 0.2F), diff --git a/common/src/common/biome/Temperature.java b/server/src/server/biome/Temperature.java similarity index 71% rename from common/src/common/biome/Temperature.java rename to server/src/server/biome/Temperature.java index 3c809c9..4eda435 100644 --- a/common/src/common/biome/Temperature.java +++ b/server/src/server/biome/Temperature.java @@ -1,4 +1,4 @@ -package common.biome; +package server.biome; public enum Temperature { SEA, COLD, MEDIUM, WARM; diff --git a/server/src/server/network/Player.java b/server/src/server/network/Player.java index e975817..c667590 100755 --- a/server/src/server/network/Player.java +++ b/server/src/server/network/Player.java @@ -841,17 +841,17 @@ public class Player extends NetHandler implements ICrafting, Executor, IPlayer public void onCriticalHit(Entity entityHit) { - this.entity.getServerWorld().sendToAllTrackingAndSelf(this.entity, new SPacketAnimation(entityHit, 4)); + this.getEntityWorld().sendToAllTrackingAndSelf(this.entity, new SPacketAnimation(entityHit, 4)); } public void onEnchantmentCritical(Entity entityHit) { - this.entity.getServerWorld().sendToAllTrackingAndSelf(this.entity, new SPacketAnimation(entityHit, 5)); + this.getEntityWorld().sendToAllTrackingAndSelf(this.entity, new SPacketAnimation(entityHit, 5)); } public void updateEffectMeta() { - this.entity.getServerWorld().updateTrackedPlayer(this.entity); + this.getEntityWorld().updateTrackedPlayer(this.entity); } public void playSound(SoundEvent name, float volume) @@ -990,7 +990,7 @@ public class Player extends NetHandler implements ICrafting, Executor, IPlayer for (Chunk chunk1 : list) { - this.entity.getServerWorld().updateChunksForPlayer(this.entity, chunk1); + this.getEntityWorld().updateChunksForPlayer(this.entity, chunk1); } } } @@ -1367,7 +1367,7 @@ public class Player extends NetHandler implements ICrafting, Executor, IPlayer int ny = this.clipboard[0].length; int nz = this.clipboard[0][0].length; BlockPos to = this.entity.getPosition(); - ClipboardPlacer placer = new ClipboardPlacer((WorldServer)this.entity.getServerWorld()); + ClipboardPlacer placer = new ClipboardPlacer(this.getEntityWorld()); BlockTransform transform = null; if(this.rotation != 0 || this.flipX || this.flipZ) { transform = new BlockTransform(); @@ -2125,7 +2125,7 @@ public class Player extends NetHandler implements ICrafting, Executor, IPlayer this.entity.vehicle.updateRiderPosition(); } - this.entity.getServerWorld().updateMountedMovingPlayer(this.entity); + this.getEntityWorld().updateMountedMovingPlayer(this.entity); if (this.entity.vehicle != null) { @@ -2278,7 +2278,7 @@ public class Player extends NetHandler implements ICrafting, Executor, IPlayer // } this.entity.onGround = packetIn.isOnGround(); - this.entity.getServerWorld().updateMountedMovingPlayer(this.entity); + this.getEntityWorld().updateMountedMovingPlayer(this.entity); this.handleFalling(this.entity.posY - d7, packetIn.isOnGround()); } else if (this.tickTime - this.lastMoved > 20) diff --git a/server/src/server/world/Converter.java b/server/src/server/world/Converter.java index 34001e7..4ce09ac 100644 --- a/server/src/server/world/Converter.java +++ b/server/src/server/world/Converter.java @@ -15,7 +15,7 @@ import java.util.Map.Entry; import java.util.zip.GZIPInputStream; import java.util.zip.InflaterInputStream; -import common.biome.Biome; +import common.biome.BaseBiome; import common.block.Block; import common.block.BlockCactus; import common.block.BlockCarpet; @@ -916,7 +916,7 @@ public abstract class Converter { } tag.setTag("Sections", sections); byte[] biomes = new byte[256]; - Arrays.fill(biomes, (byte)(Biome.DEF_BIOME.id & 255)); + Arrays.fill(biomes, (byte)(BaseBiome.DEF_BIOME.id & 255)); tag.setByteArray("Biomes", biomes); } NBTTagList ents = tag.getTagList("Entities", 10); diff --git a/server/src/server/world/Spawner.java b/server/src/server/world/Spawner.java index 5a4255b..307d605 100755 --- a/server/src/server/world/Spawner.java +++ b/server/src/server/world/Spawner.java @@ -2,8 +2,6 @@ package server.world; import java.util.Set; -import common.biome.Biome; -import common.biome.RngSpawn; import common.block.Block; import common.collect.Sets; import common.entity.npc.EntityNPC; @@ -18,6 +16,8 @@ import common.util.ChunkPos; import common.util.ExtMath; import common.world.Chunk; import common.world.World; +import server.biome.Biome; +import server.biome.RngSpawn; public abstract class Spawner { private static final int MOB_COUNT_DIV = (int)Math.pow(17.0D, 2.0D); diff --git a/server/src/server/world/WorldServer.java b/server/src/server/world/WorldServer.java index 145c86c..d20dce3 100755 --- a/server/src/server/world/WorldServer.java +++ b/server/src/server/world/WorldServer.java @@ -13,8 +13,7 @@ import java.util.TreeSet; import java.util.concurrent.ConcurrentHashMap; import java.util.function.Predicate; -import common.biome.Biome; -import common.biome.RngSpawn; +import common.biome.BaseBiome; import common.block.Block; import common.block.BlockDoor; import common.block.BlockEventData; @@ -81,25 +80,41 @@ import common.world.LightType; import common.world.State; import common.world.Weather; import common.world.World; -import common.worldgen.BiomeGenSingle; import common.worldgen.BiomeGenerator; -import common.worldgen.BlockReplacer; -import common.worldgen.ChunkGenerator; -import common.worldgen.ChunkPrimer; -import common.worldgen.FeatureDungeons; -import common.worldgen.FeatureLakes; -import common.worldgen.FeatureLiquids; -import common.worldgen.FeatureOres; -import common.worldgen.GeneratorDebug; -import common.worldgen.GeneratorDestroyed; -import common.worldgen.LootConstants; -import common.worldgen.caves.MapGenBigCaves; -import common.worldgen.caves.MapGenCaves; -import common.worldgen.caves.MapGenRavine; +import common.worldgen.FeatureLake; +import common.worldgen.FeatureLiquid; +import common.worldgen.FeatureOre; import server.Server; +import server.biome.Biome; +import server.biome.RngSpawn; import server.clipboard.ClipboardBlock; import server.network.Player; import server.village.VillageCollection; +import server.worldgen.BiomeGenLayered; +import server.worldgen.BiomeGenPerlin; +import server.worldgen.BiomeGenSingle; +import server.worldgen.BlockReplacer; +import server.worldgen.ChunkGenerator; +import server.worldgen.ChunkPrimer; +import server.worldgen.FeatureDungeons; +import server.worldgen.FeatureLakes; +import server.worldgen.FeatureLiquids; +import server.worldgen.FeatureOres; +import server.worldgen.GeneratorCavern; +import server.worldgen.GeneratorDebug; +import server.worldgen.GeneratorDestroyed; +import server.worldgen.GeneratorFlat; +import server.worldgen.GeneratorIsland; +import server.worldgen.GeneratorPerlin; +import server.worldgen.GeneratorSimple; +import server.worldgen.MobConstants; +import server.worldgen.ReplacerAltBiome; +import server.worldgen.ReplacerAltSurface; +import server.worldgen.ReplacerBiome; +import server.worldgen.ReplacerTopLayer; +import server.worldgen.caves.MapGenBigCaves; +import server.worldgen.caves.MapGenCaves; +import server.worldgen.caves.MapGenRavine; import server.worldgen.structure.MapGenBridge; import server.worldgen.structure.MapGenMineshaft; import server.worldgen.structure.MapGenScatteredFeature; @@ -131,7 +146,7 @@ public final class WorldServer extends AWorldServer { private final IntHashMap trackMap = new IntHashMap(); private final Map dataMap = Maps.newHashMap(); private final List dataList = Lists.newArrayList(); - private final Biome[] biomes = new Biome[256]; + private final BaseBiome[] biomes = new BaseBiome[256]; private MapGenCaves caveGen; private MapGenBigCaves bigCaveGen; @@ -175,6 +190,105 @@ public final class WorldServer extends AWorldServer { public static float clampGravity() { return ExtMath.clampf(Config.gravity, -10.0f, 10.0f); } + + private BiomeGenerator createBiomeGenerator(Random rand) { + return this.dimension.getBiomeSize() > 0 ? new BiomeGenLayered(rand.longv(), this.dimension.getDefaultBiome(), this.dimension.isSemiFixed(), this.dimension.getBiomeSize(), this.dimension.getRiverSize(), + this.dimension.getSnowRarity(), this.dimension.getSeaRarity(), this.dimension.getAddBiomes() == null ? new BaseBiome[0] : this.dimension.getAddBiomes(), this.dimension.getAddRarity(), + this.dimension.getHotBiomes() == null ? new BaseBiome[] {this.dimension.getDefaultBiome()} : this.dimension.getHotBiomes(), + this.dimension.getMediumBiomes() == null ? new BaseBiome[] {this.dimension.getDefaultBiome()} : this.dimension.getMediumBiomes(), + this.dimension.getColdBiomes() == null ? new BaseBiome[] {this.dimension.getDefaultBiome()} : this.dimension.getColdBiomes(), + this.dimension.getFrostBiomes() == null ? new BaseBiome[] {this.dimension.getDefaultBiome()} : this.dimension.getFrostBiomes()) : new BiomeGenSingle(this.dimension.getDefaultBiome()); + } + + private ChunkGenerator createChunkGenerator(Random rand) { + switch(this.dimension.getGeneratorType()) { + case FLAT: + return this.dimension.getLayers() == null ? new GeneratorFlat(this.dimension.getSeaLevel(), this.dimension.getFiller()) : new GeneratorFlat(this.dimension.getLayers()); + case PERLIN: + default: + return new GeneratorPerlin(rand, this.dimension.getFiller(), this.dimension.getLiquid(), this.dimension.getNoiseGen()); + case SIMPLE: + return new GeneratorSimple(rand, this.dimension.getFiller(), this.dimension.getLiquid(), + this.dimension.getBiomeSize() > 0 ? null : new BiomeGenPerlin(rand.longv())); + case ISLAND: + return new GeneratorIsland(rand, this.dimension.getFiller()); + case CAVERN: + return new GeneratorCavern(rand, this.dimension.getFiller(), this.dimension.getLiquid()); + case DESTROYED: + return new GeneratorDestroyed(this.dimension.getSeaLevel()); + } + } + + private BlockReplacer createBlockReplacer(Random rand) { + switch(this.dimension.getReplacerType()) { + case BIOMES: + default: + return new ReplacerBiome(rand); + case SIMPLE: + return new ReplacerAltBiome(rand, this.dimension.getFiller(), this.dimension.getLiquid(), this.dimension.getAlt2(), this.dimension.getAlt1()); + case ALTERNATE: + return new ReplacerAltSurface(rand, this.dimension.getFiller(), this.dimension.getAlt1(), this.dimension.getAlt2(), this.dimension.getLiquid()); + case TOPLAYER: + return new ReplacerTopLayer(this.dimension.getSurface(), this.dimension.getFiller().getBlock()); + case NONE: + return null; + } + } + + private FeatureDungeons createDungeonGenerator() { + return this.dimension.getDungeons() > 0 ? new FeatureDungeons(this.dimension.getDungeons()) : null; + } + + private MapGenCaves createCaveGenerator() { + return this.dimension.hasCaves() ? + (new MapGenCaves(this.dimension.getCaveFiller(), this.dimension.getFiller().getBlock(), this.dimension.getTop().getBlock(), + this.dimension.getSurface().getBlock(), this.dimension.getAlt1().getBlock())) : null; + } + + private MapGenRavine createRavineGenerator() { + return this.dimension.hasRavines() ? + (new MapGenRavine(this.dimension.getCaveFiller(), this.dimension.getFiller().getBlock(), + this.dimension.getTop().getBlock(), this.dimension.getSurface().getBlock())) : null; + } + + private MapGenBigCaves createBigCaveGenerator() { + return this.dimension.hasStrideCaves() ? + (new MapGenBigCaves(this.dimension.getFiller().getBlock(), + this.dimension.getTop().getBlock(), this.dimension.getSurface().getBlock())) : null; + } + + private FeatureOres[] createOres() { + if(this.dimension.getOres().isEmpty()) + return null; + FeatureOres[] gens = new FeatureOres[this.dimension.getOres().size()]; + for(int z = 0; z < gens.length; z++) { + FeatureOre gen = this.dimension.getOres().get(z); + gens[z] = new FeatureOres(gen.state, gen.count, gen.more, gen.size, gen.min, gen.max, gen.dist); + } + return gens; + } + + private FeatureLakes[] createLakes() { + if(this.dimension.getLakes().isEmpty()) + return null; + FeatureLakes[] gens = new FeatureLakes[this.dimension.getLakes().size()]; + for(int z = 0; z < gens.length; z++) { + FeatureLake gen = this.dimension.getLakes().get(z); + gens[z] = new FeatureLakes(gen.state, gen.filler, gen.top, gen.chance, gen.minHeight, gen.maxHeight, gen.ratiod); + } + return gens; + } + + private FeatureLiquids[] createLiquids() { + if(this.dimension.getLiquids().isEmpty()) + return null; + FeatureLiquids[] gens = new FeatureLiquids[this.dimension.getLiquids().size()]; + for(int z = 0; z < gens.length; z++) { + FeatureLiquid gen = this.dimension.getLiquids().get(z); + gens[z] = new FeatureLiquids(gen.state, gen.chance, gen.minHeight, gen.maxHeight, gen.lower); + } + return gens; + } public WorldServer(Server server, long dtime, Dimension dim, boolean debug) { super(dim, debug); @@ -220,7 +334,7 @@ public final class WorldServer extends AWorldServer { // GeneratorSettings settings = !debug && !this.exterminated ? dim.getSettings() : null; if(debug) { this.liquid = Blocks.air.getState(); - this.biomeGen = new BiomeGenSingle(Biome.none); + this.biomeGen = new BiomeGenSingle(BaseBiome.NONE); this.generator = new GeneratorDebug(); this.replacer = null; this.populate = false; @@ -301,13 +415,13 @@ public final class WorldServer extends AWorldServer { // } else { this.liquid = this.dimension.getLiquid(); - this.biomeGen = this.dimension.createBiomeGenerator(this.grng); - this.generator = this.dimension.createChunkGenerator(this.grng); - this.replacer = this.dimension.createBlockReplacer(this.grng); + this.biomeGen = this.createBiomeGenerator(this.grng); + this.generator = this.createChunkGenerator(this.grng); + this.replacer = this.createBlockReplacer(this.grng); this.populate = this.dimension.hasPopulator(); - this.caveGen = this.dimension.createCaveGenerator(); - this.bigCaveGen = this.dimension.createBigCaveGenerator(); - this.ravineGen = this.dimension.createRavineGenerator(); + this.caveGen = this.createCaveGenerator(); + this.bigCaveGen = this.createBigCaveGenerator(); + this.ravineGen = this.createRavineGenerator(); this.base = this.dimension.getWorldFloor(); this.ceil = this.dimension.getWorldCeiling(); this.mobs = this.dimension.hasMobs(); @@ -318,10 +432,10 @@ public final class WorldServer extends AWorldServer { this.scatteredGen = this.dimension.hasScattered() ? new MapGenScatteredFeature() : null; this.bridgeGen = this.dimension.hasFortresses() ? new MapGenBridge() : null; this.seaLevel = this.dimension.getSeaLevel(); - this.ores = this.dimension.getOres(); - this.lakes = this.dimension.getLakes(); - this.liquids = this.dimension.getLiquids(); - this.dungeons = this.dimension.createDungeonGenerator(); + this.ores = this.createOres(); + this.lakes = this.createLakes(); + this.liquids = this.createLiquids(); + this.dungeons = this.createDungeonGenerator(); } this.height = this.generator.getMaximumHeight(); // this.teleporter = new Teleporter(this); @@ -482,13 +596,13 @@ public final class WorldServer extends AWorldServer { } private WeightedList getSpawnTypes(BlockPos pos) { - Biome biome = this.getBiomeGenForCoords(pos); + BaseBiome biome = this.getBiomeGenForCoords(pos); if(this.bridgeGen != null && (this.bridgeGen.isPresent(pos) || (this.bridgeGen.isPositionInStructure(this, pos) && this.getState(pos.down()).getBlock() == Blocks.blood_brick))) - return LootConstants.FORTRESS_MOBS; + return MobConstants.FORTRESS_MOBS; else if(this.scatteredGen != null && this.scatteredGen.hasMageHut(pos)) - return LootConstants.MAGEHUT_MOBS; - return biome.getMobs(); + return MobConstants.MAGEHUT_MOBS; + return Biome.BIOMES[biome.id].getMobs(); } public RngSpawn getSpawnListEntryForTypeAt(BlockPos pos) { @@ -509,11 +623,11 @@ public final class WorldServer extends AWorldServer { return this.biomeGen; } - public Biome getBiomeGenForCoords(final BlockPos pos) { + public BaseBiome getBiomeGenForCoords(final BlockPos pos) { if(this.isBlockLoaded(pos)) return this.getChunk(pos).getBiome(pos, this.biomeGen); else - return this.biomeGen.getBiomeGenerator(pos, Biome.DEF_BIOME); + return this.biomeGen.getBiomeGenerator(pos, BaseBiome.DEF_BIOME); } public void setItemData(String dataID, WorldSavedData worldSavedDataIn) { @@ -1423,7 +1537,7 @@ public final class WorldServer extends AWorldServer { int bx = x * 16; int bz = z * 16; BlockPos pos = new BlockPos(bx, 0, bz); - Biome biome = this.getBiomeGenForCoords(pos.add(16, 0, 16)); + Biome biome = Biome.BIOMES[this.getBiomeGenForCoords(pos.add(16, 0, 16)).id]; this.grng.setSeed(this.seed); long sx = this.grng.longv() / 2L * 2L + 1L; long sz = this.grng.longv() / 2L * 2L + 1L; @@ -1521,7 +1635,7 @@ public final class WorldServer extends AWorldServer { if(this.scatteredGen != null) { this.scatteredGen.generate(this, x, z, primer); } - return new Chunk(this, primer, this.base, this.ceil, this.grng, this.biomes, x, z); + return new Chunk(this, primer.getData(), primer.height, this.base, this.ceil, this.grng, this.biomes, x, z); } public boolean isExterminated() { @@ -1627,7 +1741,7 @@ public final class WorldServer extends AWorldServer { this.scatteredGen = null; this.bridgeGen = null; this.generator = new GeneratorDestroyed(this.dimension.getSeaLevel()); - this.biomeGen = new BiomeGenSingle(Biome.exterminated); + this.biomeGen = new BiomeGenSingle(BaseBiome.EXTERMINATED); this.replacer = null; this.populate = false; this.liquid = Blocks.air.getState(); @@ -2131,7 +2245,7 @@ public final class WorldServer extends AWorldServer { // return new LazyBlock(state, this, position); // } - public final boolean setBiome(BlockPos position, Biome biome) { + public final boolean setBiome(BlockPos position, BaseBiome biome) { Chunk chunk = this.getChunk(position); if((chunk != null) && (chunk.isLoaded())) { chunk.getBiomes()[((position.getZ() & 0xF) << 4 | position.getX() & 0xF)] = (byte)biome.id; @@ -2140,7 +2254,7 @@ public final class WorldServer extends AWorldServer { return false; } - public final void setBiomes(BlockPos start, BlockPos end, Biome biome) { + public final void setBiomes(BlockPos start, BlockPos end, BaseBiome biome) { Set chunks = Sets.newHashSet(); for(int x = start.getX(); x <= end.getX(); x++) { for(int z = start.getZ(); z <= end.getZ(); z++) { @@ -2185,7 +2299,7 @@ public final class WorldServer extends AWorldServer { } public boolean isBlockinHighHumidity(BlockPos pos) { - Biome biomegenbase = this.getBiomeGenForCoords(pos); + BaseBiome biomegenbase = this.getBiomeGenForCoords(pos); return biomegenbase.isHighHumidity(); } diff --git a/common/src/common/worldgen/BiomeGenLayered.java b/server/src/server/worldgen/BiomeGenLayered.java similarity index 78% rename from common/src/common/worldgen/BiomeGenLayered.java rename to server/src/server/worldgen/BiomeGenLayered.java index 152ba93..3718e9a 100755 --- a/common/src/common/worldgen/BiomeGenLayered.java +++ b/server/src/server/worldgen/BiomeGenLayered.java @@ -1,38 +1,39 @@ -package common.worldgen; +package server.worldgen; import java.util.List; import java.util.Set; -import common.biome.Biome; +import common.biome.BaseBiome; import common.collect.Lists; import common.util.BlockPos; import common.util.LongHashMap; -import common.worldgen.layer.GenLayer; -import common.worldgen.layer.GenLayerAddAreas; -import common.worldgen.layer.GenLayerAddExtra; -import common.worldgen.layer.GenLayerAddSea; -import common.worldgen.layer.GenLayerAddSnow; -import common.worldgen.layer.GenLayerBase; -import common.worldgen.layer.GenLayerBiome; -import common.worldgen.layer.GenLayerBiomeEdge; -import common.worldgen.layer.GenLayerEdge; -import common.worldgen.layer.GenLayerFuzzyZoom; -import common.worldgen.layer.GenLayerHills; -import common.worldgen.layer.GenLayerRemoveEmpty; -import common.worldgen.layer.GenLayerRiver; -import common.worldgen.layer.GenLayerRiverInit; -import common.worldgen.layer.GenLayerRiverMix; -import common.worldgen.layer.GenLayerShore; -import common.worldgen.layer.GenLayerSmooth; -import common.worldgen.layer.GenLayerVoronoiZoom; -import common.worldgen.layer.GenLayerZoom; -import common.worldgen.layer.IntCache; +import common.worldgen.BiomeGenerator; +import server.worldgen.layer.GenLayer; +import server.worldgen.layer.GenLayerAddAreas; +import server.worldgen.layer.GenLayerAddExtra; +import server.worldgen.layer.GenLayerAddSea; +import server.worldgen.layer.GenLayerAddSnow; +import server.worldgen.layer.GenLayerBase; +import server.worldgen.layer.GenLayerBiome; +import server.worldgen.layer.GenLayerBiomeEdge; +import server.worldgen.layer.GenLayerEdge; +import server.worldgen.layer.GenLayerFuzzyZoom; +import server.worldgen.layer.GenLayerHills; +import server.worldgen.layer.GenLayerRemoveEmpty; +import server.worldgen.layer.GenLayerRiver; +import server.worldgen.layer.GenLayerRiverInit; +import server.worldgen.layer.GenLayerRiverMix; +import server.worldgen.layer.GenLayerShore; +import server.worldgen.layer.GenLayerSmooth; +import server.worldgen.layer.GenLayerVoronoiZoom; +import server.worldgen.layer.GenLayerZoom; +import server.worldgen.layer.IntCache; public class BiomeGenLayered implements BiomeGenerator { private class CacheBlock { public final double[] factors = new double[256]; - public final Biome[] biomes = new Biome[256]; + public final BaseBiome[] biomes = new BaseBiome[256]; public int xPosition; public int zPosition; public long lastAccessTime; @@ -45,7 +46,7 @@ public class BiomeGenLayered implements BiomeGenerator { BiomeGenLayered.this.getBiomes(this.biomes, x << 4, z << 4, 16, 16, false); } - public Biome getBiomeGenAt(int x, int z) + public BaseBiome getBiomeGenAt(int x, int z) { return this.biomes[x & 15 | (z & 15) << 4]; } @@ -66,8 +67,8 @@ public class BiomeGenLayered implements BiomeGenerator { // this(); // } - public BiomeGenLayered(long seed, Biome def, boolean fixed, int biomeSize, int riverSize, int snowRarity, int seaRarity, - Biome[] add, int addRarity, Biome[] hot, Biome[] medium, Biome[] cold, Biome[] frost) { + public BiomeGenLayered(long seed, BaseBiome def, boolean fixed, int biomeSize, int riverSize, int snowRarity, int seaRarity, + BaseBiome[] add, int addRarity, BaseBiome[] hot, BaseBiome[] medium, BaseBiome[] cold, BaseBiome[] frost) { // GenLayer[] layers = GenLayer.getLayers(seed, fixedBiome, biomeSize, riverSize, snowRarity, seaRarity, shroomRarity, biomeRarity); GenLayer layer0t1 = new GenLayerBase(1L); layer0t1 = new GenLayerFuzzyZoom(2000L, layer0t1); @@ -162,10 +163,10 @@ public class BiomeGenLayered implements BiomeGenerator { } } - public Biome getBiomeGenerator(BlockPos pos, Biome def) { + public BaseBiome getBiomeGenerator(BlockPos pos, BaseBiome def) { int x = pos.getX(); int z = pos.getZ(); - Biome biome = this.getBiomeCacheBlock(x, z).getBiomeGenAt(x, z); + BaseBiome biome = this.getBiomeCacheBlock(x, z).getBiomeGenAt(x, z); return biome == null ? def : biome; } @@ -175,7 +176,7 @@ public class BiomeGenLayered implements BiomeGenerator { int[] aint = this.biomeIndexLayer.getInts(x, z, width, length); for(int i = 0; i < width * length; ++i) { - Biome biome = Biome.getBiome(aint[i], Biome.DEF_BIOME); + BaseBiome biome = BaseBiome.getBiomeDef(aint[i]); listToReuse[i] = (double)biome.getFactor(); } } @@ -191,43 +192,43 @@ public class BiomeGenLayered implements BiomeGenerator { int[] aint = this.biomeIndexLayer.getInts(xPos, zPos, sizeX, sizeZ); for(int i = 0; i < sizeX * sizeZ; ++i) { - Biome biome = Biome.getBiome(aint[i], Biome.DEF_BIOME); + BaseBiome biome = BaseBiome.getBiomeDef(aint[i]); factors[i] = (double)biome.getFactor(); } } } - public void getGenBiomes(Biome[] biomes, int x, int z, int width, int height) { + public void getGenBiomes(BaseBiome[] biomes, int x, int z, int width, int height) { IntCache.resetIntCache(); int[] aint = this.genBiomes.getInts(x, z, width, height); for(int i = 0; i < width * height; ++i) { - biomes[i] = Biome.getBiome(aint[i], Biome.DEF_BIOME); + biomes[i] = BaseBiome.getBiomeDef(aint[i]); } } - public void getChunkBiomes(Biome[] oldBiomeList, int x, int z, int width, int depth) { + public void getChunkBiomes(BaseBiome[] oldBiomeList, int x, int z, int width, int depth) { this.getBiomes(oldBiomeList, x, z, width, depth, true); } - public void getBiomes(Biome[] listToReuse, int x, int z, int width, int length, boolean cache) { + public void getBiomes(BaseBiome[] listToReuse, int x, int z, int width, int length, boolean cache) { IntCache.resetIntCache(); if(cache && width == 16 && length == 16 && (x & 15) == 0 && (z & 15) == 0) { - Biome[] biomes = this.getBiomeCacheBlock(x, z).biomes; + BaseBiome[] biomes = this.getBiomeCacheBlock(x, z).biomes; System.arraycopy(biomes, 0, listToReuse, 0, width * length); } else { int[] aint = this.biomeIndexLayer.getInts(x, z, width, length); for(int i = 0; i < width * length; ++i) { - listToReuse[i] = Biome.getBiome(aint[i], Biome.DEF_BIOME); + listToReuse[i] = BaseBiome.getBiomeDef(aint[i]); } } } - public boolean areBiomesViable(int x, int z, int size, Set allowed) { + public boolean areBiomesViable(int x, int z, int size, Set allowed) { IntCache.resetIntCache(); int i = x - size >> 2; int j = z - size >> 2; @@ -238,7 +239,7 @@ public class BiomeGenLayered implements BiomeGenerator { int[] aint = this.genBiomes.getInts(i, j, i1, j1); for(int k1 = 0; k1 < i1 * j1; ++k1) { - Biome biome = Biome.getBiome(aint[k1]); + BaseBiome biome = BaseBiome.getBiome(aint[k1]); if(!allowed.contains(biome)) { return false; diff --git a/common/src/common/worldgen/BiomeGenPerlin.java b/server/src/server/worldgen/BiomeGenPerlin.java similarity index 96% rename from common/src/common/worldgen/BiomeGenPerlin.java rename to server/src/server/worldgen/BiomeGenPerlin.java index ae0e0df..3cde62c 100755 --- a/common/src/common/worldgen/BiomeGenPerlin.java +++ b/server/src/server/worldgen/BiomeGenPerlin.java @@ -1,4 +1,4 @@ -package common.worldgen; +package server.worldgen; import common.rng.PerlinGenOld; import common.rng.Random; diff --git a/common/src/common/worldgen/BiomeGenSingle.java b/server/src/server/worldgen/BiomeGenSingle.java similarity index 59% rename from common/src/common/worldgen/BiomeGenSingle.java rename to server/src/server/worldgen/BiomeGenSingle.java index 1dd6493..9af3ed9 100755 --- a/common/src/common/worldgen/BiomeGenSingle.java +++ b/server/src/server/worldgen/BiomeGenSingle.java @@ -1,31 +1,32 @@ -package common.worldgen; +package server.worldgen; import java.util.Arrays; import java.util.Set; -import common.biome.Biome; +import common.biome.BaseBiome; import common.util.BlockPos; +import common.worldgen.BiomeGenerator; public class BiomeGenSingle implements BiomeGenerator { - private final Biome biome; + private final BaseBiome biome; - public BiomeGenSingle(Biome biome) { + public BiomeGenSingle(BaseBiome biome) { this.biome = biome; } - public Biome getBiomeGenerator(BlockPos pos, Biome def) { + public BaseBiome getBiomeGenerator(BlockPos pos, BaseBiome def) { return this.biome; } - public void getGenBiomes(Biome[] biomes, int x, int z, int width, int height) { + public void getGenBiomes(BaseBiome[] biomes, int x, int z, int width, int height) { Arrays.fill(biomes, 0, width * height, this.biome); } - public void getChunkBiomes(Biome[] oldBiomeList, int x, int z, int width, int depth) { + public void getChunkBiomes(BaseBiome[] oldBiomeList, int x, int z, int width, int depth) { Arrays.fill(oldBiomeList, 0, width * depth, this.biome); } - public void getBiomes(Biome[] listToReuse, int x, int z, int width, int length, boolean cache) { + public void getBiomes(BaseBiome[] listToReuse, int x, int z, int width, int length, boolean cache) { Arrays.fill(listToReuse, 0, width * length, this.biome); } @@ -34,7 +35,7 @@ public class BiomeGenSingle implements BiomeGenerator { // : null; // } - public boolean areBiomesViable(int x, int z, int size, Set allowed) { + public boolean areBiomesViable(int x, int z, int size, Set allowed) { return allowed.contains(this.biome); } diff --git a/server/src/server/worldgen/BlockReplacer.java b/server/src/server/worldgen/BlockReplacer.java new file mode 100755 index 0000000..2350409 --- /dev/null +++ b/server/src/server/worldgen/BlockReplacer.java @@ -0,0 +1,9 @@ +package server.worldgen; + +import common.biome.BaseBiome; +import common.rng.Random; +import server.world.WorldServer; + +public interface BlockReplacer { + public void replaceBlocks(WorldServer world, int x, int z, ChunkPrimer primer, Random rand, BaseBiome[] biomes); +} diff --git a/server/src/server/worldgen/ChunkGenerator.java b/server/src/server/worldgen/ChunkGenerator.java new file mode 100755 index 0000000..fd6f685 --- /dev/null +++ b/server/src/server/worldgen/ChunkGenerator.java @@ -0,0 +1,8 @@ +package server.worldgen; + +import server.world.WorldServer; + +public interface ChunkGenerator { + public void generateChunk(WorldServer world, int x, int z, ChunkPrimer primer); + public int getMaximumHeight(); +} diff --git a/common/src/common/worldgen/ChunkPrimer.java b/server/src/server/worldgen/ChunkPrimer.java similarity index 88% rename from common/src/common/worldgen/ChunkPrimer.java rename to server/src/server/worldgen/ChunkPrimer.java index d0c6f0e..7372177 100755 --- a/common/src/common/worldgen/ChunkPrimer.java +++ b/server/src/server/worldgen/ChunkPrimer.java @@ -1,4 +1,4 @@ -package common.worldgen; +package server.worldgen; import common.init.BlockRegistry; import common.init.Blocks; @@ -12,6 +12,10 @@ public class ChunkPrimer { this.data = new short[Math.max(height, 256) * 256]; this.height = height; } + + public short[] getData() { + return this.data; + } public State get(int x, int y, int z) { State state = BlockRegistry.STATEMAP.getByValue(this.data[x << 4 | z | y << 8]); diff --git a/common/src/common/worldgen/FeatureDungeons.java b/server/src/server/worldgen/FeatureDungeons.java similarity index 96% rename from common/src/common/worldgen/FeatureDungeons.java rename to server/src/server/worldgen/FeatureDungeons.java index cb04f19..816c0d8 100755 --- a/common/src/common/worldgen/FeatureDungeons.java +++ b/server/src/server/worldgen/FeatureDungeons.java @@ -1,4 +1,4 @@ -package common.worldgen; +package server.worldgen; import common.init.Blocks; import common.init.Items; @@ -12,7 +12,7 @@ import common.tileentity.TileEntityChest; import common.tileentity.TileEntityMobSpawner; import common.util.BlockPos; import common.util.Facing; -import common.world.AWorldServer; +import server.world.WorldServer; public class FeatureDungeons { @@ -25,7 +25,7 @@ public class FeatureDungeons } - public boolean generate(AWorldServer worldIn, Random rand, BlockPos position) { + public boolean generate(WorldServer worldIn, Random rand, BlockPos position) { boolean flag = false; for(int z = 0; z < this.chance; z++) { flag |= this.generateDungeon(worldIn, rand, position.add(rand.chOffset(), rand.zrange(256), rand.chOffset())); @@ -33,7 +33,7 @@ public class FeatureDungeons return flag; } - private boolean generateDungeon(AWorldServer worldIn, Random rand, BlockPos position) + private boolean generateDungeon(WorldServer worldIn, Random rand, BlockPos position) { int i = 3; int j = rand.zrange(2) + 2; diff --git a/common/src/common/worldgen/FeatureGenerator.java b/server/src/server/worldgen/FeatureGenerator.java similarity index 67% rename from common/src/common/worldgen/FeatureGenerator.java rename to server/src/server/worldgen/FeatureGenerator.java index 6854bce..95f6331 100755 --- a/common/src/common/worldgen/FeatureGenerator.java +++ b/server/src/server/worldgen/FeatureGenerator.java @@ -1,9 +1,9 @@ -package common.worldgen; +package server.worldgen; import common.rng.Random; import common.util.BlockPos; import common.world.State; -import common.world.AWorldServer; +import server.world.WorldServer; public abstract class FeatureGenerator { @@ -19,9 +19,9 @@ public abstract class FeatureGenerator this.doBlockNotify = notify; } - public abstract boolean generate(AWorldServer worldIn, Random rand, BlockPos position); + public abstract boolean generate(WorldServer worldIn, Random rand, BlockPos position); - protected void setBlockAndNotifyAdequately(AWorldServer worldIn, BlockPos pos, State state) + protected void setBlockAndNotifyAdequately(WorldServer worldIn, BlockPos pos, State state) { if (this.doBlockNotify) { diff --git a/common/src/common/worldgen/FeatureLakes.java b/server/src/server/worldgen/FeatureLakes.java similarity index 95% rename from common/src/common/worldgen/FeatureLakes.java rename to server/src/server/worldgen/FeatureLakes.java index 47f5f97..a930b0e 100755 --- a/common/src/common/worldgen/FeatureLakes.java +++ b/server/src/server/worldgen/FeatureLakes.java @@ -1,6 +1,5 @@ -package common.worldgen; +package server.worldgen; -import common.biome.Biome; import common.block.Block; import common.init.Blocks; import common.material.Material; @@ -8,7 +7,8 @@ import common.rng.Random; import common.util.BlockPos; import common.world.LightType; import common.world.State; -import common.world.AWorldServer; +import server.biome.Biome; +import server.world.WorldServer; public class FeatureLakes { @@ -47,7 +47,7 @@ public class FeatureLakes // this(block, block == Blocks.lava ? Blocks.stone.getDefaultState() : null, Blocks.dirt, Blocks.grass.getDefaultState()); // } - public boolean generate(AWorldServer worldIn, Random rand, BlockPos position) { + public boolean generate(WorldServer worldIn, Random rand, BlockPos position) { if(this.ratiod) { if(this.chance >= 1 && rand.chance(this.chance)) { int y = rand.range(this.minHeight, this.maxHeight); // rand.zrange(rand.zrange(248) + 8); @@ -63,7 +63,7 @@ public class FeatureLakes return false; } - private boolean generateLake(AWorldServer worldIn, Random rand, BlockPos position) + private boolean generateLake(WorldServer worldIn, Random rand, BlockPos position) { for (position = position.add(-8, 0, -8); position.getY() > 5 && worldIn.isAirBlock(position); position = position.down()) { @@ -163,7 +163,7 @@ public class FeatureLakes if (worldIn.getState(blockpos).getBlock() == replace && worldIn.getLightFor(LightType.SKY, position.add(i2, j4, j3)) > 0) { - Biome biomegenbase = worldIn.getBiomeGenForCoords(blockpos); + Biome biomegenbase = Biome.BIOMES[worldIn.getBiomeGenForCoords(blockpos).id]; if (biomegenbase.topBlock.getBlock() == Blocks.mycelium) { diff --git a/common/src/common/worldgen/FeatureLiquids.java b/server/src/server/worldgen/FeatureLiquids.java similarity index 93% rename from common/src/common/worldgen/FeatureLiquids.java rename to server/src/server/worldgen/FeatureLiquids.java index e0c0e26..ff0a1e8 100755 --- a/common/src/common/worldgen/FeatureLiquids.java +++ b/server/src/server/worldgen/FeatureLiquids.java @@ -1,11 +1,11 @@ -package common.worldgen; +package server.worldgen; import common.block.Block; import common.material.Material; import common.rng.Random; import common.util.BlockPos; import common.world.State; -import common.world.AWorldServer; +import server.world.WorldServer; public class FeatureLiquids { @@ -40,7 +40,7 @@ public class FeatureLiquids } - public boolean generate(AWorldServer worldIn, Random rand, BlockPos position) { + public boolean generate(WorldServer worldIn, Random rand, BlockPos position) { Block replace = worldIn.dimension.getFiller().getBlock(); boolean flag = false; for(int z = 0; z < this.chance; z++) { @@ -56,7 +56,7 @@ public class FeatureLiquids return flag; } - private boolean generateLiquid(AWorldServer worldIn, Random rand, BlockPos position, Block replace) + private boolean generateLiquid(WorldServer worldIn, Random rand, BlockPos position, Block replace) { if (worldIn.getState(position.up()).getBlock() != replace) { diff --git a/common/src/common/worldgen/FeatureOres.java b/server/src/server/worldgen/FeatureOres.java similarity index 96% rename from common/src/common/worldgen/FeatureOres.java rename to server/src/server/worldgen/FeatureOres.java index 0786e0c..abac8a1 100755 --- a/common/src/common/worldgen/FeatureOres.java +++ b/server/src/server/worldgen/FeatureOres.java @@ -1,11 +1,11 @@ -package common.worldgen; +package server.worldgen; import common.block.Block; import common.rng.Random; import common.util.BlockPos; import common.util.ExtMath; import common.world.State; -import common.world.AWorldServer; +import server.world.WorldServer; public class FeatureOres { @@ -80,7 +80,7 @@ public class FeatureOres // this.replace = replace; } - public boolean generate(AWorldServer worldIn, Random rand, BlockPos position) { + public boolean generate(WorldServer worldIn, Random rand, BlockPos position) { Block replace = /* this.replace != null ? this.replace : */ worldIn.dimension.getFiller().getBlock(); int tries = this.spawnTries == 0 ? (rand.zrange(this.moreTries) == 0 ? 1 : 0) : @@ -106,7 +106,7 @@ public class FeatureOres return true; } - private void generateVein(AWorldServer worldIn, Random rand, BlockPos position, Block replace) + private void generateVein(WorldServer worldIn, Random rand, BlockPos position, Block replace) { float f = rand.floatv() * (float)Math.PI; double d0 = (double)(/* (float)(position.getX() + 8) */ 8.0f + ExtMath.sin(f) * (float)this.numberOfBlocks / 8.0F); diff --git a/common/src/common/worldgen/GeneratorCavern.java b/server/src/server/worldgen/GeneratorCavern.java similarity index 97% rename from common/src/common/worldgen/GeneratorCavern.java rename to server/src/server/worldgen/GeneratorCavern.java index a3e164e..12f221b 100755 --- a/common/src/common/worldgen/GeneratorCavern.java +++ b/server/src/server/worldgen/GeneratorCavern.java @@ -1,10 +1,10 @@ -package common.worldgen; +package server.worldgen; import common.rng.OctaveGen; import common.rng.Random; import common.util.ExtMath; import common.world.State; -import common.world.AWorldServer; +import server.world.WorldServer; public class GeneratorCavern implements ChunkGenerator { @@ -43,7 +43,7 @@ public class GeneratorCavern implements ChunkGenerator return 128; } - public void generateChunk(AWorldServer world, int x, int z, ChunkPrimer primer) + public void generateChunk(WorldServer world, int x, int z, ChunkPrimer primer) { int range = 4; int lh = world.getSeaLevel() / 2 + 1; diff --git a/server/src/server/worldgen/GeneratorDebug.java b/server/src/server/worldgen/GeneratorDebug.java new file mode 100755 index 0000000..d1eb549 --- /dev/null +++ b/server/src/server/worldgen/GeneratorDebug.java @@ -0,0 +1,27 @@ +package server.worldgen; + +import common.world.State; +import common.worldgen.DebugStates; +import server.world.WorldServer; + +public class GeneratorDebug implements ChunkGenerator +{ + public int getMaximumHeight() { + return 72; + } + + public void generateChunk(WorldServer world, int x, int z, ChunkPrimer primer) + { + for(int bx = 0; bx < 16; ++bx) { + for(int bz = 0; bz < 16; ++bz) { + int sx = x * 16 + bx; + int sz = z * 16 + bz; +// primer.set(bx, 60, bz, Blocks.glass.getDefaultState()); + State state = DebugStates.getState(sx, sz); + if(state != null) { + primer.set(bx, 1, bz, state); + } + } + } + } +} diff --git a/common/src/common/worldgen/GeneratorDestroyed.java b/server/src/server/worldgen/GeneratorDestroyed.java similarity index 86% rename from common/src/common/worldgen/GeneratorDestroyed.java rename to server/src/server/worldgen/GeneratorDestroyed.java index 2d7b188..cfaf319 100755 --- a/common/src/common/worldgen/GeneratorDestroyed.java +++ b/server/src/server/worldgen/GeneratorDestroyed.java @@ -1,9 +1,9 @@ -package common.worldgen; +package server.worldgen; import common.init.Blocks; import common.rng.Random; import common.world.State; -import common.world.AWorldServer; +import server.world.WorldServer; public class GeneratorDestroyed implements ChunkGenerator { @@ -23,7 +23,7 @@ public class GeneratorDestroyed implements ChunkGenerator return this.height; } - public void generateChunk(AWorldServer world, int x, int z, ChunkPrimer primer) + public void generateChunk(WorldServer world, int x, int z, ChunkPrimer primer) { for(int by = 0; by < this.height; ++by) { for(int bx = 0; bx < 16; ++bx) { diff --git a/common/src/common/worldgen/GeneratorFlat.java b/server/src/server/worldgen/GeneratorFlat.java similarity index 86% rename from common/src/common/worldgen/GeneratorFlat.java rename to server/src/server/worldgen/GeneratorFlat.java index bb97868..668e651 100755 --- a/common/src/common/worldgen/GeneratorFlat.java +++ b/server/src/server/worldgen/GeneratorFlat.java @@ -1,9 +1,9 @@ -package common.worldgen; +package server.worldgen; import java.util.Arrays; import common.world.State; -import common.world.AWorldServer; +import server.world.WorldServer; public class GeneratorFlat implements ChunkGenerator { private final State[] layers; @@ -37,7 +37,7 @@ public class GeneratorFlat implements ChunkGenerator { return this.layers.length; } - public void generateChunk(AWorldServer world, int x, int z, ChunkPrimer primer) { + public void generateChunk(WorldServer world, int x, int z, ChunkPrimer primer) { for(int by = 0; by < this.layers.length; by++) { State state = this.layers[by]; for(int bx = 0; bx < 16; bx++) { diff --git a/common/src/common/worldgen/GeneratorIsland.java b/server/src/server/worldgen/GeneratorIsland.java similarity index 97% rename from common/src/common/worldgen/GeneratorIsland.java rename to server/src/server/worldgen/GeneratorIsland.java index ffb42f9..639b28e 100755 --- a/common/src/common/worldgen/GeneratorIsland.java +++ b/server/src/server/worldgen/GeneratorIsland.java @@ -1,10 +1,10 @@ -package common.worldgen; +package server.worldgen; import common.rng.OctaveGen; import common.rng.Random; import common.util.ExtMath; import common.world.State; -import common.world.AWorldServer; +import server.world.WorldServer; public class GeneratorIsland implements ChunkGenerator { @@ -41,7 +41,7 @@ public class GeneratorIsland implements ChunkGenerator return 128; } - public void generateChunk(AWorldServer world, int x, int z, ChunkPrimer primer) + public void generateChunk(WorldServer world, int x, int z, ChunkPrimer primer) { int range = 2; int xr = range + 1; diff --git a/common/src/common/worldgen/GeneratorPerlin.java b/server/src/server/worldgen/GeneratorPerlin.java similarity index 95% rename from common/src/common/worldgen/GeneratorPerlin.java rename to server/src/server/worldgen/GeneratorPerlin.java index 7269142..659347f 100755 --- a/common/src/common/worldgen/GeneratorPerlin.java +++ b/server/src/server/worldgen/GeneratorPerlin.java @@ -1,13 +1,14 @@ -package common.worldgen; +package server.worldgen; -import common.biome.Biome; +import common.biome.BaseBiome; import common.dimension.Dimension; import common.rng.NoiseGen; import common.rng.OctaveGen; import common.rng.Random; import common.util.ExtMath; import common.world.State; -import common.world.AWorldServer; +import server.biome.Biome; +import server.world.WorldServer; public class GeneratorPerlin implements ChunkGenerator { @@ -51,7 +52,7 @@ public class GeneratorPerlin implements ChunkGenerator private final double[] lowerNoise = new double[825]; private final double[] upperNoise = new double[825]; private final double[] depthNoise = new double[25]; - private final Biome[] biomes = new Biome[100]; + private final BaseBiome[] biomes = new BaseBiome[100]; // public GeneratorNew(Random rand, GeneratorSettings settings) // { @@ -105,7 +106,7 @@ public class GeneratorPerlin implements ChunkGenerator return 256; } - public void generateChunk(AWorldServer world, int x, int z, ChunkPrimer primer) + public void generateChunk(WorldServer world, int x, int z, ChunkPrimer primer) { int sea = world.getSeaLevel(); world.getBiomeGenerator().getGenBiomes(this.biomes, x * 4 - 2, z * 4 - 2, 10, 10); @@ -196,13 +197,13 @@ public class GeneratorPerlin implements ChunkGenerator float min = 0.0F; float sum = 0.0F; int range = 2; - Biome biome = this.biomes[u + 2 + (v + 2) * 10]; + Biome biome = Biome.BIOMES[this.biomes[u + 2 + (v + 2) * 10].id]; for (int a = -range; a <= range; ++a) { for (int b = -range; b <= range; ++b) { - Biome biome2 = this.biomes[u + a + 2 + (v + b + 2) * 10]; + Biome biome2 = Biome.BIOMES[this.biomes[u + a + 2 + (v + b + 2) * 10].id]; float bmin = this.biomeDepthOffset + biome2.depth * this.biomeDepthWeight; float bmax = this.biomeScaleOffset + biome2.scale * this.biomeScaleWeight; diff --git a/common/src/common/worldgen/GeneratorSimple.java b/server/src/server/worldgen/GeneratorSimple.java similarity index 96% rename from common/src/common/worldgen/GeneratorSimple.java rename to server/src/server/worldgen/GeneratorSimple.java index fb940fc..0f84201 100755 --- a/common/src/common/worldgen/GeneratorSimple.java +++ b/server/src/server/worldgen/GeneratorSimple.java @@ -1,10 +1,10 @@ -package common.worldgen; +package server.worldgen; import common.rng.NoiseGen; import common.rng.OctaveGen; import common.rng.Random; import common.world.State; -import common.world.AWorldServer; +import server.world.WorldServer; public class GeneratorSimple implements ChunkGenerator { @@ -54,7 +54,7 @@ public class GeneratorSimple implements ChunkGenerator return 128; } - public void generateChunk(AWorldServer world, int x, int z, ChunkPrimer primer) + public void generateChunk(WorldServer world, int x, int z, ChunkPrimer primer) { if(this.biomeGen == null) world.getBiomeGenerator().genFactors(this.factors, x * 16, z * 16, 16, 16); diff --git a/common/src/common/worldgen/LootConstants.java b/server/src/server/worldgen/LootConstants.java similarity index 73% rename from common/src/common/worldgen/LootConstants.java rename to server/src/server/worldgen/LootConstants.java index 9e52c59..a26738f 100755 --- a/common/src/common/worldgen/LootConstants.java +++ b/server/src/server/worldgen/LootConstants.java @@ -1,40 +1,13 @@ -package common.worldgen; +package server.worldgen; -import common.biome.RngSpawn; import common.color.DyeColor; -import common.entity.npc.EntityDarkMage; -import common.entity.npc.EntityMage; -import common.entity.npc.EntityMagma; -import common.entity.npc.EntityTiefling; -import common.entity.npc.EntityUndead; -import common.entity.projectile.RngFishable; import common.init.Blocks; import common.init.ItemRegistry; import common.init.Items; -import common.item.ItemFishFood; -import common.item.ItemStack; import common.item.RngLoot; import common.rng.WeightedList; public abstract class LootConstants { - public static final WeightedList FISHING_JUNK = new WeightedList( - (new RngFishable(new ItemStack(Items.leather_boots), 10)).setMaxDamagePercent(0.9F), new RngFishable(new ItemStack(Items.leather), 10), - new RngFishable(new ItemStack(Items.bone), 10), new RngFishable(new ItemStack(Items.potion), 10), - new RngFishable(new ItemStack(Items.string), 5), (new RngFishable(new ItemStack(Items.fishing_rod), 2)).setMaxDamagePercent(0.9F), - new RngFishable(new ItemStack(Items.bowl), 10), new RngFishable(new ItemStack(Items.stick), 5), - new RngFishable(new ItemStack(Items.dye, 10, DyeColor.BLACK.getDyeDamage()), 1), - new RngFishable(new ItemStack(Blocks.tripwire_hook), 10), new RngFishable(new ItemStack(Items.rotten_flesh), 10)); - public static final WeightedList FISHING_TREASURE = new WeightedList( - new RngFishable(new ItemStack(Blocks.waterlily), 1), new RngFishable(new ItemStack(Items.name_tag), 1), - new RngFishable(new ItemStack(Items.saddle), 1), - (new RngFishable(new ItemStack(Items.bow), 1)).setMaxDamagePercent(0.25F).setEnchantable(), - (new RngFishable(new ItemStack(Items.fishing_rod), 1)).setMaxDamagePercent(0.25F).setEnchantable(), - (new RngFishable(new ItemStack(Items.book), 1)).setEnchantable()); - public static final WeightedList FISH_TYPES = new WeightedList( - new RngFishable(new ItemStack(Items.fish, 1, ItemFishFood.FishType.COD.getMetadata()), 60), - new RngFishable(new ItemStack(Items.fish, 1, ItemFishFood.FishType.SALMON.getMetadata()), 25), - new RngFishable(new ItemStack(Items.fish, 1, ItemFishFood.FishType.CLOWNFISH.getMetadata()), 2), - new RngFishable(new ItemStack(Items.fish, 1, ItemFishFood.FishType.PUFFERFISH.getMetadata()), 13)); public static final WeightedList VILLAGE_BLACKSMITH = new WeightedList(new RngLoot(Items.diamond, 0, 1, 3, 3), new RngLoot(Items.iron_ingot, 0, 1, 5, 10), new RngLoot(Items.gold_ingot, 0, 1, 3, 5), new RngLoot(Items.bread, 0, 1, 3, 15), new RngLoot(Items.apple, 0, 1, 3, 15), new RngLoot(Items.iron_pickaxe, 0, 1, 1, 5), new RngLoot(Items.iron_sword, 0, 1, 1, 5), @@ -95,8 +68,4 @@ public abstract class LootConstants { new RngLoot(Items.wood_axe, 0, 1, 1, 5), new RngLoot(Items.stone_pickaxe, 0, 1, 1, 3), new RngLoot(Items.wood_pickaxe, 0, 1, 1, 5), new RngLoot(Items.apple, 0, 2, 3, 5), new RngLoot(Items.bread, 0, 2, 3, 3), new RngLoot(ItemRegistry.getItemFromBlock(Blocks.acacia_log), 0, 1, 3, 10)); - public static final WeightedList MAGEHUT_MOBS = new WeightedList(new RngSpawn(EntityMage.class, 1, 1, 1)); - public static final WeightedList FORTRESS_MOBS = new WeightedList(new RngSpawn(EntityDarkMage.class, 10, 2, 3), - new RngSpawn(EntityTiefling.class, 5, 4, 4), new RngSpawn(EntityUndead.class, 10, 4, 4), - new RngSpawn(EntityMagma.class, 3, 4, 4)); } diff --git a/server/src/server/worldgen/MobConstants.java b/server/src/server/worldgen/MobConstants.java new file mode 100644 index 0000000..38b9ab5 --- /dev/null +++ b/server/src/server/worldgen/MobConstants.java @@ -0,0 +1,16 @@ +package server.worldgen; + +import common.entity.npc.EntityDarkMage; +import common.entity.npc.EntityMage; +import common.entity.npc.EntityMagma; +import common.entity.npc.EntityTiefling; +import common.entity.npc.EntityUndead; +import common.rng.WeightedList; +import server.biome.RngSpawn; + +public abstract class MobConstants { + public static final WeightedList MAGEHUT_MOBS = new WeightedList(new RngSpawn(EntityMage.class, 1, 1, 1)); + public static final WeightedList FORTRESS_MOBS = new WeightedList(new RngSpawn(EntityDarkMage.class, 10, 2, 3), + new RngSpawn(EntityTiefling.class, 5, 4, 4), new RngSpawn(EntityUndead.class, 10, 4, 4), + new RngSpawn(EntityMagma.class, 3, 4, 4)); +} diff --git a/common/src/common/worldgen/ReplacerAltBiome.java b/server/src/server/worldgen/ReplacerAltBiome.java similarity index 92% rename from common/src/common/worldgen/ReplacerAltBiome.java rename to server/src/server/worldgen/ReplacerAltBiome.java index f312858..6bb6890 100755 --- a/common/src/common/worldgen/ReplacerAltBiome.java +++ b/server/src/server/worldgen/ReplacerAltBiome.java @@ -1,13 +1,14 @@ -package common.worldgen; +package server.worldgen; -import common.biome.Biome; +import common.biome.BaseBiome; import common.block.Block; import common.init.Blocks; import common.rng.NoiseGen; import common.rng.OctaveGen; import common.rng.Random; import common.world.State; -import common.world.AWorldServer; +import server.biome.Biome; +import server.world.WorldServer; public class ReplacerAltBiome implements BlockReplacer { @@ -46,7 +47,7 @@ public class ReplacerAltBiome implements BlockReplacer this.block = filler.getBlock(); } - public void replaceBlocks(AWorldServer world, int x, int z, ChunkPrimer primer, Random rand, Biome[] biomes) + public void replaceBlocks(WorldServer world, int x, int z, ChunkPrimer primer, Random rand, BaseBiome[] biomes) { int seaLevel = world.getSeaLevel(); double scale = 0.03125D; @@ -57,7 +58,7 @@ public class ReplacerAltBiome implements BlockReplacer { for(int px = 0; px < 16; px++) { - Biome biome = biomes[pz * 16 + px]; + Biome biome = Biome.BIOMES[biomes[pz * 16 + px].id]; boolean alt2 = this.alt2Noise[pz + px * 16] + rand.doublev() * 0.20000000000000001D > 0.0D; boolean alt1 = this.alt1Noise[px + pz * 16] + rand.doublev() * 0.20000000000000001D > 3D; int excl = (int)(this.exclNoise[pz + px * 16] / 3D + 3D + rand.doublev() * 0.25D); diff --git a/common/src/common/worldgen/ReplacerAltSurface.java b/server/src/server/worldgen/ReplacerAltSurface.java similarity index 95% rename from common/src/common/worldgen/ReplacerAltSurface.java rename to server/src/server/worldgen/ReplacerAltSurface.java index 1911633..eb03789 100755 --- a/common/src/common/worldgen/ReplacerAltSurface.java +++ b/server/src/server/worldgen/ReplacerAltSurface.java @@ -1,12 +1,12 @@ -package common.worldgen; +package server.worldgen; -import common.biome.Biome; +import common.biome.BaseBiome; import common.block.Block; import common.material.Material; import common.rng.OctaveGen; import common.rng.Random; import common.world.State; -import common.world.AWorldServer; +import server.world.WorldServer; public class ReplacerAltSurface implements BlockReplacer { @@ -38,7 +38,7 @@ public class ReplacerAltSurface implements BlockReplacer this.fillerBlock = filler.getBlock(); } - public void replaceBlocks(AWorldServer world, int x, int z, ChunkPrimer primer, Random rand, Biome[] biomes) + public void replaceBlocks(WorldServer world, int x, int z, ChunkPrimer primer, Random rand, BaseBiome[] biomes) { int i = world.getSeaLevel() + 1; double d0 = 0.03125D; diff --git a/common/src/common/worldgen/ReplacerBiome.java b/server/src/server/worldgen/ReplacerBiome.java similarity index 69% rename from common/src/common/worldgen/ReplacerBiome.java rename to server/src/server/worldgen/ReplacerBiome.java index c483418..536639a 100755 --- a/common/src/common/worldgen/ReplacerBiome.java +++ b/server/src/server/worldgen/ReplacerBiome.java @@ -1,9 +1,10 @@ -package common.worldgen; +package server.worldgen; -import common.biome.Biome; +import common.biome.BaseBiome; import common.rng.PerlinGen; import common.rng.Random; -import common.world.AWorldServer; +import server.biome.Biome; +import server.world.WorldServer; public class ReplacerBiome implements BlockReplacer { @@ -15,7 +16,7 @@ public class ReplacerBiome implements BlockReplacer this.stoneNoiseGen = new PerlinGen(rand, 4); } - public void replaceBlocks(AWorldServer world, int x, int z, ChunkPrimer primer, Random rand, Biome[] biomes) + public void replaceBlocks(WorldServer world, int x, int z, ChunkPrimer primer, Random rand, BaseBiome[] biomes) { double d0 = 0.03125D; this.stoneNoiseGen.generate(this.stoneNoise, (double)(x * 16), (double)(z * 16), 16, 16, d0 * 2.0D, d0 * 2.0D, 1.0D); @@ -24,7 +25,7 @@ public class ReplacerBiome implements BlockReplacer { for (int j = 0; j < 16; ++j) { - Biome biome = biomes[j + i * 16]; + Biome biome = Biome.BIOMES[biomes[j + i * 16].id]; biome.genTerrainBlocks(world, rand, primer, x * 16 + i, z * 16 + j, this.stoneNoise[j + i * 16]); } } diff --git a/common/src/common/worldgen/ReplacerTopLayer.java b/server/src/server/worldgen/ReplacerTopLayer.java similarity index 91% rename from common/src/common/worldgen/ReplacerTopLayer.java rename to server/src/server/worldgen/ReplacerTopLayer.java index 2a1804e..b229a04 100755 --- a/common/src/common/worldgen/ReplacerTopLayer.java +++ b/server/src/server/worldgen/ReplacerTopLayer.java @@ -1,12 +1,12 @@ -package common.worldgen; +package server.worldgen; -import common.biome.Biome; +import common.biome.BaseBiome; import common.block.Block; import common.init.Blocks; import common.material.Material; import common.rng.Random; import common.world.State; -import common.world.AWorldServer; +import server.world.WorldServer; public class ReplacerTopLayer implements BlockReplacer { @@ -22,7 +22,7 @@ public class ReplacerTopLayer implements BlockReplacer this.replace = replace; } - public void replaceBlocks(AWorldServer world, int x, int z, ChunkPrimer primer, Random rand, Biome[] biomes) + public void replaceBlocks(WorldServer world, int x, int z, ChunkPrimer primer, Random rand, BaseBiome[] biomes) { for (int i = 0; i < 16; ++i) { diff --git a/common/src/common/worldgen/caves/MapGenBase.java b/server/src/server/worldgen/caves/MapGenBase.java similarity index 70% rename from common/src/common/worldgen/caves/MapGenBase.java rename to server/src/server/worldgen/caves/MapGenBase.java index f2c9b08..a16f947 100755 --- a/common/src/common/worldgen/caves/MapGenBase.java +++ b/server/src/server/worldgen/caves/MapGenBase.java @@ -1,8 +1,8 @@ -package common.worldgen.caves; +package server.worldgen.caves; import common.rng.Random; -import common.world.AWorldServer; -import common.worldgen.ChunkPrimer; +import server.world.WorldServer; +import server.worldgen.ChunkPrimer; public class MapGenBase { @@ -13,9 +13,9 @@ public class MapGenBase protected Random rand = new Random(); /** This world object. */ - protected AWorldServer worldObj; + protected WorldServer worldObj; - public void generate(AWorldServer worldIn, int x, int z, ChunkPrimer chunkPrimerIn) + public void generate(WorldServer worldIn, int x, int z, ChunkPrimer chunkPrimerIn) { int i = this.range; this.worldObj = worldIn; @@ -38,7 +38,7 @@ public class MapGenBase /** * Recursively called by generate() */ - protected void recursiveGenerate(AWorldServer worldIn, int chunkX, int chunkZ, int p_180701_4_, int p_180701_5_, ChunkPrimer chunkPrimerIn) + protected void recursiveGenerate(WorldServer worldIn, int chunkX, int chunkZ, int p_180701_4_, int p_180701_5_, ChunkPrimer chunkPrimerIn) { } } diff --git a/common/src/common/worldgen/caves/MapGenBigCaves.java b/server/src/server/worldgen/caves/MapGenBigCaves.java similarity index 97% rename from common/src/common/worldgen/caves/MapGenBigCaves.java rename to server/src/server/worldgen/caves/MapGenBigCaves.java index 9fb133e..00cd451 100755 --- a/common/src/common/worldgen/caves/MapGenBigCaves.java +++ b/server/src/server/worldgen/caves/MapGenBigCaves.java @@ -1,12 +1,12 @@ -package common.worldgen.caves; +package server.worldgen.caves; import common.block.Block; import common.init.Blocks; import common.rng.Random; import common.util.ExtMath; import common.world.State; -import common.world.AWorldServer; -import common.worldgen.ChunkPrimer; +import server.world.WorldServer; +import server.worldgen.ChunkPrimer; public class MapGenBigCaves extends MapGenBase { @@ -199,7 +199,7 @@ public class MapGenBigCaves extends MapGenBase /** * Recursively called by generate() */ - protected void recursiveGenerate(AWorldServer worldIn, int chunkX, int chunkZ, int p_180701_4_, int p_180701_5_, ChunkPrimer chunkPrimerIn) + protected void recursiveGenerate(WorldServer worldIn, int chunkX, int chunkZ, int p_180701_4_, int p_180701_5_, ChunkPrimer chunkPrimerIn) { int i = this.rand.zrange(this.rand.zrange(this.rand.zrange(10) + 1) + 1); diff --git a/common/src/common/worldgen/caves/MapGenCaves.java b/server/src/server/worldgen/caves/MapGenCaves.java similarity index 96% rename from common/src/common/worldgen/caves/MapGenCaves.java rename to server/src/server/worldgen/caves/MapGenCaves.java index ec0d0c7..368c9ed 100755 --- a/common/src/common/worldgen/caves/MapGenCaves.java +++ b/server/src/server/worldgen/caves/MapGenCaves.java @@ -1,4 +1,4 @@ -package common.worldgen.caves; +package server.worldgen.caves; import common.block.Block; import common.block.BlockColored; @@ -9,8 +9,9 @@ import common.rng.Random; import common.util.BlockPos; import common.util.ExtMath; import common.world.State; -import common.world.AWorldServer; -import common.worldgen.ChunkPrimer; +import server.biome.Biome; +import server.world.WorldServer; +import server.worldgen.ChunkPrimer; public class MapGenCaves extends MapGenBase { @@ -217,7 +218,7 @@ public class MapGenCaves extends MapGenBase if (flag1 && p_180702_5_.get(j3, j2 - 1, i2).getBlock() == this.top) { blockpos$mutableblockpos.set(j3 + p_180702_3_ * 16, 0, i2 + p_180702_4_ * 16); - p_180702_5_.set(j3, j2 - 1, i2, this.worldObj.getBiomeGenForCoords(blockpos$mutableblockpos).topBlock.getBlock().getState()); + p_180702_5_.set(j3, j2 - 1, i2, Biome.BIOMES[this.worldObj.getBiomeGenForCoords(blockpos$mutableblockpos).id].topBlock.getBlock().getState()); } } } @@ -245,7 +246,7 @@ public class MapGenCaves extends MapGenBase /** * Recursively called by generate() */ - protected void recursiveGenerate(AWorldServer worldIn, int chunkX, int chunkZ, int p_180701_4_, int p_180701_5_, ChunkPrimer chunkPrimerIn) + protected void recursiveGenerate(WorldServer worldIn, int chunkX, int chunkZ, int p_180701_4_, int p_180701_5_, ChunkPrimer chunkPrimerIn) { int i = this.rand.zrange(this.rand.zrange(this.rand.zrange(15) + 1) + 1); diff --git a/common/src/common/worldgen/caves/MapGenRavine.java b/server/src/server/worldgen/caves/MapGenRavine.java similarity index 96% rename from common/src/common/worldgen/caves/MapGenRavine.java rename to server/src/server/worldgen/caves/MapGenRavine.java index cbe9256..160d9d3 100755 --- a/common/src/common/worldgen/caves/MapGenRavine.java +++ b/server/src/server/worldgen/caves/MapGenRavine.java @@ -1,4 +1,4 @@ -package common.worldgen.caves; +package server.worldgen.caves; import common.block.Block; import common.init.Blocks; @@ -6,8 +6,9 @@ import common.rng.Random; import common.util.BlockPos; import common.util.ExtMath; import common.world.State; -import common.world.AWorldServer; -import common.worldgen.ChunkPrimer; +import server.biome.Biome; +import server.world.WorldServer; +import server.worldgen.ChunkPrimer; public class MapGenRavine extends MapGenBase { @@ -196,7 +197,7 @@ public class MapGenRavine extends MapGenBase if (flag && p_180707_5_.get(j3, j2 - 1, i2).getBlock() == this.top) { blockpos$mutableblockpos.set(j3 + p_180707_3_ * 16, 0, i2 + p_180707_4_ * 16); - p_180707_5_.set(j3, j2 - 1, i2, this.worldObj.getBiomeGenForCoords(blockpos$mutableblockpos).topBlock); + p_180707_5_.set(j3, j2 - 1, i2, Biome.BIOMES[this.worldObj.getBiomeGenForCoords(blockpos$mutableblockpos).id].topBlock); } } } @@ -219,7 +220,7 @@ public class MapGenRavine extends MapGenBase /** * Recursively called by generate() */ - protected void recursiveGenerate(AWorldServer worldIn, int chunkX, int chunkZ, int p_180701_4_, int p_180701_5_, ChunkPrimer chunkPrimerIn) + protected void recursiveGenerate(WorldServer worldIn, int chunkX, int chunkZ, int p_180701_4_, int p_180701_5_, ChunkPrimer chunkPrimerIn) { if (this.rand.zrange(50) == 0) { diff --git a/common/src/common/worldgen/feature/WorldGenAbandonedChest.java b/server/src/server/worldgen/feature/WorldGenAbandonedChest.java similarity index 89% rename from common/src/common/worldgen/feature/WorldGenAbandonedChest.java rename to server/src/server/worldgen/feature/WorldGenAbandonedChest.java index 61d7574..88b69b0 100755 --- a/common/src/common/worldgen/feature/WorldGenAbandonedChest.java +++ b/server/src/server/worldgen/feature/WorldGenAbandonedChest.java @@ -1,4 +1,4 @@ -package common.worldgen.feature; +package server.worldgen.feature; import common.block.Block; import common.init.Blocks; @@ -9,9 +9,9 @@ import common.rng.WeightedList; import common.tileentity.TileEntity; import common.tileentity.TileEntityChest; import common.util.BlockPos; -import common.world.AWorldServer; -import common.worldgen.FeatureGenerator; -import common.worldgen.LootConstants; +import server.world.WorldServer; +import server.worldgen.FeatureGenerator; +import server.worldgen.LootConstants; public class WorldGenAbandonedChest extends FeatureGenerator { @@ -30,7 +30,7 @@ public class WorldGenAbandonedChest extends FeatureGenerator this(LootConstants.ABANDONED_ITEMS, 10); } - public boolean generate(AWorldServer worldIn, Random rand, BlockPos position) + public boolean generate(WorldServer worldIn, Random rand, BlockPos position) { Block block; while (((block = worldIn.getState(position).getBlock()).getMaterial() == Material.air || block.getMaterial() == Material.leaves) && position.getY() > 1) diff --git a/common/src/common/worldgen/feature/WorldGenAsteroid.java b/server/src/server/worldgen/feature/WorldGenAsteroid.java similarity index 91% rename from common/src/common/worldgen/feature/WorldGenAsteroid.java rename to server/src/server/worldgen/feature/WorldGenAsteroid.java index c1459c6..4444a4b 100755 --- a/common/src/common/worldgen/feature/WorldGenAsteroid.java +++ b/server/src/server/worldgen/feature/WorldGenAsteroid.java @@ -1,10 +1,10 @@ -package common.worldgen.feature; +package server.worldgen.feature; import common.rng.Random; import common.util.BlockPos; import common.world.State; -import common.world.AWorldServer; -import common.worldgen.FeatureGenerator; +import server.world.WorldServer; +import server.worldgen.FeatureGenerator; public class WorldGenAsteroid extends FeatureGenerator { private final State[] blocks; @@ -13,7 +13,7 @@ public class WorldGenAsteroid extends FeatureGenerator { this.blocks = blocks; } - public boolean generate(AWorldServer world, Random rand, BlockPos pos) { + public boolean generate(WorldServer world, Random rand, BlockPos pos) { for(pos = pos.add(-8, 0, -8); pos.getY() > 9 && !world.isAirBlock(pos); pos = pos.down()) { ; } diff --git a/common/src/common/worldgen/feature/WorldGenBlockBlob.java b/server/src/server/worldgen/feature/WorldGenBlockBlob.java similarity index 91% rename from common/src/common/worldgen/feature/WorldGenBlockBlob.java rename to server/src/server/worldgen/feature/WorldGenBlockBlob.java index 5de76f4..bdc7467 100755 --- a/common/src/common/worldgen/feature/WorldGenBlockBlob.java +++ b/server/src/server/worldgen/feature/WorldGenBlockBlob.java @@ -1,11 +1,11 @@ -package common.worldgen.feature; +package server.worldgen.feature; import common.block.Block; import common.init.Blocks; import common.rng.Random; import common.util.BlockPos; -import common.world.AWorldServer; -import common.worldgen.FeatureGenerator; +import server.world.WorldServer; +import server.worldgen.FeatureGenerator; public class WorldGenBlockBlob extends FeatureGenerator { @@ -19,7 +19,7 @@ public class WorldGenBlockBlob extends FeatureGenerator this.field_150544_b = p_i45450_2_; } - public boolean generate(AWorldServer worldIn, Random rand, BlockPos position) + public boolean generate(WorldServer worldIn, Random rand, BlockPos position) { while (true) { diff --git a/common/src/common/worldgen/feature/WorldGenClay.java b/server/src/server/worldgen/feature/WorldGenClay.java similarity index 89% rename from common/src/common/worldgen/feature/WorldGenClay.java rename to server/src/server/worldgen/feature/WorldGenClay.java index 6dc622f..e1b125a 100755 --- a/common/src/common/worldgen/feature/WorldGenClay.java +++ b/server/src/server/worldgen/feature/WorldGenClay.java @@ -1,11 +1,11 @@ -package common.worldgen.feature; +package server.worldgen.feature; import common.block.Block; import common.init.Blocks; import common.rng.Random; import common.util.BlockPos; -import common.world.AWorldServer; -import common.worldgen.FeatureGenerator; +import server.world.WorldServer; +import server.worldgen.FeatureGenerator; public class WorldGenClay extends FeatureGenerator { @@ -19,7 +19,7 @@ public class WorldGenClay extends FeatureGenerator this.numberOfBlocks = blocks; } - public boolean generate(AWorldServer worldIn, Random rand, BlockPos position) + public boolean generate(WorldServer worldIn, Random rand, BlockPos position) { if (!worldIn.getState(position).getBlock().getMaterial().isColdLiquid()) { diff --git a/common/src/common/worldgen/feature/WorldGenClayExt.java b/server/src/server/worldgen/feature/WorldGenClayExt.java similarity index 93% rename from common/src/common/worldgen/feature/WorldGenClayExt.java rename to server/src/server/worldgen/feature/WorldGenClayExt.java index c9e5ce0..1f5c616 100755 --- a/common/src/common/worldgen/feature/WorldGenClayExt.java +++ b/server/src/server/worldgen/feature/WorldGenClayExt.java @@ -1,18 +1,18 @@ -package common.worldgen.feature; +package server.worldgen.feature; import common.block.Block; import common.init.Blocks; import common.rng.Random; import common.util.BlockPos; import common.util.ExtMath; -import common.world.AWorldServer; +import server.world.WorldServer; public class WorldGenClayExt extends WorldGenClay { public WorldGenClayExt(int blocks) { super(blocks); } - public boolean generate(AWorldServer worldIn, Random rand, BlockPos position) { + public boolean generate(WorldServer worldIn, Random rand, BlockPos position) { if(!worldIn.getState(position).getBlock().getMaterial().isColdLiquid()) { return false; } diff --git a/common/src/common/worldgen/feature/WorldGenDesertWells.java b/server/src/server/worldgen/feature/WorldGenDesertWells.java similarity index 94% rename from common/src/common/worldgen/feature/WorldGenDesertWells.java rename to server/src/server/worldgen/feature/WorldGenDesertWells.java index 55a49c8..f54c1e0 100755 --- a/common/src/common/worldgen/feature/WorldGenDesertWells.java +++ b/server/src/server/worldgen/feature/WorldGenDesertWells.java @@ -1,4 +1,4 @@ -package common.worldgen.feature; +package server.worldgen.feature; import common.block.BlockSand; import common.block.BlockSlab; @@ -9,8 +9,8 @@ import common.util.BlockPos; import common.util.Facing; import common.util.Predicates; import common.world.State; -import common.world.AWorldServer; -import common.worldgen.FeatureGenerator; +import server.world.WorldServer; +import server.worldgen.FeatureGenerator; public class WorldGenDesertWells extends FeatureGenerator { @@ -19,7 +19,7 @@ public class WorldGenDesertWells extends FeatureGenerator private final State field_175912_c = Blocks.sandstone.getState(); private final State field_175910_d = Blocks.flowing_water.getState(); - public boolean generate(AWorldServer worldIn, Random rand, BlockPos position) + public boolean generate(WorldServer worldIn, Random rand, BlockPos position) { while (worldIn.isAirBlock(position) && position.getY() > 2) { diff --git a/common/src/common/worldgen/feature/WorldGenFire.java b/server/src/server/worldgen/feature/WorldGenFire.java similarity index 75% rename from common/src/common/worldgen/feature/WorldGenFire.java rename to server/src/server/worldgen/feature/WorldGenFire.java index d5ffd52..2eb8728 100755 --- a/common/src/common/worldgen/feature/WorldGenFire.java +++ b/server/src/server/worldgen/feature/WorldGenFire.java @@ -1,14 +1,14 @@ -package common.worldgen.feature; +package server.worldgen.feature; import common.init.Blocks; import common.rng.Random; import common.util.BlockPos; -import common.world.AWorldServer; -import common.worldgen.FeatureGenerator; +import server.world.WorldServer; +import server.worldgen.FeatureGenerator; public class WorldGenFire extends FeatureGenerator { - public boolean generate(AWorldServer worldIn, Random rand, BlockPos position) + public boolean generate(WorldServer worldIn, Random rand, BlockPos position) { for (int i = 0; i < 64; ++i) { diff --git a/common/src/common/worldgen/feature/WorldGenGlowStone.java b/server/src/server/worldgen/feature/WorldGenGlowStone.java similarity index 88% rename from common/src/common/worldgen/feature/WorldGenGlowStone.java rename to server/src/server/worldgen/feature/WorldGenGlowStone.java index 7f8e92b..9e99c29 100755 --- a/common/src/common/worldgen/feature/WorldGenGlowStone.java +++ b/server/src/server/worldgen/feature/WorldGenGlowStone.java @@ -1,16 +1,16 @@ -package common.worldgen.feature; +package server.worldgen.feature; import common.init.Blocks; import common.material.Material; import common.rng.Random; import common.util.BlockPos; import common.util.Facing; -import common.world.AWorldServer; -import common.worldgen.FeatureGenerator; +import server.world.WorldServer; +import server.worldgen.FeatureGenerator; public class WorldGenGlowStone extends FeatureGenerator { - public boolean generate(AWorldServer worldIn, Random rand, BlockPos position) + public boolean generate(WorldServer worldIn, Random rand, BlockPos position) { if (!worldIn.isAirBlock(position)) { diff --git a/common/src/common/worldgen/feature/WorldGenHellLava.java b/server/src/server/worldgen/feature/WorldGenHellLava.java similarity index 92% rename from common/src/common/worldgen/feature/WorldGenHellLava.java rename to server/src/server/worldgen/feature/WorldGenHellLava.java index 202ab9f..9932d74 100755 --- a/common/src/common/worldgen/feature/WorldGenHellLava.java +++ b/server/src/server/worldgen/feature/WorldGenHellLava.java @@ -1,12 +1,12 @@ -package common.worldgen.feature; +package server.worldgen.feature; import common.block.Block; import common.init.Blocks; import common.material.Material; import common.rng.Random; import common.util.BlockPos; -import common.world.AWorldServer; -import common.worldgen.FeatureGenerator; +import server.world.WorldServer; +import server.worldgen.FeatureGenerator; public class WorldGenHellLava extends FeatureGenerator { @@ -19,7 +19,7 @@ public class WorldGenHellLava extends FeatureGenerator this.field_94524_b = p_i45453_2_; } - public boolean generate(AWorldServer worldIn, Random rand, BlockPos position) + public boolean generate(WorldServer worldIn, Random rand, BlockPos position) { if (worldIn.getState(position.up()).getBlock() != Blocks.hellrock) { diff --git a/common/src/common/worldgen/feature/WorldGenIcePath.java b/server/src/server/worldgen/feature/WorldGenIcePath.java similarity index 89% rename from common/src/common/worldgen/feature/WorldGenIcePath.java rename to server/src/server/worldgen/feature/WorldGenIcePath.java index b06b13d..0f84e5c 100755 --- a/common/src/common/worldgen/feature/WorldGenIcePath.java +++ b/server/src/server/worldgen/feature/WorldGenIcePath.java @@ -1,11 +1,11 @@ -package common.worldgen.feature; +package server.worldgen.feature; import common.block.Block; import common.init.Blocks; import common.rng.Random; import common.util.BlockPos; -import common.world.AWorldServer; -import common.worldgen.FeatureGenerator; +import server.world.WorldServer; +import server.worldgen.FeatureGenerator; public class WorldGenIcePath extends FeatureGenerator { @@ -17,7 +17,7 @@ public class WorldGenIcePath extends FeatureGenerator this.basePathWidth = p_i45454_1_; } - public boolean generate(AWorldServer worldIn, Random rand, BlockPos position) + public boolean generate(WorldServer worldIn, Random rand, BlockPos position) { while (worldIn.isAirBlock(position) && position.getY() > 2) { diff --git a/common/src/common/worldgen/feature/WorldGenIceSpike.java b/server/src/server/worldgen/feature/WorldGenIceSpike.java similarity index 95% rename from common/src/common/worldgen/feature/WorldGenIceSpike.java rename to server/src/server/worldgen/feature/WorldGenIceSpike.java index 03f5388..886d3d9 100755 --- a/common/src/common/worldgen/feature/WorldGenIceSpike.java +++ b/server/src/server/worldgen/feature/WorldGenIceSpike.java @@ -1,4 +1,4 @@ -package common.worldgen.feature; +package server.worldgen.feature; import common.block.Block; import common.init.Blocks; @@ -6,12 +6,12 @@ import common.material.Material; import common.rng.Random; import common.util.BlockPos; import common.util.ExtMath; -import common.world.AWorldServer; -import common.worldgen.FeatureGenerator; +import server.world.WorldServer; +import server.worldgen.FeatureGenerator; public class WorldGenIceSpike extends FeatureGenerator { - public boolean generate(AWorldServer worldIn, Random rand, BlockPos position) + public boolean generate(WorldServer worldIn, Random rand, BlockPos position) { while (worldIn.isAirBlock(position) && position.getY() > 2) { diff --git a/common/src/common/worldgen/feature/WorldGenSand.java b/server/src/server/worldgen/feature/WorldGenSand.java similarity index 89% rename from common/src/common/worldgen/feature/WorldGenSand.java rename to server/src/server/worldgen/feature/WorldGenSand.java index 1e750bf..edc5cad 100755 --- a/common/src/common/worldgen/feature/WorldGenSand.java +++ b/server/src/server/worldgen/feature/WorldGenSand.java @@ -1,11 +1,11 @@ -package common.worldgen.feature; +package server.worldgen.feature; import common.block.Block; import common.init.Blocks; import common.rng.Random; import common.util.BlockPos; -import common.world.AWorldServer; -import common.worldgen.FeatureGenerator; +import server.world.WorldServer; +import server.worldgen.FeatureGenerator; public class WorldGenSand extends FeatureGenerator { @@ -20,7 +20,7 @@ public class WorldGenSand extends FeatureGenerator this.radius = p_i45462_2_; } - public boolean generate(AWorldServer worldIn, Random rand, BlockPos position) + public boolean generate(WorldServer worldIn, Random rand, BlockPos position) { if (!worldIn.getState(position).getBlock().getMaterial().isColdLiquid()) { diff --git a/common/src/common/worldgen/feature/WorldGenSpikes.java b/server/src/server/worldgen/feature/WorldGenSpikes.java similarity index 93% rename from common/src/common/worldgen/feature/WorldGenSpikes.java rename to server/src/server/worldgen/feature/WorldGenSpikes.java index 736f13b..9885fe8 100755 --- a/common/src/common/worldgen/feature/WorldGenSpikes.java +++ b/server/src/server/worldgen/feature/WorldGenSpikes.java @@ -1,4 +1,4 @@ -package common.worldgen.feature; +package server.worldgen.feature; import common.block.Block; import common.entity.Entity; @@ -6,8 +6,8 @@ import common.entity.item.EntityCrystal; import common.rng.Random; import common.util.BlockPos; import common.world.State; -import common.world.AWorldServer; -import common.worldgen.FeatureGenerator; +import server.world.WorldServer; +import server.worldgen.FeatureGenerator; public class WorldGenSpikes extends FeatureGenerator { @@ -28,7 +28,7 @@ public class WorldGenSpikes extends FeatureGenerator this.crystals = crystals; } - public boolean generate(AWorldServer worldIn, Random rand, BlockPos position) + public boolean generate(WorldServer worldIn, Random rand, BlockPos position) { if (worldIn.isAirBlock(position) && worldIn.getState(position.down()).getBlock() == this.base) { diff --git a/common/src/common/worldgen/foliage/FeatureDoublePlant.java b/server/src/server/worldgen/foliage/FeatureDoublePlant.java similarity index 85% rename from common/src/common/worldgen/foliage/FeatureDoublePlant.java rename to server/src/server/worldgen/foliage/FeatureDoublePlant.java index 7dbfdcb..8237227 100755 --- a/common/src/common/worldgen/foliage/FeatureDoublePlant.java +++ b/server/src/server/worldgen/foliage/FeatureDoublePlant.java @@ -1,10 +1,10 @@ -package common.worldgen.foliage; +package server.worldgen.foliage; import common.block.BlockDoublePlant; import common.init.Blocks; import common.rng.Random; import common.util.BlockPos; -import common.world.AWorldServer; +import server.world.WorldServer; public class FeatureDoublePlant { @@ -15,7 +15,7 @@ public class FeatureDoublePlant this.type = type; } - public boolean generate(AWorldServer worldIn, Random rand, BlockPos position) + public boolean generate(WorldServer worldIn, Random rand, BlockPos position) { boolean flag = false; diff --git a/common/src/common/worldgen/foliage/WorldGenBigMushroom.java b/server/src/server/worldgen/foliage/WorldGenBigMushroom.java similarity index 97% rename from common/src/common/worldgen/foliage/WorldGenBigMushroom.java rename to server/src/server/worldgen/foliage/WorldGenBigMushroom.java index dac6cef..b1bf20f 100755 --- a/common/src/common/worldgen/foliage/WorldGenBigMushroom.java +++ b/server/src/server/worldgen/foliage/WorldGenBigMushroom.java @@ -1,4 +1,4 @@ -package common.worldgen.foliage; +package server.worldgen.foliage; import common.block.Block; import common.block.BlockHugeMushroom; @@ -6,8 +6,8 @@ import common.init.Blocks; import common.material.Material; import common.rng.Random; import common.util.BlockPos; -import common.world.AWorldServer; -import common.worldgen.FeatureGenerator; +import server.world.WorldServer; +import server.worldgen.FeatureGenerator; public class WorldGenBigMushroom extends FeatureGenerator { @@ -25,7 +25,7 @@ public class WorldGenBigMushroom extends FeatureGenerator super(false); } - public boolean generate(AWorldServer worldIn, Random rand, BlockPos position) + public boolean generate(WorldServer worldIn, Random rand, BlockPos position) { // if (this.mushroomType == null) // { diff --git a/common/src/common/worldgen/foliage/WorldGenCactus.java b/server/src/server/worldgen/foliage/WorldGenCactus.java similarity index 80% rename from common/src/common/worldgen/foliage/WorldGenCactus.java rename to server/src/server/worldgen/foliage/WorldGenCactus.java index f14ef17..74354e8 100755 --- a/common/src/common/worldgen/foliage/WorldGenCactus.java +++ b/server/src/server/worldgen/foliage/WorldGenCactus.java @@ -1,14 +1,14 @@ -package common.worldgen.foliage; +package server.worldgen.foliage; import common.init.Blocks; import common.rng.Random; import common.util.BlockPos; -import common.world.AWorldServer; -import common.worldgen.FeatureGenerator; +import server.world.WorldServer; +import server.worldgen.FeatureGenerator; public class WorldGenCactus extends FeatureGenerator { - public boolean generate(AWorldServer worldIn, Random rand, BlockPos position) + public boolean generate(WorldServer worldIn, Random rand, BlockPos position) { for (int i = 0; i < 10; ++i) { diff --git a/common/src/common/worldgen/foliage/WorldGenDeadBush.java b/server/src/server/worldgen/foliage/WorldGenDeadBush.java similarity index 82% rename from common/src/common/worldgen/foliage/WorldGenDeadBush.java rename to server/src/server/worldgen/foliage/WorldGenDeadBush.java index 5b84123..05f2ba8 100755 --- a/common/src/common/worldgen/foliage/WorldGenDeadBush.java +++ b/server/src/server/worldgen/foliage/WorldGenDeadBush.java @@ -1,16 +1,16 @@ -package common.worldgen.foliage; +package server.worldgen.foliage; import common.block.Block; import common.init.Blocks; import common.material.Material; import common.rng.Random; import common.util.BlockPos; -import common.world.AWorldServer; -import common.worldgen.FeatureGenerator; +import server.world.WorldServer; +import server.worldgen.FeatureGenerator; public class WorldGenDeadBush extends FeatureGenerator { - public boolean generate(AWorldServer worldIn, Random rand, BlockPos position) + public boolean generate(WorldServer worldIn, Random rand, BlockPos position) { Block block; diff --git a/common/src/common/worldgen/foliage/WorldGenFlowers.java b/server/src/server/worldgen/foliage/WorldGenFlowers.java similarity index 86% rename from common/src/common/worldgen/foliage/WorldGenFlowers.java rename to server/src/server/worldgen/foliage/WorldGenFlowers.java index f29cbb7..add8180 100755 --- a/common/src/common/worldgen/foliage/WorldGenFlowers.java +++ b/server/src/server/worldgen/foliage/WorldGenFlowers.java @@ -1,11 +1,11 @@ -package common.worldgen.foliage; +package server.worldgen.foliage; import common.block.BlockFlower; import common.rng.Random; import common.util.BlockPos; import common.world.State; -import common.world.AWorldServer; -import common.worldgen.FeatureGenerator; +import server.world.WorldServer; +import server.worldgen.FeatureGenerator; public class WorldGenFlowers extends FeatureGenerator { @@ -23,7 +23,7 @@ public class WorldGenFlowers extends FeatureGenerator this.field_175915_b = p_175914_1_.getState().withProperty(p_175914_1_.getTypeProperty(), p_175914_2_); } - public boolean generate(AWorldServer worldIn, Random rand, BlockPos position) + public boolean generate(WorldServer worldIn, Random rand, BlockPos position) { for (int i = 0; i < 64; ++i) { diff --git a/common/src/common/worldgen/foliage/WorldGenMelon.java b/server/src/server/worldgen/foliage/WorldGenMelon.java similarity index 76% rename from common/src/common/worldgen/foliage/WorldGenMelon.java rename to server/src/server/worldgen/foliage/WorldGenMelon.java index 7ae8427..c8e7319 100755 --- a/common/src/common/worldgen/foliage/WorldGenMelon.java +++ b/server/src/server/worldgen/foliage/WorldGenMelon.java @@ -1,14 +1,14 @@ -package common.worldgen.foliage; +package server.worldgen.foliage; import common.init.Blocks; import common.rng.Random; import common.util.BlockPos; -import common.world.AWorldServer; -import common.worldgen.FeatureGenerator; +import server.world.WorldServer; +import server.worldgen.FeatureGenerator; public class WorldGenMelon extends FeatureGenerator { - public boolean generate(AWorldServer worldIn, Random rand, BlockPos position) + public boolean generate(WorldServer worldIn, Random rand, BlockPos position) { for (int i = 0; i < 64; ++i) { diff --git a/common/src/common/worldgen/foliage/WorldGenMushroom.java b/server/src/server/worldgen/foliage/WorldGenMushroom.java similarity index 81% rename from common/src/common/worldgen/foliage/WorldGenMushroom.java rename to server/src/server/worldgen/foliage/WorldGenMushroom.java index f989bb2..740b3ae 100755 --- a/common/src/common/worldgen/foliage/WorldGenMushroom.java +++ b/server/src/server/worldgen/foliage/WorldGenMushroom.java @@ -1,10 +1,10 @@ -package common.worldgen.foliage; +package server.worldgen.foliage; import common.block.BlockBush; import common.rng.Random; import common.util.BlockPos; -import common.world.AWorldServer; -import common.worldgen.FeatureGenerator; +import server.world.WorldServer; +import server.worldgen.FeatureGenerator; public class WorldGenMushroom extends FeatureGenerator { @@ -15,7 +15,7 @@ public class WorldGenMushroom extends FeatureGenerator this.field_175908_a = p_i45633_1_; } - public boolean generate(AWorldServer worldIn, Random rand, BlockPos position) + public boolean generate(WorldServer worldIn, Random rand, BlockPos position) { for (int i = 0; i < 64; ++i) { diff --git a/common/src/common/worldgen/foliage/WorldGenPumpkin.java b/server/src/server/worldgen/foliage/WorldGenPumpkin.java similarity index 80% rename from common/src/common/worldgen/foliage/WorldGenPumpkin.java rename to server/src/server/worldgen/foliage/WorldGenPumpkin.java index 8a9c2e6..457db07 100755 --- a/common/src/common/worldgen/foliage/WorldGenPumpkin.java +++ b/server/src/server/worldgen/foliage/WorldGenPumpkin.java @@ -1,16 +1,16 @@ -package common.worldgen.foliage; +package server.worldgen.foliage; import common.block.BlockPumpkin; import common.init.Blocks; import common.rng.Random; import common.util.BlockPos; import common.util.Facing; -import common.world.AWorldServer; -import common.worldgen.FeatureGenerator; +import server.world.WorldServer; +import server.worldgen.FeatureGenerator; public class WorldGenPumpkin extends FeatureGenerator { - public boolean generate(AWorldServer worldIn, Random rand, BlockPos position) + public boolean generate(WorldServer worldIn, Random rand, BlockPos position) { for (int i = 0; i < 64; ++i) { diff --git a/common/src/common/worldgen/foliage/WorldGenReed.java b/server/src/server/worldgen/foliage/WorldGenReed.java similarity index 86% rename from common/src/common/worldgen/foliage/WorldGenReed.java rename to server/src/server/worldgen/foliage/WorldGenReed.java index 1c55cbd..459216e 100755 --- a/common/src/common/worldgen/foliage/WorldGenReed.java +++ b/server/src/server/worldgen/foliage/WorldGenReed.java @@ -1,15 +1,15 @@ -package common.worldgen.foliage; +package server.worldgen.foliage; import common.init.Blocks; import common.material.Material; import common.rng.Random; import common.util.BlockPos; -import common.world.AWorldServer; -import common.worldgen.FeatureGenerator; +import server.world.WorldServer; +import server.worldgen.FeatureGenerator; public class WorldGenReed extends FeatureGenerator { - public boolean generate(AWorldServer worldIn, Random rand, BlockPos position) + public boolean generate(WorldServer worldIn, Random rand, BlockPos position) { for (int i = 0; i < 20; ++i) { diff --git a/common/src/common/worldgen/foliage/WorldGenShrub.java b/server/src/server/worldgen/foliage/WorldGenShrub.java similarity index 91% rename from common/src/common/worldgen/foliage/WorldGenShrub.java rename to server/src/server/worldgen/foliage/WorldGenShrub.java index 860c885..410b5c9 100755 --- a/common/src/common/worldgen/foliage/WorldGenShrub.java +++ b/server/src/server/worldgen/foliage/WorldGenShrub.java @@ -1,4 +1,4 @@ -package common.worldgen.foliage; +package server.worldgen.foliage; import common.block.Block; import common.block.BlockLeaves; @@ -7,8 +7,8 @@ import common.material.Material; import common.rng.Random; import common.util.BlockPos; import common.world.State; -import common.world.AWorldServer; -import common.worldgen.tree.WorldGenBaseTree; +import server.world.WorldServer; +import server.worldgen.tree.WorldGenBaseTree; public class WorldGenShrub extends WorldGenBaseTree { @@ -22,7 +22,7 @@ public class WorldGenShrub extends WorldGenBaseTree this.leavesMetadata = leaves.withProperty(BlockLeaves.DECAY, Boolean.valueOf(false)); } - public boolean generate(AWorldServer worldIn, Random rand, BlockPos position) + public boolean generate(WorldServer worldIn, Random rand, BlockPos position) { Block block; diff --git a/common/src/common/worldgen/foliage/WorldGenTallGrass.java b/server/src/server/worldgen/foliage/WorldGenTallGrass.java similarity index 86% rename from common/src/common/worldgen/foliage/WorldGenTallGrass.java rename to server/src/server/worldgen/foliage/WorldGenTallGrass.java index 9adca0d..804a853 100755 --- a/common/src/common/worldgen/foliage/WorldGenTallGrass.java +++ b/server/src/server/worldgen/foliage/WorldGenTallGrass.java @@ -1,4 +1,4 @@ -package common.worldgen.foliage; +package server.worldgen.foliage; import common.block.Block; import common.block.BlockTallGrass; @@ -7,8 +7,8 @@ import common.material.Material; import common.rng.Random; import common.util.BlockPos; import common.world.State; -import common.world.AWorldServer; -import common.worldgen.FeatureGenerator; +import server.world.WorldServer; +import server.worldgen.FeatureGenerator; public class WorldGenTallGrass extends FeatureGenerator { @@ -19,7 +19,7 @@ public class WorldGenTallGrass extends FeatureGenerator this.tallGrassState = Blocks.tallgrass.getState().withProperty(BlockTallGrass.TYPE, p_i45629_1_); } - public boolean generate(AWorldServer worldIn, Random rand, BlockPos position) + public boolean generate(WorldServer worldIn, Random rand, BlockPos position) { Block block; diff --git a/common/src/common/worldgen/foliage/WorldGenVines.java b/server/src/server/worldgen/foliage/WorldGenVines.java similarity index 87% rename from common/src/common/worldgen/foliage/WorldGenVines.java rename to server/src/server/worldgen/foliage/WorldGenVines.java index dfeb2bd..ff9f427 100755 --- a/common/src/common/worldgen/foliage/WorldGenVines.java +++ b/server/src/server/worldgen/foliage/WorldGenVines.java @@ -1,4 +1,4 @@ -package common.worldgen.foliage; +package server.worldgen.foliage; import common.block.BlockVine; import common.init.Blocks; @@ -6,12 +6,12 @@ import common.rng.Random; import common.util.BlockPos; import common.util.Facing; import common.world.State; -import common.world.AWorldServer; -import common.worldgen.FeatureGenerator; +import server.world.WorldServer; +import server.worldgen.FeatureGenerator; public class WorldGenVines extends FeatureGenerator { - public boolean generate(AWorldServer worldIn, Random rand, BlockPos position) + public boolean generate(WorldServer worldIn, Random rand, BlockPos position) { for (; position.getY() < 128; position = position.up()) { diff --git a/common/src/common/worldgen/foliage/WorldGenWaterlily.java b/server/src/server/worldgen/foliage/WorldGenWaterlily.java similarity index 81% rename from common/src/common/worldgen/foliage/WorldGenWaterlily.java rename to server/src/server/worldgen/foliage/WorldGenWaterlily.java index a60117b..c5a7858 100755 --- a/common/src/common/worldgen/foliage/WorldGenWaterlily.java +++ b/server/src/server/worldgen/foliage/WorldGenWaterlily.java @@ -1,16 +1,16 @@ -package common.worldgen.foliage; +package server.worldgen.foliage; import common.block.BlockDirectional; import common.init.Blocks; import common.rng.Random; import common.util.BlockPos; import common.util.Facing; -import common.world.AWorldServer; -import common.worldgen.FeatureGenerator; +import server.world.WorldServer; +import server.worldgen.FeatureGenerator; public class WorldGenWaterlily extends FeatureGenerator { - public boolean generate(AWorldServer worldIn, Random rand, BlockPos position) + public boolean generate(WorldServer worldIn, Random rand, BlockPos position) { for (int i = 0; i < 10; ++i) { diff --git a/common/src/common/worldgen/layer/GenLayer.java b/server/src/server/worldgen/layer/GenLayer.java similarity index 94% rename from common/src/common/worldgen/layer/GenLayer.java rename to server/src/server/worldgen/layer/GenLayer.java index 82c3c5b..a696537 100755 --- a/common/src/common/worldgen/layer/GenLayer.java +++ b/server/src/server/worldgen/layer/GenLayer.java @@ -1,6 +1,7 @@ -package common.worldgen.layer; +package server.worldgen.layer; -import common.biome.Biome; +import common.biome.BaseBiome; +import server.biome.Biome; public abstract class GenLayer { private long worldGenSeed; @@ -23,7 +24,7 @@ public abstract class GenLayer { } protected static boolean isSea(int id) { - return id == Biome.sea.id || id == Biome.frozenSea.id; + return id == BaseBiome.SEA.id || id == BaseBiome.FROZENSEA.id; } public GenLayer(long base) { diff --git a/common/src/common/worldgen/layer/GenLayerAddAreas.java b/server/src/server/worldgen/layer/GenLayerAddAreas.java similarity index 99% rename from common/src/common/worldgen/layer/GenLayerAddAreas.java rename to server/src/server/worldgen/layer/GenLayerAddAreas.java index f5913b0..757a2b7 100755 --- a/common/src/common/worldgen/layer/GenLayerAddAreas.java +++ b/server/src/server/worldgen/layer/GenLayerAddAreas.java @@ -1,4 +1,4 @@ -package common.worldgen.layer; +package server.worldgen.layer; public class GenLayerAddAreas extends GenLayer { diff --git a/common/src/common/worldgen/layer/GenLayerAddExtra.java b/server/src/server/worldgen/layer/GenLayerAddExtra.java similarity index 90% rename from common/src/common/worldgen/layer/GenLayerAddExtra.java rename to server/src/server/worldgen/layer/GenLayerAddExtra.java index e9a2cc0..67444a6 100755 --- a/common/src/common/worldgen/layer/GenLayerAddExtra.java +++ b/server/src/server/worldgen/layer/GenLayerAddExtra.java @@ -1,13 +1,13 @@ -package common.worldgen.layer; +package server.worldgen.layer; -import common.biome.Biome; +import common.biome.BaseBiome; public class GenLayerAddExtra extends GenLayer { private final int[] biomes; private final int rarity; - public GenLayerAddExtra(long base, GenLayer parent, Biome[] biomes, int rarity) + public GenLayerAddExtra(long base, GenLayer parent, BaseBiome[] biomes, int rarity) { super(base); this.parent = parent; diff --git a/common/src/common/worldgen/layer/GenLayerAddSea.java b/server/src/server/worldgen/layer/GenLayerAddSea.java similarity index 92% rename from common/src/common/worldgen/layer/GenLayerAddSea.java rename to server/src/server/worldgen/layer/GenLayerAddSea.java index 4e21a0c..67123e3 100755 --- a/common/src/common/worldgen/layer/GenLayerAddSea.java +++ b/server/src/server/worldgen/layer/GenLayerAddSea.java @@ -1,6 +1,6 @@ -package common.worldgen.layer; +package server.worldgen.layer; -import common.biome.Biome; +import common.biome.BaseBiome; public class GenLayerAddSea extends GenLayer { @@ -60,7 +60,7 @@ public class GenLayerAddSea extends GenLayer this.initChunkSeed((long)(areaX + j1), (long)(areaY + i1)); if (k2 == 0 && this.nextInt(this.rarity) == 0) { - aint1[j1 + i1 * areaWidth] = l2 > 1 ? Biome.frozenSea.id : Biome.sea.id; + aint1[j1 + i1 * areaWidth] = l2 > 1 ? BaseBiome.FROZENSEA.id : BaseBiome.SEA.id; } else { diff --git a/common/src/common/worldgen/layer/GenLayerAddSnow.java b/server/src/server/worldgen/layer/GenLayerAddSnow.java similarity index 98% rename from common/src/common/worldgen/layer/GenLayerAddSnow.java rename to server/src/server/worldgen/layer/GenLayerAddSnow.java index de257dc..5b7b07a 100755 --- a/common/src/common/worldgen/layer/GenLayerAddSnow.java +++ b/server/src/server/worldgen/layer/GenLayerAddSnow.java @@ -1,4 +1,4 @@ -package common.worldgen.layer; +package server.worldgen.layer; public class GenLayerAddSnow extends GenLayer { diff --git a/common/src/common/worldgen/layer/GenLayerBase.java b/server/src/server/worldgen/layer/GenLayerBase.java similarity index 95% rename from common/src/common/worldgen/layer/GenLayerBase.java rename to server/src/server/worldgen/layer/GenLayerBase.java index bd1403d..f0c596e 100755 --- a/common/src/common/worldgen/layer/GenLayerBase.java +++ b/server/src/server/worldgen/layer/GenLayerBase.java @@ -1,4 +1,4 @@ -package common.worldgen.layer; +package server.worldgen.layer; public class GenLayerBase extends GenLayer { diff --git a/common/src/common/worldgen/layer/GenLayerBiome.java b/server/src/server/worldgen/layer/GenLayerBiome.java similarity index 83% rename from common/src/common/worldgen/layer/GenLayerBiome.java rename to server/src/server/worldgen/layer/GenLayerBiome.java index e4a58e6..ca2fc39 100755 --- a/common/src/common/worldgen/layer/GenLayerBiome.java +++ b/server/src/server/worldgen/layer/GenLayerBiome.java @@ -1,17 +1,17 @@ -package common.worldgen.layer; +package server.worldgen.layer; -import common.biome.Biome; +import common.biome.BaseBiome; public class GenLayerBiome extends GenLayer { - private final Biome[] hot; - private final Biome[] medium; - private final Biome[] cold; - private final Biome[] frost; + private final BaseBiome[] hot; + private final BaseBiome[] medium; + private final BaseBiome[] cold; + private final BaseBiome[] frost; private final int def; private final int fixed; - public GenLayerBiome(long base, GenLayer parent, Biome[] hot, Biome[] medium, Biome[] cold, Biome[] frost, Biome def, boolean fixed) + public GenLayerBiome(long base, GenLayer parent, BaseBiome[] hot, BaseBiome[] medium, BaseBiome[] cold, BaseBiome[] frost, BaseBiome def, boolean fixed) { super(base); this.parent = parent; diff --git a/common/src/common/worldgen/layer/GenLayerBiomeEdge.java b/server/src/server/worldgen/layer/GenLayerBiomeEdge.java similarity index 79% rename from common/src/common/worldgen/layer/GenLayerBiomeEdge.java rename to server/src/server/worldgen/layer/GenLayerBiomeEdge.java index f3653f7..41abf0c 100755 --- a/common/src/common/worldgen/layer/GenLayerBiomeEdge.java +++ b/server/src/server/worldgen/layer/GenLayerBiomeEdge.java @@ -1,7 +1,8 @@ -package common.worldgen.layer; +package server.worldgen.layer; -import common.biome.Biome; -import common.biome.Temperature; +import common.biome.BaseBiome; +import server.biome.Biome; +import server.biome.Temperature; public class GenLayerBiomeEdge extends GenLayer { @@ -27,45 +28,45 @@ public class GenLayerBiomeEdge extends GenLayer this.initChunkSeed((long)(j + areaX), (long)(i + areaY)); int k = aint[j + 1 + (i + 1) * (areaWidth + 2)]; - if (!this.replaceBiomeEdgeIfNecessary(aint, aint1, j, i, areaWidth, k, Biome.extremeHills.id, Biome.extremeHillsEdge.id) && /* !this.replaceBiomeEdge(aint, aint1, j, i, areaWidth, k, Biome.mesaPlateau_F.id, Biome.mesa.id) && !this.replaceBiomeEdge(aint, aint1, j, i, areaWidth, k, Biome.mesaPlateau.id, Biome.mesa.id) && */ !this.replaceBiomeEdge(aint, aint1, j, i, areaWidth, k, Biome.megaTaiga.id, Biome.taiga.id)) + if (!this.replaceBiomeEdgeIfNecessary(aint, aint1, j, i, areaWidth, k, BaseBiome.EXTREMEHILLS.id, BaseBiome.EXTREMEHILLSEDGE.id) && /* !this.replaceBiomeEdge(aint, aint1, j, i, areaWidth, k, Biome.mesaPlateau_F.id, Biome.mesa.id) && !this.replaceBiomeEdge(aint, aint1, j, i, areaWidth, k, Biome.mesaPlateau.id, Biome.mesa.id) && */ !this.replaceBiomeEdge(aint, aint1, j, i, areaWidth, k, BaseBiome.MEGATAIGA.id, BaseBiome.TAIGA.id)) { - if (k == Biome.desert.id) + if (k == BaseBiome.DESERT.id) { int l1 = aint[j + 1 + (i + 1 - 1) * (areaWidth + 2)]; int i2 = aint[j + 1 + 1 + (i + 1) * (areaWidth + 2)]; int j2 = aint[j + 1 - 1 + (i + 1) * (areaWidth + 2)]; int k2 = aint[j + 1 + (i + 1 + 1) * (areaWidth + 2)]; - if (l1 != Biome.icePlains.id && i2 != Biome.icePlains.id && j2 != Biome.icePlains.id && k2 != Biome.icePlains.id) + if (l1 != BaseBiome.ICEPLAINS.id && i2 != BaseBiome.ICEPLAINS.id && j2 != BaseBiome.ICEPLAINS.id && k2 != BaseBiome.ICEPLAINS.id) { aint1[j + i * areaWidth] = k; } else { - aint1[j + i * areaWidth] = Biome.extremeHillsPlus.id; + aint1[j + i * areaWidth] = BaseBiome.EXTREMEHILLSPLUS.id; } } - else if (k == Biome.swampland.id) + else if (k == BaseBiome.SWAMPLAND.id) { int l = aint[j + 1 + (i + 1 - 1) * (areaWidth + 2)]; int i1 = aint[j + 1 + 1 + (i + 1) * (areaWidth + 2)]; int j1 = aint[j + 1 - 1 + (i + 1) * (areaWidth + 2)]; int k1 = aint[j + 1 + (i + 1 + 1) * (areaWidth + 2)]; - if (l != Biome.desert.id && i1 != Biome.desert.id && j1 != Biome.desert.id && k1 != Biome.desert.id && l != Biome.coldTaiga.id && i1 != Biome.coldTaiga.id && j1 != Biome.coldTaiga.id && k1 != Biome.coldTaiga.id && l != Biome.icePlains.id && i1 != Biome.icePlains.id && j1 != Biome.icePlains.id && k1 != Biome.icePlains.id) + if (l != BaseBiome.DESERT.id && i1 != BaseBiome.DESERT.id && j1 != BaseBiome.DESERT.id && k1 != BaseBiome.DESERT.id && l != BaseBiome.COLDTAIGA.id && i1 != BaseBiome.COLDTAIGA.id && j1 != BaseBiome.COLDTAIGA.id && k1 != BaseBiome.COLDTAIGA.id && l != BaseBiome.ICEPLAINS.id && i1 != BaseBiome.ICEPLAINS.id && j1 != BaseBiome.ICEPLAINS.id && k1 != BaseBiome.ICEPLAINS.id) { - if (l != Biome.jungle.id && k1 != Biome.jungle.id && i1 != Biome.jungle.id && j1 != Biome.jungle.id) + if (l != BaseBiome.JUNGLE.id && k1 != BaseBiome.JUNGLE.id && i1 != BaseBiome.JUNGLE.id && j1 != BaseBiome.JUNGLE.id) { aint1[j + i * areaWidth] = k; } else { - aint1[j + i * areaWidth] = Biome.jungleEdge.id; + aint1[j + i * areaWidth] = BaseBiome.JUNGLEEDGE.id; } } else { - aint1[j + i * areaWidth] = Biome.plains.id; + aint1[j + i * areaWidth] = BaseBiome.PLAINS.id; } } else diff --git a/common/src/common/worldgen/layer/GenLayerEdge.java b/server/src/server/worldgen/layer/GenLayerEdge.java similarity index 99% rename from common/src/common/worldgen/layer/GenLayerEdge.java rename to server/src/server/worldgen/layer/GenLayerEdge.java index dda413d..26600a3 100755 --- a/common/src/common/worldgen/layer/GenLayerEdge.java +++ b/server/src/server/worldgen/layer/GenLayerEdge.java @@ -1,4 +1,4 @@ -package common.worldgen.layer; +package server.worldgen.layer; public class GenLayerEdge extends GenLayer { diff --git a/common/src/common/worldgen/layer/GenLayerFuzzyZoom.java b/server/src/server/worldgen/layer/GenLayerFuzzyZoom.java similarity index 94% rename from common/src/common/worldgen/layer/GenLayerFuzzyZoom.java rename to server/src/server/worldgen/layer/GenLayerFuzzyZoom.java index d38e3de..6db73ee 100755 --- a/common/src/common/worldgen/layer/GenLayerFuzzyZoom.java +++ b/server/src/server/worldgen/layer/GenLayerFuzzyZoom.java @@ -1,4 +1,4 @@ -package common.worldgen.layer; +package server.worldgen.layer; public class GenLayerFuzzyZoom extends GenLayerZoom { diff --git a/common/src/common/worldgen/layer/GenLayerHills.java b/server/src/server/worldgen/layer/GenLayerHills.java similarity index 72% rename from common/src/common/worldgen/layer/GenLayerHills.java rename to server/src/server/worldgen/layer/GenLayerHills.java index e8c4318..832f2c8 100755 --- a/common/src/common/worldgen/layer/GenLayerHills.java +++ b/server/src/server/worldgen/layer/GenLayerHills.java @@ -1,6 +1,6 @@ -package common.worldgen.layer; +package server.worldgen.layer; -import common.biome.Biome; +import common.biome.BaseBiome; import common.log.Log; public class GenLayerHills extends GenLayer @@ -8,7 +8,7 @@ public class GenLayerHills extends GenLayer private GenLayer field_151628_d; private final int def; - public GenLayerHills(long p_i45479_1_, GenLayer p_i45479_3_, GenLayer p_i45479_4_, Biome def) + public GenLayerHills(long p_i45479_1_, GenLayer p_i45479_3_, GenLayer p_i45479_4_, BaseBiome def) { super(p_i45479_1_); this.parent = p_i45479_3_; @@ -42,7 +42,7 @@ public class GenLayerHills extends GenLayer if (k != 0 && l >= 2 && (l - 2) % 29 == 1 && k < 128) { - if (Biome.getBiome(k + 128) != null) + if (BaseBiome.getBiome(k + 128) != null) { aint2[j + i * areaWidth] = k + 128; } @@ -59,86 +59,86 @@ public class GenLayerHills extends GenLayer { int i1 = k; - if (k == Biome.desert.id) + if (k == BaseBiome.DESERT.id) { - i1 = Biome.desertHills.id; + i1 = BaseBiome.DESERTHILLS.id; } - else if (k == Biome.forest.id) + else if (k == BaseBiome.FOREST.id) { - i1 = Biome.forestHills.id; + i1 = BaseBiome.FORESTHILLS.id; } - else if (k == Biome.birchForest.id) + else if (k == BaseBiome.BIRCHFOREST.id) { - i1 = Biome.birchForestHills.id; + i1 = BaseBiome.BIRCHFORESTHILLS.id; } - else if (k == Biome.roofedForest.id) + else if (k == BaseBiome.ROOFEDFOREST.id) { - i1 = Biome.plains.id; + i1 = BaseBiome.PLAINS.id; } - else if (k == Biome.taiga.id) + else if (k == BaseBiome.TAIGA.id) { - i1 = Biome.taigaHills.id; + i1 = BaseBiome.TAIGAHILLS.id; } - else if (k == Biome.megaTaiga.id) + else if (k == BaseBiome.MEGATAIGA.id) { - i1 = Biome.megaTaigaHills.id; + i1 = BaseBiome.MEGATAIGAHILLS.id; } - else if (k == Biome.coldTaiga.id) + else if (k == BaseBiome.COLDTAIGA.id) { - i1 = Biome.coldTaigaHills.id; + i1 = BaseBiome.COLDTAIGAHILLS.id; } - else if (k == Biome.plains.id) + else if (k == BaseBiome.PLAINS.id) { if (this.nextInt(3) == 0) { - i1 = Biome.forestHills.id; + i1 = BaseBiome.FORESTHILLS.id; } else { - i1 = Biome.forest.id; + i1 = BaseBiome.FOREST.id; } } - else if (k == Biome.icePlains.id) + else if (k == BaseBiome.ICEPLAINS.id) { - i1 = Biome.iceMountains.id; + i1 = BaseBiome.ICEMOUNTAINS.id; } - else if (k == Biome.jungle.id) + else if (k == BaseBiome.JUNGLE.id) { - i1 = Biome.jungleHills.id; + i1 = BaseBiome.JUNGLEHILLS.id; } - else if (k == Biome.none.id) + else if (k == BaseBiome.NONE.id) { i1 = this.def; } - else if (k == Biome.extremeHills.id) + else if (k == BaseBiome.EXTREMEHILLS.id) { - i1 = Biome.extremeHillsPlus.id; + i1 = BaseBiome.EXTREMEHILLSPLUS.id; } - else if (k == Biome.savanna.id) + else if (k == BaseBiome.SAVANNA.id) { - i1 = Biome.savannaPlateau.id; + i1 = BaseBiome.SAVANNAPLATEAU.id; } // else if (canBeNearby(k, Biome.mesaPlateau_F.id)) // { // i1 = Biome.mesa.id; // } - else if (k == Biome.sea.id && this.nextInt(3) == 0) + else if (k == BaseBiome.SEA.id && this.nextInt(3) == 0) { int j1 = this.nextInt(2); if (j1 == 0) { - i1 = Biome.plains.id; + i1 = BaseBiome.PLAINS.id; } else { - i1 = Biome.forest.id; + i1 = BaseBiome.FOREST.id; } } if (flag && i1 != k) { - if (Biome.getBiome(i1 + 128) != null) + if (BaseBiome.getBiome(i1 + 128) != null) { i1 += 128; } diff --git a/common/src/common/worldgen/layer/GenLayerRemoveEmpty.java b/server/src/server/worldgen/layer/GenLayerRemoveEmpty.java similarity index 98% rename from common/src/common/worldgen/layer/GenLayerRemoveEmpty.java rename to server/src/server/worldgen/layer/GenLayerRemoveEmpty.java index ef77ef2..ec07585 100755 --- a/common/src/common/worldgen/layer/GenLayerRemoveEmpty.java +++ b/server/src/server/worldgen/layer/GenLayerRemoveEmpty.java @@ -1,4 +1,4 @@ -package common.worldgen.layer; +package server.worldgen.layer; public class GenLayerRemoveEmpty extends GenLayer { diff --git a/common/src/common/worldgen/layer/GenLayerRiver.java b/server/src/server/worldgen/layer/GenLayerRiver.java similarity index 92% rename from common/src/common/worldgen/layer/GenLayerRiver.java rename to server/src/server/worldgen/layer/GenLayerRiver.java index 1bf51e0..0ea31ff 100755 --- a/common/src/common/worldgen/layer/GenLayerRiver.java +++ b/server/src/server/worldgen/layer/GenLayerRiver.java @@ -1,6 +1,6 @@ -package common.worldgen.layer; +package server.worldgen.layer; -import common.biome.Biome; +import common.biome.BaseBiome; public class GenLayerRiver extends GenLayer { @@ -39,7 +39,7 @@ public class GenLayerRiver extends GenLayer } else { - aint1[j1 + i1 * areaWidth] = Biome.river.id; + aint1[j1 + i1 * areaWidth] = BaseBiome.RIVER.id; } } } diff --git a/common/src/common/worldgen/layer/GenLayerRiverInit.java b/server/src/server/worldgen/layer/GenLayerRiverInit.java similarity index 96% rename from common/src/common/worldgen/layer/GenLayerRiverInit.java rename to server/src/server/worldgen/layer/GenLayerRiverInit.java index 04bd0e8..4bb9ed2 100755 --- a/common/src/common/worldgen/layer/GenLayerRiverInit.java +++ b/server/src/server/worldgen/layer/GenLayerRiverInit.java @@ -1,4 +1,4 @@ -package common.worldgen.layer; +package server.worldgen.layer; public class GenLayerRiverInit extends GenLayer { diff --git a/common/src/common/worldgen/layer/GenLayerRiverMix.java b/server/src/server/worldgen/layer/GenLayerRiverMix.java similarity index 81% rename from common/src/common/worldgen/layer/GenLayerRiverMix.java rename to server/src/server/worldgen/layer/GenLayerRiverMix.java index 0796530..8f34f59 100755 --- a/common/src/common/worldgen/layer/GenLayerRiverMix.java +++ b/server/src/server/worldgen/layer/GenLayerRiverMix.java @@ -1,6 +1,6 @@ -package common.worldgen.layer; +package server.worldgen.layer; -import common.biome.Biome; +import common.biome.BaseBiome; public class GenLayerRiverMix extends GenLayer { @@ -8,7 +8,7 @@ public class GenLayerRiverMix extends GenLayer private GenLayer riverPatternGeneratorChain; private final int def; - public GenLayerRiverMix(long p_i2129_1_, GenLayer p_i2129_3_, GenLayer p_i2129_4_, Biome def) + public GenLayerRiverMix(long p_i2129_1_, GenLayer p_i2129_3_, GenLayer p_i2129_4_, BaseBiome def) { super(p_i2129_1_); this.biomePatternGeneratorChain = p_i2129_3_; @@ -39,23 +39,23 @@ public class GenLayerRiverMix extends GenLayer for (int i = 0; i < areaWidth * areaHeight; ++i) { - if(biome[i] == Biome.none.id) + if(biome[i] == BaseBiome.NONE.id) { out[i] = this.def; } - else if(biome[i] == Biome.sea.id || biome[i] == Biome.frozenSea.id) + else if(biome[i] == BaseBiome.SEA.id || biome[i] == BaseBiome.FROZENSEA.id) { out[i] = biome[i]; } - else if (river[i] == Biome.river.id) + else if (river[i] == BaseBiome.RIVER.id) { - if (biome[i] == Biome.icePlains.id) + if (biome[i] == BaseBiome.ICEPLAINS.id) { - out[i] = Biome.frozenRiver.id; + out[i] = BaseBiome.FROZENRIVER.id; } else // if (biome[i] != Biome.mushroomPlains.id && biome[i] != Biome.mushroomPlainsEdge.id) { - out[i] = Biome.river.id; + out[i] = BaseBiome.RIVER.id; } // else // { diff --git a/common/src/common/worldgen/layer/GenLayerShore.java b/server/src/server/worldgen/layer/GenLayerShore.java similarity index 86% rename from common/src/common/worldgen/layer/GenLayerShore.java rename to server/src/server/worldgen/layer/GenLayerShore.java index c3936aa..a51e8c1 100755 --- a/common/src/common/worldgen/layer/GenLayerShore.java +++ b/server/src/server/worldgen/layer/GenLayerShore.java @@ -1,7 +1,8 @@ -package common.worldgen.layer; +package server.worldgen.layer; -import common.biome.Biome; -import common.biome.BiomeJungle; +import common.biome.BaseBiome; +import server.biome.Biome; +import server.biome.BiomeJungle; public class GenLayerShore extends GenLayer { @@ -56,19 +57,19 @@ public class GenLayerShore extends GenLayer } else { - data[j + i * width] = Biome.beach.id; + data[j + i * width] = BaseBiome.BEACH.id; } } else { - data[j + i * width] = Biome.jungleEdge.id; + data[j + i * width] = BaseBiome.JUNGLEEDGE.id; } } - else if (id != Biome.extremeHills.id && id != Biome.extremeHillsPlus.id && id != Biome.extremeHillsEdge.id) + else if (id != BaseBiome.EXTREMEHILLS.id && id != BaseBiome.EXTREMEHILLSPLUS.id && id != BaseBiome.EXTREMEHILLSEDGE.id) { if (biome != null && biome.allowColdBeach) { - this.putBeach(pre, data, j, i, width, id, Biome.coldBeach.id); + this.putBeach(pre, data, j, i, width, id, BaseBiome.COLDBEACH.id); } else // if (id != Biome.mesa.id && id != Biome.mesaPlateau_F.id) // { @@ -85,7 +86,7 @@ public class GenLayerShore extends GenLayer } else { - data[j + i * width] = Biome.beach.id; + data[j + i * width] = BaseBiome.BEACH.id; } } else @@ -119,7 +120,7 @@ public class GenLayerShore extends GenLayer } else { - this.putBeach(pre, data, j, i, width, id, Biome.stoneBeach.id); + this.putBeach(pre, data, j, i, width, id, BaseBiome.STONEBEACH.id); } } } @@ -153,7 +154,8 @@ public class GenLayerShore extends GenLayer private boolean canNBJungle(int id) { - return Biome.getBiome(id) != null && Biome.getBiome(id).getBiomeClass() == BiomeJungle.class ? true : id == Biome.jungleEdge.id || id == Biome.jungle.id || id == Biome.jungleHills.id || id == Biome.forest.id || id == Biome.taiga.id || isSea(id); + Biome biome = Biome.getBiome(id); + return biome != null && biome.getBiomeClass() == BiomeJungle.class ? true : id == BaseBiome.JUNGLEEDGE.id || id == BaseBiome.JUNGLE.id || id == BaseBiome.JUNGLEHILLS.id || id == BaseBiome.FOREST.id || id == BaseBiome.TAIGA.id || isSea(id); } // private boolean canNBMesa(int id) diff --git a/common/src/common/worldgen/layer/GenLayerSmooth.java b/server/src/server/worldgen/layer/GenLayerSmooth.java similarity index 98% rename from common/src/common/worldgen/layer/GenLayerSmooth.java rename to server/src/server/worldgen/layer/GenLayerSmooth.java index d67a516..e071367 100755 --- a/common/src/common/worldgen/layer/GenLayerSmooth.java +++ b/server/src/server/worldgen/layer/GenLayerSmooth.java @@ -1,4 +1,4 @@ -package common.worldgen.layer; +package server.worldgen.layer; public class GenLayerSmooth extends GenLayer { diff --git a/common/src/common/worldgen/layer/GenLayerVoronoiZoom.java b/server/src/server/worldgen/layer/GenLayerVoronoiZoom.java similarity index 99% rename from common/src/common/worldgen/layer/GenLayerVoronoiZoom.java rename to server/src/server/worldgen/layer/GenLayerVoronoiZoom.java index c53921c..f58e306 100755 --- a/common/src/common/worldgen/layer/GenLayerVoronoiZoom.java +++ b/server/src/server/worldgen/layer/GenLayerVoronoiZoom.java @@ -1,4 +1,4 @@ -package common.worldgen.layer; +package server.worldgen.layer; public class GenLayerVoronoiZoom extends GenLayer { diff --git a/common/src/common/worldgen/layer/GenLayerZoom.java b/server/src/server/worldgen/layer/GenLayerZoom.java similarity index 98% rename from common/src/common/worldgen/layer/GenLayerZoom.java rename to server/src/server/worldgen/layer/GenLayerZoom.java index 72ef702..0b9d45c 100755 --- a/common/src/common/worldgen/layer/GenLayerZoom.java +++ b/server/src/server/worldgen/layer/GenLayerZoom.java @@ -1,4 +1,4 @@ -package common.worldgen.layer; +package server.worldgen.layer; public class GenLayerZoom extends GenLayer { diff --git a/common/src/common/worldgen/layer/IntCache.java b/server/src/server/worldgen/layer/IntCache.java similarity index 98% rename from common/src/common/worldgen/layer/IntCache.java rename to server/src/server/worldgen/layer/IntCache.java index e275dc7..e9ac30a 100755 --- a/common/src/common/worldgen/layer/IntCache.java +++ b/server/src/server/worldgen/layer/IntCache.java @@ -1,4 +1,4 @@ -package common.worldgen.layer; +package server.worldgen.layer; import java.util.List; diff --git a/server/src/server/worldgen/structure/MapGenScatteredFeature.java b/server/src/server/worldgen/structure/MapGenScatteredFeature.java index e8caba9..f731099 100755 --- a/server/src/server/worldgen/structure/MapGenScatteredFeature.java +++ b/server/src/server/worldgen/structure/MapGenScatteredFeature.java @@ -3,14 +3,14 @@ package server.worldgen.structure; import java.util.Arrays; import java.util.List; -import common.biome.Biome; +import common.biome.BaseBiome; import common.rng.Random; import common.util.BlockPos; import server.world.WorldServer; public class MapGenScatteredFeature extends MapGenStructure { - private static final List biomelist = Arrays.asList(new Biome[] {Biome.desert, Biome.desertHills, Biome.jungle, Biome.jungleHills, Biome.swampland}); + private static final List biomelist = Arrays.asList(BaseBiome.DESERT, BaseBiome.DESERTHILLS, BaseBiome.JUNGLE, BaseBiome.JUNGLEHILLS, BaseBiome.SWAMPLAND); private static final int MAX_DISTANCE = 32; private static final int MIN_DISTANCE = 8; @@ -44,14 +44,14 @@ public class MapGenScatteredFeature extends MapGenStructure if (i == k && j == l) { - Biome biomegenbase = this.worldObj.getBiomeGenerator().getBiomeGenerator(new BlockPos(i * 16 + 8, 0, j * 16 + 8), null); + BaseBiome biomegenbase = this.worldObj.getBiomeGenerator().getBiomeGenerator(new BlockPos(i * 16 + 8, 0, j * 16 + 8), null); if (biomegenbase == null) { return false; } - for (Biome biomegenbase1 : biomelist) + for (BaseBiome biomegenbase1 : biomelist) { if (biomegenbase == biomegenbase1) { @@ -92,16 +92,16 @@ public class MapGenScatteredFeature extends MapGenStructure public Start(WorldServer worldIn, Random p_i2060_2_, int p_i2060_3_, int p_i2060_4_) { super(p_i2060_3_, p_i2060_4_); - Biome biomegenbase = worldIn.getBiomeGenForCoords(new BlockPos(p_i2060_3_ * 16 + 8, 0, p_i2060_4_ * 16 + 8)); + BaseBiome biomegenbase = worldIn.getBiomeGenForCoords(new BlockPos(p_i2060_3_ * 16 + 8, 0, p_i2060_4_ * 16 + 8)); - if (biomegenbase != Biome.jungle && biomegenbase != Biome.jungleHills) + if (biomegenbase != BaseBiome.JUNGLE && biomegenbase != BaseBiome.JUNGLEHILLS) { - if (biomegenbase == Biome.swampland) + if (biomegenbase == BaseBiome.SWAMPLAND) { StructureScattered.SwampHut componentscatteredfeaturepieces$swamphut = new StructureScattered.SwampHut(p_i2060_2_, p_i2060_3_ * 16, p_i2060_4_ * 16); this.components.add(componentscatteredfeaturepieces$swamphut); } - else if (biomegenbase == Biome.desert || biomegenbase == Biome.desertHills) + else if (biomegenbase == BaseBiome.DESERT || biomegenbase == BaseBiome.DESERTHILLS) { StructureScattered.DesertPyramid componentscatteredfeaturepieces$desertpyramid = new StructureScattered.DesertPyramid(p_i2060_2_, p_i2060_3_ * 16, p_i2060_4_ * 16); this.components.add(componentscatteredfeaturepieces$desertpyramid); diff --git a/server/src/server/worldgen/structure/MapGenStructure.java b/server/src/server/worldgen/structure/MapGenStructure.java index 82aca60..dc911fe 100755 --- a/server/src/server/worldgen/structure/MapGenStructure.java +++ b/server/src/server/worldgen/structure/MapGenStructure.java @@ -10,25 +10,17 @@ import common.rng.Random; import common.util.BlockPos; import common.util.ChunkPos; import common.util.LongHashMap; -import common.world.AWorldServer; import common.world.World; -import common.worldgen.ChunkPrimer; -import common.worldgen.caves.MapGenBase; import server.world.WorldServer; import server.world.WorldServer.WorldSavedData; +import server.worldgen.ChunkPrimer; +import server.worldgen.caves.MapGenBase; public abstract class MapGenStructure extends MapGenBase { private WorldSavedData structureData; protected Map structureMap = Maps.newHashMap(); - protected WorldServer worldObj; - public void generate(AWorldServer worldIn, int x, int z, ChunkPrimer chunkPrimerIn) - { - this.worldObj = (WorldServer)worldIn; - super.generate(worldIn, x, z, chunkPrimerIn); - } - public abstract String getStructureName(); /** diff --git a/server/src/server/worldgen/structure/MapGenVillage.java b/server/src/server/worldgen/structure/MapGenVillage.java index e6119f8..396d5a3 100755 --- a/server/src/server/worldgen/structure/MapGenVillage.java +++ b/server/src/server/worldgen/structure/MapGenVillage.java @@ -3,7 +3,7 @@ package server.worldgen.structure; import java.util.List; import java.util.Set; -import common.biome.Biome; +import common.biome.BaseBiome; import common.collect.Sets; import common.nbt.NBTTagCompound; import common.rng.Random; @@ -11,7 +11,7 @@ import server.world.WorldServer; public class MapGenVillage extends MapGenStructure { - public static final Set villageSpawnBiomes = Sets.newHashSet(Biome.plains, Biome.desert, Biome.savanna); + public static final Set villageSpawnBiomes = Sets.newHashSet(BaseBiome.PLAINS, BaseBiome.DESERT, BaseBiome.SAVANNA); /** World terrain type, 0 for normal, 1 for flat map */ private int terrainType; diff --git a/server/src/server/worldgen/structure/StructureBridge.java b/server/src/server/worldgen/structure/StructureBridge.java index 4dc4aa8..309a567 100755 --- a/server/src/server/worldgen/structure/StructureBridge.java +++ b/server/src/server/worldgen/structure/StructureBridge.java @@ -10,8 +10,8 @@ import common.tileentity.TileEntity; import common.tileentity.TileEntityMobSpawner; import common.util.BlockPos; import common.util.Facing; -import common.worldgen.LootConstants; import server.world.WorldServer; +import server.worldgen.LootConstants; public class StructureBridge diff --git a/server/src/server/worldgen/structure/StructureMineshaft.java b/server/src/server/worldgen/structure/StructureMineshaft.java index e3a08d5..d7a0fd9 100755 --- a/server/src/server/worldgen/structure/StructureMineshaft.java +++ b/server/src/server/worldgen/structure/StructureMineshaft.java @@ -17,8 +17,8 @@ import common.tileentity.TileEntityMobSpawner; import common.util.BlockPos; import common.util.Facing; import common.world.State; -import common.worldgen.LootConstants; import server.world.WorldServer; +import server.worldgen.LootConstants; public class StructureMineshaft diff --git a/server/src/server/worldgen/structure/StructureScattered.java b/server/src/server/worldgen/structure/StructureScattered.java index 6a667d2..8723035 100755 --- a/server/src/server/worldgen/structure/StructureScattered.java +++ b/server/src/server/worldgen/structure/StructureScattered.java @@ -17,8 +17,8 @@ import common.nbt.NBTTagCompound; import common.rng.Random; import common.util.BlockPos; import common.util.Facing; -import common.worldgen.LootConstants; import server.world.WorldServer; +import server.worldgen.LootConstants; public class StructureScattered { diff --git a/server/src/server/worldgen/structure/StructureStronghold.java b/server/src/server/worldgen/structure/StructureStronghold.java index ad13933..101d358 100755 --- a/server/src/server/worldgen/structure/StructureStronghold.java +++ b/server/src/server/worldgen/structure/StructureStronghold.java @@ -16,8 +16,8 @@ import common.tileentity.TileEntity; import common.tileentity.TileEntityMobSpawner; import common.util.BlockPos; import common.util.Facing; -import common.worldgen.LootConstants; import server.world.WorldServer; +import server.worldgen.LootConstants; public class StructureStronghold diff --git a/server/src/server/worldgen/structure/StructureVillage.java b/server/src/server/worldgen/structure/StructureVillage.java index 810a4f6..7d00750 100755 --- a/server/src/server/worldgen/structure/StructureVillage.java +++ b/server/src/server/worldgen/structure/StructureVillage.java @@ -3,7 +3,7 @@ package server.worldgen.structure; import java.util.Iterator; import java.util.List; -import common.biome.Biome; +import common.biome.BaseBiome; import common.block.Block; import common.block.BlockLog; import common.block.BlockSandStone; @@ -23,8 +23,8 @@ import common.util.BlockPos; import common.util.Facing; import common.world.State; import common.worldgen.BiomeGenerator; -import common.worldgen.LootConstants; import server.world.WorldServer; +import server.worldgen.LootConstants; public class StructureVillage @@ -1430,8 +1430,8 @@ public class StructureVillage this.biomeGen = genIn; this.structureVillageWeightedPieceList = p_i2104_6_; this.terrainType = p_i2104_7_; - Biome biomegenbase = genIn.getBiomeGenerator(new BlockPos(p_i2104_4_, 0, p_i2104_5_), Biome.DEF_BIOME); - this.inDesert = biomegenbase == Biome.desert || biomegenbase == Biome.desertHills; + BaseBiome biomegenbase = genIn.getBiomeGenerator(new BlockPos(p_i2104_4_, 0, p_i2104_5_), BaseBiome.DEF_BIOME); + this.inDesert = biomegenbase == BaseBiome.DESERT || biomegenbase == BaseBiome.DESERTHILLS; this.func_175846_a(this.inDesert); } diff --git a/common/src/common/worldgen/tree/WorldGenBaseTree.java b/server/src/server/worldgen/tree/WorldGenBaseTree.java similarity index 95% rename from common/src/common/worldgen/tree/WorldGenBaseTree.java rename to server/src/server/worldgen/tree/WorldGenBaseTree.java index 83768cc..c5cacd0 100755 --- a/common/src/common/worldgen/tree/WorldGenBaseTree.java +++ b/server/src/server/worldgen/tree/WorldGenBaseTree.java @@ -1,4 +1,4 @@ -package common.worldgen.tree; +package server.worldgen.tree; import common.block.Block; import common.block.BlockCocoa; @@ -11,7 +11,7 @@ import common.rng.Random; import common.util.BlockPos; import common.util.Facing; import common.world.State; -import common.world.AWorldServer; +import server.world.WorldServer; public class WorldGenBaseTree extends WorldGenTree { @@ -42,7 +42,7 @@ public class WorldGenBaseTree extends WorldGenTree this.vinesGrow = vines; } - public boolean generate(AWorldServer worldIn, Random rand, BlockPos position) + public boolean generate(WorldServer worldIn, Random rand, BlockPos position) { int i = rand.zrange(3) + this.minTreeHeight; boolean flag = true; @@ -233,17 +233,17 @@ public class WorldGenBaseTree extends WorldGenTree } } - private void func_181652_a(AWorldServer p_181652_1_, int p_181652_2_, BlockPos p_181652_3_, Facing p_181652_4_) + private void func_181652_a(WorldServer p_181652_1_, int p_181652_2_, BlockPos p_181652_3_, Facing p_181652_4_) { this.setBlockAndNotifyAdequately(p_181652_1_, p_181652_3_, Blocks.cocoa.getState().withProperty(BlockCocoa.AGE, p_181652_2_).withProperty(BlockCocoa.FACING, p_181652_4_)); } - private void func_181651_a(AWorldServer p_181651_1_, BlockPos p_181651_2_, PropertyBool p_181651_3_) + private void func_181651_a(WorldServer p_181651_1_, BlockPos p_181651_2_, PropertyBool p_181651_3_) { this.setBlockAndNotifyAdequately(p_181651_1_, p_181651_2_, Blocks.vine.getState().withProperty(p_181651_3_, Boolean.valueOf(true))); } - private void func_181650_b(AWorldServer p_181650_1_, BlockPos p_181650_2_, PropertyBool p_181650_3_) + private void func_181650_b(WorldServer p_181650_1_, BlockPos p_181650_2_, PropertyBool p_181650_3_) { this.func_181651_a(p_181650_1_, p_181650_2_, p_181650_3_); int i = 4; diff --git a/common/src/common/worldgen/tree/WorldGenBigTree.java b/server/src/server/worldgen/tree/WorldGenBigTree.java similarity index 98% rename from common/src/common/worldgen/tree/WorldGenBigTree.java rename to server/src/server/worldgen/tree/WorldGenBigTree.java index 91f5588..ad648bb 100755 --- a/common/src/common/worldgen/tree/WorldGenBigTree.java +++ b/server/src/server/worldgen/tree/WorldGenBigTree.java @@ -1,4 +1,4 @@ -package common.worldgen.tree; +package server.worldgen.tree; import java.util.List; @@ -12,7 +12,7 @@ import common.rng.Random; import common.util.BlockPos; import common.util.ExtMath; import common.world.State; -import common.world.AWorldServer; +import server.world.WorldServer; public class WorldGenBigTree extends WorldGenTree { @@ -20,7 +20,7 @@ public class WorldGenBigTree extends WorldGenTree private final State logBase; private Random rand; - private AWorldServer world; + private WorldServer world; private BlockPos basePos = BlockPos.ORIGIN; private int heightLimit; private int height; @@ -322,7 +322,7 @@ public class WorldGenBigTree extends WorldGenTree this.leafDistanceLimit = 5; } - public boolean generate(AWorldServer worldIn, Random rand, BlockPos position) + public boolean generate(WorldServer worldIn, Random rand, BlockPos position) { this.world = worldIn; this.basePos = position; diff --git a/common/src/common/worldgen/tree/WorldGenBirch.java b/server/src/server/worldgen/tree/WorldGenBirch.java similarity index 96% rename from common/src/common/worldgen/tree/WorldGenBirch.java rename to server/src/server/worldgen/tree/WorldGenBirch.java index eb4da07..0659ee8 100755 --- a/common/src/common/worldgen/tree/WorldGenBirch.java +++ b/server/src/server/worldgen/tree/WorldGenBirch.java @@ -1,4 +1,4 @@ -package common.worldgen.tree; +package server.worldgen.tree; import common.block.Block; import common.block.BlockLeaves; @@ -7,7 +7,7 @@ import common.material.Material; import common.rng.Random; import common.util.BlockPos; import common.world.State; -import common.world.AWorldServer; +import server.world.WorldServer; public class WorldGenBirch extends WorldGenTree { @@ -23,7 +23,7 @@ public class WorldGenBirch extends WorldGenTree this.useExtraRandomHeight = extra; } - public boolean generate(AWorldServer worldIn, Random rand, BlockPos position) + public boolean generate(WorldServer worldIn, Random rand, BlockPos position) { int i = rand.zrange(3) + 5; diff --git a/common/src/common/worldgen/tree/WorldGenDarkOak.java b/server/src/server/worldgen/tree/WorldGenDarkOak.java similarity index 94% rename from common/src/common/worldgen/tree/WorldGenDarkOak.java rename to server/src/server/worldgen/tree/WorldGenDarkOak.java index 27d5298..09f1126 100755 --- a/common/src/common/worldgen/tree/WorldGenDarkOak.java +++ b/server/src/server/worldgen/tree/WorldGenDarkOak.java @@ -1,4 +1,4 @@ -package common.worldgen.tree; +package server.worldgen.tree; import common.block.Block; import common.block.BlockLeaves; @@ -8,7 +8,7 @@ import common.rng.Random; import common.util.BlockPos; import common.util.Facing; import common.world.State; -import common.world.AWorldServer; +import server.world.WorldServer; public class WorldGenDarkOak extends WorldGenTree { @@ -22,7 +22,7 @@ public class WorldGenDarkOak extends WorldGenTree super(notify); } - public boolean generate(AWorldServer worldIn, Random rand, BlockPos position) + public boolean generate(WorldServer worldIn, Random rand, BlockPos position) { int i = rand.zrange(3) + rand.zrange(2) + 6; int j = position.getX(); @@ -161,7 +161,7 @@ public class WorldGenDarkOak extends WorldGenTree } } - private boolean func_181638_a(AWorldServer p_181638_1_, BlockPos p_181638_2_, int p_181638_3_) + private boolean func_181638_a(WorldServer p_181638_1_, BlockPos p_181638_2_, int p_181638_3_) { int i = p_181638_2_.getX(); int j = p_181638_2_.getY(); @@ -197,7 +197,7 @@ public class WorldGenDarkOak extends WorldGenTree return true; } - private void func_181639_b(AWorldServer p_181639_1_, BlockPos p_181639_2_) + private void func_181639_b(WorldServer p_181639_1_, BlockPos p_181639_2_) { if (this.canBeReplaced(p_181639_1_.getState(p_181639_2_).getBlock())) { @@ -205,7 +205,7 @@ public class WorldGenDarkOak extends WorldGenTree } } - private void func_150526_a(AWorldServer worldIn, int p_150526_2_, int p_150526_3_, int p_150526_4_) + private void func_150526_a(WorldServer worldIn, int p_150526_2_, int p_150526_3_, int p_150526_4_) { BlockPos blockpos = new BlockPos(p_150526_2_, p_150526_3_, p_150526_4_); Block block = worldIn.getState(blockpos).getBlock(); diff --git a/common/src/common/worldgen/tree/WorldGenHugeTree.java b/server/src/server/worldgen/tree/WorldGenHugeTree.java similarity index 89% rename from common/src/common/worldgen/tree/WorldGenHugeTree.java rename to server/src/server/worldgen/tree/WorldGenHugeTree.java index d13cdf6..c5d50f1 100755 --- a/common/src/common/worldgen/tree/WorldGenHugeTree.java +++ b/server/src/server/worldgen/tree/WorldGenHugeTree.java @@ -1,4 +1,4 @@ -package common.worldgen.tree; +package server.worldgen.tree; import common.block.Block; import common.block.BlockLeaves; @@ -7,7 +7,7 @@ import common.material.Material; import common.rng.Random; import common.util.BlockPos; import common.world.State; -import common.world.AWorldServer; +import server.world.WorldServer; public abstract class WorldGenHugeTree extends WorldGenTree { @@ -42,7 +42,7 @@ public abstract class WorldGenHugeTree extends WorldGenTree return i; } - private boolean func_175926_c(AWorldServer worldIn, BlockPos p_175926_2_, int p_175926_3_) + private boolean func_175926_c(WorldServer worldIn, BlockPos p_175926_2_, int p_175926_3_) { boolean flag = true; @@ -81,7 +81,7 @@ public abstract class WorldGenHugeTree extends WorldGenTree } } - private boolean func_175927_a(BlockPos p_175927_1_, AWorldServer worldIn) + private boolean func_175927_a(BlockPos p_175927_1_, WorldServer worldIn) { BlockPos blockpos = p_175927_1_.down(); Block block = worldIn.getState(blockpos).getBlock(); @@ -100,12 +100,12 @@ public abstract class WorldGenHugeTree extends WorldGenTree } } - protected boolean func_175929_a(AWorldServer worldIn, Random p_175929_2_, BlockPos p_175929_3_, int p_175929_4_) + protected boolean func_175929_a(WorldServer worldIn, Random p_175929_2_, BlockPos p_175929_3_, int p_175929_4_) { return this.func_175926_c(worldIn, p_175929_3_, p_175929_4_) && this.func_175927_a(p_175929_3_, worldIn); } - protected void func_175925_a(AWorldServer worldIn, BlockPos p_175925_2_, int p_175925_3_) + protected void func_175925_a(WorldServer worldIn, BlockPos p_175925_2_, int p_175925_3_) { int i = p_175925_3_ * p_175925_3_; @@ -130,7 +130,7 @@ public abstract class WorldGenHugeTree extends WorldGenTree } } - protected void func_175928_b(AWorldServer worldIn, BlockPos p_175928_2_, int p_175928_3_) + protected void func_175928_b(WorldServer worldIn, BlockPos p_175928_2_, int p_175928_3_) { int i = p_175928_3_ * p_175928_3_; diff --git a/common/src/common/worldgen/tree/WorldGenJungle.java b/server/src/server/worldgen/tree/WorldGenJungle.java similarity index 92% rename from common/src/common/worldgen/tree/WorldGenJungle.java rename to server/src/server/worldgen/tree/WorldGenJungle.java index cd68e7a..1edd2d4 100755 --- a/common/src/common/worldgen/tree/WorldGenJungle.java +++ b/server/src/server/worldgen/tree/WorldGenJungle.java @@ -1,4 +1,4 @@ -package common.worldgen.tree; +package server.worldgen.tree; import common.block.BlockVine; import common.init.Blocks; @@ -7,7 +7,7 @@ import common.rng.Random; import common.util.BlockPos; import common.util.ExtMath; import common.world.State; -import common.world.AWorldServer; +import server.world.WorldServer; public class WorldGenJungle extends WorldGenHugeTree { @@ -16,7 +16,7 @@ public class WorldGenJungle extends WorldGenHugeTree super(p_i46448_1_, p_i46448_2_, p_i46448_3_, p_i46448_4_, p_i46448_5_); } - public boolean generate(AWorldServer worldIn, Random rand, BlockPos position) + public boolean generate(WorldServer worldIn, Random rand, BlockPos position) { int i = this.func_150533_a(rand); @@ -113,7 +113,7 @@ public class WorldGenJungle extends WorldGenHugeTree } } - private void func_181632_a(AWorldServer p_181632_1_, Random p_181632_2_, BlockPos p_181632_3_, PropertyBool p_181632_4_) + private void func_181632_a(WorldServer p_181632_1_, Random p_181632_2_, BlockPos p_181632_3_, PropertyBool p_181632_4_) { if (p_181632_2_.zrange(3) > 0 && p_181632_1_.isAirBlock(p_181632_3_)) { @@ -121,7 +121,7 @@ public class WorldGenJungle extends WorldGenHugeTree } } - private void func_175930_c(AWorldServer worldIn, BlockPos p_175930_2_, int p_175930_3_) + private void func_175930_c(WorldServer worldIn, BlockPos p_175930_2_, int p_175930_3_) { int i = 2; diff --git a/common/src/common/worldgen/tree/WorldGenPine.java b/server/src/server/worldgen/tree/WorldGenPine.java similarity index 89% rename from common/src/common/worldgen/tree/WorldGenPine.java rename to server/src/server/worldgen/tree/WorldGenPine.java index b4ffb5c..4c90945 100755 --- a/common/src/common/worldgen/tree/WorldGenPine.java +++ b/server/src/server/worldgen/tree/WorldGenPine.java @@ -1,4 +1,4 @@ -package common.worldgen.tree; +package server.worldgen.tree; import common.block.Block; import common.block.BlockDirt; @@ -8,7 +8,7 @@ import common.rng.Random; import common.util.BlockPos; import common.util.ExtMath; import common.world.State; -import common.world.AWorldServer; +import server.world.WorldServer; public class WorldGenPine extends WorldGenHugeTree { @@ -23,7 +23,7 @@ public class WorldGenPine extends WorldGenHugeTree this.useBaseHeight = p_i45457_2_; } - public boolean generate(AWorldServer worldIn, Random rand, BlockPos position) + public boolean generate(WorldServer worldIn, Random rand, BlockPos position) { int i = this.func_150533_a(rand); @@ -73,7 +73,7 @@ public class WorldGenPine extends WorldGenHugeTree } } - private void func_150541_c(AWorldServer worldIn, int p_150541_2_, int p_150541_3_, int p_150541_4_, int p_150541_5_, Random p_150541_6_) + private void func_150541_c(WorldServer worldIn, int p_150541_2_, int p_150541_3_, int p_150541_4_, int p_150541_5_, Random p_150541_6_) { int i = p_150541_6_.zrange(5) + (this.useBaseHeight ? this.baseHeight : 3); int j = 0; @@ -87,7 +87,7 @@ public class WorldGenPine extends WorldGenHugeTree } } - public void finish(AWorldServer worldIn, Random p_180711_2_, BlockPos p_180711_3_) + public void finish(WorldServer worldIn, Random p_180711_2_, BlockPos p_180711_3_) { this.func_175933_b(worldIn, p_180711_3_.west().north()); this.func_175933_b(worldIn, p_180711_3_.east(2).north()); @@ -107,7 +107,7 @@ public class WorldGenPine extends WorldGenHugeTree } } - private void func_175933_b(AWorldServer worldIn, BlockPos p_175933_2_) + private void func_175933_b(WorldServer worldIn, BlockPos p_175933_2_) { for (int i = -2; i <= 2; ++i) { @@ -121,7 +121,7 @@ public class WorldGenPine extends WorldGenHugeTree } } - private void func_175934_c(AWorldServer worldIn, BlockPos p_175934_2_) + private void func_175934_c(WorldServer worldIn, BlockPos p_175934_2_) { for (int i = 2; i >= -3; --i) { diff --git a/common/src/common/worldgen/tree/WorldGenSavanna.java b/server/src/server/worldgen/tree/WorldGenSavanna.java similarity index 96% rename from common/src/common/worldgen/tree/WorldGenSavanna.java rename to server/src/server/worldgen/tree/WorldGenSavanna.java index c9f37cd..c348cca 100755 --- a/common/src/common/worldgen/tree/WorldGenSavanna.java +++ b/server/src/server/worldgen/tree/WorldGenSavanna.java @@ -1,4 +1,4 @@ -package common.worldgen.tree; +package server.worldgen.tree; import common.block.Block; import common.block.BlockLeaves; @@ -8,7 +8,7 @@ import common.rng.Random; import common.util.BlockPos; import common.util.Facing; import common.world.State; -import common.world.AWorldServer; +import server.world.WorldServer; public class WorldGenSavanna extends WorldGenTree { @@ -23,7 +23,7 @@ public class WorldGenSavanna extends WorldGenTree super(p_i45463_1_); } - public boolean generate(AWorldServer worldIn, Random rand, BlockPos position) + public boolean generate(WorldServer worldIn, Random rand, BlockPos position) { int i = rand.zrange(3) + rand.zrange(3) + 5; boolean flag = true; @@ -202,12 +202,12 @@ public class WorldGenSavanna extends WorldGenTree } } - private void func_181642_b(AWorldServer p_181642_1_, BlockPos p_181642_2_) + private void func_181642_b(WorldServer p_181642_1_, BlockPos p_181642_2_) { this.setBlockAndNotifyAdequately(p_181642_1_, p_181642_2_, field_181643_a); } - private void func_175924_b(AWorldServer worldIn, BlockPos p_175924_2_) + private void func_175924_b(WorldServer worldIn, BlockPos p_175924_2_) { Material material = worldIn.getState(p_175924_2_).getBlock().getMaterial(); diff --git a/common/src/common/worldgen/tree/WorldGenSwamp.java b/server/src/server/worldgen/tree/WorldGenSwamp.java similarity index 96% rename from common/src/common/worldgen/tree/WorldGenSwamp.java rename to server/src/server/worldgen/tree/WorldGenSwamp.java index ea77f4c..f8ff143 100755 --- a/common/src/common/worldgen/tree/WorldGenSwamp.java +++ b/server/src/server/worldgen/tree/WorldGenSwamp.java @@ -1,4 +1,4 @@ -package common.worldgen.tree; +package server.worldgen.tree; import common.block.Block; import common.block.BlockLeaves; @@ -9,7 +9,7 @@ import common.properties.PropertyBool; import common.rng.Random; import common.util.BlockPos; import common.world.State; -import common.world.AWorldServer; +import server.world.WorldServer; public class WorldGenSwamp extends WorldGenTree { @@ -24,7 +24,7 @@ public class WorldGenSwamp extends WorldGenTree super(false); } - public boolean generate(AWorldServer worldIn, Random rand, BlockPos position) + public boolean generate(WorldServer worldIn, Random rand, BlockPos position) { int i; @@ -186,7 +186,7 @@ public class WorldGenSwamp extends WorldGenTree } } - private void func_181647_a(AWorldServer p_181647_1_, BlockPos p_181647_2_, PropertyBool p_181647_3_) + private void func_181647_a(WorldServer p_181647_1_, BlockPos p_181647_2_, PropertyBool p_181647_3_) { State iblockstate = Blocks.vine.getState().withProperty(p_181647_3_, Boolean.valueOf(true)); this.setBlockAndNotifyAdequately(p_181647_1_, p_181647_2_, iblockstate); diff --git a/common/src/common/worldgen/tree/WorldGenTaiga1.java b/server/src/server/worldgen/tree/WorldGenTaiga1.java similarity index 96% rename from common/src/common/worldgen/tree/WorldGenTaiga1.java rename to server/src/server/worldgen/tree/WorldGenTaiga1.java index c9a2b45..a3fed91 100755 --- a/common/src/common/worldgen/tree/WorldGenTaiga1.java +++ b/server/src/server/worldgen/tree/WorldGenTaiga1.java @@ -1,4 +1,4 @@ -package common.worldgen.tree; +package server.worldgen.tree; import common.block.Block; import common.block.BlockLeaves; @@ -7,7 +7,7 @@ import common.material.Material; import common.rng.Random; import common.util.BlockPos; import common.world.State; -import common.world.AWorldServer; +import server.world.WorldServer; public class WorldGenTaiga1 extends WorldGenTree { @@ -22,7 +22,7 @@ public class WorldGenTaiga1 extends WorldGenTree super(false); } - public boolean generate(AWorldServer worldIn, Random rand, BlockPos position) + public boolean generate(WorldServer worldIn, Random rand, BlockPos position) { int i = rand.zrange(5) + 7; int j = i - rand.zrange(2) - 3; diff --git a/common/src/common/worldgen/tree/WorldGenTaiga2.java b/server/src/server/worldgen/tree/WorldGenTaiga2.java similarity index 97% rename from common/src/common/worldgen/tree/WorldGenTaiga2.java rename to server/src/server/worldgen/tree/WorldGenTaiga2.java index 10f3ec1..681bd4f 100755 --- a/common/src/common/worldgen/tree/WorldGenTaiga2.java +++ b/server/src/server/worldgen/tree/WorldGenTaiga2.java @@ -1,4 +1,4 @@ -package common.worldgen.tree; +package server.worldgen.tree; import common.block.Block; import common.block.BlockLeaves; @@ -7,7 +7,7 @@ import common.material.Material; import common.rng.Random; import common.util.BlockPos; import common.world.State; -import common.world.AWorldServer; +import server.world.WorldServer; public class WorldGenTaiga2 extends WorldGenTree { @@ -22,7 +22,7 @@ public class WorldGenTaiga2 extends WorldGenTree super(p_i2025_1_); } - public boolean generate(AWorldServer worldIn, Random rand, BlockPos position) + public boolean generate(WorldServer worldIn, Random rand, BlockPos position) { int i = rand.zrange(4) + 6; int j = 1 + rand.zrange(2); diff --git a/common/src/common/worldgen/tree/WorldGenTree.java b/server/src/server/worldgen/tree/WorldGenTree.java similarity index 79% rename from common/src/common/worldgen/tree/WorldGenTree.java rename to server/src/server/worldgen/tree/WorldGenTree.java index 4ea8b65..964385a 100755 --- a/common/src/common/worldgen/tree/WorldGenTree.java +++ b/server/src/server/worldgen/tree/WorldGenTree.java @@ -1,4 +1,4 @@ -package common.worldgen.tree; +package server.worldgen.tree; import common.block.Block; import common.block.BlockLog; @@ -7,8 +7,8 @@ import common.init.Blocks; import common.material.Material; import common.rng.Random; import common.util.BlockPos; -import common.world.AWorldServer; -import common.worldgen.FeatureGenerator; +import server.world.WorldServer; +import server.worldgen.FeatureGenerator; public abstract class WorldGenTree extends FeatureGenerator { @@ -27,11 +27,11 @@ public abstract class WorldGenTree extends FeatureGenerator { } - public void finish(AWorldServer worldIn, Random random, BlockPos pos) + public void finish(WorldServer worldIn, Random random, BlockPos pos) { } - protected void setBaseBlock(AWorldServer worldIn, BlockPos pos) + protected void setBaseBlock(WorldServer worldIn, BlockPos pos) { if (worldIn.getState(pos) != worldIn.dimension.getTop()) { From eba8f6ea983359da753881300b13b106488548c9 Mon Sep 17 00:00:00 2001 From: Sen Date: Wed, 14 May 2025 14:58:06 +0200 Subject: [PATCH 029/200] login + network changes, add forms --- client/src/client/Client.java | 9 +- client/src/client/gui/ingame/GuiForm.java | 118 ++++++++++ client/src/client/gui/ingame/GuiSign.java | 13 +- client/src/client/network/ClientPlayer.java | 13 +- common/src/common/biome/BaseBiome.java | 2 +- common/src/common/block/BlockSign.java | 17 ++ common/src/common/init/Config.java | 8 +- common/src/common/network/IClientPlayer.java | 4 +- common/src/common/network/IPlayer.java | 3 + common/src/common/network/PacketRegistry.java | 5 +- common/src/common/packet/CPacketForm.java | 86 +++++++ .../src/common/packet/SPacketDisconnect.java | 43 ++-- .../src/common/packet/SPacketDisplayForm.java | 99 ++++++++ common/src/common/util/Triplet.java | 10 + server/src/server/Server.java | 212 +++++++++++------- server/src/server/command/ArgumentParser.java | 2 +- server/src/server/command/BooleanParser.java | 4 +- .../src/server/command/CachedExecutable.java | 2 +- server/src/server/command/Command.java | 8 + .../server/command/CommandEnvironment.java | 6 + .../src/server/command/DimensionParser.java | 2 +- server/src/server/command/DoubleParser.java | 4 +- .../src/server/command/EntityListParser.java | 2 +- server/src/server/command/EntityParser.java | 2 +- server/src/server/command/EnumParser.java | 2 +- server/src/server/command/Executor.java | 9 + server/src/server/command/FixedExecutor.java | 4 + server/src/server/command/IntParser.java | 4 +- server/src/server/command/LongParser.java | 4 +- .../command/PlayerEntityListParser.java | 2 +- .../server/command/PlayerEntityParser.java | 2 +- .../src/server/command/PlayerListParser.java | 2 +- server/src/server/command/PlayerParser.java | 4 +- server/src/server/command/StringParser.java | 2 +- server/src/server/command/TagParser.java | 2 +- server/src/server/command/WorldParser.java | 2 +- .../server/command/commands/CommandKick.java | 10 +- .../command/commands/CommandPasswd.java | 64 ++++++ .../command/commands/CommandRebind.java | 17 ++ .../command/commands/CommandRevoke.java | 2 +- .../command/commands/CommandShutdown.java | 18 ++ .../server/command/commands/CommandSpawn.java | 2 +- server/src/server/network/Player.java | 113 +++------- server/src/server/util/Form.java | 179 +++++++++++++++ 44 files changed, 894 insertions(+), 224 deletions(-) create mode 100644 client/src/client/gui/ingame/GuiForm.java create mode 100644 common/src/common/packet/CPacketForm.java create mode 100644 common/src/common/packet/SPacketDisplayForm.java create mode 100644 common/src/common/util/Triplet.java create mode 100644 server/src/server/command/commands/CommandPasswd.java create mode 100644 server/src/server/command/commands/CommandRebind.java create mode 100644 server/src/server/command/commands/CommandShutdown.java create mode 100644 server/src/server/util/Form.java diff --git a/client/src/client/Client.java b/client/src/client/Client.java index 3547751..0d67257 100755 --- a/client/src/client/Client.java +++ b/client/src/client/Client.java @@ -765,6 +765,7 @@ public class Client implements IThreadListener { else if (this.connection != null) { this.connection.processReceivedPackets(); + this.connection.checkDisconnected(); } } @@ -2388,11 +2389,9 @@ public class Client implements IThreadListener { } public void unload(boolean loading) { - if(this.world != null) { - if(this.getNetHandler() != null) - this.getNetHandler().getNetworkManager().closeChannel("Quitting"); - this.unloadWorld(); - } + if(this.world != null && this.getNetHandler() != null) + this.getNetHandler().getNetworkManager().closeChannel("Quitting"); + this.unloadWorld(); this.displayGuiScreen(GuiMenu.INSTANCE); } diff --git a/client/src/client/gui/ingame/GuiForm.java b/client/src/client/gui/ingame/GuiForm.java new file mode 100644 index 0000000..33dd965 --- /dev/null +++ b/client/src/client/gui/ingame/GuiForm.java @@ -0,0 +1,118 @@ +package client.gui.ingame; + +import client.gui.Gui; +import client.gui.element.ActButton; +import client.gui.element.ActButton.Mode; +import client.gui.element.Element; +import client.gui.element.Label; +import client.gui.element.NavButton; +import client.gui.element.Switch; +import client.gui.element.Textbox; +import client.gui.element.Textbox.Action; +import client.gui.element.Toggle; +import client.network.ClientPlayer; +import common.color.TextColor; +import common.packet.CPacketForm; +import common.util.ExtMath; +import common.util.Triplet; + +public class GuiForm extends Gui implements ActButton.Callback { + private final int id; + private final String title; + private final Element[] inputs; + private final Label[] labels; + private final Triplet[] inputData; + private final Object[] outputData; + + private boolean sent; + + public void init(int width, int height) { + this.add(new Label(0, -100, 300, 20, this.title)); + for(int z = 0; z < this.inputs.length; z++) { + final int index = z; + final String name = this.inputData[z].first; + Object obj = this.inputData[z].second; + int param = this.inputData[z].third; + if(obj instanceof Boolean) { + this.inputs[z] = this.add(new Toggle(0, 50 * z, 300, 24, (Boolean)obj, (Boolean)obj, new Toggle.Callback() { + public void use(Toggle elem, boolean value) { + GuiForm.this.outputData[index] = value; + } + }, name)); + } + else if(obj instanceof String[]) { + final String[] strs = (String[])obj; + param = ExtMath.clampi(param, 0, strs.length - 1); + this.inputs[z] = this.add(new Switch(0, 50 * z, 300, 24, strs, strs[param], strs[param], new Switch.Callback() { + public void use(Switch elem, String value) { + for(int n = 0; n < strs.length; n++) { + if(value == strs[n]) { + GuiForm.this.outputData[index] = n; + break; + } + } + } + }, name)); + } + else { + this.labels[z] = this.add(new Label(0, 50 * z - 20, 300, 20, name, true)); + this.inputs[z] = this.add(new Textbox(0, 50 * z, 300, 24, Math.min(param & 0xffff, 256), true, new Textbox.Callback() { + public void use(Textbox elem, Action value) { + if(value == Action.FOCUS) + GuiForm.this.labels[index].setText(name); + } + }, (String)obj)); + } + } + this.add(new NavButton(0, 50 * (this.inputs.length + 1), 148, 24, null, "Abbrechen")); + this.add(new ActButton(152, 50 * (this.inputs.length + 1), 148, 24, this, "Senden")); + this.shift(); + } + + public String getTitle() { + return this.title; + } + + public void onGuiClosed() { + if(!this.sent) { + ClientPlayer nethandler = this.gm.getNetHandler(); + if(nethandler != null) { + nethandler.addToSendQueue(new CPacketForm(this.id, null)); + } + } + } + + public GuiForm(int id, String title, Triplet[] data) { + this.id = id; + this.title = title; + this.inputs = new Element[data.length]; + this.labels = new Label[data.length]; + this.inputData = data; + this.outputData = new Object[data.length]; + for(int z = 0; z < data.length; z++) { + Object obj = data[z].second; + this.outputData[z] = obj instanceof String[] ? data[z].third : obj; + } + } + + public void use(ActButton elem, Mode action) { + for(int z = 0; z < this.inputs.length; z++) { + if(this.inputs[z] instanceof Textbox) { + int min = this.inputData[z].third >> 16; + String text = this.inputs[z].getText(); + if(text.length() < min) { + if(!GuiForm.this.labels[z].getText().startsWith("" + TextColor.RED)) + GuiForm.this.labels[z].setText(TextColor.RED + GuiForm.this.labels[z].getText()); + return; + } + this.outputData[z] = text; + } + } + this.sent = true; + ClientPlayer nethandler = this.gm.getNetHandler(); + if(nethandler != null) { + nethandler.addToSendQueue(new CPacketForm(this.id, this.outputData)); + } + this.gm.displayGuiScreen(null); + } +} diff --git a/client/src/client/gui/ingame/GuiSign.java b/client/src/client/gui/ingame/GuiSign.java index 457c151..65eb72c 100644 --- a/client/src/client/gui/ingame/GuiSign.java +++ b/client/src/client/gui/ingame/GuiSign.java @@ -1,6 +1,7 @@ package client.gui.ingame; import client.gui.Gui; +import client.gui.element.Label; import client.gui.element.NavButton; import client.gui.element.Textbox; import client.gui.element.Textbox.Action; @@ -10,11 +11,14 @@ import common.util.BlockPos; public class GuiSign extends Gui implements Textbox.Callback { private final BlockPos position; - private final Textbox[] lines = new Textbox[4]; - private final String[] tempLines = new String[this.lines.length]; + private final Textbox[] lines; + private final String[] tempLines; public void init(int width, int height) { + this.add(new Label(0, -140, 300, 20, "Bearbeite Schild")); + this.add(new Label(0, -80, 300, 20, String.format("%d, %d, %d", this.position.getX(), this.position.getY(), this.position.getZ()))); + this.add(new Label(0, -50, 300, 20, this.gm.world == null ? "" : this.gm.world.dimension.getFormattedName(false))); for(int z = 0; z < this.lines.length; z++) { this.lines[z] = this.add(new Textbox(0, 40 * z, 300, 24, 50, true, this, this.tempLines[z] == null ? "" : this.tempLines[z])); } @@ -25,7 +29,6 @@ public class GuiSign extends Gui implements Textbox.Callback { public String getTitle() { return "Schild bearbeiten"; } - public void onGuiClosed() { ClientPlayer nethandler = this.gm.getNetHandler(); @@ -39,7 +42,9 @@ public class GuiSign extends Gui implements Textbox.Callback { public GuiSign(BlockPos sign, String[] lines) { this.position = sign; - System.arraycopy(lines, 0, this.tempLines, 0, this.lines.length); + this.lines = new Textbox[lines.length]; + this.tempLines = new String[lines.length]; + System.arraycopy(lines, 0, this.tempLines, 0, lines.length); } public void use(Textbox elem, Action value) { diff --git a/client/src/client/network/ClientPlayer.java b/client/src/client/network/ClientPlayer.java index eb1cbc1..eb3c533 100755 --- a/client/src/client/network/ClientPlayer.java +++ b/client/src/client/network/ClientPlayer.java @@ -25,6 +25,7 @@ import client.gui.container.GuiMachine; import client.gui.container.GuiMerchant; import client.gui.container.GuiRepair; import client.gui.ingame.GuiSign; +import client.gui.ingame.GuiForm; import client.renderer.particle.EntityPickupFX; import client.renderer.texture.EntityTexManager; import client.world.WorldClient; @@ -104,6 +105,7 @@ import common.packet.SPacketCollectItem; import common.packet.SPacketDestroyEntities; import common.packet.SPacketDimensionName; import common.packet.SPacketDisconnect; +import common.packet.SPacketDisplayForm; import common.packet.SPacketEntityEquipment; import common.packet.SPacketEntityVelocity; import common.packet.SPacketHeldItemChange; @@ -795,7 +797,7 @@ public class ClientPlayer extends NetHandler implements IClientPlayer */ public void handleDisconnect(SPacketDisconnect packetIn) { - this.netManager.closeChannel("Getrennt"); + this.netManager.closeChannel(packetIn.getMessage()); } public void onDisconnect(String reason) @@ -1284,6 +1286,11 @@ public class ClientPlayer extends NetHandler implements IClientPlayer this.gameController.player.openEditSign((TileEntitySign)tileentity); } + + public void handleForm(SPacketDisplayForm packet) { + NetHandler.checkThread(packet, this, this.gameController, this.clientWorldController); + this.gameController.displayGuiScreen(new GuiForm(packet.getId(), packet.getTitle(), packet.getData())); + } /** * Updates a specified sign with the specified text lines @@ -2061,8 +2068,8 @@ public class ClientPlayer extends NetHandler implements IClientPlayer this.gameController.displayGuiScreen(new GuiMerchant(inventory, title, worldObj)); } - public void displayGuiSign(BlockPos pos, String[] signText) { - this.gameController.displayGuiScreen(new GuiSign(pos, signText)); + public void displayGuiSign(BlockPos pos, String[] text) { + this.gameController.displayGuiScreen(new GuiSign(pos, text)); } public void closeGui() { diff --git a/common/src/common/biome/BaseBiome.java b/common/src/common/biome/BaseBiome.java index c2de8dd..81c9b42 100644 --- a/common/src/common/biome/BaseBiome.java +++ b/common/src/common/biome/BaseBiome.java @@ -28,7 +28,7 @@ public enum BaseBiome { ICEPLAINS(12, "icePlains", "Eisebene", 0xffffff, -20.0f), ICEMOUNTAINS(13, "iceMountains", "Vereistes Bergland", 0xa0a0a0, -20.0f), MUSHROOMPLAINS(14, "mushroomPlains", "Pilzland", 0xff00ff, 16.0f, 100.0f), - BLACKENED(15, "blackened", "Schwarz", 0x000000, 0.0f, 0.0f), + BLACKENED(15, "blackened", "Schwarz", 0x000000, 0.0f, 0.0f, 0x000000, 0x303030, 0x303030), BEACH(16, "beach", "Strand", 0xfade55, 12.0f, 40.0f), DESERTHILLS(17, "desertHills", "Wüsten-Bergland", 0xd25f12, 60.0f, 0.0f), FORESTHILLS(18, "forestHills", "Wald-Bergland", 0x22551c, 8.0f, 80.0f), diff --git a/common/src/common/block/BlockSign.java b/common/src/common/block/BlockSign.java index 70691aa..aa1aedf 100755 --- a/common/src/common/block/BlockSign.java +++ b/common/src/common/block/BlockSign.java @@ -1,5 +1,7 @@ package common.block; +import common.entity.npc.EntityNPC; +import common.init.Config; import common.init.Items; import common.item.Item; import common.material.Material; @@ -8,6 +10,7 @@ import common.tileentity.TileEntity; import common.tileentity.TileEntitySign; import common.util.BlockPos; import common.util.BoundingBox; +import common.util.Facing; import common.world.IBlockAccess; import common.world.State; import common.world.World; @@ -22,6 +25,20 @@ public class BlockSign extends BlockContainer this.setBlockBounds(0.5F - f, 0.0F, 0.5F - f, 0.5F + f, f1, 0.5F + f); } + public boolean onBlockActivated(World worldIn, BlockPos pos, State state, EntityNPC playerIn, Facing side, float hitX, float hitY, float hitZ) + { + if (!worldIn.client && Config.editSigns) + { + TileEntity tileentity = worldIn.getTileEntity(pos); + + if (tileentity instanceof TileEntitySign) + { + playerIn.openEditSign((TileEntitySign)tileentity); + } + } + return true; + } + public BoundingBox getCollisionBoundingBox(World worldIn, BlockPos pos, State state) { return null; diff --git a/common/src/common/init/Config.java b/common/src/common/init/Config.java index 3393db2..483ee54 100755 --- a/common/src/common/init/Config.java +++ b/common/src/common/init/Config.java @@ -333,8 +333,12 @@ public abstract class Config { public static boolean itemFallDamage = true; @Var(name = "registration") public static boolean register = true; + @Var(name = "authentication") + public static boolean auth = true; @Var(name = "preload_chunks") public static boolean preload = true; + @Var(name = "signEditing") + public static boolean editSigns = true; @Var(name = "keepInventory") public static boolean keepInventory = false; @@ -348,8 +352,6 @@ public abstract class Config { public static boolean rabidRabbits = false; @Var(name = "snowStacking") public static boolean snowStack = false; - @Var(name = "authentication") - public static boolean auth = false; // @Var(name = "teleportForAll") // public static boolean teleportAllowed = false; // @Var(name = "preload_chunks_all") // Vorsicht Lag!! @@ -454,6 +456,8 @@ public abstract class Config { public static int eggTimer = 6000; @Var(name = "connectionTimeout", min = 10, max = 300) public static int timeout = 30; + @Var(name = "passwordMinLength", min = 1, max = 32) + public static int minPassLength = 8; // @Var(name = "spawnX", min = -World.MAX_SIZE + 1, max = World.MAX_SIZE - 1) // public static int spawnX = 0; diff --git a/common/src/common/network/IClientPlayer.java b/common/src/common/network/IClientPlayer.java index fc6ac1d..b412c36 100644 --- a/common/src/common/network/IClientPlayer.java +++ b/common/src/common/network/IClientPlayer.java @@ -45,6 +45,7 @@ import common.packet.SPacketCollectItem; import common.packet.SPacketDestroyEntities; import common.packet.SPacketDimensionName; import common.packet.SPacketDisconnect; +import common.packet.SPacketDisplayForm; import common.packet.SPacketEntityEquipment; import common.packet.SPacketEntityVelocity; import common.packet.SPacketHeldItemChange; @@ -146,11 +147,12 @@ public interface IClientPlayer { void handleTrades(SPacketTrades packetIn); void handleWorld(SPacketWorld packetIn); void handleDimName(SPacketDimensionName packetIn); + void handleForm(SPacketDisplayForm packet); void displayGUIChest(IInventory chestInventory, InventoryPlayer inventory); void displayGui(IInteractionObject guiOwner, InventoryPlayer inventory, World worldObj); void displayGuiHorse(EntityHorse horse, InventoryPlayer inventory, IInventory horseInventory); void displayGuiMerchant(String title, InventoryPlayer inventory, World worldObj); - void displayGuiSign(BlockPos pos, String[] signText); + void displayGuiSign(BlockPos pos, String[] text); void closeGui(); } \ No newline at end of file diff --git a/common/src/common/network/IPlayer.java b/common/src/common/network/IPlayer.java index a78d4fb..42d3fb6 100644 --- a/common/src/common/network/IPlayer.java +++ b/common/src/common/network/IPlayer.java @@ -16,6 +16,7 @@ import common.packet.CPacketBreak; import common.packet.CPacketCheat; import common.packet.CPacketClick; import common.packet.CPacketComplete; +import common.packet.CPacketForm; import common.packet.CPacketInput; import common.packet.CPacketKeepAlive; import common.packet.CPacketMessage; @@ -166,6 +167,8 @@ public interface IPlayer { void processSkin(CPacketSkin packetIn); void processBook(CPacketBook packetIn); + + void processForm(CPacketForm packet); List getLoadedChunkList(); double getManagedX(); diff --git a/common/src/common/network/PacketRegistry.java b/common/src/common/network/PacketRegistry.java index 60f2e0d..0a13153 100755 --- a/common/src/common/network/PacketRegistry.java +++ b/common/src/common/network/PacketRegistry.java @@ -11,6 +11,7 @@ import common.packet.CPacketBreak; import common.packet.CPacketCheat; import common.packet.CPacketClick; import common.packet.CPacketComplete; +import common.packet.CPacketForm; import common.packet.CPacketInput; import common.packet.CPacketKeepAlive; import common.packet.CPacketMessage; @@ -63,6 +64,7 @@ import common.packet.SPacketCollectItem; import common.packet.SPacketDestroyEntities; import common.packet.SPacketDimensionName; import common.packet.SPacketDisconnect; +import common.packet.SPacketDisplayForm; import common.packet.SPacketEntityEquipment; import common.packet.SPacketEntityVelocity; import common.packet.SPacketHeldItemChange; @@ -181,6 +183,7 @@ public enum PacketRegistry this.server(SPacketCharacterList.class); this.server(SPacketServerTick.class); this.server(SPacketLoading.class); + this.server(SPacketDisplayForm.class); this.client(CPacketKeepAlive.class); this.client(CPacketMessage.class); @@ -198,7 +201,7 @@ public enum PacketRegistry this.client(CPacketSkin.class); this.client(CPacketSign.class); this.client(CPacketBook.class); -// this.client(CPacketCmdBlock.class); + this.client(CPacketForm.class); } }; diff --git a/common/src/common/packet/CPacketForm.java b/common/src/common/packet/CPacketForm.java new file mode 100644 index 0000000..136fccc --- /dev/null +++ b/common/src/common/packet/CPacketForm.java @@ -0,0 +1,86 @@ +package common.packet; + +import java.io.IOException; + +import common.network.IPlayer; +import common.network.Packet; +import common.network.PacketBuffer; + +public class CPacketForm implements Packet +{ + private int id; + private Object[] data; + + public CPacketForm() + { + } + + public CPacketForm(int id, Object[] data) + { + this.id = id; + this.data = data; + } + + public void readPacketData(PacketBuffer buf) throws IOException + { + this.id = buf.readVarIntFromBuffer(); + if(!buf.readBoolean()) { + this.data = null; + return; + } + this.data = new Object[buf.readVarIntFromBuffer()]; + for(int z = 0; z < this.data.length; z++) { + Object obj; + switch(buf.readByte()) { + case 0: + obj = buf.readBoolean(); + break; + case 1: + obj = buf.readVarIntFromBuffer(); + break; + default: + obj = buf.readStringFromBuffer(256); + break; + } + this.data[z] = obj; + } + } + + public void writePacketData(PacketBuffer buf) throws IOException + { + buf.writeVarIntToBuffer(this.id); + buf.writeBoolean(this.data != null); + if(this.data == null) + return; + buf.writeVarIntToBuffer(this.data.length); + for(int z = 0; z < this.data.length; z++) { + Object obj = this.data[z]; + if(obj instanceof Boolean) { + buf.writeByte(0); + buf.writeBoolean((Boolean)obj); + } + else if(obj instanceof Integer) { + buf.writeByte(1); + buf.writeVarIntToBuffer((Integer)obj); + } + else { + buf.writeByte(2); + buf.writeString((String)obj); + } + } + } + + public void processPacket(IPlayer handler) + { + handler.processForm(this); + } + + public Object[] getData() + { + return this.data; + } + + public int getId() { + return this.id; + } +} diff --git a/common/src/common/packet/SPacketDisconnect.java b/common/src/common/packet/SPacketDisconnect.java index 5b690b7..133acdc 100755 --- a/common/src/common/packet/SPacketDisconnect.java +++ b/common/src/common/packet/SPacketDisconnect.java @@ -6,22 +6,29 @@ import common.network.IClientPlayer; import common.network.Packet; import common.network.PacketBuffer; -public class SPacketDisconnect implements Packet -{ - public SPacketDisconnect() - { - } - - public void readPacketData(PacketBuffer buf) throws IOException - { - } - - public void writePacketData(PacketBuffer buf) throws IOException - { - } - - public void processPacket(IClientPlayer handler) - { - handler.handleDisconnect(this); - } +public class SPacketDisconnect implements Packet { + private String message; + + public SPacketDisconnect() { + } + + public SPacketDisconnect(String message) { + this.message = message; + } + + public void readPacketData(PacketBuffer buf) throws IOException { + this.message = buf.readStringFromBuffer(2048); + } + + public void writePacketData(PacketBuffer buf) throws IOException { + buf.writeString(this.message); + } + + public void processPacket(IClientPlayer handler) { + handler.handleDisconnect(this); + } + + public String getMessage() { + return this.message; + } } diff --git a/common/src/common/packet/SPacketDisplayForm.java b/common/src/common/packet/SPacketDisplayForm.java new file mode 100644 index 0000000..372e8af --- /dev/null +++ b/common/src/common/packet/SPacketDisplayForm.java @@ -0,0 +1,99 @@ +package common.packet; + +import java.io.IOException; + +import common.network.IClientPlayer; +import common.network.Packet; +import common.network.PacketBuffer; +import common.util.Triplet; + +public class SPacketDisplayForm implements Packet +{ + private int id; + private String title; + private Triplet[] data; + + public SPacketDisplayForm() + { + } + + public SPacketDisplayForm(int id, String title, Triplet[] data) + { + this.id = id; + this.title = title; + this.data = data; + } + + public void processPacket(IClientPlayer handler) + { + handler.handleForm(this); + } + + public void readPacketData(PacketBuffer buf) throws IOException + { + this.id = buf.readVarIntFromBuffer(); + this.title = buf.readStringFromBuffer(256); + this.data = new Triplet[buf.readVarIntFromBuffer()]; + for(int z = 0; z < this.data.length; z++) { + String name = buf.readStringFromBuffer(64); + Object obj; + switch(buf.readByte()) { + case 0: + obj = buf.readBoolean(); + break; + case 1: + String[] strs = new String[buf.readVarIntFromBuffer()]; + obj = strs; + for(int n = 0; n < strs.length; n++) { + strs[n] = buf.readStringFromBuffer(128); + } + break; + default: + obj = buf.readStringFromBuffer(256); + break; + } + this.data[z] = new Triplet(name, obj, buf.readVarIntFromBuffer()); + } + } + + public void writePacketData(PacketBuffer buf) throws IOException + { + buf.writeVarIntToBuffer(this.id); + buf.writeString(this.title); + buf.writeVarIntToBuffer(this.data.length); + for(int z = 0; z < this.data.length; z++) { + buf.writeString(this.data[z].first); + Object obj = this.data[z].second; + if(obj instanceof Boolean) { + buf.writeByte(0); + buf.writeBoolean((Boolean)obj); + } + else if(obj instanceof String[]) { + buf.writeByte(1); + String[] strs = (String[])obj; + buf.writeVarIntToBuffer(strs.length); + for(int n = 0; n < strs.length; n++) { + buf.writeString(strs[n]); + } + } + else { + buf.writeByte(2); + buf.writeString((String)obj); + } + buf.writeVarIntToBuffer(this.data[z].third); + } + } + + public Triplet[] getData() + { + return this.data; + } + + public String getTitle() { + return this.title; + } + + public int getId() { + return this.id; + } +} diff --git a/common/src/common/util/Triplet.java b/common/src/common/util/Triplet.java new file mode 100644 index 0000000..6029985 --- /dev/null +++ b/common/src/common/util/Triplet.java @@ -0,0 +1,10 @@ +package common.util; + +public class Triplet extends Tuple { + public final U third; + + public Triplet(S first, T second, U third) { + super(first, second); + this.third = third; + } +} diff --git a/server/src/server/Server.java b/server/src/server/Server.java index 4e33741..a85b8b8 100755 --- a/server/src/server/Server.java +++ b/server/src/server/Server.java @@ -15,6 +15,7 @@ import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Queue; +import java.util.Map.Entry; import java.util.concurrent.Callable; import java.util.concurrent.ExecutionException; import java.util.concurrent.Executors; @@ -36,6 +37,7 @@ import common.init.Config; import common.init.EntityRegistry; import common.init.Registry; import common.init.UniverseRegistry; +import common.init.Config.ValueType; import common.log.Log; import common.nbt.NBTLoader; import common.nbt.NBTTagCompound; @@ -69,7 +71,6 @@ import common.util.ExtMath; import common.util.LazyLoadBase; import common.util.PortalType; import common.util.Position; -import common.util.Tuple; import common.util.Util; import common.util.WorldPos; import common.world.World; @@ -90,6 +91,7 @@ import server.biome.Biome; import server.clipboard.ReorderRegistry; import server.clipboard.RotationRegistry; import server.command.CommandEnvironment; +import server.command.Executor; import server.command.FixedExecutor; import server.network.HandshakeHandler; import server.network.Player; @@ -121,10 +123,11 @@ public final class Server implements IThreadListener { private WorldServer space; private ChannelFuture endpoint; - + private boolean running = true; private boolean stopped; private boolean started; + private String endMessage = "Server beendet"; private long currentTime = System.nanoTime() / 1000L; private long tpsTarget; @@ -333,6 +336,90 @@ public final class Server implements IThreadListener { } } + public boolean setVar(Executor exec, String line) { + if(line.length() < 1) { + for(Entry entry : Config.VARS.entrySet()) { + Config.Value cvar = entry.getValue(); + String v = cvar.getValue(); + String comp = TextColor.YELLOW + entry.getKey() + TextColor.GRAY + " = "; + if(entry.getKey().equals("password") && !v.isEmpty()) + comp += TextColor.NEON + "'****'"; + else if(cvar.type == ValueType.STRING) + comp += TextColor.NEON + "'" + v + "'"; + else + comp += ((cvar.type == ValueType.BOOLEAN ? (v.equals("true") ? TextColor.GREEN : TextColor.RED) : TextColor.BLUE)) + v; + if(!cvar.def.equals(v)) { + comp += TextColor.GRAY + " (" + TextColor.BROWN + cvar.def + TextColor.GRAY + ")"; + } + exec.logConsole(comp); + } + exec.logConsole(TextColor.GREEN + "SVARs insgesamt registriert: %d", Config.VARS.size()); + return true; + } + line = line.trim(); + String[] args = /* line.isEmpty() ? new String[0] : */ line.split(" ", -1); + if(args.length == 1) { +// case 0: +// break; +// case 1: + Config.Value cfg = Config.VARS.get(args[0]); + if(cfg == null) + return false; + String v = cfg.getValue(); + String comp = TextColor.YELLOW + args[0] + TextColor.GRAY + " = "; + if(cfg.type == ValueType.STRING) + comp += TextColor.NEON + "'" + v + "'"; + else + comp += ((cfg.type == ValueType.BOOLEAN ? (v.equals("true") ? TextColor.GREEN : TextColor.RED) : TextColor.BLUE)) + v; + if(!cfg.def.equals(v)) + comp += TextColor.GRAY + " (" + TextColor.BROWN + cfg.def + TextColor.GRAY + ")"; + exec.logConsole(comp); +// break; +// default: + } + else { + Config.Value cv = Config.VARS.get(args[0]); + if(cv == null) + return false; + String value = args[1]; + if(cv.type == ValueType.STRING && "\"\"".equals(value)) { + value = ""; + } +// else if(cv.type == ValueType.BOOLEAN && "toggle".equalsIgnoreCase(value)) { +// value = "" + !Boolean.parseBoolean(cv.getValue()); +// } +// else + if(cv.type == ValueType.BOOLEAN && !"true".equals(value) && !"false".equals(value)) { + if(!value.equalsIgnoreCase("true") && !value.equalsIgnoreCase("false")) { + exec.logConsole(TextColor.DRED + "'%s' ist nicht 'true' oder 'false'", value); + return true; + } + value = value.toLowerCase(); + } + if(cv.type == ValueType.INTEGER) { + try { + Integer.parseInt(value); + } + catch(NumberFormatException e) { + exec.logConsole(TextColor.DRED + "'%s' ist keine gültige Zahl", value); + return true; + } + } + else if(cv.type == ValueType.FLOAT) { + try { + Float.parseFloat(value); + } + catch(NumberFormatException e) { + exec.logConsole(TextColor.DRED + "'%s' ist keine gültige Zahl", value); + return true; + } + } + Config.set(args[0], value, true); + exec.logConsole(TextColor.YELLOW + "%s" + TextColor.GRAY + " -> " + ((cv.type == ValueType.BOOLEAN ? (cv.getValue().equals("true") ? TextColor.GREEN : TextColor.RED) : (cv.type == ValueType.STRING ? TextColor.NEON : TextColor.BLUE))) + "%s", args[0], cv.type == ValueType.STRING ? ("'" + cv.getValue() + "'") : cv.getValue()); + } + return true; + } + public void run(int port) { long time = System.currentTimeMillis(); Log.JNI.info("Starte " + Config.NAME + " Server Version " + Config.VERSION); @@ -407,17 +494,12 @@ public final class Server implements IThreadListener { } if(line == null) break; - if(line.startsWith("#")) { - line = line.substring(1); - Tuple data = Util.getKeyValue(line); - if(data.first.equals("end")) - Server.this.shutdown(); - continue; - } final String cmd = line; Server.this.schedule(new Runnable() { public void run() { - Server.this.scriptEnv.execute(cmd, new FixedExecutor(Server.this, "#con", "KONSOLE", null)); + FixedExecutor exec = new FixedExecutor(Server.this, "#con", "KONSOLE", null); + if(!Server.this.setVar(exec, cmd)) + Server.this.scriptEnv.execute(cmd, exec); } }); } @@ -770,9 +852,9 @@ public final class Server implements IThreadListener { if(!Config.register) return "Anmeldung neuer Accounts ist auf diesem Server deaktiviert (Whitelisted)"; if(loginPass.length() == 0) - return "Ein neues Passwort ist erforderlich um diesen Server zu betreten (mindestens 8 Zeichen)"; - if(loginPass.length() < 8) - return "Passwort ist zu kurz, mindestens 8 Zeichen"; + return "Ein neues Passwort ist erforderlich um diesen Server zu betreten (mindestens " + Config.minPassLength + " Zeichen)"; + if(loginPass.length() < Config.minPassLength) + return "Passwort ist zu kurz, mindestens " + Config.minPassLength + " Zeichen"; conn.setPassword(loginPass); Log.JNI.info(loginUser + " registrierte sich mit Passwort"); } @@ -1135,42 +1217,12 @@ public final class Server implements IThreadListener { player.connection.setPlayerHealthUpdated(); player.connection.sendPacket(new SPacketHeldItemChange(player.inventory.currentItem)); } - - private void setLanEndpoint(int port) throws IOException { - synchronized(this.serverThread) { - if(this.endpoint != null) - this.unsetLanEndpoint(); - // throw new IllegalStateException("Eingangspunkt bereits gesetzt"); - Log.JNI.info("Öffne Port %d auf 0.0.0.0 (Timeout %ds)", port, Config.timeout); - this.endpoint = ((ServerBootstrap)((ServerBootstrap)(new ServerBootstrap()).channel(NioServerSocketChannel.class)).childHandler(new ChannelInitializer() { - protected void initChannel(Channel channel) throws Exception { - try { - channel.config().setOption(ChannelOption.TCP_NODELAY, Boolean.valueOf(true)); - } - catch(ChannelException e) { - } - channel.pipeline().addLast((String)"timeout", (ChannelHandler)(new ReadTimeoutHandler(Config.timeout))) - .addLast((String)"splitter", (ChannelHandler)(new PacketSplitter())) - .addLast((String)"decoder", (ChannelHandler)(new PacketDecoder(true))) - .addLast((String)"prepender", (ChannelHandler)(new PacketPrepender())) - .addLast((String)"encoder", (ChannelHandler)(new PacketEncoder(false))); - NetConnection manager = new NetConnection(); - Server.this.clients.add(manager); - channel.pipeline().addLast((String)"packet_handler", (ChannelHandler)manager); - manager.setNetHandler(new HandshakeHandler(Server.this, manager)); - } - }).group(SERVER_NIO_EVENTLOOP.getValue()).localAddress((InetAddress)null, port)).bind().syncUninterruptibly(); - } - } - private void unsetLanEndpoint() { - for(Player conn : Lists.newArrayList(this.players)) { - conn.disconnect(); - } - this.terminateEndpoint(); - } - - private void terminateEndpoint() { + private void terminateEndpoint(String message) { + if(this.started) + for(Player conn : Lists.newArrayList(this.players)) { + conn.disconnect(message); + } synchronized(this.serverThread) { if(this.endpoint != null) { Log.JNI.info("Schließe Port"); @@ -1201,7 +1253,7 @@ public final class Server implements IThreadListener { } catch(Exception e) { Log.JNI.error(e, "Konnte Paket von " + manager.getCutAddress() + " nicht verarbeiten"); - manager.sendPacket(new SPacketDisconnect(), new GenericFutureListener>() { + manager.sendPacket(new SPacketDisconnect(e.getMessage()), new GenericFutureListener>() { public void operationComplete(Future future) throws Exception { manager.closeChannel("Fehlerhaftes Datenpaket"); } @@ -1227,11 +1279,7 @@ public final class Server implements IThreadListener { this.setProgress(-1); this.setMessage("Stoppe server"); Log.JNI.info("Beende Server"); - if(this.started) - for(Player conn : Lists.newArrayList(this.players)) { - conn.disconnect(); - } - this.terminateEndpoint(); + this.terminateEndpoint(this.endMessage); if(this.started) { Log.JNI.info("Speichere Spieler"); this.saveAllPlayerData(true); @@ -1243,34 +1291,46 @@ public final class Server implements IThreadListener { } public void bind(int port) { -// this.schedule(new Runnable() { -// public void run() { - if(port >= 0) { - try { - Server.this.setLanEndpoint(port); + synchronized(this.serverThread) { + if(port >= 0) { + try { + if(this.endpoint != null) + this.terminateEndpoint("Wechsele auf Port " + port); + // throw new IllegalStateException("Eingangspunkt bereits gesetzt"); + Log.JNI.info("Öffne Port %d auf 0.0.0.0 (Timeout %ds)", port, Config.timeout); + this.endpoint = ((ServerBootstrap)((ServerBootstrap)(new ServerBootstrap()).channel(NioServerSocketChannel.class)).childHandler(new ChannelInitializer() { + protected void initChannel(Channel channel) throws Exception { + try { + channel.config().setOption(ChannelOption.TCP_NODELAY, Boolean.valueOf(true)); + } + catch(ChannelException e) { + } + channel.pipeline().addLast((String)"timeout", (ChannelHandler)(new ReadTimeoutHandler(Config.timeout))) + .addLast((String)"splitter", (ChannelHandler)(new PacketSplitter())) + .addLast((String)"decoder", (ChannelHandler)(new PacketDecoder(true))) + .addLast((String)"prepender", (ChannelHandler)(new PacketPrepender())) + .addLast((String)"encoder", (ChannelHandler)(new PacketEncoder(false))); + NetConnection manager = new NetConnection(); + Server.this.clients.add(manager); + channel.pipeline().addLast((String)"packet_handler", (ChannelHandler)manager); + manager.setNetHandler(new HandshakeHandler(Server.this, manager)); + } + }).group(SERVER_NIO_EVENTLOOP.getValue()).localAddress((InetAddress)null, port)).bind().syncUninterruptibly(); + } + catch(Throwable e) { + Log.JNI.error(e, "**** KONNTE NICHT AN PORT " + port + " ANBINDEN!"); + } } - catch(IOException e) { - Log.JNI.error(e, "**** KONNTE NICHT AN PORT " + port + " ANBINDEN!"); + else { + if(this.endpoint != null) + this.terminateEndpoint("Trenne Verbindung"); } } - else { - Server.this.unsetLanEndpoint(); - } -// } -// }); } - public void shutdown() { -// Futures.getUnchecked(this.schedule(new Runnable() { -// public void run() { -// for(Player conn : Lists.newArrayList(Server.this.players)) { // = Server.this.getPlayer(Server.this.owner); -// // if(conn != null) -// if(conn.isLocal()) -// Server.this.removePlayer(conn); -// } -// } -// })); + public void shutdown(String message) { this.running = false; + this.endMessage = message; } public String getInfo() { diff --git a/server/src/server/command/ArgumentParser.java b/server/src/server/command/ArgumentParser.java index 4d55712..cf3b4b9 100644 --- a/server/src/server/command/ArgumentParser.java +++ b/server/src/server/command/ArgumentParser.java @@ -88,7 +88,7 @@ public abstract class ArgumentParser { public abstract Object parse(CommandEnvironment env, String input); public abstract Object getDefault(CommandEnvironment env); public abstract Collection getCompletions(CommandEnvironment env); - public abstract Class getTypeClass(); + public abstract Class getTypeClass(boolean required); public final String getName() { return this.name; diff --git a/server/src/server/command/BooleanParser.java b/server/src/server/command/BooleanParser.java index e821832..fc0935f 100644 --- a/server/src/server/command/BooleanParser.java +++ b/server/src/server/command/BooleanParser.java @@ -5,7 +5,7 @@ public class BooleanParser extends EnumParser { super(name, Boolean.class, def, true, false); } - public Class getTypeClass() { - return this.hasDefault() ? boolean.class : Boolean.class; + public Class getTypeClass(boolean required) { + return this.hasDefault() || required ? boolean.class : Boolean.class; } } diff --git a/server/src/server/command/CachedExecutable.java b/server/src/server/command/CachedExecutable.java index 55e64bb..97344af 100644 --- a/server/src/server/command/CachedExecutable.java +++ b/server/src/server/command/CachedExecutable.java @@ -54,7 +54,7 @@ public class CachedExecutable { continue; } for(ArgumentParser parser : param.getParsers()) { - classes.add(parser.getTypeClass()); + classes.add(parser.getTypeClass(param.isRequired())); } } Method method; diff --git a/server/src/server/command/Command.java b/server/src/server/command/Command.java index 56750cc..637c07d 100644 --- a/server/src/server/command/Command.java +++ b/server/src/server/command/Command.java @@ -192,6 +192,14 @@ public abstract class Command implements Executable { protected Command addString(String name, boolean allowEmpty, StringCompleter completer) { return this.addParameter(new StringParser(name, null, allowEmpty, null, null, null, completer)); } + + protected Command addString(String name, String def, boolean allowEmpty, Object ... completions) { + return this.addParameter(new StringParser(name, def, allowEmpty, null, null, null, completions)); + } + + protected Command addString(String name, String def, boolean allowEmpty, StringCompleter completer) { + return this.addParameter(new StringParser(name, def, allowEmpty, null, null, null, completer)); + } public Map getParameters() { return this.parameters; diff --git a/server/src/server/command/CommandEnvironment.java b/server/src/server/command/CommandEnvironment.java index 34d7fbf..a3a6e6a 100644 --- a/server/src/server/command/CommandEnvironment.java +++ b/server/src/server/command/CommandEnvironment.java @@ -19,9 +19,12 @@ import server.command.commands.CommandKick; import server.command.commands.CommandMessage; import server.command.commands.CommandMilk; import server.command.commands.CommandOfflinetp; +import server.command.commands.CommandPasswd; import server.command.commands.CommandPotion; +import server.command.commands.CommandRebind; import server.command.commands.CommandRemove; import server.command.commands.CommandRevoke; +import server.command.commands.CommandShutdown; import server.command.commands.CommandSpawn; import server.command.commands.CommandTele; import server.command.commands.CommandTime; @@ -269,6 +272,9 @@ public class CommandEnvironment { this.registerExecutable(new CommandWeather()); this.registerExecutable(new CommandKick()); this.registerExecutable(new CommandMessage()); + this.registerExecutable(new CommandShutdown()); + this.registerExecutable(new CommandRebind()); + this.registerExecutable(new CommandPasswd()); this.registerExecutable(new CommandHelp(this)); } diff --git a/server/src/server/command/DimensionParser.java b/server/src/server/command/DimensionParser.java index 30f9121..6263114 100644 --- a/server/src/server/command/DimensionParser.java +++ b/server/src/server/command/DimensionParser.java @@ -43,7 +43,7 @@ public class DimensionParser extends CompletingParser { return UniverseRegistry.getWorldNames(); } - public Class getTypeClass() { + public Class getTypeClass(boolean required) { return Dimension.class; } } diff --git a/server/src/server/command/DoubleParser.java b/server/src/server/command/DoubleParser.java index 353b4be..5b57bdb 100644 --- a/server/src/server/command/DoubleParser.java +++ b/server/src/server/command/DoubleParser.java @@ -75,8 +75,8 @@ public class DoubleParser extends DefaultingParser { return (Double)super.getDefault(env); } - public Class getTypeClass() { - return this.hasDefault() ? double.class : Double.class; + public Class getTypeClass(boolean required) { + return this.hasDefault() || required ? double.class : Double.class; } public Collection getCompletions(CommandEnvironment env) { diff --git a/server/src/server/command/EntityListParser.java b/server/src/server/command/EntityListParser.java index 130ebbb..fda515d 100644 --- a/server/src/server/command/EntityListParser.java +++ b/server/src/server/command/EntityListParser.java @@ -129,7 +129,7 @@ public class EntityListParser extends EntityParser { return comp; } - public Class getTypeClass() { + public Class getTypeClass(boolean required) { return List.class; } } diff --git a/server/src/server/command/EntityParser.java b/server/src/server/command/EntityParser.java index 09a88dd..e570d98 100644 --- a/server/src/server/command/EntityParser.java +++ b/server/src/server/command/EntityParser.java @@ -54,7 +54,7 @@ public class EntityParser extends PlayerEntityParser { return comp; } - public Class getTypeClass() { + public Class getTypeClass(boolean required) { return this.livingOnly ? EntityLiving.class : Entity.class; } } diff --git a/server/src/server/command/EnumParser.java b/server/src/server/command/EnumParser.java index a8b7a78..305dd00 100644 --- a/server/src/server/command/EnumParser.java +++ b/server/src/server/command/EnumParser.java @@ -44,7 +44,7 @@ public class EnumParser extends DefaultingParser { return this.selections[id]; } - public Class getTypeClass() { + public Class getTypeClass(boolean required) { return this.clazz; } } diff --git a/server/src/server/command/Executor.java b/server/src/server/command/Executor.java index d3888eb..193de3c 100644 --- a/server/src/server/command/Executor.java +++ b/server/src/server/command/Executor.java @@ -3,6 +3,7 @@ package server.command; import common.entity.Entity; import common.util.BlockPos; import common.util.Position; +import server.network.Player; public interface Executor { void logConsole(String msg); @@ -12,6 +13,14 @@ public interface Executor { Entity getPointedEntity(); BlockPos getPointedPosition(); + default boolean isConsole() { + return false; + } + + default boolean isPlayer() { + return this instanceof Player; + } + default void logConsole(String fmt, Object ... args) { this.logConsole(String.format(fmt, args)); } diff --git a/server/src/server/command/FixedExecutor.java b/server/src/server/command/FixedExecutor.java index 5f7d2cf..54d8eb8 100644 --- a/server/src/server/command/FixedExecutor.java +++ b/server/src/server/command/FixedExecutor.java @@ -50,4 +50,8 @@ public class FixedExecutor implements Executor { public BlockPos getPointedPosition() { return null; } + + public boolean isConsole() { + return true; + } } diff --git a/server/src/server/command/IntParser.java b/server/src/server/command/IntParser.java index a1673b0..4b9bdb4 100644 --- a/server/src/server/command/IntParser.java +++ b/server/src/server/command/IntParser.java @@ -33,7 +33,7 @@ public class IntParser extends DefaultingParser { return value; } - public Class getTypeClass() { - return this.hasDefault() ? int.class : Integer.class; + public Class getTypeClass(boolean required) { + return this.hasDefault() || required ? int.class : Integer.class; } } diff --git a/server/src/server/command/LongParser.java b/server/src/server/command/LongParser.java index c072ac2..ab7cf0e 100644 --- a/server/src/server/command/LongParser.java +++ b/server/src/server/command/LongParser.java @@ -31,7 +31,7 @@ public class LongParser extends DefaultingParser { return value; } - public Class getTypeClass() { - return this.hasDefault() ? long.class : Long.class; + public Class getTypeClass(boolean required) { + return this.hasDefault() || required ? long.class : Long.class; } } diff --git a/server/src/server/command/PlayerEntityListParser.java b/server/src/server/command/PlayerEntityListParser.java index d97c1e6..2ab4890 100644 --- a/server/src/server/command/PlayerEntityListParser.java +++ b/server/src/server/command/PlayerEntityListParser.java @@ -46,7 +46,7 @@ public class PlayerEntityListParser extends PlayerEntityParser { return comp; } - public Class getTypeClass() { + public Class getTypeClass(boolean required) { return List.class; } } diff --git a/server/src/server/command/PlayerEntityParser.java b/server/src/server/command/PlayerEntityParser.java index ff9eeb7..c7fee81 100644 --- a/server/src/server/command/PlayerEntityParser.java +++ b/server/src/server/command/PlayerEntityParser.java @@ -21,7 +21,7 @@ public class PlayerEntityParser extends PlayerParser { return net == null ? null : net.getPresentEntity(); } - public Class getTypeClass() { + public Class getTypeClass(boolean required) { return EntityNPC.class; } } diff --git a/server/src/server/command/PlayerListParser.java b/server/src/server/command/PlayerListParser.java index aed9691..d66c94f 100644 --- a/server/src/server/command/PlayerListParser.java +++ b/server/src/server/command/PlayerListParser.java @@ -39,7 +39,7 @@ public class PlayerListParser extends PlayerParser { return comp; } - public Class getTypeClass() { + public Class getTypeClass(boolean required) { return List.class; } } diff --git a/server/src/server/command/PlayerParser.java b/server/src/server/command/PlayerParser.java index 6e2cc07..2ca384a 100644 --- a/server/src/server/command/PlayerParser.java +++ b/server/src/server/command/PlayerParser.java @@ -20,14 +20,14 @@ public class PlayerParser extends CompletingParser { } public Object getDefault(CommandEnvironment env) { - return this.useSender && env.getExecutor() instanceof Player ? (Player)env.getExecutor() : null; + return this.useSender && env.getExecutor().isPlayer() ? (Player)env.getExecutor() : null; } public Collection getCompletions(CommandEnvironment env) { return env.getServer().getAllUsernames(); } - public Class getTypeClass() { + public Class getTypeClass(boolean required) { return Player.class; } } diff --git a/server/src/server/command/StringParser.java b/server/src/server/command/StringParser.java index b4ce0e8..5c2e35d 100644 --- a/server/src/server/command/StringParser.java +++ b/server/src/server/command/StringParser.java @@ -53,7 +53,7 @@ public class StringParser extends DefaultingParser { return input; } - public Class getTypeClass() { + public Class getTypeClass(boolean required) { return String.class; } diff --git a/server/src/server/command/TagParser.java b/server/src/server/command/TagParser.java index 848f6d8..ab1fad2 100644 --- a/server/src/server/command/TagParser.java +++ b/server/src/server/command/TagParser.java @@ -20,7 +20,7 @@ public class TagParser extends DefaultingParser { return value; } - public Class getTypeClass() { + public Class getTypeClass(boolean required) { return NBTTagCompound.class; } } diff --git a/server/src/server/command/WorldParser.java b/server/src/server/command/WorldParser.java index c76e27c..9649e30 100644 --- a/server/src/server/command/WorldParser.java +++ b/server/src/server/command/WorldParser.java @@ -42,7 +42,7 @@ public class WorldParser extends DimensionParser { return super.getCompletions(env); } - public Class getTypeClass() { + public Class getTypeClass(boolean required) { return WorldServer.class; } } diff --git a/server/src/server/command/commands/CommandKick.java b/server/src/server/command/commands/CommandKick.java index 6785b09..80b3b5e 100644 --- a/server/src/server/command/commands/CommandKick.java +++ b/server/src/server/command/commands/CommandKick.java @@ -11,16 +11,16 @@ public class CommandKick extends Command { super("kick"); this.addPlayer("player", false); + this.setParamsOptional(); + this.addString("message", "Du wurdest vom Server geworfen", false); } - public void exec(CommandEnvironment env, Executor exec, Player player) { - if(!(exec instanceof Player)) - throw new RunException("Dieser Befehl kann nur von Spielern ausgeführt werden"); - else if(player == exec) + public void exec(CommandEnvironment env, Executor exec, Player player, String message) { + if(player == exec) throw new RunException("Du kannst nicht dich nicht selbst vom Server werfen"); else if(player.getAdmin()) throw new RunException("%s ist ein Admin", player.getUser()); - player.disconnect(); + player.disconnect(message); exec.logConsole("%s wurde vom Server geworfen", player.getUser()); } } diff --git a/server/src/server/command/commands/CommandPasswd.java b/server/src/server/command/commands/CommandPasswd.java new file mode 100644 index 0000000..e67ee5b --- /dev/null +++ b/server/src/server/command/commands/CommandPasswd.java @@ -0,0 +1,64 @@ +package server.command.commands; + +import common.color.TextColor; +import common.init.Config; +import common.network.IPlayer; +import server.command.Command; +import server.command.CommandEnvironment; +import server.command.Executor; +import server.command.RunException; +import server.network.Player; +import server.util.Form; + +public class CommandPasswd extends Command { + public CommandPasswd() { + super("passwd"); + + this.addPlayer("player", true); + this.setParamsOptional(); + this.addString("password", false); + } + + public void exec(CommandEnvironment env, Executor exec, Player player, String password) { + if(exec.isPlayer()) { + if(password != null) + throw new RunException("Bei Verwendung als Spieler darf kein Passwort angegeben werden"); + if(player.getAdmin() && player != exec) + throw new RunException("%s ist ein Admin", player.getUser()); + ((Player)exec).displayForm(new Form() { + private Field checkField; + private Field passwordField; + private Field confirmField; + + protected void init() { + this.checkField = player != exec ? null : this.addField("Aktuelles Passwort", 0, IPlayer.MAX_PASS_LENGTH, ""); + this.passwordField = this.addField("Neues Passwort", Config.minPassLength, IPlayer.MAX_PASS_LENGTH, ""); + this.confirmField = this.addField("Passwort bestätigen", Config.minPassLength, IPlayer.MAX_PASS_LENGTH, ""); + } + + public String getTitle() { + return "Passwort für " + player.getUser() + " ändern"; + } + + protected void accept() { + if(this.checkField != null && !this.checkField.get().equals(player.getPassword())) { + exec.logConsole(TextColor.RED + "Falsches Passwort eingegeben"); + return; + } + if(!this.passwordField.get().equals(this.confirmField.get())) { + exec.logConsole(TextColor.RED + "Passwörter stimmen nicht überein"); + return; + } + player.setPassword(this.passwordField.get()); + exec.logConsole(TextColor.GREEN + "Passwort" + (player != exec ? " für %s" : "") + " gesetzt", player.getUser()); + } + }); + } + else if(exec.isConsole()) { + if(password == null) + throw new RunException("Bei Verwendung in der Konsole muss ein Passwort angegeben werden"); + player.setPassword(password); + exec.logConsole(TextColor.GREEN + "Passwort für %s gesetzt", player.getUser()); + } + } +} diff --git a/server/src/server/command/commands/CommandRebind.java b/server/src/server/command/commands/CommandRebind.java new file mode 100644 index 0000000..ad45c0e --- /dev/null +++ b/server/src/server/command/commands/CommandRebind.java @@ -0,0 +1,17 @@ +package server.command.commands; + +import server.command.Command; +import server.command.CommandEnvironment; +import server.command.Executor; + +public class CommandRebind extends Command { + public CommandRebind() { + super("rebind"); + + this.addInt("port", 1024, 65535); + } + + public void exec(CommandEnvironment env, Executor exec, int port) { + env.getServer().bind(port); + } +} diff --git a/server/src/server/command/commands/CommandRevoke.java b/server/src/server/command/commands/CommandRevoke.java index 10c88d2..075dd3d 100644 --- a/server/src/server/command/commands/CommandRevoke.java +++ b/server/src/server/command/commands/CommandRevoke.java @@ -14,7 +14,7 @@ public class CommandRevoke extends Command { } public void exec(CommandEnvironment env, Executor exec, Player player) { - if(exec instanceof Player) + if(!exec.isConsole()) throw new RunException("Dieser Befehl kann nur der Konsole ausgeführt werden"); // else if(player == exec) // throw new RunException("Du kannst nicht deinen eigenen Admin-Status entfernen"); diff --git a/server/src/server/command/commands/CommandShutdown.java b/server/src/server/command/commands/CommandShutdown.java new file mode 100644 index 0000000..5872df3 --- /dev/null +++ b/server/src/server/command/commands/CommandShutdown.java @@ -0,0 +1,18 @@ +package server.command.commands; + +import server.command.Command; +import server.command.CommandEnvironment; +import server.command.Executor; + +public class CommandShutdown extends Command { + public CommandShutdown() { + super("shutdown"); + + this.setParamsOptional(); + this.addString("message", "Server beendet", false); + } + + public void exec(CommandEnvironment env, Executor exec, String message) { + env.getServer().shutdown(message); + } +} diff --git a/server/src/server/command/commands/CommandSpawn.java b/server/src/server/command/commands/CommandSpawn.java index 053ff75..ab5f0a7 100644 --- a/server/src/server/command/commands/CommandSpawn.java +++ b/server/src/server/command/commands/CommandSpawn.java @@ -53,7 +53,7 @@ public class CommandSpawn extends Command { } world.strikeLightning(pos.xCoord, pos.yCoord, pos.zCoord, color, tag != null && tag.hasKey("damage", 3) ? tag.getInteger("damage") : 0, tag != null && tag.hasKey("fire", 1) && tag.getBoolean("fire"), - exec instanceof Player && tag != null && tag.hasKey("summoned", 1) && tag.getBoolean("summoned") ? ((Player)exec).getPresentEntity() : null); + exec.isPlayer() && tag != null && tag.hasKey("summoned", 1) && tag.getBoolean("summoned") ? ((Player)exec).getPresentEntity() : null); } exec.logConsole("%sBlitz bei %d, %d, %d in %s erschaffen", count == 1 ? "" : (count + "x "), (int)pos.xCoord, (int)pos.yCoord, (int)pos.zCoord, world.dimension.getFormattedName(false)); return null; diff --git a/server/src/server/network/Player.java b/server/src/server/network/Player.java index c667590..0ef2858 100755 --- a/server/src/server/network/Player.java +++ b/server/src/server/network/Player.java @@ -4,7 +4,6 @@ import java.util.Collections; import java.util.Iterator; import java.util.LinkedList; import java.util.List; -import java.util.Map.Entry; import java.util.Set; import java.util.function.Predicate; @@ -60,6 +59,7 @@ import common.packet.CPacketBreak; import common.packet.CPacketCheat; import common.packet.CPacketClick; import common.packet.CPacketComplete; +import common.packet.CPacketForm; import common.packet.CPacketInput; import common.packet.CPacketKeepAlive; import common.packet.CPacketMessage; @@ -88,6 +88,7 @@ import common.packet.SPacketCharacterList; import common.packet.SPacketChunkData; import common.packet.SPacketDestroyEntities; import common.packet.SPacketDisconnect; +import common.packet.SPacketDisplayForm; import common.packet.SPacketKeepAlive; import common.packet.SPacketLoading; import common.packet.SPacketMapChunkBulk; @@ -132,6 +133,7 @@ import server.clipboard.RotationRegistry; import server.clipboard.RotationValue; import server.clipboard.Vector; import server.command.Executor; +import server.util.Form; import server.world.Region; import server.world.WorldServer; @@ -165,6 +167,7 @@ public class Player extends NetHandler implements ICrafting, Executor, IPlayer private double lastPosZ; private boolean hasMoved = true; private boolean charEditor = true; + private Form form; private boolean admin; private int ping; @@ -200,6 +203,7 @@ public class Player extends NetHandler implements ICrafting, Executor, IPlayer private float lastHealth = -1.0E8F; private int lastExperience = -99999999; private int currentWindowId; + private int currentFormId; private int pointedEntity; private BlockPos pointedPosition; @@ -410,6 +414,11 @@ public class Player extends NetHandler implements ICrafting, Executor, IPlayer { this.currentWindowId = this.currentWindowId % 100 + 1; } + + private void getNextFormId() + { + this.currentFormId = this.currentFormId % 100 + 1; + } public void displayTradeGui(EntityNPC npc) { @@ -1520,9 +1529,10 @@ public class Player extends NetHandler implements ICrafting, Executor, IPlayer this.characters.set(this.selected, tag); } - public void disconnect() + public void disconnect(String message) { - this.connection.sendPacket(new SPacketDisconnect(), new GenericFutureListener < Future > () + Log.JNI.info("Trenne %s: %s", this.user, message); + this.connection.sendPacket(new SPacketDisconnect(message), new GenericFutureListener < Future > () { public void operationComplete(Future p_operationComplete_1_) throws Exception { @@ -1676,87 +1686,7 @@ public class Player extends NetHandler implements ICrafting, Executor, IPlayer private boolean setVar(String line) { if(!this.isAdmin()) return false; - if(line.length() < 1) { - for(Entry entry : Config.VARS.entrySet()) { - Config.Value cvar = entry.getValue(); - String v = cvar.getValue(); - String comp = TextColor.YELLOW + entry.getKey() + TextColor.GRAY + " = "; - if(entry.getKey().equals("password") && !v.isEmpty()) - comp += TextColor.NEON + "'****'"; - else if(cvar.type == ValueType.STRING) - comp += TextColor.NEON + "'" + v + "'"; - else - comp += ((cvar.type == ValueType.BOOLEAN ? (v.equals("true") ? TextColor.GREEN : TextColor.RED) : TextColor.BLUE)) + v; - if(!cvar.def.equals(v)) { - comp += TextColor.GRAY + " (" + TextColor.BROWN + cvar.def + TextColor.GRAY + ")"; - } - this.addConsole(comp); - } - this.addConsole(TextColor.GREEN + "SVARs insgesamt registriert: %d", Config.VARS.size()); - return true; - } - line = line.trim(); - String[] args = /* line.isEmpty() ? new String[0] : */ line.split(" ", -1); - if(args.length == 1) { -// case 0: -// break; -// case 1: - Config.Value cfg = Config.VARS.get(args[0]); - if(cfg == null) - return false; - String v = cfg.getValue(); - String comp = TextColor.YELLOW + args[0] + TextColor.GRAY + " = "; - if(cfg.type == ValueType.STRING) - comp += TextColor.NEON + "'" + v + "'"; - else - comp += ((cfg.type == ValueType.BOOLEAN ? (v.equals("true") ? TextColor.GREEN : TextColor.RED) : TextColor.BLUE)) + v; - if(!cfg.def.equals(v)) - comp += TextColor.GRAY + " (" + TextColor.BROWN + cfg.def + TextColor.GRAY + ")"; - this.addConsole(comp); -// break; -// default: - } - else { - Config.Value cv = Config.VARS.get(args[0]); - if(cv == null) - return false; - String value = args[1]; - if(cv.type == ValueType.STRING && "\"\"".equals(value)) { - value = ""; - } -// else if(cv.type == ValueType.BOOLEAN && "toggle".equalsIgnoreCase(value)) { -// value = "" + !Boolean.parseBoolean(cv.getValue()); -// } -// else - if(cv.type == ValueType.BOOLEAN && !"true".equals(value) && !"false".equals(value)) { - if(!value.equalsIgnoreCase("true") && !value.equalsIgnoreCase("false")) { - this.addConsole(TextColor.DRED + "'%s' ist nicht 'true' oder 'false'", value); - return true; - } - value = value.toLowerCase(); - } - if(cv.type == ValueType.INTEGER) { - try { - Integer.parseInt(value); - } - catch(NumberFormatException e) { - this.addConsole(TextColor.DRED + "'%s' ist keine gültige Zahl", value); - return true; - } - } - else if(cv.type == ValueType.FLOAT) { - try { - Float.parseFloat(value); - } - catch(NumberFormatException e) { - this.addConsole(TextColor.DRED + "'%s' ist keine gültige Zahl", value); - return true; - } - } - Config.set(args[0], value, true); - this.addConsole(TextColor.YELLOW + "%s" + TextColor.GRAY + " -> " + ((cv.type == ValueType.BOOLEAN ? (cv.getValue().equals("true") ? TextColor.GREEN : TextColor.RED) : (cv.type == ValueType.STRING ? TextColor.NEON : TextColor.BLUE))) + "%s", args[0], cv.type == ValueType.STRING ? ("'" + cv.getValue() + "'") : cv.getValue()); - } - return true; + return this.server.setVar(this, line); } public void setAdmin(boolean admin) { @@ -3082,6 +3012,7 @@ public class Player extends NetHandler implements ICrafting, Executor, IPlayer // this.signCommand = null; // } + tileentitysign.setPlayer(null); tileentitysign.markDirty(); worldserver.markBlockForUpdate(blockpos); } @@ -3147,6 +3078,20 @@ public class Player extends NetHandler implements ICrafting, Executor, IPlayer } } } + + public void processForm(CPacketForm packet) { + NetHandler.checkThread(packet, this, this.server); + if(this.charEditor || this.form == null || packet.getId() != this.currentFormId) + return; + this.form.accept(packet.getData()); + this.form = null; + } + + public void displayForm(Form form) { + this.form = form; + this.getNextFormId(); + this.sendPacket(new SPacketDisplayForm(this.currentFormId, form.getTitle(), form.getInputList())); + } public Entity getPointedEntity() { return this.pointedEntity != -1 && this.entity != null ? this.entity.worldObj.getEntityByID(this.pointedEntity) : null; diff --git a/server/src/server/util/Form.java b/server/src/server/util/Form.java new file mode 100644 index 0000000..cb6fbbf --- /dev/null +++ b/server/src/server/util/Form.java @@ -0,0 +1,179 @@ +package server.util; + +import java.util.List; + +import common.collect.Lists; +import common.util.Displayable; +import common.util.Triplet; + +public abstract class Form { + private abstract class FormElement { + protected final String name; + + protected FormElement(String name) { + this.name = name; + } + + protected abstract Object getInputData(); + protected abstract int getInputParameter(); + protected abstract boolean acceptValue(Object obj); + } + + protected class Toggle extends FormElement { + private boolean value; + + protected Toggle(String name, boolean value) { + super(name); + this.value = value; + } + + protected Object getInputData() { + return this.value; + } + + protected int getInputParameter() { + return 0; + } + + protected boolean acceptValue(Object obj) { + if(obj instanceof Boolean) + this.value = (Boolean)obj; + return obj instanceof Boolean; + } + + public boolean get() { + return this.value; + } + } + + protected class Switch extends FormElement { + private final T[] values; + private final int def; + + private T value; + + protected Switch(String name, T[] values, T value) { + super(name); + this.values = values; + this.value = value; + int def = 0; + for(int z = 0; z < values.length; z++) { + if(values[z] == value) { + def = z; + break; + } + } + this.def = def; + } + + protected Object getInputData() { + String[] strs = new String[this.values.length]; + for(int z = 0; z < strs.length; z++) { + strs[z] = this.values[z] instanceof Displayable ? ((Displayable)this.values[z]).getDisplay() : String.valueOf(this.values[z]); + } + return strs; + } + + protected int getInputParameter() { + return this.def; + } + + protected boolean acceptValue(Object obj) { + if(obj instanceof Integer && (Integer)obj >= 0 && (Integer)obj < this.values.length) { + this.value = this.values[(Integer)obj]; + return true; + } + return false; + } + + public T get() { + return this.value; + } + } + + protected class Field extends FormElement { + private final int minLength; + private final int maxLength; + + private String value; + + protected Field(String name, String value, int min, int max) { + super(name); + this.value = value; + this.minLength = min; + this.maxLength = max; + } + + protected Object getInputData() { + return this.value; + } + + protected int getInputParameter() { + return (this.minLength << 16) | this.maxLength; + } + + protected boolean acceptValue(Object obj) { + if(obj instanceof String && ((String)obj).length() >= this.minLength && ((String)obj).length() <= this.maxLength) { + this.value = (String)obj; + return true; + } + return false; + } + + public String get() { + return this.value; + } + } + + private final List inputs = Lists.newArrayList(); + + public Form() { + this.init(); + } + + private T add(T elem) { + this.inputs.add(elem); + return elem; + } + + protected Toggle addToggle(String name, boolean def) { + return this.add(new Toggle(name, def)); + } + + protected Switch addSwitch(String name, T def, T ... values) { + return this.add(new Switch(name, values, def)); + } + + protected Field addField(String name, int minLength, int maxLength, String def) { + return this.add(new Field(name, def, minLength, maxLength)); + } + + public abstract String getTitle(); + protected abstract void init(); + protected abstract void accept(); + + protected void cancel() { + } + + public final Triplet[] getInputList() { + Triplet[] data = new Triplet[this.inputs.size()]; + for(int z = 0; z < data.length; z++) { + data[z] = new Triplet(this.inputs.get(z).name, this.inputs.get(z).getInputData(), this.inputs.get(z).getInputParameter()); + } + return data; + } + + public final void accept(Object[] data) { + if(data == null || data.length != this.inputs.size()) { + this.cancel(); + return; + } + for(int z = 0; z < data.length; z++) { + if(!this.inputs.get(z).acceptValue(data[z])) { + this.cancel(); + return; + } + } + this.accept(); + } +} From 10ba39c70b0b8a90d3f71b4278b3c3c13c07c4da Mon Sep 17 00:00:00 2001 From: Sen Date: Wed, 14 May 2025 15:12:11 +0200 Subject: [PATCH 030/200] misc refactoring --- client/src/client/Client.java | 4 +- .../src/client/renderer/EntityRenderer.java | 6 +- .../client/renderer/RegionRenderCache.java | 4 +- .../renderer/blockmodel/ModelBakery.java | 4 +- .../renderer/blockmodel/ModelManager.java | 2 +- client/src/client/world/WorldClient.java | 8 +- .../biome/{BaseBiome.java => Biome.java} | 34 ++-- common/src/common/biome/IBiome.java | 6 +- common/src/common/block/BlockDispenser.java | 2 +- common/src/common/color/Colorizer.java | 10 +- common/src/common/dimension/Dimension.java | 74 +++---- common/src/common/dimension/Space.java | 4 +- .../src/common/entity/animal/EntitySheep.java | 6 +- common/src/common/entity/npc/EntitySlime.java | 6 +- common/src/common/init/BlockRegistry.java | 2 + common/src/common/init/DispenserRegistry.java | 3 +- common/src/common/init/EntityEggInfo.java | 31 ++- common/src/common/init/ItemRegistry.java | 3 +- common/src/common/init/TileRegistry.java | 5 - common/src/common/init/UniverseRegistry.java | 66 +++--- common/src/common/item/ItemInfoWand.java | 4 +- common/src/common/item/ItemMonsterPlacer.java | 2 +- .../{init => util}/IObjectIntIterable.java | 2 +- .../src/common/{init => util}/IRegistry.java | 2 +- .../{init => util}/ObjectIntIdentityMap.java | 3 +- .../{init => util}/RegistryDefaulted.java | 2 +- .../{init => util}/RegistryNamespaced.java | 2 +- .../RegistryNamespacedDefaultedByKey.java | 2 +- .../common/{init => util}/RegistrySimple.java | 2 +- common/src/common/world/Chunk.java | 10 +- common/src/common/world/IWorldAccess.java | 4 +- common/src/common/world/World.java | 6 +- .../src/common/worldgen/BiomeGenerator.java | 12 +- server/src/server/Server.java | 4 +- server/src/server/biome/BiomeBeach.java | 6 +- server/src/server/biome/BiomeBlackened.java | 6 +- server/src/server/biome/BiomeChaos.java | 6 +- server/src/server/biome/BiomeDesert.java | 6 +- .../src/server/biome/BiomeExterminated.java | 6 +- server/src/server/biome/BiomeForest.java | 12 +- server/src/server/biome/BiomeHell.java | 6 +- server/src/server/biome/BiomeHills.java | 10 +- server/src/server/biome/BiomeJungle.java | 6 +- server/src/server/biome/BiomeMesa.java | 10 +- server/src/server/biome/BiomeMoon.java | 6 +- server/src/server/biome/BiomeMushroom.java | 6 +- server/src/server/biome/BiomeMutated.java | 12 +- server/src/server/biome/BiomeNone.java | 6 +- server/src/server/biome/BiomePlains.java | 6 +- server/src/server/biome/BiomeSavanna.java | 12 +- server/src/server/biome/BiomeSnow.java | 10 +- server/src/server/biome/BiomeSnowLand.java | 6 +- server/src/server/biome/BiomeSpace.java | 6 +- server/src/server/biome/BiomeStoneBeach.java | 6 +- server/src/server/biome/BiomeSwamp.java | 6 +- server/src/server/biome/BiomeTaiga.java | 10 +- server/src/server/biome/BiomeTian.java | 6 +- server/src/server/biome/BiomeWater.java | 6 +- .../biome/{Biome.java => GenBiome.java} | 189 +++++++++--------- server/src/server/world/Converter.java | 4 +- server/src/server/world/Spawner.java | 4 +- server/src/server/world/WorldServer.java | 36 ++-- .../src/server/worldgen/BiomeGenLayered.java | 34 ++-- .../src/server/worldgen/BiomeGenSingle.java | 16 +- server/src/server/worldgen/BlockReplacer.java | 4 +- server/src/server/worldgen/FeatureLakes.java | 4 +- .../src/server/worldgen/GeneratorPerlin.java | 10 +- .../src/server/worldgen/ReplacerAltBiome.java | 8 +- .../server/worldgen/ReplacerAltSurface.java | 4 +- server/src/server/worldgen/ReplacerBiome.java | 8 +- .../src/server/worldgen/ReplacerTopLayer.java | 4 +- .../server/worldgen/caves/MapGenCaves.java | 4 +- .../server/worldgen/caves/MapGenRavine.java | 4 +- .../src/server/worldgen/layer/GenLayer.java | 10 +- .../worldgen/layer/GenLayerAddExtra.java | 4 +- .../server/worldgen/layer/GenLayerAddSea.java | 4 +- .../server/worldgen/layer/GenLayerBiome.java | 12 +- .../worldgen/layer/GenLayerBiomeEdge.java | 26 +-- .../server/worldgen/layer/GenLayerHills.java | 66 +++--- .../server/worldgen/layer/GenLayerRiver.java | 4 +- .../worldgen/layer/GenLayerRiverMix.java | 16 +- .../server/worldgen/layer/GenLayerShore.java | 22 +- .../structure/MapGenScatteredFeature.java | 16 +- .../worldgen/structure/MapGenVillage.java | 4 +- .../worldgen/structure/StructureVillage.java | 6 +- 85 files changed, 512 insertions(+), 526 deletions(-) rename common/src/common/biome/{BaseBiome.java => Biome.java} (89%) rename common/src/common/{init => util}/IObjectIntIterable.java (75%) rename common/src/common/{init => util}/IRegistry.java (89%) rename common/src/common/{init => util}/ObjectIntIdentityMap.java (95%) rename common/src/common/{init => util}/RegistryDefaulted.java (95%) rename common/src/common/{init => util}/RegistryNamespaced.java (99%) rename common/src/common/{init => util}/RegistryNamespacedDefaultedByKey.java (98%) rename common/src/common/{init => util}/RegistrySimple.java (98%) rename server/src/server/biome/{Biome.java => GenBiome.java} (79%) diff --git a/client/src/client/Client.java b/client/src/client/Client.java index 0d67257..8535a7d 100755 --- a/client/src/client/Client.java +++ b/client/src/client/Client.java @@ -95,7 +95,7 @@ import client.window.Wheel; import client.window.Window; import client.window.WindowEvent; import client.world.WorldClient; -import common.biome.BaseBiome; +import common.biome.Biome; import common.block.Block; import common.collect.Lists; import common.collect.Maps; @@ -1730,7 +1730,7 @@ public class Client implements IThreadListener { break; } - BaseBiome biome = null; + Biome biome = null; String bline; String lline; if(this.world.isBlockLoaded(blockpos)) { diff --git a/client/src/client/renderer/EntityRenderer.java b/client/src/client/renderer/EntityRenderer.java index 0e7be20..9e5bf48 100755 --- a/client/src/client/renderer/EntityRenderer.java +++ b/client/src/client/renderer/EntityRenderer.java @@ -14,7 +14,7 @@ import client.renderer.particle.EffectRenderer; import client.renderer.texture.DynamicTexture; import client.renderer.texture.TextureMap; import client.world.WorldClient; -import common.biome.BaseBiome; +import common.biome.Biome; import common.block.Block; import common.entity.Entity; import common.entity.npc.EntityNPC; @@ -1144,7 +1144,7 @@ public class EntityRenderer { for (int l = 0; l < k; ++l) { BlockPos blockpos1 = world.getPrecipitationHeight(blockpos.add(this.random.zrange(i) - this.random.zrange(i), 0, this.random.zrange(i) - this.random.zrange(i))); - BaseBiome biomegenbase = world.getBiomeGenForCoords(blockpos1); + Biome biomegenbase = world.getBiomeGenForCoords(blockpos1); BlockPos blockpos2 = blockpos1.down(); Block block = world.getState(blockpos2).getBlock(); float temp = World.ABSOLUTE_ZERO + world.getTempOffset() + biomegenbase.getTemperature(blockpos1); @@ -1253,7 +1253,7 @@ public class EntityRenderer { double d3 = (double)this.rainXCoords[i2] * 0.5D; double d4 = (double)this.rainYCoords[i2] * 0.5D; blockpos$mutableblockpos.set(l1, 0, k1); - BaseBiome biomegenbase = world.getBiomeGenForCoords(blockpos$mutableblockpos); + Biome biomegenbase = world.getBiomeGenForCoords(blockpos$mutableblockpos); // if (biomegenbase.canRain() || biomegenbase.isSnowyBiome()) // { diff --git a/client/src/client/renderer/RegionRenderCache.java b/client/src/client/renderer/RegionRenderCache.java index f5157cc..635a77a 100755 --- a/client/src/client/renderer/RegionRenderCache.java +++ b/client/src/client/renderer/RegionRenderCache.java @@ -2,7 +2,7 @@ package client.renderer; import java.util.Arrays; -import common.biome.BaseBiome; +import common.biome.Biome; import common.init.Blocks; import common.tileentity.TileEntity; import common.util.BlockPos; @@ -125,7 +125,7 @@ public class RegionRenderCache extends ChunkCache implements IWorldAccess return i << 20 | j << 4; } - public BaseBiome getBiomeGenForCoords(BlockPos pos) + public Biome getBiomeGenForCoords(BlockPos pos) { return this.worldObj.getBiomeGenForCoords(pos); } diff --git a/client/src/client/renderer/blockmodel/ModelBakery.java b/client/src/client/renderer/blockmodel/ModelBakery.java index aaa55a3..5b58a45 100755 --- a/client/src/client/renderer/blockmodel/ModelBakery.java +++ b/client/src/client/renderer/blockmodel/ModelBakery.java @@ -15,13 +15,13 @@ import common.collect.Maps; import common.collect.Sets; import common.init.BlockRegistry; import common.init.FluidRegistry; -import common.init.IRegistry; import common.init.ItemRegistry; -import common.init.RegistrySimple; import common.item.Item; import common.item.ItemStack; import common.model.ModelRotation; import common.util.Facing; +import common.util.IRegistry; +import common.util.RegistrySimple; import common.world.State; public abstract class ModelBakery diff --git a/client/src/client/renderer/blockmodel/ModelManager.java b/client/src/client/renderer/blockmodel/ModelManager.java index 810b25d..5984f9a 100755 --- a/client/src/client/renderer/blockmodel/ModelManager.java +++ b/client/src/client/renderer/blockmodel/ModelManager.java @@ -13,8 +13,8 @@ import common.collect.Maps; import common.init.BlockRegistry; import common.init.Blocks; import common.init.FluidRegistry; -import common.init.IRegistry; import common.properties.IProperty; +import common.util.IRegistry; import common.world.State; public class ModelManager diff --git a/client/src/client/world/WorldClient.java b/client/src/client/world/WorldClient.java index 497f744..7e8f142 100755 --- a/client/src/client/world/WorldClient.java +++ b/client/src/client/world/WorldClient.java @@ -6,7 +6,7 @@ import java.util.Set; import client.Client; import client.renderer.particle.EntityFX; import client.renderer.particle.EntityFirework; -import common.biome.BaseBiome; +import common.biome.Biome; import common.block.Block; import common.collect.Lists; import common.collect.Sets; @@ -759,7 +759,7 @@ public class WorldClient extends AWorldClient public Vec3 getSkyColor(Entity entity, float partial) { BlockPos pos = new BlockPos(ExtMath.floord(entity.posX), ExtMath.floord(entity.posY), ExtMath.floord(entity.posZ)); - BaseBiome biome = this.getBiomeGenForCoords(pos); + Biome biome = this.getBiomeGenForCoords(pos); Vec3 vec; if(biome.skyColor != 0xffffffff) vec = new Vec3(biome.skyColor); @@ -815,7 +815,7 @@ public class WorldClient extends AWorldClient public Vec3 getCloudColour(Entity entity, float partialTicks) { Vec3 color = new Vec3(this.dimension.getCloudColor()); - BaseBiome biome = this.getBiomeGenForCoords(new BlockPos(ExtMath.floord(entity.posX), ExtMath.floord(entity.posY), + Biome biome = this.getBiomeGenForCoords(new BlockPos(ExtMath.floord(entity.posX), ExtMath.floord(entity.posY), ExtMath.floord(entity.posZ))); if(biome.cloudColor != 0xffffffff) color = new Vec3(biome.cloudColor); @@ -854,7 +854,7 @@ public class WorldClient extends AWorldClient public Vec3 getFogColor(Entity entity, float partialTicks) { Vec3 color = new Vec3(this.dimension.getFogColor()); - BaseBiome biome = this.getBiomeGenForCoords(new BlockPos(ExtMath.floord(entity.posX), ExtMath.floord(entity.posY), + Biome biome = this.getBiomeGenForCoords(new BlockPos(ExtMath.floord(entity.posX), ExtMath.floord(entity.posY), ExtMath.floord(entity.posZ))); if(biome.fogColor != 0xffffffff) color = new Vec3(biome.fogColor); diff --git a/common/src/common/biome/BaseBiome.java b/common/src/common/biome/Biome.java similarity index 89% rename from common/src/common/biome/BaseBiome.java rename to common/src/common/biome/Biome.java index 81c9b42..b02260c 100644 --- a/common/src/common/biome/BaseBiome.java +++ b/common/src/common/biome/Biome.java @@ -12,7 +12,7 @@ import common.rng.Random; import common.util.BlockPos; import common.util.ExtMath; -public enum BaseBiome { +public enum Biome { NONE(0, "none", "", 0x000000), PLAINS(1, "plains", "Ebene", 0x8db360, 12.0f, 40.0f), DESERT(2, "desert", "Wüste", 0xfa9418, 60.0f, 0.0f), @@ -85,11 +85,11 @@ public enum BaseBiome { MESAPLATEAUFM(166, "mesaPlateauFM", "Mesa-Waldplateau M", 0xb09765, 0.0f, 0.0f, 0xffffff, 9470285, 10387789), MESAPLATEAUM(167, "mesaPlateauM", "Mesa-Plateau M", 0xca8c65, 0.0f, 0.0f, 0xffffff, 9470285, 10387789); - public static final BaseBiome DEF_BIOME = FOREST; - private static final PerlinGen TEMP_NOISE = new PerlinGen(new Random(1234L), 1); - private static final PerlinGen COLOR_NOISE = new PerlinGen(new Random(2345L), 1); - private static final BaseBiome[] BIOMES = new BaseBiome[256]; - private static final Map LOOKUP = Maps.newTreeMap(); + public static final Biome DEF_BIOME = FOREST; + private static final PerlinGen TEMP_NOISE = new PerlinGen(new Random(836430928262265276L), 1); + private static final PerlinGen COLOR_NOISE = new PerlinGen(new Random(6549321755809421L), 1); + private static final Biome[] BIOMES = new Biome[256]; + private static final Map LOOKUP = Maps.newTreeMap(); public final int id; public final String name; @@ -105,7 +105,7 @@ public enum BaseBiome { public final int cloudColor; static { - for(BaseBiome biome : values()) { + for(Biome biome : values()) { BIOMES[biome.id] = biome; if(LOOKUP.containsKey(biome.name.toLowerCase())) throw new IllegalStateException("Biom \"" + biome.name + "\" ist als ID " + LOOKUP.get(biome.name.toLowerCase()).id + " und " + biome.id + " definiert"); @@ -113,7 +113,7 @@ public enum BaseBiome { } } - public static BaseBiome getBiome(int id) + public static Biome getBiome(int id) { if (id >= 0 && id < BIOMES.length) { @@ -126,11 +126,11 @@ public enum BaseBiome { } } - public static BaseBiome getBiomeDef(int id) + public static Biome getBiomeDef(int id) { if (id >= 0 && id < BIOMES.length) { - BaseBiome biome = BIOMES[id]; + Biome biome = BIOMES[id]; return biome == null ? DEF_BIOME : biome; } else @@ -144,8 +144,8 @@ public enum BaseBiome { return Lists.newArrayList(LOOKUP.keySet()); } - public static BaseBiome findByName(String name) { - BaseBiome biome = LOOKUP.get(name.toLowerCase().replace(" ", "").replace("_", "")); + public static Biome findByName(String name) { + Biome biome = LOOKUP.get(name.toLowerCase().replace(" ", "").replace("_", "")); if(biome == null) { int z; try { @@ -159,7 +159,7 @@ public enum BaseBiome { return biome; } - private BaseBiome(int id, String name, String display, int color, float temperature, float humidity, int waterColor, int grassColor, int foliageColor, int skyColor, int fogColor, int cloudColor) { + private Biome(int id, String name, String display, int color, float temperature, float humidity, int waterColor, int grassColor, int foliageColor, int skyColor, int fogColor, int cloudColor) { this.id = id; this.name = name; this.display = display; @@ -174,19 +174,19 @@ public enum BaseBiome { this.cloudColor = cloudColor; } - private BaseBiome(int id, String name, String display, int color, float temperature, float humidity, int waterColor, int grassColor, int foliageColor) { + private Biome(int id, String name, String display, int color, float temperature, float humidity, int waterColor, int grassColor, int foliageColor) { this(id, name, display, color, temperature, humidity, waterColor, grassColor, foliageColor, 0xffffffff, 0xffffffff, 0xffffffff); } - private BaseBiome(int id, String name, String display, int color, float temperature, float humidity) { + private Biome(int id, String name, String display, int color, float temperature, float humidity) { this(id, name, display, color, temperature, humidity, 0xffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff); } - private BaseBiome(int id, String name, String display, int color, float temperature) { + private Biome(int id, String name, String display, int color, float temperature) { this(id, name, display, color, temperature, 50.0f, 0xffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff); } - private BaseBiome(int id, String name, String display, int color) { + private Biome(int id, String name, String display, int color) { this(id, name, display, color, 0.0f, 50.0f, 0xffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff); } diff --git a/common/src/common/biome/IBiome.java b/common/src/common/biome/IBiome.java index c46503f..27027f1 100644 --- a/common/src/common/biome/IBiome.java +++ b/common/src/common/biome/IBiome.java @@ -9,7 +9,7 @@ import common.world.State; public interface IBiome { public static abstract class BiomeProvider { private static BiomeProvider provider = new BiomeProvider() { - public IBiome getBiome(BaseBiome base) { + public IBiome getBiome(Biome base) { return new IBiome() { public State getFiller() { return BlockRegistry.getRegisteredBlock("air").getState(); @@ -28,14 +28,14 @@ public interface IBiome { } }; - public abstract IBiome getBiome(BaseBiome base); + public abstract IBiome getBiome(Biome base); } public static void setProvider(BiomeProvider provider) { BiomeProvider.provider = provider; } - public static IBiome getBiome(BaseBiome base) { + public static IBiome getBiome(Biome base) { return BiomeProvider.provider.getBiome(base); } diff --git a/common/src/common/block/BlockDispenser.java b/common/src/common/block/BlockDispenser.java index 98595fe..1a80d27 100755 --- a/common/src/common/block/BlockDispenser.java +++ b/common/src/common/block/BlockDispenser.java @@ -8,7 +8,6 @@ import common.dispenser.PositionImpl; import common.entity.npc.EntityNPC; import common.entity.types.EntityLiving; import common.init.DispenserRegistry; -import common.init.RegistryDefaulted; import common.inventory.Container; import common.inventory.InventoryHelper; import common.item.CheatTab; @@ -26,6 +25,7 @@ import common.tileentity.TileEntity; import common.tileentity.TileEntityDispenser; import common.util.BlockPos; import common.util.Facing; +import common.util.RegistryDefaulted; import common.world.State; import common.world.World; import common.world.AWorldServer; diff --git a/common/src/common/color/Colorizer.java b/common/src/common/color/Colorizer.java index 468793a..dcae2c9 100755 --- a/common/src/common/color/Colorizer.java +++ b/common/src/common/color/Colorizer.java @@ -1,6 +1,6 @@ package common.color; -import common.biome.BaseBiome; +import common.biome.Biome; import common.util.BlockPos; import common.world.IWorldAccess; @@ -8,21 +8,21 @@ public enum Colorizer { NONE(0xffffff), BASIC(0x37b500), PINE(0x3f993f), BIRCH(0x68a723); private interface ColorResolver { - int getColorAtPos(BaseBiome biome, BlockPos pos); + int getColorAtPos(Biome biome, BlockPos pos); } private static final ColorResolver GRASS_COLOR = new ColorResolver() { - public int getColorAtPos(BaseBiome biome, BlockPos pos) { + public int getColorAtPos(Biome biome, BlockPos pos) { return biome.getGrassColorAtPos(pos); } }; private static final ColorResolver FOLIAGE_COLOR = new ColorResolver() { - public int getColorAtPos(BaseBiome biome, BlockPos pos) { + public int getColorAtPos(Biome biome, BlockPos pos) { return biome.getFoliageColorAtPos(pos); } }; private static final ColorResolver WATER_COLOR_MULTIPLIER = new ColorResolver() { - public int getColorAtPos(BaseBiome biome, BlockPos pos) { + public int getColorAtPos(Biome biome, BlockPos pos) { return biome.waterColor; } }; diff --git a/common/src/common/dimension/Dimension.java b/common/src/common/dimension/Dimension.java index b3ef389..bcb9137 100755 --- a/common/src/common/dimension/Dimension.java +++ b/common/src/common/dimension/Dimension.java @@ -4,7 +4,7 @@ import java.util.List; import java.util.Map; import java.util.Set; -import common.biome.BaseBiome; +import common.biome.Biome; import common.biome.IBiome; import common.block.LeavesType; import common.collect.Lists; @@ -270,7 +270,7 @@ public abstract class Dimension extends Nameable implements Comparable ores = Lists.newArrayList(); private final List lakes = Lists.newArrayList(); @@ -462,12 +462,12 @@ public abstract class Dimension extends Nameable implements Comparable 50.0D && this.posY < 70.0D && this.rand.floatv() < 0.5F && this.rand.floatv() < this.worldObj.getCurrentMoonPhaseFactor() && this.worldObj.getLightFromNeighbors(new BlockPos(this)) <= this.rand.zrange(8)) + if (biomegenbase == Biome.SWAMPLAND && this.posY > 50.0D && this.posY < 70.0D && this.rand.floatv() < 0.5F && this.rand.floatv() < this.worldObj.getCurrentMoonPhaseFactor() && this.worldObj.getLightFromNeighbors(new BlockPos(this)) <= this.rand.zrange(8)) { return super.getCanSpawnHere(); } diff --git a/common/src/common/init/BlockRegistry.java b/common/src/common/init/BlockRegistry.java index 2486248..2139cff 100755 --- a/common/src/common/init/BlockRegistry.java +++ b/common/src/common/init/BlockRegistry.java @@ -5,6 +5,8 @@ import common.color.DyeColor; import common.init.FluidRegistry.LiquidType; import common.item.CheatTab; import common.material.Material; +import common.util.ObjectIntIdentityMap; +import common.util.RegistryNamespacedDefaultedByKey; import common.world.State; public abstract class BlockRegistry { diff --git a/common/src/common/init/DispenserRegistry.java b/common/src/common/init/DispenserRegistry.java index 64bc258..3f161a1 100755 --- a/common/src/common/init/DispenserRegistry.java +++ b/common/src/common/init/DispenserRegistry.java @@ -38,6 +38,7 @@ import common.tileentity.TileEntityDispenser; import common.util.BlockPos; import common.util.ExtMath; import common.util.Facing; +import common.util.RegistryDefaulted; import common.world.State; import common.world.World; @@ -149,7 +150,7 @@ public abstract class DispenserRegistry { } }; for(EntityEggInfo egg : EntityRegistry.SPAWN_EGGS.values()) { - REGISTRY.putObject(ItemRegistry.getRegisteredItem(egg.spawnedID.toLowerCase() + "_spawner"), + REGISTRY.putObject(ItemRegistry.getRegisteredItem(egg.id.toLowerCase() + "_spawner"), disp); } REGISTRY.putObject(Items.fireworks, new BehaviorDefaultDispenseItem() diff --git a/common/src/common/init/EntityEggInfo.java b/common/src/common/init/EntityEggInfo.java index 8f7b708..87351b9 100755 --- a/common/src/common/init/EntityEggInfo.java +++ b/common/src/common/init/EntityEggInfo.java @@ -1,22 +1,15 @@ package common.init; -public class EntityEggInfo -{ - public final String spawnedID; - public final String origin; - public final int primaryColor; - public final int secondaryColor; -// public final StatBase killStat; -// public final StatBase killedByStat; +public class EntityEggInfo { + public final String id; + public final String origin; + public final int color1; + public final int color2; - public EntityEggInfo(String id, String origin, int baseColor, int spotColor) - { - this.spawnedID = id; - this.origin = origin; - this.primaryColor = baseColor; - this.secondaryColor = spotColor; -// this.killStat = new StatBase("stat.killEntity." + this.spawnedID, EntityRegistry.getEntityName(this.spawnedID) + " getötet"); -// this.killedByStat = new StatBase("stat.entityKilledBy." + this.spawnedID, -// "Von " + EntityRegistry.getEntityName(this.spawnedID) + " getötet"); - } -} \ No newline at end of file + public EntityEggInfo(String id, String origin, int color1, int color2) { + this.id = id; + this.origin = origin; + this.color1 = color1; + this.color2 = color2; + } +} diff --git a/common/src/common/init/ItemRegistry.java b/common/src/common/init/ItemRegistry.java index 1621698..18a101d 100755 --- a/common/src/common/init/ItemRegistry.java +++ b/common/src/common/init/ItemRegistry.java @@ -123,6 +123,7 @@ import common.item.ItemWall; import common.item.ItemWeatherToken; import common.potion.Potion; import common.potion.PotionHelper; +import common.util.RegistryNamespaced; import common.world.Weather; public abstract class ItemRegistry { @@ -371,7 +372,7 @@ public abstract class ItemRegistry { registerItem("tnt_minecart", (new ItemMinecart(EntityCart.EnumMinecartType.TNT)).setDisplay("TNT-Lore") .setColor(TextColor.RED)); for(EntityEggInfo egg : EntityRegistry.SPAWN_EGGS.values()) { - registerItem(egg.spawnedID.toLowerCase() + "_spawner", (new ItemMonsterPlacer(egg.spawnedID)) + registerItem(egg.id.toLowerCase() + "_spawner", (new ItemMonsterPlacer(egg.id)) .setDisplay("Spawner").setMaxStackSize(ItemStack.MAX_SIZE)); } for(SpeciesInfo species : SpeciesRegistry.SPECIMEN) { diff --git a/common/src/common/init/TileRegistry.java b/common/src/common/init/TileRegistry.java index 2f74da8..6af28ba 100755 --- a/common/src/common/init/TileRegistry.java +++ b/common/src/common/init/TileRegistry.java @@ -39,8 +39,6 @@ public abstract class TileRegistry { static void register() { addMapping(TileEntityFurnace.class, "Furnace"); addMapping(TileEntityChest.class, "Chest"); -// addMapping(TileEntityWarpChest.class, "WarpChest"); -// addMapping(BlockJukebox.TileEntityJukebox.class, "RecordPlayer"); addMapping(TileEntityDispenser.class, "Trap"); addMapping(TileEntityDropper.class, "Dropper"); addMapping(TileEntitySign.class, "Sign"); @@ -49,14 +47,11 @@ public abstract class TileRegistry { addMapping(TileEntityPiston.class, "Piston"); addMapping(TileEntityBrewingStand.class, "Cauldron"); addMapping(TileEntityEnchantmentTable.class, "EnchantTable"); -// addMapping(TileEntityPortal.class, "Portal"); -// addMapping(TileEntityCommandBlock.class, "Control"); addMapping(TileEntityBeacon.class, "Beacon"); addMapping(TileEntitySkull.class, "Skull"); addMapping(TileEntityDaylightDetector.class, "DLDetector"); addMapping(TileEntityHopper.class, "Hopper"); addMapping(TileEntityComparator.class, "Comparator"); -// addMapping(TileEntityFlowerPot.class, "FlowerPot"); addMapping(TileEntityBanner.class, "Banner"); addMapping(TileEntityTianReactor.class, "TianReactor"); } diff --git a/common/src/common/init/UniverseRegistry.java b/common/src/common/init/UniverseRegistry.java index dd02b2c..e8e2d4c 100755 --- a/common/src/common/init/UniverseRegistry.java +++ b/common/src/common/init/UniverseRegistry.java @@ -4,7 +4,7 @@ import java.util.List; import java.util.Map; import java.util.Map.Entry; -import common.biome.BaseBiome; +import common.biome.Biome; import common.block.BlockColored; import common.block.BlockSand; import common.block.LeavesType; @@ -526,12 +526,12 @@ public abstract class UniverseRegistry { 259.15f).setTimeQualifier(0) .setPerlinGen(Blocks.stone.getState(), Blocks.water.getState(), 63) .setBiomeReplacer(Blocks.gravel.getState()) - .setBiomeGen(BaseBiome.FOREST, false, 4, 4, 6, 50, 50, BaseBiome.MUSHROOMPLAINS).enableMobs().enableSnow() - .setFrostBiomes(BaseBiome.ICEPLAINS, BaseBiome.ICEPLAINS, BaseBiome.ICEPLAINS, BaseBiome.COLDTAIGA, BaseBiome.MEGATAIGA) - .setColdBiomes(BaseBiome.FOREST, BaseBiome.EXTREMEHILLS, BaseBiome.TAIGA, BaseBiome.PLAINS, BaseBiome.BLACKENED) - .setMediumBiomes(BaseBiome.FOREST, BaseBiome.ROOFEDFOREST, BaseBiome.EXTREMEHILLS, BaseBiome.PLAINS, BaseBiome.BIRCHFOREST, - BaseBiome.SWAMPLAND, BaseBiome.JUNGLE, BaseBiome.BLACKENED) - .setHotBiomes(BaseBiome.DESERT, BaseBiome.DESERT, BaseBiome.DESERT, BaseBiome.SAVANNA, BaseBiome.SAVANNA, BaseBiome.PLAINS) + .setBiomeGen(Biome.FOREST, false, 4, 4, 6, 50, 50, Biome.MUSHROOMPLAINS).enableMobs().enableSnow() + .setFrostBiomes(Biome.ICEPLAINS, Biome.ICEPLAINS, Biome.ICEPLAINS, Biome.COLDTAIGA, Biome.MEGATAIGA) + .setColdBiomes(Biome.FOREST, Biome.EXTREMEHILLS, Biome.TAIGA, Biome.PLAINS, Biome.BLACKENED) + .setMediumBiomes(Biome.FOREST, Biome.ROOFEDFOREST, Biome.EXTREMEHILLS, Biome.PLAINS, Biome.BIRCHFOREST, + Biome.SWAMPLAND, Biome.JUNGLE, Biome.BLACKENED) + .setHotBiomes(Biome.DESERT, Biome.DESERT, Biome.DESERT, Biome.SAVANNA, Biome.SAVANNA, Biome.PLAINS) .enableCavesRavines(Blocks.lava.getState()).setDungeons(8).setWorldFloor(Blocks.bedrock.getState()) .addLake(Blocks.water.getState(), null, Blocks.grass.getState(), 4, 0, 255, false) .addLake(Blocks.lava.getState(), Blocks.stone.getState(), null, 8, 8, 255, true) @@ -549,7 +549,7 @@ public abstract class UniverseRegistry { .addOre(Blocks.cinnabar_ore.getState(), 1, 0, 11, 0, 24, false) .enableVillages().enableMineshafts().enableScattered().enableStrongholds(), "sol"); registerDimension("Luna", new Moon(3, "luna", 0x333333, 0x333333, 655728L, 655728L, 1.62f, 210.0f, 8) - .setPerlinGen(Blocks.moon_rock.getState(), Blocks.air.getState(), 63).setBiome(BaseBiome.MOON) + .setPerlinGen(Blocks.moon_rock.getState(), Blocks.air.getState(), 63).setBiome(Biome.MOON) .setTimeQualifier(1), "terra"); registerDimension("Merkur", new Planet(4, "mercury", 0x666666, 0x535353, 0x858585, 2111297L, 1407509L, 3.7f, 440.0f) @@ -592,7 +592,7 @@ public abstract class UniverseRegistry { registerDimension("Gi'rok", new Star(100, "girok", 0xff8f00, 232.0f, 5220.0f, Blocks.lava.getState(), 112).setTimeQualifier(2), "solar"); registerDimension("'Elbenplanet Gharoth'", new Planet(101, "gharoth", 0xffffffff, 0xc0d8ff, 0xffffff, 4837386L, 52960L, 30.0f, 10.0f, 257.3f) .setTimeQualifier(2).setSimpleGen(Blocks.dirt.getState(), Blocks.water.getState(), 64) - .setSimpleReplacer(Blocks.gravel.getState(), Blocks.sand.getState()).setBiome(BaseBiome.ELVENFOREST) + .setSimpleReplacer(Blocks.gravel.getState(), Blocks.sand.getState()).setBiome(Biome.ELVENFOREST) .enableCaves(Blocks.air.getState()).setDungeons(4).enableMobs().enableSnow() .setWorldFloor(Blocks.bedrock.getState()) .addLake(Blocks.water.getState(), null, Blocks.grass.getState(), 4, 0, 255, false) @@ -603,7 +603,7 @@ public abstract class UniverseRegistry { .addOre(Blocks.gyriyn_ore.getState(), 0, 2, 3, 0, 12, false), "girok"); registerDimension("'Vampirplanet Transsylvanien'", new Planet(102, "transylvania", 0xffffffff, 0xc0d8ff, 0xffffff, 33850466L, 49760L, 20.0f, 10.0f, 255.5f) .setTimeQualifier(5).setPerlinGen(Blocks.rock.getState(), Blocks.water.getState(), 63) - .setBiomeReplacer(Blocks.gravel.getState()).setBiomeGen(BaseBiome.FOREST, true, 5, 3, 3, 30) + .setBiomeReplacer(Blocks.gravel.getState()).setBiomeGen(Biome.FOREST, true, 5, 3, 3, 30) .enableCavesRavines(Blocks.lava.getState()).setDungeons(10).enableMobs().enableSnow() .setWorldFloor(Blocks.bedrock.getState()) .addLake(Blocks.water.getState(), null, Blocks.grass.getState(), 4, 0, 255, false) @@ -615,12 +615,12 @@ public abstract class UniverseRegistry { .addOre(Blocks.ardite_ore.getState(), 0, 2, 3, 0, 12, false) .addOre(Blocks.nichun_ore.getState(), 0, 10, 1, 0, 10, false), "girok"); registerDimension("'Eismond Yrdinath'", new Moon(103, "yrdinath", 0xccccff, 0xccccff, 46743637L, 17460L, 2.5f, 239.15f, 8).setTimeQualifier(4) - .setPerlinGen(Blocks.snow.getState(), Blocks.ice.getState(), 63).setBiome(BaseBiome.SNOWLAND) + .setPerlinGen(Blocks.snow.getState(), Blocks.ice.getState(), 63).setBiome(Biome.SNOWLAND) .setWorldFloor(Blocks.air.getState()).enableMobs().enableSnow().setWeather(Weather.SNOW), "transylvania"); registerDimension("'Wüstenplanet Me'sar'", new Planet(104, "mesar", 0xff7f3f, 0xff6022, 0xff6f00, 56643366L, 87340L, 11.0f, 333.15f) .setTimeQualifier(5).setPerlinGen(Blocks.rock.getState(), Blocks.air.getState(), 63) .setBiomeReplacer(Blocks.sand.getState().withProperty(BlockSand.VARIANT, BlockSand.EnumType.RED_SAND)) - .setBiomeGen(BaseBiome.MESA, true, 3, 1000, 100000, 100000) + .setBiomeGen(Biome.MESA, true, 3, 1000, 100000, 100000) .enableCavesRavines(Blocks.lava.getState()).enableMobs() .setWorldFloor(Blocks.bedrock.getState()) .addLake(Blocks.lava.getState(), null, null, 8, 8, 255, true) @@ -637,7 +637,7 @@ public abstract class UniverseRegistry { registerDimension("Ov'rol", new Star(120, "ovrol", 0x000000, 302.0f, 12666.0f, Blocks.goo.getState(), 192), "blvck"); registerDimension("'Schwarzplanet'", new Planet(121, "blackplanet", 0x000000, 0x000000, 0x000000, 4632918508L, 204556L, 12.0f, 0.0f) .setPerlinGen(Blocks.blackened_stone.getState(), Blocks.goo.getState(), 63) - .setBiomeReplacer(Blocks.blackened_cobble.getState()).setBiome(BaseBiome.BLACKENED) + .setBiomeReplacer(Blocks.blackened_cobble.getState()).setBiome(Biome.BLACKENED) .enableCaves(Blocks.air.getState()).setDungeons(4).enableMobs() .setWorldFloor(Blocks.bedrock.getState()) .addLake(Blocks.goo.getState(), null, null, 8, 8, 255, true) @@ -646,7 +646,7 @@ public abstract class UniverseRegistry { registerDimension("Der Warp", new Semi(-1, "warp", 0x0c001f, 0x0c001f, 0x190033, 285.0f, 3).setCloudTexture("clouds_dense").setCloudHeight(238.0f) .setPerlinGen(Blocks.obsidian.getState(), Blocks.lava.getState(), 63) - .setBiome(BaseBiome.CHAOS).enableCavesRavines(Blocks.air.getState()).enableLongCaves().enableMobs().enableSnow() + .setBiome(Biome.CHAOS).enableCavesRavines(Blocks.air.getState()).enableLongCaves().enableMobs().enableSnow() .addLake(Blocks.water.getState(), null, Blocks.obsidian.getState(), 8, 0, 255, false) .addLake(Blocks.lava.getState(), null, null, 1, 8, 255, false) .addLiquid(Blocks.flowing_water.getState(), 1, 8, 255, false) @@ -656,7 +656,7 @@ public abstract class UniverseRegistry { registerDomain("Tian'Xin", "tianxin"); registerDimension("Ni'enrath", new Area(-2, "nienrath", 0x7f00ff, 0x7f00ff, 276.15f, 1) - .setPerlinGen(Blocks.tian.getState(), Blocks.water.getState(), 63).setBiome(BaseBiome.TIAN) + .setPerlinGen(Blocks.tian.getState(), Blocks.water.getState(), 63).setBiome(Biome.TIAN) .setBiomeReplacer(Blocks.tian.getState()).enableLongCaves().enableMobs().enableSnow() .addLake(Blocks.water.getState(), Blocks.tian.getState(), Blocks.tian.getState(), 4, 0, 255, false) .addLiquid(Blocks.flowing_water.getState(), 50, 8, 255, false), "tianxin"); @@ -670,32 +670,32 @@ public abstract class UniverseRegistry { .setWorldFloor(Blocks.air.getState()).setWorldCeiling(Blocks.bedrock.getState()).enableDenseFog() .setCavernGen(Blocks.hellrock.getState(), Blocks.lava.getState(), 63) .setSurfaceReplacer(Blocks.gravel.getState(), Blocks.soul_sand.getState()) - .setBiome(BaseBiome.UPPERHELL), "hell"); + .setBiome(Biome.UPPERHELL), "hell"); registerDimension("Kreis Kyroth", new Area(-1002, "kyroth", 0x990000, 0x990000, 387.15f, 3).enableLongCaves().enableMobs() .setWorldFloor(Blocks.air.getState()) .setSimpleGen(Blocks.hellrock.getState(), Blocks.lava.getState(), 64) .setSimpleReplacer(Blocks.obsidian.getState(), Blocks.soul_sand.getState()) - .setBiome(BaseBiome.LOWERHELL) + .setBiome(Biome.LOWERHELL) .addLake(Blocks.lava.getState(), null, null, 4, 8, 255, false) .addLiquid(Blocks.flowing_lava.getState(), 40, 8, 255, true), "hell"); registerDimension("Kreis Ahrd", new Area(-1003, "ahrd", 0xcc0000, 0xcc0000, 467.15f, 15).enableLongCaves().enableMobs() .setWorldFloor(Blocks.air.getState()) .setPerlinGen(Blocks.hellrock.getState(), Blocks.lava.getState(), 63) - .setBiomeReplacer(Blocks.soul_sand.getState()).setBiome(BaseBiome.HELLHILLS) + .setBiomeReplacer(Blocks.soul_sand.getState()).setBiome(Biome.HELLHILLS) .addLake(Blocks.lava.getState(), Blocks.soul_sand.getState(), Blocks.soul_sand.getState(), 2, 8, 255, false).addLiquid(Blocks.flowing_lava.getState(), 80, 8, 255, true), "hell"); registerDimension("Kreis Mizorath", new Area(-1004, "mizorath", 0xff0000, 0xff0000, 1067.15f, 15).enableMobs() .setWorldFloor(Blocks.air.getState()) .setPerlinGen(Blocks.hellrock.getState(), Blocks.blood.getState(), 63) - .setBiomeReplacer(Blocks.soul_sand.getState()).setBiome(BaseBiome.SOULPLAINS), "hell"); + .setBiomeReplacer(Blocks.soul_sand.getState()).setBiome(Biome.SOULPLAINS), "hell"); registerDimension("Kreis Dargoth", new Area(-1005, "dargoth", 0xff3f0c, 0xff3f0c, 1707.15f, 15).enableMobs() .setWorldFloor(Blocks.air.getState()) .setPerlinGen(Blocks.hellrock.getState(), Blocks.magma.getState(), 63) - .setBiomeReplacer(Blocks.soul_sand.getState()).setBiome(BaseBiome.SOULPLAINS), "hell"); + .setBiomeReplacer(Blocks.soul_sand.getState()).setBiome(Biome.SOULPLAINS), "hell"); registerDimension("Kreis Aasirith", new Area(-1006, "aasirith", 0x191919, 0x191919, 2482.0f, 1).enableLongCaves().enableMobs() .setWorldFloor(Blocks.air.getState()) .setPerlinGen(Blocks.rock.getState(), Blocks.magma.getState(), 63) - .setBiomeReplacer(Blocks.ash.getState()).setBiome(BaseBiome.ASHLAND) + .setBiomeReplacer(Blocks.ash.getState()).setBiome(Biome.ASHLAND) .addLake(Blocks.lava.getState(), Blocks.rock.getState(), Blocks.rock.getState(), 2, 8, 255, false).addLiquid(Blocks.flowing_lava.getState(), 80, 8, 255, true), "hell"); @@ -749,7 +749,7 @@ public abstract class UniverseRegistry { dtag.setInteger("SeaRarity", 50); dtag.setInteger("AddRarity", 50); dtag.setInteger("SeaLevel", 0); - dtag.setString("DefaultBiome", BaseBiome.NONE.name.toLowerCase()); + dtag.setString("DefaultBiome", Biome.NONE.name.toLowerCase()); dtag.setBoolean("SemiFixed", false); // dtag.setString("DefaultWeather", Weather.CLEAR.getName()); dtag.setString("DefaultLeaves", LeavesType.SPRING.getName()); @@ -768,11 +768,11 @@ public abstract class UniverseRegistry { return dim; } - private static Dimension addFlatPreset(String name, BaseBiome biome, boolean populate, State main, Object ... layers) { + private static Dimension addFlatPreset(String name, Biome biome, boolean populate, State main, Object ... layers) { return addFlatPreset(name, "terra", biome, populate, main, layers); } - private static Dimension addFlatPreset(String name, String base, BaseBiome biome, boolean populate, State main, Object ... layers) { + private static Dimension addFlatPreset(String name, String base, Biome biome, boolean populate, State main, Object ... layers) { Dimension dim = addPreset("Flach - " + name, base, "ClearGenerator:1b" + (populate ? "" : ",NoPopulation:1b")); dim.setBiome(biome); if(main != null) @@ -795,33 +795,33 @@ public abstract class UniverseRegistry { addPreset("Chaotische Höhlen", "UpperLmtScale:2.0,LowerLmtScale:64.0,SeaLevel:6"); addPreset("Viel Glück", "LiquidBlock:lava,SeaLevel:40"); - addFlatPreset("Klassisch", BaseBiome.PLAINS, false, Blocks.dirt.getState(), Blocks.bedrock.getState(), 2, Blocks.dirt.getState(), + addFlatPreset("Klassisch", Biome.PLAINS, false, Blocks.dirt.getState(), Blocks.bedrock.getState(), 2, Blocks.dirt.getState(), Blocks.grass.getState()).enableVillages(); - addFlatPreset("Abbauwelt", BaseBiome.EXTREMEHILLS, true, Blocks.stone.getState(), Blocks.bedrock.getState(), 230, Blocks.stone.getState(), + addFlatPreset("Abbauwelt", Biome.EXTREMEHILLS, true, Blocks.stone.getState(), Blocks.bedrock.getState(), 230, Blocks.stone.getState(), 5, Blocks.dirt.getState(), Blocks.grass.getState()).enableStrongholds().enableMineshafts().setDungeons(8); - addFlatPreset("Wasserwelt", BaseBiome.SEA, false, Blocks.stone.getState(), Blocks.bedrock.getState(), 5, Blocks.stone.getState(), + addFlatPreset("Wasserwelt", Biome.SEA, false, Blocks.stone.getState(), Blocks.bedrock.getState(), 5, Blocks.stone.getState(), 52, Blocks.dirt.getState(), 5, Blocks.sand.getState(), 90, Blocks.water.getState()); - addFlatPreset("Oberfläche", BaseBiome.PLAINS, true, Blocks.stone.getState(), Blocks.bedrock.getState(), 59, Blocks.stone.getState(), + addFlatPreset("Oberfläche", Biome.PLAINS, true, Blocks.stone.getState(), Blocks.bedrock.getState(), 59, Blocks.stone.getState(), 3, Blocks.dirt.getState(), Blocks.grass.getState()).setBiomeReplacer(Blocks.gravel.getState()).enableVillages().enableStrongholds().enableMineshafts().setDungeons(8) .addLake(Blocks.water.getState(), null, Blocks.grass.getState(), 4, 0, 255, false).addLake(Blocks.lava.getState(), Blocks.stone.getState(), null, 8, 8, 255, true); - addFlatPreset("Verschneites Königreich", BaseBiome.ICEPLAINS, false, Blocks.stone.getState(), Blocks.bedrock.getState(), 59, Blocks.stone.getState(), + addFlatPreset("Verschneites Königreich", Biome.ICEPLAINS, false, Blocks.stone.getState(), Blocks.bedrock.getState(), 59, Blocks.stone.getState(), 3, Blocks.dirt.getState(), Blocks.grass.getState(), Blocks.snow_layer.getState()).enableVillages(); - addFlatPreset("Verschneites Königreich +", BaseBiome.ICEPLAINS, true, Blocks.stone.getState(), Blocks.bedrock.getState(), 59, Blocks.stone.getState(), + addFlatPreset("Verschneites Königreich +", Biome.ICEPLAINS, true, Blocks.stone.getState(), Blocks.bedrock.getState(), 59, Blocks.stone.getState(), 3, Blocks.dirt.getState(), Blocks.grass.getState(), Blocks.snow_layer.getState()).setBiomeReplacer(Blocks.gravel.getState()).enableVillages() .addLake(Blocks.water.getState(), null, Blocks.grass.getState(), 4, 0, 255, false); - addFlatPreset("Unendliche Grube", BaseBiome.PLAINS, false, Blocks.dirt.getState(), 2, Blocks.cobblestone.getState(), 3, Blocks.dirt.getState(), Blocks.grass.getState()) + addFlatPreset("Unendliche Grube", Biome.PLAINS, false, Blocks.dirt.getState(), 2, Blocks.cobblestone.getState(), 3, Blocks.dirt.getState(), Blocks.grass.getState()) .setBiomeReplacer(Blocks.gravel.getState()).enableVillages(); - addFlatPreset("Wüste", BaseBiome.DESERT, false, Blocks.stone.getState(), Blocks.bedrock.getState(), 3, Blocks.stone.getState(), 52, Blocks.sandstone.getState()) + addFlatPreset("Wüste", Biome.DESERT, false, Blocks.stone.getState(), Blocks.bedrock.getState(), 3, Blocks.stone.getState(), 52, Blocks.sandstone.getState()) .enableVillages().enableScattered(); - addFlatPreset("Redstonewelt", BaseBiome.DESERT, false, Blocks.sandstone.getState(), Blocks.bedrock.getState(), 3, Blocks.stone.getState(), + addFlatPreset("Redstonewelt", Biome.DESERT, false, Blocks.sandstone.getState(), Blocks.bedrock.getState(), 3, Blocks.stone.getState(), 52, Blocks.sandstone.getState()); addPreset("Leer", "ClearGenerator:1b"); diff --git a/common/src/common/item/ItemInfoWand.java b/common/src/common/item/ItemInfoWand.java index a0250f0..6370462 100755 --- a/common/src/common/item/ItemInfoWand.java +++ b/common/src/common/item/ItemInfoWand.java @@ -1,6 +1,6 @@ package common.item; -import common.biome.BaseBiome; +import common.biome.Biome; import common.color.TextColor; import common.entity.npc.EntityNPC; import common.util.BlockPos; @@ -14,7 +14,7 @@ public class ItemInfoWand extends ItemWand { public void onUse(ItemStack stack, EntityNPC player, AWorldServer world, Vec3 vec) { - BaseBiome biome = world.getBiomeGenForCoords(new BlockPos(vec.xCoord, 0, vec.zCoord)); + Biome biome = world.getBiomeGenForCoords(new BlockPos(vec.xCoord, 0, vec.zCoord)); player.connection.addHotbar(TextColor.NEON + "* Position bei Level %d: %.3f %.3f %.3f, %s [%d], %.2f °C", world.dimension.getDimensionId(), vec.xCoord, vec.yCoord, vec.zCoord, biome.display, biome.id, world.getTemperatureC(new BlockPos(vec))); diff --git a/common/src/common/item/ItemMonsterPlacer.java b/common/src/common/item/ItemMonsterPlacer.java index 45a1c85..b5e0d4d 100755 --- a/common/src/common/item/ItemMonsterPlacer.java +++ b/common/src/common/item/ItemMonsterPlacer.java @@ -55,7 +55,7 @@ public class ItemMonsterPlacer extends Item public int getColorFromItemStack(ItemStack stack, int renderPass) { EntityEggInfo egg = EntityRegistry.SPAWN_EGGS.get(this.entityId); - return egg != null ? (renderPass == 0 ? egg.primaryColor : egg.secondaryColor) : 16777215; + return egg != null ? (renderPass == 0 ? egg.color1 : egg.color2) : 16777215; } public void addInformation(ItemStack stack, EntityNPC player, List tooltip) { diff --git a/common/src/common/init/IObjectIntIterable.java b/common/src/common/util/IObjectIntIterable.java similarity index 75% rename from common/src/common/init/IObjectIntIterable.java rename to common/src/common/util/IObjectIntIterable.java index 20e5fbf..970ee52 100755 --- a/common/src/common/init/IObjectIntIterable.java +++ b/common/src/common/util/IObjectIntIterable.java @@ -1,4 +1,4 @@ -package common.init; +package common.util; public interface IObjectIntIterable extends Iterable { diff --git a/common/src/common/init/IRegistry.java b/common/src/common/util/IRegistry.java similarity index 89% rename from common/src/common/init/IRegistry.java rename to common/src/common/util/IRegistry.java index 9dc54b3..eaf299b 100755 --- a/common/src/common/init/IRegistry.java +++ b/common/src/common/util/IRegistry.java @@ -1,4 +1,4 @@ -package common.init; +package common.util; public interface IRegistry extends Iterable { diff --git a/common/src/common/init/ObjectIntIdentityMap.java b/common/src/common/util/ObjectIntIdentityMap.java similarity index 95% rename from common/src/common/init/ObjectIntIdentityMap.java rename to common/src/common/util/ObjectIntIdentityMap.java index c6cb6b2..88b9234 100755 --- a/common/src/common/init/ObjectIntIdentityMap.java +++ b/common/src/common/util/ObjectIntIdentityMap.java @@ -1,4 +1,4 @@ -package common.init; +package common.util; import java.util.IdentityHashMap; import java.util.Iterator; @@ -6,7 +6,6 @@ import java.util.List; import common.collect.Iterators; import common.collect.Lists; -import common.util.Predicates; public class ObjectIntIdentityMap implements IObjectIntIterable { diff --git a/common/src/common/init/RegistryDefaulted.java b/common/src/common/util/RegistryDefaulted.java similarity index 95% rename from common/src/common/init/RegistryDefaulted.java rename to common/src/common/util/RegistryDefaulted.java index 9b313bc..8a5d13a 100755 --- a/common/src/common/init/RegistryDefaulted.java +++ b/common/src/common/util/RegistryDefaulted.java @@ -1,4 +1,4 @@ -package common.init; +package common.util; public class RegistryDefaulted extends RegistrySimple { diff --git a/common/src/common/init/RegistryNamespaced.java b/common/src/common/util/RegistryNamespaced.java similarity index 99% rename from common/src/common/init/RegistryNamespaced.java rename to common/src/common/util/RegistryNamespaced.java index e7c7806..e6e40d7 100755 --- a/common/src/common/init/RegistryNamespaced.java +++ b/common/src/common/util/RegistryNamespaced.java @@ -1,4 +1,4 @@ -package common.init; +package common.util; import java.util.Iterator; import java.util.Map; diff --git a/common/src/common/init/RegistryNamespacedDefaultedByKey.java b/common/src/common/util/RegistryNamespacedDefaultedByKey.java similarity index 98% rename from common/src/common/init/RegistryNamespacedDefaultedByKey.java rename to common/src/common/util/RegistryNamespacedDefaultedByKey.java index f616966..cd41360 100755 --- a/common/src/common/init/RegistryNamespacedDefaultedByKey.java +++ b/common/src/common/util/RegistryNamespacedDefaultedByKey.java @@ -1,4 +1,4 @@ -package common.init; +package common.util; public class RegistryNamespacedDefaultedByKey extends RegistryNamespaced { diff --git a/common/src/common/init/RegistrySimple.java b/common/src/common/util/RegistrySimple.java similarity index 98% rename from common/src/common/init/RegistrySimple.java rename to common/src/common/util/RegistrySimple.java index 9bc6efc..8e75927 100755 --- a/common/src/common/init/RegistrySimple.java +++ b/common/src/common/util/RegistrySimple.java @@ -1,4 +1,4 @@ -package common.init; +package common.util; import java.util.Collections; import java.util.Iterator; diff --git a/common/src/common/world/Chunk.java b/common/src/common/world/Chunk.java index 84ed58c..6a5fdf7 100755 --- a/common/src/common/world/Chunk.java +++ b/common/src/common/world/Chunk.java @@ -6,7 +6,7 @@ import java.util.Map; import java.util.concurrent.ConcurrentLinkedQueue; import java.util.function.Predicate; -import common.biome.BaseBiome; +import common.biome.Biome; import common.block.Block; import common.block.ITileEntityProvider; import common.collect.Maps; @@ -63,7 +63,7 @@ public class Chunk { Arrays.fill(this.biomes, (byte)-1); } - public Chunk(World world, short[] data, int height, State base, State ceil, Random rand, BaseBiome[] biomes, int x, int z) { + public Chunk(World world, short[] data, int height, State base, State ceil, Random rand, Biome[] biomes, int x, int z) { this(world, x, z); boolean sky = !world.dimension.hasNoLight(); for(int bx = 0; bx < 16; ++bx) { @@ -956,18 +956,18 @@ public class Chunk { } } - public BaseBiome getBiome(BlockPos pos, BiomeGenerator gen) { + public Biome getBiome(BlockPos pos, BiomeGenerator gen) { int x = pos.getX() & 15; int z = pos.getZ() & 15; int o = this.biomes[z << 4 | x] & 255; if(o == 255) { - BaseBiome biome = gen == null ? BaseBiome.DEF_BIOME : gen.getBiomeGenerator(pos, BaseBiome.DEF_BIOME); + Biome biome = gen == null ? Biome.DEF_BIOME : gen.getBiomeGenerator(pos, Biome.DEF_BIOME); o = biome.id; this.biomes[z << 4 | x] = (byte)(o & 255); } - return BaseBiome.getBiomeDef(o); + return Biome.getBiomeDef(o); } public byte[] getBiomes() { diff --git a/common/src/common/world/IWorldAccess.java b/common/src/common/world/IWorldAccess.java index e90b74f..b798152 100755 --- a/common/src/common/world/IWorldAccess.java +++ b/common/src/common/world/IWorldAccess.java @@ -1,6 +1,6 @@ package common.world; -import common.biome.BaseBiome; +import common.biome.Biome; import common.tileentity.TileEntity; import common.util.BlockPos; @@ -8,5 +8,5 @@ public interface IWorldAccess extends IBlockAccess { TileEntity getTileEntity(BlockPos pos); int getCombinedLight(BlockPos pos, int lightValue); - BaseBiome getBiomeGenForCoords(BlockPos pos); + Biome getBiomeGenForCoords(BlockPos pos); } diff --git a/common/src/common/world/World.java b/common/src/common/world/World.java index 7597092..519dc36 100755 --- a/common/src/common/world/World.java +++ b/common/src/common/world/World.java @@ -6,7 +6,7 @@ import java.util.List; import java.util.Set; import java.util.function.Predicate; -import common.biome.BaseBiome; +import common.biome.Biome; import common.block.Block; import common.block.BlockHopper; import common.block.BlockLiquid; @@ -133,11 +133,11 @@ public abstract class World implements IWorldAccess { this.gravity = Math.signum(this.gravity) * 0.075; } - public BaseBiome getBiomeGenForCoords(final BlockPos pos) { + public Biome getBiomeGenForCoords(final BlockPos pos) { if(this.isBlockLoaded(pos)) return this.getChunk(pos).getBiome(pos, null); else - return BaseBiome.DEF_BIOME; + return Biome.DEF_BIOME; } public boolean isAirBlock(BlockPos pos) { diff --git a/common/src/common/worldgen/BiomeGenerator.java b/common/src/common/worldgen/BiomeGenerator.java index c8db4d7..b6ef4e9 100755 --- a/common/src/common/worldgen/BiomeGenerator.java +++ b/common/src/common/worldgen/BiomeGenerator.java @@ -2,15 +2,15 @@ package common.worldgen; import java.util.Set; -import common.biome.BaseBiome; +import common.biome.Biome; import common.util.BlockPos; public interface BiomeGenerator { public void genFactors(double[] factors, int xPos, int zPos, int sizeX, int sizeZ); - public BaseBiome getBiomeGenerator(BlockPos pos, BaseBiome def); - public void getGenBiomes(BaseBiome[] biomes, int x, int z, int width, int height); - public void getChunkBiomes(BaseBiome[] oldBiomeList, int x, int z, int width, int depth); - public void getBiomes(BaseBiome[] listToReuse, int x, int z, int width, int length, boolean cacheFlag); - public boolean areBiomesViable(int x, int z, int size, Set allowed); + public Biome getBiomeGenerator(BlockPos pos, Biome def); + public void getGenBiomes(Biome[] biomes, int x, int z, int width, int height); + public void getChunkBiomes(Biome[] oldBiomeList, int x, int z, int width, int depth); + public void getBiomes(Biome[] listToReuse, int x, int z, int width, int length, boolean cacheFlag); + public boolean areBiomesViable(int x, int z, int size, Set allowed); public void cleanupCache(); } diff --git a/server/src/server/Server.java b/server/src/server/Server.java index a85b8b8..188151c 100755 --- a/server/src/server/Server.java +++ b/server/src/server/Server.java @@ -87,7 +87,7 @@ import io.netty.channel.socket.nio.NioServerSocketChannel; import io.netty.handler.timeout.ReadTimeoutHandler; import io.netty.util.concurrent.Future; import io.netty.util.concurrent.GenericFutureListener; -import server.biome.Biome; +import server.biome.GenBiome; import server.clipboard.ReorderRegistry; import server.clipboard.RotationRegistry; import server.command.CommandEnvironment; @@ -148,7 +148,7 @@ public final class Server implements IThreadListener { public static void main(String[] args) { Util.checkOs(); Registry.setup("Server thread"); - Biome.setAsProvider(); + GenBiome.setAsProvider(); UniverseRegistry.register(); RotationRegistry.register(); ReorderRegistry.register(); diff --git a/server/src/server/biome/BiomeBeach.java b/server/src/server/biome/BiomeBeach.java index e6fac04..a4dbee5 100755 --- a/server/src/server/biome/BiomeBeach.java +++ b/server/src/server/biome/BiomeBeach.java @@ -1,14 +1,14 @@ package server.biome; -import common.biome.BaseBiome; +import common.biome.Biome; import common.init.Blocks; import common.rng.WeightedList; -public class BiomeBeach extends Biome +public class BiomeBeach extends GenBiome { public BiomeBeach(boolean cold) { - super(cold ? BaseBiome.COLDBEACH : BaseBiome.BEACH); + super(cold ? Biome.COLDBEACH : Biome.BEACH); this.topBlock = Blocks.sand.getState(); this.fillerBlock = Blocks.sand.getState(); this.treesPerChunk = -999; diff --git a/server/src/server/biome/BiomeBlackened.java b/server/src/server/biome/BiomeBlackened.java index c917b39..f03f41f 100644 --- a/server/src/server/biome/BiomeBlackened.java +++ b/server/src/server/biome/BiomeBlackened.java @@ -1,6 +1,6 @@ package server.biome; -import common.biome.BaseBiome; +import common.biome.Biome; import common.block.BlockFlower; import common.entity.npc.EntityMetalhead; import common.init.Blocks; @@ -10,11 +10,11 @@ import common.util.BlockPos; import server.worldgen.tree.WorldGenBaseTree; import server.worldgen.tree.WorldGenTree; -public class BiomeBlackened extends Biome { +public class BiomeBlackened extends GenBiome { protected final WorldGenTree treeGen = new WorldGenBaseTree(false, Blocks.blackwood_log.getState(), Blocks.blackwood_leaves.getState()); public BiomeBlackened() { - super(BaseBiome.BLACKENED); + super(Biome.BLACKENED); this.topBlock = Blocks.blackened_soil.getState(); this.fillerBlock = Blocks.blackened_dirt.getState(); this.treesPerChunk = 3; diff --git a/server/src/server/biome/BiomeChaos.java b/server/src/server/biome/BiomeChaos.java index 7613c41..0bd3c45 100755 --- a/server/src/server/biome/BiomeChaos.java +++ b/server/src/server/biome/BiomeChaos.java @@ -1,6 +1,6 @@ package server.biome; -import common.biome.BaseBiome; +import common.biome.Biome; import common.entity.Entity; import common.entity.types.EntityLiving; import common.init.Blocks; @@ -12,13 +12,13 @@ import server.world.WorldServer; import server.worldgen.FeatureGenerator; import server.worldgen.foliage.WorldGenMushroom; -public class BiomeChaos extends Biome +public class BiomeChaos extends GenBiome { protected FeatureGenerator mushroomBlueGen = new WorldGenMushroom(Blocks.blue_mushroom); public BiomeChaos() { - super(BaseBiome.CHAOS); + super(Biome.CHAOS); this.topBlock = Blocks.obsidian.getState(); this.fillerBlock = Blocks.obsidian.getState(); } diff --git a/server/src/server/biome/BiomeDesert.java b/server/src/server/biome/BiomeDesert.java index e6b445d..0171ff5 100755 --- a/server/src/server/biome/BiomeDesert.java +++ b/server/src/server/biome/BiomeDesert.java @@ -1,6 +1,6 @@ package server.biome; -import common.biome.BaseBiome; +import common.biome.Biome; import common.init.Blocks; import common.rng.Random; import common.rng.WeightedList; @@ -8,11 +8,11 @@ import common.util.BlockPos; import server.world.WorldServer; import server.worldgen.feature.WorldGenDesertWells; -public class BiomeDesert extends Biome +public class BiomeDesert extends GenBiome { public BiomeDesert(boolean hills) { - super(hills ? BaseBiome.DESERTHILLS : BaseBiome.DESERT); + super(hills ? Biome.DESERTHILLS : Biome.DESERT); this.topBlock = Blocks.sand.getState(); this.fillerBlock = Blocks.sand.getState(); this.treesPerChunk = -999; diff --git a/server/src/server/biome/BiomeExterminated.java b/server/src/server/biome/BiomeExterminated.java index cf386f8..78b55fd 100755 --- a/server/src/server/biome/BiomeExterminated.java +++ b/server/src/server/biome/BiomeExterminated.java @@ -1,15 +1,15 @@ package server.biome; -import common.biome.BaseBiome; +import common.biome.Biome; import common.init.Blocks; import common.rng.Random; import common.rng.WeightedList; import common.util.BlockPos; import server.world.WorldServer; -public class BiomeExterminated extends Biome { +public class BiomeExterminated extends GenBiome { public BiomeExterminated() { - super(BaseBiome.EXTERMINATED); + super(Biome.EXTERMINATED); this.topBlock = Blocks.air.getState(); this.fillerBlock = Blocks.air.getState(); } diff --git a/server/src/server/biome/BiomeForest.java b/server/src/server/biome/BiomeForest.java index e77f451..c0ecc14 100755 --- a/server/src/server/biome/BiomeForest.java +++ b/server/src/server/biome/BiomeForest.java @@ -1,6 +1,6 @@ package server.biome; -import common.biome.BaseBiome; +import common.biome.Biome; import common.block.BlockDoublePlant; import common.block.BlockFlower; import common.entity.animal.EntityWolf; @@ -18,7 +18,7 @@ import server.worldgen.tree.WorldGenBirch; import server.worldgen.tree.WorldGenDarkOak; import server.worldgen.tree.WorldGenTree; -public class BiomeForest extends Biome +public class BiomeForest extends GenBiome { private static final BlockDoublePlant.EnumPlantType[] FLOWER_TYPES = new BlockDoublePlant.EnumPlantType[] { BlockDoublePlant.EnumPlantType.SYRINGA, BlockDoublePlant.EnumPlantType.ROSE, BlockDoublePlant.EnumPlantType.PAEONIA @@ -42,7 +42,7 @@ public class BiomeForest extends Biome protected WorldGenBigTree mapleBig = new WorldGenBigTree(false, Blocks.maple_log.getState(), // .withProperty(BlockNewLog.VARIANT, BlockPlanks.EnumType.MAPLE), Blocks.maple_leaves.getState()); // .withProperty(BlockLeaves.TYPE, worldIn.getLeavesGen())); - public BiomeForest(BaseBiome base, int type) + public BiomeForest(Biome base, int type) { super(base); this.subType = type; @@ -195,9 +195,9 @@ public class BiomeForest extends Biome super.decorate(worldIn, rand, pos); } - protected Biome createMutatedBiome(BaseBiome base) + protected GenBiome createMutatedBiome(Biome base) { - if (this.base == BaseBiome.FOREST) + if (this.base == Biome.FOREST) { BiomeForest biomegenforest = new BiomeForest(base, 1); biomegenforest.setScaling(this.depth, this.scale + 0.2F); @@ -205,7 +205,7 @@ public class BiomeForest extends Biome } else { - return this.base != BaseBiome.BIRCHFOREST && this.base != BaseBiome.BIRCHFORESTHILLS ? new BiomeMutated(base, this) + return this.base != Biome.BIRCHFOREST && this.base != Biome.BIRCHFORESTHILLS ? new BiomeMutated(base, this) { public void decorate(WorldServer worldIn, Random rand, BlockPos pos) { diff --git a/server/src/server/biome/BiomeHell.java b/server/src/server/biome/BiomeHell.java index 39fc07e..7e82667 100755 --- a/server/src/server/biome/BiomeHell.java +++ b/server/src/server/biome/BiomeHell.java @@ -1,6 +1,6 @@ package server.biome; -import common.biome.BaseBiome; +import common.biome.Biome; import common.entity.npc.EntityBloodElf; import common.entity.npc.EntityCultivator; import common.entity.npc.EntityFireDemon; @@ -18,7 +18,7 @@ import server.worldgen.feature.WorldGenGlowStone; import server.worldgen.feature.WorldGenHellLava; import server.worldgen.foliage.WorldGenMushroom; -public class BiomeHell extends Biome +public class BiomeHell extends GenBiome { private final int subtype; private final WorldGenFire fireGen; @@ -30,7 +30,7 @@ public class BiomeHell extends Biome private final WorldGenMushroom brownMushroomGen; private final WorldGenMushroom redMushroomGen; - public BiomeHell(BaseBiome base, int subtype) + public BiomeHell(Biome base, int subtype) { super(base); this.subtype = subtype; diff --git a/server/src/server/biome/BiomeHills.java b/server/src/server/biome/BiomeHills.java index dacd5c1..1ec2ed9 100755 --- a/server/src/server/biome/BiomeHills.java +++ b/server/src/server/biome/BiomeHills.java @@ -1,6 +1,6 @@ package server.biome; -import common.biome.BaseBiome; +import common.biome.Biome; import common.init.Blocks; import common.rng.Random; import common.util.BlockPos; @@ -10,7 +10,7 @@ import server.worldgen.FeatureOres; import server.worldgen.tree.WorldGenTaiga2; import server.worldgen.tree.WorldGenTree; -public class BiomeHills extends Biome +public class BiomeHills extends GenBiome { // private FeatureGenerator theWorldGenerator = new FeatureOres(Blocks.monster_egg.getDefaultState().withProperty(BlockSilverfish.VARIANT, BlockSilverfish.EnumType.STONE), false, 7, 9, 0, 64); private FeatureOres theEmeraldGenerator = new FeatureOres(Blocks.emerald_ore.getState(), 3, 5, 1, 4, 32, false); @@ -20,7 +20,7 @@ public class BiomeHills extends Biome private int field_150637_aG = 2; private int field_150638_aH; - protected BiomeHills(BaseBiome base, boolean large) + protected BiomeHills(Biome base, boolean large) { super(base); this.field_150638_aH = this.field_150635_aE; @@ -87,14 +87,14 @@ public class BiomeHills extends Biome /** * this creates a mutation specific to Hills biomes */ - private BiomeHills mutateHills(Biome p_150633_1_) + private BiomeHills mutateHills(GenBiome p_150633_1_) { this.field_150638_aH = this.field_150637_aG; this.setScaling(p_150633_1_.depth, p_150633_1_.scale); return this; } - protected Biome createMutatedBiome(BaseBiome base) + protected GenBiome createMutatedBiome(Biome base) { return (new BiomeHills(base, false)).mutateHills(this); } diff --git a/server/src/server/biome/BiomeJungle.java b/server/src/server/biome/BiomeJungle.java index 84517f2..e871913 100755 --- a/server/src/server/biome/BiomeJungle.java +++ b/server/src/server/biome/BiomeJungle.java @@ -1,6 +1,6 @@ package server.biome; -import common.biome.BaseBiome; +import common.biome.Biome; import common.block.BlockTallGrass; import common.entity.animal.EntityChicken; import common.entity.animal.EntityOcelot; @@ -18,7 +18,7 @@ import server.worldgen.tree.WorldGenBaseTree; import server.worldgen.tree.WorldGenJungle; import server.worldgen.tree.WorldGenTree; -public class BiomeJungle extends Biome +public class BiomeJungle extends GenBiome { private static final State LOG = Blocks.jungle_log.getState(); // .withProperty(BlockOldLog.VARIANT, BlockPlanks.EnumType.JUNGLE); private static final State LEAVES = Blocks.jungle_leaves.getState(); // .withProperty(BlockOldLeaf.VARIANT, BlockPlanks.EnumType.JUNGLE); // .withProperty(BlockLeaves.CHECK_DECAY, Boolean.valueOf(false)); @@ -26,7 +26,7 @@ public class BiomeJungle extends Biome private final boolean edge; - public BiomeJungle(BaseBiome base, boolean edge) + public BiomeJungle(Biome base, boolean edge) { super(base); this.edge = edge; diff --git a/server/src/server/biome/BiomeMesa.java b/server/src/server/biome/BiomeMesa.java index 90dca55..6651be2 100755 --- a/server/src/server/biome/BiomeMesa.java +++ b/server/src/server/biome/BiomeMesa.java @@ -2,7 +2,7 @@ package server.biome; import java.util.Arrays; -import common.biome.BaseBiome; +import common.biome.Biome; import common.block.Block; import common.block.BlockColored; import common.block.BlockDirt; @@ -19,7 +19,7 @@ import server.world.WorldServer; import server.worldgen.ChunkPrimer; import server.worldgen.tree.WorldGenTree; -public class BiomeMesa extends Biome +public class BiomeMesa extends GenBiome { private final boolean bryce; private final boolean soil; @@ -30,7 +30,7 @@ public class BiomeMesa extends Biome private PerlinGen highBryceGen; private PerlinGen clayColorGen; - public BiomeMesa(BaseBiome base, boolean bryce, boolean soil) + public BiomeMesa(Biome base, boolean bryce, boolean soil) { super(base); this.bryce = bryce; @@ -317,9 +317,9 @@ public class BiomeMesa extends Biome return this.layers[(y + i + 64) % 64]; } - protected Biome createMutatedBiome(BaseBiome base) + protected GenBiome createMutatedBiome(Biome base) { - boolean bryce = this.base == BaseBiome.MESA; + boolean bryce = this.base == Biome.MESA; BiomeMesa mesa = new BiomeMesa(base, bryce, this.soil); if (!bryce) diff --git a/server/src/server/biome/BiomeMoon.java b/server/src/server/biome/BiomeMoon.java index 2263900..cab5cfc 100755 --- a/server/src/server/biome/BiomeMoon.java +++ b/server/src/server/biome/BiomeMoon.java @@ -1,6 +1,6 @@ package server.biome; -import common.biome.BaseBiome; +import common.biome.Biome; import common.init.Blocks; import common.rng.Random; import common.rng.WeightedList; @@ -8,11 +8,11 @@ import common.util.BlockPos; import server.world.WorldServer; import server.worldgen.FeatureOres; -public class BiomeMoon extends Biome { +public class BiomeMoon extends GenBiome { private FeatureOres cheeseGenerator = new FeatureOres(Blocks.moon_cheese.getState(), 8, 8, 12, 24, 52, false); public BiomeMoon() { - super(BaseBiome.MOON); + super(Biome.MOON); this.topBlock = Blocks.moon_rock.getState(); this.fillerBlock = Blocks.moon_rock.getState(); } diff --git a/server/src/server/biome/BiomeMushroom.java b/server/src/server/biome/BiomeMushroom.java index 755e52b..1e00da7 100755 --- a/server/src/server/biome/BiomeMushroom.java +++ b/server/src/server/biome/BiomeMushroom.java @@ -1,15 +1,15 @@ package server.biome; -import common.biome.BaseBiome; +import common.biome.Biome; import common.entity.animal.EntityMooshroom; import common.init.Blocks; import common.rng.WeightedList; -public class BiomeMushroom extends Biome +public class BiomeMushroom extends GenBiome { public BiomeMushroom() { - super(BaseBiome.MUSHROOMPLAINS); + super(Biome.MUSHROOMPLAINS); this.treesPerChunk = -100; this.flowersPerChunk = -100; this.grassPerChunk = -100; diff --git a/server/src/server/biome/BiomeMutated.java b/server/src/server/biome/BiomeMutated.java index a422fda..91b3dfb 100755 --- a/server/src/server/biome/BiomeMutated.java +++ b/server/src/server/biome/BiomeMutated.java @@ -1,6 +1,6 @@ package server.biome; -import common.biome.BaseBiome; +import common.biome.Biome; import common.rng.Random; import common.rng.WeightedList; import common.util.BlockPos; @@ -8,11 +8,11 @@ import server.world.WorldServer; import server.worldgen.ChunkPrimer; import server.worldgen.tree.WorldGenTree; -public class BiomeMutated extends Biome +public class BiomeMutated extends GenBiome { - protected Biome baseBiome; + protected GenBiome baseBiome; - public BiomeMutated(BaseBiome base, Biome biome) + public BiomeMutated(Biome base, GenBiome biome) { super(base); this.baseBiome = biome; @@ -63,7 +63,7 @@ public class BiomeMutated extends Biome return this.baseBiome.genBigTreeChance(rand); } - public Class getBiomeClass() + public Class getBiomeClass() { return this.baseBiome.getBiomeClass(); } @@ -71,7 +71,7 @@ public class BiomeMutated extends Biome /** * returns true if the biome specified is equal to this biome */ - public boolean isEqualTo(Biome biome) + public boolean isEqualTo(GenBiome biome) { return this.baseBiome.isEqualTo(biome); } diff --git a/server/src/server/biome/BiomeNone.java b/server/src/server/biome/BiomeNone.java index 4ae060c..f3ef796 100755 --- a/server/src/server/biome/BiomeNone.java +++ b/server/src/server/biome/BiomeNone.java @@ -1,6 +1,6 @@ package server.biome; -import common.biome.BaseBiome; +import common.biome.Biome; import common.init.Blocks; import common.rng.Random; import common.rng.WeightedList; @@ -8,9 +8,9 @@ import common.util.BlockPos; import server.world.WorldServer; import server.worldgen.ChunkPrimer; -public class BiomeNone extends Biome { +public class BiomeNone extends GenBiome { public BiomeNone() { - super(BaseBiome.NONE); + super(Biome.NONE); this.topBlock = Blocks.air.getState(); this.fillerBlock = Blocks.air.getState(); } diff --git a/server/src/server/biome/BiomePlains.java b/server/src/server/biome/BiomePlains.java index d9b1c03..2732ac8 100755 --- a/server/src/server/biome/BiomePlains.java +++ b/server/src/server/biome/BiomePlains.java @@ -1,6 +1,6 @@ package server.biome; -import common.biome.BaseBiome; +import common.biome.Biome; import common.block.BlockDoublePlant; import common.block.BlockFlower; import common.entity.animal.EntityHorse; @@ -8,7 +8,7 @@ import common.rng.Random; import common.util.BlockPos; import server.world.WorldServer; -public class BiomePlains extends Biome +public class BiomePlains extends GenBiome { private static final BlockFlower.EnumFlowerType[] TULIP_TYPES = new BlockFlower.EnumFlowerType[] { BlockFlower.EnumFlowerType.ORANGE_TULIP, BlockFlower.EnumFlowerType.RED_TULIP, @@ -23,7 +23,7 @@ public class BiomePlains extends Biome protected BiomePlains() { - super(BaseBiome.PLAINS); + super(Biome.PLAINS); this.setScaling(Scaling.PLAINS_LOW); this.mobs.add(new RngSpawn(EntityHorse.class, 5, 2, 6)); this.treesPerChunk = -999; diff --git a/server/src/server/biome/BiomeSavanna.java b/server/src/server/biome/BiomeSavanna.java index d35f6d9..1063529 100755 --- a/server/src/server/biome/BiomeSavanna.java +++ b/server/src/server/biome/BiomeSavanna.java @@ -1,6 +1,6 @@ package server.biome; -import common.biome.BaseBiome; +import common.biome.Biome; import common.block.BlockDirt; import common.block.BlockDoublePlant; import common.entity.animal.EntityHorse; @@ -12,13 +12,13 @@ import server.worldgen.ChunkPrimer; import server.worldgen.tree.WorldGenSavanna; import server.worldgen.tree.WorldGenTree; -public class BiomeSavanna extends Biome +public class BiomeSavanna extends GenBiome { private static final WorldGenSavanna field_150627_aC = new WorldGenSavanna(false); protected BiomeSavanna(boolean plateau) { - super(plateau ? BaseBiome.SAVANNAPLATEAU : BaseBiome.SAVANNA); + super(plateau ? Biome.SAVANNAPLATEAU : Biome.SAVANNA); this.mobs.add(new RngSpawn(EntityHorse.class, 1, 2, 6)); this.treesPerChunk = 1; this.flowersPerChunk = 4; @@ -30,9 +30,9 @@ public class BiomeSavanna extends Biome return (WorldGenTree)(rand.rarity(5) ? field_150627_aC : this.worldGeneratorTrees); } - protected Biome createMutatedBiome(BaseBiome base) + protected GenBiome createMutatedBiome(Biome base) { - Biome biomegenbase = new BiomeSavanna.Mutated(base, this); + GenBiome biomegenbase = new BiomeSavanna.Mutated(base, this); biomegenbase.depth = this.depth * 0.5F + 0.3F; biomegenbase.scale = this.scale * 0.5F + 1.2F; return biomegenbase; @@ -55,7 +55,7 @@ public class BiomeSavanna extends Biome public static class Mutated extends BiomeMutated { - public Mutated(BaseBiome base, Biome p_i45382_2_) + public Mutated(Biome base, GenBiome p_i45382_2_) { super(base, p_i45382_2_); this.treesPerChunk = 2; diff --git a/server/src/server/biome/BiomeSnow.java b/server/src/server/biome/BiomeSnow.java index 134f190..ea236f2 100755 --- a/server/src/server/biome/BiomeSnow.java +++ b/server/src/server/biome/BiomeSnow.java @@ -1,6 +1,6 @@ package server.biome; -import common.biome.BaseBiome; +import common.biome.Biome; import common.init.Blocks; import common.rng.Random; import common.rng.WeightedList; @@ -11,13 +11,13 @@ import server.worldgen.feature.WorldGenIceSpike; import server.worldgen.tree.WorldGenTaiga2; import server.worldgen.tree.WorldGenTree; -public class BiomeSnow extends Biome +public class BiomeSnow extends GenBiome { private final WorldGenIceSpike spikeGen = new WorldGenIceSpike(); private final WorldGenIcePath pathGen = new WorldGenIcePath(4); private final boolean spiky; - public BiomeSnow(BaseBiome base, boolean spiky) + public BiomeSnow(Biome base, boolean spiky) { super(base); this.spiky = spiky; @@ -55,9 +55,9 @@ public class BiomeSnow extends Biome return new WorldGenTaiga2(false); } - protected Biome createMutatedBiome(BaseBiome base) + protected GenBiome createMutatedBiome(Biome base) { - Biome biomegenbase = (new BiomeSnow(base, true)).enableColdBeach().setScaling(this.depth + 0.1F, this.scale + 0.1F); + GenBiome biomegenbase = (new BiomeSnow(base, true)).enableColdBeach().setScaling(this.depth + 0.1F, this.scale + 0.1F); biomegenbase.depth = this.depth + 0.3F; biomegenbase.scale = this.scale + 0.4F; return biomegenbase; diff --git a/server/src/server/biome/BiomeSnowLand.java b/server/src/server/biome/BiomeSnowLand.java index 0ba4b65..37295ea 100755 --- a/server/src/server/biome/BiomeSnowLand.java +++ b/server/src/server/biome/BiomeSnowLand.java @@ -1,16 +1,16 @@ package server.biome; -import common.biome.BaseBiome; +import common.biome.Biome; import common.entity.animal.EntitySheep; import common.entity.npc.EntitySpirit; import common.init.Blocks; import common.rng.WeightedList; -public class BiomeSnowLand extends Biome +public class BiomeSnowLand extends GenBiome { public BiomeSnowLand() { - super(BaseBiome.SNOWLAND); + super(Biome.SNOWLAND); this.topBlock = Blocks.snow.getState(); this.fillerBlock = Blocks.snow.getState(); this.mushroomsPerChunk = -1; diff --git a/server/src/server/biome/BiomeSpace.java b/server/src/server/biome/BiomeSpace.java index ad2708a..93f8d1f 100755 --- a/server/src/server/biome/BiomeSpace.java +++ b/server/src/server/biome/BiomeSpace.java @@ -1,6 +1,6 @@ package server.biome; -import common.biome.BaseBiome; +import common.biome.Biome; import common.block.BlockDirt; import common.init.Blocks; import common.rng.Random; @@ -10,7 +10,7 @@ import server.world.WorldServer; import server.worldgen.FeatureGenerator; import server.worldgen.feature.WorldGenAsteroid; -public class BiomeSpace extends Biome +public class BiomeSpace extends GenBiome { protected FeatureGenerator asteroidGen1 = new WorldGenAsteroid(Blocks.stone.getState(), Blocks.rock.getState()); @@ -19,7 +19,7 @@ public class BiomeSpace extends Biome public BiomeSpace() { - super(BaseBiome.SPACE); + super(Biome.SPACE); this.topBlock = Blocks.air.getState(); this.fillerBlock = Blocks.air.getState(); } diff --git a/server/src/server/biome/BiomeStoneBeach.java b/server/src/server/biome/BiomeStoneBeach.java index 9c6fa69..47a4c5b 100755 --- a/server/src/server/biome/BiomeStoneBeach.java +++ b/server/src/server/biome/BiomeStoneBeach.java @@ -1,14 +1,14 @@ package server.biome; -import common.biome.BaseBiome; +import common.biome.Biome; import common.init.Blocks; import common.rng.WeightedList; -public class BiomeStoneBeach extends Biome +public class BiomeStoneBeach extends GenBiome { public BiomeStoneBeach() { - super(BaseBiome.STONEBEACH); + super(Biome.STONEBEACH); // this.mobs.clear(); this.topBlock = Blocks.stone.getState(); this.fillerBlock = Blocks.stone.getState(); diff --git a/server/src/server/biome/BiomeSwamp.java b/server/src/server/biome/BiomeSwamp.java index 6b10c37..eb5cdd0 100755 --- a/server/src/server/biome/BiomeSwamp.java +++ b/server/src/server/biome/BiomeSwamp.java @@ -1,6 +1,6 @@ package server.biome; -import common.biome.BaseBiome; +import common.biome.Biome; import common.block.BlockDirectional; import common.block.BlockFlower; import common.entity.npc.EntitySlime; @@ -13,11 +13,11 @@ import server.world.WorldServer; import server.worldgen.ChunkPrimer; import server.worldgen.tree.WorldGenTree; -public class BiomeSwamp extends Biome +public class BiomeSwamp extends GenBiome { protected BiomeSwamp() { - super(BaseBiome.SWAMPLAND); + super(Biome.SWAMPLAND); this.treesPerChunk = 2; this.flowersPerChunk = 1; this.deadBushPerChunk = 1; diff --git a/server/src/server/biome/BiomeTaiga.java b/server/src/server/biome/BiomeTaiga.java index e892d05..d7a9c5f 100755 --- a/server/src/server/biome/BiomeTaiga.java +++ b/server/src/server/biome/BiomeTaiga.java @@ -1,6 +1,6 @@ package server.biome; -import common.biome.BaseBiome; +import common.biome.Biome; import common.block.BlockDirt; import common.block.BlockDoublePlant; import common.block.BlockTallGrass; @@ -18,7 +18,7 @@ import server.worldgen.tree.WorldGenTaiga1; import server.worldgen.tree.WorldGenTaiga2; import server.worldgen.tree.WorldGenTree; -public class BiomeTaiga extends Biome +public class BiomeTaiga extends GenBiome { private static final WorldGenTaiga1 field_150639_aC = new WorldGenTaiga1(); private static final WorldGenTaiga2 field_150640_aD = new WorldGenTaiga2(false); @@ -27,7 +27,7 @@ public class BiomeTaiga extends Biome private static final WorldGenBlockBlob field_150643_aG = new WorldGenBlockBlob(Blocks.mossy_cobblestone, 0); private int field_150644_aH; - public BiomeTaiga(BaseBiome base, int p_i45385_2_) + public BiomeTaiga(Biome base, int p_i45385_2_) { super(base); this.field_150644_aH = p_i45385_2_; @@ -108,8 +108,8 @@ public class BiomeTaiga extends Biome this.generateBiomeTerrain(worldIn, rand, chunkPrimerIn, x, z, noiseVal); } - protected Biome createMutatedBiome(BaseBiome base) + protected GenBiome createMutatedBiome(Biome base) { - return this.base == BaseBiome.MEGATAIGA ? (new BiomeTaiga(base, 2)).setScaling(this.depth, this.scale) : super.createMutatedBiome(base); + return this.base == Biome.MEGATAIGA ? (new BiomeTaiga(base, 2)).setScaling(this.depth, this.scale) : super.createMutatedBiome(base); } } diff --git a/server/src/server/biome/BiomeTian.java b/server/src/server/biome/BiomeTian.java index c7a52c3..58c7d45 100755 --- a/server/src/server/biome/BiomeTian.java +++ b/server/src/server/biome/BiomeTian.java @@ -1,6 +1,6 @@ package server.biome; -import common.biome.BaseBiome; +import common.biome.Biome; import common.block.BlockFlower; import common.entity.animal.EntityBat; import common.entity.animal.EntityMouse; @@ -18,7 +18,7 @@ import server.worldgen.tree.WorldGenBaseTree; import server.worldgen.tree.WorldGenBigTree; import server.worldgen.tree.WorldGenTree; -public class BiomeTian extends Biome +public class BiomeTian extends GenBiome { protected FeatureGenerator spikeGen = new WorldGenSpikes(Blocks.tian_soil, 128, 2, 3, Blocks.obsidian.getState(), true); protected FeatureGenerator mushroomBlueGen = new WorldGenMushroom(Blocks.blue_mushroom); @@ -32,7 +32,7 @@ public class BiomeTian extends Biome public BiomeTian() { - super(BaseBiome.TIAN); + super(Biome.TIAN); this.topBlock = Blocks.tian_soil.getState(); this.fillerBlock = Blocks.tian.getState(); this.mushroomsPerChunk = -1; diff --git a/server/src/server/biome/BiomeWater.java b/server/src/server/biome/BiomeWater.java index acf45c1..48c853b 100755 --- a/server/src/server/biome/BiomeWater.java +++ b/server/src/server/biome/BiomeWater.java @@ -1,13 +1,13 @@ package server.biome; -import common.biome.BaseBiome; +import common.biome.Biome; import common.entity.animal.EntitySquid; import common.rng.WeightedList; -public class BiomeWater extends Biome { +public class BiomeWater extends GenBiome { private final boolean river; - public BiomeWater(BaseBiome base, boolean river) { + public BiomeWater(Biome base, boolean river) { super(base); this.river = river; this.disableBeach(); diff --git a/server/src/server/biome/Biome.java b/server/src/server/biome/GenBiome.java similarity index 79% rename from server/src/server/biome/Biome.java rename to server/src/server/biome/GenBiome.java index a8564f4..825b630 100755 --- a/server/src/server/biome/Biome.java +++ b/server/src/server/biome/GenBiome.java @@ -1,6 +1,6 @@ package server.biome; -import common.biome.BaseBiome; +import common.biome.Biome; import common.biome.IBiome; import common.block.Block; import common.block.BlockColored; @@ -61,70 +61,70 @@ import server.worldgen.tree.WorldGenSwamp; import server.worldgen.tree.WorldGenTaiga2; import server.worldgen.tree.WorldGenTree; -public abstract class Biome implements IBiome { - public static final Biome[] BIOMES = new Biome[256]; +public abstract class GenBiome implements IBiome { + public static final GenBiome[] BIOMES = new GenBiome[256]; - public static final Biome none = (new BiomeNone()); + public static final GenBiome none = (new BiomeNone()); - public static final Biome plains = (new BiomePlains()); - public static final Biome desert = (new BiomeDesert(false)).setScaling(Scaling.PLAINS_LOW); - public static final Biome extremeHills = (new BiomeHills(BaseBiome.EXTREMEHILLS, false)).setScaling(Scaling.HILLS_LARGE); - public static final Biome forest = (new BiomeForest(BaseBiome.FOREST, 0)); - public static final Biome taiga = (new BiomeTaiga(BaseBiome.TAIGA, 0)).setScaling(Scaling.PLAINS_MEDIUM); - public static final Biome swampland = (new BiomeSwamp()).setScaling(Scaling.SEA_POND); - public static final Biome river = (new BiomeWater(BaseBiome.RIVER, true)).setScaling(Scaling.SEA_SHALLOW); + public static final GenBiome plains = (new BiomePlains()); + public static final GenBiome desert = (new BiomeDesert(false)).setScaling(Scaling.PLAINS_LOW); + public static final GenBiome extremeHills = (new BiomeHills(Biome.EXTREMEHILLS, false)).setScaling(Scaling.HILLS_LARGE); + public static final GenBiome forest = (new BiomeForest(Biome.FOREST, 0)); + public static final GenBiome taiga = (new BiomeTaiga(Biome.TAIGA, 0)).setScaling(Scaling.PLAINS_MEDIUM); + public static final GenBiome swampland = (new BiomeSwamp()).setScaling(Scaling.SEA_POND); + public static final GenBiome river = (new BiomeWater(Biome.RIVER, true)).setScaling(Scaling.SEA_SHALLOW); - public static final Biome exterminated = (new BiomeExterminated()); - public static final Biome space = (new BiomeSpace()); + public static final GenBiome exterminated = (new BiomeExterminated()); + public static final GenBiome space = (new BiomeSpace()); - public static final Biome frozenSea = (new BiomeWater(BaseBiome.FROZENSEA, false)).enableColdBeach().setScaling(Scaling.SEA_MEDIUM); - public static final Biome frozenRiver = (new BiomeWater(BaseBiome.FROZENRIVER, true)).enableColdBeach().setScaling(Scaling.SEA_SHALLOW); - public static final Biome icePlains = (new BiomeSnow(BaseBiome.ICEPLAINS, false)).enableColdBeach().setScaling(Scaling.PLAINS_LOW); - public static final Biome iceMountains = (new BiomeSnow(BaseBiome.ICEMOUNTAINS, false)).enableColdBeach().setScaling(Scaling.HILLS_LOW); - public static final Biome mushroomPlains = (new BiomeMushroom()).setScaling(Scaling.PLAINS_VARYING); - public static final Biome blackened = (new BiomeBlackened()); - public static final Biome beach = (new BiomeBeach(false)).setScaling(Scaling.SEA_SHORE); - public static final Biome desertHills = (new BiomeDesert(true)).setScaling(Scaling.HILLS_LOW); - public static final Biome forestHills = (new BiomeForest(BaseBiome.FORESTHILLS, 0)).setScaling(Scaling.HILLS_LOW); - public static final Biome taigaHills = (new BiomeTaiga(BaseBiome.TAIGAHILLS, 0)).setScaling(Scaling.HILLS_LOW); - public static final Biome extremeHillsEdge = (new BiomeHills(BaseBiome.EXTREMEHILLSEDGE, true)).setScaling(Scaling.HILLS_MEDIUM); - public static final Biome jungle = (new BiomeJungle(BaseBiome.JUNGLE, false)); - public static final Biome jungleHills = (new BiomeJungle(BaseBiome.JUNGLEHILLS, false)).setScaling(Scaling.HILLS_LOW); - public static final Biome jungleEdge = (new BiomeJungle(BaseBiome.JUNGLEEDGE, true)); - public static final Biome sea = (new BiomeWater(BaseBiome.SEA, false)).setScaling(Scaling.SEA_MEDIUM); - public static final Biome stoneBeach = (new BiomeStoneBeach()).setScaling(Scaling.SEA_VARYING); - public static final Biome coldBeach = (new BiomeBeach(true)).setScaling(Scaling.SEA_SHORE).enableColdBeach(); - public static final Biome birchForest = (new BiomeForest(BaseBiome.BIRCHFOREST, 2)); - public static final Biome birchForestHills = (new BiomeForest(BaseBiome.BIRCHFORESTHILLS, 2)).setScaling(Scaling.HILLS_LOW); - public static final Biome roofedForest = (new BiomeForest(BaseBiome.ROOFEDFOREST, 3)); - public static final Biome coldTaiga = (new BiomeTaiga(BaseBiome.COLDTAIGA, 0)).enableColdBeach().setScaling(Scaling.PLAINS_MEDIUM); - public static final Biome coldTaigaHills = (new BiomeTaiga(BaseBiome.COLDTAIGAHILLS, 0)).enableColdBeach().setScaling(Scaling.HILLS_LOW); - public static final Biome megaTaiga = (new BiomeTaiga(BaseBiome.MEGATAIGA, 1)).setScaling(Scaling.PLAINS_MEDIUM); - public static final Biome megaTaigaHills = (new BiomeTaiga(BaseBiome.MEGATAIGAHILLS, 1)).setScaling(Scaling.HILLS_LOW); - public static final Biome extremeHillsPlus = (new BiomeHills(BaseBiome.EXTREMEHILLSPLUS, true)).setScaling(Scaling.HILLS_LARGE); - public static final Biome savanna = (new BiomeSavanna(false)).setScaling(Scaling.PLAINS_LOW); - public static final Biome savannaPlateau = (new BiomeSavanna(true)).setScaling(Scaling.HILLS_PLATEAU); + public static final GenBiome frozenSea = (new BiomeWater(Biome.FROZENSEA, false)).enableColdBeach().setScaling(Scaling.SEA_MEDIUM); + public static final GenBiome frozenRiver = (new BiomeWater(Biome.FROZENRIVER, true)).enableColdBeach().setScaling(Scaling.SEA_SHALLOW); + public static final GenBiome icePlains = (new BiomeSnow(Biome.ICEPLAINS, false)).enableColdBeach().setScaling(Scaling.PLAINS_LOW); + public static final GenBiome iceMountains = (new BiomeSnow(Biome.ICEMOUNTAINS, false)).enableColdBeach().setScaling(Scaling.HILLS_LOW); + public static final GenBiome mushroomPlains = (new BiomeMushroom()).setScaling(Scaling.PLAINS_VARYING); + public static final GenBiome blackened = (new BiomeBlackened()); + public static final GenBiome beach = (new BiomeBeach(false)).setScaling(Scaling.SEA_SHORE); + public static final GenBiome desertHills = (new BiomeDesert(true)).setScaling(Scaling.HILLS_LOW); + public static final GenBiome forestHills = (new BiomeForest(Biome.FORESTHILLS, 0)).setScaling(Scaling.HILLS_LOW); + public static final GenBiome taigaHills = (new BiomeTaiga(Biome.TAIGAHILLS, 0)).setScaling(Scaling.HILLS_LOW); + public static final GenBiome extremeHillsEdge = (new BiomeHills(Biome.EXTREMEHILLSEDGE, true)).setScaling(Scaling.HILLS_MEDIUM); + public static final GenBiome jungle = (new BiomeJungle(Biome.JUNGLE, false)); + public static final GenBiome jungleHills = (new BiomeJungle(Biome.JUNGLEHILLS, false)).setScaling(Scaling.HILLS_LOW); + public static final GenBiome jungleEdge = (new BiomeJungle(Biome.JUNGLEEDGE, true)); + public static final GenBiome sea = (new BiomeWater(Biome.SEA, false)).setScaling(Scaling.SEA_MEDIUM); + public static final GenBiome stoneBeach = (new BiomeStoneBeach()).setScaling(Scaling.SEA_VARYING); + public static final GenBiome coldBeach = (new BiomeBeach(true)).setScaling(Scaling.SEA_SHORE).enableColdBeach(); + public static final GenBiome birchForest = (new BiomeForest(Biome.BIRCHFOREST, 2)); + public static final GenBiome birchForestHills = (new BiomeForest(Biome.BIRCHFORESTHILLS, 2)).setScaling(Scaling.HILLS_LOW); + public static final GenBiome roofedForest = (new BiomeForest(Biome.ROOFEDFOREST, 3)); + public static final GenBiome coldTaiga = (new BiomeTaiga(Biome.COLDTAIGA, 0)).enableColdBeach().setScaling(Scaling.PLAINS_MEDIUM); + public static final GenBiome coldTaigaHills = (new BiomeTaiga(Biome.COLDTAIGAHILLS, 0)).enableColdBeach().setScaling(Scaling.HILLS_LOW); + public static final GenBiome megaTaiga = (new BiomeTaiga(Biome.MEGATAIGA, 1)).setScaling(Scaling.PLAINS_MEDIUM); + public static final GenBiome megaTaigaHills = (new BiomeTaiga(Biome.MEGATAIGAHILLS, 1)).setScaling(Scaling.HILLS_LOW); + public static final GenBiome extremeHillsPlus = (new BiomeHills(Biome.EXTREMEHILLSPLUS, true)).setScaling(Scaling.HILLS_LARGE); + public static final GenBiome savanna = (new BiomeSavanna(false)).setScaling(Scaling.PLAINS_LOW); + public static final GenBiome savannaPlateau = (new BiomeSavanna(true)).setScaling(Scaling.HILLS_PLATEAU); - public static final Biome mesa = (new BiomeMesa(BaseBiome.MESA, false, false)); - public static final Biome mesaPlateau_F = (new BiomeMesa(BaseBiome.MESAPLATEAUF, false, true)).setScaling(Scaling.HILLS_PLATEAU); - public static final Biome mesaPlateau = (new BiomeMesa(BaseBiome.MESAPLATEAU, false, false)).setScaling(Scaling.HILLS_PLATEAU); + public static final GenBiome mesa = (new BiomeMesa(Biome.MESA, false, false)); + public static final GenBiome mesaPlateau_F = (new BiomeMesa(Biome.MESAPLATEAUF, false, true)).setScaling(Scaling.HILLS_PLATEAU); + public static final GenBiome mesaPlateau = (new BiomeMesa(Biome.MESAPLATEAU, false, false)).setScaling(Scaling.HILLS_PLATEAU); - public static final Biome snowLand = (new BiomeSnowLand()).enableColdBeach(); - public static final Biome tian = (new BiomeTian()).setScaling(Scaling.VARYING_MEDIUM); - public static final Biome elvenForest = (new BiomeForest(BaseBiome.ELVENFOREST, 4)); - public static final Biome upperHell = (new BiomeHell(BaseBiome.UPPERHELL, 0)); - public static final Biome lowerHell = (new BiomeHell(BaseBiome.LOWERHELL, 1)); - public static final Biome hellHills = (new BiomeHell(BaseBiome.HELLHILLS, 1)).setScaling(Scaling.HILLS_LARGE); - public static final Biome soulPlains = (new BiomeHell(BaseBiome.SOULPLAINS, 1)).setScaling(Scaling.SEA_POND); - public static final Biome ashLand = (new BiomeHell(BaseBiome.ASHLAND, 2)).setScaling(Scaling.PLAINS_LOW); - public static final Biome moon = (new BiomeMoon()).setScaling(Scaling.PLAINS_LOW); - public static final Biome chaos = (new BiomeChaos()).setScaling(Scaling.VARYING_CHAOTIC); + public static final GenBiome snowLand = (new BiomeSnowLand()).enableColdBeach(); + public static final GenBiome tian = (new BiomeTian()).setScaling(Scaling.VARYING_MEDIUM); + public static final GenBiome elvenForest = (new BiomeForest(Biome.ELVENFOREST, 4)); + public static final GenBiome upperHell = (new BiomeHell(Biome.UPPERHELL, 0)); + public static final GenBiome lowerHell = (new BiomeHell(Biome.LOWERHELL, 1)); + public static final GenBiome hellHills = (new BiomeHell(Biome.HELLHILLS, 1)).setScaling(Scaling.HILLS_LARGE); + public static final GenBiome soulPlains = (new BiomeHell(Biome.SOULPLAINS, 1)).setScaling(Scaling.SEA_POND); + public static final GenBiome ashLand = (new BiomeHell(Biome.ASHLAND, 2)).setScaling(Scaling.PLAINS_LOW); + public static final GenBiome moon = (new BiomeMoon()).setScaling(Scaling.PLAINS_LOW); + public static final GenBiome chaos = (new BiomeChaos()).setScaling(Scaling.VARYING_CHAOTIC); - protected static final PerlinGen TREE_NOISE; - protected static final PerlinGen GRASS_NOISE; - protected static final FeatureDoublePlant DOUBLE_PLANT_GEN; + protected static final PerlinGen TREE_NOISE = new PerlinGen(new Random(726528729282625L), 8); + protected static final PerlinGen GRASS_NOISE = new PerlinGen(new Random(297363826225L), 1); + protected static final FeatureDoublePlant DOUBLE_PLANT_GEN = new FeatureDoublePlant(); - public final BaseBiome base; + public final Biome base; protected final WeightedList mobs = new WeightedList(); protected final WorldGenBaseTree worldGeneratorTrees = new WorldGenBaseTree(false); @@ -165,7 +165,7 @@ public abstract class Biome implements IBiome { protected int clayExtPerChunk = 0; // 10 protected int bigMushroomsPerChunk = 0; - public static Biome getBiome(int id) + public static GenBiome getBiome(int id) { if (id >= 0 && id < BIOMES.length) { @@ -173,20 +173,43 @@ public abstract class Biome implements IBiome { } else { - Log.JNI.warn("Biom-ID ist nicht im Bereich: " + id + ", verwende " + BaseBiome.DEF_BIOME.id + " (" + BaseBiome.DEF_BIOME.name + ")"); - return BIOMES[BaseBiome.DEF_BIOME.id]; + Log.JNI.warn("Biom-ID ist nicht im Bereich: " + id + ", verwende " + Biome.DEF_BIOME.id + " (" + Biome.DEF_BIOME.name + ")"); + return BIOMES[Biome.DEF_BIOME.id]; } } public static void setAsProvider() { IBiome.setProvider(new IBiome.BiomeProvider() { - public final IBiome getBiome(BaseBiome base) { + public final IBiome getBiome(Biome base) { return BIOMES[base.id]; } }); } - protected Biome(BaseBiome base) { + static { + desert.createMutatedBiome(Biome.DESERTM); + forest.createMutatedBiome(Biome.FLOWERFOREST); + taiga.createMutatedBiome(Biome.TAIGAM); + swampland.createMutatedBiome(Biome.SWAMPLANDM); + icePlains.createMutatedBiome(Biome.ICEPLAINSSPIKES); + jungle.createMutatedBiome(Biome.JUNGLEM); + jungleEdge.createMutatedBiome(Biome.JUNGLEEDGEM); + coldTaiga.createMutatedBiome(Biome.COLDTAIGAM); + savanna.createMutatedBiome(Biome.SAVANNAM); + savannaPlateau.createMutatedBiome(Biome.SAVANNAPLATEAUM); + mesa.createMutatedBiome(Biome.MESABRYCE); + mesaPlateau_F.createMutatedBiome(Biome.MESAPLATEAUFM); + mesaPlateau.createMutatedBiome(Biome.MESAPLATEAUM); + birchForest.createMutatedBiome(Biome.BIRCHFORESTM); + birchForestHills.createMutatedBiome(Biome.BIRCHFORESTHILLSM); + roofedForest.createMutatedBiome(Biome.ROOFEDFORESTM); + megaTaiga.createMutatedBiome(Biome.MEGASPRUCETAIGA); + extremeHills.createMutatedBiome(Biome.EXTREMEHILLSM); + extremeHillsPlus.createMutatedBiome(Biome.EXTREMEHILLSPLUSM); + megaTaiga.createMutatedBiome(Biome.REDWOODTAIGAHILLSM); + } + + protected GenBiome(Biome base) { BIOMES[base.id] = this; this.base = base; this.addMobs(this.mobs); @@ -210,12 +233,12 @@ public abstract class Biome implements IBiome { mobs.add(new RngSpawn(EntityMouse.class, 10, 8, 8)); } - protected final Biome setScaling(Scaling scaling) + protected final GenBiome setScaling(Scaling scaling) { return this.setScaling(scaling.depth, scaling.scale); } - protected final Biome setScaling(float depth, float scale) + protected final GenBiome setScaling(float depth, float scale) { this.depth = depth; this.scale = scale; @@ -252,13 +275,13 @@ public abstract class Biome implements IBiome { return this.topBlock; } - protected Biome enableColdBeach() + protected GenBiome enableColdBeach() { this.allowColdBeach = true; return this; } - protected Biome disableBeach() + protected GenBiome disableBeach() { this.disallowBeach = true; return this; @@ -829,17 +852,17 @@ public abstract class Biome implements IBiome { } } - protected Biome createMutatedBiome(BaseBiome base) + protected GenBiome createMutatedBiome(Biome base) { return new BiomeMutated(base, this); } - public Class getBiomeClass() + public Class getBiomeClass() { return this.getClass(); } - public boolean isEqualTo(Biome biome) + public boolean isEqualTo(GenBiome biome) { return biome == this ? true : (biome == null ? false : this.getBiomeClass() == biome.getBiomeClass()); } @@ -848,32 +871,4 @@ public abstract class Biome implements IBiome { { return this.base.temperature < -12.0f ? Temperature.COLD : (this.base.temperature < 20.0f ? Temperature.MEDIUM : Temperature.WARM); } - - static - { - desert.createMutatedBiome(BaseBiome.DESERTM); - forest.createMutatedBiome(BaseBiome.FLOWERFOREST); - taiga.createMutatedBiome(BaseBiome.TAIGAM); - swampland.createMutatedBiome(BaseBiome.SWAMPLANDM); - icePlains.createMutatedBiome(BaseBiome.ICEPLAINSSPIKES); - jungle.createMutatedBiome(BaseBiome.JUNGLEM); - jungleEdge.createMutatedBiome(BaseBiome.JUNGLEEDGEM); - coldTaiga.createMutatedBiome(BaseBiome.COLDTAIGAM); - savanna.createMutatedBiome(BaseBiome.SAVANNAM); - savannaPlateau.createMutatedBiome(BaseBiome.SAVANNAPLATEAUM); - mesa.createMutatedBiome(BaseBiome.MESABRYCE); - mesaPlateau_F.createMutatedBiome(BaseBiome.MESAPLATEAUFM); - mesaPlateau.createMutatedBiome(BaseBiome.MESAPLATEAUM); - birchForest.createMutatedBiome(BaseBiome.BIRCHFORESTM); - birchForestHills.createMutatedBiome(BaseBiome.BIRCHFORESTHILLSM); - roofedForest.createMutatedBiome(BaseBiome.ROOFEDFORESTM); - megaTaiga.createMutatedBiome(BaseBiome.MEGASPRUCETAIGA); - extremeHills.createMutatedBiome(BaseBiome.EXTREMEHILLSM); - extremeHillsPlus.createMutatedBiome(BaseBiome.EXTREMEHILLSPLUSM); - megaTaiga.createMutatedBiome(BaseBiome.REDWOODTAIGAHILLSM); - - TREE_NOISE = new PerlinGen(new Random(667L), 8); - GRASS_NOISE = new PerlinGen(new Random(2345L), 1); - DOUBLE_PLANT_GEN = new FeatureDoublePlant(); - } } diff --git a/server/src/server/world/Converter.java b/server/src/server/world/Converter.java index 4ce09ac..34001e7 100644 --- a/server/src/server/world/Converter.java +++ b/server/src/server/world/Converter.java @@ -15,7 +15,7 @@ import java.util.Map.Entry; import java.util.zip.GZIPInputStream; import java.util.zip.InflaterInputStream; -import common.biome.BaseBiome; +import common.biome.Biome; import common.block.Block; import common.block.BlockCactus; import common.block.BlockCarpet; @@ -916,7 +916,7 @@ public abstract class Converter { } tag.setTag("Sections", sections); byte[] biomes = new byte[256]; - Arrays.fill(biomes, (byte)(BaseBiome.DEF_BIOME.id & 255)); + Arrays.fill(biomes, (byte)(Biome.DEF_BIOME.id & 255)); tag.setByteArray("Biomes", biomes); } NBTTagList ents = tag.getTagList("Entities", 10); diff --git a/server/src/server/world/Spawner.java b/server/src/server/world/Spawner.java index 307d605..5133cf3 100755 --- a/server/src/server/world/Spawner.java +++ b/server/src/server/world/Spawner.java @@ -16,7 +16,7 @@ import common.util.ChunkPos; import common.util.ExtMath; import common.world.Chunk; import common.world.World; -import server.biome.Biome; +import server.biome.GenBiome; import server.biome.RngSpawn; public abstract class Spawner { @@ -162,7 +162,7 @@ public abstract class Spawner { return spawned; } - public static void generate(WorldServer world, Biome biome, int x, int z, int sx, int sz, Random rand) { + public static void generate(WorldServer world, GenBiome biome, int x, int z, int sx, int sz, Random rand) { int iters = 0; while(rand.floatv() < biome.getMobGenChance()) { if(iters++ == 10) diff --git a/server/src/server/world/WorldServer.java b/server/src/server/world/WorldServer.java index d20dce3..84c1cf1 100755 --- a/server/src/server/world/WorldServer.java +++ b/server/src/server/world/WorldServer.java @@ -13,7 +13,7 @@ import java.util.TreeSet; import java.util.concurrent.ConcurrentHashMap; import java.util.function.Predicate; -import common.biome.BaseBiome; +import common.biome.Biome; import common.block.Block; import common.block.BlockDoor; import common.block.BlockEventData; @@ -85,7 +85,7 @@ import common.worldgen.FeatureLake; import common.worldgen.FeatureLiquid; import common.worldgen.FeatureOre; import server.Server; -import server.biome.Biome; +import server.biome.GenBiome; import server.biome.RngSpawn; import server.clipboard.ClipboardBlock; import server.network.Player; @@ -146,7 +146,7 @@ public final class WorldServer extends AWorldServer { private final IntHashMap trackMap = new IntHashMap(); private final Map dataMap = Maps.newHashMap(); private final List dataList = Lists.newArrayList(); - private final BaseBiome[] biomes = new BaseBiome[256]; + private final Biome[] biomes = new Biome[256]; private MapGenCaves caveGen; private MapGenBigCaves bigCaveGen; @@ -193,11 +193,11 @@ public final class WorldServer extends AWorldServer { private BiomeGenerator createBiomeGenerator(Random rand) { return this.dimension.getBiomeSize() > 0 ? new BiomeGenLayered(rand.longv(), this.dimension.getDefaultBiome(), this.dimension.isSemiFixed(), this.dimension.getBiomeSize(), this.dimension.getRiverSize(), - this.dimension.getSnowRarity(), this.dimension.getSeaRarity(), this.dimension.getAddBiomes() == null ? new BaseBiome[0] : this.dimension.getAddBiomes(), this.dimension.getAddRarity(), - this.dimension.getHotBiomes() == null ? new BaseBiome[] {this.dimension.getDefaultBiome()} : this.dimension.getHotBiomes(), - this.dimension.getMediumBiomes() == null ? new BaseBiome[] {this.dimension.getDefaultBiome()} : this.dimension.getMediumBiomes(), - this.dimension.getColdBiomes() == null ? new BaseBiome[] {this.dimension.getDefaultBiome()} : this.dimension.getColdBiomes(), - this.dimension.getFrostBiomes() == null ? new BaseBiome[] {this.dimension.getDefaultBiome()} : this.dimension.getFrostBiomes()) : new BiomeGenSingle(this.dimension.getDefaultBiome()); + this.dimension.getSnowRarity(), this.dimension.getSeaRarity(), this.dimension.getAddBiomes() == null ? new Biome[0] : this.dimension.getAddBiomes(), this.dimension.getAddRarity(), + this.dimension.getHotBiomes() == null ? new Biome[] {this.dimension.getDefaultBiome()} : this.dimension.getHotBiomes(), + this.dimension.getMediumBiomes() == null ? new Biome[] {this.dimension.getDefaultBiome()} : this.dimension.getMediumBiomes(), + this.dimension.getColdBiomes() == null ? new Biome[] {this.dimension.getDefaultBiome()} : this.dimension.getColdBiomes(), + this.dimension.getFrostBiomes() == null ? new Biome[] {this.dimension.getDefaultBiome()} : this.dimension.getFrostBiomes()) : new BiomeGenSingle(this.dimension.getDefaultBiome()); } private ChunkGenerator createChunkGenerator(Random rand) { @@ -334,7 +334,7 @@ public final class WorldServer extends AWorldServer { // GeneratorSettings settings = !debug && !this.exterminated ? dim.getSettings() : null; if(debug) { this.liquid = Blocks.air.getState(); - this.biomeGen = new BiomeGenSingle(BaseBiome.NONE); + this.biomeGen = new BiomeGenSingle(Biome.NONE); this.generator = new GeneratorDebug(); this.replacer = null; this.populate = false; @@ -596,13 +596,13 @@ public final class WorldServer extends AWorldServer { } private WeightedList getSpawnTypes(BlockPos pos) { - BaseBiome biome = this.getBiomeGenForCoords(pos); + Biome biome = this.getBiomeGenForCoords(pos); if(this.bridgeGen != null && (this.bridgeGen.isPresent(pos) || (this.bridgeGen.isPositionInStructure(this, pos) && this.getState(pos.down()).getBlock() == Blocks.blood_brick))) return MobConstants.FORTRESS_MOBS; else if(this.scatteredGen != null && this.scatteredGen.hasMageHut(pos)) return MobConstants.MAGEHUT_MOBS; - return Biome.BIOMES[biome.id].getMobs(); + return GenBiome.BIOMES[biome.id].getMobs(); } public RngSpawn getSpawnListEntryForTypeAt(BlockPos pos) { @@ -623,11 +623,11 @@ public final class WorldServer extends AWorldServer { return this.biomeGen; } - public BaseBiome getBiomeGenForCoords(final BlockPos pos) { + public Biome getBiomeGenForCoords(final BlockPos pos) { if(this.isBlockLoaded(pos)) return this.getChunk(pos).getBiome(pos, this.biomeGen); else - return this.biomeGen.getBiomeGenerator(pos, BaseBiome.DEF_BIOME); + return this.biomeGen.getBiomeGenerator(pos, Biome.DEF_BIOME); } public void setItemData(String dataID, WorldSavedData worldSavedDataIn) { @@ -1537,7 +1537,7 @@ public final class WorldServer extends AWorldServer { int bx = x * 16; int bz = z * 16; BlockPos pos = new BlockPos(bx, 0, bz); - Biome biome = Biome.BIOMES[this.getBiomeGenForCoords(pos.add(16, 0, 16)).id]; + GenBiome biome = GenBiome.BIOMES[this.getBiomeGenForCoords(pos.add(16, 0, 16)).id]; this.grng.setSeed(this.seed); long sx = this.grng.longv() / 2L * 2L + 1L; long sz = this.grng.longv() / 2L * 2L + 1L; @@ -1741,7 +1741,7 @@ public final class WorldServer extends AWorldServer { this.scatteredGen = null; this.bridgeGen = null; this.generator = new GeneratorDestroyed(this.dimension.getSeaLevel()); - this.biomeGen = new BiomeGenSingle(BaseBiome.EXTERMINATED); + this.biomeGen = new BiomeGenSingle(Biome.EXTERMINATED); this.replacer = null; this.populate = false; this.liquid = Blocks.air.getState(); @@ -2245,7 +2245,7 @@ public final class WorldServer extends AWorldServer { // return new LazyBlock(state, this, position); // } - public final boolean setBiome(BlockPos position, BaseBiome biome) { + public final boolean setBiome(BlockPos position, Biome biome) { Chunk chunk = this.getChunk(position); if((chunk != null) && (chunk.isLoaded())) { chunk.getBiomes()[((position.getZ() & 0xF) << 4 | position.getX() & 0xF)] = (byte)biome.id; @@ -2254,7 +2254,7 @@ public final class WorldServer extends AWorldServer { return false; } - public final void setBiomes(BlockPos start, BlockPos end, BaseBiome biome) { + public final void setBiomes(BlockPos start, BlockPos end, Biome biome) { Set chunks = Sets.newHashSet(); for(int x = start.getX(); x <= end.getX(); x++) { for(int z = start.getZ(); z <= end.getZ(); z++) { @@ -2299,7 +2299,7 @@ public final class WorldServer extends AWorldServer { } public boolean isBlockinHighHumidity(BlockPos pos) { - BaseBiome biomegenbase = this.getBiomeGenForCoords(pos); + Biome biomegenbase = this.getBiomeGenForCoords(pos); return biomegenbase.isHighHumidity(); } diff --git a/server/src/server/worldgen/BiomeGenLayered.java b/server/src/server/worldgen/BiomeGenLayered.java index 3718e9a..bdf9230 100755 --- a/server/src/server/worldgen/BiomeGenLayered.java +++ b/server/src/server/worldgen/BiomeGenLayered.java @@ -3,7 +3,7 @@ package server.worldgen; import java.util.List; import java.util.Set; -import common.biome.BaseBiome; +import common.biome.Biome; import common.collect.Lists; import common.util.BlockPos; import common.util.LongHashMap; @@ -33,7 +33,7 @@ public class BiomeGenLayered implements BiomeGenerator { private class CacheBlock { public final double[] factors = new double[256]; - public final BaseBiome[] biomes = new BaseBiome[256]; + public final Biome[] biomes = new Biome[256]; public int xPosition; public int zPosition; public long lastAccessTime; @@ -46,7 +46,7 @@ public class BiomeGenLayered implements BiomeGenerator { BiomeGenLayered.this.getBiomes(this.biomes, x << 4, z << 4, 16, 16, false); } - public BaseBiome getBiomeGenAt(int x, int z) + public Biome getBiomeGenAt(int x, int z) { return this.biomes[x & 15 | (z & 15) << 4]; } @@ -67,8 +67,8 @@ public class BiomeGenLayered implements BiomeGenerator { // this(); // } - public BiomeGenLayered(long seed, BaseBiome def, boolean fixed, int biomeSize, int riverSize, int snowRarity, int seaRarity, - BaseBiome[] add, int addRarity, BaseBiome[] hot, BaseBiome[] medium, BaseBiome[] cold, BaseBiome[] frost) { + public BiomeGenLayered(long seed, Biome def, boolean fixed, int biomeSize, int riverSize, int snowRarity, int seaRarity, + Biome[] add, int addRarity, Biome[] hot, Biome[] medium, Biome[] cold, Biome[] frost) { // GenLayer[] layers = GenLayer.getLayers(seed, fixedBiome, biomeSize, riverSize, snowRarity, seaRarity, shroomRarity, biomeRarity); GenLayer layer0t1 = new GenLayerBase(1L); layer0t1 = new GenLayerFuzzyZoom(2000L, layer0t1); @@ -163,10 +163,10 @@ public class BiomeGenLayered implements BiomeGenerator { } } - public BaseBiome getBiomeGenerator(BlockPos pos, BaseBiome def) { + public Biome getBiomeGenerator(BlockPos pos, Biome def) { int x = pos.getX(); int z = pos.getZ(); - BaseBiome biome = this.getBiomeCacheBlock(x, z).getBiomeGenAt(x, z); + Biome biome = this.getBiomeCacheBlock(x, z).getBiomeGenAt(x, z); return biome == null ? def : biome; } @@ -176,7 +176,7 @@ public class BiomeGenLayered implements BiomeGenerator { int[] aint = this.biomeIndexLayer.getInts(x, z, width, length); for(int i = 0; i < width * length; ++i) { - BaseBiome biome = BaseBiome.getBiomeDef(aint[i]); + Biome biome = Biome.getBiomeDef(aint[i]); listToReuse[i] = (double)biome.getFactor(); } } @@ -192,43 +192,43 @@ public class BiomeGenLayered implements BiomeGenerator { int[] aint = this.biomeIndexLayer.getInts(xPos, zPos, sizeX, sizeZ); for(int i = 0; i < sizeX * sizeZ; ++i) { - BaseBiome biome = BaseBiome.getBiomeDef(aint[i]); + Biome biome = Biome.getBiomeDef(aint[i]); factors[i] = (double)biome.getFactor(); } } } - public void getGenBiomes(BaseBiome[] biomes, int x, int z, int width, int height) { + public void getGenBiomes(Biome[] biomes, int x, int z, int width, int height) { IntCache.resetIntCache(); int[] aint = this.genBiomes.getInts(x, z, width, height); for(int i = 0; i < width * height; ++i) { - biomes[i] = BaseBiome.getBiomeDef(aint[i]); + biomes[i] = Biome.getBiomeDef(aint[i]); } } - public void getChunkBiomes(BaseBiome[] oldBiomeList, int x, int z, int width, int depth) { + public void getChunkBiomes(Biome[] oldBiomeList, int x, int z, int width, int depth) { this.getBiomes(oldBiomeList, x, z, width, depth, true); } - public void getBiomes(BaseBiome[] listToReuse, int x, int z, int width, int length, boolean cache) { + public void getBiomes(Biome[] listToReuse, int x, int z, int width, int length, boolean cache) { IntCache.resetIntCache(); if(cache && width == 16 && length == 16 && (x & 15) == 0 && (z & 15) == 0) { - BaseBiome[] biomes = this.getBiomeCacheBlock(x, z).biomes; + Biome[] biomes = this.getBiomeCacheBlock(x, z).biomes; System.arraycopy(biomes, 0, listToReuse, 0, width * length); } else { int[] aint = this.biomeIndexLayer.getInts(x, z, width, length); for(int i = 0; i < width * length; ++i) { - listToReuse[i] = BaseBiome.getBiomeDef(aint[i]); + listToReuse[i] = Biome.getBiomeDef(aint[i]); } } } - public boolean areBiomesViable(int x, int z, int size, Set allowed) { + public boolean areBiomesViable(int x, int z, int size, Set allowed) { IntCache.resetIntCache(); int i = x - size >> 2; int j = z - size >> 2; @@ -239,7 +239,7 @@ public class BiomeGenLayered implements BiomeGenerator { int[] aint = this.genBiomes.getInts(i, j, i1, j1); for(int k1 = 0; k1 < i1 * j1; ++k1) { - BaseBiome biome = BaseBiome.getBiome(aint[k1]); + Biome biome = Biome.getBiome(aint[k1]); if(!allowed.contains(biome)) { return false; diff --git a/server/src/server/worldgen/BiomeGenSingle.java b/server/src/server/worldgen/BiomeGenSingle.java index 9af3ed9..586058f 100755 --- a/server/src/server/worldgen/BiomeGenSingle.java +++ b/server/src/server/worldgen/BiomeGenSingle.java @@ -3,30 +3,30 @@ package server.worldgen; import java.util.Arrays; import java.util.Set; -import common.biome.BaseBiome; +import common.biome.Biome; import common.util.BlockPos; import common.worldgen.BiomeGenerator; public class BiomeGenSingle implements BiomeGenerator { - private final BaseBiome biome; + private final Biome biome; - public BiomeGenSingle(BaseBiome biome) { + public BiomeGenSingle(Biome biome) { this.biome = biome; } - public BaseBiome getBiomeGenerator(BlockPos pos, BaseBiome def) { + public Biome getBiomeGenerator(BlockPos pos, Biome def) { return this.biome; } - public void getGenBiomes(BaseBiome[] biomes, int x, int z, int width, int height) { + public void getGenBiomes(Biome[] biomes, int x, int z, int width, int height) { Arrays.fill(biomes, 0, width * height, this.biome); } - public void getChunkBiomes(BaseBiome[] oldBiomeList, int x, int z, int width, int depth) { + public void getChunkBiomes(Biome[] oldBiomeList, int x, int z, int width, int depth) { Arrays.fill(oldBiomeList, 0, width * depth, this.biome); } - public void getBiomes(BaseBiome[] listToReuse, int x, int z, int width, int length, boolean cache) { + public void getBiomes(Biome[] listToReuse, int x, int z, int width, int length, boolean cache) { Arrays.fill(listToReuse, 0, width * length, this.biome); } @@ -35,7 +35,7 @@ public class BiomeGenSingle implements BiomeGenerator { // : null; // } - public boolean areBiomesViable(int x, int z, int size, Set allowed) { + public boolean areBiomesViable(int x, int z, int size, Set allowed) { return allowed.contains(this.biome); } diff --git a/server/src/server/worldgen/BlockReplacer.java b/server/src/server/worldgen/BlockReplacer.java index 2350409..ab5cb4e 100755 --- a/server/src/server/worldgen/BlockReplacer.java +++ b/server/src/server/worldgen/BlockReplacer.java @@ -1,9 +1,9 @@ package server.worldgen; -import common.biome.BaseBiome; +import common.biome.Biome; import common.rng.Random; import server.world.WorldServer; public interface BlockReplacer { - public void replaceBlocks(WorldServer world, int x, int z, ChunkPrimer primer, Random rand, BaseBiome[] biomes); + public void replaceBlocks(WorldServer world, int x, int z, ChunkPrimer primer, Random rand, Biome[] biomes); } diff --git a/server/src/server/worldgen/FeatureLakes.java b/server/src/server/worldgen/FeatureLakes.java index a930b0e..98fe8bd 100755 --- a/server/src/server/worldgen/FeatureLakes.java +++ b/server/src/server/worldgen/FeatureLakes.java @@ -7,7 +7,7 @@ import common.rng.Random; import common.util.BlockPos; import common.world.LightType; import common.world.State; -import server.biome.Biome; +import server.biome.GenBiome; import server.world.WorldServer; public class FeatureLakes @@ -163,7 +163,7 @@ public class FeatureLakes if (worldIn.getState(blockpos).getBlock() == replace && worldIn.getLightFor(LightType.SKY, position.add(i2, j4, j3)) > 0) { - Biome biomegenbase = Biome.BIOMES[worldIn.getBiomeGenForCoords(blockpos).id]; + GenBiome biomegenbase = GenBiome.BIOMES[worldIn.getBiomeGenForCoords(blockpos).id]; if (biomegenbase.topBlock.getBlock() == Blocks.mycelium) { diff --git a/server/src/server/worldgen/GeneratorPerlin.java b/server/src/server/worldgen/GeneratorPerlin.java index 659347f..e02d8ee 100755 --- a/server/src/server/worldgen/GeneratorPerlin.java +++ b/server/src/server/worldgen/GeneratorPerlin.java @@ -1,13 +1,13 @@ package server.worldgen; -import common.biome.BaseBiome; +import common.biome.Biome; import common.dimension.Dimension; import common.rng.NoiseGen; import common.rng.OctaveGen; import common.rng.Random; import common.util.ExtMath; import common.world.State; -import server.biome.Biome; +import server.biome.GenBiome; import server.world.WorldServer; public class GeneratorPerlin implements ChunkGenerator @@ -52,7 +52,7 @@ public class GeneratorPerlin implements ChunkGenerator private final double[] lowerNoise = new double[825]; private final double[] upperNoise = new double[825]; private final double[] depthNoise = new double[25]; - private final BaseBiome[] biomes = new BaseBiome[100]; + private final Biome[] biomes = new Biome[100]; // public GeneratorNew(Random rand, GeneratorSettings settings) // { @@ -197,13 +197,13 @@ public class GeneratorPerlin implements ChunkGenerator float min = 0.0F; float sum = 0.0F; int range = 2; - Biome biome = Biome.BIOMES[this.biomes[u + 2 + (v + 2) * 10].id]; + GenBiome biome = GenBiome.BIOMES[this.biomes[u + 2 + (v + 2) * 10].id]; for (int a = -range; a <= range; ++a) { for (int b = -range; b <= range; ++b) { - Biome biome2 = Biome.BIOMES[this.biomes[u + a + 2 + (v + b + 2) * 10].id]; + GenBiome biome2 = GenBiome.BIOMES[this.biomes[u + a + 2 + (v + b + 2) * 10].id]; float bmin = this.biomeDepthOffset + biome2.depth * this.biomeDepthWeight; float bmax = this.biomeScaleOffset + biome2.scale * this.biomeScaleWeight; diff --git a/server/src/server/worldgen/ReplacerAltBiome.java b/server/src/server/worldgen/ReplacerAltBiome.java index 6bb6890..8543e23 100755 --- a/server/src/server/worldgen/ReplacerAltBiome.java +++ b/server/src/server/worldgen/ReplacerAltBiome.java @@ -1,13 +1,13 @@ package server.worldgen; -import common.biome.BaseBiome; +import common.biome.Biome; import common.block.Block; import common.init.Blocks; import common.rng.NoiseGen; import common.rng.OctaveGen; import common.rng.Random; import common.world.State; -import server.biome.Biome; +import server.biome.GenBiome; import server.world.WorldServer; public class ReplacerAltBiome implements BlockReplacer @@ -47,7 +47,7 @@ public class ReplacerAltBiome implements BlockReplacer this.block = filler.getBlock(); } - public void replaceBlocks(WorldServer world, int x, int z, ChunkPrimer primer, Random rand, BaseBiome[] biomes) + public void replaceBlocks(WorldServer world, int x, int z, ChunkPrimer primer, Random rand, Biome[] biomes) { int seaLevel = world.getSeaLevel(); double scale = 0.03125D; @@ -58,7 +58,7 @@ public class ReplacerAltBiome implements BlockReplacer { for(int px = 0; px < 16; px++) { - Biome biome = Biome.BIOMES[biomes[pz * 16 + px].id]; + GenBiome biome = GenBiome.BIOMES[biomes[pz * 16 + px].id]; boolean alt2 = this.alt2Noise[pz + px * 16] + rand.doublev() * 0.20000000000000001D > 0.0D; boolean alt1 = this.alt1Noise[px + pz * 16] + rand.doublev() * 0.20000000000000001D > 3D; int excl = (int)(this.exclNoise[pz + px * 16] / 3D + 3D + rand.doublev() * 0.25D); diff --git a/server/src/server/worldgen/ReplacerAltSurface.java b/server/src/server/worldgen/ReplacerAltSurface.java index eb03789..23043ac 100755 --- a/server/src/server/worldgen/ReplacerAltSurface.java +++ b/server/src/server/worldgen/ReplacerAltSurface.java @@ -1,6 +1,6 @@ package server.worldgen; -import common.biome.BaseBiome; +import common.biome.Biome; import common.block.Block; import common.material.Material; import common.rng.OctaveGen; @@ -38,7 +38,7 @@ public class ReplacerAltSurface implements BlockReplacer this.fillerBlock = filler.getBlock(); } - public void replaceBlocks(WorldServer world, int x, int z, ChunkPrimer primer, Random rand, BaseBiome[] biomes) + public void replaceBlocks(WorldServer world, int x, int z, ChunkPrimer primer, Random rand, Biome[] biomes) { int i = world.getSeaLevel() + 1; double d0 = 0.03125D; diff --git a/server/src/server/worldgen/ReplacerBiome.java b/server/src/server/worldgen/ReplacerBiome.java index 536639a..894b8df 100755 --- a/server/src/server/worldgen/ReplacerBiome.java +++ b/server/src/server/worldgen/ReplacerBiome.java @@ -1,9 +1,9 @@ package server.worldgen; -import common.biome.BaseBiome; +import common.biome.Biome; import common.rng.PerlinGen; import common.rng.Random; -import server.biome.Biome; +import server.biome.GenBiome; import server.world.WorldServer; public class ReplacerBiome implements BlockReplacer @@ -16,7 +16,7 @@ public class ReplacerBiome implements BlockReplacer this.stoneNoiseGen = new PerlinGen(rand, 4); } - public void replaceBlocks(WorldServer world, int x, int z, ChunkPrimer primer, Random rand, BaseBiome[] biomes) + public void replaceBlocks(WorldServer world, int x, int z, ChunkPrimer primer, Random rand, Biome[] biomes) { double d0 = 0.03125D; this.stoneNoiseGen.generate(this.stoneNoise, (double)(x * 16), (double)(z * 16), 16, 16, d0 * 2.0D, d0 * 2.0D, 1.0D); @@ -25,7 +25,7 @@ public class ReplacerBiome implements BlockReplacer { for (int j = 0; j < 16; ++j) { - Biome biome = Biome.BIOMES[biomes[j + i * 16].id]; + GenBiome biome = GenBiome.BIOMES[biomes[j + i * 16].id]; biome.genTerrainBlocks(world, rand, primer, x * 16 + i, z * 16 + j, this.stoneNoise[j + i * 16]); } } diff --git a/server/src/server/worldgen/ReplacerTopLayer.java b/server/src/server/worldgen/ReplacerTopLayer.java index b229a04..8514527 100755 --- a/server/src/server/worldgen/ReplacerTopLayer.java +++ b/server/src/server/worldgen/ReplacerTopLayer.java @@ -1,6 +1,6 @@ package server.worldgen; -import common.biome.BaseBiome; +import common.biome.Biome; import common.block.Block; import common.init.Blocks; import common.material.Material; @@ -22,7 +22,7 @@ public class ReplacerTopLayer implements BlockReplacer this.replace = replace; } - public void replaceBlocks(WorldServer world, int x, int z, ChunkPrimer primer, Random rand, BaseBiome[] biomes) + public void replaceBlocks(WorldServer world, int x, int z, ChunkPrimer primer, Random rand, Biome[] biomes) { for (int i = 0; i < 16; ++i) { diff --git a/server/src/server/worldgen/caves/MapGenCaves.java b/server/src/server/worldgen/caves/MapGenCaves.java index 368c9ed..18346a0 100755 --- a/server/src/server/worldgen/caves/MapGenCaves.java +++ b/server/src/server/worldgen/caves/MapGenCaves.java @@ -9,7 +9,7 @@ import common.rng.Random; import common.util.BlockPos; import common.util.ExtMath; import common.world.State; -import server.biome.Biome; +import server.biome.GenBiome; import server.world.WorldServer; import server.worldgen.ChunkPrimer; @@ -218,7 +218,7 @@ public class MapGenCaves extends MapGenBase if (flag1 && p_180702_5_.get(j3, j2 - 1, i2).getBlock() == this.top) { blockpos$mutableblockpos.set(j3 + p_180702_3_ * 16, 0, i2 + p_180702_4_ * 16); - p_180702_5_.set(j3, j2 - 1, i2, Biome.BIOMES[this.worldObj.getBiomeGenForCoords(blockpos$mutableblockpos).id].topBlock.getBlock().getState()); + p_180702_5_.set(j3, j2 - 1, i2, GenBiome.BIOMES[this.worldObj.getBiomeGenForCoords(blockpos$mutableblockpos).id].topBlock.getBlock().getState()); } } } diff --git a/server/src/server/worldgen/caves/MapGenRavine.java b/server/src/server/worldgen/caves/MapGenRavine.java index 160d9d3..8ac2336 100755 --- a/server/src/server/worldgen/caves/MapGenRavine.java +++ b/server/src/server/worldgen/caves/MapGenRavine.java @@ -6,7 +6,7 @@ import common.rng.Random; import common.util.BlockPos; import common.util.ExtMath; import common.world.State; -import server.biome.Biome; +import server.biome.GenBiome; import server.world.WorldServer; import server.worldgen.ChunkPrimer; @@ -197,7 +197,7 @@ public class MapGenRavine extends MapGenBase if (flag && p_180707_5_.get(j3, j2 - 1, i2).getBlock() == this.top) { blockpos$mutableblockpos.set(j3 + p_180707_3_ * 16, 0, i2 + p_180707_4_ * 16); - p_180707_5_.set(j3, j2 - 1, i2, Biome.BIOMES[this.worldObj.getBiomeGenForCoords(blockpos$mutableblockpos).id].topBlock); + p_180707_5_.set(j3, j2 - 1, i2, GenBiome.BIOMES[this.worldObj.getBiomeGenForCoords(blockpos$mutableblockpos).id].topBlock); } } } diff --git a/server/src/server/worldgen/layer/GenLayer.java b/server/src/server/worldgen/layer/GenLayer.java index a696537..675f884 100755 --- a/server/src/server/worldgen/layer/GenLayer.java +++ b/server/src/server/worldgen/layer/GenLayer.java @@ -1,7 +1,7 @@ package server.worldgen.layer; -import common.biome.BaseBiome; -import server.biome.Biome; +import common.biome.Biome; +import server.biome.GenBiome; public abstract class GenLayer { private long worldGenSeed; @@ -14,8 +14,8 @@ public abstract class GenLayer { return true; } else { // if(id1 != Biome.mesaPlateau_F.id && id1 != Biome.mesaPlateau.id) { - final Biome biome1 = Biome.getBiome(id1); - final Biome biome2 = Biome.getBiome(id2); + final GenBiome biome1 = GenBiome.getBiome(id1); + final GenBiome biome2 = GenBiome.getBiome(id2); return biome1 != null && biome2 != null ? biome1.isEqualTo(biome2) : false; } // else { @@ -24,7 +24,7 @@ public abstract class GenLayer { } protected static boolean isSea(int id) { - return id == BaseBiome.SEA.id || id == BaseBiome.FROZENSEA.id; + return id == Biome.SEA.id || id == Biome.FROZENSEA.id; } public GenLayer(long base) { diff --git a/server/src/server/worldgen/layer/GenLayerAddExtra.java b/server/src/server/worldgen/layer/GenLayerAddExtra.java index 67444a6..54a1d4a 100755 --- a/server/src/server/worldgen/layer/GenLayerAddExtra.java +++ b/server/src/server/worldgen/layer/GenLayerAddExtra.java @@ -1,13 +1,13 @@ package server.worldgen.layer; -import common.biome.BaseBiome; +import common.biome.Biome; public class GenLayerAddExtra extends GenLayer { private final int[] biomes; private final int rarity; - public GenLayerAddExtra(long base, GenLayer parent, BaseBiome[] biomes, int rarity) + public GenLayerAddExtra(long base, GenLayer parent, Biome[] biomes, int rarity) { super(base); this.parent = parent; diff --git a/server/src/server/worldgen/layer/GenLayerAddSea.java b/server/src/server/worldgen/layer/GenLayerAddSea.java index 67123e3..f958542 100755 --- a/server/src/server/worldgen/layer/GenLayerAddSea.java +++ b/server/src/server/worldgen/layer/GenLayerAddSea.java @@ -1,6 +1,6 @@ package server.worldgen.layer; -import common.biome.BaseBiome; +import common.biome.Biome; public class GenLayerAddSea extends GenLayer { @@ -60,7 +60,7 @@ public class GenLayerAddSea extends GenLayer this.initChunkSeed((long)(areaX + j1), (long)(areaY + i1)); if (k2 == 0 && this.nextInt(this.rarity) == 0) { - aint1[j1 + i1 * areaWidth] = l2 > 1 ? BaseBiome.FROZENSEA.id : BaseBiome.SEA.id; + aint1[j1 + i1 * areaWidth] = l2 > 1 ? Biome.FROZENSEA.id : Biome.SEA.id; } else { diff --git a/server/src/server/worldgen/layer/GenLayerBiome.java b/server/src/server/worldgen/layer/GenLayerBiome.java index ca2fc39..a61c14f 100755 --- a/server/src/server/worldgen/layer/GenLayerBiome.java +++ b/server/src/server/worldgen/layer/GenLayerBiome.java @@ -1,17 +1,17 @@ package server.worldgen.layer; -import common.biome.BaseBiome; +import common.biome.Biome; public class GenLayerBiome extends GenLayer { - private final BaseBiome[] hot; - private final BaseBiome[] medium; - private final BaseBiome[] cold; - private final BaseBiome[] frost; + private final Biome[] hot; + private final Biome[] medium; + private final Biome[] cold; + private final Biome[] frost; private final int def; private final int fixed; - public GenLayerBiome(long base, GenLayer parent, BaseBiome[] hot, BaseBiome[] medium, BaseBiome[] cold, BaseBiome[] frost, BaseBiome def, boolean fixed) + public GenLayerBiome(long base, GenLayer parent, Biome[] hot, Biome[] medium, Biome[] cold, Biome[] frost, Biome def, boolean fixed) { super(base); this.parent = parent; diff --git a/server/src/server/worldgen/layer/GenLayerBiomeEdge.java b/server/src/server/worldgen/layer/GenLayerBiomeEdge.java index 41abf0c..b2ae7be 100755 --- a/server/src/server/worldgen/layer/GenLayerBiomeEdge.java +++ b/server/src/server/worldgen/layer/GenLayerBiomeEdge.java @@ -1,7 +1,7 @@ package server.worldgen.layer; -import common.biome.BaseBiome; -import server.biome.Biome; +import common.biome.Biome; +import server.biome.GenBiome; import server.biome.Temperature; public class GenLayerBiomeEdge extends GenLayer @@ -28,45 +28,45 @@ public class GenLayerBiomeEdge extends GenLayer this.initChunkSeed((long)(j + areaX), (long)(i + areaY)); int k = aint[j + 1 + (i + 1) * (areaWidth + 2)]; - if (!this.replaceBiomeEdgeIfNecessary(aint, aint1, j, i, areaWidth, k, BaseBiome.EXTREMEHILLS.id, BaseBiome.EXTREMEHILLSEDGE.id) && /* !this.replaceBiomeEdge(aint, aint1, j, i, areaWidth, k, Biome.mesaPlateau_F.id, Biome.mesa.id) && !this.replaceBiomeEdge(aint, aint1, j, i, areaWidth, k, Biome.mesaPlateau.id, Biome.mesa.id) && */ !this.replaceBiomeEdge(aint, aint1, j, i, areaWidth, k, BaseBiome.MEGATAIGA.id, BaseBiome.TAIGA.id)) + if (!this.replaceBiomeEdgeIfNecessary(aint, aint1, j, i, areaWidth, k, Biome.EXTREMEHILLS.id, Biome.EXTREMEHILLSEDGE.id) && /* !this.replaceBiomeEdge(aint, aint1, j, i, areaWidth, k, Biome.mesaPlateau_F.id, Biome.mesa.id) && !this.replaceBiomeEdge(aint, aint1, j, i, areaWidth, k, Biome.mesaPlateau.id, Biome.mesa.id) && */ !this.replaceBiomeEdge(aint, aint1, j, i, areaWidth, k, Biome.MEGATAIGA.id, Biome.TAIGA.id)) { - if (k == BaseBiome.DESERT.id) + if (k == Biome.DESERT.id) { int l1 = aint[j + 1 + (i + 1 - 1) * (areaWidth + 2)]; int i2 = aint[j + 1 + 1 + (i + 1) * (areaWidth + 2)]; int j2 = aint[j + 1 - 1 + (i + 1) * (areaWidth + 2)]; int k2 = aint[j + 1 + (i + 1 + 1) * (areaWidth + 2)]; - if (l1 != BaseBiome.ICEPLAINS.id && i2 != BaseBiome.ICEPLAINS.id && j2 != BaseBiome.ICEPLAINS.id && k2 != BaseBiome.ICEPLAINS.id) + if (l1 != Biome.ICEPLAINS.id && i2 != Biome.ICEPLAINS.id && j2 != Biome.ICEPLAINS.id && k2 != Biome.ICEPLAINS.id) { aint1[j + i * areaWidth] = k; } else { - aint1[j + i * areaWidth] = BaseBiome.EXTREMEHILLSPLUS.id; + aint1[j + i * areaWidth] = Biome.EXTREMEHILLSPLUS.id; } } - else if (k == BaseBiome.SWAMPLAND.id) + else if (k == Biome.SWAMPLAND.id) { int l = aint[j + 1 + (i + 1 - 1) * (areaWidth + 2)]; int i1 = aint[j + 1 + 1 + (i + 1) * (areaWidth + 2)]; int j1 = aint[j + 1 - 1 + (i + 1) * (areaWidth + 2)]; int k1 = aint[j + 1 + (i + 1 + 1) * (areaWidth + 2)]; - if (l != BaseBiome.DESERT.id && i1 != BaseBiome.DESERT.id && j1 != BaseBiome.DESERT.id && k1 != BaseBiome.DESERT.id && l != BaseBiome.COLDTAIGA.id && i1 != BaseBiome.COLDTAIGA.id && j1 != BaseBiome.COLDTAIGA.id && k1 != BaseBiome.COLDTAIGA.id && l != BaseBiome.ICEPLAINS.id && i1 != BaseBiome.ICEPLAINS.id && j1 != BaseBiome.ICEPLAINS.id && k1 != BaseBiome.ICEPLAINS.id) + if (l != Biome.DESERT.id && i1 != Biome.DESERT.id && j1 != Biome.DESERT.id && k1 != Biome.DESERT.id && l != Biome.COLDTAIGA.id && i1 != Biome.COLDTAIGA.id && j1 != Biome.COLDTAIGA.id && k1 != Biome.COLDTAIGA.id && l != Biome.ICEPLAINS.id && i1 != Biome.ICEPLAINS.id && j1 != Biome.ICEPLAINS.id && k1 != Biome.ICEPLAINS.id) { - if (l != BaseBiome.JUNGLE.id && k1 != BaseBiome.JUNGLE.id && i1 != BaseBiome.JUNGLE.id && j1 != BaseBiome.JUNGLE.id) + if (l != Biome.JUNGLE.id && k1 != Biome.JUNGLE.id && i1 != Biome.JUNGLE.id && j1 != Biome.JUNGLE.id) { aint1[j + i * areaWidth] = k; } else { - aint1[j + i * areaWidth] = BaseBiome.JUNGLEEDGE.id; + aint1[j + i * areaWidth] = Biome.JUNGLEEDGE.id; } } else { - aint1[j + i * areaWidth] = BaseBiome.PLAINS.id; + aint1[j + i * areaWidth] = Biome.PLAINS.id; } } else @@ -150,8 +150,8 @@ public class GenLayerBiomeEdge extends GenLayer } else { - Biome biomegenbase = Biome.getBiome(p_151634_1_); - Biome biomegenbase1 = Biome.getBiome(p_151634_2_); + GenBiome biomegenbase = GenBiome.getBiome(p_151634_1_); + GenBiome biomegenbase1 = GenBiome.getBiome(p_151634_2_); if (biomegenbase != null && biomegenbase1 != null) { diff --git a/server/src/server/worldgen/layer/GenLayerHills.java b/server/src/server/worldgen/layer/GenLayerHills.java index 832f2c8..c92a1f0 100755 --- a/server/src/server/worldgen/layer/GenLayerHills.java +++ b/server/src/server/worldgen/layer/GenLayerHills.java @@ -1,6 +1,6 @@ package server.worldgen.layer; -import common.biome.BaseBiome; +import common.biome.Biome; import common.log.Log; public class GenLayerHills extends GenLayer @@ -8,7 +8,7 @@ public class GenLayerHills extends GenLayer private GenLayer field_151628_d; private final int def; - public GenLayerHills(long p_i45479_1_, GenLayer p_i45479_3_, GenLayer p_i45479_4_, BaseBiome def) + public GenLayerHills(long p_i45479_1_, GenLayer p_i45479_3_, GenLayer p_i45479_4_, Biome def) { super(p_i45479_1_); this.parent = p_i45479_3_; @@ -42,7 +42,7 @@ public class GenLayerHills extends GenLayer if (k != 0 && l >= 2 && (l - 2) % 29 == 1 && k < 128) { - if (BaseBiome.getBiome(k + 128) != null) + if (Biome.getBiome(k + 128) != null) { aint2[j + i * areaWidth] = k + 128; } @@ -59,86 +59,86 @@ public class GenLayerHills extends GenLayer { int i1 = k; - if (k == BaseBiome.DESERT.id) + if (k == Biome.DESERT.id) { - i1 = BaseBiome.DESERTHILLS.id; + i1 = Biome.DESERTHILLS.id; } - else if (k == BaseBiome.FOREST.id) + else if (k == Biome.FOREST.id) { - i1 = BaseBiome.FORESTHILLS.id; + i1 = Biome.FORESTHILLS.id; } - else if (k == BaseBiome.BIRCHFOREST.id) + else if (k == Biome.BIRCHFOREST.id) { - i1 = BaseBiome.BIRCHFORESTHILLS.id; + i1 = Biome.BIRCHFORESTHILLS.id; } - else if (k == BaseBiome.ROOFEDFOREST.id) + else if (k == Biome.ROOFEDFOREST.id) { - i1 = BaseBiome.PLAINS.id; + i1 = Biome.PLAINS.id; } - else if (k == BaseBiome.TAIGA.id) + else if (k == Biome.TAIGA.id) { - i1 = BaseBiome.TAIGAHILLS.id; + i1 = Biome.TAIGAHILLS.id; } - else if (k == BaseBiome.MEGATAIGA.id) + else if (k == Biome.MEGATAIGA.id) { - i1 = BaseBiome.MEGATAIGAHILLS.id; + i1 = Biome.MEGATAIGAHILLS.id; } - else if (k == BaseBiome.COLDTAIGA.id) + else if (k == Biome.COLDTAIGA.id) { - i1 = BaseBiome.COLDTAIGAHILLS.id; + i1 = Biome.COLDTAIGAHILLS.id; } - else if (k == BaseBiome.PLAINS.id) + else if (k == Biome.PLAINS.id) { if (this.nextInt(3) == 0) { - i1 = BaseBiome.FORESTHILLS.id; + i1 = Biome.FORESTHILLS.id; } else { - i1 = BaseBiome.FOREST.id; + i1 = Biome.FOREST.id; } } - else if (k == BaseBiome.ICEPLAINS.id) + else if (k == Biome.ICEPLAINS.id) { - i1 = BaseBiome.ICEMOUNTAINS.id; + i1 = Biome.ICEMOUNTAINS.id; } - else if (k == BaseBiome.JUNGLE.id) + else if (k == Biome.JUNGLE.id) { - i1 = BaseBiome.JUNGLEHILLS.id; + i1 = Biome.JUNGLEHILLS.id; } - else if (k == BaseBiome.NONE.id) + else if (k == Biome.NONE.id) { i1 = this.def; } - else if (k == BaseBiome.EXTREMEHILLS.id) + else if (k == Biome.EXTREMEHILLS.id) { - i1 = BaseBiome.EXTREMEHILLSPLUS.id; + i1 = Biome.EXTREMEHILLSPLUS.id; } - else if (k == BaseBiome.SAVANNA.id) + else if (k == Biome.SAVANNA.id) { - i1 = BaseBiome.SAVANNAPLATEAU.id; + i1 = Biome.SAVANNAPLATEAU.id; } // else if (canBeNearby(k, Biome.mesaPlateau_F.id)) // { // i1 = Biome.mesa.id; // } - else if (k == BaseBiome.SEA.id && this.nextInt(3) == 0) + else if (k == Biome.SEA.id && this.nextInt(3) == 0) { int j1 = this.nextInt(2); if (j1 == 0) { - i1 = BaseBiome.PLAINS.id; + i1 = Biome.PLAINS.id; } else { - i1 = BaseBiome.FOREST.id; + i1 = Biome.FOREST.id; } } if (flag && i1 != k) { - if (BaseBiome.getBiome(i1 + 128) != null) + if (Biome.getBiome(i1 + 128) != null) { i1 += 128; } diff --git a/server/src/server/worldgen/layer/GenLayerRiver.java b/server/src/server/worldgen/layer/GenLayerRiver.java index 0ea31ff..00a0348 100755 --- a/server/src/server/worldgen/layer/GenLayerRiver.java +++ b/server/src/server/worldgen/layer/GenLayerRiver.java @@ -1,6 +1,6 @@ package server.worldgen.layer; -import common.biome.BaseBiome; +import common.biome.Biome; public class GenLayerRiver extends GenLayer { @@ -39,7 +39,7 @@ public class GenLayerRiver extends GenLayer } else { - aint1[j1 + i1 * areaWidth] = BaseBiome.RIVER.id; + aint1[j1 + i1 * areaWidth] = Biome.RIVER.id; } } } diff --git a/server/src/server/worldgen/layer/GenLayerRiverMix.java b/server/src/server/worldgen/layer/GenLayerRiverMix.java index 8f34f59..05d47f8 100755 --- a/server/src/server/worldgen/layer/GenLayerRiverMix.java +++ b/server/src/server/worldgen/layer/GenLayerRiverMix.java @@ -1,6 +1,6 @@ package server.worldgen.layer; -import common.biome.BaseBiome; +import common.biome.Biome; public class GenLayerRiverMix extends GenLayer { @@ -8,7 +8,7 @@ public class GenLayerRiverMix extends GenLayer private GenLayer riverPatternGeneratorChain; private final int def; - public GenLayerRiverMix(long p_i2129_1_, GenLayer p_i2129_3_, GenLayer p_i2129_4_, BaseBiome def) + public GenLayerRiverMix(long p_i2129_1_, GenLayer p_i2129_3_, GenLayer p_i2129_4_, Biome def) { super(p_i2129_1_); this.biomePatternGeneratorChain = p_i2129_3_; @@ -39,23 +39,23 @@ public class GenLayerRiverMix extends GenLayer for (int i = 0; i < areaWidth * areaHeight; ++i) { - if(biome[i] == BaseBiome.NONE.id) + if(biome[i] == Biome.NONE.id) { out[i] = this.def; } - else if(biome[i] == BaseBiome.SEA.id || biome[i] == BaseBiome.FROZENSEA.id) + else if(biome[i] == Biome.SEA.id || biome[i] == Biome.FROZENSEA.id) { out[i] = biome[i]; } - else if (river[i] == BaseBiome.RIVER.id) + else if (river[i] == Biome.RIVER.id) { - if (biome[i] == BaseBiome.ICEPLAINS.id) + if (biome[i] == Biome.ICEPLAINS.id) { - out[i] = BaseBiome.FROZENRIVER.id; + out[i] = Biome.FROZENRIVER.id; } else // if (biome[i] != Biome.mushroomPlains.id && biome[i] != Biome.mushroomPlainsEdge.id) { - out[i] = BaseBiome.RIVER.id; + out[i] = Biome.RIVER.id; } // else // { diff --git a/server/src/server/worldgen/layer/GenLayerShore.java b/server/src/server/worldgen/layer/GenLayerShore.java index a51e8c1..715e37a 100755 --- a/server/src/server/worldgen/layer/GenLayerShore.java +++ b/server/src/server/worldgen/layer/GenLayerShore.java @@ -1,7 +1,7 @@ package server.worldgen.layer; -import common.biome.BaseBiome; -import server.biome.Biome; +import common.biome.Biome; +import server.biome.GenBiome; import server.biome.BiomeJungle; public class GenLayerShore extends GenLayer @@ -23,7 +23,7 @@ public class GenLayerShore extends GenLayer { this.initChunkSeed((long)(j + x), (long)(i + z)); int id = pre[j + 1 + (i + 1) * (width + 2)]; - Biome biome = Biome.getBiome(id); + GenBiome biome = GenBiome.getBiome(id); // if (id == Biome.mushroomPlains.id) // { @@ -57,19 +57,19 @@ public class GenLayerShore extends GenLayer } else { - data[j + i * width] = BaseBiome.BEACH.id; + data[j + i * width] = Biome.BEACH.id; } } else { - data[j + i * width] = BaseBiome.JUNGLEEDGE.id; + data[j + i * width] = Biome.JUNGLEEDGE.id; } } - else if (id != BaseBiome.EXTREMEHILLS.id && id != BaseBiome.EXTREMEHILLSPLUS.id && id != BaseBiome.EXTREMEHILLSEDGE.id) + else if (id != Biome.EXTREMEHILLS.id && id != Biome.EXTREMEHILLSPLUS.id && id != Biome.EXTREMEHILLSEDGE.id) { if (biome != null && biome.allowColdBeach) { - this.putBeach(pre, data, j, i, width, id, BaseBiome.COLDBEACH.id); + this.putBeach(pre, data, j, i, width, id, Biome.COLDBEACH.id); } else // if (id != Biome.mesa.id && id != Biome.mesaPlateau_F.id) // { @@ -86,7 +86,7 @@ public class GenLayerShore extends GenLayer } else { - data[j + i * width] = BaseBiome.BEACH.id; + data[j + i * width] = Biome.BEACH.id; } } else @@ -120,7 +120,7 @@ public class GenLayerShore extends GenLayer } else { - this.putBeach(pre, data, j, i, width, id, BaseBiome.STONEBEACH.id); + this.putBeach(pre, data, j, i, width, id, Biome.STONEBEACH.id); } } } @@ -154,8 +154,8 @@ public class GenLayerShore extends GenLayer private boolean canNBJungle(int id) { - Biome biome = Biome.getBiome(id); - return biome != null && biome.getBiomeClass() == BiomeJungle.class ? true : id == BaseBiome.JUNGLEEDGE.id || id == BaseBiome.JUNGLE.id || id == BaseBiome.JUNGLEHILLS.id || id == BaseBiome.FOREST.id || id == BaseBiome.TAIGA.id || isSea(id); + GenBiome biome = GenBiome.getBiome(id); + return biome != null && biome.getBiomeClass() == BiomeJungle.class ? true : id == Biome.JUNGLEEDGE.id || id == Biome.JUNGLE.id || id == Biome.JUNGLEHILLS.id || id == Biome.FOREST.id || id == Biome.TAIGA.id || isSea(id); } // private boolean canNBMesa(int id) diff --git a/server/src/server/worldgen/structure/MapGenScatteredFeature.java b/server/src/server/worldgen/structure/MapGenScatteredFeature.java index f731099..c0393ae 100755 --- a/server/src/server/worldgen/structure/MapGenScatteredFeature.java +++ b/server/src/server/worldgen/structure/MapGenScatteredFeature.java @@ -3,14 +3,14 @@ package server.worldgen.structure; import java.util.Arrays; import java.util.List; -import common.biome.BaseBiome; +import common.biome.Biome; import common.rng.Random; import common.util.BlockPos; import server.world.WorldServer; public class MapGenScatteredFeature extends MapGenStructure { - private static final List biomelist = Arrays.asList(BaseBiome.DESERT, BaseBiome.DESERTHILLS, BaseBiome.JUNGLE, BaseBiome.JUNGLEHILLS, BaseBiome.SWAMPLAND); + private static final List biomelist = Arrays.asList(Biome.DESERT, Biome.DESERTHILLS, Biome.JUNGLE, Biome.JUNGLEHILLS, Biome.SWAMPLAND); private static final int MAX_DISTANCE = 32; private static final int MIN_DISTANCE = 8; @@ -44,14 +44,14 @@ public class MapGenScatteredFeature extends MapGenStructure if (i == k && j == l) { - BaseBiome biomegenbase = this.worldObj.getBiomeGenerator().getBiomeGenerator(new BlockPos(i * 16 + 8, 0, j * 16 + 8), null); + Biome biomegenbase = this.worldObj.getBiomeGenerator().getBiomeGenerator(new BlockPos(i * 16 + 8, 0, j * 16 + 8), null); if (biomegenbase == null) { return false; } - for (BaseBiome biomegenbase1 : biomelist) + for (Biome biomegenbase1 : biomelist) { if (biomegenbase == biomegenbase1) { @@ -92,16 +92,16 @@ public class MapGenScatteredFeature extends MapGenStructure public Start(WorldServer worldIn, Random p_i2060_2_, int p_i2060_3_, int p_i2060_4_) { super(p_i2060_3_, p_i2060_4_); - BaseBiome biomegenbase = worldIn.getBiomeGenForCoords(new BlockPos(p_i2060_3_ * 16 + 8, 0, p_i2060_4_ * 16 + 8)); + Biome biomegenbase = worldIn.getBiomeGenForCoords(new BlockPos(p_i2060_3_ * 16 + 8, 0, p_i2060_4_ * 16 + 8)); - if (biomegenbase != BaseBiome.JUNGLE && biomegenbase != BaseBiome.JUNGLEHILLS) + if (biomegenbase != Biome.JUNGLE && biomegenbase != Biome.JUNGLEHILLS) { - if (biomegenbase == BaseBiome.SWAMPLAND) + if (biomegenbase == Biome.SWAMPLAND) { StructureScattered.SwampHut componentscatteredfeaturepieces$swamphut = new StructureScattered.SwampHut(p_i2060_2_, p_i2060_3_ * 16, p_i2060_4_ * 16); this.components.add(componentscatteredfeaturepieces$swamphut); } - else if (biomegenbase == BaseBiome.DESERT || biomegenbase == BaseBiome.DESERTHILLS) + else if (biomegenbase == Biome.DESERT || biomegenbase == Biome.DESERTHILLS) { StructureScattered.DesertPyramid componentscatteredfeaturepieces$desertpyramid = new StructureScattered.DesertPyramid(p_i2060_2_, p_i2060_3_ * 16, p_i2060_4_ * 16); this.components.add(componentscatteredfeaturepieces$desertpyramid); diff --git a/server/src/server/worldgen/structure/MapGenVillage.java b/server/src/server/worldgen/structure/MapGenVillage.java index 396d5a3..47f89ec 100755 --- a/server/src/server/worldgen/structure/MapGenVillage.java +++ b/server/src/server/worldgen/structure/MapGenVillage.java @@ -3,7 +3,7 @@ package server.worldgen.structure; import java.util.List; import java.util.Set; -import common.biome.BaseBiome; +import common.biome.Biome; import common.collect.Sets; import common.nbt.NBTTagCompound; import common.rng.Random; @@ -11,7 +11,7 @@ import server.world.WorldServer; public class MapGenVillage extends MapGenStructure { - public static final Set villageSpawnBiomes = Sets.newHashSet(BaseBiome.PLAINS, BaseBiome.DESERT, BaseBiome.SAVANNA); + public static final Set villageSpawnBiomes = Sets.newHashSet(Biome.PLAINS, Biome.DESERT, Biome.SAVANNA); /** World terrain type, 0 for normal, 1 for flat map */ private int terrainType; diff --git a/server/src/server/worldgen/structure/StructureVillage.java b/server/src/server/worldgen/structure/StructureVillage.java index 7d00750..498cec0 100755 --- a/server/src/server/worldgen/structure/StructureVillage.java +++ b/server/src/server/worldgen/structure/StructureVillage.java @@ -3,7 +3,7 @@ package server.worldgen.structure; import java.util.Iterator; import java.util.List; -import common.biome.BaseBiome; +import common.biome.Biome; import common.block.Block; import common.block.BlockLog; import common.block.BlockSandStone; @@ -1430,8 +1430,8 @@ public class StructureVillage this.biomeGen = genIn; this.structureVillageWeightedPieceList = p_i2104_6_; this.terrainType = p_i2104_7_; - BaseBiome biomegenbase = genIn.getBiomeGenerator(new BlockPos(p_i2104_4_, 0, p_i2104_5_), BaseBiome.DEF_BIOME); - this.inDesert = biomegenbase == BaseBiome.DESERT || biomegenbase == BaseBiome.DESERTHILLS; + Biome biomegenbase = genIn.getBiomeGenerator(new BlockPos(p_i2104_4_, 0, p_i2104_5_), Biome.DEF_BIOME); + this.inDesert = biomegenbase == Biome.DESERT || biomegenbase == Biome.DESERTHILLS; this.func_175846_a(this.inDesert); } From 660199b1d88007a73019cae9130b176de1c7e6ba Mon Sep 17 00:00:00 2001 From: Sen Date: Wed, 14 May 2025 15:45:27 +0200 Subject: [PATCH 031/200] misc refactoring 2 --- .../src/common/init/FlammabilityRegistry.java | 41 -- common/src/common/init/Items.java | 397 ++++++++---------- common/src/common/init/TileRegistry.java | 15 +- common/src/common/init/ToolMaterial.java | 272 ++++++------ common/src/common/item/CheatTab.java | 7 + common/src/common/item/ItemArmor.java | 2 +- common/src/common/item/ItemBucket.java | 2 +- common/src/common/item/ItemHoe.java | 2 +- common/src/common/item/ItemShears.java | 4 +- common/src/common/item/ItemSword.java | 6 +- common/src/common/item/ItemTool.java | 6 +- .../packet/S35PacketUpdateTileEntity.java | 4 +- common/src/common/tileentity/TileEntity.java | 4 +- server/src/server/world/Converter.java | 2 +- 14 files changed, 344 insertions(+), 420 deletions(-) diff --git a/common/src/common/init/FlammabilityRegistry.java b/common/src/common/init/FlammabilityRegistry.java index 8403c97..54f8f47 100755 --- a/common/src/common/init/FlammabilityRegistry.java +++ b/common/src/common/init/FlammabilityRegistry.java @@ -8,7 +8,6 @@ public abstract class FlammabilityRegistry { } static void register() { -// setFlammable(Blocks.planks, 5, 20); for(WoodType wood : WoodType.values()) { setFlammable(BlockRegistry.getRegisteredBlock(wood.getName() + "_planks"), 5, 20); setFlammable(BlockRegistry.getRegisteredBlock(wood.getName() + "_slab"), 5, 20); @@ -31,45 +30,5 @@ public abstract class FlammabilityRegistry { setFlammable(Blocks.coal_block, 5, 5); setFlammable(Blocks.hay_block, 60, 20); setFlammable(Blocks.carpet, 60, 20); - -// setFlammable(Blocks.double_wooden_slab, 5, 20); -// setFlammable(Blocks.wooden_slab, 5, 20); -// setFlammable(Blocks.oak_fence_gate, 5, 20); -// setFlammable(Blocks.spruce_fence_gate, 5, 20); -// setFlammable(Blocks.birch_fence_gate, 5, 20); -// setFlammable(Blocks.jungle_fence_gate, 5, 20); -// setFlammable(Blocks.dark_oak_fence_gate, 5, 20); -// setFlammable(Blocks.acacia_fence_gate, 5, 20); -// setFlammable(Blocks.oak_fence, 5, 20); -// setFlammable(Blocks.spruce_fence, 5, 20); -// setFlammable(Blocks.birch_fence, 5, 20); -// setFlammable(Blocks.jungle_fence, 5, 20); -// setFlammable(Blocks.dark_oak_fence, 5, 20); -// setFlammable(Blocks.acacia_fence, 5, 20); -// setFlammable(Blocks.oak_stairs, 5, 20); -// setFlammable(Blocks.birch_stairs, 5, 20); -// setFlammable(Blocks.spruce_stairs, 5, 20); -// setFlammable(Blocks.jungle_stairs, 5, 20); -// setFlammable(Blocks.log, 5, 5); -// setFlammable(Blocks.log2, 5, 5); -// for(BlockLeaves leaves : BlockLeaves.LEAVES) { -// setFlammable(leaves, 30, 60); -//// setFlammable(Blocks.leaves2, 30, 60); -// } -// setFlammable(Blocks.red_flower, 60, 100); -// setFlammable(Blocks.cherry_leaves, 30, 60); -// setFlammable(Blocks.maple_leaves, 30, 60); -// setFlammable(Blocks.cherry_fence_gate, 5, 20); -// setFlammable(Blocks.maple_fence_gate, 5, 20); -// setFlammable(Blocks.cherry_fence, 5, 20); -// setFlammable(Blocks.maple_fence, 5, 20); -// setFlammable(Blocks.cherry_stairs, 5, 20); -// setFlammable(Blocks.maple_stairs, 5, 20); -// setFlammable(Blocks.wooden_vslab, 5, 20); -// setFlammable(Blocks.wooden_vslab2, 5, 20); -// for(BlockSlab slab : BlockSlab.SLABS) { -// if(slab.getMaterial() == Material.wood) -// setFlammable(slab, 5, 20); -// } } } diff --git a/common/src/common/init/Items.java b/common/src/common/init/Items.java index 099bf36..4f9779b 100755 --- a/common/src/common/init/Items.java +++ b/common/src/common/init/Items.java @@ -11,241 +11,208 @@ import common.item.ItemShears; public abstract class Items { - public static final Item iron_shovel = get("iron_shovel"); - public static final Item iron_pickaxe = get("iron_pickaxe"); - public static final Item iron_axe = get("iron_axe"); - public static final Item flint_and_steel = get("flint_and_steel"); - public static final Item apple = get("apple"); - public static final ItemBow bow = (ItemBow)get("bow"); - public static final Item arrow = get("arrow"); - public static final Item coal = get("coal"); - public static final Item diamond = get("diamond"); - public static final Item iron_ingot = get("iron_ingot"); - public static final Item gold_ingot = get("gold_ingot"); - public static final Item iron_sword = get("iron_sword"); - public static final Item wood_sword = get("wood_sword"); - public static final Item wood_shovel = get("wood_shovel"); - public static final Item wood_pickaxe = get("wood_pickaxe"); - public static final Item wood_axe = get("wood_axe"); - public static final Item stone_sword = get("stone_sword"); - public static final Item stone_shovel = get("stone_shovel"); - public static final Item stone_pickaxe = get("stone_pickaxe"); - public static final Item stone_axe = get("stone_axe"); - public static final Item diamond_sword = get("diamond_sword"); - public static final Item diamond_shovel = get("diamond_shovel"); - public static final Item diamond_pickaxe = get("diamond_pickaxe"); - public static final Item diamond_axe = get("diamond_axe"); - public static final Item stick = get("stick"); - public static final Item bowl = get("bowl"); - public static final Item mushroom_stew = get("mushroom_stew"); - public static final Item gold_sword = get("gold_sword"); - public static final Item gold_shovel = get("gold_shovel"); - public static final Item gold_pickaxe = get("gold_pickaxe"); - public static final Item gold_axe = get("gold_axe"); - public static final Item string = get("string"); - public static final Item feather = get("feather"); - public static final Item gunpowder = get("gunpowder"); - public static final Item wood_hoe = get("wood_hoe"); - public static final Item stone_hoe = get("stone_hoe"); - public static final Item iron_hoe = get("iron_hoe"); - public static final Item diamond_hoe = get("diamond_hoe"); - public static final Item gold_hoe = get("gold_hoe"); - public static final Item wheat = get("wheat"); - public static final Item wheats = get("wheats"); - public static final Item bread = get("bread"); - public static final ItemArmor leather_helmet = (ItemArmor)get("leather_helmet"); - public static final ItemArmor leather_chestplate = (ItemArmor)get("leather_chestplate"); - public static final ItemArmor leather_leggings = (ItemArmor)get("leather_leggings"); - public static final ItemArmor leather_boots = (ItemArmor)get("leather_boots"); - public static final ItemArmor chain_helmet = (ItemArmor)get("chain_helmet"); - public static final ItemArmor chain_chestplate = (ItemArmor)get("chain_chestplate"); - public static final ItemArmor chain_leggings = (ItemArmor)get("chain_leggings"); - public static final ItemArmor chain_boots = (ItemArmor)get("chain_boots"); - public static final ItemArmor iron_helmet = (ItemArmor)get("iron_helmet"); - public static final ItemArmor iron_chestplate = (ItemArmor)get("iron_chestplate"); - public static final ItemArmor iron_leggings = (ItemArmor)get("iron_leggings"); - public static final ItemArmor iron_boots = (ItemArmor)get("iron_boots"); - public static final ItemArmor diamond_helmet = (ItemArmor)get("diamond_helmet"); - public static final ItemArmor diamond_chestplate = (ItemArmor)get("diamond_chestplate"); - public static final ItemArmor diamond_leggings = (ItemArmor)get("diamond_leggings"); - public static final ItemArmor diamond_boots = (ItemArmor)get("diamond_boots"); - public static final ItemArmor gold_helmet = (ItemArmor)get("gold_helmet"); - public static final ItemArmor gold_chestplate = (ItemArmor)get("gold_chestplate"); - public static final ItemArmor gold_leggings = (ItemArmor)get("gold_leggings"); - public static final ItemArmor gold_boots = (ItemArmor)get("gold_boots"); - public static final Item flint = get("flint"); - public static final Item porkchop = get("porkchop"); - public static final Item cooked_porkchop = get("cooked_porkchop"); -// public static final Item painting = get("painting"); - public static final Item golden_apple = get("golden_apple"); - public static final Item sign = get("sign"); - public static final Item oak_door = get("oak_door"); - public static final Item spruce_door = get("spruce_door"); - public static final Item birch_door = get("birch_door"); - public static final Item jungle_door = get("jungle_door"); public static final Item acacia_door = get("acacia_door"); - public static final Item dark_oak_door = get("dark_oak_door"); - public static final Item bucket = get("bucket"); - public static final Item water_bucket = get("water_bucket"); -// public static final Item lava_bucket = get("lava_bucket"); -// public static final Item fluid_bucket = get("fluid_bucket"); - public static final Item minecart = get("minecart"); - public static final Item saddle = get("saddle"); - public static final Item iron_door = get("iron_door"); - public static final Item redstone = get("redstone"); - public static final Item snowball = get("snowball"); - public static final Item boat = get("boat"); - public static final Item leather = get("leather"); - public static final Item milk_bucket = get("milk_bucket"); - public static final Item brick = get("brick"); - public static final Item clay_ball = get("clay_ball"); - public static final Item reeds = get("reeds"); - public static final Item paper = get("paper"); - public static final Item book = get("book"); - public static final Item slime_ball = get("slime_ball"); - public static final Item chest_minecart = get("chest_minecart"); -// public static final Item furnace_minecart = get("furnace_minecart"); - public static final Item egg = get("egg"); - public static final Item navigator = get("navigator"); - public static final ItemFishingRod fishing_rod = (ItemFishingRod)get("fishing_rod"); -// public static final Item clock = get("clock"); - public static final Item glowstone_dust = get("glowstone_dust"); - public static final Item fish = get("fish"); - public static final Item cooked_fish = get("cooked_fish"); - public static final Item dye = get("dye"); - public static final Item bone = get("bone"); - public static final Item sugar = get("sugar"); - public static final Item cake = get("cake"); -// public static final Item red_bed = get("red_bed"); - public static final Item repeater = get("repeater"); - public static final Item cookie = get("cookie"); - public static final ItemShears iron_shears = (ItemShears)get("iron_shears"); - public static final Item melon = get("melon"); - public static final Item pumpkin_stem = get("pumpkin_stem"); - public static final Item melon_stem = get("melon_stem"); - public static final Item beef = get("beef"); - public static final Item cooked_beef = get("cooked_beef"); - public static final Item chicken = get("chicken"); - public static final Item cooked_chicken = get("cooked_chicken"); - public static final Item rotten_flesh = get("rotten_flesh"); - public static final Item orb = get("orb"); - public static final Item blaze_rod = get("blaze_rod"); - public static final Item ghast_tear = get("ghast_tear"); - public static final Item gold_nugget = get("gold_nugget"); - public static final Item soul_wart = get("soul_wart"); - public static final ItemPotion potion = (ItemPotion)get("potion"); - public static final Item glass_bottle = get("glass_bottle"); - public static final Item spider_eye = get("spider_eye"); - public static final Item fermented_spider_eye = get("fermented_spider_eye"); - public static final Item blaze_powder = get("blaze_powder"); - public static final Item magma_cream = get("magma_cream"); - public static final Item brewing_stand = get("brewing_stand"); - public static final Item cauldron = get("cauldron"); - public static final Item charged_orb = get("charged_orb"); - public static final Item speckled_melon = get("speckled_melon"); -// public static final Item spawn_egg = get("spawn_egg"); - public static final Item experience_bottle = get("experience_bottle"); - public static final Item fire_charge = get("fire_charge"); - public static final Item writable_book = get("writable_book"); - public static final Item written_book = get("written_book"); - public static final Item emerald = get("emerald"); -// public static final Item item_frame = get("item_frame"); - public static final Item flower_pot = get("flower_pot"); - public static final Item carrot = get("carrot"); - public static final Item potato = get("potato"); + public static final Item ahrd_fragment = get("ahrd_fragment"); + public static final Item aluminium_ingot = get("aluminium_ingot"); + public static final Item apple = get("apple"); + public static final Item arrow = get("arrow"); public static final Item baked_potato = get("baked_potato"); - public static final Item poisonous_potato = get("poisonous_potato"); - public static final Item golden_carrot = get("golden_carrot"); - public static final Item skull = get("skull"); - public static final Item carrot_on_a_stick = get("carrot_on_a_stick"); - public static final Item charge_crystal = get("charge_crystal"); - public static final Item pumpkin_pie = get("pumpkin_pie"); - public static final Item fireworks = get("fireworks"); - public static final Item firework_charge = get("firework_charge"); - public static final ItemEnchantedBook enchanted_book = (ItemEnchantedBook)get("enchanted_book"); - public static final Item comparator = get("comparator"); + public static final Item banner = get("banner"); + public static final Item beef = get("beef"); + public static final Item birch_door = get("birch_door"); + public static final Item blaze_powder = get("blaze_powder"); + public static final Item blaze_rod = get("blaze_rod"); public static final Item bloodbrick = get("bloodbrick"); - public static final Item quartz = get("quartz"); - public static final Item tnt_minecart = get("tnt_minecart"); - public static final Item hopper_minecart = get("hopper_minecart"); - public static final Item iron_horse_armor = get("iron_horse_armor"); - public static final Item gold_horse_armor = get("gold_horse_armor"); + public static final Item boat = get("boat"); + public static final ItemAmmo bolt = (ItemAmmo)get("bolt"); + public static final Item boltgun = get("boltgun"); + public static final Item bone = get("bone"); + public static final Item book = get("book"); + public static final ItemBow bow = (ItemBow)get("bow"); + public static final Item bowl = get("bowl"); + public static final Item bread = get("bread"); + public static final Item brewing_stand = get("brewing_stand"); + public static final Item brick = get("brick"); + public static final Item bucket = get("bucket"); + public static final Item cake = get("cake"); + public static final Item camera = get("camera"); + public static final Item carrot = get("carrot"); + public static final Item carrot_on_a_stick = get("carrot_on_a_stick"); + public static final Item cauldron = get("cauldron"); + public static final Item chain = get("chain"); + public static final ItemArmor chain_boots = (ItemArmor)get("chain_boots"); + public static final ItemArmor chain_chestplate = (ItemArmor)get("chain_chestplate"); + public static final ItemArmor chain_helmet = (ItemArmor)get("chain_helmet"); + public static final ItemArmor chain_leggings = (ItemArmor)get("chain_leggings"); + public static final Item charge_crystal = get("charge_crystal"); + public static final Item charged_orb = get("charged_orb"); + public static final Item cherry_door = get("cherry_door"); + public static final Item chest_minecart = get("chest_minecart"); + public static final Item chick_magnet = get("chick_magnet"); + public static final Item chicken = get("chicken"); + public static final Item cinnabar = get("cinnabar"); + public static final Item clay_ball = get("clay_ball"); + public static final Item coal = get("coal"); + public static final Item cobalt_ingot = get("cobalt_ingot"); + public static final Item comparator = get("comparator"); + public static final Item cooked_beef = get("cooked_beef"); + public static final Item cooked_chicken = get("cooked_chicken"); + public static final Item cooked_fish = get("cooked_fish"); + public static final Item cooked_porkchop = get("cooked_porkchop"); + public static final Item cookie = get("cookie"); + public static final Item copper_ingot = get("copper_ingot"); + public static final Item dark_oak_door = get("dark_oak_door"); + public static final Item diamond = get("diamond"); + public static final Item diamond_axe = get("diamond_axe"); + public static final ItemArmor diamond_boots = (ItemArmor)get("diamond_boots"); + public static final ItemArmor diamond_chestplate = (ItemArmor)get("diamond_chestplate"); + public static final ItemArmor diamond_helmet = (ItemArmor)get("diamond_helmet"); + public static final Item diamond_hoe = get("diamond_hoe"); public static final Item diamond_horse_armor = get("diamond_horse_armor"); + public static final ItemArmor diamond_leggings = (ItemArmor)get("diamond_leggings"); + public static final Item diamond_pickaxe = get("diamond_pickaxe"); + public static final ItemShears diamond_shears = (ItemShears)get("diamond_shears"); + public static final Item diamond_shovel = get("diamond_shovel"); + public static final Item diamond_sword = get("diamond_sword"); + public static final Item die = get("die"); + public static final Item dye = get("dye"); + public static final Item dynamite = get("dynamite"); + public static final Item egg = get("egg"); + public static final Item emerald = get("emerald"); + public static final ItemEnchantedBook enchanted_book = (ItemEnchantedBook)get("enchanted_book"); + public static final Item experience_bottle = get("experience_bottle"); + public static final Item feather = get("feather"); + public static final Item fermented_spider_eye = get("fermented_spider_eye"); + public static final Item fire_charge = get("fire_charge"); + public static final Item firework_charge = get("firework_charge"); + public static final Item fireworks = get("fireworks"); + public static final Item fish = get("fish"); + public static final ItemFishingRod fishing_rod = (ItemFishingRod)get("fishing_rod"); + public static final Item flint = get("flint"); + public static final Item flint_and_steel = get("flint_and_steel"); + public static final Item flower_pot = get("flower_pot"); + public static final Item ghast_tear = get("ghast_tear"); + public static final Item ghi_fragment = get("ghi_fragment"); + public static final Item glass_bottle = get("glass_bottle"); + public static final Item glowstone_dust = get("glowstone_dust"); + public static final Item gold_axe = get("gold_axe"); + public static final ItemArmor gold_boots = (ItemArmor)get("gold_boots"); + public static final ItemArmor gold_chestplate = (ItemArmor)get("gold_chestplate"); + public static final ItemArmor gold_helmet = (ItemArmor)get("gold_helmet"); + public static final Item gold_hoe = get("gold_hoe"); + public static final Item gold_horse_armor = get("gold_horse_armor"); + public static final Item gold_ingot = get("gold_ingot"); + public static final ItemArmor gold_leggings = (ItemArmor)get("gold_leggings"); + public static final Item gold_nugget = get("gold_nugget"); + public static final Item gold_pickaxe = get("gold_pickaxe"); + public static final Item gold_shovel = get("gold_shovel"); + public static final Item gold_sword = get("gold_sword"); + public static final Item golden_apple = get("golden_apple"); + public static final Item golden_carrot = get("golden_carrot"); + public static final Item gunpowder = get("gunpowder"); + public static final Item hopper_minecart = get("hopper_minecart"); + public static final Item info_wand = get("info_wand"); + public static final Item iron_axe = get("iron_axe"); + public static final ItemArmor iron_boots = (ItemArmor)get("iron_boots"); + public static final ItemArmor iron_chestplate = (ItemArmor)get("iron_chestplate"); + public static final Item iron_door = get("iron_door"); + public static final ItemArmor iron_helmet = (ItemArmor)get("iron_helmet"); + public static final Item iron_hoe = get("iron_hoe"); + public static final Item iron_horse_armor = get("iron_horse_armor"); + public static final Item iron_ingot = get("iron_ingot"); + public static final ItemArmor iron_leggings = (ItemArmor)get("iron_leggings"); + public static final Item iron_pickaxe = get("iron_pickaxe"); + public static final ItemShears iron_shears = (ItemShears)get("iron_shears"); + public static final Item iron_shovel = get("iron_shovel"); + public static final Item iron_sword = get("iron_sword"); + public static final Item jungle_door = get("jungle_door"); + public static final Item key = get("key"); public static final Item lead = get("lead"); + public static final Item lead_ingot = get("lead_ingot"); + public static final Item leather = get("leather"); + public static final ItemArmor leather_boots = (ItemArmor)get("leather_boots"); + public static final ItemArmor leather_chestplate = (ItemArmor)get("leather_chestplate"); + public static final ItemArmor leather_helmet = (ItemArmor)get("leather_helmet"); + public static final ItemArmor leather_leggings = (ItemArmor)get("leather_leggings"); + public static final Item lightning_wand = get("lightning_wand"); + public static final Item magma_cream = get("magma_cream"); + public static final Item magnet = get("magnet"); + public static final Item maple_door = get("maple_door"); + public static final Item melon = get("melon"); + public static final Item melon_stem = get("melon_stem"); + public static final Item milk_bucket = get("milk_bucket"); + public static final Item minecart = get("minecart"); + public static final Item mushroom_stew = get("mushroom_stew"); public static final Item name_tag = get("name_tag"); + public static final Item navigator = get("navigator"); + public static final Item neodymium_ingot = get("neodymium_ingot"); + public static final Item nickel_ingot = get("nickel_ingot"); + public static final Item nieh_fragment = get("nieh_fragment"); + public static final Item oak_door = get("oak_door"); + public static final Item orb = get("orb"); + public static final Item paper = get("paper"); + public static final Item poisonous_potato = get("poisonous_potato"); + public static final Item porkchop = get("porkchop"); + public static final Item portal_frame = get("portal_frame"); + public static final Item potato = get("potato"); + public static final ItemPotion potion = (ItemPotion)get("potion"); + public static final Item pumpkin_pie = get("pumpkin_pie"); + public static final Item pumpkin_stem = get("pumpkin_stem"); + public static final Item quartz = get("quartz"); + public static final Item record_11 = get("record_11"); public static final Item record_13 = get("record_13"); - public static final Item record_cat = get("record_cat"); public static final Item record_blocks = get("record_blocks"); + public static final Item record_cat = get("record_cat"); public static final Item record_chirp = get("record_chirp"); + public static final Item record_delay = get("record_delay"); + public static final Item record_extend = get("record_extend"); public static final Item record_far = get("record_far"); public static final Item record_mall = get("record_mall"); public static final Item record_mellohi = get("record_mellohi"); public static final Item record_stal = get("record_stal"); public static final Item record_strad = get("record_strad"); - public static final Item record_ward = get("record_ward"); - public static final Item record_11 = get("record_11"); public static final Item record_wait = get("record_wait"); - public static final Item record_delay = get("record_delay"); - public static final Item record_extend = get("record_extend"); - public static final Item banner = get("banner"); - - public static final Item portal_frame = get("portal_frame"); - - public static final Item dynamite = get("dynamite"); - public static final Item cherry_door = get("cherry_door"); - public static final Item maple_door = get("maple_door"); - public static final ItemShears diamond_shears = (ItemShears)get("diamond_shears"); - - public static final Item thi_fragment = get("thi_fragment"); - public static final Item ahrd_fragment = get("ahrd_fragment"); - public static final Item ghi_fragment = get("ghi_fragment"); - public static final Item nieh_fragment = get("nieh_fragment"); - -// public static final Item npc_spawner = get("npc_spawner"); - public static final Item wand = get("wand"); -// public static final Item navigator = get("navigator"); - - public static final Item copper_ingot = get("copper_ingot"); - public static final Item tin_ingot = get("tin_ingot"); - public static final Item aluminium_ingot = get("aluminium_ingot"); - public static final Item lead_ingot = get("lead_ingot"); - public static final Item nickel_ingot = get("nickel_ingot"); - public static final Item cobalt_ingot = get("cobalt_ingot"); - public static final Item neodymium_ingot = get("neodymium_ingot"); - - public static final Item die = get("die"); - public static final Item lightning_wand = get("lightning_wand"); - public static final Item info_wand = get("info_wand"); - public static final Item key = get("key"); + public static final Item record_ward = get("record_ward"); + public static final Item redstone = get("redstone"); + public static final Item reeds = get("reeds"); + public static final Item repeater = get("repeater"); + public static final Item rotten_flesh = get("rotten_flesh"); public static final Item ruby = get("ruby"); - public static final Item chick_magnet = get("chick_magnet"); - public static final Item magnet = get("magnet"); - public static final Item cinnabar = get("cinnabar"); - public static final Item chain = get("chain"); - public static final Item camera = get("camera"); - public static final Item boltgun = get("boltgun"); - public static final ItemAmmo bolt = (ItemAmmo)get("bolt"); + public static final Item saddle = get("saddle"); + public static final Item sign = get("sign"); + public static final Item skull = get("skull"); + public static final Item slime_ball = get("slime_ball"); + public static final Item snowball = get("snowball"); + public static final Item soul_wart = get("soul_wart"); + public static final Item speckled_melon = get("speckled_melon"); + public static final Item spider_eye = get("spider_eye"); + public static final Item spruce_door = get("spruce_door"); + public static final Item stick = get("stick"); + public static final Item stone_axe = get("stone_axe"); + public static final Item stone_hoe = get("stone_hoe"); + public static final Item stone_pickaxe = get("stone_pickaxe"); + public static final Item stone_shovel = get("stone_shovel"); + public static final Item stone_sword = get("stone_sword"); + public static final Item string = get("string"); + public static final Item sugar = get("sugar"); + public static final Item thi_fragment = get("thi_fragment"); + public static final Item tin_ingot = get("tin_ingot"); + public static final Item tnt_minecart = get("tnt_minecart"); + public static final Item wand = get("wand"); + public static final Item water_bucket = get("water_bucket"); + public static final Item wheat = get("wheat"); + public static final Item wheats = get("wheats"); + public static final Item wood_axe = get("wood_axe"); + public static final Item wood_hoe = get("wood_hoe"); + public static final Item wood_pickaxe = get("wood_pickaxe"); + public static final Item wood_shovel = get("wood_shovel"); + public static final Item wood_sword = get("wood_sword"); + public static final Item writable_book = get("writable_book"); + public static final Item written_book = get("written_book"); private static Item get(String id) { if(!ItemRegistry.REGISTRY.containsKey(id)) throw new RuntimeException("Item " + id + " does not exist!"); return ItemRegistry.REGISTRY.getObject(id); } - -// static { -// for(Field field : Items.class.getDeclaredFields()) { -// if(Item.class.isAssignableFrom(field.getType())) { -// if(!ItemRegistry.REGISTRY.containsKey(field.getName())) { -// throw new RuntimeException("Item " + field.getName() + " does not exist!"); -// } -// Item item = ItemRegistry.REGISTRY.getObject(field.getName()); -// try { -// field.set(null, item); -// } -// catch(IllegalArgumentException | IllegalAccessException e) { -// throw new RuntimeException(e); -// } -// } -// } -// } } diff --git a/common/src/common/init/TileRegistry.java b/common/src/common/init/TileRegistry.java index 6af28ba..ab2b3ea 100755 --- a/common/src/common/init/TileRegistry.java +++ b/common/src/common/init/TileRegistry.java @@ -23,17 +23,18 @@ import common.tileentity.TileEntitySkull; import common.tileentity.TileEntityTianReactor; public abstract class TileRegistry { - public static final Map> nameToClassMap = Maps.>newHashMap(); - public static final Map, String> classToNameMap = Maps., String>newHashMap(); - public static final Map, Integer> classToIdMap = Maps., Integer>newHashMap(); + public static final Map> NAME_TO_CLASS = Maps.>newHashMap(); + public static final Map, String> CLASS_TO_NAME = Maps., String>newHashMap(); + public static final Map, Integer> CLASS_TO_ID = Maps., Integer>newHashMap(); + private static int nextId; private static void addMapping(Class cl, String id) { - if(nameToClassMap.containsKey(id)) + if(NAME_TO_CLASS.containsKey(id)) throw new IllegalArgumentException("Duplicate id: " + id); - nameToClassMap.put(id, cl); - classToNameMap.put(cl, id); - classToIdMap.put(cl, ++nextId); + NAME_TO_CLASS.put(id, cl); + CLASS_TO_NAME.put(cl, id); + CLASS_TO_ID.put(cl, ++nextId); } static void register() { diff --git a/common/src/common/init/ToolMaterial.java b/common/src/common/init/ToolMaterial.java index 7b3b548..5923f9a 100755 --- a/common/src/common/init/ToolMaterial.java +++ b/common/src/common/init/ToolMaterial.java @@ -5,160 +5,150 @@ import java.util.Set; import common.collect.Sets; import common.item.Item; -public class ToolMaterial -{ - private static final int[] MAX_DAMAGE = new int[] {11, 16, 15, 13}; - private static final float[] RAD_REDUCE = new float[] {1.0f, 1.7f, 1.6f, 1.4f}; - private static final float[] MAG_REDUCE = new float[] {1.0f, 1.2f, 1.1f, 1.0f}; - - private final int harvestLevel; - private final int maxUses; - private final float efficiencyOnProperMaterial; - private final int damageVsEntity; - private final float radiationResistance; - private final float magicResistance; - private final int enchantability; - private final int maxDamageFactor; - private final int[] damageReductionAmountArray; - private final int armorEnchantability; - private final boolean tools; - private final boolean weapons; +public class ToolMaterial { + private static final int[] MAX_DAMAGE = new int[] {11, 16, 15, 13}; + private static final float[] RAD_REDUCE = new float[] {1.0f, 1.7f, 1.6f, 1.4f}; + private static final float[] MAG_REDUCE = new float[] {1.0f, 1.2f, 1.1f, 1.0f}; + + private final int harvestLevel; + private final int durability; + private final float efficiency; + private final int damage; + private final float radiationResistance; + private final float magicResistance; + private final int enchantability; + private final int maxDamageFactor; + private final int[] damageReduction; + private final int armorEnchantability; + private final boolean tools; + private final boolean weapons; private final boolean extras; + private final Set repair = Sets.newHashSet(); + private boolean magnetic; private int defColor = 0xffffffff; - private Set repair = Sets.newHashSet(); - private ToolMaterial(float rad, float mag, int level, int uses, float efficiency, int damage, int ench, boolean tools, - boolean weapons, boolean extras, int auses, int aench, int r1, int r2, int r3, int r4) { - this.harvestLevel = level; - this.maxUses = uses; - this.efficiencyOnProperMaterial = efficiency; - this.damageVsEntity = damage; - this.enchantability = ench; - this.maxDamageFactor = auses; - this.damageReductionAmountArray = new int[] {r1, r2, r3, r4}; - this.armorEnchantability = aench; - this.radiationResistance = rad; - this.magicResistance = mag; - this.tools = tools; - this.weapons = weapons; - this.extras = extras; - } - - protected ToolMaterial(int level) { - this(0.0f, 0.0f, level, 0, 0.0f, 0, 0, false, false, false, 0, 0, 0, 0, 0, 0); - } - - protected ToolMaterial(int level, int uses, float efficiency, int damage, int ench, boolean weapons) { - this(0.0f, 0.0f, level, uses, efficiency, damage, ench, true, weapons, false, 0, ench, 0, 0, 0, 0); - } - - protected ToolMaterial(int level, float rad, float mag, int uses, int damage, int ench, int auses, int aench, int r1, int r2, int r3, int r4) { - this(rad, mag, level, uses, 0.0F, damage, ench, false, true, false, auses, aench, r1, r2, r3, r4); - } - - protected ToolMaterial(int level, float rad, float mag, int auses, int aench, int r1, int r2, int r3, int r4) { - this(rad, mag, 0, 0, 0.0F, 0, 0, false, false, false, auses, aench, r1, r2, r3, r4); - } - - protected ToolMaterial(int level, float rad, float mag, int uses, float efficiency, int damage, int ench, boolean extras, - int auses, int aench, int r1, int r2, int r3, int r4) { - this(rad, mag, level, uses, efficiency, damage, ench, true, true, extras, auses, aench, r1, r2, r3, r4); - } - - protected ToolMaterial setDyeable(int defColor) { - this.defColor = defColor; - return this; - } - - protected ToolMaterial setMagnetic() { - this.magnetic = true; - return this; - } - - protected void addRepairItem(Item item) { - this.repair.add(item); - } - - public boolean hasArmor() { - return this.maxDamageFactor > 0; - } - - public boolean hasTools() { - return this.tools; - } - - public boolean hasWeapons() { - return this.weapons; - } - - public boolean hasExtras() { - return this.extras; - } + private ToolMaterial(float rad, float mag, int level, int uses, float efficiency, int damage, int ench, boolean tools, boolean weapons, + boolean extras, int auses, int aench, int r1, int r2, int r3, int r4) { + this.harvestLevel = level; + this.durability = uses; + this.efficiency = efficiency; + this.damage = damage; + this.enchantability = ench; + this.maxDamageFactor = auses; + this.damageReduction = new int[] {r1, r2, r3, r4}; + this.armorEnchantability = aench; + this.radiationResistance = rad; + this.magicResistance = mag; + this.tools = tools; + this.weapons = weapons; + this.extras = extras; + } - public int getMaxUses() - { - return this.maxUses; - } + protected ToolMaterial(int level) { + this(0.0f, 0.0f, level, 0, 0.0f, 0, 0, false, false, false, 0, 0, 0, 0, 0, 0); + } - public float getEfficiencyOnProperMaterial() - { - return this.efficiencyOnProperMaterial; - } + protected ToolMaterial(int level, int uses, float efficiency, int damage, int ench, boolean weapons) { + this(0.0f, 0.0f, level, uses, efficiency, damage, ench, true, weapons, false, 0, ench, 0, 0, 0, 0); + } - public int getDamageVsEntity() - { - return this.damageVsEntity; - } + protected ToolMaterial(int level, float rad, float mag, int uses, int damage, int ench, int auses, int aench, int r1, int r2, int r3, int r4) { + this(rad, mag, level, uses, 0.0F, damage, ench, false, true, false, auses, aench, r1, r2, r3, r4); + } - public int getHarvestLevel() - { - return this.harvestLevel; - } + protected ToolMaterial(int level, float rad, float mag, int auses, int aench, int r1, int r2, int r3, int r4) { + this(rad, mag, 0, 0, 0.0F, 0, 0, false, false, false, auses, aench, r1, r2, r3, r4); + } - public int getEnchantability() - { - return this.enchantability; - } + protected ToolMaterial(int level, float rad, float mag, int uses, float efficiency, int damage, int ench, boolean extras, int auses, int aench, + int r1, int r2, int r3, int r4) { + this(rad, mag, level, uses, efficiency, damage, ench, true, true, extras, auses, aench, r1, r2, r3, r4); + } - public boolean isRepairItem(Item item) { - return this.repair.contains(item); - } + protected ToolMaterial setDyeable(int defColor) { + this.defColor = defColor; + return this; + } - public int getDurability(int armorType) - { - return MAX_DAMAGE[armorType] * this.maxDamageFactor; - } + protected ToolMaterial setMagnetic() { + this.magnetic = true; + return this; + } - public float getRadiationReduction(int armorType) - { - return RAD_REDUCE[armorType] * this.radiationResistance; - } + protected void addRepairItem(Item item) { + this.repair.add(item); + } - public float getMagicReduction(int armorType) - { - return MAG_REDUCE[armorType] * this.magicResistance; - } + public boolean hasArmor() { + return this.maxDamageFactor > 0; + } - public int getDamageReductionAmount(int armorType) - { - return this.damageReductionAmountArray[armorType]; - } + public boolean hasTools() { + return this.tools; + } - public int getArmorEnchantability() - { - return this.armorEnchantability; - } - - public boolean canBeDyed() { - return this.defColor != 0xffffffff; - } - - public int getDefaultColor() { - return this.defColor; - } - - public boolean isMagnetic() { - return this.magnetic; - } + public boolean hasWeapons() { + return this.weapons; + } + + public boolean hasExtras() { + return this.extras; + } + + public int getDurability() { + return this.durability; + } + + public float getEfficiency() { + return this.efficiency; + } + + public int getDamage() { + return this.damage; + } + + public int getHarvestLevel() { + return this.harvestLevel; + } + + public int getEnchantability() { + return this.enchantability; + } + + public boolean isRepairItem(Item item) { + return this.repair.contains(item); + } + + public int getDurability(int armorType) { + return MAX_DAMAGE[armorType] * this.maxDamageFactor; + } + + public float getRadiationReduction(int armorType) { + return RAD_REDUCE[armorType] * this.radiationResistance; + } + + public float getMagicReduction(int armorType) { + return MAG_REDUCE[armorType] * this.magicResistance; + } + + public int getDamageReduction(int armorType) { + return this.damageReduction[armorType]; + } + + public int getArmorEnchantability() { + return this.armorEnchantability; + } + + public boolean canBeDyed() { + return this.defColor != 0xffffffff; + } + + public int getDefaultColor() { + return this.defColor; + } + + public boolean isMagnetic() { + return this.magnetic; + } } \ No newline at end of file diff --git a/common/src/common/item/CheatTab.java b/common/src/common/item/CheatTab.java index 3e4ea89..83729d0 100755 --- a/common/src/common/item/CheatTab.java +++ b/common/src/common/item/CheatTab.java @@ -71,6 +71,13 @@ public enum CheatTab return Items.flint_and_steel; } }, + tabLiquids("Flüssigkeiten") + { + protected Item getTabIconItem() + { + return Items.water_bucket; + } + }, tabCombat("Kampf") { protected Item getTabIconItem() diff --git a/common/src/common/item/ItemArmor.java b/common/src/common/item/ItemArmor.java index 4fc425c..09e371e 100755 --- a/common/src/common/item/ItemArmor.java +++ b/common/src/common/item/ItemArmor.java @@ -92,7 +92,7 @@ public class ItemArmor extends Item this.texture = texture; this.armorType = armorType; // this.renderIndex = renderIndex; - this.damageReduceAmount = material.getDamageReductionAmount(armorType); + this.damageReduceAmount = material.getDamageReduction(armorType); this.setMaxDamage(material.getDurability(armorType)); this.maxStackSize = 1; this.setTab(CheatTab.tabCombat); diff --git a/common/src/common/item/ItemBucket.java b/common/src/common/item/ItemBucket.java index 2cd1821..94cb7c2 100755 --- a/common/src/common/item/ItemBucket.java +++ b/common/src/common/item/ItemBucket.java @@ -104,7 +104,7 @@ public class ItemBucket extends Item this.maxStackSize = liquid == null ? 16 : 1; this.liquid = liquid; this.recursive = recursive; - this.setTab(CheatTab.tabTools); + this.setTab(liquid == null ? CheatTab.tabTools : CheatTab.tabLiquids); // if(!empty) // this.setHasSubtypes(true); } diff --git a/common/src/common/item/ItemHoe.java b/common/src/common/item/ItemHoe.java index d6e6678..1d5294c 100755 --- a/common/src/common/item/ItemHoe.java +++ b/common/src/common/item/ItemHoe.java @@ -20,7 +20,7 @@ public class ItemHoe extends Item { this.theToolMaterial = material; this.maxStackSize = 1; - this.setMaxDamage(material.getMaxUses()); + this.setMaxDamage(material.getDurability()); this.setTab(CheatTab.tabTools); } diff --git a/common/src/common/item/ItemShears.java b/common/src/common/item/ItemShears.java index 515d799..81c0b0a 100755 --- a/common/src/common/item/ItemShears.java +++ b/common/src/common/item/ItemShears.java @@ -15,7 +15,7 @@ public class ItemShears extends Item public ItemShears(ToolMaterial material) { this.setMaxStackSize(1); - this.setMaxDamage(material.getMaxUses() - 12); + this.setMaxDamage(material.getDurability() - 12); this.setTab(CheatTab.tabTools); this.material = material; } @@ -40,7 +40,7 @@ public class ItemShears extends Item public float getStrVsBlock(ItemStack stack, Block state) { - return state.getShearsEfficiency() <= 0 ? 1.0F : (((float)state.getShearsEfficiency()) * (this.material.getEfficiencyOnProperMaterial() - 1.0F)); + return state.getShearsEfficiency() <= 0 ? 1.0F : (((float)state.getShearsEfficiency()) * (this.material.getEfficiency() - 1.0F)); // state != Blocks.web && state.getMaterial() != Material.leaves ? (state == Blocks.wool ? 5.0F : super.getStrVsBlock(stack, state)) : 15.0F; } diff --git a/common/src/common/item/ItemSword.java b/common/src/common/item/ItemSword.java index 0c616a2..67840f0 100755 --- a/common/src/common/item/ItemSword.java +++ b/common/src/common/item/ItemSword.java @@ -26,9 +26,9 @@ public class ItemSword extends Item { this.material = material; this.maxStackSize = 1; - this.setMaxDamage(material.getMaxUses()); + this.setMaxDamage(material.getDurability()); this.setTab(CheatTab.tabCombat); - this.attackDamage = 4 + material.getDamageVsEntity(); + this.attackDamage = 4 + material.getDamage(); } /** @@ -36,7 +36,7 @@ public class ItemSword extends Item */ public int getDamageVsEntity() { - return this.material.getDamageVsEntity(); + return this.material.getDamage(); } public ToolMaterial getToolMaterial() diff --git a/common/src/common/item/ItemTool.java b/common/src/common/item/ItemTool.java index 2970a58..2e2f8b6 100755 --- a/common/src/common/item/ItemTool.java +++ b/common/src/common/item/ItemTool.java @@ -30,9 +30,9 @@ public abstract class ItemTool extends Item this.toolMaterial = material; // this.effectiveBlocks = effectiveBlocks; this.maxStackSize = 1; - this.setMaxDamage(material.getMaxUses()); - this.efficiencyOnProperMaterial = material.getEfficiencyOnProperMaterial(); - this.damageVsEntity = attackDamage + material.getDamageVsEntity(); + this.setMaxDamage(material.getDurability()); + this.efficiencyOnProperMaterial = material.getEfficiency(); + this.damageVsEntity = attackDamage + material.getDamage(); this.setTab(CheatTab.tabTools); } diff --git a/common/src/common/packet/S35PacketUpdateTileEntity.java b/common/src/common/packet/S35PacketUpdateTileEntity.java index c44844c..dc1f0c3 100755 --- a/common/src/common/packet/S35PacketUpdateTileEntity.java +++ b/common/src/common/packet/S35PacketUpdateTileEntity.java @@ -23,7 +23,7 @@ public class S35PacketUpdateTileEntity implements Packet public S35PacketUpdateTileEntity(TileEntity tile) { this.blockPos = tile.getPos(); - this.type = TileRegistry.classToIdMap.get(tile.getClass()); + this.type = TileRegistry.CLASS_TO_ID.get(tile.getClass()); tile.writeToNBT(this.nbt = new NBTTagCompound()); } @@ -62,7 +62,7 @@ public class S35PacketUpdateTileEntity implements Packet public boolean isTileEntityType(TileEntity tile) { - return this.type == TileRegistry.classToIdMap.get(tile.getClass()); + return this.type == TileRegistry.CLASS_TO_ID.get(tile.getClass()); } public NBTTagCompound getNbtCompound() diff --git a/common/src/common/tileentity/TileEntity.java b/common/src/common/tileentity/TileEntity.java index 45c47a9..31da294 100755 --- a/common/src/common/tileentity/TileEntity.java +++ b/common/src/common/tileentity/TileEntity.java @@ -59,7 +59,7 @@ public abstract class TileEntity public void writeToNBT(NBTTagCompound compound) { - String s = (String)TileRegistry.classToNameMap.get(this.getClass()); + String s = (String)TileRegistry.CLASS_TO_NAME.get(this.getClass()); if (s == null) { @@ -83,7 +83,7 @@ public abstract class TileEntity try { - Class oclass = (Class)TileRegistry.nameToClassMap.get(nbt.getString("id")); + Class oclass = (Class)TileRegistry.NAME_TO_CLASS.get(nbt.getString("id")); if (oclass != null) { diff --git a/server/src/server/world/Converter.java b/server/src/server/world/Converter.java index 34001e7..7564a9e 100644 --- a/server/src/server/world/Converter.java +++ b/server/src/server/world/Converter.java @@ -212,7 +212,7 @@ public abstract class Converter { } private static void mapTile(Class clazz, String ... names) { - String name = TileRegistry.classToNameMap.get(clazz); + String name = TileRegistry.CLASS_TO_NAME.get(clazz); for(String oldname : names) { TILE_MAP.put(oldname, name); } From e4034898b95bc01260118e152d567cb9c0c5447a Mon Sep 17 00:00:00 2001 From: Sen Date: Wed, 14 May 2025 16:01:08 +0200 Subject: [PATCH 032/200] remove server ipc and preloading --- common/src/common/init/Config.java | 2 - server/src/server/Server.java | 99 +++------------------------ server/src/server/network/Player.java | 2 - 3 files changed, 11 insertions(+), 92 deletions(-) diff --git a/common/src/common/init/Config.java b/common/src/common/init/Config.java index 483ee54..652f2f7 100755 --- a/common/src/common/init/Config.java +++ b/common/src/common/init/Config.java @@ -335,8 +335,6 @@ public abstract class Config { public static boolean register = true; @Var(name = "authentication") public static boolean auth = true; - @Var(name = "preload_chunks") - public static boolean preload = true; @Var(name = "signEditing") public static boolean editSigns = true; diff --git a/server/src/server/Server.java b/server/src/server/Server.java index 188151c..ae4ec08 100755 --- a/server/src/server/Server.java +++ b/server/src/server/Server.java @@ -119,7 +119,6 @@ public final class Server implements IThreadListener { private final Map warps = Maps.newTreeMap(); private final CommandEnvironment scriptEnv = new CommandEnvironment(this); private final boolean debug; - private final boolean ipcpipe; private WorldServer space; private ChannelFuture endpoint; @@ -153,9 +152,8 @@ public final class Server implements IThreadListener { RotationRegistry.register(); ReorderRegistry.register(); boolean debug = System.getProperty("server.debug", null) != null; - boolean ipc = System.getProperty("server.pipe", null) != null; int port = Integer.parseInt(System.getProperty("server.port", "" + Config.PORT)); - final Server server = new Server(debug, ipc); + final Server server = new Server(debug); Registry.addShutdownHook(new Runnable() { public void run() { server.stopServer(); @@ -223,9 +221,8 @@ public final class Server implements IThreadListener { return World.START_TIME; } - private Server(boolean debug, boolean ipc) { + private Server(boolean debug) { this.debug = debug; - this.ipcpipe = ipc; Config.setCallback(new Runnable() { public void run() { for(WorldServer world : Server.this.getWorlds()) { @@ -300,27 +297,14 @@ public final class Server implements IThreadListener { private void saveAllWorlds(boolean message) { if(this.debug) return; - if(message) { - this.startProgress(true, this.worlds.size()); - } - int done = 0; + if(message) + Log.JNI.info("Speichere Welt"); this.saveWorldInfo(); for(WorldServer world : this.worlds) { - if(message) { - this.setProgress(done); - } - ++done; world.saveAllChunks(); } - this.setProgress(-1); } - private void startProgress(boolean save, int amount) { - this.setTotal(amount); - this.setProgress(0); - Log.JNI.info((save ? "Speichere" : "Generiere und lade") + " Welt"); - } - public void unloadWorld(WorldServer world) { if(world != this.space) this.unloadWorld(world.dimension); @@ -425,7 +409,6 @@ public final class Server implements IThreadListener { Log.JNI.info("Starte " + Config.NAME + " Server Version " + Config.VERSION); if(!this.debug) { Converter.convert(); - this.setMessage("Welt wird erstellt und geladen"); long wtime = loadServerConfig(); // if(dtime == -1L) // { // dtime = World.START_TIME; @@ -535,38 +518,26 @@ public final class Server implements IThreadListener { this.lastPoll = this.currentTime; this.ticksDone = 0L; } - if(!this.started) { - this.started = true; - this.sendPipeIPC("running", true); - } + this.started = true; } try { this.stopServer(); this.stopped = true; - this.sendPipeIPC("running", false); } catch(Throwable e) { Log.JNI.error(e, "Fehler beim Beenden des Servers"); } finally { this.stopped = true; - this.sendPipeIPC("running", false); Log.JNI.info("Server wurde beendet"); } } - public void preload(WorldServer world, int bx, int bz, Player callback) { + public void preload(WorldServer world, int bx, int bz) { int done = 0; int total = Config.distance * 2 + 1; total *= total; - if(callback != null) { - callback.displayLoading("Lade Welt ..."); - callback.sendTask("Landschaft wird generiert", total); - } - else { - this.setMessage("Landschaft wird generiert"); - this.startProgress(false, total); - } + Log.JNI.info("Generiere und lade Welt"); // WorldServer world = this.getWorld(Config.spawnDim); // world = world == null ? this.space : world; bx = bx >> 4; @@ -575,26 +546,14 @@ public final class Server implements IThreadListener { for(int x = -Config.distance; x <= Config.distance; x++) { for(int z = -Config.distance; z <= Config.distance; z++) { long time = System.currentTimeMillis(); - if(time - last >= 10L) { - if(callback != null) { - callback.sendProgress(done); - } - else { - this.setProgress(done); - if(time - last > 1000L) { - Log.JNI.info("Bereite Spawnbereich vor" + ": " + (done * 100 / total) + "%"); - last = time; - } - } + if(time - last > 1000L) { + Log.JNI.info("Bereite Spawnbereich vor" + ": " + (done * 100 / total) + "%"); + last = time; } ++done; world.loadChunk(bx + x, bz + z); } } - if(callback != null) - callback.sendProgress(-1); - else - this.setProgress(-1); } // public void resetProgress() { @@ -680,7 +639,6 @@ public final class Server implements IThreadListener { if(this.perfTimer == 100) { this.perfTimer = 0; } - this.sendPipeIPC("tick", this.getLastTick()); } public WorldServer getSpace() { @@ -759,26 +717,6 @@ public final class Server implements IThreadListener { public Player getPlayer(String user) { return this.usermap.get(user); } - - private void setMessage(String message) { - this.sendPipeIPC("message", message); - } - - private void setProgress(int progress) { - this.sendPipeIPC("progress", progress); - } - - private void setTotal(int total) { - this.sendPipeIPC("total", total); - } - - public void setVar(String cv, String value) { - this.schedule(new Runnable() { - public void run() { - Config.set(cv, value, true); - } - }); - } private ListenableFuture callFromMainThread(Callable callable) { if(!this.isMainThread() && !this.stopped) { @@ -893,9 +831,6 @@ public final class Server implements IThreadListener { + player.getId() + " auf Level " + world.dimension.getDimensionId() + ": " + String.format("%.2f %.2f %.2f", player.posX, player.posY, player.posZ) + " verbunden (" + (tag == null ? "Charakter-Editor" : "'" + player.getCommandName() + "'") + ")"); - if(Config.preload && /* conn.isLocal() && */ this.players.size() == 1) - this.preload(world, (int)player.posX, (int)player.posZ, conn); - conn.sendPacket(new SPacketJoinGame(player.getId(), world.dimension, EntityRegistry.getEntityID(player), tag == null)); conn.sendPacket(new SPacketHeldItemChange(player.inventory.currentItem)); conn.sendPacket(new SPacketWorld(WorldServer.clampGravity(), @@ -1276,8 +1211,6 @@ public final class Server implements IThreadListener { private void stopServer() { if(!this.stopped) { - this.setProgress(-1); - this.setMessage("Stoppe server"); Log.JNI.info("Beende Server"); this.terminateEndpoint(this.endMessage); if(this.started) { @@ -1338,17 +1271,7 @@ public final class Server implements IThreadListener { "Geladen: " + this.getWorlds().size() + " Welten, " + WorldServer.getLoadedInfo(this); } - private void sendPipeIPC(String key, Object value) { - if(this.ipcpipe) { - System.out.println("#" + key + (value == null ? "" : " " + String.valueOf(value))); - System.out.flush(); - } - } - public void logConsole(String message) { - if(this.ipcpipe) - this.sendPipeIPC("console", message); - else - Log.CONSOLE.info(message); + Log.CONSOLE.info(message); } } diff --git a/server/src/server/network/Player.java b/server/src/server/network/Player.java index 0ef2858..9db76b8 100755 --- a/server/src/server/network/Player.java +++ b/server/src/server/network/Player.java @@ -2463,8 +2463,6 @@ public class Player extends NetHandler implements ICrafting, Executor, IPlayer world.dimension.getDimensionId()); this.entity.setOrigin(origin); Position pos = this.server.getRandomSpawnPosition(origin); - if(Config.preload && /* this.local && */ this.server.getPlayers().size() == 1) - this.server.preload(world, (int)pos.x, (int)pos.z, this); this.entity.teleport(pos); this.sendPacket(new SPacketCharacterList(this.selected, this.selected, new PlayerCharacter(this.entity.getCustomNameTag(), this.entity.getDescription(), this.entity.getAlignment(), this.entity.worldObj.dimension.getFormattedName(false), this.entity.getPosition(), EntityRegistry.getEntityName(EntityRegistry.getEntityString(this.entity)), this.entity.experienceLevel))); // if(this.local) From 9077451c088fcc476459b6df15140cf6131d61db Mon Sep 17 00:00:00 2001 From: Sen Date: Thu, 15 May 2025 21:25:28 +0200 Subject: [PATCH 033/200] add registration via command, password fields --- .../src/client/gui/element/PasswordBox.java | 27 +++++++ client/src/client/gui/ingame/GuiForm.java | 9 ++- server/src/server/Server.java | 30 +++++++- server/src/server/command/Command.java | 5 ++ .../server/command/CommandEnvironment.java | 6 ++ .../command/commands/CommandPasswd.java | 17 +++-- .../command/commands/CommandPlayers.java | 32 +++++++++ .../command/commands/CommandRegister.java | 72 +++++++++++++++++++ .../server/command/commands/CommandSave.java | 35 +++++++++ server/src/server/network/Player.java | 2 +- server/src/server/util/Form.java | 12 +++- 11 files changed, 232 insertions(+), 15 deletions(-) create mode 100644 client/src/client/gui/element/PasswordBox.java create mode 100644 server/src/server/command/commands/CommandPlayers.java create mode 100644 server/src/server/command/commands/CommandRegister.java create mode 100644 server/src/server/command/commands/CommandSave.java diff --git a/client/src/client/gui/element/PasswordBox.java b/client/src/client/gui/element/PasswordBox.java new file mode 100644 index 0000000..de104bb --- /dev/null +++ b/client/src/client/gui/element/PasswordBox.java @@ -0,0 +1,27 @@ +package client.gui.element; + +import client.gui.Font; +import client.renderer.Drawing; +import common.util.Util; + +public class PasswordBox extends Textbox { + public PasswordBox(int x, int y, int w, int h, int cap, Callback callback, String text) { + super(x, y, w, h, cap, true, callback, text); + } + + protected void drawForeground(int x1, int y1, int x2, int y2) { + Drawing.txt_draw(x1 + this.text_x, y1 + this.text_y, + x1 + this.text_x, y1 + this.text_y, + Integer.MAX_VALUE, Integer.MAX_VALUE, this.enabled ? this.gm.style.text_field : Util.mulColor(this.gm.style.text_field, 0.5f), this.text.isEmpty() ? "" : "****"); + } + + public void drawOverlay() { + if(Util.ftime() % 1.0f < 0.5f) { + int x1 = this.pos_x + this.margin_x1; + int y1 = this.pos_y + this.margin_y1; + int x2 = this.size_x - (this.margin_x1 + this.margin_x2); + int y2 = this.size_y - (this.margin_y1 + this.margin_y2); + Drawing.drawRect(x1, y1 + (y2 - Font.YGLYPH) / 2, 1, Font.YGLYPH, 0xff000000 | (~Util.mixColor(this.gm.style.field_top, this.gm.style.field_btm))); + } + } +} diff --git a/client/src/client/gui/ingame/GuiForm.java b/client/src/client/gui/ingame/GuiForm.java index 33dd965..dc5cce9 100644 --- a/client/src/client/gui/ingame/GuiForm.java +++ b/client/src/client/gui/ingame/GuiForm.java @@ -6,6 +6,7 @@ import client.gui.element.ActButton.Mode; import client.gui.element.Element; import client.gui.element.Label; import client.gui.element.NavButton; +import client.gui.element.PasswordBox; import client.gui.element.Switch; import client.gui.element.Textbox; import client.gui.element.Textbox.Action; @@ -56,12 +57,14 @@ public class GuiForm extends Gui implements ActButton.Callback { } else { this.labels[z] = this.add(new Label(0, 50 * z - 20, 300, 20, name, true)); - this.inputs[z] = this.add(new Textbox(0, 50 * z, 300, 24, Math.min(param & 0xffff, 256), true, new Textbox.Callback() { + Textbox.Callback callback = new Textbox.Callback() { public void use(Textbox elem, Action value) { if(value == Action.FOCUS) GuiForm.this.labels[index].setText(name); } - }, (String)obj)); + }; + this.inputs[z] = this.add((param & 0x80000000) != 0 ? new PasswordBox(0, 50 * z, 300, 24, Math.min(param & 0xffff, 256), callback, (String)obj) : + new Textbox(0, 50 * z, 300, 24, Math.min(param & 0xffff, 256), true, callback, (String)obj)); } } this.add(new NavButton(0, 50 * (this.inputs.length + 1), 148, 24, null, "Abbrechen")); @@ -98,7 +101,7 @@ public class GuiForm extends Gui implements ActButton.Callback { public void use(ActButton elem, Mode action) { for(int z = 0; z < this.inputs.length; z++) { if(this.inputs[z] instanceof Textbox) { - int min = this.inputData[z].third >> 16; + int min = (this.inputData[z].third & 0x7fffffff) >> 16; String text = this.inputs[z].getText(); if(text.length() < min) { if(!GuiForm.this.labels[z].getText().startsWith("" + TextColor.RED)) diff --git a/server/src/server/Server.java b/server/src/server/Server.java index ae4ec08..8b13220 100755 --- a/server/src/server/Server.java +++ b/server/src/server/Server.java @@ -267,7 +267,7 @@ public final class Server implements IThreadListener { } } - public Position getOfflinePosition(String user) { + public NBTTagCompound loadPlayerData(String user) { if(this.debug || !IPlayer.isValidUser(user)) return null; NBTTagCompound tag = null; @@ -281,6 +281,28 @@ public final class Server implements IThreadListener { catch(Exception e) { Log.JNI.error(e, "Konnte Spielerdaten für " + user + " (offline) nicht laden"); } + return tag; + } + + public void writePlayerData(String user, NBTTagCompound tag) { + if(this.debug || !IPlayer.isValidUser(user)) + return; + try { + File tmp = new File(new File("players"), user + ".nbt.tmp"); + File dat = new File(new File("players"), user + ".nbt"); + NBTLoader.writeGZip(tag, tmp); + if(dat.exists()) { + dat.delete(); + } + tmp.renameTo(dat); + } + catch(Exception e) { + Log.JNI.error(e, "Konnte Spielerdaten für " + user + " (offline) nicht speichern"); + } + } + + public Position getOfflinePosition(String user) { + NBTTagCompound tag = this.loadPlayerData(user); if(tag == null) return null; NBTTagList pos = tag.getTagList("Pos", 6); @@ -294,7 +316,7 @@ public final class Server implements IThreadListener { return new Position(posX, posY, posZ, rotYaw, rotPitch, dimension); } - private void saveAllWorlds(boolean message) { + public void saveAllWorlds(boolean message) { if(this.debug) return; if(message) @@ -672,6 +694,10 @@ public final class Server implements IThreadListener { return this.worlds; } + public void resetSaveTimer() { + this.saveTimer = 0; + } + public long[] getTickTimes() { return this.tickTimes; } diff --git a/server/src/server/command/Command.java b/server/src/server/command/Command.java index 637c07d..e58b0d7 100644 --- a/server/src/server/command/Command.java +++ b/server/src/server/command/Command.java @@ -7,6 +7,7 @@ import java.util.Map; import common.collect.Lists; import common.collect.Maps; +import common.util.CharValidator; import common.util.Vec3; import common.world.World; import server.command.DoubleParser.DefType; @@ -200,6 +201,10 @@ public abstract class Command implements Executable { protected Command addString(String name, String def, boolean allowEmpty, StringCompleter completer) { return this.addParameter(new StringParser(name, def, allowEmpty, null, null, null, completer)); } + + protected Command addString(String name, boolean allowEmpty, Integer min, Integer max, CharValidator validator) { + return this.addParameter(new StringParser(name, null, allowEmpty, min, max, validator)); + } public Map getParameters() { return this.parameters; diff --git a/server/src/server/command/CommandEnvironment.java b/server/src/server/command/CommandEnvironment.java index a3a6e6a..bb85367 100644 --- a/server/src/server/command/CommandEnvironment.java +++ b/server/src/server/command/CommandEnvironment.java @@ -20,10 +20,13 @@ import server.command.commands.CommandMessage; import server.command.commands.CommandMilk; import server.command.commands.CommandOfflinetp; import server.command.commands.CommandPasswd; +import server.command.commands.CommandPlayers; import server.command.commands.CommandPotion; import server.command.commands.CommandRebind; +import server.command.commands.CommandRegister; import server.command.commands.CommandRemove; import server.command.commands.CommandRevoke; +import server.command.commands.CommandSave; import server.command.commands.CommandShutdown; import server.command.commands.CommandSpawn; import server.command.commands.CommandTele; @@ -275,6 +278,9 @@ public class CommandEnvironment { this.registerExecutable(new CommandShutdown()); this.registerExecutable(new CommandRebind()); this.registerExecutable(new CommandPasswd()); + this.registerExecutable(new CommandPlayers()); + this.registerExecutable(new CommandSave()); + this.registerExecutable(new CommandRegister()); this.registerExecutable(new CommandHelp(this)); } diff --git a/server/src/server/command/commands/CommandPasswd.java b/server/src/server/command/commands/CommandPasswd.java index e67ee5b..7cf15ad 100644 --- a/server/src/server/command/commands/CommandPasswd.java +++ b/server/src/server/command/commands/CommandPasswd.java @@ -31,9 +31,9 @@ public class CommandPasswd extends Command { private Field confirmField; protected void init() { - this.checkField = player != exec ? null : this.addField("Aktuelles Passwort", 0, IPlayer.MAX_PASS_LENGTH, ""); - this.passwordField = this.addField("Neues Passwort", Config.minPassLength, IPlayer.MAX_PASS_LENGTH, ""); - this.confirmField = this.addField("Passwort bestätigen", Config.minPassLength, IPlayer.MAX_PASS_LENGTH, ""); + this.checkField = player != exec ? null : this.addPassword("Aktuelles Passwort", 0, IPlayer.MAX_PASS_LENGTH, ""); + this.passwordField = this.addPassword("Neues Passwort", Config.minPassLength, IPlayer.MAX_PASS_LENGTH, ""); + this.confirmField = this.addPassword("Passwort bestätigen", Config.minPassLength, IPlayer.MAX_PASS_LENGTH, ""); } public String getTitle() { @@ -41,7 +41,12 @@ public class CommandPasswd extends Command { } protected void accept() { - if(this.checkField != null && !this.checkField.get().equals(player.getPassword())) { + Player plr = env.getServer().getPlayer(player.getUser()); + if(!((Player)exec).isAdmin() || plr == null || (plr.isAdmin() && plr != exec)) { + exec.logConsole(TextColor.DRED + "Ein Fehler ist aufgetreten"); + return; + } + if(this.checkField != null && !this.checkField.get().equals(plr.getPassword())) { exec.logConsole(TextColor.RED + "Falsches Passwort eingegeben"); return; } @@ -49,8 +54,8 @@ public class CommandPasswd extends Command { exec.logConsole(TextColor.RED + "Passwörter stimmen nicht überein"); return; } - player.setPassword(this.passwordField.get()); - exec.logConsole(TextColor.GREEN + "Passwort" + (player != exec ? " für %s" : "") + " gesetzt", player.getUser()); + plr.setPassword(this.passwordField.get()); + exec.logConsole(TextColor.GREEN + "Passwort" + (plr != exec ? " für %s" : "") + " gesetzt", plr.getUser()); } }); } diff --git a/server/src/server/command/commands/CommandPlayers.java b/server/src/server/command/commands/CommandPlayers.java new file mode 100644 index 0000000..b665700 --- /dev/null +++ b/server/src/server/command/commands/CommandPlayers.java @@ -0,0 +1,32 @@ +package server.command.commands; + +import java.util.List; + +import common.color.TextColor; +import common.entity.npc.EntityNPC; +import common.util.ExtMath; +import server.command.Command; +import server.command.CommandEnvironment; +import server.command.Executor; +import server.network.Player; + +public class CommandPlayers extends Command { + public CommandPlayers() { + super("players"); + + this.addFlag("coords", 'c'); + } + + public void exec(CommandEnvironment env, Executor exec, boolean coords) { + List players = env.getServer().getPlayers(); + if(players.isEmpty()) { + exec.logConsole(TextColor.DGRAY + "Es sind keine Spieler online"); + return; + } + exec.logConsole(TextColor.GREEN + "Es " + (players.size() == 1 ? "ist" : "sind") + " " + TextColor.YELLOW + "%d" + TextColor.GREEN + " Spieler online", players.size()); + for(Player player : players) { + EntityNPC entity = player.getPresentEntity(); + exec.logConsole("%s%s" + TextColor.GRAY + ": '%s" + TextColor.GRAY + "'" + (coords ? " [" + TextColor.ORANGE + "%s @ %d, %d, %d" + TextColor.GRAY + "]" : ""), player.isAdmin() ? TextColor.RED : TextColor.NEON, player.getUser(), entity == null ? TextColor.DGRAY + "<->" : TextColor.ACID + entity.getCommandName(), entity == null ? null : entity.worldObj.dimension.getFormattedName(false), entity == null ? null : ExtMath.floord(entity.posX), entity == null ? null : ExtMath.floord(entity.posY), entity == null ? null : ExtMath.floord(entity.posZ)); + } + } +} diff --git a/server/src/server/command/commands/CommandRegister.java b/server/src/server/command/commands/CommandRegister.java new file mode 100644 index 0000000..c8a48e4 --- /dev/null +++ b/server/src/server/command/commands/CommandRegister.java @@ -0,0 +1,72 @@ +package server.command.commands; + +import common.color.TextColor; +import common.init.Config; +import common.nbt.NBTTagCompound; +import common.network.IPlayer; +import server.command.Command; +import server.command.CommandEnvironment; +import server.command.Executor; +import server.command.RunException; +import server.network.Player; +import server.util.Form; + +public class CommandRegister extends Command { + public CommandRegister() { + super("register"); + + this.addString("username", false, null, IPlayer.MAX_USER_LENGTH, IPlayer.VALID_USER); + this.setParamsOptional(); + this.addString("password", false); + this.addFlag("admin", 'a'); + } + + public void exec(CommandEnvironment env, Executor exec, String username, String password, boolean admin) { + Player player = env.getServer().getPlayer(username); + if(player != null) + throw new RunException("Ein Spieler mit diesem Nutzernamen ist bereits online"); + NBTTagCompound tag = env.getServer().loadPlayerData(username); + if(tag != null) + throw new RunException("Ein Spieler mit diesem Nutzernamen ist bereits registriert"); + if(exec.isPlayer()) { + if(password != null) + throw new RunException("Bei Verwendung als Spieler darf kein Passwort angegeben werden"); + ((Player)exec).displayForm(new Form() { + private Field passwordField; + private Field confirmField; + + protected void init() { + this.passwordField = this.addPassword("Passwort", Config.minPassLength, IPlayer.MAX_PASS_LENGTH, ""); + this.confirmField = this.addPassword("Passwort bestätigen", Config.minPassLength, IPlayer.MAX_PASS_LENGTH, ""); + } + + public String getTitle() { + return "Spieler " + username + " registrieren"; + } + + protected void accept() { + if(!((Player)exec).isAdmin() || env.getServer().getPlayer(username) != null || env.getServer().loadPlayerData(username) != null) { + exec.logConsole(TextColor.DRED + "Ein Fehler ist aufgetreten"); + return; + } + if(!this.passwordField.get().equals(this.confirmField.get())) { + exec.logConsole(TextColor.RED + "Passwörter stimmen nicht überein"); + return; + } + NBTTagCompound user = new NBTTagCompound(); + user.setString("password", this.passwordField.get()); + env.getServer().writePlayerData(username, user); + exec.logConsole(TextColor.GREEN + "Spieler %s registriert", username); + } + }); + } + else if(exec.isConsole()) { + if(password == null) + throw new RunException("Bei Verwendung in der Konsole muss ein Passwort angegeben werden"); + NBTTagCompound user = new NBTTagCompound(); + user.setString("password", password); + env.getServer().writePlayerData(username, user); + exec.logConsole(TextColor.GREEN + "Spieler %s registriert", username); + } + } +} diff --git a/server/src/server/command/commands/CommandSave.java b/server/src/server/command/commands/CommandSave.java new file mode 100644 index 0000000..4f80993 --- /dev/null +++ b/server/src/server/command/commands/CommandSave.java @@ -0,0 +1,35 @@ +package server.command.commands; + +import common.color.TextColor; +import common.packet.SPacketMessage; +import common.packet.SPacketMessage.Type; +import server.command.Command; +import server.command.CommandEnvironment; +import server.command.Executor; +import server.world.Region; + +public class CommandSave extends Command { + public CommandSave() { + super("save"); + + this.addFlag("message", 'm'); + this.addFlag("flush", 'f'); + } + + public void exec(CommandEnvironment env, Executor exec, boolean message, boolean flush) { + if(message) + env.getServer().sendPacket(new SPacketMessage(TextColor.RED + "Speichere Serverdaten, der Server könnte kurz einfrieren", Type.FEED)); + exec.logConsole(TextColor.ORANGE + "Speichere Spielerdaten ..."); + env.getServer().saveAllPlayerData(true); + exec.logConsole(TextColor.ORANGE + "Speichere Weltdaten ..."); + env.getServer().saveAllWorlds(true); + env.getServer().resetSaveTimer(); + if(flush) { + exec.logConsole(TextColor.ORANGE + "Beende E/A ..."); + Region.finishWrite(); + } + exec.logConsole(TextColor.DGREEN + "Alle Serverdaten wurden gespeichert"); + if(message) + env.getServer().sendPacket(new SPacketMessage(TextColor.GREEN + "Die Serverdaten wurden gespeichert", Type.FEED)); + } +} diff --git a/server/src/server/network/Player.java b/server/src/server/network/Player.java index 9db76b8..f42a452 100755 --- a/server/src/server/network/Player.java +++ b/server/src/server/network/Player.java @@ -339,7 +339,7 @@ public class Player extends NetHandler implements ICrafting, Executor, IPlayer } public boolean getAdmin() { - return this.admin; + return this.isAdmin(); } public void setPassword(String pass) { diff --git a/server/src/server/util/Form.java b/server/src/server/util/Form.java index cb6fbbf..e96bee5 100644 --- a/server/src/server/util/Form.java +++ b/server/src/server/util/Form.java @@ -94,14 +94,16 @@ public abstract class Form { protected class Field extends FormElement { private final int minLength; private final int maxLength; + private final boolean password; private String value; - protected Field(String name, String value, int min, int max) { + protected Field(String name, String value, int min, int max, boolean password) { super(name); this.value = value; this.minLength = min; this.maxLength = max; + this.password = password; } protected Object getInputData() { @@ -109,7 +111,7 @@ public abstract class Form { } protected int getInputParameter() { - return (this.minLength << 16) | this.maxLength; + return (this.password ? 0x80000000 : 0) | (this.minLength << 16) | this.maxLength; } protected boolean acceptValue(Object obj) { @@ -145,7 +147,11 @@ public abstract class Form { } protected Field addField(String name, int minLength, int maxLength, String def) { - return this.add(new Field(name, def, minLength, maxLength)); + return this.add(new Field(name, def, minLength, maxLength, false)); + } + + protected Field addPassword(String name, int minLength, int maxLength, String def) { + return this.add(new Field(name, def, minLength, maxLength, true)); } public abstract String getTitle(); From 2ea3267e3a360cfbee80894a35b6eb44ccc6a3ab Mon Sep 17 00:00:00 2001 From: Sen Date: Sun, 18 May 2025 14:30:35 +0200 Subject: [PATCH 034/200] split text fields --- client/src/client/Client.java | 4 +- client/src/client/audio/Volume.java | 3 +- client/src/client/gui/GuiConfirm.java | 11 +- client/src/client/gui/GuiConnect.java | 9 +- client/src/client/gui/GuiConsole.java | 47 +-- client/src/client/gui/GuiInfo.java | 4 +- client/src/client/gui/GuiMenu.java | 26 +- client/src/client/gui/GuiServer.java | 43 ++- client/src/client/gui/character/GuiChar.java | 61 +-- .../client/gui/character/GuiCharacters.java | 15 +- client/src/client/gui/character/GuiClass.java | 9 +- .../src/client/gui/character/GuiSpecies.java | 9 +- client/src/client/gui/element/ActButton.java | 16 +- client/src/client/gui/element/Area.java | 159 ++++++++ .../client/gui/element/ButtonCallback.java | 5 + client/src/client/gui/element/Dropdown.java | 10 +- .../client/gui/element/DropdownCallback.java | 5 + client/src/client/gui/element/Field.java | 194 ++++++++++ .../src/client/gui/element/FieldAction.java | 5 + .../src/client/gui/element/FieldCallback.java | 5 + client/src/client/gui/element/NavButton.java | 4 +- .../src/client/gui/element/PasswordBox.java | 27 -- .../src/client/gui/element/PasswordField.java | 20 + client/src/client/gui/element/PressType.java | 5 + .../client/gui/element/SelectableButton.java | 2 +- client/src/client/gui/element/Slider.java | 22 +- .../client/gui/element/SliderCallback.java | 5 + .../gui/element/SliderFloatCallback.java | 5 + client/src/client/gui/element/Switch.java | 10 +- .../client/gui/element/SwitchCallback.java | 5 + .../src/client/gui/element/TextCallback.java | 5 + client/src/client/gui/element/Textbox.java | 348 +++--------------- client/src/client/gui/element/Toggle.java | 10 +- .../client/gui/element/ToggleCallback.java | 5 + ...ansparentBox.java => TransparentArea.java} | 4 +- client/src/client/gui/ingame/GuiForm.java | 32 +- client/src/client/gui/ingame/GuiGameOver.java | 7 +- client/src/client/gui/ingame/GuiSign.java | 18 +- client/src/client/gui/options/GuiBinds.java | 15 +- client/src/client/gui/options/GuiDisplay.java | 9 +- client/src/client/gui/options/GuiSound.java | 7 +- client/src/client/gui/options/GuiStyle.java | 34 +- client/src/client/vars/BoolVar.java | 3 +- client/src/client/vars/ColorVar.java | 14 +- client/src/client/vars/EnumVar.java | 6 +- client/src/client/vars/FloatVar.java | 3 +- client/src/client/vars/IntVar.java | 3 +- client/src/client/vars/StringVar.java | 12 +- 48 files changed, 709 insertions(+), 571 deletions(-) create mode 100644 client/src/client/gui/element/Area.java create mode 100644 client/src/client/gui/element/ButtonCallback.java create mode 100644 client/src/client/gui/element/DropdownCallback.java create mode 100644 client/src/client/gui/element/Field.java create mode 100644 client/src/client/gui/element/FieldAction.java create mode 100644 client/src/client/gui/element/FieldCallback.java delete mode 100644 client/src/client/gui/element/PasswordBox.java create mode 100644 client/src/client/gui/element/PasswordField.java create mode 100644 client/src/client/gui/element/PressType.java create mode 100644 client/src/client/gui/element/SliderCallback.java create mode 100644 client/src/client/gui/element/SliderFloatCallback.java create mode 100644 client/src/client/gui/element/SwitchCallback.java create mode 100644 client/src/client/gui/element/TextCallback.java create mode 100644 client/src/client/gui/element/ToggleCallback.java rename client/src/client/gui/element/{TransparentBox.java => TransparentArea.java} (69%) diff --git a/client/src/client/Client.java b/client/src/client/Client.java index 8535a7d..c2b91ed 100755 --- a/client/src/client/Client.java +++ b/client/src/client/Client.java @@ -50,7 +50,7 @@ import client.gui.Style; import client.gui.character.GuiChar; import client.gui.container.GuiContainer; import client.gui.container.GuiInventory; -import client.gui.element.Textbox; +import client.gui.element.Area; import client.gui.ingame.GuiGameOver; import client.network.ClientLoginHandler; import client.network.ClientPlayer; @@ -1011,7 +1011,7 @@ public class Client implements IThreadListener { this.open.render(); else if(this.world == null || this.world.hasNoChunks() || this.charEditor) Drawing.drawScaled(this, Gui.DIRT_BACKGROUND); - if(Bind.INFO.isDown() && (this.open == null || !(this.open.selected instanceof Textbox))) + if(Bind.INFO.isDown() && (this.open == null || !(this.open.selected instanceof client.gui.element.Field || this.open.selected instanceof Area))) this.drawInfo(); if(this.hudOverlay && !(this.open instanceof GuiConsole)) { this.drawOverlay(this.feed, this.feedSize, false, 1, 0, 0); diff --git a/client/src/client/audio/Volume.java b/client/src/client/audio/Volume.java index f402a3a..5d400b7 100644 --- a/client/src/client/audio/Volume.java +++ b/client/src/client/audio/Volume.java @@ -2,6 +2,7 @@ package client.audio; import client.Client; import client.gui.element.Slider; +import client.gui.element.SliderCallback; import client.vars.CVar; import client.vars.CVarCategory; import common.color.TextColor; @@ -96,7 +97,7 @@ public enum Volume implements CVar { } public Slider selector(int x, int y, int w, int h) { - return new Slider(x, y, w, h, 0, 0, 100, 100, this.value, new Slider.Callback() { + return new Slider(x, y, w, h, 0, 0, 100, 100, this.value, new SliderCallback() { public void use(Slider elem, int value) { Volume.this.value = value; Volume.this.apply(); diff --git a/client/src/client/gui/GuiConfirm.java b/client/src/client/gui/GuiConfirm.java index fb9b117..901117c 100755 --- a/client/src/client/gui/GuiConfirm.java +++ b/client/src/client/gui/GuiConfirm.java @@ -1,11 +1,12 @@ package client.gui; import client.gui.element.ActButton; -import client.gui.element.ActButton.Mode; +import client.gui.element.ButtonCallback; import client.gui.element.Label; -import client.gui.element.TransparentBox; +import client.gui.element.PressType; +import client.gui.element.TransparentArea; -public class GuiConfirm extends Gui implements ActButton.Callback { +public class GuiConfirm extends Gui implements ButtonCallback { public static interface Callback { void confirm(boolean confirmed); } @@ -28,7 +29,7 @@ public class GuiConfirm extends Gui implements ActButton.Callback { public void init(int width, int height) { this.add(new Label(0, 0, 500, 24, this.messageLine1, true)); - this.add(new TransparentBox(0, 80, 500, 300, this.messageLine2, this.gm.world != null && !this.gm.charEditor)); + this.add(new TransparentArea(0, 80, 500, 300, this.messageLine2, this.gm.world != null && !this.gm.charEditor)); this.confirmBtn = this.add(new ActButton(48, 500, 200, 24, this, this.confirmButtonText)); this.cancelBtn = this.add(new ActButton(252, 500, 200, 24, this, this.cancelButtonText)); this.shift(); @@ -38,7 +39,7 @@ public class GuiConfirm extends Gui implements ActButton.Callback { return "Aktion bestätigen"; } - public void use(ActButton btn, Mode mode) { + public void use(ActButton btn, PressType mode) { this.callback.confirm(btn == this.confirmBtn); } } diff --git a/client/src/client/gui/GuiConnect.java b/client/src/client/gui/GuiConnect.java index 9303c20..789fcf0 100644 --- a/client/src/client/gui/GuiConnect.java +++ b/client/src/client/gui/GuiConnect.java @@ -6,10 +6,11 @@ import java.util.Collections; import java.util.Date; import client.gui.element.ActButton; -import client.gui.element.ActButton.Mode; +import client.gui.element.ButtonCallback; import client.gui.element.GuiList; import client.gui.element.ListEntry; import client.gui.element.NavButton; +import client.gui.element.PressType; import client.renderer.Drawing; import common.color.TextColor; import common.init.Config; @@ -19,7 +20,7 @@ import common.util.FileUtils; import common.util.Tuple; import common.util.Util; -public class GuiConnect extends GuiList implements ActButton.Callback { +public class GuiConnect extends GuiList implements ButtonCallback { public class ServerInfo implements Comparable, ListEntry { private String name; private String address; @@ -91,7 +92,7 @@ public class GuiConnect extends GuiList implements ActBut GuiConnect.this.copyButton.enabled = true; if(isDoubleClick) { - GuiConnect.this.use(GuiConnect.this.selectButton, Mode.PRIMARY); + GuiConnect.this.use(GuiConnect.this.selectButton, PressType.PRIMARY); } } @@ -233,7 +234,7 @@ public class GuiConnect extends GuiList implements ActBut return 56; } - public void use(ActButton button, Mode mode) { + public void use(ActButton button, PressType mode) { if(button == this.deleteButton) { if(this.selectedElement >= 0) { this.elements.remove(this.selectedElement); diff --git a/client/src/client/gui/GuiConsole.java b/client/src/client/gui/GuiConsole.java index 52f1501..d3c6aca 100644 --- a/client/src/client/gui/GuiConsole.java +++ b/client/src/client/gui/GuiConsole.java @@ -4,13 +4,16 @@ import java.util.List; import client.Client; import client.gui.element.ActButton; +import client.gui.element.ButtonCallback; import client.gui.element.Fill; -import client.gui.element.Textbox; -import client.gui.element.Textbox.Action; +import client.gui.element.PressType; +import client.gui.element.FieldAction; +import client.gui.element.Field; +import client.gui.element.FieldCallback; import client.network.ClientPlayer; import client.vars.BoolVar; import client.vars.CVar; -import client.gui.element.TransparentBox; +import client.gui.element.TransparentArea; import client.window.Keysym; import common.collect.Lists; import common.color.TextColor; @@ -20,7 +23,7 @@ import common.util.BlockPos; import common.util.ExtMath; import common.util.HitPosition; -public class GuiConsole extends Gui implements Textbox.Callback { +public class GuiConsole extends Gui implements FieldCallback { public static final GuiConsole INSTANCE = new GuiConsole(); private final List sentMessages = Lists.newArrayList(); @@ -35,8 +38,8 @@ public class GuiConsole extends Gui implements Textbox.Callback { private String prefixFirst; private int autocompleteIndex; private List foundPlayerNames = Lists.newArrayList(); - private Textbox inputField; - private TransparentBox logBox; + private Field inputField; + private TransparentArea logBox; public GuiConsole setFull(boolean full) { this.full = full; @@ -48,17 +51,17 @@ public class GuiConsole extends Gui implements Textbox.Callback { this.addSelector("con_autoclose", 0, 0, 160, 24); this.addSelector("con_timestamps", 160, 0, 160, 24); this.addSelector("con_loglevel", 320, 0, 160, 24); - this.add(new ActButton(480, 0, 160, 24, new ActButton.Callback() { - public void use(ActButton elem, ActButton.Mode action) { + this.add(new ActButton(480, 0, 160, 24, new ButtonCallback() { + public void use(ActButton elem, PressType action) { GuiConsole.this.reset(); GuiConsole.this.setLog(GuiConsole.this.gm.getBuffer()); } }, "Löschen")); } - this.logBox = this.add(new TransparentBox(0, this.full ? 24 : 0, width, height - (this.full ? 48 : 24), this.gm.getBuffer(), this.gm.world != null && !this.gm.charEditor)); + this.logBox = this.add(new TransparentArea(0, this.full ? 24 : 0, width, height - (this.full ? 48 : 24), this.gm.getBuffer(), this.gm.world != null && !this.gm.charEditor)); if(this.full) this.add(new Fill(640, 0, width - 640, 24)); - this.inputField = this.add(new Textbox(0, height - 24, width, 24, IPlayer.MAX_CMD_LENGTH, true, this, "")); + this.inputField = this.add(new Field(0, height - 24, width, 24, IPlayer.MAX_CMD_LENGTH, this, "")); this.inputField.setSelected(); this.sentHistoryCursor = this.sentMessages.size(); } @@ -90,13 +93,13 @@ public class GuiConsole extends Gui implements Textbox.Callback { this.playerNamesFound = false; } - public void use(Textbox elem, Action value) + public void use(Field elem, FieldAction value) { this.waitingOnAutocomplete = false; - if (value == Action.FORWARD || value == Action.BACKWARD) + if (value == FieldAction.FORWARD || value == FieldAction.BACKWARD) { - this.reverse = value == Action.BACKWARD; + this.reverse = value == FieldAction.BACKWARD; this.autocompletePlayerNames(); } else @@ -104,11 +107,11 @@ public class GuiConsole extends Gui implements Textbox.Callback { this.playerNamesFound = false; } - if(value == Action.PREVIOUS) + if(value == FieldAction.PREVIOUS) this.getSentHistory(-1); - else if (value == Action.NEXT) + else if (value == FieldAction.NEXT) this.getSentHistory(1); - if(value == Action.SEND) + if(value == FieldAction.SEND) { String s = this.inputField.getText().trim(); @@ -154,7 +157,7 @@ public class GuiConsole extends Gui implements Textbox.Callback { { if (this.playerNamesFound) { - this.inputField.deleteFromCursor(); + this.inputField.deleteSpaceToCur(); if (this.autocompleteIndex >= this.foundPlayerNames.size()) { @@ -167,11 +170,11 @@ public class GuiConsole extends Gui implements Textbox.Callback { } else { - int i = this.inputField.getNthCharFromPos(); + int i = this.inputField.getSpaceBeforeCur(); this.foundPlayerNames.clear(); this.autocompleteIndex = 0; // String s = this.inputField.getText().substring(i).toLowerCase(); - String s1 = this.inputField.getText().substring(0, this.inputField.getCursorPosition()); + String s1 = this.inputField.getText().substring(0, this.inputField.getCursorPos()); String[] localMatches = this.sendAutocompleteRequest(s1); if(localMatches != null) { this.onAutocompleteResponse(localMatches); @@ -184,7 +187,7 @@ public class GuiConsole extends Gui implements Textbox.Callback { } this.playerNamesFound = true; - this.inputField.deleteFromCursor(); + this.inputField.deleteSpaceToCur(); } if (this.foundPlayerNames.size() > 1) @@ -314,12 +317,12 @@ public class GuiConsole extends Gui implements Textbox.Callback { } } - String s1 = this.inputField.getText().substring(this.inputField.getNthCharFromPos()); + String s1 = this.inputField.getText().substring(this.inputField.getSpaceBeforeCur()); String s2 = getCommonPrefix(choices); if (s2.length() > 0 && !s1.equalsIgnoreCase(s2)) { - this.inputField.deleteFromCursor(); + this.inputField.deleteSpaceToCur(); this.inputField.insertText(s2); } else if (this.foundPlayerNames.size() > 0) diff --git a/client/src/client/gui/GuiInfo.java b/client/src/client/gui/GuiInfo.java index 7d64ac4..5653efb 100644 --- a/client/src/client/gui/GuiInfo.java +++ b/client/src/client/gui/GuiInfo.java @@ -1,7 +1,7 @@ package client.gui; import client.gui.element.NavButton; -import client.gui.element.TransparentBox; +import client.gui.element.TransparentArea; import common.color.TextColor; import common.init.Config; import common.log.Log; @@ -125,7 +125,7 @@ public class GuiInfo extends Gui { } public void init(int width, int height) { - this.add(new TransparentBox(10, 10, width - 20, height - 44, this.info, this.gm.world != null && !this.gm.charEditor)); + this.add(new TransparentArea(10, 10, width - 20, height - 44, this.info, this.gm.world != null && !this.gm.charEditor)); this.add(new NavButton(0, height - 24, width, 24, GuiMenu.INSTANCE, "Zurück")); } diff --git a/client/src/client/gui/GuiMenu.java b/client/src/client/gui/GuiMenu.java index e562003..fd2093b 100644 --- a/client/src/client/gui/GuiMenu.java +++ b/client/src/client/gui/GuiMenu.java @@ -4,10 +4,10 @@ import client.Timing; import client.gui.character.GuiChar; import client.gui.character.GuiCharacters; import client.gui.element.ActButton; -import client.gui.element.ActButton.Mode; +import client.gui.element.ButtonCallback; import client.gui.element.Label; import client.gui.element.NavButton; -import client.gui.element.Textbox; +import client.gui.element.PressType; import client.gui.options.GuiOptions; import client.renderer.Drawing; import client.window.Keysym; @@ -52,8 +52,8 @@ public class GuiMenu extends Gui { this.ticks = 0; this.hacked = 0; this.resetAnimation(); - this.add(new ActButton(0, -28, 400, 24, new ActButton.Callback() { - public void use(ActButton elem, Mode action) { + this.add(new ActButton(0, -28, 400, 24, new ButtonCallback() { + public void use(ActButton elem, PressType action) { if(GuiMenu.this.hacked == 9) { GuiMenu.this.hacked++; GuiMenu.this.splashLabel.setText(TextColor.VIOLET + "Hax!"); @@ -64,16 +64,16 @@ public class GuiMenu extends Gui { } }, "Server beitreten")); this.add(new NavButton(0, 0, 400, 24, GuiServer.INSTANCE, "Schnellverbindung")); - this.add(new ActButton(0, 28, 400, 24, new ActButton.Callback() { - public void use(ActButton elem, Mode action) { + this.add(new ActButton(0, 28, 400, 24, new ButtonCallback() { + public void use(ActButton elem, PressType action) { if(GuiMenu.this.hacked == 8) GuiMenu.this.hacked++; else GuiMenu.this.gm.displayGuiScreen(GuiOptions.getPage()); } }, "Einstellungen")); - this.infoButton = this.add(new ActButton(0, 56, 400, 24, new ActButton.Callback() { - public void use(ActButton elem, Mode action) { + this.infoButton = this.add(new ActButton(0, 56, 400, 24, new ButtonCallback() { + public void use(ActButton elem, PressType action) { GuiMenu.this.gm.displayGuiScreen(GuiMenu.this.hacked == 10 ? GuiInfo.HAX : GuiInfo.INSTANCE); } }, "Info / Über / Mitwirkende") { @@ -95,8 +95,8 @@ public class GuiMenu extends Gui { } } }); - this.add(new ActButton(0, 102, 400, 24, new ActButton.Callback() { - public void use(ActButton elem, ActButton.Mode action) { + this.add(new ActButton(0, 102, 400, 24, new ButtonCallback() { + public void use(ActButton elem, PressType action) { GuiMenu.this.gm.interrupted = true; } }, "Client schließen")); @@ -110,8 +110,8 @@ public class GuiMenu extends Gui { this.add(new NavButton(0, 28, this.gm.charEditor ? 400 : 198, 24, GuiOptions.getPage(), "Einstellungen")); if(!this.gm.charEditor) this.add(new NavButton(202, 28, 198, 24, GuiCharacters.INSTANCE, "Charakter")); - this.add(new ActButton(0, 102, 400, 24, new ActButton.Callback() { - public void use(ActButton elem, ActButton.Mode action) { + this.add(new ActButton(0, 102, 400, 24, new ButtonCallback() { + public void use(ActButton elem, PressType action) { GuiMenu.this.gm.unload(true); // GuiMenu.this.gm.displayGuiScreen(INSTANCE); } @@ -226,7 +226,7 @@ public class GuiMenu extends Gui { public void updateScreen() { if(this.gm.world == null) { this.ticks++; - if(this.gm.shift() && !(this.selected instanceof Textbox)) + if(this.gm.shift()) this.pickSplash(); this.updateAnimation(); } diff --git a/client/src/client/gui/GuiServer.java b/client/src/client/gui/GuiServer.java index 6fc3495..3cb509e 100644 --- a/client/src/client/gui/GuiServer.java +++ b/client/src/client/gui/GuiServer.java @@ -2,27 +2,30 @@ package client.gui; import client.gui.GuiConnect.ServerInfo; import client.gui.element.ActButton; +import client.gui.element.ButtonCallback; import client.gui.element.Label; import client.gui.element.NavButton; -import client.gui.element.Textbox; -import client.gui.element.Textbox.Action; +import client.gui.element.PressType; +import client.gui.element.FieldAction; +import client.gui.element.Field; +import client.gui.element.FieldCallback; import client.vars.CVarCategory; import client.vars.Variable; import common.color.TextColor; import common.init.Config; import common.network.IPlayer; -public class GuiServer extends Gui implements Textbox.Callback { +public class GuiServer extends Gui implements FieldCallback { public static final GuiServer INSTANCE = new GuiServer(null); private final ServerInfo server; - private Textbox nameBox; - private Textbox addrBox; - private Textbox portBox; - private Textbox userBox; - private Textbox passBox; - private Textbox accBox; + private Field nameBox; + private Field addrBox; + private Field portBox; + private Field userBox; + private Field passBox; + private Field accBox; private Label nameLabel; private Label addrLabel; private Label portLabel; @@ -47,14 +50,14 @@ public class GuiServer extends Gui implements Textbox.Callback { public void init(int width, int height) { if(this.server != null) - this.nameBox = this.add(new Textbox(0, -50, 400, 24, 128, true, this, this.server.getName())); - this.addrBox = this.add(new Textbox(0, 20, 400, 24, 128, true, this, this.server == null ? this.lastAddr : this.server.getAddress())); - this.portBox = this.add(new Textbox(404, 20, 76, 24, 5, true, this, "" + (this.server == null ? this.lastPort : this.server.getPort()))); - this.userBox = this.add(new Textbox(0, 70, 220, 24, IPlayer.MAX_USER_LENGTH, true, this, IPlayer.VALID_USER, this.server == null ? this.lastUser : this.server.getUser())); - this.passBox = this.add(new Textbox(0, 120, 480, 24, IPlayer.MAX_PASS_LENGTH, true, this, this.server == null ? this.lastPass : this.server.getPassword())); - this.accBox = this.add(new Textbox(0, 170, 480, 24, IPlayer.MAX_PASS_LENGTH, true, this, this.server == null ? this.lastAcc : this.server.getAccess())); - this.add(new ActButton(0, 220, 480, 24, new ActButton.Callback() { - public void use(ActButton elem, ActButton.Mode action) { + this.nameBox = this.add(new Field(0, -50, 400, 24, 128, this, this.server.getName())); + this.addrBox = this.add(new Field(0, 20, 400, 24, 128, this, this.server == null ? this.lastAddr : this.server.getAddress())); + this.portBox = this.add(new Field(404, 20, 76, 24, 5, this, "" + (this.server == null ? this.lastPort : this.server.getPort()))); + this.userBox = this.add(new Field(0, 70, 220, 24, IPlayer.MAX_USER_LENGTH, this, IPlayer.VALID_USER, this.server == null ? this.lastUser : this.server.getUser())); + this.passBox = this.add(new Field(0, 120, 480, 24, IPlayer.MAX_PASS_LENGTH, this, this.server == null ? this.lastPass : this.server.getPassword())); + this.accBox = this.add(new Field(0, 170, 480, 24, IPlayer.MAX_PASS_LENGTH, this, this.server == null ? this.lastAcc : this.server.getAccess())); + this.add(new ActButton(0, 220, 480, 24, new ButtonCallback() { + public void use(ActButton elem, PressType action) { GuiServer.this.connect(); } }, this.server == null ? "Verbinden" : (this.server.getName().isEmpty() ? "Hinzufügen" : "Übernehmen"))); @@ -127,12 +130,12 @@ public class GuiServer extends Gui implements Textbox.Callback { } } - public void use(Textbox elem, Action value) { - if(value == Action.SEND) { + public void use(Field elem, FieldAction value) { + if(value == FieldAction.SEND) { elem.setDeselected(); this.connect(); } - else if(value == Action.FOCUS) { + else if(value == FieldAction.FOCUS) { if(elem == this.addrBox) this.addrLabel.setText("Adresse"); else if(elem == this.portBox) diff --git a/client/src/client/gui/character/GuiChar.java b/client/src/client/gui/character/GuiChar.java index 25c3593..01117c0 100755 --- a/client/src/client/gui/character/GuiChar.java +++ b/client/src/client/gui/character/GuiChar.java @@ -20,16 +20,20 @@ import client.SkinConverter; import client.gui.FileCallback; import client.gui.GuiLoading; import client.gui.element.ActButton; -import client.gui.element.ActButton.Mode; import client.gui.element.Element; import client.gui.element.GuiList; import client.gui.element.Label; import client.gui.element.ListEntry; import client.gui.element.NavButton; +import client.gui.element.PressType; import client.gui.element.Slider; -import client.gui.element.Textbox; -import client.gui.element.Textbox.Action; -import client.gui.element.TransparentBox; +import client.gui.element.SliderCallback; +import client.gui.element.FieldAction; +import client.gui.element.Area; +import client.gui.element.ButtonCallback; +import client.gui.element.Field; +import client.gui.element.FieldCallback; +import client.gui.element.TransparentArea; import client.renderer.Drawing; import client.renderer.GlState; import client.renderer.ItemRenderer; @@ -248,7 +252,7 @@ public class GuiChar extends GuiList private ActButton templateButton; private DragAdjust adjust; private ActButton dimButton; - private TransparentBox descLines; + private TransparentArea descLines; private float yaw = -15.0f; private float pitch = -15.0f; private boolean waiting = true; @@ -273,8 +277,8 @@ public class GuiChar extends GuiList } this.currentSkin = this.gm.player != null && !EntityTexManager.hasCustomSkin(this.gm.player.getId()) ? this.gm.player.getChar() : null; this.load(this.gm.player == null ? ModelType.HUMANOID : this.gm.player.getModel(), this.gm.player != null ? this.gm.player.getSpecies() : SpeciesRegistry.CLASSES.get(EntityHuman.class)); - this.add(new ActButton(4, 4, 194, 24, new ActButton.Callback() { - public void use(ActButton elem, Mode action) { + this.add(new ActButton(4, 4, 194, 24, new ButtonCallback() { + public void use(ActButton elem, PressType action) { GuiChar.this.gm.showFileDialog(FileMode.FILE_LOAD_MULTI, "Skin konvertieren", TEXTURE_FOLDER, new FileCallback() { public void selected(File file) { if(SkinConverter.convertSkin(file, TEXTURE_FOLDER, false)) @@ -283,8 +287,8 @@ public class GuiChar extends GuiList }); } }, "Importieren: Standard")); - this.add(new ActButton(202, 4, 194, 24, new ActButton.Callback() { - public void use(ActButton elem, Mode action) { + this.add(new ActButton(202, 4, 194, 24, new ButtonCallback() { + public void use(ActButton elem, PressType action) { GuiChar.this.gm.showFileDialog(FileMode.FILE_LOAD_MULTI, "Skin konvertieren (schlank)", TEXTURE_FOLDER, new FileCallback() { public void selected(File file) { if(SkinConverter.convertSkin(file, TEXTURE_FOLDER, true)) @@ -294,13 +298,13 @@ public class GuiChar extends GuiList } }, "Importieren: Schlank")); this.addSelector("char_filter_species", 400, 4, 300, 24); - this.add(new ActButton(4, height - 28, 194, 24, new ActButton.Callback() { - public void use(ActButton elem, Mode action) { + this.add(new ActButton(4, height - 28, 194, 24, new ButtonCallback() { + public void use(ActButton elem, PressType action) { GuiChar.this.gm.displayGuiScreen(GuiChar.this); } }, "Neu laden")); - this.templateButton = this.add(new ActButton(202, height - 28, 194, 24, new ActButton.Callback() { - public void use(ActButton elem, Mode action) { + this.templateButton = this.add(new ActButton(202, height - 28, 194, 24, new ButtonCallback() { + public void use(ActButton elem, PressType action) { SkinEntry skin = GuiChar.this.getSelected(); if(skin != null && skin.getLocation() != null) { String loc = skin.getLocation(); @@ -346,8 +350,8 @@ public class GuiChar extends GuiList for (int z = 0; z < Alignment.values().length; z++) { final Alignment align = Alignment.values()[z]; - alignBtns[z] = this.add(new ActButton(width - 396 + (z % 3) * 132, height - 32 - 28 * 3 + 28 * (z / 3), 128, 24, new ActButton.Callback() { - public void use(ActButton elem, Mode action) { + alignBtns[z] = this.add(new ActButton(width - 396 + (z % 3) * 132, height - 32 - 28 * 3 + 28 * (z / 3), 128, 24, new ButtonCallback() { + public void use(ActButton elem, PressType action) { if(GuiChar.this.gm.player != null) { GuiChar.this.waiting = false; GuiChar.this.gm.player.client.addToSendQueue(new CPacketAction(CPacketAction.Action.SET_ALIGN, align.ordinal())); @@ -359,7 +363,7 @@ public class GuiChar extends GuiList }, align.color + align.display)); alignBtns[z].enabled = this.gm.player == null || this.gm.player.getAlignment() != align; } - this.add(new Slider(width / 2 - 200, height - 28, 400, 24, 1, this.gm.player == null ? 120 : this.gm.player.getMinSize(), this.gm.player == null ? 320 : this.gm.player.getMaxSize(), this.gm.player == null ? 180 : this.gm.player.getDefaultSize(), this.gm.player == null ? 180 : this.gm.player.getCurrentSize(), new Slider.Callback() { + this.add(new Slider(width / 2 - 200, height - 28, 400, 24, 1, this.gm.player == null ? 120 : this.gm.player.getMinSize(), this.gm.player == null ? 320 : this.gm.player.getMaxSize(), this.gm.player == null ? 180 : this.gm.player.getDefaultSize(), this.gm.player == null ? 180 : this.gm.player.getCurrentSize(), new SliderCallback() { public void use(Slider elem, int value) { if(GuiChar.this.gm.player != null) { GuiChar.this.waiting = false; @@ -369,12 +373,9 @@ public class GuiChar extends GuiList }, "Spieler-Größe", "cm")).enabled = this.gm.player == null || this.gm.player.getMinSize() != this.gm.player.getMaxSize(); this.add(new Label(width / 2 - 200, 36, 400, 20, "Name", true)); this.add(new Label(width - 396, height - 384, 392, 20, "Beschreibung", true)); - final Textbox descField = this.add(new Textbox(width - 396, height - 364, 392, 130, IPlayer.MAX_INFO_LENGTH, new Textbox.Callback() { - public void use(Textbox elem, Action value) { - } - }, "")); - this.add(new ActButton(width - 198, height - 28, 194, 24, new ActButton.Callback() { - public void use(ActButton elem, Mode action) { + final Area descField = this.add(new Area(width - 396, height - 364, 392, 130, IPlayer.MAX_INFO_LENGTH, "")); + this.add(new ActButton(width - 198, height - 28, 194, 24, new ButtonCallback() { + public void use(ActButton elem, PressType action) { if(GuiChar.this.gm.player != null) { GuiChar.this.gm.displayGuiScreen(GuiLoading.makeWaitTask("Lade Welt ...")); Dimension dim = UniverseRegistry.getBaseDimensions().get(GuiChar.this.dimension); @@ -383,9 +384,9 @@ public class GuiChar extends GuiList } } }, "Charakter erstellen")); - this.add(new Textbox(width / 2 - 200, 36 + 20, 400, 24, IPlayer.MAX_NICK_LENGTH, true, new Textbox.Callback() { - public void use(Textbox elem, Action value) { - if(value == Action.SEND || value == Action.UNFOCUS) { + this.add(new Field(width / 2 - 200, 36 + 20, 400, 24, IPlayer.MAX_NICK_LENGTH, new FieldCallback() { + public void use(Field elem, FieldAction value) { + if(value == FieldAction.SEND || value == FieldAction.UNFOCUS) { String name = elem.getText(); if(name.isEmpty()) elem.setText(GuiChar.this.gm.player == null ? "..." : GuiChar.this.gm.player.getCustomNameTag()); @@ -410,12 +411,12 @@ public class GuiChar extends GuiList } } } - this.dimButton = this.add(new ActButton(width - 396, height - 220, 392, 24, new ActButton.Callback() { - public void use(ActButton elem, Mode mode) { - if(mode == Mode.TERTIARY) { + this.dimButton = this.add(new ActButton(width - 396, height - 220, 392, 24, new ButtonCallback() { + public void use(ActButton elem, PressType mode) { + if(mode == PressType.TERTIARY) { GuiChar.this.dimension = new Random().zrange(UniverseRegistry.getBaseDimensions().size()); } - else if(mode == Mode.SECONDARY) { + else if(mode == PressType.SECONDARY) { if(--GuiChar.this.dimension < 0) GuiChar.this.dimension = UniverseRegistry.getBaseDimensions().size() - 1; } @@ -426,7 +427,7 @@ public class GuiChar extends GuiList GuiChar.this.setDimButton(); } }, "")); - this.descLines = this.add(new TransparentBox(width - 396, height - 220 + 24, 392, 66, "", false)); + this.descLines = this.add(new TransparentArea(width - 396, height - 220 + 24, 392, 66, "", false)); this.setDimButton(); } diff --git a/client/src/client/gui/character/GuiCharacters.java b/client/src/client/gui/character/GuiCharacters.java index 159e54f..46e99d8 100644 --- a/client/src/client/gui/character/GuiCharacters.java +++ b/client/src/client/gui/character/GuiCharacters.java @@ -3,17 +3,18 @@ package client.gui.character; import client.gui.GuiConfirm; import client.gui.GuiMenu; import client.gui.element.ActButton; -import client.gui.element.ActButton.Mode; +import client.gui.element.ButtonCallback; import client.gui.element.GuiList; import client.gui.element.ListEntry; import client.gui.element.NavButton; -import client.gui.element.TransparentBox; +import client.gui.element.PressType; +import client.gui.element.TransparentArea; import client.renderer.Drawing; import common.color.TextColor; import common.entity.npc.PlayerCharacter; import common.packet.CPacketAction; -public class GuiCharacters extends GuiList implements ActButton.Callback +public class GuiCharacters extends GuiList implements ButtonCallback { protected class CharacterEntry implements ListEntry { @@ -43,14 +44,14 @@ public class GuiCharacters extends GuiList impleme public void select(boolean dclick, int mx, int my) { if(dclick) - GuiCharacters.this.use(GuiCharacters.this.actionButtom, Mode.PRIMARY); + GuiCharacters.this.use(GuiCharacters.this.actionButtom, PressType.PRIMARY); GuiCharacters.this.updateButtons(); } } public static final GuiCharacters INSTANCE = new GuiCharacters(); - private TransparentBox descField; + private TransparentArea descField; private ActButton actionButtom; private ActButton deleteButtom; @@ -78,7 +79,7 @@ public class GuiCharacters extends GuiList impleme this.elements.add(new CharacterEntry(null, false)); this.setSelected(initialSelection); } - this.descField = this.add(new TransparentBox(width - 390, 62, 380, height - 124, "", false)); + this.descField = this.add(new TransparentArea(width - 390, 62, 380, height - 124, "", false)); this.deleteButtom = this.add(new ActButton(width / 2 - 304, height - 28, 200, 24, this, "Charakter löschen")); this.actionButtom = this.add(new ActButton(width / 2 - 100, height - 28, 200, 24, this, "")); this.add(new NavButton(width / 2 + 104, height - 28, 200, 24, GuiMenu.INSTANCE, "Abbrechen")); @@ -99,7 +100,7 @@ public class GuiCharacters extends GuiList impleme return 36 + 4; } - public void use(ActButton elem, Mode action) { + public void use(ActButton elem, PressType action) { CharacterEntry entry = GuiCharacters.this.getSelected(); if(entry != null && GuiCharacters.this.gm.getNetHandler() != null) { if(elem == this.actionButtom) { diff --git a/client/src/client/gui/character/GuiClass.java b/client/src/client/gui/character/GuiClass.java index e25e5f5..9b83871 100644 --- a/client/src/client/gui/character/GuiClass.java +++ b/client/src/client/gui/character/GuiClass.java @@ -1,14 +1,15 @@ package client.gui.character; import client.gui.element.ActButton; -import client.gui.element.ActButton.Mode; +import client.gui.element.ButtonCallback; import client.gui.element.GuiList; import client.gui.element.ListEntry; import client.gui.element.NavButton; +import client.gui.element.PressType; import client.renderer.Drawing; import common.packet.CPacketAction; -public class GuiClass extends GuiList implements ActButton.Callback +public class GuiClass extends GuiList implements ButtonCallback { protected class ClassEntry implements ListEntry { @@ -29,7 +30,7 @@ public class GuiClass extends GuiList implements ActButton. public void select(boolean dclick, int mx, int my) { if((GuiClass.this.selectButton.enabled = GuiClass.this.gm.player == null || this.clazz != GuiClass.this.gm.player.getNpcClass()) && dclick) - GuiClass.this.use(GuiClass.this.selectButton, Mode.PRIMARY); + GuiClass.this.use(GuiClass.this.selectButton, PressType.PRIMARY); } } @@ -67,7 +68,7 @@ public class GuiClass extends GuiList implements ActButton. return 44 + 4; } - public void use(ActButton elem, Mode action) { + public void use(ActButton elem, PressType action) { ClassEntry entry = this.getSelected(); if(entry != null && GuiClass.this.gm.player != null) { GuiClass.this.gm.player.client.addToSendQueue(new CPacketAction(CPacketAction.Action.SET_CLASS, entry.clazz.ordinal())); diff --git a/client/src/client/gui/character/GuiSpecies.java b/client/src/client/gui/character/GuiSpecies.java index 47a9ec7..10e8c01 100644 --- a/client/src/client/gui/character/GuiSpecies.java +++ b/client/src/client/gui/character/GuiSpecies.java @@ -1,17 +1,18 @@ package client.gui.character; import client.gui.element.ActButton; -import client.gui.element.ActButton.Mode; +import client.gui.element.ButtonCallback; import client.gui.element.GuiList; import client.gui.element.ListEntry; import client.gui.element.NavButton; +import client.gui.element.PressType; import client.renderer.Drawing; import common.entity.npc.SpeciesInfo; import common.init.EntityRegistry; import common.init.SpeciesRegistry; import common.packet.CPacketAction; -public class GuiSpecies extends GuiList implements ActButton.Callback +public class GuiSpecies extends GuiList implements ButtonCallback { protected class SpeciesEntry implements ListEntry { @@ -34,7 +35,7 @@ public class GuiSpecies extends GuiList implements ActB public void select(boolean dclick, int mx, int my) { if((GuiSpecies.this.selectButton.enabled = GuiSpecies.this.gm.player == null || this.species != GuiSpecies.this.gm.player.getSpecies()) && dclick) - GuiSpecies.this.use(GuiSpecies.this.selectButton, Mode.PRIMARY); + GuiSpecies.this.use(GuiSpecies.this.selectButton, PressType.PRIMARY); } } @@ -71,7 +72,7 @@ public class GuiSpecies extends GuiList implements ActB return 44 + 4; } - public void use(ActButton elem, Mode action) { + public void use(ActButton elem, PressType action) { SpeciesEntry entry = this.getSelected(); if(entry != null && GuiSpecies.this.gm.player != null) GuiSpecies.this.gm.player.client.addToSendQueue(new CPacketAction(CPacketAction.Action.SET_SPECIES, EntityRegistry.getEntityID(entry.species.clazz))); diff --git a/client/src/client/gui/element/ActButton.java b/client/src/client/gui/element/ActButton.java index 72a8d88..d4d32b6 100644 --- a/client/src/client/gui/element/ActButton.java +++ b/client/src/client/gui/element/ActButton.java @@ -4,30 +4,22 @@ import client.gui.Formatter; import client.window.Button; public class ActButton extends Element { - public static enum Mode { - PRIMARY, SECONDARY, TERTIARY; - } + private final ButtonCallback func; - public static interface Callback { - void use(ActButton elem, Mode action); - } - - private final Callback func; - - public ActButton(int x, int y, int w, int h, Callback callback, Formatter formatter) { + public ActButton(int x, int y, int w, int h, ButtonCallback callback, Formatter formatter) { super(x, y, w, h, formatter); this.func = callback; this.formatText(); } - public ActButton(int x, int y, int w, int h, Callback callback, String text) { + public ActButton(int x, int y, int w, int h, ButtonCallback callback, String text) { super(x, y, w, h, null); this.func = callback; this.setText(text); } public void mouse(Button btn, int x, int y, boolean ctrl, boolean shift) { - this.func.use(this, (ctrl || (btn == Button.MOUSE_MIDDLE)) ? Mode.TERTIARY : ((shift || (btn == Button.MOUSE_RIGHT)) ? Mode.SECONDARY : Mode.PRIMARY)); + this.func.use(this, (ctrl || (btn == Button.MOUSE_MIDDLE)) ? PressType.TERTIARY : ((shift || (btn == Button.MOUSE_RIGHT)) ? PressType.SECONDARY : PressType.PRIMARY)); this.formatText(); this.playSound(); } diff --git a/client/src/client/gui/element/Area.java b/client/src/client/gui/element/Area.java new file mode 100644 index 0000000..d93c6b7 --- /dev/null +++ b/client/src/client/gui/element/Area.java @@ -0,0 +1,159 @@ +package client.gui.element; + +import client.gui.Font; +import client.renderer.Drawing; +import client.renderer.Drawing.Offset; +import client.renderer.Drawing.Vec2i; +import common.util.CharValidator; +import common.util.ExtMath; +import common.util.Util; + +public class Area extends Textbox { + private int textHeight; + private int scrollPos; + private int cursorX; + private int cursorY; + + private Area(int x, int y, int w, int h, int cap, boolean editable, CharValidator validator, String text) { + super(x, y, w, h, cap, editable, null, validator); + this.setText(text); + } + + public Area(int x, int y, int w, int h, int cap, CharValidator validator, String text) { + this(x, y, w, h, cap, true, validator, text); + } + + public Area(int x, int y, int w, int h, int cap, String text) { + this(x, y, w, h, cap, true, null, text); + } + + public Area(int x, int y, int w, int h, String text) { + this(x, y, w, h, Integer.MAX_VALUE, false, null, text); + } + + public void updateText() { + this.textHeight = Drawing.txt_size(this.pos_x + this.margin_x1, this.pos_y + this.margin_y1, + this.pos_x + this.margin_x1, this.pos_y + this.margin_y1, + this.pos_x + (this.size_x - (this.margin_x1 + this.margin_x2)), Integer.MAX_VALUE, this.text).ypos; + } + + public void scroll(int scr_x, int scr_y, int x, int y, boolean ctrl, boolean shift) { + if(scr_y != 0) { + int limit = Font.YGLYPH + this.textHeight - (this.size_y - (this.margin_y1 + this.margin_y2)); + limit = ExtMath.clampi(limit, 0, 0x7fffffff); + int prev = this.text_y; + this.text_y += (scr_y < 0 ? -1 : 1) * (ctrl ? 1 : Font.YGLYPH) * this.gm.scrollLines * (shift ? 10 : 1); + this.text_y = ExtMath.clampi(this.text_y, -limit, 0); + if(this.sel_start >= 0) + this.cursorY += (this.text_y - prev); + } + } + + public void mouserel() { + this.scrollPos = 0; + } + + public void onReturn(boolean shift) { + insertText("\n"); + } + + public void onSelection(boolean up) { + if(!up && this.sel_start != this.sel_end) { + this.sel_start = this.sel_drag = this.sel_end; + } + else if(up && this.sel_start != this.sel_end) { + this.sel_end = this.sel_drag = this.sel_start; + } + if(!up && this.sel_start >= 0) { + if(this.sel_end < this.text.length()) { + int nl = this.text.indexOf('\n', this.sel_end); + this.sel_end = nl >= 0 ? nl + 1 : this.text.length(); + this.sel_start = this.sel_drag = this.sel_end; + } + else { + this.sel_end = this.sel_drag = this.sel_start; + } + gui_text_update_cur(this.sel_end, true); + } + else if(up && this.sel_start >= 0) { + if(this.sel_start > 0) { + int nl = this.text.lastIndexOf('\n', this.sel_start); + this.sel_start = nl >= 0 ? nl : 0; + } + this.sel_end = this.sel_drag = this.sel_start; + gui_text_update_cur(this.sel_end, true); + } + } + + public void update() { + if(this.scrollPos != 0) { + int n = this.updateScroll(this.scrollPos); + this.text_y += n; + if(n != 0) + gui_text_clamp_scroll(); + } + } + + public void shift(int shift_x, int shift_y) { + super.shift(shift_x, shift_y); + this.cursorX += shift_x; + this.cursorY += shift_y; + } + + protected void gui_text_clamp_scroll() { + int limit = Font.YGLYPH + this.textHeight - (this.size_y - (this.margin_y1 + this.margin_y2)); + limit = ExtMath.clampi(limit, 0, 0x7fffffff); + this.text_y = ExtMath.clampi(this.text_y, -limit, 0); + } + + protected void updateCursor(int offset, boolean shift, int x1, int y1, int x2, int y2) { + Vec2i coord = Drawing.txt_coord(offset, x1, y1 + this.text_y, + x1 + this.text_x, y1 + this.text_y, this.pos_x + x2, 0x7fffffff, this.text); + this.cursorX = coord.xpos; + this.cursorY = coord.ypos; + if(shift) { + if(this.cursorY < y1) + this.text_y += y1 - this.cursorY; + else if((this.cursorY + Font.YGLYPH) >= (y1 + y2)) + this.text_y -= (this.cursorY + Font.YGLYPH) - (y1 + y2); + gui_text_update_cur(offset, false); + } + } + + protected int onCursorOffset(int x, int y, int x1, int y1, int x2, int y2) { + Offset off = Drawing.txt_offset(x, y, x1, y1 + this.text_y, + x1 + this.text_x, y1 + this.text_y, this.pos_x + x2, 0x7fffffff, this.text); + if(off != null) { + this.cursorX = off.xpos; + this.cursorY = off.ypos; + } + int offset = off == null ? 0 : off.offset; + if(y < y1) + this.scrollPos = y1 - y; + else if(y >= (y1 + y2)) + this.scrollPos = -(y - (y1 + y2)); + return offset; + } + + protected void drawForeground(int x1, int y1, int x2, int y2) { + Drawing.txt_draw(x1, y1 + this.text_y, + x1 + this.text_x, y1 + this.text_y, + this.pos_x + x2, Integer.MAX_VALUE, this.enabled ? this.gm.style.text_field : Util.mulColor(this.gm.style.text_field, 0.5f), this.text); + if(this.sel_start >= 0 && this.sel_end != this.sel_start) + Drawing.txt_overlay(this.sel_start, this.sel_end, x1, y1 + this.text_y, + x1 + this.text_x, y1 + this.text_y, + this.pos_x + x2, Integer.MAX_VALUE, this.enabled ? 0x808080ff : 0x80404040, this.text); + } + + protected char getNewline() { + return '\n'; + } + + protected int getCursorX(int x1, int x2) { + return this.cursorX; + } + + protected int getCursorY(int y1, int y2) { + return this.cursorY; + } +} diff --git a/client/src/client/gui/element/ButtonCallback.java b/client/src/client/gui/element/ButtonCallback.java new file mode 100644 index 0000000..b22d24e --- /dev/null +++ b/client/src/client/gui/element/ButtonCallback.java @@ -0,0 +1,5 @@ +package client.gui.element; + +public interface ButtonCallback { + void use(ActButton elem, PressType action); +} \ No newline at end of file diff --git a/client/src/client/gui/element/Dropdown.java b/client/src/client/gui/element/Dropdown.java index 6ba417f..a49b053 100644 --- a/client/src/client/gui/element/Dropdown.java +++ b/client/src/client/gui/element/Dropdown.java @@ -64,18 +64,14 @@ public class Dropdown extends Element { } } - public static interface Callback { - void use(Dropdown elem, T value); - } - - private final Callback func; + private final DropdownCallback func; private final T[] values; private final Handle handle; private final int def; private int value; - public Dropdown(int x, int y, int w, int h, boolean up, T[] values, T def, T init, Callback callback, Formatter> formatter) { + public Dropdown(int x, int y, int w, int h, boolean up, T[] values, T def, T init, DropdownCallback callback, Formatter> formatter) { super(x, y, w, h, formatter); this.func = callback; this.values = values; @@ -85,7 +81,7 @@ public class Dropdown extends Element { this.formatText(); } - public Dropdown(int x, int y, int w, int h, boolean up, T[] values, T def, T init, Callback callback, final String text) { + public Dropdown(int x, int y, int w, int h, boolean up, T[] values, T def, T init, DropdownCallback callback, final String text) { this(x, y, w, h, up, values, def, init, callback, new Formatter>() { public String use(Dropdown elem) { T value = elem.getValue(); diff --git a/client/src/client/gui/element/DropdownCallback.java b/client/src/client/gui/element/DropdownCallback.java new file mode 100644 index 0000000..4161d31 --- /dev/null +++ b/client/src/client/gui/element/DropdownCallback.java @@ -0,0 +1,5 @@ +package client.gui.element; + +public interface DropdownCallback { + void use(Dropdown elem, T value); +} \ No newline at end of file diff --git a/client/src/client/gui/element/Field.java b/client/src/client/gui/element/Field.java new file mode 100644 index 0000000..bd82813 --- /dev/null +++ b/client/src/client/gui/element/Field.java @@ -0,0 +1,194 @@ +package client.gui.element; + +import client.gui.Font; +import client.renderer.Drawing; +import client.renderer.Drawing.Offset; +import client.renderer.Drawing.Vec2i; +import common.util.CharValidator; +import common.util.ExtMath; +import common.util.Util; + +public class Field extends Textbox { + private int textWidth; + private int scrollPos; + private int cursorPos; + + private Field(int x, int y, int w, int h, int cap, boolean editable, FieldCallback callback, CharValidator validator, String text) { + super(x, y, w, h, cap, editable, callback, validator); + this.text_y = (this.size_y - (this.margin_y1 + this.margin_y2 + Font.YGLYPH)) / 2; + this.setText(text); + } + + public Field(int x, int y, int w, int h, int cap, FieldCallback callback, CharValidator validator, String text) { + this(x, y, w, h, cap, true, callback, validator, text); + } + + public Field(int x, int y, int w, int h, int cap, FieldCallback callback, String text) { + this(x, y, w, h, cap, true, callback, null, text); + } + + public Field(int x, int y, int w, int h, String text) { + this(x, y, w, h, Integer.MAX_VALUE, false, null, null, text); + } + + public void updateText() { + this.textWidth = Drawing.txt_size(this.pos_x + this.margin_x1, this.pos_y + this.margin_y1, + this.pos_x + this.margin_x1, this.pos_y + this.margin_y1, + Integer.MAX_VALUE, Integer.MAX_VALUE, this.text).xpos; + } + + public void mouserel() { + this.scrollPos = 0; + } + + public void onReturn(boolean shift) { + if(this.func != null) { + this.func.use(this, shift ? FieldAction.LINE : FieldAction.SEND); + } + } + + public void onSelection(boolean up) { + if(this.func != null) { + this.func.use(this, up ? FieldAction.PREVIOUS : FieldAction.NEXT); + } + } + + public void update() { + if(this.scrollPos != 0) { + int n = this.updateScroll(this.scrollPos); + this.text_x += n; + if(n != 0) + gui_text_clamp_scroll(); + } + } + + public void shift(int shift_x, int shift_y) { + super.shift(shift_x, shift_y); + this.cursorPos += shift_x; + } + + public void scroll(int scr_x, int scr_y, int x, int y, boolean ctrl, boolean shift) { + if(scr_y != 0 || scr_x != 0) { + int limit = Font.XGLYPH + this.textWidth - (this.size_x - (this.margin_x1 + this.margin_x2)); + limit = ExtMath.clampi(limit, 0, 0x7fffffff); + int prev = this.text_x; + this.text_x += ((scr_y != 0 ? scr_y : (-scr_x)) < 0 ? -1 : 1) * (ctrl ? 1 : Font.XGLYPH) * this.gm.scrollLines * (shift ? 10 : 1); + this.text_x = ExtMath.clampi(this.text_x, -limit, 0); + if(this.sel_start >= 0) + this.cursorPos += (this.text_x - prev); + } + } + + protected int getCursorX(int x1, int x2) { + return this.cursorPos; + } + + protected int getCursorY(int y1, int y2) { + return y1 + (y2 - Font.YGLYPH) / 2; + } + + protected void gui_text_clamp_scroll() { + int limit = Font.XGLYPH + this.textWidth - (this.size_x - (this.margin_x1 + this.margin_x2)); + limit = ExtMath.clampi(limit, 0, 0x7fffffff); + this.text_x = ExtMath.clampi(this.text_x, -limit, 0); + } + + protected void updateCursor(int offset, boolean shift, int x1, int y1, int x2, int y2) { + Vec2i coord = Drawing.txt_coord(offset, x1 + this.text_x, y1 + this.text_y, + x1 + this.text_x, y1 + this.text_y, 0x7fffffff, 0x7fffffff, this.text); + this.cursorPos = coord.xpos; + if(shift) { + if(this.cursorPos < x1) + this.text_x += x1 - this.cursorPos; + else if((this.cursorPos + Font.XGLYPH) >= (x1 + x2)) + this.text_x -= (this.cursorPos + Font.XGLYPH) - (x1 + x2); + gui_text_update_cur(offset, false); + } + } + + protected int onCursorOffset(int x, int y, int x1, int y1, int x2, int y2) { + Offset off = Drawing.txt_offset(x, y, x1 + this.text_x, y1 + this.text_y, + x1 + this.text_x, y1 + this.text_y, 0x7fffffff, 0x7fffffff, this.text); + if(off != null) { + this.cursorPos = off.xpos; + } + int offset = off == null ? 0 : off.offset; + if(x < x1) + this.scrollPos = x1 - x; + else if(x >= (x1 + x2)) + this.scrollPos = -(x - (x1 + x2)); + return offset; + } + + protected void drawBackground() { + if(this.enabled) + Drawing.drawGradientBorder(this.pos_x, this.pos_y, this.size_x, this.size_y, this.gm.style.field_top, this.gm.style.field_btm, 0xff000000, this.gm.style.brdr_top, this.gm.style.brdr_btm); + else + Drawing.drawGradientBorder(this.pos_x, this.pos_y, this.size_x, this.size_y, Util.mulColor(this.gm.style.field_top, 0.5f), Util.mulColor(this.gm.style.field_btm, 0.5f), 0xff000000, Util.mulColor(this.gm.style.brdr_top, 0.5f), Util.mulColor(this.gm.style.brdr_btm, 0.5f)); + } + + protected void drawForeground(int x1, int y1, int x2, int y2) { + Drawing.txt_draw(x1 + this.text_x, y1 + this.text_y, + x1 + this.text_x, y1 + this.text_y, + Integer.MAX_VALUE, Integer.MAX_VALUE, this.enabled ? this.gm.style.text_field : Util.mulColor(this.gm.style.text_field, 0.5f), this.text); + if(this.sel_start >= 0 && this.sel_end != this.sel_start) + Drawing.txt_overlay(this.sel_start, this.sel_end, x1 + this.text_x, y1 + this.text_y, + x1 + this.text_x, y1 + this.text_y, + Integer.MAX_VALUE, Integer.MAX_VALUE, this.enabled ? 0x808080ff : 0x80404040, this.text); + } + + protected char getNewline() { + return ' '; + } + + + + + + + + public void deleteSpaceToCur() { + int num = this.getSpaceBeforeCur() - this.sel_start; + if(this.text.length() != 0) { + if(this.sel_start != this.sel_end) { + this.insertText(""); + } + else { +// boolean flag = num < 0; + int i = this.sel_start + num; // flag ? this.sel_start + num : this.sel_start; + int j = this.sel_start; // flag ? this.sel_start : this.sel_start + num; + String s = ""; + + if(i >= 0) { + s = this.text.substring(0, i); + } + + if(j < this.text.length()) { + s = s + this.text.substring(j); + } + +// this.setText(s); + this.text = s; + this.updateText(); + this.sel_start = this.sel_end = this.sel_drag = i; + gui_text_update_cur(this.sel_start, true); +// +// if(flag) { +// this.moveCursorBy(num); +// } + } + } + } + + public int getSpaceBeforeCur() { + int i = this.sel_start; + while(i > 0 && this.text.charAt(i - 1) != ' ') { + --i; + } + return i; + } + + public int getCursorPos() { + return this.sel_start == this.sel_end ? this.sel_start : -1; + } +} diff --git a/client/src/client/gui/element/FieldAction.java b/client/src/client/gui/element/FieldAction.java new file mode 100644 index 0000000..e28413d --- /dev/null +++ b/client/src/client/gui/element/FieldAction.java @@ -0,0 +1,5 @@ +package client.gui.element; + +public enum FieldAction { + FOCUS, UNFOCUS, PREVIOUS, NEXT, FUNCTION, SEND, LINE, FORWARD, BACKWARD; +} \ No newline at end of file diff --git a/client/src/client/gui/element/FieldCallback.java b/client/src/client/gui/element/FieldCallback.java new file mode 100644 index 0000000..09d2ada --- /dev/null +++ b/client/src/client/gui/element/FieldCallback.java @@ -0,0 +1,5 @@ +package client.gui.element; + +public interface FieldCallback extends TextCallback { + void use(Field elem, FieldAction value); +} \ No newline at end of file diff --git a/client/src/client/gui/element/NavButton.java b/client/src/client/gui/element/NavButton.java index f1722b8..a80d9c4 100644 --- a/client/src/client/gui/element/NavButton.java +++ b/client/src/client/gui/element/NavButton.java @@ -9,8 +9,8 @@ public class NavButton extends ActButton { private final Gui navGui; public NavButton(int x, int y, int w, int h, Gui gui, String text) { - super(x, y, w, h, new Callback() { - public void use(ActButton elem, Mode action) { + super(x, y, w, h, new ButtonCallback() { + public void use(ActButton elem, PressType action) { Client.CLIENT.displayGuiScreen(gui); } }, text); diff --git a/client/src/client/gui/element/PasswordBox.java b/client/src/client/gui/element/PasswordBox.java deleted file mode 100644 index de104bb..0000000 --- a/client/src/client/gui/element/PasswordBox.java +++ /dev/null @@ -1,27 +0,0 @@ -package client.gui.element; - -import client.gui.Font; -import client.renderer.Drawing; -import common.util.Util; - -public class PasswordBox extends Textbox { - public PasswordBox(int x, int y, int w, int h, int cap, Callback callback, String text) { - super(x, y, w, h, cap, true, callback, text); - } - - protected void drawForeground(int x1, int y1, int x2, int y2) { - Drawing.txt_draw(x1 + this.text_x, y1 + this.text_y, - x1 + this.text_x, y1 + this.text_y, - Integer.MAX_VALUE, Integer.MAX_VALUE, this.enabled ? this.gm.style.text_field : Util.mulColor(this.gm.style.text_field, 0.5f), this.text.isEmpty() ? "" : "****"); - } - - public void drawOverlay() { - if(Util.ftime() % 1.0f < 0.5f) { - int x1 = this.pos_x + this.margin_x1; - int y1 = this.pos_y + this.margin_y1; - int x2 = this.size_x - (this.margin_x1 + this.margin_x2); - int y2 = this.size_y - (this.margin_y1 + this.margin_y2); - Drawing.drawRect(x1, y1 + (y2 - Font.YGLYPH) / 2, 1, Font.YGLYPH, 0xff000000 | (~Util.mixColor(this.gm.style.field_top, this.gm.style.field_btm))); - } - } -} diff --git a/client/src/client/gui/element/PasswordField.java b/client/src/client/gui/element/PasswordField.java new file mode 100644 index 0000000..efd3d9a --- /dev/null +++ b/client/src/client/gui/element/PasswordField.java @@ -0,0 +1,20 @@ +package client.gui.element; + +import client.renderer.Drawing; +import common.util.Util; + +public class PasswordField extends Field { + public PasswordField(int x, int y, int w, int h, int cap, FieldCallback callback, String text) { + super(x, y, w, h, cap, callback, text); + } + + protected void drawForeground(int x1, int y1, int x2, int y2) { + Drawing.txt_draw(x1 + this.text_x, y1 + this.text_y, + x1 + this.text_x, y1 + this.text_y, + Integer.MAX_VALUE, Integer.MAX_VALUE, this.enabled ? this.gm.style.text_field : Util.mulColor(this.gm.style.text_field, 0.5f), this.text.isEmpty() ? "" : "****"); + } + + protected int getCursorX(int x1, int x2) { + return x1; + } +} diff --git a/client/src/client/gui/element/PressType.java b/client/src/client/gui/element/PressType.java new file mode 100644 index 0000000..4424611 --- /dev/null +++ b/client/src/client/gui/element/PressType.java @@ -0,0 +1,5 @@ +package client.gui.element; + +public enum PressType { + PRIMARY, SECONDARY, TERTIARY; +} \ No newline at end of file diff --git a/client/src/client/gui/element/SelectableButton.java b/client/src/client/gui/element/SelectableButton.java index 699121d..b9888a2 100644 --- a/client/src/client/gui/element/SelectableButton.java +++ b/client/src/client/gui/element/SelectableButton.java @@ -6,7 +6,7 @@ import common.util.Util; public class SelectableButton extends ActButton { private boolean selected; - public SelectableButton(int x, int y, int w, int h, Callback callback, String text, boolean selected) { + public SelectableButton(int x, int y, int w, int h, ButtonCallback callback, String text, boolean selected) { super(x, y, w, h, callback, text); this.selected = selected; } diff --git a/client/src/client/gui/element/Slider.java b/client/src/client/gui/element/Slider.java index 45bb1e7..347cef9 100644 --- a/client/src/client/gui/element/Slider.java +++ b/client/src/client/gui/element/Slider.java @@ -7,17 +7,9 @@ import common.util.ExtMath; import common.util.Util; public class Slider extends Element { - public static interface Callback { - void use(Slider elem, int value); - } - - public static interface FloatCallback { - void use(Slider elem, float value); - } - private static final int SLIDER_WIDTH = 10; - private final Callback func; + private final SliderCallback func; private final int def; private final int min; private final int max; @@ -27,7 +19,7 @@ public class Slider extends Element { private int value; private int position; - public Slider(int x, int y, int w, int h, int prec, int min, int max, int def, int init, Callback callback, Formatter formatter) { + public Slider(int x, int y, int w, int h, int prec, int min, int max, int def, int init, SliderCallback callback, Formatter formatter) { super(x, y, w, h, formatter); this.handle = ((this.size_y * SLIDER_WIDTH) / 24) & ~1; this.func = callback; @@ -40,7 +32,7 @@ public class Slider extends Element { this.formatText(); } - public Slider(int x, int y, int w, int h, int prec, int min, int max, int def, int init, Callback callback, final String text) { + public Slider(int x, int y, int w, int h, int prec, int min, int max, int def, int init, SliderCallback callback, final String text) { this(x, y, w, h, prec, min, max, def, init, callback, new Formatter() { public String use(Slider elem) { return String.format("%s: %d", text, elem.value); @@ -48,7 +40,7 @@ public class Slider extends Element { }); } - public Slider(int x, int y, int w, int h, int prec, int min, int max, int def, int init, Callback callback, final String text, final String unit) { + public Slider(int x, int y, int w, int h, int prec, int min, int max, int def, int init, SliderCallback callback, final String text, final String unit) { this(x, y, w, h, prec, min, max, def, init, callback, new Formatter() { private final String format = unit.isEmpty() ? "%s: %d" : "%s: %d %s"; @@ -58,15 +50,15 @@ public class Slider extends Element { }); } - public Slider(int x, int y, int w, int h, int prec, float min, float max, float def, float init, final FloatCallback callback, Formatter formatter) { - this(x, y, w, h, prec, (int)(min * 1000.0f), (int)(max * 1000.0f), (int)(def * 1000.0f), (int)(init * 1000.0f), new Callback() { + public Slider(int x, int y, int w, int h, int prec, float min, float max, float def, float init, final SliderFloatCallback callback, Formatter formatter) { + this(x, y, w, h, prec, (int)(min * 1000.0f), (int)(max * 1000.0f), (int)(def * 1000.0f), (int)(init * 1000.0f), new SliderCallback() { public void use(Slider elem, int value) { callback.use(elem, (float)value / 1000.0f); } }, formatter); } - public Slider(int x, int y, int w, int h, final int prec, float min, float max, float def, float init, FloatCallback callback, final String text, final String unit) { + public Slider(int x, int y, int w, int h, final int prec, float min, float max, float def, float init, SliderFloatCallback callback, final String text, final String unit) { this(x, y, w, h, prec < 0 ? 0 : prec, min, max, def, init, callback, new Formatter() { private final String format = "%s: " + (prec <= 0 ? "%d" : ("%." + prec + "f")) + (unit.isEmpty() ? "" : " %s"); diff --git a/client/src/client/gui/element/SliderCallback.java b/client/src/client/gui/element/SliderCallback.java new file mode 100644 index 0000000..4ed60b0 --- /dev/null +++ b/client/src/client/gui/element/SliderCallback.java @@ -0,0 +1,5 @@ +package client.gui.element; + +public interface SliderCallback { + void use(Slider elem, int value); +} \ No newline at end of file diff --git a/client/src/client/gui/element/SliderFloatCallback.java b/client/src/client/gui/element/SliderFloatCallback.java new file mode 100644 index 0000000..ca24df3 --- /dev/null +++ b/client/src/client/gui/element/SliderFloatCallback.java @@ -0,0 +1,5 @@ +package client.gui.element; + +public interface SliderFloatCallback { + void use(Slider elem, float value); +} \ No newline at end of file diff --git a/client/src/client/gui/element/Switch.java b/client/src/client/gui/element/Switch.java index 6053cd2..878ebcc 100644 --- a/client/src/client/gui/element/Switch.java +++ b/client/src/client/gui/element/Switch.java @@ -6,17 +6,13 @@ import common.util.Displayable; import common.util.Util; public class Switch extends Element { - public static interface Callback { - void use(Switch elem, T value); - } - - private final Callback func; + private final SwitchCallback func; private final T[] values; private final int def; private int value; - public Switch(int x, int y, int w, int h, T[] values, T def, T init, Callback callback, Formatter> formatter) { + public Switch(int x, int y, int w, int h, T[] values, T def, T init, SwitchCallback callback, Formatter> formatter) { super(x, y, w, h, formatter); this.func = callback; this.values = values; @@ -25,7 +21,7 @@ public class Switch extends Element { this.formatText(); } - public Switch(int x, int y, int w, int h, T[] values, T def, T init, Callback callback, final String text) { + public Switch(int x, int y, int w, int h, T[] values, T def, T init, SwitchCallback callback, final String text) { this(x, y, w, h, values, def, init, callback, new Formatter>() { public String use(Switch elem) { T value = elem.getValue(); diff --git a/client/src/client/gui/element/SwitchCallback.java b/client/src/client/gui/element/SwitchCallback.java new file mode 100644 index 0000000..2893e44 --- /dev/null +++ b/client/src/client/gui/element/SwitchCallback.java @@ -0,0 +1,5 @@ +package client.gui.element; + +public interface SwitchCallback { + void use(Switch elem, T value); +} \ No newline at end of file diff --git a/client/src/client/gui/element/TextCallback.java b/client/src/client/gui/element/TextCallback.java new file mode 100644 index 0000000..c014c89 --- /dev/null +++ b/client/src/client/gui/element/TextCallback.java @@ -0,0 +1,5 @@ +package client.gui.element; + +interface TextCallback { + void use(T elem, FieldAction value); +} \ No newline at end of file diff --git a/client/src/client/gui/element/Textbox.java b/client/src/client/gui/element/Textbox.java index 533e160..fa82c1a 100644 --- a/client/src/client/gui/element/Textbox.java +++ b/client/src/client/gui/element/Textbox.java @@ -5,97 +5,44 @@ import org.lwjgl.opengl.GL11; import client.Timing; import client.gui.Font; import client.renderer.Drawing; -import client.renderer.Drawing.Offset; -import client.renderer.Drawing.Vec2i; import client.window.Button; import client.window.Keysym; import client.window.Window; import common.util.CharValidator; -import common.util.ExtMath; import common.util.Util; -public class Textbox extends Element { - public static enum Action { - FOCUS, UNFOCUS, PREVIOUS, NEXT, FUNCTION, SEND, LINE, FORWARD, BACKWARD; - } +abstract class Textbox extends Element { + protected final TextCallback func; + protected final CharValidator validator; + protected final int capacity; + protected final boolean editable; - public static interface Callback { - void use(Textbox elem, Action value); - } - - private final Callback func; - private final CharValidator validator; - private final int capacity; - private final boolean xbreak; - private final boolean editable; - - private long tmr_scroll; - private long tmr_leftmb; - private int scrollx; - private int scrolly; - private int sel_start = -1; - private int sel_end = -1; - private int sel_drag = -1; - private int cursorX = 0; - private int cursorY = 0; - private int tsize_x = 0; - private int tsize_y = 0; + protected long tmr_scroll; + protected long tmr_leftmb; + protected int sel_start = -1; + protected int sel_end = -1; + protected int sel_drag = -1; - private Textbox(int x, int y, int w, int h, int cap, boolean line, boolean editable, Callback callback, CharValidator validator, String text) { + protected Textbox(int x, int y, int w, int h, int cap, boolean editable, TextCallback callback, CharValidator validator) { super(x, y, w, h, null); this.func = callback; this.validator = validator; this.capacity = cap; - this.xbreak = !line; this.editable = editable; - if(line) - this.text_y = (this.size_y - (this.margin_y1 + this.margin_y2 + Font.YGLYPH)) / 2; - this.setText(text); - } - - public Textbox(int x, int y, int w, int h, int cap, boolean line, Callback callback, String text) { - this(x, y, w, h, cap, line, true, callback, null, text); - } - - public Textbox(int x, int y, int w, int h, int cap, boolean line, Callback callback, CharValidator validator, String text) { - this(x, y, w, h, cap, line, true, callback, validator, text); - } - - public Textbox(int x, int y, int w, int h, int cap, Callback callback, String text) { - this(x, y, w, h, cap, false, true, callback, null, text); - } - - public Textbox(int x, int y, int w, int h, String text) { - this(x, y, w, h, Integer.MAX_VALUE, false, false, null, null, text); - } - - public Textbox(int x, int y, int w, int h, boolean line, String text) { - this(x, y, w, h, Integer.MAX_VALUE, line, false, null, null, text); } -// public void setEditable(boolean editable) { -// this.editable = editable; -// } - -// protected boolean isTextCenteredX() { -// return false; -// } -// -// protected boolean isTextCenteredY() { -// return false; -// } - -// protected boolean hasLinebreak() { -// return this.xbreak; -// } - - public void updateText() { - Vec2i size = Drawing.txt_size(this.pos_x + this.margin_x1, this.pos_y + this.margin_y1, - this.pos_x + this.margin_x1, this.pos_y + this.margin_y1, - this.xbreak ? (this.pos_x + (this.size_x - (this.margin_x1 + this.margin_x2))) : Integer.MAX_VALUE, Integer.MAX_VALUE, this.text); - this.tsize_x = size.xpos; - this.tsize_y = size.ypos; - } + public abstract void updateText(); + protected abstract void onReturn(boolean shift); + protected abstract void onSelection(boolean up); + public abstract void scroll(int scr_x, int scr_y, int x, int y, boolean ctrl, boolean shift); + public abstract void update(); + protected abstract void gui_text_clamp_scroll(); + protected abstract void updateCursor(int offset, boolean shift, int x1, int y1, int x2, int y2); + protected abstract char getNewline(); + protected abstract int getCursorX(int x1, int x2); + protected abstract int getCursorY(int y1, int y2); + protected abstract int onCursorOffset(int x, int y, int x1, int y1, int x2, int y2); + protected abstract void drawForeground(int x1, int y1, int x2, int y2); public boolean canHover() { return false; @@ -114,35 +61,11 @@ public class Textbox extends Element { gui_text_update_cur(this.sel_start, true); } - public void scroll(int scr_x, int scr_y, int x, int y, boolean ctrl, boolean shift) { - if(scr_y != 0 && this.xbreak) { - int limit = Font.YGLYPH + this.tsize_y - (this.size_y - (this.margin_y1 + this.margin_y2)); - limit = ExtMath.clampi(limit, 0, 0x7fffffff); - int prev = this.text_y; - this.text_y += (scr_y < 0 ? -1 : 1) * (ctrl ? 1 : Font.YGLYPH) * this.gm.scrollLines * (shift ? 10 : 1); - this.text_y = ExtMath.clampi(this.text_y, -limit, 0); - if(this.sel_start >= 0) - this.cursorY += (this.text_y - prev); -// this.r_dirty = true; - } - else if(scr_y != 0 || scr_x != 0) { - int limit = Font.XGLYPH + this.tsize_x - (this.size_x - (this.margin_x1 + this.margin_x2)); - limit = ExtMath.clampi(limit, 0, 0x7fffffff); - int prev = this.text_x; - this.text_x += ((scr_y != 0 ? scr_y : (-scr_x)) < 0 ? -1 : 1) * (ctrl ? 1 : Font.XGLYPH) * this.gm.scrollLines * (shift ? 10 : 1); - this.text_x = ExtMath.clampi(this.text_x, -limit, 0); - if(this.sel_start >= 0) - this.cursorX += (this.text_x - prev); -// this.r_dirty = true; - } - } - public void mouse(Button btn, int x, int y, boolean ctrl, boolean shift) { if(btn == Button.MOUSE_LEFT) { if(!shift && ((Timing.tmr_current - this.tmr_leftmb) <= (((long)this.gm.dclickDelay) * 1000L))) { this.sel_start = this.sel_drag = 0; this.sel_end = this.text.length(); -// this.r_dirty = true; } else { gui_text_select(x, y, shift); @@ -150,41 +73,28 @@ public class Textbox extends Element { this.tmr_leftmb = Timing.tmr_current; } else if((btn == Button.MOUSE_MIDDLE) && this.func != null) { - this.func.use(this, Action.FUNCTION); + this.func.use(this, FieldAction.FUNCTION); } } - public void mouserel() { - this.scrollx = this.scrolly = 0; - } - public void drag(int x, int y) { gui_text_select(x, y, true); } public void character(char code) { - if(this.editable) { -// int pos = 0; -// char chr[8]; -// utf_rwriten(chr, &pos, 8, code); -// chr[pos] = 0; + if(this.editable) insertText(Character.toString(code)); - } } public void key(Keysym key, boolean ctrl, boolean shift) { if(ctrl && key == Keysym.A) { this.sel_start = this.sel_drag = 0; this.sel_end = this.text.length(); -// this.r_dirty = true; } else if(ctrl && (key == Keysym.C) || (this.editable && (key == Keysym.X))) { if(this.sel_start >= 0 && this.sel_start != this.sel_end) { // fix empty - // char end = this.text[this.sel_end]; - // this.text[this.sel_end] = 0; String str = Util.strip(this.text, this.sel_start, this.sel_end - this.sel_start, '\n', (char)0, '?'); Window.setClipboard(str); - // this.text[this.sel_end] = end; if(key == Keysym.X) insertText(""); } @@ -193,12 +103,7 @@ public class Textbox extends Element { insertText(Window.getClipboard()); } else if(this.editable && !ctrl && key == Keysym.RETURN) { - if(this.xbreak) { - insertText("\n"); - } - else if(this.func != null) { - this.func.use(this, shift ? Action.LINE : Action.SEND); - } + this.onReturn(shift); } else if(this.editable && (!ctrl) && (key == Keysym.BACKSPACE || key == Keysym.DELETE)) { if(this.sel_start != this.sel_end) { @@ -242,150 +147,60 @@ public class Textbox extends Element { } } else if(!ctrl && (key == Keysym.DOWN || key == Keysym.UP)) { - if(this.xbreak) { - if(key == Keysym.DOWN && this.sel_start != this.sel_end) { - this.sel_start = this.sel_drag = this.sel_end; - } - else if(key == Keysym.UP && this.sel_start != this.sel_end) { - this.sel_end = this.sel_drag = this.sel_start; - } - if(key == Keysym.DOWN && this.sel_start >= 0) { - if(this.sel_end < this.text.length()) { - // char ch = this.text.charAt(this.sel_end); - // this.sel_end += 1; - int nl = this.text.indexOf('\n', this.sel_end); - // while(ch && ch != '\n') { - // ch = utf_readn(this.text, &this.sel_end); - // } - this.sel_end = nl >= 0 ? nl + 1 : this.text.length(); - // else - // this.sel_end -= 1; - this.sel_start = this.sel_drag = this.sel_end; - } - else { - this.sel_end = this.sel_drag = this.sel_start; - } - gui_text_update_cur(this.sel_end, true); - } - else if(key == Keysym.UP && this.sel_start >= 0) { - // uint ch; - if(this.sel_start > 0) { - int nl = this.text.lastIndexOf('\n', this.sel_start); - this.sel_start = nl >= 0 ? nl : 0; - // do { - // ch = utf_rreadn(this.text, &this.sel_start); - // } - // while(ch && ch != '\n'); - } - this.sel_end = this.sel_drag = this.sel_start; - gui_text_update_cur(this.sel_end, true); - } - } - else if(this.func != null) { - this.func.use(this, (key == Keysym.DOWN) ? Action.NEXT : Action.PREVIOUS); - } + this.onSelection(key == Keysym.UP); } else if((!ctrl) && key == Keysym.TAB) { if(this.func != null) { - this.func.use(this, shift ? Action.BACKWARD : Action.FORWARD); + this.func.use(this, shift ? FieldAction.BACKWARD : FieldAction.FORWARD); } } } public void select() { if(this.func != null) { - this.func.use(this, Action.FOCUS); + this.func.use(this, FieldAction.FOCUS); } } public void deselect() { this.sel_start = this.sel_end = this.sel_drag = -1; this.tmr_leftmb = 0L; -// this.r_dirty = true; if(this.func != null) { - this.func.use(this, Action.UNFOCUS); + this.func.use(this, FieldAction.UNFOCUS); } } - public void update() { - if((this.scrollx != 0 && !(this.xbreak)) || (this.scrolly != 0 && this.xbreak)) { - int n; - if(!this.xbreak) - this.text_x += (n = (int)((float)((float)this.tmr_scroll) / 1000000.0f * 4.0f * ((float)this.scrollx))); - else - this.text_y += (n = (int)((float)((float)this.tmr_scroll) / 1000000.0f * 4.0f * ((float)this.scrolly))); - if(n != 0) { - gui_text_clamp_scroll(); -// this.r_dirty = true; - } + protected int updateScroll(int value) { + if(value != 0) { + int n = (int)((float)((float)this.tmr_scroll) / 1000000.0f * 4.0f * ((float)value)); if((((long)n) * 1000000L) <= this.tmr_scroll) this.tmr_scroll -= ((long)n) * 1000000L; else this.tmr_scroll = 0L; this.tmr_scroll += Timing.tmr_delta; + return n; } + return 0; } - public void shift(int shift_x, int shift_y) { - super.shift(shift_x, shift_y); - this.cursorX += shift_x; - this.cursorY += shift_y; - } - - private void gui_text_clamp_scroll() { - int limit; - if(this.xbreak) { - limit = Font.YGLYPH + this.tsize_y - (this.size_y - (this.margin_y1 + this.margin_y2)); - limit = ExtMath.clampi(limit, 0, 0x7fffffff); - this.text_y = ExtMath.clampi(this.text_y, -limit, 0); - } - else { - limit = Font.XGLYPH + this.tsize_x - (this.size_x - (this.margin_x1 + this.margin_x2)); - limit = ExtMath.clampi(limit, 0, 0x7fffffff); - this.text_x = ExtMath.clampi(this.text_x, -limit, 0); - } - } - - private void gui_text_update_cur(int offset, boolean shift) { + protected void gui_text_update_cur(int offset, boolean shift) { int x1 = this.pos_x + this.margin_x1; int y1 = this.pos_y + this.margin_y1; int x2 = this.size_x - (this.margin_x1 + this.margin_x2); int y2 = this.size_y - (this.margin_y1 + this.margin_y2); gui_text_clamp_scroll(); - Vec2i coord = Drawing.txt_coord(offset, x1 + (this.xbreak ? 0 : this.text_x), y1 + this.text_y, - x1 + this.text_x, y1 + this.text_y, this.xbreak ? (this.pos_x + x2) : 0x7fffffff, 0x7fffffff, this.text); - this.cursorX = coord.xpos; - this.cursorY = coord.ypos; - if(shift) { - if(this.xbreak && this.cursorY < y1) - this.text_y += y1 - this.cursorY; - else if(this.xbreak && (this.cursorY + Font.YGLYPH) >= (y1 + y2)) - this.text_y -= (this.cursorY + Font.YGLYPH) - (y1 + y2); - if(!(this.xbreak) && this.cursorX < x1) - this.text_x += x1 - this.cursorX; - else if(!(this.xbreak) && (this.cursorX + Font.XGLYPH) >= (x1 + x2)) - this.text_x -= (this.cursorX + Font.XGLYPH) - (x1 + x2); - gui_text_update_cur(offset, false); - } -// else { -// this.r_dirty = true; -// } + this.updateCursor(offset, shift, x1, y1, x2, y2); } public void insertText(String str) { if(str == null || (this.sel_start == -1)) return; - str = Util.strip(str, 0, str.length(), this.xbreak ? '\n' : ' ', ' ', (char)0); + str = Util.strip(str, 0, str.length(), this.getNewline(), ' ', (char)0); if(this.validator != null) str = this.validator.filter(str); - // plen = strlen(&sys.work_buf[1 + olen - this.sel_end]); - // logd("t", "%d %d %d", olen, slen, plen); if((str.length() + this.text.length() - (this.sel_end - this.sel_start)) > this.capacity) return; this.text = this.text.substring(0, this.sel_start) + str + this.text.substring(this.sel_end); - // memcpy(sys.work_buf, &this.text[this.sel_end], 1 + this.text.length() - this.sel_end); - // memcpy(&this.text[this.sel_start], &sys.work_buf[1 + this.text.length() - this.sel_end], str.length()); - // memcpy(&this.text[this.sel_start + str.length()], sys.work_buf, 1 + this.text.length() - this.sel_end); this.sel_start += str.length(); this.sel_end = this.sel_drag = this.sel_start; this.updateText(); @@ -397,15 +212,7 @@ public class Textbox extends Element { int y1 = this.pos_y + this.margin_y1; int x2 = this.size_x - (this.margin_x1 + this.margin_x2); int y2 = this.size_y - (this.margin_y1 + this.margin_y2); - Offset off = Drawing.txt_offset(x, y, x1 + (this.xbreak ? 0 : this.text_x), y1 + this.text_y, - x1 + this.text_x, y1 + this.text_y, this.xbreak ? (this.pos_x + x2) : 0x7fffffff, 0x7fffffff, this.text); - if(off != null) { - this.cursorX = off.xpos; - this.cursorY = off.ypos; - } - int offset = off == null ? 0 : off.offset; - // logd("tst", "@A %d %d -. %d %d", x1, y1, x2, y2); - // logd("tst", "@C %d %d -. %d, %d %d", x, y, offset, this.min, this.max); + int offset = this.onCursorOffset(x, y, x1, y1, x2, y2); if(!drag) { this.sel_drag = this.sel_start = this.sel_end = offset; } @@ -417,18 +224,8 @@ public class Textbox extends Element { this.sel_start = offset; this.sel_end = this.sel_drag; } - // logd("tst", "@S %d . %d . %d", this.sel_start, this.sel_drag, this.sel_end); -// this.r_dirty = true; - if(x < x1) - this.scrollx = x1 - x; - else if(x >= (x1 + x2)) - this.scrollx = -(x - (x1 + x2)); - if(y < y1) - this.scrolly = y1 - y; - else if(y >= (y1 + y2)) - this.scrolly = -(y - (y1 + y2)); } - + protected void drawBackground() { if(this.enabled) Drawing.drawGradientBorder(this.pos_x, this.pos_y, this.size_x, this.size_y, this.gm.style.field_top, this.gm.style.field_btm, 0xff000000, this.gm.style.brdr_top, this.gm.style.brdr_btm); @@ -436,16 +233,6 @@ public class Textbox extends Element { Drawing.drawGradientBorder(this.pos_x, this.pos_y, this.size_x, this.size_y, Util.mulColor(this.gm.style.field_top, 0.5f), Util.mulColor(this.gm.style.field_btm, 0.5f), 0xff000000, Util.mulColor(this.gm.style.brdr_top, 0.5f), Util.mulColor(this.gm.style.brdr_btm, 0.5f)); } - protected void drawForeground(int x1, int y1, int x2, int y2) { - Drawing.txt_draw(x1 + (this.xbreak ? 0 : this.text_x), y1 + this.text_y, - x1 + this.text_x, y1 + this.text_y, - this.xbreak ? (this.pos_x + x2) : Integer.MAX_VALUE, Integer.MAX_VALUE, this.enabled ? this.gm.style.text_field : Util.mulColor(this.gm.style.text_field, 0.5f), this.text); - if(this.sel_start >= 0 && this.sel_end != this.sel_start) - Drawing.txt_overlay(this.sel_start, this.sel_end, x1 + (this.xbreak ? 0 : this.text_x), y1 + this.text_y, - x1 + this.text_x, y1 + this.text_y, - this.xbreak ? (this.pos_x + x2) : Integer.MAX_VALUE, Integer.MAX_VALUE, this.enabled ? 0x808080ff : 0x80404040, this.text); - } - public void drawOverlay() { if(this.editable && this.sel_start >= 0 && this.sel_end == this.sel_start && Util.ftime() % 1.0f < 0.5f) { int x1 = this.pos_x + this.margin_x1; @@ -454,61 +241,8 @@ public class Textbox extends Element { int y2 = this.size_y - (this.margin_y1 + this.margin_y2); GL11.glScissor(x1 < 0 ? 0 : x1, (this.gm.fb_y - (y1 + y2)) < 0 ? 0 : (this.gm.fb_y - (y1 + y2)), x2 < 0 ? 0 : x2, y2 < 0 ? 0 : y2); GL11.glEnable(GL11.GL_SCISSOR_TEST); - Drawing.drawRect(this.cursorX, this.cursorY, 1, Font.YGLYPH, 0xff000000 | (~Util.mixColor(this.gm.style.field_top, this.gm.style.field_btm))); + Drawing.drawRect(this.getCursorX(x1, x2), this.getCursorY(y1, y2), 1, Font.YGLYPH, 0xff000000 | (~Util.mixColor(this.gm.style.field_top, this.gm.style.field_btm))); GL11.glDisable(GL11.GL_SCISSOR_TEST); } } - - - - - - - - - - public void deleteFromCursor() { - int num = this.getNthCharFromPos() - this.sel_start; - if(this.text.length() != 0) { - if(this.sel_start != this.sel_end) { - this.insertText(""); - } - else { -// boolean flag = num < 0; - int i = this.sel_start + num; // flag ? this.sel_start + num : this.sel_start; - int j = this.sel_start; // flag ? this.sel_start : this.sel_start + num; - String s = ""; - - if(i >= 0) { - s = this.text.substring(0, i); - } - - if(j < this.text.length()) { - s = s + this.text.substring(j); - } - -// this.setText(s); - this.text = s; - this.updateText(); - this.sel_start = this.sel_end = this.sel_drag = i; - gui_text_update_cur(this.sel_start, true); -// -// if(flag) { -// this.moveCursorBy(num); -// } - } - } - } - - public int getNthCharFromPos() { - int i = this.sel_start; - while(i > 0 && this.text.charAt(i - 1) != ' ') { - --i; - } - return i; - } - - public int getCursorPosition() { - return this.sel_start == this.sel_end ? this.sel_start : -1; - } } diff --git a/client/src/client/gui/element/Toggle.java b/client/src/client/gui/element/Toggle.java index 5c4be8b..b020dd5 100644 --- a/client/src/client/gui/element/Toggle.java +++ b/client/src/client/gui/element/Toggle.java @@ -6,16 +6,12 @@ import client.window.Button; import common.util.Util; public class Toggle extends Element { - public static interface Callback { - void use(Toggle elem, boolean value); - } - - private final Callback func; + private final ToggleCallback func; private final boolean def; private boolean value; - public Toggle(int x, int y, int w, int h, boolean def, boolean init, Callback callback, Formatter formatter) { + public Toggle(int x, int y, int w, int h, boolean def, boolean init, ToggleCallback callback, Formatter formatter) { super(x, y, w, h, formatter); this.func = callback; this.def = def; @@ -23,7 +19,7 @@ public class Toggle extends Element { this.formatText(); } - public Toggle(int x, int y, int w, int h, boolean def, boolean init, Callback callback, final String text) { + public Toggle(int x, int y, int w, int h, boolean def, boolean init, ToggleCallback callback, final String text) { this(x, y, w, h, def, init, callback, new Formatter() { public String use(Toggle elem) { return String.format("%s: %s", text, elem.value ? "An" : "Aus"); diff --git a/client/src/client/gui/element/ToggleCallback.java b/client/src/client/gui/element/ToggleCallback.java new file mode 100644 index 0000000..8aa374b --- /dev/null +++ b/client/src/client/gui/element/ToggleCallback.java @@ -0,0 +1,5 @@ +package client.gui.element; + +public interface ToggleCallback { + void use(Toggle elem, boolean value); +} \ No newline at end of file diff --git a/client/src/client/gui/element/TransparentBox.java b/client/src/client/gui/element/TransparentArea.java similarity index 69% rename from client/src/client/gui/element/TransparentBox.java rename to client/src/client/gui/element/TransparentArea.java index 04f284d..d9da822 100644 --- a/client/src/client/gui/element/TransparentBox.java +++ b/client/src/client/gui/element/TransparentArea.java @@ -2,10 +2,10 @@ package client.gui.element; import client.renderer.Drawing; -public class TransparentBox extends Textbox { +public class TransparentArea extends Area { private final boolean background; - public TransparentBox(int x, int y, int w, int h, String text, boolean background) { + public TransparentArea(int x, int y, int w, int h, String text, boolean background) { super(x, y, w, h, text); this.background = background; } diff --git a/client/src/client/gui/ingame/GuiForm.java b/client/src/client/gui/ingame/GuiForm.java index dc5cce9..3533242 100644 --- a/client/src/client/gui/ingame/GuiForm.java +++ b/client/src/client/gui/ingame/GuiForm.java @@ -2,22 +2,26 @@ package client.gui.ingame; import client.gui.Gui; import client.gui.element.ActButton; -import client.gui.element.ActButton.Mode; +import client.gui.element.ButtonCallback; import client.gui.element.Element; import client.gui.element.Label; import client.gui.element.NavButton; -import client.gui.element.PasswordBox; +import client.gui.element.PasswordField; +import client.gui.element.PressType; import client.gui.element.Switch; -import client.gui.element.Textbox; -import client.gui.element.Textbox.Action; +import client.gui.element.SwitchCallback; +import client.gui.element.FieldAction; +import client.gui.element.Field; +import client.gui.element.FieldCallback; import client.gui.element.Toggle; +import client.gui.element.ToggleCallback; import client.network.ClientPlayer; import common.color.TextColor; import common.packet.CPacketForm; import common.util.ExtMath; import common.util.Triplet; -public class GuiForm extends Gui implements ActButton.Callback { +public class GuiForm extends Gui implements ButtonCallback { private final int id; private final String title; private final Element[] inputs; @@ -35,7 +39,7 @@ public class GuiForm extends Gui implements ActButton.Callback { Object obj = this.inputData[z].second; int param = this.inputData[z].third; if(obj instanceof Boolean) { - this.inputs[z] = this.add(new Toggle(0, 50 * z, 300, 24, (Boolean)obj, (Boolean)obj, new Toggle.Callback() { + this.inputs[z] = this.add(new Toggle(0, 50 * z, 300, 24, (Boolean)obj, (Boolean)obj, new ToggleCallback() { public void use(Toggle elem, boolean value) { GuiForm.this.outputData[index] = value; } @@ -44,7 +48,7 @@ public class GuiForm extends Gui implements ActButton.Callback { else if(obj instanceof String[]) { final String[] strs = (String[])obj; param = ExtMath.clampi(param, 0, strs.length - 1); - this.inputs[z] = this.add(new Switch(0, 50 * z, 300, 24, strs, strs[param], strs[param], new Switch.Callback() { + this.inputs[z] = this.add(new Switch(0, 50 * z, 300, 24, strs, strs[param], strs[param], new SwitchCallback() { public void use(Switch elem, String value) { for(int n = 0; n < strs.length; n++) { if(value == strs[n]) { @@ -57,14 +61,14 @@ public class GuiForm extends Gui implements ActButton.Callback { } else { this.labels[z] = this.add(new Label(0, 50 * z - 20, 300, 20, name, true)); - Textbox.Callback callback = new Textbox.Callback() { - public void use(Textbox elem, Action value) { - if(value == Action.FOCUS) + FieldCallback callback = new FieldCallback() { + public void use(Field elem, FieldAction value) { + if(value == FieldAction.FOCUS) GuiForm.this.labels[index].setText(name); } }; - this.inputs[z] = this.add((param & 0x80000000) != 0 ? new PasswordBox(0, 50 * z, 300, 24, Math.min(param & 0xffff, 256), callback, (String)obj) : - new Textbox(0, 50 * z, 300, 24, Math.min(param & 0xffff, 256), true, callback, (String)obj)); + this.inputs[z] = this.add((param & 0x80000000) != 0 ? new PasswordField(0, 50 * z, 300, 24, Math.min(param & 0xffff, 256), callback, (String)obj) : + new Field(0, 50 * z, 300, 24, Math.min(param & 0xffff, 256), callback, (String)obj)); } } this.add(new NavButton(0, 50 * (this.inputs.length + 1), 148, 24, null, "Abbrechen")); @@ -98,9 +102,9 @@ public class GuiForm extends Gui implements ActButton.Callback { } } - public void use(ActButton elem, Mode action) { + public void use(ActButton elem, PressType action) { for(int z = 0; z < this.inputs.length; z++) { - if(this.inputs[z] instanceof Textbox) { + if(this.inputs[z] instanceof Field) { int min = (this.inputData[z].third & 0x7fffffff) >> 16; String text = this.inputs[z].getText(); if(text.length() < min) { diff --git a/client/src/client/gui/ingame/GuiGameOver.java b/client/src/client/gui/ingame/GuiGameOver.java index d8ad0a9..ce3f7ab 100755 --- a/client/src/client/gui/ingame/GuiGameOver.java +++ b/client/src/client/gui/ingame/GuiGameOver.java @@ -2,9 +2,10 @@ package client.gui.ingame; import client.gui.Gui; import client.gui.element.ActButton; -import client.gui.element.ActButton.Mode; +import client.gui.element.ButtonCallback; import common.color.TextColor; import client.gui.element.Label; +import client.gui.element.PressType; public class GuiGameOver extends Gui { public static final GuiGameOver INSTANCE = new GuiGameOver(); @@ -19,8 +20,8 @@ public class GuiGameOver extends Gui { this.timer = 0; this.add(new Label(0, 0, 200, 20, "Du bist gestorben!")); this.add(new Label(0, 32, 200, 20, "Punktestand: " + TextColor.YELLOW + this.gm.player.experienceLevel)); - this.button = this.add(new ActButton(0, 100, 200, 24, new ActButton.Callback() { - public void use(ActButton elem, Mode action) { + this.button = this.add(new ActButton(0, 100, 200, 24, new ButtonCallback() { + public void use(ActButton elem, PressType action) { GuiGameOver.this.gm.player.respawnPlayer(); GuiGameOver.this.gm.displayGuiScreen(null); } diff --git a/client/src/client/gui/ingame/GuiSign.java b/client/src/client/gui/ingame/GuiSign.java index 65eb72c..c5530fd 100644 --- a/client/src/client/gui/ingame/GuiSign.java +++ b/client/src/client/gui/ingame/GuiSign.java @@ -3,24 +3,24 @@ package client.gui.ingame; import client.gui.Gui; import client.gui.element.Label; import client.gui.element.NavButton; -import client.gui.element.Textbox; -import client.gui.element.Textbox.Action; +import client.gui.element.FieldAction; +import client.gui.element.Field; +import client.gui.element.FieldCallback; import client.network.ClientPlayer; import common.packet.CPacketSign; import common.util.BlockPos; -public class GuiSign extends Gui implements Textbox.Callback { +public class GuiSign extends Gui implements FieldCallback { private final BlockPos position; - private final Textbox[] lines; + private final Field[] lines; private final String[] tempLines; - public void init(int width, int height) { this.add(new Label(0, -140, 300, 20, "Bearbeite Schild")); this.add(new Label(0, -80, 300, 20, String.format("%d, %d, %d", this.position.getX(), this.position.getY(), this.position.getZ()))); this.add(new Label(0, -50, 300, 20, this.gm.world == null ? "" : this.gm.world.dimension.getFormattedName(false))); for(int z = 0; z < this.lines.length; z++) { - this.lines[z] = this.add(new Textbox(0, 40 * z, 300, 24, 50, true, this, this.tempLines[z] == null ? "" : this.tempLines[z])); + this.lines[z] = this.add(new Field(0, 40 * z, 300, 24, 50, this, this.tempLines[z] == null ? "" : this.tempLines[z])); } this.add(new NavButton(0, 40 * (this.lines.length + 1), 300, 24, null, "Fertig")); this.shift(); @@ -42,13 +42,13 @@ public class GuiSign extends Gui implements Textbox.Callback { public GuiSign(BlockPos sign, String[] lines) { this.position = sign; - this.lines = new Textbox[lines.length]; + this.lines = new Field[lines.length]; this.tempLines = new String[lines.length]; System.arraycopy(lines, 0, this.tempLines, 0, lines.length); } - public void use(Textbox elem, Action value) { - if(value == Action.SEND) + public void use(Field elem, FieldAction value) { + if(value == FieldAction.SEND) this.gm.displayGuiScreen(null); } } diff --git a/client/src/client/gui/options/GuiBinds.java b/client/src/client/gui/options/GuiBinds.java index 1c1ab7a..ffc6262 100644 --- a/client/src/client/gui/options/GuiBinds.java +++ b/client/src/client/gui/options/GuiBinds.java @@ -2,8 +2,9 @@ package client.gui.options; import client.gui.Formatter; import client.gui.element.ActButton; -import client.gui.element.ActButton.Mode; +import client.gui.element.ButtonCallback; import client.gui.element.Label; +import client.gui.element.PressType; import client.window.Bind; import common.color.TextColor; @@ -16,16 +17,16 @@ public class GuiBinds extends GuiOptions { int x = 0; for(Bind bind : Bind.values()) { this.add(new Label(10 + x * 190, 80 + y * 50, 180, 20, bind.getDisplay())); - this.add(new ActButton(10 + x * 190, 100 + y * 50, 180, 24, new ActButton.Callback() { - public void use(ActButton elem, Mode action) { - if(action == Mode.SECONDARY) { + this.add(new ActButton(10 + x * 190, 100 + y * 50, 180, 24, new ButtonCallback() { + public void use(ActButton elem, PressType action) { + if(action == PressType.SECONDARY) { if(!bind.isDefault()) { bind.setDefault(); GuiBinds.this.gm.setDirty(); GuiBinds.this.reformat(); } } - else if(action == Mode.TERTIARY) { + else if(action == PressType.TERTIARY) { if(bind.getInput() != null) { bind.setInput(null); GuiBinds.this.gm.setDirty(); @@ -50,8 +51,8 @@ public class GuiBinds extends GuiOptions { } } y += x != 0 ? 1 : 0; - this.add(new ActButton(200, 100 + y * 50, 560, 24, new ActButton.Callback() { - public void use(ActButton elem, Mode action) { + this.add(new ActButton(200, 100 + y * 50, 560, 24, new ButtonCallback() { + public void use(ActButton elem, PressType action) { boolean flag = false; for(Bind bind : Bind.values()) { flag |= !bind.isDefault(); diff --git a/client/src/client/gui/options/GuiDisplay.java b/client/src/client/gui/options/GuiDisplay.java index 68febe0..22262d0 100644 --- a/client/src/client/gui/options/GuiDisplay.java +++ b/client/src/client/gui/options/GuiDisplay.java @@ -2,10 +2,13 @@ package client.gui.options; import client.gui.Formatter; import client.gui.element.Dropdown; +import client.gui.element.DropdownCallback; import client.gui.element.Element; import client.gui.element.Fill; import client.gui.element.Slider; +import client.gui.element.SliderCallback; import client.gui.element.Toggle; +import client.gui.element.ToggleCallback; import client.window.Button; import client.window.DisplayMode; import client.window.Window; @@ -36,7 +39,7 @@ public class GuiDisplay extends GuiOptions { if(modes[z].equals(this.gm.vidMode)) selected = modes[z]; } - this.add(new Dropdown(30, 80, 440, 24, false, modes, modes[modes.length - 1], selected, new Dropdown.Callback() { + this.add(new Dropdown(30, 80, 440, 24, false, modes, modes[modes.length - 1], selected, new DropdownCallback() { public void use(Dropdown elem, DisplayMode value) { GuiDisplay.this.gm.vidMode = value; GuiDisplay.this.gm.full(true); @@ -47,12 +50,12 @@ public class GuiDisplay extends GuiOptions { this.add(new Fill(30, 80, 440, 24, TextColor.RED + "Auflösung: ")); } - this.add(new Toggle(490, 80, 440, 24, false, GuiDisplay.this.gm.fullscreen, new Toggle.Callback() { + this.add(new Toggle(490, 80, 440, 24, false, GuiDisplay.this.gm.fullscreen, new ToggleCallback() { public void use(Toggle elem, boolean value) { GuiDisplay.this.gm.full(value); } }, "Vollbild")); - this.add(new Slider(30, 120, 440, 24, 0, 0, 360 - 8, 0, (this.gm.sync < 0) ? (360 - 8) : (this.gm.sync != 0 ? ((this.gm.sync < 10) ? 1 : (this.gm.sync - 9)) : 0), new Slider.Callback() { + this.add(new Slider(30, 120, 440, 24, 0, 0, 360 - 8, 0, (this.gm.sync < 0) ? (360 - 8) : (this.gm.sync != 0 ? ((this.gm.sync < 10) ? 1 : (this.gm.sync - 9)) : 0), new SliderCallback() { public void use(Slider elem, int value) { GuiDisplay.this.gm.getVar("win_sync").parse("" + ((value > 0 && value < 360 - 8) ? (value + 9) : (value != 0 ? -1 : 0))); GuiDisplay.this.gm.setDirty(); diff --git a/client/src/client/gui/options/GuiSound.java b/client/src/client/gui/options/GuiSound.java index 052c2ab..29a3814 100644 --- a/client/src/client/gui/options/GuiSound.java +++ b/client/src/client/gui/options/GuiSound.java @@ -2,7 +2,8 @@ package client.gui.options; import client.audio.Volume; import client.gui.element.ActButton; -import client.gui.element.ActButton.Mode; +import client.gui.element.ButtonCallback; +import client.gui.element.PressType; public class GuiSound extends GuiOptions { protected GuiSound() { @@ -14,8 +15,8 @@ public class GuiSound extends GuiOptions { this.addSelector("snd_buffer_size", 30, 420, 440, 24); this.addSelector("snd_frame_size", 490, 420, 440, 24); - this.add(new ActButton(30, 480, 900, 24, new ActButton.Callback() { - public void use(ActButton elem, Mode action) { + this.add(new ActButton(30, 480, 900, 24, new ButtonCallback() { + public void use(ActButton elem, PressType action) { GuiSound.this.gm.restartSound(false); } }, "Übernehmen und Audio-Thread neu starten")); diff --git a/client/src/client/gui/options/GuiStyle.java b/client/src/client/gui/options/GuiStyle.java index 6d374ee..7905591 100644 --- a/client/src/client/gui/options/GuiStyle.java +++ b/client/src/client/gui/options/GuiStyle.java @@ -2,19 +2,25 @@ package client.gui.options; import client.gui.Style; import client.gui.element.ActButton; -import client.gui.element.ActButton.Mode; +import client.gui.element.ButtonCallback; import client.gui.element.Dropdown; +import client.gui.element.DropdownCallback; import client.gui.element.Element; import client.gui.element.SelectableButton; import client.gui.element.Slider; +import client.gui.element.SliderCallback; import client.gui.element.Switch; -import client.gui.element.Textbox; -import client.gui.element.Textbox.Action; +import client.gui.element.SwitchCallback; +import client.gui.element.FieldAction; +import client.gui.element.Field; +import client.gui.element.FieldCallback; +import client.gui.element.PressType; import client.vars.CVar; import client.vars.ColorVar; import client.gui.element.Toggle; +import client.gui.element.ToggleCallback; -public class GuiStyle extends GuiOptions implements Dropdown.Callback, ActButton.Callback, Toggle.Callback, Switch.Callback, Slider.Callback, Textbox.Callback { +public class GuiStyle extends GuiOptions implements DropdownCallback, ButtonCallback, ToggleCallback, SwitchCallback, SliderCallback, FieldCallback { private static final String[] STYLE_CVARS = { "color_button_top", "color_textbox_top", @@ -39,7 +45,7 @@ public class GuiStyle extends GuiOptions implements Dropdown.Callback, A if(!color.getDisplay().isEmpty()) this.add(color.label(x, y - 20, w, 20)); if(this.gm.style != Style.CUSTOM) - return this.add(new Textbox(x, y, w, h, true, color.getFieldValue(this.gm.style))); + return this.add(new Field(x, y, w, h, color.getFieldValue(this.gm.style))); else return this.add(color.editor(x, y, w, h)); } @@ -53,8 +59,8 @@ public class GuiStyle extends GuiOptions implements Dropdown.Callback, A } z = 0; for(Style theme : Style.values()) { - ActButton.Callback callback = new ActButton.Callback() { - public void use(ActButton elem, Mode action) { + ButtonCallback callback = new ButtonCallback() { + public void use(ActButton elem, PressType action) { if(GuiStyle.this.gm.style != theme) { GuiStyle.this.gm.style = theme; GuiStyle.this.gm.setDirty(); @@ -75,11 +81,11 @@ public class GuiStyle extends GuiOptions implements Dropdown.Callback, A values = new String[] {"VALUE 1", "VALUE 2", "VALUE 3", "VALUE 4"}; this.add(new Switch(10, height - 34, 300, 24, values, values[2], values[0], this, "ENUM")); this.add(new Slider(330, height - 34, 300, 24, 0, -20, 827, 60, 120, this, "SLIDER")); - this.add(new Textbox(650, height - 34, 300, 24, 128, true, this, "FIELD")); + this.add(new Field(650, height - 34, 300, 24, 128, this, "FIELD")); if(this.gm.style != Style.CUSTOM) { - this.add(new ActButton(200, 100 + 3 * 50, 560, 24, new ActButton.Callback() { - public void use(ActButton elem, Mode action) { + this.add(new ActButton(200, 100 + 3 * 50, 560, 24, new ButtonCallback() { + public void use(ActButton elem, PressType action) { if(GuiStyle.this.gm.style != Style.CUSTOM) { GuiStyle.this.gm.style.copyToCustom(); GuiStyle.this.gm.style = Style.CUSTOM; @@ -90,8 +96,8 @@ public class GuiStyle extends GuiOptions implements Dropdown.Callback, A }, "In angepasstes Design kopieren")); } else { - this.add(new ActButton(200, 100 + 3 * 50, 560, 24, new ActButton.Callback() { - public void use(ActButton elem, Mode action) { + this.add(new ActButton(200, 100 + 3 * 50, 560, 24, new ButtonCallback() { + public void use(ActButton elem, PressType action) { GuiStyle.this.gm.style = Style.CUSTOM; for(String cvar : STYLE_CVARS) { GuiStyle.this.gm.getVar(cvar).setDefault(); @@ -108,7 +114,7 @@ public class GuiStyle extends GuiOptions implements Dropdown.Callback, A return "Benutzeroberfläche"; } - public void use(Textbox elem, Action value) { + public void use(Field elem, FieldAction value) { } public void use(Slider elem, int value) { } @@ -116,7 +122,7 @@ public class GuiStyle extends GuiOptions implements Dropdown.Callback, A } public void use(Toggle elem, boolean value) { } - public void use(ActButton elem, Mode action) { + public void use(ActButton elem, PressType action) { } public void use(Dropdown elem, String value) { } diff --git a/client/src/client/vars/BoolVar.java b/client/src/client/vars/BoolVar.java index af51d6b..103f1ca 100644 --- a/client/src/client/vars/BoolVar.java +++ b/client/src/client/vars/BoolVar.java @@ -3,6 +3,7 @@ package client.vars; import java.lang.reflect.Field; import client.gui.element.Toggle; +import client.gui.element.ToggleCallback; import common.color.TextColor; import common.util.Util; @@ -59,7 +60,7 @@ public class BoolVar extends BaseVar { public Toggle selector(int x, int y, int w, int h) { try { - return new Toggle(x, y, w, h, this.def, this.field.getBoolean(this.object), new Toggle.Callback() { + return new Toggle(x, y, w, h, this.def, this.field.getBoolean(this.object), new ToggleCallback() { public void use(Toggle elem, boolean value) { BoolVar.this.parse("" + value); } diff --git a/client/src/client/vars/ColorVar.java b/client/src/client/vars/ColorVar.java index 2a1bfb1..9f72dc6 100644 --- a/client/src/client/vars/ColorVar.java +++ b/client/src/client/vars/ColorVar.java @@ -3,10 +3,10 @@ package client.vars; import java.lang.reflect.Field; import client.gui.Style; +import client.gui.element.FieldCallback; import client.gui.element.Label; import client.gui.element.Slider; -import client.gui.element.Textbox; -import client.gui.element.Textbox.Action; +import client.gui.element.FieldAction; import common.color.TextColor; import common.util.Util; @@ -26,6 +26,8 @@ public class ColorVar extends IntVar { if(str.length() != (this.alpha ? 8 : 6)) return null; Integer value = Util.parseInt(str, -16); + if(value == null) + return null; return this.alpha || (value & 0xff000000) == 0 ? (this.alpha ? value : (0xff000000 | value)) : null; } @@ -41,10 +43,10 @@ public class ColorVar extends IntVar { return new Label(x, y, w, h, this.display); } - public Textbox editor(int x, int y, int w, int h) { - return new Textbox(x, y, w, h, this.alpha ? 8 : 6, true, new Textbox.Callback() { - public void use(Textbox elem, Textbox.Action value) { - if(value == Action.SEND || value == Action.UNFOCUS) + public client.gui.element.Field editor(int x, int y, int w, int h) { + return new client.gui.element.Field(x, y, w, h, this.alpha ? 8 : 6, new FieldCallback() { + public void use(client.gui.element.Field elem, FieldAction value) { + if(value == FieldAction.SEND || value == FieldAction.UNFOCUS) ColorVar.this.parse(elem.getText()); } }, this.format()); diff --git a/client/src/client/vars/EnumVar.java b/client/src/client/vars/EnumVar.java index ed30980..5f8273f 100644 --- a/client/src/client/vars/EnumVar.java +++ b/client/src/client/vars/EnumVar.java @@ -3,8 +3,10 @@ package client.vars; import java.lang.reflect.Field; import client.gui.element.Dropdown; +import client.gui.element.DropdownCallback; import client.gui.element.Element; import client.gui.element.Switch; +import client.gui.element.SwitchCallback; import common.color.TextColor; import common.util.Identifyable; import common.util.Util; @@ -79,7 +81,7 @@ public class EnumVar extends BaseVar { if(this.useSwitch) return this.switcher(x, y, w, h); try { - return new Dropdown(x, y, w, h, false, (T[])this.field.getType().getEnumConstants(), this.def, (T)this.field.get(this.object), new Dropdown.Callback() { + return new Dropdown(x, y, w, h, false, (T[])this.field.getType().getEnumConstants(), this.def, (T)this.field.get(this.object), new DropdownCallback() { public void use(Dropdown elem, T value) { EnumVar.this.parse(value instanceof Identifyable ? ((Identifyable)value).getName() : value.toString()); } @@ -92,7 +94,7 @@ public class EnumVar extends BaseVar { public Switch switcher(int x, int y, int w, int h) { try { - return new Switch(x, y, w, h, (T[])this.field.getType().getEnumConstants(), this.def, (T)this.field.get(this.object), new Switch.Callback() { + return new Switch(x, y, w, h, (T[])this.field.getType().getEnumConstants(), this.def, (T)this.field.get(this.object), new SwitchCallback() { public void use(Switch elem, T value) { EnumVar.this.parse(value instanceof Identifyable ? ((Identifyable)value).getName() : value.toString()); } diff --git a/client/src/client/vars/FloatVar.java b/client/src/client/vars/FloatVar.java index 2343af1..43c6a3f 100644 --- a/client/src/client/vars/FloatVar.java +++ b/client/src/client/vars/FloatVar.java @@ -3,6 +3,7 @@ package client.vars; import java.lang.reflect.Field; import client.gui.element.Slider; +import client.gui.element.SliderFloatCallback; import common.color.TextColor; import common.util.ExtMath; @@ -90,7 +91,7 @@ public class FloatVar extends BaseVar { public Slider selector(int x, int y, int w, int h) { try { - return new Slider(x, y, w, h, this.unit.equals("%") ? -1 : this.precision, this.min, this.max, this.def, this.field.getFloat(this.object), new Slider.FloatCallback() { + return new Slider(x, y, w, h, this.unit.equals("%") ? -1 : this.precision, this.min, this.max, this.def, this.field.getFloat(this.object), new SliderFloatCallback() { public void use(Slider elem, float value) { FloatVar.this.parse(String.format(FloatVar.this.format, value)); } diff --git a/client/src/client/vars/IntVar.java b/client/src/client/vars/IntVar.java index 06282fb..312bd72 100644 --- a/client/src/client/vars/IntVar.java +++ b/client/src/client/vars/IntVar.java @@ -3,6 +3,7 @@ package client.vars; import java.lang.reflect.Field; import client.gui.element.Slider; +import client.gui.element.SliderCallback; import common.color.TextColor; import common.util.ExtMath; import common.util.Util; @@ -82,7 +83,7 @@ public class IntVar extends BaseVar { public Slider selector(int x, int y, int w, int h) { try { - return new Slider(x, y, w, h, this.precision, this.min, this.max, this.def, this.field.getInt(this.object), new Slider.Callback() { + return new Slider(x, y, w, h, this.precision, this.min, this.max, this.def, this.field.getInt(this.object), new SliderCallback() { public void use(Slider elem, int value) { IntVar.this.parse(IntVar.this.formatValue(value)); } diff --git a/client/src/client/vars/StringVar.java b/client/src/client/vars/StringVar.java index 66dea94..8654948 100644 --- a/client/src/client/vars/StringVar.java +++ b/client/src/client/vars/StringVar.java @@ -2,8 +2,8 @@ package client.vars; import java.lang.reflect.Field; -import client.gui.element.Textbox; -import client.gui.element.Textbox.Action; +import client.gui.element.FieldCallback; +import client.gui.element.FieldAction; import common.color.TextColor; import common.util.CharValidator; @@ -67,10 +67,10 @@ public class StringVar extends BaseVar { return this.def; } - public Textbox selector(int x, int y, int w, int h) { - return new Textbox(x, y, w, h, this.maxLength, true, new Textbox.Callback() { - public void use(Textbox elem, Textbox.Action value) { - if(value == Action.SEND || value == Action.UNFOCUS) { + public client.gui.element.Field selector(int x, int y, int w, int h) { + return new client.gui.element.Field(x, y, w, h, this.maxLength, new FieldCallback() { + public void use(client.gui.element.Field elem, FieldAction value) { + if(value == FieldAction.SEND || value == FieldAction.UNFOCUS) { if(!StringVar.this.allowEmpty && elem.getText().isEmpty()) elem.setText(StringVar.this.format()); else From 8d4b4b361956995e97c9985cc389fcb17b61ced2 Mon Sep 17 00:00:00 2001 From: Sen Date: Sun, 18 May 2025 17:39:22 +0200 Subject: [PATCH 035/200] add encryption and enforce authentication --- client/src/client/Client.java | 6 +- .../client/network/ClientLoginHandler.java | 49 ++++--- common/src/common/init/Config.java | 17 --- .../src/common/network/EncryptionCodec.java | 41 ++++++ .../common/network/IClientLoginHandler.java | 3 + common/src/common/network/ILoginHandler.java | 6 + common/src/common/network/NetConnection.java | 13 +- .../network/NettyEncryptionDecoder.java | 20 +++ .../network/NettyEncryptionEncoder.java | 19 +++ common/src/common/network/PacketRegistry.java | 8 +- common/src/common/packet/LPacketLogin.java | 21 +++ .../common/packet/LPacketStartEncrypt.java | 47 ++++++ .../common/packet/RPacketRequestEncrypt.java | 44 ++++++ common/src/common/util/EncryptUtil.java | 135 ++++++++++++++++++ server/src/server/Server.java | 48 ++++--- server/src/server/network/LoginHandler.java | 48 +++++-- 16 files changed, 452 insertions(+), 73 deletions(-) create mode 100644 common/src/common/network/EncryptionCodec.java create mode 100644 common/src/common/network/NettyEncryptionDecoder.java create mode 100644 common/src/common/network/NettyEncryptionEncoder.java create mode 100644 common/src/common/packet/LPacketLogin.java create mode 100644 common/src/common/packet/LPacketStartEncrypt.java create mode 100644 common/src/common/packet/RPacketRequestEncrypt.java create mode 100644 common/src/common/util/EncryptUtil.java diff --git a/client/src/client/Client.java b/client/src/client/Client.java index c2b91ed..733137d 100755 --- a/client/src/client/Client.java +++ b/client/src/client/Client.java @@ -137,7 +137,7 @@ import common.packet.CPacketAction; import common.packet.CPacketCheat; import common.packet.CPacketMessage; import common.packet.HPacketHandshake; -import common.packet.LPacketPasswordResponse; +import common.packet.LPacketLogin; import common.packet.CPacketAction.Action; import common.potion.Potion; import common.potion.PotionEffect; @@ -488,9 +488,9 @@ public class Client implements IThreadListener { try { connection = createNetworkManagerAndConnect(address == null ? InetAddress.getLoopbackAddress() : InetAddress.getByName(IDN.toASCII(address)), port); - connection.setNetHandler(new ClientLoginHandler(connection, this)); + connection.setNetHandler(new ClientLoginHandler(connection, this, user, access, pass)); connection.sendPacket(new HPacketHandshake(Config.PROTOCOL)); - connection.sendPacket(new LPacketPasswordResponse(user, access, pass)); + connection.sendPacket(new LPacketLogin()); } catch (UnknownHostException u) { diff --git a/client/src/client/network/ClientLoginHandler.java b/client/src/client/network/ClientLoginHandler.java index c17ab44..cfda5c6 100755 --- a/client/src/client/network/ClientLoginHandler.java +++ b/client/src/client/network/ClientLoginHandler.java @@ -1,21 +1,37 @@ package client.network; +import java.security.PublicKey; + +import javax.crypto.SecretKey; + import client.Client; import common.network.IClientLoginHandler; import common.network.NetConnection; import common.network.NetHandler; import common.network.PacketRegistry; +import common.packet.LPacketPasswordResponse; +import common.packet.LPacketStartEncrypt; import common.packet.RPacketDisconnect; import common.packet.RPacketEnableCompression; import common.packet.RPacketLoginSuccess; +import common.packet.RPacketRequestEncrypt; +import common.util.EncryptUtil; +import io.netty.util.concurrent.Future; +import io.netty.util.concurrent.GenericFutureListener; public class ClientLoginHandler extends NetHandler implements IClientLoginHandler { private final Client gm; private final NetConnection networkManager; + private final String user; + private final String access; + private final String password; - public ClientLoginHandler(NetConnection conn, Client gmIn) { + public ClientLoginHandler(NetConnection conn, Client gmIn, String userIn, String accessIn, String passwordIn) { this.networkManager = conn; this.gm = gmIn; + this.user = userIn; + this.access = accessIn; + this.password = passwordIn; } public void onDisconnect(String reason) @@ -23,10 +39,21 @@ public class ClientLoginHandler extends NetHandler implements IClientLoginHandle this.gm.disconnected(reason); } - public final void handleDisconnect(RPacketDisconnect packetIn) + public void handleDisconnect(RPacketDisconnect packetIn) { this.networkManager.closeChannel(packetIn.getReason()); } + + public void handleEncrypt(RPacketRequestEncrypt packet) { + final SecretKey secret = EncryptUtil.createNewSharedKey(); + PublicKey pubkey = packet.getKey(); + this.networkManager.sendPacket(new LPacketStartEncrypt(secret, pubkey, packet.getToken()), new GenericFutureListener < Future > () { + public void operationComplete(Future u) throws Exception { + ClientLoginHandler.this.networkManager.startEncryption(secret); + ClientLoginHandler.this.networkManager.sendPacket(new LPacketPasswordResponse(ClientLoginHandler.this.user, ClientLoginHandler.this.access, ClientLoginHandler.this.password)); + } + }); + } public void handleLoginSuccess(RPacketLoginSuccess packetIn) { @@ -35,24 +62,8 @@ public class ClientLoginHandler extends NetHandler implements IClientLoginHandle this.networkManager.setNetHandler(new ClientPlayer(this.gm, this.networkManager)); } - public final void handleEnableCompression(RPacketEnableCompression packetIn) + public void handleEnableCompression(RPacketEnableCompression packetIn) { this.networkManager.setCompressionTreshold(packetIn.getValue()); } - -// public void handlePasswordRequest(RPacketPasswordRequest packetIn) { -// if(this.server == null) { -// this.networkManager.sendPacket(new LPacketPasswordResponse(this.user, "", "")); -// } -// else if((packetIn.getPasswordRequested() && this.server.pass.isEmpty()) || -// (packetIn.getPasswordProtected() && this.server.access.isEmpty())) { -//// this.toChange = this.gm.getConnected(); -// this.accessRequired = packetIn.getPasswordProtected() && this.server.access.isEmpty(); -// this.passwordRequired = packetIn.getPasswordRequested() && this.server.pass.isEmpty(); -// this.networkManager.closeChannel(""); -// } -// else { -// this.networkManager.sendPacket(new LPacketPasswordResponse(this.user, this.access, this.pass)); -// } -// } } diff --git a/common/src/common/init/Config.java b/common/src/common/init/Config.java index 652f2f7..d04c4e4 100755 --- a/common/src/common/init/Config.java +++ b/common/src/common/init/Config.java @@ -333,8 +333,6 @@ public abstract class Config { public static boolean itemFallDamage = true; @Var(name = "registration") public static boolean register = true; - @Var(name = "authentication") - public static boolean auth = true; @Var(name = "signEditing") public static boolean editSigns = true; @@ -350,21 +348,6 @@ public abstract class Config { public static boolean rabidRabbits = false; @Var(name = "snowStacking") public static boolean snowStack = false; -// @Var(name = "teleportForAll") -// public static boolean teleportAllowed = false; -// @Var(name = "preload_chunks_all") // Vorsicht Lag!! -// public static boolean preloadAll = false; - -// @Var(name = "maxPolygonalPoints") -// public static int polygonalPoints = -1; -// @Var(name = "maxPolyhedronPoints") -// public static int polyhedronPoints = -1; -// @Var(name = "maxEditRadius") -// public static int editRadius = -1; -// @Var(name = "maxBrushRadius") -// public static int brushRadius = 500; -// @Var(name = "historySize") -// public static int history = 300; @Var(name = "randomTickSpeed") public static int randomTick = 3; diff --git a/common/src/common/network/EncryptionCodec.java b/common/src/common/network/EncryptionCodec.java new file mode 100644 index 0000000..2598ecc --- /dev/null +++ b/common/src/common/network/EncryptionCodec.java @@ -0,0 +1,41 @@ +package common.network; + +import io.netty.buffer.ByteBuf; +import io.netty.channel.ChannelHandlerContext; +import javax.crypto.Cipher; +import javax.crypto.ShortBufferException; + +public class EncryptionCodec { + private final Cipher cipher; + private byte[] receiveBuf = new byte[0]; + private byte[] encodeBuf = new byte[0]; + + protected EncryptionCodec(Cipher cipher) { + this.cipher = cipher; + } + + private byte[] readBuffer(ByteBuf buf) { + int size = buf.readableBytes(); + if(this.receiveBuf.length < size) + this.receiveBuf = new byte[size]; + buf.readBytes((byte[])this.receiveBuf, 0, size); + return this.receiveBuf; + } + + protected ByteBuf decipher(ChannelHandlerContext ctx, ByteBuf buffer) throws ShortBufferException { + int size = buffer.readableBytes(); + byte[] data = this.readBuffer(buffer); + ByteBuf buf = ctx.alloc().heapBuffer(this.cipher.getOutputSize(size)); + buf.writerIndex(this.cipher.update(data, 0, size, buf.array(), buf.arrayOffset())); + return buf; + } + + protected void cipher(ByteBuf in, ByteBuf out) throws ShortBufferException { + int size = in.readableBytes(); + byte[] data = this.readBuffer(in); + int csize = this.cipher.getOutputSize(size); + if(this.encodeBuf.length < csize) + this.encodeBuf = new byte[csize]; + out.writeBytes((byte[])this.encodeBuf, 0, this.cipher.update(data, 0, size, this.encodeBuf)); + } +} diff --git a/common/src/common/network/IClientLoginHandler.java b/common/src/common/network/IClientLoginHandler.java index 99ac69d..b2606e1 100644 --- a/common/src/common/network/IClientLoginHandler.java +++ b/common/src/common/network/IClientLoginHandler.java @@ -3,6 +3,7 @@ package common.network; import common.packet.RPacketDisconnect; import common.packet.RPacketEnableCompression; import common.packet.RPacketLoginSuccess; +import common.packet.RPacketRequestEncrypt; public interface IClientLoginHandler { @@ -12,4 +13,6 @@ public interface IClientLoginHandler { void handleEnableCompression(RPacketEnableCompression packetIn); + void handleEncrypt(RPacketRequestEncrypt packet); + } \ No newline at end of file diff --git a/common/src/common/network/ILoginHandler.java b/common/src/common/network/ILoginHandler.java index 5361bc1..479e986 100644 --- a/common/src/common/network/ILoginHandler.java +++ b/common/src/common/network/ILoginHandler.java @@ -1,9 +1,15 @@ package common.network; +import common.packet.LPacketLogin; import common.packet.LPacketPasswordResponse; +import common.packet.LPacketStartEncrypt; public interface ILoginHandler { void processPasswordResponse(LPacketPasswordResponse packetIn); + void processEncryption(LPacketStartEncrypt packet); + + void processLogin(LPacketLogin packet); + } \ No newline at end of file diff --git a/common/src/common/network/NetConnection.java b/common/src/common/network/NetConnection.java index a77835e..5a0530a 100755 --- a/common/src/common/network/NetConnection.java +++ b/common/src/common/network/NetConnection.java @@ -1,13 +1,18 @@ package common.network; import java.net.SocketAddress; +import java.nio.channels.ClosedChannelException; import java.util.Queue; import java.util.concurrent.ConcurrentLinkedQueue; import java.util.concurrent.locks.ReentrantReadWriteLock; import java.util.regex.Pattern; +import javax.crypto.Cipher; +import javax.crypto.SecretKey; + import common.log.Log; import common.network.NetHandler.ThreadQuickExitException; +import common.util.EncryptUtil; import io.netty.channel.Channel; import io.netty.channel.ChannelFuture; import io.netty.channel.ChannelFutureListener; @@ -73,7 +78,8 @@ public class NetConnection extends SimpleChannelInboundHandler else { comp = "Interner Fehler: " + p_exceptionCaught_2_; - Log.SYSTEM.error(p_exceptionCaught_2_, "Fehler in der Verbindung mit %s", this.getCutAddress()); + if(!(p_exceptionCaught_2_ instanceof ClosedChannelException)) + Log.SYSTEM.error(p_exceptionCaught_2_, "Fehler in der Verbindung mit %s", this.getCutAddress()); } this.closeChannel(comp); @@ -356,6 +362,11 @@ public class NetConnection extends SimpleChannelInboundHandler } } } + + public void startEncryption(SecretKey key) { + this.channel.pipeline().addBefore("splitter", "decrypt", new NettyEncryptionDecoder(EncryptUtil.createNetCipherInstance(Cipher.DECRYPT_MODE, key))); + this.channel.pipeline().addBefore("prepender", "encrypt", new NettyEncryptionEncoder(EncryptUtil.createNetCipherInstance(Cipher.ENCRYPT_MODE, key))); + } static class InboundHandlerTuplePacketListener { diff --git a/common/src/common/network/NettyEncryptionDecoder.java b/common/src/common/network/NettyEncryptionDecoder.java new file mode 100644 index 0000000..dac5156 --- /dev/null +++ b/common/src/common/network/NettyEncryptionDecoder.java @@ -0,0 +1,20 @@ +package common.network; + +import io.netty.buffer.ByteBuf; +import io.netty.channel.ChannelHandlerContext; +import io.netty.handler.codec.MessageToMessageDecoder; +import java.util.List; +import javax.crypto.Cipher; +import javax.crypto.ShortBufferException; + +public class NettyEncryptionDecoder extends MessageToMessageDecoder { + private final EncryptionCodec codec; + + public NettyEncryptionDecoder(Cipher cipher) { + this.codec = new EncryptionCodec(cipher); + } + + protected void decode(ChannelHandlerContext p_decode_1_, ByteBuf p_decode_2_, List p_decode_3_) throws ShortBufferException, Exception { + p_decode_3_.add(this.codec.decipher(p_decode_1_, p_decode_2_)); + } +} diff --git a/common/src/common/network/NettyEncryptionEncoder.java b/common/src/common/network/NettyEncryptionEncoder.java new file mode 100644 index 0000000..0ec56f2 --- /dev/null +++ b/common/src/common/network/NettyEncryptionEncoder.java @@ -0,0 +1,19 @@ +package common.network; + +import io.netty.buffer.ByteBuf; +import io.netty.channel.ChannelHandlerContext; +import io.netty.handler.codec.MessageToByteEncoder; +import javax.crypto.Cipher; +import javax.crypto.ShortBufferException; + +public class NettyEncryptionEncoder extends MessageToByteEncoder { + private final EncryptionCodec codec; + + public NettyEncryptionEncoder(Cipher cipher) { + this.codec = new EncryptionCodec(cipher); + } + + protected void encode(ChannelHandlerContext p_encode_1_, ByteBuf p_encode_2_, ByteBuf p_encode_3_) throws ShortBufferException, Exception { + this.codec.cipher(p_encode_2_, p_encode_3_); + } +} diff --git a/common/src/common/network/PacketRegistry.java b/common/src/common/network/PacketRegistry.java index 0a13153..fd8e7c0 100755 --- a/common/src/common/network/PacketRegistry.java +++ b/common/src/common/network/PacketRegistry.java @@ -20,10 +20,13 @@ import common.packet.CPacketPlayer; import common.packet.CPacketSign; import common.packet.CPacketSkin; import common.packet.HPacketHandshake; +import common.packet.LPacketLogin; import common.packet.LPacketPasswordResponse; +import common.packet.LPacketStartEncrypt; import common.packet.RPacketDisconnect; import common.packet.RPacketEnableCompression; import common.packet.RPacketLoginSuccess; +import common.packet.RPacketRequestEncrypt; import common.packet.S14PacketEntity; import common.packet.S18PacketEntityTeleport; import common.packet.S19PacketEntityHeadLook; @@ -99,10 +102,11 @@ public enum PacketRegistry { { this.server(RPacketDisconnect.class); + this.server(RPacketRequestEncrypt.class); this.server(RPacketLoginSuccess.class); this.server(RPacketEnableCompression.class); -// this.server(RPacketPasswordRequest.class); -// this.client(LPacketLoginStart.class); + this.client(LPacketLogin.class); + this.client(LPacketStartEncrypt.class); this.client(LPacketPasswordResponse.class); } }, diff --git a/common/src/common/packet/LPacketLogin.java b/common/src/common/packet/LPacketLogin.java new file mode 100644 index 0000000..671fca7 --- /dev/null +++ b/common/src/common/packet/LPacketLogin.java @@ -0,0 +1,21 @@ +package common.packet; + +import java.io.IOException; +import common.network.ILoginHandler; +import common.network.Packet; +import common.network.PacketBuffer; + +public class LPacketLogin implements Packet { + public LPacketLogin() { + } + + public void readPacketData(PacketBuffer buf) throws IOException { + } + + public void writePacketData(PacketBuffer buf) throws IOException { + } + + public void processPacket(ILoginHandler handler) { + handler.processLogin(this); + } +} diff --git a/common/src/common/packet/LPacketStartEncrypt.java b/common/src/common/packet/LPacketStartEncrypt.java new file mode 100644 index 0000000..3408450 --- /dev/null +++ b/common/src/common/packet/LPacketStartEncrypt.java @@ -0,0 +1,47 @@ +package common.packet; + +import java.io.IOException; +import java.security.PrivateKey; +import java.security.PublicKey; + +import javax.crypto.SecretKey; + +import common.network.ILoginHandler; +import common.network.Packet; +import common.network.PacketBuffer; +import common.util.EncryptUtil; + +public class LPacketStartEncrypt implements Packet { + private byte[] key = new byte[0]; + private byte[] token = new byte[0]; + + public LPacketStartEncrypt() { + } + + public LPacketStartEncrypt(SecretKey secret, PublicKey pubkey, byte[] token) { + this.key = EncryptUtil.encryptData(pubkey, secret.getEncoded()); + this.token = EncryptUtil.encryptData(pubkey, token); + } + + public void readPacketData(PacketBuffer buf) throws IOException { + this.key = buf.readByteArray(); + this.token = buf.readByteArray(); + } + + public void writePacketData(PacketBuffer buf) throws IOException { + buf.writeByteArray(this.key); + buf.writeByteArray(this.token); + } + + public void processPacket(ILoginHandler handler) { + handler.processEncryption(this); + } + + public SecretKey getKey(PrivateKey key) { + return EncryptUtil.decryptSharedKey(key, this.key); + } + + public byte[] getToken(PrivateKey key) { + return key == null ? this.token : EncryptUtil.decryptData(key, this.token); + } +} diff --git a/common/src/common/packet/RPacketRequestEncrypt.java b/common/src/common/packet/RPacketRequestEncrypt.java new file mode 100644 index 0000000..2b45964 --- /dev/null +++ b/common/src/common/packet/RPacketRequestEncrypt.java @@ -0,0 +1,44 @@ +package common.packet; + +import java.io.IOException; +import java.security.PublicKey; + +import common.network.IClientLoginHandler; +import common.network.Packet; +import common.network.PacketBuffer; +import common.util.EncryptUtil; + +public class RPacketRequestEncrypt implements Packet { + private PublicKey key; + private byte[] token; + + public RPacketRequestEncrypt() { + } + + public RPacketRequestEncrypt(PublicKey key, byte[] token) { + this.key = key; + this.token = token; + } + + public final void readPacketData(PacketBuffer buf) throws IOException { + this.key = EncryptUtil.decodePublicKey(buf.readByteArray()); + this.token = buf.readByteArray(); + } + + public final void writePacketData(PacketBuffer buf) throws IOException { + buf.writeByteArray(this.key.getEncoded()); + buf.writeByteArray(this.token); + } + + public void processPacket(IClientLoginHandler handler) { + handler.handleEncrypt(this); + } + + public PublicKey getKey() { + return this.key; + } + + public byte[] getToken() { + return this.token; + } +} diff --git a/common/src/common/util/EncryptUtil.java b/common/src/common/util/EncryptUtil.java new file mode 100644 index 0000000..3ef5080 --- /dev/null +++ b/common/src/common/util/EncryptUtil.java @@ -0,0 +1,135 @@ +package common.util; + +import java.io.UnsupportedEncodingException; +import java.security.GeneralSecurityException; +import java.security.InvalidKeyException; +import java.security.Key; +import java.security.KeyFactory; +import java.security.KeyPair; +import java.security.KeyPairGenerator; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import java.security.PrivateKey; +import java.security.PublicKey; +import java.security.spec.AlgorithmParameterSpec; +import java.security.spec.EncodedKeySpec; +import java.security.spec.InvalidKeySpecException; +import java.security.spec.X509EncodedKeySpec; +import javax.crypto.BadPaddingException; +import javax.crypto.Cipher; +import javax.crypto.IllegalBlockSizeException; +import javax.crypto.KeyGenerator; +import javax.crypto.NoSuchPaddingException; +import javax.crypto.SecretKey; +import javax.crypto.spec.IvParameterSpec; +import javax.crypto.spec.SecretKeySpec; + +import common.log.Log; + +public class EncryptUtil { + public static SecretKey createNewSharedKey() { + try { + KeyGenerator keygen = KeyGenerator.getInstance("AES"); + keygen.init(128); + return keygen.generateKey(); + } + catch(NoSuchAlgorithmException e) { + throw new RuntimeException(e); + } + } + + public static KeyPair generateKeyPair() { + try { + KeyPairGenerator pairgen = KeyPairGenerator.getInstance("RSA"); + pairgen.initialize(1024); + return pairgen.generateKeyPair(); + } + catch(NoSuchAlgorithmException e) { + Log.SYSTEM.error(e, "Konnte Schlüsselpaar nicht generiren"); + return null; + } + } + + public static byte[] getServerIdHash(String id, PublicKey pubkey, SecretKey secret) { + try { + return digestOperation("SHA-1", new byte[][] {id.getBytes("ISO_8859_1"), secret.getEncoded(), pubkey.getEncoded()}); + } + catch(UnsupportedEncodingException e) { + Log.SYSTEM.error(e, "Konnte Server-Prüfwert nicht berechnen"); + return null; + } + } + + private static byte[] digestOperation(String algorithm, byte[]... data) { + try { + MessageDigest digest = MessageDigest.getInstance(algorithm); + + for(byte[] abyte : data) { + digest.update(abyte); + } + + return digest.digest(); + } + catch(NoSuchAlgorithmException e) { + Log.SYSTEM.error(e, "Konnte Prüfwert nicht berechnen"); + return null; + } + } + + public static PublicKey decodePublicKey(byte[] encoded) { + try { + EncodedKeySpec spec = new X509EncodedKeySpec(encoded); + KeyFactory factory = KeyFactory.getInstance("RSA"); + return factory.generatePublic(spec); + } + catch(NoSuchAlgorithmException | InvalidKeySpecException e) { + Log.SYSTEM.error(e, "Öffentlicher Schlüssel konnte nicht dekodiert werden"); + return null; + } + } + + public static SecretKey decryptSharedKey(PrivateKey key, byte[] secret) { + return new SecretKeySpec(decryptData(key, secret), "AES"); + } + + public static byte[] encryptData(Key key, byte[] data) { + return cipherOperation(Cipher.ENCRYPT_MODE, key, data); + } + + public static byte[] decryptData(Key key, byte[] data) { + return cipherOperation(Cipher.DECRYPT_MODE, key, data); + } + + private static byte[] cipherOperation(int mode, Key key, byte[] data) { + try { + return createCipher(mode, key.getAlgorithm(), key).doFinal(data); + } + catch(IllegalBlockSizeException | BadPaddingException e) { + Log.SYSTEM.error(e, "Konnte Daten nicht ver- oder entschlüsseln"); + return null; + } + } + + private static Cipher createCipher(int mode, String transformation, Key key) { + try { + Cipher cipher = Cipher.getInstance(transformation); + cipher.init(mode, key); + return cipher; + } + catch(InvalidKeyException | NoSuchAlgorithmException | NoSuchPaddingException e) { + Log.SYSTEM.error(e, "Konnte Verschlüsselungsverfahren nicht initialisieren"); + return null; + } + } + + public static Cipher createNetCipherInstance(int mode, Key key) { + try { + Cipher cipher = Cipher.getInstance("AES/CFB8/NoPadding"); + cipher.init(mode, (Key)key, (AlgorithmParameterSpec)(new IvParameterSpec(key.getEncoded()))); + return cipher; + } + catch(GeneralSecurityException e) { + throw new RuntimeException(e); + } + } +} diff --git a/server/src/server/Server.java b/server/src/server/Server.java index 8b13220..a4bac0a 100755 --- a/server/src/server/Server.java +++ b/server/src/server/Server.java @@ -6,6 +6,9 @@ import java.io.File; import java.io.IOException; import java.io.InputStreamReader; import java.net.InetAddress; +import java.security.KeyPair; +import java.security.PrivateKey; +import java.security.PublicKey; import java.text.SimpleDateFormat; import java.util.ArrayDeque; import java.util.ArrayList; @@ -67,6 +70,7 @@ import common.packet.SPacketTimeUpdate; import common.packet.SPacketWorld; import common.potion.PotionEffect; import common.util.BlockPos; +import common.util.EncryptUtil; import common.util.ExtMath; import common.util.LazyLoadBase; import common.util.PortalType; @@ -118,6 +122,7 @@ public final class Server implements IThreadListener { private final List unload = Lists.newArrayList(); private final Map warps = Maps.newTreeMap(); private final CommandEnvironment scriptEnv = new CommandEnvironment(this); + private final KeyPair keyPair; private final boolean debug; private WorldServer space; @@ -238,6 +243,7 @@ public final class Server implements IThreadListener { } } }, "viewDistance"); + this.keyPair = EncryptUtil.generateKeyPair(); } public CommandEnvironment getScriptEnvironment() { @@ -811,24 +817,22 @@ public final class Server implements IThreadListener { conn.readFromNBT(tag); if(Config.playerLimit > 0 && this.players.size() >= Config.playerLimit && !conn.isAdmin()) return String.format("Der Server ist voll (%d/%d)!", this.players.size(), Config.playerLimit); - if(/* !connection.isLocalChannel() && */ Config.auth) { - if(conn.getPassword() == null) { - if(!Config.register) - return "Anmeldung neuer Accounts ist auf diesem Server deaktiviert (Whitelisted)"; - if(loginPass.length() == 0) - return "Ein neues Passwort ist erforderlich um diesen Server zu betreten (mindestens " + Config.minPassLength + " Zeichen)"; - if(loginPass.length() < Config.minPassLength) - return "Passwort ist zu kurz, mindestens " + Config.minPassLength + " Zeichen"; - conn.setPassword(loginPass); - Log.JNI.info(loginUser + " registrierte sich mit Passwort"); - } - else if(!conn.getPassword().equals(loginPass)) { - return "Falsches Passwort"; - } - else { - Log.JNI.info(loginUser + " loggte sich mit Passwort ein"); - } - } + if(conn.getPassword() == null) { + if(!Config.register) + return "Anmeldung neuer Accounts ist auf diesem Server deaktiviert (Whitelisted)"; + if(loginPass.length() == 0) + return "Ein neues Passwort ist erforderlich um diesen Server zu betreten (mindestens " + Config.minPassLength + " Zeichen)"; + if(loginPass.length() < Config.minPassLength) + return "Passwort ist zu kurz, mindestens " + Config.minPassLength + " Zeichen"; + conn.setPassword(loginPass); + Log.JNI.info(loginUser + " registrierte sich mit Passwort"); + } + else if(!conn.getPassword().equals(loginPass)) { + return "Falsches Passwort"; + } + else { + Log.JNI.info(loginUser + " loggte sich mit Passwort ein"); + } if(Config.compression >= 0) { connection.sendPacket(new RPacketEnableCompression(Config.compression), new ChannelFutureListener() { public void operationComplete(ChannelFuture future) throws Exception { @@ -1300,4 +1304,12 @@ public final class Server implements IThreadListener { public void logConsole(String message) { Log.CONSOLE.info(message); } + + public PublicKey getPublicKey() { + return this.keyPair.getPublic(); + } + + public PrivateKey getPrivateKey() { + return this.keyPair.getPrivate(); + } } diff --git a/server/src/server/network/LoginHandler.java b/server/src/server/network/LoginHandler.java index a215180..d71d102 100755 --- a/server/src/server/network/LoginHandler.java +++ b/server/src/server/network/LoginHandler.java @@ -1,5 +1,11 @@ package server.network; +import java.security.PrivateKey; +import java.security.SecureRandom; +import java.util.Arrays; + +import javax.crypto.SecretKey; + import common.color.TextColor; import common.init.Config; import common.log.Log; @@ -7,23 +13,29 @@ import common.network.ILoginHandler; import common.network.IPlayer; import common.network.NetConnection; import common.network.NetHandler; +import common.packet.LPacketLogin; import common.packet.LPacketPasswordResponse; +import common.packet.LPacketStartEncrypt; import common.packet.RPacketDisconnect; +import common.packet.RPacketRequestEncrypt; import server.Server; public class LoginHandler extends NetHandler implements ILoginHandler { private static enum LoginState { - PASSWORD, READY_TO_ACCEPT, ACCEPTED; + INIT, ENCRYPT, PASSWORD, AUTHENTICATED, ACCEPTED; } + private static final SecureRandom TOKEN_RNG = new SecureRandom(); + private final Server server; public final NetConnection netManager; - private LoginState state = LoginState.PASSWORD; + private LoginState state = LoginState.INIT; private int timer; private String loginUser; private String loginPass; + private byte[] loginToken; public LoginHandler(Server server, NetConnection netManager) { @@ -58,7 +70,7 @@ public class LoginHandler extends NetHandler implements ILoginHandler public void update() { - if(this.state == LoginState.READY_TO_ACCEPT) + if(this.state == LoginState.AUTHENTICATED) this.tryAcceptPlayer(); // else if (this.currentLoginState == LoginState.DELAY_ACCEPT) // { @@ -93,15 +105,25 @@ public class LoginHandler extends NetHandler implements ILoginHandler this.state = LoginState.ACCEPTED; } -// public void processLoginStart(LPacketLoginStart packetIn) -// { -// if(this.state != LoginState.HELLO) -// throw new IllegalStateException("Unerwartetes Start-Paket"); -// if(!this.netManager.isLocalChannel()) { -// this.state = LoginState.PASSWORD; -// this.netManager.sendPacket(new RPacketPasswordRequest()); // !Config.password.isEmpty(), Config.auth -// } -// } + public void processLogin(LPacketLogin packet) { + if(this.state != LoginState.INIT) + throw new IllegalStateException("Unerwartetes Login-Paket"); + this.state = LoginState.ENCRYPT; + this.loginToken = new byte[4]; + TOKEN_RNG.nextBytes(this.loginToken); + this.netManager.sendPacket(new RPacketRequestEncrypt(this.server.getPublicKey(), this.loginToken)); + } + + public void processEncryption(LPacketStartEncrypt packet) { + if(this.state != LoginState.ENCRYPT) + throw new IllegalStateException("Unerwartetes Verschlüsselungs-Paket"); + PrivateKey pkey = this.server.getPrivateKey(); + if(!Arrays.equals(this.loginToken, packet.getToken(pkey))) + throw new IllegalStateException("Fehlerhaftes Token"); + SecretKey key = packet.getKey(pkey); + this.netManager.startEncryption(key); + this.state = LoginState.PASSWORD; + } public void processPasswordResponse(LPacketPasswordResponse packetIn) { if(this.state != LoginState.PASSWORD) @@ -116,6 +138,6 @@ public class LoginHandler extends NetHandler implements ILoginHandler this.closeConnection("Falsches Zugangspasswort"); return; } - this.state = LoginState.READY_TO_ACCEPT; + this.state = LoginState.AUTHENTICATED; } } From 5b2a51a8b5e79b37159c3051bf748701aaa5c417 Mon Sep 17 00:00:00 2001 From: Sen Date: Sun, 18 May 2025 17:46:15 +0200 Subject: [PATCH 036/200] remove unused EncryptUtil methods, rename --- common/src/common/network/NetConnection.java | 4 +-- common/src/common/util/EncryptUtil.java | 30 ++------------------ 2 files changed, 4 insertions(+), 30 deletions(-) diff --git a/common/src/common/network/NetConnection.java b/common/src/common/network/NetConnection.java index 5a0530a..a359d83 100755 --- a/common/src/common/network/NetConnection.java +++ b/common/src/common/network/NetConnection.java @@ -364,8 +364,8 @@ public class NetConnection extends SimpleChannelInboundHandler } public void startEncryption(SecretKey key) { - this.channel.pipeline().addBefore("splitter", "decrypt", new NettyEncryptionDecoder(EncryptUtil.createNetCipherInstance(Cipher.DECRYPT_MODE, key))); - this.channel.pipeline().addBefore("prepender", "encrypt", new NettyEncryptionEncoder(EncryptUtil.createNetCipherInstance(Cipher.ENCRYPT_MODE, key))); + this.channel.pipeline().addBefore("splitter", "decrypt", new NettyEncryptionDecoder(EncryptUtil.createCipher(Cipher.DECRYPT_MODE, key))); + this.channel.pipeline().addBefore("prepender", "encrypt", new NettyEncryptionEncoder(EncryptUtil.createCipher(Cipher.ENCRYPT_MODE, key))); } static class InboundHandlerTuplePacketListener diff --git a/common/src/common/util/EncryptUtil.java b/common/src/common/util/EncryptUtil.java index 3ef5080..2414eb5 100644 --- a/common/src/common/util/EncryptUtil.java +++ b/common/src/common/util/EncryptUtil.java @@ -49,33 +49,7 @@ public class EncryptUtil { return null; } } - - public static byte[] getServerIdHash(String id, PublicKey pubkey, SecretKey secret) { - try { - return digestOperation("SHA-1", new byte[][] {id.getBytes("ISO_8859_1"), secret.getEncoded(), pubkey.getEncoded()}); - } - catch(UnsupportedEncodingException e) { - Log.SYSTEM.error(e, "Konnte Server-Prüfwert nicht berechnen"); - return null; - } - } - - private static byte[] digestOperation(String algorithm, byte[]... data) { - try { - MessageDigest digest = MessageDigest.getInstance(algorithm); - - for(byte[] abyte : data) { - digest.update(abyte); - } - - return digest.digest(); - } - catch(NoSuchAlgorithmException e) { - Log.SYSTEM.error(e, "Konnte Prüfwert nicht berechnen"); - return null; - } - } - + public static PublicKey decodePublicKey(byte[] encoded) { try { EncodedKeySpec spec = new X509EncodedKeySpec(encoded); @@ -122,7 +96,7 @@ public class EncryptUtil { } } - public static Cipher createNetCipherInstance(int mode, Key key) { + public static Cipher createCipher(int mode, Key key) { try { Cipher cipher = Cipher.getInstance("AES/CFB8/NoPadding"); cipher.init(mode, (Key)key, (AlgorithmParameterSpec)(new IvParameterSpec(key.getEncoded()))); From 5b6bb3f10d06f1f1495f206d4e7e3fd28d77e7b6 Mon Sep 17 00:00:00 2001 From: Sen Date: Sun, 18 May 2025 17:49:01 +0200 Subject: [PATCH 037/200] remove unused EncryptUtil methods, rename --- common/src/common/util/EncryptUtil.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/common/src/common/util/EncryptUtil.java b/common/src/common/util/EncryptUtil.java index 2414eb5..b727708 100644 --- a/common/src/common/util/EncryptUtil.java +++ b/common/src/common/util/EncryptUtil.java @@ -1,13 +1,11 @@ package common.util; -import java.io.UnsupportedEncodingException; import java.security.GeneralSecurityException; import java.security.InvalidKeyException; import java.security.Key; import java.security.KeyFactory; import java.security.KeyPair; import java.security.KeyPairGenerator; -import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.security.PrivateKey; import java.security.PublicKey; From 5066ddf9afaddf274521da97824de5ad356c848d Mon Sep 17 00:00:00 2001 From: Sen Date: Sun, 18 May 2025 18:40:37 +0200 Subject: [PATCH 038/200] raise RSA key size 1024 -> 2048 --- common/src/common/util/EncryptUtil.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/src/common/util/EncryptUtil.java b/common/src/common/util/EncryptUtil.java index b727708..5241f2e 100644 --- a/common/src/common/util/EncryptUtil.java +++ b/common/src/common/util/EncryptUtil.java @@ -39,7 +39,7 @@ public class EncryptUtil { public static KeyPair generateKeyPair() { try { KeyPairGenerator pairgen = KeyPairGenerator.getInstance("RSA"); - pairgen.initialize(1024); + pairgen.initialize(2048); return pairgen.generateKeyPair(); } catch(NoSuchAlgorithmException e) { From 9a6c41661bf13efee010b140c16cd509e0f6e7d8 Mon Sep 17 00:00:00 2001 From: Sen Date: Sun, 18 May 2025 18:47:20 +0200 Subject: [PATCH 039/200] fix server startup time measurement --- server/src/server/Server.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/server/src/server/Server.java b/server/src/server/Server.java index a4bac0a..8f54ba4 100755 --- a/server/src/server/Server.java +++ b/server/src/server/Server.java @@ -150,8 +150,10 @@ public final class Server implements IThreadListener { private int perfTimer; public static void main(String[] args) { + long time = System.currentTimeMillis(); Util.checkOs(); Registry.setup("Server thread"); + Log.JNI.info("Starte " + Config.NAME + " Server Version " + Config.VERSION); GenBiome.setAsProvider(); UniverseRegistry.register(); RotationRegistry.register(); @@ -164,7 +166,7 @@ public final class Server implements IThreadListener { server.stopServer(); } }); - server.run(port); + server.run(time, port); Region.killIO(); Log.flushLog(); } @@ -432,9 +434,7 @@ public final class Server implements IThreadListener { return true; } - public void run(int port) { - long time = System.currentTimeMillis(); - Log.JNI.info("Starte " + Config.NAME + " Server Version " + Config.VERSION); + public void run(long time, int port) { if(!this.debug) { Converter.convert(); long wtime = loadServerConfig(); From 89d2c8f6e4ac3a4054b574daf3d808d53f5c08f4 Mon Sep 17 00:00:00 2001 From: Sen Date: Sun, 18 May 2025 19:51:32 +0200 Subject: [PATCH 040/200] fix npc sneaking --- common/src/common/entity/npc/EntityFlyingNPC.java | 4 ++++ common/src/common/entity/npc/EntityHoveringNPC.java | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/common/src/common/entity/npc/EntityFlyingNPC.java b/common/src/common/entity/npc/EntityFlyingNPC.java index c83c3ab..8457173 100755 --- a/common/src/common/entity/npc/EntityFlyingNPC.java +++ b/common/src/common/entity/npc/EntityFlyingNPC.java @@ -35,6 +35,10 @@ public abstract class EntityFlyingNPC extends EntityNPC public float getLegRotation() { return 0.2f; } + + public boolean isSneakingVisually() { + return false; + } public void fall(float distance, float damageMultiplier) { diff --git a/common/src/common/entity/npc/EntityHoveringNPC.java b/common/src/common/entity/npc/EntityHoveringNPC.java index 3c823c8..4781923 100755 --- a/common/src/common/entity/npc/EntityHoveringNPC.java +++ b/common/src/common/entity/npc/EntityHoveringNPC.java @@ -37,6 +37,10 @@ public abstract class EntityHoveringNPC extends EntityNPC this.getEntityAttribute(Attributes.FOLLOW_RANGE).setBaseValue(32.0D); } + public boolean isSneakingVisually() { + return false; + } + public boolean isHovering() { return this.getFlag(6); From a7fe2db49ff2f1c4dd17d54edab6540f57ee4558 Mon Sep 17 00:00:00 2001 From: Sen Date: Sun, 18 May 2025 20:18:44 +0200 Subject: [PATCH 041/200] change flying npc players not permananetly flying --- common/src/common/entity/npc/EntityFlyingNPC.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/common/src/common/entity/npc/EntityFlyingNPC.java b/common/src/common/entity/npc/EntityFlyingNPC.java index 8457173..9934394 100755 --- a/common/src/common/entity/npc/EntityFlyingNPC.java +++ b/common/src/common/entity/npc/EntityFlyingNPC.java @@ -49,6 +49,10 @@ public abstract class EntityFlyingNPC extends EntityNPC } public boolean isFlying() { + return !this.isPlayer() || super.isFlying(); + } + + public boolean canNaturallyFly() { return true; } From 7c80936c05c33a81aa949227e2b8a768605dbc39 Mon Sep 17 00:00:00 2001 From: Sen Date: Mon, 19 May 2025 20:46:04 +0200 Subject: [PATCH 042/200] fix rain+hail texture and empty chunk --- client/src/client/renderer/EntityRenderer.java | 4 ++-- client/src/client/world/EmptyChunk.java | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/client/src/client/renderer/EntityRenderer.java b/client/src/client/renderer/EntityRenderer.java index 9e5bf48..d9dd6a3 100755 --- a/client/src/client/renderer/EntityRenderer.java +++ b/client/src/client/renderer/EntityRenderer.java @@ -1314,14 +1314,14 @@ public class EntityRenderer { } else if (/* world.getBiomeGenerator().getTemperatureAtHeight( */ f2 /* , j2) */ > 0.0F) { - if (mode != 0) + if (mode != (f2 <= 5.0f ? 3 : 0)) { if (mode >= 0) { Tessellator.draw(); } - mode = 0; + mode = f2 <= 5.0f ? 3 : 0; this.gm.getTextureManager().bindTexture(f2 <= 5.0f ? locationHailPng : locationRainPng); worldrenderer.begin(GL11.GL_QUADS, DefaultVertexFormats.PARTICLE_POSITION_TEX_COLOR_LMAP); } diff --git a/client/src/client/world/EmptyChunk.java b/client/src/client/world/EmptyChunk.java index 190c2d7..3557561 100755 --- a/client/src/client/world/EmptyChunk.java +++ b/client/src/client/world/EmptyChunk.java @@ -88,7 +88,7 @@ public class EmptyChunk extends Chunk { public void getEntities(Class clazz, BoundingBox bb, List list, Predicate pred) { } - public boolean isDirty() { + public boolean isDirty(long time) { return false; } From e1456755259e40595d5e93188c67f19bce67bdf5 Mon Sep 17 00:00:00 2001 From: Sen Date: Mon, 19 May 2025 22:15:06 +0200 Subject: [PATCH 043/200] miscellanious fixes --- client/src/client/Client.java | 2 +- common/src/common/biome/Biome.java | 2 +- common/src/common/block/BlockBlackenedDirt.java | 2 ++ common/src/common/block/BlockBlackenedSoil.java | 2 ++ common/src/common/init/Config.java | 2 +- common/src/common/world/AWorldServer.java | 2 ++ server/src/server/world/WorldServer.java | 9 +++++++-- 7 files changed, 16 insertions(+), 5 deletions(-) diff --git a/client/src/client/Client.java b/client/src/client/Client.java index 733137d..7ceb7b6 100755 --- a/client/src/client/Client.java +++ b/client/src/client/Client.java @@ -341,7 +341,7 @@ public class Client implements IThreadListener { public EntityNPC player; public HitPosition pointed; - @Variable(name = "chunk_view_distance", category = CVarCategory.RENDER, min = 2, max = 16 /* 128 */, callback = DistanceFunction.class, display = "Sichtweite", unit = "Chunks") + @Variable(name = "chunk_view_distance", category = CVarCategory.RENDER, min = 2, max = 16, callback = DistanceFunction.class, display = "Sichtweite", unit = "Chunks") public int renderDistance = 8; @Variable(name = "chunk_build_time", category = CVarCategory.RENDER, min = 1, max = 100, display = "Max. Zeit für Chunk-Bau pro Frame", unit = "ms") public int maxBuildTime = 8; diff --git a/common/src/common/biome/Biome.java b/common/src/common/biome/Biome.java index b02260c..2ae9bb6 100644 --- a/common/src/common/biome/Biome.java +++ b/common/src/common/biome/Biome.java @@ -28,7 +28,7 @@ public enum Biome { ICEPLAINS(12, "icePlains", "Eisebene", 0xffffff, -20.0f), ICEMOUNTAINS(13, "iceMountains", "Vereistes Bergland", 0xa0a0a0, -20.0f), MUSHROOMPLAINS(14, "mushroomPlains", "Pilzland", 0xff00ff, 16.0f, 100.0f), - BLACKENED(15, "blackened", "Schwarz", 0x000000, 0.0f, 0.0f, 0x000000, 0x303030, 0x303030), + BLACKENED(15, "blackened", "Schwarz", 0x000000, 0.0f, 0.0f, 0x000000, 0x303030, 0x303030, 0x000000, 0x000000, 0x000000), BEACH(16, "beach", "Strand", 0xfade55, 12.0f, 40.0f), DESERTHILLS(17, "desertHills", "Wüsten-Bergland", 0xd25f12, 60.0f, 0.0f), FORESTHILLS(18, "forestHills", "Wald-Bergland", 0x22551c, 8.0f, 80.0f), diff --git a/common/src/common/block/BlockBlackenedDirt.java b/common/src/common/block/BlockBlackenedDirt.java index 361c7cb..6e821ae 100644 --- a/common/src/common/block/BlockBlackenedDirt.java +++ b/common/src/common/block/BlockBlackenedDirt.java @@ -1,5 +1,6 @@ package common.block; +import common.biome.Biome; import common.init.Blocks; import common.init.Config; import common.item.CheatTab; @@ -35,6 +36,7 @@ public class BlockBlackenedDirt extends Block else if (iblockstate.getBlock() == Blocks.grass && worldIn.getLightFromNeighbors(blockpos.up()) >= 2 && block.getLightOpacity() <= 6) { worldIn.setState(blockpos, Blocks.blackened_soil.getState()); + worldIn.setBiome(blockpos, Biome.BLACKENED); } else if (iblockstate.getBlock() == Blocks.stone && rand.chance(25)) { diff --git a/common/src/common/block/BlockBlackenedSoil.java b/common/src/common/block/BlockBlackenedSoil.java index 3e122f6..e6c0e26 100644 --- a/common/src/common/block/BlockBlackenedSoil.java +++ b/common/src/common/block/BlockBlackenedSoil.java @@ -1,5 +1,6 @@ package common.block; +import common.biome.Biome; import common.init.Blocks; import common.init.Config; import common.item.CheatTab; @@ -39,6 +40,7 @@ public class BlockBlackenedSoil extends Block if ((iblockstate.getBlock() == Blocks.dirt || iblockstate.getBlock() == Blocks.grass || iblockstate.getBlock() == Blocks.blackened_dirt) && worldIn.getLightFromNeighbors(blockpos.up()) >= 2 && block.getLightOpacity() <= 6) { worldIn.setState(blockpos, Blocks.blackened_soil.getState()); + worldIn.setBiome(blockpos, Biome.BLACKENED); } } } diff --git a/common/src/common/init/Config.java b/common/src/common/init/Config.java index d04c4e4..eacec16 100755 --- a/common/src/common/init/Config.java +++ b/common/src/common/init/Config.java @@ -421,7 +421,7 @@ public abstract class Config { public static int orbDamageOther = 0; @Var(name = "weatherChance") public static int weatherChance = 48000; - @Var(name = "viewDistance", min = 2, max = 128) + @Var(name = "viewDistance", min = 2, max = 16) public static int distance = 10; @Var(name = "healChance") public static int healChance = 5; diff --git a/common/src/common/world/AWorldServer.java b/common/src/common/world/AWorldServer.java index 3ab7b11..dbbda3f 100644 --- a/common/src/common/world/AWorldServer.java +++ b/common/src/common/world/AWorldServer.java @@ -2,6 +2,7 @@ package common.world; import java.util.List; +import common.biome.Biome; import common.block.Block; import common.dimension.Dimension; import common.entity.Entity; @@ -44,4 +45,5 @@ public abstract class AWorldServer extends World { public abstract boolean isBlockinHighHumidity(BlockPos pos); public abstract T findNearestEntityWithinAABB(Class entityType, BoundingBox aabb, T closestTo); public abstract long getTime(); + public abstract void setBiome(BlockPos pos, Biome biome); } diff --git a/server/src/server/world/WorldServer.java b/server/src/server/world/WorldServer.java index 84c1cf1..37b2873 100755 --- a/server/src/server/world/WorldServer.java +++ b/server/src/server/world/WorldServer.java @@ -2245,7 +2245,7 @@ public final class WorldServer extends AWorldServer { // return new LazyBlock(state, this, position); // } - public final boolean setBiome(BlockPos position, Biome biome) { + private final boolean setChunkBiome(BlockPos position, Biome biome) { Chunk chunk = this.getChunk(position); if((chunk != null) && (chunk.isLoaded())) { chunk.getBiomes()[((position.getZ() & 0xF) << 4 | position.getX() & 0xF)] = (byte)biome.id; @@ -2258,7 +2258,7 @@ public final class WorldServer extends AWorldServer { Set chunks = Sets.newHashSet(); for(int x = start.getX(); x <= end.getX(); x++) { for(int z = start.getZ(); z <= end.getZ(); z++) { - if(this.setBiome(new BlockPos(x, 0, z), biome)) + if(this.setChunkBiome(new BlockPos(x, 0, z), biome)) chunks.add(new ChunkPos(x >> 4, z >> 4)); } } @@ -2267,6 +2267,11 @@ public final class WorldServer extends AWorldServer { } chunks.clear(); } + + public final void setBiome(BlockPos pos, Biome biome) { + if(this.setChunkBiome(pos, biome)) + this.updateBiomes(pos.getX() >> 4, pos.getZ() >> 4); + } // public final List getEntities(EditRegion region) { // List entities = Lists.newArrayList(); From 31dd9d6303fe1836a4666258ea758eab6b2ee209 Mon Sep 17 00:00:00 2001 From: Sen Date: Tue, 20 May 2025 11:51:35 +0200 Subject: [PATCH 044/200] add dummy display chunks --- client/src/client/Client.java | 3 +- client/src/client/network/ClientPlayer.java | 1 + client/src/client/world/EmptyChunk.java | 101 ++++++++++++------ client/src/client/world/WorldClient.java | 52 +++++++-- common/src/common/block/BlockTorch.java | 2 +- common/src/common/dimension/Dimension.java | 46 ++++---- .../src/common/entity/types/EntityLiving.java | 2 +- common/src/common/world/Chunk.java | 6 +- common/src/common/world/World.java | 2 +- 9 files changed, 147 insertions(+), 68 deletions(-) diff --git a/client/src/client/Client.java b/client/src/client/Client.java index 7ceb7b6..0c669f3 100755 --- a/client/src/client/Client.java +++ b/client/src/client/Client.java @@ -1799,7 +1799,8 @@ public class Client implements IThreadListener { ) + "\n" + String.format("Letzte Zeitsynch.: + %d.%d s", ticked / 1000L, (ticked / 100L) % 10L - ) + + ) + "\n" + + "Startwert: " + this.world.dimension.getSeed() + (this.serverInfo != null ? "\n" + this.serverInfo : "") // IWorldServer world = this.server.getWorld(this.theWorld.dimension.getDimensionId()); // if(world != null) diff --git a/client/src/client/network/ClientPlayer.java b/client/src/client/network/ClientPlayer.java index eb3c533..1500a4e 100755 --- a/client/src/client/network/ClientPlayer.java +++ b/client/src/client/network/ClientPlayer.java @@ -722,6 +722,7 @@ public class ClientPlayer extends NetHandler implements IClientPlayer this.gameController.player.prevY = this.gameController.player.posY; this.gameController.player.prevZ = this.gameController.player.posZ; this.doneLoadingTerrain = true; + this.clientWorldController.markReload(); // this.gameController.displayGuiScreen(null); // if(this.travelSound) { // this.gameController.getSoundManager().playSound(new PositionedSound(SoundEvent.TELEPORT)); diff --git a/client/src/client/world/EmptyChunk.java b/client/src/client/world/EmptyChunk.java index 3557561..ae10017 100755 --- a/client/src/client/world/EmptyChunk.java +++ b/client/src/client/world/EmptyChunk.java @@ -3,40 +3,40 @@ package client.world; import java.util.List; import java.util.function.Predicate; +import common.biome.Biome; import common.block.Block; import common.entity.Entity; import common.init.Blocks; +import common.log.Log; import common.tileentity.TileEntity; import common.util.BlockPos; import common.util.BoundingBox; import common.world.Chunk; import common.world.LightType; +import common.world.State; +import common.worldgen.BiomeGenerator; public class EmptyChunk extends Chunk { + private final int liquidY; + private final State liquid; + private final Block liquidBlock; + private final int liquidMeta; + public EmptyChunk(WorldClient world) { super(world, 0, 0); + this.liquidY = world.dimension.getSeaLevel() - 1; + this.liquid = world.dimension.getLiquid(); + this.liquidBlock = this.liquid.getBlock(); + this.liquidMeta = this.liquidBlock.getMetaFromState(this.liquid); + Log.SYSTEM.info("See: %d", this.liquidY); } public int getHeight(int x, int z) { - return 0; - } - - public void genHeights() { - } - - public void genSkyLight() { + return this.liquidY; } public Block getBlock(BlockPos pos) { - return Blocks.air; - } - - public int getOpacity(BlockPos pos) { - return 255; - } - - public int getMeta(BlockPos pos) { - return 0; + return pos.getY() < this.liquidY ? Blocks.bedrock : (pos.getY() == this.liquidY ? this.liquidBlock : Blocks.air); } public int getLight(LightType type, BlockPos pos) { @@ -57,28 +57,19 @@ public class EmptyChunk extends Chunk { } public boolean canSeeSky(BlockPos pos) { - return false; + return pos.getY() > this.liquidY; } public TileEntity getTileEntity(BlockPos pos, TileEntity.EnumCreateEntityType type) { return null; } - public void addTileEntity(TileEntity tile) { - } - public void addTileEntity(BlockPos pos, TileEntity tile) { } public void removeTileEntity(BlockPos pos) { } - public void onChunkLoad() { - } - - public void onChunkUnload() { - } - public void setModified() { } @@ -88,15 +79,63 @@ public class EmptyChunk extends Chunk { public void getEntities(Class clazz, BoundingBox bb, List list, Predicate pred) { } - public boolean isDirty(long time) { - return false; - } - - public boolean isEmpty() { + public boolean isDummy() { return true; } public boolean isEmpty(int bottom, int top) { + return top < 0 || bottom > this.liquidY; + } + + public State getState(BlockPos pos) { + return pos.getY() < this.liquidY ? Blocks.bedrock.getState() : (pos.getY() == this.liquidY ? this.liquid : Blocks.air.getState()); + } + + public State setState(BlockPos pos, State state) { + return null; + } + + public BlockPos getPrecipitation(BlockPos pos) { + return new BlockPos(pos.getX(), this.liquidY + 1, pos.getZ()); + } + + public void update(boolean noGaps) { + } + + public void onChunkUnload() { + } + + public boolean isPopulated() { return true; } + + public void setData(byte[] data, int update, boolean biomes) { + } + + public Biome getBiome(BlockPos pos, BiomeGenerator gen) { + return Biome.DEF_BIOME; + } + + public void setBiomes(byte[] biomes) { + } + + public void resetRelight() { + } + + public void enqueueRelight() { + } + + public void checkLight() { + } + + public boolean isLoaded() { + return false; + } + + public void setLoaded(boolean loaded) { + } + + public int getLowest() { + return 0; + } } diff --git a/client/src/client/world/WorldClient.java b/client/src/client/world/WorldClient.java index 7e8f142..bd170bd 100755 --- a/client/src/client/world/WorldClient.java +++ b/client/src/client/world/WorldClient.java @@ -47,7 +47,9 @@ public class WorldClient extends AWorldClient private final Set previousActive = Sets.newHashSet(); private final LongHashMap chunkMapping = new LongHashMap(); private final List chunkListing = Lists.newArrayList(); - private final Chunk blankChunk = new EmptyChunk(this); + private final Set emptyChunkListing = Sets.newHashSet(); + private final Set nextEmptyChunkListing = Sets.newHashSet(); + private final Chunk emptyChunk = new EmptyChunk(this); // public final Profiler profiler; protected int lastLightning; protected Vec3 lightColor = new Vec3(0xffffff); @@ -63,8 +65,41 @@ public class WorldClient extends AWorldClient // this.setDifficulty(this.gm.difficulty); } + private void markReload(int cx, int cz, int range) { + this.nextEmptyChunkListing.clear(); + for(int x = cx - range; x <= cx + range; x++) { + for(int z = cz - range; z <= cz + range; z++) { + long id = LongHashMap.packInt(x, z); + ChunkPos pos = new ChunkPos(x, z); + if(this.chunkMapping.getValueByKey(id) != null) { + if(this.emptyChunkListing.contains(pos)) { + this.emptyChunkListing.remove(pos); + this.nextEmptyChunkListing.add(pos); + } + continue; + } + this.chunkMapping.add(id, this.emptyChunk); + this.emptyChunkListing.remove(pos); + this.nextEmptyChunkListing.add(pos); + this.markBlockRangeForRenderUpdate(x << 4, 0, z << 4, (x << 4) + 15, 512, (z << 4) + 15); + } + } + for(ChunkPos pos : this.emptyChunkListing) { + this.chunkMapping.remove(LongHashMap.packInt(pos.x, pos.z)); + this.markBlockRangeForRenderUpdate(pos.x << 4, 0, pos.z << 4, (pos.x << 4) + 15, 512, (pos.z << 4) + 15); + } + this.emptyChunkListing.clear(); + this.emptyChunkListing.addAll(this.nextEmptyChunkListing); + } + + public void markReload() { + if(this.gm.player != null && !this.gm.charEditor) + this.markReload((int)this.gm.player.posX >> 4, (int)this.gm.player.posZ >> 4, this.gm.renderDistance + 4); + } + public void tick() { + this.markReload(); // this.info.tick(); if (this.gm.dayCycle) @@ -127,24 +162,23 @@ public class WorldClient extends AWorldClient public void doPreChunk(int x, int z, boolean load) { + long id = LongHashMap.packInt(x, z); if (load) { - if(this.chunkMapping.getValueByKey(LongHashMap.packInt(x, z)) != null) + if(this.chunkMapping.getValueByKey(id) != null) this.doPreChunk(x, z, false); Chunk chunk = new Chunk(this, x, z); - this.chunkMapping.add(LongHashMap.packInt(x, z), chunk); + this.chunkMapping.add(id, chunk); this.chunkListing.add(chunk); chunk.setLoaded(true); } else { Chunk chunk = this.getChunk(x, z); - if (!chunk.isEmpty()) - { - chunk.onChunkUnload(); - } - this.chunkMapping.remove(LongHashMap.packInt(x, z)); + chunk.onChunkUnload(); + this.chunkMapping.remove(id); this.chunkListing.remove(chunk); + this.emptyChunkListing.remove(new ChunkPos(x, z)); } if (!load) @@ -354,7 +388,7 @@ public class WorldClient extends AWorldClient public Chunk getChunk(int x, int z) { Chunk chunk = this.chunkMapping.getValueByKey(LongHashMap.packInt(x, z)); - return chunk == null ? this.blankChunk : chunk; + return chunk == null ? this.emptyChunk : chunk; } public String getInfo() diff --git a/common/src/common/block/BlockTorch.java b/common/src/common/block/BlockTorch.java index a249b7e..3012c52 100755 --- a/common/src/common/block/BlockTorch.java +++ b/common/src/common/block/BlockTorch.java @@ -42,7 +42,7 @@ public class BlockTorch extends Block else { Chunk chunk = world.getChunk(pos.getX() >> 4, pos.getZ() >> 4); - if(chunk.isEmpty()) { + if(chunk.isDummy()) { return def; } else { diff --git a/common/src/common/dimension/Dimension.java b/common/src/common/dimension/Dimension.java index bcb9137..39b7bb3 100755 --- a/common/src/common/dimension/Dimension.java +++ b/common/src/common/dimension/Dimension.java @@ -911,14 +911,14 @@ public abstract class Dimension extends Nameable implements Comparable= UniverseRegistry.MORE_DIM_ID) { + this.seaLevel = tag.getInteger("SeaLevel"); + this.liquid = BlockRegistry.getFromIdName(tag.getString("LiquidBlock"), Blocks.water.getState()); + } + } + if(generator) { if(all || this.id >= UniverseRegistry.MORE_DIM_ID) { this.noiseGen.coordinateScale = tag.getFloat("CoordScale"); this.noiseGen.heightScale = tag.getFloat("HeightScale"); @@ -1009,7 +1015,6 @@ public abstract class Dimension extends Nameable implements Comparable= UniverseRegistry.MORE_DIM_ID) ? this.toNbt() : new NBTTagCompound(); if(this == Space.INSTANCE) { - if(generator) + if(generator || partialGen) tag.setLong("Seed", this.seed); return tag; } - if(generator) { + if(generator || partialGen) { tag.setLong("Seed", this.seed); + if(partialGen || all || this.id >= UniverseRegistry.MORE_DIM_ID) { + tag.setInteger("SeaLevel", this.seaLevel); + tag.setString("LiquidBlock", BlockRegistry.toIdName(this.liquid)); + } + } + if(generator) { if(all || this.id >= UniverseRegistry.MORE_DIM_ID) { tag.setFloat("CoordScale", this.noiseGen.coordinateScale); tag.setFloat("HeightScale", this.noiseGen.heightScale); @@ -1245,7 +1255,6 @@ public abstract class Dimension extends Nameable implements Comparable 0.0D) { diff --git a/common/src/common/world/Chunk.java b/common/src/common/world/Chunk.java index 6a5fdf7..efbb742 100755 --- a/common/src/common/world/Chunk.java +++ b/common/src/common/world/Chunk.java @@ -395,10 +395,6 @@ public class Chunk { return block; } - public Block getBlock(int x, int y, int z) { - return this.getBlock0(x & 15, y, z & 15); - } - public Block getBlock(BlockPos pos) { return this.getBlock0(pos.getX() & 15, pos.getY(), pos.getZ() & 15); } @@ -799,7 +795,7 @@ public class Chunk { return this.modified; } - public boolean isEmpty() { + public boolean isDummy() { return false; } diff --git a/common/src/common/world/World.java b/common/src/common/world/World.java index 519dc36..b1529dc 100755 --- a/common/src/common/world/World.java +++ b/common/src/common/world/World.java @@ -192,7 +192,7 @@ public abstract class World implements IWorldAccess { } protected boolean isLoaded(int x, int z, boolean allowEmpty) { - return allowEmpty || !this.getChunk(x, z).isEmpty(); + return allowEmpty || !this.getChunk(x, z).isDummy(); } public Chunk getChunk(BlockPos pos) { From e6d16405c5d00f3dbfd01f09072171048c23eb71 Mon Sep 17 00:00:00 2001 From: Sen Date: Tue, 20 May 2025 11:59:51 +0200 Subject: [PATCH 045/200] remove client world no chunks check, misc --- client/src/client/Client.java | 2 +- client/src/client/world/EmptyChunk.java | 2 -- client/src/client/world/WorldClient.java | 4 ---- 3 files changed, 1 insertion(+), 7 deletions(-) diff --git a/client/src/client/Client.java b/client/src/client/Client.java index 0c669f3..9922f2d 100755 --- a/client/src/client/Client.java +++ b/client/src/client/Client.java @@ -1009,7 +1009,7 @@ public class Client implements IThreadListener { } if(this.open != null) this.open.render(); - else if(this.world == null || this.world.hasNoChunks() || this.charEditor) + else if(this.world == null || this.charEditor) Drawing.drawScaled(this, Gui.DIRT_BACKGROUND); if(Bind.INFO.isDown() && (this.open == null || !(this.open.selected instanceof client.gui.element.Field || this.open.selected instanceof Area))) this.drawInfo(); diff --git a/client/src/client/world/EmptyChunk.java b/client/src/client/world/EmptyChunk.java index ae10017..12867ba 100755 --- a/client/src/client/world/EmptyChunk.java +++ b/client/src/client/world/EmptyChunk.java @@ -7,7 +7,6 @@ import common.biome.Biome; import common.block.Block; import common.entity.Entity; import common.init.Blocks; -import common.log.Log; import common.tileentity.TileEntity; import common.util.BlockPos; import common.util.BoundingBox; @@ -28,7 +27,6 @@ public class EmptyChunk extends Chunk { this.liquid = world.dimension.getLiquid(); this.liquidBlock = this.liquid.getBlock(); this.liquidMeta = this.liquidBlock.getMetaFromState(this.liquid); - Log.SYSTEM.info("See: %d", this.liquidY); } public int getHeight(int x, int z) { diff --git a/client/src/client/world/WorldClient.java b/client/src/client/world/WorldClient.java index bd170bd..ec6d762 100755 --- a/client/src/client/world/WorldClient.java +++ b/client/src/client/world/WorldClient.java @@ -960,8 +960,4 @@ public class WorldClient extends AWorldClient public String getDebugLoadedEntities() { return "" + this.entities.size(); } - - public boolean hasNoChunks() { - return this.chunkListing.isEmpty(); - } } From 3a5a29cf9e87bfad9c85f990697b1516e7ce4cc5 Mon Sep 17 00:00:00 2001 From: Sen Date: Tue, 20 May 2025 12:19:18 +0200 Subject: [PATCH 046/200] replace ChunkPos with LongHashMap#get(X|Z) in WorldClient --- client/src/client/world/WorldClient.java | 25 ++++++++++++------------ common/src/common/util/LongHashMap.java | 8 ++++++++ 2 files changed, 21 insertions(+), 12 deletions(-) diff --git a/client/src/client/world/WorldClient.java b/client/src/client/world/WorldClient.java index ec6d762..28d3f18 100755 --- a/client/src/client/world/WorldClient.java +++ b/client/src/client/world/WorldClient.java @@ -47,8 +47,8 @@ public class WorldClient extends AWorldClient private final Set previousActive = Sets.newHashSet(); private final LongHashMap chunkMapping = new LongHashMap(); private final List chunkListing = Lists.newArrayList(); - private final Set emptyChunkListing = Sets.newHashSet(); - private final Set nextEmptyChunkListing = Sets.newHashSet(); + private final Set emptyChunkListing = Sets.newHashSet(); + private final Set nextEmptyChunkListing = Sets.newHashSet(); private final Chunk emptyChunk = new EmptyChunk(this); // public final Profiler profiler; protected int lastLightning; @@ -70,23 +70,24 @@ public class WorldClient extends AWorldClient for(int x = cx - range; x <= cx + range; x++) { for(int z = cz - range; z <= cz + range; z++) { long id = LongHashMap.packInt(x, z); - ChunkPos pos = new ChunkPos(x, z); if(this.chunkMapping.getValueByKey(id) != null) { - if(this.emptyChunkListing.contains(pos)) { - this.emptyChunkListing.remove(pos); - this.nextEmptyChunkListing.add(pos); + if(this.emptyChunkListing.contains(id)) { + this.emptyChunkListing.remove(id); + this.nextEmptyChunkListing.add(id); } continue; } this.chunkMapping.add(id, this.emptyChunk); - this.emptyChunkListing.remove(pos); - this.nextEmptyChunkListing.add(pos); + this.emptyChunkListing.remove(id); + this.nextEmptyChunkListing.add(id); this.markBlockRangeForRenderUpdate(x << 4, 0, z << 4, (x << 4) + 15, 512, (z << 4) + 15); } } - for(ChunkPos pos : this.emptyChunkListing) { - this.chunkMapping.remove(LongHashMap.packInt(pos.x, pos.z)); - this.markBlockRangeForRenderUpdate(pos.x << 4, 0, pos.z << 4, (pos.x << 4) + 15, 512, (pos.z << 4) + 15); + for(Long id : this.emptyChunkListing) { + this.chunkMapping.remove(id); + int x = LongHashMap.getX(id); + int z = LongHashMap.getZ(id); + this.markBlockRangeForRenderUpdate(x << 4, 0, z << 4, (x << 4) + 15, 512, (z << 4) + 15); } this.emptyChunkListing.clear(); this.emptyChunkListing.addAll(this.nextEmptyChunkListing); @@ -178,7 +179,7 @@ public class WorldClient extends AWorldClient chunk.onChunkUnload(); this.chunkMapping.remove(id); this.chunkListing.remove(chunk); - this.emptyChunkListing.remove(new ChunkPos(x, z)); + this.emptyChunkListing.remove(id); } if (!load) diff --git a/common/src/common/util/LongHashMap.java b/common/src/common/util/LongHashMap.java index 89aba64..65faf9b 100755 --- a/common/src/common/util/LongHashMap.java +++ b/common/src/common/util/LongHashMap.java @@ -13,6 +13,14 @@ public class LongHashMap return (long)x & 4294967295L | ((long)z & 4294967295L) << 32; } + public static int getX(long v) { + return (int)(v & 4294967295L); + } + + public static int getZ(long v) { + return (int)(v >> 32); + } + public LongHashMap() { this.mask = this.hashArray.length - 1; From caef42dc161d26f4a6b5ea02b5a1a2da3d40fc81 Mon Sep 17 00:00:00 2001 From: Sen Date: Tue, 20 May 2025 19:06:37 +0200 Subject: [PATCH 047/200] make world taller --- client/src/client/network/ClientPlayer.java | 10 +- .../client/renderer/RegionRenderCache.java | 6 +- client/src/client/renderer/RenderGlobal.java | 5 +- client/src/client/world/EmptyChunk.java | 4 +- client/src/client/world/WorldClient.java | 7 +- common/src/common/block/BlockBanner.java | 2 +- common/src/common/block/BlockBeacon.java | 2 +- common/src/common/block/BlockBlueShroom.java | 2 +- .../src/common/block/BlockBrewingStand.java | 2 +- common/src/common/block/BlockChest.java | 2 +- .../common/block/BlockDaylightDetector.java | 2 +- common/src/common/block/BlockDispenser.java | 2 +- common/src/common/block/BlockDoor.java | 2 +- common/src/common/block/BlockDropper.java | 2 +- .../common/block/BlockEnchantmentTable.java | 2 +- common/src/common/block/BlockFurnace.java | 2 +- common/src/common/block/BlockHopper.java | 2 +- common/src/common/block/BlockLilyPad.java | 2 +- common/src/common/block/BlockMachine.java | 2 +- common/src/common/block/BlockMobSpawner.java | 2 +- common/src/common/block/BlockMushroom.java | 2 +- common/src/common/block/BlockNote.java | 2 +- common/src/common/block/BlockPistonBase.java | 4 +- .../src/common/block/BlockPistonMoving.java | 2 +- .../common/block/BlockRedstoneComparator.java | 4 +- common/src/common/block/BlockSign.java | 2 +- common/src/common/block/BlockSkull.java | 2 +- common/src/common/block/BlockTianReactor.java | 2 +- common/src/common/block/BlockVine.java | 2 +- .../src/common/block/ITileEntityProvider.java | 5 +- common/src/common/dimension/Dimension.java | 4 +- .../src/common/entity/item/EntityFalling.java | 2 +- common/src/common/entity/npc/EntityNPC.java | 2 +- common/src/common/item/ItemBucket.java | 4 +- common/src/common/network/PacketBuffer.java | 10 +- .../src/common/packet/SPacketChunkData.java | 55 ++- .../common/packet/SPacketMapChunkBulk.java | 17 +- .../packet/SPacketMultiBlockChange.java | 18 +- common/src/common/pathfinding/PathCache.java | 2 +- .../common/tileentity/TileEntityBeacon.java | 2 +- common/src/common/util/BlockPos.java | 21 -- common/src/common/world/Chunk.java | 328 ++++++++++++------ common/src/common/world/World.java | 28 +- .../src/server/clipboard/ClipboardPlacer.java | 2 - server/src/server/command/Command.java | 2 +- server/src/server/network/Player.java | 10 +- server/src/server/world/Region.java | 107 +++--- server/src/server/world/Spawner.java | 11 +- server/src/server/world/WorldServer.java | 66 +++- 49 files changed, 489 insertions(+), 291 deletions(-) diff --git a/client/src/client/network/ClientPlayer.java b/client/src/client/network/ClientPlayer.java index 1500a4e..ebea694 100755 --- a/client/src/client/network/ClientPlayer.java +++ b/client/src/client/network/ClientPlayer.java @@ -767,8 +767,8 @@ public class ClientPlayer extends NetHandler implements IClientPlayer // this.clientWorldController.invalidateBlockReceiveRegion(packetIn.getChunkX() << 4, 0, packetIn.getChunkZ() << 4, (packetIn.getChunkX() << 4) + 15, 512, (packetIn.getChunkZ() << 4) + 15); Chunk chunk = this.clientWorldController.getChunk(packetIn.getChunkX(), packetIn.getChunkZ()); - chunk.setData(packetIn.getExtractedDataBytes(), packetIn.getExtractedSize(), packetIn.hasBiomes()); - this.clientWorldController.markBlockRangeForRenderUpdate(packetIn.getChunkX() << 4, 0, packetIn.getChunkZ() << 4, (packetIn.getChunkX() << 4) + 15, 512, (packetIn.getChunkZ() << 4) + 15); + chunk.setData(packetIn.getExtractedDataBytes(), packetIn.getExtractedSize(), packetIn.getExtractedExtend(), packetIn.hasBiomes()); + this.clientWorldController.markBlockRangeForRenderUpdate(packetIn.getChunkX() << 4, -World.MAX_SIZE_Y, packetIn.getChunkZ() << 4, (packetIn.getChunkX() << 4) + 15, World.MAX_SIZE_Y, (packetIn.getChunkZ() << 4) + 15); if (!packetIn.hasBiomes() || this.clientWorldController.dimension.hasNoLight()) // TODO: check { @@ -781,7 +781,7 @@ public class ClientPlayer extends NetHandler implements IClientPlayer NetHandler.checkThread(packetIn, this, this.gameController, this.clientWorldController); Chunk chunk = this.clientWorldController.getChunk(packetIn.getChunkX(), packetIn.getChunkZ()); chunk.setBiomes(packetIn.getBiomes()); - this.clientWorldController.markBlockRangeForRenderUpdate(packetIn.getChunkX() << 4, 0, packetIn.getChunkZ() << 4, (packetIn.getChunkX() << 4) + 15, 512, (packetIn.getChunkZ() << 4) + 15); + this.clientWorldController.markBlockRangeForRenderUpdate(packetIn.getChunkX() << 4, -World.MAX_SIZE_Y, packetIn.getChunkZ() << 4, (packetIn.getChunkX() << 4) + 15, World.MAX_SIZE_Y, (packetIn.getChunkZ() << 4) + 15); } /** @@ -1413,8 +1413,8 @@ public class ClientPlayer extends NetHandler implements IClientPlayer this.clientWorldController.doPreChunk(j, k, true); // this.clientWorldController.invalidateBlockReceiveRegion(j << 4, 0, k << 4, (j << 4) + 15, 512, (k << 4) + 15); Chunk chunk = this.clientWorldController.getChunk(j, k); - chunk.setData(packetIn.getChunkBytes(i), packetIn.getChunkSize(i), true); - this.clientWorldController.markBlockRangeForRenderUpdate(j << 4, 0, k << 4, (j << 4) + 15, 512, (k << 4) + 15); + chunk.setData(packetIn.getChunkBytes(i), packetIn.getChunkSize(i), packetIn.getChunkExtend(i), true); + this.clientWorldController.markBlockRangeForRenderUpdate(j << 4, -World.MAX_SIZE_Y, k << 4, (j << 4) + 15, World.MAX_SIZE_Y, (k << 4) + 15); if (this.clientWorldController.dimension.hasNoLight()) // TODO: check { diff --git a/client/src/client/renderer/RegionRenderCache.java b/client/src/client/renderer/RegionRenderCache.java index 635a77a..e0ec2fc 100755 --- a/client/src/client/renderer/RegionRenderCache.java +++ b/client/src/client/renderer/RegionRenderCache.java @@ -87,7 +87,7 @@ public class RegionRenderCache extends ChunkCache implements IWorldAccess private State getBlockStateRaw(BlockPos pos) { - if (pos.getY() >= 0 && pos.getY() < 512) + if (pos.getY() >= -World.MAX_SIZE_Y && pos.getY() < World.MAX_SIZE_Y) { int i = (pos.getX() >> 4) - this.chunkX; int j = (pos.getZ() >> 4) - this.chunkZ; @@ -136,7 +136,7 @@ public class RegionRenderCache extends ChunkCache implements IWorldAccess { return 0; } - else if (pos.getY() >= 0 && pos.getY() < 512) + else if (pos.getY() >= -World.MAX_SIZE_Y && pos.getY() < World.MAX_SIZE_Y) { if (this.getState(pos).getBlock().getSumBrightness()) { @@ -183,7 +183,7 @@ public class RegionRenderCache extends ChunkCache implements IWorldAccess public int getLightFor(LightType p_175628_1_, BlockPos pos) { - if (pos.getY() >= 0 && pos.getY() < 512) + if (pos.getY() >= -World.MAX_SIZE_Y && pos.getY() < World.MAX_SIZE_Y) { int i = (pos.getX() >> 4) - this.chunkX; int j = (pos.getZ() >> 4) - this.chunkZ; diff --git a/client/src/client/renderer/RenderGlobal.java b/client/src/client/renderer/RenderGlobal.java index f1ad4b3..0af5835 100755 --- a/client/src/client/renderer/RenderGlobal.java +++ b/client/src/client/renderer/RenderGlobal.java @@ -53,6 +53,7 @@ import common.util.Vec3; import common.util.Vector3f; import common.world.Chunk; import common.world.State; +import common.world.World; public class RenderGlobal { @@ -632,7 +633,7 @@ public class RenderGlobal // boolean flag3 = this.gm.getRenderViewEntity() instanceof EntityLivingBase ? ((EntityLivingBase)this.gm.getRenderViewEntity()).isPlayerSleeping() : false; - if (entity2.posY < 0.0D || entity2.posY >= 512.0D || this.theWorld.isBlockLoaded(new BlockPos(entity2))) + if (entity2.posY < (double)(-World.MAX_SIZE_Y) || entity2.posY >= (double)World.MAX_SIZE_Y || this.theWorld.isBlockLoaded(new BlockPos(entity2))) { if((entity2 != this.gm.getRenderViewEntity() || this.gm.thirdPersonView != 0 /* || flag3 */)) { ++this.countEntitiesRendered; @@ -931,7 +932,7 @@ public class RenderGlobal private RenderChunk getRenderChunkOffset(BlockPos playerPos, RenderChunk renderChunkBase, Facing facing) { BlockPos blockpos = renderChunkBase.getBlockPosOffset16(facing); - return ExtMath.absi(playerPos.getX() - blockpos.getX()) > this.renderDistanceChunks * 16 ? null : (blockpos.getY() >= 0 && blockpos.getY() < 512 ? (ExtMath.absi(playerPos.getZ() - blockpos.getZ()) > this.renderDistanceChunks * 16 ? null : this.viewFrustum.getRenderChunk(blockpos)) : null); + return ExtMath.absi(playerPos.getX() - blockpos.getX()) > this.renderDistanceChunks * 16 ? null : (blockpos.getY() >= -World.MAX_SIZE_Y && blockpos.getY() < World.MAX_SIZE_Y ? (ExtMath.absi(playerPos.getZ() - blockpos.getZ()) > this.renderDistanceChunks * 16 ? null : this.viewFrustum.getRenderChunk(blockpos)) : null); } protected Vector3f getViewVector(Entity entityIn, double partialTicks) diff --git a/client/src/client/world/EmptyChunk.java b/client/src/client/world/EmptyChunk.java index 12867ba..c60a7ee 100755 --- a/client/src/client/world/EmptyChunk.java +++ b/client/src/client/world/EmptyChunk.java @@ -19,14 +19,12 @@ public class EmptyChunk extends Chunk { private final int liquidY; private final State liquid; private final Block liquidBlock; - private final int liquidMeta; public EmptyChunk(WorldClient world) { super(world, 0, 0); this.liquidY = world.dimension.getSeaLevel() - 1; this.liquid = world.dimension.getLiquid(); this.liquidBlock = this.liquid.getBlock(); - this.liquidMeta = this.liquidBlock.getMetaFromState(this.liquid); } public int getHeight(int x, int z) { @@ -107,7 +105,7 @@ public class EmptyChunk extends Chunk { return true; } - public void setData(byte[] data, int update, boolean biomes) { + public void setData(byte[] data, int update, int[] extend, boolean biomes) { } public Biome getBiome(BlockPos pos, BiomeGenerator gen) { diff --git a/client/src/client/world/WorldClient.java b/client/src/client/world/WorldClient.java index 28d3f18..32fa891 100755 --- a/client/src/client/world/WorldClient.java +++ b/client/src/client/world/WorldClient.java @@ -36,6 +36,7 @@ import common.util.BlockPos.MutableBlockPos; import common.world.Chunk; import common.world.AWorldClient; import common.world.State; +import common.world.World; public class WorldClient extends AWorldClient { @@ -80,14 +81,14 @@ public class WorldClient extends AWorldClient this.chunkMapping.add(id, this.emptyChunk); this.emptyChunkListing.remove(id); this.nextEmptyChunkListing.add(id); - this.markBlockRangeForRenderUpdate(x << 4, 0, z << 4, (x << 4) + 15, 512, (z << 4) + 15); + this.markBlockRangeForRenderUpdate(x << 4, -World.MAX_SIZE_Y, z << 4, (x << 4) + 15, World.MAX_SIZE_Y, (z << 4) + 15); } } for(Long id : this.emptyChunkListing) { this.chunkMapping.remove(id); int x = LongHashMap.getX(id); int z = LongHashMap.getZ(id); - this.markBlockRangeForRenderUpdate(x << 4, 0, z << 4, (x << 4) + 15, 512, (z << 4) + 15); + this.markBlockRangeForRenderUpdate(x << 4, -World.MAX_SIZE_Y, z << 4, (x << 4) + 15, World.MAX_SIZE_Y, (z << 4) + 15); } this.emptyChunkListing.clear(); this.emptyChunkListing.addAll(this.nextEmptyChunkListing); @@ -184,7 +185,7 @@ public class WorldClient extends AWorldClient if (!load) { - this.markBlockRangeForRenderUpdate(x * 16, 0, z * 16, x * 16 + 15, 512, z * 16 + 15); + this.markBlockRangeForRenderUpdate(x * 16, -World.MAX_SIZE_Y, z * 16, x * 16 + 15, World.MAX_SIZE_Y, z * 16 + 15); } } diff --git a/common/src/common/block/BlockBanner.java b/common/src/common/block/BlockBanner.java index b025774..0d455c7 100755 --- a/common/src/common/block/BlockBanner.java +++ b/common/src/common/block/BlockBanner.java @@ -87,7 +87,7 @@ public class BlockBanner extends BlockContainer /** * Returns a new instance of a block's tile entity class. Called on placing the block. */ - public TileEntity createNewTileEntity(World worldIn, int meta) + public TileEntity createNewTileEntity(World worldIn) { return new TileEntityBanner(); } diff --git a/common/src/common/block/BlockBeacon.java b/common/src/common/block/BlockBeacon.java index 2032c67..7789be3 100755 --- a/common/src/common/block/BlockBeacon.java +++ b/common/src/common/block/BlockBeacon.java @@ -49,7 +49,7 @@ public class BlockBeacon extends BlockContainer /** * Returns a new instance of a block's tile entity class. Called on placing the block. */ - public TileEntity createNewTileEntity(World worldIn, int meta) + public TileEntity createNewTileEntity(World worldIn) { return new TileEntityBeacon(); } diff --git a/common/src/common/block/BlockBlueShroom.java b/common/src/common/block/BlockBlueShroom.java index 648fadf..c6cc81b 100755 --- a/common/src/common/block/BlockBlueShroom.java +++ b/common/src/common/block/BlockBlueShroom.java @@ -70,7 +70,7 @@ public class BlockBlueShroom extends BlockBush public boolean canBlockStay(World worldIn, BlockPos pos, State state) { - if (pos.getY() >= 0 && pos.getY() < 512) + if (pos.getY() >= -World.MAX_SIZE_Y && pos.getY() < World.MAX_SIZE_Y) { State iblockstate = worldIn.getState(pos.down()); return (iblockstate.getBlock() == Blocks.tian_soil || iblockstate.getBlock() == Blocks.obsidian) ? true : (worldIn.getLight(pos) < 13 && this.canPlaceBlockOn(iblockstate.getBlock())); diff --git a/common/src/common/block/BlockBrewingStand.java b/common/src/common/block/BlockBrewingStand.java index dcd6dc6..db118c0 100755 --- a/common/src/common/block/BlockBrewingStand.java +++ b/common/src/common/block/BlockBrewingStand.java @@ -382,7 +382,7 @@ public class BlockBrewingStand extends BlockContainer /** * Returns a new instance of a block's tile entity class. Called on placing the block. */ - public TileEntity createNewTileEntity(World worldIn, int meta) + public TileEntity createNewTileEntity(World worldIn) { return new TileEntityBrewingStand(); } diff --git a/common/src/common/block/BlockChest.java b/common/src/common/block/BlockChest.java index a195e29..7366655 100755 --- a/common/src/common/block/BlockChest.java +++ b/common/src/common/block/BlockChest.java @@ -530,7 +530,7 @@ public class BlockChest extends BlockContainer /** * Returns a new instance of a block's tile entity class. Called on placing the block. */ - public TileEntity createNewTileEntity(World worldIn, int meta) + public TileEntity createNewTileEntity(World worldIn) { return new TileEntityChest(); } diff --git a/common/src/common/block/BlockDaylightDetector.java b/common/src/common/block/BlockDaylightDetector.java index f213c1f..420a0e1 100755 --- a/common/src/common/block/BlockDaylightDetector.java +++ b/common/src/common/block/BlockDaylightDetector.java @@ -152,7 +152,7 @@ public class BlockDaylightDetector extends BlockContainer /** * Returns a new instance of a block's tile entity class. Called on placing the block. */ - public TileEntity createNewTileEntity(World worldIn, int meta) + public TileEntity createNewTileEntity(World worldIn) { return new TileEntityDaylightDetector(); } diff --git a/common/src/common/block/BlockDispenser.java b/common/src/common/block/BlockDispenser.java index 1a80d27..7132bad 100755 --- a/common/src/common/block/BlockDispenser.java +++ b/common/src/common/block/BlockDispenser.java @@ -183,7 +183,7 @@ public class BlockDispenser extends BlockContainer /** * Returns a new instance of a block's tile entity class. Called on placing the block. */ - public TileEntity createNewTileEntity(World worldIn, int meta) + public TileEntity createNewTileEntity(World worldIn) { return new TileEntityDispenser(); } diff --git a/common/src/common/block/BlockDoor.java b/common/src/common/block/BlockDoor.java index 8388100..b8e0e96 100755 --- a/common/src/common/block/BlockDoor.java +++ b/common/src/common/block/BlockDoor.java @@ -291,7 +291,7 @@ public class BlockDoor extends Block public boolean canPlaceBlockAt(World worldIn, BlockPos pos) { - return pos.getY() >= 511 ? false : worldIn.isBlockSolid(pos.down()) && super.canPlaceBlockAt(worldIn, pos) && super.canPlaceBlockAt(worldIn, pos.up()); + return pos.getY() >= World.MAX_SIZE_Y - 1 ? false : worldIn.isBlockSolid(pos.down()) && super.canPlaceBlockAt(worldIn, pos) && super.canPlaceBlockAt(worldIn, pos.up()); } public int getMobilityFlag() diff --git a/common/src/common/block/BlockDropper.java b/common/src/common/block/BlockDropper.java index ec42106..8294171 100755 --- a/common/src/common/block/BlockDropper.java +++ b/common/src/common/block/BlockDropper.java @@ -24,7 +24,7 @@ public class BlockDropper extends BlockDispenser /** * Returns a new instance of a block's tile entity class. Called on placing the block. */ - public TileEntity createNewTileEntity(World worldIn, int meta) + public TileEntity createNewTileEntity(World worldIn) { return new TileEntityDropper(); } diff --git a/common/src/common/block/BlockEnchantmentTable.java b/common/src/common/block/BlockEnchantmentTable.java index c27dbab..b461b36 100755 --- a/common/src/common/block/BlockEnchantmentTable.java +++ b/common/src/common/block/BlockEnchantmentTable.java @@ -96,7 +96,7 @@ public class BlockEnchantmentTable extends BlockContainer /** * Returns a new instance of a block's tile entity class. Called on placing the block. */ - public TileEntity createNewTileEntity(World worldIn, int meta) + public TileEntity createNewTileEntity(World worldIn) { return new TileEntityEnchantmentTable(); } diff --git a/common/src/common/block/BlockFurnace.java b/common/src/common/block/BlockFurnace.java index 73731a1..6e344f0 100755 --- a/common/src/common/block/BlockFurnace.java +++ b/common/src/common/block/BlockFurnace.java @@ -167,7 +167,7 @@ public class BlockFurnace extends BlockContainer /** * Returns a new instance of a block's tile entity class. Called on placing the block. */ - public TileEntity createNewTileEntity(World worldIn, int meta) + public TileEntity createNewTileEntity(World worldIn) { return new TileEntityFurnace(); } diff --git a/common/src/common/block/BlockHopper.java b/common/src/common/block/BlockHopper.java index 88832e8..8b26c54 100755 --- a/common/src/common/block/BlockHopper.java +++ b/common/src/common/block/BlockHopper.java @@ -142,7 +142,7 @@ public class BlockHopper extends BlockContainer /** * Returns a new instance of a block's tile entity class. Called on placing the block. */ - public TileEntity createNewTileEntity(World worldIn, int meta) + public TileEntity createNewTileEntity(World worldIn) { return new TileEntityHopper(); } diff --git a/common/src/common/block/BlockLilyPad.java b/common/src/common/block/BlockLilyPad.java index 25e614d..2886bef 100755 --- a/common/src/common/block/BlockLilyPad.java +++ b/common/src/common/block/BlockLilyPad.java @@ -64,7 +64,7 @@ public class BlockLilyPad extends BlockBush public boolean canBlockStay(World worldIn, BlockPos pos, State state) { - if (pos.getY() >= 0 && pos.getY() < 512) + if (pos.getY() >= -World.MAX_SIZE_Y && pos.getY() < World.MAX_SIZE_Y) { State iblockstate = worldIn.getState(pos.down()); return (iblockstate.getBlock().getMaterial().isColdLiquid() && ((Integer)iblockstate.getValue(BlockLiquid.LEVEL)).intValue() == 0) diff --git a/common/src/common/block/BlockMachine.java b/common/src/common/block/BlockMachine.java index 782ab21..39ac59c 100755 --- a/common/src/common/block/BlockMachine.java +++ b/common/src/common/block/BlockMachine.java @@ -23,7 +23,7 @@ public abstract class BlockMachine extends BlockDirectional implements ITileEnti this.setTab(CheatTab.tabTech); } - public abstract TileEntity createNewTileEntity(World worldIn, int meta); + public abstract TileEntity createNewTileEntity(World worldIn); public void onBlockAdded(AWorldServer worldIn, BlockPos pos, State state) { this.updateState(worldIn, pos, state); diff --git a/common/src/common/block/BlockMobSpawner.java b/common/src/common/block/BlockMobSpawner.java index e8d4f46..18f87d3 100755 --- a/common/src/common/block/BlockMobSpawner.java +++ b/common/src/common/block/BlockMobSpawner.java @@ -22,7 +22,7 @@ public class BlockMobSpawner extends BlockContainer /** * Returns a new instance of a block's tile entity class. Called on placing the block. */ - public TileEntity createNewTileEntity(World worldIn, int meta) + public TileEntity createNewTileEntity(World worldIn) { return new TileEntityMobSpawner(); } diff --git a/common/src/common/block/BlockMushroom.java b/common/src/common/block/BlockMushroom.java index aedd4e5..2753e63 100755 --- a/common/src/common/block/BlockMushroom.java +++ b/common/src/common/block/BlockMushroom.java @@ -74,7 +74,7 @@ public class BlockMushroom extends BlockBush implements IGrowable public boolean canBlockStay(World worldIn, BlockPos pos, State state) { - if (pos.getY() >= 0 && pos.getY() < 512) + if (pos.getY() >= -World.MAX_SIZE_Y && pos.getY() < World.MAX_SIZE_Y) { State iblockstate = worldIn.getState(pos.down()); return iblockstate.getBlock() == Blocks.mycelium ? true : (iblockstate.getBlock() == Blocks.dirt && iblockstate.getValue(BlockDirt.VARIANT) == BlockDirt.DirtType.PODZOL ? true : worldIn.getLight(pos) < 13 && this.canPlaceBlockOn(iblockstate.getBlock())); diff --git a/common/src/common/block/BlockNote.java b/common/src/common/block/BlockNote.java index d1711a0..3a1203f 100755 --- a/common/src/common/block/BlockNote.java +++ b/common/src/common/block/BlockNote.java @@ -85,7 +85,7 @@ public class BlockNote extends BlockContainer /** * Returns a new instance of a block's tile entity class. Called on placing the block. */ - public TileEntity createNewTileEntity(World worldIn, int meta) + public TileEntity createNewTileEntity(World worldIn) { return new TileEntityNote(); } diff --git a/common/src/common/block/BlockPistonBase.java b/common/src/common/block/BlockPistonBase.java index e09a0e3..b4057bb 100755 --- a/common/src/common/block/BlockPistonBase.java +++ b/common/src/common/block/BlockPistonBase.java @@ -548,9 +548,9 @@ public class BlockPistonBase extends Block { return false; } - else if (pos.getY() >= 0 && (direction != Facing.DOWN || pos.getY() != 0)) + else if (pos.getY() >= -World.MAX_SIZE_Y && (direction != Facing.DOWN || pos.getY() != -World.MAX_SIZE_Y)) { - if (pos.getY() <= World.HEIGHT - 1 && (direction != Facing.UP || pos.getY() != World.HEIGHT - 1)) + if (pos.getY() <= World.MAX_SIZE_Y - 1 && (direction != Facing.UP || pos.getY() != World.MAX_SIZE_Y - 1)) { if (blockIn != Blocks.piston && blockIn != Blocks.sticky_piston) { diff --git a/common/src/common/block/BlockPistonMoving.java b/common/src/common/block/BlockPistonMoving.java index 8047a3c..1076638 100755 --- a/common/src/common/block/BlockPistonMoving.java +++ b/common/src/common/block/BlockPistonMoving.java @@ -35,7 +35,7 @@ public class BlockPistonMoving extends BlockContainer /** * Returns a new instance of a block's tile entity class. Called on placing the block. */ - public TileEntity createNewTileEntity(World worldIn, int meta) + public TileEntity createNewTileEntity(World worldIn) { return null; } diff --git a/common/src/common/block/BlockRedstoneComparator.java b/common/src/common/block/BlockRedstoneComparator.java index b44b3dc..948db47 100755 --- a/common/src/common/block/BlockRedstoneComparator.java +++ b/common/src/common/block/BlockRedstoneComparator.java @@ -242,7 +242,7 @@ public class BlockRedstoneComparator extends BlockRedstoneDiode implements ITile public void onBlockAdded(AWorldServer worldIn, BlockPos pos, State state) { super.onBlockAdded(worldIn, pos, state); - worldIn.setTileEntity(pos, this.createNewTileEntity(worldIn, 0)); + worldIn.setTileEntity(pos, this.createNewTileEntity(worldIn)); } public void onBlockRemoved(AWorldServer worldIn, BlockPos pos, State state) @@ -265,7 +265,7 @@ public class BlockRedstoneComparator extends BlockRedstoneDiode implements ITile /** * Returns a new instance of a block's tile entity class. Called on placing the block. */ - public TileEntity createNewTileEntity(World worldIn, int meta) + public TileEntity createNewTileEntity(World worldIn) { return new TileEntityComparator(); } diff --git a/common/src/common/block/BlockSign.java b/common/src/common/block/BlockSign.java index aa1aedf..ccbb72d 100755 --- a/common/src/common/block/BlockSign.java +++ b/common/src/common/block/BlockSign.java @@ -79,7 +79,7 @@ public class BlockSign extends BlockContainer /** * Returns a new instance of a block's tile entity class. Called on placing the block. */ - public TileEntity createNewTileEntity(World worldIn, int meta) + public TileEntity createNewTileEntity(World worldIn) { return new TileEntitySign(); } diff --git a/common/src/common/block/BlockSkull.java b/common/src/common/block/BlockSkull.java index 97d44ec..72ea6a0 100755 --- a/common/src/common/block/BlockSkull.java +++ b/common/src/common/block/BlockSkull.java @@ -77,7 +77,7 @@ public class BlockSkull extends BlockContainer return this.getState().withProperty(FACING, placer.getHorizontalFacing()); } - public TileEntity createNewTileEntity(World worldIn, int meta) + public TileEntity createNewTileEntity(World worldIn) { return new TileEntitySkull(); } diff --git a/common/src/common/block/BlockTianReactor.java b/common/src/common/block/BlockTianReactor.java index a073032..6855aa8 100755 --- a/common/src/common/block/BlockTianReactor.java +++ b/common/src/common/block/BlockTianReactor.java @@ -11,7 +11,7 @@ import common.world.State; import common.world.World; public class BlockTianReactor extends BlockMachine { - public TileEntity createNewTileEntity(World worldIn, int meta) { + public TileEntity createNewTileEntity(World worldIn) { return new TileEntityTianReactor(); } diff --git a/common/src/common/block/BlockVine.java b/common/src/common/block/BlockVine.java index ed6f33b..a674c81 100755 --- a/common/src/common/block/BlockVine.java +++ b/common/src/common/block/BlockVine.java @@ -280,7 +280,7 @@ public class BlockVine extends Block Facing enumfacing1 = Facing.random(rand); BlockPos blockpos1 = pos.up(); - if (enumfacing1 == Facing.UP && pos.getY() < 511 && worldIn.isAirBlock(blockpos1)) + if (enumfacing1 == Facing.UP && pos.getY() < World.MAX_SIZE_Y - 1 && worldIn.isAirBlock(blockpos1)) { if (!flag) { diff --git a/common/src/common/block/ITileEntityProvider.java b/common/src/common/block/ITileEntityProvider.java index f4628a7..e23572a 100755 --- a/common/src/common/block/ITileEntityProvider.java +++ b/common/src/common/block/ITileEntityProvider.java @@ -5,8 +5,5 @@ import common.world.World; public interface ITileEntityProvider { - /** - * Returns a new instance of a block's tile entity class. Called on placing the block. - */ - TileEntity createNewTileEntity(World worldIn, int meta); + TileEntity createNewTileEntity(World worldIn); } diff --git a/common/src/common/dimension/Dimension.java b/common/src/common/dimension/Dimension.java index 39b7bb3..e5c4b5b 100755 --- a/common/src/common/dimension/Dimension.java +++ b/common/src/common/dimension/Dimension.java @@ -975,6 +975,7 @@ public abstract class Dimension extends Nameable implements Comparable= UniverseRegistry.MORE_DIM_ID) { this.seaLevel = tag.getInteger("SeaLevel"); + this.filler = BlockRegistry.getFromIdName(tag.getString("FillerBlock"), Blocks.stone.getState()); this.liquid = BlockRegistry.getFromIdName(tag.getString("LiquidBlock"), Blocks.water.getState()); } } @@ -1021,7 +1022,6 @@ public abstract class Dimension extends Nameable implements Comparable= UniverseRegistry.MORE_DIM_ID) { tag.setInteger("SeaLevel", this.seaLevel); + tag.setString("FillerBlock", BlockRegistry.toIdName(this.filler)); tag.setString("LiquidBlock", BlockRegistry.toIdName(this.liquid)); } } @@ -1261,7 +1262,6 @@ public abstract class Dimension extends Nameable implements Comparable 100 && !this.worldObj.client && (blockpos1.getY() < 1 || blockpos1.getY() > 512) || this.fallTime > 600) + else if (this.fallTime > 100 && !this.worldObj.client && (blockpos1.getY() < -World.MAX_SIZE_Y + 1 || blockpos1.getY() > World.MAX_SIZE_Y) || this.fallTime > 600) { if (this.shouldDropItem && Config.objectDrop) { diff --git a/common/src/common/entity/npc/EntityNPC.java b/common/src/common/entity/npc/EntityNPC.java index 9bd5118..a7c9cca 100755 --- a/common/src/common/entity/npc/EntityNPC.java +++ b/common/src/common/entity/npc/EntityNPC.java @@ -2684,7 +2684,7 @@ public abstract class EntityNPC extends EntityLiving } else { - this.client.addToSendQueue(new CPacketPlayer.C06PacketPlayerPosLook(this.motionX, -999.0D, this.motionZ, this.rotYaw, this.rotPitch, this.onGround)); + this.client.addToSendQueue(new CPacketPlayer.C06PacketPlayerPosLook(this.motionX, -99999999.0D, this.motionZ, this.rotYaw, this.rotPitch, this.onGround)); flag2 = false; } diff --git a/common/src/common/item/ItemBucket.java b/common/src/common/item/ItemBucket.java index 94cb7c2..242d233 100755 --- a/common/src/common/item/ItemBucket.java +++ b/common/src/common/item/ItemBucket.java @@ -36,7 +36,7 @@ public class ItemBucket extends Item private final BlockDynamicLiquid liquid; private static boolean test(AWorldServer world, BlockPos pos, Set blocks, int max, BlockPos origin, int radius) { - if(pos.getY() < 0 || pos.getY() > max) + if(pos.getY() < -World.MAX_SIZE_Y || pos.getY() > max) return false; if(pos.getX() < origin.getX() - radius || pos.getX() > origin.getX() + radius) return false; @@ -54,7 +54,7 @@ public class ItemBucket extends Item List dirs = new ArrayList(); Set blocks = liquid == null ? null : Sets.newHashSet(FluidRegistry.getDynamicBlock(liquid), liquid, Blocks.air); State state = (liquid == null ? Blocks.air : liquid).getState(); - int max = 511; + int max = World.MAX_SIZE_Y - 1; if(liquid != null) { dirs.add(new Vec3i(1, 0, 0)); diff --git a/common/src/common/network/PacketBuffer.java b/common/src/common/network/PacketBuffer.java index 4d0df41..390c141 100755 --- a/common/src/common/network/PacketBuffer.java +++ b/common/src/common/network/PacketBuffer.java @@ -58,16 +58,14 @@ public class PacketBuffer public BlockPos readBlockPos() { -// return new BlockPos(this.readInt(), this.readInt(), this.readInt()); - return BlockPos.fromLong(this.readLong()); + return new BlockPos(this.readInt(), this.readInt(), this.readInt()); } public void writeBlockPos(BlockPos pos) { - this.writeLong(pos.toLong()); -// this.writeInt(pos.getX()); -// this.writeInt(pos.getY()); -// this.writeInt(pos.getZ()); + this.writeInt(pos.getX()); + this.writeInt(pos.getY()); + this.writeInt(pos.getZ()); } // public Text readChatComponent() throws IOException diff --git a/common/src/common/packet/SPacketChunkData.java b/common/src/common/packet/SPacketChunkData.java index 1996522..182f6b5 100755 --- a/common/src/common/packet/SPacketChunkData.java +++ b/common/src/common/packet/SPacketChunkData.java @@ -21,12 +21,12 @@ public class SPacketChunkData implements Packet { } - public SPacketChunkData(Chunk chunkIn, boolean biomes, int segUpdate) + public SPacketChunkData(Chunk chunkIn, boolean biomes, int segUpdate, int[] extend) { this.chunkX = chunkIn.xPos; this.chunkZ = chunkIn.zPos; this.biomes = biomes; - this.extractedData = getExtractedData(chunkIn, biomes, !chunkIn.getWorld().dimension.hasNoLight(), segUpdate); + this.extractedData = getExtractedData(chunkIn, biomes, !chunkIn.getWorld().dimension.hasNoLight(), segUpdate, extend); } /** @@ -40,6 +40,10 @@ public class SPacketChunkData implements Packet this.extractedData = new SPacketChunkData.Extracted(); this.extractedData.dataSize = buf.readInt(); this.extractedData.data = buf.readByteArray(); + this.extractedData.extend = new int[buf.readVarIntFromBuffer()]; + for(int z = 0; z < this.extractedData.extend.length; z++) { + this.extractedData.extend[z] = buf.readVarIntFromBuffer(); + } } /** @@ -52,6 +56,10 @@ public class SPacketChunkData implements Packet buf.writeBoolean(this.biomes); buf.writeInt(this.extractedData.dataSize); buf.writeByteArray(this.extractedData.data); + buf.writeVarIntToBuffer(this.extractedData.extend.length); + for(int z = 0; z < this.extractedData.extend.length; z++) { + buf.writeVarIntToBuffer(this.extractedData.extend[z]); + } } /** @@ -76,9 +84,11 @@ public class SPacketChunkData implements Packet return i + j + k + l; } - public static SPacketChunkData.Extracted getExtractedData(Chunk chunk, boolean biomes, boolean overworld, int segUpdate) + public static SPacketChunkData.Extracted getExtractedData(Chunk chunk, boolean biomes, boolean overworld, int segUpdate, int[] extend) { BlockArray[] aextendedblockstorage = chunk.getStorage(); + BlockArray[] down = chunk.getStorageDown(); + BlockArray[] up = chunk.getStorageUp(); SPacketChunkData.Extracted s21packetchunkdata$extracted = new SPacketChunkData.Extracted(); List list = Lists.newArrayList(); @@ -92,8 +102,37 @@ public class SPacketChunkData implements Packet list.add(extendedblockstorage); } } - - s21packetchunkdata$extracted.data = new byte[getSize(Integer.bitCount(s21packetchunkdata$extracted.dataSize), overworld, biomes)]; + int epos = list.size(); + if(extend == null) { + if(down != null) { + for(BlockArray arr : down) { + if(arr != null && (!biomes || !arr.isEmpty())) + list.add(arr); + } + } + if(up != null) { + for(BlockArray arr : up) { + if(arr != null && (!biomes || !arr.isEmpty())) + list.add(arr); + } + } + } + else { + for(int cy : extend) { + if(cy < 0 || cy >= aextendedblockstorage.length) { + BlockArray arr = chunk.getArray(cy); + if(arr != null && (!biomes || !arr.isEmpty())) + list.add(arr); + } + } + } + extend = new int[list.size() - epos]; + for(int z = 0; z < extend.length; z++) { + extend[z] = list.get(z + epos).getY(); + } + + s21packetchunkdata$extracted.extend = extend; + s21packetchunkdata$extracted.data = new byte[getSize(Integer.bitCount(s21packetchunkdata$extracted.dataSize) + extend.length, overworld, biomes)]; int j = 0; for (BlockArray extendedblockstorage1 : list) @@ -149,6 +188,11 @@ public class SPacketChunkData implements Packet return this.extractedData.dataSize; } + public int[] getExtractedExtend() + { + return this.extractedData.extend; + } + public boolean hasBiomes() { return this.biomes; @@ -158,5 +202,6 @@ public class SPacketChunkData implements Packet { public byte[] data; public int dataSize; + public int[] extend; } } diff --git a/common/src/common/packet/SPacketMapChunkBulk.java b/common/src/common/packet/SPacketMapChunkBulk.java index aebfac5..f83bc61 100755 --- a/common/src/common/packet/SPacketMapChunkBulk.java +++ b/common/src/common/packet/SPacketMapChunkBulk.java @@ -30,7 +30,7 @@ public class SPacketMapChunkBulk implements Packet for (int j = 0; j < i; ++j) { Chunk chunk = (Chunk)chunks.get(j); - SPacketChunkData.Extracted s21packetchunkdata$extracted = SPacketChunkData.getExtractedData(chunk, true, this.isOverworld, 0xffffffff); + SPacketChunkData.Extracted s21packetchunkdata$extracted = SPacketChunkData.getExtractedData(chunk, true, this.isOverworld, 0xffffffff, null); this.xPositions[j] = chunk.xPos; this.zPositions[j] = chunk.zPos; this.chunksData[j] = s21packetchunkdata$extracted; @@ -54,7 +54,11 @@ public class SPacketMapChunkBulk implements Packet this.zPositions[j] = buf.readInt(); this.chunksData[j] = new SPacketChunkData.Extracted(); this.chunksData[j].dataSize = buf.readInt(); - this.chunksData[j].data = new byte[SPacketChunkData.getSize(Integer.bitCount(this.chunksData[j].dataSize), this.isOverworld, true)]; + this.chunksData[j].extend = new int[buf.readVarIntFromBuffer()]; + for(int z = 0; z < this.chunksData[j].extend.length; z++) { + this.chunksData[j].extend[z] = buf.readVarIntFromBuffer(); + } + this.chunksData[j].data = new byte[SPacketChunkData.getSize(Integer.bitCount(this.chunksData[j].dataSize) + this.chunksData[j].extend.length, this.isOverworld, true)]; } for (int k = 0; k < i; ++k) @@ -76,6 +80,10 @@ public class SPacketMapChunkBulk implements Packet buf.writeInt(this.xPositions[i]); buf.writeInt(this.zPositions[i]); buf.writeInt(this.chunksData[i].dataSize); + buf.writeVarIntToBuffer(this.chunksData[i].extend.length); + for(int z = 0; z < this.chunksData[i].extend.length; z++) { + buf.writeVarIntToBuffer(this.chunksData[i].extend[z]); + } } for (int j = 0; j < this.xPositions.length; ++j) @@ -116,4 +124,9 @@ public class SPacketMapChunkBulk implements Packet { return this.chunksData[p_179754_1_].dataSize; } + + public int[] getChunkExtend(int index) + { + return this.chunksData[index].extend; + } } diff --git a/common/src/common/packet/SPacketMultiBlockChange.java b/common/src/common/packet/SPacketMultiBlockChange.java index 97d5e60..f6b4a4b 100755 --- a/common/src/common/packet/SPacketMultiBlockChange.java +++ b/common/src/common/packet/SPacketMultiBlockChange.java @@ -20,7 +20,7 @@ public class SPacketMultiBlockChange implements Packet { } - public SPacketMultiBlockChange(int p_i45181_1_, int[] crammedPositionsIn, Chunk chunkIn) + public SPacketMultiBlockChange(int p_i45181_1_, long[] crammedPositionsIn, Chunk chunkIn) { this.chunkPosCoord = new ChunkPos(chunkIn.xPos, chunkIn.zPos); this.changedBlocks = new SPacketMultiBlockChange.BlockUpdateData[p_i45181_1_]; @@ -41,7 +41,7 @@ public class SPacketMultiBlockChange implements Packet for (int i = 0; i < this.changedBlocks.length; ++i) { - this.changedBlocks[i] = new SPacketMultiBlockChange.BlockUpdateData(buf.readInt(), (State)BlockRegistry.STATEMAP.getByValue(buf.readVarIntFromBuffer())); + this.changedBlocks[i] = new SPacketMultiBlockChange.BlockUpdateData(buf.readLong(), (State)BlockRegistry.STATEMAP.getByValue(buf.readVarIntFromBuffer())); } } @@ -56,7 +56,7 @@ public class SPacketMultiBlockChange implements Packet for (SPacketMultiBlockChange.BlockUpdateData s22packetmultiblockchange$blockupdatedata : this.changedBlocks) { - buf.writeInt(s22packetmultiblockchange$blockupdatedata.getRawPos()); + buf.writeLong(s22packetmultiblockchange$blockupdatedata.getRawPos()); buf.writeVarIntToBuffer(BlockRegistry.STATEMAP.get(s22packetmultiblockchange$blockupdatedata.getBlockState())); } } @@ -76,16 +76,16 @@ public class SPacketMultiBlockChange implements Packet public class BlockUpdateData { - private final int position; + private final long position; private final State blockState; - public BlockUpdateData(int raw, State state) + public BlockUpdateData(long raw, State state) { this.position = raw; this.blockState = state; } - public BlockUpdateData(int raw, Chunk chunkIn) + public BlockUpdateData(long raw, Chunk chunkIn) { this.position = raw; this.blockState = chunkIn.getState(this.getPos()); @@ -93,11 +93,11 @@ public class SPacketMultiBlockChange implements Packet public BlockPos getPos() { - ChunkPos r = SPacketMultiBlockChange.this.chunkPosCoord; - return new BlockPos(new BlockPos((r.x << 4) + (this.position >> 13 & 15), this.position & 511, (r.z << 4) + (this.position >> 9 & 15))); + ChunkPos pos = SPacketMultiBlockChange.this.chunkPosCoord; + return new BlockPos(new BlockPos((pos.x << 4) + (int)(this.position >> 36 & 15L), (int)(this.position & 4294967295L), (pos.z << 4) + (int)(this.position >> 32 & 15L))); } - public int getRawPos() + public long getRawPos() { return this.position; } diff --git a/common/src/common/pathfinding/PathCache.java b/common/src/common/pathfinding/PathCache.java index 3af36a8..255b82c 100755 --- a/common/src/common/pathfinding/PathCache.java +++ b/common/src/common/pathfinding/PathCache.java @@ -17,7 +17,7 @@ public class PathCache extends ChunkCache implements IBlockAccess public State getState(BlockPos pos) { - if (pos.getY() >= 0 && pos.getY() < 512) + if (pos.getY() >= -World.MAX_SIZE_Y && pos.getY() < World.MAX_SIZE_Y) { int i = (pos.getX() >> 4) - this.chunkX; int j = (pos.getZ() >> 4) - this.chunkZ; diff --git a/common/src/common/tileentity/TileEntityBeacon.java b/common/src/common/tileentity/TileEntityBeacon.java index e8dc19f..19b6433 100755 --- a/common/src/common/tileentity/TileEntityBeacon.java +++ b/common/src/common/tileentity/TileEntityBeacon.java @@ -78,7 +78,7 @@ public class TileEntityBeacon extends TileEntity implements ITickable int j = this.pos.getX(); int k = this.pos.getY(); int l = this.pos.getZ(); - BoundingBox axisalignedbb = (new BoundingBox((double)j, (double)k, (double)l, (double)(j + 1), (double)(k + 1), (double)(l + 1))).expand(d0, d0, d0).addCoord(0.0D, (double)World.HEIGHT, 0.0D); + BoundingBox axisalignedbb = (new BoundingBox((double)j, (double)k, (double)l, (double)(j + 1), (double)(k + 1), (double)(l + 1))).expand(d0, d0, d0).addCoord(0.0D, (double)World.MAX_SIZE_Y, 0.0D); List list = this.worldObj.getEntitiesWithinAABB(EntityLiving.class, axisalignedbb); for (EntityLiving entityplayer : list) diff --git a/common/src/common/util/BlockPos.java b/common/src/common/util/BlockPos.java index 493452c..526a1f4 100755 --- a/common/src/common/util/BlockPos.java +++ b/common/src/common/util/BlockPos.java @@ -8,14 +8,6 @@ import common.entity.Entity; public class BlockPos extends Vec3i { public static final BlockPos ORIGIN = new BlockPos(0, 0, 0); - private static final int NUM_X_BITS = 1 + 26; // ExtMath.calculateLogBaseTwo(ExtMath.roundUpToPowerOfTwo(World.MAX_SIZE)); - private static final int NUM_Z_BITS = NUM_X_BITS; - private static final int NUM_Y_BITS = 64 - NUM_X_BITS - NUM_Z_BITS; - private static final int Y_SHIFT = 0 + NUM_Z_BITS; - private static final int X_SHIFT = Y_SHIFT + NUM_Y_BITS; - private static final long X_MASK = (1L << NUM_X_BITS) - 1L; - private static final long Y_MASK = (1L << NUM_Y_BITS) - 1L; - private static final long Z_MASK = (1L << NUM_Z_BITS) - 1L; public BlockPos(int x, int y, int z) { @@ -193,19 +185,6 @@ public class BlockPos extends Vec3i { return new BlockPos(this.getY() * vec.getZ() - this.getZ() * vec.getY(), this.getZ() * vec.getX() - this.getX() * vec.getZ(), this.getX() * vec.getY() - this.getY() * vec.getX()); } - - public long toLong() - { - return ((long)this.getX() & X_MASK) << X_SHIFT | ((long)this.getY() & Y_MASK) << Y_SHIFT | ((long)this.getZ() & Z_MASK) << 0; - } - - public static BlockPos fromLong(long serialized) - { - int i = (int)(serialized << 64 - X_SHIFT - NUM_X_BITS >> 64 - NUM_X_BITS); - int j = (int)(serialized << 64 - Y_SHIFT - NUM_Y_BITS >> 64 - NUM_Y_BITS); - int k = (int)(serialized << 64 - NUM_Z_BITS >> 64 - NUM_Z_BITS); - return new BlockPos(i, j, k); - } public static Iterable getAllInBox(BlockPos from, BlockPos to) { diff --git a/common/src/common/world/Chunk.java b/common/src/common/world/Chunk.java index efbb742..259a183 100755 --- a/common/src/common/world/Chunk.java +++ b/common/src/common/world/Chunk.java @@ -31,6 +31,8 @@ public class Chunk { public final int xPos; public final int zPos; private final World world; + private final State filler; + private final Block fillerBlock; private final BlockArray[] blocks = new BlockArray[32]; private final byte[] biomes = new byte[256]; private final int[] precHeight = new int[256]; @@ -48,18 +50,24 @@ public class Chunk { private boolean modified; private boolean hasEntity; private int minHeight; - private int lightChecks = 8192; + private int lightChecks = Integer.MAX_VALUE; + private int bottom = Integer.MAX_VALUE; + private int top = Integer.MIN_VALUE; private long lastSave; private long inhabited; + private BlockArray[] extendDown; + private BlockArray[] extendUp; public Chunk(World world, int x, int z) { this.world = world; this.xPos = x; this.zPos = z; + this.filler = world.dimension.getFiller(); + this.fillerBlock = this.filler.getBlock(); for(int y = 0; y < this.entities.length; ++y) { this.entities[y] = new ClassInheritanceMultiMap(Entity.class); } - Arrays.fill(this.precHeight, -999); + Arrays.fill(this.precHeight, -99999999); Arrays.fill(this.biomes, (byte)-1); } @@ -110,6 +118,8 @@ public class Chunk { for(int n = 0; n < this.biomes.length; ++n) { this.biomes[n] = (byte)biomes[n].id; } + this.bottom = height == 0 ? Integer.MAX_VALUE : 0; + this.top = height == 0 ? Integer.MIN_VALUE : (height + 15) >> 4; if(ceil == null) this.genSkyLight(); else @@ -124,29 +134,110 @@ public class Chunk { return this.height[z << 4 | x]; } - public int getTopSegment() { - for(int y = this.blocks.length - 1; y >= 0; --y) { - if(this.blocks[y] != null) { - return this.blocks[y].getY(); + private int findTopSegment() { + if(this.extendUp != null) { + for(int y = this.extendUp.length - 1; y >= 0; --y) { + if(this.extendUp[y] != null) + return this.extendUp[y].getY(); } } + for(int y = this.blocks.length - 1; y >= 0; --y) { + if(this.blocks[y] != null) + return this.blocks[y].getY(); + } + if(this.extendDown != null) { + for(int y = this.extendDown.length - 1; y >= 0; --y) { + if(this.extendDown[y] != null) + return this.extendDown[y].getY(); + } + } + return Integer.MIN_VALUE; + } - return 0; + private int findBottomSegment() { + if(this.extendDown != null) { + for(int y = 0; y < this.extendDown.length; ++y) { + if(this.extendDown[y] != null) + return this.extendDown[y].getY(); + } + } + for(int y = 0; y < this.blocks.length; ++y) { + if(this.blocks[y] != null) + return this.blocks[y].getY(); + } + if(this.extendUp != null) { + for(int y = 0; y < this.extendUp.length; ++y) { + if(this.extendUp[y] != null) + return this.extendUp[y].getY(); + } + } + return Integer.MAX_VALUE; + } + + public int getTopSegment() { + return this.top; + } + + public int getBottomSegment() { + return this.bottom; } public BlockArray[] getStorage() { return this.blocks; } + public BlockArray[] getStorageDown() { + return this.extendDown; + } + + public BlockArray[] getStorageUp() { + return this.extendUp; + } + + public BlockArray getArray(int y) { + return y >= 0 && y < this.blocks.length ? this.blocks[y] : (y < 0 ? (this.extendDown == null || -y > this.extendDown.length ? null : this.extendDown[-this.extendDown.length - y]) : (this.extendUp == null || y - this.blocks.length >= this.extendUp.length ? null : this.extendUp[y - this.blocks.length])); + } + + private void setArray(int y, BlockArray array) { + if(y >= 0 && y < this.blocks.length) { + this.blocks[y] = array; + } + else if(y < 0) { + if(this.extendDown == null) { + this.extendDown = new BlockArray[-y]; + } + else if(this.extendDown.length < -y) { + BlockArray[] extendDown = this.extendDown; + this.extendDown = new BlockArray[-y]; + System.arraycopy(extendDown, 0, this.extendDown, -y - extendDown.length, extendDown.length); + } + this.extendDown[-this.extendDown.length - y] = array; + } + else { + if(this.extendUp == null) { + this.extendUp = new BlockArray[1 + y - this.blocks.length]; + } + else if(this.extendUp.length <= y - this.blocks.length) { + BlockArray[] extendUp = this.extendUp; + this.extendUp = new BlockArray[1 + y - this.blocks.length]; + System.arraycopy(extendUp, 0, this.extendUp, 0, extendUp.length); + } + this.extendUp[y - this.blocks.length] = array; + } + this.bottom = this.findBottomSegment(); + this.top = this.findTopSegment(); + } + protected void genHeights() { - int h = this.getTopSegment(); + int top = this.getTopSegment(); + int bottom = this.getBottomSegment(); this.minHeight = Integer.MAX_VALUE; for(int x = 0; x < 16; ++x) { for(int z = 0; z < 16; ++z) { - this.precHeight[x + (z << 4)] = -999; + this.precHeight[x + (z << 4)] = -99999999; - for(int y = h + 16; y > 0; --y) { + for(int y = top + 16; y > bottom; --y) { Block block = this.getBlock0(x, y - 1, z); if(block.getLightOpacity() != 0) { @@ -166,14 +257,15 @@ public class Chunk { } public void genSkyLight() { - int h = this.getTopSegment(); + int top = this.getTopSegment(); + int bottom = this.getBottomSegment(); this.minHeight = Integer.MAX_VALUE; for(int x = 0; x < 16; ++x) { for(int z = 0; z < 16; ++z) { - this.precHeight[x + (z << 4)] = -999; + this.precHeight[x + (z << 4)] = -99999999; - for(int y = h + 16; y > 0; --y) { + for(int y = top + 16; y > bottom; --y) { if(this.getOpacity(x, y - 1, z) != 0) { this.height[z << 4 | x] = y; @@ -185,9 +277,9 @@ public class Chunk { } } - if(!this.world.dimension.hasNoLight()) { + if(!this.world.dimension.hasNoLight() && top != Integer.MIN_VALUE) { int l = 15; - int y = h + 16 - 1; + int y = top + 16 - 1; while(true) { int b = this.getOpacity(x, y, z); @@ -199,7 +291,7 @@ public class Chunk { l -= b; if(l > 0) { - BlockArray stor = this.blocks[y >> 4]; + BlockArray stor = this.getArray(y >> 4); if(stor != null) { stor.setSky(x, y & 15, z, l); @@ -209,7 +301,7 @@ public class Chunk { --y; - if(y <= 0 || l <= 0) { + if(y <= bottom || l <= 0) { break; } } @@ -285,14 +377,15 @@ public class Chunk { } private void relightBlock(int x, int y, int z) { - int h = this.height[z << 4 | x] & 511; + int h = this.height[z << 4 | x]; + int min = this.getBottomSegment(); int cy = h; if(y > h) { cy = y; } - while(cy > 0 && this.getOpacity(x, cy - 1, z) == 0) { + while(cy > min && this.getOpacity(x, cy - 1, z) == 0) { --cy; } @@ -305,7 +398,7 @@ public class Chunk { if(!this.world.dimension.hasNoLight()) { if(cy < h) { for(int n = cy; n < h; ++n) { - BlockArray stor = this.blocks[n >> 4]; + BlockArray stor = this.getArray(n >> 4); if(stor != null) { stor.setSky(x, n & 15, z, 15); @@ -315,7 +408,7 @@ public class Chunk { } else { for(int n = h; n < cy; ++n) { - BlockArray stor = this.blocks[n >> 4]; + BlockArray stor = this.getArray(n >> 4); if(stor != null) { stor.setSky(x, n & 15, z, 0); @@ -326,7 +419,7 @@ public class Chunk { int l = 15; - while(cy > 0 && l > 0) { + while(cy > min && l > 0) { --cy; int b = this.getOpacity(x, cy, z); @@ -340,7 +433,7 @@ public class Chunk { l = 0; } - BlockArray stor = this.blocks[cy >> 4]; + BlockArray stor = this.getArray(cy >> 4); if(stor != null) { stor.setSky(x, cy & 15, z, l); @@ -380,69 +473,48 @@ public class Chunk { private int getOpacity(int x, int y, int z) { return this.getBlock0(x, y, z).getLightOpacity(); } - + private Block getBlock0(int x, int y, int z) { - Block block = Blocks.air; - if(y >= 0 && y >> 4 < this.blocks.length) { BlockArray stor = this.blocks[y >> 4]; - - if(stor != null) { - block = stor.getBlock(x, y & 15, z); - } + return stor != null ? stor.getBlock(x, y & 15, z) : Blocks.air; + } + else if(y < 0 && this.extendDown != null && -(y >> 4) <= this.extendDown.length) { + BlockArray stor = this.extendDown[-this.extendDown.length - (y >> 4)]; + return stor != null ? stor.getBlock(x, y & 15, z) : this.fillerBlock; + } + else if(y >> 4 >= this.blocks.length && this.extendUp != null && (y >> 4) - this.blocks.length < this.extendUp.length) { + BlockArray stor = this.extendUp[(y >> 4) - this.blocks.length]; + return stor != null ? stor.getBlock(x, y & 15, z) : Blocks.air; + } + return y < 0 ? this.fillerBlock : Blocks.air; + } + + public State getState(BlockPos pos) { + if(this.world.debug) { + State state = pos.getY() == 1 ? DebugStates.getState(pos.getX(), pos.getZ()) : null; + return state == null ? Blocks.air.getState() : state; } - return block; + if(pos.getY() >= 0 && pos.getY() >> 4 < this.blocks.length) { + BlockArray stor = this.blocks[pos.getY() >> 4]; + return stor != null ? stor.get(pos.getX() & 15, pos.getY() & 15, pos.getZ() & 15) : Blocks.air.getState(); + } + else if(pos.getY() < 0 && this.extendDown != null && -(pos.getY() >> 4) <= this.extendDown.length) { + BlockArray stor = this.extendDown[-this.extendDown.length - (pos.getY() >> 4)]; + return stor != null ? stor.get(pos.getX() & 15, pos.getY() & 15, pos.getZ() & 15) : this.filler; + } + else if(pos.getY() >> 4 >= this.blocks.length && this.extendUp != null && (pos.getY() >> 4) - this.blocks.length < this.extendUp.length) { + BlockArray stor = this.extendUp[(pos.getY() >> 4) - this.blocks.length]; + return stor != null ? stor.get(pos.getX() & 15, pos.getY() & 15, pos.getZ() & 15) : Blocks.air.getState(); + } + return pos.getY() < 0 ? this.filler : Blocks.air.getState(); } public Block getBlock(BlockPos pos) { return this.getBlock0(pos.getX() & 15, pos.getY(), pos.getZ() & 15); } - - public State getState(BlockPos pos) { - if(this.world.debug) { - State state = null; - -// if(pos.getY() == 60) { -// state = Blocks.glass.getDefaultState(); -// } - - if(pos.getY() == 1) { - state = DebugStates.getState(pos.getX(), pos.getZ()); - } - - return state == null ? Blocks.air.getState() : state; - } - else { - if(pos.getY() >= 0 && pos.getY() >> 4 < this.blocks.length) { - BlockArray stor = this.blocks[pos.getY() >> 4]; - - if(stor != null) { - int x = pos.getX() & 15; - int y = pos.getY() & 15; - int z = pos.getZ() & 15; - return stor.get(x, y, z); - } - } - - return Blocks.air.getState(); - } - } - - private int getMeta(int x, int y, int z) { - if(y >> 4 >= this.blocks.length) { - return 0; - } - else { - BlockArray stor = this.blocks[y >> 4]; - return stor != null ? stor.getMeta(x, y & 15, z) : 0; - } - } - - public int getMeta(BlockPos pos) { - return this.getMeta(pos.getX() & 15, pos.getY(), pos.getZ() & 15); - } - + public State setState(BlockPos pos, State state) { int x = pos.getX() & 15; int y = pos.getY(); @@ -450,7 +522,7 @@ public class Chunk { int o = z << 4 | x; if(y >= this.precHeight[o] - 1) { - this.precHeight[o] = -999; + this.precHeight[o] = -99999999; } int h = this.height[o]; @@ -462,7 +534,7 @@ public class Chunk { else { Block block = state.getBlock(); Block oldb = old.getBlock(); - BlockArray stor = this.blocks[y >> 4]; + BlockArray stor = this.getArray(y >> 4); boolean up = false; if(stor == null) { @@ -470,7 +542,8 @@ public class Chunk { return null; } - stor = this.blocks[y >> 4] = new BlockArray(y >> 4 << 4, !this.world.dimension.hasNoLight()); + stor = new BlockArray(y >> 4 << 4, !this.world.dimension.hasNoLight()); + this.setArray(y >> 4, stor); up = y >= h; } @@ -526,7 +599,7 @@ public class Chunk { TileEntity tile = this.getTileEntity(pos, TileEntity.EnumCreateEntityType.CHECK); if(tile == null) { - tile = ((ITileEntityProvider)block).createNewTileEntity(this.world, block.getMetaFromState(state)); + tile = ((ITileEntityProvider)block).createNewTileEntity(this.world); this.world.setTileEntity(pos, tile); } @@ -545,7 +618,7 @@ public class Chunk { int x = pos.getX() & 15; int y = pos.getY(); int z = pos.getZ() & 15; - BlockArray stor = this.blocks[y >> 4]; + BlockArray stor = this.getArray(y >> 4); return stor == null ? (this.canSeeSky(pos) ? type.defValue : 0) : (type == LightType.SKY ? (this.world.dimension.hasNoLight() ? 0 : stor.getSky(x, y & 15, z)) : (type == LightType.BLOCK ? stor.getLight(x, y & 15, z) : type.defValue)); @@ -555,10 +628,11 @@ public class Chunk { int x = pos.getX() & 15; int y = pos.getY(); int z = pos.getZ() & 15; - BlockArray stor = this.blocks[y >> 4]; + BlockArray stor = this.getArray(y >> 4); if(stor == null) { - stor = this.blocks[y >> 4] = new BlockArray(y >> 4 << 4, !this.world.dimension.hasNoLight()); + stor = new BlockArray(y >> 4 << 4, !this.world.dimension.hasNoLight()); + this.setArray(y >> 4, stor); this.genSkyLight(); } @@ -578,7 +652,7 @@ public class Chunk { int x = pos.getX() & 15; int y = pos.getY(); int z = pos.getZ() & 15; - BlockArray stor = this.blocks[y >> 4]; + BlockArray stor = this.getArray(y >> 4); if(stor == null) { return !this.world.dimension.hasNoLight() && amount < LightType.SKY.defValue @@ -647,7 +721,7 @@ public class Chunk { private TileEntity createNewTileEntity(BlockPos pos) { Block block = this.getBlock(pos); - return !block.hasTileEntity() ? null : ((ITileEntityProvider)block).createNewTileEntity(this.world, this.getMeta(pos)); + return !block.hasTileEntity() ? null : ((ITileEntityProvider)block).createNewTileEntity(this.world); } public TileEntity getTileEntity(BlockPos pos, TileEntity.EnumCreateEntityType type) { @@ -805,12 +879,13 @@ public class Chunk { int o = x | z << 4; BlockPos loc = new BlockPos(pos.getX(), this.precHeight[o], pos.getZ()); - if(loc.getY() == -999) { + if(loc.getY() == -99999999) { int y = this.getTopSegment() + 15; + int min = this.getBottomSegment(); loc = new BlockPos(pos.getX(), y, pos.getZ()); int h = -1; - while(loc.getY() > 0 && h == -1) { + while(loc.getY() > min && h == -1) { Block block = this.getBlock(loc); Material mat = block.getMaterial(); @@ -861,16 +936,8 @@ public class Chunk { } public boolean isEmpty(int bottom, int top) { - if(bottom < 0) { - bottom = 0; - } - - if(top >= 512) { - top = 511; - } - for(int y = bottom; y <= top; y += 16) { - BlockArray stor = this.blocks[y >> 4]; + BlockArray stor = this.getArray(y >> 4); if(stor != null && !stor.isEmpty()) { return false; @@ -880,7 +947,7 @@ public class Chunk { return true; } - public void setStorage(BlockArray[] arrays) { + public void setStorage(BlockArray[] arrays, BlockArray[] down, BlockArray[] up) { if(this.blocks.length != arrays.length) { Log.JNI.warn("Konnte Sektionen des Chunks nicht setzen, Länge des Arrays ist " + arrays.length + " statt " + this.blocks.length); @@ -889,10 +956,14 @@ public class Chunk { for(int n = 0; n < this.blocks.length; ++n) { this.blocks[n] = arrays[n]; } + this.extendDown = down; + this.extendUp = up; + this.bottom = this.findBottomSegment(); + this.top = this.findTopSegment(); } } - public void setData(byte[] data, int update, boolean biomes) { + public void setData(byte[] data, int update, int[] extend, boolean biomes) { int pos = 0; boolean sky = !this.world.dimension.hasNoLight(); @@ -913,6 +984,23 @@ public class Chunk { this.blocks[n] = null; } } + if(biomes) { + this.extendDown = null; + this.extendUp = null; + } + for(int cy : extend) { + BlockArray arr = this.getArray(cy); + if(arr == null) { + arr = new BlockArray(cy << 4, sky); + } + + char[] blocks = arr.getData(); + + for(int k = 0; k < blocks.length; ++k) { + blocks[k] = (char)((data[pos + 1] & 255) << 8 | data[pos] & 255); + pos += 2; + } + } for(int n = 0; n < this.blocks.length; ++n) { if((update & 1 << n) != 0 && this.blocks[n] != null) { @@ -921,6 +1009,14 @@ public class Chunk { pos += light.getData().length; } } + for(int cy : extend) { + BlockArray arr = this.getArray(cy); + if(arr != null) { + NibbleArray light = arr.getBlocklight(); + System.arraycopy(data, pos, light.getData(), 0, light.getData().length); + pos += light.getData().length; + } + } if(sky) { for(int n = 0; n < this.blocks.length; ++n) { @@ -930,18 +1026,35 @@ public class Chunk { pos += slight.getData().length; } } + for(int cy : extend) { + BlockArray arr = this.getArray(cy); + if(arr != null) { + NibbleArray slight = arr.getSkylight(); + System.arraycopy(data, pos, slight.getData(), 0, slight.getData().length); + pos += slight.getData().length; + } + } } if(biomes) { System.arraycopy(data, pos, this.biomes, 0, this.biomes.length); // int unk = pos + this.biomes.length; } + + this.bottom = this.findBottomSegment(); + this.top = this.findTopSegment(); for(int n = 0; n < this.blocks.length; ++n) { if(this.blocks[n] != null && (update & 1 << n) != 0) { this.blocks[n].update(); } } + for(int cy : extend) { + BlockArray arr = this.getArray(cy); + if(arr != null) { + arr.update(); + } + } this.lightInit = true; this.populated = true; @@ -996,11 +1109,14 @@ public class Chunk { BlockPos pos = new BlockPos(this.xPos << 4, 0, this.zPos << 4); for(int n = 0; n < 8; ++n) { - if(this.lightChecks >= 8192) + if(this.top == Integer.MIN_VALUE) + return; + int h = 1 + this.top - this.bottom; + if(this.lightChecks >= 256 * h) return; - int s = this.lightChecks % 31; - int x = this.lightChecks / 31 % 16; + int s = (this.lightChecks % h) + this.bottom; + int x = this.lightChecks / h % 16; int z = this.lightChecks / 512; ++this.lightChecks; @@ -1008,8 +1124,9 @@ public class Chunk { BlockPos block = pos.add(x, (s << 4) + y, z); boolean edge = y == 0 || y == 15 || x == 0 || x == 15 || z == 0 || z == 15; - if(this.blocks[s] == null && edge || this.blocks[s] != null - && this.blocks[s].getBlock(x, y, z).getMaterial() == Material.air) { + BlockArray arr = this.getArray(s); + if(arr == null && edge || arr != null + && arr.getBlock(x, y, z).getMaterial() == Material.air) { for(Facing face : Facing.values()) { BlockPos side = block.offset(face); @@ -1092,11 +1209,12 @@ public class Chunk { private boolean updateColumn(int x, int z) { int top = this.getTopSegment(); + int bottom = this.getBottomSegment(); boolean opaque = false; boolean below = false; BlockPos.MutableBlockPos pos = new BlockPos.MutableBlockPos((this.xPos << 4) + x, 0, (this.zPos << 4) + z); - for(int y = top + 16 - 1; y > this.world.getSeaLevel() || y > 0 && !below; --y) { + for(int y = top + 16 - 1; y > this.world.getSeaLevel() || y > bottom && !below; --y) { pos.set(pos.getX(), y, pos.getZ()); int o = this.getOpacity(pos); @@ -1112,7 +1230,7 @@ public class Chunk { } } - for(int y = pos.getY(); y > 0; --y) { + for(int y = pos.getY(); y > bottom; --y) { pos.set(pos.getX(), y, pos.getZ()); if(this.getBlock(pos).getLightValue() > 0) { diff --git a/common/src/common/world/World.java b/common/src/common/world/World.java index b1529dc..6d991e3 100755 --- a/common/src/common/world/World.java +++ b/common/src/common/world/World.java @@ -51,7 +51,7 @@ public abstract class World implements IWorldAccess { } public static final float[] MOON_PHASES = new float[] {1.0F, 0.75F, 0.5F, 0.25F, 0.0F, 0.25F, 0.5F, 0.75F}; public static final int MAX_SIZE = 67108864; - public static final int HEIGHT = 512; + public static final int MAX_SIZE_Y = 4096; public static final long START_TIME = 4385238000L; public static final float ABSOLUTE_ZERO = -273.15f; // private static final Calendar calendar = Calendar.getInstance(); @@ -109,7 +109,7 @@ public abstract class World implements IWorldAccess { public static boolean isValid(BlockPos pos) { return pos.getX() >= -MAX_SIZE && pos.getZ() >= -MAX_SIZE && pos.getX() < MAX_SIZE && pos.getZ() < MAX_SIZE && - pos.getY() >= 0 && pos.getY() < 512; + pos.getY() >= -MAX_SIZE_Y && pos.getY() < MAX_SIZE_Y; } public static boolean isValidXZ(BlockPos pos) { @@ -170,7 +170,7 @@ public abstract class World implements IWorldAccess { } private boolean isAreaLoaded(int xStart, int yStart, int zStart, int xEnd, int yEnd, int zEnd, boolean allowEmpty) { - if(yEnd >= 0 && yStart < 512) { + if(yEnd >= -MAX_SIZE_Y && yStart < MAX_SIZE_Y) { xStart = xStart >> 4; zStart = zStart >> 4; xEnd = xEnd >> 4; @@ -344,12 +344,12 @@ public abstract class World implements IWorldAccess { } public int getLight(BlockPos pos) { - if(pos.getY() < 0) { + if(pos.getY() < -MAX_SIZE_Y) { return 0; } else { - if(pos.getY() >= 512) { - pos = new BlockPos(pos.getX(), 511, pos.getZ()); + if(pos.getY() >= MAX_SIZE_Y) { + pos = new BlockPos(pos.getX(), MAX_SIZE_Y - 1, pos.getZ()); } return this.getChunk(pos).getLightSub(pos, 0); @@ -387,12 +387,12 @@ public abstract class World implements IWorldAccess { return i1; } - else if(pos.getY() < 0) { + else if(pos.getY() < -MAX_SIZE_Y) { return 0; } else { - if(pos.getY() >= 512) { - pos = new BlockPos(pos.getX(), 511, pos.getZ()); + if(pos.getY() >= MAX_SIZE_Y) { + pos = new BlockPos(pos.getX(), MAX_SIZE_Y - 1, pos.getZ()); } Chunk chunk = this.getChunk(pos); @@ -442,8 +442,8 @@ public abstract class World implements IWorldAccess { return 0; } else { - if(pos.getY() < 0) { - pos = new BlockPos(pos.getX(), 0, pos.getZ()); + if(pos.getY() < -MAX_SIZE_Y) { + pos = new BlockPos(pos.getX(), -MAX_SIZE_Y, pos.getZ()); } if(!isValid(pos)) { @@ -485,8 +485,8 @@ public abstract class World implements IWorldAccess { } public int getLightFor(LightType type, BlockPos pos) { - if(pos.getY() < 0) { - pos = new BlockPos(pos.getX(), 0, pos.getZ()); + if(pos.getY() < -MAX_SIZE_Y) { + pos = new BlockPos(pos.getX(), -MAX_SIZE_Y, pos.getZ()); } if(!isValid(pos)) { @@ -1593,7 +1593,7 @@ public abstract class World implements IWorldAccess { return true; } else { - if(pos.getY() >= 0 && pos.getY() < 512 && this.getLightFor(LightType.BLOCK, pos) < 10) { + if(pos.getY() >= -MAX_SIZE_Y && pos.getY() < MAX_SIZE_Y && this.getLightFor(LightType.BLOCK, pos) < 10) { Block block = this.getState(pos).getBlock(); if((block.getMaterial() == Material.air || (allowLayers && block == Blocks.snow_layer)) diff --git a/server/src/server/clipboard/ClipboardPlacer.java b/server/src/server/clipboard/ClipboardPlacer.java index 24d9db5..e8239d1 100755 --- a/server/src/server/clipboard/ClipboardPlacer.java +++ b/server/src/server/clipboard/ClipboardPlacer.java @@ -41,8 +41,6 @@ public class ClipboardPlacer { } public void setBlock(BlockPos location, ClipboardBlock block) { - if(location.getY() < 0 || location.getY() > 511) - return; Block type = block.getState().getBlock(); if (ReorderRegistry.shouldPlaceLast(type)) { // Place torches, etc. last diff --git a/server/src/server/command/Command.java b/server/src/server/command/Command.java index e58b0d7..7828595 100644 --- a/server/src/server/command/Command.java +++ b/server/src/server/command/Command.java @@ -74,7 +74,7 @@ public abstract class Command implements Executable { } }, new DoubleParser("x", defaulted ? DefType.X : null, (double)(-World.MAX_SIZE), (double)World.MAX_SIZE, centered), - new DoubleParser("y", defaulted ? DefType.Y : null, 0.0, (double)World.HEIGHT, false), + new DoubleParser("y", defaulted ? DefType.Y : null, (double)(-World.MAX_SIZE_Y), (double)World.MAX_SIZE_Y, false), new DoubleParser("z", defaulted ? DefType.Z : null, (double)(-World.MAX_SIZE), (double)World.MAX_SIZE, centered)); } diff --git a/server/src/server/network/Player.java b/server/src/server/network/Player.java index f42a452..3377336 100755 --- a/server/src/server/network/Player.java +++ b/server/src/server/network/Player.java @@ -970,7 +970,7 @@ public class Player extends NetHandler implements ICrafting, Executor, IPlayer if (chunk.isPopulated()) { list.add(chunk); - list1.addAll(((WorldServer)this.entity.worldObj).getTileEntitiesIn(chunkcoordintpair.x * 16, 0, chunkcoordintpair.z * 16, chunkcoordintpair.x * 16 + 16, 512, chunkcoordintpair.z * 16 + 16)); + list1.addAll(((WorldServer)this.entity.worldObj).getTileEntitiesIn(chunkcoordintpair.x * 16, -World.MAX_SIZE_Y, chunkcoordintpair.z * 16, chunkcoordintpair.x * 16 + 16, World.MAX_SIZE_Y, chunkcoordintpair.z * 16 + 16)); iterator1.remove(); } } @@ -985,7 +985,7 @@ public class Player extends NetHandler implements ICrafting, Executor, IPlayer { if (list.size() == 1) { - this.sendPacket(new SPacketChunkData((Chunk)list.get(0), true, 0xffffffff)); + this.sendPacket(new SPacketChunkData((Chunk)list.get(0), true, 0xffffffff, null)); } else { @@ -2098,7 +2098,7 @@ public class Player extends NetHandler implements ICrafting, Executor, IPlayer float f1 = this.entity.rotYaw; float f2 = this.entity.rotPitch; - if (packetIn.isMoving() && packetIn.getPositionY() == -999.0D) + if (packetIn.isMoving() && packetIn.getPositionY() == -99999999.0D) { packetIn.setMoving(false); } @@ -2281,7 +2281,7 @@ public class Player extends NetHandler implements ICrafting, Executor, IPlayer { return; } - else if (blockpos.getY() >= World.HEIGHT) + else if (blockpos.getY() >= World.MAX_SIZE_Y) { return; } @@ -2345,7 +2345,7 @@ public class Player extends NetHandler implements ICrafting, Executor, IPlayer this.tryUseItem(itemstack); // } } - else if (blockpos.getY() < World.HEIGHT - 1 || enumfacing != Facing.UP && blockpos.getY() < World.HEIGHT) + else if (blockpos.getY() < World.MAX_SIZE_Y - 1 || enumfacing != Facing.UP && blockpos.getY() < World.MAX_SIZE_Y) { double max = this.entity.getReachDistance() + 3.0D; max *= max; diff --git a/server/src/server/world/Region.java b/server/src/server/world/Region.java index fcf1367..21618b4 100755 --- a/server/src/server/world/Region.java +++ b/server/src/server/world/Region.java @@ -376,12 +376,22 @@ public class Region { chunk.setInhabited(tag.getLong("InhabitedTime")); NBTTagList sects = tag.getTagList("Sections", 10); int stor = 32; + int min = 0; + int max = stor - 1; + for(int n = 0; n < sects.tagCount(); ++n) { + NBTTagCompound sect = sects.getCompoundTagAt(n); + int y = sect.getInteger("Y"); + min = y < min ? y : min; + max = y > max ? y : max; + } BlockArray[] sections = new BlockArray[stor]; + BlockArray[] down = min < 0 ? new BlockArray[-min] : null; + BlockArray[] up = max >= stor ? new BlockArray[1 + max - stor] : null; boolean light = !world.dimension.hasNoLight(); for(int n = 0; n < sects.tagCount(); ++n) { NBTTagCompound sect = sects.getCompoundTagAt(n); - int y = sect.getByte("Y"); + int y = sect.getInteger("Y"); BlockArray storage = new BlockArray(y << 4, light); byte[] blocks = sect.getByteArray("Blocks"); NibbleArray data = new NibbleArray(sect.getByteArray("Data")); @@ -404,10 +414,15 @@ public class Region { } storage.update(); - sections[y] = storage; + if(y >= 0 && y < stor) + sections[y] = storage; + else if(y < 0) + down[-down.length - y] = storage; + else + up[y - stor] = storage; } - chunk.setStorage(sections); + chunk.setStorage(sections, down, up); if(tag.hasKey("Biomes", 7)) { chunk.setBiomes(tag.getByteArray("Biomes")); @@ -495,52 +510,58 @@ public class Region { tag.setBoolean("LightPopulated", chunk.isLightPopulated()); tag.setLong("InhabitedTime", chunk.getInhabited()); BlockArray[] sections = chunk.getStorage(); + BlockArray[] down = chunk.getStorage(); + BlockArray[] up = chunk.getStorage(); NBTTagList sects = new NBTTagList(); boolean light = !world.dimension.hasNoLight(); - for(BlockArray storage : sections) { - if(storage != null) { - NBTTagCompound sect = new NBTTagCompound(); - sect.setByte("Y", (byte)(storage.getY() >> 4 & 511)); - byte[] blocks = new byte[storage.getData().length]; - NibbleArray data = new NibbleArray(); - NibbleArray adddata = null; - - for(int c = 0; c < storage.getData().length; ++c) { - char cd = storage.getData()[c]; - int cx = c & 15; - int cy = c >> 8 & 15; - int cz = c >> 4 & 15; - - if(cd >> 12 != 0) { - if(adddata == null) { - adddata = new NibbleArray(); + for(BlockArray[] sec : new BlockArray[][] {sections, down, up}) { + if(sec == null) + continue; + for(BlockArray storage : sec) { + if(storage != null) { + NBTTagCompound sect = new NBTTagCompound(); + sect.setInteger("Y", storage.getY() >> 4); + byte[] blocks = new byte[storage.getData().length]; + NibbleArray data = new NibbleArray(); + NibbleArray adddata = null; + + for(int c = 0; c < storage.getData().length; ++c) { + char cd = storage.getData()[c]; + int cx = c & 15; + int cy = c >> 8 & 15; + int cz = c >> 4 & 15; + + if(cd >> 12 != 0) { + if(adddata == null) { + adddata = new NibbleArray(); + } + + adddata.set(cx, cy, cz, cd >> 12); } - - adddata.set(cx, cy, cz, cd >> 12); + + blocks[c] = (byte)(cd >> 4 & 255); + data.set(cx, cy, cz, cd & 15); } - - blocks[c] = (byte)(cd >> 4 & 255); - data.set(cx, cy, cz, cd & 15); + + sect.setByteArray("Blocks", blocks); + sect.setByteArray("Data", data.getData()); + + if(adddata != null) { + sect.setByteArray("Add", adddata.getData()); + } + + sect.setByteArray("BlockLight", storage.getBlocklight().getData()); + + if(light) { + sect.setByteArray("SkyLight", storage.getSkylight().getData()); + } + else { + sect.setByteArray("SkyLight", new byte[storage.getBlocklight().getData().length]); + } + + sects.appendTag(sect); } - - sect.setByteArray("Blocks", blocks); - sect.setByteArray("Data", data.getData()); - - if(adddata != null) { - sect.setByteArray("Add", adddata.getData()); - } - - sect.setByteArray("BlockLight", storage.getBlocklight().getData()); - - if(light) { - sect.setByteArray("SkyLight", storage.getSkylight().getData()); - } - else { - sect.setByteArray("SkyLight", new byte[storage.getBlocklight().getData().length]); - } - - sects.appendTag(sect); } } diff --git a/server/src/server/world/Spawner.java b/server/src/server/world/Spawner.java index 5133cf3..49a623f 100755 --- a/server/src/server/world/Spawner.java +++ b/server/src/server/world/Spawner.java @@ -90,13 +90,10 @@ public abstract class Spawner { Chunk chunk = world.getChunk(coord.x, coord.z); int x = coord.x * 16 + world.rand.zrange(16); int z = coord.z * 16 + world.rand.zrange(16); - int h = chunk.getHeight(new BlockPos(x, 0, z)) + 1; - if(h > 0) { - int m = h % 16; - h = m == 0 ? h : h + 16 - m; - } - h = h == 0 ? 16 : (h > 0 ? h : chunk.getTopSegment() + 16 - 1); - int y = world.rand.excl(h <= 8 ? 0 : 8, h); + int h = chunk.getTopSegment(); + if(h == Integer.MIN_VALUE) + continue; + int y = world.rand.range(chunk.getBottomSegment(), h + 16); BlockPos pos = new BlockPos(x, y, z); Block block = world.getState(pos).getBlock(); if(!block.isNormalCube()) { diff --git a/server/src/server/world/WorldServer.java b/server/src/server/world/WorldServer.java index 37b2873..b6270ec 100755 --- a/server/src/server/world/WorldServer.java +++ b/server/src/server/world/WorldServer.java @@ -741,7 +741,7 @@ public final class WorldServer extends AWorldServer { private BlockPos adjustPosToNearbyEntity(BlockPos pos) { BlockPos blockpos = this.getPrecipitationHeight(pos); - BoundingBox axisalignedbb = (new BoundingBox(blockpos, new BlockPos(blockpos.getX(), World.HEIGHT, blockpos.getZ()))).expand(3.0D, + BoundingBox axisalignedbb = (new BoundingBox(blockpos, new BlockPos(blockpos.getX(), World.MAX_SIZE_Y, blockpos.getZ()))).expand(3.0D, 3.0D, 3.0D); List list = this.getEntitiesWithinAABB(EntityLiving.class, axisalignedbb, new Predicate() { public boolean test(EntityLiving p_apply_1_) { @@ -2369,7 +2369,7 @@ public final class WorldServer extends AWorldServer { if(!this.canBurnAt(pos)) { return false; } - if(pos.getY() >= 0 && pos.getY() < 512) { + if(pos.getY() >= -World.MAX_SIZE_Y && pos.getY() < World.MAX_SIZE_Y) { Block block = this.getState(pos).getBlock(); if(block.getMaterial() == Material.air && Blocks.fire.canPlaceBlockAt(this, pos)) { @@ -2385,7 +2385,7 @@ public final class WorldServer extends AWorldServer { return false; } else { - if(pos.getY() >= 0 && pos.getY() < 512 && this.getLightFor(LightType.BLOCK, pos) < 10) { + if(pos.getY() >= -World.MAX_SIZE_Y && pos.getY() < World.MAX_SIZE_Y && this.getLightFor(LightType.BLOCK, pos) < 10) { State iblockstate = this.getState(pos); Block block = iblockstate.getBlock(); @@ -2437,8 +2437,9 @@ public final class WorldServer extends AWorldServer { Chunk chunk = this.getChunk(pos); BlockPos blockpos; BlockPos blockpos1; + int bottom; - for(blockpos = new BlockPos(pos.getX(), chunk.getTopSegment() + 16, pos.getZ()); blockpos.getY() >= 0; blockpos = blockpos1) { + for(blockpos = new BlockPos(pos.getX(), chunk.getTopSegment() + 16, pos.getZ()), bottom = chunk.getBottomSegment(); blockpos.getY() >= bottom; blockpos = blockpos1) { blockpos1 = blockpos.down(); Material material = chunk.getBlock(blockpos1).getMaterial(); @@ -2802,8 +2803,10 @@ public final class WorldServer extends AWorldServer { private class PlayerInstance { private final List watching = Lists.newArrayList(); + private final Set extend = Sets.newHashSet(); + private final long[] changes = new long[64]; private final ChunkPos position; - private int[] changes = new int[64]; + private int updates; private int sections; private long prevTime; @@ -2834,7 +2837,7 @@ public final class WorldServer extends AWorldServer { Chunk chunk = WorldServer.this.getChunk(this.position.x, this.position.z); if(chunk.isPopulated()) { - player.connection.sendPacket(new SPacketChunkData(chunk, true, 0)); + player.connection.sendPacket(new SPacketChunkData(chunk, true, 0, new int[0])); } this.watching.remove(player); @@ -2877,10 +2880,13 @@ public final class WorldServer extends AWorldServer { WorldServer.this.toUpdate.add(this); } - this.sections |= 1 << (y >> 4); + if(y >= 0 && y >> 4 < 32) + this.sections |= 1 << (y >> 4); + else + this.extend.add(y >> 4); if(this.updates < 64) { - int pos = x << 13 | z << 9 | y; + long pos = ((long)x & 4294967295L) << 36 | ((long)z & 4294967295L) << 32 | (y & 4294967295L); for(int i = 0; i < this.updates; ++i) { if(this.changes[i] == pos) { @@ -2905,9 +2911,9 @@ public final class WorldServer extends AWorldServer { public void onUpdate() { if(this.updates != 0) { if(this.updates == 1) { - int x = (this.changes[0] >> 13 & 15) + this.position.x * 16; - int y = this.changes[0] & 511; - int z = (this.changes[0] >> 9 & 15) + this.position.z * 16; + int x = (int)(this.changes[0] >> 36 & 15L) + this.position.x * 16; + int y = (int)(this.changes[0] & 4294967295L); + int z = (int)(this.changes[0] >> 32 & 15L) + this.position.z * 16; BlockPos pos = new BlockPos(x, y, z); this.sendToAllPlayersWatchingChunk(new SPacketBlockChange(WorldServer.this, pos)); @@ -2918,11 +2924,36 @@ public final class WorldServer extends AWorldServer { else if(this.updates == 64) { int x = this.position.x * 16; int z = this.position.z * 16; + int[] extend = null; + if(!this.biomes) { + extend = new int[this.extend.size()]; + int n = 0; + for(Integer i : this.extend) { + extend[n++] = i; + } + } this.sendToAllPlayersWatchingChunk(new SPacketChunkData(WorldServer.this.getChunk(this.position.x, this.position.z), - this.biomes, this.sections)); + this.biomes, this.sections, extend)); + + if(this.biomes) { + List list = WorldServer.this.getTileEntitiesIn(x, Integer.MIN_VALUE, z, x + 16, Integer.MAX_VALUE, z + 16); - for(int cy = 0; cy < 32; ++cy) { - if((this.sections & 1 << cy) != 0) { + for(int n = 0; n < list.size(); ++n) { + this.sendTileToAllPlayersWatchingChunk(list.get(n)); + } + } + else { + for(int cy = 0; cy < 32; ++cy) { + if((this.sections & 1 << cy) != 0) { + int y = cy << 4; + List list = WorldServer.this.getTileEntitiesIn(x, y, z, x + 16, y + 16, z + 16); + + for(int n = 0; n < list.size(); ++n) { + this.sendTileToAllPlayersWatchingChunk(list.get(n)); + } + } + } + for(Integer cy : this.extend) { int y = cy << 4; List list = WorldServer.this.getTileEntitiesIn(x, y, z, x + 16, y + 16, z + 16); @@ -2937,9 +2968,9 @@ public final class WorldServer extends AWorldServer { WorldServer.this.getChunk(this.position.x, this.position.z))); for(int n = 0; n < this.updates; ++n) { - int x = (this.changes[n] >> 13 & 15) + this.position.x * 16; - int y = this.changes[n] & 511; - int z = (this.changes[n] >> 9 & 15) + this.position.z * 16; + int x = (int)(this.changes[n] >> 36 & 15L) + this.position.x * 16; + int y = (int)(this.changes[n] & 4294967295L); + int z = (int)(this.changes[n] >> 32 & 15L) + this.position.z * 16; BlockPos pos = new BlockPos(x, y, z); if(WorldServer.this.getState(pos).getBlock().hasTileEntity()) { @@ -2950,6 +2981,7 @@ public final class WorldServer extends AWorldServer { this.updates = 0; this.sections = 0; + this.extend.clear(); this.biomes = false; } } From 4d1d323c722c5afee5979b7bebeabde8e31b2b58 Mon Sep 17 00:00:00 2001 From: Sen Date: Tue, 20 May 2025 19:09:19 +0200 Subject: [PATCH 048/200] Revert "make world taller" This reverts commit caef42dc161d26f4a6b5ea02b5a1a2da3d40fc81. --- client/src/client/network/ClientPlayer.java | 10 +- .../client/renderer/RegionRenderCache.java | 6 +- client/src/client/renderer/RenderGlobal.java | 5 +- client/src/client/world/EmptyChunk.java | 4 +- client/src/client/world/WorldClient.java | 7 +- common/src/common/block/BlockBanner.java | 2 +- common/src/common/block/BlockBeacon.java | 2 +- common/src/common/block/BlockBlueShroom.java | 2 +- .../src/common/block/BlockBrewingStand.java | 2 +- common/src/common/block/BlockChest.java | 2 +- .../common/block/BlockDaylightDetector.java | 2 +- common/src/common/block/BlockDispenser.java | 2 +- common/src/common/block/BlockDoor.java | 2 +- common/src/common/block/BlockDropper.java | 2 +- .../common/block/BlockEnchantmentTable.java | 2 +- common/src/common/block/BlockFurnace.java | 2 +- common/src/common/block/BlockHopper.java | 2 +- common/src/common/block/BlockLilyPad.java | 2 +- common/src/common/block/BlockMachine.java | 2 +- common/src/common/block/BlockMobSpawner.java | 2 +- common/src/common/block/BlockMushroom.java | 2 +- common/src/common/block/BlockNote.java | 2 +- common/src/common/block/BlockPistonBase.java | 4 +- .../src/common/block/BlockPistonMoving.java | 2 +- .../common/block/BlockRedstoneComparator.java | 4 +- common/src/common/block/BlockSign.java | 2 +- common/src/common/block/BlockSkull.java | 2 +- common/src/common/block/BlockTianReactor.java | 2 +- common/src/common/block/BlockVine.java | 2 +- .../src/common/block/ITileEntityProvider.java | 5 +- common/src/common/dimension/Dimension.java | 4 +- .../src/common/entity/item/EntityFalling.java | 2 +- common/src/common/entity/npc/EntityNPC.java | 2 +- common/src/common/item/ItemBucket.java | 4 +- common/src/common/network/PacketBuffer.java | 10 +- .../src/common/packet/SPacketChunkData.java | 55 +-- .../common/packet/SPacketMapChunkBulk.java | 17 +- .../packet/SPacketMultiBlockChange.java | 18 +- common/src/common/pathfinding/PathCache.java | 2 +- .../common/tileentity/TileEntityBeacon.java | 2 +- common/src/common/util/BlockPos.java | 21 ++ common/src/common/world/Chunk.java | 330 ++++++------------ common/src/common/world/World.java | 28 +- .../src/server/clipboard/ClipboardPlacer.java | 2 + server/src/server/command/Command.java | 2 +- server/src/server/network/Player.java | 10 +- server/src/server/world/Region.java | 107 +++--- server/src/server/world/Spawner.java | 11 +- server/src/server/world/WorldServer.java | 66 +--- 49 files changed, 292 insertions(+), 490 deletions(-) diff --git a/client/src/client/network/ClientPlayer.java b/client/src/client/network/ClientPlayer.java index ebea694..1500a4e 100755 --- a/client/src/client/network/ClientPlayer.java +++ b/client/src/client/network/ClientPlayer.java @@ -767,8 +767,8 @@ public class ClientPlayer extends NetHandler implements IClientPlayer // this.clientWorldController.invalidateBlockReceiveRegion(packetIn.getChunkX() << 4, 0, packetIn.getChunkZ() << 4, (packetIn.getChunkX() << 4) + 15, 512, (packetIn.getChunkZ() << 4) + 15); Chunk chunk = this.clientWorldController.getChunk(packetIn.getChunkX(), packetIn.getChunkZ()); - chunk.setData(packetIn.getExtractedDataBytes(), packetIn.getExtractedSize(), packetIn.getExtractedExtend(), packetIn.hasBiomes()); - this.clientWorldController.markBlockRangeForRenderUpdate(packetIn.getChunkX() << 4, -World.MAX_SIZE_Y, packetIn.getChunkZ() << 4, (packetIn.getChunkX() << 4) + 15, World.MAX_SIZE_Y, (packetIn.getChunkZ() << 4) + 15); + chunk.setData(packetIn.getExtractedDataBytes(), packetIn.getExtractedSize(), packetIn.hasBiomes()); + this.clientWorldController.markBlockRangeForRenderUpdate(packetIn.getChunkX() << 4, 0, packetIn.getChunkZ() << 4, (packetIn.getChunkX() << 4) + 15, 512, (packetIn.getChunkZ() << 4) + 15); if (!packetIn.hasBiomes() || this.clientWorldController.dimension.hasNoLight()) // TODO: check { @@ -781,7 +781,7 @@ public class ClientPlayer extends NetHandler implements IClientPlayer NetHandler.checkThread(packetIn, this, this.gameController, this.clientWorldController); Chunk chunk = this.clientWorldController.getChunk(packetIn.getChunkX(), packetIn.getChunkZ()); chunk.setBiomes(packetIn.getBiomes()); - this.clientWorldController.markBlockRangeForRenderUpdate(packetIn.getChunkX() << 4, -World.MAX_SIZE_Y, packetIn.getChunkZ() << 4, (packetIn.getChunkX() << 4) + 15, World.MAX_SIZE_Y, (packetIn.getChunkZ() << 4) + 15); + this.clientWorldController.markBlockRangeForRenderUpdate(packetIn.getChunkX() << 4, 0, packetIn.getChunkZ() << 4, (packetIn.getChunkX() << 4) + 15, 512, (packetIn.getChunkZ() << 4) + 15); } /** @@ -1413,8 +1413,8 @@ public class ClientPlayer extends NetHandler implements IClientPlayer this.clientWorldController.doPreChunk(j, k, true); // this.clientWorldController.invalidateBlockReceiveRegion(j << 4, 0, k << 4, (j << 4) + 15, 512, (k << 4) + 15); Chunk chunk = this.clientWorldController.getChunk(j, k); - chunk.setData(packetIn.getChunkBytes(i), packetIn.getChunkSize(i), packetIn.getChunkExtend(i), true); - this.clientWorldController.markBlockRangeForRenderUpdate(j << 4, -World.MAX_SIZE_Y, k << 4, (j << 4) + 15, World.MAX_SIZE_Y, (k << 4) + 15); + chunk.setData(packetIn.getChunkBytes(i), packetIn.getChunkSize(i), true); + this.clientWorldController.markBlockRangeForRenderUpdate(j << 4, 0, k << 4, (j << 4) + 15, 512, (k << 4) + 15); if (this.clientWorldController.dimension.hasNoLight()) // TODO: check { diff --git a/client/src/client/renderer/RegionRenderCache.java b/client/src/client/renderer/RegionRenderCache.java index e0ec2fc..635a77a 100755 --- a/client/src/client/renderer/RegionRenderCache.java +++ b/client/src/client/renderer/RegionRenderCache.java @@ -87,7 +87,7 @@ public class RegionRenderCache extends ChunkCache implements IWorldAccess private State getBlockStateRaw(BlockPos pos) { - if (pos.getY() >= -World.MAX_SIZE_Y && pos.getY() < World.MAX_SIZE_Y) + if (pos.getY() >= 0 && pos.getY() < 512) { int i = (pos.getX() >> 4) - this.chunkX; int j = (pos.getZ() >> 4) - this.chunkZ; @@ -136,7 +136,7 @@ public class RegionRenderCache extends ChunkCache implements IWorldAccess { return 0; } - else if (pos.getY() >= -World.MAX_SIZE_Y && pos.getY() < World.MAX_SIZE_Y) + else if (pos.getY() >= 0 && pos.getY() < 512) { if (this.getState(pos).getBlock().getSumBrightness()) { @@ -183,7 +183,7 @@ public class RegionRenderCache extends ChunkCache implements IWorldAccess public int getLightFor(LightType p_175628_1_, BlockPos pos) { - if (pos.getY() >= -World.MAX_SIZE_Y && pos.getY() < World.MAX_SIZE_Y) + if (pos.getY() >= 0 && pos.getY() < 512) { int i = (pos.getX() >> 4) - this.chunkX; int j = (pos.getZ() >> 4) - this.chunkZ; diff --git a/client/src/client/renderer/RenderGlobal.java b/client/src/client/renderer/RenderGlobal.java index 0af5835..f1ad4b3 100755 --- a/client/src/client/renderer/RenderGlobal.java +++ b/client/src/client/renderer/RenderGlobal.java @@ -53,7 +53,6 @@ import common.util.Vec3; import common.util.Vector3f; import common.world.Chunk; import common.world.State; -import common.world.World; public class RenderGlobal { @@ -633,7 +632,7 @@ public class RenderGlobal // boolean flag3 = this.gm.getRenderViewEntity() instanceof EntityLivingBase ? ((EntityLivingBase)this.gm.getRenderViewEntity()).isPlayerSleeping() : false; - if (entity2.posY < (double)(-World.MAX_SIZE_Y) || entity2.posY >= (double)World.MAX_SIZE_Y || this.theWorld.isBlockLoaded(new BlockPos(entity2))) + if (entity2.posY < 0.0D || entity2.posY >= 512.0D || this.theWorld.isBlockLoaded(new BlockPos(entity2))) { if((entity2 != this.gm.getRenderViewEntity() || this.gm.thirdPersonView != 0 /* || flag3 */)) { ++this.countEntitiesRendered; @@ -932,7 +931,7 @@ public class RenderGlobal private RenderChunk getRenderChunkOffset(BlockPos playerPos, RenderChunk renderChunkBase, Facing facing) { BlockPos blockpos = renderChunkBase.getBlockPosOffset16(facing); - return ExtMath.absi(playerPos.getX() - blockpos.getX()) > this.renderDistanceChunks * 16 ? null : (blockpos.getY() >= -World.MAX_SIZE_Y && blockpos.getY() < World.MAX_SIZE_Y ? (ExtMath.absi(playerPos.getZ() - blockpos.getZ()) > this.renderDistanceChunks * 16 ? null : this.viewFrustum.getRenderChunk(blockpos)) : null); + return ExtMath.absi(playerPos.getX() - blockpos.getX()) > this.renderDistanceChunks * 16 ? null : (blockpos.getY() >= 0 && blockpos.getY() < 512 ? (ExtMath.absi(playerPos.getZ() - blockpos.getZ()) > this.renderDistanceChunks * 16 ? null : this.viewFrustum.getRenderChunk(blockpos)) : null); } protected Vector3f getViewVector(Entity entityIn, double partialTicks) diff --git a/client/src/client/world/EmptyChunk.java b/client/src/client/world/EmptyChunk.java index c60a7ee..12867ba 100755 --- a/client/src/client/world/EmptyChunk.java +++ b/client/src/client/world/EmptyChunk.java @@ -19,12 +19,14 @@ public class EmptyChunk extends Chunk { private final int liquidY; private final State liquid; private final Block liquidBlock; + private final int liquidMeta; public EmptyChunk(WorldClient world) { super(world, 0, 0); this.liquidY = world.dimension.getSeaLevel() - 1; this.liquid = world.dimension.getLiquid(); this.liquidBlock = this.liquid.getBlock(); + this.liquidMeta = this.liquidBlock.getMetaFromState(this.liquid); } public int getHeight(int x, int z) { @@ -105,7 +107,7 @@ public class EmptyChunk extends Chunk { return true; } - public void setData(byte[] data, int update, int[] extend, boolean biomes) { + public void setData(byte[] data, int update, boolean biomes) { } public Biome getBiome(BlockPos pos, BiomeGenerator gen) { diff --git a/client/src/client/world/WorldClient.java b/client/src/client/world/WorldClient.java index 32fa891..28d3f18 100755 --- a/client/src/client/world/WorldClient.java +++ b/client/src/client/world/WorldClient.java @@ -36,7 +36,6 @@ import common.util.BlockPos.MutableBlockPos; import common.world.Chunk; import common.world.AWorldClient; import common.world.State; -import common.world.World; public class WorldClient extends AWorldClient { @@ -81,14 +80,14 @@ public class WorldClient extends AWorldClient this.chunkMapping.add(id, this.emptyChunk); this.emptyChunkListing.remove(id); this.nextEmptyChunkListing.add(id); - this.markBlockRangeForRenderUpdate(x << 4, -World.MAX_SIZE_Y, z << 4, (x << 4) + 15, World.MAX_SIZE_Y, (z << 4) + 15); + this.markBlockRangeForRenderUpdate(x << 4, 0, z << 4, (x << 4) + 15, 512, (z << 4) + 15); } } for(Long id : this.emptyChunkListing) { this.chunkMapping.remove(id); int x = LongHashMap.getX(id); int z = LongHashMap.getZ(id); - this.markBlockRangeForRenderUpdate(x << 4, -World.MAX_SIZE_Y, z << 4, (x << 4) + 15, World.MAX_SIZE_Y, (z << 4) + 15); + this.markBlockRangeForRenderUpdate(x << 4, 0, z << 4, (x << 4) + 15, 512, (z << 4) + 15); } this.emptyChunkListing.clear(); this.emptyChunkListing.addAll(this.nextEmptyChunkListing); @@ -185,7 +184,7 @@ public class WorldClient extends AWorldClient if (!load) { - this.markBlockRangeForRenderUpdate(x * 16, -World.MAX_SIZE_Y, z * 16, x * 16 + 15, World.MAX_SIZE_Y, z * 16 + 15); + this.markBlockRangeForRenderUpdate(x * 16, 0, z * 16, x * 16 + 15, 512, z * 16 + 15); } } diff --git a/common/src/common/block/BlockBanner.java b/common/src/common/block/BlockBanner.java index 0d455c7..b025774 100755 --- a/common/src/common/block/BlockBanner.java +++ b/common/src/common/block/BlockBanner.java @@ -87,7 +87,7 @@ public class BlockBanner extends BlockContainer /** * Returns a new instance of a block's tile entity class. Called on placing the block. */ - public TileEntity createNewTileEntity(World worldIn) + public TileEntity createNewTileEntity(World worldIn, int meta) { return new TileEntityBanner(); } diff --git a/common/src/common/block/BlockBeacon.java b/common/src/common/block/BlockBeacon.java index 7789be3..2032c67 100755 --- a/common/src/common/block/BlockBeacon.java +++ b/common/src/common/block/BlockBeacon.java @@ -49,7 +49,7 @@ public class BlockBeacon extends BlockContainer /** * Returns a new instance of a block's tile entity class. Called on placing the block. */ - public TileEntity createNewTileEntity(World worldIn) + public TileEntity createNewTileEntity(World worldIn, int meta) { return new TileEntityBeacon(); } diff --git a/common/src/common/block/BlockBlueShroom.java b/common/src/common/block/BlockBlueShroom.java index c6cc81b..648fadf 100755 --- a/common/src/common/block/BlockBlueShroom.java +++ b/common/src/common/block/BlockBlueShroom.java @@ -70,7 +70,7 @@ public class BlockBlueShroom extends BlockBush public boolean canBlockStay(World worldIn, BlockPos pos, State state) { - if (pos.getY() >= -World.MAX_SIZE_Y && pos.getY() < World.MAX_SIZE_Y) + if (pos.getY() >= 0 && pos.getY() < 512) { State iblockstate = worldIn.getState(pos.down()); return (iblockstate.getBlock() == Blocks.tian_soil || iblockstate.getBlock() == Blocks.obsidian) ? true : (worldIn.getLight(pos) < 13 && this.canPlaceBlockOn(iblockstate.getBlock())); diff --git a/common/src/common/block/BlockBrewingStand.java b/common/src/common/block/BlockBrewingStand.java index db118c0..dcd6dc6 100755 --- a/common/src/common/block/BlockBrewingStand.java +++ b/common/src/common/block/BlockBrewingStand.java @@ -382,7 +382,7 @@ public class BlockBrewingStand extends BlockContainer /** * Returns a new instance of a block's tile entity class. Called on placing the block. */ - public TileEntity createNewTileEntity(World worldIn) + public TileEntity createNewTileEntity(World worldIn, int meta) { return new TileEntityBrewingStand(); } diff --git a/common/src/common/block/BlockChest.java b/common/src/common/block/BlockChest.java index 7366655..a195e29 100755 --- a/common/src/common/block/BlockChest.java +++ b/common/src/common/block/BlockChest.java @@ -530,7 +530,7 @@ public class BlockChest extends BlockContainer /** * Returns a new instance of a block's tile entity class. Called on placing the block. */ - public TileEntity createNewTileEntity(World worldIn) + public TileEntity createNewTileEntity(World worldIn, int meta) { return new TileEntityChest(); } diff --git a/common/src/common/block/BlockDaylightDetector.java b/common/src/common/block/BlockDaylightDetector.java index 420a0e1..f213c1f 100755 --- a/common/src/common/block/BlockDaylightDetector.java +++ b/common/src/common/block/BlockDaylightDetector.java @@ -152,7 +152,7 @@ public class BlockDaylightDetector extends BlockContainer /** * Returns a new instance of a block's tile entity class. Called on placing the block. */ - public TileEntity createNewTileEntity(World worldIn) + public TileEntity createNewTileEntity(World worldIn, int meta) { return new TileEntityDaylightDetector(); } diff --git a/common/src/common/block/BlockDispenser.java b/common/src/common/block/BlockDispenser.java index 7132bad..1a80d27 100755 --- a/common/src/common/block/BlockDispenser.java +++ b/common/src/common/block/BlockDispenser.java @@ -183,7 +183,7 @@ public class BlockDispenser extends BlockContainer /** * Returns a new instance of a block's tile entity class. Called on placing the block. */ - public TileEntity createNewTileEntity(World worldIn) + public TileEntity createNewTileEntity(World worldIn, int meta) { return new TileEntityDispenser(); } diff --git a/common/src/common/block/BlockDoor.java b/common/src/common/block/BlockDoor.java index b8e0e96..8388100 100755 --- a/common/src/common/block/BlockDoor.java +++ b/common/src/common/block/BlockDoor.java @@ -291,7 +291,7 @@ public class BlockDoor extends Block public boolean canPlaceBlockAt(World worldIn, BlockPos pos) { - return pos.getY() >= World.MAX_SIZE_Y - 1 ? false : worldIn.isBlockSolid(pos.down()) && super.canPlaceBlockAt(worldIn, pos) && super.canPlaceBlockAt(worldIn, pos.up()); + return pos.getY() >= 511 ? false : worldIn.isBlockSolid(pos.down()) && super.canPlaceBlockAt(worldIn, pos) && super.canPlaceBlockAt(worldIn, pos.up()); } public int getMobilityFlag() diff --git a/common/src/common/block/BlockDropper.java b/common/src/common/block/BlockDropper.java index 8294171..ec42106 100755 --- a/common/src/common/block/BlockDropper.java +++ b/common/src/common/block/BlockDropper.java @@ -24,7 +24,7 @@ public class BlockDropper extends BlockDispenser /** * Returns a new instance of a block's tile entity class. Called on placing the block. */ - public TileEntity createNewTileEntity(World worldIn) + public TileEntity createNewTileEntity(World worldIn, int meta) { return new TileEntityDropper(); } diff --git a/common/src/common/block/BlockEnchantmentTable.java b/common/src/common/block/BlockEnchantmentTable.java index b461b36..c27dbab 100755 --- a/common/src/common/block/BlockEnchantmentTable.java +++ b/common/src/common/block/BlockEnchantmentTable.java @@ -96,7 +96,7 @@ public class BlockEnchantmentTable extends BlockContainer /** * Returns a new instance of a block's tile entity class. Called on placing the block. */ - public TileEntity createNewTileEntity(World worldIn) + public TileEntity createNewTileEntity(World worldIn, int meta) { return new TileEntityEnchantmentTable(); } diff --git a/common/src/common/block/BlockFurnace.java b/common/src/common/block/BlockFurnace.java index 6e344f0..73731a1 100755 --- a/common/src/common/block/BlockFurnace.java +++ b/common/src/common/block/BlockFurnace.java @@ -167,7 +167,7 @@ public class BlockFurnace extends BlockContainer /** * Returns a new instance of a block's tile entity class. Called on placing the block. */ - public TileEntity createNewTileEntity(World worldIn) + public TileEntity createNewTileEntity(World worldIn, int meta) { return new TileEntityFurnace(); } diff --git a/common/src/common/block/BlockHopper.java b/common/src/common/block/BlockHopper.java index 8b26c54..88832e8 100755 --- a/common/src/common/block/BlockHopper.java +++ b/common/src/common/block/BlockHopper.java @@ -142,7 +142,7 @@ public class BlockHopper extends BlockContainer /** * Returns a new instance of a block's tile entity class. Called on placing the block. */ - public TileEntity createNewTileEntity(World worldIn) + public TileEntity createNewTileEntity(World worldIn, int meta) { return new TileEntityHopper(); } diff --git a/common/src/common/block/BlockLilyPad.java b/common/src/common/block/BlockLilyPad.java index 2886bef..25e614d 100755 --- a/common/src/common/block/BlockLilyPad.java +++ b/common/src/common/block/BlockLilyPad.java @@ -64,7 +64,7 @@ public class BlockLilyPad extends BlockBush public boolean canBlockStay(World worldIn, BlockPos pos, State state) { - if (pos.getY() >= -World.MAX_SIZE_Y && pos.getY() < World.MAX_SIZE_Y) + if (pos.getY() >= 0 && pos.getY() < 512) { State iblockstate = worldIn.getState(pos.down()); return (iblockstate.getBlock().getMaterial().isColdLiquid() && ((Integer)iblockstate.getValue(BlockLiquid.LEVEL)).intValue() == 0) diff --git a/common/src/common/block/BlockMachine.java b/common/src/common/block/BlockMachine.java index 39ac59c..782ab21 100755 --- a/common/src/common/block/BlockMachine.java +++ b/common/src/common/block/BlockMachine.java @@ -23,7 +23,7 @@ public abstract class BlockMachine extends BlockDirectional implements ITileEnti this.setTab(CheatTab.tabTech); } - public abstract TileEntity createNewTileEntity(World worldIn); + public abstract TileEntity createNewTileEntity(World worldIn, int meta); public void onBlockAdded(AWorldServer worldIn, BlockPos pos, State state) { this.updateState(worldIn, pos, state); diff --git a/common/src/common/block/BlockMobSpawner.java b/common/src/common/block/BlockMobSpawner.java index 18f87d3..e8d4f46 100755 --- a/common/src/common/block/BlockMobSpawner.java +++ b/common/src/common/block/BlockMobSpawner.java @@ -22,7 +22,7 @@ public class BlockMobSpawner extends BlockContainer /** * Returns a new instance of a block's tile entity class. Called on placing the block. */ - public TileEntity createNewTileEntity(World worldIn) + public TileEntity createNewTileEntity(World worldIn, int meta) { return new TileEntityMobSpawner(); } diff --git a/common/src/common/block/BlockMushroom.java b/common/src/common/block/BlockMushroom.java index 2753e63..aedd4e5 100755 --- a/common/src/common/block/BlockMushroom.java +++ b/common/src/common/block/BlockMushroom.java @@ -74,7 +74,7 @@ public class BlockMushroom extends BlockBush implements IGrowable public boolean canBlockStay(World worldIn, BlockPos pos, State state) { - if (pos.getY() >= -World.MAX_SIZE_Y && pos.getY() < World.MAX_SIZE_Y) + if (pos.getY() >= 0 && pos.getY() < 512) { State iblockstate = worldIn.getState(pos.down()); return iblockstate.getBlock() == Blocks.mycelium ? true : (iblockstate.getBlock() == Blocks.dirt && iblockstate.getValue(BlockDirt.VARIANT) == BlockDirt.DirtType.PODZOL ? true : worldIn.getLight(pos) < 13 && this.canPlaceBlockOn(iblockstate.getBlock())); diff --git a/common/src/common/block/BlockNote.java b/common/src/common/block/BlockNote.java index 3a1203f..d1711a0 100755 --- a/common/src/common/block/BlockNote.java +++ b/common/src/common/block/BlockNote.java @@ -85,7 +85,7 @@ public class BlockNote extends BlockContainer /** * Returns a new instance of a block's tile entity class. Called on placing the block. */ - public TileEntity createNewTileEntity(World worldIn) + public TileEntity createNewTileEntity(World worldIn, int meta) { return new TileEntityNote(); } diff --git a/common/src/common/block/BlockPistonBase.java b/common/src/common/block/BlockPistonBase.java index b4057bb..e09a0e3 100755 --- a/common/src/common/block/BlockPistonBase.java +++ b/common/src/common/block/BlockPistonBase.java @@ -548,9 +548,9 @@ public class BlockPistonBase extends Block { return false; } - else if (pos.getY() >= -World.MAX_SIZE_Y && (direction != Facing.DOWN || pos.getY() != -World.MAX_SIZE_Y)) + else if (pos.getY() >= 0 && (direction != Facing.DOWN || pos.getY() != 0)) { - if (pos.getY() <= World.MAX_SIZE_Y - 1 && (direction != Facing.UP || pos.getY() != World.MAX_SIZE_Y - 1)) + if (pos.getY() <= World.HEIGHT - 1 && (direction != Facing.UP || pos.getY() != World.HEIGHT - 1)) { if (blockIn != Blocks.piston && blockIn != Blocks.sticky_piston) { diff --git a/common/src/common/block/BlockPistonMoving.java b/common/src/common/block/BlockPistonMoving.java index 1076638..8047a3c 100755 --- a/common/src/common/block/BlockPistonMoving.java +++ b/common/src/common/block/BlockPistonMoving.java @@ -35,7 +35,7 @@ public class BlockPistonMoving extends BlockContainer /** * Returns a new instance of a block's tile entity class. Called on placing the block. */ - public TileEntity createNewTileEntity(World worldIn) + public TileEntity createNewTileEntity(World worldIn, int meta) { return null; } diff --git a/common/src/common/block/BlockRedstoneComparator.java b/common/src/common/block/BlockRedstoneComparator.java index 948db47..b44b3dc 100755 --- a/common/src/common/block/BlockRedstoneComparator.java +++ b/common/src/common/block/BlockRedstoneComparator.java @@ -242,7 +242,7 @@ public class BlockRedstoneComparator extends BlockRedstoneDiode implements ITile public void onBlockAdded(AWorldServer worldIn, BlockPos pos, State state) { super.onBlockAdded(worldIn, pos, state); - worldIn.setTileEntity(pos, this.createNewTileEntity(worldIn)); + worldIn.setTileEntity(pos, this.createNewTileEntity(worldIn, 0)); } public void onBlockRemoved(AWorldServer worldIn, BlockPos pos, State state) @@ -265,7 +265,7 @@ public class BlockRedstoneComparator extends BlockRedstoneDiode implements ITile /** * Returns a new instance of a block's tile entity class. Called on placing the block. */ - public TileEntity createNewTileEntity(World worldIn) + public TileEntity createNewTileEntity(World worldIn, int meta) { return new TileEntityComparator(); } diff --git a/common/src/common/block/BlockSign.java b/common/src/common/block/BlockSign.java index ccbb72d..aa1aedf 100755 --- a/common/src/common/block/BlockSign.java +++ b/common/src/common/block/BlockSign.java @@ -79,7 +79,7 @@ public class BlockSign extends BlockContainer /** * Returns a new instance of a block's tile entity class. Called on placing the block. */ - public TileEntity createNewTileEntity(World worldIn) + public TileEntity createNewTileEntity(World worldIn, int meta) { return new TileEntitySign(); } diff --git a/common/src/common/block/BlockSkull.java b/common/src/common/block/BlockSkull.java index 72ea6a0..97d44ec 100755 --- a/common/src/common/block/BlockSkull.java +++ b/common/src/common/block/BlockSkull.java @@ -77,7 +77,7 @@ public class BlockSkull extends BlockContainer return this.getState().withProperty(FACING, placer.getHorizontalFacing()); } - public TileEntity createNewTileEntity(World worldIn) + public TileEntity createNewTileEntity(World worldIn, int meta) { return new TileEntitySkull(); } diff --git a/common/src/common/block/BlockTianReactor.java b/common/src/common/block/BlockTianReactor.java index 6855aa8..a073032 100755 --- a/common/src/common/block/BlockTianReactor.java +++ b/common/src/common/block/BlockTianReactor.java @@ -11,7 +11,7 @@ import common.world.State; import common.world.World; public class BlockTianReactor extends BlockMachine { - public TileEntity createNewTileEntity(World worldIn) { + public TileEntity createNewTileEntity(World worldIn, int meta) { return new TileEntityTianReactor(); } diff --git a/common/src/common/block/BlockVine.java b/common/src/common/block/BlockVine.java index a674c81..ed6f33b 100755 --- a/common/src/common/block/BlockVine.java +++ b/common/src/common/block/BlockVine.java @@ -280,7 +280,7 @@ public class BlockVine extends Block Facing enumfacing1 = Facing.random(rand); BlockPos blockpos1 = pos.up(); - if (enumfacing1 == Facing.UP && pos.getY() < World.MAX_SIZE_Y - 1 && worldIn.isAirBlock(blockpos1)) + if (enumfacing1 == Facing.UP && pos.getY() < 511 && worldIn.isAirBlock(blockpos1)) { if (!flag) { diff --git a/common/src/common/block/ITileEntityProvider.java b/common/src/common/block/ITileEntityProvider.java index e23572a..f4628a7 100755 --- a/common/src/common/block/ITileEntityProvider.java +++ b/common/src/common/block/ITileEntityProvider.java @@ -5,5 +5,8 @@ import common.world.World; public interface ITileEntityProvider { - TileEntity createNewTileEntity(World worldIn); + /** + * Returns a new instance of a block's tile entity class. Called on placing the block. + */ + TileEntity createNewTileEntity(World worldIn, int meta); } diff --git a/common/src/common/dimension/Dimension.java b/common/src/common/dimension/Dimension.java index e5c4b5b..39b7bb3 100755 --- a/common/src/common/dimension/Dimension.java +++ b/common/src/common/dimension/Dimension.java @@ -975,7 +975,6 @@ public abstract class Dimension extends Nameable implements Comparable= UniverseRegistry.MORE_DIM_ID) { this.seaLevel = tag.getInteger("SeaLevel"); - this.filler = BlockRegistry.getFromIdName(tag.getString("FillerBlock"), Blocks.stone.getState()); this.liquid = BlockRegistry.getFromIdName(tag.getString("LiquidBlock"), Blocks.water.getState()); } } @@ -1022,6 +1021,7 @@ public abstract class Dimension extends Nameable implements Comparable= UniverseRegistry.MORE_DIM_ID) { tag.setInteger("SeaLevel", this.seaLevel); - tag.setString("FillerBlock", BlockRegistry.toIdName(this.filler)); tag.setString("LiquidBlock", BlockRegistry.toIdName(this.liquid)); } } @@ -1262,6 +1261,7 @@ public abstract class Dimension extends Nameable implements Comparable 100 && !this.worldObj.client && (blockpos1.getY() < -World.MAX_SIZE_Y + 1 || blockpos1.getY() > World.MAX_SIZE_Y) || this.fallTime > 600) + else if (this.fallTime > 100 && !this.worldObj.client && (blockpos1.getY() < 1 || blockpos1.getY() > 512) || this.fallTime > 600) { if (this.shouldDropItem && Config.objectDrop) { diff --git a/common/src/common/entity/npc/EntityNPC.java b/common/src/common/entity/npc/EntityNPC.java index a7c9cca..9bd5118 100755 --- a/common/src/common/entity/npc/EntityNPC.java +++ b/common/src/common/entity/npc/EntityNPC.java @@ -2684,7 +2684,7 @@ public abstract class EntityNPC extends EntityLiving } else { - this.client.addToSendQueue(new CPacketPlayer.C06PacketPlayerPosLook(this.motionX, -99999999.0D, this.motionZ, this.rotYaw, this.rotPitch, this.onGround)); + this.client.addToSendQueue(new CPacketPlayer.C06PacketPlayerPosLook(this.motionX, -999.0D, this.motionZ, this.rotYaw, this.rotPitch, this.onGround)); flag2 = false; } diff --git a/common/src/common/item/ItemBucket.java b/common/src/common/item/ItemBucket.java index 242d233..94cb7c2 100755 --- a/common/src/common/item/ItemBucket.java +++ b/common/src/common/item/ItemBucket.java @@ -36,7 +36,7 @@ public class ItemBucket extends Item private final BlockDynamicLiquid liquid; private static boolean test(AWorldServer world, BlockPos pos, Set blocks, int max, BlockPos origin, int radius) { - if(pos.getY() < -World.MAX_SIZE_Y || pos.getY() > max) + if(pos.getY() < 0 || pos.getY() > max) return false; if(pos.getX() < origin.getX() - radius || pos.getX() > origin.getX() + radius) return false; @@ -54,7 +54,7 @@ public class ItemBucket extends Item List dirs = new ArrayList(); Set blocks = liquid == null ? null : Sets.newHashSet(FluidRegistry.getDynamicBlock(liquid), liquid, Blocks.air); State state = (liquid == null ? Blocks.air : liquid).getState(); - int max = World.MAX_SIZE_Y - 1; + int max = 511; if(liquid != null) { dirs.add(new Vec3i(1, 0, 0)); diff --git a/common/src/common/network/PacketBuffer.java b/common/src/common/network/PacketBuffer.java index 390c141..4d0df41 100755 --- a/common/src/common/network/PacketBuffer.java +++ b/common/src/common/network/PacketBuffer.java @@ -58,14 +58,16 @@ public class PacketBuffer public BlockPos readBlockPos() { - return new BlockPos(this.readInt(), this.readInt(), this.readInt()); +// return new BlockPos(this.readInt(), this.readInt(), this.readInt()); + return BlockPos.fromLong(this.readLong()); } public void writeBlockPos(BlockPos pos) { - this.writeInt(pos.getX()); - this.writeInt(pos.getY()); - this.writeInt(pos.getZ()); + this.writeLong(pos.toLong()); +// this.writeInt(pos.getX()); +// this.writeInt(pos.getY()); +// this.writeInt(pos.getZ()); } // public Text readChatComponent() throws IOException diff --git a/common/src/common/packet/SPacketChunkData.java b/common/src/common/packet/SPacketChunkData.java index 182f6b5..1996522 100755 --- a/common/src/common/packet/SPacketChunkData.java +++ b/common/src/common/packet/SPacketChunkData.java @@ -21,12 +21,12 @@ public class SPacketChunkData implements Packet { } - public SPacketChunkData(Chunk chunkIn, boolean biomes, int segUpdate, int[] extend) + public SPacketChunkData(Chunk chunkIn, boolean biomes, int segUpdate) { this.chunkX = chunkIn.xPos; this.chunkZ = chunkIn.zPos; this.biomes = biomes; - this.extractedData = getExtractedData(chunkIn, biomes, !chunkIn.getWorld().dimension.hasNoLight(), segUpdate, extend); + this.extractedData = getExtractedData(chunkIn, biomes, !chunkIn.getWorld().dimension.hasNoLight(), segUpdate); } /** @@ -40,10 +40,6 @@ public class SPacketChunkData implements Packet this.extractedData = new SPacketChunkData.Extracted(); this.extractedData.dataSize = buf.readInt(); this.extractedData.data = buf.readByteArray(); - this.extractedData.extend = new int[buf.readVarIntFromBuffer()]; - for(int z = 0; z < this.extractedData.extend.length; z++) { - this.extractedData.extend[z] = buf.readVarIntFromBuffer(); - } } /** @@ -56,10 +52,6 @@ public class SPacketChunkData implements Packet buf.writeBoolean(this.biomes); buf.writeInt(this.extractedData.dataSize); buf.writeByteArray(this.extractedData.data); - buf.writeVarIntToBuffer(this.extractedData.extend.length); - for(int z = 0; z < this.extractedData.extend.length; z++) { - buf.writeVarIntToBuffer(this.extractedData.extend[z]); - } } /** @@ -84,11 +76,9 @@ public class SPacketChunkData implements Packet return i + j + k + l; } - public static SPacketChunkData.Extracted getExtractedData(Chunk chunk, boolean biomes, boolean overworld, int segUpdate, int[] extend) + public static SPacketChunkData.Extracted getExtractedData(Chunk chunk, boolean biomes, boolean overworld, int segUpdate) { BlockArray[] aextendedblockstorage = chunk.getStorage(); - BlockArray[] down = chunk.getStorageDown(); - BlockArray[] up = chunk.getStorageUp(); SPacketChunkData.Extracted s21packetchunkdata$extracted = new SPacketChunkData.Extracted(); List list = Lists.newArrayList(); @@ -102,37 +92,8 @@ public class SPacketChunkData implements Packet list.add(extendedblockstorage); } } - int epos = list.size(); - if(extend == null) { - if(down != null) { - for(BlockArray arr : down) { - if(arr != null && (!biomes || !arr.isEmpty())) - list.add(arr); - } - } - if(up != null) { - for(BlockArray arr : up) { - if(arr != null && (!biomes || !arr.isEmpty())) - list.add(arr); - } - } - } - else { - for(int cy : extend) { - if(cy < 0 || cy >= aextendedblockstorage.length) { - BlockArray arr = chunk.getArray(cy); - if(arr != null && (!biomes || !arr.isEmpty())) - list.add(arr); - } - } - } - extend = new int[list.size() - epos]; - for(int z = 0; z < extend.length; z++) { - extend[z] = list.get(z + epos).getY(); - } - - s21packetchunkdata$extracted.extend = extend; - s21packetchunkdata$extracted.data = new byte[getSize(Integer.bitCount(s21packetchunkdata$extracted.dataSize) + extend.length, overworld, biomes)]; + + s21packetchunkdata$extracted.data = new byte[getSize(Integer.bitCount(s21packetchunkdata$extracted.dataSize), overworld, biomes)]; int j = 0; for (BlockArray extendedblockstorage1 : list) @@ -188,11 +149,6 @@ public class SPacketChunkData implements Packet return this.extractedData.dataSize; } - public int[] getExtractedExtend() - { - return this.extractedData.extend; - } - public boolean hasBiomes() { return this.biomes; @@ -202,6 +158,5 @@ public class SPacketChunkData implements Packet { public byte[] data; public int dataSize; - public int[] extend; } } diff --git a/common/src/common/packet/SPacketMapChunkBulk.java b/common/src/common/packet/SPacketMapChunkBulk.java index f83bc61..aebfac5 100755 --- a/common/src/common/packet/SPacketMapChunkBulk.java +++ b/common/src/common/packet/SPacketMapChunkBulk.java @@ -30,7 +30,7 @@ public class SPacketMapChunkBulk implements Packet for (int j = 0; j < i; ++j) { Chunk chunk = (Chunk)chunks.get(j); - SPacketChunkData.Extracted s21packetchunkdata$extracted = SPacketChunkData.getExtractedData(chunk, true, this.isOverworld, 0xffffffff, null); + SPacketChunkData.Extracted s21packetchunkdata$extracted = SPacketChunkData.getExtractedData(chunk, true, this.isOverworld, 0xffffffff); this.xPositions[j] = chunk.xPos; this.zPositions[j] = chunk.zPos; this.chunksData[j] = s21packetchunkdata$extracted; @@ -54,11 +54,7 @@ public class SPacketMapChunkBulk implements Packet this.zPositions[j] = buf.readInt(); this.chunksData[j] = new SPacketChunkData.Extracted(); this.chunksData[j].dataSize = buf.readInt(); - this.chunksData[j].extend = new int[buf.readVarIntFromBuffer()]; - for(int z = 0; z < this.chunksData[j].extend.length; z++) { - this.chunksData[j].extend[z] = buf.readVarIntFromBuffer(); - } - this.chunksData[j].data = new byte[SPacketChunkData.getSize(Integer.bitCount(this.chunksData[j].dataSize) + this.chunksData[j].extend.length, this.isOverworld, true)]; + this.chunksData[j].data = new byte[SPacketChunkData.getSize(Integer.bitCount(this.chunksData[j].dataSize), this.isOverworld, true)]; } for (int k = 0; k < i; ++k) @@ -80,10 +76,6 @@ public class SPacketMapChunkBulk implements Packet buf.writeInt(this.xPositions[i]); buf.writeInt(this.zPositions[i]); buf.writeInt(this.chunksData[i].dataSize); - buf.writeVarIntToBuffer(this.chunksData[i].extend.length); - for(int z = 0; z < this.chunksData[i].extend.length; z++) { - buf.writeVarIntToBuffer(this.chunksData[i].extend[z]); - } } for (int j = 0; j < this.xPositions.length; ++j) @@ -124,9 +116,4 @@ public class SPacketMapChunkBulk implements Packet { return this.chunksData[p_179754_1_].dataSize; } - - public int[] getChunkExtend(int index) - { - return this.chunksData[index].extend; - } } diff --git a/common/src/common/packet/SPacketMultiBlockChange.java b/common/src/common/packet/SPacketMultiBlockChange.java index f6b4a4b..97d5e60 100755 --- a/common/src/common/packet/SPacketMultiBlockChange.java +++ b/common/src/common/packet/SPacketMultiBlockChange.java @@ -20,7 +20,7 @@ public class SPacketMultiBlockChange implements Packet { } - public SPacketMultiBlockChange(int p_i45181_1_, long[] crammedPositionsIn, Chunk chunkIn) + public SPacketMultiBlockChange(int p_i45181_1_, int[] crammedPositionsIn, Chunk chunkIn) { this.chunkPosCoord = new ChunkPos(chunkIn.xPos, chunkIn.zPos); this.changedBlocks = new SPacketMultiBlockChange.BlockUpdateData[p_i45181_1_]; @@ -41,7 +41,7 @@ public class SPacketMultiBlockChange implements Packet for (int i = 0; i < this.changedBlocks.length; ++i) { - this.changedBlocks[i] = new SPacketMultiBlockChange.BlockUpdateData(buf.readLong(), (State)BlockRegistry.STATEMAP.getByValue(buf.readVarIntFromBuffer())); + this.changedBlocks[i] = new SPacketMultiBlockChange.BlockUpdateData(buf.readInt(), (State)BlockRegistry.STATEMAP.getByValue(buf.readVarIntFromBuffer())); } } @@ -56,7 +56,7 @@ public class SPacketMultiBlockChange implements Packet for (SPacketMultiBlockChange.BlockUpdateData s22packetmultiblockchange$blockupdatedata : this.changedBlocks) { - buf.writeLong(s22packetmultiblockchange$blockupdatedata.getRawPos()); + buf.writeInt(s22packetmultiblockchange$blockupdatedata.getRawPos()); buf.writeVarIntToBuffer(BlockRegistry.STATEMAP.get(s22packetmultiblockchange$blockupdatedata.getBlockState())); } } @@ -76,16 +76,16 @@ public class SPacketMultiBlockChange implements Packet public class BlockUpdateData { - private final long position; + private final int position; private final State blockState; - public BlockUpdateData(long raw, State state) + public BlockUpdateData(int raw, State state) { this.position = raw; this.blockState = state; } - public BlockUpdateData(long raw, Chunk chunkIn) + public BlockUpdateData(int raw, Chunk chunkIn) { this.position = raw; this.blockState = chunkIn.getState(this.getPos()); @@ -93,11 +93,11 @@ public class SPacketMultiBlockChange implements Packet public BlockPos getPos() { - ChunkPos pos = SPacketMultiBlockChange.this.chunkPosCoord; - return new BlockPos(new BlockPos((pos.x << 4) + (int)(this.position >> 36 & 15L), (int)(this.position & 4294967295L), (pos.z << 4) + (int)(this.position >> 32 & 15L))); + ChunkPos r = SPacketMultiBlockChange.this.chunkPosCoord; + return new BlockPos(new BlockPos((r.x << 4) + (this.position >> 13 & 15), this.position & 511, (r.z << 4) + (this.position >> 9 & 15))); } - public long getRawPos() + public int getRawPos() { return this.position; } diff --git a/common/src/common/pathfinding/PathCache.java b/common/src/common/pathfinding/PathCache.java index 255b82c..3af36a8 100755 --- a/common/src/common/pathfinding/PathCache.java +++ b/common/src/common/pathfinding/PathCache.java @@ -17,7 +17,7 @@ public class PathCache extends ChunkCache implements IBlockAccess public State getState(BlockPos pos) { - if (pos.getY() >= -World.MAX_SIZE_Y && pos.getY() < World.MAX_SIZE_Y) + if (pos.getY() >= 0 && pos.getY() < 512) { int i = (pos.getX() >> 4) - this.chunkX; int j = (pos.getZ() >> 4) - this.chunkZ; diff --git a/common/src/common/tileentity/TileEntityBeacon.java b/common/src/common/tileentity/TileEntityBeacon.java index 19b6433..e8dc19f 100755 --- a/common/src/common/tileentity/TileEntityBeacon.java +++ b/common/src/common/tileentity/TileEntityBeacon.java @@ -78,7 +78,7 @@ public class TileEntityBeacon extends TileEntity implements ITickable int j = this.pos.getX(); int k = this.pos.getY(); int l = this.pos.getZ(); - BoundingBox axisalignedbb = (new BoundingBox((double)j, (double)k, (double)l, (double)(j + 1), (double)(k + 1), (double)(l + 1))).expand(d0, d0, d0).addCoord(0.0D, (double)World.MAX_SIZE_Y, 0.0D); + BoundingBox axisalignedbb = (new BoundingBox((double)j, (double)k, (double)l, (double)(j + 1), (double)(k + 1), (double)(l + 1))).expand(d0, d0, d0).addCoord(0.0D, (double)World.HEIGHT, 0.0D); List list = this.worldObj.getEntitiesWithinAABB(EntityLiving.class, axisalignedbb); for (EntityLiving entityplayer : list) diff --git a/common/src/common/util/BlockPos.java b/common/src/common/util/BlockPos.java index 526a1f4..493452c 100755 --- a/common/src/common/util/BlockPos.java +++ b/common/src/common/util/BlockPos.java @@ -8,6 +8,14 @@ import common.entity.Entity; public class BlockPos extends Vec3i { public static final BlockPos ORIGIN = new BlockPos(0, 0, 0); + private static final int NUM_X_BITS = 1 + 26; // ExtMath.calculateLogBaseTwo(ExtMath.roundUpToPowerOfTwo(World.MAX_SIZE)); + private static final int NUM_Z_BITS = NUM_X_BITS; + private static final int NUM_Y_BITS = 64 - NUM_X_BITS - NUM_Z_BITS; + private static final int Y_SHIFT = 0 + NUM_Z_BITS; + private static final int X_SHIFT = Y_SHIFT + NUM_Y_BITS; + private static final long X_MASK = (1L << NUM_X_BITS) - 1L; + private static final long Y_MASK = (1L << NUM_Y_BITS) - 1L; + private static final long Z_MASK = (1L << NUM_Z_BITS) - 1L; public BlockPos(int x, int y, int z) { @@ -185,6 +193,19 @@ public class BlockPos extends Vec3i { return new BlockPos(this.getY() * vec.getZ() - this.getZ() * vec.getY(), this.getZ() * vec.getX() - this.getX() * vec.getZ(), this.getX() * vec.getY() - this.getY() * vec.getX()); } + + public long toLong() + { + return ((long)this.getX() & X_MASK) << X_SHIFT | ((long)this.getY() & Y_MASK) << Y_SHIFT | ((long)this.getZ() & Z_MASK) << 0; + } + + public static BlockPos fromLong(long serialized) + { + int i = (int)(serialized << 64 - X_SHIFT - NUM_X_BITS >> 64 - NUM_X_BITS); + int j = (int)(serialized << 64 - Y_SHIFT - NUM_Y_BITS >> 64 - NUM_Y_BITS); + int k = (int)(serialized << 64 - NUM_Z_BITS >> 64 - NUM_Z_BITS); + return new BlockPos(i, j, k); + } public static Iterable getAllInBox(BlockPos from, BlockPos to) { diff --git a/common/src/common/world/Chunk.java b/common/src/common/world/Chunk.java index 259a183..efbb742 100755 --- a/common/src/common/world/Chunk.java +++ b/common/src/common/world/Chunk.java @@ -31,8 +31,6 @@ public class Chunk { public final int xPos; public final int zPos; private final World world; - private final State filler; - private final Block fillerBlock; private final BlockArray[] blocks = new BlockArray[32]; private final byte[] biomes = new byte[256]; private final int[] precHeight = new int[256]; @@ -50,24 +48,18 @@ public class Chunk { private boolean modified; private boolean hasEntity; private int minHeight; - private int lightChecks = Integer.MAX_VALUE; - private int bottom = Integer.MAX_VALUE; - private int top = Integer.MIN_VALUE; + private int lightChecks = 8192; private long lastSave; private long inhabited; - private BlockArray[] extendDown; - private BlockArray[] extendUp; public Chunk(World world, int x, int z) { this.world = world; this.xPos = x; this.zPos = z; - this.filler = world.dimension.getFiller(); - this.fillerBlock = this.filler.getBlock(); for(int y = 0; y < this.entities.length; ++y) { this.entities[y] = new ClassInheritanceMultiMap(Entity.class); } - Arrays.fill(this.precHeight, -99999999); + Arrays.fill(this.precHeight, -999); Arrays.fill(this.biomes, (byte)-1); } @@ -118,8 +110,6 @@ public class Chunk { for(int n = 0; n < this.biomes.length; ++n) { this.biomes[n] = (byte)biomes[n].id; } - this.bottom = height == 0 ? Integer.MAX_VALUE : 0; - this.top = height == 0 ? Integer.MIN_VALUE : (height + 15) >> 4; if(ceil == null) this.genSkyLight(); else @@ -134,110 +124,29 @@ public class Chunk { return this.height[z << 4 | x]; } - private int findTopSegment() { - if(this.extendUp != null) { - for(int y = this.extendUp.length - 1; y >= 0; --y) { - if(this.extendUp[y] != null) - return this.extendUp[y].getY(); - } - } - for(int y = this.blocks.length - 1; y >= 0; --y) { - if(this.blocks[y] != null) - return this.blocks[y].getY(); - } - if(this.extendDown != null) { - for(int y = this.extendDown.length - 1; y >= 0; --y) { - if(this.extendDown[y] != null) - return this.extendDown[y].getY(); - } - } - return Integer.MIN_VALUE; - } - - private int findBottomSegment() { - if(this.extendDown != null) { - for(int y = 0; y < this.extendDown.length; ++y) { - if(this.extendDown[y] != null) - return this.extendDown[y].getY(); - } - } - for(int y = 0; y < this.blocks.length; ++y) { - if(this.blocks[y] != null) - return this.blocks[y].getY(); - } - if(this.extendUp != null) { - for(int y = 0; y < this.extendUp.length; ++y) { - if(this.extendUp[y] != null) - return this.extendUp[y].getY(); - } - } - return Integer.MAX_VALUE; - } - public int getTopSegment() { - return this.top; - } + for(int y = this.blocks.length - 1; y >= 0; --y) { + if(this.blocks[y] != null) { + return this.blocks[y].getY(); + } + } - public int getBottomSegment() { - return this.bottom; + return 0; } public BlockArray[] getStorage() { return this.blocks; } - public BlockArray[] getStorageDown() { - return this.extendDown; - } - - public BlockArray[] getStorageUp() { - return this.extendUp; - } - - public BlockArray getArray(int y) { - return y >= 0 && y < this.blocks.length ? this.blocks[y] : (y < 0 ? (this.extendDown == null || -y > this.extendDown.length ? null : this.extendDown[-this.extendDown.length - y]) : (this.extendUp == null || y - this.blocks.length >= this.extendUp.length ? null : this.extendUp[y - this.blocks.length])); - } - - private void setArray(int y, BlockArray array) { - if(y >= 0 && y < this.blocks.length) { - this.blocks[y] = array; - } - else if(y < 0) { - if(this.extendDown == null) { - this.extendDown = new BlockArray[-y]; - } - else if(this.extendDown.length < -y) { - BlockArray[] extendDown = this.extendDown; - this.extendDown = new BlockArray[-y]; - System.arraycopy(extendDown, 0, this.extendDown, -y - extendDown.length, extendDown.length); - } - this.extendDown[-this.extendDown.length - y] = array; - } - else { - if(this.extendUp == null) { - this.extendUp = new BlockArray[1 + y - this.blocks.length]; - } - else if(this.extendUp.length <= y - this.blocks.length) { - BlockArray[] extendUp = this.extendUp; - this.extendUp = new BlockArray[1 + y - this.blocks.length]; - System.arraycopy(extendUp, 0, this.extendUp, 0, extendUp.length); - } - this.extendUp[y - this.blocks.length] = array; - } - this.bottom = this.findBottomSegment(); - this.top = this.findTopSegment(); - } - protected void genHeights() { - int top = this.getTopSegment(); - int bottom = this.getBottomSegment(); + int h = this.getTopSegment(); this.minHeight = Integer.MAX_VALUE; for(int x = 0; x < 16; ++x) { for(int z = 0; z < 16; ++z) { - this.precHeight[x + (z << 4)] = -99999999; + this.precHeight[x + (z << 4)] = -999; - for(int y = top + 16; y > bottom; --y) { + for(int y = h + 16; y > 0; --y) { Block block = this.getBlock0(x, y - 1, z); if(block.getLightOpacity() != 0) { @@ -257,15 +166,14 @@ public class Chunk { } public void genSkyLight() { - int top = this.getTopSegment(); - int bottom = this.getBottomSegment(); + int h = this.getTopSegment(); this.minHeight = Integer.MAX_VALUE; for(int x = 0; x < 16; ++x) { for(int z = 0; z < 16; ++z) { - this.precHeight[x + (z << 4)] = -99999999; + this.precHeight[x + (z << 4)] = -999; - for(int y = top + 16; y > bottom; --y) { + for(int y = h + 16; y > 0; --y) { if(this.getOpacity(x, y - 1, z) != 0) { this.height[z << 4 | x] = y; @@ -277,9 +185,9 @@ public class Chunk { } } - if(!this.world.dimension.hasNoLight() && top != Integer.MIN_VALUE) { + if(!this.world.dimension.hasNoLight()) { int l = 15; - int y = top + 16 - 1; + int y = h + 16 - 1; while(true) { int b = this.getOpacity(x, y, z); @@ -291,7 +199,7 @@ public class Chunk { l -= b; if(l > 0) { - BlockArray stor = this.getArray(y >> 4); + BlockArray stor = this.blocks[y >> 4]; if(stor != null) { stor.setSky(x, y & 15, z, l); @@ -301,7 +209,7 @@ public class Chunk { --y; - if(y <= bottom || l <= 0) { + if(y <= 0 || l <= 0) { break; } } @@ -377,15 +285,14 @@ public class Chunk { } private void relightBlock(int x, int y, int z) { - int h = this.height[z << 4 | x]; - int min = this.getBottomSegment(); + int h = this.height[z << 4 | x] & 511; int cy = h; if(y > h) { cy = y; } - while(cy > min && this.getOpacity(x, cy - 1, z) == 0) { + while(cy > 0 && this.getOpacity(x, cy - 1, z) == 0) { --cy; } @@ -398,7 +305,7 @@ public class Chunk { if(!this.world.dimension.hasNoLight()) { if(cy < h) { for(int n = cy; n < h; ++n) { - BlockArray stor = this.getArray(n >> 4); + BlockArray stor = this.blocks[n >> 4]; if(stor != null) { stor.setSky(x, n & 15, z, 15); @@ -408,7 +315,7 @@ public class Chunk { } else { for(int n = h; n < cy; ++n) { - BlockArray stor = this.getArray(n >> 4); + BlockArray stor = this.blocks[n >> 4]; if(stor != null) { stor.setSky(x, n & 15, z, 0); @@ -419,7 +326,7 @@ public class Chunk { int l = 15; - while(cy > min && l > 0) { + while(cy > 0 && l > 0) { --cy; int b = this.getOpacity(x, cy, z); @@ -433,7 +340,7 @@ public class Chunk { l = 0; } - BlockArray stor = this.getArray(cy >> 4); + BlockArray stor = this.blocks[cy >> 4]; if(stor != null) { stor.setSky(x, cy & 15, z, l); @@ -473,48 +380,69 @@ public class Chunk { private int getOpacity(int x, int y, int z) { return this.getBlock0(x, y, z).getLightOpacity(); } - + private Block getBlock0(int x, int y, int z) { + Block block = Blocks.air; + if(y >= 0 && y >> 4 < this.blocks.length) { BlockArray stor = this.blocks[y >> 4]; - return stor != null ? stor.getBlock(x, y & 15, z) : Blocks.air; - } - else if(y < 0 && this.extendDown != null && -(y >> 4) <= this.extendDown.length) { - BlockArray stor = this.extendDown[-this.extendDown.length - (y >> 4)]; - return stor != null ? stor.getBlock(x, y & 15, z) : this.fillerBlock; - } - else if(y >> 4 >= this.blocks.length && this.extendUp != null && (y >> 4) - this.blocks.length < this.extendUp.length) { - BlockArray stor = this.extendUp[(y >> 4) - this.blocks.length]; - return stor != null ? stor.getBlock(x, y & 15, z) : Blocks.air; - } - return y < 0 ? this.fillerBlock : Blocks.air; - } - - public State getState(BlockPos pos) { - if(this.world.debug) { - State state = pos.getY() == 1 ? DebugStates.getState(pos.getX(), pos.getZ()) : null; - return state == null ? Blocks.air.getState() : state; + + if(stor != null) { + block = stor.getBlock(x, y & 15, z); + } } - if(pos.getY() >= 0 && pos.getY() >> 4 < this.blocks.length) { - BlockArray stor = this.blocks[pos.getY() >> 4]; - return stor != null ? stor.get(pos.getX() & 15, pos.getY() & 15, pos.getZ() & 15) : Blocks.air.getState(); - } - else if(pos.getY() < 0 && this.extendDown != null && -(pos.getY() >> 4) <= this.extendDown.length) { - BlockArray stor = this.extendDown[-this.extendDown.length - (pos.getY() >> 4)]; - return stor != null ? stor.get(pos.getX() & 15, pos.getY() & 15, pos.getZ() & 15) : this.filler; - } - else if(pos.getY() >> 4 >= this.blocks.length && this.extendUp != null && (pos.getY() >> 4) - this.blocks.length < this.extendUp.length) { - BlockArray stor = this.extendUp[(pos.getY() >> 4) - this.blocks.length]; - return stor != null ? stor.get(pos.getX() & 15, pos.getY() & 15, pos.getZ() & 15) : Blocks.air.getState(); - } - return pos.getY() < 0 ? this.filler : Blocks.air.getState(); + return block; } public Block getBlock(BlockPos pos) { return this.getBlock0(pos.getX() & 15, pos.getY(), pos.getZ() & 15); } - + + public State getState(BlockPos pos) { + if(this.world.debug) { + State state = null; + +// if(pos.getY() == 60) { +// state = Blocks.glass.getDefaultState(); +// } + + if(pos.getY() == 1) { + state = DebugStates.getState(pos.getX(), pos.getZ()); + } + + return state == null ? Blocks.air.getState() : state; + } + else { + if(pos.getY() >= 0 && pos.getY() >> 4 < this.blocks.length) { + BlockArray stor = this.blocks[pos.getY() >> 4]; + + if(stor != null) { + int x = pos.getX() & 15; + int y = pos.getY() & 15; + int z = pos.getZ() & 15; + return stor.get(x, y, z); + } + } + + return Blocks.air.getState(); + } + } + + private int getMeta(int x, int y, int z) { + if(y >> 4 >= this.blocks.length) { + return 0; + } + else { + BlockArray stor = this.blocks[y >> 4]; + return stor != null ? stor.getMeta(x, y & 15, z) : 0; + } + } + + public int getMeta(BlockPos pos) { + return this.getMeta(pos.getX() & 15, pos.getY(), pos.getZ() & 15); + } + public State setState(BlockPos pos, State state) { int x = pos.getX() & 15; int y = pos.getY(); @@ -522,7 +450,7 @@ public class Chunk { int o = z << 4 | x; if(y >= this.precHeight[o] - 1) { - this.precHeight[o] = -99999999; + this.precHeight[o] = -999; } int h = this.height[o]; @@ -534,7 +462,7 @@ public class Chunk { else { Block block = state.getBlock(); Block oldb = old.getBlock(); - BlockArray stor = this.getArray(y >> 4); + BlockArray stor = this.blocks[y >> 4]; boolean up = false; if(stor == null) { @@ -542,8 +470,7 @@ public class Chunk { return null; } - stor = new BlockArray(y >> 4 << 4, !this.world.dimension.hasNoLight()); - this.setArray(y >> 4, stor); + stor = this.blocks[y >> 4] = new BlockArray(y >> 4 << 4, !this.world.dimension.hasNoLight()); up = y >= h; } @@ -599,7 +526,7 @@ public class Chunk { TileEntity tile = this.getTileEntity(pos, TileEntity.EnumCreateEntityType.CHECK); if(tile == null) { - tile = ((ITileEntityProvider)block).createNewTileEntity(this.world); + tile = ((ITileEntityProvider)block).createNewTileEntity(this.world, block.getMetaFromState(state)); this.world.setTileEntity(pos, tile); } @@ -618,7 +545,7 @@ public class Chunk { int x = pos.getX() & 15; int y = pos.getY(); int z = pos.getZ() & 15; - BlockArray stor = this.getArray(y >> 4); + BlockArray stor = this.blocks[y >> 4]; return stor == null ? (this.canSeeSky(pos) ? type.defValue : 0) : (type == LightType.SKY ? (this.world.dimension.hasNoLight() ? 0 : stor.getSky(x, y & 15, z)) : (type == LightType.BLOCK ? stor.getLight(x, y & 15, z) : type.defValue)); @@ -628,11 +555,10 @@ public class Chunk { int x = pos.getX() & 15; int y = pos.getY(); int z = pos.getZ() & 15; - BlockArray stor = this.getArray(y >> 4); + BlockArray stor = this.blocks[y >> 4]; if(stor == null) { - stor = new BlockArray(y >> 4 << 4, !this.world.dimension.hasNoLight()); - this.setArray(y >> 4, stor); + stor = this.blocks[y >> 4] = new BlockArray(y >> 4 << 4, !this.world.dimension.hasNoLight()); this.genSkyLight(); } @@ -652,7 +578,7 @@ public class Chunk { int x = pos.getX() & 15; int y = pos.getY(); int z = pos.getZ() & 15; - BlockArray stor = this.getArray(y >> 4); + BlockArray stor = this.blocks[y >> 4]; if(stor == null) { return !this.world.dimension.hasNoLight() && amount < LightType.SKY.defValue @@ -721,7 +647,7 @@ public class Chunk { private TileEntity createNewTileEntity(BlockPos pos) { Block block = this.getBlock(pos); - return !block.hasTileEntity() ? null : ((ITileEntityProvider)block).createNewTileEntity(this.world); + return !block.hasTileEntity() ? null : ((ITileEntityProvider)block).createNewTileEntity(this.world, this.getMeta(pos)); } public TileEntity getTileEntity(BlockPos pos, TileEntity.EnumCreateEntityType type) { @@ -879,13 +805,12 @@ public class Chunk { int o = x | z << 4; BlockPos loc = new BlockPos(pos.getX(), this.precHeight[o], pos.getZ()); - if(loc.getY() == -99999999) { + if(loc.getY() == -999) { int y = this.getTopSegment() + 15; - int min = this.getBottomSegment(); loc = new BlockPos(pos.getX(), y, pos.getZ()); int h = -1; - while(loc.getY() > min && h == -1) { + while(loc.getY() > 0 && h == -1) { Block block = this.getBlock(loc); Material mat = block.getMaterial(); @@ -936,8 +861,16 @@ public class Chunk { } public boolean isEmpty(int bottom, int top) { + if(bottom < 0) { + bottom = 0; + } + + if(top >= 512) { + top = 511; + } + for(int y = bottom; y <= top; y += 16) { - BlockArray stor = this.getArray(y >> 4); + BlockArray stor = this.blocks[y >> 4]; if(stor != null && !stor.isEmpty()) { return false; @@ -947,7 +880,7 @@ public class Chunk { return true; } - public void setStorage(BlockArray[] arrays, BlockArray[] down, BlockArray[] up) { + public void setStorage(BlockArray[] arrays) { if(this.blocks.length != arrays.length) { Log.JNI.warn("Konnte Sektionen des Chunks nicht setzen, Länge des Arrays ist " + arrays.length + " statt " + this.blocks.length); @@ -956,14 +889,10 @@ public class Chunk { for(int n = 0; n < this.blocks.length; ++n) { this.blocks[n] = arrays[n]; } - this.extendDown = down; - this.extendUp = up; - this.bottom = this.findBottomSegment(); - this.top = this.findTopSegment(); } } - public void setData(byte[] data, int update, int[] extend, boolean biomes) { + public void setData(byte[] data, int update, boolean biomes) { int pos = 0; boolean sky = !this.world.dimension.hasNoLight(); @@ -984,23 +913,6 @@ public class Chunk { this.blocks[n] = null; } } - if(biomes) { - this.extendDown = null; - this.extendUp = null; - } - for(int cy : extend) { - BlockArray arr = this.getArray(cy); - if(arr == null) { - arr = new BlockArray(cy << 4, sky); - } - - char[] blocks = arr.getData(); - - for(int k = 0; k < blocks.length; ++k) { - blocks[k] = (char)((data[pos + 1] & 255) << 8 | data[pos] & 255); - pos += 2; - } - } for(int n = 0; n < this.blocks.length; ++n) { if((update & 1 << n) != 0 && this.blocks[n] != null) { @@ -1009,14 +921,6 @@ public class Chunk { pos += light.getData().length; } } - for(int cy : extend) { - BlockArray arr = this.getArray(cy); - if(arr != null) { - NibbleArray light = arr.getBlocklight(); - System.arraycopy(data, pos, light.getData(), 0, light.getData().length); - pos += light.getData().length; - } - } if(sky) { for(int n = 0; n < this.blocks.length; ++n) { @@ -1026,35 +930,18 @@ public class Chunk { pos += slight.getData().length; } } - for(int cy : extend) { - BlockArray arr = this.getArray(cy); - if(arr != null) { - NibbleArray slight = arr.getSkylight(); - System.arraycopy(data, pos, slight.getData(), 0, slight.getData().length); - pos += slight.getData().length; - } - } } if(biomes) { System.arraycopy(data, pos, this.biomes, 0, this.biomes.length); // int unk = pos + this.biomes.length; } - - this.bottom = this.findBottomSegment(); - this.top = this.findTopSegment(); for(int n = 0; n < this.blocks.length; ++n) { if(this.blocks[n] != null && (update & 1 << n) != 0) { this.blocks[n].update(); } } - for(int cy : extend) { - BlockArray arr = this.getArray(cy); - if(arr != null) { - arr.update(); - } - } this.lightInit = true; this.populated = true; @@ -1109,14 +996,11 @@ public class Chunk { BlockPos pos = new BlockPos(this.xPos << 4, 0, this.zPos << 4); for(int n = 0; n < 8; ++n) { - if(this.top == Integer.MIN_VALUE) - return; - int h = 1 + this.top - this.bottom; - if(this.lightChecks >= 256 * h) + if(this.lightChecks >= 8192) return; - int s = (this.lightChecks % h) + this.bottom; - int x = this.lightChecks / h % 16; + int s = this.lightChecks % 31; + int x = this.lightChecks / 31 % 16; int z = this.lightChecks / 512; ++this.lightChecks; @@ -1124,9 +1008,8 @@ public class Chunk { BlockPos block = pos.add(x, (s << 4) + y, z); boolean edge = y == 0 || y == 15 || x == 0 || x == 15 || z == 0 || z == 15; - BlockArray arr = this.getArray(s); - if(arr == null && edge || arr != null - && arr.getBlock(x, y, z).getMaterial() == Material.air) { + if(this.blocks[s] == null && edge || this.blocks[s] != null + && this.blocks[s].getBlock(x, y, z).getMaterial() == Material.air) { for(Facing face : Facing.values()) { BlockPos side = block.offset(face); @@ -1209,12 +1092,11 @@ public class Chunk { private boolean updateColumn(int x, int z) { int top = this.getTopSegment(); - int bottom = this.getBottomSegment(); boolean opaque = false; boolean below = false; BlockPos.MutableBlockPos pos = new BlockPos.MutableBlockPos((this.xPos << 4) + x, 0, (this.zPos << 4) + z); - for(int y = top + 16 - 1; y > this.world.getSeaLevel() || y > bottom && !below; --y) { + for(int y = top + 16 - 1; y > this.world.getSeaLevel() || y > 0 && !below; --y) { pos.set(pos.getX(), y, pos.getZ()); int o = this.getOpacity(pos); @@ -1230,7 +1112,7 @@ public class Chunk { } } - for(int y = pos.getY(); y > bottom; --y) { + for(int y = pos.getY(); y > 0; --y) { pos.set(pos.getX(), y, pos.getZ()); if(this.getBlock(pos).getLightValue() > 0) { diff --git a/common/src/common/world/World.java b/common/src/common/world/World.java index 6d991e3..b1529dc 100755 --- a/common/src/common/world/World.java +++ b/common/src/common/world/World.java @@ -51,7 +51,7 @@ public abstract class World implements IWorldAccess { } public static final float[] MOON_PHASES = new float[] {1.0F, 0.75F, 0.5F, 0.25F, 0.0F, 0.25F, 0.5F, 0.75F}; public static final int MAX_SIZE = 67108864; - public static final int MAX_SIZE_Y = 4096; + public static final int HEIGHT = 512; public static final long START_TIME = 4385238000L; public static final float ABSOLUTE_ZERO = -273.15f; // private static final Calendar calendar = Calendar.getInstance(); @@ -109,7 +109,7 @@ public abstract class World implements IWorldAccess { public static boolean isValid(BlockPos pos) { return pos.getX() >= -MAX_SIZE && pos.getZ() >= -MAX_SIZE && pos.getX() < MAX_SIZE && pos.getZ() < MAX_SIZE && - pos.getY() >= -MAX_SIZE_Y && pos.getY() < MAX_SIZE_Y; + pos.getY() >= 0 && pos.getY() < 512; } public static boolean isValidXZ(BlockPos pos) { @@ -170,7 +170,7 @@ public abstract class World implements IWorldAccess { } private boolean isAreaLoaded(int xStart, int yStart, int zStart, int xEnd, int yEnd, int zEnd, boolean allowEmpty) { - if(yEnd >= -MAX_SIZE_Y && yStart < MAX_SIZE_Y) { + if(yEnd >= 0 && yStart < 512) { xStart = xStart >> 4; zStart = zStart >> 4; xEnd = xEnd >> 4; @@ -344,12 +344,12 @@ public abstract class World implements IWorldAccess { } public int getLight(BlockPos pos) { - if(pos.getY() < -MAX_SIZE_Y) { + if(pos.getY() < 0) { return 0; } else { - if(pos.getY() >= MAX_SIZE_Y) { - pos = new BlockPos(pos.getX(), MAX_SIZE_Y - 1, pos.getZ()); + if(pos.getY() >= 512) { + pos = new BlockPos(pos.getX(), 511, pos.getZ()); } return this.getChunk(pos).getLightSub(pos, 0); @@ -387,12 +387,12 @@ public abstract class World implements IWorldAccess { return i1; } - else if(pos.getY() < -MAX_SIZE_Y) { + else if(pos.getY() < 0) { return 0; } else { - if(pos.getY() >= MAX_SIZE_Y) { - pos = new BlockPos(pos.getX(), MAX_SIZE_Y - 1, pos.getZ()); + if(pos.getY() >= 512) { + pos = new BlockPos(pos.getX(), 511, pos.getZ()); } Chunk chunk = this.getChunk(pos); @@ -442,8 +442,8 @@ public abstract class World implements IWorldAccess { return 0; } else { - if(pos.getY() < -MAX_SIZE_Y) { - pos = new BlockPos(pos.getX(), -MAX_SIZE_Y, pos.getZ()); + if(pos.getY() < 0) { + pos = new BlockPos(pos.getX(), 0, pos.getZ()); } if(!isValid(pos)) { @@ -485,8 +485,8 @@ public abstract class World implements IWorldAccess { } public int getLightFor(LightType type, BlockPos pos) { - if(pos.getY() < -MAX_SIZE_Y) { - pos = new BlockPos(pos.getX(), -MAX_SIZE_Y, pos.getZ()); + if(pos.getY() < 0) { + pos = new BlockPos(pos.getX(), 0, pos.getZ()); } if(!isValid(pos)) { @@ -1593,7 +1593,7 @@ public abstract class World implements IWorldAccess { return true; } else { - if(pos.getY() >= -MAX_SIZE_Y && pos.getY() < MAX_SIZE_Y && this.getLightFor(LightType.BLOCK, pos) < 10) { + if(pos.getY() >= 0 && pos.getY() < 512 && this.getLightFor(LightType.BLOCK, pos) < 10) { Block block = this.getState(pos).getBlock(); if((block.getMaterial() == Material.air || (allowLayers && block == Blocks.snow_layer)) diff --git a/server/src/server/clipboard/ClipboardPlacer.java b/server/src/server/clipboard/ClipboardPlacer.java index e8239d1..24d9db5 100755 --- a/server/src/server/clipboard/ClipboardPlacer.java +++ b/server/src/server/clipboard/ClipboardPlacer.java @@ -41,6 +41,8 @@ public class ClipboardPlacer { } public void setBlock(BlockPos location, ClipboardBlock block) { + if(location.getY() < 0 || location.getY() > 511) + return; Block type = block.getState().getBlock(); if (ReorderRegistry.shouldPlaceLast(type)) { // Place torches, etc. last diff --git a/server/src/server/command/Command.java b/server/src/server/command/Command.java index 7828595..e58b0d7 100644 --- a/server/src/server/command/Command.java +++ b/server/src/server/command/Command.java @@ -74,7 +74,7 @@ public abstract class Command implements Executable { } }, new DoubleParser("x", defaulted ? DefType.X : null, (double)(-World.MAX_SIZE), (double)World.MAX_SIZE, centered), - new DoubleParser("y", defaulted ? DefType.Y : null, (double)(-World.MAX_SIZE_Y), (double)World.MAX_SIZE_Y, false), + new DoubleParser("y", defaulted ? DefType.Y : null, 0.0, (double)World.HEIGHT, false), new DoubleParser("z", defaulted ? DefType.Z : null, (double)(-World.MAX_SIZE), (double)World.MAX_SIZE, centered)); } diff --git a/server/src/server/network/Player.java b/server/src/server/network/Player.java index 3377336..f42a452 100755 --- a/server/src/server/network/Player.java +++ b/server/src/server/network/Player.java @@ -970,7 +970,7 @@ public class Player extends NetHandler implements ICrafting, Executor, IPlayer if (chunk.isPopulated()) { list.add(chunk); - list1.addAll(((WorldServer)this.entity.worldObj).getTileEntitiesIn(chunkcoordintpair.x * 16, -World.MAX_SIZE_Y, chunkcoordintpair.z * 16, chunkcoordintpair.x * 16 + 16, World.MAX_SIZE_Y, chunkcoordintpair.z * 16 + 16)); + list1.addAll(((WorldServer)this.entity.worldObj).getTileEntitiesIn(chunkcoordintpair.x * 16, 0, chunkcoordintpair.z * 16, chunkcoordintpair.x * 16 + 16, 512, chunkcoordintpair.z * 16 + 16)); iterator1.remove(); } } @@ -985,7 +985,7 @@ public class Player extends NetHandler implements ICrafting, Executor, IPlayer { if (list.size() == 1) { - this.sendPacket(new SPacketChunkData((Chunk)list.get(0), true, 0xffffffff, null)); + this.sendPacket(new SPacketChunkData((Chunk)list.get(0), true, 0xffffffff)); } else { @@ -2098,7 +2098,7 @@ public class Player extends NetHandler implements ICrafting, Executor, IPlayer float f1 = this.entity.rotYaw; float f2 = this.entity.rotPitch; - if (packetIn.isMoving() && packetIn.getPositionY() == -99999999.0D) + if (packetIn.isMoving() && packetIn.getPositionY() == -999.0D) { packetIn.setMoving(false); } @@ -2281,7 +2281,7 @@ public class Player extends NetHandler implements ICrafting, Executor, IPlayer { return; } - else if (blockpos.getY() >= World.MAX_SIZE_Y) + else if (blockpos.getY() >= World.HEIGHT) { return; } @@ -2345,7 +2345,7 @@ public class Player extends NetHandler implements ICrafting, Executor, IPlayer this.tryUseItem(itemstack); // } } - else if (blockpos.getY() < World.MAX_SIZE_Y - 1 || enumfacing != Facing.UP && blockpos.getY() < World.MAX_SIZE_Y) + else if (blockpos.getY() < World.HEIGHT - 1 || enumfacing != Facing.UP && blockpos.getY() < World.HEIGHT) { double max = this.entity.getReachDistance() + 3.0D; max *= max; diff --git a/server/src/server/world/Region.java b/server/src/server/world/Region.java index 21618b4..fcf1367 100755 --- a/server/src/server/world/Region.java +++ b/server/src/server/world/Region.java @@ -376,22 +376,12 @@ public class Region { chunk.setInhabited(tag.getLong("InhabitedTime")); NBTTagList sects = tag.getTagList("Sections", 10); int stor = 32; - int min = 0; - int max = stor - 1; - for(int n = 0; n < sects.tagCount(); ++n) { - NBTTagCompound sect = sects.getCompoundTagAt(n); - int y = sect.getInteger("Y"); - min = y < min ? y : min; - max = y > max ? y : max; - } BlockArray[] sections = new BlockArray[stor]; - BlockArray[] down = min < 0 ? new BlockArray[-min] : null; - BlockArray[] up = max >= stor ? new BlockArray[1 + max - stor] : null; boolean light = !world.dimension.hasNoLight(); for(int n = 0; n < sects.tagCount(); ++n) { NBTTagCompound sect = sects.getCompoundTagAt(n); - int y = sect.getInteger("Y"); + int y = sect.getByte("Y"); BlockArray storage = new BlockArray(y << 4, light); byte[] blocks = sect.getByteArray("Blocks"); NibbleArray data = new NibbleArray(sect.getByteArray("Data")); @@ -414,15 +404,10 @@ public class Region { } storage.update(); - if(y >= 0 && y < stor) - sections[y] = storage; - else if(y < 0) - down[-down.length - y] = storage; - else - up[y - stor] = storage; + sections[y] = storage; } - chunk.setStorage(sections, down, up); + chunk.setStorage(sections); if(tag.hasKey("Biomes", 7)) { chunk.setBiomes(tag.getByteArray("Biomes")); @@ -510,58 +495,52 @@ public class Region { tag.setBoolean("LightPopulated", chunk.isLightPopulated()); tag.setLong("InhabitedTime", chunk.getInhabited()); BlockArray[] sections = chunk.getStorage(); - BlockArray[] down = chunk.getStorage(); - BlockArray[] up = chunk.getStorage(); NBTTagList sects = new NBTTagList(); boolean light = !world.dimension.hasNoLight(); - for(BlockArray[] sec : new BlockArray[][] {sections, down, up}) { - if(sec == null) - continue; - for(BlockArray storage : sec) { - if(storage != null) { - NBTTagCompound sect = new NBTTagCompound(); - sect.setInteger("Y", storage.getY() >> 4); - byte[] blocks = new byte[storage.getData().length]; - NibbleArray data = new NibbleArray(); - NibbleArray adddata = null; - - for(int c = 0; c < storage.getData().length; ++c) { - char cd = storage.getData()[c]; - int cx = c & 15; - int cy = c >> 8 & 15; - int cz = c >> 4 & 15; - - if(cd >> 12 != 0) { - if(adddata == null) { - adddata = new NibbleArray(); - } - - adddata.set(cx, cy, cz, cd >> 12); + for(BlockArray storage : sections) { + if(storage != null) { + NBTTagCompound sect = new NBTTagCompound(); + sect.setByte("Y", (byte)(storage.getY() >> 4 & 511)); + byte[] blocks = new byte[storage.getData().length]; + NibbleArray data = new NibbleArray(); + NibbleArray adddata = null; + + for(int c = 0; c < storage.getData().length; ++c) { + char cd = storage.getData()[c]; + int cx = c & 15; + int cy = c >> 8 & 15; + int cz = c >> 4 & 15; + + if(cd >> 12 != 0) { + if(adddata == null) { + adddata = new NibbleArray(); } - - blocks[c] = (byte)(cd >> 4 & 255); - data.set(cx, cy, cz, cd & 15); + + adddata.set(cx, cy, cz, cd >> 12); } - - sect.setByteArray("Blocks", blocks); - sect.setByteArray("Data", data.getData()); - - if(adddata != null) { - sect.setByteArray("Add", adddata.getData()); - } - - sect.setByteArray("BlockLight", storage.getBlocklight().getData()); - - if(light) { - sect.setByteArray("SkyLight", storage.getSkylight().getData()); - } - else { - sect.setByteArray("SkyLight", new byte[storage.getBlocklight().getData().length]); - } - - sects.appendTag(sect); + + blocks[c] = (byte)(cd >> 4 & 255); + data.set(cx, cy, cz, cd & 15); } + + sect.setByteArray("Blocks", blocks); + sect.setByteArray("Data", data.getData()); + + if(adddata != null) { + sect.setByteArray("Add", adddata.getData()); + } + + sect.setByteArray("BlockLight", storage.getBlocklight().getData()); + + if(light) { + sect.setByteArray("SkyLight", storage.getSkylight().getData()); + } + else { + sect.setByteArray("SkyLight", new byte[storage.getBlocklight().getData().length]); + } + + sects.appendTag(sect); } } diff --git a/server/src/server/world/Spawner.java b/server/src/server/world/Spawner.java index 49a623f..5133cf3 100755 --- a/server/src/server/world/Spawner.java +++ b/server/src/server/world/Spawner.java @@ -90,10 +90,13 @@ public abstract class Spawner { Chunk chunk = world.getChunk(coord.x, coord.z); int x = coord.x * 16 + world.rand.zrange(16); int z = coord.z * 16 + world.rand.zrange(16); - int h = chunk.getTopSegment(); - if(h == Integer.MIN_VALUE) - continue; - int y = world.rand.range(chunk.getBottomSegment(), h + 16); + int h = chunk.getHeight(new BlockPos(x, 0, z)) + 1; + if(h > 0) { + int m = h % 16; + h = m == 0 ? h : h + 16 - m; + } + h = h == 0 ? 16 : (h > 0 ? h : chunk.getTopSegment() + 16 - 1); + int y = world.rand.excl(h <= 8 ? 0 : 8, h); BlockPos pos = new BlockPos(x, y, z); Block block = world.getState(pos).getBlock(); if(!block.isNormalCube()) { diff --git a/server/src/server/world/WorldServer.java b/server/src/server/world/WorldServer.java index b6270ec..37b2873 100755 --- a/server/src/server/world/WorldServer.java +++ b/server/src/server/world/WorldServer.java @@ -741,7 +741,7 @@ public final class WorldServer extends AWorldServer { private BlockPos adjustPosToNearbyEntity(BlockPos pos) { BlockPos blockpos = this.getPrecipitationHeight(pos); - BoundingBox axisalignedbb = (new BoundingBox(blockpos, new BlockPos(blockpos.getX(), World.MAX_SIZE_Y, blockpos.getZ()))).expand(3.0D, + BoundingBox axisalignedbb = (new BoundingBox(blockpos, new BlockPos(blockpos.getX(), World.HEIGHT, blockpos.getZ()))).expand(3.0D, 3.0D, 3.0D); List list = this.getEntitiesWithinAABB(EntityLiving.class, axisalignedbb, new Predicate() { public boolean test(EntityLiving p_apply_1_) { @@ -2369,7 +2369,7 @@ public final class WorldServer extends AWorldServer { if(!this.canBurnAt(pos)) { return false; } - if(pos.getY() >= -World.MAX_SIZE_Y && pos.getY() < World.MAX_SIZE_Y) { + if(pos.getY() >= 0 && pos.getY() < 512) { Block block = this.getState(pos).getBlock(); if(block.getMaterial() == Material.air && Blocks.fire.canPlaceBlockAt(this, pos)) { @@ -2385,7 +2385,7 @@ public final class WorldServer extends AWorldServer { return false; } else { - if(pos.getY() >= -World.MAX_SIZE_Y && pos.getY() < World.MAX_SIZE_Y && this.getLightFor(LightType.BLOCK, pos) < 10) { + if(pos.getY() >= 0 && pos.getY() < 512 && this.getLightFor(LightType.BLOCK, pos) < 10) { State iblockstate = this.getState(pos); Block block = iblockstate.getBlock(); @@ -2437,9 +2437,8 @@ public final class WorldServer extends AWorldServer { Chunk chunk = this.getChunk(pos); BlockPos blockpos; BlockPos blockpos1; - int bottom; - for(blockpos = new BlockPos(pos.getX(), chunk.getTopSegment() + 16, pos.getZ()), bottom = chunk.getBottomSegment(); blockpos.getY() >= bottom; blockpos = blockpos1) { + for(blockpos = new BlockPos(pos.getX(), chunk.getTopSegment() + 16, pos.getZ()); blockpos.getY() >= 0; blockpos = blockpos1) { blockpos1 = blockpos.down(); Material material = chunk.getBlock(blockpos1).getMaterial(); @@ -2803,10 +2802,8 @@ public final class WorldServer extends AWorldServer { private class PlayerInstance { private final List watching = Lists.newArrayList(); - private final Set extend = Sets.newHashSet(); - private final long[] changes = new long[64]; private final ChunkPos position; - + private int[] changes = new int[64]; private int updates; private int sections; private long prevTime; @@ -2837,7 +2834,7 @@ public final class WorldServer extends AWorldServer { Chunk chunk = WorldServer.this.getChunk(this.position.x, this.position.z); if(chunk.isPopulated()) { - player.connection.sendPacket(new SPacketChunkData(chunk, true, 0, new int[0])); + player.connection.sendPacket(new SPacketChunkData(chunk, true, 0)); } this.watching.remove(player); @@ -2880,13 +2877,10 @@ public final class WorldServer extends AWorldServer { WorldServer.this.toUpdate.add(this); } - if(y >= 0 && y >> 4 < 32) - this.sections |= 1 << (y >> 4); - else - this.extend.add(y >> 4); + this.sections |= 1 << (y >> 4); if(this.updates < 64) { - long pos = ((long)x & 4294967295L) << 36 | ((long)z & 4294967295L) << 32 | (y & 4294967295L); + int pos = x << 13 | z << 9 | y; for(int i = 0; i < this.updates; ++i) { if(this.changes[i] == pos) { @@ -2911,9 +2905,9 @@ public final class WorldServer extends AWorldServer { public void onUpdate() { if(this.updates != 0) { if(this.updates == 1) { - int x = (int)(this.changes[0] >> 36 & 15L) + this.position.x * 16; - int y = (int)(this.changes[0] & 4294967295L); - int z = (int)(this.changes[0] >> 32 & 15L) + this.position.z * 16; + int x = (this.changes[0] >> 13 & 15) + this.position.x * 16; + int y = this.changes[0] & 511; + int z = (this.changes[0] >> 9 & 15) + this.position.z * 16; BlockPos pos = new BlockPos(x, y, z); this.sendToAllPlayersWatchingChunk(new SPacketBlockChange(WorldServer.this, pos)); @@ -2924,36 +2918,11 @@ public final class WorldServer extends AWorldServer { else if(this.updates == 64) { int x = this.position.x * 16; int z = this.position.z * 16; - int[] extend = null; - if(!this.biomes) { - extend = new int[this.extend.size()]; - int n = 0; - for(Integer i : this.extend) { - extend[n++] = i; - } - } this.sendToAllPlayersWatchingChunk(new SPacketChunkData(WorldServer.this.getChunk(this.position.x, this.position.z), - this.biomes, this.sections, extend)); - - if(this.biomes) { - List list = WorldServer.this.getTileEntitiesIn(x, Integer.MIN_VALUE, z, x + 16, Integer.MAX_VALUE, z + 16); + this.biomes, this.sections)); - for(int n = 0; n < list.size(); ++n) { - this.sendTileToAllPlayersWatchingChunk(list.get(n)); - } - } - else { - for(int cy = 0; cy < 32; ++cy) { - if((this.sections & 1 << cy) != 0) { - int y = cy << 4; - List list = WorldServer.this.getTileEntitiesIn(x, y, z, x + 16, y + 16, z + 16); - - for(int n = 0; n < list.size(); ++n) { - this.sendTileToAllPlayersWatchingChunk(list.get(n)); - } - } - } - for(Integer cy : this.extend) { + for(int cy = 0; cy < 32; ++cy) { + if((this.sections & 1 << cy) != 0) { int y = cy << 4; List list = WorldServer.this.getTileEntitiesIn(x, y, z, x + 16, y + 16, z + 16); @@ -2968,9 +2937,9 @@ public final class WorldServer extends AWorldServer { WorldServer.this.getChunk(this.position.x, this.position.z))); for(int n = 0; n < this.updates; ++n) { - int x = (int)(this.changes[n] >> 36 & 15L) + this.position.x * 16; - int y = (int)(this.changes[n] & 4294967295L); - int z = (int)(this.changes[n] >> 32 & 15L) + this.position.z * 16; + int x = (this.changes[n] >> 13 & 15) + this.position.x * 16; + int y = this.changes[n] & 511; + int z = (this.changes[n] >> 9 & 15) + this.position.z * 16; BlockPos pos = new BlockPos(x, y, z); if(WorldServer.this.getState(pos).getBlock().hasTileEntity()) { @@ -2981,7 +2950,6 @@ public final class WorldServer extends AWorldServer { this.updates = 0; this.sections = 0; - this.extend.clear(); this.biomes = false; } } From 7fd8a49d5cc23f66c75f85e999549c38ffd43f85 Mon Sep 17 00:00:00 2001 From: Sen Date: Wed, 21 May 2025 12:04:28 +0200 Subject: [PATCH 049/200] initial bugfix for taller chunks --- client/src/client/renderer/RenderGlobal.java | 23 +++++----- client/src/client/renderer/ViewFrustum.java | 45 ++++++++++--------- .../src/common/packet/SPacketChunkData.java | 2 +- common/src/common/world/BlockArray.java | 9 +++- common/src/common/world/Chunk.java | 35 ++++++++------- server/src/server/world/Region.java | 8 ++-- 6 files changed, 67 insertions(+), 55 deletions(-) diff --git a/client/src/client/renderer/RenderGlobal.java b/client/src/client/renderer/RenderGlobal.java index 0af5835..39b65cc 100755 --- a/client/src/client/renderer/RenderGlobal.java +++ b/client/src/client/renderer/RenderGlobal.java @@ -464,7 +464,7 @@ public class RenderGlobal if (entity != null) { - this.viewFrustum.updateChunkPositions(entity.posX, entity.posZ); + this.viewFrustum.updateChunkPositions(entity.posX, entity.posY, entity.posZ); } } @@ -605,7 +605,7 @@ public class RenderGlobal for (RenderGlobal.ContainerLocalRenderInformation renderglobal$containerlocalrenderinformation : this.renderInfos) { Chunk chunk = this.theWorld.getChunk(renderglobal$containerlocalrenderinformation.renderChunk.getPosition()); - ClassInheritanceMultiMap classinheritancemultimap = chunk.getEntities()[renderglobal$containerlocalrenderinformation.renderChunk.getPosition().getY() / 16]; + ClassInheritanceMultiMap classinheritancemultimap = chunk.getEntities()[ExtMath.clampi(renderglobal$containerlocalrenderinformation.renderChunk.getPosition().getY() / 16, 0, 31)]; if (!classinheritancemultimap.isEmpty()) { @@ -761,7 +761,7 @@ public class RenderGlobal this.frustumUpdatePosChunkX = viewEntity.chunkCoordX; this.frustumUpdatePosChunkY = viewEntity.chunkCoordY; this.frustumUpdatePosChunkZ = viewEntity.chunkCoordZ; - this.viewFrustum.updateChunkPositions(viewEntity.posX, viewEntity.posZ); + this.viewFrustum.updateChunkPositions(viewEntity.posX, viewEntity.posY, viewEntity.posZ); } double d3 = viewEntity.lastTickPosX + (viewEntity.posX - viewEntity.lastTickPosX) * partialTicks; double d4 = viewEntity.lastTickPosY + (viewEntity.posY - viewEntity.lastTickPosY) * partialTicks; @@ -821,18 +821,21 @@ public class RenderGlobal else { // int i = blockpos1.getY() > 0 ? 248 : 8; - int i = blockpos1.getY() > 0 ? 504 : 8; +// int i = blockpos1.getY() > 0 ? 504 : 8; for (int j = -this.renderDistanceChunks; j <= this.renderDistanceChunks; ++j) { for (int k = -this.renderDistanceChunks; k <= this.renderDistanceChunks; ++k) { - RenderChunk renderchunk1 = this.viewFrustum.getRenderChunk(new BlockPos((j << 4) + 8, i, (k << 4) + 8)); - - if (renderchunk1 != null && Frustum.isInFrustum(renderchunk1.boundingBox)) + for (int i = -this.renderDistanceChunks; i <= this.renderDistanceChunks; ++i) { - renderchunk1.setFrameIndex(frameCount); - queue.add(new RenderGlobal.ContainerLocalRenderInformation(renderchunk1, (Facing)null, 0)); + RenderChunk renderchunk1 = this.viewFrustum.getRenderChunk(new BlockPos((j << 4) + 8, (i << 4) + 8, (k << 4) + 8)); + + if (renderchunk1 != null && Frustum.isInFrustum(renderchunk1.boundingBox)) + { + renderchunk1.setFrameIndex(frameCount); + queue.add(new RenderGlobal.ContainerLocalRenderInformation(renderchunk1, (Facing)null, 0)); + } } } } @@ -932,7 +935,7 @@ public class RenderGlobal private RenderChunk getRenderChunkOffset(BlockPos playerPos, RenderChunk renderChunkBase, Facing facing) { BlockPos blockpos = renderChunkBase.getBlockPosOffset16(facing); - return ExtMath.absi(playerPos.getX() - blockpos.getX()) > this.renderDistanceChunks * 16 ? null : (blockpos.getY() >= -World.MAX_SIZE_Y && blockpos.getY() < World.MAX_SIZE_Y ? (ExtMath.absi(playerPos.getZ() - blockpos.getZ()) > this.renderDistanceChunks * 16 ? null : this.viewFrustum.getRenderChunk(blockpos)) : null); + return ExtMath.absi(playerPos.getX() - blockpos.getX()) > this.renderDistanceChunks * 16 ? null : (ExtMath.absi(playerPos.getY() - blockpos.getY()) <= this.renderDistanceChunks * 16 ? (ExtMath.absi(playerPos.getZ() - blockpos.getZ()) > this.renderDistanceChunks * 16 ? null : this.viewFrustum.getRenderChunk(blockpos)) : null); } protected Vector3f getViewVector(Entity entityIn, double partialTicks) diff --git a/client/src/client/renderer/ViewFrustum.java b/client/src/client/renderer/ViewFrustum.java index df65bd6..a9a95af 100755 --- a/client/src/client/renderer/ViewFrustum.java +++ b/client/src/client/renderer/ViewFrustum.java @@ -58,13 +58,14 @@ public class ViewFrustum { int i = renderDistanceChunks * 2 + 1; this.countChunksX = i; - this.countChunksY = 32; + this.countChunksY = i; this.countChunksZ = i; } - public void updateChunkPositions(double viewEntityX, double viewEntityZ) + public void updateChunkPositions(double viewEntityX, double viewEntityY, double viewEntityZ) { int i = ExtMath.floord(viewEntityX) - 8; + int n = ExtMath.floord(viewEntityY) - 8; int j = ExtMath.floord(viewEntityZ) - 8; int k = this.countChunksX * 16; @@ -78,7 +79,7 @@ public class ViewFrustum for (int l1 = 0; l1 < this.countChunksY; ++l1) { - int i2 = l1 * 16; + int i2 = this.func_178157_a(n, k, l1); RenderChunk renderchunk = this.renderChunks[(j1 * this.countChunksY + l1) * this.countChunksX + l]; BlockPos blockpos = new BlockPos(i1, i2, k1); @@ -154,28 +155,28 @@ public class ViewFrustum int y = bucketInt(pos.getY()); int z = bucketInt(pos.getZ()); - if (y >= 0 && y < this.countChunksY) + x = x % this.countChunksX; + + if (x < 0) { - x = x % this.countChunksX; - - if (x < 0) - { - x += this.countChunksX; - } - - z = z % this.countChunksZ; - - if (z < 0) - { - z += this.countChunksZ; - } - - int p = (z * this.countChunksY + y) * this.countChunksX + x; - return this.renderChunks[p]; + x += this.countChunksX; } - else + + y = y % this.countChunksY; + + if (y < 0) { - return null; + y += this.countChunksY; } + + z = z % this.countChunksZ; + + if (z < 0) + { + z += this.countChunksZ; + } + + int p = (z * this.countChunksY + y) * this.countChunksX + x; + return this.renderChunks[p]; } } diff --git a/common/src/common/packet/SPacketChunkData.java b/common/src/common/packet/SPacketChunkData.java index 182f6b5..e7d94bc 100755 --- a/common/src/common/packet/SPacketChunkData.java +++ b/common/src/common/packet/SPacketChunkData.java @@ -128,7 +128,7 @@ public class SPacketChunkData implements Packet } extend = new int[list.size() - epos]; for(int z = 0; z < extend.length; z++) { - extend[z] = list.get(z + epos).getY(); + extend[z] = list.get(z + epos).getY() >> 4; } s21packetchunkdata$extracted.extend = extend; diff --git a/common/src/common/world/BlockArray.java b/common/src/common/world/BlockArray.java index 44fba70..effebfe 100755 --- a/common/src/common/world/BlockArray.java +++ b/common/src/common/world/BlockArray.java @@ -1,5 +1,7 @@ package common.world; +import java.util.Arrays; + import common.block.Block; import common.init.BlockRegistry; import common.init.Blocks; @@ -13,12 +15,17 @@ public class BlockArray { private NibbleArray blocklight; private NibbleArray skylight; - public BlockArray(int y, boolean sky) { + public BlockArray(int y, boolean sky, State filler) { this.yBase = y; this.data = new char[4096]; this.blocklight = new NibbleArray(); if(sky) this.skylight = new NibbleArray(); + if(filler != null && filler.getBlock() != Blocks.air) { + Arrays.fill(this.data, (char)BlockRegistry.STATEMAP.get(filler)); + this.blocks = this.data.length; + this.ticked = filler.getBlock().getTickRandomly() ? this.data.length : 0; + } } public State get(int x, int y, int z) { diff --git a/common/src/common/world/Chunk.java b/common/src/common/world/Chunk.java index 259a183..0228b27 100755 --- a/common/src/common/world/Chunk.java +++ b/common/src/common/world/Chunk.java @@ -81,7 +81,7 @@ public class Chunk { if(state != null && state.getBlock().getMaterial() != Material.air) { int y = by >> 4; if(this.blocks[y] == null) - this.blocks[y] = new BlockArray(y << 4, sky); + this.blocks[y] = new BlockArray(y << 4, sky, null); this.blocks[y].set(bx, by & 15, bz, state); } } @@ -89,7 +89,7 @@ public class Chunk { } if(base != null) { if(this.blocks[0] == null) - this.blocks[0] = new BlockArray(0, sky); + this.blocks[0] = new BlockArray(0, sky, null); for(int bx = 0; bx < 16; ++bx) { for(int bz = 0; bz < 16; ++bz) { for(int by = 0; by < 5; ++by) { @@ -102,10 +102,10 @@ public class Chunk { if(ceil != null) { int y = (height - 1) >> 4; if(this.blocks[y] == null) - this.blocks[y] = new BlockArray(y << 4, sky); + this.blocks[y] = new BlockArray(y << 4, sky, null); y = (height - 5) >> 4; if(this.blocks[y] == null) - this.blocks[y] = new BlockArray(y << 4, sky); + this.blocks[y] = new BlockArray(y << 4, sky, null); for(int bx = 0; bx < 16; ++bx) { for(int bz = 0; bz < 16; ++bz) { for(int by = height - 1; by >= height - 5; --by) { @@ -119,7 +119,7 @@ public class Chunk { this.biomes[n] = (byte)biomes[n].id; } this.bottom = height == 0 ? Integer.MAX_VALUE : 0; - this.top = height == 0 ? Integer.MIN_VALUE : (height + 15) >> 4; + this.top = height == 0 ? Integer.MIN_VALUE : ((height + 15) >> 4) << 4; if(ceil == null) this.genSkyLight(); else @@ -195,7 +195,7 @@ public class Chunk { } public BlockArray getArray(int y) { - return y >= 0 && y < this.blocks.length ? this.blocks[y] : (y < 0 ? (this.extendDown == null || -y > this.extendDown.length ? null : this.extendDown[-this.extendDown.length - y]) : (this.extendUp == null || y - this.blocks.length >= this.extendUp.length ? null : this.extendUp[y - this.blocks.length])); + return y >= 0 && y < this.blocks.length ? this.blocks[y] : (y < 0 ? (this.extendDown == null || -y > this.extendDown.length ? null : this.extendDown[this.extendDown.length + y]) : (this.extendUp == null || y - this.blocks.length >= this.extendUp.length ? null : this.extendUp[y - this.blocks.length])); } private void setArray(int y, BlockArray array) { @@ -211,7 +211,7 @@ public class Chunk { this.extendDown = new BlockArray[-y]; System.arraycopy(extendDown, 0, this.extendDown, -y - extendDown.length, extendDown.length); } - this.extendDown[-this.extendDown.length - y] = array; + this.extendDown[this.extendDown.length + y] = array; } else { if(this.extendUp == null) { @@ -480,7 +480,7 @@ public class Chunk { return stor != null ? stor.getBlock(x, y & 15, z) : Blocks.air; } else if(y < 0 && this.extendDown != null && -(y >> 4) <= this.extendDown.length) { - BlockArray stor = this.extendDown[-this.extendDown.length - (y >> 4)]; + BlockArray stor = this.extendDown[this.extendDown.length + (y >> 4)]; return stor != null ? stor.getBlock(x, y & 15, z) : this.fillerBlock; } else if(y >> 4 >= this.blocks.length && this.extendUp != null && (y >> 4) - this.blocks.length < this.extendUp.length) { @@ -501,7 +501,7 @@ public class Chunk { return stor != null ? stor.get(pos.getX() & 15, pos.getY() & 15, pos.getZ() & 15) : Blocks.air.getState(); } else if(pos.getY() < 0 && this.extendDown != null && -(pos.getY() >> 4) <= this.extendDown.length) { - BlockArray stor = this.extendDown[-this.extendDown.length - (pos.getY() >> 4)]; + BlockArray stor = this.extendDown[this.extendDown.length + (pos.getY() >> 4)]; return stor != null ? stor.get(pos.getX() & 15, pos.getY() & 15, pos.getZ() & 15) : this.filler; } else if(pos.getY() >> 4 >= this.blocks.length && this.extendUp != null && (pos.getY() >> 4) - this.blocks.length < this.extendUp.length) { @@ -538,11 +538,11 @@ public class Chunk { boolean up = false; if(stor == null) { - if(block == Blocks.air) { + if(block == Blocks.air && (y >= 0 || this.fillerBlock == Blocks.air)) { return null; } - stor = new BlockArray(y >> 4 << 4, !this.world.dimension.hasNoLight()); + stor = new BlockArray(y >> 4 << 4, !this.world.dimension.hasNoLight(), y < 0 ? this.filler : null); this.setArray(y >> 4, stor); up = y >= h; } @@ -631,7 +631,7 @@ public class Chunk { BlockArray stor = this.getArray(y >> 4); if(stor == null) { - stor = new BlockArray(y >> 4 << 4, !this.world.dimension.hasNoLight()); + stor = new BlockArray(y >> 4 << 4, !this.world.dimension.hasNoLight(), y < 0 ? this.filler : null); this.setArray(y >> 4, stor); this.genSkyLight(); } @@ -939,7 +939,7 @@ public class Chunk { for(int y = bottom; y <= top; y += 16) { BlockArray stor = this.getArray(y >> 4); - if(stor != null && !stor.isEmpty()) { + if(stor != null ? !stor.isEmpty() : (y < 0 && this.fillerBlock != Blocks.air)) { return false; } } @@ -970,7 +970,7 @@ public class Chunk { for(int n = 0; n < this.blocks.length; ++n) { if((update & 1 << n) != 0) { if(this.blocks[n] == null) { - this.blocks[n] = new BlockArray(n << 4, sky); + this.blocks[n] = new BlockArray(n << 4, sky, null); } char[] blocks = this.blocks[n].getData(); @@ -991,7 +991,8 @@ public class Chunk { for(int cy : extend) { BlockArray arr = this.getArray(cy); if(arr == null) { - arr = new BlockArray(cy << 4, sky); + arr = new BlockArray(cy << 4, sky, null); + this.setArray(cy, arr); } char[] blocks = arr.getData(); @@ -1111,11 +1112,11 @@ public class Chunk { for(int n = 0; n < 8; ++n) { if(this.top == Integer.MIN_VALUE) return; - int h = 1 + this.top - this.bottom; + int h = 1 + (this.top >> 4) - (this.bottom >> 4); if(this.lightChecks >= 256 * h) return; - int s = (this.lightChecks % h) + this.bottom; + int s = (this.lightChecks % h) + (this.bottom >> 4); int x = this.lightChecks / h % 16; int z = this.lightChecks / 512; ++this.lightChecks; diff --git a/server/src/server/world/Region.java b/server/src/server/world/Region.java index 21618b4..41e874d 100755 --- a/server/src/server/world/Region.java +++ b/server/src/server/world/Region.java @@ -392,7 +392,7 @@ public class Region { for(int n = 0; n < sects.tagCount(); ++n) { NBTTagCompound sect = sects.getCompoundTagAt(n); int y = sect.getInteger("Y"); - BlockArray storage = new BlockArray(y << 4, light); + BlockArray storage = new BlockArray(y << 4, light, null); byte[] blocks = sect.getByteArray("Blocks"); NibbleArray data = new NibbleArray(sect.getByteArray("Data")); NibbleArray adddata = sect.hasKey("Add", 7) ? new NibbleArray(sect.getByteArray("Add")) : null; @@ -417,7 +417,7 @@ public class Region { if(y >= 0 && y < stor) sections[y] = storage; else if(y < 0) - down[-down.length - y] = storage; + down[down.length + y] = storage; else up[y - stor] = storage; } @@ -510,8 +510,8 @@ public class Region { tag.setBoolean("LightPopulated", chunk.isLightPopulated()); tag.setLong("InhabitedTime", chunk.getInhabited()); BlockArray[] sections = chunk.getStorage(); - BlockArray[] down = chunk.getStorage(); - BlockArray[] up = chunk.getStorage(); + BlockArray[] down = chunk.getStorageDown(); + BlockArray[] up = chunk.getStorageUp(); NBTTagList sects = new NBTTagList(); boolean light = !world.dimension.hasNoLight(); From c62e3386aabc50d756616b71790476486f9ffd13 Mon Sep 17 00:00:00 2001 From: Sen Date: Wed, 21 May 2025 12:08:58 +0200 Subject: [PATCH 050/200] change entity kill height --- common/src/common/entity/Entity.java | 2 +- common/src/common/entity/item/EntityCart.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/common/src/common/entity/Entity.java b/common/src/common/entity/Entity.java index 59c59a1..4b351fa 100755 --- a/common/src/common/entity/Entity.java +++ b/common/src/common/entity/Entity.java @@ -346,7 +346,7 @@ public abstract class Entity this.setOnFireFromMolten(); } - if (this.posY < -64.0D) + if (this.posY < (double)(-World.MAX_SIZE_Y)) { this.onVoidUpdate(); } diff --git a/common/src/common/entity/item/EntityCart.java b/common/src/common/entity/item/EntityCart.java index a9222fe..bf376a3 100755 --- a/common/src/common/entity/item/EntityCart.java +++ b/common/src/common/entity/item/EntityCart.java @@ -242,7 +242,7 @@ public abstract class EntityCart extends Entity implements IWorldNameable this.setDamage(this.getDamage() - 1); } - if (this.posY < -64.0D) + if (this.posY < (double)(-World.MAX_SIZE_Y)) { this.onVoidUpdate(); } From 7b6cff41c5597d206785378a49dcf53576af42fd Mon Sep 17 00:00:00 2001 From: Sen Date: Wed, 21 May 2025 12:15:13 +0200 Subject: [PATCH 051/200] fix bottom filler --- server/src/server/world/WorldServer.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/server/src/server/world/WorldServer.java b/server/src/server/world/WorldServer.java index b6270ec..e22fba9 100755 --- a/server/src/server/world/WorldServer.java +++ b/server/src/server/world/WorldServer.java @@ -422,7 +422,7 @@ public final class WorldServer extends AWorldServer { this.caveGen = this.createCaveGenerator(); this.bigCaveGen = this.createBigCaveGenerator(); this.ravineGen = this.createRavineGenerator(); - this.base = this.dimension.getWorldFloor(); + this.base = this.dimension.getFiller().getBlock() == Blocks.air ? null : this.dimension.getFiller(); this.ceil = this.dimension.getWorldCeiling(); this.mobs = this.dimension.hasMobs(); this.snow = this.dimension.hasSnow(); @@ -1745,7 +1745,7 @@ public final class WorldServer extends AWorldServer { this.replacer = null; this.populate = false; this.liquid = Blocks.air.getState(); - this.base = Blocks.air.getState(); + this.base = null; this.ceil = null; this.height = this.generator.getMaximumHeight(); this.seaLevel = this.dimension.getSeaLevel(); From 26c71df5427b1f89fd2ab7bcad6ad623cf124b3e Mon Sep 17 00:00:00 2001 From: Sen Date: Wed, 21 May 2025 13:51:51 +0200 Subject: [PATCH 052/200] misc fixes, rendering --- client/src/client/Client.java | 2 +- common/src/common/world/Chunk.java | 11 ++++++----- common/src/common/world/World.java | 2 +- 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/client/src/client/Client.java b/client/src/client/Client.java index 9922f2d..9ae4f1f 100755 --- a/client/src/client/Client.java +++ b/client/src/client/Client.java @@ -1753,7 +1753,7 @@ public class Client implements IThreadListener { + String.format("%.3f", this.world.getCelestialAngle(1.0f)); } - float temp = this.world.getTempOffset() + (biome != null ? biome.getTemperature(blockpos) : 0.0f); + float temp = Math.max(this.world.getTempOffset() + (biome != null ? biome.getTemperature(blockpos) : 0.0f), 0.0f); long ticked = System.currentTimeMillis() - this.lastTicked; return diff --git a/common/src/common/world/Chunk.java b/common/src/common/world/Chunk.java index 0228b27..c4cfd85 100755 --- a/common/src/common/world/Chunk.java +++ b/common/src/common/world/Chunk.java @@ -683,6 +683,11 @@ public class Chunk { int y = ExtMath.floord(entity.posY / 16.0D); + entity.addedToChunk = true; + entity.chunkCoordX = this.xPos; + entity.chunkCoordY = y; + entity.chunkCoordZ = this.zPos; + if(y < 0) { y = 0; } @@ -690,11 +695,7 @@ public class Chunk { if(y >= this.entities.length) { y = this.entities.length - 1; } - - entity.addedToChunk = true; - entity.chunkCoordX = this.xPos; - entity.chunkCoordY = y; - entity.chunkCoordZ = this.zPos; + this.entities[y].add(entity); } diff --git a/common/src/common/world/World.java b/common/src/common/world/World.java index 6d991e3..869fcc4 100755 --- a/common/src/common/world/World.java +++ b/common/src/common/world/World.java @@ -1562,7 +1562,7 @@ public abstract class World implements IWorldAccess { } public float getTemperatureK(BlockPos pos) { - return this.temp + this.getBiomeGenForCoords(pos).getTemperature(pos); + return Math.max(this.temp + this.getBiomeGenForCoords(pos).getTemperature(pos), 0.0f); } public float getTemperatureC(BlockPos pos) { From 5e2b36dc828e519f64632a64a671a961bf732d0e Mon Sep 17 00:00:00 2001 From: Sen Date: Wed, 21 May 2025 14:31:29 +0200 Subject: [PATCH 053/200] fix chunk y rendering --- client/src/client/renderer/RenderGlobal.java | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/client/src/client/renderer/RenderGlobal.java b/client/src/client/renderer/RenderGlobal.java index 39b65cc..07a6f6a 100755 --- a/client/src/client/renderer/RenderGlobal.java +++ b/client/src/client/renderer/RenderGlobal.java @@ -752,6 +752,7 @@ public class RenderGlobal double d0 = viewEntity.posX - this.frustumUpdatePosX; double d1 = viewEntity.posY - this.frustumUpdatePosY; double d2 = viewEntity.posZ - this.frustumUpdatePosZ; + int prev = this.frustumUpdatePosChunkY; if (this.frustumUpdatePosChunkX != viewEntity.chunkCoordX || this.frustumUpdatePosChunkY != viewEntity.chunkCoordY || this.frustumUpdatePosChunkZ != viewEntity.chunkCoordZ || d0 * d0 + d1 * d1 + d2 * d2 > 16.0D) { @@ -904,6 +905,24 @@ public class RenderGlobal } this.chunksToUpdate.addAll(set); + + if(prev != Integer.MIN_VALUE && viewEntity.chunkCoordY != prev) { + for (int j = -this.renderDistanceChunks; j <= this.renderDistanceChunks; ++j) + { + for (int k = -this.renderDistanceChunks; k <= this.renderDistanceChunks; ++k) + { + for (int i = -this.renderDistanceChunks; i <= this.renderDistanceChunks; ++i) + { + RenderChunk renderchunk1 = this.viewFrustum.getRenderChunk(new BlockPos((j << 4) + 8, (i << 4) + 8, (k << 4) + 8)); + + if (renderchunk1 != null) + { + renderchunk1.setNeedsUpdate(true); + } + } + } + } + } } private boolean isPositionInRenderChunk(BlockPos pos, RenderChunk renderChunkIn) From 2dd83c61dc3fdd22e8747e478aef16a09db46a25 Mon Sep 17 00:00:00 2001 From: Sen Date: Wed, 21 May 2025 15:31:50 +0200 Subject: [PATCH 054/200] make chunk storage a map --- client/src/client/network/ClientPlayer.java | 6 +- client/src/client/world/EmptyChunk.java | 2 +- .../src/common/packet/SPacketChunkData.java | 64 ++--- .../common/packet/SPacketMapChunkBulk.java | 13 +- common/src/common/world/BlockArray.java | 8 + common/src/common/world/Chunk.java | 239 +++++------------- server/src/server/network/Player.java | 2 +- server/src/server/world/Region.java | 111 ++++---- server/src/server/world/WorldServer.java | 27 +- 9 files changed, 144 insertions(+), 328 deletions(-) diff --git a/client/src/client/network/ClientPlayer.java b/client/src/client/network/ClientPlayer.java index ebea694..3a6b688 100755 --- a/client/src/client/network/ClientPlayer.java +++ b/client/src/client/network/ClientPlayer.java @@ -756,7 +756,7 @@ public class ClientPlayer extends NetHandler implements IClientPlayer if (packetIn.hasBiomes()) { - if (packetIn.getExtractedSize() == 0) + if (packetIn.getExtractedExtend().length == 0) { this.clientWorldController.doPreChunk(packetIn.getChunkX(), packetIn.getChunkZ(), false); return; @@ -767,7 +767,7 @@ public class ClientPlayer extends NetHandler implements IClientPlayer // this.clientWorldController.invalidateBlockReceiveRegion(packetIn.getChunkX() << 4, 0, packetIn.getChunkZ() << 4, (packetIn.getChunkX() << 4) + 15, 512, (packetIn.getChunkZ() << 4) + 15); Chunk chunk = this.clientWorldController.getChunk(packetIn.getChunkX(), packetIn.getChunkZ()); - chunk.setData(packetIn.getExtractedDataBytes(), packetIn.getExtractedSize(), packetIn.getExtractedExtend(), packetIn.hasBiomes()); + chunk.setData(packetIn.getExtractedDataBytes(), packetIn.getExtractedExtend(), packetIn.hasBiomes()); this.clientWorldController.markBlockRangeForRenderUpdate(packetIn.getChunkX() << 4, -World.MAX_SIZE_Y, packetIn.getChunkZ() << 4, (packetIn.getChunkX() << 4) + 15, World.MAX_SIZE_Y, (packetIn.getChunkZ() << 4) + 15); if (!packetIn.hasBiomes() || this.clientWorldController.dimension.hasNoLight()) // TODO: check @@ -1413,7 +1413,7 @@ public class ClientPlayer extends NetHandler implements IClientPlayer this.clientWorldController.doPreChunk(j, k, true); // this.clientWorldController.invalidateBlockReceiveRegion(j << 4, 0, k << 4, (j << 4) + 15, 512, (k << 4) + 15); Chunk chunk = this.clientWorldController.getChunk(j, k); - chunk.setData(packetIn.getChunkBytes(i), packetIn.getChunkSize(i), packetIn.getChunkExtend(i), true); + chunk.setData(packetIn.getChunkBytes(i), packetIn.getChunkExtend(i), true); this.clientWorldController.markBlockRangeForRenderUpdate(j << 4, -World.MAX_SIZE_Y, k << 4, (j << 4) + 15, World.MAX_SIZE_Y, (k << 4) + 15); if (this.clientWorldController.dimension.hasNoLight()) // TODO: check diff --git a/client/src/client/world/EmptyChunk.java b/client/src/client/world/EmptyChunk.java index c60a7ee..24ded26 100755 --- a/client/src/client/world/EmptyChunk.java +++ b/client/src/client/world/EmptyChunk.java @@ -105,7 +105,7 @@ public class EmptyChunk extends Chunk { return true; } - public void setData(byte[] data, int update, int[] extend, boolean biomes) { + public void setData(byte[] data, int[] extend, boolean biomes) { } public Biome getBiome(BlockPos pos, BiomeGenerator gen) { diff --git a/common/src/common/packet/SPacketChunkData.java b/common/src/common/packet/SPacketChunkData.java index e7d94bc..ee87912 100755 --- a/common/src/common/packet/SPacketChunkData.java +++ b/common/src/common/packet/SPacketChunkData.java @@ -2,6 +2,7 @@ package common.packet; import java.io.IOException; import java.util.List; +import java.util.Set; import common.collect.Lists; import common.network.IClientPlayer; @@ -21,12 +22,12 @@ public class SPacketChunkData implements Packet { } - public SPacketChunkData(Chunk chunkIn, boolean biomes, int segUpdate, int[] extend) + public SPacketChunkData(Chunk chunkIn, boolean biomes, int[] extend) { this.chunkX = chunkIn.xPos; this.chunkZ = chunkIn.zPos; this.biomes = biomes; - this.extractedData = getExtractedData(chunkIn, biomes, !chunkIn.getWorld().dimension.hasNoLight(), segUpdate, extend); + this.extractedData = getExtractedData(chunkIn, biomes, !chunkIn.getWorld().dimension.hasNoLight(), extend); } /** @@ -38,7 +39,6 @@ public class SPacketChunkData implements Packet this.chunkZ = buf.readInt(); this.biomes = buf.readBoolean(); this.extractedData = new SPacketChunkData.Extracted(); - this.extractedData.dataSize = buf.readInt(); this.extractedData.data = buf.readByteArray(); this.extractedData.extend = new int[buf.readVarIntFromBuffer()]; for(int z = 0; z < this.extractedData.extend.length; z++) { @@ -54,7 +54,6 @@ public class SPacketChunkData implements Packet buf.writeInt(this.chunkX); buf.writeInt(this.chunkZ); buf.writeBoolean(this.biomes); - buf.writeInt(this.extractedData.dataSize); buf.writeByteArray(this.extractedData.data); buf.writeVarIntToBuffer(this.extractedData.extend.length); for(int z = 0; z < this.extractedData.extend.length; z++) { @@ -84,55 +83,32 @@ public class SPacketChunkData implements Packet return i + j + k + l; } - public static SPacketChunkData.Extracted getExtractedData(Chunk chunk, boolean biomes, boolean overworld, int segUpdate, int[] extend) + public static SPacketChunkData.Extracted getExtractedData(Chunk chunk, boolean biomes, boolean overworld, int[] extend) { - BlockArray[] aextendedblockstorage = chunk.getStorage(); - BlockArray[] down = chunk.getStorageDown(); - BlockArray[] up = chunk.getStorageUp(); + Set aextendedblockstorage = chunk.getStorage(); SPacketChunkData.Extracted s21packetchunkdata$extracted = new SPacketChunkData.Extracted(); List list = Lists.newArrayList(); - - for (int i = 0; i < aextendedblockstorage.length; ++i) - { - BlockArray extendedblockstorage = aextendedblockstorage[i]; - - if (extendedblockstorage != null && (!biomes || !extendedblockstorage.isEmpty()) && (segUpdate & 1 << i) != 0) - { - s21packetchunkdata$extracted.dataSize |= 1 << i; - list.add(extendedblockstorage); - } - } - int epos = list.size(); + if(extend == null) { - if(down != null) { - for(BlockArray arr : down) { - if(arr != null && (!biomes || !arr.isEmpty())) - list.add(arr); - } - } - if(up != null) { - for(BlockArray arr : up) { - if(arr != null && (!biomes || !arr.isEmpty())) - list.add(arr); - } - } + for(BlockArray arr : aextendedblockstorage) { + if(arr != null && (!biomes || !arr.isEmpty())) + list.add(arr); + } } else { for(int cy : extend) { - if(cy < 0 || cy >= aextendedblockstorage.length) { - BlockArray arr = chunk.getArray(cy); - if(arr != null && (!biomes || !arr.isEmpty())) - list.add(arr); - } + BlockArray arr = chunk.getArray(cy); + if(arr != null && (!biomes || !arr.isEmpty())) + list.add(arr); } } - extend = new int[list.size() - epos]; + extend = new int[list.size()]; for(int z = 0; z < extend.length; z++) { - extend[z] = list.get(z + epos).getY() >> 4; + extend[z] = list.get(z).getY() >> 4; } s21packetchunkdata$extracted.extend = extend; - s21packetchunkdata$extracted.data = new byte[getSize(Integer.bitCount(s21packetchunkdata$extracted.dataSize) + extend.length, overworld, biomes)]; + s21packetchunkdata$extracted.data = new byte[getSize(extend.length, overworld, biomes)]; int j = 0; for (BlockArray extendedblockstorage1 : list) @@ -182,12 +158,7 @@ public class SPacketChunkData implements Packet { return this.chunkZ; } - - public int getExtractedSize() - { - return this.extractedData.dataSize; - } - + public int[] getExtractedExtend() { return this.extractedData.extend; @@ -201,7 +172,6 @@ public class SPacketChunkData implements Packet public static class Extracted { public byte[] data; - public int dataSize; public int[] extend; } } diff --git a/common/src/common/packet/SPacketMapChunkBulk.java b/common/src/common/packet/SPacketMapChunkBulk.java index f83bc61..4c7c4bb 100755 --- a/common/src/common/packet/SPacketMapChunkBulk.java +++ b/common/src/common/packet/SPacketMapChunkBulk.java @@ -30,7 +30,7 @@ public class SPacketMapChunkBulk implements Packet for (int j = 0; j < i; ++j) { Chunk chunk = (Chunk)chunks.get(j); - SPacketChunkData.Extracted s21packetchunkdata$extracted = SPacketChunkData.getExtractedData(chunk, true, this.isOverworld, 0xffffffff, null); + SPacketChunkData.Extracted s21packetchunkdata$extracted = SPacketChunkData.getExtractedData(chunk, true, this.isOverworld, null); this.xPositions[j] = chunk.xPos; this.zPositions[j] = chunk.zPos; this.chunksData[j] = s21packetchunkdata$extracted; @@ -53,12 +53,11 @@ public class SPacketMapChunkBulk implements Packet this.xPositions[j] = buf.readInt(); this.zPositions[j] = buf.readInt(); this.chunksData[j] = new SPacketChunkData.Extracted(); - this.chunksData[j].dataSize = buf.readInt(); this.chunksData[j].extend = new int[buf.readVarIntFromBuffer()]; for(int z = 0; z < this.chunksData[j].extend.length; z++) { this.chunksData[j].extend[z] = buf.readVarIntFromBuffer(); } - this.chunksData[j].data = new byte[SPacketChunkData.getSize(Integer.bitCount(this.chunksData[j].dataSize) + this.chunksData[j].extend.length, this.isOverworld, true)]; + this.chunksData[j].data = new byte[SPacketChunkData.getSize(this.chunksData[j].extend.length, this.isOverworld, true)]; } for (int k = 0; k < i; ++k) @@ -79,7 +78,6 @@ public class SPacketMapChunkBulk implements Packet { buf.writeInt(this.xPositions[i]); buf.writeInt(this.zPositions[i]); - buf.writeInt(this.chunksData[i].dataSize); buf.writeVarIntToBuffer(this.chunksData[i].extend.length); for(int z = 0; z < this.chunksData[i].extend.length; z++) { buf.writeVarIntToBuffer(this.chunksData[i].extend[z]); @@ -119,12 +117,7 @@ public class SPacketMapChunkBulk implements Packet { return this.chunksData[p_149256_1_].data; } - - public int getChunkSize(int p_179754_1_) - { - return this.chunksData[p_179754_1_].dataSize; - } - + public int[] getChunkExtend(int index) { return this.chunksData[index].extend; diff --git a/common/src/common/world/BlockArray.java b/common/src/common/world/BlockArray.java index effebfe..12dd515 100755 --- a/common/src/common/world/BlockArray.java +++ b/common/src/common/world/BlockArray.java @@ -127,4 +127,12 @@ public class BlockArray { public void setSkylight(NibbleArray data) { this.skylight = data; } + + public int hashCode() { + return this.yBase >> 4; + } + + public boolean equals(Object other) { + return other instanceof BlockArray && ((BlockArray)other).yBase == this.yBase; + } } diff --git a/common/src/common/world/Chunk.java b/common/src/common/world/Chunk.java index c4cfd85..6e6156c 100755 --- a/common/src/common/world/Chunk.java +++ b/common/src/common/world/Chunk.java @@ -3,6 +3,7 @@ package common.world; import java.util.Arrays; import java.util.List; import java.util.Map; +import java.util.Set; import java.util.concurrent.ConcurrentLinkedQueue; import java.util.function.Predicate; @@ -10,6 +11,7 @@ import common.biome.Biome; import common.block.Block; import common.block.ITileEntityProvider; import common.collect.Maps; +import common.collect.Sets; import common.entity.Entity; import common.init.BlockRegistry; import common.init.Blocks; @@ -23,6 +25,7 @@ import common.util.ChunkPos; import common.util.ClassInheritanceMultiMap; import common.util.ExtMath; import common.util.Facing; +import common.util.IntHashMap; import common.util.NibbleArray; import common.worldgen.BiomeGenerator; import common.worldgen.DebugStates; @@ -33,7 +36,8 @@ public class Chunk { private final World world; private final State filler; private final Block fillerBlock; - private final BlockArray[] blocks = new BlockArray[32]; + private final IntHashMap blocks = new IntHashMap(); + private final Set blockList = Sets.newHashSet(); private final byte[] biomes = new byte[256]; private final int[] precHeight = new int[256]; private final boolean[] updateSky = new boolean[256]; @@ -55,8 +59,6 @@ public class Chunk { private int top = Integer.MIN_VALUE; private long lastSave; private long inhabited; - private BlockArray[] extendDown; - private BlockArray[] extendUp; public Chunk(World world, int x, int z) { this.world = world; @@ -80,37 +82,49 @@ public class Chunk { State state = BlockRegistry.STATEMAP.getByValue(data[bx << 4 | bz | by << 8]); if(state != null && state.getBlock().getMaterial() != Material.air) { int y = by >> 4; - if(this.blocks[y] == null) - this.blocks[y] = new BlockArray(y << 4, sky, null); - this.blocks[y].set(bx, by & 15, bz, state); + BlockArray arr = this.getArray(y); + if(arr == null) { + arr = new BlockArray(y << 4, sky, null); + this.setArray(arr); + } + arr.set(bx, by & 15, bz, state); } } } } if(base != null) { - if(this.blocks[0] == null) - this.blocks[0] = new BlockArray(0, sky, null); + BlockArray arr = this.getArray(0); + if(arr == null) { + arr = new BlockArray(0, sky, null); + this.setArray(arr); + } for(int bx = 0; bx < 16; ++bx) { for(int bz = 0; bz < 16; ++bz) { for(int by = 0; by < 5; ++by) { if(by <= rand.zrange(5)) - this.blocks[0].set(bx, by, bz, base); + arr.set(bx, by, bz, base); } } } } if(ceil != null) { int y = (height - 1) >> 4; - if(this.blocks[y] == null) - this.blocks[y] = new BlockArray(y << 4, sky, null); + BlockArray arr = this.getArray(y); + if(arr == null) { + arr = new BlockArray(y << 4, sky, null); + this.setArray(arr); + } y = (height - 5) >> 4; - if(this.blocks[y] == null) - this.blocks[y] = new BlockArray(y << 4, sky, null); + arr = this.getArray(y); + if(arr == null) { + arr = new BlockArray(y << 4, sky, null); + this.setArray(arr); + } for(int bx = 0; bx < 16; ++bx) { for(int bz = 0; bz < 16; ++bz) { for(int by = height - 1; by >= height - 5; --by) { if(by >= (height - 1) - rand.zrange(5)) - this.blocks[by >> 4].set(bx, by & 15, bz, ceil); + this.getArray(by >> 4).set(bx, by & 15, bz, ceil); } } } @@ -133,47 +147,7 @@ public class Chunk { public int getHeight(int x, int z) { return this.height[z << 4 | x]; } - - private int findTopSegment() { - if(this.extendUp != null) { - for(int y = this.extendUp.length - 1; y >= 0; --y) { - if(this.extendUp[y] != null) - return this.extendUp[y].getY(); - } - } - for(int y = this.blocks.length - 1; y >= 0; --y) { - if(this.blocks[y] != null) - return this.blocks[y].getY(); - } - if(this.extendDown != null) { - for(int y = this.extendDown.length - 1; y >= 0; --y) { - if(this.extendDown[y] != null) - return this.extendDown[y].getY(); - } - } - return Integer.MIN_VALUE; - } - - private int findBottomSegment() { - if(this.extendDown != null) { - for(int y = 0; y < this.extendDown.length; ++y) { - if(this.extendDown[y] != null) - return this.extendDown[y].getY(); - } - } - for(int y = 0; y < this.blocks.length; ++y) { - if(this.blocks[y] != null) - return this.blocks[y].getY(); - } - if(this.extendUp != null) { - for(int y = 0; y < this.extendUp.length; ++y) { - if(this.extendUp[y] != null) - return this.extendUp[y].getY(); - } - } - return Integer.MAX_VALUE; - } - + public int getTopSegment() { return this.top; } @@ -182,50 +156,28 @@ public class Chunk { return this.bottom; } - public BlockArray[] getStorage() { - return this.blocks; - } - - public BlockArray[] getStorageDown() { - return this.extendDown; - } - - public BlockArray[] getStorageUp() { - return this.extendUp; + public Set getStorage() { + return this.blockList; } public BlockArray getArray(int y) { - return y >= 0 && y < this.blocks.length ? this.blocks[y] : (y < 0 ? (this.extendDown == null || -y > this.extendDown.length ? null : this.extendDown[this.extendDown.length + y]) : (this.extendUp == null || y - this.blocks.length >= this.extendUp.length ? null : this.extendUp[y - this.blocks.length])); + return this.blocks.lookup(y); } - private void setArray(int y, BlockArray array) { - if(y >= 0 && y < this.blocks.length) { - this.blocks[y] = array; - } - else if(y < 0) { - if(this.extendDown == null) { - this.extendDown = new BlockArray[-y]; - } - else if(this.extendDown.length < -y) { - BlockArray[] extendDown = this.extendDown; - this.extendDown = new BlockArray[-y]; - System.arraycopy(extendDown, 0, this.extendDown, -y - extendDown.length, extendDown.length); - } - this.extendDown[this.extendDown.length + y] = array; - } - else { - if(this.extendUp == null) { - this.extendUp = new BlockArray[1 + y - this.blocks.length]; - } - else if(this.extendUp.length <= y - this.blocks.length) { - BlockArray[] extendUp = this.extendUp; - this.extendUp = new BlockArray[1 + y - this.blocks.length]; - System.arraycopy(extendUp, 0, this.extendUp, 0, extendUp.length); - } - this.extendUp[y - this.blocks.length] = array; - } - this.bottom = this.findBottomSegment(); - this.top = this.findTopSegment(); + private void setArray(BlockArray array) { + int y = array.getY() >> 4; + this.blocks.addKey(y, array); + this.blockList.add(array); + y <<= 4; + this.bottom = y < this.bottom ? y : this.bottom; + this.top = y > this.top ? y : this.top; + } + + private void clearArrays() { + this.blocks.clearMap(); + this.blockList.clear(); + this.bottom = Integer.MAX_VALUE; + this.top = Integer.MIN_VALUE; } protected void genHeights() { @@ -475,19 +427,8 @@ public class Chunk { } private Block getBlock0(int x, int y, int z) { - if(y >= 0 && y >> 4 < this.blocks.length) { - BlockArray stor = this.blocks[y >> 4]; - return stor != null ? stor.getBlock(x, y & 15, z) : Blocks.air; - } - else if(y < 0 && this.extendDown != null && -(y >> 4) <= this.extendDown.length) { - BlockArray stor = this.extendDown[this.extendDown.length + (y >> 4)]; - return stor != null ? stor.getBlock(x, y & 15, z) : this.fillerBlock; - } - else if(y >> 4 >= this.blocks.length && this.extendUp != null && (y >> 4) - this.blocks.length < this.extendUp.length) { - BlockArray stor = this.extendUp[(y >> 4) - this.blocks.length]; - return stor != null ? stor.getBlock(x, y & 15, z) : Blocks.air; - } - return y < 0 ? this.fillerBlock : Blocks.air; + BlockArray stor = this.getArray(y >> 4); + return stor != null ? stor.getBlock(x, y & 15, z) : (y < 0 ? this.fillerBlock : Blocks.air); } public State getState(BlockPos pos) { @@ -496,19 +437,8 @@ public class Chunk { return state == null ? Blocks.air.getState() : state; } - if(pos.getY() >= 0 && pos.getY() >> 4 < this.blocks.length) { - BlockArray stor = this.blocks[pos.getY() >> 4]; - return stor != null ? stor.get(pos.getX() & 15, pos.getY() & 15, pos.getZ() & 15) : Blocks.air.getState(); - } - else if(pos.getY() < 0 && this.extendDown != null && -(pos.getY() >> 4) <= this.extendDown.length) { - BlockArray stor = this.extendDown[this.extendDown.length + (pos.getY() >> 4)]; - return stor != null ? stor.get(pos.getX() & 15, pos.getY() & 15, pos.getZ() & 15) : this.filler; - } - else if(pos.getY() >> 4 >= this.blocks.length && this.extendUp != null && (pos.getY() >> 4) - this.blocks.length < this.extendUp.length) { - BlockArray stor = this.extendUp[(pos.getY() >> 4) - this.blocks.length]; - return stor != null ? stor.get(pos.getX() & 15, pos.getY() & 15, pos.getZ() & 15) : Blocks.air.getState(); - } - return pos.getY() < 0 ? this.filler : Blocks.air.getState(); + BlockArray stor = this.getArray(pos.getY() >> 4); + return stor != null ? stor.get(pos.getX() & 15, pos.getY() & 15, pos.getZ() & 15) : (pos.getY() < 0 ? this.filler : Blocks.air.getState()); } public Block getBlock(BlockPos pos) { @@ -543,7 +473,7 @@ public class Chunk { } stor = new BlockArray(y >> 4 << 4, !this.world.dimension.hasNoLight(), y < 0 ? this.filler : null); - this.setArray(y >> 4, stor); + this.setArray(stor); up = y >= h; } @@ -632,7 +562,7 @@ public class Chunk { if(stor == null) { stor = new BlockArray(y >> 4 << 4, !this.world.dimension.hasNoLight(), y < 0 ? this.filler : null); - this.setArray(y >> 4, stor); + this.setArray(stor); this.genSkyLight(); } @@ -948,52 +878,24 @@ public class Chunk { return true; } - public void setStorage(BlockArray[] arrays, BlockArray[] down, BlockArray[] up) { - if(this.blocks.length != arrays.length) { - Log.JNI.warn("Konnte Sektionen des Chunks nicht setzen, Länge des Arrays ist " + arrays.length + " statt " - + this.blocks.length); - } - else { - for(int n = 0; n < this.blocks.length; ++n) { - this.blocks[n] = arrays[n]; - } - this.extendDown = down; - this.extendUp = up; - this.bottom = this.findBottomSegment(); - this.top = this.findTopSegment(); + public void setStorage(BlockArray[] data) { + for(BlockArray arr : data) { + this.setArray(arr); } } - public void setData(byte[] data, int update, int[] extend, boolean biomes) { + public void setData(byte[] data, int[] extend, boolean biomes) { int pos = 0; boolean sky = !this.world.dimension.hasNoLight(); - - for(int n = 0; n < this.blocks.length; ++n) { - if((update & 1 << n) != 0) { - if(this.blocks[n] == null) { - this.blocks[n] = new BlockArray(n << 4, sky, null); - } - - char[] blocks = this.blocks[n].getData(); - - for(int k = 0; k < blocks.length; ++k) { - blocks[k] = (char)((data[pos + 1] & 255) << 8 | data[pos] & 255); - pos += 2; - } - } - else if(biomes && this.blocks[n] != null) { - this.blocks[n] = null; - } - } + if(biomes) { - this.extendDown = null; - this.extendUp = null; + this.clearArrays(); } for(int cy : extend) { BlockArray arr = this.getArray(cy); if(arr == null) { arr = new BlockArray(cy << 4, sky, null); - this.setArray(cy, arr); + this.setArray(arr); } char[] blocks = arr.getData(); @@ -1004,13 +906,6 @@ public class Chunk { } } - for(int n = 0; n < this.blocks.length; ++n) { - if((update & 1 << n) != 0 && this.blocks[n] != null) { - NibbleArray light = this.blocks[n].getBlocklight(); - System.arraycopy(data, pos, light.getData(), 0, light.getData().length); - pos += light.getData().length; - } - } for(int cy : extend) { BlockArray arr = this.getArray(cy); if(arr != null) { @@ -1021,13 +916,6 @@ public class Chunk { } if(sky) { - for(int n = 0; n < this.blocks.length; ++n) { - if((update & 1 << n) != 0 && this.blocks[n] != null) { - NibbleArray slight = this.blocks[n].getSkylight(); - System.arraycopy(data, pos, slight.getData(), 0, slight.getData().length); - pos += slight.getData().length; - } - } for(int cy : extend) { BlockArray arr = this.getArray(cy); if(arr != null) { @@ -1040,17 +928,8 @@ public class Chunk { if(biomes) { System.arraycopy(data, pos, this.biomes, 0, this.biomes.length); -// int unk = pos + this.biomes.length; } - this.bottom = this.findBottomSegment(); - this.top = this.findTopSegment(); - - for(int n = 0; n < this.blocks.length; ++n) { - if(this.blocks[n] != null && (update & 1 << n) != 0) { - this.blocks[n].update(); - } - } for(int cy : extend) { BlockArray arr = this.getArray(cy); if(arr != null) { diff --git a/server/src/server/network/Player.java b/server/src/server/network/Player.java index 3377336..a185bbc 100755 --- a/server/src/server/network/Player.java +++ b/server/src/server/network/Player.java @@ -985,7 +985,7 @@ public class Player extends NetHandler implements ICrafting, Executor, IPlayer { if (list.size() == 1) { - this.sendPacket(new SPacketChunkData((Chunk)list.get(0), true, 0xffffffff, null)); + this.sendPacket(new SPacketChunkData((Chunk)list.get(0), true, null)); } else { diff --git a/server/src/server/world/Region.java b/server/src/server/world/Region.java index 41e874d..0753655 100755 --- a/server/src/server/world/Region.java +++ b/server/src/server/world/Region.java @@ -14,6 +14,7 @@ import java.util.Collections; import java.util.Iterator; import java.util.List; import java.util.Map; +import java.util.Set; import java.util.zip.DeflaterOutputStream; import java.util.zip.InflaterInputStream; @@ -375,18 +376,7 @@ public class Region { chunk.setLightPopulated(tag.getBoolean("LightPopulated")); chunk.setInhabited(tag.getLong("InhabitedTime")); NBTTagList sects = tag.getTagList("Sections", 10); - int stor = 32; - int min = 0; - int max = stor - 1; - for(int n = 0; n < sects.tagCount(); ++n) { - NBTTagCompound sect = sects.getCompoundTagAt(n); - int y = sect.getInteger("Y"); - min = y < min ? y : min; - max = y > max ? y : max; - } - BlockArray[] sections = new BlockArray[stor]; - BlockArray[] down = min < 0 ? new BlockArray[-min] : null; - BlockArray[] up = max >= stor ? new BlockArray[1 + max - stor] : null; + BlockArray[] sections = new BlockArray[sects.tagCount()]; boolean light = !world.dimension.hasNoLight(); for(int n = 0; n < sects.tagCount(); ++n) { @@ -414,15 +404,10 @@ public class Region { } storage.update(); - if(y >= 0 && y < stor) - sections[y] = storage; - else if(y < 0) - down[down.length + y] = storage; - else - up[y - stor] = storage; + sections[n] = storage; } - chunk.setStorage(sections, down, up); + chunk.setStorage(sections); if(tag.hasKey("Biomes", 7)) { chunk.setBiomes(tag.getByteArray("Biomes")); @@ -509,59 +494,53 @@ public class Region { tag.setBoolean("TerrainPopulated", chunk.isTerrainPopulated()); tag.setBoolean("LightPopulated", chunk.isLightPopulated()); tag.setLong("InhabitedTime", chunk.getInhabited()); - BlockArray[] sections = chunk.getStorage(); - BlockArray[] down = chunk.getStorageDown(); - BlockArray[] up = chunk.getStorageUp(); + Set sections = chunk.getStorage(); NBTTagList sects = new NBTTagList(); boolean light = !world.dimension.hasNoLight(); - for(BlockArray[] sec : new BlockArray[][] {sections, down, up}) { - if(sec == null) - continue; - for(BlockArray storage : sec) { - if(storage != null) { - NBTTagCompound sect = new NBTTagCompound(); - sect.setInteger("Y", storage.getY() >> 4); - byte[] blocks = new byte[storage.getData().length]; - NibbleArray data = new NibbleArray(); - NibbleArray adddata = null; - - for(int c = 0; c < storage.getData().length; ++c) { - char cd = storage.getData()[c]; - int cx = c & 15; - int cy = c >> 8 & 15; - int cz = c >> 4 & 15; - - if(cd >> 12 != 0) { - if(adddata == null) { - adddata = new NibbleArray(); - } - - adddata.set(cx, cy, cz, cd >> 12); + for(BlockArray storage : sections) { + if(storage != null) { + NBTTagCompound sect = new NBTTagCompound(); + sect.setInteger("Y", storage.getY() >> 4); + byte[] blocks = new byte[storage.getData().length]; + NibbleArray data = new NibbleArray(); + NibbleArray adddata = null; + + for(int c = 0; c < storage.getData().length; ++c) { + char cd = storage.getData()[c]; + int cx = c & 15; + int cy = c >> 8 & 15; + int cz = c >> 4 & 15; + + if(cd >> 12 != 0) { + if(adddata == null) { + adddata = new NibbleArray(); } - - blocks[c] = (byte)(cd >> 4 & 255); - data.set(cx, cy, cz, cd & 15); + + adddata.set(cx, cy, cz, cd >> 12); } - - sect.setByteArray("Blocks", blocks); - sect.setByteArray("Data", data.getData()); - - if(adddata != null) { - sect.setByteArray("Add", adddata.getData()); - } - - sect.setByteArray("BlockLight", storage.getBlocklight().getData()); - - if(light) { - sect.setByteArray("SkyLight", storage.getSkylight().getData()); - } - else { - sect.setByteArray("SkyLight", new byte[storage.getBlocklight().getData().length]); - } - - sects.appendTag(sect); + + blocks[c] = (byte)(cd >> 4 & 255); + data.set(cx, cy, cz, cd & 15); } + + sect.setByteArray("Blocks", blocks); + sect.setByteArray("Data", data.getData()); + + if(adddata != null) { + sect.setByteArray("Add", adddata.getData()); + } + + sect.setByteArray("BlockLight", storage.getBlocklight().getData()); + + if(light) { + sect.setByteArray("SkyLight", storage.getSkylight().getData()); + } + else { + sect.setByteArray("SkyLight", new byte[storage.getBlocklight().getData().length]); + } + + sects.appendTag(sect); } } diff --git a/server/src/server/world/WorldServer.java b/server/src/server/world/WorldServer.java index e22fba9..53672f3 100755 --- a/server/src/server/world/WorldServer.java +++ b/server/src/server/world/WorldServer.java @@ -146,6 +146,7 @@ public final class WorldServer extends AWorldServer { private final IntHashMap trackMap = new IntHashMap(); private final Map dataMap = Maps.newHashMap(); private final List dataList = Lists.newArrayList(); + private final List toTick = Lists.newArrayList(); private final Biome[] biomes = new Biome[256]; private MapGenCaves caveGen; @@ -712,7 +713,8 @@ public final class WorldServer extends AWorldServer { l2 = Config.randomTick; if(l2 > 0) { - for(BlockArray extendedblockstorage : chunk.getStorage()) { + this.toTick.addAll(chunk.getStorage()); + for(BlockArray extendedblockstorage : this.toTick) { if(extendedblockstorage != null && extendedblockstorage.isTicked()) { for(int j1 = 0; j1 < l2; ++j1) { this.updateLCG = this.updateLCG * 3 + 1013904223; @@ -732,6 +734,7 @@ public final class WorldServer extends AWorldServer { } } } + this.toTick.clear(); } // this.profiler.end(); @@ -2808,7 +2811,6 @@ public final class WorldServer extends AWorldServer { private final ChunkPos position; private int updates; - private int sections; private long prevTime; private boolean biomes; @@ -2837,7 +2839,7 @@ public final class WorldServer extends AWorldServer { Chunk chunk = WorldServer.this.getChunk(this.position.x, this.position.z); if(chunk.isPopulated()) { - player.connection.sendPacket(new SPacketChunkData(chunk, true, 0, new int[0])); + player.connection.sendPacket(new SPacketChunkData(chunk, true, new int[0])); } this.watching.remove(player); @@ -2866,7 +2868,6 @@ public final class WorldServer extends AWorldServer { if(this.updates == 0) WorldServer.this.toUpdate.add(this); this.updates = 64; - this.sections = 0xffffffff; this.biomes = true; } @@ -2880,10 +2881,7 @@ public final class WorldServer extends AWorldServer { WorldServer.this.toUpdate.add(this); } - if(y >= 0 && y >> 4 < 32) - this.sections |= 1 << (y >> 4); - else - this.extend.add(y >> 4); + this.extend.add(y >> 4); if(this.updates < 64) { long pos = ((long)x & 4294967295L) << 36 | ((long)z & 4294967295L) << 32 | (y & 4294967295L); @@ -2933,7 +2931,7 @@ public final class WorldServer extends AWorldServer { } } this.sendToAllPlayersWatchingChunk(new SPacketChunkData(WorldServer.this.getChunk(this.position.x, this.position.z), - this.biomes, this.sections, extend)); + this.biomes, extend)); if(this.biomes) { List list = WorldServer.this.getTileEntitiesIn(x, Integer.MIN_VALUE, z, x + 16, Integer.MAX_VALUE, z + 16); @@ -2943,16 +2941,6 @@ public final class WorldServer extends AWorldServer { } } else { - for(int cy = 0; cy < 32; ++cy) { - if((this.sections & 1 << cy) != 0) { - int y = cy << 4; - List list = WorldServer.this.getTileEntitiesIn(x, y, z, x + 16, y + 16, z + 16); - - for(int n = 0; n < list.size(); ++n) { - this.sendTileToAllPlayersWatchingChunk(list.get(n)); - } - } - } for(Integer cy : this.extend) { int y = cy << 4; List list = WorldServer.this.getTileEntitiesIn(x, y, z, x + 16, y + 16, z + 16); @@ -2980,7 +2968,6 @@ public final class WorldServer extends AWorldServer { } this.updates = 0; - this.sections = 0; this.extend.clear(); this.biomes = false; } From dfa5026a2960ca21f6346436cef7afc78bc0afed Mon Sep 17 00:00:00 2001 From: Sen Date: Wed, 21 May 2025 15:49:02 +0200 Subject: [PATCH 055/200] cap chunk height check in worldgen --- common/src/common/world/Chunk.java | 18 +++++++++--------- server/src/server/world/WorldServer.java | 11 ++++++++--- 2 files changed, 17 insertions(+), 12 deletions(-) diff --git a/common/src/common/world/Chunk.java b/common/src/common/world/Chunk.java index 6e6156c..506aa4f 100755 --- a/common/src/common/world/Chunk.java +++ b/common/src/common/world/Chunk.java @@ -181,8 +181,8 @@ public class Chunk { } protected void genHeights() { - int top = this.getTopSegment(); - int bottom = this.getBottomSegment(); + int top = this.top; + int bottom = this.bottom; this.minHeight = Integer.MAX_VALUE; for(int x = 0; x < 16; ++x) { @@ -209,8 +209,8 @@ public class Chunk { } public void genSkyLight() { - int top = this.getTopSegment(); - int bottom = this.getBottomSegment(); + int top = this.top; + int bottom = this.bottom; this.minHeight = Integer.MAX_VALUE; for(int x = 0; x < 16; ++x) { @@ -330,7 +330,7 @@ public class Chunk { private void relightBlock(int x, int y, int z) { int h = this.height[z << 4 | x]; - int min = this.getBottomSegment(); + int min = this.bottom; int cy = h; if(y > h) { @@ -811,8 +811,8 @@ public class Chunk { BlockPos loc = new BlockPos(pos.getX(), this.precHeight[o], pos.getZ()); if(loc.getY() == -99999999) { - int y = this.getTopSegment() + 15; - int min = this.getBottomSegment(); + int y = this.top + 15; + int min = this.bottom; loc = new BlockPos(pos.getX(), y, pos.getZ()); int h = -1; @@ -1089,8 +1089,8 @@ public class Chunk { } private boolean updateColumn(int x, int z) { - int top = this.getTopSegment(); - int bottom = this.getBottomSegment(); + int top = this.top; + int bottom = this.bottom; boolean opaque = false; boolean below = false; BlockPos.MutableBlockPos pos = new BlockPos.MutableBlockPos((this.xPos << 4) + x, 0, (this.zPos << 4) + z); diff --git a/server/src/server/world/WorldServer.java b/server/src/server/world/WorldServer.java index 53672f3..dd8a4f9 100755 --- a/server/src/server/world/WorldServer.java +++ b/server/src/server/world/WorldServer.java @@ -2438,11 +2438,16 @@ public final class WorldServer extends AWorldServer { public BlockPos getTopSolidOrLiquidBlock(BlockPos pos) { Chunk chunk = this.getChunk(pos); - BlockPos blockpos; + int h = chunk.getTopSegment(); + if(h == Integer.MIN_VALUE) + return new BlockPos(pos.getX(), 0, pos.getZ()); + BlockPos blockpos = new BlockPos(pos.getX(), h + 16, pos.getZ()); BlockPos blockpos1; - int bottom; + h = chunk.getBottomSegment(); + if(blockpos.getY() - h > 512) + h = blockpos.getY() - 512; - for(blockpos = new BlockPos(pos.getX(), chunk.getTopSegment() + 16, pos.getZ()), bottom = chunk.getBottomSegment(); blockpos.getY() >= bottom; blockpos = blockpos1) { + for(; blockpos.getY() >= h; blockpos = blockpos1) { blockpos1 = blockpos.down(); Material material = chunk.getBlock(blockpos1).getMaterial(); From 272392c8ea9ee26d57f4139b0253562b04193bac Mon Sep 17 00:00:00 2001 From: Sen Date: Wed, 21 May 2025 16:32:28 +0200 Subject: [PATCH 056/200] change world floor and ceiling to filler an optional flag --- common/src/common/dimension/Dimension.java | 39 +++++--------------- common/src/common/init/UniverseRegistry.java | 15 ++------ common/src/common/world/Chunk.java | 24 ++++++------ server/src/server/world/WorldServer.java | 16 ++++---- 4 files changed, 33 insertions(+), 61 deletions(-) diff --git a/common/src/common/dimension/Dimension.java b/common/src/common/dimension/Dimension.java index e5c4b5b..5e63fa8 100755 --- a/common/src/common/dimension/Dimension.java +++ b/common/src/common/dimension/Dimension.java @@ -279,8 +279,7 @@ public abstract class Dimension extends Nameable implements Comparable> 4; BlockArray arr = this.getArray(y); if(arr == null) { @@ -124,7 +128,7 @@ public class Chunk { for(int bz = 0; bz < 16; ++bz) { for(int by = height - 1; by >= height - 5; --by) { if(by >= (height - 1) - rand.zrange(5)) - this.getArray(by >> 4).set(bx, by & 15, bz, ceil); + this.getArray(by >> 4).set(bx, by & 15, bz, Blocks.air.getState()); } } } @@ -132,12 +136,10 @@ public class Chunk { for(int n = 0; n < this.biomes.length; ++n) { this.biomes[n] = (byte)biomes[n].id; } - this.bottom = height == 0 ? Integer.MAX_VALUE : 0; - this.top = height == 0 ? Integer.MIN_VALUE : ((height + 15) >> 4) << 4; - if(ceil == null) - this.genSkyLight(); - else + if(ceil) this.resetRelight(); + else + this.genSkyLight(); } public int getHeight(BlockPos pos) { diff --git a/server/src/server/world/WorldServer.java b/server/src/server/world/WorldServer.java index dd8a4f9..f151139 100755 --- a/server/src/server/world/WorldServer.java +++ b/server/src/server/world/WorldServer.java @@ -163,8 +163,8 @@ public final class WorldServer extends AWorldServer { private BlockReplacer replacer; private FeatureDungeons dungeons; private State liquid; - private State base; - private State ceil; + private boolean base; + private boolean ceil; private FeatureOres[] ores; private FeatureLakes[] lakes; private FeatureLiquids[] liquids; @@ -342,8 +342,8 @@ public final class WorldServer extends AWorldServer { this.caveGen = null; this.bigCaveGen = null; this.ravineGen = null; - this.base = null; - this.ceil = null; + this.base = false; + this.ceil = false; this.mobs = false; this.snow = false; this.strongholdGen = null; @@ -423,8 +423,8 @@ public final class WorldServer extends AWorldServer { this.caveGen = this.createCaveGenerator(); this.bigCaveGen = this.createBigCaveGenerator(); this.ravineGen = this.createRavineGenerator(); - this.base = this.dimension.getFiller().getBlock() == Blocks.air ? null : this.dimension.getFiller(); - this.ceil = this.dimension.getWorldCeiling(); + this.base = this.dimension.getFiller().getBlock() != Blocks.air; + this.ceil = this.dimension.hasWorldCeiling(); this.mobs = this.dimension.hasMobs(); this.snow = this.dimension.hasSnow(); this.strongholdGen = this.dimension.hasStrongholds() ? new MapGenStronghold() : null; @@ -1748,8 +1748,8 @@ public final class WorldServer extends AWorldServer { this.replacer = null; this.populate = false; this.liquid = Blocks.air.getState(); - this.base = null; - this.ceil = null; + this.base = false; + this.ceil = false; this.height = this.generator.getMaximumHeight(); this.seaLevel = this.dimension.getSeaLevel(); this.ores = null; From 688522c5caab2c971fa46ed89d3de78686b8f8d5 Mon Sep 17 00:00:00 2001 From: Sen Date: Wed, 21 May 2025 16:35:37 +0200 Subject: [PATCH 057/200] change view distance default to 8 --- common/src/common/init/Config.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/src/common/init/Config.java b/common/src/common/init/Config.java index eacec16..c50fd3f 100755 --- a/common/src/common/init/Config.java +++ b/common/src/common/init/Config.java @@ -422,7 +422,7 @@ public abstract class Config { @Var(name = "weatherChance") public static int weatherChance = 48000; @Var(name = "viewDistance", min = 2, max = 16) - public static int distance = 10; + public static int distance = 8; @Var(name = "healChance") public static int healChance = 5; @Var(name = "hopperCooldown", min = 0, max = 160) From f6b2fdf422a4a835645351f36bd5d04c1a599b75 Mon Sep 17 00:00:00 2001 From: Sen Date: Wed, 21 May 2025 16:50:59 +0200 Subject: [PATCH 058/200] fix entity void height --- common/src/common/entity/Entity.java | 2 +- common/src/common/entity/item/EntityCart.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/common/src/common/entity/Entity.java b/common/src/common/entity/Entity.java index 4b351fa..52fad4f 100755 --- a/common/src/common/entity/Entity.java +++ b/common/src/common/entity/Entity.java @@ -346,7 +346,7 @@ public abstract class Entity this.setOnFireFromMolten(); } - if (this.posY < (double)(-World.MAX_SIZE_Y)) + if (this.posY < (double)(-World.MAX_SIZE_Y) - 64.0) { this.onVoidUpdate(); } diff --git a/common/src/common/entity/item/EntityCart.java b/common/src/common/entity/item/EntityCart.java index bf376a3..e94b911 100755 --- a/common/src/common/entity/item/EntityCart.java +++ b/common/src/common/entity/item/EntityCart.java @@ -242,7 +242,7 @@ public abstract class EntityCart extends Entity implements IWorldNameable this.setDamage(this.getDamage() - 1); } - if (this.posY < (double)(-World.MAX_SIZE_Y)) + if (this.posY < (double)(-World.MAX_SIZE_Y) - 64.0) { this.onVoidUpdate(); } From 41fae1317f0a0242d2927274fdf28248f69a714f Mon Sep 17 00:00:00 2001 From: Sen Date: Wed, 21 May 2025 18:45:45 +0200 Subject: [PATCH 059/200] network bug workaround test --- client/src/client/Client.java | 10 +++++++++- common/src/common/network/PacketEncoder.java | 2 +- common/src/common/packet/LPacketLogin.java | 2 ++ server/src/server/Server.java | 1 + 4 files changed, 13 insertions(+), 2 deletions(-) diff --git a/client/src/client/Client.java b/client/src/client/Client.java index 9ae4f1f..082184b 100755 --- a/client/src/client/Client.java +++ b/client/src/client/Client.java @@ -1613,6 +1613,7 @@ public class Client implements IThreadListener { } catch (Exception exception) { + Log.SYSTEM.error(exception, "Fehler beim sofortigen Ausführen von Render-Task " + callableToSchedule); return Futures.immediateFailedFuture(exception); } } @@ -2577,7 +2578,7 @@ public class Client implements IThreadListener { Client.this.soundManager.stopSounds(); } }); - this.registerDebug(Keysym.Q, "Programm sofort beenden und speichern", new DebugRunner() { + this.registerDebug(Keysym.Q, "Programm sofort beenden und trennen", new DebugRunner() { public void execute(Keysym key) { Client.this.interrupted = true; } @@ -2617,6 +2618,13 @@ public class Client implements IThreadListener { } } }); + this.registerDebug(Keysym.AE, "Programm sofort beenden und server beenden", new DebugRunner() { + public void execute(Keysym key) { + if(Client.this.player != null) + Client.this.player.client.addToSendQueue(new CPacketMessage(CPacketMessage.Type.COMMAND, "shutdown")); + Client.this.interrupted = true; + } + }); } private boolean handleDebugKey(Keysym key) { diff --git a/common/src/common/network/PacketEncoder.java b/common/src/common/network/PacketEncoder.java index ff7cdbf..fec4859 100755 --- a/common/src/common/network/PacketEncoder.java +++ b/common/src/common/network/PacketEncoder.java @@ -22,7 +22,7 @@ public class PacketEncoder extends MessageToByteEncoder // if (Log.isTraceEnabled()) // { -// Log.debug("AUS: [" + p_encode_1_.channel().attr(NetConnection.ATTR_STATE).get() + ":" + integer + "] " + p_encode_2_.getClass().getName()); +// Log.SYSTEM.debug("AUS: [" + p_encode_1_.channel().attr(NetConnection.ATTR_STATE).get() + ":" + integer + "] " + p_encode_2_.getClass().getName()); // } if (integer == null) diff --git a/common/src/common/packet/LPacketLogin.java b/common/src/common/packet/LPacketLogin.java index 671fca7..997d370 100644 --- a/common/src/common/packet/LPacketLogin.java +++ b/common/src/common/packet/LPacketLogin.java @@ -10,9 +10,11 @@ public class LPacketLogin implements Packet { } public void readPacketData(PacketBuffer buf) throws IOException { + buf.readStringFromBuffer(16); } public void writePacketData(PacketBuffer buf) throws IOException { + buf.writeString("TESTtestPlceHldr"); } public void processPacket(ILoginHandler handler) { diff --git a/server/src/server/Server.java b/server/src/server/Server.java index 8f54ba4..e7f5598 100755 --- a/server/src/server/Server.java +++ b/server/src/server/Server.java @@ -763,6 +763,7 @@ public final class Server implements IThreadListener { return Futures.immediateFuture(callable.call()); } catch(Exception exception) { + Log.SYSTEM.error(exception, "Fehler beim sofortigen Ausführen von Server-Task " + callable); return Futures.immediateFailedFuture(exception); } } From 0055cbf80669c9554b28297fc038c232320e0646 Mon Sep 17 00:00:00 2001 From: Sen Date: Fri, 23 May 2025 09:36:57 +0200 Subject: [PATCH 060/200] remove some old comments --- common/src/common/world/Chunk.java | 15 +-------------- 1 file changed, 1 insertion(+), 14 deletions(-) diff --git a/common/src/common/world/Chunk.java b/common/src/common/world/Chunk.java index c393786..9feacdc 100755 --- a/common/src/common/world/Chunk.java +++ b/common/src/common/world/Chunk.java @@ -272,8 +272,6 @@ public class Chunk { } private void recheckGaps(boolean single) { -// this.world.profiler.start("recheckGaps"); - if(this.world.isAreaLoaded(new BlockPos(this.xPos * 16 + 8, 0, this.zPos * 16 + 8), 16)) { for(int x = 0; x < 16; ++x) { for(int z = 0; z < 16; ++z) { @@ -296,7 +294,6 @@ public class Chunk { } if(single) { -// this.world.profiler.end(); return; } } @@ -305,8 +302,6 @@ public class Chunk { this.gapUpdate = false; } - -// this.world.profiler.end(); } private void checkNeighbor(int x, int z, int max) { @@ -788,17 +783,9 @@ public class Chunk { } public boolean isDirty(long time) { -// if (all) -// { - if(this.hasEntity && time /* this.world.getTime() */ != this.lastSave || this.modified) { + if(this.hasEntity && time != this.lastSave || this.modified) { return true; } -// } -// else if (this.hasEntity && this.world.getTime() >= this.lastSave + 600L) -// { -// return true; -// } - return this.modified; } From 7126ca5a9fbab3f361f0edfdf77bc3f2b32af3a9 Mon Sep 17 00:00:00 2001 From: Sen Date: Sat, 24 May 2025 11:46:37 +0200 Subject: [PATCH 061/200] add soul+black fire --- client/src/client/init/RenderRegistry.java | 4 + .../renderer/ticked/TextureFlamesFX1.java | 22 +- .../renderer/ticked/TextureFlamesFX2.java | 8 +- .../renderer/ticked/TextureFlamesFXMono1.java | 7 + .../renderer/ticked/TextureFlamesFXMono2.java | 7 + common/src/common/block/Block.java | 4 + common/src/common/block/BlockFire.java | 421 +++++++++--------- common/src/common/block/BlockTintedFire.java | 35 ++ common/src/common/init/BlockRegistry.java | 4 + common/src/common/init/Blocks.java | 2 + .../src/common/init/FlammabilityRegistry.java | 65 ++- common/src/common/init/ItemRegistry.java | 8 +- common/src/common/item/ItemFlintAndSteel.java | 9 +- common/src/common/world/World.java | 4 +- .../src/server/clipboard/ReorderRegistry.java | 2 + 15 files changed, 346 insertions(+), 256 deletions(-) create mode 100644 client/src/client/renderer/ticked/TextureFlamesFXMono1.java create mode 100644 client/src/client/renderer/ticked/TextureFlamesFXMono2.java create mode 100644 common/src/common/block/BlockTintedFire.java diff --git a/client/src/client/init/RenderRegistry.java b/client/src/client/init/RenderRegistry.java index d57d794..8445a62 100644 --- a/client/src/client/init/RenderRegistry.java +++ b/client/src/client/init/RenderRegistry.java @@ -57,6 +57,8 @@ import client.renderer.model.ModelWolf; import client.renderer.texture.TextureTicked; import client.renderer.ticked.TextureFlamesFX1; import client.renderer.ticked.TextureFlamesFX2; +import client.renderer.ticked.TextureFlamesFXMono1; +import client.renderer.ticked.TextureFlamesFXMono2; import client.renderer.ticked.TextureLavaFX; import client.renderer.ticked.TextureLavaFlowFX; import client.renderer.ticked.TextureWaterFX; @@ -165,6 +167,8 @@ public abstract class RenderRegistry { public static void registerAnimations(Map> anim) { anim.put("fire1", TextureFlamesFX1.class); anim.put("fire2", TextureFlamesFX2.class); + anim.put("flame1", TextureFlamesFXMono1.class); + anim.put("flame2", TextureFlamesFXMono2.class); anim.put("lavaflow", TextureLavaFlowFX.class); anim.put("lava", TextureLavaFX.class); anim.put("waterflow", TextureWaterFlowFX.class); diff --git a/client/src/client/renderer/ticked/TextureFlamesFX1.java b/client/src/client/renderer/ticked/TextureFlamesFX1.java index 6b07093..470957b 100755 --- a/client/src/client/renderer/ticked/TextureFlamesFX1.java +++ b/client/src/client/renderer/ticked/TextureFlamesFX1.java @@ -4,12 +4,18 @@ import client.renderer.texture.TextureTicked; public class TextureFlamesFX1 extends TextureTicked -{ +{ + private final boolean mono; - public TextureFlamesFX1() + public TextureFlamesFX1(boolean mono) { field_1133_g = new float[320]; - field_1132_h = new float[320]; + field_1132_h = new float[320]; + this.mono = mono; + } + + public TextureFlamesFX1() { + this(false); } public void renderStep(int textureData[]) @@ -76,8 +82,14 @@ public class TextureFlamesFX1 extends TextureTicked // j1 = l2; // l1 = i3; // j2 = j3; -// } - textureData[k] = (c << 24) | (j1 << 16) | (l1 << 8) | j2; +// } + if(this.mono) { + j2 = (j1 + l1 + j2) / 3; + textureData[k] = (c << 24) | (j2 << 16) | (j2 << 8) | j2; + } + else { + textureData[k] = (c << 24) | (j1 << 16) | (l1 << 8) | j2; + } } } diff --git a/client/src/client/renderer/ticked/TextureFlamesFX2.java b/client/src/client/renderer/ticked/TextureFlamesFX2.java index 615af67..89ede38 100755 --- a/client/src/client/renderer/ticked/TextureFlamesFX2.java +++ b/client/src/client/renderer/ticked/TextureFlamesFX2.java @@ -1,11 +1,17 @@ package client.renderer.ticked; public class TextureFlamesFX2 extends TextureFlamesFX1 { - public TextureFlamesFX2() + public TextureFlamesFX2(boolean mono) { + super(mono); int[] tex = new int[256]; for(int z = 0; z < 160; z++) { this.renderStep(tex); } } + + public TextureFlamesFX2() + { + this(false); + } } diff --git a/client/src/client/renderer/ticked/TextureFlamesFXMono1.java b/client/src/client/renderer/ticked/TextureFlamesFXMono1.java new file mode 100644 index 0000000..df13b2a --- /dev/null +++ b/client/src/client/renderer/ticked/TextureFlamesFXMono1.java @@ -0,0 +1,7 @@ +package client.renderer.ticked; + +public class TextureFlamesFXMono1 extends TextureFlamesFX1 { + public TextureFlamesFXMono1() { + super(true); + } +} diff --git a/client/src/client/renderer/ticked/TextureFlamesFXMono2.java b/client/src/client/renderer/ticked/TextureFlamesFXMono2.java new file mode 100644 index 0000000..2c4a094 --- /dev/null +++ b/client/src/client/renderer/ticked/TextureFlamesFXMono2.java @@ -0,0 +1,7 @@ +package client.renderer.ticked; + +public class TextureFlamesFXMono2 extends TextureFlamesFX2 { + public TextureFlamesFXMono2() { + super(true); + } +} diff --git a/common/src/common/block/Block.java b/common/src/common/block/Block.java index d1c321a..9a52336 100755 --- a/common/src/common/block/Block.java +++ b/common/src/common/block/Block.java @@ -1441,6 +1441,10 @@ public class Block return false; } + public boolean canExtinguish() { + return false; + } + public void onDestroyedByFire(World world, BlockPos pos, State state) { } } diff --git a/common/src/common/block/BlockFire.java b/common/src/common/block/BlockFire.java index e0bc2f7..aee1003 100755 --- a/common/src/common/block/BlockFire.java +++ b/common/src/common/block/BlockFire.java @@ -2,9 +2,9 @@ package common.block; import java.util.Map; -import common.collect.Maps; import common.init.Blocks; import common.init.Config; +import common.init.FlammabilityRegistry; import common.init.SoundEvent; import common.material.Material; import common.model.BlockLayer; @@ -36,8 +36,6 @@ public class BlockFire extends Block public static final PropertyBool SOUTH = PropertyBool.create("south"); public static final PropertyBool WEST = PropertyBool.create("west"); public static final PropertyInteger UPPER = PropertyInteger.create("upper", 0, 2); - private final Map encouragements = Maps.newIdentityHashMap(); - private final Map flammabilities = Maps.newIdentityHashMap(); /** * Get the actual Block state of this Block at the given position. This applies properties not visible in the @@ -75,12 +73,6 @@ public class BlockFire extends Block this.setTickRandomly(); } - public void setFireInfo(Block blockIn, int encouragement, int flammability) - { - this.encouragements.put(blockIn, Integer.valueOf(encouragement)); - this.flammabilities.put(blockIn, Integer.valueOf(flammability)); - } - public BoundingBox getCollisionBoundingBox(World worldIn, BlockPos pos, State state) { return null; @@ -242,21 +234,9 @@ public class BlockFire extends Block return false; } - private int getFlammability(Block blockIn) - { - Integer integer = (Integer)this.flammabilities.get(blockIn); - return integer == null ? 0 : integer.intValue(); - } - - private int getEncouragement(Block blockIn) - { - Integer integer = (Integer)this.encouragements.get(blockIn); - return integer == null ? 0 : integer.intValue(); - } - private void catchOnFire(World worldIn, BlockPos pos, int chance, Random random, int age) { - int i = this.getFlammability(worldIn.getState(pos).getBlock()); + int i = FlammabilityRegistry.getFlammability(worldIn.getState(pos).getBlock()); if (random.zrange(chance) < i) { @@ -311,7 +291,7 @@ public class BlockFire extends Block for (Facing enumfacing : Facing.values()) { - i = Math.max(this.getEncouragement(worldIn.getState(pos.offset(enumfacing)).getBlock()), i); + i = Math.max(FlammabilityRegistry.getEncouragement(worldIn.getState(pos.offset(enumfacing)).getBlock()), i); } return i; @@ -331,7 +311,7 @@ public class BlockFire extends Block */ public boolean canCatchFire(IBlockAccess worldIn, BlockPos pos) { - return this.getEncouragement(worldIn.getState(pos).getBlock()) > 0; + return FlammabilityRegistry.getEncouragement(worldIn.getState(pos).getBlock()) > 0; } public boolean canPlaceBlockAt(World worldIn, BlockPos pos) @@ -479,485 +459,484 @@ public class BlockFire extends Block private static Model fire_nsu2_flip(String fire) { return ModelProvider.getModelProvider().getModel(fire).noOcclude() .add(0, 1, 0.01f, 16, 23.4f, 0.01f).noShade() - .s().uv(16, 0, 0, 16).noCull() + .s().uv(16, 0, 0, 16).noCull().tint() .add(0, 1, 0.01f, 16, 23.4f, 0.01f).noShade() - .n().uv(16, 0, 0, 16).noCull() + .n().uv(16, 0, 0, 16).noCull().tint() .add(0, 1, 15.99f, 16, 23.4f, 15.99f).noShade() - .s().uv(16, 0, 0, 16).noCull() + .s().uv(16, 0, 0, 16).noCull().tint() .add(0, 1, 15.99f, 16, 23.4f, 15.99f).noShade() - .n().uv(16, 0, 0, 16).noCull() + .n().uv(16, 0, 0, 16).noCull().tint() .add(0, 16, 0, 16, 16, 16).noShade().rotate(8, 16, 16, Facing.Axis.X, -22.5f, true) - .d().uv(0, 0, 16, 16).rot(180).noCull() + .d().uv(0, 0, 16, 16).rot(180).noCull().tint() .add(0, 16, 0, 16, 16, 16).noShade().rotate(8, 16, 0, Facing.Axis.X, 22.5f, true) - .d().uv(0, 0, 16, 16).noCull(); + .d().uv(0, 0, 16, 16).noCull().tint(); } private static Model fire_nu1(String fire) { return ModelProvider.getModelProvider().getModel(fire).noOcclude() .add(0, 1, 0.01f, 16, 23.4f, 0.01f).noShade() - .s().uv(0, 0, 16, 16).noCull() + .s().uv(0, 0, 16, 16).noCull().tint() .add(0, 1, 0.01f, 16, 23.4f, 0.01f).noShade() - .n().uv(0, 0, 16, 16).noCull() + .n().uv(0, 0, 16, 16).noCull().tint() .add(0, 16, 0, 16, 16, 16).noShade().rotate(16, 16, 8, Facing.Axis.Z, 22.5f, true) - .d().uv(0, 0, 16, 16).rot(270).noCull() + .d().uv(0, 0, 16, 16).rot(270).noCull().tint() .add(0, 16, 0, 16, 16, 16).noShade().rotate(0, 16, 8, Facing.Axis.Z, -22.5f, true) - .d().uv(0, 0, 16, 16).rot(90).noCull(); + .d().uv(0, 0, 16, 16).rot(90).noCull().tint(); } private static Model fire_nseu2_flip(String fire) { return ModelProvider.getModelProvider().getModel(fire).noOcclude() .add(0, 1, 0.01f, 16, 23.4f, 0.01f).noShade() - .s().uv(16, 0, 0, 16).noCull() + .s().uv(16, 0, 0, 16).noCull().tint() .add(0, 1, 0.01f, 16, 23.4f, 0.01f).noShade() - .n().uv(16, 0, 0, 16).noCull() + .n().uv(16, 0, 0, 16).noCull().tint() .add(0, 1, 15.99f, 16, 23.4f, 15.99f).noShade() - .s().uv(16, 0, 0, 16).noCull() + .s().uv(16, 0, 0, 16).noCull().tint() .add(0, 1, 15.99f, 16, 23.4f, 15.99f).noShade() - .n().uv(16, 0, 0, 16).noCull() + .n().uv(16, 0, 0, 16).noCull().tint() .add(15.99f, 1, 0, 15.99f, 23.4f, 16).noShade() - .e().uv(16, 0, 0, 16).noCull() + .e().uv(16, 0, 0, 16).noCull().tint() .add(15.99f, 1, 0, 15.99f, 23.4f, 16).noShade() - .w().uv(16, 0, 0, 16).noCull() + .w().uv(16, 0, 0, 16).noCull().tint() .add(0, 16, 0, 16, 16, 16).noShade().rotate(8, 16, 16, Facing.Axis.X, -22.5f, true) - .d().uv(0, 0, 16, 16).rot(180).noCull() + .d().uv(0, 0, 16, 16).rot(180).noCull().tint() .add(0, 16, 0, 16, 16, 16).noShade().rotate(8, 16, 0, Facing.Axis.X, 22.5f, true) - .d().uv(0, 0, 16, 16).noCull(); + .d().uv(0, 0, 16, 16).noCull().tint(); } private static Model fire_neu1_flip(String fire) { return ModelProvider.getModelProvider().getModel(fire).noOcclude() .add(0, 1, 0.01f, 16, 23.4f, 0.01f).noShade() - .s().uv(16, 0, 0, 16).noCull() + .s().uv(16, 0, 0, 16).noCull().tint() .add(0, 1, 0.01f, 16, 23.4f, 0.01f).noShade() - .n().uv(16, 0, 0, 16).noCull() + .n().uv(16, 0, 0, 16).noCull().tint() .add(15.99f, 1, 0, 15.99f, 23.4f, 16).noShade() - .e().uv(16, 0, 0, 16).noCull() + .e().uv(16, 0, 0, 16).noCull().tint() .add(15.99f, 1, 0, 15.99f, 23.4f, 16).noShade() - .w().uv(16, 0, 0, 16).noCull() + .w().uv(16, 0, 0, 16).noCull().tint() .add(0, 16, 0, 16, 16, 16).noShade().rotate(16, 16, 8, Facing.Axis.Z, 22.5f, true) - .d().uv(0, 0, 16, 16).rot(270).noCull() + .d().uv(0, 0, 16, 16).rot(270).noCull().tint() .add(0, 16, 0, 16, 16, 16).noShade().rotate(0, 16, 8, Facing.Axis.Z, -22.5f, true) - .d().uv(0, 0, 16, 16).rot(90).noCull(); + .d().uv(0, 0, 16, 16).rot(90).noCull().tint(); } private static Model fire_nsu2(String fire) { return ModelProvider.getModelProvider().getModel(fire).noOcclude() .add(0, 1, 0.01f, 16, 23.4f, 0.01f).noShade() - .s().uv(0, 0, 16, 16).noCull() + .s().uv(0, 0, 16, 16).noCull().tint() .add(0, 1, 0.01f, 16, 23.4f, 0.01f).noShade() - .n().uv(0, 0, 16, 16).noCull() + .n().uv(0, 0, 16, 16).noCull().tint() .add(0, 1, 15.99f, 16, 23.4f, 15.99f).noShade() - .s().uv(0, 0, 16, 16).noCull() + .s().uv(0, 0, 16, 16).noCull().tint() .add(0, 1, 15.99f, 16, 23.4f, 15.99f).noShade() - .n().uv(0, 0, 16, 16).noCull() + .n().uv(0, 0, 16, 16).noCull().tint() .add(0, 16, 0, 16, 16, 16).noShade().rotate(8, 16, 16, Facing.Axis.X, -22.5f, true) - .d().uv(0, 0, 16, 16).rot(180).noCull() + .d().uv(0, 0, 16, 16).rot(180).noCull().tint() .add(0, 16, 0, 16, 16, 16).noShade().rotate(8, 16, 0, Facing.Axis.X, 22.5f, true) - .d().uv(0, 0, 16, 16).noCull(); + .d().uv(0, 0, 16, 16).noCull().tint(); } private static Model fire_nu2_flip(String fire) { return ModelProvider.getModelProvider().getModel(fire).noOcclude() .add(0, 1, 0.01f, 16, 23.4f, 0.01f).noShade() - .s().uv(16, 0, 0, 16).noCull() + .s().uv(16, 0, 0, 16).noCull().tint() .add(0, 1, 0.01f, 16, 23.4f, 0.01f).noShade() - .n().uv(16, 0, 0, 16).noCull() + .n().uv(16, 0, 0, 16).noCull().tint() .add(0, 16, 0, 16, 16, 16).noShade().rotate(8, 16, 16, Facing.Axis.X, -22.5f, true) - .d().uv(0, 0, 16, 16).rot(180).noCull() + .d().uv(0, 0, 16, 16).rot(180).noCull().tint() .add(0, 16, 0, 16, 16, 16).noShade().rotate(8, 16, 0, Facing.Axis.X, 22.5f, true) - .d().uv(0, 0, 16, 16).noCull(); + .d().uv(0, 0, 16, 16).noCull().tint(); } private static Model fire_neu2_flip(String fire) { return ModelProvider.getModelProvider().getModel(fire).noOcclude() .add(0, 1, 0.01f, 16, 23.4f, 0.01f).noShade() - .s().uv(16, 0, 0, 16).noCull() + .s().uv(16, 0, 0, 16).noCull().tint() .add(0, 1, 0.01f, 16, 23.4f, 0.01f).noShade() - .n().uv(16, 0, 0, 16).noCull() + .n().uv(16, 0, 0, 16).noCull().tint() .add(15.99f, 1, 0, 15.99f, 23.4f, 16).noShade() - .e().uv(16, 0, 0, 16).noCull() + .e().uv(16, 0, 0, 16).noCull().tint() .add(15.99f, 1, 0, 15.99f, 23.4f, 16).noShade() - .w().uv(16, 0, 0, 16).noCull() + .w().uv(16, 0, 0, 16).noCull().tint() .add(0, 16, 0, 16, 16, 16).noShade().rotate(8, 16, 16, Facing.Axis.X, -22.5f, true) - .d().uv(0, 0, 16, 16).rot(180).noCull() + .d().uv(0, 0, 16, 16).rot(180).noCull().tint() .add(0, 16, 0, 16, 16, 16).noShade().rotate(8, 16, 0, Facing.Axis.X, 22.5f, true) - .d().uv(0, 0, 16, 16).noCull(); + .d().uv(0, 0, 16, 16).noCull().tint(); } private static Model fire_nsewu2_flip(String fire) { return ModelProvider.getModelProvider().getModel(fire).noOcclude() .add(0, 1, 0.01f, 16, 23.4f, 0.01f).noShade() - .s().uv(16, 0, 0, 16).noCull() + .s().uv(16, 0, 0, 16).noCull().tint() .add(0, 1, 0.01f, 16, 23.4f, 0.01f).noShade() - .n().uv(16, 0, 0, 16).noCull() + .n().uv(16, 0, 0, 16).noCull().tint() .add(0, 1, 15.99f, 16, 23.4f, 15.99f).noShade() - .s().uv(16, 0, 0, 16).noCull() + .s().uv(16, 0, 0, 16).noCull().tint() .add(0, 1, 15.99f, 16, 23.4f, 15.99f).noShade() - .n().uv(16, 0, 0, 16).noCull() + .n().uv(16, 0, 0, 16).noCull().tint() .add(15.99f, 1, 0, 15.99f, 23.4f, 16).noShade() - .e().uv(16, 0, 0, 16).noCull() + .e().uv(16, 0, 0, 16).noCull().tint() .add(15.99f, 1, 0, 15.99f, 23.4f, 16).noShade() - .w().uv(16, 0, 0, 16).noCull() + .w().uv(16, 0, 0, 16).noCull().tint() .add(0.01f, 1, 0, 0.01f, 23.4f, 16).noShade() - .e().uv(16, 0, 0, 16).noCull() + .e().uv(16, 0, 0, 16).noCull().tint() .add(15.99f, 1, 0, 0.01f, 23.4f, 16).noShade() - .w().uv(16, 0, 0, 16).noCull() + .w().uv(16, 0, 0, 16).noCull().tint() .add(0, 16, 0, 16, 16, 16).noShade().rotate(8, 16, 16, Facing.Axis.X, -22.5f, true) - .d().uv(0, 0, 16, 16).rot(180).noCull() + .d().uv(0, 0, 16, 16).rot(180).noCull().tint() .add(0, 16, 0, 16, 16, 16).noShade().rotate(8, 16, 0, Facing.Axis.X, 22.5f, true) - .d().uv(0, 0, 16, 16).noCull(); + .d().uv(0, 0, 16, 16).noCull().tint(); } private static Model fire_nsewu2(String fire) { return ModelProvider.getModelProvider().getModel(fire).noOcclude() .add(0, 1, 0.01f, 16, 23.4f, 0.01f).noShade() - .s().uv(0, 0, 16, 16).noCull() + .s().uv(0, 0, 16, 16).noCull().tint() .add(0, 1, 0.01f, 16, 23.4f, 0.01f).noShade() - .n().uv(0, 0, 16, 16).noCull() + .n().uv(0, 0, 16, 16).noCull().tint() .add(0, 1, 15.99f, 16, 23.4f, 15.99f).noShade() - .s().uv(0, 0, 16, 16).noCull() + .s().uv(0, 0, 16, 16).noCull().tint() .add(0, 1, 15.99f, 16, 23.4f, 15.99f).noShade() - .n().uv(0, 0, 16, 16).noCull() + .n().uv(0, 0, 16, 16).noCull().tint() .add(15.99f, 1, 0, 15.99f, 23.4f, 16).noShade() - .e().uv(0, 0, 16, 16).noCull() + .e().uv(0, 0, 16, 16).noCull().tint() .add(15.99f, 1, 0, 15.99f, 23.4f, 16).noShade() - .w().uv(0, 0, 16, 16).noCull() + .w().uv(0, 0, 16, 16).noCull().tint() .add(0.01f, 1, 0, 0.01f, 23.4f, 16).noShade() - .e().uv(0, 0, 16, 16).noCull() + .e().uv(0, 0, 16, 16).noCull().tint() .add(15.99f, 1, 0, 0.01f, 23.4f, 16).noShade() - .w().uv(0, 0, 16, 16).noCull() + .w().uv(0, 0, 16, 16).noCull().tint() .add(0, 16, 0, 16, 16, 16).noShade().rotate(8, 16, 16, Facing.Axis.X, -22.5f, true) - .d().uv(0, 0, 16, 16).rot(180).noCull() + .d().uv(0, 0, 16, 16).rot(180).noCull().tint() .add(0, 16, 0, 16, 16, 16).noShade().rotate(8, 16, 0, Facing.Axis.X, 22.5f, true) - .d().uv(0, 0, 16, 16).noCull(); + .d().uv(0, 0, 16, 16).noCull().tint(); } private static Model fire_nsew(String fire) { return ModelProvider.getModelProvider().getModel(fire).noOcclude() .add(0, 1, 0.01f, 16, 23.4f, 0.01f).noShade() - .s().uv(0, 0, 16, 16).noCull() + .s().uv(0, 0, 16, 16).noCull().tint() .add(0, 1, 0.01f, 16, 23.4f, 0.01f).noShade() - .n().uv(0, 0, 16, 16).noCull() + .n().uv(0, 0, 16, 16).noCull().tint() .add(0, 1, 15.99f, 16, 23.4f, 15.99f).noShade() - .s().uv(0, 0, 16, 16).noCull() + .s().uv(0, 0, 16, 16).noCull().tint() .add(0, 1, 15.99f, 16, 23.4f, 15.99f).noShade() - .n().uv(0, 0, 16, 16).noCull() + .n().uv(0, 0, 16, 16).noCull().tint() .add(15.99f, 1, 0, 15.99f, 23.4f, 16).noShade() - .e().uv(0, 0, 16, 16).noCull() + .e().uv(0, 0, 16, 16).noCull().tint() .add(15.99f, 1, 0, 15.99f, 23.4f, 16).noShade() - .w().uv(0, 0, 16, 16).noCull() + .w().uv(0, 0, 16, 16).noCull().tint() .add(0.01f, 1, 0, 0.01f, 23.4f, 16).noShade() - .e().uv(0, 0, 16, 16).noCull() + .e().uv(0, 0, 16, 16).noCull().tint() .add(15.99f, 1, 0, 0.01f, 23.4f, 16).noShade() - .w().uv(0, 0, 16, 16).noCull(); + .w().uv(0, 0, 16, 16).noCull().tint(); } private static Model fire_floor(String fire) { return ModelProvider.getModelProvider().getModel(fire).noOcclude() .add(0, 0, 8.8f, 16, 22.4f, 8.8f).noShade().rotate(8, 8, 8, Facing.Axis.X, -22.5f, true) - .s().uv(0, 0, 16, 16).noCull() + .s().uv(0, 0, 16, 16).noCull().tint() .add(0, 0, 7.2f, 16, 22.4f, 7.2f).noShade().rotate(8, 8, 8, Facing.Axis.X, 22.5f, true) - .n().uv(0, 0, 16, 16).noCull() + .n().uv(0, 0, 16, 16).noCull().tint() .add(8.8f, 0, 0, 8.8f, 22.4f, 16).noShade().rotate(8, 8, 8, Facing.Axis.Z, -22.5f, true) - .w().uv(0, 0, 16, 16).noCull() + .w().uv(0, 0, 16, 16).noCull().tint() .add(7.2f, 0, 0, 7.2f, 22.4f, 16).noShade().rotate(8, 8, 8, Facing.Axis.Z, 22.5f, true) - .e().uv(0, 0, 16, 16).noCull() + .e().uv(0, 0, 16, 16).noCull().tint() .add(0, 0, 15.99f, 16, 22.4f, 15.99f).noShade() - .s().uv(0, 0, 16, 16).noCull() + .s().uv(0, 0, 16, 16).noCull().tint() .add(0, 0, 0.01f, 16, 22.4f, 0.01f).noShade() - .n().uv(0, 0, 16, 16).noCull() + .n().uv(0, 0, 16, 16).noCull().tint() .add(0.01f, 0, 0, 0.01f, 22.4f, 16).noShade() - .w().uv(0, 0, 16, 16).noCull() + .w().uv(0, 0, 16, 16).noCull().tint() .add(15.99f, 0, 0, 15.99f, 22.4f, 16).noShade() - .e().uv(0, 0, 16, 16).noCull(); + .e().uv(0, 0, 16, 16).noCull().tint(); } private static Model fire_u1(String fire) { return ModelProvider.getModelProvider().getModel(fire).noOcclude() .add(0, 16, 0, 16, 16, 16).noShade().rotate(16, 16, 8, Facing.Axis.Z, 22.5f, true) - .d().uv(0, 0, 16, 16).rot(270).noCull() + .d().uv(0, 0, 16, 16).rot(270).noCull().tint() .add(0, 16, 0, 16, 16, 16).noShade().rotate(0, 16, 8, Facing.Axis.Z, -22.5f, true) - .d().uv(0, 0, 16, 16).rot(90).noCull(); + .d().uv(0, 0, 16, 16).rot(90).noCull().tint(); } private static Model fire_n_flip(String fire) { return ModelProvider.getModelProvider().getModel(fire).noOcclude() .add(0, 1, 0.01f, 16, 23.4f, 0.01f).noShade() - .s().uv(16, 0, 0, 16).noCull() + .s().uv(16, 0, 0, 16).noCull().tint() .add(0, 1, 0.01f, 16, 23.4f, 0.01f).noShade() - .n().uv(16, 0, 0, 16).noCull(); + .n().uv(16, 0, 0, 16).noCull().tint(); } private static Model fire_ne(String fire) { return ModelProvider.getModelProvider().getModel(fire).noOcclude() .add(0, 1, 0.01f, 16, 23.4f, 0.01f).noShade() - .s().uv(0, 0, 16, 16).noCull() + .s().uv(0, 0, 16, 16).noCull().tint() .add(0, 1, 0.01f, 16, 23.4f, 0.01f).noShade() - .n().uv(0, 0, 16, 16).noCull() + .n().uv(0, 0, 16, 16).noCull().tint() .add(15.99f, 1, 0, 15.99f, 23.4f, 16).noShade() - .e().uv(0, 0, 16, 16).noCull() + .e().uv(0, 0, 16, 16).noCull().tint() .add(15.99f, 1, 0, 15.99f, 23.4f, 16).noShade() - .w().uv(0, 0, 16, 16).noCull(); + .w().uv(0, 0, 16, 16).noCull().tint(); } private static Model fire_nsew_flip(String fire) { return ModelProvider.getModelProvider().getModel(fire).noOcclude() .add(0, 1, 0.01f, 16, 23.4f, 0.01f).noShade() - .s().uv(16, 0, 0, 16).noCull() + .s().uv(16, 0, 0, 16).noCull().tint() .add(0, 1, 0.01f, 16, 23.4f, 0.01f).noShade() - .n().uv(16, 0, 0, 16).noCull() + .n().uv(16, 0, 0, 16).noCull().tint() .add(0, 1, 15.99f, 16, 23.4f, 15.99f).noShade() - .s().uv(16, 0, 0, 16).noCull() + .s().uv(16, 0, 0, 16).noCull().tint() .add(0, 1, 15.99f, 16, 23.4f, 15.99f).noShade() - .n().uv(16, 0, 0, 16).noCull() + .n().uv(16, 0, 0, 16).noCull().tint() .add(15.99f, 1, 0, 15.99f, 23.4f, 16).noShade() - .e().uv(16, 0, 0, 16).noCull() + .e().uv(16, 0, 0, 16).noCull().tint() .add(15.99f, 1, 0, 15.99f, 23.4f, 16).noShade() - .w().uv(16, 0, 0, 16).noCull() + .w().uv(16, 0, 0, 16).noCull().tint() .add(0.01f, 1, 0, 0.01f, 23.4f, 16).noShade() - .e().uv(16, 0, 0, 16).noCull() + .e().uv(16, 0, 0, 16).noCull().tint() .add(15.99f, 1, 0, 0.01f, 23.4f, 16).noShade() - .w().uv(16, 0, 0, 16).noCull(); + .w().uv(16, 0, 0, 16).noCull().tint(); } private static Model fire_nse(String fire) { return ModelProvider.getModelProvider().getModel(fire).noOcclude() .add(0, 1, 0.01f, 16, 23.4f, 0.01f).noShade() - .s().uv(0, 0, 16, 16).noCull() + .s().uv(0, 0, 16, 16).noCull().tint() .add(0, 1, 0.01f, 16, 23.4f, 0.01f).noShade() - .n().uv(0, 0, 16, 16).noCull() + .n().uv(0, 0, 16, 16).noCull().tint() .add(0, 1, 15.99f, 16, 23.4f, 15.99f).noShade() - .s().uv(0, 0, 16, 16).noCull() + .s().uv(0, 0, 16, 16).noCull().tint() .add(0, 1, 15.99f, 16, 23.4f, 15.99f).noShade() - .n().uv(0, 0, 16, 16).noCull() + .n().uv(0, 0, 16, 16).noCull().tint() .add(15.99f, 1, 0, 15.99f, 23.4f, 16).noShade() - .e().uv(0, 0, 16, 16).noCull() + .e().uv(0, 0, 16, 16).noCull().tint() .add(15.99f, 1, 0, 15.99f, 23.4f, 16).noShade() - .w().uv(0, 0, 16, 16).noCull(); + .w().uv(0, 0, 16, 16).noCull().tint(); } private static Model fire_nse_flip(String fire) { return ModelProvider.getModelProvider().getModel(fire).noOcclude() .add(0, 1, 0.01f, 16, 23.4f, 0.01f).noShade() - .s().uv(16, 0, 0, 16).noCull() + .s().uv(16, 0, 0, 16).noCull().tint() .add(0, 1, 0.01f, 16, 23.4f, 0.01f).noShade() - .n().uv(16, 0, 0, 16).noCull() + .n().uv(16, 0, 0, 16).noCull().tint() .add(0, 1, 15.99f, 16, 23.4f, 15.99f).noShade() - .s().uv(16, 0, 0, 16).noCull() + .s().uv(16, 0, 0, 16).noCull().tint() .add(0, 1, 15.99f, 16, 23.4f, 15.99f).noShade() - .n().uv(16, 0, 0, 16).noCull() + .n().uv(16, 0, 0, 16).noCull().tint() .add(15.99f, 1, 0, 15.99f, 23.4f, 16).noShade() - .e().uv(16, 0, 0, 16).noCull() + .e().uv(16, 0, 0, 16).noCull().tint() .add(15.99f, 1, 0, 15.99f, 23.4f, 16).noShade() - .w().uv(16, 0, 0, 16).noCull(); + .w().uv(16, 0, 0, 16).noCull().tint(); } private static Model fire_nsu1_flip(String fire) { return ModelProvider.getModelProvider().getModel(fire).noOcclude() .add(0, 1, 0.01f, 16, 23.4f, 0.01f).noShade() - .s().uv(16, 0, 0, 16).noCull() + .s().uv(16, 0, 0, 16).noCull().tint() .add(0, 1, 0.01f, 16, 23.4f, 0.01f).noShade() - .n().uv(16, 0, 0, 16).noCull() + .n().uv(16, 0, 0, 16).noCull().tint() .add(0, 1, 15.99f, 16, 23.4f, 15.99f).noShade() - .s().uv(16, 0, 0, 16).noCull() + .s().uv(16, 0, 0, 16).noCull().tint() .add(0, 1, 15.99f, 16, 23.4f, 15.99f).noShade() - .n().uv(16, 0, 0, 16).noCull() + .n().uv(16, 0, 0, 16).noCull().tint() .add(0, 16, 0, 16, 16, 16).noShade().rotate(16, 16, 8, Facing.Axis.Z, 22.5f, true) - .d().uv(0, 0, 16, 16).rot(270).noCull() + .d().uv(0, 0, 16, 16).rot(270).noCull().tint() .add(0, 16, 0, 16, 16, 16).noShade().rotate(0, 16, 8, Facing.Axis.Z, -22.5f, true) - .d().uv(0, 0, 16, 16).rot(90).noCull(); + .d().uv(0, 0, 16, 16).rot(90).noCull().tint(); } private static Model fire_n(String fire) { return ModelProvider.getModelProvider().getModel(fire).noOcclude() .add(0, 1, 0.01f, 16, 23.4f, 0.01f).noShade() - .s().uv(0, 0, 16, 16).noCull() + .s().uv(0, 0, 16, 16).noCull().tint() .add(0, 1, 0.01f, 16, 23.4f, 0.01f).noShade() - .n().uv(0, 0, 16, 16).noCull(); + .n().uv(0, 0, 16, 16).noCull().tint(); } private static Model fire_ns(String fire) { return ModelProvider.getModelProvider().getModel(fire).noOcclude() .add(0, 1, 0.01f, 16, 23.4f, 0.01f).noShade() - .s().uv(0, 0, 16, 16).noCull() + .s().uv(0, 0, 16, 16).noCull().tint() .add(0, 1, 0.01f, 16, 23.4f, 0.01f).noShade() - .n().uv(0, 0, 16, 16).noCull() + .n().uv(0, 0, 16, 16).noCull().tint() .add(0, 1, 15.99f, 16, 23.4f, 15.99f).noShade() - .s().uv(0, 0, 16, 16).noCull() + .s().uv(0, 0, 16, 16).noCull().tint() .add(0, 1, 15.99f, 16, 23.4f, 15.99f).noShade() - .n().uv(0, 0, 16, 16).noCull(); + .n().uv(0, 0, 16, 16).noCull().tint(); } private static Model fire_neu1(String fire) { return ModelProvider.getModelProvider().getModel(fire).noOcclude() .add(0, 1, 0.01f, 16, 23.4f, 0.01f).noShade() - .s().uv(0, 0, 16, 16).noCull() + .s().uv(0, 0, 16, 16).noCull().tint() .add(0, 1, 0.01f, 16, 23.4f, 0.01f).noShade() - .n().uv(0, 0, 16, 16).noCull() + .n().uv(0, 0, 16, 16).noCull().tint() .add(15.99f, 1, 0, 15.99f, 23.4f, 16).noShade() - .e().uv(0, 0, 16, 16).noCull() + .e().uv(0, 0, 16, 16).noCull().tint() .add(15.99f, 1, 0, 15.99f, 23.4f, 16).noShade() - .w().uv(0, 0, 16, 16).noCull() + .w().uv(0, 0, 16, 16).noCull().tint() .add(0, 16, 0, 16, 16, 16).noShade().rotate(16, 16, 8, Facing.Axis.Z, 22.5f, true) - .d().uv(0, 0, 16, 16).rot(270).noCull() + .d().uv(0, 0, 16, 16).rot(270).noCull().tint() .add(0, 16, 0, 16, 16, 16).noShade().rotate(0, 16, 8, Facing.Axis.Z, -22.5f, true) - .d().uv(0, 0, 16, 16).rot(90).noCull(); + .d().uv(0, 0, 16, 16).rot(90).noCull().tint(); } private static Model fire_u2(String fire) { return ModelProvider.getModelProvider().getModel(fire).noOcclude() .add(0, 16, 0, 16, 16, 16).noShade().rotate(8, 16, 16, Facing.Axis.X, -22.5f, true) - .d().uv(0, 0, 16, 16).rot(180).noCull() + .d().uv(0, 0, 16, 16).rot(180).noCull().tint() .add(0, 16, 0, 16, 16, 16).noShade().rotate(8, 16, 0, Facing.Axis.X, 22.5f, true) - .d().uv(0, 0, 16, 16).noCull(); + .d().uv(0, 0, 16, 16).noCull().tint(); } private static Model fire_nseu2(String fire) { return ModelProvider.getModelProvider().getModel(fire).noOcclude() .add(0, 1, 0.01f, 16, 23.4f, 0.01f).noShade() - .s().uv(0, 0, 16, 16).noCull() + .s().uv(0, 0, 16, 16).noCull().tint() .add(0, 1, 0.01f, 16, 23.4f, 0.01f).noShade() - .n().uv(0, 0, 16, 16).noCull() + .n().uv(0, 0, 16, 16).noCull().tint() .add(0, 1, 15.99f, 16, 23.4f, 15.99f).noShade() - .s().uv(0, 0, 16, 16).noCull() + .s().uv(0, 0, 16, 16).noCull().tint() .add(0, 1, 15.99f, 16, 23.4f, 15.99f).noShade() - .n().uv(0, 0, 16, 16).noCull() + .n().uv(0, 0, 16, 16).noCull().tint() .add(15.99f, 1, 0, 15.99f, 23.4f, 16).noShade() - .e().uv(0, 0, 16, 16).noCull() + .e().uv(0, 0, 16, 16).noCull().tint() .add(15.99f, 1, 0, 15.99f, 23.4f, 16).noShade() - .w().uv(0, 0, 16, 16).noCull() + .w().uv(0, 0, 16, 16).noCull().tint() .add(0, 16, 0, 16, 16, 16).noShade().rotate(8, 16, 16, Facing.Axis.X, -22.5f, true) - .d().uv(0, 0, 16, 16).rot(180).noCull() + .d().uv(0, 0, 16, 16).rot(180).noCull().tint() .add(0, 16, 0, 16, 16, 16).noShade().rotate(8, 16, 0, Facing.Axis.X, 22.5f, true) - .d().uv(0, 0, 16, 16).noCull(); + .d().uv(0, 0, 16, 16).noCull().tint(); } private static Model fire_neu2(String fire) { return ModelProvider.getModelProvider().getModel(fire).noOcclude() .add(0, 1, 0.01f, 16, 23.4f, 0.01f).noShade() - .s().uv(0, 0, 16, 16).noCull() + .s().uv(0, 0, 16, 16).noCull().tint() .add(0, 1, 0.01f, 16, 23.4f, 0.01f).noShade() - .n().uv(0, 0, 16, 16).noCull() + .n().uv(0, 0, 16, 16).noCull().tint() .add(15.99f, 1, 0, 15.99f, 23.4f, 16).noShade() - .e().uv(0, 0, 16, 16).noCull() + .e().uv(0, 0, 16, 16).noCull().tint() .add(15.99f, 1, 0, 15.99f, 23.4f, 16).noShade() - .w().uv(0, 0, 16, 16).noCull() + .w().uv(0, 0, 16, 16).noCull().tint() .add(0, 16, 0, 16, 16, 16).noShade().rotate(8, 16, 16, Facing.Axis.X, -22.5f, true) - .d().uv(0, 0, 16, 16).rot(180).noCull() + .d().uv(0, 0, 16, 16).rot(180).noCull().tint() .add(0, 16, 0, 16, 16, 16).noShade().rotate(8, 16, 0, Facing.Axis.X, 22.5f, true) - .d().uv(0, 0, 16, 16).noCull(); + .d().uv(0, 0, 16, 16).noCull().tint(); } private static Model fire_nu2(String fire) { return ModelProvider.getModelProvider().getModel(fire).noOcclude() .add(0, 1, 0.01f, 16, 23.4f, 0.01f).noShade() - .s().uv(0, 0, 16, 16).noCull() + .s().uv(0, 0, 16, 16).noCull().tint() .add(0, 1, 0.01f, 16, 23.4f, 0.01f).noShade() - .n().uv(0, 0, 16, 16).noCull() + .n().uv(0, 0, 16, 16).noCull().tint() .add(0, 16, 0, 16, 16, 16).noShade().rotate(8, 16, 16, Facing.Axis.X, -22.5f, true) - .d().uv(0, 0, 16, 16).rot(180).noCull() + .d().uv(0, 0, 16, 16).rot(180).noCull().tint() .add(0, 16, 0, 16, 16, 16).noShade().rotate(8, 16, 0, Facing.Axis.X, 22.5f, true) - .d().uv(0, 0, 16, 16).noCull(); + .d().uv(0, 0, 16, 16).noCull().tint(); } private static Model fire_nseu1(String fire) { return ModelProvider.getModelProvider().getModel(fire).noOcclude() .add(0, 1, 0.01f, 16, 23.4f, 0.01f).noShade() - .s().uv(0, 0, 16, 16).noCull() + .s().uv(0, 0, 16, 16).noCull().tint() .add(0, 1, 0.01f, 16, 23.4f, 0.01f).noShade() - .n().uv(0, 0, 16, 16).noCull() + .n().uv(0, 0, 16, 16).noCull().tint() .add(0, 1, 15.99f, 16, 23.4f, 15.99f).noShade() - .s().uv(0, 0, 16, 16).noCull() + .s().uv(0, 0, 16, 16).noCull().tint() .add(0, 1, 15.99f, 16, 23.4f, 15.99f).noShade() - .n().uv(0, 0, 16, 16).noCull() + .n().uv(0, 0, 16, 16).noCull().tint() .add(15.99f, 1, 0, 15.99f, 23.4f, 16).noShade() - .e().uv(0, 0, 16, 16).noCull() + .e().uv(0, 0, 16, 16).noCull().tint() .add(15.99f, 1, 0, 15.99f, 23.4f, 16).noShade() - .w().uv(0, 0, 16, 16).noCull() + .w().uv(0, 0, 16, 16).noCull().tint() .add(0, 16, 0, 16, 16, 16).noShade().rotate(16, 16, 8, Facing.Axis.Z, 22.5f, true) - .d().uv(0, 0, 16, 16).rot(270).noCull() + .d().uv(0, 0, 16, 16).rot(270).noCull().tint() .add(0, 16, 0, 16, 16, 16).noShade().rotate(0, 16, 8, Facing.Axis.Z, -22.5f, true) - .d().uv(0, 0, 16, 16).rot(90).noCull(); + .d().uv(0, 0, 16, 16).rot(90).noCull().tint(); } private static Model fire_ns_flip(String fire) { return ModelProvider.getModelProvider().getModel(fire).noOcclude() .add(0, 1, 0.01f, 16, 23.4f, 0.01f).noShade() - .s().uv(16, 0, 0, 16).noCull() + .s().uv(16, 0, 0, 16).noCull().tint() .add(0, 1, 0.01f, 16, 23.4f, 0.01f).noShade() - .n().uv(16, 0, 0, 16).noCull() + .n().uv(16, 0, 0, 16).noCull().tint() .add(0, 1, 15.99f, 16, 23.4f, 15.99f).noShade() - .s().uv(16, 0, 0, 16).noCull() + .s().uv(16, 0, 0, 16).noCull().tint() .add(0, 1, 15.99f, 16, 23.4f, 15.99f).noShade() - .n().uv(16, 0, 0, 16).noCull(); + .n().uv(16, 0, 0, 16).noCull().tint(); } private static Model fire_nsewu1(String fire) { return ModelProvider.getModelProvider().getModel(fire).noOcclude() .add(0, 1, 0.01f, 16, 23.4f, 0.01f).noShade() - .s().uv(0, 0, 16, 16).noCull() + .s().uv(0, 0, 16, 16).noCull().tint() .add(0, 1, 0.01f, 16, 23.4f, 0.01f).noShade() - .n().uv(0, 0, 16, 16).noCull() + .n().uv(0, 0, 16, 16).noCull().tint() .add(0, 1, 15.99f, 16, 23.4f, 15.99f).noShade() - .s().uv(0, 0, 16, 16).noCull() + .s().uv(0, 0, 16, 16).noCull().tint() .add(0, 1, 15.99f, 16, 23.4f, 15.99f).noShade() - .n().uv(0, 0, 16, 16).noCull() + .n().uv(0, 0, 16, 16).noCull().tint() .add(15.99f, 1, 0, 15.99f, 23.4f, 16).noShade() - .e().uv(0, 0, 16, 16).noCull() + .e().uv(0, 0, 16, 16).noCull().tint() .add(15.99f, 1, 0, 15.99f, 23.4f, 16).noShade() - .w().uv(0, 0, 16, 16).noCull() + .w().uv(0, 0, 16, 16).noCull().tint() .add(0.01f, 1, 0, 0.01f, 23.4f, 16).noShade() - .e().uv(0, 0, 16, 16).noCull() + .e().uv(0, 0, 16, 16).noCull().tint() .add(15.99f, 1, 0, 0.01f, 23.4f, 16).noShade() - .w().uv(0, 0, 16, 16).noCull() + .w().uv(0, 0, 16, 16).noCull().tint() .add(0, 16, 0, 16, 16, 16).noShade().rotate(16, 16, 8, Facing.Axis.Z, 22.5f, true) - .d().uv(0, 0, 16, 16).rot(270).noCull() + .d().uv(0, 0, 16, 16).rot(270).noCull().tint() .add(0, 16, 0, 16, 16, 16).noShade().rotate(0, 16, 8, Facing.Axis.Z, -22.5f, true) - .d().uv(0, 0, 16, 16).rot(90).noCull(); + .d().uv(0, 0, 16, 16).rot(90).noCull().tint(); } private static Model fire_nsu1(String fire) { return ModelProvider.getModelProvider().getModel(fire).noOcclude() .add(0, 1, 0.01f, 16, 23.4f, 0.01f).noShade() - .s().uv(0, 0, 16, 16).noCull() + .s().uv(0, 0, 16, 16).noCull().tint() .add(0, 1, 0.01f, 16, 23.4f, 0.01f).noShade() - .n().uv(0, 0, 16, 16).noCull() + .n().uv(0, 0, 16, 16).noCull().tint() .add(0, 1, 15.99f, 16, 23.4f, 15.99f).noShade() - .s().uv(0, 0, 16, 16).noCull() + .s().uv(0, 0, 16, 16).noCull().tint() .add(0, 1, 15.99f, 16, 23.4f, 15.99f).noShade() - .n().uv(0, 0, 16, 16).noCull() + .n().uv(0, 0, 16, 16).noCull().tint() .add(0, 16, 0, 16, 16, 16).noShade().rotate(16, 16, 8, Facing.Axis.Z, 22.5f, true) - .d().uv(0, 0, 16, 16).rot(270).noCull() + .d().uv(0, 0, 16, 16).rot(270).noCull().tint() .add(0, 16, 0, 16, 16, 16).noShade().rotate(0, 16, 8, Facing.Axis.Z, -22.5f, true) - .d().uv(0, 0, 16, 16).rot(90).noCull(); + .d().uv(0, 0, 16, 16).rot(90).noCull().tint(); } private static Model fire_nsewu1_flip(String fire) { return ModelProvider.getModelProvider().getModel(fire).noOcclude() .add(0, 1, 0.01f, 16, 23.4f, 0.01f).noShade() - .s().uv(16, 0, 0, 16).noCull() + .s().uv(16, 0, 0, 16).noCull().tint() .add(0, 1, 0.01f, 16, 23.4f, 0.01f).noShade() - .n().uv(16, 0, 0, 16).noCull() + .n().uv(16, 0, 0, 16).noCull().tint() .add(0, 1, 15.99f, 16, 23.4f, 15.99f).noShade() - .s().uv(16, 0, 0, 16).noCull() + .s().uv(16, 0, 0, 16).noCull().tint() .add(0, 1, 15.99f, 16, 23.4f, 15.99f).noShade() - .n().uv(16, 0, 0, 16).noCull() + .n().uv(16, 0, 0, 16).noCull().tint() .add(15.99f, 1, 0, 15.99f, 23.4f, 16).noShade() - .e().uv(16, 0, 0, 16).noCull() + .e().uv(16, 0, 0, 16).noCull().tint() .add(15.99f, 1, 0, 15.99f, 23.4f, 16).noShade() - .w().uv(16, 0, 0, 16).noCull() + .w().uv(16, 0, 0, 16).noCull().tint() .add(0.01f, 1, 0, 0.01f, 23.4f, 16).noShade() - .e().uv(16, 0, 0, 16).noCull() + .e().uv(16, 0, 0, 16).noCull().tint() .add(15.99f, 1, 0, 0.01f, 23.4f, 16).noShade() - .w().uv(16, 0, 0, 16).noCull() + .w().uv(16, 0, 0, 16).noCull().tint() .add(0, 16, 0, 16, 16, 16).noShade().rotate(16, 16, 8, Facing.Axis.Z, 22.5f, true) - .d().uv(0, 0, 16, 16).rot(270).noCull() + .d().uv(0, 0, 16, 16).rot(270).noCull().tint() .add(0, 16, 0, 16, 16, 16).noShade().rotate(0, 16, 8, Facing.Axis.Z, -22.5f, true) - .d().uv(0, 0, 16, 16).rot(90).noCull(); + .d().uv(0, 0, 16, 16).rot(90).noCull().tint(); } private static Model fire_ne_flip(String fire) { return ModelProvider.getModelProvider().getModel(fire).noOcclude() .add(0, 1, 0.01f, 16, 23.4f, 0.01f).noShade() - .s().uv(16, 0, 0, 16).noCull() + .s().uv(16, 0, 0, 16).noCull().tint() .add(0, 1, 0.01f, 16, 23.4f, 0.01f).noShade() - .n().uv(16, 0, 0, 16).noCull() + .n().uv(16, 0, 0, 16).noCull().tint() .add(15.99f, 1, 0, 15.99f, 23.4f, 16).noShade() - .e().uv(16, 0, 0, 16).noCull() + .e().uv(16, 0, 0, 16).noCull().tint() .add(15.99f, 1, 0, 15.99f, 23.4f, 16).noShade() - .w().uv(16, 0, 0, 16).noCull(); + .w().uv(16, 0, 0, 16).noCull().tint(); } private static Model fire_nseu1_flip(String fire) { return ModelProvider.getModelProvider().getModel(fire).noOcclude() .add(0, 1, 0.01f, 16, 23.4f, 0.01f).noShade() - .s().uv(16, 0, 0, 16).noCull() + .s().uv(16, 0, 0, 16).noCull().tint() .add(0, 1, 0.01f, 16, 23.4f, 0.01f).noShade() - .n().uv(16, 0, 0, 16).noCull() + .n().uv(16, 0, 0, 16).noCull().tint() .add(0, 1, 15.99f, 16, 23.4f, 15.99f).noShade() - .s().uv(16, 0, 0, 16).noCull() + .s().uv(16, 0, 0, 16).noCull().tint() .add(0, 1, 15.99f, 16, 23.4f, 15.99f).noShade() - .n().uv(16, 0, 0, 16).noCull() + .n().uv(16, 0, 0, 16).noCull().tint() .add(15.99f, 1, 0, 15.99f, 23.4f, 16).noShade() - .e().uv(16, 0, 0, 16).noCull() + .e().uv(16, 0, 0, 16).noCull().tint() .add(15.99f, 1, 0, 15.99f, 23.4f, 16).noShade() - .w().uv(16, 0, 0, 16).noCull() + .w().uv(16, 0, 0, 16).noCull().tint() .add(0, 16, 0, 16, 16, 16).noShade().rotate(16, 16, 8, Facing.Axis.Z, 22.5f, true) - .d().uv(0, 0, 16, 16).rot(270).noCull() + .d().uv(0, 0, 16, 16).rot(270).noCull().tint() .add(0, 16, 0, 16, 16, 16).noShade().rotate(0, 16, 8, Facing.Axis.Z, -22.5f, true) - .d().uv(0, 0, 16, 16).rot(90).noCull(); + .d().uv(0, 0, 16, 16).rot(90).noCull().tint(); } - private static Model getFireModel(boolean alt, boolean flip, int upper, boolean n, boolean s, boolean w, boolean e) { - String tex = alt ? "fire_layer_1" : "fire_layer_0"; + protected static Model getFireModel(String tex, boolean flip, int upper, boolean n, boolean s, boolean w, boolean e) { if(!e && !flip && !n && !s && upper == 0 && !w) return fire_floor(tex); else if(!e && !flip && !n && s && upper == 0 && !w) @@ -1155,7 +1134,7 @@ public class BlockFire extends Block } public Model getModel(ModelProvider provider, String name, State state) { - return getFireModel(state.getValue(ALT), state.getValue(FLIP), state.getValue(UPPER), + return getFireModel(state.getValue(ALT) ? "fire_layer_1" : "fire_layer_0", state.getValue(FLIP), state.getValue(UPPER), state.getValue(NORTH), state.getValue(SOUTH), state.getValue(WEST), state.getValue(EAST)); } @@ -1167,4 +1146,8 @@ public class BlockFire extends Block map.put("blocks/fire_layer_0", "fire1"); map.put("blocks/fire_layer_1", "fire2"); } + + public boolean canExtinguish() { + return true; + } } diff --git a/common/src/common/block/BlockTintedFire.java b/common/src/common/block/BlockTintedFire.java new file mode 100644 index 0000000..fa450ad --- /dev/null +++ b/common/src/common/block/BlockTintedFire.java @@ -0,0 +1,35 @@ +package common.block; + +import java.util.Map; + +import common.model.Model; +import common.model.ModelProvider; +import common.util.BlockPos; +import common.world.IWorldAccess; +import common.world.State; + +public class BlockTintedFire extends BlockFire { + private final int tint; + + public BlockTintedFire(int tint) { + this.tint = tint; + } + + public int getRenderColor(State state) { + return this.tint; + } + + public int colorMultiplier(IWorldAccess worldIn, BlockPos pos, int renderPass) { + return this.tint; + } + + public Model getModel(ModelProvider provider, String name, State state) { + return getFireModel(state.getValue(ALT) ? "flame_layer_1" : "flame_layer_0", state.getValue(FLIP), state.getValue(UPPER), + state.getValue(NORTH), state.getValue(SOUTH), state.getValue(WEST), state.getValue(EAST)); + } + + public void getAnimatedTextures(Map map) { + map.put("blocks/flame_layer_0", "flame1"); + map.put("blocks/flame_layer_1", "flame2"); + } +} diff --git a/common/src/common/init/BlockRegistry.java b/common/src/common/init/BlockRegistry.java index 2139cff..c348564 100755 --- a/common/src/common/init/BlockRegistry.java +++ b/common/src/common/init/BlockRegistry.java @@ -306,6 +306,10 @@ public abstract class BlockRegistry { .setDisplay(wood.getDisplay() + "setzling")); } + registerBlock(252, "soul_fire", + (new BlockTintedFire(0x4010ff)).setHardness(0.0F).setLightLevel(1.0F).setStepSound(SoundType.CLOTH).setDisplay("Feuer der Seelen")); + registerBlock(253, "black_fire", + (new BlockTintedFire(0x202020)).setHardness(0.0F).setLightLevel(1.0F).setStepSound(SoundType.CLOTH).setDisplay("Dunkles Feuer")); registerBlock(254, "web", (new BlockWeb()).setLightOpacity(1).setHardness(4.0F).setDisplay("Spinnennetz")); registerBlock(255, "fire", (new BlockFire()).setHardness(0.0F).setLightLevel(1.0F).setStepSound(SoundType.CLOTH).setDisplay("Feuer")); diff --git a/common/src/common/init/Blocks.java b/common/src/common/init/Blocks.java index eb86097..056473c 100755 --- a/common/src/common/init/Blocks.java +++ b/common/src/common/init/Blocks.java @@ -134,6 +134,8 @@ public abstract class Blocks { public static final Block obsidian = get("obsidian"); public static final Block torch = get("torch"); public static final BlockFire fire = (BlockFire)get("fire"); + public static final BlockFire black_fire = (BlockFire)get("black_fire"); + public static final BlockFire soul_fire = (BlockFire)get("soul_fire"); public static final Block mob_spawner = get("mob_spawner"); public static final Block oak_stairs = get("oak_stairs"); public static final BlockChest chest = (BlockChest)get("chest"); diff --git a/common/src/common/init/FlammabilityRegistry.java b/common/src/common/init/FlammabilityRegistry.java index 54f8f47..0d0a632 100755 --- a/common/src/common/init/FlammabilityRegistry.java +++ b/common/src/common/init/FlammabilityRegistry.java @@ -1,34 +1,51 @@ package common.init; +import java.util.Map; + import common.block.Block; +import common.collect.Maps; public abstract class FlammabilityRegistry { - private static void setFlammable(Block blockIn, int encouragement, int flammability) { - Blocks.fire.setFireInfo(blockIn, encouragement, flammability); + private static final Map ENCOURAGEMENT = Maps.newIdentityHashMap(); + private static final Map FLAMMABILITY = Maps.newIdentityHashMap(); + + private static void setFlammable(Block block, int encouragement, int flammability) { + ENCOURAGEMENT.put(block, encouragement); + FLAMMABILITY.put(block, flammability); } static void register() { - for(WoodType wood : WoodType.values()) { - setFlammable(BlockRegistry.getRegisteredBlock(wood.getName() + "_planks"), 5, 20); - setFlammable(BlockRegistry.getRegisteredBlock(wood.getName() + "_slab"), 5, 20); - setFlammable(BlockRegistry.getRegisteredBlock(wood.getName() + "_stairs"), 5, 20); - setFlammable(BlockRegistry.getRegisteredBlock(wood.getName() + "_fence"), 5, 20); - setFlammable(BlockRegistry.getRegisteredBlock(wood.getName() + "_fence_gate"), 5, 20); - setFlammable(BlockRegistry.getRegisteredBlock(wood.getName() + "_log"), 5, 5); - setFlammable(BlockRegistry.getRegisteredBlock(wood.getName() + "_leaves"), 30, 60); - setFlammable(BlockRegistry.getRegisteredBlock(wood.getName() + "_sapling"), 15, 100); - } - setFlammable(Blocks.bookshelf, 30, 20); - setFlammable(Blocks.tnt, 15, 100); - setFlammable(Blocks.tallgrass, 60, 100); - setFlammable(Blocks.double_plant, 60, 100); - setFlammable(Blocks.flower, 60, 100); - setFlammable(Blocks.deadbush, 60, 100); - setFlammable(Blocks.dry_leaves, 60, 100); - setFlammable(Blocks.wool, 30, 60); - setFlammable(Blocks.vine, 15, 100); - setFlammable(Blocks.coal_block, 5, 5); - setFlammable(Blocks.hay_block, 60, 20); - setFlammable(Blocks.carpet, 60, 20); + for(WoodType wood : WoodType.values()) { + setFlammable(BlockRegistry.getRegisteredBlock(wood.getName() + "_planks"), 5, 20); + setFlammable(BlockRegistry.getRegisteredBlock(wood.getName() + "_slab"), 5, 20); + setFlammable(BlockRegistry.getRegisteredBlock(wood.getName() + "_stairs"), 5, 20); + setFlammable(BlockRegistry.getRegisteredBlock(wood.getName() + "_fence"), 5, 20); + setFlammable(BlockRegistry.getRegisteredBlock(wood.getName() + "_fence_gate"), 5, 20); + setFlammable(BlockRegistry.getRegisteredBlock(wood.getName() + "_log"), 5, 5); + setFlammable(BlockRegistry.getRegisteredBlock(wood.getName() + "_leaves"), 30, 60); + setFlammable(BlockRegistry.getRegisteredBlock(wood.getName() + "_sapling"), 15, 100); + } + setFlammable(Blocks.bookshelf, 30, 20); + setFlammable(Blocks.tnt, 15, 100); + setFlammable(Blocks.tallgrass, 60, 100); + setFlammable(Blocks.double_plant, 60, 100); + setFlammable(Blocks.flower, 60, 100); + setFlammable(Blocks.deadbush, 60, 100); + setFlammable(Blocks.dry_leaves, 60, 100); + setFlammable(Blocks.wool, 30, 60); + setFlammable(Blocks.vine, 15, 100); + setFlammable(Blocks.coal_block, 5, 5); + setFlammable(Blocks.hay_block, 60, 20); + setFlammable(Blocks.carpet, 60, 20); + } + + public static int getFlammability(Block block) { + Integer value = FLAMMABILITY.get(block); + return value == null ? 0 : value.intValue(); + } + + public static int getEncouragement(Block block) { + Integer value = ENCOURAGEMENT.get(block); + return value == null ? 0 : value.intValue(); } } diff --git a/common/src/common/init/ItemRegistry.java b/common/src/common/init/ItemRegistry.java index 18a101d..5ff4a91 100755 --- a/common/src/common/init/ItemRegistry.java +++ b/common/src/common/init/ItemRegistry.java @@ -396,8 +396,10 @@ public abstract class ItemRegistry { for(Weather weather : Weather.values()) { registerItem("weather_token_" + weather.getName(), new ItemWeatherToken(weather).setDisplay("Wetterkristall").setTab(CheatTab.tabTools)); } - - registerItem("flint_and_steel", (new ItemFlintAndSteel()).setDisplay("Feuerzeug")); + + registerItem("flint_and_steel", (new ItemFlintAndSteel(Blocks.fire)).setDisplay("Feuerzeug")); + registerItem("burning_soul", (new ItemFlintAndSteel(Blocks.soul_fire)).setDisplay("Brennende Seele")); + registerItem("dark_lighter", (new ItemFlintAndSteel(Blocks.black_fire)).setDisplay("Verdunkelndes Feuerzeug")); registerItem("apple", (new ItemFood(4, false)).setDisplay("Apfel").setMaxStackSize(128)); registerItem("bow", (new ItemBow()).setDisplay("Bogen")); registerItem("boltgun", (new ItemBoltgun()).setDisplay("Bolter")); @@ -614,6 +616,8 @@ public abstract class ItemRegistry { // registerSpecial(Blocks.reeds); registerSpecial(Blocks.fire); + registerSpecial(Blocks.soul_fire); + registerSpecial(Blocks.black_fire); registerSpecial(Blocks.portal); registerSpecial(Blocks.floor_portal); // registerSpecial(Blocks.standing_sign); diff --git a/common/src/common/item/ItemFlintAndSteel.java b/common/src/common/item/ItemFlintAndSteel.java index 52ba772..5d029a4 100755 --- a/common/src/common/item/ItemFlintAndSteel.java +++ b/common/src/common/item/ItemFlintAndSteel.java @@ -1,7 +1,7 @@ package common.item; +import common.block.BlockFire; import common.entity.npc.EntityNPC; -import common.init.Blocks; import common.init.SoundEvent; import common.material.Material; import common.util.BlockPos; @@ -10,8 +10,11 @@ import common.world.World; public class ItemFlintAndSteel extends Item { - public ItemFlintAndSteel() + private final BlockFire fireBlock; + + public ItemFlintAndSteel(BlockFire fireBlock) { + this.fireBlock = fireBlock; this.maxStackSize = 1; this.setMaxDamage(64); this.setTab(CheatTab.tabTools); @@ -33,7 +36,7 @@ public class ItemFlintAndSteel extends Item if (worldIn.getState(pos).getBlock().getMaterial() == Material.air) { worldIn.playSound(SoundEvent.IGNITE, (double)pos.getX() + 0.5D, (double)pos.getY() + 0.5D, (double)pos.getZ() + 0.5D, 1.0F); - worldIn.setState(pos, Blocks.fire.getState()); + worldIn.setState(pos, this.fireBlock.getState()); } stack.damageItem(1, playerIn); diff --git a/common/src/common/world/World.java b/common/src/common/world/World.java index 869fcc4..41c6290 100755 --- a/common/src/common/world/World.java +++ b/common/src/common/world/World.java @@ -1233,7 +1233,7 @@ public abstract class World implements IWorldAccess { for(int i2 = i1; i2 < j1; ++i2) { Block block = this.getState(blockpos$mutableblockpos.set(k1, l1, i2)).getBlock(); - if(block == Blocks.fire || block == Blocks.flowing_lava || block == Blocks.lava) { + if(block == Blocks.fire || block == Blocks.soul_fire || block == Blocks.flowing_lava || block == Blocks.lava || block.getMaterial().isHotLiquid()) { return true; } } @@ -1406,7 +1406,7 @@ public abstract class World implements IWorldAccess { public boolean extinguishFire(EntityNPC player, BlockPos pos, Facing side) { pos = pos.offset(side); - if(this.getState(pos).getBlock() == Blocks.fire) { + if(this.getState(pos).getBlock().canExtinguish()) { this.playAuxSFX(player, 1004, pos, 0); this.setBlockToAir(pos); return true; diff --git a/server/src/server/clipboard/ReorderRegistry.java b/server/src/server/clipboard/ReorderRegistry.java index 8e872b9..4f346ec 100755 --- a/server/src/server/clipboard/ReorderRegistry.java +++ b/server/src/server/clipboard/ReorderRegistry.java @@ -54,6 +54,8 @@ public abstract class ReorderRegistry { PLACE_LAST.add(Blocks.red_mushroom_block); PLACE_LAST.add(Blocks.torch); PLACE_LAST.add(Blocks.fire); + PLACE_LAST.add(Blocks.soul_fire); + PLACE_LAST.add(Blocks.black_fire); PLACE_LAST.add(Blocks.redstone); PLACE_LAST.add(Blocks.wheat); PLACE_LAST.add(Blocks.ladder); From 71e50743fd4da419a541aae2e7c9b1d33d972ceb Mon Sep 17 00:00:00 2001 From: Sen Date: Sat, 24 May 2025 18:18:04 +0200 Subject: [PATCH 062/200] split chunk class into server and client --- client/src/client/Client.java | 6 +- client/src/client/network/ClientPlayer.java | 12 +- .../client/renderer/RegionRenderCache.java | 70 ++-- client/src/client/renderer/RenderGlobal.java | 6 +- client/src/client/renderer/ViewFrustum.java | 6 +- .../client/renderer/chunk/RenderChunk.java | 6 +- client/src/client/world/ChunkClient.java | 140 +++++++ .../{EmptyChunk.java => ChunkEmpty.java} | 15 +- client/src/client/world/WorldClient.java | 36 +- common/src/common/block/BlockTorch.java | 17 +- common/src/common/dimension/Dimension.java | 35 +- .../FeatureLake.java => dimension/Lake.java} | 6 +- .../Liquid.java} | 6 +- .../FeatureOre.java => dimension/Ore.java} | 6 +- common/src/common/entity/npc/EntitySlime.java | 6 +- .../src/common/packet/SPacketChunkData.java | 82 +--- .../common/packet/SPacketMapChunkBulk.java | 33 +- .../packet/SPacketMultiBlockChange.java | 41 +- common/src/common/pathfinding/PathCache.java | 26 +- common/src/common/tileentity/TileEntity.java | 4 +- common/src/common/world/AWorldServer.java | 1 + common/src/common/world/Chunk.java | 392 ++---------------- common/src/common/world/ChunkCache.java | 27 -- .../{worldgen => world}/DebugStates.java | 3 +- common/src/common/world/World.java | 17 +- server/src/server/network/Player.java | 104 ++++- server/src/server/world/ChunkServer.java | 216 ++++++++++ server/src/server/world/Region.java | 7 +- server/src/server/world/Spawner.java | 3 +- server/src/server/world/WorldServer.java | 112 ++--- .../src/server/worldgen/BiomeGenLayered.java | 1 - .../src/server/worldgen/BiomeGenSingle.java | 1 - .../src/server}/worldgen/BiomeGenerator.java | 2 +- .../src/server/worldgen/GeneratorDebug.java | 2 +- .../worldgen/structure/StructureVillage.java | 2 +- 35 files changed, 734 insertions(+), 715 deletions(-) create mode 100644 client/src/client/world/ChunkClient.java rename client/src/client/world/{EmptyChunk.java => ChunkEmpty.java} (90%) rename common/src/common/{worldgen/FeatureLake.java => dimension/Lake.java} (70%) rename common/src/common/{worldgen/FeatureLiquid.java => dimension/Liquid.java} (67%) rename common/src/common/{worldgen/FeatureOre.java => dimension/Ore.java} (70%) delete mode 100755 common/src/common/world/ChunkCache.java rename common/src/common/{worldgen => world}/DebugStates.java (94%) create mode 100644 server/src/server/world/ChunkServer.java rename {common/src/common => server/src/server}/worldgen/BiomeGenerator.java (96%) diff --git a/client/src/client/Client.java b/client/src/client/Client.java index 082184b..cfa961b 100755 --- a/client/src/client/Client.java +++ b/client/src/client/Client.java @@ -94,6 +94,7 @@ import client.window.Keysym; import client.window.Wheel; import client.window.Window; import client.window.WindowEvent; +import client.world.ChunkClient; import client.world.WorldClient; import common.biome.Biome; import common.block.Block; @@ -156,7 +157,6 @@ import common.util.HitPosition; import common.util.LazyLoadBase; import common.util.Util; import common.util.HitPosition.ObjectType; -import common.world.Chunk; import common.world.LightType; import common.world.State; import common.world.World; @@ -1735,8 +1735,8 @@ public class Client implements IThreadListener { String bline; String lline; if(this.world.isBlockLoaded(blockpos)) { - Chunk chunk = this.world.getChunk(blockpos); - biome = chunk.getBiome(blockpos, null); + ChunkClient chunk = this.world.getChunk(blockpos); + biome = chunk.getBiome(blockpos); bline = "Biom: " + biome.display + " (" + biome.id + ")" + /* (this.debugHideInfo ? "" : */ (", D: " + TextColor.stripCodes(this.world.dimension.getFormattedName(false)) + " (" + this.world.dimension.getDimensionId() + ")"); diff --git a/client/src/client/network/ClientPlayer.java b/client/src/client/network/ClientPlayer.java index 3a6b688..4a4fdce 100755 --- a/client/src/client/network/ClientPlayer.java +++ b/client/src/client/network/ClientPlayer.java @@ -28,6 +28,7 @@ import client.gui.ingame.GuiSign; import client.gui.ingame.GuiForm; import client.renderer.particle.EntityPickupFX; import client.renderer.texture.EntityTexManager; +import client.world.ChunkClient; import client.world.WorldClient; import common.attributes.Attribute; import common.attributes.AttributeInstance; @@ -137,7 +138,6 @@ import common.tileentity.TileEntityMachine; import common.tileentity.TileEntitySign; import common.util.BlockPos; import common.village.MerchantRecipeList; -import common.world.Chunk; import common.world.Explosion; import common.world.Weather; import common.world.World; @@ -741,9 +741,9 @@ public class ClientPlayer extends NetHandler implements IClientPlayer { NetHandler.checkThread(packetIn, this, this.gameController, this.clientWorldController); - for (SPacketMultiBlockChange.BlockUpdateData s22packetmultiblockchange$blockupdatedata : packetIn.getChangedBlocks()) + for (SPacketMultiBlockChange.BlockUpdateData update : packetIn.getChangedBlocks()) { - this.clientWorldController.invalidateRegionAndSetBlock(s22packetmultiblockchange$blockupdatedata.getPos(), s22packetmultiblockchange$blockupdatedata.getBlockState()); + this.clientWorldController.invalidateRegionAndSetBlock(SPacketMultiBlockChange.getPos(packetIn.getChunkPos(), update.getRawPos()), update.getBlockState()); } } @@ -766,7 +766,7 @@ public class ClientPlayer extends NetHandler implements IClientPlayer } // this.clientWorldController.invalidateBlockReceiveRegion(packetIn.getChunkX() << 4, 0, packetIn.getChunkZ() << 4, (packetIn.getChunkX() << 4) + 15, 512, (packetIn.getChunkZ() << 4) + 15); - Chunk chunk = this.clientWorldController.getChunk(packetIn.getChunkX(), packetIn.getChunkZ()); + ChunkClient chunk = this.clientWorldController.getChunk(packetIn.getChunkX(), packetIn.getChunkZ()); chunk.setData(packetIn.getExtractedDataBytes(), packetIn.getExtractedExtend(), packetIn.hasBiomes()); this.clientWorldController.markBlockRangeForRenderUpdate(packetIn.getChunkX() << 4, -World.MAX_SIZE_Y, packetIn.getChunkZ() << 4, (packetIn.getChunkX() << 4) + 15, World.MAX_SIZE_Y, (packetIn.getChunkZ() << 4) + 15); @@ -779,7 +779,7 @@ public class ClientPlayer extends NetHandler implements IClientPlayer public void handleBiomes(SPacketBiomes packetIn) { NetHandler.checkThread(packetIn, this, this.gameController, this.clientWorldController); - Chunk chunk = this.clientWorldController.getChunk(packetIn.getChunkX(), packetIn.getChunkZ()); + ChunkClient chunk = this.clientWorldController.getChunk(packetIn.getChunkX(), packetIn.getChunkZ()); chunk.setBiomes(packetIn.getBiomes()); this.clientWorldController.markBlockRangeForRenderUpdate(packetIn.getChunkX() << 4, -World.MAX_SIZE_Y, packetIn.getChunkZ() << 4, (packetIn.getChunkX() << 4) + 15, World.MAX_SIZE_Y, (packetIn.getChunkZ() << 4) + 15); } @@ -1412,7 +1412,7 @@ public class ClientPlayer extends NetHandler implements IClientPlayer int k = packetIn.getChunkZ(i); this.clientWorldController.doPreChunk(j, k, true); // this.clientWorldController.invalidateBlockReceiveRegion(j << 4, 0, k << 4, (j << 4) + 15, 512, (k << 4) + 15); - Chunk chunk = this.clientWorldController.getChunk(j, k); + ChunkClient chunk = this.clientWorldController.getChunk(j, k); chunk.setData(packetIn.getChunkBytes(i), packetIn.getChunkExtend(i), true); this.clientWorldController.markBlockRangeForRenderUpdate(j << 4, -World.MAX_SIZE_Y, k << 4, (j << 4) + 15, World.MAX_SIZE_Y, (k << 4) + 15); diff --git a/client/src/client/renderer/RegionRenderCache.java b/client/src/client/renderer/RegionRenderCache.java index e0ec2fc..5d90530 100755 --- a/client/src/client/renderer/RegionRenderCache.java +++ b/client/src/client/renderer/RegionRenderCache.java @@ -2,48 +2,62 @@ package client.renderer; import java.util.Arrays; +import client.world.ChunkClient; +import client.world.WorldClient; import common.biome.Biome; import common.init.Blocks; import common.tileentity.TileEntity; import common.util.BlockPos; import common.util.Facing; import common.util.Vec3i; -import common.world.Chunk; -import common.world.ChunkCache; import common.world.IWorldAccess; import common.world.LightType; import common.world.State; import common.world.World; -public class RegionRenderCache extends ChunkCache implements IWorldAccess +public class RegionRenderCache implements IWorldAccess { private static final State DEFAULT_STATE = Blocks.air.getState(); - - private final World worldObj; + + private final int xPos; + private final int zPos; + private final ChunkClient[][] chunks; + private final World world; private final BlockPos position; private final boolean empty; private int[] combinedLights; private State[] blockStates; - public RegionRenderCache(World worldIn, BlockPos posFromIn, BlockPos posToIn, int subIn) + public RegionRenderCache(WorldClient world, BlockPos from, BlockPos to, int sub) { - super(worldIn, posFromIn, posToIn, subIn); - this.worldObj = worldIn; - boolean empty = true; - for (int i1 = posFromIn.getX() >> 4; i1 <= posToIn.getX() >> 4; ++i1) + this.world = world; + this.xPos = from.getX() - sub >> 4; + this.zPos = from.getZ() - sub >> 4; + int x2 = to.getX() + sub >> 4; + int z2 = to.getZ() + sub >> 4; + this.chunks = new ChunkClient[x2 - this.xPos + 1][z2 - this.zPos + 1]; + for (int x = this.xPos; x <= x2; ++x) { - for (int j1 = posFromIn.getZ() >> 4; j1 <= posToIn.getZ() >> 4; ++j1) + for (int z = this.zPos; z <= z2; ++z) { - Chunk chunk = this.chunkArray[i1 - this.chunkX][j1 - this.chunkZ]; + this.chunks[x - this.xPos][z - this.zPos] = world.getChunk(x, z); + } + } + boolean empty = true; + for (int x = from.getX() >> 4; x <= to.getX() >> 4; ++x) + { + for (int z = from.getZ() >> 4; z <= to.getZ() >> 4; ++z) + { + ChunkClient chunk = this.chunks[x - this.xPos][z - this.zPos]; - if (chunk != null && !chunk.isEmpty(posFromIn.getY(), posToIn.getY())) + if (chunk != null && !chunk.isEmpty(from.getY(), to.getY())) { empty = false; } } } this.empty = empty; - this.position = posFromIn.subtract(new Vec3i(subIn, subIn, subIn)); + this.position = from.subtract(new Vec3i(sub, sub, sub)); int i = 16000; this.combinedLights = new int[16000]; Arrays.fill((int[])this.combinedLights, (int) - 1); @@ -52,9 +66,9 @@ public class RegionRenderCache extends ChunkCache implements IWorldAccess public TileEntity getTileEntity(BlockPos pos) { - int i = (pos.getX() >> 4) - this.chunkX; - int j = (pos.getZ() >> 4) - this.chunkZ; - return this.chunkArray[i][j].getTileEntity(pos, TileEntity.EnumCreateEntityType.QUEUED); + int i = (pos.getX() >> 4) - this.xPos; + int j = (pos.getZ() >> 4) - this.zPos; + return this.chunks[i][j].getTileEntity(pos, TileEntity.EnumCreateEntityType.QUEUED); } public int getCombinedLight(BlockPos pos, int lightValue) @@ -89,9 +103,9 @@ public class RegionRenderCache extends ChunkCache implements IWorldAccess { if (pos.getY() >= -World.MAX_SIZE_Y && pos.getY() < World.MAX_SIZE_Y) { - int i = (pos.getX() >> 4) - this.chunkX; - int j = (pos.getZ() >> 4) - this.chunkZ; - return this.chunkArray[i][j].getState(pos); + int i = (pos.getX() >> 4) - this.xPos; + int j = (pos.getZ() >> 4) - this.zPos; + return this.chunks[i][j].getState(pos); } else { @@ -127,12 +141,12 @@ public class RegionRenderCache extends ChunkCache implements IWorldAccess public Biome getBiomeGenForCoords(BlockPos pos) { - return this.worldObj.getBiomeGenForCoords(pos); + return this.world.getBiomeGenForCoords(pos); } private int getLightForExt(LightType p_175629_1_, BlockPos pos) { - if (p_175629_1_ == LightType.SKY && this.worldObj.dimension.hasNoLight()) + if (p_175629_1_ == LightType.SKY && this.world.dimension.hasNoLight()) { return 0; } @@ -161,9 +175,9 @@ public class RegionRenderCache extends ChunkCache implements IWorldAccess } else { - int i = (pos.getX() >> 4) - this.chunkX; - int j = (pos.getZ() >> 4) - this.chunkZ; - return this.chunkArray[i][j].getLight(p_175629_1_, pos); + int i = (pos.getX() >> 4) - this.xPos; + int j = (pos.getZ() >> 4) - this.zPos; + return this.chunks[i][j].getLight(p_175629_1_, pos); } } else @@ -185,9 +199,9 @@ public class RegionRenderCache extends ChunkCache implements IWorldAccess { if (pos.getY() >= -World.MAX_SIZE_Y && pos.getY() < World.MAX_SIZE_Y) { - int i = (pos.getX() >> 4) - this.chunkX; - int j = (pos.getZ() >> 4) - this.chunkZ; - return this.chunkArray[i][j].getLight(p_175628_1_, pos); + int i = (pos.getX() >> 4) - this.xPos; + int j = (pos.getZ() >> 4) - this.zPos; + return this.chunks[i][j].getLight(p_175628_1_, pos); } else { diff --git a/client/src/client/renderer/RenderGlobal.java b/client/src/client/renderer/RenderGlobal.java index 07a6f6a..302609c 100755 --- a/client/src/client/renderer/RenderGlobal.java +++ b/client/src/client/renderer/RenderGlobal.java @@ -25,6 +25,7 @@ import client.renderer.texture.TextureAtlasSprite; import client.renderer.texture.TextureManager; import client.renderer.texture.TextureMap; import client.renderer.tileentity.TileEntityRendererDispatcher; +import client.world.ChunkClient; import client.world.WorldClient; import common.block.Block; import common.block.BlockChest; @@ -51,7 +52,6 @@ import common.util.Facing; import common.util.HitPosition; import common.util.Vec3; import common.util.Vector3f; -import common.world.Chunk; import common.world.State; import common.world.World; @@ -604,7 +604,7 @@ public class RenderGlobal for (RenderGlobal.ContainerLocalRenderInformation renderglobal$containerlocalrenderinformation : this.renderInfos) { - Chunk chunk = this.theWorld.getChunk(renderglobal$containerlocalrenderinformation.renderChunk.getPosition()); + ChunkClient chunk = this.theWorld.getChunk(renderglobal$containerlocalrenderinformation.renderChunk.getPosition()); ClassInheritanceMultiMap classinheritancemultimap = chunk.getEntities()[ExtMath.clampi(renderglobal$containerlocalrenderinformation.renderChunk.getPosition().getY() / 16, 0, 31)]; if (!classinheritancemultimap.isEmpty()) @@ -935,7 +935,7 @@ public class RenderGlobal { VisGraph visgraph = new VisGraph(); BlockPos blockpos = new BlockPos(pos.getX() >> 4 << 4, pos.getY() >> 4 << 4, pos.getZ() >> 4 << 4); - Chunk chunk = this.theWorld.getChunk(blockpos); + ChunkClient chunk = this.theWorld.getChunk(blockpos); for (BlockPos.MutableBlockPos blockpos$mutableblockpos : BlockPos.getAllInBoxMutable(blockpos, blockpos.add(15, 15, 15))) { diff --git a/client/src/client/renderer/ViewFrustum.java b/client/src/client/renderer/ViewFrustum.java index a9a95af..ede3e1c 100755 --- a/client/src/client/renderer/ViewFrustum.java +++ b/client/src/client/renderer/ViewFrustum.java @@ -1,14 +1,14 @@ package client.renderer; import client.renderer.chunk.RenderChunk; +import client.world.WorldClient; import common.util.BlockPos; import common.util.ExtMath; -import common.world.World; public class ViewFrustum { protected final RenderGlobal renderGlobal; - protected final World world; + protected final WorldClient world; protected int countChunksY; protected int countChunksX; protected int countChunksZ; @@ -18,7 +18,7 @@ public class ViewFrustum return i < 0 ? -((-i - 1) / 16) - 1 : i / 16; } - public ViewFrustum(World worldIn, int renderDistanceChunks, RenderGlobal p_i46246_3_) + public ViewFrustum(WorldClient worldIn, int renderDistanceChunks, RenderGlobal p_i46246_3_) { this.renderGlobal = p_i46246_3_; this.world = worldIn; diff --git a/client/src/client/renderer/chunk/RenderChunk.java b/client/src/client/renderer/chunk/RenderChunk.java index 8667584..06de2e2 100755 --- a/client/src/client/renderer/chunk/RenderChunk.java +++ b/client/src/client/renderer/chunk/RenderChunk.java @@ -19,6 +19,7 @@ import client.renderer.RenderGlobal; import client.renderer.VertexBuffer; import client.renderer.tileentity.TileEntityRendererDispatcher; import client.renderer.tileentity.TileEntitySpecialRenderer; +import client.world.WorldClient; import common.block.Block; import common.collect.Maps; import common.collect.Sets; @@ -28,11 +29,10 @@ import common.util.BlockPos; import common.util.BoundingBox; import common.util.Facing; import common.world.State; -import common.world.World; public class RenderChunk { - private World world; + private WorldClient world; private final RenderGlobal renderGlobal; public static int renderChunksUpdated; private BlockPos position; @@ -49,7 +49,7 @@ public class RenderChunk private boolean needsUpdate = true; private EnumMap mapEnumFacing = Maps.newEnumMap(Facing.class); - public RenderChunk(World worldIn, RenderGlobal renderGlobalIn, BlockPos blockPosIn, int indexIn) + public RenderChunk(WorldClient worldIn, RenderGlobal renderGlobalIn, BlockPos blockPosIn, int indexIn) { this.world = worldIn; this.renderGlobal = renderGlobalIn; diff --git a/client/src/client/world/ChunkClient.java b/client/src/client/world/ChunkClient.java new file mode 100644 index 0000000..a016246 --- /dev/null +++ b/client/src/client/world/ChunkClient.java @@ -0,0 +1,140 @@ +package client.world; + +import common.biome.Biome; +import common.block.Block; +import common.init.Blocks; +import common.tileentity.TileEntity; +import common.util.BlockPos; +import common.util.NibbleArray; +import common.world.BlockArray; +import common.world.Chunk; +import common.world.World; + +public class ChunkClient extends Chunk { + public ChunkClient(World world, int x, int z) { + super(world, x, z); + } + + private void clearArrays() { + this.blocks.clearMap(); + this.blockList.clear(); + this.bottom = Integer.MAX_VALUE; + this.top = Integer.MIN_VALUE; + } + + private void genHeights() { + int top = this.top; + int bottom = this.bottom; + this.minHeight = Integer.MAX_VALUE; + + for(int x = 0; x < 16; ++x) { + for(int z = 0; z < 16; ++z) { + this.precHeight[x + (z << 4)] = -99999999; + + for(int y = top + 16; y > bottom; --y) { + Block block = this.getBlock0(x, y - 1, z); + + if(block.getLightOpacity() != 0) { + this.height[z << 4 | x] = y; + + if(y < this.minHeight) { + this.minHeight = y; + } + + break; + } + } + } + } + + this.modified = true; + } + + public boolean isEmpty(int bottom, int top) { + for(int y = bottom; y <= top; y += 16) { + BlockArray stor = this.getArray(y >> 4); + + if(stor != null ? !stor.isEmpty() : (y < 0 && this.fillerBlock != Blocks.air)) { + return false; + } + } + + return true; + } + + public void setData(byte[] data, int[] extend, boolean biomes) { + int pos = 0; + boolean sky = !this.world.dimension.hasNoLight(); + + if(biomes) { + this.clearArrays(); + } + for(int cy : extend) { + BlockArray arr = this.getArray(cy); + if(arr == null) { + arr = new BlockArray(cy << 4, sky, null); + this.setArray(arr); + } + + char[] blocks = arr.getData(); + + for(int k = 0; k < blocks.length; ++k) { + blocks[k] = (char)((data[pos + 1] & 255) << 8 | data[pos] & 255); + pos += 2; + } + } + + for(int cy : extend) { + BlockArray arr = this.getArray(cy); + if(arr != null) { + NibbleArray light = arr.getBlocklight(); + System.arraycopy(data, pos, light.getData(), 0, light.getData().length); + pos += light.getData().length; + } + } + + if(sky) { + for(int cy : extend) { + BlockArray arr = this.getArray(cy); + if(arr != null) { + NibbleArray slight = arr.getSkylight(); + System.arraycopy(data, pos, slight.getData(), 0, slight.getData().length); + pos += slight.getData().length; + } + } + } + + if(biomes) { + System.arraycopy(data, pos, this.biomes, 0, this.biomes.length); + } + + for(int cy : extend) { + BlockArray arr = this.getArray(cy); + if(arr != null) { + arr.update(); + } + } + + this.lightInit = true; + this.populated = true; + this.genHeights(); + + for(TileEntity tile : this.tiles.values()) { + tile.updateContainingBlockInfo(); + } + } + + public void setLoaded() { + this.loaded = true; + } + + public Biome getBiome(BlockPos pos) { + int x = pos.getX() & 15; + int z = pos.getZ() & 15; + return Biome.getBiomeDef(this.biomes[z << 4 | x] & 255); + } + + public boolean isDummy() { + return false; + } +} diff --git a/client/src/client/world/EmptyChunk.java b/client/src/client/world/ChunkEmpty.java similarity index 90% rename from client/src/client/world/EmptyChunk.java rename to client/src/client/world/ChunkEmpty.java index 24ded26..31a78d2 100755 --- a/client/src/client/world/EmptyChunk.java +++ b/client/src/client/world/ChunkEmpty.java @@ -10,17 +10,15 @@ import common.init.Blocks; import common.tileentity.TileEntity; import common.util.BlockPos; import common.util.BoundingBox; -import common.world.Chunk; import common.world.LightType; import common.world.State; -import common.worldgen.BiomeGenerator; -public class EmptyChunk extends Chunk { +public class ChunkEmpty extends ChunkClient { private final int liquidY; private final State liquid; private final Block liquidBlock; - public EmptyChunk(WorldClient world) { + public ChunkEmpty(WorldClient world) { super(world, 0, 0); this.liquidY = world.dimension.getSeaLevel() - 1; this.liquid = world.dimension.getLiquid(); @@ -65,10 +63,7 @@ public class EmptyChunk extends Chunk { public void removeTileEntity(BlockPos pos) { } - - public void setModified() { - } - + public void getEntities(Entity exclude, BoundingBox bb, List list, Predicate pred) { } @@ -108,7 +103,7 @@ public class EmptyChunk extends Chunk { public void setData(byte[] data, int[] extend, boolean biomes) { } - public Biome getBiome(BlockPos pos, BiomeGenerator gen) { + public Biome getBiome(BlockPos pos) { return Biome.DEF_BIOME; } @@ -128,7 +123,7 @@ public class EmptyChunk extends Chunk { return false; } - public void setLoaded(boolean loaded) { + public void setLoaded() { } public int getLowest() { diff --git a/client/src/client/world/WorldClient.java b/client/src/client/world/WorldClient.java index 32fa891..1ef10ff 100755 --- a/client/src/client/world/WorldClient.java +++ b/client/src/client/world/WorldClient.java @@ -33,7 +33,6 @@ import common.util.ExtMath; import common.util.LongHashMap; import common.util.Vec3; import common.util.BlockPos.MutableBlockPos; -import common.world.Chunk; import common.world.AWorldClient; import common.world.State; import common.world.World; @@ -46,11 +45,11 @@ public class WorldClient extends AWorldClient private final Set entityList = Sets.newHashSet(); private final Set spawnQueue = Sets.newHashSet(); private final Set previousActive = Sets.newHashSet(); - private final LongHashMap chunkMapping = new LongHashMap(); - private final List chunkListing = Lists.newArrayList(); + private final LongHashMap chunkMapping = new LongHashMap(); + private final List chunkListing = Lists.newArrayList(); private final Set emptyChunkListing = Sets.newHashSet(); private final Set nextEmptyChunkListing = Sets.newHashSet(); - private final Chunk emptyChunk = new EmptyChunk(this); + private final ChunkClient emptyChunk = new ChunkEmpty(this); // public final Profiler profiler; protected int lastLightning; protected Vec3 lightColor = new Vec3(0xffffff); @@ -120,7 +119,7 @@ public class WorldClient extends AWorldClient } } long time = System.currentTimeMillis(); - for (Chunk chunk : this.chunkListing) + for (ChunkClient chunk : this.chunkListing) { chunk.update(System.currentTimeMillis() - time > 5L); } @@ -149,7 +148,7 @@ public class WorldClient extends AWorldClient { int j = chunkcoordintpair.x * 16; int k = chunkcoordintpair.z * 16; - Chunk chunk = this.getChunk(chunkcoordintpair.x, chunkcoordintpair.z); + ChunkClient chunk = this.getChunk(chunkcoordintpair.x, chunkcoordintpair.z); chunk.enqueueRelight(); this.previousActive.add(chunkcoordintpair); ++i; @@ -169,14 +168,14 @@ public class WorldClient extends AWorldClient { if(this.chunkMapping.getValueByKey(id) != null) this.doPreChunk(x, z, false); - Chunk chunk = new Chunk(this, x, z); + ChunkClient chunk = new ChunkClient(this, x, z); this.chunkMapping.add(id, chunk); this.chunkListing.add(chunk); - chunk.setLoaded(true); + chunk.setLoaded(); } else { - Chunk chunk = this.getChunk(x, z); + ChunkClient chunk = this.getChunk(x, z); chunk.onChunkUnload(); this.chunkMapping.remove(id); this.chunkListing.remove(chunk); @@ -387,11 +386,26 @@ public class WorldClient extends AWorldClient this.gm.effectRenderer.addEffect(new EntityFirework.StarterFX(this.gm.world, x, y, z, motionX, motionY, motionZ, this.gm.effectRenderer, compund)); } - public Chunk getChunk(int x, int z) + public ChunkClient getChunk(int x, int z) { - Chunk chunk = this.chunkMapping.getValueByKey(LongHashMap.packInt(x, z)); + ChunkClient chunk = this.chunkMapping.getValueByKey(LongHashMap.packInt(x, z)); return chunk == null ? this.emptyChunk : chunk; } + + public ChunkClient getChunk(BlockPos pos) { + return this.getChunk(pos.getX() >> 4, pos.getZ() >> 4); + } + + public Biome getBiomeGenForCoords(BlockPos pos) { + if(this.isBlockLoaded(pos)) + return this.getChunk(pos).getBiome(pos); + else + return Biome.DEF_BIOME; + } + + protected boolean isLoaded(int x, int z, boolean allowEmpty) { + return allowEmpty || !this.getChunk(x, z).isDummy(); + } public String getInfo() { diff --git a/common/src/common/block/BlockTorch.java b/common/src/common/block/BlockTorch.java index 3012c52..ca7552b 100755 --- a/common/src/common/block/BlockTorch.java +++ b/common/src/common/block/BlockTorch.java @@ -19,7 +19,6 @@ import common.util.BoundingBox; import common.util.Facing; import common.util.HitPosition; import common.util.Vec3; -import common.world.Chunk; import common.world.AWorldClient; import common.world.State; import common.world.World; @@ -36,20 +35,10 @@ public class BlockTorch extends Block }); private static boolean isBlockNormalCube(World world, BlockPos pos, boolean def) { - if(!World.isValid(pos)) { + if(!World.isValid(pos) || (world.client && !world.isBlockLoaded(pos, false))) return def; - } - else { - Chunk chunk = world.getChunk(pos.getX() >> 4, pos.getZ() >> 4); - - if(chunk.isDummy()) { - return def; - } - else { - Block block = world.getState(pos).getBlock(); - return block.getMaterial().isOpaque() && block.isFullCube(); - } - } + Block block = world.getState(pos).getBlock(); + return block.getMaterial().isOpaque() && block.isFullCube(); } public BlockTorch() diff --git a/common/src/common/dimension/Dimension.java b/common/src/common/dimension/Dimension.java index 5e63fa8..5ed1030 100755 --- a/common/src/common/dimension/Dimension.java +++ b/common/src/common/dimension/Dimension.java @@ -21,9 +21,6 @@ import common.util.ExtMath; import common.util.Vec3; import common.world.State; import common.world.Weather; -import common.worldgen.FeatureLake; -import common.worldgen.FeatureLiquid; -import common.worldgen.FeatureOre; public abstract class Dimension extends Nameable implements Comparable { public class GeneratorSettings { @@ -288,9 +285,9 @@ public abstract class Dimension extends Nameable implements Comparable ores = Lists.newArrayList(); - private final List lakes = Lists.newArrayList(); - private final List liquids = Lists.newArrayList(); + private final List ores = Lists.newArrayList(); + private final List lakes = Lists.newArrayList(); + private final List liquids = Lists.newArrayList(); private long seed = 0L; @@ -584,24 +581,24 @@ public abstract class Dimension extends Nameable implements Comparable getOres() { + public List getOres() { return this.ores; } - public List getLakes() { + public List getLakes() { return this.lakes; } - public List getLiquids() { + public List getLiquids() { return this.liquids; } } diff --git a/common/src/common/worldgen/FeatureLake.java b/common/src/common/dimension/Lake.java similarity index 70% rename from common/src/common/worldgen/FeatureLake.java rename to common/src/common/dimension/Lake.java index b279e52..2b21b58 100644 --- a/common/src/common/worldgen/FeatureLake.java +++ b/common/src/common/dimension/Lake.java @@ -1,8 +1,8 @@ -package common.worldgen; +package common.dimension; import common.world.State; -public class FeatureLake { +public class Lake { public final State state; public final State filler; public final State top; @@ -11,7 +11,7 @@ public class FeatureLake { public final int maxHeight; public final boolean ratiod; - public FeatureLake(State state, State filler, State top, int chance, int minHeight, int maxHeight, boolean ratiod) { + public Lake(State state, State filler, State top, int chance, int minHeight, int maxHeight, boolean ratiod) { this.state = state; this.filler = filler; this.top = top; diff --git a/common/src/common/worldgen/FeatureLiquid.java b/common/src/common/dimension/Liquid.java similarity index 67% rename from common/src/common/worldgen/FeatureLiquid.java rename to common/src/common/dimension/Liquid.java index d2794c0..b1643f3 100644 --- a/common/src/common/worldgen/FeatureLiquid.java +++ b/common/src/common/dimension/Liquid.java @@ -1,15 +1,15 @@ -package common.worldgen; +package common.dimension; import common.world.State; -public class FeatureLiquid { +public class Liquid { public final State state; public final int chance; public final int minHeight; public final int maxHeight; public final boolean lower; - public FeatureLiquid(State state, int chance, int minHeight, int maxHeight, boolean lower) { + public Liquid(State state, int chance, int minHeight, int maxHeight, boolean lower) { this.state = state; this.chance = chance; this.minHeight = minHeight; diff --git a/common/src/common/worldgen/FeatureOre.java b/common/src/common/dimension/Ore.java similarity index 70% rename from common/src/common/worldgen/FeatureOre.java rename to common/src/common/dimension/Ore.java index 38237ff..5171c68 100644 --- a/common/src/common/worldgen/FeatureOre.java +++ b/common/src/common/dimension/Ore.java @@ -1,8 +1,8 @@ -package common.worldgen; +package common.dimension; import common.world.State; -public class FeatureOre { +public class Ore { public final State state; public final int count; public final int more; @@ -11,7 +11,7 @@ public class FeatureOre { public final int max; public final boolean dist; - public FeatureOre(State state, int count, int more, int size, int min, int max, boolean dist) { + public Ore(State state, int count, int more, int size, int min, int max, boolean dist) { this.state = state; this.count = count; this.more = more; diff --git a/common/src/common/entity/npc/EntitySlime.java b/common/src/common/entity/npc/EntitySlime.java index 2fb6b0a..da33477 100755 --- a/common/src/common/entity/npc/EntitySlime.java +++ b/common/src/common/entity/npc/EntitySlime.java @@ -15,7 +15,6 @@ import common.pathfinding.PathNavigateGround; import common.rng.Random; import common.util.BlockPos; import common.util.ExtMath; -import common.world.Chunk; import common.world.World; import common.world.AWorldServer; @@ -386,8 +385,7 @@ public class EntitySlime extends EntityNPC public boolean getCanSpawnHere() { BlockPos blockpos = new BlockPos(ExtMath.floord(this.posX), 0, ExtMath.floord(this.posZ)); - Chunk chunk = this.worldObj.getChunk(blockpos); - + // if (this.worldObj.getWorldInfo().getTerrainType() == WorldType.FLAT && this.rand.nextInt(4) != 1) // { // return false; @@ -403,7 +401,7 @@ public class EntitySlime extends EntityNPC return super.getCanSpawnHere(); } - if (this.rand.zrange(10) == 0 && getRandomWithSeed((AWorldServer)this.worldObj, chunk.xPos, chunk.zPos, 987234911L).zrange(10) == 0 && this.posY < 40.0D) + if (this.rand.zrange(10) == 0 && getRandomWithSeed((AWorldServer)this.worldObj, blockpos.getX() >> 4, blockpos.getZ() >> 4, 987234911L).zrange(10) == 0 && this.posY < 40.0D) { return super.getCanSpawnHere(); } diff --git a/common/src/common/packet/SPacketChunkData.java b/common/src/common/packet/SPacketChunkData.java index ee87912..66438d6 100755 --- a/common/src/common/packet/SPacketChunkData.java +++ b/common/src/common/packet/SPacketChunkData.java @@ -1,15 +1,9 @@ package common.packet; import java.io.IOException; -import java.util.List; -import java.util.Set; - -import common.collect.Lists; import common.network.IClientPlayer; import common.network.Packet; import common.network.PacketBuffer; -import common.world.BlockArray; -import common.world.Chunk; public class SPacketChunkData implements Packet { @@ -22,12 +16,12 @@ public class SPacketChunkData implements Packet { } - public SPacketChunkData(Chunk chunkIn, boolean biomes, int[] extend) + public SPacketChunkData(int x, int z, boolean biomes, SPacketChunkData.Extracted data) { - this.chunkX = chunkIn.xPos; - this.chunkZ = chunkIn.zPos; + this.chunkX = x; + this.chunkZ = z; this.biomes = biomes; - this.extractedData = getExtractedData(chunkIn, biomes, !chunkIn.getWorld().dimension.hasNoLight(), extend); + this.extractedData = data; } /** @@ -74,7 +68,7 @@ public class SPacketChunkData implements Packet return this.extractedData.data; } - protected static int getSize(int segments, boolean overworld, boolean biomes) + public static int getSize(int segments, boolean overworld, boolean biomes) { int i = segments * 2 * 16 * 16 * 16; int j = segments * 16 * 16 * 16 / 2; @@ -83,72 +77,6 @@ public class SPacketChunkData implements Packet return i + j + k + l; } - public static SPacketChunkData.Extracted getExtractedData(Chunk chunk, boolean biomes, boolean overworld, int[] extend) - { - Set aextendedblockstorage = chunk.getStorage(); - SPacketChunkData.Extracted s21packetchunkdata$extracted = new SPacketChunkData.Extracted(); - List list = Lists.newArrayList(); - - if(extend == null) { - for(BlockArray arr : aextendedblockstorage) { - if(arr != null && (!biomes || !arr.isEmpty())) - list.add(arr); - } - } - else { - for(int cy : extend) { - BlockArray arr = chunk.getArray(cy); - if(arr != null && (!biomes || !arr.isEmpty())) - list.add(arr); - } - } - extend = new int[list.size()]; - for(int z = 0; z < extend.length; z++) { - extend[z] = list.get(z).getY() >> 4; - } - - s21packetchunkdata$extracted.extend = extend; - s21packetchunkdata$extracted.data = new byte[getSize(extend.length, overworld, biomes)]; - int j = 0; - - for (BlockArray extendedblockstorage1 : list) - { - char[] achar = extendedblockstorage1.getData(); - - for (char c0 : achar) - { - s21packetchunkdata$extracted.data[j++] = (byte)(c0 & 255); - s21packetchunkdata$extracted.data[j++] = (byte)(c0 >> 8 & 255); - } - } - - for (BlockArray extendedblockstorage2 : list) - { - j = copyTo(extendedblockstorage2.getBlocklight().getData(), s21packetchunkdata$extracted.data, j); - } - - if (overworld) - { - for (BlockArray extendedblockstorage3 : list) - { - j = copyTo(extendedblockstorage3.getSkylight().getData(), s21packetchunkdata$extracted.data, j); - } - } - - if (biomes) - { - copyTo(chunk.getBiomes(), s21packetchunkdata$extracted.data, j); - } - - return s21packetchunkdata$extracted; - } - - private static int copyTo(byte[] src, byte[] dest, int offset) - { - System.arraycopy(src, 0, dest, offset, src.length); - return offset + src.length; - } - public int getChunkX() { return this.chunkX; diff --git a/common/src/common/packet/SPacketMapChunkBulk.java b/common/src/common/packet/SPacketMapChunkBulk.java index 4c7c4bb..4ba19d2 100755 --- a/common/src/common/packet/SPacketMapChunkBulk.java +++ b/common/src/common/packet/SPacketMapChunkBulk.java @@ -1,48 +1,35 @@ package common.packet; import java.io.IOException; -import java.util.List; - import common.network.IClientPlayer; import common.network.Packet; import common.network.PacketBuffer; -import common.world.Chunk; public class SPacketMapChunkBulk implements Packet { private int[] xPositions; private int[] zPositions; private SPacketChunkData.Extracted[] chunksData; - private boolean isOverworld; + private boolean sky; public SPacketMapChunkBulk() { } - public SPacketMapChunkBulk(List chunks) + public SPacketMapChunkBulk(int[] x, int[] z, SPacketChunkData.Extracted[] chunks, boolean sky) { - int i = chunks.size(); - this.xPositions = new int[i]; - this.zPositions = new int[i]; - this.chunksData = new SPacketChunkData.Extracted[i]; - this.isOverworld = !((Chunk)chunks.get(0)).getWorld().dimension.hasNoLight(); - - for (int j = 0; j < i; ++j) - { - Chunk chunk = (Chunk)chunks.get(j); - SPacketChunkData.Extracted s21packetchunkdata$extracted = SPacketChunkData.getExtractedData(chunk, true, this.isOverworld, null); - this.xPositions[j] = chunk.xPos; - this.zPositions[j] = chunk.zPos; - this.chunksData[j] = s21packetchunkdata$extracted; - } + this.xPositions = x; + this.zPositions = z; + this.chunksData = chunks; + this.sky = sky; } - + /** * Reads the raw packet data from the data stream. */ public void readPacketData(PacketBuffer buf) throws IOException { - this.isOverworld = buf.readBoolean(); + this.sky = buf.readBoolean(); int i = buf.readVarIntFromBuffer(); this.xPositions = new int[i]; this.zPositions = new int[i]; @@ -57,7 +44,7 @@ public class SPacketMapChunkBulk implements Packet for(int z = 0; z < this.chunksData[j].extend.length; z++) { this.chunksData[j].extend[z] = buf.readVarIntFromBuffer(); } - this.chunksData[j].data = new byte[SPacketChunkData.getSize(this.chunksData[j].extend.length, this.isOverworld, true)]; + this.chunksData[j].data = new byte[SPacketChunkData.getSize(this.chunksData[j].extend.length, this.sky, true)]; } for (int k = 0; k < i; ++k) @@ -71,7 +58,7 @@ public class SPacketMapChunkBulk implements Packet */ public void writePacketData(PacketBuffer buf) throws IOException { - buf.writeBoolean(this.isOverworld); + buf.writeBoolean(this.sky); buf.writeVarIntToBuffer(this.chunksData.length); for (int i = 0; i < this.xPositions.length; ++i) diff --git a/common/src/common/packet/SPacketMultiBlockChange.java b/common/src/common/packet/SPacketMultiBlockChange.java index f6b4a4b..6694b98 100755 --- a/common/src/common/packet/SPacketMultiBlockChange.java +++ b/common/src/common/packet/SPacketMultiBlockChange.java @@ -8,7 +8,6 @@ import common.network.Packet; import common.network.PacketBuffer; import common.util.BlockPos; import common.util.ChunkPos; -import common.world.Chunk; import common.world.State; public class SPacketMultiBlockChange implements Packet @@ -16,19 +15,18 @@ public class SPacketMultiBlockChange implements Packet private ChunkPos chunkPosCoord; private SPacketMultiBlockChange.BlockUpdateData[] changedBlocks; + public static BlockPos getPos(ChunkPos pos, long position) + { + return new BlockPos(new BlockPos((pos.x << 4) + (int)(position >> 36 & 15L), (int)(position & 4294967295L), (pos.z << 4) + (int)(position >> 32 & 15L))); + } + public SPacketMultiBlockChange() { } - - public SPacketMultiBlockChange(int p_i45181_1_, long[] crammedPositionsIn, Chunk chunkIn) - { - this.chunkPosCoord = new ChunkPos(chunkIn.xPos, chunkIn.zPos); - this.changedBlocks = new SPacketMultiBlockChange.BlockUpdateData[p_i45181_1_]; - - for (int i = 0; i < this.changedBlocks.length; ++i) - { - this.changedBlocks[i] = new SPacketMultiBlockChange.BlockUpdateData(crammedPositionsIn[i], chunkIn); - } + + public SPacketMultiBlockChange(ChunkPos pos, SPacketMultiBlockChange.BlockUpdateData[] changes) { + this.chunkPosCoord = pos; + this.changedBlocks = changes; } /** @@ -74,7 +72,12 @@ public class SPacketMultiBlockChange implements Packet return this.changedBlocks; } - public class BlockUpdateData + public ChunkPos getChunkPos() + { + return this.chunkPosCoord; + } + + public static class BlockUpdateData { private final long position; private final State blockState; @@ -84,19 +87,7 @@ public class SPacketMultiBlockChange implements Packet this.position = raw; this.blockState = state; } - - public BlockUpdateData(long raw, Chunk chunkIn) - { - this.position = raw; - this.blockState = chunkIn.getState(this.getPos()); - } - - public BlockPos getPos() - { - ChunkPos pos = SPacketMultiBlockChange.this.chunkPosCoord; - return new BlockPos(new BlockPos((pos.x << 4) + (int)(this.position >> 36 & 15L), (int)(this.position & 4294967295L), (pos.z << 4) + (int)(this.position >> 32 & 15L))); - } - + public long getRawPos() { return this.position; diff --git a/common/src/common/pathfinding/PathCache.java b/common/src/common/pathfinding/PathCache.java index 255b82c..b33d97b 100755 --- a/common/src/common/pathfinding/PathCache.java +++ b/common/src/common/pathfinding/PathCache.java @@ -3,16 +3,30 @@ package common.pathfinding; import common.init.Blocks; import common.util.BlockPos; import common.world.Chunk; -import common.world.ChunkCache; import common.world.IBlockAccess; import common.world.State; import common.world.World; -public class PathCache extends ChunkCache implements IBlockAccess +public class PathCache implements IBlockAccess { - public PathCache(World worldIn, BlockPos posFromIn, BlockPos posToIn) + protected final int chunkX; + protected final int chunkZ; + protected final Chunk[][] data; + + public PathCache(World world, BlockPos pos1, BlockPos pos2) { - super(worldIn, posFromIn, posToIn, 0); + this.chunkX = pos1.getX() >> 4; + this.chunkZ = pos1.getZ() >> 4; + int cx2 = pos2.getX() >> 4; + int cz2 = pos2.getZ() >> 4; + this.data = new Chunk[cx2 - this.chunkX + 1][cz2 - this.chunkZ + 1]; + for (int x = this.chunkX; x <= cx2; ++x) + { + for (int z = this.chunkZ; z <= cz2; ++z) + { + this.data[x - this.chunkX][z - this.chunkZ] = world.getChunk(x, z); + } + } } public State getState(BlockPos pos) @@ -22,9 +36,9 @@ public class PathCache extends ChunkCache implements IBlockAccess int i = (pos.getX() >> 4) - this.chunkX; int j = (pos.getZ() >> 4) - this.chunkZ; - if (i >= 0 && i < this.chunkArray.length && j >= 0 && j < this.chunkArray[i].length) + if (i >= 0 && i < this.data.length && j >= 0 && j < this.data[i].length) { - Chunk chunk = this.chunkArray[i][j]; + Chunk chunk = this.data[i][j]; if (chunk != null) { diff --git a/common/src/common/tileentity/TileEntity.java b/common/src/common/tileentity/TileEntity.java index 31da294..ce17bb0 100755 --- a/common/src/common/tileentity/TileEntity.java +++ b/common/src/common/tileentity/TileEntity.java @@ -7,6 +7,7 @@ import common.log.Log; import common.nbt.NBTTagCompound; import common.network.Packet; import common.util.BlockPos; +import common.world.AWorldServer; import common.world.State; import common.world.World; @@ -128,7 +129,8 @@ public abstract class TileEntity { State iblockstate = this.worldObj.getState(this.pos); this.blockMetadata = iblockstate.getBlock().getMetaFromState(iblockstate); - this.worldObj.markChunkDirty(this.pos, this); + if(!this.worldObj.client) + ((AWorldServer)this.worldObj).markChunkDirty(this.pos); if (this.getBlockType() != Blocks.air) { diff --git a/common/src/common/world/AWorldServer.java b/common/src/common/world/AWorldServer.java index dbbda3f..3ca91f0 100644 --- a/common/src/common/world/AWorldServer.java +++ b/common/src/common/world/AWorldServer.java @@ -46,4 +46,5 @@ public abstract class AWorldServer extends World { public abstract T findNearestEntityWithinAABB(Class entityType, BoundingBox aabb, T closestTo); public abstract long getTime(); public abstract void setBiome(BlockPos pos, Biome biome); + public abstract void markChunkDirty(BlockPos pos); } diff --git a/common/src/common/world/Chunk.java b/common/src/common/world/Chunk.java index 9feacdc..841292b 100755 --- a/common/src/common/world/Chunk.java +++ b/common/src/common/world/Chunk.java @@ -7,58 +7,49 @@ import java.util.Set; import java.util.concurrent.ConcurrentLinkedQueue; import java.util.function.Predicate; -import common.biome.Biome; import common.block.Block; import common.block.ITileEntityProvider; import common.collect.Maps; import common.collect.Sets; import common.entity.Entity; -import common.init.BlockRegistry; import common.init.Blocks; import common.log.Log; import common.material.Material; -import common.rng.Random; import common.tileentity.TileEntity; import common.util.BlockPos; import common.util.BoundingBox; -import common.util.ChunkPos; import common.util.ClassInheritanceMultiMap; import common.util.ExtMath; import common.util.Facing; import common.util.IntHashMap; -import common.util.NibbleArray; -import common.worldgen.BiomeGenerator; -import common.worldgen.DebugStates; -public class Chunk { +public abstract class Chunk { public final int xPos; public final int zPos; - private final World world; - private final State filler; - private final Block fillerBlock; - private final IntHashMap blocks = new IntHashMap(); - private final Set blockList = Sets.newHashSet(); - private final byte[] biomes = new byte[256]; - private final int[] precHeight = new int[256]; - private final boolean[] updateSky = new boolean[256]; - private final int[] height = new int[256]; - private final Map tiles = Maps.newHashMap(); - private final ClassInheritanceMultiMap[] entities = new ClassInheritanceMultiMap[32]; - private final ConcurrentLinkedQueue tileQueue = new ConcurrentLinkedQueue(); + protected final World world; + protected final State filler; + protected final Block fillerBlock; + protected final IntHashMap blocks = new IntHashMap(); + protected final Set blockList = Sets.newHashSet(); + protected final byte[] biomes = new byte[256]; + protected final int[] precHeight = new int[256]; + protected final boolean[] updateSky = new boolean[256]; + protected final int[] height = new int[256]; + protected final Map tiles = Maps.newHashMap(); + protected final ClassInheritanceMultiMap[] entities = new ClassInheritanceMultiMap[32]; + protected final ConcurrentLinkedQueue tileQueue = new ConcurrentLinkedQueue(); - private boolean loaded; - private boolean gapUpdate; - private boolean populated; - private boolean lightInit; - private boolean updated; - private boolean modified; - private boolean hasEntity; - private int minHeight; - private int lightChecks = Integer.MAX_VALUE; - private int bottom = Integer.MAX_VALUE; - private int top = Integer.MIN_VALUE; - private long lastSave; - private long inhabited; + protected boolean loaded; + protected boolean gapUpdate; + protected boolean populated; + protected boolean lightInit; + protected boolean updated; + protected boolean modified; + protected boolean hasEntity; + protected int minHeight; + protected int lightChecks = Integer.MAX_VALUE; + protected int bottom = Integer.MAX_VALUE; + protected int top = Integer.MIN_VALUE; public Chunk(World world, int x, int z) { this.world = world; @@ -72,101 +63,16 @@ public class Chunk { Arrays.fill(this.precHeight, -99999999); Arrays.fill(this.biomes, (byte)-1); } - - public Chunk(World world, short[] data, int height, boolean base, boolean ceil, Random rand, Biome[] biomes, int x, int z) { - this(world, x, z); - boolean sky = !world.dimension.hasNoLight(); - for(int bx = 0; bx < 16; ++bx) { - for(int bz = 0; bz < 16; ++bz) { - for(int by = 0; by < height; ++by) { - State state = BlockRegistry.STATEMAP.getByValue(data[bx << 4 | bz | by << 8]); - if(state != null && state.getBlock().getMaterial() != Material.air) { - int y = by >> 4; - BlockArray arr = this.getArray(y); - if(arr == null) { - arr = new BlockArray(y << 4, sky, null); - this.setArray(arr); - } - arr.set(bx, by & 15, bz, state); - } - } - } - } - if(base) { - Block caves = world.dimension.getCaveFiller().getBlock(); - BlockArray arr = this.getArray(0); - if(arr == null) { - arr = new BlockArray(0, sky, null); - this.setArray(arr); - } - for(int bx = 0; bx < 16; ++bx) { - for(int bz = 0; bz < 16; ++bz) { - for(int by = 0; by < 5; ++by) { - if(by <= rand.zrange(5)) { - Block block = arr.get(bx, by, bz).getBlock(); - if(block == Blocks.air || block.getMaterial().isLiquid() || block == caves) - arr.set(bx, by, bz, this.filler); - } - } - } - } - } - if(ceil) { - int y = (height - 1) >> 4; - BlockArray arr = this.getArray(y); - if(arr == null) { - arr = new BlockArray(y << 4, sky, null); - this.setArray(arr); - } - y = (height - 5) >> 4; - arr = this.getArray(y); - if(arr == null) { - arr = new BlockArray(y << 4, sky, null); - this.setArray(arr); - } - for(int bx = 0; bx < 16; ++bx) { - for(int bz = 0; bz < 16; ++bz) { - for(int by = height - 1; by >= height - 5; --by) { - if(by >= (height - 1) - rand.zrange(5)) - this.getArray(by >> 4).set(bx, by & 15, bz, Blocks.air.getState()); - } - } - } - } - for(int n = 0; n < this.biomes.length; ++n) { - this.biomes[n] = (byte)biomes[n].id; - } - if(ceil) - this.resetRelight(); - else - this.genSkyLight(); - } - - public int getHeight(BlockPos pos) { - return this.getHeight(pos.getX() & 15, pos.getZ() & 15); - } - + public int getHeight(int x, int z) { return this.height[z << 4 | x]; } - public int getTopSegment() { - return this.top; - } - - public int getBottomSegment() { - return this.bottom; - } - - public Set getStorage() { - return this.blockList; - } - public BlockArray getArray(int y) { return this.blocks.lookup(y); } - private void setArray(BlockArray array) { + protected void setArray(BlockArray array) { int y = array.getY() >> 4; this.blocks.addKey(y, array); this.blockList.add(array); @@ -174,42 +80,7 @@ public class Chunk { this.bottom = y < this.bottom ? y : this.bottom; this.top = y > this.top ? y : this.top; } - - private void clearArrays() { - this.blocks.clearMap(); - this.blockList.clear(); - this.bottom = Integer.MAX_VALUE; - this.top = Integer.MIN_VALUE; - } - - protected void genHeights() { - int top = this.top; - int bottom = this.bottom; - this.minHeight = Integer.MAX_VALUE; - - for(int x = 0; x < 16; ++x) { - for(int z = 0; z < 16; ++z) { - this.precHeight[x + (z << 4)] = -99999999; - - for(int y = top + 16; y > bottom; --y) { - Block block = this.getBlock0(x, y - 1, z); - - if(block.getLightOpacity() != 0) { - this.height[z << 4 | x] = y; - - if(y < this.minHeight) { - this.minHeight = y; - } - - break; - } - } - } - } - - this.modified = true; - } - + public void genSkyLight() { int top = this.top; int bottom = this.bottom; @@ -415,7 +286,7 @@ public class Chunk { } } - public int getOpacity(BlockPos pos) { + private int getOpacity(BlockPos pos) { return this.getBlock(pos).getLightOpacity(); } @@ -423,7 +294,7 @@ public class Chunk { return this.getBlock0(x, y, z).getLightOpacity(); } - private Block getBlock0(int x, int y, int z) { + protected Block getBlock0(int x, int y, int z) { BlockArray stor = this.getArray(y >> 4); return stor != null ? stor.getBlock(x, y & 15, z) : (y < 0 ? this.fillerBlock : Blocks.air); } @@ -672,14 +543,6 @@ public class Chunk { return tile; } - public void addTileEntity(TileEntity tile) { - this.addTileEntity(tile.getPos(), tile); - - if(this.loaded) { - this.world.addTileEntity(tile); - } - } - public void addTileEntity(BlockPos pos, TileEntity tile) { tile.setWorldObj(this.world); tile.setPos(pos); @@ -690,7 +553,7 @@ public class Chunk { } if(tile.validate()) { - this.setModified(); + this.modified = true; } this.tiles.put(pos, tile); } @@ -706,19 +569,6 @@ public class Chunk { } } - public void onChunkLoad() { - this.loaded = true; - this.world.addTileEntities(this.tiles.values()); - - for(int n = 0; n < this.entities.length; ++n) { - for(Entity entity : this.entities[n]) { - entity.onChunkLoad(); - } - - this.world.loadEntities(this.entities[n]); - } - } - public void onChunkUnload() { this.loaded = false; @@ -731,10 +581,6 @@ public class Chunk { } } - public void setModified() { - this.modified = true; - } - public void getEntities(Entity exclude, BoundingBox bb, List list, Predicate pred) { int sy = ExtMath.floord((bb.minY - 2.0D) / 16.0D); int ey = ExtMath.floord((bb.maxY + 2.0D) / 16.0D); @@ -782,17 +628,6 @@ public class Chunk { } } - public boolean isDirty(long time) { - if(this.hasEntity && time != this.lastSave || this.modified) { - return true; - } - return this.modified; - } - - public boolean isDummy() { - return false; - } - public BlockPos getPrecipitation(BlockPos pos) { int x = pos.getX() & 15; int z = pos.getZ() & 15; @@ -851,108 +686,6 @@ public class Chunk { return this.updated && this.populated && this.lightInit; } - public ChunkPos getPos() { - return new ChunkPos(this.xPos, this.zPos); - } - - public boolean isEmpty(int bottom, int top) { - for(int y = bottom; y <= top; y += 16) { - BlockArray stor = this.getArray(y >> 4); - - if(stor != null ? !stor.isEmpty() : (y < 0 && this.fillerBlock != Blocks.air)) { - return false; - } - } - - return true; - } - - public void setStorage(BlockArray[] data) { - for(BlockArray arr : data) { - this.setArray(arr); - } - } - - public void setData(byte[] data, int[] extend, boolean biomes) { - int pos = 0; - boolean sky = !this.world.dimension.hasNoLight(); - - if(biomes) { - this.clearArrays(); - } - for(int cy : extend) { - BlockArray arr = this.getArray(cy); - if(arr == null) { - arr = new BlockArray(cy << 4, sky, null); - this.setArray(arr); - } - - char[] blocks = arr.getData(); - - for(int k = 0; k < blocks.length; ++k) { - blocks[k] = (char)((data[pos + 1] & 255) << 8 | data[pos] & 255); - pos += 2; - } - } - - for(int cy : extend) { - BlockArray arr = this.getArray(cy); - if(arr != null) { - NibbleArray light = arr.getBlocklight(); - System.arraycopy(data, pos, light.getData(), 0, light.getData().length); - pos += light.getData().length; - } - } - - if(sky) { - for(int cy : extend) { - BlockArray arr = this.getArray(cy); - if(arr != null) { - NibbleArray slight = arr.getSkylight(); - System.arraycopy(data, pos, slight.getData(), 0, slight.getData().length); - pos += slight.getData().length; - } - } - } - - if(biomes) { - System.arraycopy(data, pos, this.biomes, 0, this.biomes.length); - } - - for(int cy : extend) { - BlockArray arr = this.getArray(cy); - if(arr != null) { - arr.update(); - } - } - - this.lightInit = true; - this.populated = true; - this.genHeights(); - - for(TileEntity tile : this.tiles.values()) { - tile.updateContainingBlockInfo(); - } - } - - public Biome getBiome(BlockPos pos, BiomeGenerator gen) { - int x = pos.getX() & 15; - int z = pos.getZ() & 15; - int o = this.biomes[z << 4 | x] & 255; - - if(o == 255) { - Biome biome = gen == null ? Biome.DEF_BIOME : gen.getBiomeGenerator(pos, Biome.DEF_BIOME); - o = biome.id; - this.biomes[z << 4 | x] = (byte)(o & 255); - } - - return Biome.getBiomeDef(o); - } - - public byte[] getBiomes() { - return this.biomes; - } - public void setBiomes(byte[] biomes) { if(this.biomes.length != biomes.length) { Log.JNI.warn("Konnte Biome des Chunks nicht setzen, Länge des Arrays ist " + biomes.length + " statt " + this.biomes.length); @@ -1114,75 +847,12 @@ public class Chunk { public boolean isLoaded() { return this.loaded; } - - public void setLoaded(boolean loaded) { - this.loaded = loaded; - } - - public World getWorld() { - return this.world; - } - - public int[] getHeights() { - return this.height; - } - - public void setHeights(int[] map) { - if(this.height.length != map.length) { - Log.JNI.warn("Konnte Höhen des Chunks nicht setzen, Länge des Arrays ist " + map.length + " statt " + this.height.length); - } - else { - for(int n = 0; n < this.height.length; ++n) { - this.height[n] = map[n]; - } - } - } - - public Map getTiles() { - return this.tiles; - } - + public ClassInheritanceMultiMap[] getEntities() { return this.entities; } - public boolean isTerrainPopulated() { - return this.populated; - } - - public void setTerrainPopulated(boolean populated) { - this.populated = populated; - } - - public boolean isLightPopulated() { - return this.lightInit; - } - - public void setLightPopulated(boolean populated) { - this.lightInit = populated; - } - - public void setModified(boolean modified) { - this.modified = modified; - } - - public void setHasEntities(boolean entities) { - this.hasEntity = entities; - } - - public void setSaved(long time) { - this.lastSave = time; - } - public int getLowest() { return this.minHeight; } - - public long getInhabited() { - return this.inhabited; - } - - public void setInhabited(long time) { - this.inhabited = time; - } } diff --git a/common/src/common/world/ChunkCache.java b/common/src/common/world/ChunkCache.java deleted file mode 100755 index d495ab1..0000000 --- a/common/src/common/world/ChunkCache.java +++ /dev/null @@ -1,27 +0,0 @@ -package common.world; - -import common.util.BlockPos; - -public class ChunkCache -{ - protected final int chunkX; - protected final int chunkZ; - protected final Chunk[][] chunkArray; - - public ChunkCache(World worldIn, BlockPos posFromIn, BlockPos posToIn, int subIn) - { - this.chunkX = posFromIn.getX() - subIn >> 4; - this.chunkZ = posFromIn.getZ() - subIn >> 4; - int i = posToIn.getX() + subIn >> 4; - int j = posToIn.getZ() + subIn >> 4; - this.chunkArray = new Chunk[i - this.chunkX + 1][j - this.chunkZ + 1]; - - for (int k = this.chunkX; k <= i; ++k) - { - for (int l = this.chunkZ; l <= j; ++l) - { - this.chunkArray[k - this.chunkX][l - this.chunkZ] = worldIn.getChunk(k, l); - } - } - } -} diff --git a/common/src/common/worldgen/DebugStates.java b/common/src/common/world/DebugStates.java similarity index 94% rename from common/src/common/worldgen/DebugStates.java rename to common/src/common/world/DebugStates.java index 7487eb7..a569464 100644 --- a/common/src/common/worldgen/DebugStates.java +++ b/common/src/common/world/DebugStates.java @@ -1,4 +1,4 @@ -package common.worldgen; +package common.world; import java.util.List; @@ -6,7 +6,6 @@ import common.block.Block; import common.collect.Lists; import common.init.BlockRegistry; import common.util.ExtMath; -import common.world.State; public class DebugStates { private static final List STATES = Lists.newArrayList(); diff --git a/common/src/common/world/World.java b/common/src/common/world/World.java index 41c6290..66e66ce 100755 --- a/common/src/common/world/World.java +++ b/common/src/common/world/World.java @@ -133,12 +133,7 @@ public abstract class World implements IWorldAccess { this.gravity = Math.signum(this.gravity) * 0.075; } - public Biome getBiomeGenForCoords(final BlockPos pos) { - if(this.isBlockLoaded(pos)) - return this.getChunk(pos).getBiome(pos, null); - else - return Biome.DEF_BIOME; - } + public abstract Biome getBiomeGenForCoords(BlockPos pos); public boolean isAirBlock(BlockPos pos) { return this.getState(pos).getBlock().getMaterial() == Material.air; @@ -191,9 +186,7 @@ public abstract class World implements IWorldAccess { } } - protected boolean isLoaded(int x, int z, boolean allowEmpty) { - return allowEmpty || !this.getChunk(x, z).isDummy(); - } + protected abstract boolean isLoaded(int x, int z, boolean allowEmpty); public Chunk getChunk(BlockPos pos) { return this.getChunk(pos.getX() >> 4, pos.getZ() >> 4); @@ -1822,12 +1815,6 @@ public abstract class World implements IWorldAccess { return (Entity)this.entityIds.lookup(id); } - public void markChunkDirty(BlockPos pos, TileEntity unusedTileEntity) { - if(this.isBlockLoaded(pos)) { - this.getChunk(pos).setModified(); - } - } - public void loadEntities(Collection entityCollection) { this.entities.addAll(entityCollection); diff --git a/server/src/server/network/Player.java b/server/src/server/network/Player.java index a185bbc..f2a7bfb 100755 --- a/server/src/server/network/Player.java +++ b/server/src/server/network/Player.java @@ -119,7 +119,7 @@ import common.util.Position; import common.util.Vec3i; import common.util.WorldPos; import common.village.MerchantRecipeList; -import common.world.Chunk; +import common.world.BlockArray; import common.world.State; import common.world.World; import io.netty.util.concurrent.Future; @@ -134,6 +134,7 @@ import server.clipboard.RotationValue; import server.clipboard.Vector; import server.command.Executor; import server.util.Form; +import server.world.ChunkServer; import server.world.Region; import server.world.WorldServer; @@ -915,6 +916,97 @@ public class Player extends NetHandler implements ICrafting, Executor, IPlayer } + + public static SPacketChunkData.Extracted getExtractedData(ChunkServer chunk, boolean biomes, boolean overworld, int[] extend) + { + Set aextendedblockstorage = chunk.getStorage(); + SPacketChunkData.Extracted s21packetchunkdata$extracted = new SPacketChunkData.Extracted(); + List list = Lists.newArrayList(); + + if(extend == null) { + for(BlockArray arr : aextendedblockstorage) { + if(arr != null && (!biomes || !arr.isEmpty())) + list.add(arr); + } + } + else { + for(int cy : extend) { + BlockArray arr = chunk.getArray(cy); + if(arr != null && (!biomes || !arr.isEmpty())) + list.add(arr); + } + } + extend = new int[list.size()]; + for(int z = 0; z < extend.length; z++) { + extend[z] = list.get(z).getY() >> 4; + } + + s21packetchunkdata$extracted.extend = extend; + s21packetchunkdata$extracted.data = new byte[SPacketChunkData.getSize(extend.length, overworld, biomes)]; + int j = 0; + + for (BlockArray extendedblockstorage1 : list) + { + char[] achar = extendedblockstorage1.getData(); + + for (char c0 : achar) + { + s21packetchunkdata$extracted.data[j++] = (byte)(c0 & 255); + s21packetchunkdata$extracted.data[j++] = (byte)(c0 >> 8 & 255); + } + } + + for (BlockArray extendedblockstorage2 : list) + { + j = copyTo(extendedblockstorage2.getBlocklight().getData(), s21packetchunkdata$extracted.data, j); + } + + if (overworld) + { + for (BlockArray extendedblockstorage3 : list) + { + j = copyTo(extendedblockstorage3.getSkylight().getData(), s21packetchunkdata$extracted.data, j); + } + } + + if (biomes) + { + copyTo(chunk.getBiomes(), s21packetchunkdata$extracted.data, j); + } + + return s21packetchunkdata$extracted; + } + + private static int copyTo(byte[] src, byte[] dest, int offset) + { + System.arraycopy(src, 0, dest, offset, src.length); + return offset + src.length; + } + + public static SPacketChunkData getPacket(ChunkServer chunkIn, boolean biomes, int[] extend, boolean sky) + { + return new SPacketChunkData(chunkIn.xPos, chunkIn.zPos, biomes, getExtractedData(chunkIn, biomes, sky, extend)); + } + + private static SPacketMapChunkBulk getPacket(List chunks, boolean sky) + { + int i = chunks.size(); + int[] xPositions = new int[i]; + int[] zPositions = new int[i]; + SPacketChunkData.Extracted[] chunksData = new SPacketChunkData.Extracted[i]; + + for (int j = 0; j < i; ++j) + { + ChunkServer chunk = chunks.get(j); + SPacketChunkData.Extracted s21packetchunkdata$extracted = getExtractedData(chunk, true, sky, null); + xPositions[j] = chunk.xPos; + zPositions[j] = chunk.zPos; + chunksData[j] = s21packetchunkdata$extracted; + } + + return new SPacketMapChunkBulk(xPositions, zPositions, chunksData, sky); + } + public void updateEntity() { @@ -951,7 +1043,7 @@ public class Player extends NetHandler implements ICrafting, Executor, IPlayer if (!this.loadedChunks.isEmpty()) { - List list = Lists.newArrayList(); + List list = Lists.newArrayList(); Iterator iterator1 = this.loadedChunks.iterator(); List list1 = Lists.newArrayList(); @@ -965,7 +1057,7 @@ public class Player extends NetHandler implements ICrafting, Executor, IPlayer { if (this.entity.worldObj.isBlockLoaded(new BlockPos(chunkcoordintpair.x << 4, 0, chunkcoordintpair.z << 4))) { - Chunk chunk = this.entity.worldObj.getChunk(chunkcoordintpair.x, chunkcoordintpair.z); + ChunkServer chunk = this.getEntityWorld().getChunk(chunkcoordintpair.x, chunkcoordintpair.z); if (chunk.isPopulated()) { @@ -985,11 +1077,11 @@ public class Player extends NetHandler implements ICrafting, Executor, IPlayer { if (list.size() == 1) { - this.sendPacket(new SPacketChunkData((Chunk)list.get(0), true, null)); + this.sendPacket(getPacket(list.get(0), true, null, !this.entity.worldObj.dimension.hasNoLight())); } else { - this.sendPacket(new SPacketMapChunkBulk(list)); + this.sendPacket(getPacket(list, !this.entity.worldObj.dimension.hasNoLight())); } for (TileEntity tileentity : list1) @@ -997,7 +1089,7 @@ public class Player extends NetHandler implements ICrafting, Executor, IPlayer this.sendTileEntityUpdate(tileentity); } - for (Chunk chunk1 : list) + for (ChunkServer chunk1 : list) { this.getEntityWorld().updateChunksForPlayer(this.entity, chunk1); } diff --git a/server/src/server/world/ChunkServer.java b/server/src/server/world/ChunkServer.java new file mode 100644 index 0000000..15ee816 --- /dev/null +++ b/server/src/server/world/ChunkServer.java @@ -0,0 +1,216 @@ +package server.world; + +import java.util.Map; +import java.util.Set; +import common.biome.Biome; +import common.block.Block; +import common.entity.Entity; +import common.init.BlockRegistry; +import common.init.Blocks; +import common.log.Log; +import common.material.Material; +import common.rng.Random; +import common.tileentity.TileEntity; +import common.util.BlockPos; +import common.world.BlockArray; +import common.world.Chunk; +import common.world.State; +import common.world.World; +import server.worldgen.BiomeGenerator; + +public class ChunkServer extends Chunk { + private long lastSave; + private long inhabited; + + public ChunkServer(World world, int x, int z) { + super(world, x, z); + } + + public ChunkServer(World world, short[] data, int height, boolean base, boolean ceil, Random rand, Biome[] biomes, int x, int z) { + this(world, x, z); + boolean sky = !world.dimension.hasNoLight(); + for(int bx = 0; bx < 16; ++bx) { + for(int bz = 0; bz < 16; ++bz) { + for(int by = 0; by < height; ++by) { + State state = BlockRegistry.STATEMAP.getByValue(data[bx << 4 | bz | by << 8]); + if(state != null && state.getBlock().getMaterial() != Material.air) { + int y = by >> 4; + BlockArray arr = this.getArray(y); + if(arr == null) { + arr = new BlockArray(y << 4, sky, null); + this.setArray(arr); + } + arr.set(bx, by & 15, bz, state); + } + } + } + } + if(base) { + Block caves = world.dimension.getCaveFiller().getBlock(); + BlockArray arr = this.getArray(0); + if(arr == null) { + arr = new BlockArray(0, sky, null); + this.setArray(arr); + } + for(int bx = 0; bx < 16; ++bx) { + for(int bz = 0; bz < 16; ++bz) { + for(int by = 0; by < 5; ++by) { + if(by <= rand.zrange(5)) { + Block block = arr.get(bx, by, bz).getBlock(); + if(block == Blocks.air || block.getMaterial().isLiquid() || block == caves) + arr.set(bx, by, bz, this.filler); + } + } + } + } + } + if(ceil) { + int y = (height - 1) >> 4; + BlockArray arr = this.getArray(y); + if(arr == null) { + arr = new BlockArray(y << 4, sky, null); + this.setArray(arr); + } + y = (height - 5) >> 4; + arr = this.getArray(y); + if(arr == null) { + arr = new BlockArray(y << 4, sky, null); + this.setArray(arr); + } + for(int bx = 0; bx < 16; ++bx) { + for(int bz = 0; bz < 16; ++bz) { + for(int by = height - 1; by >= height - 5; --by) { + if(by >= (height - 1) - rand.zrange(5)) + this.getArray(by >> 4).set(bx, by & 15, bz, Blocks.air.getState()); + } + } + } + } + for(int n = 0; n < this.biomes.length; ++n) { + this.biomes[n] = (byte)biomes[n].id; + } + if(ceil) + this.resetRelight(); + else + this.genSkyLight(); + } + + public int getTopSegment() { + return this.top; + } + + public int getBottomSegment() { + return this.bottom; + } + + public Set getStorage() { + return this.blockList; + } + + public void addTileEntity(TileEntity tile) { + this.addTileEntity(tile.getPos(), tile); + + if(this.loaded) { + this.world.addTileEntity(tile); + } + } + + public void onChunkLoad() { + this.loaded = true; + this.world.addTileEntities(this.tiles.values()); + + for(int n = 0; n < this.entities.length; ++n) { + for(Entity entity : this.entities[n]) { + entity.onChunkLoad(); + } + + this.world.loadEntities(this.entities[n]); + } + } + + public boolean isDirty(long time) { + if(this.hasEntity && time != this.lastSave || this.modified) { + return true; + } + return this.modified; + } + + public void setStorage(BlockArray[] data) { + for(BlockArray arr : data) { + this.setArray(arr); + } + } + + public Biome getBiome(BlockPos pos, BiomeGenerator gen) { + int x = pos.getX() & 15; + int z = pos.getZ() & 15; + int o = this.biomes[z << 4 | x] & 255; + + if(o == 255) { + Biome biome = gen == null ? Biome.DEF_BIOME : gen.getBiomeGenerator(pos, Biome.DEF_BIOME); + o = biome.id; + this.biomes[z << 4 | x] = (byte)(o & 255); + } + + return Biome.getBiomeDef(o); + } + + public byte[] getBiomes() { + return this.biomes; + } + + public int[] getHeights() { + return this.height; + } + + public void setHeights(int[] map) { + if(this.height.length != map.length) { + Log.JNI.warn("Konnte Höhen des Chunks nicht setzen, Länge des Arrays ist " + map.length + " statt " + this.height.length); + } + else { + for(int n = 0; n < this.height.length; ++n) { + this.height[n] = map[n]; + } + } + } + + public Map getTiles() { + return this.tiles; + } + + public boolean isTerrainPopulated() { + return this.populated; + } + + public void setTerrainPopulated(boolean populated) { + this.populated = populated; + } + + public boolean isLightPopulated() { + return this.lightInit; + } + + public void setLightPopulated(boolean populated) { + this.lightInit = populated; + } + + public void setModified(boolean modified) { + this.modified = modified; + } + + public void setHasEntities(boolean entities) { + this.hasEntity = entities; + } + + public void setSaved(long time) { + this.lastSave = time; + } + + public long getInhabited() { + return this.inhabited; + } + + public void setInhabited(long time) { + this.inhabited = time; + } +} diff --git a/server/src/server/world/Region.java b/server/src/server/world/Region.java index 0753655..50921d6 100755 --- a/server/src/server/world/Region.java +++ b/server/src/server/world/Region.java @@ -34,7 +34,6 @@ import common.util.NextTickListEntry; import common.util.NibbleArray; import common.util.Util; import common.world.BlockArray; -import common.world.Chunk; public class Region { private static class ChunkBuffer extends ByteArrayOutputStream { @@ -360,7 +359,7 @@ public class Region { // getRegionFile(dir, x >> 3, z >> 3).writeTag(x & 7, z & 7, tag); } - public static Chunk readNbt(WorldServer world, int x, int z, NBTTagCompound tag) { + public static ChunkServer readNbt(WorldServer world, int x, int z, NBTTagCompound tag) { // if(!tag.hasKey("Level", 10)) { // Log.error("Chunk-Datei bei " + x + "," + z + " hat keine Level-Daten, überspringe"); // return null; @@ -370,7 +369,7 @@ public class Region { Log.JNI.warn("Chunk-Datei bei " + x + "," + z + " hat keine Block-Daten, überspringe"); return null; } - Chunk chunk = new Chunk(world, x, z); + ChunkServer chunk = new ChunkServer(world, x, z); chunk.setHeights(tag.getIntArray("HeightMap")); chunk.setTerrainPopulated(tag.getBoolean("TerrainPopulated")); chunk.setLightPopulated(tag.getBoolean("LightPopulated")); @@ -486,7 +485,7 @@ public class Region { return chunk; } - public static NBTTagCompound writeNbt(WorldServer world, Chunk chunk) { + public static NBTTagCompound writeNbt(WorldServer world, ChunkServer chunk) { NBTTagCompound tag = new NBTTagCompound(); // tag.setShort("V", (short)Config.PROTOCOL); tag.setLong("LastUpdate", world.getTime()); diff --git a/server/src/server/world/Spawner.java b/server/src/server/world/Spawner.java index 49a623f..bbaea74 100755 --- a/server/src/server/world/Spawner.java +++ b/server/src/server/world/Spawner.java @@ -14,7 +14,6 @@ import common.rng.WeightedList; import common.util.BlockPos; import common.util.ChunkPos; import common.util.ExtMath; -import common.world.Chunk; import common.world.World; import server.biome.GenBiome; import server.biome.RngSpawn; @@ -87,7 +86,7 @@ public abstract class Spawner { if(cur <= max) { typeLabel: for(ChunkPos coord : CHUNKS) { - Chunk chunk = world.getChunk(coord.x, coord.z); + ChunkServer chunk = world.getChunk(coord.x, coord.z); int x = coord.x * 16 + world.rand.zrange(16); int z = coord.z * 16 + world.rand.zrange(16); int h = chunk.getTopSegment(); diff --git a/server/src/server/world/WorldServer.java b/server/src/server/world/WorldServer.java index f151139..46f8957 100755 --- a/server/src/server/world/WorldServer.java +++ b/server/src/server/world/WorldServer.java @@ -24,6 +24,9 @@ import common.collect.Lists; import common.collect.Maps; import common.collect.Sets; import common.dimension.Dimension; +import common.dimension.Lake; +import common.dimension.Liquid; +import common.dimension.Ore; import common.entity.DamageSource; import common.entity.Entity; import common.entity.EntityTrackerEntry; @@ -55,7 +58,6 @@ import common.packet.SPacketBiomes; import common.packet.SPacketBlockAction; import common.packet.SPacketBlockBreakAnim; import common.packet.SPacketBlockChange; -import common.packet.SPacketChunkData; import common.packet.SPacketMultiBlockChange; import common.rng.Random; import common.rng.WeightedList; @@ -73,17 +75,12 @@ import common.util.Position; import common.util.Vec3; import common.village.Village; import common.world.BlockArray; -import common.world.Chunk; import common.world.Explosion; import common.world.AWorldServer; import common.world.LightType; import common.world.State; import common.world.Weather; import common.world.World; -import common.worldgen.BiomeGenerator; -import common.worldgen.FeatureLake; -import common.worldgen.FeatureLiquid; -import common.worldgen.FeatureOre; import server.Server; import server.biome.GenBiome; import server.biome.RngSpawn; @@ -93,6 +90,7 @@ import server.village.VillageCollection; import server.worldgen.BiomeGenLayered; import server.worldgen.BiomeGenPerlin; import server.worldgen.BiomeGenSingle; +import server.worldgen.BiomeGenerator; import server.worldgen.BlockReplacer; import server.worldgen.ChunkGenerator; import server.worldgen.ChunkPrimer; @@ -132,8 +130,8 @@ public final class WorldServer extends AWorldServer { private final EventList[] queue = new EventList[] {new EventList(), new EventList()}; private final List ticksNow = Lists.newArrayList(); private final Set dropped = Collections.newSetFromMap(new ConcurrentHashMap()); - private final LongHashMap chunks = new LongHashMap(); - private final List loaded = Lists.newArrayList(); + private final LongHashMap chunks = new LongHashMap(); + private final List loaded = Lists.newArrayList(); private final Map toRemove = new ConcurrentHashMap(); private final Set pending = Collections.newSetFromMap(new ConcurrentHashMap()); private final LongHashMap loaders = new LongHashMap(); @@ -263,7 +261,7 @@ public final class WorldServer extends AWorldServer { return null; FeatureOres[] gens = new FeatureOres[this.dimension.getOres().size()]; for(int z = 0; z < gens.length; z++) { - FeatureOre gen = this.dimension.getOres().get(z); + Ore gen = this.dimension.getOres().get(z); gens[z] = new FeatureOres(gen.state, gen.count, gen.more, gen.size, gen.min, gen.max, gen.dist); } return gens; @@ -274,7 +272,7 @@ public final class WorldServer extends AWorldServer { return null; FeatureLakes[] gens = new FeatureLakes[this.dimension.getLakes().size()]; for(int z = 0; z < gens.length; z++) { - FeatureLake gen = this.dimension.getLakes().get(z); + Lake gen = this.dimension.getLakes().get(z); gens[z] = new FeatureLakes(gen.state, gen.filler, gen.top, gen.chance, gen.minHeight, gen.maxHeight, gen.ratiod); } return gens; @@ -285,7 +283,7 @@ public final class WorldServer extends AWorldServer { return null; FeatureLiquids[] gens = new FeatureLiquids[this.dimension.getLiquids().size()]; for(int z = 0; z < gens.length; z++) { - FeatureLiquid gen = this.dimension.getLiquids().get(z); + Liquid gen = this.dimension.getLiquids().get(z); gens[z] = new FeatureLiquids(gen.state, gen.chance, gen.minHeight, gen.maxHeight, gen.lower); } return gens; @@ -515,7 +513,7 @@ public final class WorldServer extends AWorldServer { for(int i = 0; i < 100; ++i) { if(!this.dropped.isEmpty()) { Long v = (Long)this.dropped.iterator().next(); - Chunk chunk = (Chunk)this.chunks.getValueByKey(v.longValue()); + ChunkServer chunk = this.chunks.getValueByKey(v.longValue()); if(chunk != null) { chunk.onChunkUnload(); this.saveChunkData(chunk); @@ -656,7 +654,7 @@ public final class WorldServer extends AWorldServer { int k = chunkcoordintpair.x * 16; int l = chunkcoordintpair.z * 16; // this.profiler.start("getChunk"); - Chunk chunk = this.getChunk(chunkcoordintpair.x, chunkcoordintpair.z); + ChunkServer chunk = this.getChunk(chunkcoordintpair.x, chunkcoordintpair.z); // this.profiler.next("moodSound"); // this.playMoodSound(k, l, chunk); // this.profiler.next("checkLight"); @@ -891,7 +889,7 @@ public final class WorldServer extends AWorldServer { } } - public List getPendingBlockUpdates(Chunk chunk) { + public List getPendingBlockUpdates(ChunkServer chunk) { int x1 = (chunk.xPos << 4) - 2; int x2 = x1 + 16 + 2; int z1 = (chunk.zPos << 4) - 2; @@ -1071,15 +1069,15 @@ public final class WorldServer extends AWorldServer { Log.JNI.error(e, "Konnte Dorfliste nicht speichern"); } } - List list = Lists.newArrayList(this.loaded); + List list = Lists.newArrayList(this.loaded); for(int n = 0; n < list.size(); ++n) { - Chunk chunk = list.get(n); + ChunkServer chunk = list.get(n); if(chunk.isDirty(this.time)) { this.saveChunkData(chunk); chunk.setModified(false); } } - for(Chunk chunk : Lists.newArrayList(this.loaded)) { + for(ChunkServer chunk : Lists.newArrayList(this.loaded)) { if(chunk != null && !this.hasPlayerInstance(chunk.xPos, chunk.zPos)) { this.dropChunk(chunk.xPos, chunk.zPos); } @@ -1325,14 +1323,18 @@ public final class WorldServer extends AWorldServer { } protected boolean isLoaded(int x, int z, boolean allowEmpty) { - return this.chunkExists(x, z) && super.isLoaded(x, z, allowEmpty); + return this.chunkExists(x, z); } - public Chunk getChunk(int x, int z) { - Chunk chunk = this.chunks.getValueByKey(LongHashMap.packInt(x, z)); + public ChunkServer getChunk(int x, int z) { + ChunkServer chunk = this.chunks.getValueByKey(LongHashMap.packInt(x, z)); return chunk == null ? this.loadChunk(x, z) : chunk; } + public ChunkServer getChunk(BlockPos pos) { + return this.getChunk(pos.getX() >> 4, pos.getZ() >> 4); + } + private boolean chunkExists(int x, int z) { return this.chunks.containsItem(LongHashMap.packInt(x, z)); } @@ -1350,15 +1352,15 @@ public final class WorldServer extends AWorldServer { } public void unloadAllChunks() { - for(Chunk chunk : this.loaded) { + for(ChunkServer chunk : this.loaded) { this.dropChunk(chunk.xPos, chunk.zPos); } } - public Chunk loadChunk(int x, int z) { + public ChunkServer loadChunk(int x, int z) { long id = LongHashMap.packInt(x, z); this.dropped.remove(Long.valueOf(id)); - Chunk chunk = (Chunk)this.chunks.getValueByKey(id); + ChunkServer chunk = this.chunks.getValueByKey(id); if(chunk == null) { if(!this.debug) @@ -1377,7 +1379,7 @@ public final class WorldServer extends AWorldServer { return chunk; } - private Chunk loadChunkFromFile(int x, int z) { + private ChunkServer loadChunkFromFile(int x, int z) { try { ChunkPos coord = new ChunkPos(x, z); NBTTagCompound tag = this.toRemove.get(coord); @@ -1389,7 +1391,7 @@ public final class WorldServer extends AWorldServer { } // tag = CompressedStreamTools.read(in); } - Chunk chunk = Region.readNbt(this, x, z, tag); + ChunkServer chunk = Region.readNbt(this, x, z, tag); if(chunk != null) { chunk.setSaved(this.time); if(this.mineshaftGen != null) { @@ -1416,7 +1418,7 @@ public final class WorldServer extends AWorldServer { } } - private void saveChunkData(Chunk chunk) { + private void saveChunkData(ChunkServer chunk) { // try { chunk.setSaved(this.time); // this.lock.check(); @@ -1424,7 +1426,7 @@ public final class WorldServer extends AWorldServer { // NBTTagCompound ltag = new NBTTagCompound(); // tag.setTag("Level", ltag); NBTTagCompound tag = Region.writeNbt(this, chunk); - ChunkPos coord = chunk.getPos(); + ChunkPos coord = new ChunkPos(chunk.xPos, chunk.zPos); if(!this.pending.contains(coord)) { this.toRemove.put(coord, tag); } @@ -1533,7 +1535,7 @@ public final class WorldServer extends AWorldServer { } private void populate(int x, int z) { - Chunk chunk = this.getChunk(x, z); + ChunkServer chunk = this.getChunk(x, z); if(!chunk.isTerrainPopulated()) { chunk.checkLight(); BlockFalling.fallInstantly = true; @@ -1602,11 +1604,11 @@ public final class WorldServer extends AWorldServer { } // } BlockFalling.fallInstantly = false; - chunk.setModified(); + chunk.setModified(true); } } - private Chunk generate(int x, int z) { + private ChunkServer generate(int x, int z) { this.grng.setSeed((long)x * 341873128712L + (long)z * 132897987541L); ChunkPrimer primer = new ChunkPrimer(this.height); this.generator.generateChunk(this, x, z, primer); @@ -1638,7 +1640,7 @@ public final class WorldServer extends AWorldServer { if(this.scatteredGen != null) { this.scatteredGen.generate(this, x, z, primer); } - return new Chunk(this, primer.getData(), primer.height, this.base, this.ceil, this.grng, this.biomes, x, z); + return new ChunkServer(this, primer.getData(), primer.height, this.base, this.ceil, this.grng, this.biomes, x, z); } public boolean isExterminated() { @@ -1673,7 +1675,7 @@ public final class WorldServer extends AWorldServer { this.exterminated = true; // this.dataModified = true; for(Long v : this.dropped) { - Chunk chunk = this.chunks.getValueByKey(v.longValue()); + ChunkServer chunk = this.chunks.getValueByKey(v.longValue()); if(chunk != null) { chunk.onChunkUnload(); this.chunks.remove(v.longValue()); @@ -1681,10 +1683,10 @@ public final class WorldServer extends AWorldServer { } } this.dropped.clear(); - List loaded = Lists.newArrayList(this.loaded); + List loaded = Lists.newArrayList(this.loaded); this.loaded.clear(); this.setExterminatedGen(); - for(Chunk chunk : loaded) { + for(ChunkServer chunk : loaded) { long pos = LongHashMap.packInt(chunk.xPos, chunk.zPos); chunk.onChunkUnload(); this.chunks.remove(pos); @@ -1693,9 +1695,9 @@ public final class WorldServer extends AWorldServer { this.loaded.add(chunk); chunk.onChunkLoad(); chunk.checkLight(); - chunk.setModified(); + chunk.setModified(true); } - for(Chunk chunk : this.loaded) { + for(ChunkServer chunk : this.loaded) { chunk.update(false); } this.entities.removeAll(this.unloaded); @@ -1877,8 +1879,8 @@ public final class WorldServer extends AWorldServer { PlayerInstance ins = this.instances.getValueByKey(v); if(ins == null) return false; - Chunk chunk = this.getChunk(chunkX, chunkZ); - chunk.setModified(); + ChunkServer chunk = this.getChunk(chunkX, chunkZ); + chunk.setModified(true); ins.sendToAllPlayersWatchingChunk(new SPacketBiomes(chunkX, chunkZ, chunk.getBiomes())); return true; } @@ -2176,7 +2178,7 @@ public final class WorldServer extends AWorldServer { } } - public void updateChunksForPlayer(EntityNPC player, Chunk chunk) { + public void updateChunksForPlayer(EntityNPC player, ChunkServer chunk) { for(EntityTrackerEntry entitytrackerentry : this.tracked) { if(entitytrackerentry.trackedEntity != player && entitytrackerentry.trackedEntity.chunkCoordX == chunk.xPos && entitytrackerentry.trackedEntity.chunkCoordZ == chunk.zPos) { @@ -2189,7 +2191,7 @@ public final class WorldServer extends AWorldServer { // int x = position.getBlockX(); // int y = position.getBlockY(); // int z = position.getBlockZ(); - Chunk chunk = this.getChunk(pos.getX() >> 4, pos.getZ() >> 4); + ChunkServer chunk = this.getChunk(pos.getX() >> 4, pos.getZ() >> 4); // BlockPos pos = new BlockPos(x, y, z); State old = chunk.getState(pos); State newState = block.getState(); @@ -2249,7 +2251,7 @@ public final class WorldServer extends AWorldServer { // } private final boolean setChunkBiome(BlockPos position, Biome biome) { - Chunk chunk = this.getChunk(position); + ChunkServer chunk = this.getChunk(position); if((chunk != null) && (chunk.isLoaded())) { chunk.getBiomes()[((position.getZ() & 0xF) << 4 | position.getX() & 0xF)] = (byte)biome.id; return true; @@ -2437,7 +2439,7 @@ public final class WorldServer extends AWorldServer { } public BlockPos getTopSolidOrLiquidBlock(BlockPos pos) { - Chunk chunk = this.getChunk(pos); + ChunkServer chunk = this.getChunk(pos); int h = chunk.getTopSegment(); if(h == Integer.MIN_VALUE) return new BlockPos(pos.getX(), 0, pos.getZ()); @@ -2792,6 +2794,11 @@ public final class WorldServer extends AWorldServer { return this.server.getWorld(dimension); } + public void markChunkDirty(BlockPos pos) { + if(this.isBlockLoaded(pos)) + this.getChunk(pos).setModified(true); + } + private static class EventList extends ArrayList { private EventList() { } @@ -2808,6 +2815,15 @@ public final class WorldServer extends AWorldServer { this.tag = tag; } } + + private static SPacketMultiBlockChange getPacket(int amount, long[] list, ChunkServer chunk) { + ChunkPos pos = new ChunkPos(chunk.xPos, chunk.zPos); + SPacketMultiBlockChange.BlockUpdateData[] changes = new SPacketMultiBlockChange.BlockUpdateData[amount]; + for(int z = 0; z < changes.length; z++) { + changes[z] = new SPacketMultiBlockChange.BlockUpdateData(list[z], chunk.getState(SPacketMultiBlockChange.getPos(pos, list[z]))); + } + return new SPacketMultiBlockChange(pos, changes); + } private class PlayerInstance { private final List watching = Lists.newArrayList(); @@ -2841,10 +2857,10 @@ public final class WorldServer extends AWorldServer { public void removePlayer(EntityNPC player) { if(this.watching.contains(player)) { - Chunk chunk = WorldServer.this.getChunk(this.position.x, this.position.z); + ChunkServer chunk = WorldServer.this.getChunk(this.position.x, this.position.z); if(chunk.isPopulated()) { - player.connection.sendPacket(new SPacketChunkData(chunk, true, new int[0])); + player.connection.sendPacket(Player.getPacket(chunk, true, new int[0], !WorldServer.this.dimension.hasNoLight())); } this.watching.remove(player); @@ -2876,7 +2892,7 @@ public final class WorldServer extends AWorldServer { this.biomes = true; } - private void increaseInhabitedTime(Chunk chunk) { + private void increaseInhabitedTime(ChunkServer chunk) { chunk.setInhabited(chunk.getInhabited() + WorldServer.this.time - this.prevTime); this.prevTime = WorldServer.this.time; } @@ -2935,8 +2951,8 @@ public final class WorldServer extends AWorldServer { extend[n++] = i; } } - this.sendToAllPlayersWatchingChunk(new SPacketChunkData(WorldServer.this.getChunk(this.position.x, this.position.z), - this.biomes, extend)); + this.sendToAllPlayersWatchingChunk(Player.getPacket(WorldServer.this.getChunk(this.position.x, this.position.z), + this.biomes, extend, !WorldServer.this.dimension.hasNoLight())); if(this.biomes) { List list = WorldServer.this.getTileEntitiesIn(x, Integer.MIN_VALUE, z, x + 16, Integer.MAX_VALUE, z + 16); @@ -2957,7 +2973,7 @@ public final class WorldServer extends AWorldServer { } } else { - this.sendToAllPlayersWatchingChunk(new SPacketMultiBlockChange(this.updates, this.changes, + this.sendToAllPlayersWatchingChunk(getPacket(this.updates, this.changes, WorldServer.this.getChunk(this.position.x, this.position.z))); for(int n = 0; n < this.updates; ++n) { diff --git a/server/src/server/worldgen/BiomeGenLayered.java b/server/src/server/worldgen/BiomeGenLayered.java index bdf9230..7c03681 100755 --- a/server/src/server/worldgen/BiomeGenLayered.java +++ b/server/src/server/worldgen/BiomeGenLayered.java @@ -7,7 +7,6 @@ import common.biome.Biome; import common.collect.Lists; import common.util.BlockPos; import common.util.LongHashMap; -import common.worldgen.BiomeGenerator; import server.worldgen.layer.GenLayer; import server.worldgen.layer.GenLayerAddAreas; import server.worldgen.layer.GenLayerAddExtra; diff --git a/server/src/server/worldgen/BiomeGenSingle.java b/server/src/server/worldgen/BiomeGenSingle.java index 586058f..cd5bade 100755 --- a/server/src/server/worldgen/BiomeGenSingle.java +++ b/server/src/server/worldgen/BiomeGenSingle.java @@ -5,7 +5,6 @@ import java.util.Set; import common.biome.Biome; import common.util.BlockPos; -import common.worldgen.BiomeGenerator; public class BiomeGenSingle implements BiomeGenerator { private final Biome biome; diff --git a/common/src/common/worldgen/BiomeGenerator.java b/server/src/server/worldgen/BiomeGenerator.java similarity index 96% rename from common/src/common/worldgen/BiomeGenerator.java rename to server/src/server/worldgen/BiomeGenerator.java index b6ef4e9..6d75568 100755 --- a/common/src/common/worldgen/BiomeGenerator.java +++ b/server/src/server/worldgen/BiomeGenerator.java @@ -1,4 +1,4 @@ -package common.worldgen; +package server.worldgen; import java.util.Set; diff --git a/server/src/server/worldgen/GeneratorDebug.java b/server/src/server/worldgen/GeneratorDebug.java index d1eb549..1158b5c 100755 --- a/server/src/server/worldgen/GeneratorDebug.java +++ b/server/src/server/worldgen/GeneratorDebug.java @@ -1,7 +1,7 @@ package server.worldgen; +import common.world.DebugStates; import common.world.State; -import common.worldgen.DebugStates; import server.world.WorldServer; public class GeneratorDebug implements ChunkGenerator diff --git a/server/src/server/worldgen/structure/StructureVillage.java b/server/src/server/worldgen/structure/StructureVillage.java index 498cec0..0fb61ae 100755 --- a/server/src/server/worldgen/structure/StructureVillage.java +++ b/server/src/server/worldgen/structure/StructureVillage.java @@ -22,8 +22,8 @@ import common.rng.Random; import common.util.BlockPos; import common.util.Facing; import common.world.State; -import common.worldgen.BiomeGenerator; import server.world.WorldServer; +import server.worldgen.BiomeGenerator; import server.worldgen.LootConstants; From ffca1f62e54195a4858f5810410a8671ac4d17ca Mon Sep 17 00:00:00 2001 From: Sen Date: Sat, 24 May 2025 18:49:24 +0200 Subject: [PATCH 063/200] change biome packet --- client/src/client/network/ClientPlayer.java | 2 +- client/src/client/world/ChunkClient.java | 4 ++ client/src/client/world/ChunkEmpty.java | 2 +- common/src/common/packet/SPacketBiomes.java | 40 ++++++++------ common/src/common/world/Chunk.java | 11 ---- server/src/server/world/ChunkServer.java | 11 ++++ server/src/server/world/WorldServer.java | 60 ++++----------------- 7 files changed, 50 insertions(+), 80 deletions(-) diff --git a/client/src/client/network/ClientPlayer.java b/client/src/client/network/ClientPlayer.java index 4a4fdce..42de3ce 100755 --- a/client/src/client/network/ClientPlayer.java +++ b/client/src/client/network/ClientPlayer.java @@ -780,7 +780,7 @@ public class ClientPlayer extends NetHandler implements IClientPlayer { NetHandler.checkThread(packetIn, this, this.gameController, this.clientWorldController); ChunkClient chunk = this.clientWorldController.getChunk(packetIn.getChunkX(), packetIn.getChunkZ()); - chunk.setBiomes(packetIn.getBiomes()); + chunk.setBiome(packetIn.getPos(), packetIn.getBiome()); this.clientWorldController.markBlockRangeForRenderUpdate(packetIn.getChunkX() << 4, -World.MAX_SIZE_Y, packetIn.getChunkZ() << 4, (packetIn.getChunkX() << 4) + 15, World.MAX_SIZE_Y, (packetIn.getChunkZ() << 4) + 15); } diff --git a/client/src/client/world/ChunkClient.java b/client/src/client/world/ChunkClient.java index a016246..8f59b89 100644 --- a/client/src/client/world/ChunkClient.java +++ b/client/src/client/world/ChunkClient.java @@ -133,6 +133,10 @@ public class ChunkClient extends Chunk { int z = pos.getZ() & 15; return Biome.getBiomeDef(this.biomes[z << 4 | x] & 255); } + + public void setBiome(BlockPos pos, Biome biome) { + this.biomes[((pos.getZ() & 15) << 4 | pos.getX() & 15)] = (byte)biome.id; + } public boolean isDummy() { return false; diff --git a/client/src/client/world/ChunkEmpty.java b/client/src/client/world/ChunkEmpty.java index 31a78d2..1b03600 100755 --- a/client/src/client/world/ChunkEmpty.java +++ b/client/src/client/world/ChunkEmpty.java @@ -107,7 +107,7 @@ public class ChunkEmpty extends ChunkClient { return Biome.DEF_BIOME; } - public void setBiomes(byte[] biomes) { + public void setBiome(BlockPos pos, Biome biome) { } public void resetRelight() { diff --git a/common/src/common/packet/SPacketBiomes.java b/common/src/common/packet/SPacketBiomes.java index 3d83aed..9cb7ef3 100755 --- a/common/src/common/packet/SPacketBiomes.java +++ b/common/src/common/packet/SPacketBiomes.java @@ -2,34 +2,36 @@ package common.packet; import java.io.IOException; +import common.biome.Biome; import common.network.IClientPlayer; import common.network.Packet; import common.network.PacketBuffer; +import common.util.BlockPos; public class SPacketBiomes implements Packet { - private int chunkX; - private int chunkZ; - private byte[] biomes; + private int posX; + private int posZ; + private Biome biome; public SPacketBiomes() { } - public SPacketBiomes(int chunkX, int chunkZ, byte[] biomes) { - this.chunkX = chunkX; - this.chunkZ = chunkZ; - this.biomes = biomes; + public SPacketBiomes(BlockPos pos, Biome biome) { + this.posX = pos.getX(); + this.posZ = pos.getZ(); + this.biome = biome; } public void readPacketData(PacketBuffer buf) throws IOException { - this.chunkX = buf.readInt(); - this.chunkZ = buf.readInt(); - buf.readBytes(this.biomes = new byte[256]); + this.posX = buf.readInt(); + this.posZ = buf.readInt(); + this.biome = buf.readEnumValue(Biome.class); } public void writePacketData(PacketBuffer buf) throws IOException { - buf.writeInt(this.chunkX); - buf.writeInt(this.chunkZ); - buf.writeBytes(this.biomes); + buf.writeInt(this.posX); + buf.writeInt(this.posZ); + buf.writeEnumValue(this.biome); } public void processPacket(IClientPlayer handler) { @@ -37,14 +39,18 @@ public class SPacketBiomes implements Packet { } public int getChunkX() { - return this.chunkX; + return this.posX >> 4; } public int getChunkZ() { - return this.chunkZ; + return this.posZ >> 4; + } + + public BlockPos getPos() { + return new BlockPos(this.posX, 0, this.posZ); } - public byte[] getBiomes() { - return this.biomes; + public Biome getBiome() { + return this.biome; } } diff --git a/common/src/common/world/Chunk.java b/common/src/common/world/Chunk.java index 841292b..3210d9f 100755 --- a/common/src/common/world/Chunk.java +++ b/common/src/common/world/Chunk.java @@ -686,17 +686,6 @@ public abstract class Chunk { return this.updated && this.populated && this.lightInit; } - public void setBiomes(byte[] biomes) { - if(this.biomes.length != biomes.length) { - Log.JNI.warn("Konnte Biome des Chunks nicht setzen, Länge des Arrays ist " + biomes.length + " statt " + this.biomes.length); - } - else { - for(int n = 0; n < this.biomes.length; ++n) { - this.biomes[n] = biomes[n]; - } - } - } - public void resetRelight() { this.lightChecks = 0; } diff --git a/server/src/server/world/ChunkServer.java b/server/src/server/world/ChunkServer.java index 15ee816..675ec10 100644 --- a/server/src/server/world/ChunkServer.java +++ b/server/src/server/world/ChunkServer.java @@ -159,6 +159,17 @@ public class ChunkServer extends Chunk { return this.biomes; } + public void setBiomes(byte[] biomes) { + if(this.biomes.length != biomes.length) { + Log.JNI.warn("Konnte Biome des Chunks nicht setzen, Länge des Arrays ist " + biomes.length + " statt " + this.biomes.length); + } + else { + for(int n = 0; n < this.biomes.length; ++n) { + this.biomes[n] = biomes[n]; + } + } + } + public int[] getHeights() { return this.height; } diff --git a/server/src/server/world/WorldServer.java b/server/src/server/world/WorldServer.java index 46f8957..037b7cd 100755 --- a/server/src/server/world/WorldServer.java +++ b/server/src/server/world/WorldServer.java @@ -1874,15 +1874,18 @@ public final class WorldServer extends AWorldServer { return this.instances.getValueByKey(v) != null; } - public boolean updateBiomes(int chunkX, int chunkZ) { + public void setBiome(BlockPos pos, Biome biome) { + ChunkServer chunk = this.getChunk(pos); + if(chunk == null || !chunk.isLoaded()) + return; + chunk.getBiomes()[((pos.getZ() & 0xF) << 4 | pos.getX() & 0xF)] = (byte)biome.id; + chunk.setModified(true); + int chunkX = pos.getX() >> 4; + int chunkZ = pos.getZ() >> 4; long v = (long)chunkX + 2147483647L | (long)chunkZ + 2147483647L << 32; PlayerInstance ins = this.instances.getValueByKey(v); - if(ins == null) - return false; - ChunkServer chunk = this.getChunk(chunkX, chunkZ); - chunk.setModified(true); - ins.sendToAllPlayersWatchingChunk(new SPacketBiomes(chunkX, chunkZ, chunk.getBiomes())); - return true; + if(ins != null) + ins.sendToAllPlayersWatchingChunk(new SPacketBiomes(pos, biome)); } private PlayerInstance getPlayerInstance(int chunkX, int chunkZ, boolean create) { @@ -2244,50 +2247,7 @@ public final class WorldServer extends AWorldServer { return new ClipboardBlock(state); } } - -// public final EditBlock getLazyBlock(Vector position) { -// State state = this.getState(new BlockPos(position.getBlockX(), position.getBlockY(), position.getBlockZ())); -// return new LazyBlock(state, this, position); -// } - - private final boolean setChunkBiome(BlockPos position, Biome biome) { - ChunkServer chunk = this.getChunk(position); - if((chunk != null) && (chunk.isLoaded())) { - chunk.getBiomes()[((position.getZ() & 0xF) << 4 | position.getX() & 0xF)] = (byte)biome.id; - return true; - } - return false; - } - public final void setBiomes(BlockPos start, BlockPos end, Biome biome) { - Set chunks = Sets.newHashSet(); - for(int x = start.getX(); x <= end.getX(); x++) { - for(int z = start.getZ(); z <= end.getZ(); z++) { - if(this.setChunkBiome(new BlockPos(x, 0, z), biome)) - chunks.add(new ChunkPos(x >> 4, z >> 4)); - } - } - for(ChunkPos pos : chunks) { - this.updateBiomes(pos.x, pos.z); - } - chunks.clear(); - } - - public final void setBiome(BlockPos pos, Biome biome) { - if(this.setChunkBiome(pos, biome)) - this.updateBiomes(pos.getX() >> 4, pos.getZ() >> 4); - } - -// public final List getEntities(EditRegion region) { -// List entities = Lists.newArrayList(); -// for(Entity entity : this.entities) { -// if(region.contains(new Vector(entity.posX, entity.posY, entity.posZ))) { -// entities.add(entity); -// } -// } -// return entities; -// } - public final List getEntities() { List entities = Lists.newArrayList(); for(Entity entity : this.entities) { From 1eefb197f09ba4f2b2570654ee2f4072b1a7858b Mon Sep 17 00:00:00 2001 From: Sen Date: Sat, 24 May 2025 18:49:50 +0200 Subject: [PATCH 064/200] rename biome packet --- client/src/client/network/ClientPlayer.java | 4 ++-- common/src/common/network/IClientPlayer.java | 4 ++-- common/src/common/network/PacketRegistry.java | 4 ++-- .../common/packet/{SPacketBiomes.java => SPacketBiome.java} | 6 +++--- server/src/server/world/WorldServer.java | 4 ++-- 5 files changed, 11 insertions(+), 11 deletions(-) rename common/src/common/packet/{SPacketBiomes.java => SPacketBiome.java} (88%) diff --git a/client/src/client/network/ClientPlayer.java b/client/src/client/network/ClientPlayer.java index 42de3ce..c972aea 100755 --- a/client/src/client/network/ClientPlayer.java +++ b/client/src/client/network/ClientPlayer.java @@ -95,7 +95,7 @@ import common.packet.S39PacketPlayerAbilities; import common.packet.S3APacketTabComplete; import common.packet.S43PacketUpdateEntityNBT; import common.packet.SPacketAnimation; -import common.packet.SPacketBiomes; +import common.packet.SPacketBiome; import common.packet.SPacketBlockAction; import common.packet.SPacketBlockBreakAnim; import common.packet.SPacketBlockChange; @@ -776,7 +776,7 @@ public class ClientPlayer extends NetHandler implements IClientPlayer } } - public void handleBiomes(SPacketBiomes packetIn) + public void handleBiomes(SPacketBiome packetIn) { NetHandler.checkThread(packetIn, this, this.gameController, this.clientWorldController); ChunkClient chunk = this.clientWorldController.getChunk(packetIn.getChunkX(), packetIn.getChunkZ()); diff --git a/common/src/common/network/IClientPlayer.java b/common/src/common/network/IClientPlayer.java index b412c36..292929b 100644 --- a/common/src/common/network/IClientPlayer.java +++ b/common/src/common/network/IClientPlayer.java @@ -34,7 +34,7 @@ import common.packet.S39PacketPlayerAbilities; import common.packet.S3APacketTabComplete; import common.packet.S43PacketUpdateEntityNBT; import common.packet.SPacketAnimation; -import common.packet.SPacketBiomes; +import common.packet.SPacketBiome; import common.packet.SPacketBlockAction; import common.packet.SPacketBlockBreakAnim; import common.packet.SPacketBlockChange; @@ -100,7 +100,7 @@ public interface IClientPlayer { void handlePlayerPosLook(SPacketPlayerPosLook packetIn); void handleMultiBlockChange(SPacketMultiBlockChange packetIn); void handleChunkData(SPacketChunkData packetIn); - void handleBiomes(SPacketBiomes packetIn); + void handleBiomes(SPacketBiome packetIn); void handleBlockChange(SPacketBlockChange packetIn); void handleDisconnect(SPacketDisconnect packetIn); void handleCollectItem(SPacketCollectItem packetIn); diff --git a/common/src/common/network/PacketRegistry.java b/common/src/common/network/PacketRegistry.java index fd8e7c0..b6a4b59 100755 --- a/common/src/common/network/PacketRegistry.java +++ b/common/src/common/network/PacketRegistry.java @@ -56,7 +56,7 @@ import common.packet.S39PacketPlayerAbilities; import common.packet.S3APacketTabComplete; import common.packet.S43PacketUpdateEntityNBT; import common.packet.SPacketAnimation; -import common.packet.SPacketBiomes; +import common.packet.SPacketBiome; import common.packet.SPacketBlockAction; import common.packet.SPacketBlockBreakAnim; import common.packet.SPacketBlockChange; @@ -177,7 +177,7 @@ public enum PacketRegistry this.server(SPacketWorld.class); // this.server(SPacketCapes.class); this.server(SPacketCamera.class); - this.server(SPacketBiomes.class); + this.server(SPacketBiome.class); // this.server(S42PacketTitle.class); this.server(S43PacketUpdateEntityNBT.class); // this.server(SPacketBook.class); diff --git a/common/src/common/packet/SPacketBiomes.java b/common/src/common/packet/SPacketBiome.java similarity index 88% rename from common/src/common/packet/SPacketBiomes.java rename to common/src/common/packet/SPacketBiome.java index 9cb7ef3..9991545 100755 --- a/common/src/common/packet/SPacketBiomes.java +++ b/common/src/common/packet/SPacketBiome.java @@ -8,15 +8,15 @@ import common.network.Packet; import common.network.PacketBuffer; import common.util.BlockPos; -public class SPacketBiomes implements Packet { +public class SPacketBiome implements Packet { private int posX; private int posZ; private Biome biome; - public SPacketBiomes() { + public SPacketBiome() { } - public SPacketBiomes(BlockPos pos, Biome biome) { + public SPacketBiome(BlockPos pos, Biome biome) { this.posX = pos.getX(); this.posZ = pos.getZ(); this.biome = biome; diff --git a/server/src/server/world/WorldServer.java b/server/src/server/world/WorldServer.java index 037b7cd..0d79a09 100755 --- a/server/src/server/world/WorldServer.java +++ b/server/src/server/world/WorldServer.java @@ -54,7 +54,7 @@ import common.packet.S29PacketSoundEffect; import common.packet.S2APacketParticles; import common.packet.S2BPacketChangeGameState; import common.packet.S2CPacketSpawnGlobalEntity; -import common.packet.SPacketBiomes; +import common.packet.SPacketBiome; import common.packet.SPacketBlockAction; import common.packet.SPacketBlockBreakAnim; import common.packet.SPacketBlockChange; @@ -1885,7 +1885,7 @@ public final class WorldServer extends AWorldServer { long v = (long)chunkX + 2147483647L | (long)chunkZ + 2147483647L << 32; PlayerInstance ins = this.instances.getValueByKey(v); if(ins != null) - ins.sendToAllPlayersWatchingChunk(new SPacketBiomes(pos, biome)); + ins.sendToAllPlayersWatchingChunk(new SPacketBiome(pos, biome)); } private PlayerInstance getPlayerInstance(int chunkX, int chunkZ, boolean create) { From bd4b8d427a4abe120a244c9201406e542c81a755 Mon Sep 17 00:00:00 2001 From: Sen Date: Sat, 24 May 2025 20:38:49 +0200 Subject: [PATCH 065/200] network code cleanup --- client/src/client/network/ClientPlayer.java | 118 +-- common/src/common/block/BlockChest.java | 6 +- common/src/common/entity/DataWatcher.java | 6 +- .../src/common/entity/EntityTrackerEntry.java | 48 +- common/src/common/entity/npc/EntityNPC.java | 13 +- .../src/common/entity/types/EntityLiving.java | 6 +- common/src/common/item/Item.java | 8 - .../common/network/CompressionDecoder.java | 47 ++ .../common/network/CompressionEncoder.java | 42 ++ ...ionDecoder.java => EncryptionDecoder.java} | 8 +- ...ionEncoder.java => EncryptionEncoder.java} | 8 +- .../common/network/IClientLoginHandler.java | 13 +- common/src/common/network/IClientPlayer.java | 178 ++--- .../src/common/network/IHandshakeHandler.java | 6 +- common/src/common/network/ILoginHandler.java | 8 +- common/src/common/network/IPlayer.java | 97 +-- .../src/common/network/IThreadListener.java | 3 +- common/src/common/network/NetConnection.java | 170 ++--- common/src/common/network/NetHandler.java | 9 +- .../network/NettyCompressionDecoder.java | 62 -- .../network/NettyCompressionEncoder.java | 53 -- common/src/common/network/Packet.java | 3 +- common/src/common/network/PacketBuffer.java | 685 +++++++----------- common/src/common/network/PacketDecoder.java | 59 +- common/src/common/network/PacketEncoder.java | 55 +- .../src/common/network/PacketPrepender.java | 30 +- common/src/common/network/PacketRegistry.java | 296 ++++---- common/src/common/network/PacketSplitter.java | 72 +- common/src/common/packet/APacketVarInt.java | 4 +- common/src/common/packet/CPacketAction.java | 4 +- common/src/common/packet/CPacketBook.java | 52 -- common/src/common/packet/CPacketCheat.java | 4 +- common/src/common/packet/CPacketClick.java | 4 +- common/src/common/packet/CPacketComplete.java | 6 +- common/src/common/packet/CPacketForm.java | 14 +- common/src/common/packet/CPacketMessage.java | 2 +- common/src/common/packet/CPacketPlace.java | 4 +- common/src/common/packet/CPacketPlayer.java | 104 --- .../src/common/packet/CPacketPlayerLook.java | 35 + .../common/packet/CPacketPlayerPosLook.java | 46 ++ .../common/packet/CPacketPlayerPosition.java | 38 + common/src/common/packet/CPacketSign.java | 2 +- common/src/common/packet/CPacketSkin.java | 2 +- .../src/common/packet/HPacketHandshake.java | 4 +- common/src/common/packet/LPacketLogin.java | 2 +- .../packet/LPacketPasswordResponse.java | 6 +- .../src/common/packet/RPacketDisconnect.java | 2 +- common/src/common/packet/S14PacketEntity.java | 208 ------ .../src/common/packet/SPacketAnimation.java | 4 +- .../src/common/packet/SPacketBlockAction.java | 4 +- .../common/packet/SPacketBlockBreakAnim.java | 4 +- .../src/common/packet/SPacketBlockChange.java | 4 +- common/src/common/packet/SPacketCamera.java | 4 +- ...State.java => SPacketChangeGameState.java} | 14 +- .../common/packet/SPacketCharacterList.java | 24 +- .../src/common/packet/SPacketChunkData.java | 8 +- ...oseWindow.java => SPacketCloseWindow.java} | 6 +- .../src/common/packet/SPacketCollectItem.java | 8 +- ...on.java => SPacketConfirmTransaction.java} | 6 +- .../common/packet/SPacketDestroyEntities.java | 8 +- .../common/packet/SPacketDimensionName.java | 4 +- .../src/common/packet/SPacketDisconnect.java | 2 +- .../src/common/packet/SPacketDisplayForm.java | 24 +- ...28PacketEffect.java => SPacketEffect.java} | 6 +- common/src/common/packet/SPacketEntity.java | 99 +++ ...tyAttach.java => SPacketEntityAttach.java} | 6 +- ...tyEffect.java => SPacketEntityEffect.java} | 22 +- .../common/packet/SPacketEntityEquipment.java | 8 +- ...adLook.java => SPacketEntityHeadLook.java} | 10 +- .../src/common/packet/SPacketEntityLook.java | 38 + .../common/packet/SPacketEntityLookMove.java | 47 ++ ...tadata.java => SPacketEntityMetadata.java} | 10 +- ...ties.java => SPacketEntityProperties.java} | 26 +- .../common/packet/SPacketEntityRelMove.java | 39 + ...tyStatus.java => SPacketEntityStatus.java} | 6 +- ...leport.java => SPacketEntityTeleport.java} | 12 +- .../common/packet/SPacketEntityVelocity.java | 4 +- ...etExplosion.java => SPacketExplosion.java} | 6 +- common/src/common/packet/SPacketJoinGame.java | 4 +- common/src/common/packet/SPacketLoading.java | 4 +- .../common/packet/SPacketMapChunkBulk.java | 12 +- common/src/common/packet/SPacketMessage.java | 2 +- .../packet/SPacketMultiBlockChange.java | 8 +- ...OpenWindow.java => SPacketOpenWindow.java} | 16 +- ...etParticles.java => SPacketParticles.java} | 10 +- ...ities.java => SPacketPlayerAbilities.java} | 6 +- ...stItem.java => SPacketPlayerListItem.java} | 16 +- ...ct.java => SPacketRemoveEntityEffect.java} | 10 +- common/src/common/packet/SPacketRespawn.java | 4 +- .../common/packet/SPacketSetExperience.java | 8 +- ...PacketSetSlot.java => SPacketSetSlot.java} | 10 +- ...orOpen.java => SPacketSignEditorOpen.java} | 6 +- common/src/common/packet/SPacketSkin.java | 4 +- ...undEffect.java => SPacketSoundEffect.java} | 6 +- ...ity.java => SPacketSpawnGlobalEntity.java} | 14 +- common/src/common/packet/SPacketSpawnMob.java | 4 +- .../src/common/packet/SPacketSpawnObject.java | 4 +- .../src/common/packet/SPacketSpawnPlayer.java | 4 +- ...bComplete.java => SPacketTabComplete.java} | 12 +- .../src/common/packet/SPacketTimeUpdate.java | 2 +- common/src/common/packet/SPacketTrades.java | 12 +- ...tyNBT.java => SPacketUpdateEntityNBT.java} | 14 +- ...UpdateSign.java => SPacketUpdateSign.java} | 8 +- ...tity.java => SPacketUpdateTileEntity.java} | 10 +- ...ndowItems.java => SPacketWindowItems.java} | 10 +- ...operty.java => SPacketWindowProperty.java} | 6 +- common/src/common/packet/SPacketWorld.java | 4 +- .../common/tileentity/TileEntityBanner.java | 4 +- .../common/tileentity/TileEntityBeacon.java | 4 +- .../common/tileentity/TileEntityMachine.java | 4 +- .../tileentity/TileEntityMobSpawner.java | 4 +- .../src/common/tileentity/TileEntitySign.java | 4 +- .../common/tileentity/TileEntitySkull.java | 4 +- server/src/server/Server.java | 34 +- server/src/server/network/Player.java | 118 ++- server/src/server/world/WorldServer.java | 42 +- 116 files changed, 1541 insertions(+), 2022 deletions(-) create mode 100755 common/src/common/network/CompressionDecoder.java create mode 100755 common/src/common/network/CompressionEncoder.java rename common/src/common/network/{NettyEncryptionDecoder.java => EncryptionDecoder.java} (50%) rename common/src/common/network/{NettyEncryptionEncoder.java => EncryptionEncoder.java} (50%) delete mode 100755 common/src/common/network/NettyCompressionDecoder.java delete mode 100755 common/src/common/network/NettyCompressionEncoder.java delete mode 100755 common/src/common/packet/CPacketBook.java create mode 100644 common/src/common/packet/CPacketPlayerLook.java create mode 100644 common/src/common/packet/CPacketPlayerPosLook.java create mode 100644 common/src/common/packet/CPacketPlayerPosition.java delete mode 100755 common/src/common/packet/S14PacketEntity.java rename common/src/common/packet/{S2BPacketChangeGameState.java => SPacketChangeGameState.java} (76%) rename common/src/common/packet/{S2EPacketCloseWindow.java => SPacketCloseWindow.java} (84%) rename common/src/common/packet/{S32PacketConfirmTransaction.java => SPacketConfirmTransaction.java} (86%) rename common/src/common/packet/{S28PacketEffect.java => SPacketEffect.java} (84%) create mode 100755 common/src/common/packet/SPacketEntity.java rename common/src/common/packet/{S1BPacketEntityAttach.java => SPacketEntityAttach.java} (88%) rename common/src/common/packet/{S1DPacketEntityEffect.java => SPacketEntityEffect.java} (77%) rename common/src/common/packet/{S19PacketEntityHeadLook.java => SPacketEntityHeadLook.java} (79%) create mode 100644 common/src/common/packet/SPacketEntityLook.java create mode 100644 common/src/common/packet/SPacketEntityLookMove.java rename common/src/common/packet/{S1CPacketEntityMetadata.java => SPacketEntityMetadata.java} (82%) rename common/src/common/packet/{S20PacketEntityProperties.java => SPacketEntityProperties.java} (72%) create mode 100644 common/src/common/packet/SPacketEntityRelMove.java rename common/src/common/packet/{S1APacketEntityStatus.java => SPacketEntityStatus.java} (87%) rename common/src/common/packet/{S18PacketEntityTeleport.java => SPacketEntityTeleport.java} (86%) rename common/src/common/packet/{S27PacketExplosion.java => SPacketExplosion.java} (93%) rename common/src/common/packet/{S2DPacketOpenWindow.java => SPacketOpenWindow.java} (79%) rename common/src/common/packet/{S2APacketParticles.java => SPacketParticles.java} (90%) rename common/src/common/packet/{S39PacketPlayerAbilities.java => SPacketPlayerAbilities.java} (84%) rename common/src/common/packet/{S38PacketPlayerListItem.java => SPacketPlayerListItem.java} (70%) rename common/src/common/packet/{S1EPacketRemoveEntityEffect.java => SPacketRemoveEntityEffect.java} (79%) rename common/src/common/packet/{S2FPacketSetSlot.java => SPacketSetSlot.java} (82%) rename common/src/common/packet/{S36PacketSignEditorOpen.java => SPacketSignEditorOpen.java} (85%) rename common/src/common/packet/{S29PacketSoundEffect.java => SPacketSoundEffect.java} (90%) rename common/src/common/packet/{S2CPacketSpawnGlobalEntity.java => SPacketSpawnGlobalEntity.java} (82%) rename common/src/common/packet/{S3APacketTabComplete.java => SPacketTabComplete.java} (74%) rename common/src/common/packet/{S43PacketUpdateEntityNBT.java => SPacketUpdateEntityNBT.java} (72%) rename common/src/common/packet/{S33PacketUpdateSign.java => SPacketUpdateSign.java} (88%) rename common/src/common/packet/{S35PacketUpdateTileEntity.java => SPacketUpdateTileEntity.java} (84%) rename common/src/common/packet/{S30PacketWindowItems.java => SPacketWindowItems.java} (84%) rename common/src/common/packet/{S31PacketWindowProperty.java => SPacketWindowProperty.java} (87%) diff --git a/client/src/client/network/ClientPlayer.java b/client/src/client/network/ClientPlayer.java index c972aea..167b8ae 100755 --- a/client/src/client/network/ClientPlayer.java +++ b/client/src/client/network/ClientPlayer.java @@ -63,37 +63,37 @@ import common.network.IClientPlayer; import common.network.NetConnection; import common.network.NetHandler; import common.network.Packet; +import common.packet.CPacketPlayerPosLook; import common.packet.CPacketAction; import common.packet.CPacketKeepAlive; -import common.packet.CPacketPlayer; -import common.packet.S14PacketEntity; -import common.packet.S18PacketEntityTeleport; -import common.packet.S19PacketEntityHeadLook; -import common.packet.S1APacketEntityStatus; -import common.packet.S1BPacketEntityAttach; -import common.packet.S1CPacketEntityMetadata; -import common.packet.S1DPacketEntityEffect; -import common.packet.S1EPacketRemoveEntityEffect; -import common.packet.S20PacketEntityProperties; -import common.packet.S27PacketExplosion; -import common.packet.S28PacketEffect; -import common.packet.S29PacketSoundEffect; -import common.packet.S2APacketParticles; -import common.packet.S2BPacketChangeGameState; -import common.packet.S2CPacketSpawnGlobalEntity; -import common.packet.S2DPacketOpenWindow; -import common.packet.S2EPacketCloseWindow; -import common.packet.S2FPacketSetSlot; -import common.packet.S30PacketWindowItems; -import common.packet.S31PacketWindowProperty; -import common.packet.S32PacketConfirmTransaction; -import common.packet.S33PacketUpdateSign; -import common.packet.S35PacketUpdateTileEntity; -import common.packet.S36PacketSignEditorOpen; -import common.packet.S38PacketPlayerListItem; -import common.packet.S39PacketPlayerAbilities; -import common.packet.S3APacketTabComplete; -import common.packet.S43PacketUpdateEntityNBT; +import common.packet.SPacketEntity; +import common.packet.SPacketEntityTeleport; +import common.packet.SPacketEntityHeadLook; +import common.packet.SPacketEntityStatus; +import common.packet.SPacketEntityAttach; +import common.packet.SPacketEntityMetadata; +import common.packet.SPacketEntityEffect; +import common.packet.SPacketRemoveEntityEffect; +import common.packet.SPacketEntityProperties; +import common.packet.SPacketExplosion; +import common.packet.SPacketEffect; +import common.packet.SPacketSoundEffect; +import common.packet.SPacketParticles; +import common.packet.SPacketChangeGameState; +import common.packet.SPacketSpawnGlobalEntity; +import common.packet.SPacketOpenWindow; +import common.packet.SPacketCloseWindow; +import common.packet.SPacketSetSlot; +import common.packet.SPacketWindowItems; +import common.packet.SPacketWindowProperty; +import common.packet.SPacketConfirmTransaction; +import common.packet.SPacketUpdateSign; +import common.packet.SPacketUpdateTileEntity; +import common.packet.SPacketSignEditorOpen; +import common.packet.SPacketPlayerListItem; +import common.packet.SPacketPlayerAbilities; +import common.packet.SPacketTabComplete; +import common.packet.SPacketUpdateEntityNBT; import common.packet.SPacketAnimation; import common.packet.SPacketBiome; import common.packet.SPacketBlockAction; @@ -452,7 +452,7 @@ public class ClientPlayer extends NetHandler implements IClientPlayer /** * Handles globally visible entities. Used in vanilla for lightning bolts */ - public void handleSpawnGlobalEntity(S2CPacketSpawnGlobalEntity packetIn) + public void handleSpawnGlobalEntity(SPacketSpawnGlobalEntity packetIn) { NetHandler.checkThread(packetIn, this, this.gameController, this.clientWorldController); double d0 = (double)packetIn.getEncodedX() / 32.0D; @@ -505,7 +505,7 @@ public class ClientPlayer extends NetHandler implements IClientPlayer * Invoked when the server registers new proximate objects in your watchlist or when objects in your watchlist have * changed -> Registers any changes locally */ - public void handleEntityMetadata(S1CPacketEntityMetadata packetIn) + public void handleEntityMetadata(SPacketEntityMetadata packetIn) { NetHandler.checkThread(packetIn, this, this.gameController, this.clientWorldController); Entity entity = this.clientWorldController.getEntityByID(packetIn.getEntityId()); @@ -562,7 +562,7 @@ public class ClientPlayer extends NetHandler implements IClientPlayer /** * Updates an entity's position and rotation as specified by the packet */ - public void handleEntityTeleport(S18PacketEntityTeleport packetIn) + public void handleEntityTeleport(SPacketEntityTeleport packetIn) { NetHandler.checkThread(packetIn, this, this.gameController, this.clientWorldController); Entity entity = this.clientWorldController.getEntityByID(packetIn.getEntityId()); @@ -609,7 +609,7 @@ public class ClientPlayer extends NetHandler implements IClientPlayer * subclassing of the packet allows for the specification of a subset of this data (e.g. only rel. position, abs. * rotation or both). */ - public void handleEntityMovement(S14PacketEntity packetIn) + public void handleEntityMovement(SPacketEntity packetIn) { NetHandler.checkThread(packetIn, this, this.gameController, this.clientWorldController); Entity entity = packetIn.getEntity(this.clientWorldController); @@ -633,7 +633,7 @@ public class ClientPlayer extends NetHandler implements IClientPlayer * Updates the direction in which the specified entity is looking, normally this head rotation is independent of the * rotation of the entity itself */ - public void handleEntityHeadLook(S19PacketEntityHeadLook packetIn) + public void handleEntityHeadLook(SPacketEntityHeadLook packetIn) { NetHandler.checkThread(packetIn, this, this.gameController, this.clientWorldController); Entity entity = packetIn.getEntity(this.clientWorldController); @@ -714,7 +714,7 @@ public class ClientPlayer extends NetHandler implements IClientPlayer } entityplayer.setPositionAndRotation(d0, d1, d2, f, f1); - this.netManager.sendPacket(new CPacketPlayer.C06PacketPlayerPosLook(entityplayer.posX, entityplayer.getEntityBoundingBox().minY, entityplayer.posZ, entityplayer.rotYaw, entityplayer.rotPitch, false)); + this.netManager.sendPacket(new CPacketPlayerPosLook(entityplayer.posX, entityplayer.getEntityBoundingBox().minY, entityplayer.posZ, entityplayer.rotYaw, entityplayer.rotPitch, false)); if (!this.doneLoadingTerrain) { @@ -1008,7 +1008,7 @@ public class ClientPlayer extends NetHandler implements IClientPlayer // this.gameController.thePlayer.setSpawnPoint(packetIn.getSpawnPos(), true); // } - public void handleEntityAttach(S1BPacketEntityAttach packetIn) + public void handleEntityAttach(SPacketEntityAttach packetIn) { NetHandler.checkThread(packetIn, this, this.gameController, this.clientWorldController); Entity entity = this.clientWorldController.getEntityByID(packetIn.getEntityId()); @@ -1065,7 +1065,7 @@ public class ClientPlayer extends NetHandler implements IClientPlayer * (spawn particles), Zombie (villager transformation), Animal (breeding mode particles), Horse (breeding/smoke * particles), Sheep (...), Tameable (...), Villager (particles for breeding mode, angry and happy), Wolf (...) */ - public void handleEntityStatus(S1APacketEntityStatus packetIn) + public void handleEntityStatus(SPacketEntityStatus packetIn) { NetHandler.checkThread(packetIn, this, this.gameController, this.clientWorldController); Entity entity = packetIn.getEntity(this.clientWorldController); @@ -1127,7 +1127,7 @@ public class ClientPlayer extends NetHandler implements IClientPlayer /** * Initiates a new explosion (sound, particles, drop spawn) for the affected blocks indicated by the packet. */ - public void handleExplosion(S27PacketExplosion packetIn) + public void handleExplosion(SPacketExplosion packetIn) { NetHandler.checkThread(packetIn, this, this.gameController, this.clientWorldController); Explosion explosion = new Explosion(this.gameController.world, (Entity)null, packetIn.getX(), packetIn.getY(), packetIn.getZ(), packetIn.getStrength(), packetIn.getAffectedBlockPositions()); @@ -1141,7 +1141,7 @@ public class ClientPlayer extends NetHandler implements IClientPlayer * Displays a GUI by ID. In order starting from id 0: Chest, Workbench, Furnace, Dispenser, Enchanting table, * Brewing stand, Villager merchant, Beacon, Anvil, Hopper, Dropper, Horse */ - public void handleOpenWindow(S2DPacketOpenWindow packetIn) + public void handleOpenWindow(SPacketOpenWindow packetIn) { NetHandler.checkThread(packetIn, this, this.gameController, this.clientWorldController); EntityNPC entityplayersp = this.gameController.player; @@ -1190,7 +1190,7 @@ public class ClientPlayer extends NetHandler implements IClientPlayer /** * Handles pickin up an ItemStack or dropping one in your inventory or an open container */ - public void handleSetSlot(S2FPacketSetSlot packetIn) + public void handleSetSlot(SPacketSetSlot packetIn) { NetHandler.checkThread(packetIn, this, this.gameController, this.clientWorldController); EntityNPC entityplayer = this.gameController.player; @@ -1231,7 +1231,7 @@ public class ClientPlayer extends NetHandler implements IClientPlayer * Verifies that the server and client are synchronized with respect to the inventory/container opened by the player * and confirms if it is the case. */ - public void handleConfirmTransaction(S32PacketConfirmTransaction packetIn) + public void handleConfirmTransaction(SPacketConfirmTransaction packetIn) { NetHandler.checkThread(packetIn, this, this.gameController, this.clientWorldController); Container container = null; @@ -1255,7 +1255,7 @@ public class ClientPlayer extends NetHandler implements IClientPlayer /** * Handles the placement of a specified ItemStack in a specified container/inventory slot */ - public void handleWindowItems(S30PacketWindowItems packetIn) + public void handleWindowItems(SPacketWindowItems packetIn) { NetHandler.checkThread(packetIn, this, this.gameController, this.clientWorldController); EntityNPC entityplayer = this.gameController.player; @@ -1273,7 +1273,7 @@ public class ClientPlayer extends NetHandler implements IClientPlayer /** * Creates a sign in the specified location if it didn't exist and opens the GUI to edit its text */ - public void handleSignEditorOpen(S36PacketSignEditorOpen packetIn) + public void handleSignEditorOpen(SPacketSignEditorOpen packetIn) { NetHandler.checkThread(packetIn, this, this.gameController, this.clientWorldController); TileEntity tileentity = this.clientWorldController.getTileEntity(packetIn.getSignPosition()); @@ -1296,7 +1296,7 @@ public class ClientPlayer extends NetHandler implements IClientPlayer /** * Updates a specified sign with the specified text lines */ - public void handleUpdateSign(S33PacketUpdateSign packetIn) + public void handleUpdateSign(SPacketUpdateSign packetIn) { NetHandler.checkThread(packetIn, this, this.gameController, this.clientWorldController); // boolean flag = false; @@ -1331,7 +1331,7 @@ public class ClientPlayer extends NetHandler implements IClientPlayer * Updates the NBTTagCompound metadata of instances of the following entitytypes: Mob spawners, command blocks, * beacons, skulls, flowerpot */ - public void handleUpdateTileEntity(S35PacketUpdateTileEntity packetIn) + public void handleUpdateTileEntity(SPacketUpdateTileEntity packetIn) { NetHandler.checkThread(packetIn, this, this.gameController, this.clientWorldController); @@ -1350,7 +1350,7 @@ public class ClientPlayer extends NetHandler implements IClientPlayer /** * Sets the progressbar of the opened window to the specified value */ - public void handleWindowProperty(S31PacketWindowProperty packetIn) + public void handleWindowProperty(SPacketWindowProperty packetIn) { NetHandler.checkThread(packetIn, this, this.gameController, this.clientWorldController); EntityNPC entityplayer = this.gameController.player; @@ -1375,7 +1375,7 @@ public class ClientPlayer extends NetHandler implements IClientPlayer /** * Resets the ItemStack held in hand and closes the window that is opened */ - public void handleCloseWindow(S2EPacketCloseWindow packetIn) + public void handleCloseWindow(SPacketCloseWindow packetIn) { NetHandler.checkThread(packetIn, this, this.gameController, this.clientWorldController); // this.gameController.thePlayer.closeScreenAndDropStack(); @@ -1423,7 +1423,7 @@ public class ClientPlayer extends NetHandler implements IClientPlayer } } - public void handleChangeGameState(S2BPacketChangeGameState packetIn) + public void handleChangeGameState(SPacketChangeGameState packetIn) { NetHandler.checkThread(packetIn, this, this.gameController, this.clientWorldController); switch(packetIn.getAction()) { @@ -1448,7 +1448,7 @@ public class ClientPlayer extends NetHandler implements IClientPlayer } } - public void handleEffect(S28PacketEffect packetIn) + public void handleEffect(SPacketEffect packetIn) { NetHandler.checkThread(packetIn, this, this.gameController, this.clientWorldController); @@ -1513,7 +1513,7 @@ public class ClientPlayer extends NetHandler implements IClientPlayer // } // } - public void handleEntityEffect(S1DPacketEntityEffect packetIn) + public void handleEntityEffect(SPacketEntityEffect packetIn) { NetHandler.checkThread(packetIn, this, this.gameController, this.clientWorldController); Entity entity = this.clientWorldController.getEntityByID(packetIn.getEntityId()); @@ -1590,7 +1590,7 @@ public class ClientPlayer extends NetHandler implements IClientPlayer //// } // } - public void handleRemoveEntityEffect(S1EPacketRemoveEntityEffect packetIn) + public void handleRemoveEntityEffect(SPacketRemoveEntityEffect packetIn) { NetHandler.checkThread(packetIn, this, this.gameController, this.clientWorldController); Entity entity = this.clientWorldController.getEntityByID(packetIn.getEntityId()); @@ -1602,7 +1602,7 @@ public class ClientPlayer extends NetHandler implements IClientPlayer } - public void handlePlayerListItem(S38PacketPlayerListItem packetIn) + public void handlePlayerListItem(SPacketPlayerListItem packetIn) { NetHandler.checkThread(packetIn, this, this.gameController); @@ -1649,7 +1649,7 @@ public class ClientPlayer extends NetHandler implements IClientPlayer this.addToSendQueue(new CPacketKeepAlive(packetIn.getValue())); } - public void handlePlayerAbilities(S39PacketPlayerAbilities packetIn) + public void handlePlayerAbilities(SPacketPlayerAbilities packetIn) { NetHandler.checkThread(packetIn, this, this.gameController, this.clientWorldController); EntityNPC entityplayer = this.gameController.player; @@ -1662,7 +1662,7 @@ public class ClientPlayer extends NetHandler implements IClientPlayer /** * Displays the available command-completion options the server knows of */ - public void handleTabComplete(S3APacketTabComplete packetIn) + public void handleTabComplete(SPacketTabComplete packetIn) { NetHandler.checkThread(packetIn, this, this.gameController, this.clientWorldController); String[] astring = packetIn.func_149630_c(); @@ -1674,7 +1674,7 @@ public class ClientPlayer extends NetHandler implements IClientPlayer } } - public void handleSoundEffect(S29PacketSoundEffect packetIn) + public void handleSoundEffect(SPacketSoundEffect packetIn) { NetHandler.checkThread(packetIn, this, this.gameController, this.clientWorldController); if(packetIn.getSound() == null) { @@ -1711,7 +1711,7 @@ public class ClientPlayer extends NetHandler implements IClientPlayer //// } // } - public void handleEntityNBT(S43PacketUpdateEntityNBT packetIn) + public void handleEntityNBT(SPacketUpdateEntityNBT packetIn) { NetHandler.checkThread(packetIn, this, this.gameController, this.clientWorldController); Entity entity = packetIn.getEntity(this.clientWorldController); @@ -1835,7 +1835,7 @@ public class ClientPlayer extends NetHandler implements IClientPlayer * Spawns a specified number of particles at the specified location with a randomized displacement according to * specified bounds */ - public void handleParticles(S2APacketParticles packetIn) + public void handleParticles(SPacketParticles packetIn) { NetHandler.checkThread(packetIn, this, this.gameController, this.clientWorldController); @@ -1885,7 +1885,7 @@ public class ClientPlayer extends NetHandler implements IClientPlayer * sprinting, animals fleeing, baby speed), weapon/tool attackDamage, hostiles followRange randomization, zombie * maxHealth and knockback resistance as well as reinforcement spawning chance. */ - public void handleEntityProperties(S20PacketEntityProperties packetIn) + public void handleEntityProperties(SPacketEntityProperties packetIn) { NetHandler.checkThread(packetIn, this, this.gameController, this.clientWorldController); Entity entity = this.clientWorldController.getEntityByID(packetIn.getEntityId()); @@ -1900,7 +1900,7 @@ public class ClientPlayer extends NetHandler implements IClientPlayer { AttributeMap baseattributemap = ((EntityLiving)entity).getAttributeMap(); - for (S20PacketEntityProperties.Snapshot s20packetentityproperties$snapshot : packetIn.func_149441_d()) + for (SPacketEntityProperties.Snapshot s20packetentityproperties$snapshot : packetIn.func_149441_d()) { AttributeInstance iattributeinstance = baseattributemap.getAttributeInstanceByName(s20packetentityproperties$snapshot.func_151409_a()); diff --git a/common/src/common/block/BlockChest.java b/common/src/common/block/BlockChest.java index 7366655..9b2ed6b 100755 --- a/common/src/common/block/BlockChest.java +++ b/common/src/common/block/BlockChest.java @@ -15,7 +15,7 @@ import common.inventory.InventoryLargeChest; import common.item.CheatTab; import common.item.ItemStack; import common.material.Material; -import common.packet.S29PacketSoundEffect; +import common.packet.SPacketSoundEffect; import common.properties.IProperty; import common.properties.PropertyDirection; import common.tileentity.ILockableContainer; @@ -448,7 +448,7 @@ public class BlockChest extends BlockContainer ilockablecontainer.setLockCode(LockCode.EMPTY_CODE); // playerIn.triggerAchievement(StatRegistry.chestUnlockedStat); playerIn.connection.addHotbar(TextColor.BLUE + "%s wurde entriegelt", ilockablecontainer.getCommandName()); - playerIn.connection.sendPacket(new S29PacketSoundEffect(SoundEvent.DOOR, playerIn.posX, playerIn.posY, playerIn.posZ, 1.0F)); + playerIn.connection.sendPacket(new SPacketSoundEffect(SoundEvent.DOOR, playerIn.posX, playerIn.posY, playerIn.posZ, 1.0F)); return true; } } @@ -456,7 +456,7 @@ public class BlockChest extends BlockContainer ilockablecontainer.setLockCode(new LockCode(stack.getDisplayName())); // playerIn.triggerAchievement(StatRegistry.chestLockedStat); playerIn.connection.addHotbar(TextColor.ORANGE + "%s wurde verriegelt", ilockablecontainer.getCommandName()); - playerIn.connection.sendPacket(new S29PacketSoundEffect(SoundEvent.DOOR, playerIn.posX, playerIn.posY, playerIn.posZ, 1.0F)); + playerIn.connection.sendPacket(new SPacketSoundEffect(SoundEvent.DOOR, playerIn.posX, playerIn.posY, playerIn.posZ, 1.0F)); return true; } } diff --git a/common/src/common/entity/DataWatcher.java b/common/src/common/entity/DataWatcher.java index e4b9a7e..222676a 100755 --- a/common/src/common/entity/DataWatcher.java +++ b/common/src/common/entity/DataWatcher.java @@ -202,7 +202,7 @@ public class DataWatcher { case 5: ItemStack itemstack = (ItemStack)object.getObject(); - buffer.writeItemStackToBuffer(itemstack); + buffer.writeItemStack(itemstack); break; case 6: @@ -250,11 +250,11 @@ public class DataWatcher { break; case 4: - datawatcher$watchableobject = new DataWatcher.WatchableObject(j, k, buffer.readStringFromBuffer(32767)); + datawatcher$watchableobject = new DataWatcher.WatchableObject(j, k, buffer.readString(32767)); break; case 5: - datawatcher$watchableobject = new DataWatcher.WatchableObject(j, k, buffer.readItemStackFromBuffer()); + datawatcher$watchableobject = new DataWatcher.WatchableObject(j, k, buffer.readItemStack()); break; case 6: diff --git a/common/src/common/entity/EntityTrackerEntry.java b/common/src/common/entity/EntityTrackerEntry.java index 9b3a96f..fdcfcb0 100755 --- a/common/src/common/entity/EntityTrackerEntry.java +++ b/common/src/common/entity/EntityTrackerEntry.java @@ -14,14 +14,16 @@ import common.item.ItemStack; import common.log.Log; import common.nbt.NBTTagCompound; import common.network.Packet; -import common.packet.S14PacketEntity; -import common.packet.S18PacketEntityTeleport; -import common.packet.S19PacketEntityHeadLook; -import common.packet.S1BPacketEntityAttach; -import common.packet.S1CPacketEntityMetadata; -import common.packet.S1DPacketEntityEffect; -import common.packet.S20PacketEntityProperties; -import common.packet.S43PacketUpdateEntityNBT; +import common.packet.SPacketEntityRelMove; +import common.packet.SPacketEntityLook; +import common.packet.SPacketEntityLookMove; +import common.packet.SPacketEntityTeleport; +import common.packet.SPacketEntityHeadLook; +import common.packet.SPacketEntityAttach; +import common.packet.SPacketEntityMetadata; +import common.packet.SPacketEntityEffect; +import common.packet.SPacketEntityProperties; +import common.packet.SPacketUpdateEntityNBT; import common.packet.SPacketEntityEquipment; import common.packet.SPacketEntityVelocity; import common.packet.SPacketSpawnMob; @@ -96,7 +98,7 @@ public class EntityTrackerEntry { if(this.lastRiding != this.trackedEntity.vehicle || this.trackedEntity.vehicle != null && this.updateCounter % 60 == 0) { this.lastRiding = this.trackedEntity.vehicle; - this.sendPacketToTrackedPlayers(new S1BPacketEntityAttach(0, this.trackedEntity, this.trackedEntity.vehicle)); + this.sendPacketToTrackedPlayers(new SPacketEntityAttach(0, this.trackedEntity, this.trackedEntity.vehicle)); } // if(this.trackedEntity instanceof EntityFrame && this.updateCounter % 10 == 0) { @@ -141,23 +143,23 @@ public class EntityTrackerEntry { && !this.ridingEntity && this.onGround == this.trackedEntity.onGround) { if((!flag || !flag1) && !(this.trackedEntity instanceof EntityArrow)) { if(flag) { - packet1 = new S14PacketEntity.S15PacketEntityRelMove(this.trackedEntity.getId(), (byte)j2, (byte)k2, (byte)i, + packet1 = new SPacketEntityRelMove(this.trackedEntity.getId(), (byte)j2, (byte)k2, (byte)i, this.trackedEntity.onGround); } else if(flag1) { - packet1 = new S14PacketEntity.S16PacketEntityLook(this.trackedEntity.getId(), (byte)l1, (byte)i2, + packet1 = new SPacketEntityLook(this.trackedEntity.getId(), (byte)l1, (byte)i2, this.trackedEntity.onGround); } } else { - packet1 = new S14PacketEntity.S17PacketEntityLookMove(this.trackedEntity.getId(), (byte)j2, (byte)k2, (byte)i, + packet1 = new SPacketEntityLookMove(this.trackedEntity.getId(), (byte)j2, (byte)k2, (byte)i, (byte)l1, (byte)i2, this.trackedEntity.onGround); } } else { this.onGround = this.trackedEntity.onGround; this.ticksSinceLastForcedTeleport = 0; - packet1 = new S18PacketEntityTeleport(this.trackedEntity.getId(), k, j1, k1, (byte)l1, (byte)i2, + packet1 = new SPacketEntityTeleport(this.trackedEntity.getId(), k, j1, k1, (byte)l1, (byte)i2, this.trackedEntity.onGround); } } @@ -204,7 +206,7 @@ public class EntityTrackerEntry { boolean flag2 = Math.abs(j - this.encodedRotationYaw) >= 4 || Math.abs(i1 - this.encodedRotationPitch) >= 4; if(flag2) { - this.sendPacketToTrackedPlayers(new S14PacketEntity.S16PacketEntityLook(this.trackedEntity.getId(), (byte)j, (byte)i1, + this.sendPacketToTrackedPlayers(new SPacketEntityLook(this.trackedEntity.getId(), (byte)j, (byte)i1, this.trackedEntity.onGround)); this.encodedRotationYaw = j; this.encodedRotationPitch = i1; @@ -220,7 +222,7 @@ public class EntityTrackerEntry { int l = ExtMath.floorf(this.trackedEntity.getRotationYawHead() * 256.0F / 360.0F); if(Math.abs(l - this.lastHeadMotion) >= 4) { - this.sendPacketToTrackedPlayers(new S19PacketEntityHeadLook(this.trackedEntity, (byte)l)); + this.sendPacketToTrackedPlayers(new SPacketEntityHeadLook(this.trackedEntity, (byte)l)); this.lastHeadMotion = l; } @@ -239,7 +241,7 @@ public class EntityTrackerEntry { DataWatcher datawatcher = this.trackedEntity.getDataWatcher(); if(datawatcher.hasObjectChanged()) { - this.sendPacketToTrackedAndSelf(new S1CPacketEntityMetadata(this.trackedEntity.getId(), datawatcher, false)); + this.sendPacketToTrackedAndSelf(new SPacketEntityMetadata(this.trackedEntity.getId(), datawatcher, false)); } if(this.trackedEntity instanceof EntityLiving) { @@ -247,7 +249,7 @@ public class EntityTrackerEntry { Set set = serversideattributemap.getDirty(); if(!set.isEmpty()) { - this.sendPacketToTrackedAndSelf(new S20PacketEntityProperties(this.trackedEntity.getId(), set)); + this.sendPacketToTrackedAndSelf(new SPacketEntityProperties(this.trackedEntity.getId(), set)); } set.clear(); @@ -291,13 +293,13 @@ public class EntityTrackerEntry { if(!this.trackedEntity.getDataWatcher().isBlank()) { playerMP.connection - .sendPacket(new S1CPacketEntityMetadata(this.trackedEntity.getId(), this.trackedEntity.getDataWatcher(), true)); + .sendPacket(new SPacketEntityMetadata(this.trackedEntity.getId(), this.trackedEntity.getDataWatcher(), true)); } NBTTagCompound nbttagcompound = this.trackedEntity.getNBTTagCompound(); if(nbttagcompound != null) { - playerMP.connection.sendPacket(new S43PacketUpdateEntityNBT(this.trackedEntity.getId(), nbttagcompound)); + playerMP.connection.sendPacket(new SPacketUpdateEntityNBT(this.trackedEntity.getId(), nbttagcompound)); } if(this.trackedEntity instanceof EntityLiving) { @@ -305,7 +307,7 @@ public class EntityTrackerEntry { Collection collection = serversideattributemap.getWatchedAttributes(); if(!collection.isEmpty()) { - playerMP.connection.sendPacket(new S20PacketEntityProperties(this.trackedEntity.getId(), collection)); + playerMP.connection.sendPacket(new SPacketEntityProperties(this.trackedEntity.getId(), collection)); } } @@ -322,12 +324,12 @@ public class EntityTrackerEntry { } if(this.trackedEntity.vehicle != null) { - playerMP.connection.sendPacket(new S1BPacketEntityAttach(0, this.trackedEntity, this.trackedEntity.vehicle)); + playerMP.connection.sendPacket(new SPacketEntityAttach(0, this.trackedEntity, this.trackedEntity.vehicle)); } if(this.trackedEntity instanceof EntityLiving && ((EntityLiving)this.trackedEntity).getLeashedTo() != null) { playerMP.connection.sendPacket( - new S1BPacketEntityAttach(1, this.trackedEntity, ((EntityLiving)this.trackedEntity).getLeashedTo())); + new SPacketEntityAttach(1, this.trackedEntity, ((EntityLiving)this.trackedEntity).getLeashedTo())); } if(this.trackedEntity instanceof EntityLiving) { @@ -353,7 +355,7 @@ public class EntityTrackerEntry { EntityLiving entitylivingbase = (EntityLiving)this.trackedEntity; for(PotionEffect potioneffect : entitylivingbase.getEffects()) { - playerMP.connection.sendPacket(new S1DPacketEntityEffect(this.trackedEntity.getId(), potioneffect)); + playerMP.connection.sendPacket(new SPacketEntityEffect(this.trackedEntity.getId(), potioneffect)); } } } diff --git a/common/src/common/entity/npc/EntityNPC.java b/common/src/common/entity/npc/EntityNPC.java index a7c9cca..bc3c447 100755 --- a/common/src/common/entity/npc/EntityNPC.java +++ b/common/src/common/entity/npc/EntityNPC.java @@ -71,6 +71,9 @@ import common.nbt.NBTTagCompound; import common.nbt.NBTTagList; import common.network.IClientPlayer; import common.network.IPlayer; +import common.packet.CPacketPlayerPosition; +import common.packet.CPacketPlayerLook; +import common.packet.CPacketPlayerPosLook; import common.packet.CPacketAction; import common.packet.CPacketBreak; import common.packet.CPacketInput; @@ -1799,7 +1802,7 @@ public abstract class EntityNPC extends EntityLiving if (this.isRiding()) { - this.client.addToSendQueue(new CPacketPlayer.C05PacketPlayerLook(this.rotYaw, this.rotPitch, this.onGround)); + this.client.addToSendQueue(new CPacketPlayerLook(this.rotYaw, this.rotPitch, this.onGround)); this.client.addToSendQueue(new CPacketInput(this.moveStrafe, this.moveForward, this.client.isJumping(), this.client.isSneaking())); } else @@ -2667,15 +2670,15 @@ public abstract class EntityNPC extends EntityLiving { if (flag2 && flag3) { - this.client.addToSendQueue(new CPacketPlayer.C06PacketPlayerPosLook(this.posX, this.getEntityBoundingBox().minY, this.posZ, this.rotYaw, this.rotPitch, this.onGround)); + this.client.addToSendQueue(new CPacketPlayerPosLook(this.posX, this.getEntityBoundingBox().minY, this.posZ, this.rotYaw, this.rotPitch, this.onGround)); } else if (flag2) { - this.client.addToSendQueue(new CPacketPlayer.C04PacketPlayerPosition(this.posX, this.getEntityBoundingBox().minY, this.posZ, this.onGround)); + this.client.addToSendQueue(new CPacketPlayerPosition(this.posX, this.getEntityBoundingBox().minY, this.posZ, this.onGround)); } else if (flag3) { - this.client.addToSendQueue(new CPacketPlayer.C05PacketPlayerLook(this.rotYaw, this.rotPitch, this.onGround)); + this.client.addToSendQueue(new CPacketPlayerLook(this.rotYaw, this.rotPitch, this.onGround)); } else { @@ -2684,7 +2687,7 @@ public abstract class EntityNPC extends EntityLiving } else { - this.client.addToSendQueue(new CPacketPlayer.C06PacketPlayerPosLook(this.motionX, -99999999.0D, this.motionZ, this.rotYaw, this.rotPitch, this.onGround)); + this.client.addToSendQueue(new CPacketPlayerPosLook(this.motionX, -99999999.0D, this.motionZ, this.rotYaw, this.rotPitch, this.onGround)); flag2 = false; } diff --git a/common/src/common/entity/types/EntityLiving.java b/common/src/common/entity/types/EntityLiving.java index e247346..4ec9250 100755 --- a/common/src/common/entity/types/EntityLiving.java +++ b/common/src/common/entity/types/EntityLiving.java @@ -51,7 +51,7 @@ import common.model.ParticleType; import common.nbt.NBTTagCompound; import common.nbt.NBTTagList; import common.network.IPlayer; -import common.packet.S1BPacketEntityAttach; +import common.packet.SPacketEntityAttach; import common.packet.SPacketAnimation; import common.packet.SPacketCollectItem; import common.pathfinding.PathNavigate; @@ -3094,7 +3094,7 @@ public abstract class EntityLiving extends Entity } if(!this.worldObj.client && pkt && this.worldObj instanceof AWorldServer) { - ((AWorldServer)this.worldObj).sendToAllTrackingEntity(this, new S1BPacketEntityAttach(1, this, (Entity)null)); + ((AWorldServer)this.worldObj).sendToAllTrackingEntity(this, new SPacketEntityAttach(1, this, (Entity)null)); } } } @@ -3116,7 +3116,7 @@ public abstract class EntityLiving extends Entity this.leashedTo = entity; if(!this.worldObj.client && pkt && this.worldObj instanceof AWorldServer) { - ((AWorldServer)this.worldObj).sendToAllTrackingEntity(this, new S1BPacketEntityAttach(1, this, this.leashedTo)); + ((AWorldServer)this.worldObj).sendToAllTrackingEntity(this, new SPacketEntityAttach(1, this, this.leashedTo)); } } diff --git a/common/src/common/item/Item.java b/common/src/common/item/Item.java index f968ee9..b144b84 100755 --- a/common/src/common/item/Item.java +++ b/common/src/common/item/Item.java @@ -231,14 +231,6 @@ public class Item return this.display; } - /** - * If this function returns true (or the item is damageable), the ItemStack's NBT tag will be sent to the client. - */ - public boolean getShareTag() - { - return true; - } - public Item getContainerItem() { return this.containerItem; diff --git a/common/src/common/network/CompressionDecoder.java b/common/src/common/network/CompressionDecoder.java new file mode 100755 index 0000000..e681218 --- /dev/null +++ b/common/src/common/network/CompressionDecoder.java @@ -0,0 +1,47 @@ +package common.network; + +import java.util.List; +import java.util.zip.DataFormatException; +import java.util.zip.Inflater; + +import io.netty.buffer.ByteBuf; +import io.netty.buffer.Unpooled; +import io.netty.channel.ChannelHandlerContext; +import io.netty.handler.codec.ByteToMessageDecoder; +import io.netty.handler.codec.DecoderException; + +public class CompressionDecoder extends ByteToMessageDecoder { + private final Inflater inflater; + private int treshold; + + public CompressionDecoder(int treshold) { + this.treshold = treshold; + this.inflater = new Inflater(); + } + + protected void decode(ChannelHandlerContext context, ByteBuf buffer, List output) throws DataFormatException, Exception { + if(buffer.readableBytes() == 0) + return; + PacketBuffer pbuf = new PacketBuffer(buffer); + int len = pbuf.readVarInt(); + if(len == 0) { + output.add(pbuf.readBytes(pbuf.readableBytes())); + return; + } + if(len < this.treshold) + throw new DecoderException("Badly compressed packet - size of " + len + " is below server threshold of " + this.treshold); + if(len > 2097152) + throw new DecoderException("Badly compressed packet - size of " + len + " is larger than protocol maximum of " + 2097152); + byte[] comp = new byte[pbuf.readableBytes()]; + pbuf.readBytes(comp); + this.inflater.setInput(comp); + byte[] data = new byte[len]; + this.inflater.inflate(data); + output.add(Unpooled.wrappedBuffer(data)); + this.inflater.reset(); + } + + public void setTreshold(int treshold) { + this.treshold = treshold; + } +} diff --git a/common/src/common/network/CompressionEncoder.java b/common/src/common/network/CompressionEncoder.java new file mode 100755 index 0000000..8d975f2 --- /dev/null +++ b/common/src/common/network/CompressionEncoder.java @@ -0,0 +1,42 @@ +package common.network; + +import java.util.zip.Deflater; + +import io.netty.buffer.ByteBuf; +import io.netty.channel.ChannelHandlerContext; +import io.netty.handler.codec.MessageToByteEncoder; + +public class CompressionEncoder extends MessageToByteEncoder { + private final byte[] buffer = new byte[8192]; + private final Deflater deflater; + private int treshold; + + public CompressionEncoder(int treshold) { + this.treshold = treshold; + this.deflater = new Deflater(); + } + + protected void encode(ChannelHandlerContext context, ByteBuf buffer, ByteBuf output) throws Exception { + int len = buffer.readableBytes(); + PacketBuffer pbuf = new PacketBuffer(output); + if(len < this.treshold) { + pbuf.writeVarInt(0); + pbuf.writeBuffer(buffer); + return; + } + byte[] data = new byte[len]; + buffer.readBytes(data); + pbuf.writeVarInt(data.length); + this.deflater.setInput(data, 0, len); + this.deflater.finish(); + while(!this.deflater.finished()) { + int size = this.deflater.deflate(this.buffer); + pbuf.writeBytes(this.buffer, 0, size); + } + this.deflater.reset(); + } + + public void setTreshold(int treshold) { + this.treshold = treshold; + } +} diff --git a/common/src/common/network/NettyEncryptionDecoder.java b/common/src/common/network/EncryptionDecoder.java similarity index 50% rename from common/src/common/network/NettyEncryptionDecoder.java rename to common/src/common/network/EncryptionDecoder.java index dac5156..244773b 100644 --- a/common/src/common/network/NettyEncryptionDecoder.java +++ b/common/src/common/network/EncryptionDecoder.java @@ -7,14 +7,14 @@ import java.util.List; import javax.crypto.Cipher; import javax.crypto.ShortBufferException; -public class NettyEncryptionDecoder extends MessageToMessageDecoder { +public class EncryptionDecoder extends MessageToMessageDecoder { private final EncryptionCodec codec; - public NettyEncryptionDecoder(Cipher cipher) { + public EncryptionDecoder(Cipher cipher) { this.codec = new EncryptionCodec(cipher); } - protected void decode(ChannelHandlerContext p_decode_1_, ByteBuf p_decode_2_, List p_decode_3_) throws ShortBufferException, Exception { - p_decode_3_.add(this.codec.decipher(p_decode_1_, p_decode_2_)); + protected void decode(ChannelHandlerContext context, ByteBuf buffer, List output) throws ShortBufferException, Exception { + output.add(this.codec.decipher(context, buffer)); } } diff --git a/common/src/common/network/NettyEncryptionEncoder.java b/common/src/common/network/EncryptionEncoder.java similarity index 50% rename from common/src/common/network/NettyEncryptionEncoder.java rename to common/src/common/network/EncryptionEncoder.java index 0ec56f2..abfa860 100644 --- a/common/src/common/network/NettyEncryptionEncoder.java +++ b/common/src/common/network/EncryptionEncoder.java @@ -6,14 +6,14 @@ import io.netty.handler.codec.MessageToByteEncoder; import javax.crypto.Cipher; import javax.crypto.ShortBufferException; -public class NettyEncryptionEncoder extends MessageToByteEncoder { +public class EncryptionEncoder extends MessageToByteEncoder { private final EncryptionCodec codec; - public NettyEncryptionEncoder(Cipher cipher) { + public EncryptionEncoder(Cipher cipher) { this.codec = new EncryptionCodec(cipher); } - protected void encode(ChannelHandlerContext p_encode_1_, ByteBuf p_encode_2_, ByteBuf p_encode_3_) throws ShortBufferException, Exception { - this.codec.cipher(p_encode_2_, p_encode_3_); + protected void encode(ChannelHandlerContext context, ByteBuf buffer, ByteBuf output) throws ShortBufferException, Exception { + this.codec.cipher(buffer, output); } } diff --git a/common/src/common/network/IClientLoginHandler.java b/common/src/common/network/IClientLoginHandler.java index b2606e1..8f6de83 100644 --- a/common/src/common/network/IClientLoginHandler.java +++ b/common/src/common/network/IClientLoginHandler.java @@ -6,13 +6,8 @@ import common.packet.RPacketLoginSuccess; import common.packet.RPacketRequestEncrypt; public interface IClientLoginHandler { - - void handleDisconnect(RPacketDisconnect packetIn); - - void handleLoginSuccess(RPacketLoginSuccess packetIn); - - void handleEnableCompression(RPacketEnableCompression packetIn); - + void handleDisconnect(RPacketDisconnect packet); + void handleLoginSuccess(RPacketLoginSuccess packet); + void handleEnableCompression(RPacketEnableCompression packet); void handleEncrypt(RPacketRequestEncrypt packet); - -} \ No newline at end of file +} diff --git a/common/src/common/network/IClientPlayer.java b/common/src/common/network/IClientPlayer.java index 292929b..7884c94 100644 --- a/common/src/common/network/IClientPlayer.java +++ b/common/src/common/network/IClientPlayer.java @@ -5,34 +5,34 @@ import common.entity.animal.EntityHorse; import common.inventory.IInventory; import common.inventory.InventoryPlayer; import common.model.ParticleType; -import common.packet.S14PacketEntity; -import common.packet.S18PacketEntityTeleport; -import common.packet.S19PacketEntityHeadLook; -import common.packet.S1APacketEntityStatus; -import common.packet.S1BPacketEntityAttach; -import common.packet.S1CPacketEntityMetadata; -import common.packet.S1DPacketEntityEffect; -import common.packet.S1EPacketRemoveEntityEffect; -import common.packet.S20PacketEntityProperties; -import common.packet.S27PacketExplosion; -import common.packet.S28PacketEffect; -import common.packet.S29PacketSoundEffect; -import common.packet.S2APacketParticles; -import common.packet.S2BPacketChangeGameState; -import common.packet.S2CPacketSpawnGlobalEntity; -import common.packet.S2DPacketOpenWindow; -import common.packet.S2EPacketCloseWindow; -import common.packet.S2FPacketSetSlot; -import common.packet.S30PacketWindowItems; -import common.packet.S31PacketWindowProperty; -import common.packet.S32PacketConfirmTransaction; -import common.packet.S33PacketUpdateSign; -import common.packet.S35PacketUpdateTileEntity; -import common.packet.S36PacketSignEditorOpen; -import common.packet.S38PacketPlayerListItem; -import common.packet.S39PacketPlayerAbilities; -import common.packet.S3APacketTabComplete; -import common.packet.S43PacketUpdateEntityNBT; +import common.packet.SPacketEntity; +import common.packet.SPacketEntityTeleport; +import common.packet.SPacketEntityHeadLook; +import common.packet.SPacketEntityStatus; +import common.packet.SPacketEntityAttach; +import common.packet.SPacketEntityMetadata; +import common.packet.SPacketEntityEffect; +import common.packet.SPacketRemoveEntityEffect; +import common.packet.SPacketEntityProperties; +import common.packet.SPacketExplosion; +import common.packet.SPacketEffect; +import common.packet.SPacketSoundEffect; +import common.packet.SPacketParticles; +import common.packet.SPacketChangeGameState; +import common.packet.SPacketSpawnGlobalEntity; +import common.packet.SPacketOpenWindow; +import common.packet.SPacketCloseWindow; +import common.packet.SPacketSetSlot; +import common.packet.SPacketWindowItems; +import common.packet.SPacketWindowProperty; +import common.packet.SPacketConfirmTransaction; +import common.packet.SPacketUpdateSign; +import common.packet.SPacketUpdateTileEntity; +import common.packet.SPacketSignEditorOpen; +import common.packet.SPacketPlayerListItem; +import common.packet.SPacketPlayerAbilities; +import common.packet.SPacketTabComplete; +import common.packet.SPacketUpdateEntityNBT; import common.packet.SPacketAnimation; import common.packet.SPacketBiome; import common.packet.SPacketBlockAction; @@ -76,7 +76,7 @@ public interface IClientPlayer { void playSound(Sound sound); boolean isRenderViewEntity(Entity entity); void updatePlayerMoveState(); - void emitParticleAtEntity(Entity entityIn, ParticleType particleTypes); + void emitParticleAtEntity(Entity entity, ParticleType particleTypes); boolean isJumping(); boolean isSprinting(); boolean isSneaking(); @@ -86,73 +86,73 @@ public interface IClientPlayer { void setMoveStrafe(float value); void addToSendQueue(Packet packet); - void handleJoinGame(SPacketJoinGame packetIn); - void handleSpawnObject(SPacketSpawnObject packetIn); - void handleSpawnGlobalEntity(S2CPacketSpawnGlobalEntity packetIn); - void handleEntityVelocity(SPacketEntityVelocity packetIn); - void handleEntityMetadata(S1CPacketEntityMetadata packetIn); - void handleSpawnPlayer(SPacketSpawnPlayer packetIn); - void handleEntityTeleport(S18PacketEntityTeleport packetIn); - void handleHeldItemChange(SPacketHeldItemChange packetIn); - void handleEntityMovement(S14PacketEntity packetIn); - void handleEntityHeadLook(S19PacketEntityHeadLook packetIn); - void handleDestroyEntities(SPacketDestroyEntities packetIn); - void handlePlayerPosLook(SPacketPlayerPosLook packetIn); - void handleMultiBlockChange(SPacketMultiBlockChange packetIn); - void handleChunkData(SPacketChunkData packetIn); - void handleBiomes(SPacketBiome packetIn); - void handleBlockChange(SPacketBlockChange packetIn); - void handleDisconnect(SPacketDisconnect packetIn); - void handleCollectItem(SPacketCollectItem packetIn); - void handleMessage(SPacketMessage packetIn); + void handleJoinGame(SPacketJoinGame packet); + void handleSpawnObject(SPacketSpawnObject packet); + void handleSpawnGlobalEntity(SPacketSpawnGlobalEntity packet); + void handleEntityVelocity(SPacketEntityVelocity packet); + void handleEntityMetadata(SPacketEntityMetadata packet); + void handleSpawnPlayer(SPacketSpawnPlayer packet); + void handleEntityTeleport(SPacketEntityTeleport packet); + void handleHeldItemChange(SPacketHeldItemChange packet); + void handleEntityMovement(SPacketEntity packet); + void handleEntityHeadLook(SPacketEntityHeadLook packet); + void handleDestroyEntities(SPacketDestroyEntities packet); + void handlePlayerPosLook(SPacketPlayerPosLook packet); + void handleMultiBlockChange(SPacketMultiBlockChange packet); + void handleChunkData(SPacketChunkData packet); + void handleBiomes(SPacketBiome packet); + void handleBlockChange(SPacketBlockChange packet); + void handleDisconnect(SPacketDisconnect packet); + void handleCollectItem(SPacketCollectItem packet); + void handleMessage(SPacketMessage packet); void handleLoading(SPacketLoading packet); - void handleAnimation(SPacketAnimation packetIn); - void handleSpawnMob(SPacketSpawnMob packetIn); - void handleTimeUpdate(SPacketTimeUpdate packetIn); + void handleAnimation(SPacketAnimation packet); + void handleSpawnMob(SPacketSpawnMob packet); + void handleTimeUpdate(SPacketTimeUpdate packet); void handleServerTick(SPacketServerTick packet); - void handleEntityAttach(S1BPacketEntityAttach packetIn); - void handleEntityStatus(S1APacketEntityStatus packetIn); - void handleUpdateHealth(SPacketUpdateHealth packetIn); - void handleSetExperience(SPacketSetExperience packetIn); - void handleRespawn(SPacketRespawn packetIn); - void handleExplosion(S27PacketExplosion packetIn); - void handleOpenWindow(S2DPacketOpenWindow packetIn); - void handleSetSlot(S2FPacketSetSlot packetIn); - void handleConfirmTransaction(S32PacketConfirmTransaction packetIn); - void handleWindowItems(S30PacketWindowItems packetIn); - void handleSignEditorOpen(S36PacketSignEditorOpen packetIn); - void handleUpdateSign(S33PacketUpdateSign packetIn); - void handleUpdateTileEntity(S35PacketUpdateTileEntity packetIn); - void handleWindowProperty(S31PacketWindowProperty packetIn); - void handleEntityEquipment(SPacketEntityEquipment packetIn); - void handleCloseWindow(S2EPacketCloseWindow packetIn); - void handleBlockAction(SPacketBlockAction packetIn); - void handleBlockBreakAnim(SPacketBlockBreakAnim packetIn); - void handleMapChunkBulk(SPacketMapChunkBulk packetIn); - void handleChangeGameState(S2BPacketChangeGameState packetIn); - void handleEffect(S28PacketEffect packetIn); - void handleEntityEffect(S1DPacketEntityEffect packetIn); - void handleCamera(SPacketCamera packetIn); - void handleRemoveEntityEffect(S1EPacketRemoveEntityEffect packetIn); - void handlePlayerListItem(S38PacketPlayerListItem packetIn); + void handleEntityAttach(SPacketEntityAttach packet); + void handleEntityStatus(SPacketEntityStatus packet); + void handleUpdateHealth(SPacketUpdateHealth packet); + void handleSetExperience(SPacketSetExperience packet); + void handleRespawn(SPacketRespawn packet); + void handleExplosion(SPacketExplosion packet); + void handleOpenWindow(SPacketOpenWindow packet); + void handleSetSlot(SPacketSetSlot packet); + void handleConfirmTransaction(SPacketConfirmTransaction packet); + void handleWindowItems(SPacketWindowItems packet); + void handleSignEditorOpen(SPacketSignEditorOpen packet); + void handleUpdateSign(SPacketUpdateSign packet); + void handleUpdateTileEntity(SPacketUpdateTileEntity packet); + void handleWindowProperty(SPacketWindowProperty packet); + void handleEntityEquipment(SPacketEntityEquipment packet); + void handleCloseWindow(SPacketCloseWindow packet); + void handleBlockAction(SPacketBlockAction packet); + void handleBlockBreakAnim(SPacketBlockBreakAnim packet); + void handleMapChunkBulk(SPacketMapChunkBulk packet); + void handleChangeGameState(SPacketChangeGameState packet); + void handleEffect(SPacketEffect packet); + void handleEntityEffect(SPacketEntityEffect packet); + void handleCamera(SPacketCamera packet); + void handleRemoveEntityEffect(SPacketRemoveEntityEffect packet); + void handlePlayerListItem(SPacketPlayerListItem packet); void handleCharacterList(SPacketCharacterList packet); - void handleKeepAlive(SPacketKeepAlive packetIn); - void handlePlayerAbilities(S39PacketPlayerAbilities packetIn); - void handleTabComplete(S3APacketTabComplete packetIn); - void handleSoundEffect(S29PacketSoundEffect packetIn); - void handleEntityNBT(S43PacketUpdateEntityNBT packetIn); - void handleParticles(S2APacketParticles packetIn); - void handleEntityProperties(S20PacketEntityProperties packetIn); - void handleSkin(SPacketSkin packetIn); - void handleTrades(SPacketTrades packetIn); - void handleWorld(SPacketWorld packetIn); - void handleDimName(SPacketDimensionName packetIn); + void handleKeepAlive(SPacketKeepAlive packet); + void handlePlayerAbilities(SPacketPlayerAbilities packet); + void handleTabComplete(SPacketTabComplete packet); + void handleSoundEffect(SPacketSoundEffect packet); + void handleEntityNBT(SPacketUpdateEntityNBT packet); + void handleParticles(SPacketParticles packet); + void handleEntityProperties(SPacketEntityProperties packet); + void handleSkin(SPacketSkin packet); + void handleTrades(SPacketTrades packet); + void handleWorld(SPacketWorld packet); + void handleDimName(SPacketDimensionName packet); void handleForm(SPacketDisplayForm packet); void displayGUIChest(IInventory chestInventory, InventoryPlayer inventory); - void displayGui(IInteractionObject guiOwner, InventoryPlayer inventory, World worldObj); + void displayGui(IInteractionObject guiOwner, InventoryPlayer inventory, World world); void displayGuiHorse(EntityHorse horse, InventoryPlayer inventory, IInventory horseInventory); - void displayGuiMerchant(String title, InventoryPlayer inventory, World worldObj); + void displayGuiMerchant(String title, InventoryPlayer inventory, World world); void displayGuiSign(BlockPos pos, String[] text); void closeGui(); } \ No newline at end of file diff --git a/common/src/common/network/IHandshakeHandler.java b/common/src/common/network/IHandshakeHandler.java index b6815e8..1a534ba 100644 --- a/common/src/common/network/IHandshakeHandler.java +++ b/common/src/common/network/IHandshakeHandler.java @@ -3,7 +3,5 @@ package common.network; import common.packet.HPacketHandshake; public interface IHandshakeHandler { - - void processHandshake(HPacketHandshake packetIn); - -} \ No newline at end of file + void processHandshake(HPacketHandshake packet); +} diff --git a/common/src/common/network/ILoginHandler.java b/common/src/common/network/ILoginHandler.java index 479e986..b33bca6 100644 --- a/common/src/common/network/ILoginHandler.java +++ b/common/src/common/network/ILoginHandler.java @@ -5,11 +5,7 @@ import common.packet.LPacketPasswordResponse; import common.packet.LPacketStartEncrypt; public interface ILoginHandler { - - void processPasswordResponse(LPacketPasswordResponse packetIn); - + void processPasswordResponse(LPacketPasswordResponse packet); void processEncryption(LPacketStartEncrypt packet); - void processLogin(LPacketLogin packet); - -} \ No newline at end of file +} diff --git a/common/src/common/network/IPlayer.java b/common/src/common/network/IPlayer.java index 42d3fb6..bbe9652 100644 --- a/common/src/common/network/IPlayer.java +++ b/common/src/common/network/IPlayer.java @@ -11,7 +11,6 @@ import common.inventory.Container; import common.inventory.IInventory; import common.item.ItemStack; import common.packet.CPacketAction; -import common.packet.CPacketBook; import common.packet.CPacketBreak; import common.packet.CPacketCheat; import common.packet.CPacketClick; @@ -63,115 +62,61 @@ public interface IPlayer { } void onEntityDeath(); - boolean isInEditor(); - EntityNPC getPresentEntity(); - String getUser(); - int getLatency(); - boolean isAdmin(); - void addToPlayerScore(EntityLiving entity); - - void displayTradeGui(EntityNPC npc); - + void displayTradeGui(EntityNPC entity); void setPlayerHealthUpdated(); - - void removeEntity(Entity p_152339_1_); - + void removeEntity(Entity entity); void sendPlayerAbilities(); - void addFeed(String msg); - void addHotbar(String msg); - void addHotbar(String format, Object... args); - void sendThrowMessage(ItemStack stack); - void resetLastExperience(); - - void travelToDimension(int dimensionId, BlockPos pos, float yaw, float pitch, PortalType portal); - + void travelToDimension(int dimension, BlockPos pos, float yaw, float pitch, PortalType portal); void teleport(double x, double y, double z, float yaw, float pitch, int dimension); - void onItemPickup(Entity entity, int amount); - - void mountEntity(Entity entityIn); - + void mountEntity(Entity entity); void openEditSign(TileEntitySign signTile); - void displayGui(IInteractionObject guiOwner); - void displayGUIChest(IInventory chestInventory); - void displayGUIHorse(EntityHorse horse, IInventory horseInventory); - void closeScreen(); - void onItemUseFinish(); - void onNewEffect(PotionEffect id); - void onChangedEffect(PotionEffect id, boolean added); - void onFinishedEffect(PotionEffect effect); - void setPositionAndUpdate(double x, double y, double z); - - void onCriticalHit(Entity entityHit); - - void onEnchantmentCritical(Entity entityHit); - + void onCriticalHit(Entity entity); + void onEnchantmentCritical(Entity entity); void updateEffectMeta(); - void playSound(SoundEvent name, float volume); - void sendContainerToPlayer(Container container); - void updateEntity(); - void setSelection(boolean primary, BlockPos pos); - void setSelectMode(); - void sendPacket(Packet packet); - void setPlayerLocation(double x, double y, double z, float yaw, float pitch); - - void processKeepAlive(CPacketKeepAlive packetIn); - - void processMessage(CPacketMessage packetIn); - - void processComplete(CPacketComplete packetIn); - - void processPlayer(CPacketPlayer packetIn); - - void processBreak(CPacketBreak packetIn); - - void processPlace(CPacketPlace packetIn); - - void processAction(CPacketAction packetIn); - - void processInput(CPacketInput packetIn); - - void processClick(CPacketClick packetIn); - - void processCheat(CPacketCheat packetIn); - - void processSign(CPacketSign packetIn); - - void processSkin(CPacketSkin packetIn); - - void processBook(CPacketBook packetIn); - - void processForm(CPacketForm packet); - List getLoadedChunkList(); double getManagedX(); double getManagedZ(); void setManagedPos(double x, double z); -} \ No newline at end of file + + void processKeepAlive(CPacketKeepAlive packet); + void processMessage(CPacketMessage packet); + void processComplete(CPacketComplete packet); + void processPlayer(CPacketPlayer packet); + void processBreak(CPacketBreak packet); + void processPlace(CPacketPlace packet); + void processAction(CPacketAction packet); + void processInput(CPacketInput packet); + void processClick(CPacketClick packet); + void processCheat(CPacketCheat packet); + void processSign(CPacketSign packet); + void processSkin(CPacketSkin packet); + void processForm(CPacketForm packet); +} diff --git a/common/src/common/network/IThreadListener.java b/common/src/common/network/IThreadListener.java index e6f14d4..646777a 100755 --- a/common/src/common/network/IThreadListener.java +++ b/common/src/common/network/IThreadListener.java @@ -2,8 +2,7 @@ package common.network; import common.future.ListenableFuture; -public interface IThreadListener -{ +public interface IThreadListener { ListenableFuture schedule(Runnable run); boolean isMainThread(); default void log(String prefixed, String line) { diff --git a/common/src/common/network/NetConnection.java b/common/src/common/network/NetConnection.java index a359d83..216b3cb 100755 --- a/common/src/common/network/NetConnection.java +++ b/common/src/common/network/NetConnection.java @@ -27,34 +27,32 @@ public class NetConnection extends SimpleChannelInboundHandler { private static final Pattern IP_REPLACER = Pattern.compile("([0-9]*)\\.([0-9]*)\\.[0-9]*\\.[0-9]*"); public static final AttributeKey ATTR_STATE = AttributeKey.valueOf("protocol"); - private final Queue outboundPacketsQueue = new ConcurrentLinkedQueue(); - private final ReentrantReadWriteLock readWriteLock = new ReentrantReadWriteLock(); + + private final Queue queue = new ConcurrentLinkedQueue(); + private final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(); private Channel channel; - private SocketAddress socketAddress; - private NetHandler packetListener; - private String terminationReason; + private SocketAddress address; + private NetHandler handler; + private String exitReason; private boolean disconnected; - public void channelActive(ChannelHandlerContext p_channelActive_1_) throws Exception + public void channelActive(ChannelHandlerContext context) throws Exception { - super.channelActive(p_channelActive_1_); - this.channel = p_channelActive_1_.channel(); - this.socketAddress = this.channel.remoteAddress(); + super.channelActive(context); + this.channel = context.channel(); + this.address = this.channel.remoteAddress(); try { this.setConnectionState(PacketRegistry.HANDSHAKE); } - catch (Throwable throwable) + catch (Throwable t) { - Log.JNI.error(throwable, "Fehler beim Aufbauen der Verbindung für Handshake"); + Log.JNI.error(t, "Fehler beim Aufbauen der Verbindung für Handshake"); } } - /** - * Sets the new connection state and registers which packets this channel may send and receive - */ public void setConnectionState(PacketRegistry newState) { this.channel.attr(ATTR_STATE).set(newState); @@ -62,36 +60,36 @@ public class NetConnection extends SimpleChannelInboundHandler // Log.debug("Automatisches Lesen eingeschaltet"); } - public void channelInactive(ChannelHandlerContext p_channelInactive_1_) throws Exception + public void channelInactive(ChannelHandlerContext context) throws Exception { this.closeChannel("Ende der Datenübertragung"); } - public void exceptionCaught(ChannelHandlerContext p_exceptionCaught_1_, Throwable p_exceptionCaught_2_) throws Exception + public void exceptionCaught(ChannelHandlerContext context, Throwable throwable) throws Exception { String comp; - if (p_exceptionCaught_2_ instanceof TimeoutException) + if (throwable instanceof TimeoutException) { comp = "Zeitüberschreitung"; } else { - comp = "Interner Fehler: " + p_exceptionCaught_2_; - if(!(p_exceptionCaught_2_ instanceof ClosedChannelException)) - Log.SYSTEM.error(p_exceptionCaught_2_, "Fehler in der Verbindung mit %s", this.getCutAddress()); + comp = "Interner Fehler: " + throwable; + if(!(throwable instanceof ClosedChannelException)) + Log.SYSTEM.error(throwable, "Fehler in der Verbindung mit %s", this.getCutAddress()); } this.closeChannel(comp); } - protected void channelRead0(ChannelHandlerContext p_channelRead0_1_, Packet p_channelRead0_2_) throws Exception + protected void channelRead0(ChannelHandlerContext context, Packet packet) throws Exception { if (this.channel.isOpen()) { try { - p_channelRead0_2_.processPacket(this.packetListener); + packet.processPacket(this.handler); } catch (ThreadQuickExitException e) { @@ -100,17 +98,13 @@ public class NetConnection extends SimpleChannelInboundHandler } } - /** - * Sets the NetHandler for this NetworkManager, no checks are made if this handler is suitable for the particular - * connection state (protocol) - */ public void setNetHandler(NetHandler handler) { if (handler == null) { throw new NullPointerException("Handler ist Null"); } // Log.debug("Setze Handler von " + this + " auf " + handler); - this.packetListener = handler; + this.handler = handler; } public void sendPacket(Packet packetIn) @@ -122,15 +116,15 @@ public class NetConnection extends SimpleChannelInboundHandler } else { - this.readWriteLock.writeLock().lock(); + this.lock.writeLock().lock(); try { - this.outboundPacketsQueue.add(new NetConnection.InboundHandlerTuplePacketListener(packetIn, null)); + this.queue.add(new NetConnection.InboundHandlerTuplePacketListener(packetIn, null)); } finally { - this.readWriteLock.writeLock().unlock(); + this.lock.writeLock().unlock(); } } } @@ -144,29 +138,25 @@ public class NetConnection extends SimpleChannelInboundHandler } else { - this.readWriteLock.writeLock().lock(); + this.lock.writeLock().lock(); try { - this.outboundPacketsQueue.add(new NetConnection.InboundHandlerTuplePacketListener(packetIn, listener)); + this.queue.add(new NetConnection.InboundHandlerTuplePacketListener(packetIn, listener)); } finally { - this.readWriteLock.writeLock().unlock(); + this.lock.writeLock().unlock(); } } } - /** - * Will commit the packet to the channel. If the current thread 'owns' the channel it will write and flush the - * packet, otherwise it will add a task for the channel eventloop thread to do that. - */ private void dispatchPacket(final Packet inPacket, final GenericFutureListener > [] futureListeners) { - final PacketRegistry enumconnectionstate = PacketRegistry.getType(inPacket); - final PacketRegistry enumconnectionstate1 = (PacketRegistry)this.channel.attr(ATTR_STATE).get(); + final PacketRegistry state = PacketRegistry.getType(inPacket); + final PacketRegistry current = this.channel.attr(ATTR_STATE).get(); - if (enumconnectionstate1 != enumconnectionstate) + if (current != state) { // Log.debug("Automatisches Lesen ausgeschaltet"); this.channel.config().setAutoRead(false); @@ -174,9 +164,9 @@ public class NetConnection extends SimpleChannelInboundHandler if (this.channel.eventLoop().inEventLoop()) { - if (enumconnectionstate != enumconnectionstate1) + if (state != current) { - this.setConnectionState(enumconnectionstate); + this.setConnectionState(state); } ChannelFuture channelfuture = this.channel.writeAndFlush(inPacket); @@ -194,9 +184,9 @@ public class NetConnection extends SimpleChannelInboundHandler { public void run() { - if (enumconnectionstate != enumconnectionstate1) + if (state != current) { - NetConnection.this.setConnectionState(enumconnectionstate); + NetConnection.this.setConnectionState(state); } ChannelFuture channelfuture1 = NetConnection.this.channel.writeAndFlush(inPacket); @@ -212,68 +202,46 @@ public class NetConnection extends SimpleChannelInboundHandler } } - /** - * Will iterate through the outboundPacketQueue and dispatch all Packets - */ private void flushOutboundQueue() { if (this.channel != null && this.channel.isOpen()) { - this.readWriteLock.readLock().lock(); + this.lock.readLock().lock(); try { - while (!this.outboundPacketsQueue.isEmpty()) + while (!this.queue.isEmpty()) { - NetConnection.InboundHandlerTuplePacketListener networkmanager$inboundhandlertuplepacketlistener = (NetConnection.InboundHandlerTuplePacketListener)this.outboundPacketsQueue.poll(); - if(networkmanager$inboundhandlertuplepacketlistener != null) { // NPE Fix - this.dispatchPacket(networkmanager$inboundhandlertuplepacketlistener.packet, networkmanager$inboundhandlertuplepacketlistener.futureListeners); - } + NetConnection.InboundHandlerTuplePacketListener entry = this.queue.poll(); + if(entry != null) // NPE Fix + this.dispatchPacket(entry.packet, entry.listeners); } } finally { - this.readWriteLock.readLock().unlock(); + this.lock.readLock().unlock(); } } } - /** - * Checks timeouts and processes all packets received - */ public void processReceivedPackets() { this.flushOutboundQueue(); - this.packetListener.update(); -// if (this.packetListener instanceof ITickable) -// { -// ((ITickable)this.packetListener).update(); -// } + this.handler.update(); if(this.channel != null) this.channel.flush(); } - -// /** -// * Returns the socket address of the remote side. Server-only. -// */ -// public SocketAddress getRemoteAddress() -// { -// return this.socketAddress; -// } public String getCutAddress() { - return this.socketAddress == null ? "?.?.*.*" : IP_REPLACER.matcher(this.socketAddress.toString()).replaceAll("$1.$2.*.*"); + return this.address == null ? "?.?.*.*" : IP_REPLACER.matcher(this.address.toString()).replaceAll("$1.$2.*.*"); } - /** - * Closes the channel, the parameter can be used for an exit message (not certain how it gets sent) - */ public void closeChannel(String message) { if (this.channel.isOpen()) { this.channel.close().awaitUninterruptibly(); - this.terminationReason = message; + this.exitReason = message; } } @@ -287,17 +255,6 @@ public class NetConnection extends SimpleChannelInboundHandler return this.channel == null; } - /** - * Gets the current handler for processing packets - */ - public NetHandler getNetHandler() - { - return this.packetListener; - } - - /** - * Switches the channel to manual reading modus - */ public void disableAutoRead() { this.channel.config().setAutoRead(false); @@ -307,32 +264,32 @@ public class NetConnection extends SimpleChannelInboundHandler { if (treshold >= 0) { - if (this.channel.pipeline().get("decompress") instanceof NettyCompressionDecoder) + if (this.channel.pipeline().get("decompress") instanceof CompressionDecoder) { - ((NettyCompressionDecoder)this.channel.pipeline().get("decompress")).setCompressionTreshold(treshold); + ((CompressionDecoder)this.channel.pipeline().get("decompress")).setTreshold(treshold); } else { - this.channel.pipeline().addBefore("decoder", "decompress", new NettyCompressionDecoder(treshold)); + this.channel.pipeline().addBefore("decoder", "decompress", new CompressionDecoder(treshold)); } - if (this.channel.pipeline().get("compress") instanceof NettyCompressionEncoder) + if (this.channel.pipeline().get("compress") instanceof CompressionEncoder) { - ((NettyCompressionEncoder)this.channel.pipeline().get("compress")).setCompressionTreshold(treshold); + ((CompressionEncoder)this.channel.pipeline().get("compress")).setTreshold(treshold); } else { - this.channel.pipeline().addBefore("encoder", "compress", new NettyCompressionEncoder(treshold)); + this.channel.pipeline().addBefore("encoder", "compress", new CompressionEncoder(treshold)); } } else { - if (this.channel.pipeline().get("decompress") instanceof NettyCompressionDecoder) + if (this.channel.pipeline().get("decompress") instanceof CompressionDecoder) { this.channel.pipeline().remove("decompress"); } - if (this.channel.pipeline().get("compress") instanceof NettyCompressionEncoder) + if (this.channel.pipeline().get("compress") instanceof CompressionEncoder) { this.channel.pipeline().remove("compress"); } @@ -346,15 +303,8 @@ public class NetConnection extends SimpleChannelInboundHandler if (!this.disconnected) { this.disconnected = true; - - if (this.terminationReason != null) - { - this.getNetHandler().onDisconnect(this.terminationReason); - } - else if (this.getNetHandler() != null) - { - this.getNetHandler().onDisconnect("Verbindung getrennt"); - } + if(this.handler != null) + this.handler.onDisconnect(this.exitReason != null ? this.exitReason : "Verbindung getrennt"); } else { @@ -364,19 +314,19 @@ public class NetConnection extends SimpleChannelInboundHandler } public void startEncryption(SecretKey key) { - this.channel.pipeline().addBefore("splitter", "decrypt", new NettyEncryptionDecoder(EncryptUtil.createCipher(Cipher.DECRYPT_MODE, key))); - this.channel.pipeline().addBefore("prepender", "encrypt", new NettyEncryptionEncoder(EncryptUtil.createCipher(Cipher.ENCRYPT_MODE, key))); + this.channel.pipeline().addBefore("splitter", "decrypt", new EncryptionDecoder(EncryptUtil.createCipher(Cipher.DECRYPT_MODE, key))); + this.channel.pipeline().addBefore("prepender", "encrypt", new EncryptionEncoder(EncryptUtil.createCipher(Cipher.ENCRYPT_MODE, key))); } - static class InboundHandlerTuplePacketListener + private static class InboundHandlerTuplePacketListener { private final Packet packet; - private final GenericFutureListener > [] futureListeners; + private final GenericFutureListener > [] listeners; - public InboundHandlerTuplePacketListener(Packet inPacket, GenericFutureListener > inFutureListener) + public InboundHandlerTuplePacketListener(Packet packet, GenericFutureListener > listener) { - this.packet = inPacket; - this.futureListeners = inFutureListener == null ? null : new GenericFutureListener[] {inFutureListener}; + this.packet = packet; + this.listeners = listener == null ? null : new GenericFutureListener[] {listener}; } } } diff --git a/common/src/common/network/NetHandler.java b/common/src/common/network/NetHandler.java index 1454ec5..2c1f59a 100755 --- a/common/src/common/network/NetHandler.java +++ b/common/src/common/network/NetHandler.java @@ -19,8 +19,7 @@ public abstract class NetHandler { public void update() { } - public static void checkThread(final Packet packet, final T handler, IThreadListener listener) - throws ThreadQuickExitException { + public static void checkThread(final Packet packet, final T handler, IThreadListener listener) throws ThreadQuickExitException { if(!listener.isMainThread()) { listener.schedule(new Runnable() { public void run() { @@ -31,11 +30,9 @@ public abstract class NetHandler { } } - public static void checkThread(final Packet packet, final T handler, IThreadListener listener, Object check) - throws ThreadQuickExitException { - if(check == null && listener.isMainThread()) { + public static void checkThread(final Packet packet, final T handler, IThreadListener listener, Object check) throws ThreadQuickExitException { + if(check == null && listener.isMainThread()) throw EXIT; - } checkThread(packet, handler, listener); } } diff --git a/common/src/common/network/NettyCompressionDecoder.java b/common/src/common/network/NettyCompressionDecoder.java deleted file mode 100755 index d77de45..0000000 --- a/common/src/common/network/NettyCompressionDecoder.java +++ /dev/null @@ -1,62 +0,0 @@ -package common.network; - -import java.util.List; -import java.util.zip.DataFormatException; -import java.util.zip.Inflater; - -import io.netty.buffer.ByteBuf; -import io.netty.buffer.Unpooled; -import io.netty.channel.ChannelHandlerContext; -import io.netty.handler.codec.ByteToMessageDecoder; -import io.netty.handler.codec.DecoderException; - -public class NettyCompressionDecoder extends ByteToMessageDecoder -{ - private final Inflater inflater; - private int treshold; - - public NettyCompressionDecoder(int treshold) - { - this.treshold = treshold; - this.inflater = new Inflater(); - } - - protected void decode(ChannelHandlerContext p_decode_1_, ByteBuf p_decode_2_, List p_decode_3_) throws DataFormatException, Exception - { - if (p_decode_2_.readableBytes() != 0) - { - PacketBuffer packetbuffer = new PacketBuffer(p_decode_2_); - int i = packetbuffer.readVarIntFromBuffer(); - - if (i == 0) - { - p_decode_3_.add(packetbuffer.readBytes(packetbuffer.readableBytes())); - } - else - { - if (i < this.treshold) - { - throw new DecoderException("Badly compressed packet - size of " + i + " is below server threshold of " + this.treshold); - } - - if (i > 2097152) - { - throw new DecoderException("Badly compressed packet - size of " + i + " is larger than protocol maximum of " + 2097152); - } - - byte[] abyte = new byte[packetbuffer.readableBytes()]; - packetbuffer.readBytes(abyte); - this.inflater.setInput(abyte); - byte[] abyte1 = new byte[i]; - this.inflater.inflate(abyte1); - p_decode_3_.add(Unpooled.wrappedBuffer(abyte1)); - this.inflater.reset(); - } - } - } - - public void setCompressionTreshold(int treshold) - { - this.treshold = treshold; - } -} diff --git a/common/src/common/network/NettyCompressionEncoder.java b/common/src/common/network/NettyCompressionEncoder.java deleted file mode 100755 index 9719f99..0000000 --- a/common/src/common/network/NettyCompressionEncoder.java +++ /dev/null @@ -1,53 +0,0 @@ -package common.network; - -import java.util.zip.Deflater; - -import io.netty.buffer.ByteBuf; -import io.netty.channel.ChannelHandlerContext; -import io.netty.handler.codec.MessageToByteEncoder; - -public class NettyCompressionEncoder extends MessageToByteEncoder -{ - private final byte[] buffer = new byte[8192]; - private final Deflater deflater; - private int treshold; - - public NettyCompressionEncoder(int treshold) - { - this.treshold = treshold; - this.deflater = new Deflater(); - } - - protected void encode(ChannelHandlerContext p_encode_1_, ByteBuf p_encode_2_, ByteBuf p_encode_3_) throws Exception - { - int i = p_encode_2_.readableBytes(); - PacketBuffer packetbuffer = new PacketBuffer(p_encode_3_); - - if (i < this.treshold) - { - packetbuffer.writeVarIntToBuffer(0); - packetbuffer.writeBytes(p_encode_2_); - } - else - { - byte[] abyte = new byte[i]; - p_encode_2_.readBytes(abyte); - packetbuffer.writeVarIntToBuffer(abyte.length); - this.deflater.setInput(abyte, 0, i); - this.deflater.finish(); - - while (!this.deflater.finished()) - { - int j = this.deflater.deflate(this.buffer); - packetbuffer.writeBytes((byte[])this.buffer, 0, j); - } - - this.deflater.reset(); - } - } - - public void setCompressionTreshold(int treshold) - { - this.treshold = treshold; - } -} diff --git a/common/src/common/network/Packet.java b/common/src/common/network/Packet.java index 4ba381f..bc9c9d9 100755 --- a/common/src/common/network/Packet.java +++ b/common/src/common/network/Packet.java @@ -2,8 +2,7 @@ package common.network; import java.io.IOException; -public interface Packet -{ +public interface Packet { void readPacketData(PacketBuffer buf) throws IOException; void writePacketData(PacketBuffer buf) throws IOException; void processPacket(T handler); diff --git a/common/src/common/network/PacketBuffer.java b/common/src/common/network/PacketBuffer.java index 390c141..cbc0a3b 100755 --- a/common/src/common/network/PacketBuffer.java +++ b/common/src/common/network/PacketBuffer.java @@ -15,449 +15,250 @@ import io.netty.buffer.ByteBufOutputStream; import io.netty.handler.codec.DecoderException; import io.netty.handler.codec.EncoderException; -public class PacketBuffer -{ +public class PacketBuffer { private static final Charset UTF_8 = Charset.forName("UTF-8"); + + private final ByteBuf buf; + + public PacketBuffer(ByteBuf wrapped) { + this.buf = wrapped; + } + + public static int getVarIntSize(int input) { + for(int i = 1; i < 5; ++i) { + if((input & -1 << i * 7) == 0) + return i; + } + return 5; + } + + public void writeByteArray(byte[] data) { + this.writeVarInt(data.length); + this.writeBytes(data); + } + + public byte[] readByteArray() { + byte[] data = new byte[this.readVarInt()]; + this.readBytes(data); + return data; + } + + public void writeBlockPos(BlockPos pos) { + this.writeInt(pos.getX()); + this.writeInt(pos.getY()); + this.writeInt(pos.getZ()); + } + + public BlockPos readBlockPos() { + return new BlockPos(this.readInt(), this.readInt(), this.readInt()); + } + + public void writeEnumValue(Enum value) { + this.writeVarInt(value.ordinal()); + } + + public > T readEnumValue(Class clazz) { + return (T)((Enum[])clazz.getEnumConstants())[this.readVarInt()]; + } + + public void writeEnumOrNull(Enum value) { + this.writeVarInt(value == null ? -1 : value.ordinal()); + } + + public > T readEnumOrNull(Class clazz) { + int n = this.readVarInt(); + return n < 0 ? null : (T)((Enum[])clazz.getEnumConstants())[n]; + } + + public void writeVarInt(int value) { + while((value & -128) != 0) { + this.writeByte(value & 127 | 128); + value >>>= 7; + } + this.writeByte(value); + } + + public int readVarInt() { + int v = 0; + int c = 0; + while(true) { + byte b = this.readByte(); + v |= (b & 127) << c++ * 7; + if(c > 5) + throw new RuntimeException("VarInt too big"); + if((b & 128) != 128) + break; + } + return v; + } - private final ByteBuf buf; + public void writeTag(NBTTagCompound tag) { + if(tag == null) { + this.writeByte(0); + return; + } + try { + NBTLoader.write(tag, new ByteBufOutputStream(this.buf)); + } + catch(IOException e) { + throw new EncoderException(e); + } + } + + public NBTTagCompound readTag() throws IOException { + int i = this.buf.readerIndex(); + byte b = this.readByte(); + if(b == 0) + return null; + this.buf.readerIndex(i); + return NBTLoader.read(new ByteBufInputStream(this.buf), new NBTSizeTracker(2097152L)); + } + + public void writeItemStack(ItemStack stack) { + if(stack == null) { + this.writeShort(-1); + return; + } + this.writeShort(ItemRegistry.getIdFromItem(stack.getItem())); + this.writeVarInt(stack.stackSize); + this.writeShort(stack.getMetadata()); + this.writeTag(stack.getTagCompound()); + } + + public ItemStack readItemStack() throws IOException { + int id = this.readShort(); + if(id < 0) + return null; + int amt = this.readVarInt(); + int meta = this.readShort(); + ItemStack stack = new ItemStack(ItemRegistry.getItemById(id), amt, meta); + stack.setTagCompound(this.readTag()); + return stack; + } + + public void writeString(String str) { + byte[] data = str.getBytes(UTF_8); + if(data.length > 32767) + throw new EncoderException("String too big (was " + str.length() + " bytes encoded, max " + 32767 + ")"); + this.writeVarInt(data.length); + this.writeBytes(data); + } + + public String readString(int limit) { + int len = this.readVarInt(); + if(len > limit * 4) + throw new DecoderException("The received encoded string buffer length is longer than maximum allowed (" + len + " > " + limit * 4 + ")"); + else if(len < 0) + throw new DecoderException("The received encoded string buffer length is less than zero! Weird string!"); + byte[] data = new byte[len]; + this.readBytes(data); + String str = new String(data, UTF_8); + if(str.length() > limit) + throw new DecoderException("The received string length is longer than maximum allowed (" + len + " > " + limit + ")"); + return str; + } + + public void writeBoolean(boolean value) { + this.buf.writeBoolean(value); + } + + public boolean readBoolean() { + return this.buf.readBoolean(); + } + + public void writeByte(int value) { + this.buf.writeByte(value); + } + + public byte readByte() { + return this.buf.readByte(); + } + + public short readUnsignedByte() { + return this.buf.readUnsignedByte(); + } + + public void writeShort(int value) { + this.buf.writeShort(value); + } + + public short readShort() { + return this.buf.readShort(); + } + + public int readUnsignedShort() { + return this.buf.readUnsignedShort(); + } + + public void writeInt(int value) { + this.buf.writeInt(value); + } + + public int readInt() { + return this.buf.readInt(); + } + + public long readUnsignedInt() { + return this.buf.readUnsignedInt(); + } + + public void writeLong(long value) { + this.buf.writeLong(value); + } + + public long readLong() { + return this.buf.readLong(); + } + + public void writeFloat(float value) { + this.buf.writeFloat(value); + } + + public float readFloat() { + return this.buf.readFloat(); + } + + public void writeDouble(double value) { + this.buf.writeDouble(value); + } + + public double readDouble() { + return this.buf.readDouble(); + } + + public ByteBuf readBytes(int size) { + return this.buf.readBytes(size); + } + + public void writeBytes(byte[] data) { + this.buf.writeBytes(data); + } + + public void readBytes(byte[] buffer) { + this.buf.readBytes(buffer); + } + + public void writeBytes(byte[] data, int offset, int length) { + this.buf.writeBytes(data, offset, length); + } + + public void writeBuffer(ByteBuf buf) { + this.buf.writeBytes(buf); + } + + public void writeBuffer(ByteBuf buf, int offset, int length) { + this.buf.writeBytes(buf, offset, length); + } + + public int readableBytes() { + return this.buf.readableBytes(); + } + + public void ensureWritable(int size) { + this.buf.ensureWritable(size); + } - public PacketBuffer(ByteBuf wrapped) - { - this.buf = wrapped; - } - - /** - * Calculates the number of bytes required to fit the supplied int (0-5) if it were to be read/written using - * readVarIntFromBuffer or writeVarIntToBuffer - */ - public static int getVarIntSize(int input) - { - for (int i = 1; i < 5; ++i) - { - if ((input & -1 << i * 7) == 0) - { - return i; - } - } - - return 5; - } - - public void writeByteArray(byte[] array) - { - this.writeVarIntToBuffer(array.length); - this.writeBytes(array); - } - - public byte[] readByteArray() - { - byte[] abyte = new byte[this.readVarIntFromBuffer()]; - this.readBytes(abyte); - return abyte; - } - - public BlockPos readBlockPos() - { - return new BlockPos(this.readInt(), this.readInt(), this.readInt()); - } - - public void writeBlockPos(BlockPos pos) - { - this.writeInt(pos.getX()); - this.writeInt(pos.getY()); - this.writeInt(pos.getZ()); - } - -// public Text readChatComponent() throws IOException -// { -// return Text.toComponent(this.readNBTTagCompoundFromBuffer()); -// } -// -// public void writeChatComponent(Text component) throws IOException -// { -// this.writeNBTTagCompoundToBuffer(Text.toNbt(component)); -//// String s = ; -//// if(s.length() > 32767) { -//// s = component.getFormattedText(); -//// s = s.length() > 32720 ? s.substring(0, 32720) : s; -//// s = TextSerializer.toNbt(new TextComponent(s + ChatFormat.GRAY + ChatFormat.ITALIC + " [...]")); -//// } -//// this.writeString(s); -// } - - public > T readEnumValue(Class enumClass) - { - return (T)((Enum[])enumClass.getEnumConstants())[this.readVarIntFromBuffer()]; - } - - public > T readEnumOrNull(Class enumClass) - { - int n = this.readVarIntFromBuffer(); - return n < 0 ? null : (T)((Enum[])enumClass.getEnumConstants())[n]; - } - - public void writeEnumValue(Enum value) - { - this.writeVarIntToBuffer(value.ordinal()); - } - - public void writeEnumOrNull(Enum value) - { - this.writeVarIntToBuffer(value == null ? -1 : value.ordinal()); - } - - /** - * Reads a compressed int from the buffer. To do so it maximally reads 5 byte-sized chunks whose most significant - * bit dictates whether another byte should be read. - */ - public int readVarIntFromBuffer() - { - int i = 0; - int j = 0; - - while (true) - { - byte b0 = this.readByte(); - i |= (b0 & 127) << j++ * 7; - - if (j > 5) - { - throw new RuntimeException("VarInt too big"); - } - - if ((b0 & 128) != 128) - { - break; - } - } - - return i; - } - - public long readVarLong() - { - long i = 0L; - int j = 0; - - while (true) - { - byte b0 = this.readByte(); - i |= (long)(b0 & 127) << j++ * 7; - - if (j > 10) - { - throw new RuntimeException("VarLong too big"); - } - - if ((b0 & 128) != 128) - { - break; - } - } - - return i; - } - -// public void writeUuid(UUID uuid) -// { -// this.writeLong(uuid.getMostSignificantBits()); -// this.writeLong(uuid.getLeastSignificantBits()); -// } -// -// public UUID readUuid() -// { -// return new UUID(this.readLong(), this.readLong()); -// } - - /** - * Writes a compressed int to the buffer. The smallest number of bytes to fit the passed int will be written. Of - * each such byte only 7 bits will be used to describe the actual value since its most significant bit dictates - * whether the next byte is part of that same int. Micro-optimization for int values that are expected to have - * values below 128. - */ - public void writeVarIntToBuffer(int input) - { - while ((input & -128) != 0) - { - this.writeByte(input & 127 | 128); - input >>>= 7; - } - - this.writeByte(input); - } - - public void writeVarLong(long value) - { - while ((value & -128L) != 0L) - { - this.writeByte((int)(value & 127L) | 128); - value >>>= 7; - } - - this.writeByte((int)value); - } - - /** - * Writes a compressed NBTTagCompound to this buffer - */ - public void writeNBTTagCompoundToBuffer(NBTTagCompound nbt) - { - if (nbt == null) - { - this.writeByte(0); - } - else - { - try - { - NBTLoader.write(nbt, new ByteBufOutputStream(this.buf)); - } - catch (IOException ioexception) - { - throw new EncoderException(ioexception); - } - } - } - - /** - * Reads a compressed NBTTagCompound from this buffer - */ - public NBTTagCompound readNBTTagCompoundFromBuffer() throws IOException - { - int i = this.buf.readerIndex(); - byte b0 = this.readByte(); - - if (b0 == 0) - { - return null; - } - else - { - this.buf.readerIndex(i); - return NBTLoader.read(new ByteBufInputStream(this.buf), new NBTSizeTracker(2097152L)); - } - } - - /** - * Writes the ItemStack's ID (short), then size (byte), then damage. (short) - */ - public void writeItemStackToBuffer(ItemStack stack) - { - if (stack == null) - { - this.writeShort(-1); - } - else - { - this.writeShort(ItemRegistry.getIdFromItem(stack.getItem())); - this.writeVarIntToBuffer(stack.stackSize); - this.writeShort(stack.getMetadata()); - NBTTagCompound nbttagcompound = null; - - if (stack.getItem().isDamageable() || stack.getItem().getShareTag()) - { - nbttagcompound = stack.getTagCompound(); - } - - this.writeNBTTagCompoundToBuffer(nbttagcompound); - } - } - - /** - * Reads an ItemStack from this buffer - */ - public ItemStack readItemStackFromBuffer() throws IOException - { - ItemStack itemstack = null; - int i = this.readShort(); - - if (i >= 0) - { - int j = this.readVarIntFromBuffer(); - int k = this.readShort(); - itemstack = new ItemStack(ItemRegistry.getItemById(i), j, k); - itemstack.setTagCompound(this.readNBTTagCompoundFromBuffer()); - } - - return itemstack; - } - - /** - * Reads a string from this buffer. Expected parameter is maximum allowed string length. Will throw IOException if - * string length exceeds this value! - */ - public String readStringFromBuffer(int maxLength) - { - int i = this.readVarIntFromBuffer(); - - if (i > maxLength * 4) - { - throw new DecoderException("The received encoded string buffer length is longer than maximum allowed (" + i + " > " + maxLength * 4 + ")"); - } - else if (i < 0) - { - throw new DecoderException("The received encoded string buffer length is less than zero! Weird string!"); - } - else - { - byte[] abyte = new byte[i]; - this.readBytes(abyte); - String s = new String(abyte, UTF_8); // this.readBytes(i).array() - - if (s.length() > maxLength) - { - throw new DecoderException("The received string length is longer than maximum allowed (" + i + " > " + maxLength + ")"); - } - else - { - return s; - } - } - } - - public PacketBuffer writeString(String string) - { - byte[] abyte = string.getBytes(UTF_8); - - if (abyte.length > 32767) - { - throw new EncoderException("String too big (was " + string.length() + " bytes encoded, max " + 32767 + ")"); - } - else - { - this.writeVarIntToBuffer(abyte.length); - this.writeBytes(abyte); - return this; - } - } - - public int readableBytes() - { - return this.buf.readableBytes(); - } - - public ByteBuf ensureWritable(int p_ensureWritable_1_) - { - return this.buf.ensureWritable(p_ensureWritable_1_); - } - - public boolean readBoolean() - { - return this.buf.readBoolean(); - } - - public byte readByte() - { - return this.buf.readByte(); - } - - public short readUnsignedByte() - { - return this.buf.readUnsignedByte(); - } - - public short readShort() - { - return this.buf.readShort(); - } - - public int readUnsignedShort() - { - return this.buf.readUnsignedShort(); - } - - public int readInt() - { - return this.buf.readInt(); - } - - public long readUnsignedInt() - { - return this.buf.readUnsignedInt(); - } - - public long readLong() - { - return this.buf.readLong(); - } - - public float readFloat() - { - return this.buf.readFloat(); - } - - public double readDouble() - { - return this.buf.readDouble(); - } - - public ByteBuf readBytes(int p_readBytes_1_) - { - return this.buf.readBytes(p_readBytes_1_); - } - - public ByteBuf readBytes(byte[] p_readBytes_1_) - { - return this.buf.readBytes(p_readBytes_1_); - } - - public ByteBuf writeBoolean(boolean p_writeBoolean_1_) - { - return this.buf.writeBoolean(p_writeBoolean_1_); - } - - public ByteBuf writeByte(int p_writeByte_1_) - { - return this.buf.writeByte(p_writeByte_1_); - } - - public ByteBuf writeShort(int p_writeShort_1_) - { - return this.buf.writeShort(p_writeShort_1_); - } - - public ByteBuf writeInt(int p_writeInt_1_) - { - return this.buf.writeInt(p_writeInt_1_); - } - - public ByteBuf writeLong(long p_writeLong_1_) - { - return this.buf.writeLong(p_writeLong_1_); - } - - public ByteBuf writeFloat(float p_writeFloat_1_) - { - return this.buf.writeFloat(p_writeFloat_1_); - } - - public ByteBuf writeDouble(double p_writeDouble_1_) - { - return this.buf.writeDouble(p_writeDouble_1_); - } - - public ByteBuf writeBytes(ByteBuf p_writeBytes_1_) - { - return this.buf.writeBytes(p_writeBytes_1_); - } - - public ByteBuf writeBytes(ByteBuf p_writeBytes_1_, int p_writeBytes_2_, int p_writeBytes_3_) - { - return this.buf.writeBytes(p_writeBytes_1_, p_writeBytes_2_, p_writeBytes_3_); - } - - public ByteBuf writeBytes(byte[] p_writeBytes_1_) - { - return this.buf.writeBytes(p_writeBytes_1_); - } - - public ByteBuf writeBytes(byte[] p_writeBytes_1_, int p_writeBytes_2_, int p_writeBytes_3_) - { - return this.buf.writeBytes(p_writeBytes_1_, p_writeBytes_2_, p_writeBytes_3_); - } - - public boolean release() - { - return this.buf.release(); - } + public void release() { + this.buf.release(); + } } diff --git a/common/src/common/network/PacketDecoder.java b/common/src/common/network/PacketDecoder.java index e00089d..9d5f1c3 100755 --- a/common/src/common/network/PacketDecoder.java +++ b/common/src/common/network/PacketDecoder.java @@ -7,45 +7,26 @@ import io.netty.buffer.ByteBuf; import io.netty.channel.ChannelHandlerContext; import io.netty.handler.codec.ByteToMessageDecoder; -public class PacketDecoder extends ByteToMessageDecoder -{ - private final boolean client; +public class PacketDecoder extends ByteToMessageDecoder { + private final boolean client; - public PacketDecoder(boolean client) - { - this.client = client; - } + public PacketDecoder(boolean client) { + this.client = client; + } - protected void decode(ChannelHandlerContext p_decode_1_, ByteBuf p_decode_2_, List p_decode_3_) throws IOException, InstantiationException, IllegalAccessException, Exception - { - if (p_decode_2_.readableBytes() != 0) - { - PacketBuffer packetbuffer = new PacketBuffer(p_decode_2_); - int i = packetbuffer.readVarIntFromBuffer(); - Packet packet = ((PacketRegistry)p_decode_1_.channel().attr(NetConnection.ATTR_STATE).get()).getPacket(this.client, i); - - if (packet == null) - { - throw new IOException("Ungültige Paket-ID " + i); - } - else - { - packet.readPacketData(packetbuffer); - - if (packetbuffer.readableBytes() > 0) - { - throw new IOException("Paket " + ((PacketRegistry)p_decode_1_.channel().attr(NetConnection.ATTR_STATE).get()).ordinal() + "/" + i + " (" + packet.getClass() + ") war größer als erwartet, " + packetbuffer.readableBytes() + " weitere Bytes wurden beim Lesen von Paket " + i + " gefunden"); - } - else - { - p_decode_3_.add(packet); - -// if (Log.isTraceEnabled()) -// { -// Log.SYSTEM.info("EIN: [" + p_decode_1_.channel().attr(NetConnection.ATTR_STATE).get() + ":" + i + "] " + packet.getClass().getName()); -// } - } - } - } - } + protected void decode(ChannelHandlerContext context, ByteBuf buffer, List output) throws IOException, InstantiationException, IllegalAccessException, Exception { + if(buffer.readableBytes() == 0) + return; + PacketBuffer pbuf = new PacketBuffer(buffer); + int id = pbuf.readVarInt(); + Packet packet = context.channel().attr(NetConnection.ATTR_STATE).get().getPacket(this.client, id); + if(packet == null) + throw new IOException("Ungültige Paket-ID " + id); + packet.readPacketData(pbuf); + if(pbuf.readableBytes() > 0) + throw new IOException("Paket " + ((PacketRegistry)context.channel().attr(NetConnection.ATTR_STATE).get()).ordinal() + "/" + id + " (" + + packet.getClass() + ") war größer als erwartet, " + pbuf.readableBytes() + " weitere Bytes wurden beim Lesen von Paket " + id + " gefunden"); + output.add(packet); +// common.log.Log.SYSTEM.info("EIN: [" + context.channel().attr(NetConnection.ATTR_STATE).get() + ":" + id + "] " + packet.getClass().getName()); + } } diff --git a/common/src/common/network/PacketEncoder.java b/common/src/common/network/PacketEncoder.java index fec4859..26f1190 100755 --- a/common/src/common/network/PacketEncoder.java +++ b/common/src/common/network/PacketEncoder.java @@ -2,46 +2,29 @@ package common.network; import java.io.IOException; -import common.log.Log; import io.netty.buffer.ByteBuf; import io.netty.channel.ChannelHandlerContext; import io.netty.handler.codec.MessageToByteEncoder; -public class PacketEncoder extends MessageToByteEncoder -{ - private final boolean client; +public class PacketEncoder extends MessageToByteEncoder { + private final boolean client; - public PacketEncoder(boolean client) - { - this.client = client; - } + public PacketEncoder(boolean client) { + this.client = client; + } - protected void encode(ChannelHandlerContext p_encode_1_, Packet p_encode_2_, ByteBuf p_encode_3_) throws IOException, Exception - { - Integer integer = ((PacketRegistry)p_encode_1_.channel().attr(NetConnection.ATTR_STATE).get()).getId(this.client, p_encode_2_); - -// if (Log.isTraceEnabled()) -// { -// Log.SYSTEM.debug("AUS: [" + p_encode_1_.channel().attr(NetConnection.ATTR_STATE).get() + ":" + integer + "] " + p_encode_2_.getClass().getName()); -// } - - if (integer == null) - { - throw new IOException("Kann nicht registriertes Paket nicht serialisieren"); - } - else - { - PacketBuffer packetbuffer = new PacketBuffer(p_encode_3_); - packetbuffer.writeVarIntToBuffer(integer.intValue()); - - try - { - p_encode_2_.writePacketData(packetbuffer); - } - catch (Throwable throwable) - { - Log.JNI.error(throwable, "Fehler beim Schreiben der Paketdaten"); - } - } - } + protected void encode(ChannelHandlerContext context, Packet packet, ByteBuf output) throws IOException, Exception { + Integer id = context.channel().attr(NetConnection.ATTR_STATE).get().getId(this.client, packet); + if(id == null) + throw new IOException("Kann nicht registriertes Paket nicht serialisieren"); +// common.log.Log.SYSTEM.debug("AUS: [" + context.channel().attr(NetConnection.ATTR_STATE).get() + ":" + id + "] " + packet.getClass().getName()); + PacketBuffer pbuf = new PacketBuffer(output); + pbuf.writeVarInt(id); + try { + packet.writePacketData(pbuf); + } + catch(Throwable t) { + throw new IOException("Fehler beim Schreiben der Paketdaten", t); + } + } } diff --git a/common/src/common/network/PacketPrepender.java b/common/src/common/network/PacketPrepender.java index 670f337..7a89749 100755 --- a/common/src/common/network/PacketPrepender.java +++ b/common/src/common/network/PacketPrepender.java @@ -4,23 +4,15 @@ import io.netty.buffer.ByteBuf; import io.netty.channel.ChannelHandlerContext; import io.netty.handler.codec.MessageToByteEncoder; -public class PacketPrepender extends MessageToByteEncoder -{ - protected void encode(ChannelHandlerContext p_encode_1_, ByteBuf p_encode_2_, ByteBuf p_encode_3_) throws Exception - { - int i = p_encode_2_.readableBytes(); - int j = PacketBuffer.getVarIntSize(i); - - if (j > 3) - { - throw new IllegalArgumentException("unable to fit " + i + " into " + 3); - } - else - { - PacketBuffer packetbuffer = new PacketBuffer(p_encode_3_); - packetbuffer.ensureWritable(j + i); - packetbuffer.writeVarIntToBuffer(i); - packetbuffer.writeBytes(p_encode_2_, p_encode_2_.readerIndex(), i); - } - } +public class PacketPrepender extends MessageToByteEncoder { + protected void encode(ChannelHandlerContext context, ByteBuf buffer, ByteBuf output) throws Exception { + int len = buffer.readableBytes(); + int vs = PacketBuffer.getVarIntSize(len); + if(vs > 3) + throw new IllegalArgumentException("unable to fit " + len + " into " + 3); + PacketBuffer pbuf = new PacketBuffer(output); + pbuf.ensureWritable(vs + len); + pbuf.writeVarInt(len); + pbuf.writeBuffer(buffer, buffer.readerIndex(), len); + } } diff --git a/common/src/common/network/PacketRegistry.java b/common/src/common/network/PacketRegistry.java index b6a4b59..a1930de 100755 --- a/common/src/common/network/PacketRegistry.java +++ b/common/src/common/network/PacketRegistry.java @@ -5,8 +5,10 @@ import java.util.Map; import common.collect.BiMap; import common.collect.HashBiMap; import common.collect.Maps; +import common.packet.CPacketPlayerPosition; +import common.packet.CPacketPlayerLook; +import common.packet.CPacketPlayerPosLook; import common.packet.CPacketAction; -import common.packet.CPacketBook; import common.packet.CPacketBreak; import common.packet.CPacketCheat; import common.packet.CPacketClick; @@ -27,34 +29,37 @@ import common.packet.RPacketDisconnect; import common.packet.RPacketEnableCompression; import common.packet.RPacketLoginSuccess; import common.packet.RPacketRequestEncrypt; -import common.packet.S14PacketEntity; -import common.packet.S18PacketEntityTeleport; -import common.packet.S19PacketEntityHeadLook; -import common.packet.S1APacketEntityStatus; -import common.packet.S1BPacketEntityAttach; -import common.packet.S1CPacketEntityMetadata; -import common.packet.S1DPacketEntityEffect; -import common.packet.S1EPacketRemoveEntityEffect; -import common.packet.S20PacketEntityProperties; -import common.packet.S27PacketExplosion; -import common.packet.S28PacketEffect; -import common.packet.S29PacketSoundEffect; -import common.packet.S2APacketParticles; -import common.packet.S2BPacketChangeGameState; -import common.packet.S2CPacketSpawnGlobalEntity; -import common.packet.S2DPacketOpenWindow; -import common.packet.S2EPacketCloseWindow; -import common.packet.S2FPacketSetSlot; -import common.packet.S30PacketWindowItems; -import common.packet.S31PacketWindowProperty; -import common.packet.S32PacketConfirmTransaction; -import common.packet.S33PacketUpdateSign; -import common.packet.S35PacketUpdateTileEntity; -import common.packet.S36PacketSignEditorOpen; -import common.packet.S38PacketPlayerListItem; -import common.packet.S39PacketPlayerAbilities; -import common.packet.S3APacketTabComplete; -import common.packet.S43PacketUpdateEntityNBT; +import common.packet.SPacketEntityRelMove; +import common.packet.SPacketEntityLook; +import common.packet.SPacketEntityLookMove; +import common.packet.SPacketEntity; +import common.packet.SPacketEntityTeleport; +import common.packet.SPacketEntityHeadLook; +import common.packet.SPacketEntityStatus; +import common.packet.SPacketEntityAttach; +import common.packet.SPacketEntityMetadata; +import common.packet.SPacketEntityEffect; +import common.packet.SPacketRemoveEntityEffect; +import common.packet.SPacketEntityProperties; +import common.packet.SPacketExplosion; +import common.packet.SPacketEffect; +import common.packet.SPacketSoundEffect; +import common.packet.SPacketParticles; +import common.packet.SPacketChangeGameState; +import common.packet.SPacketSpawnGlobalEntity; +import common.packet.SPacketOpenWindow; +import common.packet.SPacketCloseWindow; +import common.packet.SPacketSetSlot; +import common.packet.SPacketWindowItems; +import common.packet.SPacketWindowProperty; +import common.packet.SPacketConfirmTransaction; +import common.packet.SPacketUpdateSign; +import common.packet.SPacketUpdateTileEntity; +import common.packet.SPacketSignEditorOpen; +import common.packet.SPacketPlayerListItem; +import common.packet.SPacketPlayerAbilities; +import common.packet.SPacketTabComplete; +import common.packet.SPacketUpdateEntityNBT; import common.packet.SPacketAnimation; import common.packet.SPacketBiome; import common.packet.SPacketBlockAction; @@ -92,144 +97,122 @@ import common.packet.SPacketWorld; public enum PacketRegistry { - HANDSHAKE - { - { - this.client(HPacketHandshake.class); - } - }, - LOGIN - { - { - this.server(RPacketDisconnect.class); - this.server(RPacketRequestEncrypt.class); - this.server(RPacketLoginSuccess.class); - this.server(RPacketEnableCompression.class); - this.client(LPacketLogin.class); - this.client(LPacketStartEncrypt.class); - this.client(LPacketPasswordResponse.class); - } - }, - PLAY - { - { - this.server(SPacketKeepAlive.class); - this.server(SPacketJoinGame.class); - this.server(SPacketMessage.class); -// this.server(SPacketMessage.class); - this.server(SPacketTimeUpdate.class); - this.server(SPacketEntityEquipment.class); - this.server(SPacketUpdateHealth.class); - this.server(SPacketRespawn.class); - this.server(SPacketPlayerPosLook.class); - this.server(SPacketHeldItemChange.class); - this.server(SPacketAnimation.class); - this.server(SPacketSpawnPlayer.class); - this.server(SPacketCollectItem.class); - this.server(SPacketSpawnObject.class); - this.server(SPacketSpawnMob.class); -// this.server(SPacketSpawnPainting.class); -// this.server(SPacketSpawnExperienceOrb.class); - this.server(SPacketEntityVelocity.class); - this.server(SPacketDestroyEntities.class); - this.server(S14PacketEntity.class); - this.server(S14PacketEntity.S15PacketEntityRelMove.class); - this.server(S14PacketEntity.S16PacketEntityLook.class); - this.server(S14PacketEntity.S17PacketEntityLookMove.class); - this.server(S18PacketEntityTeleport.class); - this.server(S19PacketEntityHeadLook.class); - this.server(S1APacketEntityStatus.class); - this.server(S1BPacketEntityAttach.class); - this.server(S1CPacketEntityMetadata.class); - this.server(S1DPacketEntityEffect.class); - this.server(S1EPacketRemoveEntityEffect.class); - this.server(SPacketSetExperience.class); - this.server(S20PacketEntityProperties.class); - this.server(SPacketChunkData.class); - this.server(SPacketMultiBlockChange.class); - this.server(SPacketBlockChange.class); - this.server(SPacketBlockAction.class); - this.server(SPacketBlockBreakAnim.class); - this.server(SPacketMapChunkBulk.class); - this.server(S27PacketExplosion.class); - this.server(S28PacketEffect.class); - this.server(S29PacketSoundEffect.class); - this.server(S2APacketParticles.class); - this.server(S2BPacketChangeGameState.class); - this.server(S2CPacketSpawnGlobalEntity.class); - this.server(S2DPacketOpenWindow.class); - this.server(S2EPacketCloseWindow.class); - this.server(S2FPacketSetSlot.class); - this.server(S30PacketWindowItems.class); - this.server(S31PacketWindowProperty.class); - this.server(S32PacketConfirmTransaction.class); - this.server(S33PacketUpdateSign.class); -// this.server(S34PacketMaps.class); - this.server(S35PacketUpdateTileEntity.class); - this.server(S36PacketSignEditorOpen.class); -// this.server(S37PacketStatistics.class); - this.server(S38PacketPlayerListItem.class); - this.server(S39PacketPlayerAbilities.class); - this.server(S3APacketTabComplete.class); -// this.server(SPacketDisplay.class); - this.server(SPacketSkin.class); - this.server(SPacketDisconnect.class); - this.server(SPacketWorld.class); -// this.server(SPacketCapes.class); - this.server(SPacketCamera.class); - this.server(SPacketBiome.class); -// this.server(S42PacketTitle.class); - this.server(S43PacketUpdateEntityNBT.class); -// this.server(SPacketBook.class); - this.server(SPacketTrades.class); -// this.server(SPacketNotify.class); - this.server(SPacketDimensionName.class); - this.server(SPacketCharacterList.class); - this.server(SPacketServerTick.class); - this.server(SPacketLoading.class); - this.server(SPacketDisplayForm.class); - - this.client(CPacketKeepAlive.class); - this.client(CPacketMessage.class); - this.client(CPacketAction.class); - this.client(CPacketPlayer.class); - this.client(CPacketPlayer.C04PacketPlayerPosition.class); - this.client(CPacketPlayer.C05PacketPlayerLook.class); - this.client(CPacketPlayer.C06PacketPlayerPosLook.class); - this.client(CPacketBreak.class); - this.client(CPacketPlace.class); - this.client(CPacketInput.class); - this.client(CPacketClick.class); - this.client(CPacketCheat.class); - this.client(CPacketComplete.class); - this.client(CPacketSkin.class); - this.client(CPacketSign.class); - this.client(CPacketBook.class); - this.client(CPacketForm.class); - } - }; + HANDSHAKE {{ + this.client(HPacketHandshake.class); + }}, + LOGIN {{ + this.server(RPacketDisconnect.class); + this.server(RPacketRequestEncrypt.class); + this.server(RPacketLoginSuccess.class); + this.server(RPacketEnableCompression.class); + + this.client(LPacketLogin.class); + this.client(LPacketStartEncrypt.class); + this.client(LPacketPasswordResponse.class); + }}, + PLAY {{ + this.server(SPacketKeepAlive.class); + this.server(SPacketJoinGame.class); + this.server(SPacketMessage.class); + this.server(SPacketTimeUpdate.class); + this.server(SPacketEntityEquipment.class); + this.server(SPacketUpdateHealth.class); + this.server(SPacketRespawn.class); + this.server(SPacketPlayerPosLook.class); + this.server(SPacketHeldItemChange.class); + this.server(SPacketAnimation.class); + this.server(SPacketSpawnPlayer.class); + this.server(SPacketCollectItem.class); + this.server(SPacketSpawnObject.class); + this.server(SPacketSpawnMob.class); + this.server(SPacketEntityVelocity.class); + this.server(SPacketDestroyEntities.class); + this.server(SPacketEntity.class); + this.server(SPacketEntityRelMove.class); + this.server(SPacketEntityLook.class); + this.server(SPacketEntityLookMove.class); + this.server(SPacketEntityTeleport.class); + this.server(SPacketEntityHeadLook.class); + this.server(SPacketEntityStatus.class); + this.server(SPacketEntityAttach.class); + this.server(SPacketEntityMetadata.class); + this.server(SPacketEntityEffect.class); + this.server(SPacketRemoveEntityEffect.class); + this.server(SPacketSetExperience.class); + this.server(SPacketEntityProperties.class); + this.server(SPacketChunkData.class); + this.server(SPacketMultiBlockChange.class); + this.server(SPacketBlockChange.class); + this.server(SPacketBlockAction.class); + this.server(SPacketBlockBreakAnim.class); + this.server(SPacketMapChunkBulk.class); + this.server(SPacketExplosion.class); + this.server(SPacketEffect.class); + this.server(SPacketSoundEffect.class); + this.server(SPacketParticles.class); + this.server(SPacketChangeGameState.class); + this.server(SPacketSpawnGlobalEntity.class); + this.server(SPacketOpenWindow.class); + this.server(SPacketCloseWindow.class); + this.server(SPacketSetSlot.class); + this.server(SPacketWindowItems.class); + this.server(SPacketWindowProperty.class); + this.server(SPacketConfirmTransaction.class); + this.server(SPacketUpdateSign.class); + this.server(SPacketUpdateTileEntity.class); + this.server(SPacketSignEditorOpen.class); + this.server(SPacketPlayerListItem.class); + this.server(SPacketPlayerAbilities.class); + this.server(SPacketTabComplete.class); + this.server(SPacketSkin.class); + this.server(SPacketDisconnect.class); + this.server(SPacketWorld.class); + this.server(SPacketCamera.class); + this.server(SPacketBiome.class); + this.server(SPacketUpdateEntityNBT.class); + this.server(SPacketTrades.class); + this.server(SPacketDimensionName.class); + this.server(SPacketCharacterList.class); + this.server(SPacketServerTick.class); + this.server(SPacketLoading.class); + this.server(SPacketDisplayForm.class); + + this.client(CPacketKeepAlive.class); + this.client(CPacketMessage.class); + this.client(CPacketAction.class); + this.client(CPacketPlayer.class); + this.client(CPacketPlayerPosition.class); + this.client(CPacketPlayerLook.class); + this.client(CPacketPlayerPosLook.class); + this.client(CPacketBreak.class); + this.client(CPacketPlace.class); + this.client(CPacketInput.class); + this.client(CPacketClick.class); + this.client(CPacketCheat.class); + this.client(CPacketComplete.class); + this.client(CPacketSkin.class); + this.client(CPacketSign.class); + this.client(CPacketForm.class); + }}; private static final Map, PacketRegistry> STATES = Maps., PacketRegistry>newHashMap(); private final BiMap> server = HashBiMap.>create(); private final BiMap> client = HashBiMap.>create(); - protected void server(Class clazz) - { + protected void server(Class clazz) { if(this.server.containsValue(clazz)) throw new IllegalArgumentException("S-Paket " + clazz + " ist bereits bekannt unter ID " + this.server.inverse().get(clazz)); this.server.put(Integer.valueOf(this.server.size()), clazz); } - protected void client(Class clazz) - { + protected void client(Class clazz) { if(this.client.containsValue(clazz)) throw new IllegalArgumentException("C-Paket " + clazz + " ist bereits bekannt unter ID " + this.client.inverse().get(clazz)); this.client.put(Integer.valueOf(this.client.size()), clazz); } - public Integer getId(boolean client, Packet packet) - { + public Integer getId(boolean client, Packet packet) { return (client ? this.client : this.server).inverse().get(packet.getClass()); } @@ -238,19 +221,16 @@ public enum PacketRegistry return oclass == null ? null : oclass.newInstance(); } - public static PacketRegistry getType(Packet packetIn) - { - return STATES.get(packetIn.getClass()); + public static PacketRegistry getType(Packet packet) { + return STATES.get(packet.getClass()); } static { for(PacketRegistry reg : values()) { for(BiMap> map : new BiMap[] {reg.server, reg.client}) { for(Class clazz : map.values()) { - if(STATES.containsKey(clazz) && STATES.get(clazz) != reg) { - throw new Error("Paket " + clazz + " ist bereits zu ID " + STATES.get(clazz) - + " zugewiesen - kann nicht auf " + reg + " neu zuweisen"); - } + if(STATES.containsKey(clazz) && STATES.get(clazz) != reg) + throw new Error("Paket " + clazz + " ist bereits zu ID " + STATES.get(clazz) + " zugewiesen - kann nicht auf " + reg + " neu zuweisen"); try { clazz.newInstance(); } diff --git a/common/src/common/network/PacketSplitter.java b/common/src/common/network/PacketSplitter.java index 7540257..acb73d5 100755 --- a/common/src/common/network/PacketSplitter.java +++ b/common/src/common/network/PacketSplitter.java @@ -8,48 +8,32 @@ import io.netty.channel.ChannelHandlerContext; import io.netty.handler.codec.ByteToMessageDecoder; import io.netty.handler.codec.CorruptedFrameException; -public class PacketSplitter extends ByteToMessageDecoder -{ - protected void decode(ChannelHandlerContext p_decode_1_, ByteBuf p_decode_2_, List p_decode_3_) throws Exception - { - p_decode_2_.markReaderIndex(); - byte[] abyte = new byte[3]; - - for (int i = 0; i < abyte.length; ++i) - { - if (!p_decode_2_.isReadable()) - { - p_decode_2_.resetReaderIndex(); - return; - } - - abyte[i] = p_decode_2_.readByte(); - - if (abyte[i] >= 0) - { - PacketBuffer packetbuffer = new PacketBuffer(Unpooled.wrappedBuffer(abyte)); - - try - { - int j = packetbuffer.readVarIntFromBuffer(); - - if (p_decode_2_.readableBytes() >= j) - { - p_decode_3_.add(p_decode_2_.readBytes(j)); - return; - } - - p_decode_2_.resetReaderIndex(); - } - finally - { - packetbuffer.release(); - } - - return; - } - } - - throw new CorruptedFrameException("length wider than 21-bit"); - } +public class PacketSplitter extends ByteToMessageDecoder { + protected void decode(ChannelHandlerContext context, ByteBuf buffer, List output) throws Exception { + buffer.markReaderIndex(); + byte[] data = new byte[3]; + for(int z = 0; z < data.length; z++) { + if(!buffer.isReadable()) { + buffer.resetReaderIndex(); + return; + } + data[z] = buffer.readByte(); + if(data[z] < 0) + continue; + PacketBuffer pbuf = new PacketBuffer(Unpooled.wrappedBuffer(data)); + try { + int len = pbuf.readVarInt(); + if(buffer.readableBytes() >= len) { + output.add(buffer.readBytes(len)); + return; + } + buffer.resetReaderIndex(); + } + finally { + pbuf.release(); + } + return; + } + throw new CorruptedFrameException("length wider than 21-bit"); + } } diff --git a/common/src/common/packet/APacketVarInt.java b/common/src/common/packet/APacketVarInt.java index e3196af..f68d407 100755 --- a/common/src/common/packet/APacketVarInt.java +++ b/common/src/common/packet/APacketVarInt.java @@ -16,11 +16,11 @@ public abstract class APacketVarInt implements Packet { } public final void readPacketData(PacketBuffer buf) throws IOException { - this.value = buf.readVarIntFromBuffer(); + this.value = buf.readVarInt(); } public final void writePacketData(PacketBuffer buf) throws IOException { - buf.writeVarIntToBuffer(this.value); + buf.writeVarInt(this.value); } public final int getValue() { diff --git a/common/src/common/packet/CPacketAction.java b/common/src/common/packet/CPacketAction.java index 1df60fb..39988f6 100755 --- a/common/src/common/packet/CPacketAction.java +++ b/common/src/common/packet/CPacketAction.java @@ -29,13 +29,13 @@ public class CPacketAction implements Packet public void readPacketData(PacketBuffer buf) throws IOException { this.action = buf.readEnumValue(Action.class); - this.auxData = buf.readVarIntFromBuffer(); + this.auxData = buf.readVarInt(); } public void writePacketData(PacketBuffer buf) throws IOException { buf.writeEnumValue(this.action); - buf.writeVarIntToBuffer(this.auxData); + buf.writeVarInt(this.auxData); } public void processPacket(IPlayer handler) diff --git a/common/src/common/packet/CPacketBook.java b/common/src/common/packet/CPacketBook.java deleted file mode 100755 index 771fa06..0000000 --- a/common/src/common/packet/CPacketBook.java +++ /dev/null @@ -1,52 +0,0 @@ -package common.packet; - -import java.io.IOException; - -import common.network.IPlayer; -import common.network.Packet; -import common.network.PacketBuffer; - -public class CPacketBook implements Packet -{ - private String[] pages; - - public CPacketBook() - { - } - - public CPacketBook(String[] pages) - { - this.pages = pages; - } - - public void readPacketData(PacketBuffer buf) throws IOException - { - int pages = (int)buf.readByte(); - if(pages > 50) { - this.pages = new String[0]; - return; - } - this.pages = new String[pages]; - for(int z = 0; z < pages; z++) { - this.pages[z] = buf.readStringFromBuffer(1024); - } - } - - public void writePacketData(PacketBuffer buf) throws IOException - { - buf.writeByte(this.pages.length); - for(int z = 0; z < this.pages.length; z++) { - buf.writeString(this.pages[z]); - } - } - - public void processPacket(IPlayer handler) - { - handler.processBook(this); - } - - public String[] getPages() - { - return this.pages; - } -} diff --git a/common/src/common/packet/CPacketCheat.java b/common/src/common/packet/CPacketCheat.java index f2b0715..2ce9395 100755 --- a/common/src/common/packet/CPacketCheat.java +++ b/common/src/common/packet/CPacketCheat.java @@ -30,13 +30,13 @@ public class CPacketCheat implements Packet public void readPacketData(PacketBuffer buf) throws IOException { - this.stack = buf.readItemStackFromBuffer(); + this.stack = buf.readItemStack(); this.slot = buf.readByte(); } public void writePacketData(PacketBuffer buf) throws IOException { - buf.writeItemStackToBuffer(this.stack); + buf.writeItemStack(this.stack); buf.writeByte(this.slot); } diff --git a/common/src/common/packet/CPacketClick.java b/common/src/common/packet/CPacketClick.java index cb4e282..efdf80f 100755 --- a/common/src/common/packet/CPacketClick.java +++ b/common/src/common/packet/CPacketClick.java @@ -53,7 +53,7 @@ public class CPacketClick implements Packet this.usedButton = buf.readByte(); this.actionNumber = buf.readShort(); this.mode = buf.readByte(); - this.clickedItem = buf.readItemStackFromBuffer(); + this.clickedItem = buf.readItemStack(); } public void writePacketData(PacketBuffer buf) throws IOException @@ -63,7 +63,7 @@ public class CPacketClick implements Packet buf.writeByte(this.usedButton); buf.writeShort(this.actionNumber); buf.writeByte(this.mode); - buf.writeItemStackToBuffer(this.clickedItem); + buf.writeItemStack(this.clickedItem); } public int getWindowId() diff --git a/common/src/common/packet/CPacketComplete.java b/common/src/common/packet/CPacketComplete.java index 31b0cc6..83fd0f0 100755 --- a/common/src/common/packet/CPacketComplete.java +++ b/common/src/common/packet/CPacketComplete.java @@ -26,8 +26,8 @@ public class CPacketComplete implements Packet public void readPacketData(PacketBuffer buf) throws IOException { - this.message = buf.readStringFromBuffer(32767); - this.entityId = buf.readVarIntFromBuffer(); + this.message = buf.readString(32767); + this.entityId = buf.readVarInt(); if(buf.readBoolean()) this.position = buf.readBlockPos(); } @@ -35,7 +35,7 @@ public class CPacketComplete implements Packet public void writePacketData(PacketBuffer buf) throws IOException { buf.writeString(this.message.length() > 32767 ? this.message.substring(0, 32767) : this.message); - buf.writeVarIntToBuffer(this.entityId); + buf.writeVarInt(this.entityId); buf.writeBoolean(this.position != null); if(this.position != null) buf.writeBlockPos(this.position); diff --git a/common/src/common/packet/CPacketForm.java b/common/src/common/packet/CPacketForm.java index 136fccc..127ddfb 100644 --- a/common/src/common/packet/CPacketForm.java +++ b/common/src/common/packet/CPacketForm.java @@ -23,12 +23,12 @@ public class CPacketForm implements Packet public void readPacketData(PacketBuffer buf) throws IOException { - this.id = buf.readVarIntFromBuffer(); + this.id = buf.readVarInt(); if(!buf.readBoolean()) { this.data = null; return; } - this.data = new Object[buf.readVarIntFromBuffer()]; + this.data = new Object[buf.readVarInt()]; for(int z = 0; z < this.data.length; z++) { Object obj; switch(buf.readByte()) { @@ -36,10 +36,10 @@ public class CPacketForm implements Packet obj = buf.readBoolean(); break; case 1: - obj = buf.readVarIntFromBuffer(); + obj = buf.readVarInt(); break; default: - obj = buf.readStringFromBuffer(256); + obj = buf.readString(256); break; } this.data[z] = obj; @@ -48,11 +48,11 @@ public class CPacketForm implements Packet public void writePacketData(PacketBuffer buf) throws IOException { - buf.writeVarIntToBuffer(this.id); + buf.writeVarInt(this.id); buf.writeBoolean(this.data != null); if(this.data == null) return; - buf.writeVarIntToBuffer(this.data.length); + buf.writeVarInt(this.data.length); for(int z = 0; z < this.data.length; z++) { Object obj = this.data[z]; if(obj instanceof Boolean) { @@ -61,7 +61,7 @@ public class CPacketForm implements Packet } else if(obj instanceof Integer) { buf.writeByte(1); - buf.writeVarIntToBuffer((Integer)obj); + buf.writeVarInt((Integer)obj); } else { buf.writeByte(2); diff --git a/common/src/common/packet/CPacketMessage.java b/common/src/common/packet/CPacketMessage.java index c7141ea..3b34e2d 100755 --- a/common/src/common/packet/CPacketMessage.java +++ b/common/src/common/packet/CPacketMessage.java @@ -24,7 +24,7 @@ public class CPacketMessage implements Packet public void readPacketData(PacketBuffer buf) throws IOException { this.type = buf.readEnumValue(Type.class); - this.message = buf.readStringFromBuffer(this.type.length); + this.message = buf.readString(this.type.length); } public void writePacketData(PacketBuffer buf) throws IOException diff --git a/common/src/common/packet/CPacketPlace.java b/common/src/common/packet/CPacketPlace.java index c082f6e..a2b8964 100755 --- a/common/src/common/packet/CPacketPlace.java +++ b/common/src/common/packet/CPacketPlace.java @@ -42,7 +42,7 @@ public class CPacketPlace implements Packet { this.position = buf.readBlockPos(); this.placedBlockDirection = buf.readUnsignedByte(); - this.stack = buf.readItemStackFromBuffer(); + this.stack = buf.readItemStack(); this.facingX = (float)buf.readUnsignedByte() / 16.0F; this.facingY = (float)buf.readUnsignedByte() / 16.0F; this.facingZ = (float)buf.readUnsignedByte() / 16.0F; @@ -52,7 +52,7 @@ public class CPacketPlace implements Packet { buf.writeBlockPos(this.position); buf.writeByte(this.placedBlockDirection); - buf.writeItemStackToBuffer(this.stack); + buf.writeItemStack(this.stack); buf.writeByte((int)(this.facingX * 16.0F)); buf.writeByte((int)(this.facingY * 16.0F)); buf.writeByte((int)(this.facingZ * 16.0F)); diff --git a/common/src/common/packet/CPacketPlayer.java b/common/src/common/packet/CPacketPlayer.java index 58c70e7..ccafdc3 100755 --- a/common/src/common/packet/CPacketPlayer.java +++ b/common/src/common/packet/CPacketPlayer.java @@ -85,108 +85,4 @@ public class CPacketPlayer implements Packet { this.moving = isMoving; } - - public static class C04PacketPlayerPosition extends CPacketPlayer - { - public C04PacketPlayerPosition() - { - this.moving = true; - } - - public C04PacketPlayerPosition(double posX, double posY, double posZ, boolean isOnGround) - { - this.x = posX; - this.y = posY; - this.z = posZ; - this.onGround = isOnGround; - this.moving = true; - } - - public void readPacketData(PacketBuffer buf) throws IOException - { - this.x = buf.readDouble(); - this.y = buf.readDouble(); - this.z = buf.readDouble(); - super.readPacketData(buf); - } - - public void writePacketData(PacketBuffer buf) throws IOException - { - buf.writeDouble(this.x); - buf.writeDouble(this.y); - buf.writeDouble(this.z); - super.writePacketData(buf); - } - } - - public static class C05PacketPlayerLook extends CPacketPlayer - { - public C05PacketPlayerLook() - { - this.rotating = true; - } - - public C05PacketPlayerLook(float playerYaw, float playerPitch, boolean isOnGround) - { - this.yaw = playerYaw; - this.pitch = playerPitch; - this.onGround = isOnGround; - this.rotating = true; - } - - public void readPacketData(PacketBuffer buf) throws IOException - { - this.yaw = buf.readFloat(); - this.pitch = buf.readFloat(); - super.readPacketData(buf); - } - - public void writePacketData(PacketBuffer buf) throws IOException - { - buf.writeFloat(this.yaw); - buf.writeFloat(this.pitch); - super.writePacketData(buf); - } - } - - public static class C06PacketPlayerPosLook extends CPacketPlayer - { - public C06PacketPlayerPosLook() - { - this.moving = true; - this.rotating = true; - } - - public C06PacketPlayerPosLook(double playerX, double playerY, double playerZ, float playerYaw, float playerPitch, boolean playerIsOnGround) - { - this.x = playerX; - this.y = playerY; - this.z = playerZ; - this.yaw = playerYaw; - this.pitch = playerPitch; - this.onGround = playerIsOnGround; - this.rotating = true; - this.moving = true; - } - - public void readPacketData(PacketBuffer buf) throws IOException - { - this.x = buf.readDouble(); - this.y = buf.readDouble(); - this.z = buf.readDouble(); - this.yaw = buf.readFloat(); - this.pitch = buf.readFloat(); - super.readPacketData(buf); - } - - public void writePacketData(PacketBuffer buf) throws IOException - { - buf.writeDouble(this.x); - buf.writeDouble(this.y); - buf.writeDouble(this.z); - buf.writeFloat(this.yaw); - buf.writeFloat(this.pitch); - super.writePacketData(buf); - } - } } diff --git a/common/src/common/packet/CPacketPlayerLook.java b/common/src/common/packet/CPacketPlayerLook.java new file mode 100644 index 0000000..47237f7 --- /dev/null +++ b/common/src/common/packet/CPacketPlayerLook.java @@ -0,0 +1,35 @@ +package common.packet; + +import java.io.IOException; + +import common.network.PacketBuffer; + +public class CPacketPlayerLook extends CPacketPlayer +{ + public CPacketPlayerLook() + { + this.rotating = true; + } + + public CPacketPlayerLook(float playerYaw, float playerPitch, boolean isOnGround) + { + this.yaw = playerYaw; + this.pitch = playerPitch; + this.onGround = isOnGround; + this.rotating = true; + } + + public void readPacketData(PacketBuffer buf) throws IOException + { + this.yaw = buf.readFloat(); + this.pitch = buf.readFloat(); + super.readPacketData(buf); + } + + public void writePacketData(PacketBuffer buf) throws IOException + { + buf.writeFloat(this.yaw); + buf.writeFloat(this.pitch); + super.writePacketData(buf); + } +} \ No newline at end of file diff --git a/common/src/common/packet/CPacketPlayerPosLook.java b/common/src/common/packet/CPacketPlayerPosLook.java new file mode 100644 index 0000000..9b02b82 --- /dev/null +++ b/common/src/common/packet/CPacketPlayerPosLook.java @@ -0,0 +1,46 @@ +package common.packet; + +import java.io.IOException; + +import common.network.PacketBuffer; + +public class CPacketPlayerPosLook extends CPacketPlayer +{ + public CPacketPlayerPosLook() + { + this.moving = true; + this.rotating = true; + } + + public CPacketPlayerPosLook(double playerX, double playerY, double playerZ, float playerYaw, float playerPitch, boolean playerIsOnGround) + { + this.x = playerX; + this.y = playerY; + this.z = playerZ; + this.yaw = playerYaw; + this.pitch = playerPitch; + this.onGround = playerIsOnGround; + this.rotating = true; + this.moving = true; + } + + public void readPacketData(PacketBuffer buf) throws IOException + { + this.x = buf.readDouble(); + this.y = buf.readDouble(); + this.z = buf.readDouble(); + this.yaw = buf.readFloat(); + this.pitch = buf.readFloat(); + super.readPacketData(buf); + } + + public void writePacketData(PacketBuffer buf) throws IOException + { + buf.writeDouble(this.x); + buf.writeDouble(this.y); + buf.writeDouble(this.z); + buf.writeFloat(this.yaw); + buf.writeFloat(this.pitch); + super.writePacketData(buf); + } +} \ No newline at end of file diff --git a/common/src/common/packet/CPacketPlayerPosition.java b/common/src/common/packet/CPacketPlayerPosition.java new file mode 100644 index 0000000..a82ad3e --- /dev/null +++ b/common/src/common/packet/CPacketPlayerPosition.java @@ -0,0 +1,38 @@ +package common.packet; + +import java.io.IOException; + +import common.network.PacketBuffer; + +public class CPacketPlayerPosition extends CPacketPlayer +{ + public CPacketPlayerPosition() + { + this.moving = true; + } + + public CPacketPlayerPosition(double posX, double posY, double posZ, boolean isOnGround) + { + this.x = posX; + this.y = posY; + this.z = posZ; + this.onGround = isOnGround; + this.moving = true; + } + + public void readPacketData(PacketBuffer buf) throws IOException + { + this.x = buf.readDouble(); + this.y = buf.readDouble(); + this.z = buf.readDouble(); + super.readPacketData(buf); + } + + public void writePacketData(PacketBuffer buf) throws IOException + { + buf.writeDouble(this.x); + buf.writeDouble(this.y); + buf.writeDouble(this.z); + super.writePacketData(buf); + } +} \ No newline at end of file diff --git a/common/src/common/packet/CPacketSign.java b/common/src/common/packet/CPacketSign.java index 3653f78..9e01415 100755 --- a/common/src/common/packet/CPacketSign.java +++ b/common/src/common/packet/CPacketSign.java @@ -34,7 +34,7 @@ public class CPacketSign implements Packet for (int i = 0; i < 4; ++i) { - this.lines[i] = buf.readStringFromBuffer(50); + this.lines[i] = buf.readString(50); } } diff --git a/common/src/common/packet/CPacketSkin.java b/common/src/common/packet/CPacketSkin.java index 30e476c..d587918 100755 --- a/common/src/common/packet/CPacketSkin.java +++ b/common/src/common/packet/CPacketSkin.java @@ -29,7 +29,7 @@ public class CPacketSkin implements Packet { public void readPacketData(PacketBuffer buf) throws IOException { if(buf.readBoolean()) { this.texture = null; - this.character = buf.readStringFromBuffer(64); + this.character = buf.readString(64); } else { this.texture = buf.readByteArray(); diff --git a/common/src/common/packet/HPacketHandshake.java b/common/src/common/packet/HPacketHandshake.java index e2a0018..f94e44e 100755 --- a/common/src/common/packet/HPacketHandshake.java +++ b/common/src/common/packet/HPacketHandshake.java @@ -17,7 +17,7 @@ public class HPacketHandshake implements Packet { } public void readPacketData(PacketBuffer buf) throws IOException { - this.protocol = buf.readVarIntFromBuffer(); + this.protocol = buf.readVarInt(); int r = buf.readableBytes(); if(r > 0) { this.protocol = 0; @@ -27,7 +27,7 @@ public class HPacketHandshake implements Packet { } public void writePacketData(PacketBuffer buf) throws IOException { - buf.writeVarIntToBuffer(this.protocol); + buf.writeVarInt(this.protocol); } public void processPacket(IHandshakeHandler handler) { diff --git a/common/src/common/packet/LPacketLogin.java b/common/src/common/packet/LPacketLogin.java index 997d370..50c647d 100644 --- a/common/src/common/packet/LPacketLogin.java +++ b/common/src/common/packet/LPacketLogin.java @@ -10,7 +10,7 @@ public class LPacketLogin implements Packet { } public void readPacketData(PacketBuffer buf) throws IOException { - buf.readStringFromBuffer(16); + buf.readString(16); } public void writePacketData(PacketBuffer buf) throws IOException { diff --git a/common/src/common/packet/LPacketPasswordResponse.java b/common/src/common/packet/LPacketPasswordResponse.java index 073009c..60dc63c 100755 --- a/common/src/common/packet/LPacketPasswordResponse.java +++ b/common/src/common/packet/LPacketPasswordResponse.java @@ -29,9 +29,9 @@ public class LPacketPasswordResponse implements Packet */ public void readPacketData(PacketBuffer buf) throws IOException { - this.user = buf.readStringFromBuffer(IPlayer.MAX_USER_LENGTH); - this.access = buf.readStringFromBuffer(IPlayer.MAX_PASS_LENGTH); - this.password = buf.readStringFromBuffer(IPlayer.MAX_PASS_LENGTH); + this.user = buf.readString(IPlayer.MAX_USER_LENGTH); + this.access = buf.readString(IPlayer.MAX_PASS_LENGTH); + this.password = buf.readString(IPlayer.MAX_PASS_LENGTH); } /** diff --git a/common/src/common/packet/RPacketDisconnect.java b/common/src/common/packet/RPacketDisconnect.java index 3e1c8cb..36f8aad 100755 --- a/common/src/common/packet/RPacketDisconnect.java +++ b/common/src/common/packet/RPacketDisconnect.java @@ -24,7 +24,7 @@ public class RPacketDisconnect implements Packet */ public void readPacketData(PacketBuffer buf) throws IOException { - this.reason = buf.readStringFromBuffer(8192); + this.reason = buf.readString(8192); } /** diff --git a/common/src/common/packet/S14PacketEntity.java b/common/src/common/packet/S14PacketEntity.java deleted file mode 100755 index 68507af..0000000 --- a/common/src/common/packet/S14PacketEntity.java +++ /dev/null @@ -1,208 +0,0 @@ -package common.packet; - -import java.io.IOException; - -import common.entity.Entity; -import common.network.IClientPlayer; -import common.network.Packet; -import common.network.PacketBuffer; -import common.world.World; - -public class S14PacketEntity implements Packet -{ - protected int entityId; - protected byte posX; - protected byte posY; - protected byte posZ; - protected byte yaw; - protected byte pitch; - protected boolean onGround; - protected boolean rotation; - - public S14PacketEntity() - { - } - - public S14PacketEntity(int entityIdIn) - { - this.entityId = entityIdIn; - } - - /** - * Reads the raw packet data from the data stream. - */ - public void readPacketData(PacketBuffer buf) throws IOException - { - this.entityId = buf.readVarIntFromBuffer(); - } - - /** - * Writes the raw packet data to the data stream. - */ - public void writePacketData(PacketBuffer buf) throws IOException - { - buf.writeVarIntToBuffer(this.entityId); - } - - /** - * Passes this Packet on to the NetHandler for processing. - */ - public void processPacket(IClientPlayer handler) - { - handler.handleEntityMovement(this); - } - - public String toString() - { - return "Entity_" + super.toString(); - } - - public Entity getEntity(World worldIn) - { - return worldIn.getEntityByID(this.entityId); - } - - public byte getPosX() - { - return this.posX; - } - - public byte getPosY() - { - return this.posY; - } - - public byte getPosZ() - { - return this.posZ; - } - - public byte getYaw() - { - return this.yaw; - } - - public byte getPitch() - { - return this.pitch; - } - - public boolean hasRotations() - { - return this.rotation; - } - - public boolean getOnGround() - { - return this.onGround; - } - - public static class S15PacketEntityRelMove extends S14PacketEntity - { - public S15PacketEntityRelMove() - { - } - - public S15PacketEntityRelMove(int entityIdIn, byte x, byte y, byte z, boolean onGroundIn) - { - super(entityIdIn); - this.posX = x; - this.posY = y; - this.posZ = z; - this.onGround = onGroundIn; - } - - public void readPacketData(PacketBuffer buf) throws IOException - { - super.readPacketData(buf); - this.posX = buf.readByte(); - this.posY = buf.readByte(); - this.posZ = buf.readByte(); - this.onGround = buf.readBoolean(); - } - - public void writePacketData(PacketBuffer buf) throws IOException - { - super.writePacketData(buf); - buf.writeByte(this.posX); - buf.writeByte(this.posY); - buf.writeByte(this.posZ); - buf.writeBoolean(this.onGround); - } - } - - public static class S16PacketEntityLook extends S14PacketEntity - { - public S16PacketEntityLook() - { - this.rotation = true; - } - - public S16PacketEntityLook(int entityIdIn, byte yawIn, byte pitchIn, boolean onGroundIn) - { - super(entityIdIn); - this.yaw = yawIn; - this.pitch = pitchIn; - this.rotation = true; - this.onGround = onGroundIn; - } - - public void readPacketData(PacketBuffer buf) throws IOException - { - super.readPacketData(buf); - this.yaw = buf.readByte(); - this.pitch = buf.readByte(); - this.onGround = buf.readBoolean(); - } - - public void writePacketData(PacketBuffer buf) throws IOException - { - super.writePacketData(buf); - buf.writeByte(this.yaw); - buf.writeByte(this.pitch); - buf.writeBoolean(this.onGround); - } - } - - public static class S17PacketEntityLookMove extends S14PacketEntity - { - public S17PacketEntityLookMove() - { - this.rotation = true; - } - - public S17PacketEntityLookMove(int p_i45973_1_, byte p_i45973_2_, byte p_i45973_3_, byte p_i45973_4_, byte p_i45973_5_, byte p_i45973_6_, boolean p_i45973_7_) - { - super(p_i45973_1_); - this.posX = p_i45973_2_; - this.posY = p_i45973_3_; - this.posZ = p_i45973_4_; - this.yaw = p_i45973_5_; - this.pitch = p_i45973_6_; - this.onGround = p_i45973_7_; - this.rotation = true; - } - - public void readPacketData(PacketBuffer buf) throws IOException - { - super.readPacketData(buf); - this.posX = buf.readByte(); - this.posY = buf.readByte(); - this.posZ = buf.readByte(); - this.yaw = buf.readByte(); - this.pitch = buf.readByte(); - this.onGround = buf.readBoolean(); - } - - public void writePacketData(PacketBuffer buf) throws IOException - { - super.writePacketData(buf); - buf.writeByte(this.posX); - buf.writeByte(this.posY); - buf.writeByte(this.posZ); - buf.writeByte(this.yaw); - buf.writeByte(this.pitch); - buf.writeBoolean(this.onGround); - } - } -} diff --git a/common/src/common/packet/SPacketAnimation.java b/common/src/common/packet/SPacketAnimation.java index ad62a60..de8b50d 100755 --- a/common/src/common/packet/SPacketAnimation.java +++ b/common/src/common/packet/SPacketAnimation.java @@ -33,14 +33,14 @@ public class SPacketAnimation implements Packet public void readPacketData(PacketBuffer buf) throws IOException { - this.entityId = buf.readVarIntFromBuffer(); + this.entityId = buf.readVarInt(); this.type = buf.readUnsignedByte(); // this.par = buf.readVarIntFromBuffer(); } public void writePacketData(PacketBuffer buf) throws IOException { - buf.writeVarIntToBuffer(this.entityId); + buf.writeVarInt(this.entityId); buf.writeByte(this.type); // buf.writeVarIntToBuffer(this.par); } diff --git a/common/src/common/packet/SPacketBlockAction.java b/common/src/common/packet/SPacketBlockAction.java index 239d6eb..083cf7f 100755 --- a/common/src/common/packet/SPacketBlockAction.java +++ b/common/src/common/packet/SPacketBlockAction.java @@ -36,7 +36,7 @@ public class SPacketBlockAction implements Packet this.blockPosition = buf.readBlockPos(); this.instrument = buf.readUnsignedByte(); this.pitch = buf.readUnsignedByte(); - this.block = BlockRegistry.getBlockById(buf.readVarIntFromBuffer() & 4095); + this.block = BlockRegistry.getBlockById(buf.readVarInt() & 4095); } /** @@ -47,7 +47,7 @@ public class SPacketBlockAction implements Packet buf.writeBlockPos(this.blockPosition); buf.writeByte(this.instrument); buf.writeByte(this.pitch); - buf.writeVarIntToBuffer(BlockRegistry.getIdFromBlock(this.block) & 4095); + buf.writeVarInt(BlockRegistry.getIdFromBlock(this.block) & 4095); } /** diff --git a/common/src/common/packet/SPacketBlockBreakAnim.java b/common/src/common/packet/SPacketBlockBreakAnim.java index ccebc7e..1b1acec 100755 --- a/common/src/common/packet/SPacketBlockBreakAnim.java +++ b/common/src/common/packet/SPacketBlockBreakAnim.java @@ -29,7 +29,7 @@ public class SPacketBlockBreakAnim implements Packet */ public void readPacketData(PacketBuffer buf) throws IOException { - this.breakerId = buf.readVarIntFromBuffer(); + this.breakerId = buf.readVarInt(); this.position = buf.readBlockPos(); this.progress = buf.readUnsignedByte(); } @@ -39,7 +39,7 @@ public class SPacketBlockBreakAnim implements Packet */ public void writePacketData(PacketBuffer buf) throws IOException { - buf.writeVarIntToBuffer(this.breakerId); + buf.writeVarInt(this.breakerId); buf.writeBlockPos(this.position); buf.writeByte(this.progress); } diff --git a/common/src/common/packet/SPacketBlockChange.java b/common/src/common/packet/SPacketBlockChange.java index 9ab2a01..ca79376 100755 --- a/common/src/common/packet/SPacketBlockChange.java +++ b/common/src/common/packet/SPacketBlockChange.java @@ -31,7 +31,7 @@ public class SPacketBlockChange implements Packet public void readPacketData(PacketBuffer buf) throws IOException { this.blockPosition = buf.readBlockPos(); - this.blockState = (State)BlockRegistry.STATEMAP.getByValue(buf.readVarIntFromBuffer()); + this.blockState = (State)BlockRegistry.STATEMAP.getByValue(buf.readVarInt()); } /** @@ -40,7 +40,7 @@ public class SPacketBlockChange implements Packet public void writePacketData(PacketBuffer buf) throws IOException { buf.writeBlockPos(this.blockPosition); - buf.writeVarIntToBuffer(BlockRegistry.STATEMAP.get(this.blockState)); + buf.writeVarInt(BlockRegistry.STATEMAP.get(this.blockState)); } /** diff --git a/common/src/common/packet/SPacketCamera.java b/common/src/common/packet/SPacketCamera.java index 40edc45..d72765c 100755 --- a/common/src/common/packet/SPacketCamera.java +++ b/common/src/common/packet/SPacketCamera.java @@ -23,12 +23,12 @@ public class SPacketCamera implements Packet public void readPacketData(PacketBuffer buf) throws IOException { - this.entityId = buf.readVarIntFromBuffer(); + this.entityId = buf.readVarInt(); } public void writePacketData(PacketBuffer buf) throws IOException { - buf.writeVarIntToBuffer(this.entityId); + buf.writeVarInt(this.entityId); } public void processPacket(IClientPlayer handler) diff --git a/common/src/common/packet/S2BPacketChangeGameState.java b/common/src/common/packet/SPacketChangeGameState.java similarity index 76% rename from common/src/common/packet/S2BPacketChangeGameState.java rename to common/src/common/packet/SPacketChangeGameState.java index 488573a..2485d8a 100755 --- a/common/src/common/packet/S2BPacketChangeGameState.java +++ b/common/src/common/packet/SPacketChangeGameState.java @@ -7,26 +7,26 @@ import common.network.Packet; import common.network.PacketBuffer; import common.util.ExtMath; -public class S2BPacketChangeGameState implements Packet +public class SPacketChangeGameState implements Packet { private Action action; private int param; - public S2BPacketChangeGameState() + public SPacketChangeGameState() { } - public S2BPacketChangeGameState(Action action) + public SPacketChangeGameState(Action action) { this(action, 0); } - public S2BPacketChangeGameState(Action action, float param) + public SPacketChangeGameState(Action action, float param) { this(action, (int)(param * 1000.0f)); } - public S2BPacketChangeGameState(Action action, int param) + public SPacketChangeGameState(Action action, int param) { this.action = action; this.param = param; @@ -35,13 +35,13 @@ public class S2BPacketChangeGameState implements Packet public void readPacketData(PacketBuffer buf) throws IOException { this.action = buf.readEnumValue(Action.class); - this.param = buf.readVarIntFromBuffer(); + this.param = buf.readVarInt(); } public void writePacketData(PacketBuffer buf) throws IOException { buf.writeEnumValue(this.action); - buf.writeVarIntToBuffer(this.param); + buf.writeVarInt(this.param); } public void processPacket(IClientPlayer handler) diff --git a/common/src/common/packet/SPacketCharacterList.java b/common/src/common/packet/SPacketCharacterList.java index 8978d9d..c27e226 100644 --- a/common/src/common/packet/SPacketCharacterList.java +++ b/common/src/common/packet/SPacketCharacterList.java @@ -40,31 +40,31 @@ public class SPacketCharacterList implements Packet { } public void readPacketData(PacketBuffer buf) throws IOException { - int n = buf.readVarIntFromBuffer(); + int n = buf.readVarInt(); for(int z = 0; z < n; z++) { - int id = buf.readVarIntFromBuffer(); - String name = buf.readStringFromBuffer(IPlayer.MAX_NICK_LENGTH); + int id = buf.readVarInt(); + String name = buf.readString(IPlayer.MAX_NICK_LENGTH); if(name.isEmpty()) { this.players.put(id, null); continue; } - String info = buf.readStringFromBuffer(IPlayer.MAX_INFO_LENGTH); + String info = buf.readString(IPlayer.MAX_INFO_LENGTH); info = info.isEmpty() ? null : info; Alignment align = buf.readEnumValue(Alignment.class); - String dim = buf.readStringFromBuffer(256); + String dim = buf.readString(256); BlockPos pos = buf.readBlockPos(); - String type = buf.readStringFromBuffer(256); - int level = buf.readVarIntFromBuffer(); + String type = buf.readString(256); + int level = buf.readVarInt(); this.players.put(id, new PlayerCharacter(name, info, align, dim, pos, type, level)); } - this.selected = buf.readVarIntFromBuffer(); + this.selected = buf.readVarInt(); } public void writePacketData(PacketBuffer buf) throws IOException { - buf.writeVarIntToBuffer(this.players.size()); + buf.writeVarInt(this.players.size()); for(Entry data : this.players.entrySet()) { PlayerCharacter chr = data.getValue(); - buf.writeVarIntToBuffer(data.getKey()); + buf.writeVarInt(data.getKey()); if(chr == null) { buf.writeString(""); continue; @@ -75,9 +75,9 @@ public class SPacketCharacterList implements Packet { buf.writeString(chr.dim); buf.writeBlockPos(chr.pos); buf.writeString(chr.type); - buf.writeVarIntToBuffer(chr.level); + buf.writeVarInt(chr.level); } - buf.writeVarIntToBuffer(this.selected); + buf.writeVarInt(this.selected); } public void processPacket(IClientPlayer handler) { diff --git a/common/src/common/packet/SPacketChunkData.java b/common/src/common/packet/SPacketChunkData.java index 66438d6..3aac135 100755 --- a/common/src/common/packet/SPacketChunkData.java +++ b/common/src/common/packet/SPacketChunkData.java @@ -34,9 +34,9 @@ public class SPacketChunkData implements Packet this.biomes = buf.readBoolean(); this.extractedData = new SPacketChunkData.Extracted(); this.extractedData.data = buf.readByteArray(); - this.extractedData.extend = new int[buf.readVarIntFromBuffer()]; + this.extractedData.extend = new int[buf.readVarInt()]; for(int z = 0; z < this.extractedData.extend.length; z++) { - this.extractedData.extend[z] = buf.readVarIntFromBuffer(); + this.extractedData.extend[z] = buf.readVarInt(); } } @@ -49,9 +49,9 @@ public class SPacketChunkData implements Packet buf.writeInt(this.chunkZ); buf.writeBoolean(this.biomes); buf.writeByteArray(this.extractedData.data); - buf.writeVarIntToBuffer(this.extractedData.extend.length); + buf.writeVarInt(this.extractedData.extend.length); for(int z = 0; z < this.extractedData.extend.length; z++) { - buf.writeVarIntToBuffer(this.extractedData.extend[z]); + buf.writeVarInt(this.extractedData.extend[z]); } } diff --git a/common/src/common/packet/S2EPacketCloseWindow.java b/common/src/common/packet/SPacketCloseWindow.java similarity index 84% rename from common/src/common/packet/S2EPacketCloseWindow.java rename to common/src/common/packet/SPacketCloseWindow.java index 7629715..28b01f9 100755 --- a/common/src/common/packet/S2EPacketCloseWindow.java +++ b/common/src/common/packet/SPacketCloseWindow.java @@ -6,15 +6,15 @@ import common.network.IClientPlayer; import common.network.Packet; import common.network.PacketBuffer; -public class S2EPacketCloseWindow implements Packet +public class SPacketCloseWindow implements Packet { private int windowId; - public S2EPacketCloseWindow() + public SPacketCloseWindow() { } - public S2EPacketCloseWindow(int windowIdIn) + public SPacketCloseWindow(int windowIdIn) { this.windowId = windowIdIn; } diff --git a/common/src/common/packet/SPacketCollectItem.java b/common/src/common/packet/SPacketCollectItem.java index 4c0deb7..ea5d18f 100755 --- a/common/src/common/packet/SPacketCollectItem.java +++ b/common/src/common/packet/SPacketCollectItem.java @@ -26,8 +26,8 @@ public class SPacketCollectItem implements Packet */ public void readPacketData(PacketBuffer buf) throws IOException { - this.collectedItemEntityId = buf.readVarIntFromBuffer(); - this.entityId = buf.readVarIntFromBuffer(); + this.collectedItemEntityId = buf.readVarInt(); + this.entityId = buf.readVarInt(); } /** @@ -35,8 +35,8 @@ public class SPacketCollectItem implements Packet */ public void writePacketData(PacketBuffer buf) throws IOException { - buf.writeVarIntToBuffer(this.collectedItemEntityId); - buf.writeVarIntToBuffer(this.entityId); + buf.writeVarInt(this.collectedItemEntityId); + buf.writeVarInt(this.entityId); } /** diff --git a/common/src/common/packet/S32PacketConfirmTransaction.java b/common/src/common/packet/SPacketConfirmTransaction.java similarity index 86% rename from common/src/common/packet/S32PacketConfirmTransaction.java rename to common/src/common/packet/SPacketConfirmTransaction.java index 2bf7c0f..e09cd3e 100755 --- a/common/src/common/packet/S32PacketConfirmTransaction.java +++ b/common/src/common/packet/SPacketConfirmTransaction.java @@ -6,17 +6,17 @@ import common.network.IClientPlayer; import common.network.Packet; import common.network.PacketBuffer; -public class S32PacketConfirmTransaction implements Packet +public class SPacketConfirmTransaction implements Packet { private int windowId; private short actionNumber; private boolean matching; - public S32PacketConfirmTransaction() + public SPacketConfirmTransaction() { } - public S32PacketConfirmTransaction(int windowIdIn, short actionNumberIn, boolean matching) + public SPacketConfirmTransaction(int windowIdIn, short actionNumberIn, boolean matching) { this.windowId = windowIdIn; this.actionNumber = actionNumberIn; diff --git a/common/src/common/packet/SPacketDestroyEntities.java b/common/src/common/packet/SPacketDestroyEntities.java index 9927461..aafef94 100755 --- a/common/src/common/packet/SPacketDestroyEntities.java +++ b/common/src/common/packet/SPacketDestroyEntities.java @@ -24,11 +24,11 @@ public class SPacketDestroyEntities implements Packet */ public void readPacketData(PacketBuffer buf) throws IOException { - this.entityIDs = new int[buf.readVarIntFromBuffer()]; + this.entityIDs = new int[buf.readVarInt()]; for (int i = 0; i < this.entityIDs.length; ++i) { - this.entityIDs[i] = buf.readVarIntFromBuffer(); + this.entityIDs[i] = buf.readVarInt(); } } @@ -37,11 +37,11 @@ public class SPacketDestroyEntities implements Packet */ public void writePacketData(PacketBuffer buf) throws IOException { - buf.writeVarIntToBuffer(this.entityIDs.length); + buf.writeVarInt(this.entityIDs.length); for (int i = 0; i < this.entityIDs.length; ++i) { - buf.writeVarIntToBuffer(this.entityIDs[i]); + buf.writeVarInt(this.entityIDs[i]); } } diff --git a/common/src/common/packet/SPacketDimensionName.java b/common/src/common/packet/SPacketDimensionName.java index feb1c80..2523147 100755 --- a/common/src/common/packet/SPacketDimensionName.java +++ b/common/src/common/packet/SPacketDimensionName.java @@ -25,8 +25,8 @@ public class SPacketDimensionName implements Packet { } public void readPacketData(PacketBuffer buf) throws IOException { - this.fullName = buf.readStringFromBuffer(64); - this.customName = buf.readStringFromBuffer(64); + this.fullName = buf.readString(64); + this.customName = buf.readString(64); this.customName = this.customName.isEmpty() ? null : this.customName; } diff --git a/common/src/common/packet/SPacketDisconnect.java b/common/src/common/packet/SPacketDisconnect.java index 133acdc..f558fc0 100755 --- a/common/src/common/packet/SPacketDisconnect.java +++ b/common/src/common/packet/SPacketDisconnect.java @@ -17,7 +17,7 @@ public class SPacketDisconnect implements Packet { } public void readPacketData(PacketBuffer buf) throws IOException { - this.message = buf.readStringFromBuffer(2048); + this.message = buf.readString(2048); } public void writePacketData(PacketBuffer buf) throws IOException { diff --git a/common/src/common/packet/SPacketDisplayForm.java b/common/src/common/packet/SPacketDisplayForm.java index 372e8af..5128331 100644 --- a/common/src/common/packet/SPacketDisplayForm.java +++ b/common/src/common/packet/SPacketDisplayForm.java @@ -31,36 +31,36 @@ public class SPacketDisplayForm implements Packet public void readPacketData(PacketBuffer buf) throws IOException { - this.id = buf.readVarIntFromBuffer(); - this.title = buf.readStringFromBuffer(256); - this.data = new Triplet[buf.readVarIntFromBuffer()]; + this.id = buf.readVarInt(); + this.title = buf.readString(256); + this.data = new Triplet[buf.readVarInt()]; for(int z = 0; z < this.data.length; z++) { - String name = buf.readStringFromBuffer(64); + String name = buf.readString(64); Object obj; switch(buf.readByte()) { case 0: obj = buf.readBoolean(); break; case 1: - String[] strs = new String[buf.readVarIntFromBuffer()]; + String[] strs = new String[buf.readVarInt()]; obj = strs; for(int n = 0; n < strs.length; n++) { - strs[n] = buf.readStringFromBuffer(128); + strs[n] = buf.readString(128); } break; default: - obj = buf.readStringFromBuffer(256); + obj = buf.readString(256); break; } - this.data[z] = new Triplet(name, obj, buf.readVarIntFromBuffer()); + this.data[z] = new Triplet(name, obj, buf.readVarInt()); } } public void writePacketData(PacketBuffer buf) throws IOException { - buf.writeVarIntToBuffer(this.id); + buf.writeVarInt(this.id); buf.writeString(this.title); - buf.writeVarIntToBuffer(this.data.length); + buf.writeVarInt(this.data.length); for(int z = 0; z < this.data.length; z++) { buf.writeString(this.data[z].first); Object obj = this.data[z].second; @@ -71,7 +71,7 @@ public class SPacketDisplayForm implements Packet else if(obj instanceof String[]) { buf.writeByte(1); String[] strs = (String[])obj; - buf.writeVarIntToBuffer(strs.length); + buf.writeVarInt(strs.length); for(int n = 0; n < strs.length; n++) { buf.writeString(strs[n]); } @@ -80,7 +80,7 @@ public class SPacketDisplayForm implements Packet buf.writeByte(2); buf.writeString((String)obj); } - buf.writeVarIntToBuffer(this.data[z].third); + buf.writeVarInt(this.data[z].third); } } diff --git a/common/src/common/packet/S28PacketEffect.java b/common/src/common/packet/SPacketEffect.java similarity index 84% rename from common/src/common/packet/S28PacketEffect.java rename to common/src/common/packet/SPacketEffect.java index cd826e2..9c81fb1 100755 --- a/common/src/common/packet/S28PacketEffect.java +++ b/common/src/common/packet/SPacketEffect.java @@ -7,15 +7,15 @@ import common.network.Packet; import common.network.PacketBuffer; import common.util.BlockPos; -public class S28PacketEffect implements Packet { +public class SPacketEffect implements Packet { private int soundType; private BlockPos soundPos; private int soundData; - public S28PacketEffect() { + public SPacketEffect() { } - public S28PacketEffect(int soundTypeIn, BlockPos soundPosIn, int soundDataIn) { + public SPacketEffect(int soundTypeIn, BlockPos soundPosIn, int soundDataIn) { this.soundType = soundTypeIn; this.soundPos = soundPosIn; this.soundData = soundDataIn; diff --git a/common/src/common/packet/SPacketEntity.java b/common/src/common/packet/SPacketEntity.java new file mode 100755 index 0000000..7b05088 --- /dev/null +++ b/common/src/common/packet/SPacketEntity.java @@ -0,0 +1,99 @@ +package common.packet; + +import java.io.IOException; + +import common.entity.Entity; +import common.network.IClientPlayer; +import common.network.Packet; +import common.network.PacketBuffer; +import common.world.World; + +public class SPacketEntity implements Packet +{ + protected int entityId; + protected byte posX; + protected byte posY; + protected byte posZ; + protected byte yaw; + protected byte pitch; + protected boolean onGround; + protected boolean rotation; + + public SPacketEntity() + { + } + + public SPacketEntity(int entityIdIn) + { + this.entityId = entityIdIn; + } + + /** + * Reads the raw packet data from the data stream. + */ + public void readPacketData(PacketBuffer buf) throws IOException + { + this.entityId = buf.readVarInt(); + } + + /** + * Writes the raw packet data to the data stream. + */ + public void writePacketData(PacketBuffer buf) throws IOException + { + buf.writeVarInt(this.entityId); + } + + /** + * Passes this Packet on to the NetHandler for processing. + */ + public void processPacket(IClientPlayer handler) + { + handler.handleEntityMovement(this); + } + + public String toString() + { + return "Entity_" + super.toString(); + } + + public Entity getEntity(World worldIn) + { + return worldIn.getEntityByID(this.entityId); + } + + public byte getPosX() + { + return this.posX; + } + + public byte getPosY() + { + return this.posY; + } + + public byte getPosZ() + { + return this.posZ; + } + + public byte getYaw() + { + return this.yaw; + } + + public byte getPitch() + { + return this.pitch; + } + + public boolean hasRotations() + { + return this.rotation; + } + + public boolean getOnGround() + { + return this.onGround; + } +} diff --git a/common/src/common/packet/S1BPacketEntityAttach.java b/common/src/common/packet/SPacketEntityAttach.java similarity index 88% rename from common/src/common/packet/S1BPacketEntityAttach.java rename to common/src/common/packet/SPacketEntityAttach.java index 24c0807..618311a 100755 --- a/common/src/common/packet/S1BPacketEntityAttach.java +++ b/common/src/common/packet/SPacketEntityAttach.java @@ -7,17 +7,17 @@ import common.network.IClientPlayer; import common.network.Packet; import common.network.PacketBuffer; -public class S1BPacketEntityAttach implements Packet +public class SPacketEntityAttach implements Packet { private int leash; private int entityId; private int vehicleEntityId; - public S1BPacketEntityAttach() + public SPacketEntityAttach() { } - public S1BPacketEntityAttach(int leashIn, Entity entityIn, Entity vehicle) + public SPacketEntityAttach(int leashIn, Entity entityIn, Entity vehicle) { this.leash = leashIn; this.entityId = entityIn.getId(); diff --git a/common/src/common/packet/S1DPacketEntityEffect.java b/common/src/common/packet/SPacketEntityEffect.java similarity index 77% rename from common/src/common/packet/S1DPacketEntityEffect.java rename to common/src/common/packet/SPacketEntityEffect.java index faf5dc6..ce38939 100755 --- a/common/src/common/packet/S1DPacketEntityEffect.java +++ b/common/src/common/packet/SPacketEntityEffect.java @@ -8,7 +8,7 @@ import common.network.PacketBuffer; import common.potion.Potion; import common.potion.PotionEffect; -public class S1DPacketEntityEffect implements Packet +public class SPacketEntityEffect implements Packet { private int entityId; private Potion effectId; @@ -17,11 +17,11 @@ public class S1DPacketEntityEffect implements Packet private int remaining; private boolean particles; - public S1DPacketEntityEffect() + public SPacketEntityEffect() { } - public S1DPacketEntityEffect(int entityIdIn, PotionEffect effect) + public SPacketEntityEffect(int entityIdIn, PotionEffect effect) { this.entityId = entityIdIn; this.effectId = effect.getPotion(); @@ -45,11 +45,11 @@ public class S1DPacketEntityEffect implements Packet */ public void readPacketData(PacketBuffer buf) throws IOException { - this.entityId = buf.readVarIntFromBuffer(); + this.entityId = buf.readVarInt(); this.effectId = buf.readEnumValue(Potion.class); - this.amplifier = buf.readVarIntFromBuffer(); - this.duration = buf.readVarIntFromBuffer(); - this.remaining = buf.readVarIntFromBuffer(); + this.amplifier = buf.readVarInt(); + this.duration = buf.readVarInt(); + this.remaining = buf.readVarInt(); this.particles = buf.readBoolean(); } @@ -58,11 +58,11 @@ public class S1DPacketEntityEffect implements Packet */ public void writePacketData(PacketBuffer buf) throws IOException { - buf.writeVarIntToBuffer(this.entityId); + buf.writeVarInt(this.entityId); buf.writeEnumValue(this.effectId); - buf.writeVarIntToBuffer(this.amplifier); - buf.writeVarIntToBuffer(this.duration); - buf.writeVarIntToBuffer(this.remaining); + buf.writeVarInt(this.amplifier); + buf.writeVarInt(this.duration); + buf.writeVarInt(this.remaining); buf.writeBoolean(this.particles); } diff --git a/common/src/common/packet/SPacketEntityEquipment.java b/common/src/common/packet/SPacketEntityEquipment.java index 0ee5fd8..8497508 100755 --- a/common/src/common/packet/SPacketEntityEquipment.java +++ b/common/src/common/packet/SPacketEntityEquipment.java @@ -29,9 +29,9 @@ public class SPacketEntityEquipment implements Packet */ public void readPacketData(PacketBuffer buf) throws IOException { - this.entityID = buf.readVarIntFromBuffer(); + this.entityID = buf.readVarInt(); this.equipmentSlot = buf.readShort(); - this.itemStack = buf.readItemStackFromBuffer(); + this.itemStack = buf.readItemStack(); } /** @@ -39,9 +39,9 @@ public class SPacketEntityEquipment implements Packet */ public void writePacketData(PacketBuffer buf) throws IOException { - buf.writeVarIntToBuffer(this.entityID); + buf.writeVarInt(this.entityID); buf.writeShort(this.equipmentSlot); - buf.writeItemStackToBuffer(this.itemStack); + buf.writeItemStack(this.itemStack); } /** diff --git a/common/src/common/packet/S19PacketEntityHeadLook.java b/common/src/common/packet/SPacketEntityHeadLook.java similarity index 79% rename from common/src/common/packet/S19PacketEntityHeadLook.java rename to common/src/common/packet/SPacketEntityHeadLook.java index 885659e..76f5ddf 100755 --- a/common/src/common/packet/S19PacketEntityHeadLook.java +++ b/common/src/common/packet/SPacketEntityHeadLook.java @@ -8,16 +8,16 @@ import common.network.Packet; import common.network.PacketBuffer; import common.world.World; -public class S19PacketEntityHeadLook implements Packet +public class SPacketEntityHeadLook implements Packet { private int entityId; private byte yaw; - public S19PacketEntityHeadLook() + public SPacketEntityHeadLook() { } - public S19PacketEntityHeadLook(Entity entityIn, byte p_i45214_2_) + public SPacketEntityHeadLook(Entity entityIn, byte p_i45214_2_) { this.entityId = entityIn.getId(); this.yaw = p_i45214_2_; @@ -28,7 +28,7 @@ public class S19PacketEntityHeadLook implements Packet */ public void readPacketData(PacketBuffer buf) throws IOException { - this.entityId = buf.readVarIntFromBuffer(); + this.entityId = buf.readVarInt(); this.yaw = buf.readByte(); } @@ -37,7 +37,7 @@ public class S19PacketEntityHeadLook implements Packet */ public void writePacketData(PacketBuffer buf) throws IOException { - buf.writeVarIntToBuffer(this.entityId); + buf.writeVarInt(this.entityId); buf.writeByte(this.yaw); } diff --git a/common/src/common/packet/SPacketEntityLook.java b/common/src/common/packet/SPacketEntityLook.java new file mode 100644 index 0000000..e9ffbb0 --- /dev/null +++ b/common/src/common/packet/SPacketEntityLook.java @@ -0,0 +1,38 @@ +package common.packet; + +import java.io.IOException; + +import common.network.PacketBuffer; + +public class SPacketEntityLook extends SPacketEntity +{ + public SPacketEntityLook() + { + this.rotation = true; + } + + public SPacketEntityLook(int entityIdIn, byte yawIn, byte pitchIn, boolean onGroundIn) + { + super(entityIdIn); + this.yaw = yawIn; + this.pitch = pitchIn; + this.rotation = true; + this.onGround = onGroundIn; + } + + public void readPacketData(PacketBuffer buf) throws IOException + { + super.readPacketData(buf); + this.yaw = buf.readByte(); + this.pitch = buf.readByte(); + this.onGround = buf.readBoolean(); + } + + public void writePacketData(PacketBuffer buf) throws IOException + { + super.writePacketData(buf); + buf.writeByte(this.yaw); + buf.writeByte(this.pitch); + buf.writeBoolean(this.onGround); + } +} \ No newline at end of file diff --git a/common/src/common/packet/SPacketEntityLookMove.java b/common/src/common/packet/SPacketEntityLookMove.java new file mode 100644 index 0000000..878aa46 --- /dev/null +++ b/common/src/common/packet/SPacketEntityLookMove.java @@ -0,0 +1,47 @@ +package common.packet; + +import java.io.IOException; + +import common.network.PacketBuffer; + +public class SPacketEntityLookMove extends SPacketEntity +{ + public SPacketEntityLookMove() + { + this.rotation = true; + } + + public SPacketEntityLookMove(int p_i45973_1_, byte p_i45973_2_, byte p_i45973_3_, byte p_i45973_4_, byte p_i45973_5_, byte p_i45973_6_, boolean p_i45973_7_) + { + super(p_i45973_1_); + this.posX = p_i45973_2_; + this.posY = p_i45973_3_; + this.posZ = p_i45973_4_; + this.yaw = p_i45973_5_; + this.pitch = p_i45973_6_; + this.onGround = p_i45973_7_; + this.rotation = true; + } + + public void readPacketData(PacketBuffer buf) throws IOException + { + super.readPacketData(buf); + this.posX = buf.readByte(); + this.posY = buf.readByte(); + this.posZ = buf.readByte(); + this.yaw = buf.readByte(); + this.pitch = buf.readByte(); + this.onGround = buf.readBoolean(); + } + + public void writePacketData(PacketBuffer buf) throws IOException + { + super.writePacketData(buf); + buf.writeByte(this.posX); + buf.writeByte(this.posY); + buf.writeByte(this.posZ); + buf.writeByte(this.yaw); + buf.writeByte(this.pitch); + buf.writeBoolean(this.onGround); + } +} \ No newline at end of file diff --git a/common/src/common/packet/S1CPacketEntityMetadata.java b/common/src/common/packet/SPacketEntityMetadata.java similarity index 82% rename from common/src/common/packet/S1CPacketEntityMetadata.java rename to common/src/common/packet/SPacketEntityMetadata.java index 645e1a2..fc748e1 100755 --- a/common/src/common/packet/S1CPacketEntityMetadata.java +++ b/common/src/common/packet/SPacketEntityMetadata.java @@ -8,16 +8,16 @@ import common.network.IClientPlayer; import common.network.Packet; import common.network.PacketBuffer; -public class S1CPacketEntityMetadata implements Packet +public class SPacketEntityMetadata implements Packet { private int entityId; private List field_149378_b; - public S1CPacketEntityMetadata() + public SPacketEntityMetadata() { } - public S1CPacketEntityMetadata(int entityIdIn, DataWatcher p_i45217_2_, boolean p_i45217_3_) + public SPacketEntityMetadata(int entityIdIn, DataWatcher p_i45217_2_, boolean p_i45217_3_) { this.entityId = entityIdIn; @@ -36,7 +36,7 @@ public class S1CPacketEntityMetadata implements Packet */ public void readPacketData(PacketBuffer buf) throws IOException { - this.entityId = buf.readVarIntFromBuffer(); + this.entityId = buf.readVarInt(); this.field_149378_b = DataWatcher.readWatchedListFromPacketBuffer(buf); } @@ -45,7 +45,7 @@ public class S1CPacketEntityMetadata implements Packet */ public void writePacketData(PacketBuffer buf) throws IOException { - buf.writeVarIntToBuffer(this.entityId); + buf.writeVarInt(this.entityId); DataWatcher.writeWatchedListToPacketBuffer(this.field_149378_b, buf); } diff --git a/common/src/common/packet/S20PacketEntityProperties.java b/common/src/common/packet/SPacketEntityProperties.java similarity index 72% rename from common/src/common/packet/S20PacketEntityProperties.java rename to common/src/common/packet/SPacketEntityProperties.java index f3ca49a..2c6c11f 100755 --- a/common/src/common/packet/S20PacketEntityProperties.java +++ b/common/src/common/packet/SPacketEntityProperties.java @@ -11,22 +11,22 @@ import common.network.IClientPlayer; import common.network.Packet; import common.network.PacketBuffer; -public class S20PacketEntityProperties implements Packet +public class SPacketEntityProperties implements Packet { private int entityId; - private final List field_149444_b = Lists.newArrayList(); + private final List field_149444_b = Lists.newArrayList(); - public S20PacketEntityProperties() + public SPacketEntityProperties() { } - public S20PacketEntityProperties(int entityIdIn, Collection p_i45236_2_) + public SPacketEntityProperties(int entityIdIn, Collection p_i45236_2_) { this.entityId = entityIdIn; for (AttributeInstance iattributeinstance : p_i45236_2_) { - this.field_149444_b.add(new S20PacketEntityProperties.Snapshot(iattributeinstance.getAttribute().getUnlocalizedName(), iattributeinstance.getBaseValue(), iattributeinstance.getModifiers())); + this.field_149444_b.add(new SPacketEntityProperties.Snapshot(iattributeinstance.getAttribute().getUnlocalizedName(), iattributeinstance.getBaseValue(), iattributeinstance.getModifiers())); } } @@ -35,15 +35,15 @@ public class S20PacketEntityProperties implements Packet */ public void readPacketData(PacketBuffer buf) throws IOException { - this.entityId = buf.readVarIntFromBuffer(); + this.entityId = buf.readVarInt(); int i = buf.readInt(); for (int j = 0; j < i; ++j) { - String s = buf.readStringFromBuffer(64); + String s = buf.readString(64); double d0 = buf.readDouble(); List list = Lists.newArrayList(); - int k = buf.readVarIntFromBuffer(); + int k = buf.readVarInt(); for (int l = 0; l < k; ++l) { @@ -51,7 +51,7 @@ public class S20PacketEntityProperties implements Packet list.add(new AttributeModifier(id, "Unknown synced attribute modifier", buf.readDouble(), buf.readBoolean())); } - this.field_149444_b.add(new S20PacketEntityProperties.Snapshot(s, d0, list)); + this.field_149444_b.add(new SPacketEntityProperties.Snapshot(s, d0, list)); } } @@ -60,14 +60,14 @@ public class S20PacketEntityProperties implements Packet */ public void writePacketData(PacketBuffer buf) throws IOException { - buf.writeVarIntToBuffer(this.entityId); + buf.writeVarInt(this.entityId); buf.writeInt(this.field_149444_b.size()); - for (S20PacketEntityProperties.Snapshot s20packetentityproperties$snapshot : this.field_149444_b) + for (SPacketEntityProperties.Snapshot s20packetentityproperties$snapshot : this.field_149444_b) { buf.writeString(s20packetentityproperties$snapshot.func_151409_a()); buf.writeDouble(s20packetentityproperties$snapshot.func_151410_b()); - buf.writeVarIntToBuffer(s20packetentityproperties$snapshot.func_151408_c().size()); + buf.writeVarInt(s20packetentityproperties$snapshot.func_151408_c().size()); for (AttributeModifier attributemodifier : s20packetentityproperties$snapshot.func_151408_c()) { @@ -91,7 +91,7 @@ public class S20PacketEntityProperties implements Packet return this.entityId; } - public List func_149441_d() + public List func_149441_d() { return this.field_149444_b; } diff --git a/common/src/common/packet/SPacketEntityRelMove.java b/common/src/common/packet/SPacketEntityRelMove.java new file mode 100644 index 0000000..4c5a9fa --- /dev/null +++ b/common/src/common/packet/SPacketEntityRelMove.java @@ -0,0 +1,39 @@ +package common.packet; + +import java.io.IOException; + +import common.network.PacketBuffer; + +public class SPacketEntityRelMove extends SPacketEntity +{ + public SPacketEntityRelMove() + { + } + + public SPacketEntityRelMove(int entityIdIn, byte x, byte y, byte z, boolean onGroundIn) + { + super(entityIdIn); + this.posX = x; + this.posY = y; + this.posZ = z; + this.onGround = onGroundIn; + } + + public void readPacketData(PacketBuffer buf) throws IOException + { + super.readPacketData(buf); + this.posX = buf.readByte(); + this.posY = buf.readByte(); + this.posZ = buf.readByte(); + this.onGround = buf.readBoolean(); + } + + public void writePacketData(PacketBuffer buf) throws IOException + { + super.writePacketData(buf); + buf.writeByte(this.posX); + buf.writeByte(this.posY); + buf.writeByte(this.posZ); + buf.writeBoolean(this.onGround); + } +} \ No newline at end of file diff --git a/common/src/common/packet/S1APacketEntityStatus.java b/common/src/common/packet/SPacketEntityStatus.java similarity index 87% rename from common/src/common/packet/S1APacketEntityStatus.java rename to common/src/common/packet/SPacketEntityStatus.java index 1775cec..6c201c1 100755 --- a/common/src/common/packet/S1APacketEntityStatus.java +++ b/common/src/common/packet/SPacketEntityStatus.java @@ -8,16 +8,16 @@ import common.network.Packet; import common.network.PacketBuffer; import common.world.World; -public class S1APacketEntityStatus implements Packet +public class SPacketEntityStatus implements Packet { private int entityId; private byte logicOpcode; - public S1APacketEntityStatus() + public SPacketEntityStatus() { } - public S1APacketEntityStatus(Entity entityIn, byte opCodeIn) + public SPacketEntityStatus(Entity entityIn, byte opCodeIn) { this.entityId = entityIn.getId(); this.logicOpcode = opCodeIn; diff --git a/common/src/common/packet/S18PacketEntityTeleport.java b/common/src/common/packet/SPacketEntityTeleport.java similarity index 86% rename from common/src/common/packet/S18PacketEntityTeleport.java rename to common/src/common/packet/SPacketEntityTeleport.java index 67f4118..204fa21 100755 --- a/common/src/common/packet/S18PacketEntityTeleport.java +++ b/common/src/common/packet/SPacketEntityTeleport.java @@ -8,7 +8,7 @@ import common.network.Packet; import common.network.PacketBuffer; import common.util.ExtMath; -public class S18PacketEntityTeleport implements Packet +public class SPacketEntityTeleport implements Packet { private int entityId; private int posX; @@ -18,11 +18,11 @@ public class S18PacketEntityTeleport implements Packet private byte pitch; private boolean onGround; - public S18PacketEntityTeleport() + public SPacketEntityTeleport() { } - public S18PacketEntityTeleport(Entity entityIn) + public SPacketEntityTeleport(Entity entityIn) { this.entityId = entityIn.getId(); this.posX = ExtMath.floord(entityIn.posX * 32.0D); @@ -33,7 +33,7 @@ public class S18PacketEntityTeleport implements Packet this.onGround = entityIn.onGround; } - public S18PacketEntityTeleport(int entityIdIn, int posXIn, int posYIn, int posZIn, byte yawIn, byte pitchIn, boolean onGroundIn) + public SPacketEntityTeleport(int entityIdIn, int posXIn, int posYIn, int posZIn, byte yawIn, byte pitchIn, boolean onGroundIn) { this.entityId = entityIdIn; this.posX = posXIn; @@ -49,7 +49,7 @@ public class S18PacketEntityTeleport implements Packet */ public void readPacketData(PacketBuffer buf) throws IOException { - this.entityId = buf.readVarIntFromBuffer(); + this.entityId = buf.readVarInt(); this.posX = buf.readInt(); this.posY = buf.readInt(); this.posZ = buf.readInt(); @@ -63,7 +63,7 @@ public class S18PacketEntityTeleport implements Packet */ public void writePacketData(PacketBuffer buf) throws IOException { - buf.writeVarIntToBuffer(this.entityId); + buf.writeVarInt(this.entityId); buf.writeInt(this.posX); buf.writeInt(this.posY); buf.writeInt(this.posZ); diff --git a/common/src/common/packet/SPacketEntityVelocity.java b/common/src/common/packet/SPacketEntityVelocity.java index 8b6520c..60818b0 100755 --- a/common/src/common/packet/SPacketEntityVelocity.java +++ b/common/src/common/packet/SPacketEntityVelocity.java @@ -68,7 +68,7 @@ public class SPacketEntityVelocity implements Packet */ public void readPacketData(PacketBuffer buf) throws IOException { - this.entityID = buf.readVarIntFromBuffer(); + this.entityID = buf.readVarInt(); this.motionX = buf.readShort(); this.motionY = buf.readShort(); this.motionZ = buf.readShort(); @@ -79,7 +79,7 @@ public class SPacketEntityVelocity implements Packet */ public void writePacketData(PacketBuffer buf) throws IOException { - buf.writeVarIntToBuffer(this.entityID); + buf.writeVarInt(this.entityID); buf.writeShort(this.motionX); buf.writeShort(this.motionY); buf.writeShort(this.motionZ); diff --git a/common/src/common/packet/S27PacketExplosion.java b/common/src/common/packet/SPacketExplosion.java similarity index 93% rename from common/src/common/packet/S27PacketExplosion.java rename to common/src/common/packet/SPacketExplosion.java index 85f90ee..d9fa7cf 100755 --- a/common/src/common/packet/S27PacketExplosion.java +++ b/common/src/common/packet/SPacketExplosion.java @@ -11,7 +11,7 @@ import common.network.PacketBuffer; import common.util.BlockPos; import common.util.Vec3; -public class S27PacketExplosion implements Packet +public class SPacketExplosion implements Packet { private double posX; private double posY; @@ -23,11 +23,11 @@ public class S27PacketExplosion implements Packet private float field_149159_h; private boolean altSound; - public S27PacketExplosion() + public SPacketExplosion() { } - public S27PacketExplosion(double p_i45193_1_, double y, double z, float strengthIn, List affectedBlocksIn, Vec3 p_i45193_9_, boolean altSound) + public SPacketExplosion(double p_i45193_1_, double y, double z, float strengthIn, List affectedBlocksIn, Vec3 p_i45193_9_, boolean altSound) { this.posX = p_i45193_1_; this.posY = y; diff --git a/common/src/common/packet/SPacketJoinGame.java b/common/src/common/packet/SPacketJoinGame.java index 1f452fd..ffef6cc 100755 --- a/common/src/common/packet/SPacketJoinGame.java +++ b/common/src/common/packet/SPacketJoinGame.java @@ -26,14 +26,14 @@ public class SPacketJoinGame implements Packet { public void readPacketData(PacketBuffer buf) throws IOException { this.entityId = buf.readInt(); - this.dimension = buf.readNBTTagCompoundFromBuffer(); + this.dimension = buf.readTag(); this.type = buf.readUnsignedShort(); this.editor = buf.readBoolean(); } public void writePacketData(PacketBuffer buf) throws IOException { buf.writeInt(this.entityId); - buf.writeNBTTagCompoundToBuffer(this.dimension); + buf.writeTag(this.dimension); buf.writeShort(this.type & 65535); buf.writeBoolean(this.editor); } diff --git a/common/src/common/packet/SPacketLoading.java b/common/src/common/packet/SPacketLoading.java index 4daa761..2a090f9 100644 --- a/common/src/common/packet/SPacketLoading.java +++ b/common/src/common/packet/SPacketLoading.java @@ -29,10 +29,10 @@ public class SPacketLoading implements Packet { } public void readPacketData(PacketBuffer buf) throws IOException { - this.message = buf.readStringFromBuffer(128); + this.message = buf.readString(128); this.message = this.message != null && this.message.isEmpty() ? null : this.message; if(this.message == null) { - this.task = buf.readStringFromBuffer(128); + this.task = buf.readString(128); this.task = this.task != null && this.task.isEmpty() ? null : this.task; this.total = buf.readInt(); this.progress = buf.readInt(); diff --git a/common/src/common/packet/SPacketMapChunkBulk.java b/common/src/common/packet/SPacketMapChunkBulk.java index 4ba19d2..8adceef 100755 --- a/common/src/common/packet/SPacketMapChunkBulk.java +++ b/common/src/common/packet/SPacketMapChunkBulk.java @@ -30,7 +30,7 @@ public class SPacketMapChunkBulk implements Packet public void readPacketData(PacketBuffer buf) throws IOException { this.sky = buf.readBoolean(); - int i = buf.readVarIntFromBuffer(); + int i = buf.readVarInt(); this.xPositions = new int[i]; this.zPositions = new int[i]; this.chunksData = new SPacketChunkData.Extracted[i]; @@ -40,9 +40,9 @@ public class SPacketMapChunkBulk implements Packet this.xPositions[j] = buf.readInt(); this.zPositions[j] = buf.readInt(); this.chunksData[j] = new SPacketChunkData.Extracted(); - this.chunksData[j].extend = new int[buf.readVarIntFromBuffer()]; + this.chunksData[j].extend = new int[buf.readVarInt()]; for(int z = 0; z < this.chunksData[j].extend.length; z++) { - this.chunksData[j].extend[z] = buf.readVarIntFromBuffer(); + this.chunksData[j].extend[z] = buf.readVarInt(); } this.chunksData[j].data = new byte[SPacketChunkData.getSize(this.chunksData[j].extend.length, this.sky, true)]; } @@ -59,15 +59,15 @@ public class SPacketMapChunkBulk implements Packet public void writePacketData(PacketBuffer buf) throws IOException { buf.writeBoolean(this.sky); - buf.writeVarIntToBuffer(this.chunksData.length); + buf.writeVarInt(this.chunksData.length); for (int i = 0; i < this.xPositions.length; ++i) { buf.writeInt(this.xPositions[i]); buf.writeInt(this.zPositions[i]); - buf.writeVarIntToBuffer(this.chunksData[i].extend.length); + buf.writeVarInt(this.chunksData[i].extend.length); for(int z = 0; z < this.chunksData[i].extend.length; z++) { - buf.writeVarIntToBuffer(this.chunksData[i].extend[z]); + buf.writeVarInt(this.chunksData[i].extend[z]); } } diff --git a/common/src/common/packet/SPacketMessage.java b/common/src/common/packet/SPacketMessage.java index 3832c29..4b72178 100755 --- a/common/src/common/packet/SPacketMessage.java +++ b/common/src/common/packet/SPacketMessage.java @@ -23,7 +23,7 @@ public class SPacketMessage implements Packet { } public void readPacketData(PacketBuffer buf) throws IOException { - this.message = buf.readStringFromBuffer(32767); + this.message = buf.readString(32767); this.type = buf.readEnumValue(Type.class); } diff --git a/common/src/common/packet/SPacketMultiBlockChange.java b/common/src/common/packet/SPacketMultiBlockChange.java index 6694b98..df86ebb 100755 --- a/common/src/common/packet/SPacketMultiBlockChange.java +++ b/common/src/common/packet/SPacketMultiBlockChange.java @@ -35,11 +35,11 @@ public class SPacketMultiBlockChange implements Packet public void readPacketData(PacketBuffer buf) throws IOException { this.chunkPosCoord = new ChunkPos(buf.readInt(), buf.readInt()); - this.changedBlocks = new SPacketMultiBlockChange.BlockUpdateData[buf.readVarIntFromBuffer()]; + this.changedBlocks = new SPacketMultiBlockChange.BlockUpdateData[buf.readVarInt()]; for (int i = 0; i < this.changedBlocks.length; ++i) { - this.changedBlocks[i] = new SPacketMultiBlockChange.BlockUpdateData(buf.readLong(), (State)BlockRegistry.STATEMAP.getByValue(buf.readVarIntFromBuffer())); + this.changedBlocks[i] = new SPacketMultiBlockChange.BlockUpdateData(buf.readLong(), (State)BlockRegistry.STATEMAP.getByValue(buf.readVarInt())); } } @@ -50,12 +50,12 @@ public class SPacketMultiBlockChange implements Packet { buf.writeInt(this.chunkPosCoord.x); buf.writeInt(this.chunkPosCoord.z); - buf.writeVarIntToBuffer(this.changedBlocks.length); + buf.writeVarInt(this.changedBlocks.length); for (SPacketMultiBlockChange.BlockUpdateData s22packetmultiblockchange$blockupdatedata : this.changedBlocks) { buf.writeLong(s22packetmultiblockchange$blockupdatedata.getRawPos()); - buf.writeVarIntToBuffer(BlockRegistry.STATEMAP.get(s22packetmultiblockchange$blockupdatedata.getBlockState())); + buf.writeVarInt(BlockRegistry.STATEMAP.get(s22packetmultiblockchange$blockupdatedata.getBlockState())); } } diff --git a/common/src/common/packet/S2DPacketOpenWindow.java b/common/src/common/packet/SPacketOpenWindow.java similarity index 79% rename from common/src/common/packet/S2DPacketOpenWindow.java rename to common/src/common/packet/SPacketOpenWindow.java index 6fb2370..c66e944 100755 --- a/common/src/common/packet/S2DPacketOpenWindow.java +++ b/common/src/common/packet/SPacketOpenWindow.java @@ -7,7 +7,7 @@ import common.network.Packet; import common.network.PacketBuffer; import common.util.BlockPos; -public class S2DPacketOpenWindow implements Packet +public class SPacketOpenWindow implements Packet { private int windowId; private String inventoryType; @@ -16,16 +16,16 @@ public class S2DPacketOpenWindow implements Packet private int entityId; private BlockPos tilePos; - public S2DPacketOpenWindow() + public SPacketOpenWindow() { } - public S2DPacketOpenWindow(int incomingWindowId, String incomingWindowTitle, String windowTitleIn) + public SPacketOpenWindow(int incomingWindowId, String incomingWindowTitle, String windowTitleIn) { this(incomingWindowId, incomingWindowTitle, windowTitleIn, 0); } - public S2DPacketOpenWindow(int windowIdIn, String guiId, String windowTitleIn, int slotCountIn) + public SPacketOpenWindow(int windowIdIn, String guiId, String windowTitleIn, int slotCountIn) { this.windowId = windowIdIn; this.inventoryType = guiId; @@ -33,13 +33,13 @@ public class S2DPacketOpenWindow implements Packet this.slotCount = slotCountIn; } - public S2DPacketOpenWindow(int windowIdIn, String guiId, String windowTitleIn, int slotCountIn, int incomingEntityId) + public SPacketOpenWindow(int windowIdIn, String guiId, String windowTitleIn, int slotCountIn, int incomingEntityId) { this(windowIdIn, guiId, windowTitleIn, slotCountIn); this.entityId = incomingEntityId; } - public S2DPacketOpenWindow(int windowIdIn, String guiId, String windowTitleIn, int slotCountIn, BlockPos incomingTilePos) + public SPacketOpenWindow(int windowIdIn, String guiId, String windowTitleIn, int slotCountIn, BlockPos incomingTilePos) { this(windowIdIn, guiId, windowTitleIn, slotCountIn); this.tilePos = incomingTilePos; @@ -59,8 +59,8 @@ public class S2DPacketOpenWindow implements Packet public void readPacketData(PacketBuffer buf) throws IOException { this.windowId = buf.readUnsignedByte(); - this.inventoryType = buf.readStringFromBuffer(32); - this.windowTitle = buf.readStringFromBuffer(256); + this.inventoryType = buf.readString(32); + this.windowTitle = buf.readString(256); this.slotCount = buf.readUnsignedByte(); if (this.inventoryType.equals("EntityHorse")) diff --git a/common/src/common/packet/S2APacketParticles.java b/common/src/common/packet/SPacketParticles.java similarity index 90% rename from common/src/common/packet/S2APacketParticles.java rename to common/src/common/packet/SPacketParticles.java index 0d6329c..f2fd4ba 100755 --- a/common/src/common/packet/S2APacketParticles.java +++ b/common/src/common/packet/SPacketParticles.java @@ -7,7 +7,7 @@ import common.network.IClientPlayer; import common.network.Packet; import common.network.PacketBuffer; -public class S2APacketParticles implements Packet +public class SPacketParticles implements Packet { private ParticleType particleType; private float xCoord; @@ -25,11 +25,11 @@ public class S2APacketParticles implements Packet */ private int[] particleArguments; - public S2APacketParticles() + public SPacketParticles() { } - public S2APacketParticles(ParticleType particleTypeIn, boolean longDistanceIn, float x, float y, float z, float xOffsetIn, float yOffset, float zOffset, float particleSpeedIn, int particleCountIn, int[] particleArgumentsIn) + public SPacketParticles(ParticleType particleTypeIn, boolean longDistanceIn, float x, float y, float z, float xOffsetIn, float yOffset, float zOffset, float particleSpeedIn, int particleCountIn, int[] particleArgumentsIn) { this.particleType = particleTypeIn; this.longDistance = longDistanceIn; @@ -70,7 +70,7 @@ public class S2APacketParticles implements Packet for (int j = 0; j < i; ++j) { - this.particleArguments[j] = buf.readVarIntFromBuffer(); + this.particleArguments[j] = buf.readVarInt(); } } @@ -93,7 +93,7 @@ public class S2APacketParticles implements Packet for (int j = 0; j < i; ++j) { - buf.writeVarIntToBuffer(this.particleArguments[j]); + buf.writeVarInt(this.particleArguments[j]); } } diff --git a/common/src/common/packet/S39PacketPlayerAbilities.java b/common/src/common/packet/SPacketPlayerAbilities.java similarity index 84% rename from common/src/common/packet/S39PacketPlayerAbilities.java rename to common/src/common/packet/SPacketPlayerAbilities.java index 24f0537..d7b7d34 100755 --- a/common/src/common/packet/S39PacketPlayerAbilities.java +++ b/common/src/common/packet/SPacketPlayerAbilities.java @@ -7,14 +7,14 @@ import common.network.IClientPlayer; import common.network.Packet; import common.network.PacketBuffer; -public class S39PacketPlayerAbilities implements Packet { +public class SPacketPlayerAbilities implements Packet { private boolean flying; private boolean noClip; - public S39PacketPlayerAbilities() { + public SPacketPlayerAbilities() { } - public S39PacketPlayerAbilities(EntityNPC capabilities) { + public SPacketPlayerAbilities(EntityNPC capabilities) { this.flying = capabilities.flying; this.noClip = capabilities.noclip; } diff --git a/common/src/common/packet/S38PacketPlayerListItem.java b/common/src/common/packet/SPacketPlayerListItem.java similarity index 70% rename from common/src/common/packet/S38PacketPlayerListItem.java rename to common/src/common/packet/SPacketPlayerListItem.java index f83caa5..2bc0601 100755 --- a/common/src/common/packet/S38PacketPlayerListItem.java +++ b/common/src/common/packet/SPacketPlayerListItem.java @@ -11,36 +11,36 @@ import common.network.IPlayer; import common.network.Packet; import common.network.PacketBuffer; -public class S38PacketPlayerListItem implements Packet { +public class SPacketPlayerListItem implements Packet { private final Map players = Maps.newHashMap(); - public S38PacketPlayerListItem() { + public SPacketPlayerListItem() { } - public S38PacketPlayerListItem(boolean remove, IPlayer... conns) { + public SPacketPlayerListItem(boolean remove, IPlayer... conns) { for(IPlayer conn : conns) { this.players.put(conn.getUser(), remove ? -1 : conn.getLatency()); } } - public S38PacketPlayerListItem(Iterable conns) { + public SPacketPlayerListItem(Iterable conns) { for(IPlayer conn : conns) { this.players.put(((IPlayer)conn).getUser(), ((IPlayer)conn).getLatency()); } } public void readPacketData(PacketBuffer buf) throws IOException { - int n = buf.readVarIntFromBuffer(); + int n = buf.readVarInt(); for(int z = 0; z < n; z++) { - this.players.put(buf.readStringFromBuffer(16), buf.readVarIntFromBuffer()); + this.players.put(buf.readString(16), buf.readVarInt()); } } public void writePacketData(PacketBuffer buf) throws IOException { - buf.writeVarIntToBuffer(this.players.size()); + buf.writeVarInt(this.players.size()); for(Entry data : this.players.entrySet()) { buf.writeString(data.getKey()); - buf.writeVarIntToBuffer(data.getValue()); + buf.writeVarInt(data.getValue()); } } diff --git a/common/src/common/packet/S1EPacketRemoveEntityEffect.java b/common/src/common/packet/SPacketRemoveEntityEffect.java similarity index 79% rename from common/src/common/packet/S1EPacketRemoveEntityEffect.java rename to common/src/common/packet/SPacketRemoveEntityEffect.java index 9cd091e..7a27c9d 100755 --- a/common/src/common/packet/S1EPacketRemoveEntityEffect.java +++ b/common/src/common/packet/SPacketRemoveEntityEffect.java @@ -8,16 +8,16 @@ import common.network.PacketBuffer; import common.potion.Potion; import common.potion.PotionEffect; -public class S1EPacketRemoveEntityEffect implements Packet +public class SPacketRemoveEntityEffect implements Packet { private int entityId; private Potion effectId; - public S1EPacketRemoveEntityEffect() + public SPacketRemoveEntityEffect() { } - public S1EPacketRemoveEntityEffect(int entityIdIn, PotionEffect effect) + public SPacketRemoveEntityEffect(int entityIdIn, PotionEffect effect) { this.entityId = entityIdIn; this.effectId = effect.getPotion(); @@ -28,7 +28,7 @@ public class S1EPacketRemoveEntityEffect implements Packet */ public void readPacketData(PacketBuffer buf) throws IOException { - this.entityId = buf.readVarIntFromBuffer(); + this.entityId = buf.readVarInt(); this.effectId = buf.readEnumValue(Potion.class); } @@ -37,7 +37,7 @@ public class S1EPacketRemoveEntityEffect implements Packet */ public void writePacketData(PacketBuffer buf) throws IOException { - buf.writeVarIntToBuffer(this.entityId); + buf.writeVarInt(this.entityId); buf.writeEnumValue(this.effectId); } diff --git a/common/src/common/packet/SPacketRespawn.java b/common/src/common/packet/SPacketRespawn.java index 3e8d3fd..215269f 100755 --- a/common/src/common/packet/SPacketRespawn.java +++ b/common/src/common/packet/SPacketRespawn.java @@ -32,14 +32,14 @@ public class SPacketRespawn implements Packet public void readPacketData(PacketBuffer buf) throws IOException { - this.dimension = buf.readNBTTagCompoundFromBuffer(); + this.dimension = buf.readTag(); this.type = buf.readUnsignedShort(); this.editor = buf.readBoolean(); } public void writePacketData(PacketBuffer buf) throws IOException { - buf.writeNBTTagCompoundToBuffer(this.dimension); + buf.writeTag(this.dimension); buf.writeShort(this.type & 65535); buf.writeBoolean(this.editor); } diff --git a/common/src/common/packet/SPacketSetExperience.java b/common/src/common/packet/SPacketSetExperience.java index 1b60ca9..b2f2b06 100755 --- a/common/src/common/packet/SPacketSetExperience.java +++ b/common/src/common/packet/SPacketSetExperience.java @@ -29,8 +29,8 @@ public class SPacketSetExperience implements Packet public void readPacketData(PacketBuffer buf) throws IOException { this.progress = buf.readFloat(); - this.level = buf.readVarIntFromBuffer(); - this.totalExperience = buf.readVarIntFromBuffer(); + this.level = buf.readVarInt(); + this.totalExperience = buf.readVarInt(); } /** @@ -39,8 +39,8 @@ public class SPacketSetExperience implements Packet public void writePacketData(PacketBuffer buf) throws IOException { buf.writeFloat(this.progress); - buf.writeVarIntToBuffer(this.level); - buf.writeVarIntToBuffer(this.totalExperience); + buf.writeVarInt(this.level); + buf.writeVarInt(this.totalExperience); } /** diff --git a/common/src/common/packet/S2FPacketSetSlot.java b/common/src/common/packet/SPacketSetSlot.java similarity index 82% rename from common/src/common/packet/S2FPacketSetSlot.java rename to common/src/common/packet/SPacketSetSlot.java index def36be..0eaf219 100755 --- a/common/src/common/packet/S2FPacketSetSlot.java +++ b/common/src/common/packet/SPacketSetSlot.java @@ -7,17 +7,17 @@ import common.network.IClientPlayer; import common.network.Packet; import common.network.PacketBuffer; -public class S2FPacketSetSlot implements Packet +public class SPacketSetSlot implements Packet { private int windowId; private int slot; private ItemStack item; - public S2FPacketSetSlot() + public SPacketSetSlot() { } - public S2FPacketSetSlot(int windowIdIn, int slotIn, ItemStack itemIn) + public SPacketSetSlot(int windowIdIn, int slotIn, ItemStack itemIn) { this.windowId = windowIdIn; this.slot = slotIn; @@ -39,7 +39,7 @@ public class S2FPacketSetSlot implements Packet { this.windowId = buf.readByte(); this.slot = buf.readShort(); - this.item = buf.readItemStackFromBuffer(); + this.item = buf.readItemStack(); } /** @@ -49,7 +49,7 @@ public class S2FPacketSetSlot implements Packet { buf.writeByte(this.windowId); buf.writeShort(this.slot); - buf.writeItemStackToBuffer(this.item); + buf.writeItemStack(this.item); } public int getWindowId() diff --git a/common/src/common/packet/S36PacketSignEditorOpen.java b/common/src/common/packet/SPacketSignEditorOpen.java similarity index 85% rename from common/src/common/packet/S36PacketSignEditorOpen.java rename to common/src/common/packet/SPacketSignEditorOpen.java index 1059d0c..b7b09e9 100755 --- a/common/src/common/packet/S36PacketSignEditorOpen.java +++ b/common/src/common/packet/SPacketSignEditorOpen.java @@ -7,15 +7,15 @@ import common.network.Packet; import common.network.PacketBuffer; import common.util.BlockPos; -public class S36PacketSignEditorOpen implements Packet +public class SPacketSignEditorOpen implements Packet { private BlockPos signPosition; - public S36PacketSignEditorOpen() + public SPacketSignEditorOpen() { } - public S36PacketSignEditorOpen(BlockPos signPositionIn) + public SPacketSignEditorOpen(BlockPos signPositionIn) { this.signPosition = signPositionIn; } diff --git a/common/src/common/packet/SPacketSkin.java b/common/src/common/packet/SPacketSkin.java index 2efdcc9..4cf14f1 100755 --- a/common/src/common/packet/SPacketSkin.java +++ b/common/src/common/packet/SPacketSkin.java @@ -40,7 +40,7 @@ public class SPacketSkin implements Packet public void readPacketData(PacketBuffer buf) throws IOException { - this.id = buf.readVarIntFromBuffer(); + this.id = buf.readVarInt(); // this.model = buf.readEnumValue(ModelType.class); this.texture = buf.readByteArray(); if(this.texture.length == 0) { @@ -53,7 +53,7 @@ public class SPacketSkin implements Packet public void writePacketData(PacketBuffer buf) throws IOException { - buf.writeVarIntToBuffer(this.id); + buf.writeVarInt(this.id); // buf.writeEnumValue(this.model); buf.writeByteArray(this.texture == null ? new byte[0] : this.texture); } diff --git a/common/src/common/packet/S29PacketSoundEffect.java b/common/src/common/packet/SPacketSoundEffect.java similarity index 90% rename from common/src/common/packet/S29PacketSoundEffect.java rename to common/src/common/packet/SPacketSoundEffect.java index c39ca1a..d6ecedf 100755 --- a/common/src/common/packet/S29PacketSoundEffect.java +++ b/common/src/common/packet/SPacketSoundEffect.java @@ -7,7 +7,7 @@ import common.network.IClientPlayer; import common.network.Packet; import common.network.PacketBuffer; -public class S29PacketSoundEffect implements Packet +public class SPacketSoundEffect implements Packet { private SoundEvent sound; private int posX; @@ -15,12 +15,12 @@ public class S29PacketSoundEffect implements Packet private int posZ; private float soundVolume; - public S29PacketSoundEffect() + public SPacketSoundEffect() { this.sound = null; } - public S29PacketSoundEffect(SoundEvent sound, double soundX, double soundY, double soundZ, float volume) + public SPacketSoundEffect(SoundEvent sound, double soundX, double soundY, double soundZ, float volume) { this.sound = sound; if(this.sound == null) { diff --git a/common/src/common/packet/S2CPacketSpawnGlobalEntity.java b/common/src/common/packet/SPacketSpawnGlobalEntity.java similarity index 82% rename from common/src/common/packet/S2CPacketSpawnGlobalEntity.java rename to common/src/common/packet/SPacketSpawnGlobalEntity.java index 4741c44..baf214a 100755 --- a/common/src/common/packet/S2CPacketSpawnGlobalEntity.java +++ b/common/src/common/packet/SPacketSpawnGlobalEntity.java @@ -8,7 +8,7 @@ import common.network.Packet; import common.network.PacketBuffer; import common.util.ExtMath; -public class S2CPacketSpawnGlobalEntity implements Packet +public class SPacketSpawnGlobalEntity implements Packet { private int entityId; private int x; @@ -17,11 +17,11 @@ public class S2CPacketSpawnGlobalEntity implements Packet private int type; private int data; - public S2CPacketSpawnGlobalEntity() + public SPacketSpawnGlobalEntity() { } - public S2CPacketSpawnGlobalEntity(Entity entityIn, int type, int data) + public SPacketSpawnGlobalEntity(Entity entityIn, int type, int data) { this.entityId = entityIn.getId(); this.x = ExtMath.floord(entityIn.posX * 32.0D); @@ -36,12 +36,12 @@ public class S2CPacketSpawnGlobalEntity implements Packet */ public void readPacketData(PacketBuffer buf) throws IOException { - this.entityId = buf.readVarIntFromBuffer(); + this.entityId = buf.readVarInt(); this.type = buf.readByte(); this.x = buf.readInt(); this.y = buf.readInt(); this.z = buf.readInt(); - this.data = buf.readVarIntFromBuffer(); + this.data = buf.readVarInt(); } /** @@ -49,12 +49,12 @@ public class S2CPacketSpawnGlobalEntity implements Packet */ public void writePacketData(PacketBuffer buf) throws IOException { - buf.writeVarIntToBuffer(this.entityId); + buf.writeVarInt(this.entityId); buf.writeByte(this.type); buf.writeInt(this.x); buf.writeInt(this.y); buf.writeInt(this.z); - buf.writeVarIntToBuffer(this.data); + buf.writeVarInt(this.data); } /** diff --git a/common/src/common/packet/SPacketSpawnMob.java b/common/src/common/packet/SPacketSpawnMob.java index b26ba57..5542cb0 100755 --- a/common/src/common/packet/SPacketSpawnMob.java +++ b/common/src/common/packet/SPacketSpawnMob.java @@ -84,7 +84,7 @@ public class SPacketSpawnMob implements Packet public void readPacketData(PacketBuffer buf) throws IOException { - this.entityId = buf.readVarIntFromBuffer(); + this.entityId = buf.readVarInt(); this.type = buf.readUnsignedShort(); this.x = buf.readInt(); this.y = buf.readInt(); @@ -100,7 +100,7 @@ public class SPacketSpawnMob implements Packet public void writePacketData(PacketBuffer buf) throws IOException { - buf.writeVarIntToBuffer(this.entityId); + buf.writeVarInt(this.entityId); buf.writeShort(this.type & 65535); buf.writeInt(this.x); buf.writeInt(this.y); diff --git a/common/src/common/packet/SPacketSpawnObject.java b/common/src/common/packet/SPacketSpawnObject.java index 6af450a..6ae2456 100755 --- a/common/src/common/packet/SPacketSpawnObject.java +++ b/common/src/common/packet/SPacketSpawnObject.java @@ -106,7 +106,7 @@ public class SPacketSpawnObject implements Packet public void readPacketData(PacketBuffer buf) throws IOException { - this.entityId = buf.readVarIntFromBuffer(); + this.entityId = buf.readVarInt(); this.type = buf.readUnsignedShort(); this.x = buf.readInt(); this.y = buf.readInt(); @@ -123,7 +123,7 @@ public class SPacketSpawnObject implements Packet public void writePacketData(PacketBuffer buf) throws IOException { - buf.writeVarIntToBuffer(this.entityId); + buf.writeVarInt(this.entityId); buf.writeShort(this.type & 65535); buf.writeInt(this.x); buf.writeInt(this.y); diff --git a/common/src/common/packet/SPacketSpawnPlayer.java b/common/src/common/packet/SPacketSpawnPlayer.java index 7c1ab02..a12ede6 100755 --- a/common/src/common/packet/SPacketSpawnPlayer.java +++ b/common/src/common/packet/SPacketSpawnPlayer.java @@ -52,7 +52,7 @@ public class SPacketSpawnPlayer implements Packet */ public void readPacketData(PacketBuffer buf) throws IOException { - this.entityId = buf.readVarIntFromBuffer(); + this.entityId = buf.readVarInt(); this.type = buf.readUnsignedShort(); this.x = buf.readInt(); this.y = buf.readInt(); @@ -75,7 +75,7 @@ public class SPacketSpawnPlayer implements Packet */ public void writePacketData(PacketBuffer buf) throws IOException { - buf.writeVarIntToBuffer(this.entityId); + buf.writeVarInt(this.entityId); buf.writeShort(this.type & 65535); buf.writeInt(this.x); buf.writeInt(this.y); diff --git a/common/src/common/packet/S3APacketTabComplete.java b/common/src/common/packet/SPacketTabComplete.java similarity index 74% rename from common/src/common/packet/S3APacketTabComplete.java rename to common/src/common/packet/SPacketTabComplete.java index 76beea3..88ef0e2 100755 --- a/common/src/common/packet/S3APacketTabComplete.java +++ b/common/src/common/packet/SPacketTabComplete.java @@ -6,15 +6,15 @@ import common.network.IClientPlayer; import common.network.Packet; import common.network.PacketBuffer; -public class S3APacketTabComplete implements Packet +public class SPacketTabComplete implements Packet { private String[] matches; - public S3APacketTabComplete() + public SPacketTabComplete() { } - public S3APacketTabComplete(String[] matchesIn) + public SPacketTabComplete(String[] matchesIn) { this.matches = matchesIn; } @@ -24,11 +24,11 @@ public class S3APacketTabComplete implements Packet */ public void readPacketData(PacketBuffer buf) throws IOException { - this.matches = new String[buf.readVarIntFromBuffer()]; + this.matches = new String[buf.readVarInt()]; for (int i = 0; i < this.matches.length; ++i) { - this.matches[i] = buf.readStringFromBuffer(32767); + this.matches[i] = buf.readString(32767); } } @@ -37,7 +37,7 @@ public class S3APacketTabComplete implements Packet */ public void writePacketData(PacketBuffer buf) throws IOException { - buf.writeVarIntToBuffer(this.matches.length); + buf.writeVarInt(this.matches.length); for (String s : this.matches) { diff --git a/common/src/common/packet/SPacketTimeUpdate.java b/common/src/common/packet/SPacketTimeUpdate.java index 3885c3a..4ed2a98 100755 --- a/common/src/common/packet/SPacketTimeUpdate.java +++ b/common/src/common/packet/SPacketTimeUpdate.java @@ -20,7 +20,7 @@ public class SPacketTimeUpdate implements Packet { public void readPacketData(PacketBuffer buf) throws IOException { this.worldTime = buf.readLong(); - this.serverInfo = buf.readStringFromBuffer(512); + this.serverInfo = buf.readString(512); } public void writePacketData(PacketBuffer buf) throws IOException { diff --git a/common/src/common/packet/SPacketTrades.java b/common/src/common/packet/SPacketTrades.java index 94a5e65..2b1f8fb 100755 --- a/common/src/common/packet/SPacketTrades.java +++ b/common/src/common/packet/SPacketTrades.java @@ -35,13 +35,13 @@ public class SPacketTrades implements Packet for (int j = 0; j < i; ++j) { - ItemStack itemstack = buf.readItemStackFromBuffer(); - ItemStack itemstack1 = buf.readItemStackFromBuffer(); + ItemStack itemstack = buf.readItemStack(); + ItemStack itemstack1 = buf.readItemStack(); ItemStack itemstack2 = null; if (buf.readBoolean()) { - itemstack2 = buf.readItemStackFromBuffer(); + itemstack2 = buf.readItemStack(); } // boolean flag = buf.readBoolean(); @@ -69,14 +69,14 @@ public class SPacketTrades implements Packet for (int i = 0; i < this.recipes.size(); ++i) { MerchantRecipe merchantrecipe = (MerchantRecipe)this.recipes.get(i); - buf.writeItemStackToBuffer(merchantrecipe.getItemToBuy()); - buf.writeItemStackToBuffer(merchantrecipe.getItemToSell()); + buf.writeItemStack(merchantrecipe.getItemToBuy()); + buf.writeItemStack(merchantrecipe.getItemToSell()); ItemStack itemstack = merchantrecipe.getSecondItemToBuy(); buf.writeBoolean(itemstack != null); if (itemstack != null) { - buf.writeItemStackToBuffer(itemstack); + buf.writeItemStack(itemstack); } // buf.writeBoolean(merchantrecipe.isRecipeDisabled()); diff --git a/common/src/common/packet/S43PacketUpdateEntityNBT.java b/common/src/common/packet/SPacketUpdateEntityNBT.java similarity index 72% rename from common/src/common/packet/S43PacketUpdateEntityNBT.java rename to common/src/common/packet/SPacketUpdateEntityNBT.java index ad56eac..d68a4d8 100755 --- a/common/src/common/packet/S43PacketUpdateEntityNBT.java +++ b/common/src/common/packet/SPacketUpdateEntityNBT.java @@ -9,16 +9,16 @@ import common.network.Packet; import common.network.PacketBuffer; import common.world.World; -public class S43PacketUpdateEntityNBT implements Packet +public class SPacketUpdateEntityNBT implements Packet { private int entityId; private NBTTagCompound tagCompound; - public S43PacketUpdateEntityNBT() + public SPacketUpdateEntityNBT() { } - public S43PacketUpdateEntityNBT(int entityIdIn, NBTTagCompound tagCompoundIn) + public SPacketUpdateEntityNBT(int entityIdIn, NBTTagCompound tagCompoundIn) { this.entityId = entityIdIn; this.tagCompound = tagCompoundIn; @@ -29,8 +29,8 @@ public class S43PacketUpdateEntityNBT implements Packet */ public void readPacketData(PacketBuffer buf) throws IOException { - this.entityId = buf.readVarIntFromBuffer(); - this.tagCompound = buf.readNBTTagCompoundFromBuffer(); + this.entityId = buf.readVarInt(); + this.tagCompound = buf.readTag(); } /** @@ -38,8 +38,8 @@ public class S43PacketUpdateEntityNBT implements Packet */ public void writePacketData(PacketBuffer buf) throws IOException { - buf.writeVarIntToBuffer(this.entityId); - buf.writeNBTTagCompoundToBuffer(this.tagCompound); + buf.writeVarInt(this.entityId); + buf.writeTag(this.tagCompound); } /** diff --git a/common/src/common/packet/S33PacketUpdateSign.java b/common/src/common/packet/SPacketUpdateSign.java similarity index 88% rename from common/src/common/packet/S33PacketUpdateSign.java rename to common/src/common/packet/SPacketUpdateSign.java index 8c75e28..25a586b 100755 --- a/common/src/common/packet/S33PacketUpdateSign.java +++ b/common/src/common/packet/SPacketUpdateSign.java @@ -8,18 +8,18 @@ import common.network.PacketBuffer; import common.util.BlockPos; import common.world.World; -public class S33PacketUpdateSign implements Packet +public class SPacketUpdateSign implements Packet { private World world; private BlockPos blockPos; private String[] lines; // private String command; - public S33PacketUpdateSign() + public SPacketUpdateSign() { } - public S33PacketUpdateSign(World worldIn, BlockPos blockPosIn, String[] linesIn) + public SPacketUpdateSign(World worldIn, BlockPos blockPosIn, String[] linesIn) { this.world = worldIn; this.blockPos = blockPosIn; @@ -37,7 +37,7 @@ public class S33PacketUpdateSign implements Packet for (int i = 0; i < 4; ++i) { - this.lines[i] = buf.readStringFromBuffer(64); + this.lines[i] = buf.readString(64); } // this.command = buf.readStringFromBuffer(1024); diff --git a/common/src/common/packet/S35PacketUpdateTileEntity.java b/common/src/common/packet/SPacketUpdateTileEntity.java similarity index 84% rename from common/src/common/packet/S35PacketUpdateTileEntity.java rename to common/src/common/packet/SPacketUpdateTileEntity.java index dc1f0c3..99cd78d 100755 --- a/common/src/common/packet/S35PacketUpdateTileEntity.java +++ b/common/src/common/packet/SPacketUpdateTileEntity.java @@ -10,17 +10,17 @@ import common.network.PacketBuffer; import common.tileentity.TileEntity; import common.util.BlockPos; -public class S35PacketUpdateTileEntity implements Packet +public class SPacketUpdateTileEntity implements Packet { private BlockPos blockPos; private int type; private NBTTagCompound nbt; - public S35PacketUpdateTileEntity() + public SPacketUpdateTileEntity() { } - public S35PacketUpdateTileEntity(TileEntity tile) + public SPacketUpdateTileEntity(TileEntity tile) { this.blockPos = tile.getPos(); this.type = TileRegistry.CLASS_TO_ID.get(tile.getClass()); @@ -34,7 +34,7 @@ public class S35PacketUpdateTileEntity implements Packet { this.blockPos = buf.readBlockPos(); this.type = buf.readUnsignedByte(); - this.nbt = buf.readNBTTagCompoundFromBuffer(); + this.nbt = buf.readTag(); } /** @@ -44,7 +44,7 @@ public class S35PacketUpdateTileEntity implements Packet { buf.writeBlockPos(this.blockPos); buf.writeByte((byte)this.type); - buf.writeNBTTagCompoundToBuffer(this.nbt); + buf.writeTag(this.nbt); } /** diff --git a/common/src/common/packet/S30PacketWindowItems.java b/common/src/common/packet/SPacketWindowItems.java similarity index 84% rename from common/src/common/packet/S30PacketWindowItems.java rename to common/src/common/packet/SPacketWindowItems.java index c3e37f3..ad38bca 100755 --- a/common/src/common/packet/S30PacketWindowItems.java +++ b/common/src/common/packet/SPacketWindowItems.java @@ -8,16 +8,16 @@ import common.network.IClientPlayer; import common.network.Packet; import common.network.PacketBuffer; -public class S30PacketWindowItems implements Packet +public class SPacketWindowItems implements Packet { private int windowId; private ItemStack[] itemStacks; - public S30PacketWindowItems() + public SPacketWindowItems() { } - public S30PacketWindowItems(int windowIdIn, List p_i45186_2_) + public SPacketWindowItems(int windowIdIn, List p_i45186_2_) { this.windowId = windowIdIn; this.itemStacks = new ItemStack[p_i45186_2_.size()]; @@ -40,7 +40,7 @@ public class S30PacketWindowItems implements Packet for (int j = 0; j < i; ++j) { - this.itemStacks[j] = buf.readItemStackFromBuffer(); + this.itemStacks[j] = buf.readItemStack(); } } @@ -54,7 +54,7 @@ public class S30PacketWindowItems implements Packet for (ItemStack itemstack : this.itemStacks) { - buf.writeItemStackToBuffer(itemstack); + buf.writeItemStack(itemstack); } } diff --git a/common/src/common/packet/S31PacketWindowProperty.java b/common/src/common/packet/SPacketWindowProperty.java similarity index 87% rename from common/src/common/packet/S31PacketWindowProperty.java rename to common/src/common/packet/SPacketWindowProperty.java index e8b02ff..ef546c5 100755 --- a/common/src/common/packet/S31PacketWindowProperty.java +++ b/common/src/common/packet/SPacketWindowProperty.java @@ -6,17 +6,17 @@ import common.network.IClientPlayer; import common.network.Packet; import common.network.PacketBuffer; -public class S31PacketWindowProperty implements Packet +public class SPacketWindowProperty implements Packet { private int windowId; private int varIndex; private int varValue; - public S31PacketWindowProperty() + public SPacketWindowProperty() { } - public S31PacketWindowProperty(int windowIdIn, int varIndexIn, int varValueIn) + public SPacketWindowProperty(int windowIdIn, int varIndexIn, int varValueIn) { this.windowId = windowIdIn; this.varIndex = varIndexIn; diff --git a/common/src/common/packet/SPacketWorld.java b/common/src/common/packet/SPacketWorld.java index 17ff613..6b79517 100755 --- a/common/src/common/packet/SPacketWorld.java +++ b/common/src/common/packet/SPacketWorld.java @@ -26,14 +26,14 @@ public class SPacketWorld implements Packet { public void readPacketData(PacketBuffer buf) throws IOException { this.gravity = buf.readFloat(); - this.timeFactor = buf.readVarIntFromBuffer(); + this.timeFactor = buf.readVarInt(); int flags = buf.readUnsignedByte(); this.dayCycle = (flags & 1) > 0; } public void writePacketData(PacketBuffer buf) throws IOException { buf.writeFloat(this.gravity); - buf.writeVarIntToBuffer(this.timeFactor); + buf.writeVarInt(this.timeFactor); buf.writeByte(this.dayCycle ? 1 : 0); } diff --git a/common/src/common/tileentity/TileEntityBanner.java b/common/src/common/tileentity/TileEntityBanner.java index 90e0668..c4c7b1b 100755 --- a/common/src/common/tileentity/TileEntityBanner.java +++ b/common/src/common/tileentity/TileEntityBanner.java @@ -11,7 +11,7 @@ import common.item.ItemStack; import common.nbt.NBTTagCompound; import common.nbt.NBTTagList; import common.network.Packet; -import common.packet.S35PacketUpdateTileEntity; +import common.packet.SPacketUpdateTileEntity; public class TileEntityBanner extends TileEntity { @@ -94,7 +94,7 @@ public class TileEntityBanner extends TileEntity */ public Packet getDescriptionPacket() { - return new S35PacketUpdateTileEntity(this); + return new SPacketUpdateTileEntity(this); } public int getBaseColor() diff --git a/common/src/common/tileentity/TileEntityBeacon.java b/common/src/common/tileentity/TileEntityBeacon.java index 19b6433..9cdb493 100755 --- a/common/src/common/tileentity/TileEntityBeacon.java +++ b/common/src/common/tileentity/TileEntityBeacon.java @@ -8,7 +8,7 @@ import common.entity.types.EntityLiving; import common.init.Blocks; import common.nbt.NBTTagCompound; import common.network.Packet; -import common.packet.S35PacketUpdateTileEntity; +import common.packet.SPacketUpdateTileEntity; import common.potion.Potion; import common.potion.PotionEffect; import common.util.BlockPos; @@ -280,7 +280,7 @@ public class TileEntityBeacon extends TileEntity implements ITickable */ public Packet getDescriptionPacket() { - return new S35PacketUpdateTileEntity(this); + return new SPacketUpdateTileEntity(this); } public double getMaxRenderDistanceSquared() diff --git a/common/src/common/tileentity/TileEntityMachine.java b/common/src/common/tileentity/TileEntityMachine.java index 45d9d6b..84fb12c 100755 --- a/common/src/common/tileentity/TileEntityMachine.java +++ b/common/src/common/tileentity/TileEntityMachine.java @@ -9,7 +9,7 @@ import common.item.ItemStack; import common.nbt.NBTTagCompound; import common.nbt.NBTTagList; import common.network.Packet; -import common.packet.S35PacketUpdateTileEntity; +import common.packet.SPacketUpdateTileEntity; import common.rng.Random; import common.util.ExtMath; @@ -326,7 +326,7 @@ public abstract class TileEntityMachine extends TileEntityLockable implements IH public Packet getDescriptionPacket() { - return new S35PacketUpdateTileEntity(this); + return new SPacketUpdateTileEntity(this); } public int getColor() { diff --git a/common/src/common/tileentity/TileEntityMobSpawner.java b/common/src/common/tileentity/TileEntityMobSpawner.java index 0847f04..0168d35 100755 --- a/common/src/common/tileentity/TileEntityMobSpawner.java +++ b/common/src/common/tileentity/TileEntityMobSpawner.java @@ -8,7 +8,7 @@ import common.init.EntityRegistry; import common.model.ParticleType; import common.nbt.NBTTagCompound; import common.network.Packet; -import common.packet.S35PacketUpdateTileEntity; +import common.packet.SPacketUpdateTileEntity; import common.util.BlockPos; import common.util.BoundingBox; import common.world.World; @@ -29,7 +29,7 @@ public class TileEntityMobSpawner extends TileEntity implements ITickable public Packet getDescriptionPacket() { - return new S35PacketUpdateTileEntity(this); + return new SPacketUpdateTileEntity(this); } public boolean receiveClientEvent(int id, int type) diff --git a/common/src/common/tileentity/TileEntitySign.java b/common/src/common/tileentity/TileEntitySign.java index 4c5301a..b567287 100755 --- a/common/src/common/tileentity/TileEntitySign.java +++ b/common/src/common/tileentity/TileEntitySign.java @@ -3,7 +3,7 @@ package common.tileentity; import common.entity.npc.EntityNPC; import common.nbt.NBTTagCompound; import common.network.Packet; -import common.packet.S33PacketUpdateSign; +import common.packet.SPacketUpdateSign; public class TileEntitySign extends TileEntity { public final String[] signText = new String[] {"", "", "", ""}; @@ -95,7 +95,7 @@ public class TileEntitySign extends TileEntity { String[] aichatcomponent = new String[4]; System.arraycopy(this.signText, 0, aichatcomponent, 0, 4); // Sign sign = Server.getServer().getSigns().getEntry(new WorldPos(this).toString()); - return new S33PacketUpdateSign(this.worldObj, this.pos, aichatcomponent); + return new SPacketUpdateSign(this.worldObj, this.pos, aichatcomponent); } // public boolean hasSpecialNBT() { diff --git a/common/src/common/tileentity/TileEntitySkull.java b/common/src/common/tileentity/TileEntitySkull.java index 48f9349..cd55919 100755 --- a/common/src/common/tileentity/TileEntitySkull.java +++ b/common/src/common/tileentity/TileEntitySkull.java @@ -2,7 +2,7 @@ package common.tileentity; import common.nbt.NBTTagCompound; import common.network.Packet; -import common.packet.S35PacketUpdateTileEntity; +import common.packet.SPacketUpdateTileEntity; public class TileEntitySkull extends TileEntity { @@ -36,7 +36,7 @@ public class TileEntitySkull extends TileEntity */ public Packet getDescriptionPacket() { - return new S35PacketUpdateTileEntity(this); + return new SPacketUpdateTileEntity(this); } // public void setUser(String user) diff --git a/server/src/server/Server.java b/server/src/server/Server.java index e7f5598..96774ac 100755 --- a/server/src/server/Server.java +++ b/server/src/server/Server.java @@ -56,10 +56,10 @@ import common.network.PacketSplitter; import common.network.NetHandler.ThreadQuickExitException; import common.packet.RPacketEnableCompression; import common.packet.RPacketLoginSuccess; -import common.packet.S1DPacketEntityEffect; -import common.packet.S2BPacketChangeGameState; -import common.packet.S38PacketPlayerListItem; -import common.packet.S39PacketPlayerAbilities; +import common.packet.SPacketEntityEffect; +import common.packet.SPacketChangeGameState; +import common.packet.SPacketPlayerListItem; +import common.packet.SPacketPlayerAbilities; import common.packet.SPacketDisconnect; import common.packet.SPacketHeldItemChange; import common.packet.SPacketJoinGame; @@ -655,7 +655,7 @@ public final class Server implements IThreadListener { } this.networkTick(); if(++this.pingTimer > 600) { - this.sendPacket(new S38PacketPlayerListItem((List)this.getPlayers())); + this.sendPacket(new SPacketPlayerListItem((List)this.getPlayers())); this.pingTimer = 0; } if(Config.saveInterval > 0 && ++this.saveTimer >= Config.saveInterval) { @@ -867,22 +867,22 @@ public final class Server implements IThreadListener { conn.sendPacket(new SPacketWorld(WorldServer.clampGravity(), Config.dayCycle, Config.timeFlow)); // conn.initializeStats(); - this.sendPacket(new S38PacketPlayerListItem(false, conn)); + this.sendPacket(new SPacketPlayerListItem(false, conn)); world.spawnEntityInWorld(player); this.preparePlayer(player, null); for(int i = 0; i < this.players.size(); ++i) { Player other = this.players.get(i); - conn.sendPacket(new S38PacketPlayerListItem(false, other)); + conn.sendPacket(new SPacketPlayerListItem(false, other)); } conn.sendPacket(new SPacketSkin(player.getId(), player.getSkin())); // , player.getModel())); conn.setPlayerLocation(player.posX, player.posY, player.posZ, player.rotYaw, player.rotPitch); this.updateTimeAndWeatherForPlayer(conn, world); for(PotionEffect effect : player.getEffects()) { - conn.sendPacket(new S1DPacketEntityEffect(player.getId(), effect)); + conn.sendPacket(new SPacketEntityEffect(player.getId(), effect)); } - conn.sendPacket(new S39PacketPlayerAbilities(player)); + conn.sendPacket(new SPacketPlayerAbilities(player)); conn.addSelfToInternalCraftingInventory(); conn.onConnect(); return null; @@ -897,7 +897,7 @@ public final class Server implements IThreadListener { world.removePlayer(player); this.players.remove(conn); this.usermap.remove(conn.getUser()); - this.sendPacket(new S38PacketPlayerListItem(true, conn)); + this.sendPacket(new SPacketPlayerListItem(true, conn)); } private void preparePlayer(EntityNPC player, WorldServer oldWorld) { @@ -1060,7 +1060,7 @@ public final class Server implements IThreadListener { this.updateTimeAndWeatherForPlayer(conn, world); this.syncPlayerInventory(nplayer); for(PotionEffect effect : nplayer.getEffects()) { - conn.sendPacket(new S1DPacketEntityEffect(nplayer.getId(), effect)); + conn.sendPacket(new SPacketEntityEffect(nplayer.getId(), effect)); } conn.sendPlayerAbilities(); return oldTag; @@ -1087,7 +1087,7 @@ public final class Server implements IThreadListener { this.updateTimeAndWeatherForPlayer((Player)player.connection, newWorld); this.syncPlayerInventory(player); for(PotionEffect effect : player.getEffects()) { - player.connection.sendPacket(new S1DPacketEntityEffect(player.getId(), effect)); + player.connection.sendPacket(new SPacketEntityEffect(player.getId(), effect)); } player.connection.sendPlayerAbilities(); } @@ -1171,11 +1171,11 @@ public final class Server implements IThreadListener { private void updateTimeAndWeatherForPlayer(Player conn, WorldServer world) { conn.sendPacket(new SPacketTimeUpdate(world.getDayTime(), this.getInfo())); - conn.sendPacket(new S2BPacketChangeGameState(S2BPacketChangeGameState.Action.SET_WEATHER, world.getWeather().getID())); - conn.sendPacket(new S2BPacketChangeGameState(S2BPacketChangeGameState.Action.RAIN_STRENGTH, world.getRainStrength())); - conn.sendPacket(new S2BPacketChangeGameState(S2BPacketChangeGameState.Action.DARKNESS, world.getDarkness())); - conn.sendPacket(new S2BPacketChangeGameState(S2BPacketChangeGameState.Action.FOG_STRENGTH, world.getFogStrength())); - conn.sendPacket(new S2BPacketChangeGameState(S2BPacketChangeGameState.Action.TEMPERATURE, world.getTempOffset())); + conn.sendPacket(new SPacketChangeGameState(SPacketChangeGameState.Action.SET_WEATHER, world.getWeather().getID())); + conn.sendPacket(new SPacketChangeGameState(SPacketChangeGameState.Action.RAIN_STRENGTH, world.getRainStrength())); + conn.sendPacket(new SPacketChangeGameState(SPacketChangeGameState.Action.DARKNESS, world.getDarkness())); + conn.sendPacket(new SPacketChangeGameState(SPacketChangeGameState.Action.FOG_STRENGTH, world.getFogStrength())); + conn.sendPacket(new SPacketChangeGameState(SPacketChangeGameState.Action.TEMPERATURE, world.getTempOffset())); } public void syncPlayerInventory(EntityNPC player) { diff --git a/server/src/server/network/Player.java b/server/src/server/network/Player.java index f2a7bfb..2429ab0 100755 --- a/server/src/server/network/Player.java +++ b/server/src/server/network/Player.java @@ -48,13 +48,11 @@ import common.log.Log; import common.material.Material; import common.nbt.NBTTagCompound; import common.nbt.NBTTagList; -import common.nbt.NBTTagString; import common.network.IPlayer; import common.network.NetConnection; import common.network.NetHandler; import common.network.Packet; import common.packet.CPacketAction; -import common.packet.CPacketBook; import common.packet.CPacketBreak; import common.packet.CPacketCheat; import common.packet.CPacketClick; @@ -67,21 +65,21 @@ import common.packet.CPacketPlace; import common.packet.CPacketPlayer; import common.packet.CPacketSign; import common.packet.CPacketSkin; -import common.packet.S18PacketEntityTeleport; -import common.packet.S1APacketEntityStatus; -import common.packet.S1BPacketEntityAttach; -import common.packet.S1DPacketEntityEffect; -import common.packet.S1EPacketRemoveEntityEffect; -import common.packet.S29PacketSoundEffect; -import common.packet.S2DPacketOpenWindow; -import common.packet.S2EPacketCloseWindow; -import common.packet.S2FPacketSetSlot; -import common.packet.S30PacketWindowItems; -import common.packet.S31PacketWindowProperty; -import common.packet.S32PacketConfirmTransaction; -import common.packet.S36PacketSignEditorOpen; -import common.packet.S39PacketPlayerAbilities; -import common.packet.S3APacketTabComplete; +import common.packet.SPacketEntityTeleport; +import common.packet.SPacketEntityStatus; +import common.packet.SPacketEntityAttach; +import common.packet.SPacketEntityEffect; +import common.packet.SPacketRemoveEntityEffect; +import common.packet.SPacketSoundEffect; +import common.packet.SPacketOpenWindow; +import common.packet.SPacketCloseWindow; +import common.packet.SPacketSetSlot; +import common.packet.SPacketWindowItems; +import common.packet.SPacketWindowProperty; +import common.packet.SPacketConfirmTransaction; +import common.packet.SPacketSignEditorOpen; +import common.packet.SPacketPlayerAbilities; +import common.packet.SPacketTabComplete; import common.packet.SPacketAnimation; import common.packet.SPacketBlockChange; import common.packet.SPacketCharacterList; @@ -429,7 +427,7 @@ public class Player extends NetHandler implements ICrafting, Executor, IPlayer this.entity.openContainer.onCraftGuiOpened(this); IInventory iinventory = ((ContainerMerchant)this.entity.openContainer).getMerchantInventory(); String ichatcomponent = npc.getName(); - this.sendPacket(new S2DPacketOpenWindow(this.currentWindowId, "trade", ichatcomponent, iinventory.getSizeInventory())); + this.sendPacket(new SPacketOpenWindow(this.currentWindowId, "trade", ichatcomponent, iinventory.getSizeInventory())); MerchantRecipeList merchantrecipelist = npc.getTrades(this.entity); if (merchantrecipelist != null) @@ -445,7 +443,7 @@ public class Player extends NetHandler implements ICrafting, Executor, IPlayer { if (!this.isChangingQuantityOnly) { - this.sendPacket(new S2FPacketSetSlot(-1, -1, this.entity.inventory.getItemStack())); + this.sendPacket(new SPacketSetSlot(-1, -1, this.entity.inventory.getItemStack())); } } @@ -553,7 +551,7 @@ public class Player extends NetHandler implements ICrafting, Executor, IPlayer { if (this.entity != null) { - this.sendPacket(new S39PacketPlayerAbilities(this.entity)); + this.sendPacket(new SPacketPlayerAbilities(this.entity)); this.entity.updateEffectMeta(); } } @@ -707,20 +705,20 @@ public class Player extends NetHandler implements ICrafting, Executor, IPlayer public void mountEntity(Entity entityIn) { - this.sendPacket(new S1BPacketEntityAttach(0, this.entity, this.entity.vehicle)); + this.sendPacket(new SPacketEntityAttach(0, this.entity, this.entity.vehicle)); this.setPlayerLocation(this.entity.posX, this.entity.posY, this.entity.posZ, this.entity.rotYaw, this.entity.rotPitch); } public void openEditSign(TileEntitySign signTile) { signTile.setPlayer(this.entity); - this.sendPacket(new S36PacketSignEditorOpen(signTile.getPos())); + this.sendPacket(new SPacketSignEditorOpen(signTile.getPos())); } public void displayGui(IInteractionObject guiOwner) { this.getNextWindowId(); - this.sendPacket(new S2DPacketOpenWindow(this.currentWindowId, guiOwner.getGuiID(), guiOwner.getCommandName())); + this.sendPacket(new SPacketOpenWindow(this.currentWindowId, guiOwner.getGuiID(), guiOwner.getCommandName())); this.entity.openContainer = guiOwner.createContainer(this.entity.inventory, this.entity); this.entity.openContainer.windowId = this.currentWindowId; this.entity.openContainer.onCraftGuiOpened(this); @@ -740,7 +738,7 @@ public class Player extends NetHandler implements ICrafting, Executor, IPlayer if (ilockablecontainer.isLocked() && !this.entity.canOpen(ilockablecontainer.getLockCode())) // && !this.isSpectator()) { this.addHotbar(TextColor.RED + "%s ist verschlossen!", chestInventory.getCommandName()); - this.sendPacket(new S29PacketSoundEffect(SoundEvent.DOOR, this.entity.posX, this.entity.posY, this.entity.posZ, 1.0F)); + this.sendPacket(new SPacketSoundEffect(SoundEvent.DOOR, this.entity.posX, this.entity.posY, this.entity.posZ, 1.0F)); return; } } @@ -749,18 +747,18 @@ public class Player extends NetHandler implements ICrafting, Executor, IPlayer if (chestInventory instanceof TileEntityMachine) { - this.sendPacket(new S2DPacketOpenWindow(this.currentWindowId, "machine_" + ((IInteractionObject)chestInventory).getGuiID(), chestInventory.getCommandName(), chestInventory.getSizeInventory(), + this.sendPacket(new SPacketOpenWindow(this.currentWindowId, "machine_" + ((IInteractionObject)chestInventory).getGuiID(), chestInventory.getCommandName(), chestInventory.getSizeInventory(), ((TileEntityMachine)chestInventory).getPos())); this.entity.openContainer = ((IInteractionObject)chestInventory).createContainer(this.entity.inventory, this.entity); } else if (chestInventory instanceof IInteractionObject) { - this.sendPacket(new S2DPacketOpenWindow(this.currentWindowId, ((IInteractionObject)chestInventory).getGuiID(), chestInventory.getCommandName(), chestInventory.getSizeInventory())); + this.sendPacket(new SPacketOpenWindow(this.currentWindowId, ((IInteractionObject)chestInventory).getGuiID(), chestInventory.getCommandName(), chestInventory.getSizeInventory())); this.entity.openContainer = ((IInteractionObject)chestInventory).createContainer(this.entity.inventory, this.entity); } else { - this.sendPacket(new S2DPacketOpenWindow(this.currentWindowId, "container", chestInventory.getCommandName(), chestInventory.getSizeInventory())); + this.sendPacket(new SPacketOpenWindow(this.currentWindowId, "container", chestInventory.getCommandName(), chestInventory.getSizeInventory())); this.entity.openContainer = new ContainerChest(this.entity.inventory, chestInventory, this.entity); } @@ -776,7 +774,7 @@ public class Player extends NetHandler implements ICrafting, Executor, IPlayer } this.getNextWindowId(); - this.sendPacket(new S2DPacketOpenWindow(this.currentWindowId, "EntityHorse", horseInventory.getCommandName(), horseInventory.getSizeInventory(), horse.getId())); + this.sendPacket(new SPacketOpenWindow(this.currentWindowId, "EntityHorse", horseInventory.getCommandName(), horseInventory.getSizeInventory(), horse.getId())); this.entity.openContainer = new ContainerHorseInventory(this.entity.inventory, horseInventory, horse, this.entity); this.entity.openContainer.windowId = this.currentWindowId; this.entity.openContainer.onCraftGuiOpened(this); @@ -794,7 +792,7 @@ public class Player extends NetHandler implements ICrafting, Executor, IPlayer public void closeScreen() { - this.sendPacket(new S2EPacketCloseWindow(this.entity.openContainer.windowId)); + this.sendPacket(new SPacketCloseWindow(this.entity.openContainer.windowId)); this.closeContainer(); } @@ -813,7 +811,7 @@ public class Player extends NetHandler implements ICrafting, Executor, IPlayer public void onItemUseFinish() { - this.sendPacket(new S1APacketEntityStatus(this.entity, (byte)9)); + this.sendPacket(new SPacketEntityStatus(this.entity, (byte)9)); } // /** @@ -831,17 +829,17 @@ public class Player extends NetHandler implements ICrafting, Executor, IPlayer public void onNewEffect(PotionEffect id) { - this.sendPacket(new S1DPacketEntityEffect(this.entity.getId(), id)); + this.sendPacket(new SPacketEntityEffect(this.entity.getId(), id)); } public void onChangedEffect(PotionEffect id, boolean added) { - this.sendPacket(new S1DPacketEntityEffect(this.entity.getId(), id)); + this.sendPacket(new SPacketEntityEffect(this.entity.getId(), id)); } public void onFinishedEffect(PotionEffect effect) { - this.sendPacket(new S1EPacketRemoveEntityEffect(this.entity.getId(), effect)); + this.sendPacket(new SPacketRemoveEntityEffect(this.entity.getId(), effect)); } public void setPositionAndUpdate(double x, double y, double z) @@ -866,7 +864,7 @@ public class Player extends NetHandler implements ICrafting, Executor, IPlayer public void playSound(SoundEvent name, float volume) { - this.server.sendNearExcept(this.entity, this.entity.posX, this.entity.posY, this.entity.posZ, volume > 1.0F ? (double)(16.0F * volume) : 16.0D, this.entity.worldObj.dimension.getDimensionId(), new S29PacketSoundEffect(name, this.entity.posX, this.entity.posY, this.entity.posZ, volume)); + this.server.sendNearExcept(this.entity, this.entity.posX, this.entity.posY, this.entity.posZ, volume > 1.0F ? (double)(16.0F * volume) : 16.0D, this.entity.worldObj.dimension.getDimensionId(), new SPacketSoundEffect(name, this.entity.posX, this.entity.posY, this.entity.posZ, volume)); } @@ -886,7 +884,7 @@ public class Player extends NetHandler implements ICrafting, Executor, IPlayer { if (!this.isChangingQuantityOnly) { - this.sendPacket(new S2FPacketSetSlot(containerToSend.windowId, slotInd, stack)); + this.sendPacket(new SPacketSetSlot(containerToSend.windowId, slotInd, stack)); } } } @@ -898,20 +896,20 @@ public class Player extends NetHandler implements ICrafting, Executor, IPlayer public void updateCraftingInventory(Container containerToSend, List itemsList) { - this.sendPacket(new S30PacketWindowItems(containerToSend.windowId, itemsList)); - this.sendPacket(new S2FPacketSetSlot(-1, -1, this.entity.inventory.getItemStack())); + this.sendPacket(new SPacketWindowItems(containerToSend.windowId, itemsList)); + this.sendPacket(new SPacketSetSlot(-1, -1, this.entity.inventory.getItemStack())); } public void sendProgressBarUpdate(Container containerIn, int varToUpdate, int newValue) { - this.sendPacket(new S31PacketWindowProperty(containerIn.windowId, varToUpdate, newValue)); + this.sendPacket(new SPacketWindowProperty(containerIn.windowId, varToUpdate, newValue)); } public void sendAllWindowProperties(Container p_175173_1_, IInventory p_175173_2_) { for (int i = 0; i < p_175173_2_.getFieldCount(); ++i) { - this.sendPacket(new S31PacketWindowProperty(p_175173_1_.windowId, i, p_175173_2_.getField(i))); + this.sendPacket(new SPacketWindowProperty(p_175173_1_.windowId, i, p_175173_2_.getField(i))); } } @@ -2055,13 +2053,13 @@ public class Player extends NetHandler implements ICrafting, Executor, IPlayer { NetHandler.checkThread(packetIn, this, this.server); if(this.charEditor || !this.isAdmin()) { - this.entity.connection.sendPacket(new S3APacketTabComplete(new String[0])); + this.entity.connection.sendPacket(new SPacketTabComplete(new String[0])); return; } this.pointedEntity = packetIn.getEntityId(); this.pointedPosition = packetIn.getPosition(); if(packetIn.getMessage().startsWith(" ")) { - this.entity.connection.sendPacket(new S3APacketTabComplete(new String[0])); + this.entity.connection.sendPacket(new SPacketTabComplete(new String[0])); return; } List list = Lists.newArrayList(); @@ -2074,7 +2072,7 @@ public class Player extends NetHandler implements ICrafting, Executor, IPlayer list.add(s1); } list.addAll(this.completeCommand(packetIn.getMessage())); - this.entity.connection.sendPacket(new S3APacketTabComplete(list.toArray(new String[list.size()]))); + this.entity.connection.sendPacket(new SPacketTabComplete(list.toArray(new String[list.size()]))); } private static boolean isFinite(double value) { @@ -2154,7 +2152,7 @@ public class Player extends NetHandler implements ICrafting, Executor, IPlayer if (d3 > 4.0D) { Entity entity = this.entity.vehicle; - this.entity.connection.sendPacket(new S18PacketEntityTeleport(entity)); + this.entity.connection.sendPacket(new SPacketEntityTeleport(entity)); this.setPlayerLocation(this.entity.posX, this.entity.posY, this.entity.posZ, this.entity.rotYaw, this.entity.rotPitch); } @@ -2480,7 +2478,7 @@ public class Player extends NetHandler implements ICrafting, Executor, IPlayer if (!ItemStack.areItemStacksEqual(this.entity.inventory.getCurrentItem(), packetIn.getStack())) { - this.sendPacket(new S2FPacketSetSlot(this.entity.openContainer.windowId, slot.slotNumber, this.entity.inventory.getCurrentItem())); + this.sendPacket(new SPacketSetSlot(this.entity.openContainer.windowId, slot.slotNumber, this.entity.inventory.getCurrentItem())); } } } @@ -2943,7 +2941,7 @@ public class Player extends NetHandler implements ICrafting, Executor, IPlayer if (ItemStack.areItemStacksEqual(packetIn.getClickedItem(), itemstack)) { - this.entity.connection.sendPacket(new S32PacketConfirmTransaction(packetIn.getWindowId(), packetIn.getActionNumber(), true)); + this.entity.connection.sendPacket(new SPacketConfirmTransaction(packetIn.getWindowId(), packetIn.getActionNumber(), true)); this.isChangingQuantityOnly = true; this.entity.openContainer.detectAndSendChanges(); this.updateHeldItem(); @@ -2952,7 +2950,7 @@ public class Player extends NetHandler implements ICrafting, Executor, IPlayer else { this.transactions.addKey(this.entity.openContainer.windowId, Short.valueOf(packetIn.getActionNumber())); - this.entity.connection.sendPacket(new S32PacketConfirmTransaction(packetIn.getWindowId(), packetIn.getActionNumber(), false)); + this.entity.connection.sendPacket(new SPacketConfirmTransaction(packetIn.getWindowId(), packetIn.getActionNumber(), false)); this.entity.openContainer.setCanCraft(this.entity, false); List list1 = Lists.newArrayList(); @@ -3141,34 +3139,6 @@ public class Player extends NetHandler implements ICrafting, Executor, IPlayer // this.lastSkinUpdate = System.currentTimeMillis(); } - public void processBook(CPacketBook packetIn) { - NetHandler.checkThread(packetIn, this, this.server); - if(this.charEditor) - return; - - String[] pages = packetIn.getPages(); -// if (!ItemWritableBook.isNBTValid(itemstack1.getTagCompound())) -// throw new IOException("Fehlerhafter Buch-Tag!"); - ItemStack itemstack = this.entity.inventory.getCurrentItem(); - if (itemstack != null && itemstack.getItem() == Items.writable_book) - { - if(pages.length == 0) { - if(itemstack.hasTagCompound()) { - itemstack.getTagCompound().removeTag("pages"); - if(itemstack.getTagCompound().hasNoTags()) - itemstack.setTagCompound(null); - } - } - else { - NBTTagList list = new NBTTagList(); - for(String page : pages) { - list.appendTag(new NBTTagString(page)); - } - itemstack.setTagInfo("pages", list); - } - } - } - public void processForm(CPacketForm packet) { NetHandler.checkThread(packet, this, this.server); if(this.charEditor || this.form == null || packet.getId() != this.currentFormId) diff --git a/server/src/server/world/WorldServer.java b/server/src/server/world/WorldServer.java index 0d79a09..ee652d8 100755 --- a/server/src/server/world/WorldServer.java +++ b/server/src/server/world/WorldServer.java @@ -47,13 +47,13 @@ import common.nbt.NBTTagInt; import common.nbt.NBTTagList; import common.network.IPlayer; import common.network.Packet; -import common.packet.S1APacketEntityStatus; -import common.packet.S27PacketExplosion; -import common.packet.S28PacketEffect; -import common.packet.S29PacketSoundEffect; -import common.packet.S2APacketParticles; -import common.packet.S2BPacketChangeGameState; -import common.packet.S2CPacketSpawnGlobalEntity; +import common.packet.SPacketEntityStatus; +import common.packet.SPacketExplosion; +import common.packet.SPacketEffect; +import common.packet.SPacketSoundEffect; +import common.packet.SPacketParticles; +import common.packet.SPacketChangeGameState; +import common.packet.SPacketSpawnGlobalEntity; import common.packet.SPacketBiome; import common.packet.SPacketBlockAction; import common.packet.SPacketBlockBreakAnim; @@ -1113,7 +1113,7 @@ public final class WorldServer extends AWorldServer { EntityLightning entity = new EntityLightning(this, x, y, z, color, damage, fire, summoner); this.effects.add(entity); this.server.sendNear(entity.posX, entity.posY, entity.posZ, 512.0D, this.dimension.getDimensionId(), - new S2CPacketSpawnGlobalEntity(entity, 1, entity.color)); + new SPacketSpawnGlobalEntity(entity, 1, entity.color)); if(fire && Config.fire) { BlockPos pos = new BlockPos(entity); if(this.isAreaLoaded(pos, 10)) { @@ -1129,7 +1129,7 @@ public final class WorldServer extends AWorldServer { } public void setEntityState(Entity entityIn, byte state) { - this.sendToAllTrackingAndSelf(entityIn, new S1APacketEntityStatus(entityIn, state)); + this.sendToAllTrackingAndSelf(entityIn, new SPacketEntityStatus(entityIn, state)); } public Explosion newExplosion(Entity entityIn, double x, double y, double z, float strength, boolean isFlaming, boolean isSmoking, boolean altSound) { @@ -1143,7 +1143,7 @@ public final class WorldServer extends AWorldServer { for(EntityNPC entityplayer : this.players) { if(entityplayer.getDistanceSq(x, y, z) < 4096.0D) { - entityplayer.connection.sendPacket(new S27PacketExplosion(x, y, z, strength, explosion.getAffectedBlockPositions(), + entityplayer.connection.sendPacket(new SPacketExplosion(x, y, z, strength, explosion.getAffectedBlockPositions(), (Vec3)explosion.getPlayerKnockbackMap().get(entityplayer), altSound)); } } @@ -1196,7 +1196,7 @@ public final class WorldServer extends AWorldServer { public void setWeather(Weather weather) { this.weather = weather; // this.dataModified = true; - this.server.sendPacket(new S2BPacketChangeGameState(S2BPacketChangeGameState.Action.SET_WEATHER, + this.server.sendPacket(new SPacketChangeGameState(SPacketChangeGameState.Action.SET_WEATHER, weather.getID()), this.dimension.getDimensionId()); } @@ -1268,15 +1268,15 @@ public final class WorldServer extends AWorldServer { } if(prevRain != this.rain || force) { - this.server.sendPacket(new S2BPacketChangeGameState(S2BPacketChangeGameState.Action.RAIN_STRENGTH, this.rain), this.dimension.getDimensionId()); + this.server.sendPacket(new SPacketChangeGameState(SPacketChangeGameState.Action.RAIN_STRENGTH, this.rain), this.dimension.getDimensionId()); } if(prevDarkness != this.darkness || force) { - this.server.sendPacket(new S2BPacketChangeGameState(S2BPacketChangeGameState.Action.DARKNESS, this.darkness), this.dimension.getDimensionId()); + this.server.sendPacket(new SPacketChangeGameState(SPacketChangeGameState.Action.DARKNESS, this.darkness), this.dimension.getDimensionId()); } if(prevFog != this.fog || force) { - this.server.sendPacket(new S2BPacketChangeGameState(S2BPacketChangeGameState.Action.FOG_STRENGTH, this.fog), this.dimension.getDimensionId()); + this.server.sendPacket(new SPacketChangeGameState(SPacketChangeGameState.Action.FOG_STRENGTH, this.fog), this.dimension.getDimensionId()); } } @@ -1292,7 +1292,7 @@ public final class WorldServer extends AWorldServer { } if(prevTemp != this.temp || force) { - this.server.sendPacket(new S2BPacketChangeGameState(S2BPacketChangeGameState.Action.TEMPERATURE, this.temp), this.dimension.getDimensionId()); + this.server.sendPacket(new SPacketChangeGameState(SPacketChangeGameState.Action.TEMPERATURE, this.temp), this.dimension.getDimensionId()); } } @@ -1308,7 +1308,7 @@ public final class WorldServer extends AWorldServer { public void spawnParticle(ParticleType particleType, boolean longDistance, double xCoord, double yCoord, double zCoord, int numberOfParticles, double xOffset, double yOffset, double zOffset, double particleSpeed, int[] particleArguments) { - Packet packet = new S2APacketParticles(particleType, longDistance, (float)xCoord, (float)yCoord, (float)zCoord, (float)xOffset, + Packet packet = new SPacketParticles(particleType, longDistance, (float)xCoord, (float)yCoord, (float)zCoord, (float)xOffset, (float)yOffset, (float)zOffset, (float)particleSpeed, numberOfParticles, particleArguments); for(int i = 0; i < this.players.size(); ++i) { @@ -1719,15 +1719,15 @@ public final class WorldServer extends AWorldServer { } for(EntityNPC player : this.players) { player.attackEntityFrom(DamageSource.causeExterminatusDamage(null), 5000); - Packet packet = new S2APacketParticles(ParticleType.EXPLOSION_HUGE, true, + Packet packet = new SPacketParticles(ParticleType.EXPLOSION_HUGE, true, (float)player.posX, (float)this.getSeaLevel() + 4.0f, (float)player.posZ, (float)128.0, (float)2.0, (float)128.0, (float)0.15, 1000, new int[0]); player.connection.sendPacket(packet); - packet = new S2APacketParticles(ParticleType.CLOUD, true, + packet = new SPacketParticles(ParticleType.CLOUD, true, (float)player.posX, (float)this.getSeaLevel() + 4.0f, (float)player.posZ, (float)128.0, (float)2.0, (float)128.0, (float)0.15, 1000, new int[0]); player.connection.sendPacket(packet); - packet = new S28PacketEffect(1025, new BlockPos(player.posX, (double)this.getSeaLevel() + 4.0, player.posZ), 0); + packet = new SPacketEffect(1025, new BlockPos(player.posX, (double)this.getSeaLevel() + 4.0, player.posZ), 0); player.connection.sendPacket(packet); } return true; @@ -1803,7 +1803,7 @@ public final class WorldServer extends AWorldServer { public void playSound(SoundEvent sound, double x, double y, double z, float volume) { - this.server.sendNear(x, y, z, volume > 1.0F ? (double)(16.0F * volume) : 16.0D, this.dimension.getDimensionId(), new S29PacketSoundEffect(sound, x, y, z, volume)); + this.server.sendNear(x, y, z, volume > 1.0F ? (double)(16.0F * volume) : 16.0D, this.dimension.getDimensionId(), new SPacketSoundEffect(sound, x, y, z, volume)); } public void markBlockRangeForRenderUpdate(int x1, int y1, int z1, int x2, int y2, int z2) @@ -1816,7 +1816,7 @@ public final class WorldServer extends AWorldServer { public void playAuxSFX(EntityNPC player, int sfxType, BlockPos blockPosIn, int data) { - this.server.sendNearExcept(player, (double)blockPosIn.getX(), (double)blockPosIn.getY(), (double)blockPosIn.getZ(), 64.0D, this.dimension.getDimensionId(), new S28PacketEffect(sfxType, blockPosIn, data)); + this.server.sendNearExcept(player, (double)blockPosIn.getX(), (double)blockPosIn.getY(), (double)blockPosIn.getZ(), 64.0D, this.dimension.getDimensionId(), new SPacketEffect(sfxType, blockPosIn, data)); } // public void broadcastSound(int soundID, BlockPos pos, int data) From d6d934f1f3f21876abd2e4a683d665b4b915778a Mon Sep 17 00:00:00 2001 From: Sen Date: Sat, 24 May 2025 20:42:53 +0200 Subject: [PATCH 066/200] small network code cleanup --- common/src/common/network/NetConnection.java | 464 ++++++++---------- common/src/common/network/PacketRegistry.java | 3 +- 2 files changed, 203 insertions(+), 264 deletions(-) diff --git a/common/src/common/network/NetConnection.java b/common/src/common/network/NetConnection.java index 216b3cb..c430fdb 100755 --- a/common/src/common/network/NetConnection.java +++ b/common/src/common/network/NetConnection.java @@ -23,310 +23,250 @@ import io.netty.util.AttributeKey; import io.netty.util.concurrent.Future; import io.netty.util.concurrent.GenericFutureListener; -public class NetConnection extends SimpleChannelInboundHandler -{ +public class NetConnection extends SimpleChannelInboundHandler { private static final Pattern IP_REPLACER = Pattern.compile("([0-9]*)\\.([0-9]*)\\.[0-9]*\\.[0-9]*"); public static final AttributeKey ATTR_STATE = AttributeKey.valueOf("protocol"); - - private final Queue queue = new ConcurrentLinkedQueue(); - private final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(); - - private Channel channel; - private SocketAddress address; - private NetHandler handler; - private String exitReason; - private boolean disconnected; - - public void channelActive(ChannelHandlerContext context) throws Exception - { - super.channelActive(context); - this.channel = context.channel(); - this.address = this.channel.remoteAddress(); - try - { - this.setConnectionState(PacketRegistry.HANDSHAKE); - } - catch (Throwable t) - { - Log.JNI.error(t, "Fehler beim Aufbauen der Verbindung für Handshake"); - } - } + private final Queue queue = new ConcurrentLinkedQueue(); + private final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(); - public void setConnectionState(PacketRegistry newState) - { - this.channel.attr(ATTR_STATE).set(newState); - this.channel.config().setAutoRead(true); + private Channel channel; + private SocketAddress address; + private NetHandler handler; + private String exitReason; + private boolean disconnected; + + public void channelActive(ChannelHandlerContext context) throws Exception { + super.channelActive(context); + this.channel = context.channel(); + this.address = this.channel.remoteAddress(); + + try { + this.setConnectionState(PacketRegistry.HANDSHAKE); + } + catch(Throwable t) { + Log.JNI.error(t, "Fehler beim Aufbauen der Verbindung für Handshake"); + } + } + + public void setConnectionState(PacketRegistry newState) { + this.channel.attr(ATTR_STATE).set(newState); + this.channel.config().setAutoRead(true); // Log.debug("Automatisches Lesen eingeschaltet"); - } + } - public void channelInactive(ChannelHandlerContext context) throws Exception - { - this.closeChannel("Ende der Datenübertragung"); - } + public void channelInactive(ChannelHandlerContext context) throws Exception { + this.closeChannel("Ende der Datenübertragung"); + } - public void exceptionCaught(ChannelHandlerContext context, Throwable throwable) throws Exception - { - String comp; + public void exceptionCaught(ChannelHandlerContext context, Throwable throwable) throws Exception { + String comp; - if (throwable instanceof TimeoutException) - { - comp = "Zeitüberschreitung"; - } - else - { - comp = "Interner Fehler: " + throwable; - if(!(throwable instanceof ClosedChannelException)) - Log.SYSTEM.error(throwable, "Fehler in der Verbindung mit %s", this.getCutAddress()); - } + if(throwable instanceof TimeoutException) { + comp = "Zeitüberschreitung"; + } + else { + comp = "Interner Fehler: " + throwable; + if(!(throwable instanceof ClosedChannelException)) + Log.SYSTEM.error(throwable, "Fehler in der Verbindung mit %s", this.getCutAddress()); + } - this.closeChannel(comp); - } + this.closeChannel(comp); + } - protected void channelRead0(ChannelHandlerContext context, Packet packet) throws Exception - { - if (this.channel.isOpen()) - { - try - { - packet.processPacket(this.handler); - } - catch (ThreadQuickExitException e) - { - ; - } - } - } + protected void channelRead0(ChannelHandlerContext context, Packet packet) throws Exception { + if(this.channel.isOpen()) { + try { + packet.processPacket(this.handler); + } + catch(ThreadQuickExitException e) { + ; + } + } + } - public void setNetHandler(NetHandler handler) - { - if (handler == null) { + public void setNetHandler(NetHandler handler) { + if(handler == null) { throw new NullPointerException("Handler ist Null"); } // Log.debug("Setze Handler von " + this + " auf " + handler); - this.handler = handler; - } + this.handler = handler; + } - public void sendPacket(Packet packetIn) - { - if (this.isChannelOpen()) - { - this.flushOutboundQueue(); - this.dispatchPacket(packetIn, null); - } - else - { - this.lock.writeLock().lock(); + public void sendPacket(Packet packet) { + if(this.isChannelOpen()) { + this.flushOutboundQueue(); + this.dispatchPacket(packet, null); + } + else { + this.lock.writeLock().lock(); - try - { - this.queue.add(new NetConnection.InboundHandlerTuplePacketListener(packetIn, null)); - } - finally - { - this.lock.writeLock().unlock(); - } - } - } + try { + this.queue.add(new NetConnection.InboundHandlerTuplePacketListener(packet, null)); + } + finally { + this.lock.writeLock().unlock(); + } + } + } - public void sendPacket(Packet packetIn, GenericFutureListener > listener) - { - if (this.isChannelOpen()) - { - this.flushOutboundQueue(); - this.dispatchPacket(packetIn, new GenericFutureListener[] {listener}); - } - else - { - this.lock.writeLock().lock(); + public void sendPacket(Packet packet, GenericFutureListener> listener) { + if(this.isChannelOpen()) { + this.flushOutboundQueue(); + this.dispatchPacket(packet, new GenericFutureListener[] {listener}); + } + else { + this.lock.writeLock().lock(); - try - { - this.queue.add(new NetConnection.InboundHandlerTuplePacketListener(packetIn, listener)); - } - finally - { - this.lock.writeLock().unlock(); - } - } - } + try { + this.queue.add(new NetConnection.InboundHandlerTuplePacketListener(packet, listener)); + } + finally { + this.lock.writeLock().unlock(); + } + } + } - private void dispatchPacket(final Packet inPacket, final GenericFutureListener > [] futureListeners) - { - final PacketRegistry state = PacketRegistry.getType(inPacket); - final PacketRegistry current = this.channel.attr(ATTR_STATE).get(); + private void dispatchPacket(final Packet packet, final GenericFutureListener>[] listeners) { + final PacketRegistry state = PacketRegistry.getType(packet); + final PacketRegistry current = this.channel.attr(ATTR_STATE).get(); - if (current != state) - { + if(current != state) { // Log.debug("Automatisches Lesen ausgeschaltet"); - this.channel.config().setAutoRead(false); - } + this.channel.config().setAutoRead(false); + } - if (this.channel.eventLoop().inEventLoop()) - { - if (state != current) - { - this.setConnectionState(state); - } + if(this.channel.eventLoop().inEventLoop()) { + if(state != current) { + this.setConnectionState(state); + } - ChannelFuture channelfuture = this.channel.writeAndFlush(inPacket); + ChannelFuture future = this.channel.writeAndFlush(packet); - if (futureListeners != null) - { - channelfuture.addListeners(futureListeners); - } + if(listeners != null) { + future.addListeners(listeners); + } - channelfuture.addListener(ChannelFutureListener.FIRE_EXCEPTION_ON_FAILURE); - } - else - { - this.channel.eventLoop().execute(new Runnable() - { - public void run() - { - if (state != current) - { - NetConnection.this.setConnectionState(state); - } + future.addListener(ChannelFutureListener.FIRE_EXCEPTION_ON_FAILURE); + } + else { + this.channel.eventLoop().execute(new Runnable() { + public void run() { + if(state != current) { + NetConnection.this.setConnectionState(state); + } - ChannelFuture channelfuture1 = NetConnection.this.channel.writeAndFlush(inPacket); + ChannelFuture future = NetConnection.this.channel.writeAndFlush(packet); - if (futureListeners != null) - { - channelfuture1.addListeners(futureListeners); - } + if(listeners != null) { + future.addListeners(listeners); + } - channelfuture1.addListener(ChannelFutureListener.FIRE_EXCEPTION_ON_FAILURE); - } - }); - } - } + future.addListener(ChannelFutureListener.FIRE_EXCEPTION_ON_FAILURE); + } + }); + } + } - private void flushOutboundQueue() - { - if (this.channel != null && this.channel.isOpen()) - { - this.lock.readLock().lock(); + private void flushOutboundQueue() { + if(this.channel != null && this.channel.isOpen()) { + this.lock.readLock().lock(); - try - { - while (!this.queue.isEmpty()) - { - NetConnection.InboundHandlerTuplePacketListener entry = this.queue.poll(); - if(entry != null) // NPE Fix - this.dispatchPacket(entry.packet, entry.listeners); - } - } - finally - { - this.lock.readLock().unlock(); - } - } - } + try { + while(!this.queue.isEmpty()) { + NetConnection.InboundHandlerTuplePacketListener entry = this.queue.poll(); + if(entry != null) // NPE Fix + this.dispatchPacket(entry.packet, entry.listeners); + } + } + finally { + this.lock.readLock().unlock(); + } + } + } + + public void processReceivedPackets() { + this.flushOutboundQueue(); + this.handler.update(); + if(this.channel != null) + this.channel.flush(); + } - public void processReceivedPackets() - { - this.flushOutboundQueue(); - this.handler.update(); - if(this.channel != null) - this.channel.flush(); - } - public String getCutAddress() { return this.address == null ? "?.?.*.*" : IP_REPLACER.matcher(this.address.toString()).replaceAll("$1.$2.*.*"); } - public void closeChannel(String message) - { - if (this.channel.isOpen()) - { - this.channel.close().awaitUninterruptibly(); - this.exitReason = message; - } - } + public void closeChannel(String message) { + if(this.channel.isOpen()) { + this.channel.close().awaitUninterruptibly(); + this.exitReason = message; + } + } - public boolean isChannelOpen() - { - return this.channel != null && this.channel.isOpen(); - } + public boolean isChannelOpen() { + return this.channel != null && this.channel.isOpen(); + } - public boolean hasNoChannel() - { - return this.channel == null; - } + public boolean hasNoChannel() { + return this.channel == null; + } - public void disableAutoRead() - { - this.channel.config().setAutoRead(false); - } + public void disableAutoRead() { + this.channel.config().setAutoRead(false); + } - public void setCompressionTreshold(int treshold) - { - if (treshold >= 0) - { - if (this.channel.pipeline().get("decompress") instanceof CompressionDecoder) - { - ((CompressionDecoder)this.channel.pipeline().get("decompress")).setTreshold(treshold); - } - else - { - this.channel.pipeline().addBefore("decoder", "decompress", new CompressionDecoder(treshold)); - } + public void setCompressionTreshold(int treshold) { + if(treshold >= 0) { + if(this.channel.pipeline().get("decompress") instanceof CompressionDecoder) { + ((CompressionDecoder)this.channel.pipeline().get("decompress")).setTreshold(treshold); + } + else { + this.channel.pipeline().addBefore("decoder", "decompress", new CompressionDecoder(treshold)); + } - if (this.channel.pipeline().get("compress") instanceof CompressionEncoder) - { - ((CompressionEncoder)this.channel.pipeline().get("compress")).setTreshold(treshold); - } - else - { - this.channel.pipeline().addBefore("encoder", "compress", new CompressionEncoder(treshold)); - } - } - else - { - if (this.channel.pipeline().get("decompress") instanceof CompressionDecoder) - { - this.channel.pipeline().remove("decompress"); - } + if(this.channel.pipeline().get("compress") instanceof CompressionEncoder) { + ((CompressionEncoder)this.channel.pipeline().get("compress")).setTreshold(treshold); + } + else { + this.channel.pipeline().addBefore("encoder", "compress", new CompressionEncoder(treshold)); + } + } + else { + if(this.channel.pipeline().get("decompress") instanceof CompressionDecoder) { + this.channel.pipeline().remove("decompress"); + } - if (this.channel.pipeline().get("compress") instanceof CompressionEncoder) - { - this.channel.pipeline().remove("compress"); - } - } - } + if(this.channel.pipeline().get("compress") instanceof CompressionEncoder) { + this.channel.pipeline().remove("compress"); + } + } + } - public void checkDisconnected() - { - if (this.channel != null && !this.channel.isOpen()) - { - if (!this.disconnected) - { - this.disconnected = true; - if(this.handler != null) - this.handler.onDisconnect(this.exitReason != null ? this.exitReason : "Verbindung getrennt"); - } - else - { - Log.JNI.warn("handleDisconnection() zweifach aufgerufen"); - } - } - } - - public void startEncryption(SecretKey key) { - this.channel.pipeline().addBefore("splitter", "decrypt", new EncryptionDecoder(EncryptUtil.createCipher(Cipher.DECRYPT_MODE, key))); - this.channel.pipeline().addBefore("prepender", "encrypt", new EncryptionEncoder(EncryptUtil.createCipher(Cipher.ENCRYPT_MODE, key))); - } + public void checkDisconnected() { + if(this.channel != null && !this.channel.isOpen()) { + if(!this.disconnected) { + this.disconnected = true; + if(this.handler != null) + this.handler.onDisconnect(this.exitReason != null ? this.exitReason : "Verbindung getrennt"); + } + else { + Log.JNI.warn("handleDisconnection() zweifach aufgerufen"); + } + } + } - private static class InboundHandlerTuplePacketListener - { - private final Packet packet; - private final GenericFutureListener > [] listeners; + public void startEncryption(SecretKey key) { + this.channel.pipeline().addBefore("splitter", "decrypt", new EncryptionDecoder(EncryptUtil.createCipher(Cipher.DECRYPT_MODE, key))); + this.channel.pipeline().addBefore("prepender", "encrypt", new EncryptionEncoder(EncryptUtil.createCipher(Cipher.ENCRYPT_MODE, key))); + } - public InboundHandlerTuplePacketListener(Packet packet, GenericFutureListener > listener) - { - this.packet = packet; - this.listeners = listener == null ? null : new GenericFutureListener[] {listener}; - } - } + private static class InboundHandlerTuplePacketListener { + private final Packet packet; + private final GenericFutureListener>[] listeners; + + public InboundHandlerTuplePacketListener(Packet packet, GenericFutureListener> listener) { + this.packet = packet; + this.listeners = listener == null ? null : new GenericFutureListener[] {listener}; + } + } } diff --git a/common/src/common/network/PacketRegistry.java b/common/src/common/network/PacketRegistry.java index a1930de..e896dbb 100755 --- a/common/src/common/network/PacketRegistry.java +++ b/common/src/common/network/PacketRegistry.java @@ -95,8 +95,7 @@ import common.packet.SPacketTrades; import common.packet.SPacketUpdateHealth; import common.packet.SPacketWorld; -public enum PacketRegistry -{ +public enum PacketRegistry { HANDSHAKE {{ this.client(HPacketHandshake.class); }}, From aa0ff6cf96ffcb2a29b0db96507c0bd5406690b9 Mon Sep 17 00:00:00 2001 From: Sen Date: Sat, 24 May 2025 21:24:13 +0200 Subject: [PATCH 067/200] code cleanup --- client/src/client/Client.java | 131 +++++++++++------- client/src/client/Timing.java | 30 ---- client/src/client/audio/SoundManager.java | 2 +- client/src/client/gui/Font.java | 2 +- client/src/client/gui/GuiConnect.java | 2 +- client/src/client/gui/GuiMenu.java | 7 +- client/src/client/gui/character/GuiChar.java | 4 +- client/src/client/gui/element/Textbox.java | 7 +- client/src/client/network/ClientPlayer.java | 2 +- .../renderer/texture/ColormapLoader.java | 2 +- .../renderer/texture/EntityTexManager.java | 2 +- .../texture/LayeredColorMaskTexture.java | 2 +- .../renderer/texture/LayeredTexture.java | 2 +- .../renderer/texture/SimpleTexture.java | 2 +- .../client/renderer/texture/TextureMap.java | 2 +- .../client/renderer/texture/TextureUtil.java | 2 +- client/src/client/util/FileUtils.java | 65 +++++++++ client/src/client/{ => util}/PerfSection.java | 2 +- .../client/{ => util}/PlayerController.java | 3 +- .../src/client/{ => util}/SkinConverter.java | 2 +- common/src/common/ai/EntityAIEatGrass.java | 17 +-- .../src/common/entity/animal/EntitySheep.java | 2 +- .../src/common/pattern/BlockStateHelper.java | 61 -------- common/src/common/util/FileUtils.java | 97 ------------- server/src/server/world/WorldServer.java | 27 +++- .../worldgen/feature/WorldGenDesertWells.java | 6 +- 26 files changed, 207 insertions(+), 276 deletions(-) delete mode 100644 client/src/client/Timing.java create mode 100644 client/src/client/util/FileUtils.java rename client/src/client/{ => util}/PerfSection.java (97%) rename client/src/client/{ => util}/PlayerController.java (99%) rename client/src/client/{ => util}/SkinConverter.java (99%) delete mode 100755 common/src/common/pattern/BlockStateHelper.java delete mode 100644 common/src/common/util/FileUtils.java diff --git a/client/src/client/Client.java b/client/src/client/Client.java index cfa961b..c3c6e18 100755 --- a/client/src/client/Client.java +++ b/client/src/client/Client.java @@ -70,6 +70,9 @@ import client.renderer.texture.ColormapLoader; import client.renderer.texture.EntityTexManager; import client.renderer.texture.TextureManager; import client.renderer.texture.TextureMap; +import client.util.FileUtils; +import client.util.PerfSection; +import client.util.PlayerController; import client.vars.BoolVar; import client.vars.CVar; import client.vars.CVarCategory; @@ -152,7 +155,6 @@ import common.util.BoundingBox; import common.util.CharValidator; import common.util.ExtMath; import common.util.Facing; -import common.util.FileUtils; import common.util.HitPosition; import common.util.LazyLoadBase; import common.util.Util; @@ -316,6 +318,33 @@ public class Client implements IThreadListener { public float moveForward; public float zoomLevel; public float gravity = 1.0f; + + private long tmr_timer; + private long tmr_start; + private long tmr_current; + private long tmr_last; + + private long tmr_delta; + private long tmr_update; + private long tmr_frames; + private long tmr_iters; + + private long tick_torun; + private long tick_done; + private long tick_total; + private long tick_time; + private long tick_stime; + private long tick_ftime; + + private long tick_ttime; + private long tick_update; + + private double tick_fraction; + private float framerate; + private float tickrate; + private float fdelta; + private int tickTarget; + private int tickFrame; private TextureManager textureManager; private RenderManager renderManager; @@ -784,14 +813,14 @@ public class Client implements IThreadListener { this.deltaX = this.deltaY = 0.0f; } if(this.player != null) - this.soundManager.setListener(this.player, (float)Timing.tick_fraction); + this.soundManager.setListener(this.player, (float)this.tick_fraction); if(this.player != null && this.player.isEntityInsideOpaqueBlock()) this.thirdPersonView = 0; GL11.glPushMatrix(); GL11.glClear(16640); GlState.enableTexture2D(); if(this.world != null) - this.entityRenderer.renderWorld((float)Timing.tick_fraction, System.nanoTime() - this.tickStart); + this.entityRenderer.renderWorld((float)this.tick_fraction, System.nanoTime() - this.tickStart); GL11.glPopMatrix(); GlState.disableTexture2D(); @@ -824,7 +853,7 @@ public class Client implements IThreadListener { this.setupOverlay(); if(this.world != null && this.open == null && this.thirdPersonView == 0 && this.viewEntity != null) { if(this.drawDebug) { - this.renderWorldDirections((float)Timing.tick_fraction); + this.renderWorldDirections((float)this.tick_fraction); } else { Drawing.drawRect(this.fb_x / 2 - 1, this.fb_y / 2 - 16, 2, 32, this.pointed != null && this.pointed.type != ObjectType.MISS ? 0xffffffff : 0xffcfcfcf); @@ -1025,7 +1054,7 @@ public class Client implements IThreadListener { this.renderLagometer(); } else { - Drawing.drawText(String.format("%s%.2f", framecode(), Timing.framerate), 0, 0, 0xffffffff); + Drawing.drawText(String.format("%s%.2f", framecode(), this.framerate), 0, 0, 0xffffffff); } } GlState.enableBlend(); @@ -1053,13 +1082,13 @@ public class Client implements IThreadListener { , GL11.glGetString(GL11.GL_VERSION), // WCF.glGetString(WCF.GL_SHADING_LANGUAGE_VERSION), GL11.glGetString(GL11.GL_RENDERER), GL11.glGetString(GL11.GL_VENDOR), - this.framecode(), Timing.framerate < 1.0f ? 1.0f / Timing.framerate : Timing.framerate, Timing.framerate < 1.0f ? "SPF" : "FPS", + this.framecode(), this.framerate < 1.0f ? 1.0f / this.framerate : this.framerate, this.framerate < 1.0f ? "SPF" : "FPS", this.vsync ? TextColor.DGRAY + "VSYNC" : (this.syncLimited ? TextColor.GREEN + "" + this.syncLimit : TextColor.RED + "UNL"), (float)PerfSection.getTotal(false) / 1000.0f, this.fb_x, this.fb_y, this.fullscreen ? " @ " + (this.vidMode == null ? "?" : this.vidMode.refresh) + " Hz" : "", - this.tpscode(), Timing.tickrate < 1.0f ? 1.0f / Timing.tickrate : Timing.tickrate, - Timing.tickrate < 1.0f ? "SPT" : "TPS", (float)Timing.tickTarget / 1000.0f, - (float)Timing.tick_time / 1000.0f, this.tickTimeout, + this.tpscode(), this.tickrate < 1.0f ? 1.0f / this.tickrate : this.tickrate, + this.tickrate < 1.0f ? "SPT" : "TPS", (float)this.tickTarget / 1000.0f, + (float)this.tick_time / 1000.0f, this.tickTimeout, str != null ? "\n" : "", str != null ? str : "" ); // if(str) @@ -2165,14 +2194,14 @@ public class Client implements IThreadListener { while(!this.interrupted) { PerfSection.swap(); PerfSection.TIMING.enter(); - Timing.tmr_current = Util.rtime(); - Timing.tmr_delta = Timing.tmr_current - Timing.tmr_last; - Timing.tmr_last = Timing.tmr_current; - Timing.fdelta = ((float)Timing.tmr_delta) / 1000000.0f; - if((Timing.tmr_current - Timing.tmr_update) >= 1000000L) { - Timing.framerate = ((float)Timing.tmr_frames) * 1000000.0f / ((float)(long)(Timing.tmr_current - Timing.tmr_update)); - Timing.tmr_frames = 0L; - Timing.tmr_update = Timing.tmr_current; + this.tmr_current = Util.rtime(); + this.tmr_delta = this.tmr_current - this.tmr_last; + this.tmr_last = this.tmr_current; + this.fdelta = ((float)this.tmr_delta) / 1000000.0f; + if((this.tmr_current - this.tmr_update) >= 1000000L) { + this.framerate = ((float)this.tmr_frames) * 1000000.0f / ((float)(long)(this.tmr_current - this.tmr_update)); + this.tmr_frames = 0L; + this.tmr_update = this.tmr_current; } this.start(); PerfSection.INPUT.enter(); @@ -2205,10 +2234,10 @@ public class Client implements IThreadListener { long now = System.nanoTime(); this.addFrame(now - this.startNanoTime); this.startNanoTime = now; - while(this.syncLimited && (Util.rtime() - Timing.tmr_current) < (1000000L / this.syncLimit)) { + while(this.syncLimited && (Util.rtime() - this.tmr_current) < (1000000L / this.syncLimit)) { ; } - Timing.tmr_frames += 1L; + this.tmr_frames += 1L; } Log.SYSTEM.info("Beende ..."); @@ -2348,46 +2377,46 @@ public class Client implements IThreadListener { } public TextColor framecode() { - return (Timing.framerate >= 59.0f) ? TextColor.GREEN : ((Timing.framerate >= 29.0f) ? TextColor.YELLOW : ((Timing.framerate >= 14.0f) ? TextColor.ORANGE : TextColor.RED)); + return (this.framerate >= 59.0f) ? TextColor.GREEN : ((this.framerate >= 29.0f) ? TextColor.YELLOW : ((this.framerate >= 14.0f) ? TextColor.ORANGE : TextColor.RED)); } public TextColor tpscode() { - return (Timing.tickrate >= (((float)Timing.tickTarget / 1000.0f) - 1.0f)) ? TextColor.GREEN : ((Timing.tickrate >= (((float)Timing.tickTarget / 1000.0f) / 2.0f - 1.0f)) ? TextColor.YELLOW : - ((Timing.tickrate >= (((float)Timing.tickTarget / 1000.0f) / 4.0f - 1.0f)) ? TextColor.ORANGE : TextColor.RED)); + return (this.tickrate >= (((float)this.tickTarget / 1000.0f) - 1.0f)) ? TextColor.GREEN : ((this.tickrate >= (((float)this.tickTarget / 1000.0f) / 2.0f - 1.0f)) ? TextColor.YELLOW : + ((this.tickrate >= (((float)this.tickTarget / 1000.0f) / 4.0f - 1.0f)) ? TextColor.ORANGE : TextColor.RED)); } private void doTicks() { - Timing.tick_stime = Util.rtime(); - if((Timing.tick_stime - Timing.tick_update) >= 1000000L) { - Timing.tickrate = ((float)Timing.tick_done) * 1000000.0f / ((float)(long)(Timing.tick_stime - Timing.tick_update)); - Timing.tick_done = 0; - Timing.tick_update = Timing.tick_stime; + this.tick_stime = Util.rtime(); + if((this.tick_stime - this.tick_update) >= 1000000L) { + this.tickrate = ((float)this.tick_done) * 1000000.0f / ((float)(long)(this.tick_stime - this.tick_update)); + this.tick_done = 0; + this.tick_update = this.tick_stime; } - Timing.tick_torun += (((long)Timing.tickTarget) * Timing.tmr_delta) / 1000L; - Timing.tickFrame = 0; - Timing.tick_torun = Timing.tick_torun > 2000000L ? 1000000L : Timing.tick_torun; - while(Timing.tick_torun >= 1000000L) { + this.tick_torun += (((long)this.tickTarget) * this.tmr_delta) / 1000L; + this.tickFrame = 0; + this.tick_torun = this.tick_torun > 2000000L ? 1000000L : this.tick_torun; + while(this.tick_torun >= 1000000L) { this.tick(); - Timing.tick_done += 1L; - Timing.tickFrame += 1; - Timing.tick_total += 1L; - Timing.tick_torun -= 1000000L; - if((Timing.tick_ftime = (Util.rtime() - Timing.tick_stime)) >= (((long)this.tickTimeout) * 1000L)) { - Log.TICK.warn("Ticks benötigten %d ms dieses Frame (maximal %d ms), überspringe %d Ticks", Timing.tick_ftime / 1000L, this.tickTimeout, Timing.tick_torun / 1000000L); - Timing.tick_torun = 0L; + this.tick_done += 1L; + this.tickFrame += 1; + this.tick_total += 1L; + this.tick_torun -= 1000000L; + if((this.tick_ftime = (Util.rtime() - this.tick_stime)) >= (((long)this.tickTimeout) * 1000L)) { + Log.TICK.warn("Ticks benötigten %d ms dieses Frame (maximal %d ms), überspringe %d Ticks", this.tick_ftime / 1000L, this.tickTimeout, this.tick_torun / 1000000L); + this.tick_torun = 0L; break; } } - Timing.tick_fraction = ((double)Timing.tick_torun) / 1000000.0; - Timing.tick_ttime += Timing.tick_ftime; - Timing.tick_time = Timing.tickFrame != 0 ? (Timing.tick_ftime / (long)Timing.tickFrame) : 0L; + this.tick_fraction = ((double)this.tick_torun) / 1000000.0; + this.tick_ttime += this.tick_ftime; + this.tick_time = this.tickFrame != 0 ? (this.tick_ftime / (long)this.tickFrame) : 0L; } public void tick_target(float tps) { - Timing.tickTarget = (int)(tps * 1000.0f); - Timing.tick_torun = 0L; - Timing.tick_done = 0L; - Timing.tick_update = Util.rtime(); + this.tickTarget = (int)(tps * 1000.0f); + this.tick_torun = 0L; + this.tick_done = 0L; + this.tick_update = Util.rtime(); } public void unload(boolean loading) { @@ -2748,6 +2777,14 @@ public class Client implements IThreadListener { return buffer; } + public float getTickFraction() { + return (float)this.tick_fraction; + } + + public long getPassedTime() { + return this.tmr_delta; + } + private void regVar(CVar cv) { if(cvars.containsKey(cv.getCVarName())) throw new IllegalArgumentException("Variable " + cv.getCVarName() + " existiert bereits!"); @@ -2963,7 +3000,7 @@ public class Client implements IThreadListener { Log.CONSOLE.user(msg); if(size > 0) { for(String line : msg.split("\n")) { - Message lmsg = new Message(line, Timing.tmr_current); + Message lmsg = new Message(line, this.tmr_current); while(log.size() >= size) { log.remove(log.size() - 1); } @@ -3011,7 +3048,7 @@ public class Client implements IThreadListener { y = up ? y - Font.YGLYPH : y; for(Iterator iter = log.iterator(); iter.hasNext();) { Message msg = iter.next(); - if((Timing.tmr_current - msg.time) <= fade || (log == this.chat && this.chatPermanent)) { + if((this.tmr_current - msg.time) <= fade || (log == this.chat && this.chatPermanent)) { if(align > 0) Drawing.drawTextbox(msg.message, x, y, bg); else if(align < 0) diff --git a/client/src/client/Timing.java b/client/src/client/Timing.java deleted file mode 100644 index 96094f3..0000000 --- a/client/src/client/Timing.java +++ /dev/null @@ -1,30 +0,0 @@ -package client; - -public class Timing { - public static long tmr_timer; - public static long tmr_start; - public static long tmr_current; - public static long tmr_last; - - public static long tmr_delta; - public static long tmr_update; - public static long tmr_frames; - public static long tmr_iters; - - public static long tick_torun; - public static long tick_done; - public static long tick_total; - public static long tick_time; - public static long tick_stime; - public static long tick_ftime; - - public static long tick_ttime; - public static long tick_update; - - public static double tick_fraction; - public static float framerate; - public static float tickrate; - public static float fdelta; - public static int tickTarget; - public static int tickFrame; -} diff --git a/client/src/client/audio/SoundManager.java b/client/src/client/audio/SoundManager.java index 6942153..8886b95 100755 --- a/client/src/client/audio/SoundManager.java +++ b/client/src/client/audio/SoundManager.java @@ -11,6 +11,7 @@ import java.util.Map; import java.util.Map.Entry; import client.Client; +import client.util.FileUtils; import common.collect.BiMap; import common.collect.HashBiMap; import common.collect.Lists; @@ -22,7 +23,6 @@ import common.rng.Random; import common.sound.MovingSound; import common.sound.Sound; import common.util.ExtMath; -import common.util.FileUtils; public class SoundManager { private class Source { diff --git a/client/src/client/gui/Font.java b/client/src/client/gui/Font.java index 51fa18b..302ebb6 100644 --- a/client/src/client/gui/Font.java +++ b/client/src/client/gui/Font.java @@ -8,8 +8,8 @@ import org.lwjgl.opengl.GL11; import client.renderer.GlState; import client.renderer.texture.TextureUtil; +import client.util.FileUtils; import common.log.Log; -import common.util.FileUtils; public class Font { public static final FontChar[] SIZES = new FontChar[256]; diff --git a/client/src/client/gui/GuiConnect.java b/client/src/client/gui/GuiConnect.java index 789fcf0..67135c0 100644 --- a/client/src/client/gui/GuiConnect.java +++ b/client/src/client/gui/GuiConnect.java @@ -12,11 +12,11 @@ import client.gui.element.ListEntry; import client.gui.element.NavButton; import client.gui.element.PressType; import client.renderer.Drawing; +import client.util.FileUtils; import common.color.TextColor; import common.init.Config; import common.log.Log; import common.network.IPlayer; -import common.util.FileUtils; import common.util.Tuple; import common.util.Util; diff --git a/client/src/client/gui/GuiMenu.java b/client/src/client/gui/GuiMenu.java index fd2093b..398d962 100644 --- a/client/src/client/gui/GuiMenu.java +++ b/client/src/client/gui/GuiMenu.java @@ -1,6 +1,5 @@ package client.gui; -import client.Timing; import client.gui.character.GuiChar; import client.gui.character.GuiCharacters; import client.gui.element.ActButton; @@ -26,7 +25,7 @@ public class GuiMenu extends Gui { if(this.gm.world != null) super.drawMainBackground(); else - this.gm.renderGlobal.renderStarField(this.gm.fb_x, this.gm.fb_y, 0x000000, 0xffffff, (float)this.ticks + (float)Timing.tick_fraction, this.rand); + this.gm.renderGlobal.renderStarField(this.gm.fb_x, this.gm.fb_y, 0x000000, 0xffffff, (float)this.ticks + this.gm.getTickFraction(), this.rand); } private final Random rand = new Random(); @@ -84,9 +83,9 @@ public class GuiMenu extends Gui { int width = Drawing.getWidth("Hax!"); for(int z = 0; z < 64; z++) { Drawing.drawText("Hax!", GuiMenu.this.rand.zrange(Math.max(1, this.gm.fb_x - width)) + - (int)(ExtMath.sin(((float)(GuiMenu.this.ticks + GuiMenu.this.rand.zrange(256)) + (float)Timing.tick_fraction) / 100.0f * (float)Math.PI * 2.0f) * 16.0f), + (int)(ExtMath.sin(((float)(GuiMenu.this.ticks + GuiMenu.this.rand.zrange(256)) + this.gm.getTickFraction()) / 100.0f * (float)Math.PI * 2.0f) * 16.0f), GuiMenu.this.rand.zrange(Math.max(1, this.gm.fb_y - Font.YGLYPH)) + - (int)(ExtMath.sin(((float)(GuiMenu.this.ticks + GuiMenu.this.rand.zrange(256)) + (float)Timing.tick_fraction) / 100.0f * (float)Math.PI * 2.0f) * 16.0f), + (int)(ExtMath.sin(((float)(GuiMenu.this.ticks + GuiMenu.this.rand.zrange(256)) + this.gm.getTickFraction()) / 100.0f * (float)Math.PI * 2.0f) * 16.0f), 0xff0000ff | (GuiMenu.this.rand.zrange(256) << 16)); } } diff --git a/client/src/client/gui/character/GuiChar.java b/client/src/client/gui/character/GuiChar.java index 01117c0..7ed4397 100755 --- a/client/src/client/gui/character/GuiChar.java +++ b/client/src/client/gui/character/GuiChar.java @@ -16,7 +16,6 @@ import org.lwjgl.opengl.GL13; import client.Client; import client.Client.FileMode; -import client.SkinConverter; import client.gui.FileCallback; import client.gui.GuiLoading; import client.gui.element.ActButton; @@ -39,6 +38,8 @@ import client.renderer.GlState; import client.renderer.ItemRenderer; import client.renderer.entity.RenderManager; import client.renderer.texture.EntityTexManager; +import client.util.FileUtils; +import client.util.SkinConverter; import client.vars.CVarCategory; import client.vars.EnumVar; import client.vars.Variable; @@ -65,7 +66,6 @@ import common.packet.CPacketMessage; import common.packet.CPacketSkin; import common.rng.Random; import common.util.Displayable; -import common.util.FileUtils; import common.util.Identifyable; import common.util.Util; diff --git a/client/src/client/gui/element/Textbox.java b/client/src/client/gui/element/Textbox.java index fa82c1a..c4e3506 100644 --- a/client/src/client/gui/element/Textbox.java +++ b/client/src/client/gui/element/Textbox.java @@ -2,7 +2,6 @@ package client.gui.element; import org.lwjgl.opengl.GL11; -import client.Timing; import client.gui.Font; import client.renderer.Drawing; import client.window.Button; @@ -63,14 +62,14 @@ abstract class Textbox extends Element { public void mouse(Button btn, int x, int y, boolean ctrl, boolean shift) { if(btn == Button.MOUSE_LEFT) { - if(!shift && ((Timing.tmr_current - this.tmr_leftmb) <= (((long)this.gm.dclickDelay) * 1000L))) { + if(!shift && ((System.currentTimeMillis() - this.tmr_leftmb) <= (long)this.gm.dclickDelay)) { this.sel_start = this.sel_drag = 0; this.sel_end = this.text.length(); } else { gui_text_select(x, y, shift); } - this.tmr_leftmb = Timing.tmr_current; + this.tmr_leftmb = System.currentTimeMillis(); } else if((btn == Button.MOUSE_MIDDLE) && this.func != null) { this.func.use(this, FieldAction.FUNCTION); @@ -177,7 +176,7 @@ abstract class Textbox extends Element { this.tmr_scroll -= ((long)n) * 1000000L; else this.tmr_scroll = 0L; - this.tmr_scroll += Timing.tmr_delta; + this.tmr_scroll += this.gm.getPassedTime(); return n; } return 0; diff --git a/client/src/client/network/ClientPlayer.java b/client/src/client/network/ClientPlayer.java index 167b8ae..2fbf084 100755 --- a/client/src/client/network/ClientPlayer.java +++ b/client/src/client/network/ClientPlayer.java @@ -7,7 +7,6 @@ import java.util.Map.Entry; import java.util.Set; import client.Client; -import client.PlayerController; import client.gui.Gui; import client.gui.GuiConsole; import client.gui.GuiLoading; @@ -28,6 +27,7 @@ import client.gui.ingame.GuiSign; import client.gui.ingame.GuiForm; import client.renderer.particle.EntityPickupFX; import client.renderer.texture.EntityTexManager; +import client.util.PlayerController; import client.world.ChunkClient; import client.world.WorldClient; import common.attributes.Attribute; diff --git a/client/src/client/renderer/texture/ColormapLoader.java b/client/src/client/renderer/texture/ColormapLoader.java index 7566500..96ff88c 100644 --- a/client/src/client/renderer/texture/ColormapLoader.java +++ b/client/src/client/renderer/texture/ColormapLoader.java @@ -2,8 +2,8 @@ package client.renderer.texture; import java.awt.image.BufferedImage; +import client.util.FileUtils; import common.color.Colorizer; -import common.util.FileUtils; public abstract class ColormapLoader { private static final String GRASS_TEX = "textures/world/grass.png"; diff --git a/client/src/client/renderer/texture/EntityTexManager.java b/client/src/client/renderer/texture/EntityTexManager.java index b273901..1c0dcc6 100755 --- a/client/src/client/renderer/texture/EntityTexManager.java +++ b/client/src/client/renderer/texture/EntityTexManager.java @@ -13,6 +13,7 @@ import java.util.Set; import client.Client; import client.renderer.entity.RenderNpc; import client.renderer.layers.LayerExtra; +import client.util.FileUtils; import common.collect.Lists; import common.collect.Maps; import common.collect.Sets; @@ -20,7 +21,6 @@ import common.entity.npc.EntityNPC; import common.init.SpeciesRegistry; import common.init.SpeciesRegistry.ModelType; import common.log.Log; -import common.util.FileUtils; public abstract class EntityTexManager { diff --git a/client/src/client/renderer/texture/LayeredColorMaskTexture.java b/client/src/client/renderer/texture/LayeredColorMaskTexture.java index 654e960..93e2a2c 100755 --- a/client/src/client/renderer/texture/LayeredColorMaskTexture.java +++ b/client/src/client/renderer/texture/LayeredColorMaskTexture.java @@ -7,9 +7,9 @@ import java.io.IOException; import java.io.InputStream; import java.util.List; +import client.util.FileUtils; import common.color.DyeColor; import common.log.Log; -import common.util.FileUtils; public class LayeredColorMaskTexture extends Texture { diff --git a/client/src/client/renderer/texture/LayeredTexture.java b/client/src/client/renderer/texture/LayeredTexture.java index 5339db5..a6e29a3 100755 --- a/client/src/client/renderer/texture/LayeredTexture.java +++ b/client/src/client/renderer/texture/LayeredTexture.java @@ -6,9 +6,9 @@ import java.io.IOException; import java.io.InputStream; import java.util.List; +import client.util.FileUtils; import common.collect.Lists; import common.log.Log; -import common.util.FileUtils; public class LayeredTexture extends Texture { diff --git a/client/src/client/renderer/texture/SimpleTexture.java b/client/src/client/renderer/texture/SimpleTexture.java index 43c4629..c4aa0ed 100755 --- a/client/src/client/renderer/texture/SimpleTexture.java +++ b/client/src/client/renderer/texture/SimpleTexture.java @@ -4,7 +4,7 @@ import java.awt.image.BufferedImage; import java.io.IOException; import java.io.InputStream; -import common.util.FileUtils; +import client.util.FileUtils; public class SimpleTexture extends Texture { private final String location; diff --git a/client/src/client/renderer/texture/TextureMap.java b/client/src/client/renderer/texture/TextureMap.java index 5e5c2ee..b975ff7 100755 --- a/client/src/client/renderer/texture/TextureMap.java +++ b/client/src/client/renderer/texture/TextureMap.java @@ -9,13 +9,13 @@ import java.util.Map.Entry; import client.init.RenderRegistry; import client.renderer.GlState; +import client.util.FileUtils; import common.block.Block; import common.collect.Lists; import common.collect.Maps; import common.init.BlockRegistry; import common.init.FluidRegistry; import common.log.Log; -import common.util.FileUtils; public class TextureMap extends Texture { diff --git a/client/src/client/renderer/texture/TextureUtil.java b/client/src/client/renderer/texture/TextureUtil.java index 71bced9..5fb705e 100755 --- a/client/src/client/renderer/texture/TextureUtil.java +++ b/client/src/client/renderer/texture/TextureUtil.java @@ -15,7 +15,7 @@ import org.lwjgl.opengl.GL11; import org.lwjgl.opengl.GL12; import client.renderer.GlState; -import common.util.FileUtils; +import client.util.FileUtils; public class TextureUtil { diff --git a/client/src/client/util/FileUtils.java b/client/src/client/util/FileUtils.java new file mode 100644 index 0000000..86f2731 --- /dev/null +++ b/client/src/client/util/FileUtils.java @@ -0,0 +1,65 @@ +package client.util; + +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.nio.charset.Charset; + +public class FileUtils { + private static final Charset UTF_8 = Charset.forName("UTF-8"); + + public static String read(File file) throws IOException { + FileInputStream in = null; + String s; + try { + in = new FileInputStream(file); + ByteArrayOutputStream output = new ByteArrayOutputStream(); + byte[] buffer = new byte[4096]; + long count = 0L; + int n; + for(boolean u = false; -1 != (n = in.read(buffer)); count += (long)n) { + output.write(buffer, 0, n); + } + s = new String(output.toByteArray(), UTF_8); + } + finally { + try { + if(in != null) + in.close(); + } + catch(IOException e) { + } + } + return s; + } + + public static void write(File file, String data) throws IOException { + FileOutputStream out = null; + try { + out = new FileOutputStream(file); + if(out != null) { + out.write(data.getBytes(UTF_8)); + out.close(); + } + } + finally { + try { + if(out != null) + out.close(); + } + catch(IOException e) { + } + } + } + + public static InputStream getResource(String path) throws FileNotFoundException { + InputStream in = FileUtils.class.getResourceAsStream("/" + path); + if(in == null) + throw new FileNotFoundException(path); + return in; + } +} diff --git a/client/src/client/PerfSection.java b/client/src/client/util/PerfSection.java similarity index 97% rename from client/src/client/PerfSection.java rename to client/src/client/util/PerfSection.java index ba9599f..9938445 100644 --- a/client/src/client/PerfSection.java +++ b/client/src/client/util/PerfSection.java @@ -1,4 +1,4 @@ -package client; +package client.util; import common.util.Util; diff --git a/client/src/client/PlayerController.java b/client/src/client/util/PlayerController.java similarity index 99% rename from client/src/client/PlayerController.java rename to client/src/client/util/PlayerController.java index a06986e..f23337f 100755 --- a/client/src/client/PlayerController.java +++ b/client/src/client/util/PlayerController.java @@ -1,5 +1,6 @@ -package client; +package client.util; +import client.Client; import client.network.ClientPlayer; import client.world.WorldClient; import common.block.Block; diff --git a/client/src/client/SkinConverter.java b/client/src/client/util/SkinConverter.java similarity index 99% rename from client/src/client/SkinConverter.java rename to client/src/client/util/SkinConverter.java index 6c7695e..037b0ea 100755 --- a/client/src/client/SkinConverter.java +++ b/client/src/client/util/SkinConverter.java @@ -1,4 +1,4 @@ -package client; +package client.util; import java.awt.Color; import java.awt.Graphics; diff --git a/common/src/common/ai/EntityAIEatGrass.java b/common/src/common/ai/EntityAIEatGrass.java index f04e8fd..0cd3820 100755 --- a/common/src/common/ai/EntityAIEatGrass.java +++ b/common/src/common/ai/EntityAIEatGrass.java @@ -1,22 +1,16 @@ package common.ai; -import java.util.function.Predicate; - import common.block.BlockTallGrass; import common.entity.animal.EntitySheep; import common.init.BlockRegistry; import common.init.Blocks; import common.init.Config; -import common.pattern.BlockStateHelper; import common.util.BlockPos; -import common.util.Predicates; import common.world.State; import common.world.World; public class EntityAIEatGrass extends EntityAIBase { - private static final Predicate field_179505_b = BlockStateHelper.forBlock(Blocks.tallgrass).where(BlockTallGrass.TYPE, Predicates.equalTo(BlockTallGrass.EnumType.GRASS)); - private EntitySheep grassEaterEntity; private World entityWorld; int eatingGrassTimer; @@ -40,7 +34,9 @@ public class EntityAIEatGrass extends EntityAIBase else { BlockPos blockpos = new BlockPos(this.grassEaterEntity.posX, this.grassEaterEntity.posY, this.grassEaterEntity.posZ); - return field_179505_b.test(this.entityWorld.getState(blockpos)) ? true : this.entityWorld.getState(blockpos.down()).getBlock() == Blocks.grass; + State state = this.entityWorld.getState(blockpos); + return (state.getBlock() == Blocks.tallgrass && state.getValue(BlockTallGrass.TYPE) == BlockTallGrass.EnumType.GRASS) || + this.entityWorld.getState(blockpos.down()).getBlock() == Blocks.grass; } } @@ -89,14 +85,15 @@ public class EntityAIEatGrass extends EntityAIBase { BlockPos blockpos = new BlockPos(this.grassEaterEntity.posX, this.grassEaterEntity.posY, this.grassEaterEntity.posZ); - if (field_179505_b.test(this.entityWorld.getState(blockpos))) + State state = this.entityWorld.getState(blockpos); + if (state.getBlock() == Blocks.tallgrass && state.getValue(BlockTallGrass.TYPE) == BlockTallGrass.EnumType.GRASS) { if (Config.mobGrief) { this.entityWorld.destroyBlock(blockpos, false); } - this.grassEaterEntity.eatGrassBonus(); + this.grassEaterEntity.eatGrass(); } else { @@ -110,7 +107,7 @@ public class EntityAIEatGrass extends EntityAIBase this.entityWorld.setState(blockpos1, Blocks.dirt.getState(), 2); } - this.grassEaterEntity.eatGrassBonus(); + this.grassEaterEntity.eatGrass(); } } } diff --git a/common/src/common/entity/animal/EntitySheep.java b/common/src/common/entity/animal/EntitySheep.java index dae424c..2ef3341 100755 --- a/common/src/common/entity/animal/EntitySheep.java +++ b/common/src/common/entity/animal/EntitySheep.java @@ -330,7 +330,7 @@ public class EntitySheep extends EntityAnimal * This function applies the benefits of growing back wool and faster growing up to the acting entity. (This * function is used in the AIEatGrass) */ - public void eatGrassBonus() + public void eatGrass() { this.setSheared(false); diff --git a/common/src/common/pattern/BlockStateHelper.java b/common/src/common/pattern/BlockStateHelper.java deleted file mode 100755 index df47558..0000000 --- a/common/src/common/pattern/BlockStateHelper.java +++ /dev/null @@ -1,61 +0,0 @@ -package common.pattern; - -import java.util.Map; -import java.util.Map.Entry; -import java.util.function.Predicate; - -import common.block.Block; -import common.collect.Maps; -import common.properties.IProperty; -import common.world.State; - -public class BlockStateHelper implements Predicate -{ - private final Block block; - private final Map predicates = Maps.newHashMap(); - - private BlockStateHelper(Block blockStateIn) - { - this.block = blockStateIn; - } - - public static BlockStateHelper forBlock(Block blockIn) - { - return new BlockStateHelper(blockIn); - } - - public boolean test(State p_apply_1_) - { - if (p_apply_1_ != null && p_apply_1_.getBlock().equals(this.block)) - { - for (Entry entry : this.predicates.entrySet()) - { - Object object = p_apply_1_.getValue((IProperty)entry.getKey()); - - if (!((Predicate)entry.getValue()).test(object)) - { - return false; - } - } - - return true; - } - else - { - return false; - } - } - - public > BlockStateHelper where(IProperty property, Predicate is) - { - if (!this.block.getPropertyMap().contains(property)) - { - throw new IllegalArgumentException(this.block + " cannot support property " + property); - } - else - { - this.predicates.put(property, is); - return this; - } - } -} diff --git a/common/src/common/util/FileUtils.java b/common/src/common/util/FileUtils.java deleted file mode 100644 index 5c01c4b..0000000 --- a/common/src/common/util/FileUtils.java +++ /dev/null @@ -1,97 +0,0 @@ -package common.util; - -import java.io.ByteArrayOutputStream; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; - -import common.log.Log; -import io.netty.util.CharsetUtil; - -public class FileUtils { - public static String read(InputStream input) throws IOException { - return new String(readBytes(input), CharsetUtil.UTF_8); - } - - public static byte[] readBytes(InputStream input) throws IOException { - ByteArrayOutputStream output = new ByteArrayOutputStream(); - byte[] buffer = new byte[4096]; - long count = 0L; - int n; - for(boolean u = false; -1 != (n = input.read(buffer)); count += (long)n) { - output.write(buffer, 0, n); - } - return output.toByteArray(); - } - - public static String read(File file) throws IOException { - FileInputStream in = null; - String s; - try { - in = new FileInputStream(file); - s = FileUtils.read(in); - } - finally { - try { - if(in != null) - in.close(); - } - catch(IOException e) { - } - } - return s; - } - - public static void write(File file, String data) throws IOException { - FileOutputStream out = null; - try { - out = new FileOutputStream(file); - if(out != null) { - out.write(data.getBytes(CharsetUtil.UTF_8)); - out.close(); - } - } - finally { - try { - if(out != null) - out.close(); - } - catch(IOException e) { - } - } - } - - public static InputStream getResource(String path) throws FileNotFoundException { - InputStream in = FileUtils.class.getResourceAsStream("/" + path); - if(in == null) - throw new FileNotFoundException(path); - return in; - } - - public static boolean deleteFiles(File[] files) { - if(files == null) { - Log.JNI.warn("Konnte Ordner nicht löschen"); - return false; - } - - for(int i = 0; i < files.length; ++i) { - File file = files[i]; - Log.JNI.info("Lösche " + file); - - if(file.isDirectory() && !deleteFiles(file.listFiles())) { - Log.JNI.warn("Konnte Ordner " + file + " nicht löschen"); - return false; - } - - if(!file.delete()) { - Log.JNI.warn("Konnte Datei " + file + " nicht löschen"); - return false; - } - } - - return true; - } -} diff --git a/server/src/server/world/WorldServer.java b/server/src/server/world/WorldServer.java index ee652d8..7808ed8 100755 --- a/server/src/server/world/WorldServer.java +++ b/server/src/server/world/WorldServer.java @@ -66,7 +66,6 @@ import common.util.BlockPos; import common.util.BoundingBox; import common.util.ChunkPos; import common.util.ExtMath; -import common.util.FileUtils; import common.util.IntHashMap; import common.util.LongHashMap; import common.util.NextTickListEntry; @@ -1002,6 +1001,30 @@ public final class WorldServer extends AWorldServer { map.clear(); } + private static boolean deleteFiles(File[] files) { + if(files == null) { + Log.JNI.warn("Konnte Ordner nicht löschen"); + return false; + } + + for(int i = 0; i < files.length; ++i) { + File file = files[i]; + Log.JNI.info("Lösche " + file); + + if(file.isDirectory() && !deleteFiles(file.listFiles())) { + Log.JNI.warn("Konnte Ordner " + file + " nicht löschen"); + return false; + } + + if(!file.delete()) { + Log.JNI.warn("Konnte Datei " + file + " nicht löschen"); + return false; + } + } + + return true; + } + public void saveAllChunks() { if(/* (force || !this.disableSaving) && */ !this.debug) { // if(this.primary) { @@ -1667,7 +1690,7 @@ public final class WorldServer extends AWorldServer { iter.remove(); } Region.finishWrite(); - FileUtils.deleteFiles(this.chunkDir.listFiles(new FileFilter() { + deleteFiles(this.chunkDir.listFiles(new FileFilter() { public boolean accept(File file) { return file.isDirectory(); } diff --git a/server/src/server/worldgen/feature/WorldGenDesertWells.java b/server/src/server/worldgen/feature/WorldGenDesertWells.java index f54c1e0..2fbe7f9 100755 --- a/server/src/server/worldgen/feature/WorldGenDesertWells.java +++ b/server/src/server/worldgen/feature/WorldGenDesertWells.java @@ -3,18 +3,15 @@ package server.worldgen.feature; import common.block.BlockSand; import common.block.BlockSlab; import common.init.Blocks; -import common.pattern.BlockStateHelper; import common.rng.Random; import common.util.BlockPos; import common.util.Facing; -import common.util.Predicates; import common.world.State; import server.world.WorldServer; import server.worldgen.FeatureGenerator; public class WorldGenDesertWells extends FeatureGenerator { - private static final BlockStateHelper field_175913_a = BlockStateHelper.forBlock(Blocks.sand).where(BlockSand.VARIANT, Predicates.equalTo(BlockSand.EnumType.SAND)); private final State field_175911_b = Blocks.sandstone_slab.getState().withProperty(BlockSlab.FACING, Facing.DOWN); private final State field_175912_c = Blocks.sandstone.getState(); private final State field_175910_d = Blocks.flowing_water.getState(); @@ -26,7 +23,8 @@ public class WorldGenDesertWells extends FeatureGenerator position = position.down(); } - if (!field_175913_a.test(worldIn.getState(position))) + State state = worldIn.getState(position); + if (state.getBlock() != Blocks.sand || state.getValue(BlockSand.VARIANT) != BlockSand.EnumType.SAND) { return false; } From 8bd9370bab48cb7754f5ac1e3ace25465219fcbb Mon Sep 17 00:00:00 2001 From: Sen Date: Sun, 25 May 2025 00:10:02 +0200 Subject: [PATCH 068/200] make larger crafting grids possible --- .../src/client/gui/container/GuiCrafting.java | 46 +++++------------ client/src/client/network/ClientPlayer.java | 13 +++-- common/src/common/block/BlockWorkbench.java | 34 ++++++------- common/src/common/init/BlockRegistry.java | 4 +- common/src/common/init/Blocks.java | 4 +- common/src/common/init/CraftingRegistry.java | 40 ++++++++------- common/src/common/init/Items.java | 1 + .../common/inventory/ContainerWorkbench.java | 51 ++++++++++--------- server/src/server/world/Converter.java | 2 +- .../structure/StructureScattered.java | 2 +- .../worldgen/structure/StructureVillage.java | 2 +- 11 files changed, 97 insertions(+), 102 deletions(-) diff --git a/client/src/client/gui/container/GuiCrafting.java b/client/src/client/gui/container/GuiCrafting.java index d38e913..954e6cf 100755 --- a/client/src/client/gui/container/GuiCrafting.java +++ b/client/src/client/gui/container/GuiCrafting.java @@ -1,42 +1,22 @@ package client.gui.container; +import common.block.BlockWorkbench; import common.inventory.ContainerWorkbench; import common.inventory.InventoryPlayer; import common.util.BlockPos; import common.world.World; -public class GuiCrafting extends GuiContainer -{ -// private static final String craftingTableGuiTextures = "textures/gui/crafting_table.png"; +public class GuiCrafting extends GuiContainer { + private final BlockWorkbench type; + + public GuiCrafting(InventoryPlayer playerInv, World worldIn, BlockWorkbench type) { + super(new ContainerWorkbench(playerInv, worldIn, BlockPos.ORIGIN, type)); + this.type = type; + this.ySize = 112 + 18 * this.type.getSize(); + } - public GuiCrafting(InventoryPlayer playerInv, World worldIn) - { - this(playerInv, worldIn, BlockPos.ORIGIN); - } - - public GuiCrafting(InventoryPlayer playerInv, World worldIn, BlockPos blockPosition) - { - super(new ContainerWorkbench(playerInv, worldIn, blockPosition)); - } - - /** - * Draw the foreground layer for the GuiContainer (everything in front of the items). Args : mouseX, mouseY - */ - public void drawGuiContainerForegroundLayer() - { - this.drawString("Handwerk", 28, 6); - this.drawString("Inventar", 8, this.ySize - 96 + 2); - } - -// /** -// * Args : renderPartialTicks, mouseX, mouseY -// */ -// protected void drawGuiContainerBackgroundLayer(int mouseX, int mouseY) -// { -// GlState.color(1.0F, 1.0F, 1.0F, 1.0F); -// this.gm.getTextureManager().bindTexture(craftingTableGuiTextures); -// int i = (this.width - this.xSize) / 2; -// int j = (this.height - this.ySize) / 2; -//// this.rect(i, j, 0, 0, this.xSize, this.ySize); -// } + public void drawGuiContainerForegroundLayer() { + this.drawString("Handwerk (" + this.type.getDisplay() + ")", 26, 6); + this.drawString("Inventar", 8, this.ySize - 96 + 2); + } } diff --git a/client/src/client/network/ClientPlayer.java b/client/src/client/network/ClientPlayer.java index 2fbf084..94602af 100755 --- a/client/src/client/network/ClientPlayer.java +++ b/client/src/client/network/ClientPlayer.java @@ -34,6 +34,8 @@ import common.attributes.Attribute; import common.attributes.AttributeInstance; import common.attributes.AttributeMap; import common.attributes.AttributeModifier; +import common.block.Block; +import common.block.BlockWorkbench; import common.collect.Lists; import common.collect.Maps; import common.dimension.Dimension; @@ -47,6 +49,7 @@ import common.entity.npc.EntityNPC; import common.entity.npc.PlayerCharacter; import common.entity.projectile.EntityProjectile; import common.entity.types.EntityLiving; +import common.init.BlockRegistry; import common.init.EntityRegistry; import common.init.ItemRegistry; import common.init.SoundEvent; @@ -2047,11 +2050,11 @@ public class ClientPlayer extends NetHandler implements IClientPlayer public void displayGui(IInteractionObject guiOwner, InventoryPlayer inventory, World worldObj) { String s = guiOwner.getGuiID(); - if ("crafting_table".equals(s)) - { - this.gameController.displayGuiScreen(new GuiCrafting(inventory, worldObj)); - } - else if ("enchanting_table".equals(s)) + Block block = BlockRegistry.getRegisteredBlock(s); + if(block instanceof BlockWorkbench) { + this.gameController.displayGuiScreen(new GuiCrafting(inventory, worldObj, (BlockWorkbench)block)); + } + else if ("enchanting_table".equals(s)) { this.gameController.displayGuiScreen(new GuiEnchant(inventory, worldObj, guiOwner)); } diff --git a/common/src/common/block/BlockWorkbench.java b/common/src/common/block/BlockWorkbench.java index 3ac24c8..3280f32 100755 --- a/common/src/common/block/BlockWorkbench.java +++ b/common/src/common/block/BlockWorkbench.java @@ -1,6 +1,7 @@ package common.block; import common.entity.npc.EntityNPC; +import common.init.BlockRegistry; import common.inventory.Container; import common.inventory.ContainerWorkbench; import common.inventory.InventoryPlayer; @@ -16,11 +17,18 @@ import common.world.World; public class BlockWorkbench extends Block { - public BlockWorkbench() + private final int size; + + public BlockWorkbench(int size) { super(Material.wood); this.setTab(CheatTab.tabTech); + this.size = size; } + + public int getSize() { + return this.size; + } public boolean onBlockActivated(World worldIn, BlockPos pos, State state, EntityNPC playerIn, Facing side, float hitX, float hitY, float hitZ) { @@ -30,7 +38,7 @@ public class BlockWorkbench extends Block } else { - playerIn.displayGui(new BlockWorkbench.InterfaceCraftingTable(worldIn, pos)); + playerIn.displayGui(new BlockWorkbench.InterfaceCraftingTable(worldIn, pos, this)); // playerIn.triggerAchievement(StatRegistry.craftingTableStat); return true; } @@ -45,36 +53,28 @@ public class BlockWorkbench extends Block { private final World world; private final BlockPos position; + private final BlockWorkbench block; - public InterfaceCraftingTable(World worldIn, BlockPos pos) + public InterfaceCraftingTable(World worldIn, BlockPos pos, BlockWorkbench block) { this.world = worldIn; this.position = pos; + this.block = block; } - - public String getName() - { - return null; - } - - public boolean hasCustomName() - { - return false; - } - + public String getCommandName() { - return "Werkbank"; + return this.block.getDisplay(); } public Container createContainer(InventoryPlayer playerInventory, EntityNPC playerIn) { - return new ContainerWorkbench(playerInventory, this.world, this.position); + return new ContainerWorkbench(playerInventory, this.world, this.position, this.block); } public String getGuiID() { - return "crafting_table"; + return BlockRegistry.REGISTRY.getNameForObject(this.block); } } } diff --git a/common/src/common/init/BlockRegistry.java b/common/src/common/init/BlockRegistry.java index c348564..ec7703a 100755 --- a/common/src/common/init/BlockRegistry.java +++ b/common/src/common/init/BlockRegistry.java @@ -527,7 +527,7 @@ public abstract class BlockRegistry { .setDisplay("Chunk-Lade-Kern")); registerBlock(2001, "mob_spawner", (new BlockMobSpawner()).setHardness(5.0F).setStepSound(SoundType.STONE).setDisplay("Monsterspawner")); - registerBlock(2002, "crafting_table", (new BlockWorkbench()).setHardness(2.5F).setStepSound(SoundType.WOOD).setDisplay("Werkbank")); + registerBlock(2002, "workbench", (new BlockWorkbench(3)).setHardness(2.5F).setStepSound(SoundType.WOOD).setDisplay("Werkbank")); registerBlock(2003, "furnace", (new BlockFurnace(false)).setHardness(3.5F).setStepSound(SoundType.STONE).setDisplay("Ofen") .setTab(CheatTab.tabTech)); registerBlock(2004, "lit_furnace", (new BlockFurnace(true)).setHardness(3.5F).setStepSound(SoundType.STONE).setLightLevel(0.875F) @@ -542,6 +542,8 @@ public abstract class BlockRegistry { registerBlock(2010, "noteblock", (new BlockNote()).setHardness(0.8F).setDisplay("Notenblock")); registerBlock(2011, "jukebox", (new BlockJukebox()).setHardness(2.0F).setResistance(10.0F).setStepSound(SoundType.STONE).setDisplay("Plattenspieler")); + registerBlock(2012, "construction_table", (new BlockWorkbench(4)).setHardness(2.5F).setStepSound(SoundType.WOOD).setDisplay("Konstruktionstisch")); + registerBlock(2013, "assembly_unit", (new BlockWorkbench(5)).setHardness(2.5F).setStepSound(SoundType.WOOD).setDisplay("Fertigungseinheit")); registerBlock(2100, "chest", (new BlockChest(0)).setHardness(2.5F).setStepSound(SoundType.WOOD).setDisplay("Truhe")); registerBlock(2101, "trapped_chest", (new BlockChest(1)).setHardness(2.5F).setStepSound(SoundType.WOOD).setDisplay("Redstonetruhe")); diff --git a/common/src/common/init/Blocks.java b/common/src/common/init/Blocks.java index 056473c..508ec50 100755 --- a/common/src/common/init/Blocks.java +++ b/common/src/common/init/Blocks.java @@ -142,7 +142,9 @@ public abstract class Blocks { public static final BlockRedstoneWire redstone = (BlockRedstoneWire)get("redstone"); public static final BlockOre diamond_ore = (BlockOre)get("diamond_ore"); public static final Block diamond_block = get("diamond_block"); - public static final Block crafting_table = get("crafting_table"); + public static final Block workbench = get("workbench"); + public static final Block construction_table = get("construction_table"); + public static final Block assembly_unit = get("assembly_unit"); public static final Block wheat = get("wheat"); public static final Block farmland = get("farmland"); public static final Block furnace = get("furnace"); diff --git a/common/src/common/init/CraftingRegistry.java b/common/src/common/init/CraftingRegistry.java index 7e5ea06..e76ddfb 100755 --- a/common/src/common/init/CraftingRegistry.java +++ b/common/src/common/init/CraftingRegistry.java @@ -315,7 +315,8 @@ public abstract class CraftingRegistry add(new ItemStack(Blocks.daylight_detector), "GGG", "QQQ", "WWW", 'G', Blocks.glass, 'Q', Items.quartz, 'W', slab); add(new ItemStack(Blocks.chest), "###", "# #", "###", '#', planks); - addBasic(new ItemStack(Blocks.crafting_table), "##", "##", '#', planks); + addBasic(new ItemStack(Blocks.workbench), "##", "##", '#', planks); + add(new ItemStack(Blocks.assembly_unit), "----", "XXXX", "X##X", '#', Blocks.construction_table, '-', Items.titanium_ingot, 'X', planks); add(new ItemStack(Blocks.jukebox, 1), "###", "#X#", "###", '#', planks, 'X', Items.diamond); @@ -466,6 +467,9 @@ public abstract class CraftingRegistry add(new ItemStack(Items.magnet, 1), "I I", "N N", " R ", 'I', Items.iron_ingot, 'N', Items.neodymium_ingot, 'R', Items.redstone); addShapeless(new ItemStack(Items.potion, 1, 16384), new ItemStack(Items.potion, 1, 0), Items.gunpowder); + + add(new ItemStack(Blocks.construction_table), "---", "-#-", "---", '#', Blocks.workbench, '-', Items.iron_ingot); + add(new ItemStack(Blocks.bedrock), "#####", "#####", "#####", "#####", "#####", '#', Blocks.obsidian); Collections.sort(recipes, new Comparator() { @@ -1570,9 +1574,9 @@ public abstract class CraftingRegistry */ public boolean matches(InventoryCrafting inv, World worldIn) { - for (int i = 0; i <= 3 - this.recipeWidth; ++i) + for (int i = 0; i <= inv.getWidth() - this.recipeWidth; ++i) { - for (int j = 0; j <= 3 - this.recipeHeight; ++j) + for (int j = 0; j <= inv.getHeight() - this.recipeHeight; ++j) { if (this.checkMatch(inv, i, j, true)) { @@ -1592,43 +1596,43 @@ public abstract class CraftingRegistry /** * Checks if the region of a crafting inventory is match for the recipe. */ - private boolean checkMatch(InventoryCrafting p_77573_1_, int p_77573_2_, int p_77573_3_, boolean p_77573_4_) + private boolean checkMatch(InventoryCrafting inv, int xPos, int yPos, boolean mirror) { - for (int i = 0; i < 3; ++i) + for (int x = 0; x < inv.getWidth(); ++x) { - for (int j = 0; j < 3; ++j) + for (int y = 0; y < inv.getHeight(); ++y) { - int k = i - p_77573_2_; - int l = j - p_77573_3_; - ItemStack itemstack = null; + int rx = x - xPos; + int ry = y - yPos; + ItemStack stack = null; - if (k >= 0 && l >= 0 && k < this.recipeWidth && l < this.recipeHeight) + if (rx >= 0 && ry >= 0 && rx < this.recipeWidth && ry < this.recipeHeight) { - if (p_77573_4_) + if (mirror) { - itemstack = this.recipeItems[this.recipeWidth - k - 1 + l * this.recipeWidth]; + stack = this.recipeItems[this.recipeWidth - rx - 1 + ry * this.recipeWidth]; } else { - itemstack = this.recipeItems[k + l * this.recipeWidth]; + stack = this.recipeItems[rx + ry * this.recipeWidth]; } } - ItemStack itemstack1 = p_77573_1_.getStackInRowAndColumn(i, j); + ItemStack ingredient = inv.getStackInRowAndColumn(x, y); - if (itemstack1 != null || itemstack != null) + if (ingredient != null || stack != null) { - if (itemstack1 == null && itemstack != null || itemstack1 != null && itemstack == null) + if (ingredient == null && stack != null || ingredient != null && stack == null) { return false; } - if (itemstack.getItem() != itemstack1.getItem()) + if (stack.getItem() != ingredient.getItem()) { return false; } - if (itemstack.getMetadata() != 32767 && itemstack.getMetadata() != itemstack1.getMetadata()) + if (stack.getMetadata() != 32767 && stack.getMetadata() != ingredient.getMetadata()) { return false; } diff --git a/common/src/common/init/Items.java b/common/src/common/init/Items.java index 4f9779b..50f5534 100755 --- a/common/src/common/init/Items.java +++ b/common/src/common/init/Items.java @@ -120,6 +120,7 @@ public abstract class Items { public static final Item iron_hoe = get("iron_hoe"); public static final Item iron_horse_armor = get("iron_horse_armor"); public static final Item iron_ingot = get("iron_ingot"); + public static final Item titanium_ingot = get("titanium_ingot"); public static final ItemArmor iron_leggings = (ItemArmor)get("iron_leggings"); public static final Item iron_pickaxe = get("iron_pickaxe"); public static final ItemShears iron_shears = (ItemShears)get("iron_shears"); diff --git a/common/src/common/inventory/ContainerWorkbench.java b/common/src/common/inventory/ContainerWorkbench.java index 2dce2fc..4450495 100755 --- a/common/src/common/inventory/ContainerWorkbench.java +++ b/common/src/common/inventory/ContainerWorkbench.java @@ -1,7 +1,7 @@ package common.inventory; +import common.block.BlockWorkbench; import common.entity.npc.EntityNPC; -import common.init.Blocks; import common.init.CraftingRegistry; import common.item.ItemStack; import common.util.BlockPos; @@ -9,25 +9,28 @@ import common.world.World; public class ContainerWorkbench extends Container { - /** The crafting matrix inventory (3x3). */ - public InventoryCrafting craftMatrix = new InventoryCrafting(this, 3, 3); - public IInventory craftResult = new InventoryCraftResult(); - private World worldObj; + private final int craftSlots; + public final InventoryCrafting craftMatrix; + public final IInventory craftResult = new InventoryCraftResult(); + private final World worldObj; + private final BlockPos pos; + private final BlockWorkbench block; - /** Position of the workbench */ - private BlockPos pos; - - public ContainerWorkbench(InventoryPlayer playerInventory, World worldIn, BlockPos posIn) + public ContainerWorkbench(InventoryPlayer playerInventory, World worldIn, BlockPos posIn, BlockWorkbench block) { + int size = block.getSize(); + this.block = block; this.worldObj = worldIn; this.pos = posIn; - this.addSlotToContainer(new SlotCrafting(playerInventory.player, this.craftMatrix, this.craftResult, 0, 124, 35)); + this.craftSlots = size * size; + this.craftMatrix = new InventoryCrafting(this, size, size); + this.addSlotToContainer(new SlotCrafting(playerInventory.player, this.craftMatrix, this.craftResult, 0, 134, 17 + ((size - 1) * 18) / 2)); - for (int i = 0; i < 3; ++i) + for (int i = 0; i < size; ++i) { - for (int j = 0; j < 3; ++j) + for (int j = 0; j < size; ++j) { - this.addSlotToContainer(new Slot(this.craftMatrix, j + i * 3, 30 + j * 18, 17 + i * 18)); + this.addSlotToContainer(new Slot(this.craftMatrix, j + i * size, 26 + j * 18, 17 + i * 18)); } } @@ -35,13 +38,13 @@ public class ContainerWorkbench extends Container { for (int i1 = 0; i1 < 9; ++i1) { - this.addSlotToContainer(new Slot(playerInventory, i1 + k * 9 + 9, 8 + i1 * 18, 84 + k * 18)); + this.addSlotToContainer(new Slot(playerInventory, i1 + k * 9 + 9, 8 + i1 * 18, 30 + size * 18 + k * 18)); } } for (int l = 0; l < 9; ++l) { - this.addSlotToContainer(new Slot(playerInventory, l, 8 + l * 18, 142)); + this.addSlotToContainer(new Slot(playerInventory, l, 8 + l * 18, 88 + size * 18)); } this.onCraftMatrixChanged(this.craftMatrix); @@ -64,7 +67,7 @@ public class ContainerWorkbench extends Container if (!this.worldObj.client) { - for (int i = 0; i < 9; ++i) + for (int i = 0; i < this.craftSlots; ++i) { ItemStack itemstack = this.craftMatrix.removeStackFromSlot(i); @@ -78,7 +81,7 @@ public class ContainerWorkbench extends Container public boolean canInteractWith(EntityNPC playerIn) { - return this.worldObj.getState(this.pos).getBlock() != Blocks.crafting_table ? false : playerIn.getDistanceSq((double)this.pos.getX() + 0.5D, (double)this.pos.getY() + 0.5D, (double)this.pos.getZ() + 0.5D) <= 64.0D; + return this.worldObj.getState(this.pos).getBlock() != this.block ? false : playerIn.getDistanceSq((double)this.pos.getX() + 0.5D, (double)this.pos.getY() + 0.5D, (double)this.pos.getZ() + 0.5D) <= 64.0D; } /** @@ -87,7 +90,7 @@ public class ContainerWorkbench extends Container public ItemStack transferStackInSlot(EntityNPC playerIn, int index) { ItemStack itemstack = null; - Slot slot = (Slot)this.inventorySlots.get(index); + Slot slot = this.inventorySlots.get(index); if (slot != null && slot.getHasStack()) { @@ -96,28 +99,28 @@ public class ContainerWorkbench extends Container if (index == 0) { - if (!this.mergeItemStack(itemstack1, 10, 46, true)) + if (!this.mergeItemStack(itemstack1, this.craftSlots + 1, this.craftSlots + 37, true)) { return null; } slot.onSlotChange(itemstack1, itemstack); } - else if (index >= 10 && index < 37) + else if (index >= this.craftSlots + 1 && index < this.craftSlots + 28) { - if (!this.mergeItemStack(itemstack1, 37, 46, false)) + if (!this.mergeItemStack(itemstack1, this.craftSlots + 28, this.craftSlots + 37, false)) { return null; } } - else if (index >= 37 && index < 46) + else if (index >= this.craftSlots + 28 && index < this.craftSlots + 37) { - if (!this.mergeItemStack(itemstack1, 10, 37, false)) + if (!this.mergeItemStack(itemstack1, this.craftSlots + 1, this.craftSlots + 28, false)) { return null; } } - else if (!this.mergeItemStack(itemstack1, 10, 46, false)) + else if (!this.mergeItemStack(itemstack1, this.craftSlots + 1, this.craftSlots + 37, false)) { return null; } diff --git a/server/src/server/world/Converter.java b/server/src/server/world/Converter.java index 7564a9e..d5f31c0 100644 --- a/server/src/server/world/Converter.java +++ b/server/src/server/world/Converter.java @@ -521,7 +521,7 @@ public abstract class Converter { mapBlockData(Blocks.redstone, 55); mapBlock(Blocks.diamond_ore, 56); mapBlock(Blocks.diamond_block, 57); - mapBlock(Blocks.crafting_table, 58); + mapBlock(Blocks.workbench, 58); mapBlockData(Blocks.wheat, 59); mapBlockData(Blocks.farmland, 60); mapBlockData(Blocks.furnace, 61); diff --git a/server/src/server/worldgen/structure/StructureScattered.java b/server/src/server/worldgen/structure/StructureScattered.java index 8723035..8b30816 100755 --- a/server/src/server/worldgen/structure/StructureScattered.java +++ b/server/src/server/worldgen/structure/StructureScattered.java @@ -650,7 +650,7 @@ public class StructureScattered this.setBlockState(worldIn, Blocks.air.getState(), 5, 3, 4, structureBoundingBoxIn); this.setBlockState(worldIn, Blocks.air.getState(), 5, 3, 5, structureBoundingBoxIn); this.setBlockState(worldIn, Blocks.flower_pot.getState().withProperty(BlockFlowerPot.CONTENTS, 2 + BlockFlower.EnumFlowerType.BLACK_LOTUS.getMeta()), 1, 3, 5, structureBoundingBoxIn); - this.setBlockState(worldIn, Blocks.crafting_table.getState(), 3, 2, 6, structureBoundingBoxIn); + this.setBlockState(worldIn, Blocks.workbench.getState(), 3, 2, 6, structureBoundingBoxIn); this.setBlockState(worldIn, Blocks.cauldron.getState(), 4, 2, 6, structureBoundingBoxIn); this.setBlockState(worldIn, Blocks.oak_fence.getState(), 1, 2, 1, structureBoundingBoxIn); this.setBlockState(worldIn, Blocks.oak_fence.getState(), 5, 2, 1, structureBoundingBoxIn); diff --git a/server/src/server/worldgen/structure/StructureVillage.java b/server/src/server/worldgen/structure/StructureVillage.java index 0fb61ae..905d5ca 100755 --- a/server/src/server/worldgen/structure/StructureVillage.java +++ b/server/src/server/worldgen/structure/StructureVillage.java @@ -806,7 +806,7 @@ public class StructureVillage this.setBlockState(worldIn, Blocks.wooden_pressure_plate.getState(), 6, 2, 3, structureBoundingBoxIn); this.setBlockState(worldIn, Blocks.oak_fence.getState(), 4, 1, 3, structureBoundingBoxIn); this.setBlockState(worldIn, Blocks.wooden_pressure_plate.getState(), 4, 2, 3, structureBoundingBoxIn); - this.setBlockState(worldIn, Blocks.crafting_table.getState(), 7, 1, 1, structureBoundingBoxIn); + this.setBlockState(worldIn, Blocks.workbench.getState(), 7, 1, 1, structureBoundingBoxIn); this.setBlockState(worldIn, Blocks.air.getState(), 1, 1, 0, structureBoundingBoxIn); this.setBlockState(worldIn, Blocks.air.getState(), 1, 2, 0, structureBoundingBoxIn); this.placeDoorCurrentPosition(worldIn, structureBoundingBoxIn, randomIn, 1, 1, 0, Facing.getHorizontal(this.getMetadataWithOffset(Blocks.oak_door, 1))); From 7fd8879c7319c6129e95f835848963122e1ebccf Mon Sep 17 00:00:00 2001 From: Sen Date: Sun, 25 May 2025 12:13:15 +0200 Subject: [PATCH 069/200] general Block* code cleanup --- client/src/client/Client.java | 14 +- .../src/client/gui/container/GuiCrafting.java | 2 +- client/src/client/network/ClientPlayer.java | 2 +- .../src/client/renderer/ActiveRenderInfo.java | 2 +- client/src/client/renderer/BlockRenderer.java | 2 +- .../src/client/renderer/EntityRenderer.java | 3 +- .../client/renderer/RegionRenderCache.java | 2 +- client/src/client/renderer/RenderGlobal.java | 12 +- .../renderer/blockmodel/ModelManager.java | 2 +- .../renderer/entity/RenderTntPrimed.java | 2 +- .../renderer/particle/EffectRenderer.java | 4 +- .../renderer/particle/EntityDownfallFX.java | 2 +- .../particle/EntityDropParticleFX.java | 2 +- .../tileentity/TileEntityChestRenderer.java | 2 +- .../tileentity/TileEntityPistonRenderer.java | 7 +- client/src/client/util/PlayerController.java | 8 +- client/src/client/world/WorldClient.java | 4 +- .../common/ai/EntityAIControlledByPlayer.java | 8 +- .../src/common/ai/EntityAIDoorInteract.java | 2 +- common/src/common/ai/EntityAIEatGrass.java | 2 +- common/src/common/ai/EntityAIOcelotSit.java | 2 +- common/src/common/ai/EntityAITakePlace.java | 5 +- common/src/common/block/Block.java | 2226 +++++++---------- common/src/common/block/BlockAir.java | 64 +- common/src/common/block/BlockBreakable.java | 48 - common/src/common/block/BlockColored.java | 83 +- common/src/common/block/BlockContainer.java | 60 +- common/src/common/block/BlockDirectional.java | 12 +- common/src/common/block/BlockFalling.java | 132 +- common/src/common/block/BlockGlass.java | 38 - common/src/common/block/BlockIce.java | 94 - .../src/common/block/BlockRotatedPillar.java | 16 +- common/src/common/block/BlockSlime.java | 93 - common/src/common/block/BlockSnowBlock.java | 47 - .../src/common/block/BlockStainedGlass.java | 120 - common/src/common/block/BlockTranslucent.java | 28 + common/src/common/block/BlockTreasure.java | 4 +- .../src/common/block/ITileEntityProvider.java | 5 +- .../block/{ => artificial}/BlockBed.java | 4 +- .../{ => artificial}/BlockBookshelf.java | 3 +- .../block/{ => artificial}/BlockCake.java | 3 +- .../block/{ => artificial}/BlockCarpet.java | 3 +- .../BlockCompressedPowered.java | 3 +- .../block/{ => artificial}/BlockDoor.java | 3 +- .../{ => artificial}/BlockDragonEgg.java | 7 +- .../block/{ => artificial}/BlockFence.java | 5 +- .../{ => artificial}/BlockFenceGate.java | 4 +- .../{ => artificial}/BlockFloorPortal.java | 3 +- .../{ => artificial}/BlockFlowerPot.java | 4 +- .../common/block/artificial/BlockGlass.java | 44 + .../block/{ => artificial}/BlockHay.java | 3 +- .../block/{ => artificial}/BlockLadder.java | 4 +- .../block/{ => artificial}/BlockPane.java | 3 +- .../block/{ => artificial}/BlockPortal.java | 25 +- .../{ => artificial}/BlockPortalFrame.java | 3 +- .../block/{ => artificial}/BlockQuartz.java | 3 +- .../block/{ => artificial}/BlockSlab.java | 3 +- .../block/artificial/BlockStainedGlass.java | 52 + .../BlockStainedGlassPane.java | 2 +- .../block/{ => artificial}/BlockStairs.java | 15 +- .../{ => artificial}/BlockStoneBrick.java | 3 +- .../block/{ => artificial}/BlockTrapDoor.java | 5 +- .../block/{ => artificial}/BlockWall.java | 14 +- .../block/{ => foliage}/BlockBaseFlower.java | 2 +- .../{ => foliage}/BlockBlackenedSoil.java | 3 +- .../block/{ => foliage}/BlockBlueShroom.java | 3 +- .../common/block/{ => foliage}/BlockBush.java | 3 +- .../block/{ => foliage}/BlockCactus.java | 3 +- .../block/{ => foliage}/BlockCarrot.java | 2 +- .../block/{ => foliage}/BlockCocoa.java | 4 +- .../block/{ => foliage}/BlockCrops.java | 4 +- .../block/{ => foliage}/BlockDeadBush.java | 3 +- .../block/{ => foliage}/BlockDoublePlant.java | 5 +- .../block/{ => foliage}/BlockDryLeaves.java | 3 +- .../block/{ => foliage}/BlockFarmland.java | 4 +- .../block/{ => foliage}/BlockFlower.java | 2 +- .../block/{ => foliage}/BlockGrass.java | 4 +- .../{ => foliage}/BlockHugeMushroom.java | 3 +- .../block/{ => foliage}/BlockLeaves.java | 4 +- .../block/{ => foliage}/BlockLeavesBase.java | 3 +- .../block/{ => foliage}/BlockLilyPad.java | 6 +- .../common/block/{ => foliage}/BlockLog.java | 4 +- .../block/{ => foliage}/BlockMelon.java | 3 +- .../block/{ => foliage}/BlockMushroom.java | 4 +- .../block/{ => foliage}/BlockMycelium.java | 4 +- .../block/{ => foliage}/BlockPotato.java | 2 +- .../block/{ => foliage}/BlockPumpkin.java | 5 +- .../common/block/{ => foliage}/BlockReed.java | 3 +- .../block/{ => foliage}/BlockSapling.java | 2 +- .../common/block/{ => foliage}/BlockStem.java | 6 +- .../block/{ => foliage}/BlockTallGrass.java | 2 +- .../block/{ => foliage}/BlockTianSoil.java | 3 +- .../common/block/{ => foliage}/BlockVine.java | 11 +- .../common/block/{ => foliage}/BlockWart.java | 3 +- .../common/block/{ => foliage}/IGrowable.java | 2 +- .../block/{ => foliage}/LeavesType.java | 2 +- .../{ => liquid}/BlockDynamicLiquid.java | 6 +- .../block/{ => liquid}/BlockLiquid.java | 9 +- .../block/{ => liquid}/BlockStaticLiquid.java | 7 +- .../block/{ => natural}/BlockBedrock.java | 3 +- .../{ => natural}/BlockBlackenedDirt.java | 3 +- .../{ => natural}/BlockBlackenedStone.java | 3 +- .../common/block/{ => natural}/BlockClay.java | 3 +- .../common/block/{ => natural}/BlockDirt.java | 3 +- .../common/block/{ => natural}/BlockFire.java | 17 +- .../block/{ => natural}/BlockGlowstone.java | 3 +- .../block/{ => natural}/BlockGravel.java | 10 +- .../{ => natural}/BlockHardenedClay.java | 3 +- .../block/{ => natural}/BlockHellRock.java | 3 +- common/src/common/block/natural/BlockIce.java | 65 + .../block/{ => natural}/BlockObsidian.java | 3 +- .../common/block/{ => natural}/BlockOre.java | 3 +- .../block/{ => natural}/BlockPackedIce.java | 3 +- .../block/{ => natural}/BlockRedstoneOre.java | 3 +- .../common/block/{ => natural}/BlockRock.java | 3 +- .../common/block/{ => natural}/BlockSand.java | 6 +- .../block/{ => natural}/BlockSandStone.java | 3 +- .../src/common/block/natural/BlockSlime.java | 63 + .../common/block/{ => natural}/BlockSnow.java | 7 +- .../common/block/natural/BlockSnowBlock.java | 36 + .../block/{ => natural}/BlockSoulSand.java | 3 +- .../block/{ => natural}/BlockStone.java | 3 +- .../block/{ => natural}/BlockTintedFire.java | 2 +- .../common/block/{ => natural}/BlockWeb.java | 3 +- .../common/block/{ => tech}/BlockAnvil.java | 3 +- .../{ => tech}/BlockBasePressurePlate.java | 4 +- .../common/block/{ => tech}/BlockBeacon.java | 4 +- .../block/{ => tech}/BlockBrewingStand.java | 3 +- .../common/block/{ => tech}/BlockButton.java | 3 +- .../block/{ => tech}/BlockCauldron.java | 3 +- .../common/block/{ => tech}/BlockChest.java | 4 +- .../common/block/{ => tech}/BlockCore.java | 3 +- .../{ => tech}/BlockDaylightDetector.java | 4 +- .../block/{ => tech}/BlockDispenser.java | 4 +- .../common/block/{ => tech}/BlockDropper.java | 2 +- .../{ => tech}/BlockEnchantmentTable.java | 3 +- .../common/block/{ => tech}/BlockFurnace.java | 4 +- .../common/block/{ => tech}/BlockHopper.java | 4 +- .../common/block/{ => tech}/BlockJukebox.java | 3 +- .../common/block/{ => tech}/BlockLever.java | 3 +- .../common/block/{ => tech}/BlockMachine.java | 5 +- .../block/{ => tech}/BlockMobSpawner.java | 3 +- .../common/block/{ => tech}/BlockNote.java | 4 +- .../common/block/{ => tech}/BlockNuke.java | 3 +- .../block/{ => tech}/BlockPistonBase.java | 13 +- .../block/{ => tech}/BlockPistonHead.java | 4 +- .../block/{ => tech}/BlockPistonMoving.java | 8 +- .../block/{ => tech}/BlockPressurePlate.java | 2 +- .../BlockPressurePlateWeighted.java | 2 +- .../common/block/{ => tech}/BlockRail.java | 3 +- .../block/{ => tech}/BlockRailBase.java | 3 +- .../block/{ => tech}/BlockRailDetector.java | 2 +- .../block/{ => tech}/BlockRailPowered.java | 3 +- .../{ => tech}/BlockRedstoneComparator.java | 6 +- .../block/{ => tech}/BlockRedstoneDiode.java | 4 +- .../block/{ => tech}/BlockRedstoneLight.java | 3 +- .../{ => tech}/BlockRedstoneRepeater.java | 3 +- .../block/{ => tech}/BlockRedstoneTorch.java | 3 +- .../block/{ => tech}/BlockRedstoneWire.java | 3 +- .../block/{ => tech}/BlockSourceImpl.java | 2 +- .../src/common/block/{ => tech}/BlockTNT.java | 3 +- .../block/{ => tech}/BlockTianReactor.java | 2 +- .../common/block/{ => tech}/BlockTorch.java | 5 +- .../block/{ => tech}/BlockTripWire.java | 3 +- .../block/{ => tech}/BlockTripWireHook.java | 3 +- .../block/{ => tech}/BlockWarpChest.java | 3 +- .../block/{ => tech}/BlockWorkbench.java | 3 +- .../common/block/{ => tile}/BlockBanner.java | 4 +- .../common/block/{ => tile}/BlockSign.java | 3 +- .../common/block/{ => tile}/BlockSkull.java | 3 +- .../block/{ => tile}/BlockStandingSign.java | 3 +- .../block/{ => tile}/BlockWallSign.java | 3 +- common/src/common/dimension/Dimension.java | 2 +- .../BehaviorDefaultDispenseItem.java | 2 +- .../dispenser/BehaviorProjectileDispense.java | 2 +- common/src/common/entity/Entity.java | 12 +- .../src/common/entity/animal/EntityHorse.java | 3 +- .../common/entity/animal/EntityRabbit.java | 2 +- .../common/entity/effect/EntityLightning.java | 3 +- common/src/common/entity/item/EntityCart.java | 4 +- .../common/entity/item/EntityChestCart.java | 2 +- .../src/common/entity/item/EntityFalling.java | 7 +- .../common/entity/item/EntityLeashKnot.java | 2 +- .../src/common/entity/item/EntityTntCart.java | 2 +- common/src/common/entity/npc/EntityNPC.java | 2 +- .../common/entity/projectile/EntityArrow.java | 6 +- .../src/common/entity/types/EntityLiving.java | 5 +- .../common/entity/types/EntityThrowable.java | 2 +- common/src/common/init/BlockRegistry.java | 128 +- common/src/common/init/Blocks.java | 72 +- common/src/common/init/CraftingRegistry.java | 18 +- common/src/common/init/DispenserRegistry.java | 14 +- common/src/common/init/FluidRegistry.java | 6 +- common/src/common/init/ItemRegistry.java | 30 +- common/src/common/init/SmeltingRegistry.java | 2 +- common/src/common/init/UniverseRegistry.java | 4 +- .../src/common/inventory/ContainerRepair.java | 2 +- .../common/inventory/ContainerWorkbench.java | 2 +- common/src/common/item/ItemArmor.java | 2 +- common/src/common/item/ItemBanner.java | 4 +- common/src/common/item/ItemBed.java | 2 +- common/src/common/item/ItemBucket.java | 6 +- common/src/common/item/ItemButton.java | 2 +- common/src/common/item/ItemChargedOrb.java | 2 +- common/src/common/item/ItemDoor.java | 2 +- common/src/common/item/ItemDoublePlant.java | 4 +- common/src/common/item/ItemDye.java | 7 +- common/src/common/item/ItemFence.java | 2 +- common/src/common/item/ItemFireball.java | 3 +- common/src/common/item/ItemFlintAndSteel.java | 6 +- common/src/common/item/ItemHoe.java | 5 +- common/src/common/item/ItemLead.java | 2 +- common/src/common/item/ItemLeaves.java | 4 +- common/src/common/item/ItemLilyPad.java | 2 +- common/src/common/item/ItemMinecart.java | 8 +- common/src/common/item/ItemMonsterPlacer.java | 4 +- common/src/common/item/ItemNpcSpawner.java | 4 +- common/src/common/item/ItemPressurePlate.java | 2 +- common/src/common/item/ItemReed.java | 2 +- common/src/common/item/ItemSign.java | 4 +- common/src/common/item/ItemSkull.java | 2 +- common/src/common/item/ItemSlab.java | 2 +- common/src/common/item/ItemSnow.java | 2 +- common/src/common/item/ItemSword.java | 2 +- common/src/common/item/ItemWall.java | 2 +- common/src/common/material/Material.java | 15 +- .../pathfinding/PathNavigateGround.java | 3 +- .../common/pathfinding/WalkNodeProcessor.java | 12 +- .../common/tileentity/TileEntityBanner.java | 2 +- .../tileentity/TileEntityBrewingStand.java | 2 +- .../common/tileentity/TileEntityChest.java | 2 +- .../TileEntityDaylightDetector.java | 2 +- .../common/tileentity/TileEntityFurnace.java | 6 +- .../common/tileentity/TileEntityHopper.java | 4 +- .../src/common/tileentity/TileEntityNote.java | 3 +- common/src/common/village/Village.java | 2 +- common/src/common/world/Chunk.java | 2 +- common/src/common/world/Explosion.java | 11 +- common/src/common/world/World.java | 18 +- server/src/server/biome/BiomeBlackened.java | 2 +- server/src/server/biome/BiomeForest.java | 4 +- server/src/server/biome/BiomeJungle.java | 2 +- server/src/server/biome/BiomeMesa.java | 11 +- server/src/server/biome/BiomePlains.java | 4 +- server/src/server/biome/BiomeSavanna.java | 4 +- server/src/server/biome/BiomeSpace.java | 2 +- server/src/server/biome/BiomeSwamp.java | 5 +- server/src/server/biome/BiomeTaiga.java | 6 +- server/src/server/biome/BiomeTian.java | 2 +- server/src/server/biome/GenBiome.java | 16 +- .../src/server/clipboard/ClipboardPlacer.java | 4 +- .../src/server/clipboard/ReorderRegistry.java | 4 +- .../server/clipboard/RotationRegistry.java | 18 +- server/src/server/network/Player.java | 22 +- .../src/server/village/VillageCollection.java | 2 +- .../src/server/world}/BlockEventData.java | 3 +- server/src/server/world/ChunkServer.java | 3 +- server/src/server/world/Converter.java | 46 +- server/src/server/world/WorldServer.java | 25 +- .../src/server/worldgen/FeatureLiquids.java | 4 +- .../server/worldgen/ReplacerAltSurface.java | 6 +- .../src/server/worldgen/ReplacerTopLayer.java | 3 +- .../server/worldgen/caves/MapGenCaves.java | 2 +- .../feature/WorldGenAbandonedChest.java | 2 +- .../worldgen/feature/WorldGenDesertWells.java | 4 +- .../worldgen/feature/WorldGenGlowStone.java | 3 +- .../worldgen/feature/WorldGenHellLava.java | 3 +- .../worldgen/feature/WorldGenIceSpike.java | 7 +- .../worldgen/foliage/FeatureDoublePlant.java | 2 +- .../worldgen/foliage/WorldGenBigMushroom.java | 4 +- .../worldgen/foliage/WorldGenDeadBush.java | 2 +- .../worldgen/foliage/WorldGenFlowers.java | 2 +- .../worldgen/foliage/WorldGenMushroom.java | 2 +- .../worldgen/foliage/WorldGenPumpkin.java | 2 +- .../worldgen/foliage/WorldGenShrub.java | 4 +- .../worldgen/foliage/WorldGenTallGrass.java | 4 +- .../worldgen/foliage/WorldGenVines.java | 2 +- .../structure/StructureComponent.java | 11 +- .../structure/StructureMineshaft.java | 9 +- .../structure/StructureScattered.java | 14 +- .../structure/StructureStronghold.java | 4 +- .../worldgen/structure/StructureVillage.java | 25 +- .../worldgen/tree/WorldGenBaseTree.java | 20 +- .../server/worldgen/tree/WorldGenBigTree.java | 8 +- .../server/worldgen/tree/WorldGenBirch.java | 6 +- .../server/worldgen/tree/WorldGenDarkOak.java | 8 +- .../worldgen/tree/WorldGenHugeTree.java | 10 +- .../server/worldgen/tree/WorldGenJungle.java | 2 +- .../server/worldgen/tree/WorldGenPine.java | 12 +- .../server/worldgen/tree/WorldGenSavanna.java | 14 +- .../server/worldgen/tree/WorldGenSwamp.java | 18 +- .../server/worldgen/tree/WorldGenTaiga1.java | 4 +- .../server/worldgen/tree/WorldGenTaiga2.java | 6 +- .../server/worldgen/tree/WorldGenTree.java | 7 +- 294 files changed, 2229 insertions(+), 2650 deletions(-) delete mode 100755 common/src/common/block/BlockBreakable.java delete mode 100755 common/src/common/block/BlockGlass.java delete mode 100755 common/src/common/block/BlockIce.java delete mode 100755 common/src/common/block/BlockSlime.java delete mode 100755 common/src/common/block/BlockSnowBlock.java delete mode 100755 common/src/common/block/BlockStainedGlass.java create mode 100755 common/src/common/block/BlockTranslucent.java rename common/src/common/block/{ => artificial}/BlockBed.java (98%) rename common/src/common/block/{ => artificial}/BlockBookshelf.java (93%) rename common/src/common/block/{ => artificial}/BlockCake.java (99%) rename common/src/common/block/{ => artificial}/BlockCarpet.java (98%) rename common/src/common/block/{ => artificial}/BlockCompressedPowered.java (91%) rename common/src/common/block/{ => artificial}/BlockDoor.java (99%) rename common/src/common/block/{ => artificial}/BlockDragonEgg.java (97%) rename common/src/common/block/{ => artificial}/BlockFence.java (97%) rename common/src/common/block/{ => artificial}/BlockFenceGate.java (99%) rename common/src/common/block/{ => artificial}/BlockFloorPortal.java (98%) rename common/src/common/block/{ => artificial}/BlockFlowerPot.java (99%) create mode 100755 common/src/common/block/artificial/BlockGlass.java rename common/src/common/block/{ => artificial}/BlockHay.java (96%) rename common/src/common/block/{ => artificial}/BlockLadder.java (98%) rename common/src/common/block/{ => artificial}/BlockPane.java (99%) rename common/src/common/block/{ => artificial}/BlockPortal.java (97%) rename common/src/common/block/{ => artificial}/BlockPortalFrame.java (98%) rename common/src/common/block/{ => artificial}/BlockQuartz.java (99%) rename common/src/common/block/{ => artificial}/BlockSlab.java (99%) create mode 100755 common/src/common/block/artificial/BlockStainedGlass.java rename common/src/common/block/{ => artificial}/BlockStainedGlassPane.java (98%) rename common/src/common/block/{ => artificial}/BlockStairs.java (98%) rename common/src/common/block/{ => artificial}/BlockStoneBrick.java (98%) rename common/src/common/block/{ => artificial}/BlockTrapDoor.java (97%) rename common/src/common/block/{ => artificial}/BlockWall.java (94%) rename common/src/common/block/{ => foliage}/BlockBaseFlower.java (84%) rename common/src/common/block/{ => foliage}/BlockBlackenedSoil.java (97%) rename common/src/common/block/{ => foliage}/BlockBlueShroom.java (97%) rename common/src/common/block/{ => foliage}/BlockBush.java (97%) rename common/src/common/block/{ => foliage}/BlockCactus.java (98%) rename common/src/common/block/{ => foliage}/BlockCarrot.java (94%) rename common/src/common/block/{ => foliage}/BlockCocoa.java (98%) rename common/src/common/block/{ => foliage}/BlockCrops.java (98%) rename common/src/common/block/{ => foliage}/BlockDeadBush.java (97%) rename common/src/common/block/{ => foliage}/BlockDoublePlant.java (99%) rename common/src/common/block/{ => foliage}/BlockDryLeaves.java (96%) rename common/src/common/block/{ => foliage}/BlockFarmland.java (98%) rename common/src/common/block/{ => foliage}/BlockFlower.java (99%) rename common/src/common/block/{ => foliage}/BlockGrass.java (98%) rename common/src/common/block/{ => foliage}/BlockHugeMushroom.java (99%) rename common/src/common/block/{ => foliage}/BlockLeaves.java (99%) rename common/src/common/block/{ => foliage}/BlockLeavesBase.java (94%) rename common/src/common/block/{ => foliage}/BlockLilyPad.java (95%) rename common/src/common/block/{ => foliage}/BlockLog.java (98%) rename common/src/common/block/{ => foliage}/BlockMelon.java (95%) rename common/src/common/block/{ => foliage}/BlockMushroom.java (97%) rename common/src/common/block/{ => foliage}/BlockMycelium.java (97%) rename common/src/common/block/{ => foliage}/BlockPotato.java (97%) rename common/src/common/block/{ => foliage}/BlockPumpkin.java (97%) rename common/src/common/block/{ => foliage}/BlockReed.java (98%) rename common/src/common/block/{ => foliage}/BlockSapling.java (99%) rename common/src/common/block/{ => foliage}/BlockStem.java (98%) rename common/src/common/block/{ => foliage}/BlockTallGrass.java (99%) rename common/src/common/block/{ => foliage}/BlockTianSoil.java (96%) rename common/src/common/block/{ => foliage}/BlockVine.java (98%) rename common/src/common/block/{ => foliage}/BlockWart.java (98%) rename common/src/common/block/{ => foliage}/IGrowable.java (93%) rename common/src/common/block/{ => foliage}/LeavesType.java (93%) rename common/src/common/block/{ => liquid}/BlockDynamicLiquid.java (97%) rename common/src/common/block/{ => liquid}/BlockLiquid.java (97%) rename common/src/common/block/{ => liquid}/BlockStaticLiquid.java (94%) rename common/src/common/block/{ => natural}/BlockBedrock.java (89%) rename common/src/common/block/{ => natural}/BlockBlackenedDirt.java (96%) rename common/src/common/block/{ => natural}/BlockBlackenedStone.java (89%) rename common/src/common/block/{ => natural}/BlockClay.java (92%) rename common/src/common/block/{ => natural}/BlockDirt.java (99%) rename common/src/common/block/{ => natural}/BlockFire.java (99%) rename common/src/common/block/{ => natural}/BlockGlowstone.java (95%) rename common/src/common/block/{ => natural}/BlockGravel.java (76%) rename common/src/common/block/{ => natural}/BlockHardenedClay.java (87%) rename common/src/common/block/{ => natural}/BlockHellRock.java (89%) create mode 100755 common/src/common/block/natural/BlockIce.java rename common/src/common/block/{ => natural}/BlockObsidian.java (93%) rename common/src/common/block/{ => natural}/BlockOre.java (98%) rename common/src/common/block/{ => natural}/BlockPackedIce.java (88%) rename common/src/common/block/{ => natural}/BlockRedstoneOre.java (98%) rename common/src/common/block/{ => natural}/BlockRock.java (95%) rename common/src/common/block/{ => natural}/BlockSand.java (95%) rename common/src/common/block/{ => natural}/BlockSandStone.java (98%) create mode 100755 common/src/common/block/natural/BlockSlime.java rename common/src/common/block/{ => natural}/BlockSnow.java (95%) create mode 100755 common/src/common/block/natural/BlockSnowBlock.java rename common/src/common/block/{ => natural}/BlockSoulSand.java (94%) rename common/src/common/block/{ => natural}/BlockStone.java (89%) rename common/src/common/block/{ => natural}/BlockTintedFire.java (96%) rename common/src/common/block/{ => natural}/BlockWeb.java (96%) rename common/src/common/block/{ => tech}/BlockAnvil.java (99%) rename common/src/common/block/{ => tech}/BlockBasePressurePlate.java (98%) rename common/src/common/block/{ => tech}/BlockBeacon.java (97%) rename common/src/common/block/{ => tech}/BlockBrewingStand.java (99%) rename common/src/common/block/{ => tech}/BlockButton.java (99%) rename common/src/common/block/{ => tech}/BlockCauldron.java (99%) rename common/src/common/block/{ => tech}/BlockChest.java (99%) rename common/src/common/block/{ => tech}/BlockCore.java (91%) rename common/src/common/block/{ => tech}/BlockDaylightDetector.java (98%) rename common/src/common/block/{ => tech}/BlockDispenser.java (99%) rename common/src/common/block/{ => tech}/BlockDropper.java (99%) rename common/src/common/block/{ => tech}/BlockEnchantmentTable.java (98%) rename common/src/common/block/{ => tech}/BlockFurnace.java (99%) rename common/src/common/block/{ => tech}/BlockHopper.java (99%) rename common/src/common/block/{ => tech}/BlockJukebox.java (94%) rename common/src/common/block/{ => tech}/BlockLever.java (99%) rename common/src/common/block/{ => tech}/BlockMachine.java (96%) rename common/src/common/block/{ => tech}/BlockMobSpawner.java (97%) rename common/src/common/block/{ => tech}/BlockNote.java (97%) rename common/src/common/block/{ => tech}/BlockNuke.java (97%) rename common/src/common/block/{ => tech}/BlockPistonBase.java (97%) rename common/src/common/block/{ => tech}/BlockPistonHead.java (99%) rename common/src/common/block/{ => tech}/BlockPistonMoving.java (98%) rename common/src/common/block/{ => tech}/BlockPressurePlate.java (99%) rename common/src/common/block/{ => tech}/BlockPressurePlateWeighted.java (98%) rename common/src/common/block/{ => tech}/BlockRail.java (96%) rename common/src/common/block/{ => tech}/BlockRailBase.java (99%) rename common/src/common/block/{ => tech}/BlockRailDetector.java (99%) rename common/src/common/block/{ => tech}/BlockRailPowered.java (99%) rename common/src/common/block/{ => tech}/BlockRedstoneComparator.java (99%) rename common/src/common/block/{ => tech}/BlockRedstoneDiode.java (99%) rename common/src/common/block/{ => tech}/BlockRedstoneLight.java (97%) rename common/src/common/block/{ => tech}/BlockRedstoneRepeater.java (99%) rename common/src/common/block/{ => tech}/BlockRedstoneTorch.java (99%) rename common/src/common/block/{ => tech}/BlockRedstoneWire.java (99%) rename common/src/common/block/{ => tech}/BlockSourceImpl.java (97%) rename common/src/common/block/{ => tech}/BlockTNT.java (99%) rename common/src/common/block/{ => tech}/BlockTianReactor.java (96%) rename common/src/common/block/{ => tech}/BlockTorch.java (98%) rename common/src/common/block/{ => tech}/BlockTripWire.java (99%) rename common/src/common/block/{ => tech}/BlockTripWireHook.java (99%) rename common/src/common/block/{ => tech}/BlockWarpChest.java (98%) rename common/src/common/block/{ => tech}/BlockWorkbench.java (97%) rename common/src/common/block/{ => tile}/BlockBanner.java (98%) rename common/src/common/block/{ => tile}/BlockSign.java (98%) rename common/src/common/block/{ => tile}/BlockSkull.java (98%) rename common/src/common/block/{ => tile}/BlockStandingSign.java (96%) rename common/src/common/block/{ => tile}/BlockWallSign.java (97%) rename {common/src/common/block => server/src/server/world}/BlockEventData.java (96%) diff --git a/client/src/client/Client.java b/client/src/client/Client.java index c3c6e18..3c249a0 100755 --- a/client/src/client/Client.java +++ b/client/src/client/Client.java @@ -114,6 +114,7 @@ import common.future.ListenableFuture; import common.future.ListenableFutureTask; import common.future.ThreadFactoryBuilder; import common.init.BlockRegistry; +import common.init.Blocks; import common.init.Config; import common.init.EntityRegistry; import common.init.ItemRegistry; @@ -129,7 +130,6 @@ import common.item.ItemStack; import common.log.Log; import common.log.LogLevel; import common.log.Message; -import common.material.Material; import common.network.IThreadListener; import common.network.NetConnection; import common.network.PacketDecoder; @@ -1267,7 +1267,7 @@ public class Client implements IThreadListener { { BlockPos blockpos = this.pointed.block; - if (this.world.getState(blockpos).getBlock().getMaterial() != Material.air && this.controller.onPlayerDamageBlock(blockpos, this.pointed.side)) + if (this.world.getState(blockpos).getBlock() != Blocks.air && this.controller.onPlayerDamageBlock(blockpos, this.pointed.side)) { this.effectRenderer.addBlockHitEffects(blockpos, this.pointed.side); this.player.swingItem(); @@ -1293,7 +1293,7 @@ public class Client implements IThreadListener { else { ItemStack itemstack = this.player.inventory.getCurrentItem(); - if ((this.pointed.type != ObjectType.BLOCK || this.world.getState(this.pointed.block).getBlock().getMaterial() == Material.air) && itemstack != null && itemstack.getItem().onAction(itemstack, this.player, this.world, ItemControl.PRIMARY, null)) + if ((this.pointed.type != ObjectType.BLOCK || this.world.getState(this.pointed.block).getBlock() == Blocks.air) && itemstack != null && itemstack.getItem().onAction(itemstack, this.player, this.world, ItemControl.PRIMARY, null)) { this.player.swingItem(); this.player.client.addToSendQueue(new CPacketAction(Action.ITEM_ACTION, ItemControl.PRIMARY.ordinal())); @@ -1310,7 +1310,7 @@ public class Client implements IThreadListener { case BLOCK: this.player.swingItem(); BlockPos blockpos = this.pointed.block; - if (this.world.getState(blockpos).getBlock().getMaterial() != Material.air) + if (this.world.getState(blockpos).getBlock() != Blocks.air) { this.controller.clickBlock(blockpos, this.pointed.side); break; @@ -1345,7 +1345,7 @@ public class Client implements IThreadListener { } else { - if ((this.pointed.type != ObjectType.BLOCK || this.world.getState(this.pointed.block).getBlock().getMaterial() == Material.air) && itemstack != null && itemstack.getItem().onAction(itemstack, this.player, this.world, ItemControl.SECONDARY, null)) + if ((this.pointed.type != ObjectType.BLOCK || this.world.getState(this.pointed.block).getBlock() == Blocks.air) && itemstack != null && itemstack.getItem().onAction(itemstack, this.player, this.world, ItemControl.SECONDARY, null)) { this.player.swingItem(); this.player.client.addToSendQueue(new CPacketAction(Action.ITEM_ACTION, ItemControl.SECONDARY.ordinal())); @@ -1370,7 +1370,7 @@ public class Client implements IThreadListener { case BLOCK: BlockPos blockpos = this.pointed.block; - if (this.world.getState(blockpos).getBlock().getMaterial() != Material.air) + if (this.world.getState(blockpos).getBlock() != Blocks.air) { int i = itemstack != null ? itemstack.stackSize : 0; @@ -1430,7 +1430,7 @@ public class Client implements IThreadListener { BlockPos blockpos = this.pointed.block; Block block = this.world.getState(blockpos).getBlock(); - if (block.getMaterial() == Material.air) + if (block == Blocks.air) { return; } diff --git a/client/src/client/gui/container/GuiCrafting.java b/client/src/client/gui/container/GuiCrafting.java index 954e6cf..36b3eb5 100755 --- a/client/src/client/gui/container/GuiCrafting.java +++ b/client/src/client/gui/container/GuiCrafting.java @@ -1,6 +1,6 @@ package client.gui.container; -import common.block.BlockWorkbench; +import common.block.tech.BlockWorkbench; import common.inventory.ContainerWorkbench; import common.inventory.InventoryPlayer; import common.util.BlockPos; diff --git a/client/src/client/network/ClientPlayer.java b/client/src/client/network/ClientPlayer.java index 94602af..dfd828a 100755 --- a/client/src/client/network/ClientPlayer.java +++ b/client/src/client/network/ClientPlayer.java @@ -35,7 +35,7 @@ import common.attributes.AttributeInstance; import common.attributes.AttributeMap; import common.attributes.AttributeModifier; import common.block.Block; -import common.block.BlockWorkbench; +import common.block.tech.BlockWorkbench; import common.collect.Lists; import common.collect.Maps; import common.dimension.Dimension; diff --git a/client/src/client/renderer/ActiveRenderInfo.java b/client/src/client/renderer/ActiveRenderInfo.java index 653eff6..a8e79b2 100755 --- a/client/src/client/renderer/ActiveRenderInfo.java +++ b/client/src/client/renderer/ActiveRenderInfo.java @@ -8,7 +8,7 @@ import java.nio.IntBuffer; import org.lwjgl.opengl.GL11; import common.block.Block; -import common.block.BlockLiquid; +import common.block.liquid.BlockLiquid; import common.entity.Entity; import common.entity.npc.EntityNPC; import common.util.BlockPos; diff --git a/client/src/client/renderer/BlockRenderer.java b/client/src/client/renderer/BlockRenderer.java index 0288aaf..ce1f00d 100755 --- a/client/src/client/renderer/BlockRenderer.java +++ b/client/src/client/renderer/BlockRenderer.java @@ -15,7 +15,7 @@ import client.renderer.texture.TextureAtlasSprite; import client.renderer.texture.TextureMap; import client.renderer.tileentity.TileEntityItemStackRenderer; import common.block.Block; -import common.block.BlockLiquid; +import common.block.liquid.BlockLiquid; import common.collect.Maps; import common.init.BlockRegistry; import common.init.FluidRegistry; diff --git a/client/src/client/renderer/EntityRenderer.java b/client/src/client/renderer/EntityRenderer.java index d9dd6a3..919707d 100755 --- a/client/src/client/renderer/EntityRenderer.java +++ b/client/src/client/renderer/EntityRenderer.java @@ -20,6 +20,7 @@ import common.entity.Entity; import common.entity.npc.EntityNPC; import common.entity.types.EntityAnimal; import common.entity.types.EntityLiving; +import common.init.Blocks; import common.init.Items; import common.init.SoundEvent; import common.material.Material; @@ -1168,7 +1169,7 @@ public class EntityRenderer { if(temp < 194.0f || this.random.chance(5)) this.gm.world.spawnParticle(temp >= 194.0f && this.random.chance(10) ? ParticleType.LAVA : ParticleType.SMOKE_NORMAL, (double)blockpos1.getX() + d3, (double)((float)blockpos1.getY() + 0.1F) - block.getBlockBoundsMinY(), (double)blockpos1.getZ() + d4, 0.0D, 0.0D, 0.0D); } - else if (block.getMaterial() != Material.air) + else if (block != Blocks.air) { block.setBlockBoundsBasedOnState(world, blockpos2); ++j; diff --git a/client/src/client/renderer/RegionRenderCache.java b/client/src/client/renderer/RegionRenderCache.java index 5d90530..d2cba9e 100755 --- a/client/src/client/renderer/RegionRenderCache.java +++ b/client/src/client/renderer/RegionRenderCache.java @@ -192,7 +192,7 @@ public class RegionRenderCache implements IWorldAccess // */ // public boolean isAirBlock(BlockPos pos) // { -// return this.getBlockState(pos).getBlock().getMaterial() == Material.air; +// return this.getBlockState(pos).getBlock() == Blocks.air; // } public int getLightFor(LightType p_175628_1_, BlockPos pos) diff --git a/client/src/client/renderer/RenderGlobal.java b/client/src/client/renderer/RenderGlobal.java index 302609c..46d270e 100755 --- a/client/src/client/renderer/RenderGlobal.java +++ b/client/src/client/renderer/RenderGlobal.java @@ -28,9 +28,9 @@ import client.renderer.tileentity.TileEntityRendererDispatcher; import client.world.ChunkClient; import client.world.WorldClient; import common.block.Block; -import common.block.BlockChest; -import common.block.BlockSign; -import common.block.BlockSkull; +import common.block.tech.BlockChest; +import common.block.tile.BlockSign; +import common.block.tile.BlockSkull; import common.collect.Lists; import common.collect.Maps; import common.collect.Sets; @@ -38,7 +38,7 @@ import common.entity.Entity; import common.entity.npc.EntityNPC; import common.entity.projectile.EntityBox; import common.entity.types.EntityLiving; -import common.material.Material; +import common.init.Blocks; import common.model.BlockLayer; import common.rng.Random; import common.sound.Sound; @@ -1580,7 +1580,7 @@ public class RenderGlobal { State iblockstate = this.theWorld.getState(blockpos); - if (iblockstate.getBlock().getMaterial() != Material.air) + if (iblockstate.getBlock() != Blocks.air) { int i = destroyblockprogress.getPartialBlockDamage(); TextureAtlasSprite textureatlassprite = this.destroyBlockIcons[i]; @@ -1616,7 +1616,7 @@ public class RenderGlobal BlockPos blockpos = movingObjectPositionIn.block; Block block = this.theWorld.getState(blockpos).getBlock(); - if (block.getMaterial() != Material.air) // && this.theWorld.getWorldBorder().contains(blockpos)) + if (block != Blocks.air) // && this.theWorld.getWorldBorder().contains(blockpos)) { block.setBlockBoundsBasedOnState(this.theWorld, blockpos); double d0 = player.lastTickPosX + (player.posX - player.lastTickPosX) * (double)partialTicks; diff --git a/client/src/client/renderer/blockmodel/ModelManager.java b/client/src/client/renderer/blockmodel/ModelManager.java index 5984f9a..50484e1 100755 --- a/client/src/client/renderer/blockmodel/ModelManager.java +++ b/client/src/client/renderer/blockmodel/ModelManager.java @@ -8,7 +8,7 @@ import java.util.Set; import client.renderer.texture.TextureAtlasSprite; import client.renderer.texture.TextureMap; import common.block.Block; -import common.block.BlockLiquid; +import common.block.liquid.BlockLiquid; import common.collect.Maps; import common.init.BlockRegistry; import common.init.Blocks; diff --git a/client/src/client/renderer/entity/RenderTntPrimed.java b/client/src/client/renderer/entity/RenderTntPrimed.java index 85aa3f8..616fd3b 100755 --- a/client/src/client/renderer/entity/RenderTntPrimed.java +++ b/client/src/client/renderer/entity/RenderTntPrimed.java @@ -6,7 +6,7 @@ import client.Client; import client.renderer.BlockRenderer; import client.renderer.GlState; import client.renderer.texture.TextureMap; -import common.block.BlockTNT; +import common.block.tech.BlockTNT; import common.entity.item.EntityTnt; import common.init.Blocks; import common.util.ExtMath; diff --git a/client/src/client/renderer/particle/EffectRenderer.java b/client/src/client/renderer/particle/EffectRenderer.java index 5d6ea5f..49d88cb 100755 --- a/client/src/client/renderer/particle/EffectRenderer.java +++ b/client/src/client/renderer/particle/EffectRenderer.java @@ -16,7 +16,7 @@ import common.block.Block; import common.collect.Lists; import common.collect.Maps; import common.entity.Entity; -import common.material.Material; +import common.init.Blocks; import common.model.ParticleType; import common.rng.Random; import common.util.BlockPos; @@ -319,7 +319,7 @@ public class EffectRenderer public void addBlockDestroyEffects(BlockPos pos, State state) { - if (state.getBlock().getMaterial() != Material.air) + if (state.getBlock() != Blocks.air) { state = state.getBlock().getActualState(state, this.worldObj, pos); int i = 4; diff --git a/client/src/client/renderer/particle/EntityDownfallFX.java b/client/src/client/renderer/particle/EntityDownfallFX.java index b2bd951..6b5191e 100755 --- a/client/src/client/renderer/particle/EntityDownfallFX.java +++ b/client/src/client/renderer/particle/EntityDownfallFX.java @@ -1,7 +1,7 @@ package client.renderer.particle; import common.block.Block; -import common.block.BlockLiquid; +import common.block.liquid.BlockLiquid; import common.material.Material; import common.util.BlockPos; import common.util.ExtMath; diff --git a/client/src/client/renderer/particle/EntityDropParticleFX.java b/client/src/client/renderer/particle/EntityDropParticleFX.java index 90542cd..6bed5e8 100755 --- a/client/src/client/renderer/particle/EntityDropParticleFX.java +++ b/client/src/client/renderer/particle/EntityDropParticleFX.java @@ -1,6 +1,6 @@ package client.renderer.particle; -import common.block.BlockLiquid; +import common.block.liquid.BlockLiquid; import common.material.Material; import common.model.ParticleType; import common.util.BlockPos; diff --git a/client/src/client/renderer/tileentity/TileEntityChestRenderer.java b/client/src/client/renderer/tileentity/TileEntityChestRenderer.java index 4fbb70f..3e543fd 100755 --- a/client/src/client/renderer/tileentity/TileEntityChestRenderer.java +++ b/client/src/client/renderer/tileentity/TileEntityChestRenderer.java @@ -6,7 +6,7 @@ import client.renderer.GlState; import client.renderer.model.ModelChest; import client.renderer.model.ModelLargeChest; import common.block.Block; -import common.block.BlockChest; +import common.block.tech.BlockChest; import common.tileentity.TileEntityChest; diff --git a/client/src/client/renderer/tileentity/TileEntityPistonRenderer.java b/client/src/client/renderer/tileentity/TileEntityPistonRenderer.java index ce055f1..f40c247 100755 --- a/client/src/client/renderer/tileentity/TileEntityPistonRenderer.java +++ b/client/src/client/renderer/tileentity/TileEntityPistonRenderer.java @@ -11,10 +11,9 @@ import client.renderer.RenderBuffer; import client.renderer.Tessellator; import client.renderer.texture.TextureMap; import common.block.Block; -import common.block.BlockPistonBase; -import common.block.BlockPistonHead; +import common.block.tech.BlockPistonBase; +import common.block.tech.BlockPistonHead; import common.init.Blocks; -import common.material.Material; import common.tileentity.TileEntityPiston; import common.util.BlockPos; import common.world.State; @@ -30,7 +29,7 @@ public class TileEntityPistonRenderer extends TileEntitySpecialRenderer implements Iterable - { - private final Class clazz; - private final Iterable [] iterables; +public class Block { + private static class Product implements Iterable { + private final Class clazz; + private final Iterable[] iterables; - private Product(Class clazz, Iterable [] iterables) - { - this.clazz = clazz; - this.iterables = iterables; - } + private Product(Class clazz, Iterable[] iterables) { + this.clazz = clazz; + this.iterables = iterables; + } - public Iterator iterator() - { - return (Iterator)(this.iterables.length <= 0 ? Collections.singletonList((Object[])createArray(this.clazz, 0)).iterator() : new Product.ProductIterator(this.clazz, this.iterables)); - } + public Iterator iterator() { + return (Iterator)(this.iterables.length <= 0 ? Collections.singletonList((Object[])createArray(this.clazz, 0)).iterator() + : new Product.ProductIterator(this.clazz, this.iterables)); + } - static class ProductIterator extends UnmodifiableIterator - { - private int index; - private final Iterable [] iterables; - private final Iterator [] iterators; - private final T[] results; + static class ProductIterator extends UnmodifiableIterator { + private int index; + private final Iterable[] iterables; + private final Iterator[] iterators; + private final T[] results; - private ProductIterator(Class clazz, Iterable [] iterables) - { - this.index = -2; - this.iterables = iterables; - this.iterators = (Iterator[])createArray(Iterator.class, this.iterables.length); + private ProductIterator(Class clazz, Iterable[] iterables) { + this.index = -2; + this.iterables = iterables; + this.iterators = (Iterator[])createArray(Iterator.class, this.iterables.length); - for (int i = 0; i < this.iterables.length; ++i) - { - this.iterators[i] = iterables[i].iterator(); - } + for(int i = 0; i < this.iterables.length; ++i) { + this.iterators[i] = iterables[i].iterator(); + } - this.results = createArray(clazz, this.iterators.length); - } + this.results = createArray(clazz, this.iterators.length); + } - private void endOfData() - { - this.index = -1; - Arrays.fill(this.iterators, (Object)null); - Arrays.fill(this.results, (Object)null); - } + private void endOfData() { + this.index = -1; + Arrays.fill(this.iterators, (Object)null); + Arrays.fill(this.results, (Object)null); + } - public boolean hasNext() - { - if (this.index == -2) - { - this.index = 0; + public boolean hasNext() { + if(this.index == -2) { + this.index = 0; - for (Iterator iterator1 : this.iterators) - { - if (!iterator1.hasNext()) - { - this.endOfData(); - break; - } - } + for(Iterator iterator : this.iterators) { + if(!iterator.hasNext()) { + this.endOfData(); + break; + } + } - return true; - } - else - { - if (this.index >= this.iterators.length) - { - for (this.index = this.iterators.length - 1; this.index >= 0; --this.index) - { - Iterator iterator = this.iterators[this.index]; + return true; + } + else { + if(this.index >= this.iterators.length) { + for(this.index = this.iterators.length - 1; this.index >= 0; --this.index) { + Iterator iterator = this.iterators[this.index]; - if (iterator.hasNext()) - { - break; - } + if(iterator.hasNext()) { + break; + } - if (this.index == 0) - { - this.endOfData(); - break; - } + if(this.index == 0) { + this.endOfData(); + break; + } - iterator = this.iterables[this.index].iterator(); - this.iterators[this.index] = iterator; + iterator = this.iterables[this.index].iterator(); + this.iterators[this.index] = iterator; - if (!iterator.hasNext()) - { - this.endOfData(); - break; - } - } - } + if(!iterator.hasNext()) { + this.endOfData(); + break; + } + } + } - return this.index >= 0; - } - } + return this.index >= 0; + } + } - public T[] next() - { - if (!this.hasNext()) - { - throw new NoSuchElementException(); - } - else - { - while (this.index < this.iterators.length) - { - this.results[this.index] = this.iterators[this.index].next(); - ++this.index; - } + public T[] next() { + if(!this.hasNext()) { + throw new NoSuchElementException(); + } + else { + while(this.index < this.iterators.length) { + this.results[this.index] = this.iterators[this.index].next(); + ++this.index; + } - return (T[])((Object[])this.results.clone()); - } - } - } - } + return (T[])((Object[])this.results.clone()); + } + } + } + } - private static class GetList implements Function> - { - private GetList() - { - } + private static class GetList implements Function> { + private GetList() { + } + + public List apply(Object[] data) { + return Arrays.asList((T[])data); + } + } - public List apply(Object[] p_apply_1_) - { - return Arrays.asList((T[])p_apply_1_); - } - } - private final ImmutableList properties; private final ImmutableList states; - protected final Material material; + protected final Material material; + + protected boolean fullBlock; + protected boolean translucent; + protected boolean sumBrightness; + protected boolean axeHarvest; + protected boolean shovelHarvest; + protected boolean ticked; + protected boolean hasTile; + protected int lightOpacity; + protected int lightValue; + protected int miningLevel; + protected int shearsEfficiency; + protected float blockHardness; + protected float blockResistance; + protected float radiation; + public float slipperiness; + protected double minX; + protected double minY; + protected double minZ; + protected double maxX; + protected double maxY; + protected double maxZ; + private State defaultState; + private String display; + private CheatTab tab; + public SoundType sound; + + private static Iterable> cartesianProduct(Iterable> sets) { + return arraysAsLists(cartesianProduct(Object.class, sets)); + } + + private static Iterable cartesianProduct(Class clazz, Iterable> sets) { + return new Product(clazz, (Iterable[])toArray(Iterable.class, sets)); + } + + private static Iterable> arraysAsLists(Iterable arrays) { + return Iterables.transform(arrays, new GetList()); + } + + private static T[] toArray(Class clazz, Iterable it) { + List list = Lists.newArrayList(); + + for(T t : it) { + list.add(t); + } + + return (T[])((Object[])list.toArray(createArray(clazz, list.size()))); + } + + private static T[] createArray(Class clazz, int size) { + return (T[])((Object[])((Object[])Array.newInstance(clazz, size))); + } + + private static Map createMap(Iterable keys, Iterable values) { + return populateMap(keys, values, Maps.newLinkedHashMap()); + } + + private static Map populateMap(Iterable keys, Iterable values, Map map) { + Iterator iterator = values.iterator(); + + for(IProperty prop : keys) { + map.put(prop, iterator.next()); + } + + if(iterator.hasNext()) { + throw new NoSuchElementException(); + } + else { + return map; + } + } + + private static List> getAllowedValues(List properties) { + List> list = Lists.>newArrayList(); + for(int z = 0; z < properties.size(); z++) { + list.add((properties.get(z)).getAllowedValues()); + } + return list; + } - protected boolean fullBlock; - protected boolean translucent; - protected boolean sumBrightness; - protected boolean axeHarvest; - protected boolean shovelHarvest; -// protected boolean enableStats; - protected boolean ticked; - protected boolean hasTile; - protected int lightOpacity; - protected int lightValue; - protected int miningLevel; - protected int shearsEfficiency; - protected float blockHardness; - protected float blockResistance; - protected float radiation; - public float slipperiness; - protected double minX; - protected double minY; - protected double minZ; - protected double maxX; - protected double maxY; - protected double maxZ; - private State defaultState; - private String display; - private CheatTab tab; - public SoundType sound; - - private static Iterable> cartesianProduct(Iterable > sets) - { - return arraysAsLists(cartesianProduct(Object.class, sets)); - } - - private static Iterable cartesianProduct(Class clazz, Iterable > sets) - { - return new Product(clazz, (Iterable[])toArray(Iterable.class, sets)); - } - - private static Iterable> arraysAsLists(Iterable arrays) - { - return Iterables.transform(arrays, new GetList()); - } - - private static T[] toArray(Class clazz, Iterable it) - { - List list = Lists.newArrayList(); - - for (T t : it) - { - list.add(t); - } - - return (T[])((Object[])list.toArray(createArray(clazz, list.size()))); - } - - private static T[] createArray(Class p_179319_0_, int p_179319_1_) - { - return (T[])((Object[])((Object[])Array.newInstance(p_179319_0_, p_179319_1_))); - } - - private static Map createMap(Iterable keys, Iterable values) - { - return populateMap(keys, values, Maps.newLinkedHashMap()); - } - - private static Map populateMap(Iterable keys, Iterable values, Map map) - { - Iterator iterator = values.iterator(); - - for (IProperty k : keys) - { - map.put(k, iterator.next()); - } - - if (iterator.hasNext()) - { - throw new NoSuchElementException(); - } - else - { - return map; - } - } - - public Block(Material material) - { - this.miningLevel = (material == Material.rock || material == Material.iron || material == Material.anvil) ? 0 : -1; - this.axeHarvest = material == Material.wood || material == Material.plants || material == Material.vine || - material == Material.gourd; - this.shearsEfficiency = (material == Material.leaves || material == Material.web) ? 3 : -1; -// this.enableStats = true; - this.sound = SoundType.STONE; - this.slipperiness = 0.6F; - this.material = material; -// this.blockMapColor = blockMapColorIn; - this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F); - this.fullBlock = this.isOpaqueCube(); - this.lightOpacity = this.isOpaqueCube() ? 255 : 0; - this.translucent = !material.blocksLight(); -// this.smap = new StateList(this, this.getProperties()); - IProperty[] properties = this.getProperties(); + private static ImmutableList getPropertyList(IProperty[] properties) { Arrays.sort(properties, new Comparator() { public int compare(IProperty p1, IProperty p2) { return p1.getName().compareTo(p2.getName()); } }); - this.properties = ImmutableList.copyOf(properties); + return ImmutableList.copyOf(properties); + } + + private static ImmutableList getStateList(List properties, Block block) { Map, State> map = Maps., State>newLinkedHashMap(); List list = Lists.newArrayList(); - for(List allowed : cartesianProduct(this.getAllowedValues())) { - Map props = createMap(this.properties, allowed); - State state = new State(this, ImmutableMap.copyOf(props)); + for(List allowed : cartesianProduct(getAllowedValues(properties))) { + Map props = createMap(properties, allowed); + State state = new State(block, ImmutableMap.copyOf(props)); map.put(props, state); list.add(state); } for(State state : list) { state.buildTable(map); } - this.states = ImmutableList.copyOf(list); - this.setDefaultState(this.getBaseState()); - } + return ImmutableList.copyOf(list); + } - /** - * Sets the footstep sound for the block. Returns the object for convenience in constructing. - */ - public Block setStepSound(SoundType sound) - { - this.sound = sound; - return this; - } + public Block(Material material) { + this.miningLevel = (material == Material.rock || material == Material.iron || material == Material.anvil) ? 0 : -1; + this.axeHarvest = material == Material.wood || material == Material.plants || material == Material.vine || material == Material.gourd; + this.shearsEfficiency = (material == Material.leaves || material == Material.web) ? 3 : -1; + this.sound = SoundType.STONE; + this.slipperiness = 0.6F; + this.material = material; + this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F); + this.fullBlock = this.isOpaqueCube(); + this.lightOpacity = this.isOpaqueCube() ? 255 : 0; + this.translucent = !material.blocksLight(); + this.properties = getPropertyList(this.getProperties()); + this.states = getStateList(this.properties, this); + this.setDefaultState(this.getBaseState()); + } - /** - * Sets how much light is blocked going through this block. Returns the object for convenience in constructing. - */ - public Block setLightOpacity(int opacity) - { - this.lightOpacity = opacity; - return this; - } + public Block setStepSound(SoundType sound) { + this.sound = sound; + return this; + } - /** - * Sets the light value that the block emits. Returns resulting block instance for constructing convenience. Args: - * level - */ - public Block setLightLevel(float value) - { - this.lightValue = (int)(15.0F * value); - return this; - } + public Block setLightOpacity(int opacity) { + this.lightOpacity = opacity; + return this; + } - /** - * Sets the the blocks resistance to explosions. Returns the object for convenience in constructing. - */ - public Block setResistance(float resistance) - { - this.blockResistance = resistance * 3.0F; - return this; - } + public Block setLightLevel(float value) { + this.lightValue = (int)(15.0F * value); + return this; + } - /** - * Sets how many hits it takes to break a block. - */ - public Block setHardness(float hardness) - { - this.blockHardness = hardness; + public Block setResistance(float resistance) { + this.blockResistance = resistance * 3.0F; + return this; + } - if (this.blockResistance < hardness * 5.0F) - { - this.blockResistance = hardness * 5.0F; - } + public Block setHardness(float hardness) { + this.blockHardness = hardness; - return this; - } + if(this.blockResistance < hardness * 5.0F) { + this.blockResistance = hardness * 5.0F; + } -// public Block setBlockUnbreakable() -// { -// this.setHardness(-1.0F); -// this.setResistance(6000000.0F); -// return this; -// } + return this; + } - /** - * Sets whether this block type will receive random update ticks - */ - protected Block setTickRandomly() - { - this.ticked = true; - return this; - } + protected Block setTickRandomly() { + this.ticked = true; + return this; + } - public Block setDisplay(String name) - { - this.display = name; - return this; - } + public Block setDisplay(String name) { + this.display = name; + return this; + } -// public Block disableStats() -// { -// this.enableStats = false; -// return this; -// } + public Block setTab(CheatTab tab) { + this.tab = tab; + return this; + } - public Block setTab(CheatTab tab) - { - this.tab = tab; - return this; - } - - public Block setSumBrightness() - { - this.sumBrightness = true; - return this; - } - - public Block setMiningLevel(int level) - { - this.miningLevel = level; - return this; - } - - public Block setAxeHarvestable() - { - this.axeHarvest = true; - return this; - } - - public Block setShovelHarvestable() - { - this.shovelHarvest = true; - return this; - } - - public Block setShearsEfficiency(int efficiency) - { - this.shearsEfficiency = efficiency; - return this; - } - - public Block setRadiation(float value) - { - this.radiation = value; - if(value > 0.0f) - this.ticked = true; - return this; - } - - + public Block setSumBrightness() { + this.sumBrightness = true; + return this; + } - public boolean isFullBlock() - { - return this.fullBlock; - } + public Block setMiningLevel(int level) { + this.miningLevel = level; + return this; + } - public int getLightOpacity() - { - return this.lightOpacity; - } + public Block setAxeHarvestable() { + this.axeHarvest = true; + return this; + } - /** - * Used in the renderer to apply ambient occlusion - */ - public boolean isTranslucent() - { - return this.translucent; - } + public Block setShovelHarvestable() { + this.shovelHarvest = true; + return this; + } - public int getLightValue() - { - return this.lightValue; - } + public Block setShearsEfficiency(int efficiency) { + this.shearsEfficiency = efficiency; + return this; + } - /** - * Should block use the brightest neighbor light value as its own - */ - public boolean getSumBrightness() - { - return this.sumBrightness; - } + public Block setRadiation(float value) { + this.radiation = value; + if(value > 0.0f) + this.ticked = true; + return this; + } - /** - * Get a material of block - */ - public Material getMaterial() - { - return this.material; - } + public boolean isFullBlock() { + return this.fullBlock; + } + + public int getLightOpacity() { + return this.lightOpacity; + } + + public boolean isTranslucent() { + return this.translucent; + } + + public int getLightValue() { + return this.lightValue; + } + + public boolean getSumBrightness() { + return this.sumBrightness; + } + + public final Material getMaterial() { + return this.material; + } public ImmutableList getValidStates() { return this.states; } - private List> getAllowedValues() { - List> list = Lists.>newArrayList(); - for(int z = 0; z < this.properties.size(); z++) { - list.add((this.properties.get(z)).getAllowedValues()); - } - return list; - } - public final State getBaseState() { return this.states.get(0); } -// public Block getBlock() { -// return this; -// } - public Collection getPropertyMap() { return this.properties; } -// public String toString() { -// return Objects.toStringHelper(this).add("block", BlockRegistry.REGISTRY.getNameForObject(this)) -// .add("properties", Iterables.transform(this.properties, GET_NAME_FUNC)).toString(); -// } - -// /** -// * Get the MapColor for this Block and the given BlockState -// */ -// public final MapColor getMapColor(IBlockState state) -// { -// return this.blockMapColor; -// } - - /** - * Convert the given metadata into a BlockState for this Block - */ - public State getStateFromMeta(int meta) - { - return this.getState(); - } - - /** - * Convert the BlockState into the correct metadata value - */ - public int getMetaFromState(State state) - { - if (state != null && !state.getPropertyNames().isEmpty()) - { - throw new IllegalArgumentException("Don\'t know how to convert " + state + " back into data..."); - } - else - { - return 0; - } - } - - /** - * Get the actual Block state of this Block at the given position. This applies properties not visible in the - * metadata, such as fence connections. - */ - public State getActualState(State state, IWorldAccess worldIn, BlockPos pos) - { - return state; - } - - /** - * Indicate if a material is a normal solid opaque cube - */ - public boolean isBlockNormalCube() - { - return this.material.blocksMovement() && this.isFullCube(); - } - - /** - * Used for nearly all game logic (non-rendering) purposes. Use Forge-provided isNormalCube(IBlockAccess, BlockPos) - * instead. - */ - public boolean isNormalCube() - { - return this.material.isOpaque() && this.isFullCube() && !this.canProvidePower(); - } - - public boolean isVisuallyOpaque() - { - return this.material.blocksMovement() && this.isFullCube(); - } - - public boolean isFullCube() - { - return true; - } - - public boolean isPassable(IBlockAccess worldIn, BlockPos pos) - { - return !this.material.blocksMovement(); - } - - /** - * The type of render function called. 3 for standard block models, 2 for TESR's, 1 for liquids, -1 is no render - */ - public int getRenderType() - { - return 3; - } - - public boolean isXrayVisible() - { - return false; - } - - /** - * Whether this Block can be replaced directly by other blocks (true for e.g. tall grass) - */ - public boolean isReplaceable(World worldIn, BlockPos pos) - { - return false; - } - - public float getBlockHardness(World worldIn, BlockPos pos) - { - return this.blockHardness; - } - - /** - * Returns whether or not this block is of a type that needs random ticking. Called for ref-counting purposes by - * ExtendedBlockStorage in order to broadly cull a chunk from the random chunk update list for efficiency's sake. - */ - public boolean getTickRandomly() - { - return this.ticked; - } - - public boolean hasTileEntity() - { - return this.hasTile; - } - - protected final void setBlockBounds(float minX, float minY, float minZ, float maxX, float maxY, float maxZ) - { - this.minX = (double)minX; - this.minY = (double)minY; - this.minZ = (double)minZ; - this.maxX = (double)maxX; - this.maxY = (double)maxY; - this.maxZ = (double)maxZ; - } - - public int getMixedBrightnessForBlock(IWorldAccess worldIn, BlockPos pos) - { - Block block = worldIn.getState(pos).getBlock(); - int i = worldIn.getCombinedLight(pos, block.getLightValue()); - - if (i == 0 && block instanceof BlockSlab) - { - pos = pos.down(); - block = worldIn.getState(pos).getBlock(); - return worldIn.getCombinedLight(pos, block.getLightValue()); - } - else - { - return i; - } - } - - public boolean shouldSideBeRendered(IWorldAccess worldIn, BlockPos pos, Facing side) - { - return side == Facing.DOWN && this.minY > 0.0D ? true : (side == Facing.UP && this.maxY < 1.0D ? true : (side == Facing.NORTH && this.minZ > 0.0D ? true : (side == Facing.SOUTH && this.maxZ < 1.0D ? true : (side == Facing.WEST && this.minX > 0.0D ? true : (side == Facing.EAST && this.maxX < 1.0D ? true : !worldIn.getState(pos).getBlock().isOpaqueCube()))))); - } - - /** - * Whether this Block is solid on the given Side - */ - public boolean isBlockSolid(IBlockAccess worldIn, BlockPos pos, Facing side) - { - return worldIn.getState(pos).getBlock().getMaterial().isSolid(); - } - - public BoundingBox getSelectedBoundingBox(World worldIn, BlockPos pos) - { - return new BoundingBox((double)pos.getX() + this.minX, (double)pos.getY() + this.minY, (double)pos.getZ() + this.minZ, (double)pos.getX() + this.maxX, (double)pos.getY() + this.maxY, (double)pos.getZ() + this.maxZ); - } - - /** - * Add all collision boxes of this Block to the list that intersect with the given mask. - */ - public void addCollisionBoxesToList(World worldIn, BlockPos pos, State state, BoundingBox mask, List list, Entity collidingEntity) - { - BoundingBox axisalignedbb = this.getCollisionBoundingBox(worldIn, pos, state); - - if (axisalignedbb != null && mask.intersectsWith(axisalignedbb)) - { - list.add(axisalignedbb); - } - } - - public BoundingBox getCollisionBoundingBox(World worldIn, BlockPos pos, State state) - { - return new BoundingBox((double)pos.getX() + this.minX, (double)pos.getY() + this.minY, (double)pos.getZ() + this.minZ, (double)pos.getX() + this.maxX, (double)pos.getY() + this.maxY, (double)pos.getZ() + this.maxZ); - } - - /** - * Used to determine ambient occlusion and culling when rebuilding chunks for render - */ - public boolean isOpaqueCube() - { - return true; - } - - public boolean canCollideCheck(State state, boolean hitIfLiquid) - { - return this.isCollidable(); - } - - /** - * Returns if this block is collidable (only used by Fire). Args: x, y, z - */ - public boolean isCollidable() - { - return true; - } - - /** - * Called randomly when setTickRandomly is set to true (used by e.g. crops to grow, etc.) - */ - public void randomTick(AWorldServer worldIn, BlockPos pos, State state, Random random) - { - this.updateTick(worldIn, pos, state, random); - if(this.radiation > 0.0f && /* worldIn.getTime() % 5L == 0L && */ random.chance(Config.randomTick / 3)) - this.affectEntities(worldIn, pos, state, this.radiation * 8.0f * 0.25f); - } - - private void affectEntities(AWorldServer worldIn, BlockPos pos, State state, float rad) - { - float r = ExtMath.clampf(rad * 2.0f, 0.0f, 25.0f); - BoundingBox box = this.getCollisionBoundingBox(worldIn, pos, state); - if(box == null) - box = new BoundingBox(pos, pos.add(1, 1, 1)); - for (EntityLiving entity : worldIn.getEntitiesWithinAABB(EntityLiving.class, box.expand(r, r, r))) - { - float effect = rad * 2.0f * (r - ExtMath.sqrtf((float)entity.getDistanceSq(pos))) / r; - if(effect > 0.0f) - entity.addRadiation(effect); - } - } - - public void updateTick(AWorldServer worldIn, BlockPos pos, State state, Random rand) - { - } - - public void randomDisplayTick(AWorldClient worldIn, BlockPos pos, State state, Random rand) - { - } - - /** - * Called when a player destroys this Block - */ - public void onBlockDestroyedByPlayer(World worldIn, BlockPos pos, State state) - { - } - - /** - * Called when a neighboring block changes. - */ - public void onNeighborBlockChange(World worldIn, BlockPos pos, State state, Block neighborBlock) - { - } - - /** - * How many world ticks before ticking - */ - public int tickRate(World worldIn, BlockPos pos) - { - return 10; - } - - public void onBlockAdded(AWorldServer world, BlockPos pos, State state) - { - } - - public void onBlockRemoved(AWorldServer world, BlockPos pos, State state) - { - } - - /** - * Returns the quantity of items to drop on block destruction. - */ - public int quantityDropped(Random random) - { - return 1; - } - - /** - * Get the Item that this Block should drop when harvested. - */ - public Item getItemDropped(State state, Random rand, int fortune) - { - return ItemRegistry.getItemFromBlock(this); - } - - /** - * Get the hardness of this Block relative to the ability of the given player - */ - public float getPlayerRelativeBlockHardness(EntityNPC playerIn, World worldIn, BlockPos pos) - { - float f = this.getBlockHardness(worldIn, pos); - return f < 0.0F ? 0.0F : (!playerIn.canHarvestBlock(this) ? playerIn.getToolDigEfficiency(this) / f / 100.0F : playerIn.getToolDigEfficiency(this) / f / 30.0F); - } - - /** - * Spawn this Block's drops into the World as EntityItems - */ - public final void dropBlockAsItem(World worldIn, BlockPos pos, State state, int forture) - { - this.dropBlockAsItemWithChance(worldIn, pos, state, 1.0F, forture); - } - - /** - * Spawns this Block's drops into the World as EntityItems. - */ - public void dropBlockAsItemWithChance(World worldIn, BlockPos pos, State state, float chance, int fortune) - { - if (!worldIn.client) - { - int i = this.quantityDroppedWithBonus(fortune, worldIn.rand); - - for (int j = 0; j < i; ++j) - { - if (worldIn.rand.floatv() <= chance) - { - Item item = this.getItemDropped(state, worldIn.rand, fortune); - - if (item != null) - { - spawnAsEntity(worldIn, pos, new ItemStack(item, 1, this.damageDropped(state))); - } - } - } - } - } - - /** - * Spawns the given ItemStack as an EntityItem into the World at the given position - */ - public static void spawnAsEntity(World worldIn, BlockPos pos, ItemStack stack) - { - if (!worldIn.client && Config.blockDrop) - { - float f = 0.5F; - double d0 = (double)(worldIn.rand.floatv() * f) + (double)(1.0F - f) * 0.5D; - double d1 = (double)(worldIn.rand.floatv() * f) + (double)(1.0F - f) * 0.5D; - double d2 = (double)(worldIn.rand.floatv() * f) + (double)(1.0F - f) * 0.5D; - EntityItem entityitem = new EntityItem(worldIn, (double)pos.getX() + d0, (double)pos.getY() + d1, (double)pos.getZ() + d2, stack); - entityitem.setDefaultPickupDelay(); - worldIn.spawnEntityInWorld(entityitem); - } - } - - /** - * Spawns the given amount of experience into the World as XP orb entities - */ - protected void dropXpOnBlockBreak(World worldIn, BlockPos pos, int amount) - { - if (!worldIn.client && Config.blockXP) - { - while (amount > 0) - { - int i = EntityXp.getXPSplit(amount); - amount -= i; - worldIn.spawnEntityInWorld(new EntityXp(worldIn, (double)pos.getX() + 0.5D, (double)pos.getY() + 0.5D, (double)pos.getZ() + 0.5D, i)); - } - } - } - - /** - * Gets the metadata of the item this Block can drop. This method is called when the block gets destroyed. It - * returns the metadata of the dropped item based on the old metadata of the block. - */ - public int damageDropped(State state) - { - return 0; - } - - /** - * Returns how much this block can resist explosions from the passed in entity. - */ - public float getExplosionResistance(Entity exploder) - { - return this.blockResistance / 5.0F; - } - - /** - * Ray traces through the blocks collision from start vector to end vector returning a ray trace hit. - */ - public HitPosition collisionRayTrace(World worldIn, BlockPos pos, Vec3 start, Vec3 end) - { - this.setBlockBoundsBasedOnState(worldIn, pos); - start = start.addVector((double)(-pos.getX()), (double)(-pos.getY()), (double)(-pos.getZ())); - end = end.addVector((double)(-pos.getX()), (double)(-pos.getY()), (double)(-pos.getZ())); - Vec3 vec3 = start.getIntermediateWithXValue(end, this.minX); - Vec3 vec31 = start.getIntermediateWithXValue(end, this.maxX); - Vec3 vec32 = start.getIntermediateWithYValue(end, this.minY); - Vec3 vec33 = start.getIntermediateWithYValue(end, this.maxY); - Vec3 vec34 = start.getIntermediateWithZValue(end, this.minZ); - Vec3 vec35 = start.getIntermediateWithZValue(end, this.maxZ); - - if (!this.isVecInsideYZBounds(vec3)) - { - vec3 = null; - } - - if (!this.isVecInsideYZBounds(vec31)) - { - vec31 = null; - } - - if (!this.isVecInsideXZBounds(vec32)) - { - vec32 = null; - } - - if (!this.isVecInsideXZBounds(vec33)) - { - vec33 = null; - } - - if (!this.isVecInsideXYBounds(vec34)) - { - vec34 = null; - } - - if (!this.isVecInsideXYBounds(vec35)) - { - vec35 = null; - } - - Vec3 vec36 = null; - - if (vec3 != null && (vec36 == null || start.squareDistanceTo(vec3) < start.squareDistanceTo(vec36))) - { - vec36 = vec3; - } - - if (vec31 != null && (vec36 == null || start.squareDistanceTo(vec31) < start.squareDistanceTo(vec36))) - { - vec36 = vec31; - } - - if (vec32 != null && (vec36 == null || start.squareDistanceTo(vec32) < start.squareDistanceTo(vec36))) - { - vec36 = vec32; - } - - if (vec33 != null && (vec36 == null || start.squareDistanceTo(vec33) < start.squareDistanceTo(vec36))) - { - vec36 = vec33; - } - - if (vec34 != null && (vec36 == null || start.squareDistanceTo(vec34) < start.squareDistanceTo(vec36))) - { - vec36 = vec34; - } - - if (vec35 != null && (vec36 == null || start.squareDistanceTo(vec35) < start.squareDistanceTo(vec36))) - { - vec36 = vec35; - } - - if (vec36 == null) - { - return null; - } - else - { - Facing enumfacing = null; - - if (vec36 == vec3) - { - enumfacing = Facing.WEST; - } - - if (vec36 == vec31) - { - enumfacing = Facing.EAST; - } - - if (vec36 == vec32) - { - enumfacing = Facing.DOWN; - } - - if (vec36 == vec33) - { - enumfacing = Facing.UP; - } - - if (vec36 == vec34) - { - enumfacing = Facing.NORTH; - } - - if (vec36 == vec35) - { - enumfacing = Facing.SOUTH; - } - - return new HitPosition(ObjectType.BLOCK, vec36.addVector((double)pos.getX(), (double)pos.getY(), (double)pos.getZ()), enumfacing, pos); - } - } - - /** - * Checks if a vector is within the Y and Z bounds of the block. - */ - private boolean isVecInsideYZBounds(Vec3 point) - { - return point == null ? false : point.yCoord >= this.minY && point.yCoord <= this.maxY && point.zCoord >= this.minZ && point.zCoord <= this.maxZ; - } - - /** - * Checks if a vector is within the X and Z bounds of the block. - */ - private boolean isVecInsideXZBounds(Vec3 point) - { - return point == null ? false : point.xCoord >= this.minX && point.xCoord <= this.maxX && point.zCoord >= this.minZ && point.zCoord <= this.maxZ; - } - - /** - * Checks if a vector is within the X and Y bounds of the block. - */ - private boolean isVecInsideXYBounds(Vec3 point) - { - return point == null ? false : point.xCoord >= this.minX && point.xCoord <= this.maxX && point.yCoord >= this.minY && point.yCoord <= this.maxY; - } - - /** - * Called when this Block is destroyed by an Explosion - */ - public void onBlockDestroyedByExplosion(World worldIn, BlockPos pos, Explosion explosionIn, State prevState) - { - } - - public BlockLayer getBlockLayer() - { - return BlockLayer.SOLID; - } - - public boolean canReplace(World worldIn, BlockPos pos, Facing side, ItemStack stack) - { - return this.canPlaceBlockOnSide(worldIn, pos, side); - } - - /** - * Check whether this Block can be placed on the given side - */ - public boolean canPlaceBlockOnSide(World worldIn, BlockPos pos, Facing side) - { - return this.canPlaceBlockAt(worldIn, pos); - } - - public boolean canPlaceBlockAt(World worldIn, BlockPos pos) - { - return worldIn.getState(pos).getBlock().material.isReplaceable(); - } - - public boolean onBlockActivated(World worldIn, BlockPos pos, State state, EntityNPC playerIn, Facing side, float hitX, float hitY, float hitZ) - { - return false; - } - - /** - * Triggered whenever an entity collides with this block (enters into the block) - */ - public void onEntityCollidedWithBlock(World worldIn, BlockPos pos, Entity entityIn) - { - } - - /** - * Called by ItemBlocks just before a block is actually set in the world, to allow for adjustments to the - * IBlockstate - */ - public State onBlockPlaced(World worldIn, BlockPos pos, Facing facing, float hitX, float hitY, float hitZ, int meta, EntityLiving placer) - { - return this.getStateFromMeta(meta); - } - - public void onBlockClicked(World worldIn, BlockPos pos, EntityNPC playerIn) - { - } - - public Vec3 modifyAcceleration(World worldIn, BlockPos pos, Entity entityIn, Vec3 motion) - { - return motion; - } - - public void setBlockBoundsBasedOnState(IWorldAccess worldIn, BlockPos pos) - { - } - - /** - * returns the block bounderies minX value - */ - public final double getBlockBoundsMinX() - { - return this.minX; - } - - /** - * returns the block bounderies maxX value - */ - public final double getBlockBoundsMaxX() - { - return this.maxX; - } - - /** - * returns the block bounderies minY value - */ - public final double getBlockBoundsMinY() - { - return this.minY; - } - - /** - * returns the block bounderies maxY value - */ - public final double getBlockBoundsMaxY() - { - return this.maxY; - } - - /** - * returns the block bounderies minZ value - */ - public final double getBlockBoundsMinZ() - { - return this.minZ; - } - - /** - * returns the block bounderies maxZ value - */ - public final double getBlockBoundsMaxZ() - { - return this.maxZ; - } - -// public int getBlockColor() -// { -// return 16777215; -// } - - public int getRenderColor(State state) - { - return 16777215; - } - - public int colorMultiplier(IWorldAccess worldIn, BlockPos pos, int renderPass) - { - return 16777215; - } - - public final int colorMultiplier(IWorldAccess worldIn, BlockPos pos) - { - return this.colorMultiplier(worldIn, pos, 0); - } - - public int getWeakPower(IWorldAccess worldIn, BlockPos pos, State state, Facing side) - { - return 0; - } - - /** - * Can this block provide power. Only wire currently seems to have this change based on its state. - */ - public boolean canProvidePower() - { - return false; - } - - /** - * Called When an Entity Collided with the Block - */ - public void onEntityCollidedWithBlock(World worldIn, BlockPos pos, State state, Entity entityIn) - { - } - - public int getStrongPower(IWorldAccess worldIn, BlockPos pos, State state, Facing side) - { - return 0; - } - - /** - * Sets the block's bounds for rendering it as an item - */ - public void setBlockBoundsForItemRender() - { - } - - public void harvestBlock(World worldIn, EntityNPC player, BlockPos pos, State state, TileEntity te) - { -// player.triggerAchievement(StatRegistry.mineBlockStatArray[BlockRegistry.getIdFromBlock(this)]); - - if (this.canSilkHarvest() && EnchantmentHelper.getSilkTouchModifier(player)) - { - ItemStack itemstack = this.createStackedBlock(state); - - if (itemstack != null) - { - spawnAsEntity(worldIn, pos, itemstack); - } - } - else - { - int i = EnchantmentHelper.getFortuneModifier(player); - this.dropBlockAsItem(worldIn, pos, state, i); - } - } - - public boolean canSilkHarvest() - { - return this.isFullCube() && !this.hasTile; - } - - public ItemStack createStackedBlock(State state) - { - int i = 0; - Item item = ItemRegistry.getItemFromBlock(this); - - if (item != null && item.getHasSubtypes()) - { - i = this.getMetaFromState(state); - } - - return new ItemStack(item, 1, i); - } - - /** - * Get the quantity dropped based on the given fortune level - */ - public int quantityDroppedWithBonus(int fortune, Random random) - { - return this.quantityDropped(random); - } - - /** - * Called by ItemBlocks after a block is set in the world, to allow post-place logic - */ - public void onBlockPlacedBy(World worldIn, BlockPos pos, State state, EntityLiving placer, ItemStack stack) - { - } - - /** - * Return true if an entity can be spawned inside the block (used to get the player's bed spawn location) - */ - public boolean canSpawnInBlock() - { - return !this.material.isSolid() && !this.material.isLiquid(); - } - -// /** -// * Gets the localized name of this block. Used for the statistics page. -// */ -// public String getLocalizedName() -// { -// return Strs.get(this.getUnlocalizedName() + ".name"); -// } - - public final String getDisplay() - { - return this.display; - } - - /** - * Called on both Client and Server when World#addBlockEvent is called - */ - public boolean onBlockEventReceived(World worldIn, BlockPos pos, State state, int eventID, int eventParam) - { - return false; - } - -// /** -// * Return the state of blocks statistics flags - if the block is counted for mined and placed. -// */ -// public boolean getEnableStats() -// { -// return this.enableStats; -// } - - public int getMobilityFlag() - { - return this.material.getMaterialMobility(); - } - - /** - * Returns the default ambient occlusion value based on block opacity - */ - public float getAmbientOcclusionLightValue() - { - return this.isBlockNormalCube() ? 0.2F : 1.0F; - } - - /** - * Block's chance to react to a living entity falling on it. - */ - public void onFallenUpon(World worldIn, BlockPos pos, Entity entityIn, float fallDistance) - { - entityIn.fall(fallDistance, 1.0F); - } - - /** - * Called when an Entity lands on this Block. This method *must* update motionY because the entity will not do that - * on its own - */ - public void onLanded(World worldIn, Entity entityIn) - { - entityIn.motionY = 0.0D; - } - - public Item getItem(World worldIn, BlockPos pos) - { - return ItemRegistry.getItemFromBlock(this); - } - - /** - * Gets the meta to use for the Pick Block ItemStack result - */ - public int getDamageValue(World worldIn, BlockPos pos) - { - return this.damageDropped(worldIn.getState(pos)); - } - - /** - * returns a list of blocks with the same ID, but different meta (eg: wood returns 4 blocks) - */ - public void getSubBlocks(Item itemIn, CheatTab tab, List list) - { - list.add(new ItemStack(itemIn, 1, 0)); - } - - /** - * Returns the tab to display the given block on. - */ - public CheatTab getTab() - { - return this.tab; - } - - public void onBlockHarvested(World worldIn, BlockPos pos, State state, EntityNPC player) - { - } - - /** - * Called similar to random ticks, but only when it is raining. - */ - public void fillWithRain(World worldIn, BlockPos pos) - { - } - - public boolean isPickStrict() - { - return false; - } - - public boolean requiresUpdates() - { - return true; - } - - /** - * Return whether this block can drop from an explosion. - */ - public boolean canDropFromExplosion(Explosion explosionIn) - { - return true; - } - - public boolean isAssociatedBlock(Block other) - { - return this == other; - } - - public static boolean isEqualTo(Block blockIn, Block other) - { - return blockIn != null && other != null ? (blockIn == other ? true : blockIn.isAssociatedBlock(other)) : false; - } - - public boolean hasComparatorInputOverride() - { - return false; - } - - public int getComparatorInputOverride(World worldIn, BlockPos pos) - { - return 0; - } - - /** - * Possibly modify the given BlockState before rendering it on an Entity (Minecarts, Endermen, ...) - */ - public State getStateForEntityRender(State state) - { - return state; - } - - protected IProperty[] getProperties() - { - return new IProperty[0]; - } - - protected final void setDefaultState(State state) - { - this.defaultState = state; - } - - public final State getState() - { - return this.defaultState; - } - -// public EnumOffsetType getOffsetType() -// { -// return EnumOffsetType.NONE; -// } - -// public String toString() -// { -// return "Block{" + BlockRegistry.REGISTRY.getNameForObject(this) + "}"; -// } - - public int getMiningLevel() { - return this.miningLevel; - } - - public boolean canAxeHarvest() { - return this.axeHarvest; - } - - public boolean canShovelHarvest() { - return this.shovelHarvest; - } - - public int getShearsEfficiency() { - return this.shearsEfficiency; - } - - public boolean isMagnetic() { - return false; - } - - public Transforms getTransform() { - return Transforms.BLOCK; - } - - public Model getModel(ModelProvider provider, String name, State state) { - return provider.getModel(name).add().all(); - } - - public IProperty[] getIgnoredProperties() { - return null; - } - - public void getAnimatedTextures(Map map) { - } - - public boolean canKeepFire() { - return false; - } - - public boolean canExtinguish() { - return false; - } - - public void onDestroyedByFire(World world, BlockPos pos, State state) { - } + public State getStateFromMeta(int meta) { + return this.getState(); + } + + public int getMetaFromState(State state) { + if(state != null && !state.getPropertyNames().isEmpty()) { + throw new IllegalArgumentException("Don\'t know how to convert " + state + " back into data..."); + } + else { + return 0; + } + } + + public State getActualState(State state, IWorldAccess worldIn, BlockPos pos) { + return state; + } + + public boolean isBlockNormalCube() { + return this.material.blocksMovement() && this.isFullCube(); + } + + public boolean isNormalCube() { + return this.material.isOpaque() && this.isFullCube() && !this.canProvidePower(); + } + + public boolean isVisuallyOpaque() { + return this.material.blocksMovement() && this.isFullCube(); + } + + public boolean isFullCube() { + return true; + } + + public boolean isPassable(IBlockAccess worldIn, BlockPos pos) { + return !this.material.blocksMovement(); + } + + public int getRenderType() { + return 3; + } + + public boolean isXrayVisible() { + return false; + } + + public boolean isReplaceable(World worldIn, BlockPos pos) { + return false; + } + + public float getBlockHardness(World worldIn, BlockPos pos) { + return this.blockHardness; + } + + public final float getRawHardness() { + return this.blockHardness; + } + + public final float getRawResistance() { + return this.blockResistance; + } + + public boolean getTickRandomly() { + return this.ticked; + } + + public boolean hasTileEntity() { + return this.hasTile; + } + + protected final void setBlockBounds(float minX, float minY, float minZ, float maxX, float maxY, float maxZ) { + this.minX = (double)minX; + this.minY = (double)minY; + this.minZ = (double)minZ; + this.maxX = (double)maxX; + this.maxY = (double)maxY; + this.maxZ = (double)maxZ; + } + + public int getMixedBrightnessForBlock(IWorldAccess worldIn, BlockPos pos) { + Block block = worldIn.getState(pos).getBlock(); + int i = worldIn.getCombinedLight(pos, block.getLightValue()); + + if(i == 0 && block instanceof BlockSlab) { + pos = pos.down(); + block = worldIn.getState(pos).getBlock(); + return worldIn.getCombinedLight(pos, block.getLightValue()); + } + else { + return i; + } + } + + public boolean shouldSideBeRendered(IWorldAccess worldIn, BlockPos pos, Facing side) { + return side == Facing.DOWN && this.minY > 0.0D ? true + : (side == Facing.UP && this.maxY < 1.0D ? true + : (side == Facing.NORTH && this.minZ > 0.0D ? true + : (side == Facing.SOUTH && this.maxZ < 1.0D ? true + : (side == Facing.WEST && this.minX > 0.0D ? true + : (side == Facing.EAST && this.maxX < 1.0D ? true + : !worldIn.getState(pos).getBlock().isOpaqueCube()))))); + } + + public boolean isBlockSolid(IBlockAccess worldIn, BlockPos pos, Facing side) { + return worldIn.getState(pos).getBlock().getMaterial().isSolid(); + } + + public BoundingBox getSelectedBoundingBox(World worldIn, BlockPos pos) { + return new BoundingBox((double)pos.getX() + this.minX, (double)pos.getY() + this.minY, (double)pos.getZ() + this.minZ, + (double)pos.getX() + this.maxX, (double)pos.getY() + this.maxY, (double)pos.getZ() + this.maxZ); + } + + public void addCollisionBoxesToList(World worldIn, BlockPos pos, State state, BoundingBox mask, List list, Entity collidingEntity) { + BoundingBox axisalignedbb = this.getCollisionBoundingBox(worldIn, pos, state); + + if(axisalignedbb != null && mask.intersectsWith(axisalignedbb)) { + list.add(axisalignedbb); + } + } + + public BoundingBox getCollisionBoundingBox(World worldIn, BlockPos pos, State state) { + return new BoundingBox((double)pos.getX() + this.minX, (double)pos.getY() + this.minY, (double)pos.getZ() + this.minZ, + (double)pos.getX() + this.maxX, (double)pos.getY() + this.maxY, (double)pos.getZ() + this.maxZ); + } + + public boolean isOpaqueCube() { + return true; + } + + public boolean canCollideCheck(State state, boolean liquid) { + return this.isCollidable(); + } + + public boolean isCollidable() { + return true; + } + + public void randomTick(AWorldServer worldIn, BlockPos pos, State state, Random random) { + this.updateTick(worldIn, pos, state, random); + if(this.radiation > 0.0f && /* worldIn.getTime() % 5L == 0L && */ random.chance(Config.randomTick / 3)) + this.affectEntities(worldIn, pos, state, this.radiation * 8.0f * 0.25f); + } + + private void affectEntities(AWorldServer worldIn, BlockPos pos, State state, float rad) { + float r = ExtMath.clampf(rad * 2.0f, 0.0f, 25.0f); + BoundingBox box = this.getCollisionBoundingBox(worldIn, pos, state); + if(box == null) + box = new BoundingBox(pos, pos.add(1, 1, 1)); + for(EntityLiving entity : worldIn.getEntitiesWithinAABB(EntityLiving.class, box.expand(r, r, r))) { + float effect = rad * 2.0f * (r - ExtMath.sqrtf((float)entity.getDistanceSq(pos))) / r; + if(effect > 0.0f) + entity.addRadiation(effect); + } + } + + public void updateTick(AWorldServer worldIn, BlockPos pos, State state, Random rand) { + } + + public void randomDisplayTick(AWorldClient worldIn, BlockPos pos, State state, Random rand) { + } + + public void onBlockDestroyedByPlayer(World worldIn, BlockPos pos, State state) { + } + + public void onNeighborBlockChange(World worldIn, BlockPos pos, State state, Block neighborBlock) { + } + + public int tickRate(World worldIn, BlockPos pos) { + return 10; + } + + public void onBlockAdded(AWorldServer world, BlockPos pos, State state) { + } + + public void onBlockRemoved(AWorldServer world, BlockPos pos, State state) { + } + + public int quantityDropped(Random random) { + return 1; + } + + public Item getItemDropped(State state, Random rand, int fortune) { + return ItemRegistry.getItemFromBlock(this); + } + + public float getPlayerRelativeBlockHardness(EntityNPC playerIn, World worldIn, BlockPos pos) { + float f = this.getBlockHardness(worldIn, pos); + return f < 0.0F ? 0.0F + : (!playerIn.canHarvestBlock(this) ? playerIn.getToolDigEfficiency(this) / f / 100.0F + : playerIn.getToolDigEfficiency(this) / f / 30.0F); + } + + public final void dropBlockAsItem(World worldIn, BlockPos pos, State state, int forture) { + this.dropBlockAsItemWithChance(worldIn, pos, state, 1.0F, forture); + } + + public void dropBlockAsItemWithChance(World worldIn, BlockPos pos, State state, float chance, int fortune) { + if(!worldIn.client) { + int i = this.quantityDroppedWithBonus(fortune, worldIn.rand); + + for(int j = 0; j < i; ++j) { + if(worldIn.rand.floatv() <= chance) { + Item item = this.getItemDropped(state, worldIn.rand, fortune); + + if(item != null) { + spawnAsEntity(worldIn, pos, new ItemStack(item, 1, this.damageDropped(state))); + } + } + } + } + } + + public static void spawnAsEntity(World worldIn, BlockPos pos, ItemStack stack) { + if(!worldIn.client && Config.blockDrop) { + float f = 0.5F; + double d0 = (double)(worldIn.rand.floatv() * f) + (double)(1.0F - f) * 0.5D; + double d1 = (double)(worldIn.rand.floatv() * f) + (double)(1.0F - f) * 0.5D; + double d2 = (double)(worldIn.rand.floatv() * f) + (double)(1.0F - f) * 0.5D; + EntityItem entityitem = new EntityItem(worldIn, (double)pos.getX() + d0, (double)pos.getY() + d1, (double)pos.getZ() + d2, stack); + entityitem.setDefaultPickupDelay(); + worldIn.spawnEntityInWorld(entityitem); + } + } + + protected void dropXpOnBlockBreak(World worldIn, BlockPos pos, int amount) { + if(!worldIn.client && Config.blockXP) { + while(amount > 0) { + int i = EntityXp.getXPSplit(amount); + amount -= i; + worldIn.spawnEntityInWorld(new EntityXp(worldIn, (double)pos.getX() + 0.5D, (double)pos.getY() + 0.5D, (double)pos.getZ() + 0.5D, i)); + } + } + } + + public int damageDropped(State state) { + return 0; + } + + public float getExplosionResistance(Entity exploder) { + return this.blockResistance / 5.0F; + } + + public HitPosition collisionRayTrace(World worldIn, BlockPos pos, Vec3 start, Vec3 end) { + this.setBlockBoundsBasedOnState(worldIn, pos); + start = start.addVector((double)(-pos.getX()), (double)(-pos.getY()), (double)(-pos.getZ())); + end = end.addVector((double)(-pos.getX()), (double)(-pos.getY()), (double)(-pos.getZ())); + Vec3 vec3 = start.getIntermediateWithXValue(end, this.minX); + Vec3 vec31 = start.getIntermediateWithXValue(end, this.maxX); + Vec3 vec32 = start.getIntermediateWithYValue(end, this.minY); + Vec3 vec33 = start.getIntermediateWithYValue(end, this.maxY); + Vec3 vec34 = start.getIntermediateWithZValue(end, this.minZ); + Vec3 vec35 = start.getIntermediateWithZValue(end, this.maxZ); + + if(!this.isVecInsideYZBounds(vec3)) { + vec3 = null; + } + + if(!this.isVecInsideYZBounds(vec31)) { + vec31 = null; + } + + if(!this.isVecInsideXZBounds(vec32)) { + vec32 = null; + } + + if(!this.isVecInsideXZBounds(vec33)) { + vec33 = null; + } + + if(!this.isVecInsideXYBounds(vec34)) { + vec34 = null; + } + + if(!this.isVecInsideXYBounds(vec35)) { + vec35 = null; + } + + Vec3 vec36 = null; + + if(vec3 != null && (vec36 == null || start.squareDistanceTo(vec3) < start.squareDistanceTo(vec36))) { + vec36 = vec3; + } + + if(vec31 != null && (vec36 == null || start.squareDistanceTo(vec31) < start.squareDistanceTo(vec36))) { + vec36 = vec31; + } + + if(vec32 != null && (vec36 == null || start.squareDistanceTo(vec32) < start.squareDistanceTo(vec36))) { + vec36 = vec32; + } + + if(vec33 != null && (vec36 == null || start.squareDistanceTo(vec33) < start.squareDistanceTo(vec36))) { + vec36 = vec33; + } + + if(vec34 != null && (vec36 == null || start.squareDistanceTo(vec34) < start.squareDistanceTo(vec36))) { + vec36 = vec34; + } + + if(vec35 != null && (vec36 == null || start.squareDistanceTo(vec35) < start.squareDistanceTo(vec36))) { + vec36 = vec35; + } + + if(vec36 == null) { + return null; + } + else { + Facing enumfacing = null; + + if(vec36 == vec3) { + enumfacing = Facing.WEST; + } + + if(vec36 == vec31) { + enumfacing = Facing.EAST; + } + + if(vec36 == vec32) { + enumfacing = Facing.DOWN; + } + + if(vec36 == vec33) { + enumfacing = Facing.UP; + } + + if(vec36 == vec34) { + enumfacing = Facing.NORTH; + } + + if(vec36 == vec35) { + enumfacing = Facing.SOUTH; + } + + return new HitPosition(ObjectType.BLOCK, vec36.addVector((double)pos.getX(), (double)pos.getY(), (double)pos.getZ()), enumfacing, pos); + } + } + + private boolean isVecInsideYZBounds(Vec3 point) { + return point == null ? false + : point.yCoord >= this.minY && point.yCoord <= this.maxY && point.zCoord >= this.minZ && point.zCoord <= this.maxZ; + } + + private boolean isVecInsideXZBounds(Vec3 point) { + return point == null ? false + : point.xCoord >= this.minX && point.xCoord <= this.maxX && point.zCoord >= this.minZ && point.zCoord <= this.maxZ; + } + + private boolean isVecInsideXYBounds(Vec3 point) { + return point == null ? false + : point.xCoord >= this.minX && point.xCoord <= this.maxX && point.yCoord >= this.minY && point.yCoord <= this.maxY; + } + + public void onBlockDestroyedByExplosion(World worldIn, BlockPos pos, Explosion explosionIn, State prevState) { + } + + public BlockLayer getBlockLayer() { + return BlockLayer.SOLID; + } + + public boolean canReplace(World worldIn, BlockPos pos, Facing side, ItemStack stack) { + return this.canPlaceBlockOnSide(worldIn, pos, side); + } + + public boolean canPlaceBlockOnSide(World worldIn, BlockPos pos, Facing side) { + return this.canPlaceBlockAt(worldIn, pos); + } + + public boolean canPlaceBlockAt(World worldIn, BlockPos pos) { + return worldIn.getState(pos).getBlock().material.isReplaceable(); + } + + public boolean onBlockActivated(World worldIn, BlockPos pos, State state, EntityNPC playerIn, Facing side, float hitX, float hitY, float hitZ) { + return false; + } + + public void onEntityCollidedWithBlock(World worldIn, BlockPos pos, Entity entityIn) { + } + + public State onBlockPlaced(World worldIn, BlockPos pos, Facing facing, float hitX, float hitY, float hitZ, int meta, EntityLiving placer) { + return this.getStateFromMeta(meta); + } + + public void onBlockClicked(World worldIn, BlockPos pos, EntityNPC playerIn) { + } + + public Vec3 modifyAcceleration(World worldIn, BlockPos pos, Entity entityIn, Vec3 motion) { + return motion; + } + + public void setBlockBoundsBasedOnState(IWorldAccess worldIn, BlockPos pos) { + } + + public final double getBlockBoundsMinX() { + return this.minX; + } + + public final double getBlockBoundsMaxX() { + return this.maxX; + } + + public final double getBlockBoundsMinY() { + return this.minY; + } + + public final double getBlockBoundsMaxY() { + return this.maxY; + } + + public final double getBlockBoundsMinZ() { + return this.minZ; + } + + public final double getBlockBoundsMaxZ() { + return this.maxZ; + } + + public int getRenderColor(State state) { + return 16777215; + } + + public int colorMultiplier(IWorldAccess worldIn, BlockPos pos, int renderPass) { + return 16777215; + } + + public final int colorMultiplier(IWorldAccess worldIn, BlockPos pos) { + return this.colorMultiplier(worldIn, pos, 0); + } + + public int getWeakPower(IWorldAccess worldIn, BlockPos pos, State state, Facing side) { + return 0; + } + + public boolean canProvidePower() { + return false; + } + + public void onEntityCollidedWithBlock(World worldIn, BlockPos pos, State state, Entity entityIn) { + } + + public int getStrongPower(IWorldAccess worldIn, BlockPos pos, State state, Facing side) { + return 0; + } + + public void setBlockBoundsForItemRender() { + } + + public void harvestBlock(World worldIn, EntityNPC player, BlockPos pos, State state, TileEntity te) { + if(this.canSilkHarvest() && EnchantmentHelper.getSilkTouchModifier(player)) { + ItemStack itemstack = this.createStackedBlock(state); + + if(itemstack != null) { + spawnAsEntity(worldIn, pos, itemstack); + } + } + else { + int i = EnchantmentHelper.getFortuneModifier(player); + this.dropBlockAsItem(worldIn, pos, state, i); + } + } + + public boolean canSilkHarvest() { + return this.isFullCube() && !this.hasTile; + } + + public ItemStack createStackedBlock(State state) { + int i = 0; + Item item = ItemRegistry.getItemFromBlock(this); + + if(item != null && item.getHasSubtypes()) { + i = this.getMetaFromState(state); + } + + return new ItemStack(item, 1, i); + } + + public int quantityDroppedWithBonus(int fortune, Random random) { + return this.quantityDropped(random); + } + + public void onBlockPlacedBy(World worldIn, BlockPos pos, State state, EntityLiving placer, ItemStack stack) { + } + + public boolean canSpawnInBlock() { + return !this.material.isSolid() && !this.material.isLiquid(); + } + + public final String getDisplay() { + return this.display; + } + + public boolean onBlockEventReceived(World worldIn, BlockPos pos, State state, int eventID, int eventParam) { + return false; + } + + public int getMobilityFlag() { + return this.material.getMaterialMobility(); + } + + public float getAmbientOcclusionLightValue() { + return this.isBlockNormalCube() ? 0.2F : 1.0F; + } + + public void onFallenUpon(World worldIn, BlockPos pos, Entity entityIn, float fallDistance) { + entityIn.fall(fallDistance, 1.0F); + } + + public void onLanded(World worldIn, Entity entityIn) { + entityIn.motionY = 0.0D; + } + + public Item getItem(World worldIn, BlockPos pos) { + return ItemRegistry.getItemFromBlock(this); + } + + public int getDamageValue(World worldIn, BlockPos pos) { + return this.damageDropped(worldIn.getState(pos)); + } + + public void getSubBlocks(Item itemIn, CheatTab tab, List list) { + list.add(new ItemStack(itemIn, 1, 0)); + } + + public CheatTab getTab() { + return this.tab; + } + + public void onBlockHarvested(World worldIn, BlockPos pos, State state, EntityNPC player) { + } + + public void fillWithRain(World worldIn, BlockPos pos) { + } + + public boolean isPickStrict() { + return false; + } + + public boolean requiresUpdates() { + return true; + } + + public boolean canDropFromExplosion(Explosion explosionIn) { + return true; + } + + public boolean isAssociatedBlock(Block other) { + return this == other; + } + + public static boolean isEqualTo(Block blockIn, Block other) { + return blockIn != null && other != null ? (blockIn == other ? true : blockIn.isAssociatedBlock(other)) : false; + } + + public boolean hasComparatorInputOverride() { + return false; + } + + public int getComparatorInputOverride(World worldIn, BlockPos pos) { + return 0; + } + + public State getStateForEntityRender(State state) { + return state; + } + + protected IProperty[] getProperties() { + return new IProperty[0]; + } + + protected final void setDefaultState(State state) { + this.defaultState = state; + } + + public final State getState() { + return this.defaultState; + } + + public int getMiningLevel() { + return this.miningLevel; + } + + public boolean canAxeHarvest() { + return this.axeHarvest; + } + + public boolean canShovelHarvest() { + return this.shovelHarvest; + } + + public int getShearsEfficiency() { + return this.shearsEfficiency; + } + + public boolean isMagnetic() { + return false; + } + + public Transforms getTransform() { + return Transforms.BLOCK; + } + + public Model getModel(ModelProvider provider, String name, State state) { + return provider.getModel(name).add().all(); + } + + public IProperty[] getIgnoredProperties() { + return null; + } + + public void getAnimatedTextures(Map map) { + } + + public boolean canKeepFire() { + return false; + } + + public boolean canExtinguish() { + return false; + } + + public void onDestroyedByFire(World world, BlockPos pos, State state) { + } } diff --git a/common/src/common/block/BlockAir.java b/common/src/common/block/BlockAir.java index e0a27ff..a5177a8 100755 --- a/common/src/common/block/BlockAir.java +++ b/common/src/common/block/BlockAir.java @@ -1,56 +1,36 @@ package common.block; -import common.material.Material; +import common.material.MaterialTransparent; import common.util.BlockPos; import common.util.BoundingBox; import common.world.State; import common.world.World; -public class BlockAir extends Block -{ - public BlockAir() - { - super(Material.air); - } +public final class BlockAir extends Block { + public BlockAir() { + super(new MaterialTransparent()); + } - /** - * The type of render function called. 3 for standard block models, 2 for TESR's, 1 for liquids, -1 is no render - */ - public int getRenderType() - { - return -1; - } + public int getRenderType() { + return -1; + } - public BoundingBox getCollisionBoundingBox(World worldIn, BlockPos pos, State state) - { - return null; - } + public BoundingBox getCollisionBoundingBox(World world, BlockPos pos, State state) { + return null; + } - /** - * Used to determine ambient occlusion and culling when rebuilding chunks for render - */ - public boolean isOpaqueCube() - { - return false; - } + public boolean isOpaqueCube() { + return false; + } - public boolean canCollideCheck(State state, boolean hitIfLiquid) - { - return false; - } + public boolean canCollideCheck(State state, boolean liquid) { + return false; + } - /** - * Spawns this Block's drops into the World as EntityItems. - */ - public void dropBlockAsItemWithChance(World worldIn, BlockPos pos, State state, float chance, int fortune) - { - } + public void dropBlockAsItemWithChance(World world, BlockPos pos, State state, float chance, int fortune) { + } - /** - * Whether this Block can be replaced directly by other blocks (true for e.g. tall grass) - */ - public boolean isReplaceable(World worldIn, BlockPos pos) - { - return true; - } + public boolean isReplaceable(World world, BlockPos pos) { + return true; + } } diff --git a/common/src/common/block/BlockBreakable.java b/common/src/common/block/BlockBreakable.java deleted file mode 100755 index 23a1c5d..0000000 --- a/common/src/common/block/BlockBreakable.java +++ /dev/null @@ -1,48 +0,0 @@ -package common.block; - -import common.init.Blocks; -import common.material.Material; -import common.util.BlockPos; -import common.util.Facing; -import common.world.IWorldAccess; -import common.world.State; - -public class BlockBreakable extends Block -{ - private boolean ignoreSimilarity; - - public BlockBreakable(Material p_i46393_1_, boolean p_i46393_2_) - { - super(p_i46393_1_); - this.ignoreSimilarity = p_i46393_2_; - } - - /** - * Used to determine ambient occlusion and culling when rebuilding chunks for render - */ - public boolean isOpaqueCube() - { - return false; - } - - public boolean shouldSideBeRendered(IWorldAccess worldIn, BlockPos pos, Facing side) - { - State iblockstate = worldIn.getState(pos); - Block block = iblockstate.getBlock(); - - if (this == Blocks.glass || this == Blocks.stained_glass) - { - if (worldIn.getState(pos.offset(side.getOpposite())) != iblockstate) - { - return true; - } - - if (block == this) - { - return false; - } - } - - return !this.ignoreSimilarity && block == this ? false : super.shouldSideBeRendered(worldIn, pos, side); - } -} diff --git a/common/src/common/block/BlockColored.java b/common/src/common/block/BlockColored.java index 8516cbc..ae9af9d 100755 --- a/common/src/common/block/BlockColored.java +++ b/common/src/common/block/BlockColored.java @@ -13,67 +13,38 @@ import common.properties.IProperty; import common.properties.PropertyEnum; import common.world.State; -public class BlockColored extends Block -{ - public static final PropertyEnum COLOR = PropertyEnum.create("color", DyeColor.class); +public class BlockColored extends Block { + public static final PropertyEnum COLOR = PropertyEnum.create("color", DyeColor.class); - public BlockColored(Material materialIn) - { - super(materialIn); - this.setDefaultState(this.getBaseState().withProperty(COLOR, DyeColor.WHITE)); - this.setTab(CheatTab.tabBlocks); - } + public BlockColored(Material material) { + super(material); + this.setDefaultState(this.getBaseState().withProperty(COLOR, DyeColor.WHITE)); + this.setTab(CheatTab.tabBlocks); + } - /** - * Gets the metadata of the item this Block can drop. This method is called when the block gets destroyed. It - * returns the metadata of the dropped item based on the old metadata of the block. - */ - public int damageDropped(State state) - { - return ((DyeColor)state.getValue(COLOR)).getMetadata(); - } + public int damageDropped(State state) { + return state.getValue(COLOR).getMetadata(); + } - /** - * returns a list of blocks with the same ID, but different meta (eg: wood returns 4 blocks) - */ - public void getSubBlocks(Item itemIn, CheatTab tab, List list) - { - for (DyeColor enumdyecolor : DyeColor.values()) - { - list.add(new ItemStack(itemIn, 1, enumdyecolor.getMetadata())); - } - } + public void getSubBlocks(Item item, CheatTab tab, List list) { + for(DyeColor color : DyeColor.values()) { + list.add(new ItemStack(item, 1, color.getMetadata())); + } + } -// /** -// * Get the MapColor for this Block and the given BlockState -// */ -// public MapColor getMapColor(IBlockState state) -// { -// return ((EnumDyeColor)state.getValue(COLOR)).getMapColor(); -// } + public State getStateFromMeta(int meta) { + return this.getState().withProperty(COLOR, DyeColor.byMetadata(meta)); + } - /** - * Convert the given metadata into a BlockState for this Block - */ - public State getStateFromMeta(int meta) - { - return this.getState().withProperty(COLOR, DyeColor.byMetadata(meta)); - } + public int getMetaFromState(State state) { + return state.getValue(COLOR).getMetadata(); + } - /** - * Convert the BlockState into the correct metadata value - */ - public int getMetaFromState(State state) - { - return ((DyeColor)state.getValue(COLOR)).getMetadata(); - } + protected IProperty[] getProperties() { + return new IProperty[] {COLOR}; + } - protected IProperty[] getProperties() - { - return new IProperty[] {COLOR}; - } - - public Model getModel(ModelProvider provider, String name, State state) { - return provider.getModel(state.getValue(COLOR).getName() + "_" + name).add().all(); - } + public Model getModel(ModelProvider provider, String name, State state) { + return provider.getModel(state.getValue(COLOR).getName() + "_" + name).add().all(); + } } diff --git a/common/src/common/block/BlockContainer.java b/common/src/common/block/BlockContainer.java index 78a927b..8c1a06f 100755 --- a/common/src/common/block/BlockContainer.java +++ b/common/src/common/block/BlockContainer.java @@ -8,45 +8,33 @@ import common.world.State; import common.world.World; import common.world.AWorldServer; -public abstract class BlockContainer extends Block implements ITileEntityProvider -{ - public BlockContainer(Material p_i46402_1_) - { - super(p_i46402_1_); - this.hasTile = true; - } +public abstract class BlockContainer extends Block implements ITileEntityProvider { + public BlockContainer(Material material) { + super(material); + this.hasTile = true; + } - protected boolean isInvalidNeighbor(World p_181086_1_, BlockPos p_181086_2_, Facing p_181086_3_) - { - return p_181086_1_.getState(p_181086_2_.offset(p_181086_3_)).getBlock().getMaterial() == Material.cactus; - } + protected boolean isInvalidNeighbor(World world, BlockPos pos, Facing face) { + return world.getState(pos.offset(face)).getBlock().getMaterial() == Material.cactus; + } - protected boolean hasInvalidNeighbor(World p_181087_1_, BlockPos p_181087_2_) - { - return this.isInvalidNeighbor(p_181087_1_, p_181087_2_, Facing.NORTH) || this.isInvalidNeighbor(p_181087_1_, p_181087_2_, Facing.SOUTH) || this.isInvalidNeighbor(p_181087_1_, p_181087_2_, Facing.WEST) || this.isInvalidNeighbor(p_181087_1_, p_181087_2_, Facing.EAST); - } + protected boolean hasInvalidNeighbor(World world, BlockPos pos) { + return this.isInvalidNeighbor(world, pos, Facing.NORTH) || this.isInvalidNeighbor(world, pos, Facing.SOUTH) + || this.isInvalidNeighbor(world, pos, Facing.WEST) || this.isInvalidNeighbor(world, pos, Facing.EAST); + } - /** - * The type of render function called. 3 for standard block models, 2 for TESR's, 1 for liquids, -1 is no render - */ - public int getRenderType() - { - return -1; - } + public int getRenderType() { + return -1; + } - public void onBlockRemoved(AWorldServer worldIn, BlockPos pos, State state) - { - super.onBlockRemoved(worldIn, pos, state); - worldIn.removeTileEntity(pos); - } + public void onBlockRemoved(AWorldServer world, BlockPos pos, State state) { + super.onBlockRemoved(world, pos, state); + world.removeTileEntity(pos); + } - /** - * Called on both Client and Server when World#addBlockEvent is called - */ - public boolean onBlockEventReceived(World worldIn, BlockPos pos, State state, int eventID, int eventParam) - { - super.onBlockEventReceived(worldIn, pos, state, eventID, eventParam); - TileEntity tileentity = worldIn.getTileEntity(pos); - return tileentity == null ? false : tileentity.receiveClientEvent(eventID, eventParam); - } + public boolean onBlockEventReceived(World world, BlockPos pos, State state, int id, int param) { + super.onBlockEventReceived(world, pos, state, id, param); + TileEntity tile = world.getTileEntity(pos); + return tile == null ? false : tile.receiveClientEvent(id, param); + } } diff --git a/common/src/common/block/BlockDirectional.java b/common/src/common/block/BlockDirectional.java index b80351a..bd75e9c 100755 --- a/common/src/common/block/BlockDirectional.java +++ b/common/src/common/block/BlockDirectional.java @@ -4,12 +4,10 @@ import common.material.Material; import common.properties.PropertyDirection; import common.util.Facing; -public abstract class BlockDirectional extends Block -{ - public static final PropertyDirection FACING = PropertyDirection.create("facing", Facing.Plane.HORIZONTAL); +public abstract class BlockDirectional extends Block { + public static final PropertyDirection FACING = PropertyDirection.create("facing", Facing.Plane.HORIZONTAL); - public BlockDirectional(Material materialIn) - { - super(materialIn); - } + public BlockDirectional(Material material) { + super(material); + } } diff --git a/common/src/common/block/BlockFalling.java b/common/src/common/block/BlockFalling.java index e483126..41ebf28 100755 --- a/common/src/common/block/BlockFalling.java +++ b/common/src/common/block/BlockFalling.java @@ -1,9 +1,9 @@ package common.block; +import common.block.natural.BlockFire; import common.entity.item.EntityFalling; import common.init.Blocks; import common.init.Config; -import common.item.CheatTab; import common.material.Material; import common.rng.Random; import common.util.BlockPos; @@ -11,93 +11,63 @@ import common.world.State; import common.world.World; import common.world.AWorldServer; -public class BlockFalling extends Block -{ - public static boolean fallInstantly; +public class BlockFalling extends Block { + public static boolean fallInstantly; - public BlockFalling() - { - super(Material.sand); - this.setTab(CheatTab.tabNature); - } + public static boolean canFallInto(World world, BlockPos pos) { + Block block = world.getState(pos).getBlock(); + return block instanceof BlockFire || block == Blocks.air || block.material.isLiquid(); + } - public BlockFalling(Material materialIn) - { - super(materialIn); - } + public BlockFalling(Material material) { + super(material); + } - public void onBlockAdded(AWorldServer worldIn, BlockPos pos, State state) - { - worldIn.scheduleUpdate(pos, this, this.tickRate(worldIn, pos)); - } + public void onBlockAdded(AWorldServer world, BlockPos pos, State state) { + world.scheduleUpdate(pos, this, this.tickRate(world, pos)); + } - /** - * Called when a neighboring block changes. - */ - public void onNeighborBlockChange(World worldIn, BlockPos pos, State state, Block neighborBlock) - { - worldIn.scheduleUpdate(pos, this, this.tickRate(worldIn, pos)); - } + public void onNeighborBlockChange(World world, BlockPos pos, State state, Block neighbor) { + world.scheduleUpdate(pos, this, this.tickRate(world, pos)); + } - public void updateTick(AWorldServer worldIn, BlockPos pos, State state, Random rand) - { - if(/* !worldIn.client && */ Config.blockGravity) - this.checkFallable(worldIn, pos); - } + public void updateTick(AWorldServer world, BlockPos pos, State state, Random rand) { + if(Config.blockGravity) + this.checkFallable(world, pos); + } - private void checkFallable(World worldIn, BlockPos pos) - { - if (canFallInto(worldIn, pos.down()) && pos.getY() >= 0) - { - int i = 32; + private void checkFallable(World world, BlockPos pos) { + if(canFallInto(world, pos.down()) && pos.getY() >= 0) { + int range = 32; + if(!fallInstantly && world.isAreaLoaded(pos.add(-range, -range, -range), pos.add(range, range, range))) { + if(!world.client) { + EntityFalling entity = new EntityFalling(world, (double)pos.getX() + 0.5D, (double)pos.getY(), + (double)pos.getZ() + 0.5D, world.getState(pos)); + this.onStartFalling(entity); + world.spawnEntityInWorld(entity); + } + } + else { + world.setBlockToAir(pos); + BlockPos loc; + int limit = 512; + for(loc = pos.down(); canFallInto(world, loc) && loc.getY() > -World.MAX_SIZE_Y; loc = loc.down()) { + if(--limit <= 0) + return; + } + if(loc.getY() > -World.MAX_SIZE_Y) + world.setState(loc.up(), this.getState()); + } + } + } - if (!fallInstantly && worldIn.isAreaLoaded(pos.add(-i, -i, -i), pos.add(i, i, i))) - { - if (!worldIn.client) - { - EntityFalling entityfallingblock = new EntityFalling(worldIn, (double)pos.getX() + 0.5D, (double)pos.getY(), (double)pos.getZ() + 0.5D, worldIn.getState(pos)); - this.onStartFalling(entityfallingblock); - worldIn.spawnEntityInWorld(entityfallingblock); - } - } - else - { - worldIn.setBlockToAir(pos); - BlockPos blockpos; + public int tickRate(World world, BlockPos pos) { + return 2; + } - for (blockpos = pos.down(); canFallInto(worldIn, blockpos) && blockpos.getY() > 0; blockpos = blockpos.down()) - { - ; - } + protected void onStartFalling(EntityFalling entity) { + } - if (blockpos.getY() > 0) - { - worldIn.setState(blockpos.up(), this.getState()); - } - } - } - } - - protected void onStartFalling(EntityFalling fallingEntity) - { - } - - /** - * How many world ticks before ticking - */ - public int tickRate(World worldIn, BlockPos pos) - { - return 2; - } - - public static boolean canFallInto(World worldIn, BlockPos pos) - { - Block block = worldIn.getState(pos).getBlock(); - Material material = block.material; - return block == Blocks.fire || material == Material.air || material.isLiquid(); - } - - public void onEndFalling(World worldIn, BlockPos pos) - { - } + public void onEndFalling(World world, BlockPos pos) { + } } diff --git a/common/src/common/block/BlockGlass.java b/common/src/common/block/BlockGlass.java deleted file mode 100755 index adc1e63..0000000 --- a/common/src/common/block/BlockGlass.java +++ /dev/null @@ -1,38 +0,0 @@ -package common.block; - -import common.item.CheatTab; -import common.material.Material; -import common.model.BlockLayer; -import common.rng.Random; - -public class BlockGlass extends BlockBreakable -{ - public BlockGlass(Material materialIn, boolean ignoreSimilarity) - { - super(materialIn, ignoreSimilarity); - this.setTab(CheatTab.tabBlocks); - } - - /** - * Returns the quantity of items to drop on block destruction. - */ - public int quantityDropped(Random random) - { - return 0; - } - - public BlockLayer getBlockLayer() - { - return BlockLayer.CUTOUT; - } - - public boolean isFullCube() - { - return false; - } - - public boolean canSilkHarvest() - { - return true; - } -} diff --git a/common/src/common/block/BlockIce.java b/common/src/common/block/BlockIce.java deleted file mode 100755 index a1e5981..0000000 --- a/common/src/common/block/BlockIce.java +++ /dev/null @@ -1,94 +0,0 @@ -package common.block; - -import common.enchantment.EnchantmentHelper; -import common.entity.npc.EntityNPC; -import common.init.Blocks; -import common.init.Config; -import common.item.CheatTab; -import common.item.ItemStack; -import common.material.Material; -import common.model.BlockLayer; -import common.rng.Random; -import common.tileentity.TileEntity; -import common.util.BlockPos; -import common.world.LightType; -import common.world.State; -import common.world.World; -import common.world.AWorldServer; - -public class BlockIce extends BlockBreakable -{ - public BlockIce() - { - super(Material.ice, false); - this.slipperiness = 0.98F; - this.setTickRandomly(); - this.setTab(CheatTab.tabNature); - } - - public BlockLayer getBlockLayer() - { - return BlockLayer.TRANSLUCENT; - } - - public void harvestBlock(World worldIn, EntityNPC player, BlockPos pos, State state, TileEntity te) - { -// player.triggerAchievement(StatRegistry.mineBlockStatArray[BlockRegistry.getIdFromBlock(this)]); - - if (this.canSilkHarvest() && EnchantmentHelper.getSilkTouchModifier(player)) - { - ItemStack itemstack = this.createStackedBlock(state); - - if (itemstack != null) - { - spawnAsEntity(worldIn, pos, itemstack); - } - } - else - { - if (worldIn.doesWaterVaporize(pos)) - { - worldIn.setBlockToAir(pos); - return; - } - - int i = EnchantmentHelper.getFortuneModifier(player); - this.dropBlockAsItem(worldIn, pos, state, i); - Material material = worldIn.getState(pos.down()).getBlock().getMaterial(); - - if (material.blocksMovement() || material.isLiquid()) - { - worldIn.setState(pos, Blocks.flowing_water.getState()); - } - } - } - - /** - * Returns the quantity of items to drop on block destruction. - */ - public int quantityDropped(Random random) - { - return 0; - } - - public void updateTick(AWorldServer worldIn, BlockPos pos, State state, Random rand) - { - if (Config.iceMelt && ((worldIn.getLightFor(LightType.BLOCK, pos) > 11 - this.getLightOpacity()) || !worldIn.canFreezeAt(pos))) - { - if (worldIn.doesWaterVaporize(pos)) - { - worldIn.setBlockToAir(pos); - } - else - { - this.dropBlockAsItem(worldIn, pos, worldIn.getState(pos), 0); - worldIn.setState(pos, Blocks.water.getState()); - } - } - } - - public int getMobilityFlag() - { - return 0; - } -} diff --git a/common/src/common/block/BlockRotatedPillar.java b/common/src/common/block/BlockRotatedPillar.java index 232db9c..3c72302 100755 --- a/common/src/common/block/BlockRotatedPillar.java +++ b/common/src/common/block/BlockRotatedPillar.java @@ -8,16 +8,14 @@ import common.properties.PropertyEnum; import common.util.Facing; import common.world.State; -public abstract class BlockRotatedPillar extends Block -{ - public static final PropertyEnum AXIS = PropertyEnum.create("axis", Facing.Axis.class); +public abstract class BlockRotatedPillar extends Block { + public static final PropertyEnum AXIS = PropertyEnum.create("axis", Facing.Axis.class); - public BlockRotatedPillar(Material materialIn) - { - super(materialIn); - } + public BlockRotatedPillar(Material material) { + super(material); + } - public Model getModel(ModelProvider provider, String name, State state) { + public Model getModel(ModelProvider provider, String name, State state) { switch(state.getValue(AXIS)) { case X: return provider.getModel(name + "_side").add().d().rot(180).u() @@ -31,5 +29,5 @@ public abstract class BlockRotatedPillar extends Block .n(name + "_top").rot(180).s(name + "_top").w().rot(270) .e().rot(90); } - } + } } diff --git a/common/src/common/block/BlockSlime.java b/common/src/common/block/BlockSlime.java deleted file mode 100755 index 64ba03a..0000000 --- a/common/src/common/block/BlockSlime.java +++ /dev/null @@ -1,93 +0,0 @@ -package common.block; - -import common.entity.Entity; -import common.item.CheatTab; -import common.material.Material; -import common.model.BlockLayer; -import common.model.Model; -import common.model.ModelProvider; -import common.util.BlockPos; -import common.world.State; -import common.world.World; - -public class BlockSlime extends BlockBreakable -{ - private static final Model slime = ModelProvider.getModelProvider().getModel("slime") - .add(0, 0, 0, 16, 16, 16) - .d().uv(0, 0, 16, 16).noCull() - .u().uv(0, 0, 16, 16).noCull() - .n().uv(0, 0, 16, 16).noCull() - .s().uv(0, 0, 16, 16).noCull() - .w().uv(0, 0, 16, 16).noCull() - .e().uv(0, 0, 16, 16).noCull() - .add(3, 3, 3, 13, 13, 13) - .d().uv(3, 3, 13, 13).noCull() - .u().uv(3, 3, 13, 13).noCull() - .n().uv(3, 3, 13, 13).noCull() - .s().uv(3, 3, 13, 13).noCull() - .w().uv(3, 3, 13, 13).noCull() - .e().uv(3, 3, 13, 13).noCull() - ; - - public BlockSlime() - { - super(Material.clay, false); - this.setTab(CheatTab.tabTech); - this.slipperiness = 0.8F; - } - - public BlockLayer getBlockLayer() - { - return BlockLayer.TRANSLUCENT; - } - - /** - * Block's chance to react to a living entity falling on it. - */ - public void onFallenUpon(World worldIn, BlockPos pos, Entity entityIn, float fallDistance) - { - if (entityIn.isSneaking()) - { - super.onFallenUpon(worldIn, pos, entityIn, fallDistance); - } - else - { - entityIn.fall(fallDistance, 0.0F); - } - } - - /** - * Called when an Entity lands on this Block. This method *must* update motionY because the entity will not do that - * on its own - */ - public void onLanded(World worldIn, Entity entityIn) - { - if (entityIn.isSneaking()) - { - super.onLanded(worldIn, entityIn); - } - else if (entityIn.motionY < 0.0D) - { - entityIn.motionY = -entityIn.motionY; - } - } - - /** - * Triggered whenever an entity collides with this block (enters into the block) - */ - public void onEntityCollidedWithBlock(World worldIn, BlockPos pos, Entity entityIn) - { - if (Math.abs(entityIn.motionY) < 0.1D && !entityIn.isSneaking()) - { - double d0 = 0.4D + Math.abs(entityIn.motionY) * 0.2D; - entityIn.motionX *= d0; - entityIn.motionZ *= d0; - } - - super.onEntityCollidedWithBlock(worldIn, pos, entityIn); - } - - public Model getModel(ModelProvider provider, String name, State state) { - return slime; - } -} diff --git a/common/src/common/block/BlockSnowBlock.java b/common/src/common/block/BlockSnowBlock.java deleted file mode 100755 index 0e4a60e..0000000 --- a/common/src/common/block/BlockSnowBlock.java +++ /dev/null @@ -1,47 +0,0 @@ -package common.block; - -import common.init.Config; -import common.init.Items; -import common.item.CheatTab; -import common.item.Item; -import common.material.Material; -import common.rng.Random; -import common.util.BlockPos; -import common.world.LightType; -import common.world.State; -import common.world.AWorldServer; - -public class BlockSnowBlock extends Block -{ - public BlockSnowBlock() - { - super(Material.craftedSnow); - this.setTickRandomly(); - this.setTab(CheatTab.tabNature); - } - - /** - * Get the Item that this Block should drop when harvested. - */ - public Item getItemDropped(State state, Random rand, int fortune) - { - return Items.snowball; - } - - /** - * Returns the quantity of items to drop on block destruction. - */ - public int quantityDropped(Random random) - { - return 4; - } - - public void updateTick(AWorldServer worldIn, BlockPos pos, State state, Random rand) - { - if (Config.snowFullMelt && worldIn.getLightFor(LightType.BLOCK, pos) > 11) - { - this.dropBlockAsItem(worldIn, pos, worldIn.getState(pos), 0); - worldIn.setBlockToAir(pos); - } - } -} diff --git a/common/src/common/block/BlockStainedGlass.java b/common/src/common/block/BlockStainedGlass.java deleted file mode 100755 index de0f6a2..0000000 --- a/common/src/common/block/BlockStainedGlass.java +++ /dev/null @@ -1,120 +0,0 @@ -package common.block; - -import java.util.List; - -import common.color.DyeColor; -import common.item.CheatTab; -import common.item.Item; -import common.item.ItemStack; -import common.material.Material; -import common.model.BlockLayer; -import common.model.Model; -import common.model.ModelProvider; -import common.properties.IProperty; -import common.properties.PropertyEnum; -import common.rng.Random; -import common.world.State; - -public class BlockStainedGlass extends BlockBreakable -{ - public static final PropertyEnum COLOR = PropertyEnum.create("color", DyeColor.class); - - public BlockStainedGlass(Material materialIn) - { - super(materialIn, false); - this.setDefaultState(this.getBaseState().withProperty(COLOR, DyeColor.WHITE)); - this.setTab(CheatTab.tabBlocks); - } - - /** - * Gets the metadata of the item this Block can drop. This method is called when the block gets destroyed. It - * returns the metadata of the dropped item based on the old metadata of the block. - */ - public int damageDropped(State state) - { - return ((DyeColor)state.getValue(COLOR)).getMetadata(); - } - - /** - * returns a list of blocks with the same ID, but different meta (eg: wood returns 4 blocks) - */ - public void getSubBlocks(Item itemIn, CheatTab tab, List list) - { - for (DyeColor enumdyecolor : DyeColor.values()) - { - list.add(new ItemStack(itemIn, 1, enumdyecolor.getMetadata())); - } - } - -// /** -// * Get the MapColor for this Block and the given BlockState -// */ -// public MapColor getMapColor(IBlockState state) -// { -// return ((EnumDyeColor)state.getValue(COLOR)).getMapColor(); -// } - - public BlockLayer getBlockLayer() - { - return BlockLayer.TRANSLUCENT; - } - - /** - * Returns the quantity of items to drop on block destruction. - */ - public int quantityDropped(Random random) - { - return 0; - } - - public boolean canSilkHarvest() - { - return true; - } - - public boolean isFullCube() - { - return false; - } - - /** - * Convert the given metadata into a BlockState for this Block - */ - public State getStateFromMeta(int meta) - { - return this.getState().withProperty(COLOR, DyeColor.byMetadata(meta)); - } - -// public void onBlockAdded(IWorldServer worldIn, BlockPos pos, State state) -// { -// if (!worldIn.client) -// { -// BlockBeacon.updateColorAsync(worldIn, pos); -// } -// } -// -// public void onBlockRemoved(IWorldServer worldIn, BlockPos pos, State state) -// { -// if (!worldIn.client) -// { -// BlockBeacon.updateColorAsync(worldIn, pos); -// } -// } - - /** - * Convert the BlockState into the correct metadata value - */ - public int getMetaFromState(State state) - { - return ((DyeColor)state.getValue(COLOR)).getMetadata(); - } - - protected IProperty[] getProperties() - { - return new IProperty[] {COLOR}; - } - - public Model getModel(ModelProvider provider, String name, State state) { - return provider.getModel(state.getValue(COLOR).getName() + "_glass").add().all(); - } -} diff --git a/common/src/common/block/BlockTranslucent.java b/common/src/common/block/BlockTranslucent.java new file mode 100755 index 0000000..d8466d4 --- /dev/null +++ b/common/src/common/block/BlockTranslucent.java @@ -0,0 +1,28 @@ +package common.block; + +import common.material.Material; +import common.model.BlockLayer; +import common.util.BlockPos; +import common.util.Facing; +import common.world.IWorldAccess; +import common.world.State; + +public class BlockTranslucent extends Block { + public BlockTranslucent(Material material) { + super(material); + } + + public final boolean isOpaqueCube() { + return false; + } + + public final BlockLayer getBlockLayer() { + return BlockLayer.TRANSLUCENT; + } + + public boolean shouldSideBeRendered(IWorldAccess world, BlockPos pos, Facing side) { + State state = world.getState(pos); + Block block = state.getBlock(); + return block != this && super.shouldSideBeRendered(world, pos, side); + } +} diff --git a/common/src/common/block/BlockTreasure.java b/common/src/common/block/BlockTreasure.java index 7f79172..d855f06 100755 --- a/common/src/common/block/BlockTreasure.java +++ b/common/src/common/block/BlockTreasure.java @@ -3,8 +3,8 @@ package common.block; import common.material.Material; public class BlockTreasure extends Block { - public BlockTreasure(Material materialIn) { - super(materialIn); + public BlockTreasure(Material material) { + super(material); } public boolean isXrayVisible() { diff --git a/common/src/common/block/ITileEntityProvider.java b/common/src/common/block/ITileEntityProvider.java index e23572a..fe4ab9f 100755 --- a/common/src/common/block/ITileEntityProvider.java +++ b/common/src/common/block/ITileEntityProvider.java @@ -3,7 +3,6 @@ package common.block; import common.tileentity.TileEntity; import common.world.World; -public interface ITileEntityProvider -{ - TileEntity createNewTileEntity(World worldIn); +public interface ITileEntityProvider { + TileEntity createNewTileEntity(World world); } diff --git a/common/src/common/block/BlockBed.java b/common/src/common/block/artificial/BlockBed.java similarity index 98% rename from common/src/common/block/BlockBed.java rename to common/src/common/block/artificial/BlockBed.java index 02e759e..057a671 100755 --- a/common/src/common/block/BlockBed.java +++ b/common/src/common/block/artificial/BlockBed.java @@ -1,5 +1,7 @@ -package common.block; +package common.block.artificial; +import common.block.Block; +import common.block.BlockDirectional; import common.color.DyeColor; import common.color.TextColor; import common.entity.npc.EntityNPC; diff --git a/common/src/common/block/BlockBookshelf.java b/common/src/common/block/artificial/BlockBookshelf.java similarity index 93% rename from common/src/common/block/BlockBookshelf.java rename to common/src/common/block/artificial/BlockBookshelf.java index a555b4c..1a05805 100755 --- a/common/src/common/block/BlockBookshelf.java +++ b/common/src/common/block/artificial/BlockBookshelf.java @@ -1,5 +1,6 @@ -package common.block; +package common.block.artificial; +import common.block.Block; import common.init.Items; import common.item.CheatTab; import common.item.Item; diff --git a/common/src/common/block/BlockCake.java b/common/src/common/block/artificial/BlockCake.java similarity index 99% rename from common/src/common/block/BlockCake.java rename to common/src/common/block/artificial/BlockCake.java index 6422758..7416723 100755 --- a/common/src/common/block/BlockCake.java +++ b/common/src/common/block/artificial/BlockCake.java @@ -1,5 +1,6 @@ -package common.block; +package common.block.artificial; +import common.block.Block; import common.entity.npc.EntityNPC; import common.init.Items; import common.item.Item; diff --git a/common/src/common/block/BlockCarpet.java b/common/src/common/block/artificial/BlockCarpet.java similarity index 98% rename from common/src/common/block/BlockCarpet.java rename to common/src/common/block/artificial/BlockCarpet.java index 9b9a970..b65b714 100755 --- a/common/src/common/block/BlockCarpet.java +++ b/common/src/common/block/artificial/BlockCarpet.java @@ -1,7 +1,8 @@ -package common.block; +package common.block.artificial; import java.util.List; +import common.block.Block; import common.color.DyeColor; import common.item.CheatTab; import common.item.Item; diff --git a/common/src/common/block/BlockCompressedPowered.java b/common/src/common/block/artificial/BlockCompressedPowered.java similarity index 91% rename from common/src/common/block/BlockCompressedPowered.java rename to common/src/common/block/artificial/BlockCompressedPowered.java index 4168977..94f5d1d 100755 --- a/common/src/common/block/BlockCompressedPowered.java +++ b/common/src/common/block/artificial/BlockCompressedPowered.java @@ -1,5 +1,6 @@ -package common.block; +package common.block.artificial; +import common.block.Block; import common.material.Material; import common.util.BlockPos; import common.util.Facing; diff --git a/common/src/common/block/BlockDoor.java b/common/src/common/block/artificial/BlockDoor.java similarity index 99% rename from common/src/common/block/BlockDoor.java rename to common/src/common/block/artificial/BlockDoor.java index b8e0e96..a57ff29 100755 --- a/common/src/common/block/BlockDoor.java +++ b/common/src/common/block/artificial/BlockDoor.java @@ -1,7 +1,8 @@ -package common.block; +package common.block.artificial; import java.util.List; +import common.block.Block; import common.collect.Lists; import common.entity.npc.EntityNPC; import common.init.Blocks; diff --git a/common/src/common/block/BlockDragonEgg.java b/common/src/common/block/artificial/BlockDragonEgg.java similarity index 97% rename from common/src/common/block/BlockDragonEgg.java rename to common/src/common/block/artificial/BlockDragonEgg.java index 2d90ee8..505977d 100755 --- a/common/src/common/block/BlockDragonEgg.java +++ b/common/src/common/block/artificial/BlockDragonEgg.java @@ -1,7 +1,10 @@ -package common.block; +package common.block.artificial; +import common.block.Block; +import common.block.BlockFalling; import common.entity.item.EntityFalling; import common.entity.npc.EntityNPC; +import common.init.Blocks; import common.init.Config; import common.material.Material; import common.model.Model; @@ -146,7 +149,7 @@ public class BlockDragonEgg extends Block { BlockPos blockpos = pos.add(worldIn.rand.zrange(16) - worldIn.rand.zrange(16), worldIn.rand.zrange(8) - worldIn.rand.zrange(8), worldIn.rand.zrange(16) - worldIn.rand.zrange(16)); - if (worldIn.getState(blockpos).getBlock().material == Material.air) + if (worldIn.getState(blockpos).getBlock() == Blocks.air) { if (worldIn.client) { diff --git a/common/src/common/block/BlockFence.java b/common/src/common/block/artificial/BlockFence.java similarity index 97% rename from common/src/common/block/BlockFence.java rename to common/src/common/block/artificial/BlockFence.java index 3bd2657..f13437d 100755 --- a/common/src/common/block/BlockFence.java +++ b/common/src/common/block/artificial/BlockFence.java @@ -1,7 +1,8 @@ -package common.block; +package common.block.artificial; import java.util.List; +import common.block.Block; import common.collect.Lists; import common.entity.Entity; import common.entity.npc.EntityNPC; @@ -165,7 +166,7 @@ public class BlockFence extends Block public boolean canConnectTo(IBlockAccess worldIn, BlockPos pos) { Block block = worldIn.getState(pos).getBlock(); - return ((!(block instanceof BlockFence) || block.material != this.material) && !(block instanceof BlockFenceGate) ? (block.material.isOpaque() && block.isFullCube() ? block.material != Material.gourd : false) : true); + return ((!(block instanceof BlockFence) || block.getMaterial() != this.material) && !(block instanceof BlockFenceGate) ? (block.getMaterial().isOpaque() && block.isFullCube() ? block.getMaterial() != Material.gourd : false) : true); } public boolean shouldSideBeRendered(IWorldAccess worldIn, BlockPos pos, Facing side) diff --git a/common/src/common/block/BlockFenceGate.java b/common/src/common/block/artificial/BlockFenceGate.java similarity index 99% rename from common/src/common/block/BlockFenceGate.java rename to common/src/common/block/artificial/BlockFenceGate.java index 93421f8..41305d5 100755 --- a/common/src/common/block/BlockFenceGate.java +++ b/common/src/common/block/artificial/BlockFenceGate.java @@ -1,5 +1,7 @@ -package common.block; +package common.block.artificial; +import common.block.Block; +import common.block.BlockDirectional; import common.entity.npc.EntityNPC; import common.entity.types.EntityLiving; import common.init.Blocks; diff --git a/common/src/common/block/BlockFloorPortal.java b/common/src/common/block/artificial/BlockFloorPortal.java similarity index 98% rename from common/src/common/block/BlockFloorPortal.java rename to common/src/common/block/artificial/BlockFloorPortal.java index a365a47..7ae4afc 100755 --- a/common/src/common/block/BlockFloorPortal.java +++ b/common/src/common/block/artificial/BlockFloorPortal.java @@ -1,9 +1,10 @@ -package common.block; +package common.block.artificial; import java.util.List; import java.util.Map; import java.util.Set; +import common.block.Block; import common.collect.Sets; import common.entity.Entity; import common.item.Item; diff --git a/common/src/common/block/BlockFlowerPot.java b/common/src/common/block/artificial/BlockFlowerPot.java similarity index 99% rename from common/src/common/block/BlockFlowerPot.java rename to common/src/common/block/artificial/BlockFlowerPot.java index d25970a..85884a6 100755 --- a/common/src/common/block/BlockFlowerPot.java +++ b/common/src/common/block/artificial/BlockFlowerPot.java @@ -1,5 +1,7 @@ -package common.block; +package common.block.artificial; +import common.block.Block; +import common.block.foliage.BlockFlower; import common.entity.npc.EntityNPC; import common.init.Blocks; import common.init.ItemRegistry; diff --git a/common/src/common/block/artificial/BlockGlass.java b/common/src/common/block/artificial/BlockGlass.java new file mode 100755 index 0000000..fb3fe69 --- /dev/null +++ b/common/src/common/block/artificial/BlockGlass.java @@ -0,0 +1,44 @@ +package common.block.artificial; + +import common.block.Block; +import common.item.CheatTab; +import common.material.Material; +import common.model.BlockLayer; +import common.rng.Random; +import common.util.BlockPos; +import common.util.Facing; +import common.world.IWorldAccess; +import common.world.State; + +public class BlockGlass extends Block { + public BlockGlass() { + super(Material.glass); + this.setTab(CheatTab.tabBlocks); + } + + public int quantityDropped(Random rand) { + return 0; + } + + public BlockLayer getBlockLayer() { + return BlockLayer.CUTOUT; + } + + public boolean isOpaqueCube() { + return false; + } + + public boolean isFullCube() { + return false; + } + + public boolean canSilkHarvest() { + return true; + } + + public boolean shouldSideBeRendered(IWorldAccess world, BlockPos pos, Facing side) { + State state = world.getState(pos); + Block block = state.getBlock(); + return world.getState(pos.offset(side.getOpposite())) != state || (block != this && super.shouldSideBeRendered(world, pos, side)); + } +} diff --git a/common/src/common/block/BlockHay.java b/common/src/common/block/artificial/BlockHay.java similarity index 96% rename from common/src/common/block/BlockHay.java rename to common/src/common/block/artificial/BlockHay.java index a051aa5..e57d006 100755 --- a/common/src/common/block/BlockHay.java +++ b/common/src/common/block/artificial/BlockHay.java @@ -1,5 +1,6 @@ -package common.block; +package common.block.artificial; +import common.block.BlockRotatedPillar; import common.entity.types.EntityLiving; import common.init.ItemRegistry; import common.item.CheatTab; diff --git a/common/src/common/block/BlockLadder.java b/common/src/common/block/artificial/BlockLadder.java similarity index 98% rename from common/src/common/block/BlockLadder.java rename to common/src/common/block/artificial/BlockLadder.java index ee9d14a..b858fa4 100755 --- a/common/src/common/block/BlockLadder.java +++ b/common/src/common/block/artificial/BlockLadder.java @@ -1,5 +1,7 @@ -package common.block; +package common.block.artificial; +import common.block.Block; +import common.block.BlockDirectional; import common.entity.types.EntityLiving; import common.item.CheatTab; import common.material.Material; diff --git a/common/src/common/block/BlockPane.java b/common/src/common/block/artificial/BlockPane.java similarity index 99% rename from common/src/common/block/BlockPane.java rename to common/src/common/block/artificial/BlockPane.java index 5de8821..7637b62 100755 --- a/common/src/common/block/BlockPane.java +++ b/common/src/common/block/artificial/BlockPane.java @@ -1,7 +1,8 @@ -package common.block; +package common.block.artificial; import java.util.List; +import common.block.Block; import common.entity.Entity; import common.init.Blocks; import common.item.CheatTab; diff --git a/common/src/common/block/BlockPortal.java b/common/src/common/block/artificial/BlockPortal.java similarity index 97% rename from common/src/common/block/BlockPortal.java rename to common/src/common/block/artificial/BlockPortal.java index 190f899..f072880 100755 --- a/common/src/common/block/BlockPortal.java +++ b/common/src/common/block/artificial/BlockPortal.java @@ -1,7 +1,9 @@ -package common.block; +package common.block.artificial; import java.util.Map; +import common.block.Block; +import common.block.natural.BlockFire; import common.entity.Entity; import common.init.Blocks; import common.item.Item; @@ -23,7 +25,7 @@ import common.world.AWorldClient; import common.world.State; import common.world.World; -public class BlockPortal extends BlockBreakable +public class BlockPortal extends Block { public static final PropertyEnum AXIS = PropertyEnum.create("axis", Facing.Axis.class, Facing.Axis.X, Facing.Axis.Z); public static final PropertyInteger DIM = PropertyInteger.create("dim", 0, 7); @@ -32,7 +34,7 @@ public class BlockPortal extends BlockBreakable public BlockPortal() { - super(Material.portal, false); + super(Material.portal); this.setDefaultState(this.getBaseState().withProperty(AXIS, Facing.Axis.X).withProperty(DIM, 0)); // this.setTickRandomly(); } @@ -97,6 +99,14 @@ public class BlockPortal extends BlockBreakable return false; } + public boolean isOpaqueCube() { + return false; + } + + public BlockLayer getBlockLayer() { + return BlockLayer.TRANSLUCENT; + } + public boolean tryIgnitePortal(World worldIn, BlockPos pos, int dim) { BlockPortal.Size size = new BlockPortal.Size(worldIn, pos, Facing.Axis.X, dim); @@ -192,11 +202,6 @@ public class BlockPortal extends BlockBreakable return 0; } - public BlockLayer getBlockLayer() - { - return BlockLayer.TRANSLUCENT; - } - /** * Called When an Entity Collided with the Block */ @@ -323,7 +328,7 @@ public class BlockPortal extends BlockBreakable // { // BlockWorldState blockworldstate = blockpattern$patternhelper.translateOffset(i, j, 1); // -// if (blockworldstate.getBlockState() != null && blockworldstate.getBlockState().getBlock().getMaterial() != Material.air) +// if (blockworldstate.getBlockState() != null && blockworldstate.getBlockState().getBlock() != Blocks.air) // { // ++aint[enumfacing$axisdirection.ordinal()]; // } @@ -493,7 +498,7 @@ public class BlockPortal extends BlockBreakable protected boolean func_150857_a(Block p_150857_1_) { - return p_150857_1_.material == Material.air || p_150857_1_ == Blocks.fire || p_150857_1_ == Blocks.portal; + return p_150857_1_ == Blocks.air || p_150857_1_ instanceof BlockFire || p_150857_1_ == Blocks.portal; } public boolean func_150860_b() diff --git a/common/src/common/block/BlockPortalFrame.java b/common/src/common/block/artificial/BlockPortalFrame.java similarity index 98% rename from common/src/common/block/BlockPortalFrame.java rename to common/src/common/block/artificial/BlockPortalFrame.java index 2f2d61e..7be3dc0 100755 --- a/common/src/common/block/BlockPortalFrame.java +++ b/common/src/common/block/artificial/BlockPortalFrame.java @@ -1,7 +1,8 @@ -package common.block; +package common.block.artificial; import java.util.List; +import common.block.Block; import common.entity.Entity; import common.entity.npc.EntityNPC; import common.entity.types.EntityLiving; diff --git a/common/src/common/block/BlockQuartz.java b/common/src/common/block/artificial/BlockQuartz.java similarity index 99% rename from common/src/common/block/BlockQuartz.java rename to common/src/common/block/artificial/BlockQuartz.java index d8e6619..8aa5018 100755 --- a/common/src/common/block/BlockQuartz.java +++ b/common/src/common/block/artificial/BlockQuartz.java @@ -1,7 +1,8 @@ -package common.block; +package common.block.artificial; import java.util.List; +import common.block.Block; import common.entity.types.EntityLiving; import common.init.ItemRegistry; import common.item.CheatTab; diff --git a/common/src/common/block/BlockSlab.java b/common/src/common/block/artificial/BlockSlab.java similarity index 99% rename from common/src/common/block/BlockSlab.java rename to common/src/common/block/artificial/BlockSlab.java index 1daa63d..30c0ca2 100755 --- a/common/src/common/block/BlockSlab.java +++ b/common/src/common/block/artificial/BlockSlab.java @@ -1,7 +1,8 @@ -package common.block; +package common.block.artificial; import java.util.List; +import common.block.Block; import common.collect.Lists; import common.entity.Entity; import common.entity.types.EntityLiving; diff --git a/common/src/common/block/artificial/BlockStainedGlass.java b/common/src/common/block/artificial/BlockStainedGlass.java new file mode 100755 index 0000000..8ca8637 --- /dev/null +++ b/common/src/common/block/artificial/BlockStainedGlass.java @@ -0,0 +1,52 @@ +package common.block.artificial; + +import java.util.List; + +import common.color.DyeColor; +import common.item.CheatTab; +import common.item.Item; +import common.item.ItemStack; +import common.model.BlockLayer; +import common.model.Model; +import common.model.ModelProvider; +import common.properties.IProperty; +import common.properties.PropertyEnum; +import common.world.State; + +public class BlockStainedGlass extends BlockGlass { + public static final PropertyEnum COLOR = PropertyEnum.create("color", DyeColor.class); + + public BlockStainedGlass() { + this.setDefaultState(this.getBaseState().withProperty(COLOR, DyeColor.WHITE)); + } + + public int damageDropped(State state) { + return state.getValue(COLOR).getMetadata(); + } + + public void getSubBlocks(Item item, CheatTab tab, List list) { + for(DyeColor color : DyeColor.values()) { + list.add(new ItemStack(item, 1, color.getMetadata())); + } + } + + public BlockLayer getBlockLayer() { + return BlockLayer.TRANSLUCENT; + } + + public State getStateFromMeta(int meta) { + return this.getState().withProperty(COLOR, DyeColor.byMetadata(meta)); + } + + public int getMetaFromState(State state) { + return state.getValue(COLOR).getMetadata(); + } + + protected IProperty[] getProperties() { + return new IProperty[] {COLOR}; + } + + public Model getModel(ModelProvider provider, String name, State state) { + return provider.getModel(state.getValue(COLOR).getName() + "_glass").add().all(); + } +} diff --git a/common/src/common/block/BlockStainedGlassPane.java b/common/src/common/block/artificial/BlockStainedGlassPane.java similarity index 98% rename from common/src/common/block/BlockStainedGlassPane.java rename to common/src/common/block/artificial/BlockStainedGlassPane.java index 254d120..985dedd 100755 --- a/common/src/common/block/BlockStainedGlassPane.java +++ b/common/src/common/block/artificial/BlockStainedGlassPane.java @@ -1,4 +1,4 @@ -package common.block; +package common.block.artificial; import java.util.List; diff --git a/common/src/common/block/BlockStairs.java b/common/src/common/block/artificial/BlockStairs.java similarity index 98% rename from common/src/common/block/BlockStairs.java rename to common/src/common/block/artificial/BlockStairs.java index 8c6f5d9..6631556 100755 --- a/common/src/common/block/BlockStairs.java +++ b/common/src/common/block/artificial/BlockStairs.java @@ -1,8 +1,9 @@ -package common.block; +package common.block.artificial; import java.util.Arrays; import java.util.List; +import common.block.Block; import common.entity.Entity; import common.entity.npc.EntityNPC; import common.entity.types.EntityLiving; @@ -52,15 +53,15 @@ public class BlockStairs extends Block public BlockStairs(State modelState, String down, String up) { - super(modelState.getBlock().material); + super(modelState.getBlock().getMaterial()); this.setDefaultState(this.getBaseState().withProperty(FACING, Facing.NORTH).withProperty(HALF, BlockStairs.EnumHalf.BOTTOM).withProperty(SHAPE, BlockStairs.EnumShape.STRAIGHT)); this.modelBlock = modelState.getBlock(); this.modelState = modelState; - this.setHardness(this.modelBlock.blockHardness); - this.setResistance(this.modelBlock.blockResistance / 3.0F); + this.setHardness(this.modelBlock.getRawHardness()); + this.setResistance(this.modelBlock.getRawResistance() / 3.0F); this.setStepSound(this.modelBlock.sound); this.setLightOpacity(255); - this.setTab(modelState.getBlock().material == Material.wood ? CheatTab.tabWood : CheatTab.tabBlocks); + this.setTab(modelState.getBlock().getMaterial() == Material.wood ? CheatTab.tabWood : CheatTab.tabBlocks); this.downTex = down; this.upTex = up; } @@ -623,9 +624,9 @@ public class BlockStairs extends Block return this.modelBlock.isCollidable(); } - public boolean canCollideCheck(State state, boolean hitIfLiquid) + public boolean canCollideCheck(State state, boolean liquid) { - return this.modelBlock.canCollideCheck(state, hitIfLiquid); + return this.modelBlock.canCollideCheck(state, liquid); } public boolean canPlaceBlockAt(World worldIn, BlockPos pos) diff --git a/common/src/common/block/BlockStoneBrick.java b/common/src/common/block/artificial/BlockStoneBrick.java similarity index 98% rename from common/src/common/block/BlockStoneBrick.java rename to common/src/common/block/artificial/BlockStoneBrick.java index 0d38a04..cf3b2e5 100755 --- a/common/src/common/block/BlockStoneBrick.java +++ b/common/src/common/block/artificial/BlockStoneBrick.java @@ -1,7 +1,8 @@ -package common.block; +package common.block.artificial; import java.util.List; +import common.block.Block; import common.item.CheatTab; import common.item.Item; import common.item.ItemStack; diff --git a/common/src/common/block/BlockTrapDoor.java b/common/src/common/block/artificial/BlockTrapDoor.java similarity index 97% rename from common/src/common/block/BlockTrapDoor.java rename to common/src/common/block/artificial/BlockTrapDoor.java index c8fc2d7..ce757a3 100755 --- a/common/src/common/block/BlockTrapDoor.java +++ b/common/src/common/block/artificial/BlockTrapDoor.java @@ -1,5 +1,6 @@ -package common.block; +package common.block.artificial; +import common.block.Block; import common.entity.npc.EntityNPC; import common.entity.types.EntityLiving; import common.init.Blocks; @@ -249,7 +250,7 @@ public class BlockTrapDoor extends Block private static boolean isValidSupportBlock(Block blockIn) { - return blockIn.material.isOpaque() && blockIn.isFullCube() || blockIn == Blocks.glass || blockIn == Blocks.stained_glass || blockIn == Blocks.glowstone || blockIn instanceof BlockSlab || blockIn instanceof BlockStairs; + return blockIn.getMaterial().isOpaque() && blockIn.isFullCube() || blockIn == Blocks.glass || blockIn == Blocks.stained_glass || blockIn == Blocks.glowstone || blockIn instanceof BlockSlab || blockIn instanceof BlockStairs; } public BlockLayer getBlockLayer() diff --git a/common/src/common/block/BlockWall.java b/common/src/common/block/artificial/BlockWall.java similarity index 94% rename from common/src/common/block/BlockWall.java rename to common/src/common/block/artificial/BlockWall.java index 41ad2bf..ad017d8 100755 --- a/common/src/common/block/BlockWall.java +++ b/common/src/common/block/artificial/BlockWall.java @@ -1,7 +1,9 @@ -package common.block; +package common.block.artificial; import java.util.List; +import common.block.Block; +import common.init.Blocks; import common.item.CheatTab; import common.item.Item; import common.item.ItemStack; @@ -32,10 +34,10 @@ public class BlockWall extends Block public BlockWall(Block modelBlock) { - super(modelBlock.material); + super(modelBlock.getMaterial()); this.setDefaultState(this.getBaseState().withProperty(UP, Boolean.valueOf(false)).withProperty(NORTH, Boolean.valueOf(false)).withProperty(EAST, Boolean.valueOf(false)).withProperty(SOUTH, Boolean.valueOf(false)).withProperty(WEST, Boolean.valueOf(false)).withProperty(VARIANT, BlockWall.EnumType.NORMAL)); - this.setHardness(modelBlock.blockHardness); - this.setResistance(modelBlock.blockResistance / 3.0F); + this.setHardness(modelBlock.getRawHardness()); + this.setResistance(modelBlock.getRawResistance() / 3.0F); this.setStepSound(modelBlock.sound); this.setTab(CheatTab.tabBlocks); } @@ -124,7 +126,7 @@ public class BlockWall extends Block public boolean canConnectTo(IBlockAccess worldIn, BlockPos pos) { Block block = worldIn.getState(pos).getBlock(); - return (block != this && !(block instanceof BlockFenceGate) ? (block.material.isOpaque() && block.isFullCube() ? block.material != Material.gourd : false) : true); + return (block != this && !(block instanceof BlockFenceGate) ? (block.getMaterial().isOpaque() && block.isFullCube() ? block.getMaterial() != Material.gourd : false) : true); } /** @@ -174,7 +176,7 @@ public class BlockWall extends Block */ public State getActualState(State state, IWorldAccess worldIn, BlockPos pos) { - return state.withProperty(UP, Boolean.valueOf(worldIn.getState(pos.up()).getBlock().getMaterial() != Material.air)).withProperty(NORTH, Boolean.valueOf(this.canConnectTo(worldIn, pos.north()))).withProperty(EAST, Boolean.valueOf(this.canConnectTo(worldIn, pos.east()))).withProperty(SOUTH, Boolean.valueOf(this.canConnectTo(worldIn, pos.south()))).withProperty(WEST, Boolean.valueOf(this.canConnectTo(worldIn, pos.west()))); + return state.withProperty(UP, Boolean.valueOf(worldIn.getState(pos.up()).getBlock() != Blocks.air)).withProperty(NORTH, Boolean.valueOf(this.canConnectTo(worldIn, pos.north()))).withProperty(EAST, Boolean.valueOf(this.canConnectTo(worldIn, pos.east()))).withProperty(SOUTH, Boolean.valueOf(this.canConnectTo(worldIn, pos.south()))).withProperty(WEST, Boolean.valueOf(this.canConnectTo(worldIn, pos.west()))); } protected IProperty[] getProperties() diff --git a/common/src/common/block/BlockBaseFlower.java b/common/src/common/block/foliage/BlockBaseFlower.java similarity index 84% rename from common/src/common/block/BlockBaseFlower.java rename to common/src/common/block/foliage/BlockBaseFlower.java index 5d07b1b..413ec6e 100755 --- a/common/src/common/block/BlockBaseFlower.java +++ b/common/src/common/block/foliage/BlockBaseFlower.java @@ -1,4 +1,4 @@ -package common.block; +package common.block.foliage; public class BlockBaseFlower extends BlockFlower { diff --git a/common/src/common/block/BlockBlackenedSoil.java b/common/src/common/block/foliage/BlockBlackenedSoil.java similarity index 97% rename from common/src/common/block/BlockBlackenedSoil.java rename to common/src/common/block/foliage/BlockBlackenedSoil.java index e6c0e26..03d9df4 100644 --- a/common/src/common/block/BlockBlackenedSoil.java +++ b/common/src/common/block/foliage/BlockBlackenedSoil.java @@ -1,6 +1,7 @@ -package common.block; +package common.block.foliage; import common.biome.Biome; +import common.block.Block; import common.init.Blocks; import common.init.Config; import common.item.CheatTab; diff --git a/common/src/common/block/BlockBlueShroom.java b/common/src/common/block/foliage/BlockBlueShroom.java similarity index 97% rename from common/src/common/block/BlockBlueShroom.java rename to common/src/common/block/foliage/BlockBlueShroom.java index c6cc81b..a2e3a3c 100755 --- a/common/src/common/block/BlockBlueShroom.java +++ b/common/src/common/block/foliage/BlockBlueShroom.java @@ -1,5 +1,6 @@ -package common.block; +package common.block.foliage; +import common.block.Block; import common.init.Blocks; import common.init.Config; import common.model.Model; diff --git a/common/src/common/block/BlockBush.java b/common/src/common/block/foliage/BlockBush.java similarity index 97% rename from common/src/common/block/BlockBush.java rename to common/src/common/block/foliage/BlockBush.java index 4ff09d6..361bfeb 100755 --- a/common/src/common/block/BlockBush.java +++ b/common/src/common/block/foliage/BlockBush.java @@ -1,5 +1,6 @@ -package common.block; +package common.block.foliage; +import common.block.Block; import common.init.Blocks; import common.item.CheatTab; import common.material.Material; diff --git a/common/src/common/block/BlockCactus.java b/common/src/common/block/foliage/BlockCactus.java similarity index 98% rename from common/src/common/block/BlockCactus.java rename to common/src/common/block/foliage/BlockCactus.java index 92db3ca..5504d57 100755 --- a/common/src/common/block/BlockCactus.java +++ b/common/src/common/block/foliage/BlockCactus.java @@ -1,5 +1,6 @@ -package common.block; +package common.block.foliage; +import common.block.Block; import common.entity.DamageSource; import common.entity.Entity; import common.init.Blocks; diff --git a/common/src/common/block/BlockCarrot.java b/common/src/common/block/foliage/BlockCarrot.java similarity index 94% rename from common/src/common/block/BlockCarrot.java rename to common/src/common/block/foliage/BlockCarrot.java index be7f274..e35b94b 100755 --- a/common/src/common/block/BlockCarrot.java +++ b/common/src/common/block/foliage/BlockCarrot.java @@ -1,4 +1,4 @@ -package common.block; +package common.block.foliage; import common.init.Items; import common.item.Item; diff --git a/common/src/common/block/BlockCocoa.java b/common/src/common/block/foliage/BlockCocoa.java similarity index 98% rename from common/src/common/block/BlockCocoa.java rename to common/src/common/block/foliage/BlockCocoa.java index 7eff652..b8166d1 100755 --- a/common/src/common/block/BlockCocoa.java +++ b/common/src/common/block/foliage/BlockCocoa.java @@ -1,5 +1,7 @@ -package common.block; +package common.block.foliage; +import common.block.Block; +import common.block.BlockDirectional; import common.color.DyeColor; import common.entity.types.EntityLiving; import common.init.Blocks; diff --git a/common/src/common/block/BlockCrops.java b/common/src/common/block/foliage/BlockCrops.java similarity index 98% rename from common/src/common/block/BlockCrops.java rename to common/src/common/block/foliage/BlockCrops.java index fee8af4..7a5277a 100755 --- a/common/src/common/block/BlockCrops.java +++ b/common/src/common/block/foliage/BlockCrops.java @@ -1,5 +1,7 @@ -package common.block; +package common.block.foliage; +import common.block.Block; +import common.block.SoundType; import common.init.Blocks; import common.init.Config; import common.init.Items; diff --git a/common/src/common/block/BlockDeadBush.java b/common/src/common/block/foliage/BlockDeadBush.java similarity index 97% rename from common/src/common/block/BlockDeadBush.java rename to common/src/common/block/foliage/BlockDeadBush.java index 3e091db..87ae7aa 100755 --- a/common/src/common/block/BlockDeadBush.java +++ b/common/src/common/block/foliage/BlockDeadBush.java @@ -1,5 +1,6 @@ -package common.block; +package common.block.foliage; +import common.block.Block; import common.entity.npc.EntityNPC; import common.init.Blocks; import common.init.Items; diff --git a/common/src/common/block/BlockDoublePlant.java b/common/src/common/block/foliage/BlockDoublePlant.java similarity index 99% rename from common/src/common/block/BlockDoublePlant.java rename to common/src/common/block/foliage/BlockDoublePlant.java index 2e835f5..b854fb7 100755 --- a/common/src/common/block/BlockDoublePlant.java +++ b/common/src/common/block/foliage/BlockDoublePlant.java @@ -1,7 +1,10 @@ -package common.block; +package common.block.foliage; import java.util.List; +import common.block.Block; +import common.block.BlockDirectional; +import common.block.SoundType; import common.color.Colorizer; import common.entity.npc.EntityNPC; import common.entity.types.EntityLiving; diff --git a/common/src/common/block/BlockDryLeaves.java b/common/src/common/block/foliage/BlockDryLeaves.java similarity index 96% rename from common/src/common/block/BlockDryLeaves.java rename to common/src/common/block/foliage/BlockDryLeaves.java index 5ed08d6..d0d363a 100755 --- a/common/src/common/block/BlockDryLeaves.java +++ b/common/src/common/block/foliage/BlockDryLeaves.java @@ -1,5 +1,6 @@ -package common.block; +package common.block.foliage; +import common.block.SoundType; import common.init.Items; import common.item.CheatTab; import common.item.Item; diff --git a/common/src/common/block/BlockFarmland.java b/common/src/common/block/foliage/BlockFarmland.java similarity index 98% rename from common/src/common/block/BlockFarmland.java rename to common/src/common/block/foliage/BlockFarmland.java index 7367cf4..c195ff4 100755 --- a/common/src/common/block/BlockFarmland.java +++ b/common/src/common/block/foliage/BlockFarmland.java @@ -1,5 +1,7 @@ -package common.block; +package common.block.foliage; +import common.block.Block; +import common.block.natural.BlockDirt; import common.entity.Entity; import common.entity.types.EntityLiving; import common.init.Blocks; diff --git a/common/src/common/block/BlockFlower.java b/common/src/common/block/foliage/BlockFlower.java similarity index 99% rename from common/src/common/block/BlockFlower.java rename to common/src/common/block/foliage/BlockFlower.java index 2b2091f..15ab373 100755 --- a/common/src/common/block/BlockFlower.java +++ b/common/src/common/block/foliage/BlockFlower.java @@ -1,4 +1,4 @@ -package common.block; +package common.block.foliage; import java.util.Collection; import java.util.List; diff --git a/common/src/common/block/BlockGrass.java b/common/src/common/block/foliage/BlockGrass.java similarity index 98% rename from common/src/common/block/BlockGrass.java rename to common/src/common/block/foliage/BlockGrass.java index 2f1ddcf..d121dd4 100755 --- a/common/src/common/block/BlockGrass.java +++ b/common/src/common/block/foliage/BlockGrass.java @@ -1,6 +1,8 @@ -package common.block; +package common.block.foliage; import common.biome.IBiome; +import common.block.Block; +import common.block.natural.BlockDirt; import common.color.Colorizer; import common.init.Blocks; import common.init.Config; diff --git a/common/src/common/block/BlockHugeMushroom.java b/common/src/common/block/foliage/BlockHugeMushroom.java similarity index 99% rename from common/src/common/block/BlockHugeMushroom.java rename to common/src/common/block/foliage/BlockHugeMushroom.java index f4d6262..57d8da5 100755 --- a/common/src/common/block/BlockHugeMushroom.java +++ b/common/src/common/block/foliage/BlockHugeMushroom.java @@ -1,5 +1,6 @@ -package common.block; +package common.block.foliage; +import common.block.Block; import common.entity.types.EntityLiving; import common.init.ItemRegistry; import common.item.Item; diff --git a/common/src/common/block/BlockLeaves.java b/common/src/common/block/foliage/BlockLeaves.java similarity index 99% rename from common/src/common/block/BlockLeaves.java rename to common/src/common/block/foliage/BlockLeaves.java index 8c2014a..d3eaddb 100755 --- a/common/src/common/block/BlockLeaves.java +++ b/common/src/common/block/foliage/BlockLeaves.java @@ -1,7 +1,9 @@ -package common.block; +package common.block.foliage; import java.util.List; +import common.block.Block; +import common.block.SoundType; import common.collect.Lists; import common.color.Colorizer; import common.entity.npc.EntityNPC; diff --git a/common/src/common/block/BlockLeavesBase.java b/common/src/common/block/foliage/BlockLeavesBase.java similarity index 94% rename from common/src/common/block/BlockLeavesBase.java rename to common/src/common/block/foliage/BlockLeavesBase.java index 2c7a3c2..f2e8cad 100755 --- a/common/src/common/block/BlockLeavesBase.java +++ b/common/src/common/block/foliage/BlockLeavesBase.java @@ -1,5 +1,6 @@ -package common.block; +package common.block.foliage; +import common.block.Block; import common.material.Material; import common.model.BlockLayer; diff --git a/common/src/common/block/BlockLilyPad.java b/common/src/common/block/foliage/BlockLilyPad.java similarity index 95% rename from common/src/common/block/BlockLilyPad.java rename to common/src/common/block/foliage/BlockLilyPad.java index 2886bef..42f22ba 100755 --- a/common/src/common/block/BlockLilyPad.java +++ b/common/src/common/block/foliage/BlockLilyPad.java @@ -1,7 +1,11 @@ -package common.block; +package common.block.foliage; import java.util.List; +import common.block.Block; +import common.block.BlockDirectional; +import common.block.liquid.BlockLiquid; +import common.block.liquid.BlockStaticLiquid; import common.entity.Entity; import common.entity.item.EntityBoat; import common.entity.types.EntityLiving; diff --git a/common/src/common/block/BlockLog.java b/common/src/common/block/foliage/BlockLog.java similarity index 98% rename from common/src/common/block/BlockLog.java rename to common/src/common/block/foliage/BlockLog.java index 1646cf3..9397b97 100755 --- a/common/src/common/block/BlockLog.java +++ b/common/src/common/block/foliage/BlockLog.java @@ -1,5 +1,7 @@ -package common.block; +package common.block.foliage; +import common.block.BlockRotatedPillar; +import common.block.SoundType; import common.entity.types.EntityLiving; import common.item.CheatTab; import common.material.Material; diff --git a/common/src/common/block/BlockMelon.java b/common/src/common/block/foliage/BlockMelon.java similarity index 95% rename from common/src/common/block/BlockMelon.java rename to common/src/common/block/foliage/BlockMelon.java index 53e8c84..03988f0 100755 --- a/common/src/common/block/BlockMelon.java +++ b/common/src/common/block/foliage/BlockMelon.java @@ -1,5 +1,6 @@ -package common.block; +package common.block.foliage; +import common.block.Block; import common.init.Items; import common.item.CheatTab; import common.item.Item; diff --git a/common/src/common/block/BlockMushroom.java b/common/src/common/block/foliage/BlockMushroom.java similarity index 97% rename from common/src/common/block/BlockMushroom.java rename to common/src/common/block/foliage/BlockMushroom.java index 2753e63..bd39bc4 100755 --- a/common/src/common/block/BlockMushroom.java +++ b/common/src/common/block/foliage/BlockMushroom.java @@ -1,6 +1,8 @@ -package common.block; +package common.block.foliage; import common.biome.IBiome; +import common.block.Block; +import common.block.natural.BlockDirt; import common.init.Blocks; import common.init.Config; import common.model.Model; diff --git a/common/src/common/block/BlockMycelium.java b/common/src/common/block/foliage/BlockMycelium.java similarity index 97% rename from common/src/common/block/BlockMycelium.java rename to common/src/common/block/foliage/BlockMycelium.java index 977c979..f1580ef 100755 --- a/common/src/common/block/BlockMycelium.java +++ b/common/src/common/block/foliage/BlockMycelium.java @@ -1,5 +1,7 @@ -package common.block; +package common.block.foliage; +import common.block.Block; +import common.block.natural.BlockDirt; import common.init.Blocks; import common.init.Config; import common.item.CheatTab; diff --git a/common/src/common/block/BlockPotato.java b/common/src/common/block/foliage/BlockPotato.java similarity index 97% rename from common/src/common/block/BlockPotato.java rename to common/src/common/block/foliage/BlockPotato.java index bc74922..2083b27 100755 --- a/common/src/common/block/BlockPotato.java +++ b/common/src/common/block/foliage/BlockPotato.java @@ -1,4 +1,4 @@ -package common.block; +package common.block.foliage; import common.init.Items; import common.item.Item; diff --git a/common/src/common/block/BlockPumpkin.java b/common/src/common/block/foliage/BlockPumpkin.java similarity index 97% rename from common/src/common/block/BlockPumpkin.java rename to common/src/common/block/foliage/BlockPumpkin.java index 53866ad..49a23bd 100755 --- a/common/src/common/block/BlockPumpkin.java +++ b/common/src/common/block/foliage/BlockPumpkin.java @@ -1,5 +1,6 @@ -package common.block; +package common.block.foliage; +import common.block.BlockDirectional; import common.entity.types.EntityLiving; import common.item.CheatTab; import common.material.Material; @@ -111,7 +112,7 @@ public class BlockPumpkin extends BlockDirectional public boolean canPlaceBlockAt(World worldIn, BlockPos pos) { - return worldIn.getState(pos).getBlock().material.isReplaceable() && worldIn.isBlockSolid(pos.down()); + return worldIn.getState(pos).getBlock().getMaterial().isReplaceable() && worldIn.isBlockSolid(pos.down()); } /** diff --git a/common/src/common/block/BlockReed.java b/common/src/common/block/foliage/BlockReed.java similarity index 98% rename from common/src/common/block/BlockReed.java rename to common/src/common/block/foliage/BlockReed.java index 8d7b151..16a91e4 100755 --- a/common/src/common/block/BlockReed.java +++ b/common/src/common/block/foliage/BlockReed.java @@ -1,5 +1,6 @@ -package common.block; +package common.block.foliage; +import common.block.Block; import common.init.Blocks; import common.init.Config; import common.init.Items; diff --git a/common/src/common/block/BlockSapling.java b/common/src/common/block/foliage/BlockSapling.java similarity index 99% rename from common/src/common/block/BlockSapling.java rename to common/src/common/block/foliage/BlockSapling.java index f03ba37..b2b4702 100755 --- a/common/src/common/block/BlockSapling.java +++ b/common/src/common/block/foliage/BlockSapling.java @@ -1,4 +1,4 @@ -package common.block; +package common.block.foliage; import java.util.List; diff --git a/common/src/common/block/BlockStem.java b/common/src/common/block/foliage/BlockStem.java similarity index 98% rename from common/src/common/block/BlockStem.java rename to common/src/common/block/foliage/BlockStem.java index d42ae2b..7467439 100755 --- a/common/src/common/block/BlockStem.java +++ b/common/src/common/block/foliage/BlockStem.java @@ -1,14 +1,14 @@ -package common.block; +package common.block.foliage; import java.util.function.Predicate; +import common.block.Block; import common.init.Blocks; import common.init.Config; import common.init.Items; import common.item.CheatTab; import common.item.Item; import common.item.ItemStack; -import common.material.Material; import common.model.Model; import common.model.ModelProvider; import common.model.ModelRotation; @@ -103,7 +103,7 @@ public class BlockStem extends BlockBush implements IGrowable pos = pos.offset(Facing.Plane.HORIZONTAL.random(rand)); Block block = worldIn.getState(pos.down()).getBlock(); - if (worldIn.getState(pos).getBlock().material == Material.air && (block == Blocks.farmland || block == Blocks.dirt || block == Blocks.grass)) + if (worldIn.getState(pos).getBlock() == Blocks.air && (block == Blocks.farmland || block == Blocks.dirt || block == Blocks.grass)) { worldIn.setState(pos, this.crop.getState()); } diff --git a/common/src/common/block/BlockTallGrass.java b/common/src/common/block/foliage/BlockTallGrass.java similarity index 99% rename from common/src/common/block/BlockTallGrass.java rename to common/src/common/block/foliage/BlockTallGrass.java index a527f19..f7cf36d 100755 --- a/common/src/common/block/BlockTallGrass.java +++ b/common/src/common/block/foliage/BlockTallGrass.java @@ -1,4 +1,4 @@ -package common.block; +package common.block.foliage; import java.util.List; diff --git a/common/src/common/block/BlockTianSoil.java b/common/src/common/block/foliage/BlockTianSoil.java similarity index 96% rename from common/src/common/block/BlockTianSoil.java rename to common/src/common/block/foliage/BlockTianSoil.java index ac03fd9..de7465e 100755 --- a/common/src/common/block/BlockTianSoil.java +++ b/common/src/common/block/foliage/BlockTianSoil.java @@ -1,5 +1,6 @@ -package common.block; +package common.block.foliage; +import common.block.Block; import common.init.Blocks; import common.item.CheatTab; import common.item.Item; diff --git a/common/src/common/block/BlockVine.java b/common/src/common/block/foliage/BlockVine.java similarity index 98% rename from common/src/common/block/BlockVine.java rename to common/src/common/block/foliage/BlockVine.java index a674c81..7f2a9a1 100755 --- a/common/src/common/block/BlockVine.java +++ b/common/src/common/block/foliage/BlockVine.java @@ -1,5 +1,6 @@ -package common.block; +package common.block.foliage; +import common.block.Block; import common.color.Colorizer; import common.entity.npc.EntityNPC; import common.entity.types.EntityLiving; @@ -177,7 +178,7 @@ public class BlockVine extends Block private boolean canPlaceOn(Block blockIn) { - return blockIn.isFullCube() && blockIn.material.blocksMovement(); + return blockIn.isFullCube() && blockIn.getMaterial().blocksMovement(); } private boolean recheckGrownSides(World worldIn, BlockPos pos, State state) @@ -307,7 +308,7 @@ public class BlockVine extends Block BlockPos blockpos3 = pos.offset(enumfacing1); Block block1 = worldIn.getState(blockpos3).getBlock(); - if (block1.material == Material.air) + if (block1 == Blocks.air) { Facing enumfacing2 = enumfacing1.rotateY(); Facing enumfacing4 = enumfacing1.rotateYCCW(); @@ -337,7 +338,7 @@ public class BlockVine extends Block worldIn.setState(blockpos3, this.getState(), 2); } } - else if (block1.material.isOpaque() && block1.isFullCube()) + else if (block1.getMaterial().isOpaque() && block1.isFullCube()) { worldIn.setState(pos, state.withProperty(getPropertyFor(enumfacing1), Boolean.valueOf(true)), 2); } @@ -351,7 +352,7 @@ public class BlockVine extends Block State iblockstate = worldIn.getState(blockpos2); Block block = iblockstate.getBlock(); - if (block.material == Material.air) + if (block == Blocks.air) { State iblockstate1 = state; diff --git a/common/src/common/block/BlockWart.java b/common/src/common/block/foliage/BlockWart.java similarity index 98% rename from common/src/common/block/BlockWart.java rename to common/src/common/block/foliage/BlockWart.java index 3937dbe..7ac9919 100755 --- a/common/src/common/block/BlockWart.java +++ b/common/src/common/block/foliage/BlockWart.java @@ -1,5 +1,6 @@ -package common.block; +package common.block.foliage; +import common.block.Block; import common.init.Blocks; import common.init.Config; import common.init.Items; diff --git a/common/src/common/block/IGrowable.java b/common/src/common/block/foliage/IGrowable.java similarity index 93% rename from common/src/common/block/IGrowable.java rename to common/src/common/block/foliage/IGrowable.java index 9bb72c7..87ca9b8 100755 --- a/common/src/common/block/IGrowable.java +++ b/common/src/common/block/foliage/IGrowable.java @@ -1,4 +1,4 @@ -package common.block; +package common.block.foliage; import common.rng.Random; import common.util.BlockPos; diff --git a/common/src/common/block/LeavesType.java b/common/src/common/block/foliage/LeavesType.java similarity index 93% rename from common/src/common/block/LeavesType.java rename to common/src/common/block/foliage/LeavesType.java index 25b730d..0a918bf 100755 --- a/common/src/common/block/LeavesType.java +++ b/common/src/common/block/foliage/LeavesType.java @@ -1,4 +1,4 @@ -package common.block; +package common.block.foliage; import common.util.Identifyable; diff --git a/common/src/common/block/BlockDynamicLiquid.java b/common/src/common/block/liquid/BlockDynamicLiquid.java similarity index 97% rename from common/src/common/block/BlockDynamicLiquid.java rename to common/src/common/block/liquid/BlockDynamicLiquid.java index e9a1eda..3684eec 100755 --- a/common/src/common/block/BlockDynamicLiquid.java +++ b/common/src/common/block/liquid/BlockDynamicLiquid.java @@ -1,8 +1,10 @@ -package common.block; +package common.block.liquid; import java.util.EnumSet; import java.util.Set; +import common.block.Block; +import common.block.artificial.BlockDoor; import common.init.Blocks; import common.init.Config; import common.material.Material; @@ -260,7 +262,7 @@ public class BlockDynamicLiquid extends BlockLiquid private boolean isBlocked(World worldIn, BlockPos pos, State state) { Block block = worldIn.getState(pos).getBlock(); - return !(block instanceof BlockDoor) && block != Blocks.sign && block != Blocks.ladder && block != Blocks.reeds ? (block.material == Material.portal ? true : block.material.blocksMovement()) : true; + return !(block instanceof BlockDoor) && block != Blocks.sign && block != Blocks.ladder && block != Blocks.reeds ? (block.getMaterial() == Material.portal ? true : block.getMaterial().blocksMovement()) : true; } protected int checkAdjacentBlock(World worldIn, BlockPos pos, int currentMinLevel) diff --git a/common/src/common/block/BlockLiquid.java b/common/src/common/block/liquid/BlockLiquid.java similarity index 97% rename from common/src/common/block/BlockLiquid.java rename to common/src/common/block/liquid/BlockLiquid.java index 9f036fd..2b82174 100755 --- a/common/src/common/block/BlockLiquid.java +++ b/common/src/common/block/liquid/BlockLiquid.java @@ -1,5 +1,6 @@ -package common.block; +package common.block.liquid; +import common.block.Block; import common.color.Colorizer; import common.entity.Entity; import common.init.Blocks; @@ -90,9 +91,9 @@ public abstract class BlockLiquid extends Block return false; } - public boolean canCollideCheck(State state, boolean hitIfLiquid) + public boolean canCollideCheck(State state, boolean liquid) { - return hitIfLiquid && ((Integer)state.getValue(LEVEL)).intValue() == 0; + return liquid && ((Integer)state.getValue(LEVEL)).intValue() == 0; } /** @@ -257,7 +258,7 @@ public abstract class BlockLiquid extends Block } } - if (this.material == Material.lava && worldIn.getState(pos.up()).getBlock().getMaterial() == Material.air && !worldIn.getState(pos.up()).getBlock().isOpaqueCube()) + if (this.material == Material.lava && worldIn.getState(pos.up()).getBlock() == Blocks.air && !worldIn.getState(pos.up()).getBlock().isOpaqueCube()) { if (rand.chance(100)) { diff --git a/common/src/common/block/BlockStaticLiquid.java b/common/src/common/block/liquid/BlockStaticLiquid.java similarity index 94% rename from common/src/common/block/BlockStaticLiquid.java rename to common/src/common/block/liquid/BlockStaticLiquid.java index 5b5b29f..5c7f069 100755 --- a/common/src/common/block/BlockStaticLiquid.java +++ b/common/src/common/block/liquid/BlockStaticLiquid.java @@ -1,5 +1,6 @@ -package common.block; +package common.block.liquid; +import common.block.Block; import common.init.Blocks; import common.init.Config; import common.material.Material; @@ -58,7 +59,7 @@ public class BlockStaticLiquid extends BlockLiquid blockpos = blockpos.add(rand.zrange(3) - 1, 1, rand.zrange(3) - 1); Block block = worldIn.getState(blockpos).getBlock(); - if (block.material == Material.air) + if (block == Blocks.air) { if (this.isSurroundingBlockFlammable(worldIn, blockpos)) { @@ -66,7 +67,7 @@ public class BlockStaticLiquid extends BlockLiquid return; } } - else if (block.material.blocksMovement()) + else if (block.getMaterial().blocksMovement()) { return; } diff --git a/common/src/common/block/BlockBedrock.java b/common/src/common/block/natural/BlockBedrock.java similarity index 89% rename from common/src/common/block/BlockBedrock.java rename to common/src/common/block/natural/BlockBedrock.java index 71ec977..831e002 100755 --- a/common/src/common/block/BlockBedrock.java +++ b/common/src/common/block/natural/BlockBedrock.java @@ -1,5 +1,6 @@ -package common.block; +package common.block.natural; +import common.block.Block; import common.material.Material; import common.model.ParticleType; import common.rng.Random; diff --git a/common/src/common/block/BlockBlackenedDirt.java b/common/src/common/block/natural/BlockBlackenedDirt.java similarity index 96% rename from common/src/common/block/BlockBlackenedDirt.java rename to common/src/common/block/natural/BlockBlackenedDirt.java index 6e821ae..6eff390 100644 --- a/common/src/common/block/BlockBlackenedDirt.java +++ b/common/src/common/block/natural/BlockBlackenedDirt.java @@ -1,6 +1,7 @@ -package common.block; +package common.block.natural; import common.biome.Biome; +import common.block.Block; import common.init.Blocks; import common.init.Config; import common.item.CheatTab; diff --git a/common/src/common/block/BlockBlackenedStone.java b/common/src/common/block/natural/BlockBlackenedStone.java similarity index 89% rename from common/src/common/block/BlockBlackenedStone.java rename to common/src/common/block/natural/BlockBlackenedStone.java index a28fdae..6e8dec7 100644 --- a/common/src/common/block/BlockBlackenedStone.java +++ b/common/src/common/block/natural/BlockBlackenedStone.java @@ -1,5 +1,6 @@ -package common.block; +package common.block.natural; +import common.block.Block; import common.init.Blocks; import common.init.ItemRegistry; import common.item.CheatTab; diff --git a/common/src/common/block/BlockClay.java b/common/src/common/block/natural/BlockClay.java similarity index 92% rename from common/src/common/block/BlockClay.java rename to common/src/common/block/natural/BlockClay.java index c1d0259..1e34ea9 100755 --- a/common/src/common/block/BlockClay.java +++ b/common/src/common/block/natural/BlockClay.java @@ -1,5 +1,6 @@ -package common.block; +package common.block.natural; +import common.block.Block; import common.init.Items; import common.item.CheatTab; import common.item.Item; diff --git a/common/src/common/block/BlockDirt.java b/common/src/common/block/natural/BlockDirt.java similarity index 99% rename from common/src/common/block/BlockDirt.java rename to common/src/common/block/natural/BlockDirt.java index 11e24ab..682418e 100755 --- a/common/src/common/block/BlockDirt.java +++ b/common/src/common/block/natural/BlockDirt.java @@ -1,7 +1,8 @@ -package common.block; +package common.block.natural; import java.util.List; +import common.block.Block; import common.init.Blocks; import common.item.CheatTab; import common.item.Item; diff --git a/common/src/common/block/BlockFire.java b/common/src/common/block/natural/BlockFire.java similarity index 99% rename from common/src/common/block/BlockFire.java rename to common/src/common/block/natural/BlockFire.java index aee1003..bf1a0fe 100755 --- a/common/src/common/block/BlockFire.java +++ b/common/src/common/block/natural/BlockFire.java @@ -1,7 +1,8 @@ -package common.block; +package common.block.natural; import java.util.Map; +import common.block.Block; import common.init.Blocks; import common.init.Config; import common.init.FlammabilityRegistry; @@ -47,7 +48,7 @@ public class BlockFire extends Block int j = pos.getY(); int k = pos.getZ(); - if (!World.isSolidSurface(worldIn.getState(pos.down())) && !Blocks.fire.canCatchFire(worldIn, pos.down())) + if (!World.isSolidSurface(worldIn.getState(pos.down())) && !this.canCatchFire(worldIn, pos.down())) { boolean flag = (i + j + k & 1) == 1; boolean flag1 = (i / 2 + j / 2 + k / 2 & 1) == 1; @@ -353,9 +354,9 @@ public class BlockFire extends Block worldIn.playSound((double)((float)pos.getX() + 0.5F), (double)((float)pos.getY() + 0.5F), (double)((float)pos.getZ() + 0.5F), SoundEvent.FIRE, 1.0F + rand.floatv()); } - if (!worldIn.isBlockSolid(pos.down()) && !Blocks.fire.canCatchFire(worldIn, pos.down())) + if (!worldIn.isBlockSolid(pos.down()) && !this.canCatchFire(worldIn, pos.down())) { - if (Blocks.fire.canCatchFire(worldIn, pos.west())) + if (this.canCatchFire(worldIn, pos.west())) { for (int j = 0; j < 2; ++j) { @@ -366,7 +367,7 @@ public class BlockFire extends Block } } - if (Blocks.fire.canCatchFire(worldIn, pos.east())) + if (this.canCatchFire(worldIn, pos.east())) { for (int k = 0; k < 2; ++k) { @@ -377,7 +378,7 @@ public class BlockFire extends Block } } - if (Blocks.fire.canCatchFire(worldIn, pos.north())) + if (this.canCatchFire(worldIn, pos.north())) { for (int l = 0; l < 2; ++l) { @@ -388,7 +389,7 @@ public class BlockFire extends Block } } - if (Blocks.fire.canCatchFire(worldIn, pos.south())) + if (this.canCatchFire(worldIn, pos.south())) { for (int i1 = 0; i1 < 2; ++i1) { @@ -399,7 +400,7 @@ public class BlockFire extends Block } } - if (Blocks.fire.canCatchFire(worldIn, pos.up())) + if (this.canCatchFire(worldIn, pos.up())) { for (int j1 = 0; j1 < 2; ++j1) { diff --git a/common/src/common/block/BlockGlowstone.java b/common/src/common/block/natural/BlockGlowstone.java similarity index 95% rename from common/src/common/block/BlockGlowstone.java rename to common/src/common/block/natural/BlockGlowstone.java index ddcdf75..acd4128 100755 --- a/common/src/common/block/BlockGlowstone.java +++ b/common/src/common/block/natural/BlockGlowstone.java @@ -1,5 +1,6 @@ -package common.block; +package common.block.natural; +import common.block.Block; import common.init.Items; import common.item.CheatTab; import common.item.Item; diff --git a/common/src/common/block/BlockGravel.java b/common/src/common/block/natural/BlockGravel.java similarity index 76% rename from common/src/common/block/BlockGravel.java rename to common/src/common/block/natural/BlockGravel.java index 9206e53..7324de7 100755 --- a/common/src/common/block/BlockGravel.java +++ b/common/src/common/block/natural/BlockGravel.java @@ -1,14 +1,22 @@ -package common.block; +package common.block.natural; +import common.block.BlockFalling; import common.init.Config; import common.init.ItemRegistry; import common.init.Items; +import common.item.CheatTab; import common.item.Item; +import common.material.Material; import common.rng.Random; import common.world.State; public class BlockGravel extends BlockFalling { + public BlockGravel() { + super(Material.sand); + this.setTab(CheatTab.tabNature); + } + public Item getItemDropped(State state, Random rand, int fortune) { int chance = Config.flintChance; diff --git a/common/src/common/block/BlockHardenedClay.java b/common/src/common/block/natural/BlockHardenedClay.java similarity index 87% rename from common/src/common/block/BlockHardenedClay.java rename to common/src/common/block/natural/BlockHardenedClay.java index d3be1c4..ce20f4c 100755 --- a/common/src/common/block/BlockHardenedClay.java +++ b/common/src/common/block/natural/BlockHardenedClay.java @@ -1,5 +1,6 @@ -package common.block; +package common.block.natural; +import common.block.Block; import common.item.CheatTab; import common.material.Material; diff --git a/common/src/common/block/BlockHellRock.java b/common/src/common/block/natural/BlockHellRock.java similarity index 89% rename from common/src/common/block/BlockHellRock.java rename to common/src/common/block/natural/BlockHellRock.java index 26a4859..f381c4d 100755 --- a/common/src/common/block/BlockHellRock.java +++ b/common/src/common/block/natural/BlockHellRock.java @@ -1,5 +1,6 @@ -package common.block; +package common.block.natural; +import common.block.Block; import common.item.CheatTab; import common.material.Material; diff --git a/common/src/common/block/natural/BlockIce.java b/common/src/common/block/natural/BlockIce.java new file mode 100755 index 0000000..e63c36d --- /dev/null +++ b/common/src/common/block/natural/BlockIce.java @@ -0,0 +1,65 @@ +package common.block.natural; + +import common.block.BlockTranslucent; +import common.enchantment.EnchantmentHelper; +import common.entity.npc.EntityNPC; +import common.init.Blocks; +import common.init.Config; +import common.item.CheatTab; +import common.item.ItemStack; +import common.material.Material; +import common.rng.Random; +import common.tileentity.TileEntity; +import common.util.BlockPos; +import common.world.LightType; +import common.world.State; +import common.world.World; +import common.world.AWorldServer; + +public class BlockIce extends BlockTranslucent { + public BlockIce() { + super(Material.ice); + this.slipperiness = 0.98F; + this.setTickRandomly(); + this.setTab(CheatTab.tabNature); + } + + public void harvestBlock(World world, EntityNPC player, BlockPos pos, State state, TileEntity tile) { + if(this.canSilkHarvest() && EnchantmentHelper.getSilkTouchModifier(player)) { + ItemStack stack = this.createStackedBlock(state); + if(stack != null) + spawnAsEntity(world, pos, stack); + } + else { + if(world.doesWaterVaporize(pos)) { + world.setBlockToAir(pos); + return; + } + int fortune = EnchantmentHelper.getFortuneModifier(player); + this.dropBlockAsItem(world, pos, state, fortune); + Material material = world.getState(pos.down()).getBlock().getMaterial(); + if(material.blocksMovement() || material.isLiquid()) + world.setState(pos, Blocks.flowing_water.getState()); + } + } + + public int quantityDropped(Random rand) { + return 0; + } + + public void updateTick(AWorldServer world, BlockPos pos, State state, Random rand) { + if(Config.iceMelt && (world.getLightFor(LightType.BLOCK, pos) > 11 - this.getLightOpacity() || !world.canFreezeAt(pos))) { + if(world.doesWaterVaporize(pos)) { + world.setBlockToAir(pos); + } + else { + this.dropBlockAsItem(world, pos, world.getState(pos), 0); + world.setState(pos, Blocks.water.getState()); + } + } + } + + public int getMobilityFlag() { + return 0; + } +} diff --git a/common/src/common/block/BlockObsidian.java b/common/src/common/block/natural/BlockObsidian.java similarity index 93% rename from common/src/common/block/BlockObsidian.java rename to common/src/common/block/natural/BlockObsidian.java index b2c80f9..b8d60e9 100755 --- a/common/src/common/block/BlockObsidian.java +++ b/common/src/common/block/natural/BlockObsidian.java @@ -1,5 +1,6 @@ -package common.block; +package common.block.natural; +import common.block.Block; import common.init.Blocks; import common.init.ItemRegistry; import common.item.CheatTab; diff --git a/common/src/common/block/BlockOre.java b/common/src/common/block/natural/BlockOre.java similarity index 98% rename from common/src/common/block/BlockOre.java rename to common/src/common/block/natural/BlockOre.java index e83b028..3b7c759 100755 --- a/common/src/common/block/BlockOre.java +++ b/common/src/common/block/natural/BlockOre.java @@ -1,5 +1,6 @@ -package common.block; +package common.block.natural; +import common.block.Block; import common.init.Config; import common.init.ItemRegistry; import common.item.CheatTab; diff --git a/common/src/common/block/BlockPackedIce.java b/common/src/common/block/natural/BlockPackedIce.java similarity index 88% rename from common/src/common/block/BlockPackedIce.java rename to common/src/common/block/natural/BlockPackedIce.java index c21ff05..b79cee6 100755 --- a/common/src/common/block/BlockPackedIce.java +++ b/common/src/common/block/natural/BlockPackedIce.java @@ -1,5 +1,6 @@ -package common.block; +package common.block.natural; +import common.block.Block; import common.item.CheatTab; import common.material.Material; import common.rng.Random; diff --git a/common/src/common/block/BlockRedstoneOre.java b/common/src/common/block/natural/BlockRedstoneOre.java similarity index 98% rename from common/src/common/block/BlockRedstoneOre.java rename to common/src/common/block/natural/BlockRedstoneOre.java index 13eb609..48f4345 100755 --- a/common/src/common/block/BlockRedstoneOre.java +++ b/common/src/common/block/natural/BlockRedstoneOre.java @@ -1,5 +1,6 @@ -package common.block; +package common.block.natural; +import common.block.Block; import common.entity.Entity; import common.entity.npc.EntityNPC; import common.init.Blocks; diff --git a/common/src/common/block/BlockRock.java b/common/src/common/block/natural/BlockRock.java similarity index 95% rename from common/src/common/block/BlockRock.java rename to common/src/common/block/natural/BlockRock.java index a6f0e4d..83faa97 100755 --- a/common/src/common/block/BlockRock.java +++ b/common/src/common/block/natural/BlockRock.java @@ -1,7 +1,8 @@ -package common.block; +package common.block.natural; import java.util.List; +import common.block.Block; import common.item.CheatTab; import common.item.Item; import common.item.ItemStack; diff --git a/common/src/common/block/BlockSand.java b/common/src/common/block/natural/BlockSand.java similarity index 95% rename from common/src/common/block/BlockSand.java rename to common/src/common/block/natural/BlockSand.java index 147941b..d875ca4 100755 --- a/common/src/common/block/BlockSand.java +++ b/common/src/common/block/natural/BlockSand.java @@ -1,10 +1,12 @@ -package common.block; +package common.block.natural; import java.util.List; +import common.block.BlockFalling; import common.item.CheatTab; import common.item.Item; import common.item.ItemStack; +import common.material.Material; import common.model.Model; import common.model.ModelProvider; import common.properties.IProperty; @@ -18,7 +20,9 @@ public class BlockSand extends BlockFalling public BlockSand() { + super(Material.sand); this.setDefaultState(this.getBaseState().withProperty(VARIANT, BlockSand.EnumType.SAND)); + this.setTab(CheatTab.tabNature); } /** diff --git a/common/src/common/block/BlockSandStone.java b/common/src/common/block/natural/BlockSandStone.java similarity index 98% rename from common/src/common/block/BlockSandStone.java rename to common/src/common/block/natural/BlockSandStone.java index 3ed7fcc..76ff781 100755 --- a/common/src/common/block/BlockSandStone.java +++ b/common/src/common/block/natural/BlockSandStone.java @@ -1,7 +1,8 @@ -package common.block; +package common.block.natural; import java.util.List; +import common.block.Block; import common.item.CheatTab; import common.item.Item; import common.item.ItemStack; diff --git a/common/src/common/block/natural/BlockSlime.java b/common/src/common/block/natural/BlockSlime.java new file mode 100755 index 0000000..7ea4f3d --- /dev/null +++ b/common/src/common/block/natural/BlockSlime.java @@ -0,0 +1,63 @@ +package common.block.natural; + +import common.block.BlockTranslucent; +import common.entity.Entity; +import common.item.CheatTab; +import common.material.Material; +import common.model.Model; +import common.model.ModelProvider; +import common.util.BlockPos; +import common.world.State; +import common.world.World; + +public class BlockSlime extends BlockTranslucent { + private static final Model slime = ModelProvider.getModelProvider().getModel("slime") + .add(0, 0, 0, 16, 16, 16) + .d().uv(0, 0, 16, 16).noCull() + .u().uv(0, 0, 16, 16).noCull() + .n().uv(0, 0, 16, 16).noCull() + .s().uv(0, 0, 16, 16).noCull() + .w().uv(0, 0, 16, 16).noCull() + .e().uv(0, 0, 16, 16).noCull() + .add(3, 3, 3, 13, 13, 13) + .d().uv(3, 3, 13, 13).noCull() + .u().uv(3, 3, 13, 13).noCull() + .n().uv(3, 3, 13, 13).noCull() + .s().uv(3, 3, 13, 13).noCull() + .w().uv(3, 3, 13, 13).noCull() + .e().uv(3, 3, 13, 13).noCull() + ; + + public BlockSlime() { + super(Material.clay); + this.setTab(CheatTab.tabTech); + this.slipperiness = 0.8F; + } + + public void onFallenUpon(World world, BlockPos pos, Entity entity, float distance) { + if(entity.isSneaking()) + super.onFallenUpon(world, pos, entity, distance); + else + entity.fall(distance, 0.0F); + } + + public void onLanded(World world, Entity entity) { + if(entity.isSneaking()) + super.onLanded(world, entity); + else if(entity.motionY < 0.0D) + entity.motionY = -entity.motionY; + } + + public void onEntityCollidedWithBlock(World world, BlockPos pos, Entity entity) { + if(Math.abs(entity.motionY) < 0.1D && !entity.isSneaking()) { + double friction = 0.4D + Math.abs(entity.motionY) * 0.2D; + entity.motionX *= friction; + entity.motionZ *= friction; + } + super.onEntityCollidedWithBlock(world, pos, entity); + } + + public Model getModel(ModelProvider provider, String name, State state) { + return slime; + } +} diff --git a/common/src/common/block/BlockSnow.java b/common/src/common/block/natural/BlockSnow.java similarity index 95% rename from common/src/common/block/BlockSnow.java rename to common/src/common/block/natural/BlockSnow.java index 3647804..e87a6ed 100755 --- a/common/src/common/block/BlockSnow.java +++ b/common/src/common/block/natural/BlockSnow.java @@ -1,5 +1,6 @@ -package common.block; +package common.block.natural; +import common.block.Block; import common.entity.npc.EntityNPC; import common.init.Blocks; import common.init.Config; @@ -87,7 +88,7 @@ public class BlockSnow extends Block { State iblockstate = worldIn.getState(pos.down()); Block block = iblockstate.getBlock(); - return block != Blocks.ice && block != Blocks.packed_ice ? (block.getMaterial() == Material.leaves ? true : (block == this && ((Integer)iblockstate.getValue(LAYERS)).intValue() >= 7 ? true : block.isOpaqueCube() && block.material.blocksMovement())) : false; + return block != Blocks.ice && block != Blocks.packed_ice ? (block.getMaterial() == Material.leaves ? true : (block == this && ((Integer)iblockstate.getValue(LAYERS)).intValue() >= 7 ? true : block.isOpaqueCube() && block.getMaterial().blocksMovement())) : false; } /** @@ -137,7 +138,7 @@ public class BlockSnow extends Block public void updateTick(AWorldServer worldIn, BlockPos pos, State state, Random rand) { - if (Config.snowMelt && ((worldIn.getLightFor(LightType.BLOCK, pos) > 11) || !worldIn.canFreezeAt(pos))) + if (Config.snowMelt && (worldIn.getLightFor(LightType.BLOCK, pos) > 11 || !worldIn.canFreezeAt(pos))) { this.dropBlockAsItem(worldIn, pos, worldIn.getState(pos), 0); worldIn.setBlockToAir(pos); diff --git a/common/src/common/block/natural/BlockSnowBlock.java b/common/src/common/block/natural/BlockSnowBlock.java new file mode 100755 index 0000000..6721f0f --- /dev/null +++ b/common/src/common/block/natural/BlockSnowBlock.java @@ -0,0 +1,36 @@ +package common.block.natural; + +import common.block.Block; +import common.init.Config; +import common.init.Items; +import common.item.CheatTab; +import common.item.Item; +import common.material.Material; +import common.rng.Random; +import common.util.BlockPos; +import common.world.LightType; +import common.world.State; +import common.world.AWorldServer; + +public class BlockSnowBlock extends Block { + public BlockSnowBlock() { + super(Material.craftedSnow); + this.setTickRandomly(); + this.setTab(CheatTab.tabNature); + } + + public Item getItemDropped(State state, Random rand, int fortune) { + return Items.snowball; + } + + public int quantityDropped(Random rand) { + return rand.range(2, 4); + } + + public void updateTick(AWorldServer world, BlockPos pos, State state, Random rand) { + if(Config.snowFullMelt && (world.getLightFor(LightType.BLOCK, pos) > 11 || !world.canFreezeAt(pos))) { + this.dropBlockAsItem(world, pos, world.getState(pos), 0); + world.setBlockToAir(pos); + } + } +} diff --git a/common/src/common/block/BlockSoulSand.java b/common/src/common/block/natural/BlockSoulSand.java similarity index 94% rename from common/src/common/block/BlockSoulSand.java rename to common/src/common/block/natural/BlockSoulSand.java index b9aa80a..efce90e 100755 --- a/common/src/common/block/BlockSoulSand.java +++ b/common/src/common/block/natural/BlockSoulSand.java @@ -1,5 +1,6 @@ -package common.block; +package common.block.natural; +import common.block.Block; import common.entity.Entity; import common.item.CheatTab; import common.material.Material; diff --git a/common/src/common/block/BlockStone.java b/common/src/common/block/natural/BlockStone.java similarity index 89% rename from common/src/common/block/BlockStone.java rename to common/src/common/block/natural/BlockStone.java index bbfe84c..b2fe230 100755 --- a/common/src/common/block/BlockStone.java +++ b/common/src/common/block/natural/BlockStone.java @@ -1,5 +1,6 @@ -package common.block; +package common.block.natural; +import common.block.Block; import common.init.Blocks; import common.init.ItemRegistry; import common.item.CheatTab; diff --git a/common/src/common/block/BlockTintedFire.java b/common/src/common/block/natural/BlockTintedFire.java similarity index 96% rename from common/src/common/block/BlockTintedFire.java rename to common/src/common/block/natural/BlockTintedFire.java index fa450ad..70e64c6 100644 --- a/common/src/common/block/BlockTintedFire.java +++ b/common/src/common/block/natural/BlockTintedFire.java @@ -1,4 +1,4 @@ -package common.block; +package common.block.natural; import java.util.Map; diff --git a/common/src/common/block/BlockWeb.java b/common/src/common/block/natural/BlockWeb.java similarity index 96% rename from common/src/common/block/BlockWeb.java rename to common/src/common/block/natural/BlockWeb.java index 9778a73..156da3d 100755 --- a/common/src/common/block/BlockWeb.java +++ b/common/src/common/block/natural/BlockWeb.java @@ -1,5 +1,6 @@ -package common.block; +package common.block.natural; +import common.block.Block; import common.entity.Entity; import common.init.Items; import common.item.CheatTab; diff --git a/common/src/common/block/BlockAnvil.java b/common/src/common/block/tech/BlockAnvil.java similarity index 99% rename from common/src/common/block/BlockAnvil.java rename to common/src/common/block/tech/BlockAnvil.java index 6b9406f..34a19c9 100755 --- a/common/src/common/block/BlockAnvil.java +++ b/common/src/common/block/tech/BlockAnvil.java @@ -1,7 +1,8 @@ -package common.block; +package common.block.tech; import java.util.List; +import common.block.BlockFalling; import common.entity.item.EntityFalling; import common.entity.npc.EntityNPC; import common.entity.types.EntityLiving; diff --git a/common/src/common/block/BlockBasePressurePlate.java b/common/src/common/block/tech/BlockBasePressurePlate.java similarity index 98% rename from common/src/common/block/BlockBasePressurePlate.java rename to common/src/common/block/tech/BlockBasePressurePlate.java index b19329d..f0c48de 100755 --- a/common/src/common/block/BlockBasePressurePlate.java +++ b/common/src/common/block/tech/BlockBasePressurePlate.java @@ -1,5 +1,7 @@ -package common.block; +package common.block.tech; +import common.block.Block; +import common.block.artificial.BlockFence; import common.entity.Entity; import common.init.SoundEvent; import common.item.CheatTab; diff --git a/common/src/common/block/BlockBeacon.java b/common/src/common/block/tech/BlockBeacon.java similarity index 97% rename from common/src/common/block/BlockBeacon.java rename to common/src/common/block/tech/BlockBeacon.java index 7789be3..3a752a1 100755 --- a/common/src/common/block/BlockBeacon.java +++ b/common/src/common/block/tech/BlockBeacon.java @@ -1,5 +1,7 @@ -package common.block; +package common.block.tech; +import common.block.Block; +import common.block.BlockContainer; import common.entity.npc.EntityNPC; import common.item.CheatTab; import common.material.Material; diff --git a/common/src/common/block/BlockBrewingStand.java b/common/src/common/block/tech/BlockBrewingStand.java similarity index 99% rename from common/src/common/block/BlockBrewingStand.java rename to common/src/common/block/tech/BlockBrewingStand.java index db118c0..036b238 100755 --- a/common/src/common/block/BlockBrewingStand.java +++ b/common/src/common/block/tech/BlockBrewingStand.java @@ -1,7 +1,8 @@ -package common.block; +package common.block.tech; import java.util.List; +import common.block.BlockContainer; import common.entity.Entity; import common.entity.npc.EntityNPC; import common.entity.types.EntityLiving; diff --git a/common/src/common/block/BlockButton.java b/common/src/common/block/tech/BlockButton.java similarity index 99% rename from common/src/common/block/BlockButton.java rename to common/src/common/block/tech/BlockButton.java index 28b690c..c0b60fb 100755 --- a/common/src/common/block/BlockButton.java +++ b/common/src/common/block/tech/BlockButton.java @@ -1,7 +1,8 @@ -package common.block; +package common.block.tech; import java.util.List; +import common.block.Block; import common.collect.Lists; import common.entity.Entity; import common.entity.npc.EntityNPC; diff --git a/common/src/common/block/BlockCauldron.java b/common/src/common/block/tech/BlockCauldron.java similarity index 99% rename from common/src/common/block/BlockCauldron.java rename to common/src/common/block/tech/BlockCauldron.java index 79f5739..75e05e8 100755 --- a/common/src/common/block/BlockCauldron.java +++ b/common/src/common/block/tech/BlockCauldron.java @@ -1,7 +1,8 @@ -package common.block; +package common.block.tech; import java.util.List; +import common.block.Block; import common.entity.Entity; import common.entity.item.EntityItem; import common.entity.npc.EntityNPC; diff --git a/common/src/common/block/BlockChest.java b/common/src/common/block/tech/BlockChest.java similarity index 99% rename from common/src/common/block/BlockChest.java rename to common/src/common/block/tech/BlockChest.java index 9b2ed6b..11c0e60 100755 --- a/common/src/common/block/BlockChest.java +++ b/common/src/common/block/tech/BlockChest.java @@ -1,5 +1,7 @@ -package common.block; +package common.block.tech; +import common.block.Block; +import common.block.BlockContainer; import common.color.TextColor; import common.entity.Entity; import common.entity.animal.EntityOcelot; diff --git a/common/src/common/block/BlockCore.java b/common/src/common/block/tech/BlockCore.java similarity index 91% rename from common/src/common/block/BlockCore.java rename to common/src/common/block/tech/BlockCore.java index d23bada..3378fea 100755 --- a/common/src/common/block/BlockCore.java +++ b/common/src/common/block/tech/BlockCore.java @@ -1,5 +1,6 @@ -package common.block; +package common.block.tech; +import common.block.Block; import common.init.Config; import common.item.CheatTab; import common.material.Material; diff --git a/common/src/common/block/BlockDaylightDetector.java b/common/src/common/block/tech/BlockDaylightDetector.java similarity index 98% rename from common/src/common/block/BlockDaylightDetector.java rename to common/src/common/block/tech/BlockDaylightDetector.java index 420a0e1..9b6a91a 100755 --- a/common/src/common/block/BlockDaylightDetector.java +++ b/common/src/common/block/tech/BlockDaylightDetector.java @@ -1,7 +1,9 @@ -package common.block; +package common.block.tech; import java.util.List; +import common.block.BlockContainer; +import common.block.SoundType; import common.entity.npc.EntityNPC; import common.init.Blocks; import common.init.ItemRegistry; diff --git a/common/src/common/block/BlockDispenser.java b/common/src/common/block/tech/BlockDispenser.java similarity index 99% rename from common/src/common/block/BlockDispenser.java rename to common/src/common/block/tech/BlockDispenser.java index 7132bad..15d1875 100755 --- a/common/src/common/block/BlockDispenser.java +++ b/common/src/common/block/tech/BlockDispenser.java @@ -1,5 +1,7 @@ -package common.block; +package common.block.tech; +import common.block.Block; +import common.block.BlockContainer; import common.dispenser.BehaviorDefaultDispenseItem; import common.dispenser.IBehaviorDispenseItem; import common.dispenser.IBlockSource; diff --git a/common/src/common/block/BlockDropper.java b/common/src/common/block/tech/BlockDropper.java similarity index 99% rename from common/src/common/block/BlockDropper.java rename to common/src/common/block/tech/BlockDropper.java index 8294171..5d8f39e 100755 --- a/common/src/common/block/BlockDropper.java +++ b/common/src/common/block/tech/BlockDropper.java @@ -1,4 +1,4 @@ -package common.block; +package common.block.tech; import common.dispenser.BehaviorDefaultDispenseItem; import common.dispenser.IBehaviorDispenseItem; diff --git a/common/src/common/block/BlockEnchantmentTable.java b/common/src/common/block/tech/BlockEnchantmentTable.java similarity index 98% rename from common/src/common/block/BlockEnchantmentTable.java rename to common/src/common/block/tech/BlockEnchantmentTable.java index b461b36..3c8b3da 100755 --- a/common/src/common/block/BlockEnchantmentTable.java +++ b/common/src/common/block/tech/BlockEnchantmentTable.java @@ -1,5 +1,6 @@ -package common.block; +package common.block.tech; +import common.block.BlockContainer; import common.entity.npc.EntityNPC; import common.entity.types.EntityLiving; import common.init.Blocks; diff --git a/common/src/common/block/BlockFurnace.java b/common/src/common/block/tech/BlockFurnace.java similarity index 99% rename from common/src/common/block/BlockFurnace.java rename to common/src/common/block/tech/BlockFurnace.java index 6e344f0..dfb8811 100755 --- a/common/src/common/block/BlockFurnace.java +++ b/common/src/common/block/tech/BlockFurnace.java @@ -1,5 +1,7 @@ -package common.block; +package common.block.tech; +import common.block.Block; +import common.block.BlockContainer; import common.entity.npc.EntityNPC; import common.entity.types.EntityLiving; import common.init.Blocks; diff --git a/common/src/common/block/BlockHopper.java b/common/src/common/block/tech/BlockHopper.java similarity index 99% rename from common/src/common/block/BlockHopper.java rename to common/src/common/block/tech/BlockHopper.java index 8b26c54..729dfca 100755 --- a/common/src/common/block/BlockHopper.java +++ b/common/src/common/block/tech/BlockHopper.java @@ -1,8 +1,10 @@ -package common.block; +package common.block.tech; import java.util.List; import java.util.function.Predicate; +import common.block.Block; +import common.block.BlockContainer; import common.entity.Entity; import common.entity.npc.EntityNPC; import common.entity.types.EntityLiving; diff --git a/common/src/common/block/BlockJukebox.java b/common/src/common/block/tech/BlockJukebox.java similarity index 94% rename from common/src/common/block/BlockJukebox.java rename to common/src/common/block/tech/BlockJukebox.java index 87f2fce..fde7f5e 100755 --- a/common/src/common/block/BlockJukebox.java +++ b/common/src/common/block/tech/BlockJukebox.java @@ -1,5 +1,6 @@ -package common.block; +package common.block.tech; +import common.block.Block; import common.entity.npc.EntityNPC; import common.init.SoundEvent; import common.item.CheatTab; diff --git a/common/src/common/block/BlockLever.java b/common/src/common/block/tech/BlockLever.java similarity index 99% rename from common/src/common/block/BlockLever.java rename to common/src/common/block/tech/BlockLever.java index 3e33154..fef2544 100755 --- a/common/src/common/block/BlockLever.java +++ b/common/src/common/block/tech/BlockLever.java @@ -1,5 +1,6 @@ -package common.block; +package common.block.tech; +import common.block.Block; import common.entity.npc.EntityNPC; import common.entity.types.EntityLiving; import common.init.SoundEvent; diff --git a/common/src/common/block/BlockMachine.java b/common/src/common/block/tech/BlockMachine.java similarity index 96% rename from common/src/common/block/BlockMachine.java rename to common/src/common/block/tech/BlockMachine.java index 39ac59c..be00a26 100755 --- a/common/src/common/block/BlockMachine.java +++ b/common/src/common/block/tech/BlockMachine.java @@ -1,5 +1,8 @@ -package common.block; +package common.block.tech; +import common.block.Block; +import common.block.BlockDirectional; +import common.block.ITileEntityProvider; import common.entity.npc.EntityNPC; import common.entity.types.EntityLiving; import common.inventory.Container; diff --git a/common/src/common/block/BlockMobSpawner.java b/common/src/common/block/tech/BlockMobSpawner.java similarity index 97% rename from common/src/common/block/BlockMobSpawner.java rename to common/src/common/block/tech/BlockMobSpawner.java index 18f87d3..acfbb2f 100755 --- a/common/src/common/block/BlockMobSpawner.java +++ b/common/src/common/block/tech/BlockMobSpawner.java @@ -1,5 +1,6 @@ -package common.block; +package common.block.tech; +import common.block.BlockContainer; import common.item.CheatTab; import common.item.Item; import common.material.Material; diff --git a/common/src/common/block/BlockNote.java b/common/src/common/block/tech/BlockNote.java similarity index 97% rename from common/src/common/block/BlockNote.java rename to common/src/common/block/tech/BlockNote.java index 3a1203f..7d2f198 100755 --- a/common/src/common/block/BlockNote.java +++ b/common/src/common/block/tech/BlockNote.java @@ -1,5 +1,7 @@ -package common.block; +package common.block.tech; +import common.block.Block; +import common.block.BlockContainer; import common.entity.npc.EntityNPC; import common.init.SoundEvent; import common.item.CheatTab; diff --git a/common/src/common/block/BlockNuke.java b/common/src/common/block/tech/BlockNuke.java similarity index 97% rename from common/src/common/block/BlockNuke.java rename to common/src/common/block/tech/BlockNuke.java index 7f70ced..add3c4c 100755 --- a/common/src/common/block/BlockNuke.java +++ b/common/src/common/block/tech/BlockNuke.java @@ -1,5 +1,6 @@ -package common.block; +package common.block.tech; +import common.block.Block; import common.entity.item.EntityNuke; import common.init.Blocks; import common.init.SoundEvent; diff --git a/common/src/common/block/BlockPistonBase.java b/common/src/common/block/tech/BlockPistonBase.java similarity index 97% rename from common/src/common/block/BlockPistonBase.java rename to common/src/common/block/tech/BlockPistonBase.java index b4057bb..313a9a2 100755 --- a/common/src/common/block/BlockPistonBase.java +++ b/common/src/common/block/tech/BlockPistonBase.java @@ -1,7 +1,10 @@ -package common.block; +package common.block.tech; import java.util.List; +import common.block.Block; +import common.block.ITileEntityProvider; +import common.block.SoundType; import common.collect.Lists; import common.entity.Entity; import common.entity.types.EntityLiving; @@ -98,7 +101,7 @@ public class BlockPistonBase extends Block { Block block = this.world.getState(origin).getBlock(); - if (block.getMaterial() == Material.air) + if (block == Blocks.air) { return true; } @@ -129,7 +132,7 @@ public class BlockPistonBase extends Block BlockPos blockpos = origin.offset(this.moveDirection.getOpposite(), i); block = this.world.getState(blockpos).getBlock(); - if (block.getMaterial() == Material.air || !BlockPistonBase.canPush(block, this.world, blockpos, this.moveDirection, false) || blockpos.equals(this.pistonPos)) + if (block == Blocks.air || !BlockPistonBase.canPush(block, this.world, blockpos, this.moveDirection, false) || blockpos.equals(this.pistonPos)) { break; } @@ -176,7 +179,7 @@ public class BlockPistonBase extends Block block = this.world.getState(blockpos1).getBlock(); - if (block.getMaterial() == Material.air) + if (block == Blocks.air) { return true; } @@ -424,7 +427,7 @@ public class BlockPistonBase extends Block } } - if (!flag1 && block.getMaterial() != Material.air && canPush(block, worldIn, blockpos, enumfacing.getOpposite(), false) && (block.getMobilityFlag() == 0 || block == Blocks.piston || block == Blocks.sticky_piston)) + if (!flag1 && block != Blocks.air && canPush(block, worldIn, blockpos, enumfacing.getOpposite(), false) && (block.getMobilityFlag() == 0 || block == Blocks.piston || block == Blocks.sticky_piston)) { this.doMove(worldIn, pos, enumfacing, false); } diff --git a/common/src/common/block/BlockPistonHead.java b/common/src/common/block/tech/BlockPistonHead.java similarity index 99% rename from common/src/common/block/BlockPistonHead.java rename to common/src/common/block/tech/BlockPistonHead.java index fff8415..ce55cce 100755 --- a/common/src/common/block/BlockPistonHead.java +++ b/common/src/common/block/tech/BlockPistonHead.java @@ -1,7 +1,9 @@ -package common.block; +package common.block.tech; import java.util.List; +import common.block.Block; +import common.block.SoundType; import common.entity.Entity; import common.init.Blocks; import common.init.ItemRegistry; diff --git a/common/src/common/block/BlockPistonMoving.java b/common/src/common/block/tech/BlockPistonMoving.java similarity index 98% rename from common/src/common/block/BlockPistonMoving.java rename to common/src/common/block/tech/BlockPistonMoving.java index 1076638..9da811e 100755 --- a/common/src/common/block/BlockPistonMoving.java +++ b/common/src/common/block/tech/BlockPistonMoving.java @@ -1,5 +1,7 @@ -package common.block; +package common.block.tech; +import common.block.Block; +import common.block.BlockContainer; import common.entity.npc.EntityNPC; import common.init.Blocks; import common.item.Item; @@ -186,7 +188,7 @@ public class BlockPistonMoving extends BlockContainer State iblockstate = tileentitypiston.getPistonState(); Block block = iblockstate.getBlock(); - if (block == this || block.getMaterial() == Material.air) + if (block == this || block == Blocks.air) { return; } @@ -217,7 +219,7 @@ public class BlockPistonMoving extends BlockContainer public BoundingBox getBoundingBox(World worldIn, BlockPos pos, State extendingBlock, float progress, Facing direction) { - if (extendingBlock.getBlock() != this && extendingBlock.getBlock().getMaterial() != Material.air) + if (extendingBlock.getBlock() != this && extendingBlock.getBlock() != Blocks.air) { BoundingBox axisalignedbb = extendingBlock.getBlock().getCollisionBoundingBox(worldIn, pos, extendingBlock); diff --git a/common/src/common/block/BlockPressurePlate.java b/common/src/common/block/tech/BlockPressurePlate.java similarity index 99% rename from common/src/common/block/BlockPressurePlate.java rename to common/src/common/block/tech/BlockPressurePlate.java index 3efdea7..677f88d 100755 --- a/common/src/common/block/BlockPressurePlate.java +++ b/common/src/common/block/tech/BlockPressurePlate.java @@ -1,4 +1,4 @@ -package common.block; +package common.block.tech; import java.util.List; diff --git a/common/src/common/block/BlockPressurePlateWeighted.java b/common/src/common/block/tech/BlockPressurePlateWeighted.java similarity index 98% rename from common/src/common/block/BlockPressurePlateWeighted.java rename to common/src/common/block/tech/BlockPressurePlateWeighted.java index be01b35..55e7b7c 100755 --- a/common/src/common/block/BlockPressurePlateWeighted.java +++ b/common/src/common/block/tech/BlockPressurePlateWeighted.java @@ -1,4 +1,4 @@ -package common.block; +package common.block.tech; import common.entity.Entity; import common.material.Material; diff --git a/common/src/common/block/BlockRail.java b/common/src/common/block/tech/BlockRail.java similarity index 96% rename from common/src/common/block/BlockRail.java rename to common/src/common/block/tech/BlockRail.java index db02ca7..de178aa 100755 --- a/common/src/common/block/BlockRail.java +++ b/common/src/common/block/tech/BlockRail.java @@ -1,5 +1,6 @@ -package common.block; +package common.block.tech; +import common.block.Block; import common.properties.IProperty; import common.properties.PropertyEnum; import common.util.BlockPos; diff --git a/common/src/common/block/BlockRailBase.java b/common/src/common/block/tech/BlockRailBase.java similarity index 99% rename from common/src/common/block/BlockRailBase.java rename to common/src/common/block/tech/BlockRailBase.java index 01c0256..2ef7c4c 100755 --- a/common/src/common/block/BlockRailBase.java +++ b/common/src/common/block/tech/BlockRailBase.java @@ -1,7 +1,8 @@ -package common.block; +package common.block.tech; import java.util.List; +import common.block.Block; import common.collect.Lists; import common.init.Blocks; import common.item.CheatTab; diff --git a/common/src/common/block/BlockRailDetector.java b/common/src/common/block/tech/BlockRailDetector.java similarity index 99% rename from common/src/common/block/BlockRailDetector.java rename to common/src/common/block/tech/BlockRailDetector.java index 1c2fbd6..330cc6c 100755 --- a/common/src/common/block/BlockRailDetector.java +++ b/common/src/common/block/tech/BlockRailDetector.java @@ -1,4 +1,4 @@ -package common.block; +package common.block.tech; import java.util.List; import java.util.function.Predicate; diff --git a/common/src/common/block/BlockRailPowered.java b/common/src/common/block/tech/BlockRailPowered.java similarity index 99% rename from common/src/common/block/BlockRailPowered.java rename to common/src/common/block/tech/BlockRailPowered.java index 5989b95..727800b 100755 --- a/common/src/common/block/BlockRailPowered.java +++ b/common/src/common/block/tech/BlockRailPowered.java @@ -1,7 +1,8 @@ -package common.block; +package common.block.tech; import java.util.function.Predicate; +import common.block.Block; import common.model.Model; import common.model.ModelProvider; import common.properties.IProperty; diff --git a/common/src/common/block/BlockRedstoneComparator.java b/common/src/common/block/tech/BlockRedstoneComparator.java similarity index 99% rename from common/src/common/block/BlockRedstoneComparator.java rename to common/src/common/block/tech/BlockRedstoneComparator.java index 948db47..9a484fe 100755 --- a/common/src/common/block/BlockRedstoneComparator.java +++ b/common/src/common/block/tech/BlockRedstoneComparator.java @@ -1,5 +1,7 @@ -package common.block; +package common.block.tech; +import common.block.Block; +import common.block.ITileEntityProvider; import common.entity.npc.EntityNPC; import common.entity.types.EntityLiving; import common.init.Blocks; @@ -132,7 +134,7 @@ public class BlockRedstoneComparator extends BlockRedstoneDiode implements ITile { i = block.getComparatorInputOverride(worldIn, blockpos); } -// else if (block.getMaterial() == Material.air) +// else if (block == Blocks.air) // { // EntityFrame entityitemframe = this.findItemFrame(worldIn, enumfacing, blockpos); // diff --git a/common/src/common/block/BlockRedstoneDiode.java b/common/src/common/block/tech/BlockRedstoneDiode.java similarity index 99% rename from common/src/common/block/BlockRedstoneDiode.java rename to common/src/common/block/tech/BlockRedstoneDiode.java index 7be2128..63cf8e9 100755 --- a/common/src/common/block/BlockRedstoneDiode.java +++ b/common/src/common/block/tech/BlockRedstoneDiode.java @@ -1,5 +1,7 @@ -package common.block; +package common.block.tech; +import common.block.Block; +import common.block.BlockDirectional; import common.entity.types.EntityLiving; import common.init.Blocks; import common.item.ItemStack; diff --git a/common/src/common/block/BlockRedstoneLight.java b/common/src/common/block/tech/BlockRedstoneLight.java similarity index 97% rename from common/src/common/block/BlockRedstoneLight.java rename to common/src/common/block/tech/BlockRedstoneLight.java index 579156b..4ca9c78 100755 --- a/common/src/common/block/BlockRedstoneLight.java +++ b/common/src/common/block/tech/BlockRedstoneLight.java @@ -1,5 +1,6 @@ -package common.block; +package common.block.tech; +import common.block.Block; import common.init.Blocks; import common.init.ItemRegistry; import common.item.Item; diff --git a/common/src/common/block/BlockRedstoneRepeater.java b/common/src/common/block/tech/BlockRedstoneRepeater.java similarity index 99% rename from common/src/common/block/BlockRedstoneRepeater.java rename to common/src/common/block/tech/BlockRedstoneRepeater.java index a98316f..54adc67 100755 --- a/common/src/common/block/BlockRedstoneRepeater.java +++ b/common/src/common/block/tech/BlockRedstoneRepeater.java @@ -1,5 +1,6 @@ -package common.block; +package common.block.tech; +import common.block.Block; import common.entity.npc.EntityNPC; import common.init.Blocks; import common.init.Items; diff --git a/common/src/common/block/BlockRedstoneTorch.java b/common/src/common/block/tech/BlockRedstoneTorch.java similarity index 99% rename from common/src/common/block/BlockRedstoneTorch.java rename to common/src/common/block/tech/BlockRedstoneTorch.java index 1de1741..7f73f2b 100755 --- a/common/src/common/block/BlockRedstoneTorch.java +++ b/common/src/common/block/tech/BlockRedstoneTorch.java @@ -1,8 +1,9 @@ -package common.block; +package common.block.tech; import java.util.List; import java.util.Map; +import common.block.Block; import common.collect.Lists; import common.collect.Maps; import common.init.Blocks; diff --git a/common/src/common/block/BlockRedstoneWire.java b/common/src/common/block/tech/BlockRedstoneWire.java similarity index 99% rename from common/src/common/block/BlockRedstoneWire.java rename to common/src/common/block/tech/BlockRedstoneWire.java index a77e77a..ba4c65c 100755 --- a/common/src/common/block/BlockRedstoneWire.java +++ b/common/src/common/block/tech/BlockRedstoneWire.java @@ -1,9 +1,10 @@ -package common.block; +package common.block.tech; import java.util.EnumSet; import java.util.List; import java.util.Set; +import common.block.Block; import common.collect.Lists; import common.collect.Sets; import common.init.Blocks; diff --git a/common/src/common/block/BlockSourceImpl.java b/common/src/common/block/tech/BlockSourceImpl.java similarity index 97% rename from common/src/common/block/BlockSourceImpl.java rename to common/src/common/block/tech/BlockSourceImpl.java index c5e241e..f22c91d 100755 --- a/common/src/common/block/BlockSourceImpl.java +++ b/common/src/common/block/tech/BlockSourceImpl.java @@ -1,4 +1,4 @@ -package common.block; +package common.block.tech; import common.dispenser.IBlockSource; import common.tileentity.TileEntity; diff --git a/common/src/common/block/BlockTNT.java b/common/src/common/block/tech/BlockTNT.java similarity index 99% rename from common/src/common/block/BlockTNT.java rename to common/src/common/block/tech/BlockTNT.java index 1dfc2a3..a5f3769 100755 --- a/common/src/common/block/BlockTNT.java +++ b/common/src/common/block/tech/BlockTNT.java @@ -1,7 +1,8 @@ -package common.block; +package common.block.tech; import java.util.List; +import common.block.Block; import common.entity.Entity; import common.entity.item.EntityTnt; import common.entity.npc.EntityNPC; diff --git a/common/src/common/block/BlockTianReactor.java b/common/src/common/block/tech/BlockTianReactor.java similarity index 96% rename from common/src/common/block/BlockTianReactor.java rename to common/src/common/block/tech/BlockTianReactor.java index 6855aa8..0ba0921 100755 --- a/common/src/common/block/BlockTianReactor.java +++ b/common/src/common/block/tech/BlockTianReactor.java @@ -1,4 +1,4 @@ -package common.block; +package common.block.tech; import java.util.Map; diff --git a/common/src/common/block/BlockTorch.java b/common/src/common/block/tech/BlockTorch.java similarity index 98% rename from common/src/common/block/BlockTorch.java rename to common/src/common/block/tech/BlockTorch.java index ca7552b..090960c 100755 --- a/common/src/common/block/BlockTorch.java +++ b/common/src/common/block/tech/BlockTorch.java @@ -1,7 +1,10 @@ -package common.block; +package common.block.tech; import java.util.function.Predicate; +import common.block.Block; +import common.block.BlockDirectional; +import common.block.artificial.BlockFence; import common.entity.types.EntityLiving; import common.init.Blocks; import common.item.CheatTab; diff --git a/common/src/common/block/BlockTripWire.java b/common/src/common/block/tech/BlockTripWire.java similarity index 99% rename from common/src/common/block/BlockTripWire.java rename to common/src/common/block/tech/BlockTripWire.java index e02e941..258db32 100755 --- a/common/src/common/block/BlockTripWire.java +++ b/common/src/common/block/tech/BlockTripWire.java @@ -1,7 +1,8 @@ -package common.block; +package common.block.tech; import java.util.List; +import common.block.Block; import common.entity.Entity; import common.entity.npc.EntityNPC; import common.init.Blocks; diff --git a/common/src/common/block/BlockTripWireHook.java b/common/src/common/block/tech/BlockTripWireHook.java similarity index 99% rename from common/src/common/block/BlockTripWireHook.java rename to common/src/common/block/tech/BlockTripWireHook.java index 778de6c..af7e37a 100755 --- a/common/src/common/block/BlockTripWireHook.java +++ b/common/src/common/block/tech/BlockTripWireHook.java @@ -1,5 +1,6 @@ -package common.block; +package common.block.tech; +import common.block.Block; import common.entity.types.EntityLiving; import common.init.Blocks; import common.init.SoundEvent; diff --git a/common/src/common/block/BlockWarpChest.java b/common/src/common/block/tech/BlockWarpChest.java similarity index 98% rename from common/src/common/block/BlockWarpChest.java rename to common/src/common/block/tech/BlockWarpChest.java index f3aab50..d6270b7 100755 --- a/common/src/common/block/BlockWarpChest.java +++ b/common/src/common/block/tech/BlockWarpChest.java @@ -1,5 +1,6 @@ -package common.block; +package common.block.tech; +import common.block.Block; import common.entity.npc.EntityNPC; import common.entity.types.EntityLiving; import common.init.Blocks; diff --git a/common/src/common/block/BlockWorkbench.java b/common/src/common/block/tech/BlockWorkbench.java similarity index 97% rename from common/src/common/block/BlockWorkbench.java rename to common/src/common/block/tech/BlockWorkbench.java index 3280f32..fcaea1d 100755 --- a/common/src/common/block/BlockWorkbench.java +++ b/common/src/common/block/tech/BlockWorkbench.java @@ -1,5 +1,6 @@ -package common.block; +package common.block.tech; +import common.block.Block; import common.entity.npc.EntityNPC; import common.init.BlockRegistry; import common.inventory.Container; diff --git a/common/src/common/block/BlockBanner.java b/common/src/common/block/tile/BlockBanner.java similarity index 98% rename from common/src/common/block/BlockBanner.java rename to common/src/common/block/tile/BlockBanner.java index 0d455c7..78a419b 100755 --- a/common/src/common/block/BlockBanner.java +++ b/common/src/common/block/tile/BlockBanner.java @@ -1,5 +1,7 @@ -package common.block; +package common.block.tile; +import common.block.Block; +import common.block.BlockContainer; import common.entity.npc.EntityNPC; import common.init.Items; import common.item.Item; diff --git a/common/src/common/block/BlockSign.java b/common/src/common/block/tile/BlockSign.java similarity index 98% rename from common/src/common/block/BlockSign.java rename to common/src/common/block/tile/BlockSign.java index ccbb72d..639a546 100755 --- a/common/src/common/block/BlockSign.java +++ b/common/src/common/block/tile/BlockSign.java @@ -1,5 +1,6 @@ -package common.block; +package common.block.tile; +import common.block.BlockContainer; import common.entity.npc.EntityNPC; import common.init.Config; import common.init.Items; diff --git a/common/src/common/block/BlockSkull.java b/common/src/common/block/tile/BlockSkull.java similarity index 98% rename from common/src/common/block/BlockSkull.java rename to common/src/common/block/tile/BlockSkull.java index 72ea6a0..e85a740 100755 --- a/common/src/common/block/BlockSkull.java +++ b/common/src/common/block/tile/BlockSkull.java @@ -1,5 +1,6 @@ -package common.block; +package common.block.tile; +import common.block.BlockContainer; import common.entity.types.EntityLiving; import common.init.Items; import common.item.Item; diff --git a/common/src/common/block/BlockStandingSign.java b/common/src/common/block/tile/BlockStandingSign.java similarity index 96% rename from common/src/common/block/BlockStandingSign.java rename to common/src/common/block/tile/BlockStandingSign.java index 156dabe..f6a616a 100755 --- a/common/src/common/block/BlockStandingSign.java +++ b/common/src/common/block/tile/BlockStandingSign.java @@ -1,5 +1,6 @@ -package common.block; +package common.block.tile; +import common.block.Block; import common.properties.IProperty; import common.properties.PropertyInteger; import common.util.BlockPos; diff --git a/common/src/common/block/BlockWallSign.java b/common/src/common/block/tile/BlockWallSign.java similarity index 97% rename from common/src/common/block/BlockWallSign.java rename to common/src/common/block/tile/BlockWallSign.java index 29da816..b390bd6 100755 --- a/common/src/common/block/BlockWallSign.java +++ b/common/src/common/block/tile/BlockWallSign.java @@ -1,5 +1,6 @@ -package common.block; +package common.block.tile; +import common.block.Block; import common.properties.IProperty; import common.properties.PropertyDirection; import common.util.BlockPos; diff --git a/common/src/common/dimension/Dimension.java b/common/src/common/dimension/Dimension.java index 5ed1030..315dc8f 100755 --- a/common/src/common/dimension/Dimension.java +++ b/common/src/common/dimension/Dimension.java @@ -6,7 +6,7 @@ import java.util.Set; import common.biome.Biome; import common.biome.IBiome; -import common.block.LeavesType; +import common.block.foliage.LeavesType; import common.collect.Lists; import common.collect.Maps; import common.collect.Sets; diff --git a/common/src/common/dispenser/BehaviorDefaultDispenseItem.java b/common/src/common/dispenser/BehaviorDefaultDispenseItem.java index e4aea80..e8c65a5 100755 --- a/common/src/common/dispenser/BehaviorDefaultDispenseItem.java +++ b/common/src/common/dispenser/BehaviorDefaultDispenseItem.java @@ -1,6 +1,6 @@ package common.dispenser; -import common.block.BlockDispenser; +import common.block.tech.BlockDispenser; import common.entity.item.EntityItem; import common.item.ItemStack; import common.util.Facing; diff --git a/common/src/common/dispenser/BehaviorProjectileDispense.java b/common/src/common/dispenser/BehaviorProjectileDispense.java index dc4dbaa..96d6eb1 100755 --- a/common/src/common/dispenser/BehaviorProjectileDispense.java +++ b/common/src/common/dispenser/BehaviorProjectileDispense.java @@ -1,6 +1,6 @@ package common.dispenser; -import common.block.BlockDispenser; +import common.block.tech.BlockDispenser; import common.entity.Entity; import common.entity.types.IProjectile; import common.item.ItemStack; diff --git a/common/src/common/entity/Entity.java b/common/src/common/entity/Entity.java index 52fad4f..890739c 100755 --- a/common/src/common/entity/Entity.java +++ b/common/src/common/entity/Entity.java @@ -3,11 +3,11 @@ package common.entity; import java.util.List; import common.block.Block; -import common.block.BlockFence; -import common.block.BlockFenceGate; -import common.block.BlockLiquid; -import common.block.BlockWall; import common.block.SoundType; +import common.block.artificial.BlockFence; +import common.block.artificial.BlockFenceGate; +import common.block.artificial.BlockWall; +import common.block.liquid.BlockLiquid; import common.color.TextColor; import common.dimension.DimType; import common.enchantment.EnchantmentHelper; @@ -704,7 +704,7 @@ public abstract class Entity BlockPos blockpos = new BlockPos(i, j, k); Block block1 = this.worldObj.getState(blockpos).getBlock(); - if (block1.getMaterial() == Material.air) + if (block1 == Blocks.air) { Block block = this.worldObj.getState(blockpos.down()).getBlock(); @@ -751,7 +751,7 @@ public abstract class Entity this.walkDistMod = (float)((double)this.walkDistMod + (double)ExtMath.sqrtd(d12 * d12 + d14 * d14) * 0.6D); this.stepDistMod = (float)((double)this.stepDistMod + (double)ExtMath.sqrtd(d12 * d12 + d13 * d13 + d14 * d14) * 0.6D); - if (this.stepDistMod > (float)this.nextStepDist && block1.getMaterial() != Material.air) + if (this.stepDistMod > (float)this.nextStepDist && block1 != Blocks.air) { this.nextStepDist = (int)this.stepDistMod + 1; diff --git a/common/src/common/entity/animal/EntityHorse.java b/common/src/common/entity/animal/EntityHorse.java index 7352c24..458f30a 100755 --- a/common/src/common/entity/animal/EntityHorse.java +++ b/common/src/common/entity/animal/EntityHorse.java @@ -30,7 +30,6 @@ import common.inventory.InventoryBasic; import common.item.Item; import common.item.ItemMonsterPlacer; import common.item.ItemStack; -import common.material.Material; import common.model.ParticleType; import common.nbt.NBTTagCompound; import common.nbt.NBTTagList; @@ -436,7 +435,7 @@ public class EntityHorse extends EntityAnimal implements IInvBasic Block block = this.worldObj.getState(new BlockPos(this.posX, this.posY - 0.2D - (double)this.prevYaw, this.posZ)).getBlock(); - if (block.getMaterial() != Material.air) // && !this.isSilent()) + if (block != Blocks.air) // && !this.isSilent()) { SoundType block$soundtype = block.sound; if(block$soundtype.getStepSound() != null) diff --git a/common/src/common/entity/animal/EntityRabbit.java b/common/src/common/entity/animal/EntityRabbit.java index 93ce36f..40e1c34 100755 --- a/common/src/common/entity/animal/EntityRabbit.java +++ b/common/src/common/entity/animal/EntityRabbit.java @@ -17,7 +17,7 @@ import common.ai.EntityJumpHelper; import common.ai.EntityMoveHelper; import common.attributes.Attributes; import common.block.Block; -import common.block.BlockTallGrass; +import common.block.foliage.BlockTallGrass; import common.entity.DamageSource; import common.entity.Entity; import common.entity.npc.Alignment; diff --git a/common/src/common/entity/effect/EntityLightning.java b/common/src/common/entity/effect/EntityLightning.java index 4de8d0f..bbd24c0 100755 --- a/common/src/common/entity/effect/EntityLightning.java +++ b/common/src/common/entity/effect/EntityLightning.java @@ -8,7 +8,6 @@ import common.entity.types.EntityWeatherEffect; import common.init.Blocks; import common.init.Config; import common.init.SoundEvent; -import common.material.Material; import common.util.BlockPos; import common.util.BoundingBox; import common.world.AWorldClient; @@ -66,7 +65,7 @@ public class EntityLightning extends EntityWeatherEffect this.boltVertex = this.rand.longv(); BlockPos blockpos = new BlockPos(this); - if (!this.worldObj.client && this.fire && Config.fire && this.worldObj.isAreaLoaded(blockpos, 10) && this.worldObj.getState(blockpos).getBlock().getMaterial() == Material.air && Blocks.fire.canPlaceBlockAt(this.worldObj, blockpos)) + if (!this.worldObj.client && this.fire && Config.fire && this.worldObj.isAreaLoaded(blockpos, 10) && this.worldObj.getState(blockpos).getBlock() == Blocks.air && Blocks.fire.canPlaceBlockAt(this.worldObj, blockpos)) { this.worldObj.setState(blockpos, Blocks.fire.getState()); } diff --git a/common/src/common/entity/item/EntityCart.java b/common/src/common/entity/item/EntityCart.java index e94b911..6c58128 100755 --- a/common/src/common/entity/item/EntityCart.java +++ b/common/src/common/entity/item/EntityCart.java @@ -1,8 +1,8 @@ package common.entity.item; import common.block.Block; -import common.block.BlockRailBase; -import common.block.BlockRailPowered; +import common.block.tech.BlockRailBase; +import common.block.tech.BlockRailPowered; import common.entity.DamageSource; import common.entity.Entity; import common.entity.EntityType; diff --git a/common/src/common/entity/item/EntityChestCart.java b/common/src/common/entity/item/EntityChestCart.java index 73d7966..1c0f47b 100755 --- a/common/src/common/entity/item/EntityChestCart.java +++ b/common/src/common/entity/item/EntityChestCart.java @@ -1,6 +1,6 @@ package common.entity.item; -import common.block.BlockChest; +import common.block.tech.BlockChest; import common.entity.DamageSource; import common.entity.npc.EntityNPC; import common.init.Blocks; diff --git a/common/src/common/entity/item/EntityFalling.java b/common/src/common/entity/item/EntityFalling.java index f5bdfb0..b130c2d 100755 --- a/common/src/common/entity/item/EntityFalling.java +++ b/common/src/common/entity/item/EntityFalling.java @@ -3,9 +3,9 @@ package common.entity.item; import java.util.List; import common.block.Block; -import common.block.BlockAnvil; import common.block.BlockFalling; import common.block.ITileEntityProvider; +import common.block.tech.BlockAnvil; import common.collect.Lists; import common.entity.DamageSource; import common.entity.Entity; @@ -15,7 +15,6 @@ import common.init.BlockRegistry; import common.init.Blocks; import common.init.Config; import common.item.ItemStack; -import common.material.Material; import common.nbt.NBTBase; import common.nbt.NBTTagCompound; import common.tileentity.TileEntity; @@ -89,7 +88,7 @@ public class EntityFalling extends Entity implements IObjectData { Block block = this.fallTile.getBlock(); - if (block.getMaterial() == Material.air) + if (block == Blocks.air) { this.setDead(); } @@ -291,7 +290,7 @@ public class EntityFalling extends Entity implements IObjectData this.tileEntityData = tagCompund.getCompoundTag("TileEntityData"); } - if (block == null || block.getMaterial() == Material.air) + if (block == null || block == Blocks.air) { this.fallTile = Blocks.sand.getState(); } diff --git a/common/src/common/entity/item/EntityLeashKnot.java b/common/src/common/entity/item/EntityLeashKnot.java index 764cc21..08b8882 100755 --- a/common/src/common/entity/item/EntityLeashKnot.java +++ b/common/src/common/entity/item/EntityLeashKnot.java @@ -1,6 +1,6 @@ package common.entity.item; -import common.block.BlockFence; +import common.block.artificial.BlockFence; import common.entity.DamageSource; import common.entity.Entity; import common.entity.EntityType; diff --git a/common/src/common/entity/item/EntityTntCart.java b/common/src/common/entity/item/EntityTntCart.java index 3f9005c..4d59b8e 100755 --- a/common/src/common/entity/item/EntityTntCart.java +++ b/common/src/common/entity/item/EntityTntCart.java @@ -1,6 +1,6 @@ package common.entity.item; -import common.block.BlockRailBase; +import common.block.tech.BlockRailBase; import common.entity.DamageSource; import common.entity.Entity; import common.entity.projectile.EntityArrow; diff --git a/common/src/common/entity/npc/EntityNPC.java b/common/src/common/entity/npc/EntityNPC.java index bc3c447..80ece57 100755 --- a/common/src/common/entity/npc/EntityNPC.java +++ b/common/src/common/entity/npc/EntityNPC.java @@ -22,7 +22,7 @@ import common.ai.EntityAIWatchClosest2; import common.attributes.AttributeInstance; import common.attributes.Attributes; import common.block.Block; -import common.block.BlockBed; +import common.block.artificial.BlockBed; import common.dimension.Space; import common.enchantment.Enchantment; import common.enchantment.EnchantmentHelper; diff --git a/common/src/common/entity/projectile/EntityArrow.java b/common/src/common/entity/projectile/EntityArrow.java index 3174775..1b8fd19 100755 --- a/common/src/common/entity/projectile/EntityArrow.java +++ b/common/src/common/entity/projectile/EntityArrow.java @@ -12,11 +12,11 @@ import common.entity.types.EntityLiving; import common.entity.types.IObjectData; import common.entity.types.IProjectile; import common.init.BlockRegistry; +import common.init.Blocks; import common.init.Config; import common.init.Items; import common.init.SoundEvent; import common.item.ItemStack; -import common.material.Material; import common.model.ParticleType; import common.nbt.NBTTagCompound; import common.util.BlockPos; @@ -201,7 +201,7 @@ public class EntityArrow extends Entity implements IProjectile, IObjectData State iblockstate = this.worldObj.getState(blockpos); Block block = iblockstate.getBlock(); - if (block.getMaterial() != Material.air) + if (block != Blocks.air) { block.setBlockBoundsBasedOnState(this.worldObj, blockpos); BoundingBox axisalignedbb = block.getCollisionBoundingBox(this.worldObj, blockpos, iblockstate); @@ -397,7 +397,7 @@ public class EntityArrow extends Entity implements IProjectile, IObjectData this.arrowShake = 7; this.setIsCritical(false); - if (this.inTile.getMaterial() != Material.air) + if (this.inTile != Blocks.air) { this.inTile.onEntityCollidedWithBlock(this.worldObj, blockpos1, iblockstate1, this); } diff --git a/common/src/common/entity/types/EntityLiving.java b/common/src/common/entity/types/EntityLiving.java index 4ec9250..57174bf 100755 --- a/common/src/common/entity/types/EntityLiving.java +++ b/common/src/common/entity/types/EntityLiving.java @@ -46,7 +46,6 @@ import common.item.Item; import common.item.ItemArmor; import common.item.ItemMonsterPlacer; import common.item.ItemStack; -import common.material.Material; import common.model.ParticleType; import common.nbt.NBTTagCompound; import common.nbt.NBTTagList; @@ -224,7 +223,7 @@ public abstract class EntityLiving extends Entity Block block = iblockstate.getBlock(); float f = (float)ExtMath.ceilf(this.fallDistance - 3.0F); - if (block.getMaterial() != Material.air) + if (block != Blocks.air) { double d0 = (double)Math.min(0.2F + f / 15.0F, 10.0F); @@ -1247,7 +1246,7 @@ public abstract class EntityLiving extends Entity int l = ExtMath.floord(this.posZ); Block block = this.worldObj.getState(new BlockPos(j, k, l)).getBlock(); - if (block.getMaterial() != Material.air) + if (block != Blocks.air) { SoundType block$soundtype = block.sound; if(block$soundtype.getStepSound() != null) diff --git a/common/src/common/entity/types/EntityThrowable.java b/common/src/common/entity/types/EntityThrowable.java index e325a29..babb6a8 100755 --- a/common/src/common/entity/types/EntityThrowable.java +++ b/common/src/common/entity/types/EntityThrowable.java @@ -3,7 +3,7 @@ package common.entity.types; import java.util.List; import common.block.Block; -import common.block.BlockPortal; +import common.block.artificial.BlockPortal; import common.entity.Entity; import common.entity.EntityType; import common.init.BlockRegistry; diff --git a/common/src/common/init/BlockRegistry.java b/common/src/common/init/BlockRegistry.java index ec7703a..036be1a 100755 --- a/common/src/common/init/BlockRegistry.java +++ b/common/src/common/init/BlockRegistry.java @@ -1,6 +1,128 @@ package common.init; import common.block.*; +import common.block.artificial.BlockBed; +import common.block.artificial.BlockBookshelf; +import common.block.artificial.BlockCake; +import common.block.artificial.BlockCarpet; +import common.block.artificial.BlockCompressedPowered; +import common.block.artificial.BlockDoor; +import common.block.artificial.BlockDragonEgg; +import common.block.artificial.BlockFence; +import common.block.artificial.BlockFenceGate; +import common.block.artificial.BlockFloorPortal; +import common.block.artificial.BlockFlowerPot; +import common.block.artificial.BlockGlass; +import common.block.artificial.BlockHay; +import common.block.artificial.BlockLadder; +import common.block.artificial.BlockPane; +import common.block.artificial.BlockPortal; +import common.block.artificial.BlockPortalFrame; +import common.block.artificial.BlockQuartz; +import common.block.artificial.BlockSlab; +import common.block.artificial.BlockStainedGlass; +import common.block.artificial.BlockStainedGlassPane; +import common.block.artificial.BlockStairs; +import common.block.artificial.BlockStoneBrick; +import common.block.artificial.BlockTrapDoor; +import common.block.artificial.BlockWall; +import common.block.foliage.BlockBaseFlower; +import common.block.foliage.BlockBlackenedSoil; +import common.block.foliage.BlockBlueShroom; +import common.block.foliage.BlockCactus; +import common.block.foliage.BlockCarrot; +import common.block.foliage.BlockCocoa; +import common.block.foliage.BlockCrops; +import common.block.foliage.BlockDeadBush; +import common.block.foliage.BlockDoublePlant; +import common.block.foliage.BlockDryLeaves; +import common.block.foliage.BlockFarmland; +import common.block.foliage.BlockGrass; +import common.block.foliage.BlockHugeMushroom; +import common.block.foliage.BlockLeaves; +import common.block.foliage.BlockLilyPad; +import common.block.foliage.BlockLog; +import common.block.foliage.BlockMelon; +import common.block.foliage.BlockMushroom; +import common.block.foliage.BlockMycelium; +import common.block.foliage.BlockPotato; +import common.block.foliage.BlockPumpkin; +import common.block.foliage.BlockReed; +import common.block.foliage.BlockSapling; +import common.block.foliage.BlockStem; +import common.block.foliage.BlockTallGrass; +import common.block.foliage.BlockTianSoil; +import common.block.foliage.BlockVine; +import common.block.foliage.BlockWart; +import common.block.liquid.BlockDynamicLiquid; +import common.block.liquid.BlockStaticLiquid; +import common.block.natural.BlockBedrock; +import common.block.natural.BlockBlackenedDirt; +import common.block.natural.BlockBlackenedStone; +import common.block.natural.BlockClay; +import common.block.natural.BlockDirt; +import common.block.natural.BlockFire; +import common.block.natural.BlockGlowstone; +import common.block.natural.BlockGravel; +import common.block.natural.BlockHardenedClay; +import common.block.natural.BlockHellRock; +import common.block.natural.BlockIce; +import common.block.natural.BlockObsidian; +import common.block.natural.BlockOre; +import common.block.natural.BlockPackedIce; +import common.block.natural.BlockRedstoneOre; +import common.block.natural.BlockRock; +import common.block.natural.BlockSand; +import common.block.natural.BlockSandStone; +import common.block.natural.BlockSlime; +import common.block.natural.BlockSnow; +import common.block.natural.BlockSnowBlock; +import common.block.natural.BlockSoulSand; +import common.block.natural.BlockStone; +import common.block.natural.BlockTintedFire; +import common.block.natural.BlockWeb; +import common.block.tech.BlockAnvil; +import common.block.tech.BlockBeacon; +import common.block.tech.BlockBrewingStand; +import common.block.tech.BlockButton; +import common.block.tech.BlockCauldron; +import common.block.tech.BlockChest; +import common.block.tech.BlockCore; +import common.block.tech.BlockDaylightDetector; +import common.block.tech.BlockDispenser; +import common.block.tech.BlockDropper; +import common.block.tech.BlockEnchantmentTable; +import common.block.tech.BlockFurnace; +import common.block.tech.BlockHopper; +import common.block.tech.BlockJukebox; +import common.block.tech.BlockLever; +import common.block.tech.BlockMobSpawner; +import common.block.tech.BlockNote; +import common.block.tech.BlockNuke; +import common.block.tech.BlockPistonBase; +import common.block.tech.BlockPistonHead; +import common.block.tech.BlockPistonMoving; +import common.block.tech.BlockPressurePlate; +import common.block.tech.BlockPressurePlateWeighted; +import common.block.tech.BlockRail; +import common.block.tech.BlockRailDetector; +import common.block.tech.BlockRailPowered; +import common.block.tech.BlockRedstoneComparator; +import common.block.tech.BlockRedstoneLight; +import common.block.tech.BlockRedstoneRepeater; +import common.block.tech.BlockRedstoneTorch; +import common.block.tech.BlockRedstoneWire; +import common.block.tech.BlockTNT; +import common.block.tech.BlockTianReactor; +import common.block.tech.BlockTorch; +import common.block.tech.BlockTripWire; +import common.block.tech.BlockTripWireHook; +import common.block.tech.BlockWarpChest; +import common.block.tech.BlockWorkbench; +import common.block.tile.BlockBanner; +import common.block.tile.BlockSkull; +import common.block.tile.BlockStandingSign; +import common.block.tile.BlockWallSign; import common.color.DyeColor; import common.init.FluidRegistry.LiquidType; import common.item.CheatTab; @@ -114,7 +236,7 @@ public abstract class BlockRegistry { REGISTRY.validateKey(); for(Block block : REGISTRY) { - if(block.getMaterial() != Material.air + if(block != Blocks.air && ((block instanceof BlockStairs) || /* (block instanceof BlockSlab) || */ (block instanceof BlockSlab) || (block instanceof BlockFarmland) || block.isTranslucent() || block.getLightOpacity() == 0)) { block.setSumBrightness(); @@ -324,9 +446,9 @@ public abstract class BlockRegistry { .setStepSound(SoundType.STONE).setDisplay("Redstone-Block").setTab(CheatTab.tabTech)); registerBlock(270, "glass", - (new BlockGlass(Material.glass, false)).setHardness(0.3F).setStepSound(SoundType.GLASS).setDisplay("Glas")); + (new BlockGlass()).setHardness(0.3F).setStepSound(SoundType.GLASS).setDisplay("Glas")); registerBlock(271, "stained_glass", - (new BlockStainedGlass(Material.glass)).setHardness(0.3F).setStepSound(SoundType.GLASS).setDisplay("gefärbtes Glas")); + (new BlockStainedGlass()).setHardness(0.3F).setStepSound(SoundType.GLASS).setDisplay("gefärbtes Glas")); registerBlock(272, "glass_pane", (new BlockPane(Material.glass, false)).setHardness(0.3F).setStepSound(SoundType.GLASS).setDisplay("Glasscheibe")); registerBlock(273, "stained_glass_pane", diff --git a/common/src/common/init/Blocks.java b/common/src/common/init/Blocks.java index 508ec50..2d1a966 100755 --- a/common/src/common/init/Blocks.java +++ b/common/src/common/init/Blocks.java @@ -1,42 +1,42 @@ package common.init; import common.block.Block; -import common.block.BlockBeacon; -import common.block.BlockBed; -import common.block.BlockBlackenedSoil; -import common.block.BlockBush; -import common.block.BlockCactus; -import common.block.BlockCauldron; -import common.block.BlockChest; -import common.block.BlockDaylightDetector; -import common.block.BlockDeadBush; -import common.block.BlockDoublePlant; -import common.block.BlockDryLeaves; -import common.block.BlockDynamicLiquid; -import common.block.BlockFire; -import common.block.BlockFlower; -import common.block.BlockGrass; -import common.block.BlockHopper; -import common.block.BlockLeaves; -import common.block.BlockMycelium; -import common.block.BlockOre; -import common.block.BlockPistonBase; -import common.block.BlockPistonHead; -import common.block.BlockPistonMoving; -import common.block.BlockPortal; -import common.block.BlockRedstoneComparator; -import common.block.BlockRedstoneRepeater; -import common.block.BlockRedstoneWire; -import common.block.BlockReed; -import common.block.BlockSand; -import common.block.BlockSkull; -import common.block.BlockSlab; -import common.block.BlockStainedGlass; -import common.block.BlockStainedGlassPane; -import common.block.BlockStaticLiquid; -import common.block.BlockTallGrass; -import common.block.BlockTianReactor; -import common.block.BlockTripWireHook; +import common.block.artificial.BlockBed; +import common.block.artificial.BlockPortal; +import common.block.artificial.BlockSlab; +import common.block.artificial.BlockStainedGlass; +import common.block.artificial.BlockStainedGlassPane; +import common.block.foliage.BlockBlackenedSoil; +import common.block.foliage.BlockBush; +import common.block.foliage.BlockCactus; +import common.block.foliage.BlockDeadBush; +import common.block.foliage.BlockDoublePlant; +import common.block.foliage.BlockDryLeaves; +import common.block.foliage.BlockFlower; +import common.block.foliage.BlockGrass; +import common.block.foliage.BlockLeaves; +import common.block.foliage.BlockMycelium; +import common.block.foliage.BlockReed; +import common.block.foliage.BlockTallGrass; +import common.block.liquid.BlockDynamicLiquid; +import common.block.liquid.BlockStaticLiquid; +import common.block.natural.BlockFire; +import common.block.natural.BlockOre; +import common.block.natural.BlockSand; +import common.block.tech.BlockBeacon; +import common.block.tech.BlockCauldron; +import common.block.tech.BlockChest; +import common.block.tech.BlockDaylightDetector; +import common.block.tech.BlockHopper; +import common.block.tech.BlockPistonBase; +import common.block.tech.BlockPistonHead; +import common.block.tech.BlockPistonMoving; +import common.block.tech.BlockRedstoneComparator; +import common.block.tech.BlockRedstoneRepeater; +import common.block.tech.BlockRedstoneWire; +import common.block.tech.BlockTianReactor; +import common.block.tech.BlockTripWireHook; +import common.block.tile.BlockSkull; public abstract class Blocks { diff --git a/common/src/common/init/CraftingRegistry.java b/common/src/common/init/CraftingRegistry.java index e76ddfb..113fe06 100755 --- a/common/src/common/init/CraftingRegistry.java +++ b/common/src/common/init/CraftingRegistry.java @@ -7,15 +7,15 @@ import java.util.Map; import java.util.Set; import common.block.Block; -import common.block.BlockBed; -import common.block.BlockDirt; -import common.block.BlockDoublePlant; -import common.block.BlockFlower; -import common.block.BlockQuartz; -import common.block.BlockSand; -import common.block.BlockSandStone; -import common.block.BlockStoneBrick; -import common.block.BlockWall; +import common.block.artificial.BlockBed; +import common.block.artificial.BlockQuartz; +import common.block.artificial.BlockStoneBrick; +import common.block.artificial.BlockWall; +import common.block.foliage.BlockDoublePlant; +import common.block.foliage.BlockFlower; +import common.block.natural.BlockDirt; +import common.block.natural.BlockSand; +import common.block.natural.BlockSandStone; import common.collect.Lists; import common.collect.Maps; import common.color.DyeColor; diff --git a/common/src/common/init/DispenserRegistry.java b/common/src/common/init/DispenserRegistry.java index 3f161a1..d4ef76d 100755 --- a/common/src/common/init/DispenserRegistry.java +++ b/common/src/common/init/DispenserRegistry.java @@ -1,10 +1,10 @@ package common.init; import common.block.Block; -import common.block.BlockDispenser; -import common.block.BlockDynamicLiquid; -import common.block.BlockLiquid; -import common.block.BlockTNT; +import common.block.liquid.BlockDynamicLiquid; +import common.block.liquid.BlockLiquid; +import common.block.tech.BlockDispenser; +import common.block.tech.BlockTNT; import common.color.DyeColor; import common.dispenser.BehaviorDefaultDispenseItem; import common.dispenser.BehaviorProjectileDispense; @@ -205,16 +205,16 @@ public abstract class DispenserRegistry { double d1 = source.getY() + (double)((float)enumfacing.getFrontOffsetY() * 1.125F); double d2 = source.getZ() + (double)((float)enumfacing.getFrontOffsetZ() * 1.125F); BlockPos blockpos = source.getBlockPos().offset(enumfacing); - Material material = world.getState(blockpos).getBlock().getMaterial(); + Block block = world.getState(blockpos).getBlock(); double d3; - if (material.isColdLiquid()) + if (block.getMaterial().isColdLiquid()) { d3 = 1.0D; } else { - if (!Material.air.equals(material) || !world.getState(blockpos.down()).getBlock().getMaterial().isColdLiquid()) + if (block != Blocks.air || !world.getState(blockpos.down()).getBlock().getMaterial().isColdLiquid()) { return this.field_150842_b.dispense(source, stack); } diff --git a/common/src/common/init/FluidRegistry.java b/common/src/common/init/FluidRegistry.java index e585f54..c808342 100755 --- a/common/src/common/init/FluidRegistry.java +++ b/common/src/common/init/FluidRegistry.java @@ -4,9 +4,9 @@ import java.util.List; import java.util.Map; import common.block.Block; -import common.block.BlockDynamicLiquid; -import common.block.BlockLiquid; -import common.block.BlockStaticLiquid; +import common.block.liquid.BlockDynamicLiquid; +import common.block.liquid.BlockLiquid; +import common.block.liquid.BlockStaticLiquid; import common.collect.Lists; import common.collect.Maps; import common.material.Material; diff --git a/common/src/common/init/ItemRegistry.java b/common/src/common/init/ItemRegistry.java index 5ff4a91..d16839e 100755 --- a/common/src/common/init/ItemRegistry.java +++ b/common/src/common/init/ItemRegistry.java @@ -5,21 +5,21 @@ import java.util.Set; import java.util.function.Function; import common.block.Block; -import common.block.BlockBed; -import common.block.BlockButton; -import common.block.BlockDirt; -import common.block.BlockDoor; -import common.block.BlockDoublePlant; -import common.block.BlockFence; -import common.block.BlockFlower; -import common.block.BlockLeaves; -import common.block.BlockOre; -import common.block.BlockSand; -import common.block.BlockSandStone; -import common.block.BlockSapling; -import common.block.BlockSlab; -import common.block.BlockStoneBrick; -import common.block.BlockWall; +import common.block.artificial.BlockBed; +import common.block.artificial.BlockDoor; +import common.block.artificial.BlockFence; +import common.block.artificial.BlockSlab; +import common.block.artificial.BlockStoneBrick; +import common.block.artificial.BlockWall; +import common.block.foliage.BlockDoublePlant; +import common.block.foliage.BlockFlower; +import common.block.foliage.BlockLeaves; +import common.block.foliage.BlockSapling; +import common.block.natural.BlockDirt; +import common.block.natural.BlockOre; +import common.block.natural.BlockSand; +import common.block.natural.BlockSandStone; +import common.block.tech.BlockButton; import common.collect.Maps; import common.collect.Sets; import common.color.DyeColor; diff --git a/common/src/common/init/SmeltingRegistry.java b/common/src/common/init/SmeltingRegistry.java index f47f6b2..4a316bc 100755 --- a/common/src/common/init/SmeltingRegistry.java +++ b/common/src/common/init/SmeltingRegistry.java @@ -4,7 +4,7 @@ import java.util.Map; import java.util.Map.Entry; import common.block.Block; -import common.block.BlockStoneBrick; +import common.block.artificial.BlockStoneBrick; import common.collect.Maps; import common.color.DyeColor; import common.item.Item; diff --git a/common/src/common/init/UniverseRegistry.java b/common/src/common/init/UniverseRegistry.java index a87f9a6..4fffd2f 100755 --- a/common/src/common/init/UniverseRegistry.java +++ b/common/src/common/init/UniverseRegistry.java @@ -6,8 +6,8 @@ import java.util.Map.Entry; import common.biome.Biome; import common.block.BlockColored; -import common.block.BlockSand; -import common.block.LeavesType; +import common.block.foliage.LeavesType; +import common.block.natural.BlockSand; import common.collect.Lists; import common.collect.Maps; import common.collect.Sets; diff --git a/common/src/common/inventory/ContainerRepair.java b/common/src/common/inventory/ContainerRepair.java index 82da6ed..505cd44 100755 --- a/common/src/common/inventory/ContainerRepair.java +++ b/common/src/common/inventory/ContainerRepair.java @@ -3,7 +3,7 @@ package common.inventory; import java.util.Iterator; import java.util.Map; -import common.block.BlockAnvil; +import common.block.tech.BlockAnvil; import common.enchantment.Enchantment; import common.enchantment.EnchantmentHelper; import common.entity.npc.EntityNPC; diff --git a/common/src/common/inventory/ContainerWorkbench.java b/common/src/common/inventory/ContainerWorkbench.java index 4450495..e25af25 100755 --- a/common/src/common/inventory/ContainerWorkbench.java +++ b/common/src/common/inventory/ContainerWorkbench.java @@ -1,6 +1,6 @@ package common.inventory; -import common.block.BlockWorkbench; +import common.block.tech.BlockWorkbench; import common.entity.npc.EntityNPC; import common.init.CraftingRegistry; import common.item.ItemStack; diff --git a/common/src/common/item/ItemArmor.java b/common/src/common/item/ItemArmor.java index 09e371e..9c2f2ab 100755 --- a/common/src/common/item/ItemArmor.java +++ b/common/src/common/item/ItemArmor.java @@ -8,7 +8,7 @@ import java.util.function.Predicate; import common.attributes.Attribute; import common.attributes.AttributeModifier; import common.attributes.Attributes; -import common.block.BlockDispenser; +import common.block.tech.BlockDispenser; import common.collect.Sets; import common.dispenser.BehaviorDefaultDispenseItem; import common.dispenser.IBehaviorDispenseItem; diff --git a/common/src/common/item/ItemBanner.java b/common/src/common/item/ItemBanner.java index dc04e64..32989a3 100755 --- a/common/src/common/item/ItemBanner.java +++ b/common/src/common/item/ItemBanner.java @@ -2,8 +2,8 @@ package common.item; import java.util.List; -import common.block.BlockStandingSign; -import common.block.BlockWallSign; +import common.block.tile.BlockStandingSign; +import common.block.tile.BlockWallSign; import common.color.DyeColor; import common.entity.npc.EntityNPC; import common.init.Blocks; diff --git a/common/src/common/item/ItemBed.java b/common/src/common/item/ItemBed.java index f2c927e..403a0b0 100755 --- a/common/src/common/item/ItemBed.java +++ b/common/src/common/item/ItemBed.java @@ -1,7 +1,7 @@ package common.item; import common.block.Block; -import common.block.BlockBed; +import common.block.artificial.BlockBed; import common.entity.npc.EntityNPC; import common.util.BlockPos; import common.util.ExtMath; diff --git a/common/src/common/item/ItemBucket.java b/common/src/common/item/ItemBucket.java index 242d233..d5e3ee9 100755 --- a/common/src/common/item/ItemBucket.java +++ b/common/src/common/item/ItemBucket.java @@ -8,9 +8,9 @@ import java.util.Queue; import java.util.Set; import common.block.Block; -import common.block.BlockDynamicLiquid; -import common.block.BlockLiquid; -import common.block.BlockStaticLiquid; +import common.block.liquid.BlockDynamicLiquid; +import common.block.liquid.BlockLiquid; +import common.block.liquid.BlockStaticLiquid; import common.collect.Sets; import common.entity.npc.EntityNPC; import common.init.BlockRegistry; diff --git a/common/src/common/item/ItemButton.java b/common/src/common/item/ItemButton.java index 34c50ce..95b923b 100755 --- a/common/src/common/item/ItemButton.java +++ b/common/src/common/item/ItemButton.java @@ -1,6 +1,6 @@ package common.item; -import common.block.BlockButton; +import common.block.tech.BlockButton; import common.model.Model; import common.model.ModelProvider; diff --git a/common/src/common/item/ItemChargedOrb.java b/common/src/common/item/ItemChargedOrb.java index 8e93c20..0016734 100755 --- a/common/src/common/item/ItemChargedOrb.java +++ b/common/src/common/item/ItemChargedOrb.java @@ -1,6 +1,6 @@ package common.item; -import common.block.BlockPortalFrame; +import common.block.artificial.BlockPortalFrame; import common.color.TextColor; import common.entity.item.EntityOrb; import common.entity.npc.EntityNPC; diff --git a/common/src/common/item/ItemDoor.java b/common/src/common/item/ItemDoor.java index ed84de0..244bc09 100755 --- a/common/src/common/item/ItemDoor.java +++ b/common/src/common/item/ItemDoor.java @@ -1,7 +1,7 @@ package common.item; import common.block.Block; -import common.block.BlockDoor; +import common.block.artificial.BlockDoor; import common.entity.npc.EntityNPC; import common.init.Blocks; import common.material.Material; diff --git a/common/src/common/item/ItemDoublePlant.java b/common/src/common/item/ItemDoublePlant.java index fe2b963..2e1875e 100755 --- a/common/src/common/item/ItemDoublePlant.java +++ b/common/src/common/item/ItemDoublePlant.java @@ -3,8 +3,8 @@ package common.item; import java.util.function.Function; import common.block.Block; -import common.block.BlockDoublePlant; -import common.block.BlockDoublePlant.EnumPlantType; +import common.block.foliage.BlockDoublePlant; +import common.block.foliage.BlockDoublePlant.EnumPlantType; import common.color.Colorizer; import common.model.Model; import common.model.ModelProvider; diff --git a/common/src/common/item/ItemDye.java b/common/src/common/item/ItemDye.java index c42120e..5013ce7 100755 --- a/common/src/common/item/ItemDye.java +++ b/common/src/common/item/ItemDye.java @@ -3,15 +3,14 @@ package common.item; import java.util.List; import common.block.Block; -import common.block.BlockBed; -import common.block.IGrowable; +import common.block.artificial.BlockBed; +import common.block.foliage.IGrowable; import common.color.DyeColor; import common.entity.animal.EntitySheep; import common.entity.npc.EntityNPC; import common.entity.types.EntityLiving; import common.init.BlockRegistry; import common.init.Blocks; -import common.material.Material; import common.model.Model; import common.model.ModelProvider; import common.model.ParticleType; @@ -181,7 +180,7 @@ public class ItemDye extends Item Block block = worldIn.getState(pos).getBlock(); - if (block.getMaterial() != Material.air) + if (block != Blocks.air) { block.setBlockBoundsBasedOnState(worldIn, pos); diff --git a/common/src/common/item/ItemFence.java b/common/src/common/item/ItemFence.java index 38089d5..007ce6b 100755 --- a/common/src/common/item/ItemFence.java +++ b/common/src/common/item/ItemFence.java @@ -1,7 +1,7 @@ package common.item; import common.block.Block; -import common.block.BlockFence; +import common.block.artificial.BlockFence; import common.model.Model; import common.model.ModelProvider; diff --git a/common/src/common/item/ItemFireball.java b/common/src/common/item/ItemFireball.java index 5870b25..51cbe0a 100755 --- a/common/src/common/item/ItemFireball.java +++ b/common/src/common/item/ItemFireball.java @@ -3,7 +3,6 @@ package common.item; import common.entity.npc.EntityNPC; import common.init.Blocks; import common.init.SoundEvent; -import common.material.Material; import common.util.BlockPos; import common.util.Facing; import common.world.World; @@ -34,7 +33,7 @@ public class ItemFireball extends Item } else { - if (worldIn.getState(pos).getBlock().getMaterial() == Material.air) + if (worldIn.getState(pos).getBlock() == Blocks.air) { worldIn.playSound(SoundEvent.FIREBALL, (double)pos.getX() + 0.5D, (double)pos.getY() + 0.5D, (double)pos.getZ() + 0.5D, 1.0F); worldIn.setState(pos, Blocks.fire.getState()); diff --git a/common/src/common/item/ItemFlintAndSteel.java b/common/src/common/item/ItemFlintAndSteel.java index 5d029a4..e0096ae 100755 --- a/common/src/common/item/ItemFlintAndSteel.java +++ b/common/src/common/item/ItemFlintAndSteel.java @@ -1,9 +1,9 @@ package common.item; -import common.block.BlockFire; +import common.block.natural.BlockFire; import common.entity.npc.EntityNPC; +import common.init.Blocks; import common.init.SoundEvent; -import common.material.Material; import common.util.BlockPos; import common.util.Facing; import common.world.World; @@ -33,7 +33,7 @@ public class ItemFlintAndSteel extends Item } else { - if (worldIn.getState(pos).getBlock().getMaterial() == Material.air) + if (worldIn.getState(pos).getBlock() == Blocks.air) { worldIn.playSound(SoundEvent.IGNITE, (double)pos.getX() + 0.5D, (double)pos.getY() + 0.5D, (double)pos.getZ() + 0.5D, 1.0F); worldIn.setState(pos, this.fireBlock.getState()); diff --git a/common/src/common/item/ItemHoe.java b/common/src/common/item/ItemHoe.java index 1d5294c..7512f93 100755 --- a/common/src/common/item/ItemHoe.java +++ b/common/src/common/item/ItemHoe.java @@ -1,11 +1,10 @@ package common.item; import common.block.Block; -import common.block.BlockDirt; +import common.block.natural.BlockDirt; import common.entity.npc.EntityNPC; import common.init.Blocks; import common.init.ToolMaterial; -import common.material.Material; import common.model.Transforms; import common.util.BlockPos; import common.util.Facing; @@ -40,7 +39,7 @@ public class ItemHoe extends Item State iblockstate = worldIn.getState(pos); Block block = iblockstate.getBlock(); - if (side != Facing.DOWN && worldIn.getState(pos.up()).getBlock().getMaterial() == Material.air) + if (side != Facing.DOWN && worldIn.getState(pos.up()).getBlock() == Blocks.air) { if (block == Blocks.grass) { diff --git a/common/src/common/item/ItemLead.java b/common/src/common/item/ItemLead.java index 263e5f3..6ea2819 100755 --- a/common/src/common/item/ItemLead.java +++ b/common/src/common/item/ItemLead.java @@ -1,7 +1,7 @@ package common.item; import common.block.Block; -import common.block.BlockFence; +import common.block.artificial.BlockFence; import common.entity.item.EntityLeashKnot; import common.entity.npc.EntityNPC; import common.entity.types.EntityLiving; diff --git a/common/src/common/item/ItemLeaves.java b/common/src/common/item/ItemLeaves.java index 16e91d0..efe717c 100755 --- a/common/src/common/item/ItemLeaves.java +++ b/common/src/common/item/ItemLeaves.java @@ -1,7 +1,7 @@ package common.item; -import common.block.BlockLeaves; -import common.block.LeavesType; +import common.block.foliage.BlockLeaves; +import common.block.foliage.LeavesType; public class ItemLeaves extends ItemBlock { diff --git a/common/src/common/item/ItemLilyPad.java b/common/src/common/item/ItemLilyPad.java index 6a69dc2..c8ad9e4 100755 --- a/common/src/common/item/ItemLilyPad.java +++ b/common/src/common/item/ItemLilyPad.java @@ -2,7 +2,7 @@ package common.item; import common.block.Block; import common.block.BlockDirectional; -import common.block.BlockLiquid; +import common.block.liquid.BlockLiquid; import common.entity.npc.EntityNPC; import common.init.Blocks; import common.util.BlockPos; diff --git a/common/src/common/item/ItemMinecart.java b/common/src/common/item/ItemMinecart.java index 73ab5b6..25b0513 100755 --- a/common/src/common/item/ItemMinecart.java +++ b/common/src/common/item/ItemMinecart.java @@ -1,14 +1,14 @@ package common.item; -import common.block.BlockDispenser; -import common.block.BlockRailBase; +import common.block.tech.BlockDispenser; +import common.block.tech.BlockRailBase; import common.dispenser.BehaviorDefaultDispenseItem; import common.dispenser.IBehaviorDispenseItem; import common.dispenser.IBlockSource; import common.entity.item.EntityCart; import common.entity.npc.EntityNPC; +import common.init.Blocks; import common.init.DispenserRegistry; -import common.material.Material; import common.util.BlockPos; import common.util.Facing; import common.world.State; @@ -44,7 +44,7 @@ public class ItemMinecart extends Item } else { - if (iblockstate.getBlock().getMaterial() != Material.air || !BlockRailBase.isRailBlock(world.getState(blockpos.down()))) + if (iblockstate.getBlock() != Blocks.air || !BlockRailBase.isRailBlock(world.getState(blockpos.down()))) { return this.behaviourDefaultDispenseItem.dispense(source, stack); } diff --git a/common/src/common/item/ItemMonsterPlacer.java b/common/src/common/item/ItemMonsterPlacer.java index b5e0d4d..995adc8 100755 --- a/common/src/common/item/ItemMonsterPlacer.java +++ b/common/src/common/item/ItemMonsterPlacer.java @@ -2,8 +2,8 @@ package common.item; import java.util.List; -import common.block.BlockFence; -import common.block.BlockLiquid; +import common.block.artificial.BlockFence; +import common.block.liquid.BlockLiquid; import common.color.TextColor; import common.dimension.Dimension; import common.entity.Entity; diff --git a/common/src/common/item/ItemNpcSpawner.java b/common/src/common/item/ItemNpcSpawner.java index 1f81811..934dbca 100755 --- a/common/src/common/item/ItemNpcSpawner.java +++ b/common/src/common/item/ItemNpcSpawner.java @@ -3,8 +3,8 @@ package common.item; import java.lang.reflect.InvocationTargetException; import java.util.List; -import common.block.BlockFence; -import common.block.BlockLiquid; +import common.block.artificial.BlockFence; +import common.block.liquid.BlockLiquid; import common.color.TextColor; import common.dimension.Dimension; import common.entity.Entity; diff --git a/common/src/common/item/ItemPressurePlate.java b/common/src/common/item/ItemPressurePlate.java index 5a246b2..e644b4b 100755 --- a/common/src/common/item/ItemPressurePlate.java +++ b/common/src/common/item/ItemPressurePlate.java @@ -1,7 +1,7 @@ package common.item; import common.block.Block; -import common.block.BlockBasePressurePlate; +import common.block.tech.BlockBasePressurePlate; import common.model.Model; import common.model.ModelProvider; diff --git a/common/src/common/item/ItemReed.java b/common/src/common/item/ItemReed.java index 263df61..91853cf 100755 --- a/common/src/common/item/ItemReed.java +++ b/common/src/common/item/ItemReed.java @@ -1,7 +1,7 @@ package common.item; import common.block.Block; -import common.block.BlockSnow; +import common.block.natural.BlockSnow; import common.entity.Entity; import common.entity.npc.EntityNPC; import common.init.Blocks; diff --git a/common/src/common/item/ItemSign.java b/common/src/common/item/ItemSign.java index 81719ad..1708631 100755 --- a/common/src/common/item/ItemSign.java +++ b/common/src/common/item/ItemSign.java @@ -1,8 +1,8 @@ package common.item; import common.block.Block; -import common.block.BlockStandingSign; -import common.block.BlockWallSign; +import common.block.tile.BlockStandingSign; +import common.block.tile.BlockWallSign; import common.entity.npc.EntityNPC; import common.init.Blocks; import common.tileentity.TileEntity; diff --git a/common/src/common/item/ItemSkull.java b/common/src/common/item/ItemSkull.java index ce5443e..20ee545 100755 --- a/common/src/common/item/ItemSkull.java +++ b/common/src/common/item/ItemSkull.java @@ -1,7 +1,7 @@ package common.item; import common.block.Block; -import common.block.BlockSkull; +import common.block.tile.BlockSkull; import common.entity.npc.EntityNPC; import common.init.Blocks; import common.model.Model; diff --git a/common/src/common/item/ItemSlab.java b/common/src/common/item/ItemSlab.java index 4b171ba..919e9ba 100755 --- a/common/src/common/item/ItemSlab.java +++ b/common/src/common/item/ItemSlab.java @@ -1,7 +1,7 @@ package common.item; import common.block.Block; -import common.block.BlockSlab; +import common.block.artificial.BlockSlab; import common.entity.npc.EntityNPC; import common.util.BlockPos; import common.util.Facing; diff --git a/common/src/common/item/ItemSnow.java b/common/src/common/item/ItemSnow.java index d98bc65..30bd2fc 100755 --- a/common/src/common/item/ItemSnow.java +++ b/common/src/common/item/ItemSnow.java @@ -1,7 +1,7 @@ package common.item; import common.block.Block; -import common.block.BlockSnow; +import common.block.natural.BlockSnow; import common.entity.npc.EntityNPC; import common.util.BlockPos; import common.util.BoundingBox; diff --git a/common/src/common/item/ItemSword.java b/common/src/common/item/ItemSword.java index 67840f0..1634327 100755 --- a/common/src/common/item/ItemSword.java +++ b/common/src/common/item/ItemSword.java @@ -53,7 +53,7 @@ public class ItemSword extends Item else { Material material = state.getMaterial(); - return material != Material.plants && material != Material.vine && material != Material.coral && material != Material.leaves && material != Material.gourd ? 1.0F : 1.5F; + return material != Material.plants && material != Material.vine && material != Material.leaves && material != Material.gourd ? 1.0F : 1.5F; } } diff --git a/common/src/common/item/ItemWall.java b/common/src/common/item/ItemWall.java index 0579baa..fbb0276 100755 --- a/common/src/common/item/ItemWall.java +++ b/common/src/common/item/ItemWall.java @@ -3,7 +3,7 @@ package common.item; import java.util.function.Function; import common.block.Block; -import common.block.BlockWall; +import common.block.artificial.BlockWall; import common.model.Model; import common.model.ModelProvider; diff --git a/common/src/common/material/Material.java b/common/src/common/material/Material.java index c71b80c..28a2f84 100755 --- a/common/src/common/material/Material.java +++ b/common/src/common/material/Material.java @@ -2,7 +2,6 @@ package common.material; public class Material { - public static final Material air = new MaterialTransparent(); public static final Material grass = new Material(); public static final Material ground = new Material(); public static final Material wood = (new Material()).setBurning(); @@ -22,15 +21,12 @@ public class Material public static final Material sand = new Material(); public static final Material circuits = (new MaterialLogic()).setNoPushMobility(); public static final Material carpet = (new MaterialLogic()).setBurning(); - public static final Material glass = (new Material()).setTranslucent(); // .setAdventureModeExempt(); - public static final Material redstoneLight = (new Material()); // .setAdventureModeExempt(); + public static final Material glass = (new Material()).setTranslucent(); + public static final Material redstoneLight = (new Material()); public static final Material tnt = (new Material()).setBurning().setTranslucent(); - public static final Material coral = (new Material()).setNoPushMobility(); - public static final Material ice = (new Material()).setTranslucent(); // .setAdventureModeExempt(); - public static final Material packedIce = (new Material()); // .setAdventureModeExempt(); + public static final Material ice = (new Material()).setTranslucent(); + public static final Material packedIce = (new Material()); public static final Material snow = (new MaterialLogic()).setReplaceable().setTranslucent().setRequiresTool().setNoPushMobility(); - - /** The material for crafted snow. */ public static final Material craftedSnow = (new Material()).setRequiresTool(); public static final Material cactus = (new Material()).setTranslucent().setNoPushMobility(); public static final Material clay = new Material(); @@ -45,10 +41,7 @@ public class Material return false; } }).setRequiresTool().setNoPushMobility(); - - /** Pistons' material. */ public static final Material piston = (new Material()).setImmovableMobility(); -// public static final Material barrier = (new Material()).setRequiresTool().setImmovableMobility(); /** Bool defining if the block can burn or not. */ private boolean canBurn; diff --git a/common/src/common/pathfinding/PathNavigateGround.java b/common/src/common/pathfinding/PathNavigateGround.java index f12b1c8..0ecbf86 100755 --- a/common/src/common/pathfinding/PathNavigateGround.java +++ b/common/src/common/pathfinding/PathNavigateGround.java @@ -4,6 +4,7 @@ import common.block.Block; import common.entity.animal.EntityChicken; import common.entity.npc.EntityZombie; import common.entity.types.EntityLiving; +import common.init.Blocks; import common.material.Material; import common.util.BlockPos; import common.util.ExtMath; @@ -206,7 +207,7 @@ public class PathNavigateGround extends PathNavigate Block block = this.worldObj.getState(new BlockPos(k, y - 1, l)).getBlock(); Material material = block.getMaterial(); - if (material == Material.air) + if (block == Blocks.air) { return false; } diff --git a/common/src/common/pathfinding/WalkNodeProcessor.java b/common/src/common/pathfinding/WalkNodeProcessor.java index 1233bcd..8ba5d42 100755 --- a/common/src/common/pathfinding/WalkNodeProcessor.java +++ b/common/src/common/pathfinding/WalkNodeProcessor.java @@ -1,11 +1,11 @@ package common.pathfinding; import common.block.Block; -import common.block.BlockDoor; -import common.block.BlockFence; -import common.block.BlockFenceGate; -import common.block.BlockRailBase; -import common.block.BlockWall; +import common.block.artificial.BlockDoor; +import common.block.artificial.BlockFence; +import common.block.artificial.BlockFenceGate; +import common.block.artificial.BlockWall; +import common.block.tech.BlockRailBase; import common.entity.Entity; import common.init.Blocks; import common.material.Material; @@ -205,7 +205,7 @@ public class WalkNodeProcessor extends NodeProcessor mpos.set(i, j, k); Block block = world.getState(mpos).getBlock(); - if (block.getMaterial() != Material.air) + if (block != Blocks.air) { if (block != Blocks.trapdoor && block != Blocks.iron_trapdoor) { diff --git a/common/src/common/tileentity/TileEntityBanner.java b/common/src/common/tileentity/TileEntityBanner.java index c4c7b1b..5691dd5 100755 --- a/common/src/common/tileentity/TileEntityBanner.java +++ b/common/src/common/tileentity/TileEntityBanner.java @@ -2,7 +2,7 @@ package common.tileentity; import java.util.List; -import common.block.BlockFlower; +import common.block.foliage.BlockFlower; import common.collect.Lists; import common.color.DyeColor; import common.init.Blocks; diff --git a/common/src/common/tileentity/TileEntityBrewingStand.java b/common/src/common/tileentity/TileEntityBrewingStand.java index 3ae0f5e..b1c3152 100755 --- a/common/src/common/tileentity/TileEntityBrewingStand.java +++ b/common/src/common/tileentity/TileEntityBrewingStand.java @@ -3,7 +3,7 @@ package common.tileentity; import java.util.Arrays; import java.util.List; -import common.block.BlockBrewingStand; +import common.block.tech.BlockBrewingStand; import common.entity.npc.EntityNPC; import common.init.Items; import common.inventory.Container; diff --git a/common/src/common/tileentity/TileEntityChest.java b/common/src/common/tileentity/TileEntityChest.java index b85965f..d426c7c 100755 --- a/common/src/common/tileentity/TileEntityChest.java +++ b/common/src/common/tileentity/TileEntityChest.java @@ -1,7 +1,7 @@ package common.tileentity; import common.block.Block; -import common.block.BlockChest; +import common.block.tech.BlockChest; import common.entity.npc.EntityNPC; import common.init.SoundEvent; import common.inventory.Container; diff --git a/common/src/common/tileentity/TileEntityDaylightDetector.java b/common/src/common/tileentity/TileEntityDaylightDetector.java index a3518e2..6355815 100755 --- a/common/src/common/tileentity/TileEntityDaylightDetector.java +++ b/common/src/common/tileentity/TileEntityDaylightDetector.java @@ -1,6 +1,6 @@ package common.tileentity; -import common.block.BlockDaylightDetector; +import common.block.tech.BlockDaylightDetector; import common.world.AWorldServer; public class TileEntityDaylightDetector extends TileEntity implements ITickable diff --git a/common/src/common/tileentity/TileEntityFurnace.java b/common/src/common/tileentity/TileEntityFurnace.java index af1c0f3..2f3a1f6 100755 --- a/common/src/common/tileentity/TileEntityFurnace.java +++ b/common/src/common/tileentity/TileEntityFurnace.java @@ -1,9 +1,9 @@ package common.tileentity; import common.block.Block; -import common.block.BlockFurnace; -import common.block.BlockSapling; -import common.block.BlockSlab; +import common.block.artificial.BlockSlab; +import common.block.foliage.BlockSapling; +import common.block.tech.BlockFurnace; import common.entity.npc.EntityNPC; import common.init.Blocks; import common.init.Items; diff --git a/common/src/common/tileentity/TileEntityHopper.java b/common/src/common/tileentity/TileEntityHopper.java index 60db278..4667f09 100755 --- a/common/src/common/tileentity/TileEntityHopper.java +++ b/common/src/common/tileentity/TileEntityHopper.java @@ -4,8 +4,8 @@ import java.util.List; import java.util.function.Predicate; import common.block.Block; -import common.block.BlockChest; -import common.block.BlockHopper; +import common.block.tech.BlockChest; +import common.block.tech.BlockHopper; import common.entity.Entity; import common.entity.item.EntityItem; import common.entity.npc.EntityNPC; diff --git a/common/src/common/tileentity/TileEntityNote.java b/common/src/common/tileentity/TileEntityNote.java index 214d94c..092fe9e 100755 --- a/common/src/common/tileentity/TileEntityNote.java +++ b/common/src/common/tileentity/TileEntityNote.java @@ -1,7 +1,6 @@ package common.tileentity; import common.init.Blocks; -import common.material.Material; import common.nbt.NBTTagCompound; import common.util.BlockPos; import common.util.ExtMath; @@ -39,7 +38,7 @@ public class TileEntityNote extends TileEntity public void triggerNote(World worldIn, BlockPos p_175108_2_) { - if (worldIn.getState(p_175108_2_.up()).getBlock().getMaterial() == Material.air) + if (worldIn.getState(p_175108_2_.up()).getBlock() == Blocks.air) { // Material material = worldIn.getBlockState(p_175108_2_.down()).getBlock().getMaterial(); // int i = 0; diff --git a/common/src/common/village/Village.java b/common/src/common/village/Village.java index 7ecc458..4a805dc 100755 --- a/common/src/common/village/Village.java +++ b/common/src/common/village/Village.java @@ -4,7 +4,7 @@ import java.util.Iterator; import java.util.List; import common.block.Block; -import common.block.BlockDoor; +import common.block.artificial.BlockDoor; import common.collect.Lists; import common.material.Material; import common.nbt.NBTTagCompound; diff --git a/common/src/common/world/Chunk.java b/common/src/common/world/Chunk.java index 3210d9f..16af85a 100755 --- a/common/src/common/world/Chunk.java +++ b/common/src/common/world/Chunk.java @@ -718,7 +718,7 @@ public abstract class Chunk { BlockArray arr = this.getArray(s); if(arr == null && edge || arr != null - && arr.getBlock(x, y, z).getMaterial() == Material.air) { + && arr.getBlock(x, y, z) == Blocks.air) { for(Facing face : Facing.values()) { BlockPos side = block.offset(face); diff --git a/common/src/common/world/Explosion.java b/common/src/common/world/Explosion.java index f3c1e2f..04e5166 100755 --- a/common/src/common/world/Explosion.java +++ b/common/src/common/world/Explosion.java @@ -17,7 +17,6 @@ import common.entity.types.EntityLiving; import common.init.Blocks; import common.init.Config; import common.init.SoundEvent; -import common.material.Material; import common.model.ParticleType; import common.rng.Random; import common.util.BlockPos; @@ -97,7 +96,7 @@ public class Explosion BlockPos blockpos = new BlockPos(d4, d6, d8); State iblockstate = this.worldObj.getState(blockpos); - if (iblockstate.getBlock().getMaterial() != Material.air) + if (iblockstate.getBlock() != Blocks.air) { float f2 = this.exploder != null ? this.exploder.getExplosionResistance(this, this.worldObj, blockpos, iblockstate) : iblockstate.getBlock().getExplosionResistance((Entity)null); f -= (f2 + 0.3F) * 0.3F; @@ -136,7 +135,7 @@ public class Explosion State iblockstate = this.worldObj.getState(blockpos); float f = this.explosionSize; // * (0.7F + this.worldObj.rand.nextFloat() * 0.6F); - if (iblockstate.getBlock().getMaterial() != Material.air) + if (iblockstate.getBlock() != Blocks.air) { float f2 = this.exploder != null ? this.exploder.getExplosionResistance(this, this.worldObj, blockpos, iblockstate) : iblockstate.getBlock().getExplosionResistance((Entity)null); f -= (f2 + 0.3F) * 0.3F; @@ -168,7 +167,7 @@ public class Explosion (dist < explosionSize && rand.doublev() + ((dist - (explosionSize - falloff)) / falloff) < 1.0d))) { BlockPos blockpos = new BlockPos(explosionX + x, explosionY + y, explosionZ + z); State iblockstate = worldObj.getState(blockpos); - if(iblockstate.getBlock().getMaterial() != Material.air && iblockstate.getBlock().getExplosionResistance(null) < 60000.0f) { + if(iblockstate.getBlock() != Blocks.air && iblockstate.getBlock().getExplosionResistance(null) < 60000.0f) { worldObj.setState(blockpos, Blocks.air.getState(), 3); if(rand.chance(1000)) { worldObj.playSound(SoundEvent.EXPLODE, explosionX + x, explosionY + y, explosionZ + z, 4.0F); @@ -306,7 +305,7 @@ public class Explosion this.worldObj.spawnParticle(ParticleType.SMOKE_NORMAL, d0, d1, d2, d3, d4, d5); } - if (block.getMaterial() != Material.air) + if (block != Blocks.air) { if (block.canDropFromExplosion(this)) { @@ -323,7 +322,7 @@ public class Explosion { for (BlockPos blockpos1 : this.affectedBlockPositions) { - if (this.worldObj.getState(blockpos1).getBlock().getMaterial() == Material.air && this.worldObj.getState(blockpos1.down()).getBlock().isFullBlock() && this.explosionRNG.zrange(3) == 0) + if (this.worldObj.getState(blockpos1).getBlock() == Blocks.air && this.worldObj.getState(blockpos1.down()).getBlock().isFullBlock() && this.explosionRNG.zrange(3) == 0) { this.worldObj.setState(blockpos1, Blocks.fire.getState()); } diff --git a/common/src/common/world/World.java b/common/src/common/world/World.java index 66e66ce..42a7f98 100755 --- a/common/src/common/world/World.java +++ b/common/src/common/world/World.java @@ -8,12 +8,12 @@ import java.util.function.Predicate; import common.biome.Biome; import common.block.Block; -import common.block.BlockHopper; -import common.block.BlockLiquid; -import common.block.BlockSlab; -import common.block.BlockSnow; -import common.block.BlockStairs; -import common.block.LeavesType; +import common.block.artificial.BlockSlab; +import common.block.artificial.BlockStairs; +import common.block.foliage.LeavesType; +import common.block.liquid.BlockLiquid; +import common.block.natural.BlockSnow; +import common.block.tech.BlockHopper; import common.collect.Lists; import common.collect.Sets; import common.dimension.Dimension; @@ -136,7 +136,7 @@ public abstract class World implements IWorldAccess { public abstract Biome getBiomeGenForCoords(BlockPos pos); public boolean isAirBlock(BlockPos pos) { - return this.getState(pos).getBlock().getMaterial() == Material.air; + return this.getState(pos).getBlock() == Blocks.air; } public boolean isBlockLoaded(BlockPos pos) { @@ -249,7 +249,7 @@ public abstract class World implements IWorldAccess { State iblockstate = this.getState(pos); Block block = iblockstate.getBlock(); - if(block.getMaterial() == Material.air) { + if(block == Blocks.air) { return false; } else { @@ -1589,7 +1589,7 @@ public abstract class World implements IWorldAccess { if(pos.getY() >= -MAX_SIZE_Y && pos.getY() < MAX_SIZE_Y && this.getLightFor(LightType.BLOCK, pos) < 10) { Block block = this.getState(pos).getBlock(); - if((block.getMaterial() == Material.air || (allowLayers && block == Blocks.snow_layer)) + if((block == Blocks.air || (allowLayers && block == Blocks.snow_layer)) && Blocks.snow_layer.canPlaceBlockAt(this, pos)) { return true; } diff --git a/server/src/server/biome/BiomeBlackened.java b/server/src/server/biome/BiomeBlackened.java index f03f41f..04383c2 100644 --- a/server/src/server/biome/BiomeBlackened.java +++ b/server/src/server/biome/BiomeBlackened.java @@ -1,7 +1,7 @@ package server.biome; import common.biome.Biome; -import common.block.BlockFlower; +import common.block.foliage.BlockFlower; import common.entity.npc.EntityMetalhead; import common.init.Blocks; import common.rng.Random; diff --git a/server/src/server/biome/BiomeForest.java b/server/src/server/biome/BiomeForest.java index c0ecc14..7d3d03b 100755 --- a/server/src/server/biome/BiomeForest.java +++ b/server/src/server/biome/BiomeForest.java @@ -1,8 +1,8 @@ package server.biome; import common.biome.Biome; -import common.block.BlockDoublePlant; -import common.block.BlockFlower; +import common.block.foliage.BlockDoublePlant; +import common.block.foliage.BlockFlower; import common.entity.animal.EntityWolf; import common.entity.npc.EntityElf; import common.entity.npc.EntityWoodElf; diff --git a/server/src/server/biome/BiomeJungle.java b/server/src/server/biome/BiomeJungle.java index e871913..34faff3 100755 --- a/server/src/server/biome/BiomeJungle.java +++ b/server/src/server/biome/BiomeJungle.java @@ -1,7 +1,7 @@ package server.biome; import common.biome.Biome; -import common.block.BlockTallGrass; +import common.block.foliage.BlockTallGrass; import common.entity.animal.EntityChicken; import common.entity.animal.EntityOcelot; import common.init.Blocks; diff --git a/server/src/server/biome/BiomeMesa.java b/server/src/server/biome/BiomeMesa.java index 6651be2..19251d3 100755 --- a/server/src/server/biome/BiomeMesa.java +++ b/server/src/server/biome/BiomeMesa.java @@ -5,11 +5,10 @@ import java.util.Arrays; import common.biome.Biome; import common.block.Block; import common.block.BlockColored; -import common.block.BlockDirt; -import common.block.BlockSand; +import common.block.natural.BlockDirt; +import common.block.natural.BlockSand; import common.color.DyeColor; import common.init.Blocks; -import common.material.Material; import common.rng.PerlinGen; import common.rng.Random; import common.rng.WeightedList; @@ -122,7 +121,7 @@ public class BiomeMesa extends GenBiome for (int i1 = chunkPrimerIn.height - 1; i1 >= 0; --i1) { - if (chunkPrimerIn.get(k1, i1, j1).getBlock().getMaterial() == Material.air && i1 < (int)d4) + if (chunkPrimerIn.get(k1, i1, j1).getBlock() == Blocks.air && i1 < (int)d4) { chunkPrimerIn.set(k1, i1, j1, worldState); } @@ -135,7 +134,7 @@ public class BiomeMesa extends GenBiome // { State iblockstate1 = chunkPrimerIn.get(k1, i1, j1); - if (iblockstate1.getBlock().getMaterial() == Material.air) + if (iblockstate1.getBlock() == Blocks.air) { l = -1; } @@ -156,7 +155,7 @@ public class BiomeMesa extends GenBiome iblockstate3 = this.fillerBlock; } - if (i1 < l1 && (iblockstate == null || iblockstate.getBlock().getMaterial() == Material.air)) + if (i1 < l1 && (iblockstate == null || iblockstate.getBlock() == Blocks.air)) { iblockstate = liquid; } diff --git a/server/src/server/biome/BiomePlains.java b/server/src/server/biome/BiomePlains.java index 2732ac8..15a969a 100755 --- a/server/src/server/biome/BiomePlains.java +++ b/server/src/server/biome/BiomePlains.java @@ -1,8 +1,8 @@ package server.biome; import common.biome.Biome; -import common.block.BlockDoublePlant; -import common.block.BlockFlower; +import common.block.foliage.BlockDoublePlant; +import common.block.foliage.BlockFlower; import common.entity.animal.EntityHorse; import common.rng.Random; import common.util.BlockPos; diff --git a/server/src/server/biome/BiomeSavanna.java b/server/src/server/biome/BiomeSavanna.java index 1063529..f2124ae 100755 --- a/server/src/server/biome/BiomeSavanna.java +++ b/server/src/server/biome/BiomeSavanna.java @@ -1,8 +1,8 @@ package server.biome; import common.biome.Biome; -import common.block.BlockDirt; -import common.block.BlockDoublePlant; +import common.block.foliage.BlockDoublePlant; +import common.block.natural.BlockDirt; import common.entity.animal.EntityHorse; import common.init.Blocks; import common.rng.Random; diff --git a/server/src/server/biome/BiomeSpace.java b/server/src/server/biome/BiomeSpace.java index 93f8d1f..b83c9de 100755 --- a/server/src/server/biome/BiomeSpace.java +++ b/server/src/server/biome/BiomeSpace.java @@ -1,7 +1,7 @@ package server.biome; import common.biome.Biome; -import common.block.BlockDirt; +import common.block.natural.BlockDirt; import common.init.Blocks; import common.rng.Random; import common.rng.WeightedList; diff --git a/server/src/server/biome/BiomeSwamp.java b/server/src/server/biome/BiomeSwamp.java index eb5cdd0..9c3854d 100755 --- a/server/src/server/biome/BiomeSwamp.java +++ b/server/src/server/biome/BiomeSwamp.java @@ -2,10 +2,9 @@ package server.biome; import common.biome.Biome; import common.block.BlockDirectional; -import common.block.BlockFlower; +import common.block.foliage.BlockFlower; import common.entity.npc.EntitySlime; import common.init.Blocks; -import common.material.Material; import common.rng.Random; import common.util.BlockPos; import common.util.Facing; @@ -53,7 +52,7 @@ public class BiomeSwamp extends GenBiome for (int k = chunkPrimerIn.height - 1; k >= 0; --k) { - if (chunkPrimerIn.get(j, k, i).getBlock().getMaterial() != Material.air) + if (chunkPrimerIn.get(j, k, i).getBlock() != Blocks.air) { if (k == 62 && chunkPrimerIn.get(j, k, i).getBlock() != Blocks.water) { diff --git a/server/src/server/biome/BiomeTaiga.java b/server/src/server/biome/BiomeTaiga.java index d7a9c5f..97812ff 100755 --- a/server/src/server/biome/BiomeTaiga.java +++ b/server/src/server/biome/BiomeTaiga.java @@ -1,9 +1,9 @@ package server.biome; import common.biome.Biome; -import common.block.BlockDirt; -import common.block.BlockDoublePlant; -import common.block.BlockTallGrass; +import common.block.foliage.BlockDoublePlant; +import common.block.foliage.BlockTallGrass; +import common.block.natural.BlockDirt; import common.entity.animal.EntityWolf; import common.init.Blocks; import common.rng.Random; diff --git a/server/src/server/biome/BiomeTian.java b/server/src/server/biome/BiomeTian.java index 58c7d45..021a972 100755 --- a/server/src/server/biome/BiomeTian.java +++ b/server/src/server/biome/BiomeTian.java @@ -1,7 +1,7 @@ package server.biome; import common.biome.Biome; -import common.block.BlockFlower; +import common.block.foliage.BlockFlower; import common.entity.animal.EntityBat; import common.entity.animal.EntityMouse; import common.entity.animal.EntityRabbit; diff --git a/server/src/server/biome/GenBiome.java b/server/src/server/biome/GenBiome.java index 825b630..4878746 100755 --- a/server/src/server/biome/GenBiome.java +++ b/server/src/server/biome/GenBiome.java @@ -4,10 +4,10 @@ import common.biome.Biome; import common.biome.IBiome; import common.block.Block; import common.block.BlockColored; -import common.block.BlockFlower; -import common.block.BlockSand; -import common.block.BlockSapling; -import common.block.BlockTallGrass; +import common.block.foliage.BlockFlower; +import common.block.foliage.BlockSapling; +import common.block.foliage.BlockTallGrass; +import common.block.natural.BlockSand; import common.color.DyeColor; import common.entity.animal.EntityBat; import common.entity.animal.EntityChicken; @@ -368,7 +368,7 @@ public abstract class GenBiome implements IBiome { BlockFlower.EnumFlowerType blockflower$enumflowertype = this.pickRandomFlower(rand, blockpos1); BlockFlower blockflower = blockflower$enumflowertype.getBlockType().getBlock(); - if (blockflower.getMaterial() != Material.air) + if (blockflower != Blocks.air) { this.yellowFlowerGen.setGeneratedBlock(blockflower, blockflower$enumflowertype); this.yellowFlowerGen.generate(world, rand, blockpos1); @@ -567,7 +567,7 @@ public abstract class GenBiome implements IBiome { { State iblockstate2 = chunkPrimerIn.get(i1, j1, l); - if (iblockstate2.getBlock().getMaterial() == Material.air) + if (iblockstate2.getBlock() == Blocks.air) { j = -1; } @@ -586,7 +586,7 @@ public abstract class GenBiome implements IBiome { iblockstate1 = this.fillerBlock; } - if (j1 < i && (iblockstate == null || iblockstate.getBlock().getMaterial() == Material.air)) + if (j1 < i && (iblockstate == null || iblockstate.getBlock() == Blocks.air)) { if (freeze && World.ABSOLUTE_ZERO + worldIn.getTempOffset() + this.base.getTemperature(blockpos$mutableblockpos.set(x, j1, z)) <= 0.0F) { @@ -813,7 +813,7 @@ public abstract class GenBiome implements IBiome { { if (j >= i / 16) { - if (worldIn.getState(blockpos1).getBlock().getMaterial() == Material.air) + if (worldIn.getState(blockpos1).getBlock() == Blocks.air) { if (rand.chance(8)) { diff --git a/server/src/server/clipboard/ClipboardPlacer.java b/server/src/server/clipboard/ClipboardPlacer.java index e8239d1..f69acfa 100755 --- a/server/src/server/clipboard/ClipboardPlacer.java +++ b/server/src/server/clipboard/ClipboardPlacer.java @@ -9,9 +9,9 @@ import java.util.Map; import java.util.Set; import common.block.Block; -import common.block.BlockDoor; -import common.block.BlockRailBase; import common.block.ITileEntityProvider; +import common.block.artificial.BlockDoor; +import common.block.tech.BlockRailBase; import common.collect.Lists; import common.init.Blocks; import common.inventory.IInventory; diff --git a/server/src/server/clipboard/ReorderRegistry.java b/server/src/server/clipboard/ReorderRegistry.java index 4f346ec..3040b08 100755 --- a/server/src/server/clipboard/ReorderRegistry.java +++ b/server/src/server/clipboard/ReorderRegistry.java @@ -6,8 +6,8 @@ import java.util.Map; import java.util.Set; import common.block.Block; -import common.block.BlockBed; -import common.block.BlockDoor; +import common.block.artificial.BlockBed; +import common.block.artificial.BlockDoor; import common.color.DyeColor; import common.init.BlockRegistry; import common.init.Blocks; diff --git a/server/src/server/clipboard/RotationRegistry.java b/server/src/server/clipboard/RotationRegistry.java index 38bc0c7..6212c0d 100755 --- a/server/src/server/clipboard/RotationRegistry.java +++ b/server/src/server/clipboard/RotationRegistry.java @@ -6,16 +6,16 @@ import java.util.Map; import java.util.function.Predicate; import common.block.Block; -import common.block.BlockDoor; -import common.block.BlockLever; -import common.block.BlockLog; -import common.block.BlockPortal; -import common.block.BlockQuartz; -import common.block.BlockRail; -import common.block.BlockRailBase; -import common.block.BlockRailDetector; -import common.block.BlockRailPowered; import common.block.BlockRotatedPillar; +import common.block.artificial.BlockDoor; +import common.block.artificial.BlockPortal; +import common.block.artificial.BlockQuartz; +import common.block.foliage.BlockLog; +import common.block.tech.BlockLever; +import common.block.tech.BlockRail; +import common.block.tech.BlockRailBase; +import common.block.tech.BlockRailDetector; +import common.block.tech.BlockRailPowered; import common.collect.Lists; import common.collect.Maps; import common.properties.IProperty; diff --git a/server/src/server/network/Player.java b/server/src/server/network/Player.java index 2429ab0..d1ca5d4 100755 --- a/server/src/server/network/Player.java +++ b/server/src/server/network/Player.java @@ -8,9 +8,9 @@ import java.util.Set; import java.util.function.Predicate; import common.block.Block; -import common.block.BlockFence; -import common.block.BlockFenceGate; -import common.block.BlockWall; +import common.block.artificial.BlockFence; +import common.block.artificial.BlockFenceGate; +import common.block.artificial.BlockWall; import common.collect.Lists; import common.color.TextColor; import common.dimension.Dimension; @@ -26,6 +26,7 @@ import common.entity.projectile.EntityArrow; import common.entity.types.EntityLiving; import common.future.Futures; import common.init.BlockRegistry; +import common.init.Blocks; import common.init.Config; import common.init.EntityRegistry; import common.init.Items; @@ -45,7 +46,6 @@ import common.item.ItemArmor; import common.item.ItemControl; import common.item.ItemStack; import common.log.Log; -import common.material.Material; import common.nbt.NBTTagCompound; import common.nbt.NBTTagList; import common.network.IPlayer; @@ -395,7 +395,7 @@ public class Player extends NetHandler implements ICrafting, Executor, IPlayer BlockPos blockpos = new BlockPos(i, j, k); Block block = this.entity.worldObj.getState(blockpos).getBlock(); - if (block.getMaterial() == Material.air) + if (block == Blocks.air) { Block block1 = this.entity.worldObj.getState(blockpos.down()).getBlock(); @@ -1106,7 +1106,7 @@ public class Player extends NetHandler implements ICrafting, Executor, IPlayer int i = this.curblockDamage - this.initialBlockDamage; Block block = this.entity.worldObj.getState(this.removingPos).getBlock(); - if (block.getMaterial() == Material.air) + if (block == Blocks.air) { this.receivedFinishDiggingPacket = false; } @@ -1132,7 +1132,7 @@ public class Player extends NetHandler implements ICrafting, Executor, IPlayer { Block block1 = this.entity.worldObj.getState(this.startPos).getBlock(); - if (block1.getMaterial() == Material.air) + if (block1 == Blocks.air) { this.entity.worldObj.sendBlockBreakProgress(this.entity.getId(), this.startPos, -1); this.durabilityRemainingOnBlock = -1; @@ -1175,13 +1175,13 @@ public class Player extends NetHandler implements ICrafting, Executor, IPlayer this.initialDamage = this.curblockDamage; float f = 1.0F; - if (block.getMaterial() != Material.air) + if (block != Blocks.air) { block.onBlockClicked(this.entity.worldObj, pos, this.entity); f = block.getPlayerRelativeBlockHardness(this.entity, this.entity.worldObj, pos); } - if (block.getMaterial() != Material.air && f >= 1.0F) + if (block != Blocks.air && f >= 1.0F) { this.tryHarvestBlock(pos); } @@ -1203,7 +1203,7 @@ public class Player extends NetHandler implements ICrafting, Executor, IPlayer int i = this.curblockDamage - this.initialDamage; Block block = this.entity.worldObj.getState(pos).getBlock(); - if (block.getMaterial() != Material.air) + if (block != Blocks.air) { float f = block.getPlayerRelativeBlockHardness(this.entity, this.entity.worldObj, pos) * (float)(i + 1); @@ -2399,7 +2399,7 @@ public class Player extends NetHandler implements ICrafting, Executor, IPlayer this.cancelDestroyingBlock(); } - if (worldserver.getState(blockpos).getBlock().getMaterial() != Material.air) + if (worldserver.getState(blockpos).getBlock() != Blocks.air) { this.sendPacket(new SPacketBlockChange(worldserver, blockpos)); } diff --git a/server/src/server/village/VillageCollection.java b/server/src/server/village/VillageCollection.java index 53ad125..59c9ccb 100755 --- a/server/src/server/village/VillageCollection.java +++ b/server/src/server/village/VillageCollection.java @@ -4,7 +4,7 @@ import java.util.Iterator; import java.util.List; import common.block.Block; -import common.block.BlockDoor; +import common.block.artificial.BlockDoor; import common.collect.Lists; import common.material.Material; import common.nbt.NBTTagCompound; diff --git a/common/src/common/block/BlockEventData.java b/server/src/server/world/BlockEventData.java similarity index 96% rename from common/src/common/block/BlockEventData.java rename to server/src/server/world/BlockEventData.java index e8fdcf4..9ab6c8f 100755 --- a/common/src/common/block/BlockEventData.java +++ b/server/src/server/world/BlockEventData.java @@ -1,5 +1,6 @@ -package common.block; +package server.world; +import common.block.Block; import common.util.BlockPos; public class BlockEventData diff --git a/server/src/server/world/ChunkServer.java b/server/src/server/world/ChunkServer.java index 675ec10..98ceb4d 100644 --- a/server/src/server/world/ChunkServer.java +++ b/server/src/server/world/ChunkServer.java @@ -8,7 +8,6 @@ import common.entity.Entity; import common.init.BlockRegistry; import common.init.Blocks; import common.log.Log; -import common.material.Material; import common.rng.Random; import common.tileentity.TileEntity; import common.util.BlockPos; @@ -33,7 +32,7 @@ public class ChunkServer extends Chunk { for(int bz = 0; bz < 16; ++bz) { for(int by = 0; by < height; ++by) { State state = BlockRegistry.STATEMAP.getByValue(data[bx << 4 | bz | by << 8]); - if(state != null && state.getBlock().getMaterial() != Material.air) { + if(state != null && state.getBlock() != Blocks.air) { int y = by >> 4; BlockArray arr = this.getArray(y); if(arr == null) { diff --git a/server/src/server/world/Converter.java b/server/src/server/world/Converter.java index d5f31c0..360288e 100644 --- a/server/src/server/world/Converter.java +++ b/server/src/server/world/Converter.java @@ -17,30 +17,30 @@ import java.util.zip.InflaterInputStream; import common.biome.Biome; import common.block.Block; -import common.block.BlockCactus; -import common.block.BlockCarpet; import common.block.BlockColored; -import common.block.BlockDirt; -import common.block.BlockFire; -import common.block.BlockFlower; -import common.block.BlockFlowerPot; -import common.block.BlockLeaves; -import common.block.BlockLiquid; -import common.block.BlockLog; -import common.block.BlockPistonBase; -import common.block.BlockPistonHead; -import common.block.BlockQuartz; -import common.block.BlockRock; -import common.block.BlockSand; -import common.block.BlockSandStone; -import common.block.BlockSlab; -import common.block.BlockStainedGlass; -import common.block.BlockStainedGlassPane; -import common.block.BlockStoneBrick; -import common.block.BlockTNT; -import common.block.BlockTallGrass; -import common.block.BlockWall; -import common.block.LeavesType; +import common.block.artificial.BlockCarpet; +import common.block.artificial.BlockFlowerPot; +import common.block.artificial.BlockQuartz; +import common.block.artificial.BlockSlab; +import common.block.artificial.BlockStainedGlass; +import common.block.artificial.BlockStainedGlassPane; +import common.block.artificial.BlockStoneBrick; +import common.block.artificial.BlockWall; +import common.block.foliage.BlockCactus; +import common.block.foliage.BlockFlower; +import common.block.foliage.BlockLeaves; +import common.block.foliage.BlockLog; +import common.block.foliage.BlockTallGrass; +import common.block.foliage.LeavesType; +import common.block.liquid.BlockLiquid; +import common.block.natural.BlockDirt; +import common.block.natural.BlockFire; +import common.block.natural.BlockRock; +import common.block.natural.BlockSand; +import common.block.natural.BlockSandStone; +import common.block.tech.BlockPistonBase; +import common.block.tech.BlockPistonHead; +import common.block.tech.BlockTNT; import common.collect.Maps; import common.color.DyeColor; import common.entity.Entity; diff --git a/server/src/server/world/WorldServer.java b/server/src/server/world/WorldServer.java index 7808ed8..6c9f485 100755 --- a/server/src/server/world/WorldServer.java +++ b/server/src/server/world/WorldServer.java @@ -15,11 +15,10 @@ import java.util.function.Predicate; import common.biome.Biome; import common.block.Block; -import common.block.BlockDoor; -import common.block.BlockEventData; import common.block.BlockFalling; -import common.block.BlockLiquid; -import common.block.BlockSnow; +import common.block.artificial.BlockDoor; +import common.block.liquid.BlockLiquid; +import common.block.natural.BlockSnow; import common.collect.Lists; import common.collect.Maps; import common.collect.Sets; @@ -764,14 +763,14 @@ public final class WorldServer extends AWorldServer { NextTickListEntry nextticklistentry = new NextTickListEntry(pos, blockIn); int i = 0; - if(this.updateForced && blockIn.getMaterial() != Material.air) { + if(this.updateForced && blockIn != Blocks.air) { if(blockIn.requiresUpdates()) { i = 8; if(this.isAreaLoaded(nextticklistentry.position.add(-i, -i, -i), nextticklistentry.position.add(i, i, i))) { State iblockstate = this.getState(nextticklistentry.position); - if(iblockstate.getBlock().getMaterial() != Material.air && iblockstate.getBlock() == nextticklistentry.getBlock()) { + if(iblockstate.getBlock() != Blocks.air && iblockstate.getBlock() == nextticklistentry.getBlock()) { iblockstate.getBlock().updateTick(this, nextticklistentry.position, iblockstate, this.rand); } } @@ -783,7 +782,7 @@ public final class WorldServer extends AWorldServer { } if(this.isAreaLoaded(pos.add(-i, -i, -i), pos.add(i, i, i))) { - if(blockIn.getMaterial() != Material.air) { + if(blockIn != Blocks.air) { nextticklistentry.setScheduledTime((long)delay + this.time); nextticklistentry.setPriority(priority); } @@ -799,7 +798,7 @@ public final class WorldServer extends AWorldServer { NextTickListEntry nextticklistentry = new NextTickListEntry(pos, blockIn); nextticklistentry.setPriority(priority); - if(blockIn.getMaterial() != Material.air) { + if(blockIn != Blocks.air) { nextticklistentry.setScheduledTime((long)delay + this.time); } @@ -871,7 +870,7 @@ public final class WorldServer extends AWorldServer { if(this.isAreaLoaded(nextticklistentry1.position.add(-k, -k, -k), nextticklistentry1.position.add(k, k, k))) { State iblockstate = this.getState(nextticklistentry1.position); - if(iblockstate.getBlock().getMaterial() != Material.air + if(iblockstate.getBlock() != Blocks.air && Block.isEqualTo(iblockstate.getBlock(), nextticklistentry1.getBlock())) { iblockstate.getBlock().updateTick(this, nextticklistentry1.position, iblockstate, this.rand); } @@ -1140,11 +1139,11 @@ public final class WorldServer extends AWorldServer { if(fire && Config.fire) { BlockPos pos = new BlockPos(entity); if(this.isAreaLoaded(pos, 10)) { - if(this.getState(pos).getBlock().getMaterial() == Material.air && Blocks.fire.canPlaceBlockAt(this, pos)) + if(this.getState(pos).getBlock() == Blocks.air && Blocks.fire.canPlaceBlockAt(this, pos)) this.setState(pos, Blocks.fire.getState()); for(int n = 0; n < 4; n++) { BlockPos extra = pos.add(this.rand.range(-1, 1), this.rand.range(-1, 1), this.rand.range(-1, 1)); - if(this.getState(extra).getBlock().getMaterial() == Material.air && Blocks.fire.canPlaceBlockAt(this, extra)) + if(this.getState(extra).getBlock() == Blocks.air && Blocks.fire.canPlaceBlockAt(this, extra)) this.setState(extra, Blocks.fire.getState()); } } @@ -2360,7 +2359,7 @@ public final class WorldServer extends AWorldServer { if(pos.getY() >= -World.MAX_SIZE_Y && pos.getY() < World.MAX_SIZE_Y) { Block block = this.getState(pos).getBlock(); - if(block.getMaterial() == Material.air && Blocks.fire.canPlaceBlockAt(this, pos)) { + if(block == Blocks.air && Blocks.fire.canPlaceBlockAt(this, pos)) { return true; } } @@ -2411,7 +2410,7 @@ public final class WorldServer extends AWorldServer { for(int i2 = i1; i2 <= j1; ++i2) { Block block = this.getState(blockpos$mutableblockpos.set(k1, l1, i2)).getBlock(); - if(block.getMaterial() != Material.air) { + if(block != Blocks.air) { return true; } } diff --git a/server/src/server/worldgen/FeatureLiquids.java b/server/src/server/worldgen/FeatureLiquids.java index ff0a1e8..69f5871 100755 --- a/server/src/server/worldgen/FeatureLiquids.java +++ b/server/src/server/worldgen/FeatureLiquids.java @@ -1,7 +1,7 @@ package server.worldgen; import common.block.Block; -import common.material.Material; +import common.init.Blocks; import common.rng.Random; import common.util.BlockPos; import common.world.State; @@ -66,7 +66,7 @@ public class FeatureLiquids { return false; } - else if (worldIn.getState(position).getBlock().getMaterial() != Material.air && worldIn.getState(position).getBlock() != replace) + else if (worldIn.getState(position).getBlock() != Blocks.air && worldIn.getState(position).getBlock() != replace) { return false; } diff --git a/server/src/server/worldgen/ReplacerAltSurface.java b/server/src/server/worldgen/ReplacerAltSurface.java index 23043ac..e3daac1 100755 --- a/server/src/server/worldgen/ReplacerAltSurface.java +++ b/server/src/server/worldgen/ReplacerAltSurface.java @@ -2,7 +2,7 @@ package server.worldgen; import common.biome.Biome; import common.block.Block; -import common.material.Material; +import common.init.Blocks; import common.rng.OctaveGen; import common.rng.Random; import common.world.State; @@ -63,7 +63,7 @@ public class ReplacerAltSurface implements BlockReplacer // { State iblockstate2 = primer.get(k, j1, j); - if (iblockstate2.getBlock() != null && iblockstate2.getBlock().getMaterial() != Material.air) + if (iblockstate2.getBlock() != Blocks.air) { if (iblockstate2.getBlock() == this.fillerBlock) { @@ -92,7 +92,7 @@ public class ReplacerAltSurface implements BlockReplacer } } - if (j1 < i && (iblockstate == null || iblockstate.getBlock().getMaterial() == Material.air)) + if (j1 < i && (iblockstate == null || iblockstate.getBlock() == Blocks.air)) { iblockstate = this.liquid; } diff --git a/server/src/server/worldgen/ReplacerTopLayer.java b/server/src/server/worldgen/ReplacerTopLayer.java index 8514527..5f2a52c 100755 --- a/server/src/server/worldgen/ReplacerTopLayer.java +++ b/server/src/server/worldgen/ReplacerTopLayer.java @@ -3,7 +3,6 @@ package server.worldgen; import common.biome.Biome; import common.block.Block; import common.init.Blocks; -import common.material.Material; import common.rng.Random; import common.world.State; import server.world.WorldServer; @@ -37,7 +36,7 @@ public class ReplacerTopLayer implements BlockReplacer { State iblockstate2 = primer.get(i, i1, j); - if (iblockstate2.getBlock().getMaterial() == Material.air) + if (iblockstate2.getBlock() == Blocks.air) { l = -1; } diff --git a/server/src/server/worldgen/caves/MapGenCaves.java b/server/src/server/worldgen/caves/MapGenCaves.java index 18346a0..c3c67d4 100755 --- a/server/src/server/worldgen/caves/MapGenCaves.java +++ b/server/src/server/worldgen/caves/MapGenCaves.java @@ -2,7 +2,7 @@ package server.worldgen.caves; import common.block.Block; import common.block.BlockColored; -import common.block.BlockSand; +import common.block.natural.BlockSand; import common.color.DyeColor; import common.init.Blocks; import common.rng.Random; diff --git a/server/src/server/worldgen/feature/WorldGenAbandonedChest.java b/server/src/server/worldgen/feature/WorldGenAbandonedChest.java index 88b69b0..c71efea 100755 --- a/server/src/server/worldgen/feature/WorldGenAbandonedChest.java +++ b/server/src/server/worldgen/feature/WorldGenAbandonedChest.java @@ -33,7 +33,7 @@ public class WorldGenAbandonedChest extends FeatureGenerator public boolean generate(WorldServer worldIn, Random rand, BlockPos position) { Block block; - while (((block = worldIn.getState(position).getBlock()).getMaterial() == Material.air || block.getMaterial() == Material.leaves) && position.getY() > 1) + while (((block = worldIn.getState(position).getBlock()) == Blocks.air || block.getMaterial() == Material.leaves) && position.getY() > 1) { position = position.down(); } diff --git a/server/src/server/worldgen/feature/WorldGenDesertWells.java b/server/src/server/worldgen/feature/WorldGenDesertWells.java index 2fbe7f9..90b0636 100755 --- a/server/src/server/worldgen/feature/WorldGenDesertWells.java +++ b/server/src/server/worldgen/feature/WorldGenDesertWells.java @@ -1,7 +1,7 @@ package server.worldgen.feature; -import common.block.BlockSand; -import common.block.BlockSlab; +import common.block.artificial.BlockSlab; +import common.block.natural.BlockSand; import common.init.Blocks; import common.rng.Random; import common.util.BlockPos; diff --git a/server/src/server/worldgen/feature/WorldGenGlowStone.java b/server/src/server/worldgen/feature/WorldGenGlowStone.java index 9e99c29..951ece1 100755 --- a/server/src/server/worldgen/feature/WorldGenGlowStone.java +++ b/server/src/server/worldgen/feature/WorldGenGlowStone.java @@ -1,7 +1,6 @@ package server.worldgen.feature; import common.init.Blocks; -import common.material.Material; import common.rng.Random; import common.util.BlockPos; import common.util.Facing; @@ -28,7 +27,7 @@ public class WorldGenGlowStone extends FeatureGenerator { BlockPos blockpos = position.add(rand.zrange(8) - rand.zrange(8), -rand.zrange(12), rand.zrange(8) - rand.zrange(8)); - if (worldIn.getState(blockpos).getBlock().getMaterial() == Material.air) + if (worldIn.getState(blockpos).getBlock() == Blocks.air) { int j = 0; diff --git a/server/src/server/worldgen/feature/WorldGenHellLava.java b/server/src/server/worldgen/feature/WorldGenHellLava.java index 9932d74..4d536bf 100755 --- a/server/src/server/worldgen/feature/WorldGenHellLava.java +++ b/server/src/server/worldgen/feature/WorldGenHellLava.java @@ -2,7 +2,6 @@ package server.worldgen.feature; import common.block.Block; import common.init.Blocks; -import common.material.Material; import common.rng.Random; import common.util.BlockPos; import server.world.WorldServer; @@ -25,7 +24,7 @@ public class WorldGenHellLava extends FeatureGenerator { return false; } - else if (worldIn.getState(position).getBlock().getMaterial() != Material.air && worldIn.getState(position).getBlock() != Blocks.hellrock) + else if (worldIn.getState(position).getBlock() != Blocks.air && worldIn.getState(position).getBlock() != Blocks.hellrock) { return false; } diff --git a/server/src/server/worldgen/feature/WorldGenIceSpike.java b/server/src/server/worldgen/feature/WorldGenIceSpike.java index 886d3d9..97d8efd 100755 --- a/server/src/server/worldgen/feature/WorldGenIceSpike.java +++ b/server/src/server/worldgen/feature/WorldGenIceSpike.java @@ -2,7 +2,6 @@ package server.worldgen.feature; import common.block.Block; import common.init.Blocks; -import common.material.Material; import common.rng.Random; import common.util.BlockPos; import common.util.ExtMath; @@ -50,7 +49,7 @@ public class WorldGenIceSpike extends FeatureGenerator { Block block = worldIn.getState(position.add(i1, k, j1)).getBlock(); - if (block.getMaterial() == Material.air || block == Blocks.dirt || block == Blocks.snow || block == Blocks.ice) + if (block == Blocks.air || block == Blocks.dirt || block == Blocks.snow || block == Blocks.ice) { this.setBlockAndNotifyAdequately(worldIn, position.add(i1, k, j1), Blocks.packed_ice.getState()); } @@ -59,7 +58,7 @@ public class WorldGenIceSpike extends FeatureGenerator { block = worldIn.getState(position.add(i1, -k, j1)).getBlock(); - if (block.getMaterial() == Material.air || block == Blocks.dirt || block == Blocks.snow || block == Blocks.ice) + if (block == Blocks.air || block == Blocks.dirt || block == Blocks.snow || block == Blocks.ice) { this.setBlockAndNotifyAdequately(worldIn, position.add(i1, -k, j1), Blocks.packed_ice.getState()); } @@ -96,7 +95,7 @@ public class WorldGenIceSpike extends FeatureGenerator { Block block1 = worldIn.getState(blockpos).getBlock(); - if (block1.getMaterial() != Material.air && block1 != Blocks.dirt && block1 != Blocks.snow && block1 != Blocks.ice && block1 != Blocks.packed_ice) + if (block1 != Blocks.air && block1 != Blocks.dirt && block1 != Blocks.snow && block1 != Blocks.ice && block1 != Blocks.packed_ice) { break; } diff --git a/server/src/server/worldgen/foliage/FeatureDoublePlant.java b/server/src/server/worldgen/foliage/FeatureDoublePlant.java index 8237227..548e584 100755 --- a/server/src/server/worldgen/foliage/FeatureDoublePlant.java +++ b/server/src/server/worldgen/foliage/FeatureDoublePlant.java @@ -1,6 +1,6 @@ package server.worldgen.foliage; -import common.block.BlockDoublePlant; +import common.block.foliage.BlockDoublePlant; import common.init.Blocks; import common.rng.Random; import common.util.BlockPos; diff --git a/server/src/server/worldgen/foliage/WorldGenBigMushroom.java b/server/src/server/worldgen/foliage/WorldGenBigMushroom.java index b1bf20f..450cd1a 100755 --- a/server/src/server/worldgen/foliage/WorldGenBigMushroom.java +++ b/server/src/server/worldgen/foliage/WorldGenBigMushroom.java @@ -1,7 +1,7 @@ package server.worldgen.foliage; import common.block.Block; -import common.block.BlockHugeMushroom; +import common.block.foliage.BlockHugeMushroom; import common.init.Blocks; import common.material.Material; import common.rng.Random; @@ -56,7 +56,7 @@ public class WorldGenBigMushroom extends FeatureGenerator { Block block = worldIn.getState(blockpos$mutableblockpos.set(l, j, i1)).getBlock(); - if (block.getMaterial() != Material.air && block.getMaterial() != Material.leaves) + if (block != Blocks.air && block.getMaterial() != Material.leaves) { flag = false; } diff --git a/server/src/server/worldgen/foliage/WorldGenDeadBush.java b/server/src/server/worldgen/foliage/WorldGenDeadBush.java index 05f2ba8..422576f 100755 --- a/server/src/server/worldgen/foliage/WorldGenDeadBush.java +++ b/server/src/server/worldgen/foliage/WorldGenDeadBush.java @@ -14,7 +14,7 @@ public class WorldGenDeadBush extends FeatureGenerator { Block block; - while (((block = worldIn.getState(position).getBlock()).getMaterial() == Material.air || block.getMaterial() == Material.leaves) && position.getY() > 0) + while (((block = worldIn.getState(position).getBlock()) == Blocks.air || block.getMaterial() == Material.leaves) && position.getY() > 0) { position = position.down(); } diff --git a/server/src/server/worldgen/foliage/WorldGenFlowers.java b/server/src/server/worldgen/foliage/WorldGenFlowers.java index add8180..4bc978c 100755 --- a/server/src/server/worldgen/foliage/WorldGenFlowers.java +++ b/server/src/server/worldgen/foliage/WorldGenFlowers.java @@ -1,6 +1,6 @@ package server.worldgen.foliage; -import common.block.BlockFlower; +import common.block.foliage.BlockFlower; import common.rng.Random; import common.util.BlockPos; import common.world.State; diff --git a/server/src/server/worldgen/foliage/WorldGenMushroom.java b/server/src/server/worldgen/foliage/WorldGenMushroom.java index 740b3ae..07b999b 100755 --- a/server/src/server/worldgen/foliage/WorldGenMushroom.java +++ b/server/src/server/worldgen/foliage/WorldGenMushroom.java @@ -1,6 +1,6 @@ package server.worldgen.foliage; -import common.block.BlockBush; +import common.block.foliage.BlockBush; import common.rng.Random; import common.util.BlockPos; import server.world.WorldServer; diff --git a/server/src/server/worldgen/foliage/WorldGenPumpkin.java b/server/src/server/worldgen/foliage/WorldGenPumpkin.java index 457db07..1aa47b3 100755 --- a/server/src/server/worldgen/foliage/WorldGenPumpkin.java +++ b/server/src/server/worldgen/foliage/WorldGenPumpkin.java @@ -1,6 +1,6 @@ package server.worldgen.foliage; -import common.block.BlockPumpkin; +import common.block.foliage.BlockPumpkin; import common.init.Blocks; import common.rng.Random; import common.util.BlockPos; diff --git a/server/src/server/worldgen/foliage/WorldGenShrub.java b/server/src/server/worldgen/foliage/WorldGenShrub.java index 410b5c9..ec49a02 100755 --- a/server/src/server/worldgen/foliage/WorldGenShrub.java +++ b/server/src/server/worldgen/foliage/WorldGenShrub.java @@ -1,7 +1,7 @@ package server.worldgen.foliage; import common.block.Block; -import common.block.BlockLeaves; +import common.block.foliage.BlockLeaves; import common.init.Blocks; import common.material.Material; import common.rng.Random; @@ -26,7 +26,7 @@ public class WorldGenShrub extends WorldGenBaseTree { Block block; - while (((block = worldIn.getState(position).getBlock()).getMaterial() == Material.air || block.getMaterial() == Material.leaves) && position.getY() > 0) + while (((block = worldIn.getState(position).getBlock()) == Blocks.air || block.getMaterial() == Material.leaves) && position.getY() > 0) { position = position.down(); } diff --git a/server/src/server/worldgen/foliage/WorldGenTallGrass.java b/server/src/server/worldgen/foliage/WorldGenTallGrass.java index 804a853..cd8d788 100755 --- a/server/src/server/worldgen/foliage/WorldGenTallGrass.java +++ b/server/src/server/worldgen/foliage/WorldGenTallGrass.java @@ -1,7 +1,7 @@ package server.worldgen.foliage; import common.block.Block; -import common.block.BlockTallGrass; +import common.block.foliage.BlockTallGrass; import common.init.Blocks; import common.material.Material; import common.rng.Random; @@ -23,7 +23,7 @@ public class WorldGenTallGrass extends FeatureGenerator { Block block; - while (((block = worldIn.getState(position).getBlock()).getMaterial() == Material.air || block.getMaterial() == Material.leaves) && position.getY() > 0) + while (((block = worldIn.getState(position).getBlock()) == Blocks.air || block.getMaterial() == Material.leaves) && position.getY() > 0) { position = position.down(); } diff --git a/server/src/server/worldgen/foliage/WorldGenVines.java b/server/src/server/worldgen/foliage/WorldGenVines.java index ff9f427..86fd327 100755 --- a/server/src/server/worldgen/foliage/WorldGenVines.java +++ b/server/src/server/worldgen/foliage/WorldGenVines.java @@ -1,6 +1,6 @@ package server.worldgen.foliage; -import common.block.BlockVine; +import common.block.foliage.BlockVine; import common.init.Blocks; import common.rng.Random; import common.util.BlockPos; diff --git a/server/src/server/worldgen/structure/StructureComponent.java b/server/src/server/worldgen/structure/StructureComponent.java index 54d9af1..8698a75 100755 --- a/server/src/server/worldgen/structure/StructureComponent.java +++ b/server/src/server/worldgen/structure/StructureComponent.java @@ -4,11 +4,10 @@ import java.util.List; import common.block.Block; import common.block.BlockDirectional; -import common.block.BlockDoor; +import common.block.artificial.BlockDoor; import common.init.Blocks; import common.item.ItemDoor; import common.item.RngLoot; -import common.material.Material; import common.nbt.NBTTagCompound; import common.rng.Random; import common.rng.WeightedList; @@ -638,7 +637,7 @@ public abstract class StructureComponent { for (int k = zMin; k <= zMax; ++k) { - if (!existingOnly || this.getBlockStateFromPos(worldIn, j, i, k, boundingboxIn).getBlock().getMaterial() != Material.air) + if (!existingOnly || this.getBlockStateFromPos(worldIn, j, i, k, boundingboxIn).getBlock() != Blocks.air) { if (i != yMin && i != yMax && j != xMin && j != xMax && k != zMin && k != zMax) { @@ -666,7 +665,7 @@ public abstract class StructureComponent { for (int k = minZ; k <= maxZ; ++k) { - if (!alwaysReplace || this.getBlockStateFromPos(worldIn, j, i, k, boundingboxIn).getBlock().getMaterial() != Material.air) + if (!alwaysReplace || this.getBlockStateFromPos(worldIn, j, i, k, boundingboxIn).getBlock() != Blocks.air) { blockselector.selectBlocks(rand, j, i, k, i == minY || i == maxY || j == minX || j == maxX || k == minZ || k == maxZ); this.setBlockState(worldIn, blockselector.getBlockState(), j, i, k, boundingboxIn); @@ -684,7 +683,7 @@ public abstract class StructureComponent { for (int k = minZ; k <= maxZ; ++k) { - if (rand.floatv() <= chance && (!p_175805_13_ || this.getBlockStateFromPos(worldIn, j, i, k, boundingboxIn).getBlock().getMaterial() != Material.air)) + if (rand.floatv() <= chance && (!p_175805_13_ || this.getBlockStateFromPos(worldIn, j, i, k, boundingboxIn).getBlock() != Blocks.air)) { if (i != minY && i != maxY && j != minX && j != maxX && k != minZ && k != maxZ) { @@ -728,7 +727,7 @@ public abstract class StructureComponent { float f7 = ((float)k - f4) / (f2 * 0.5F); - if (!p_180777_10_ || this.getBlockStateFromPos(worldIn, j, i, k, boundingboxIn).getBlock().getMaterial() != Material.air) + if (!p_180777_10_ || this.getBlockStateFromPos(worldIn, j, i, k, boundingboxIn).getBlock() != Blocks.air) { float f8 = f6 * f6 + f5 * f5 + f7 * f7; diff --git a/server/src/server/worldgen/structure/StructureMineshaft.java b/server/src/server/worldgen/structure/StructureMineshaft.java index d7a0fd9..bc88140 100755 --- a/server/src/server/worldgen/structure/StructureMineshaft.java +++ b/server/src/server/worldgen/structure/StructureMineshaft.java @@ -7,7 +7,6 @@ import common.entity.item.EntityChestCart; import common.init.Blocks; import common.init.Items; import common.item.RngLoot; -import common.material.Material; import common.nbt.NBTTagCompound; import common.nbt.NBTTagList; import common.rng.Random; @@ -289,7 +288,7 @@ public class StructureMineshaft { BlockPos blockpos = new BlockPos(this.getXWithOffset(x, z), this.getYWithOffset(y), this.getZWithOffset(x, z)); - if (boundingBoxIn.isVecInside(blockpos) && worldIn.getState(blockpos).getBlock().getMaterial() == Material.air) + if (boundingBoxIn.isVecInside(blockpos) && worldIn.getState(blockpos).getBlock() == Blocks.air) { int i = rand.chance() ? 1 : 0; worldIn.setState(blockpos, Blocks.rail.getStateFromMeta(this.getMetadataWithOffset(Blocks.rail, i)), 2); @@ -391,7 +390,7 @@ public class StructureMineshaft int j3 = -1; State iblockstate1 = this.getBlockStateFromPos(worldIn, k2, j3, i3, structureBoundingBoxIn); - if (iblockstate1.getBlock().getMaterial() == Material.air) + if (iblockstate1.getBlock() == Blocks.air) { int k3 = -1; this.setBlockState(worldIn, Blocks.oak_planks.getState(), k2, k3, i3, structureBoundingBoxIn); @@ -405,7 +404,7 @@ public class StructureMineshaft { State iblockstate = this.getBlockStateFromPos(worldIn, 1, -1, l2, structureBoundingBoxIn); - if (iblockstate.getBlock().getMaterial() != Material.air && iblockstate.getBlock().isFullBlock()) + if (iblockstate.getBlock() != Blocks.air && iblockstate.getBlock().isFullBlock()) { this.randomlyPlaceBlock(worldIn, structureBoundingBoxIn, randomIn, 0.7F, 1, 0, l2, Blocks.rail.getStateFromMeta(this.getMetadataWithOffset(Blocks.rail, 0))); } @@ -569,7 +568,7 @@ public class StructureMineshaft { for (int j = this.boundingBox.minZ; j <= this.boundingBox.maxZ; ++j) { - if (this.getBlockStateFromPos(worldIn, i, this.boundingBox.minY - 1, j, structureBoundingBoxIn).getBlock().getMaterial() == Material.air) + if (this.getBlockStateFromPos(worldIn, i, this.boundingBox.minY - 1, j, structureBoundingBoxIn).getBlock() == Blocks.air) { this.setBlockState(worldIn, Blocks.oak_planks.getState(), i, this.boundingBox.minY - 1, j, structureBoundingBoxIn); } diff --git a/server/src/server/worldgen/structure/StructureScattered.java b/server/src/server/worldgen/structure/StructureScattered.java index 8b30816..70fcb34 100755 --- a/server/src/server/worldgen/structure/StructureScattered.java +++ b/server/src/server/worldgen/structure/StructureScattered.java @@ -1,12 +1,12 @@ package server.worldgen.structure; -import common.block.BlockFlower; -import common.block.BlockFlowerPot; -import common.block.BlockLever; -import common.block.BlockSandStone; -import common.block.BlockStoneBrick; -import common.block.BlockTripWire; -import common.block.BlockTripWireHook; +import common.block.artificial.BlockFlowerPot; +import common.block.artificial.BlockStoneBrick; +import common.block.foliage.BlockFlower; +import common.block.natural.BlockSandStone; +import common.block.tech.BlockLever; +import common.block.tech.BlockTripWire; +import common.block.tech.BlockTripWireHook; import common.color.DyeColor; import common.entity.npc.EntityMage; import common.init.Blocks; diff --git a/server/src/server/worldgen/structure/StructureStronghold.java b/server/src/server/worldgen/structure/StructureStronghold.java index 101d358..3679f4e 100755 --- a/server/src/server/worldgen/structure/StructureStronghold.java +++ b/server/src/server/worldgen/structure/StructureStronghold.java @@ -3,8 +3,8 @@ package server.worldgen.structure; import java.util.List; import java.util.Map; -import common.block.BlockSlab; -import common.block.BlockStoneBrick; +import common.block.artificial.BlockSlab; +import common.block.artificial.BlockStoneBrick; import common.collect.Lists; import common.collect.Maps; import common.init.Blocks; diff --git a/server/src/server/worldgen/structure/StructureVillage.java b/server/src/server/worldgen/structure/StructureVillage.java index 905d5ca..7a81ed1 100755 --- a/server/src/server/worldgen/structure/StructureVillage.java +++ b/server/src/server/worldgen/structure/StructureVillage.java @@ -5,18 +5,17 @@ import java.util.List; import common.biome.Biome; import common.block.Block; -import common.block.BlockLog; -import common.block.BlockSandStone; -import common.block.BlockSlab; -import common.block.BlockStairs; -import common.block.BlockTorch; +import common.block.artificial.BlockSlab; +import common.block.artificial.BlockStairs; +import common.block.foliage.BlockLog; +import common.block.natural.BlockSandStone; +import common.block.tech.BlockTorch; import common.collect.Lists; import common.color.DyeColor; import common.entity.npc.EntityHuman; import common.init.BlockRegistry; import common.init.Blocks; import common.init.Config; -import common.material.Material; import common.nbt.NBTTagCompound; import common.rng.Random; import common.util.BlockPos; @@ -358,7 +357,7 @@ public class StructureVillage this.setBlockState(worldIn, Blocks.air.getState(), 2, 2, 0, structureBoundingBoxIn); this.placeDoorCurrentPosition(worldIn, structureBoundingBoxIn, randomIn, 2, 1, 0, Facing.getHorizontal(this.getMetadataWithOffset(Blocks.oak_door, 1))); - if (this.getBlockStateFromPos(worldIn, 2, 0, -1, structureBoundingBoxIn).getBlock().getMaterial() == Material.air && this.getBlockStateFromPos(worldIn, 2, -1, -1, structureBoundingBoxIn).getBlock().getMaterial() != Material.air) + if (this.getBlockStateFromPos(worldIn, 2, 0, -1, structureBoundingBoxIn).getBlock() == Blocks.air && this.getBlockStateFromPos(worldIn, 2, -1, -1, structureBoundingBoxIn).getBlock() != Blocks.air) { this.setBlockState(worldIn, Blocks.cobblestone_stairs.getStateFromMeta(this.getMetadataWithOffset(Blocks.cobblestone_stairs, 3)), 2, 0, -1, structureBoundingBoxIn); } @@ -683,7 +682,7 @@ public class StructureVillage this.setBlockState(worldIn, Blocks.torch.getState().withProperty(BlockTorch.FACING, this.coordBaseMode), 2, 3, 1, structureBoundingBoxIn); this.placeDoorCurrentPosition(worldIn, structureBoundingBoxIn, randomIn, 2, 1, 0, Facing.getHorizontal(this.getMetadataWithOffset(Blocks.oak_door, 1))); - if (this.getBlockStateFromPos(worldIn, 2, 0, -1, structureBoundingBoxIn).getBlock().getMaterial() == Material.air && this.getBlockStateFromPos(worldIn, 2, -1, -1, structureBoundingBoxIn).getBlock().getMaterial() != Material.air) + if (this.getBlockStateFromPos(worldIn, 2, 0, -1, structureBoundingBoxIn).getBlock() == Blocks.air && this.getBlockStateFromPos(worldIn, 2, -1, -1, structureBoundingBoxIn).getBlock() != Blocks.air) { this.setBlockState(worldIn, Blocks.cobblestone_stairs.getStateFromMeta(this.getMetadataWithOffset(Blocks.cobblestone_stairs, 3)), 2, 0, -1, structureBoundingBoxIn); } @@ -811,7 +810,7 @@ public class StructureVillage this.setBlockState(worldIn, Blocks.air.getState(), 1, 2, 0, structureBoundingBoxIn); this.placeDoorCurrentPosition(worldIn, structureBoundingBoxIn, randomIn, 1, 1, 0, Facing.getHorizontal(this.getMetadataWithOffset(Blocks.oak_door, 1))); - if (this.getBlockStateFromPos(worldIn, 1, 0, -1, structureBoundingBoxIn).getBlock().getMaterial() == Material.air && this.getBlockStateFromPos(worldIn, 1, -1, -1, structureBoundingBoxIn).getBlock().getMaterial() != Material.air) + if (this.getBlockStateFromPos(worldIn, 1, 0, -1, structureBoundingBoxIn).getBlock() == Blocks.air && this.getBlockStateFromPos(worldIn, 1, -1, -1, structureBoundingBoxIn).getBlock() != Blocks.air) { this.setBlockState(worldIn, Blocks.cobblestone_stairs.getStateFromMeta(this.getMetadataWithOffset(Blocks.cobblestone_stairs, 3)), 1, 0, -1, structureBoundingBoxIn); } @@ -926,7 +925,7 @@ public class StructureVillage for (int i = 6; i <= 8; ++i) { - if (this.getBlockStateFromPos(worldIn, i, 0, -1, structureBoundingBoxIn).getBlock().getMaterial() == Material.air && this.getBlockStateFromPos(worldIn, i, -1, -1, structureBoundingBoxIn).getBlock().getMaterial() != Material.air) + if (this.getBlockStateFromPos(worldIn, i, 0, -1, structureBoundingBoxIn).getBlock() == Blocks.air && this.getBlockStateFromPos(worldIn, i, -1, -1, structureBoundingBoxIn).getBlock() != Blocks.air) { this.setBlockState(worldIn, Blocks.cobblestone_stairs.getStateFromMeta(this.getMetadataWithOffset(Blocks.cobblestone_stairs, 3)), i, 0, -1, structureBoundingBoxIn); } @@ -1080,7 +1079,7 @@ public class StructureVillage this.placeDoorCurrentPosition(worldIn, structureBoundingBoxIn, randomIn, 2, 1, 0, Facing.getHorizontal(this.getMetadataWithOffset(Blocks.oak_door, 1))); this.fillWithBlocks(worldIn, structureBoundingBoxIn, 1, 0, -1, 3, 2, -1, Blocks.air.getState(), Blocks.air.getState(), false); - if (this.getBlockStateFromPos(worldIn, 2, 0, -1, structureBoundingBoxIn).getBlock().getMaterial() == Material.air && this.getBlockStateFromPos(worldIn, 2, -1, -1, structureBoundingBoxIn).getBlock().getMaterial() != Material.air) + if (this.getBlockStateFromPos(worldIn, 2, 0, -1, structureBoundingBoxIn).getBlock() == Blocks.air && this.getBlockStateFromPos(worldIn, 2, -1, -1, structureBoundingBoxIn).getBlock() != Blocks.air) { this.setBlockState(worldIn, Blocks.cobblestone_stairs.getStateFromMeta(this.getMetadataWithOffset(Blocks.cobblestone_stairs, 3)), 2, 0, -1, structureBoundingBoxIn); } @@ -1185,7 +1184,7 @@ public class StructureVillage this.setBlockState(worldIn, Blocks.oak_planks.getState(), 3, 2, 0, structureBoundingBoxIn); this.setBlockState(worldIn, Blocks.oak_planks.getState(), 3, 1, 0, structureBoundingBoxIn); - if (this.getBlockStateFromPos(worldIn, 2, 0, -1, structureBoundingBoxIn).getBlock().getMaterial() == Material.air && this.getBlockStateFromPos(worldIn, 2, -1, -1, structureBoundingBoxIn).getBlock().getMaterial() != Material.air) + if (this.getBlockStateFromPos(worldIn, 2, 0, -1, structureBoundingBoxIn).getBlock() == Blocks.air && this.getBlockStateFromPos(worldIn, 2, -1, -1, structureBoundingBoxIn).getBlock() != Blocks.air) { this.setBlockState(worldIn, Blocks.cobblestone_stairs.getStateFromMeta(this.getMetadataWithOffset(Blocks.cobblestone_stairs, 3)), 2, 0, -1, structureBoundingBoxIn); } @@ -1868,7 +1867,7 @@ public class StructureVillage this.setBlockState(worldIn, Blocks.air.getState(), 1, 2, 0, structureBoundingBoxIn); this.placeDoorCurrentPosition(worldIn, structureBoundingBoxIn, randomIn, 1, 1, 0, Facing.getHorizontal(this.getMetadataWithOffset(Blocks.oak_door, 1))); - if (this.getBlockStateFromPos(worldIn, 1, 0, -1, structureBoundingBoxIn).getBlock().getMaterial() == Material.air && this.getBlockStateFromPos(worldIn, 1, -1, -1, structureBoundingBoxIn).getBlock().getMaterial() != Material.air) + if (this.getBlockStateFromPos(worldIn, 1, 0, -1, structureBoundingBoxIn).getBlock() == Blocks.air && this.getBlockStateFromPos(worldIn, 1, -1, -1, structureBoundingBoxIn).getBlock() != Blocks.air) { this.setBlockState(worldIn, Blocks.cobblestone_stairs.getStateFromMeta(this.getMetadataWithOffset(Blocks.cobblestone_stairs, 3)), 1, 0, -1, structureBoundingBoxIn); } diff --git a/server/src/server/worldgen/tree/WorldGenBaseTree.java b/server/src/server/worldgen/tree/WorldGenBaseTree.java index c5cacd0..43e2221 100755 --- a/server/src/server/worldgen/tree/WorldGenBaseTree.java +++ b/server/src/server/worldgen/tree/WorldGenBaseTree.java @@ -1,9 +1,9 @@ package server.worldgen.tree; import common.block.Block; -import common.block.BlockCocoa; -import common.block.BlockLeaves; -import common.block.BlockVine; +import common.block.foliage.BlockCocoa; +import common.block.foliage.BlockLeaves; +import common.block.foliage.BlockVine; import common.init.Blocks; import common.material.Material; import common.properties.PropertyBool; @@ -116,7 +116,7 @@ public class WorldGenBaseTree extends WorldGenTree BlockPos blockpos = new BlockPos(k1, i3, i2); Block block = worldIn.getState(blockpos).getBlock(); - if (block.getMaterial() == Material.air || block.getMaterial() == Material.leaves || block.getMaterial() == Material.vine) + if (block == Blocks.air || block.getMaterial() == Material.leaves || block.getMaterial() == Material.vine) { this.setBlockAndNotifyAdequately(worldIn, blockpos, this.metaLeaves.withProperty(BlockLeaves.TYPE, worldIn.getLeavesGen(blockpos))); } @@ -129,7 +129,7 @@ public class WorldGenBaseTree extends WorldGenTree { Block block2 = worldIn.getState(position.up(j3)).getBlock(); - if (block2.getMaterial() == Material.air || block2.getMaterial() == Material.leaves || block2.getMaterial() == Material.vine) + if (block2 == Blocks.air || block2.getMaterial() == Material.leaves || block2.getMaterial() == Material.vine) { this.setBlockAndNotifyAdequately(worldIn, position.up(j3), this.metaWood); @@ -179,22 +179,22 @@ public class WorldGenBaseTree extends WorldGenTree BlockPos blockpos4 = blockpos$mutableblockpos1.north(); BlockPos blockpos1 = blockpos$mutableblockpos1.south(); - if (rand.zrange(4) == 0 && worldIn.getState(blockpos2).getBlock().getMaterial() == Material.air) + if (rand.zrange(4) == 0 && worldIn.getState(blockpos2).getBlock() == Blocks.air) { this.func_181650_b(worldIn, blockpos2, BlockVine.EAST); } - if (rand.zrange(4) == 0 && worldIn.getState(blockpos3).getBlock().getMaterial() == Material.air) + if (rand.zrange(4) == 0 && worldIn.getState(blockpos3).getBlock() == Blocks.air) { this.func_181650_b(worldIn, blockpos3, BlockVine.WEST); } - if (rand.zrange(4) == 0 && worldIn.getState(blockpos4).getBlock().getMaterial() == Material.air) + if (rand.zrange(4) == 0 && worldIn.getState(blockpos4).getBlock() == Blocks.air) { this.func_181650_b(worldIn, blockpos4, BlockVine.SOUTH); } - if (rand.zrange(4) == 0 && worldIn.getState(blockpos1).getBlock().getMaterial() == Material.air) + if (rand.zrange(4) == 0 && worldIn.getState(blockpos1).getBlock() == Blocks.air) { this.func_181650_b(worldIn, blockpos1, BlockVine.NORTH); } @@ -248,7 +248,7 @@ public class WorldGenBaseTree extends WorldGenTree this.func_181651_a(p_181650_1_, p_181650_2_, p_181650_3_); int i = 4; - for (p_181650_2_ = p_181650_2_.down(); p_181650_1_.getState(p_181650_2_).getBlock().getMaterial() == Material.air && i > 0; --i) + for (p_181650_2_ = p_181650_2_.down(); p_181650_1_.getState(p_181650_2_).getBlock() == Blocks.air && i > 0; --i) { this.func_181651_a(p_181650_1_, p_181650_2_, p_181650_3_); p_181650_2_ = p_181650_2_.down(); diff --git a/server/src/server/worldgen/tree/WorldGenBigTree.java b/server/src/server/worldgen/tree/WorldGenBigTree.java index ad648bb..d9482a6 100755 --- a/server/src/server/worldgen/tree/WorldGenBigTree.java +++ b/server/src/server/worldgen/tree/WorldGenBigTree.java @@ -3,8 +3,8 @@ package server.worldgen.tree; import java.util.List; import common.block.Block; -import common.block.BlockLeaves; -import common.block.BlockLog; +import common.block.foliage.BlockLeaves; +import common.block.foliage.BlockLog; import common.collect.Lists; import common.init.Blocks; import common.material.Material; @@ -125,9 +125,9 @@ public class WorldGenBigTree extends WorldGenTree if (Math.pow((double)Math.abs(j) + 0.5D, 2.0D) + Math.pow((double)Math.abs(k) + 0.5D, 2.0D) <= (double)(p_181631_2_ * p_181631_2_)) { BlockPos blockpos = p_181631_1_.add(j, 0, k); - Material material = this.world.getState(blockpos).getBlock().getMaterial(); + Block block = this.world.getState(blockpos).getBlock(); - if (material == Material.air || material == Material.leaves) + if (block == Blocks.air || block.getMaterial() == Material.leaves) { this.setBlockAndNotifyAdequately(this.world, blockpos, p_181631_3_); } diff --git a/server/src/server/worldgen/tree/WorldGenBirch.java b/server/src/server/worldgen/tree/WorldGenBirch.java index 0659ee8..ba62e4c 100755 --- a/server/src/server/worldgen/tree/WorldGenBirch.java +++ b/server/src/server/worldgen/tree/WorldGenBirch.java @@ -1,7 +1,7 @@ package server.worldgen.tree; import common.block.Block; -import common.block.BlockLeaves; +import common.block.foliage.BlockLeaves; import common.init.Blocks; import common.material.Material; import common.rng.Random; @@ -101,7 +101,7 @@ public class WorldGenBirch extends WorldGenTree BlockPos blockpos = new BlockPos(i3, i2, k1); Block block = worldIn.getState(blockpos).getBlock(); - if (block.getMaterial() == Material.air || block.getMaterial() == Material.leaves) + if (block == Blocks.air || block.getMaterial() == Material.leaves) { this.setBlockAndNotifyAdequately(worldIn, blockpos, leavesBlock.withProperty(BlockLeaves.TYPE, worldIn.getLeavesGen(blockpos))); } @@ -114,7 +114,7 @@ public class WorldGenBirch extends WorldGenTree { Block block2 = worldIn.getState(position.up(j2)).getBlock(); - if (block2.getMaterial() == Material.air || block2.getMaterial() == Material.leaves) + if (block2 == Blocks.air || block2.getMaterial() == Material.leaves) { this.setBlockAndNotifyAdequately(worldIn, position.up(j2), logBlock); } diff --git a/server/src/server/worldgen/tree/WorldGenDarkOak.java b/server/src/server/worldgen/tree/WorldGenDarkOak.java index 09f1126..51a021a 100755 --- a/server/src/server/worldgen/tree/WorldGenDarkOak.java +++ b/server/src/server/worldgen/tree/WorldGenDarkOak.java @@ -1,7 +1,7 @@ package server.worldgen.tree; import common.block.Block; -import common.block.BlockLeaves; +import common.block.foliage.BlockLeaves; import common.init.Blocks; import common.material.Material; import common.rng.Random; @@ -66,9 +66,9 @@ public class WorldGenDarkOak extends WorldGenTree int k2 = k + j2; BlockPos blockpos1 = new BlockPos(k1, k2, l1); - Material material = worldIn.getState(blockpos1).getBlock().getMaterial(); + Block block1 = worldIn.getState(blockpos1).getBlock(); - if (material == Material.air || material == Material.leaves) + if (block1 == Blocks.air || block1.getMaterial() == Material.leaves) { this.func_181639_b(worldIn, blockpos1); this.func_181639_b(worldIn, blockpos1.east()); @@ -210,7 +210,7 @@ public class WorldGenDarkOak extends WorldGenTree BlockPos blockpos = new BlockPos(p_150526_2_, p_150526_3_, p_150526_4_); Block block = worldIn.getState(blockpos).getBlock(); - if (block.getMaterial() == Material.air) + if (block == Blocks.air) { this.setBlockAndNotifyAdequately(worldIn, blockpos, leavesBlock.withProperty(BlockLeaves.TYPE, worldIn.getLeavesGen(blockpos))); } diff --git a/server/src/server/worldgen/tree/WorldGenHugeTree.java b/server/src/server/worldgen/tree/WorldGenHugeTree.java index c5d50f1..24b9553 100755 --- a/server/src/server/worldgen/tree/WorldGenHugeTree.java +++ b/server/src/server/worldgen/tree/WorldGenHugeTree.java @@ -1,7 +1,7 @@ package server.worldgen.tree; import common.block.Block; -import common.block.BlockLeaves; +import common.block.foliage.BlockLeaves; import common.init.Blocks; import common.material.Material; import common.rng.Random; @@ -119,9 +119,9 @@ public abstract class WorldGenHugeTree extends WorldGenTree if (j * j + k * k <= i || l * l + i1 * i1 <= i || j * j + i1 * i1 <= i || l * l + k * k <= i) { BlockPos blockpos = p_175925_2_.add(j, 0, k); - Material material = worldIn.getState(blockpos).getBlock().getMaterial(); + Block block = worldIn.getState(blockpos).getBlock(); - if (material == Material.air || material == Material.leaves) + if (block == Blocks.air || block.getMaterial() == Material.leaves) { this.setBlockAndNotifyAdequately(worldIn, blockpos, this.leavesMetadata.withProperty(BlockLeaves.TYPE, worldIn.getLeavesGen(blockpos))); } @@ -141,9 +141,9 @@ public abstract class WorldGenHugeTree extends WorldGenTree if (j * j + k * k <= i) { BlockPos blockpos = p_175928_2_.add(j, 0, k); - Material material = worldIn.getState(blockpos).getBlock().getMaterial(); + Block block = worldIn.getState(blockpos).getBlock(); - if (material == Material.air || material == Material.leaves) + if (block == Blocks.air || block.getMaterial() == Material.leaves) { this.setBlockAndNotifyAdequately(worldIn, blockpos, this.leavesMetadata.withProperty(BlockLeaves.TYPE, worldIn.getLeavesGen(blockpos))); } diff --git a/server/src/server/worldgen/tree/WorldGenJungle.java b/server/src/server/worldgen/tree/WorldGenJungle.java index 1edd2d4..ba30cdb 100755 --- a/server/src/server/worldgen/tree/WorldGenJungle.java +++ b/server/src/server/worldgen/tree/WorldGenJungle.java @@ -1,6 +1,6 @@ package server.worldgen.tree; -import common.block.BlockVine; +import common.block.foliage.BlockVine; import common.init.Blocks; import common.properties.PropertyBool; import common.rng.Random; diff --git a/server/src/server/worldgen/tree/WorldGenPine.java b/server/src/server/worldgen/tree/WorldGenPine.java index 4c90945..497e880 100755 --- a/server/src/server/worldgen/tree/WorldGenPine.java +++ b/server/src/server/worldgen/tree/WorldGenPine.java @@ -1,7 +1,7 @@ package server.worldgen.tree; import common.block.Block; -import common.block.BlockDirt; +import common.block.natural.BlockDirt; import common.init.Blocks; import common.material.Material; import common.rng.Random; @@ -39,7 +39,7 @@ public class WorldGenPine extends WorldGenHugeTree { Block block = worldIn.getState(position.up(j)).getBlock(); - if (block.getMaterial() == Material.air || block.getMaterial() == Material.leaves) + if (block == Blocks.air || block.getMaterial() == Material.leaves) { this.setBlockAndNotifyAdequately(worldIn, position.up(j), this.woodMetadata); } @@ -48,21 +48,21 @@ public class WorldGenPine extends WorldGenHugeTree { block = worldIn.getState(position.add(1, j, 0)).getBlock(); - if (block.getMaterial() == Material.air || block.getMaterial() == Material.leaves) + if (block == Blocks.air || block.getMaterial() == Material.leaves) { this.setBlockAndNotifyAdequately(worldIn, position.add(1, j, 0), this.woodMetadata); } block = worldIn.getState(position.add(1, j, 1)).getBlock(); - if (block.getMaterial() == Material.air || block.getMaterial() == Material.leaves) + if (block == Blocks.air || block.getMaterial() == Material.leaves) { this.setBlockAndNotifyAdequately(worldIn, position.add(1, j, 1), this.woodMetadata); } block = worldIn.getState(position.add(0, j, 1)).getBlock(); - if (block.getMaterial() == Material.air || block.getMaterial() == Material.leaves) + if (block == Blocks.air || block.getMaterial() == Material.leaves) { this.setBlockAndNotifyAdequately(worldIn, position.add(0, j, 1), this.woodMetadata); } @@ -134,7 +134,7 @@ public class WorldGenPine extends WorldGenHugeTree break; } - if (block.getMaterial() != Material.air && i < 0) + if (block != Blocks.air && i < 0) { break; } diff --git a/server/src/server/worldgen/tree/WorldGenSavanna.java b/server/src/server/worldgen/tree/WorldGenSavanna.java index c348cca..7c85bee 100755 --- a/server/src/server/worldgen/tree/WorldGenSavanna.java +++ b/server/src/server/worldgen/tree/WorldGenSavanna.java @@ -1,7 +1,7 @@ package server.worldgen.tree; import common.block.Block; -import common.block.BlockLeaves; +import common.block.foliage.BlockLeaves; import common.init.Blocks; import common.material.Material; import common.rng.Random; @@ -95,9 +95,9 @@ public class WorldGenSavanna extends WorldGenTree } BlockPos blockpos = new BlockPos(i3, i2, j1); - Material material = worldIn.getState(blockpos).getBlock().getMaterial(); + Block block1 = worldIn.getState(blockpos).getBlock(); - if (material == Material.air || material == Material.leaves) + if (block1 == Blocks.air || block1.getMaterial() == Material.leaves) { this.func_181642_b(worldIn, blockpos); k1 = i2; @@ -149,9 +149,9 @@ public class WorldGenSavanna extends WorldGenTree i3 += enumfacing1.getFrontOffsetX(); j1 += enumfacing1.getFrontOffsetZ(); BlockPos blockpos1 = new BlockPos(i3, j2, j1); - Material material1 = worldIn.getState(blockpos1).getBlock().getMaterial(); + Block block1 = worldIn.getState(blockpos1).getBlock(); - if (material1 == Material.air || material1 == Material.leaves) + if (block1 == Blocks.air || block1.getMaterial() == Material.leaves) { this.func_181642_b(worldIn, blockpos1); k1 = j2; @@ -209,9 +209,9 @@ public class WorldGenSavanna extends WorldGenTree private void func_175924_b(WorldServer worldIn, BlockPos p_175924_2_) { - Material material = worldIn.getState(p_175924_2_).getBlock().getMaterial(); + Block block = worldIn.getState(p_175924_2_).getBlock(); - if (material == Material.air || material == Material.leaves) + if (block == Blocks.air || block.getMaterial() == Material.leaves) { this.setBlockAndNotifyAdequately(worldIn, p_175924_2_, field_181644_b.withProperty(BlockLeaves.TYPE, worldIn.getLeavesGen(p_175924_2_))); } diff --git a/server/src/server/worldgen/tree/WorldGenSwamp.java b/server/src/server/worldgen/tree/WorldGenSwamp.java index f8ff143..9773b8d 100755 --- a/server/src/server/worldgen/tree/WorldGenSwamp.java +++ b/server/src/server/worldgen/tree/WorldGenSwamp.java @@ -1,8 +1,8 @@ package server.worldgen.tree; import common.block.Block; -import common.block.BlockLeaves; -import common.block.BlockVine; +import common.block.foliage.BlockLeaves; +import common.block.foliage.BlockVine; import common.init.Blocks; import common.material.Material; import common.properties.PropertyBool; @@ -61,7 +61,7 @@ public class WorldGenSwamp extends WorldGenTree { Block block = worldIn.getState(blockpos$mutableblockpos.set(l, j, i1)).getBlock(); - if (block.getMaterial() != Material.air && block.getMaterial() != Material.leaves) + if (block != Blocks.air && block.getMaterial() != Material.leaves) { if (block != Blocks.water && block != Blocks.flowing_water) { @@ -123,7 +123,7 @@ public class WorldGenSwamp extends WorldGenTree { Block block2 = worldIn.getState(position.up(i2)).getBlock(); - if (block2.getMaterial() == Material.air || block2.getMaterial() == Material.leaves || block2 == Blocks.flowing_water || block2 == Blocks.water) + if (block2 == Blocks.air || block2.getMaterial() == Material.leaves || block2 == Blocks.flowing_water || block2 == Blocks.water) { this.setBlockAndNotifyAdequately(worldIn, position.up(i2), field_181648_a); } @@ -148,22 +148,22 @@ public class WorldGenSwamp extends WorldGenTree BlockPos blockpos1 = blockpos$mutableblockpos1.north(); BlockPos blockpos2 = blockpos$mutableblockpos1.south(); - if (rand.zrange(4) == 0 && worldIn.getState(blockpos3).getBlock().getMaterial() == Material.air) + if (rand.zrange(4) == 0 && worldIn.getState(blockpos3).getBlock() == Blocks.air) { this.func_181647_a(worldIn, blockpos3, BlockVine.EAST); } - if (rand.zrange(4) == 0 && worldIn.getState(blockpos4).getBlock().getMaterial() == Material.air) + if (rand.zrange(4) == 0 && worldIn.getState(blockpos4).getBlock() == Blocks.air) { this.func_181647_a(worldIn, blockpos4, BlockVine.WEST); } - if (rand.zrange(4) == 0 && worldIn.getState(blockpos1).getBlock().getMaterial() == Material.air) + if (rand.zrange(4) == 0 && worldIn.getState(blockpos1).getBlock() == Blocks.air) { this.func_181647_a(worldIn, blockpos1, BlockVine.SOUTH); } - if (rand.zrange(4) == 0 && worldIn.getState(blockpos2).getBlock().getMaterial() == Material.air) + if (rand.zrange(4) == 0 && worldIn.getState(blockpos2).getBlock() == Blocks.air) { this.func_181647_a(worldIn, blockpos2, BlockVine.NORTH); } @@ -192,7 +192,7 @@ public class WorldGenSwamp extends WorldGenTree this.setBlockAndNotifyAdequately(p_181647_1_, p_181647_2_, iblockstate); int i = 4; - for (p_181647_2_ = p_181647_2_.down(); p_181647_1_.getState(p_181647_2_).getBlock().getMaterial() == Material.air && i > 0; --i) + for (p_181647_2_ = p_181647_2_.down(); p_181647_1_.getState(p_181647_2_).getBlock() == Blocks.air && i > 0; --i) { this.setBlockAndNotifyAdequately(p_181647_1_, p_181647_2_, iblockstate); p_181647_2_ = p_181647_2_.down(); diff --git a/server/src/server/worldgen/tree/WorldGenTaiga1.java b/server/src/server/worldgen/tree/WorldGenTaiga1.java index a3fed91..8774152 100755 --- a/server/src/server/worldgen/tree/WorldGenTaiga1.java +++ b/server/src/server/worldgen/tree/WorldGenTaiga1.java @@ -1,7 +1,7 @@ package server.worldgen.tree; import common.block.Block; -import common.block.BlockLeaves; +import common.block.foliage.BlockLeaves; import common.init.Blocks; import common.material.Material; import common.rng.Random; @@ -115,7 +115,7 @@ public class WorldGenTaiga1 extends WorldGenTree { Block block1 = worldIn.getState(position.up(i3)).getBlock(); - if (block1.getMaterial() == Material.air || block1.getMaterial() == Material.leaves) + if (block1 == Blocks.air || block1.getMaterial() == Material.leaves) { this.setBlockAndNotifyAdequately(worldIn, position.up(i3), field_181636_a); } diff --git a/server/src/server/worldgen/tree/WorldGenTaiga2.java b/server/src/server/worldgen/tree/WorldGenTaiga2.java index 681bd4f..a38208f 100755 --- a/server/src/server/worldgen/tree/WorldGenTaiga2.java +++ b/server/src/server/worldgen/tree/WorldGenTaiga2.java @@ -1,7 +1,7 @@ package server.worldgen.tree; import common.block.Block; -import common.block.BlockLeaves; +import common.block.foliage.BlockLeaves; import common.init.Blocks; import common.material.Material; import common.rng.Random; @@ -55,7 +55,7 @@ public class WorldGenTaiga2 extends WorldGenTree { Block block = worldIn.getState(blockpos$mutableblockpos.set(k1, i1, l1)).getBlock(); - if (block.getMaterial() != Material.air && block.getMaterial() != Material.leaves) + if (block != Blocks.air && block.getMaterial() != Material.leaves) { flag = false; } @@ -130,7 +130,7 @@ public class WorldGenTaiga2 extends WorldGenTree { Block block2 = worldIn.getState(position.up(k4)).getBlock(); - if (block2.getMaterial() == Material.air || block2.getMaterial() == Material.leaves) + if (block2 == Blocks.air || block2.getMaterial() == Material.leaves) { this.setBlockAndNotifyAdequately(worldIn, position.up(k4), field_181645_a); } diff --git a/server/src/server/worldgen/tree/WorldGenTree.java b/server/src/server/worldgen/tree/WorldGenTree.java index 964385a..e444636 100755 --- a/server/src/server/worldgen/tree/WorldGenTree.java +++ b/server/src/server/worldgen/tree/WorldGenTree.java @@ -1,8 +1,8 @@ package server.worldgen.tree; import common.block.Block; -import common.block.BlockLog; -import common.block.BlockSapling; +import common.block.foliage.BlockLog; +import common.block.foliage.BlockSapling; import common.init.Blocks; import common.material.Material; import common.rng.Random; @@ -19,8 +19,7 @@ public abstract class WorldGenTree extends FeatureGenerator protected boolean canBeReplaced(Block block) { - Material material = block.getMaterial(); - return material == Material.air || material == Material.leaves || block == Blocks.grass || block == Blocks.dirt || block instanceof BlockLog || block instanceof BlockSapling || block == Blocks.vine; + return block == Blocks.air || block.getMaterial() == Material.leaves || block == Blocks.grass || block == Blocks.dirt || block instanceof BlockLog || block instanceof BlockSapling || block == Blocks.vine; } public void prepare() From 7299ab8e5cccda68f74b919f9d16e9a2f8908627 Mon Sep 17 00:00:00 2001 From: Sen Date: Sun, 25 May 2025 14:45:04 +0200 Subject: [PATCH 070/200] general Block* code cleanup --- .../client/gui/container/GuiContainer.java | 6 +- client/src/client/renderer/BlockRenderer.java | 2 +- .../src/client/renderer/EntityRenderer.java | 4 +- .../renderer/particle/EntityBubbleFX.java | 4 +- .../renderer/particle/EntityDownfallFX.java | 2 +- .../particle/EntityDropParticleFX.java | 16 +- .../renderer/particle/EntitySuspendFX.java | 4 +- .../src/common/ai/EntityAIDoorInteract.java | 4 +- common/src/common/block/Block.java | 15 +- common/src/common/block/BlockAir.java | 3 +- common/src/common/block/BlockColored.java | 3 +- common/src/common/block/BlockContainer.java | 3 +- common/src/common/block/BlockDirectional.java | 1 - common/src/common/block/BlockFalling.java | 3 +- .../src/common/block/BlockRotatedPillar.java | 1 - common/src/common/block/BlockTranslucent.java | 1 - common/src/common/block/BlockTreasure.java | 2 - common/src/common/block/Material.java | 192 +++++++++++++ .../src/common/block/artificial/BlockBed.java | 4 +- .../block/artificial/BlockBookshelf.java | 6 +- .../common/block/artificial/BlockCake.java | 4 +- .../common/block/artificial/BlockCarpet.java | 6 +- .../artificial/BlockCompressedPowered.java | 2 +- .../common/block/artificial/BlockDoor.java | 4 +- .../block/artificial/BlockDragonEgg.java | 4 +- .../common/block/artificial/BlockFence.java | 6 +- .../block/artificial/BlockFenceGate.java | 6 +- .../block/artificial/BlockFloorPortal.java | 2 +- .../block/artificial/BlockFlowerPot.java | 4 +- .../common/block/artificial/BlockGlass.java | 6 +- .../src/common/block/artificial/BlockHay.java | 6 +- .../common/block/artificial/BlockLadder.java | 6 +- .../common/block/artificial/BlockPane.java | 6 +- .../common/block/artificial/BlockPortal.java | 4 +- .../block/artificial/BlockPortalFrame.java | 4 +- .../common/block/artificial/BlockQuartz.java | 6 +- .../common/block/artificial/BlockSlab.java | 4 +- .../artificial/BlockStainedGlassPane.java | 6 +- .../common/block/artificial/BlockStairs.java | 4 +- .../block/artificial/BlockStoneBrick.java | 6 +- .../block/artificial/BlockTrapDoor.java | 8 +- .../common/block/artificial/BlockWall.java | 6 +- .../block/foliage/BlockBlackenedSoil.java | 6 +- .../src/common/block/foliage/BlockBush.java | 6 +- .../src/common/block/foliage/BlockCactus.java | 6 +- .../src/common/block/foliage/BlockCocoa.java | 4 +- .../common/block/foliage/BlockDeadBush.java | 4 +- .../block/foliage/BlockDoublePlant.java | 4 +- .../common/block/foliage/BlockDryLeaves.java | 6 +- .../common/block/foliage/BlockFarmland.java | 6 +- .../src/common/block/foliage/BlockGrass.java | 6 +- .../block/foliage/BlockHugeMushroom.java | 2 +- .../src/common/block/foliage/BlockLeaves.java | 10 +- .../common/block/foliage/BlockLeavesBase.java | 2 +- .../common/block/foliage/BlockLilyPad.java | 2 +- common/src/common/block/foliage/BlockLog.java | 8 +- .../src/common/block/foliage/BlockMelon.java | 6 +- .../common/block/foliage/BlockMycelium.java | 6 +- .../common/block/foliage/BlockPumpkin.java | 6 +- .../src/common/block/foliage/BlockReed.java | 6 +- .../common/block/foliage/BlockSapling.java | 2 +- .../common/block/foliage/BlockTallGrass.java | 4 +- .../common/block/foliage/BlockTianSoil.java | 6 +- .../src/common/block/foliage/BlockVine.java | 6 +- .../src/common/block/foliage/BlockWart.java | 4 +- .../block/liquid/BlockDynamicLiquid.java | 18 +- .../src/common/block/liquid/BlockLiquid.java | 27 +- .../block/liquid/BlockStaticLiquid.java | 6 +- .../common/block/natural/BlockBedrock.java | 4 +- .../block/natural/BlockBlackenedDirt.java | 6 +- .../block/natural/BlockBlackenedStone.java | 6 +- .../src/common/block/natural/BlockClay.java | 6 +- .../src/common/block/natural/BlockDirt.java | 6 +- .../src/common/block/natural/BlockFire.java | 4 +- .../common/block/natural/BlockGlowstone.java | 4 +- .../src/common/block/natural/BlockGravel.java | 6 +- .../block/natural/BlockHardenedClay.java | 6 +- .../common/block/natural/BlockHellRock.java | 6 +- common/src/common/block/natural/BlockIce.java | 6 +- .../common/block/natural/BlockObsidian.java | 6 +- common/src/common/block/natural/BlockOre.java | 6 +- .../common/block/natural/BlockPackedIce.java | 6 +- .../block/natural/BlockRedstoneOre.java | 4 +- .../src/common/block/natural/BlockRock.java | 6 +- .../src/common/block/natural/BlockSand.java | 6 +- .../common/block/natural/BlockSandStone.java | 6 +- .../src/common/block/natural/BlockSlime.java | 6 +- .../src/common/block/natural/BlockSnow.java | 8 +- .../common/block/natural/BlockSnowBlock.java | 6 +- .../common/block/natural/BlockSoulSand.java | 6 +- .../src/common/block/natural/BlockStone.java | 6 +- common/src/common/block/natural/BlockWeb.java | 6 +- common/src/common/block/tech/BlockAnvil.java | 6 +- .../block/tech/BlockBasePressurePlate.java | 4 +- common/src/common/block/tech/BlockBeacon.java | 6 +- .../common/block/tech/BlockBrewingStand.java | 4 +- common/src/common/block/tech/BlockButton.java | 6 +- .../src/common/block/tech/BlockCauldron.java | 4 +- common/src/common/block/tech/BlockChest.java | 6 +- common/src/common/block/tech/BlockCore.java | 6 +- .../block/tech/BlockDaylightDetector.java | 6 +- .../src/common/block/tech/BlockDispenser.java | 6 +- .../block/tech/BlockEnchantmentTable.java | 6 +- .../src/common/block/tech/BlockFurnace.java | 4 +- common/src/common/block/tech/BlockHopper.java | 6 +- .../src/common/block/tech/BlockJukebox.java | 6 +- common/src/common/block/tech/BlockLever.java | 6 +- .../src/common/block/tech/BlockMachine.java | 6 +- .../common/block/tech/BlockMobSpawner.java | 6 +- common/src/common/block/tech/BlockNote.java | 6 +- common/src/common/block/tech/BlockNuke.java | 6 +- .../common/block/tech/BlockPistonBase.java | 6 +- .../common/block/tech/BlockPistonHead.java | 4 +- .../common/block/tech/BlockPistonMoving.java | 4 +- .../common/block/tech/BlockPressurePlate.java | 2 +- .../tech/BlockPressurePlateWeighted.java | 2 +- .../src/common/block/tech/BlockRailBase.java | 6 +- .../common/block/tech/BlockRedstoneDiode.java | 4 +- .../common/block/tech/BlockRedstoneLight.java | 4 +- .../common/block/tech/BlockRedstoneWire.java | 4 +- common/src/common/block/tech/BlockTNT.java | 6 +- common/src/common/block/tech/BlockTorch.java | 6 +- .../src/common/block/tech/BlockTripWire.java | 4 +- .../common/block/tech/BlockTripWireHook.java | 6 +- .../src/common/block/tech/BlockWarpChest.java | 6 +- .../src/common/block/tech/BlockWorkbench.java | 6 +- common/src/common/block/tile/BlockBanner.java | 4 +- common/src/common/block/tile/BlockSign.java | 4 +- common/src/common/block/tile/BlockSkull.java | 4 +- common/src/common/entity/Entity.java | 4 +- common/src/common/entity/item/EntityItem.java | 4 +- common/src/common/entity/item/EntityXp.java | 4 +- common/src/common/init/BlockRegistry.java | 171 ++++++------ common/src/common/init/DispenserRegistry.java | 2 +- common/src/common/init/FluidRegistry.java | 4 +- common/src/common/init/ItemRegistry.java | 112 ++++---- .../src/common/inventory/InventoryPlayer.java | 14 +- common/src/common/item/CheatTab.java | 260 +++++++----------- common/src/common/item/ItemAmmo.java | 2 +- common/src/common/item/ItemArmor.java | 2 +- common/src/common/item/ItemAxe.java | 22 +- common/src/common/item/ItemBanner.java | 4 +- common/src/common/item/ItemBed.java | 2 +- common/src/common/item/ItemBoat.java | 2 +- common/src/common/item/ItemBow.java | 2 +- common/src/common/item/ItemBucket.java | 6 +- common/src/common/item/ItemBucketMilk.java | 2 +- .../src/common/item/ItemCarrotOnAStick.java | 2 +- common/src/common/item/ItemChargedOrb.java | 2 +- common/src/common/item/ItemCoal.java | 2 +- common/src/common/item/ItemDie.java | 2 +- common/src/common/item/ItemDoor.java | 4 +- common/src/common/item/ItemDye.java | 2 +- common/src/common/item/ItemDynamite.java | 2 +- common/src/common/item/ItemEditWand.java | 2 +- common/src/common/item/ItemEgg.java | 2 +- common/src/common/item/ItemExpBottle.java | 2 +- common/src/common/item/ItemFireball.java | 2 +- common/src/common/item/ItemFishingRod.java | 2 +- common/src/common/item/ItemFlintAndSteel.java | 2 +- common/src/common/item/ItemFood.java | 2 +- common/src/common/item/ItemGlassBottle.java | 6 +- common/src/common/item/ItemGunBase.java | 2 +- common/src/common/item/ItemHoe.java | 2 +- common/src/common/item/ItemHorseArmor.java | 2 +- common/src/common/item/ItemLead.java | 2 +- common/src/common/item/ItemMagnet.java | 2 +- common/src/common/item/ItemMinecart.java | 2 +- common/src/common/item/ItemMonsterPlacer.java | 2 +- common/src/common/item/ItemNameTag.java | 2 +- common/src/common/item/ItemNpcSpawner.java | 2 +- common/src/common/item/ItemPickaxe.java | 48 +--- common/src/common/item/ItemPotion.java | 2 +- common/src/common/item/ItemRecord.java | 2 +- common/src/common/item/ItemRedstone.java | 2 +- common/src/common/item/ItemSaddle.java | 2 +- common/src/common/item/ItemSeedFood.java | 2 +- common/src/common/item/ItemSeeds.java | 2 +- common/src/common/item/ItemShears.java | 6 +- common/src/common/item/ItemShovel.java | 19 ++ common/src/common/item/ItemSign.java | 2 +- common/src/common/item/ItemSkull.java | 2 +- common/src/common/item/ItemSnowball.java | 2 +- common/src/common/item/ItemSpade.java | 28 -- common/src/common/item/ItemSword.java | 6 +- common/src/common/item/ItemTool.java | 146 ++++------ common/src/common/item/ItemWand.java | 2 +- common/src/common/material/Material.java | 228 --------------- .../common/material/MaterialColdFluid.java | 24 -- .../src/common/material/MaterialHotFluid.java | 24 -- common/src/common/material/MaterialLogic.java | 28 -- .../src/common/material/MaterialPortal.java | 28 -- .../common/material/MaterialTransparent.java | 33 --- .../pathfinding/PathNavigateGround.java | 2 +- .../common/pathfinding/WalkNodeProcessor.java | 6 +- .../common/tileentity/TileEntityFurnace.java | 6 +- common/src/common/village/Village.java | 4 +- common/src/common/world/Chunk.java | 6 +- common/src/common/world/World.java | 4 +- server/src/server/biome/GenBiome.java | 4 +- .../src/server/village/VillageCollection.java | 4 +- server/src/server/world/WorldServer.java | 12 +- .../src/server/worldgen/FeatureDungeons.java | 2 +- server/src/server/worldgen/FeatureLakes.java | 4 +- .../feature/WorldGenAbandonedChest.java | 4 +- .../worldgen/foliage/WorldGenBigMushroom.java | 4 +- .../worldgen/foliage/WorldGenDeadBush.java | 4 +- .../server/worldgen/foliage/WorldGenReed.java | 4 +- .../worldgen/foliage/WorldGenShrub.java | 4 +- .../worldgen/foliage/WorldGenTallGrass.java | 4 +- .../worldgen/tree/WorldGenBaseTree.java | 8 +- .../server/worldgen/tree/WorldGenBigTree.java | 4 +- .../server/worldgen/tree/WorldGenBirch.java | 6 +- .../server/worldgen/tree/WorldGenDarkOak.java | 4 +- .../worldgen/tree/WorldGenHugeTree.java | 6 +- .../server/worldgen/tree/WorldGenPine.java | 10 +- .../server/worldgen/tree/WorldGenSavanna.java | 8 +- .../server/worldgen/tree/WorldGenSwamp.java | 10 +- .../server/worldgen/tree/WorldGenTaiga1.java | 4 +- .../server/worldgen/tree/WorldGenTaiga2.java | 6 +- .../server/worldgen/tree/WorldGenTree.java | 4 +- 221 files changed, 1000 insertions(+), 1340 deletions(-) create mode 100755 common/src/common/block/Material.java create mode 100755 common/src/common/item/ItemShovel.java delete mode 100755 common/src/common/item/ItemSpade.java delete mode 100755 common/src/common/material/Material.java delete mode 100755 common/src/common/material/MaterialColdFluid.java delete mode 100755 common/src/common/material/MaterialHotFluid.java delete mode 100755 common/src/common/material/MaterialLogic.java delete mode 100755 common/src/common/material/MaterialPortal.java delete mode 100755 common/src/common/material/MaterialTransparent.java diff --git a/client/src/client/gui/container/GuiContainer.java b/client/src/client/gui/container/GuiContainer.java index 7ae0eb8..c88a15b 100755 --- a/client/src/client/gui/container/GuiContainer.java +++ b/client/src/client/gui/container/GuiContainer.java @@ -42,7 +42,7 @@ public abstract class GuiContainer extends Gui private static final List ITEM_LIST = Lists.newArrayList(); - private static CheatTab selectedTab = CheatTab.tabBlocks; + private static CheatTab selectedTab = CheatTab.BLOCKS; // /** The location of the inventory background texture */ // protected static final String inventoryBackground = "textures/gui/inventory.png"; @@ -1151,7 +1151,7 @@ public abstract class GuiContainer extends Gui protected void drawTab(CheatTab tab) { this.itemRender.zLevel = 100.0F; - ItemStack itemstack = tab.getIconItemStack(); + ItemStack itemstack = tab.getIcon(); GlState.enableDepth(); this.itemRender.renderItemAndEffectIntoGUI(itemstack, this.xSize + 2 + 18 * tab.getHorizontal() + 1, 9 * 18 + 4 + 20 * tab.getVertical() + 1); this.itemRender.zLevel = 0.0F; @@ -1176,7 +1176,7 @@ public abstract class GuiContainer extends Gui selectedTab = tab; this.dragSplittingSlots.clear(); ITEM_LIST.clear(); - tab.displayAllReleventItems(ITEM_LIST); + tab.filter(ITEM_LIST); this.currentScroll = 0.0F; } diff --git a/client/src/client/renderer/BlockRenderer.java b/client/src/client/renderer/BlockRenderer.java index ce1f00d..6a3ff0b 100755 --- a/client/src/client/renderer/BlockRenderer.java +++ b/client/src/client/renderer/BlockRenderer.java @@ -15,12 +15,12 @@ import client.renderer.texture.TextureAtlasSprite; import client.renderer.texture.TextureMap; import client.renderer.tileentity.TileEntityItemStackRenderer; import common.block.Block; +import common.block.Material; import common.block.liquid.BlockLiquid; import common.collect.Maps; import common.init.BlockRegistry; import common.init.FluidRegistry; import common.item.ItemStack; -import common.material.Material; import common.util.BlockPos; import common.util.ExtMath; import common.util.Facing; diff --git a/client/src/client/renderer/EntityRenderer.java b/client/src/client/renderer/EntityRenderer.java index 919707d..6caa036 100755 --- a/client/src/client/renderer/EntityRenderer.java +++ b/client/src/client/renderer/EntityRenderer.java @@ -16,6 +16,7 @@ import client.renderer.texture.TextureMap; import client.world.WorldClient; import common.biome.Biome; import common.block.Block; +import common.block.Material; import common.entity.Entity; import common.entity.npc.EntityNPC; import common.entity.types.EntityAnimal; @@ -23,7 +24,6 @@ import common.entity.types.EntityLiving; import common.init.Blocks; import common.init.Items; import common.init.SoundEvent; -import common.material.Material; import common.model.BlockLayer; import common.model.ParticleType; import common.potion.Potion; @@ -1155,7 +1155,7 @@ public class EntityRenderer { double d3 = this.random.doublev(); double d4 = this.random.doublev(); - if (temp >= 194.0f || block.getMaterial() == Material.lava) + if (temp >= 194.0f || block.getMaterial() == Material.LAVA) { if(temp >= 194.0f) { ++n; diff --git a/client/src/client/renderer/particle/EntityBubbleFX.java b/client/src/client/renderer/particle/EntityBubbleFX.java index 44c03f7..909b2b5 100755 --- a/client/src/client/renderer/particle/EntityBubbleFX.java +++ b/client/src/client/renderer/particle/EntityBubbleFX.java @@ -1,6 +1,6 @@ package client.renderer.particle; -import common.material.Material; +import common.block.Material; import common.util.BlockPos; import common.world.World; @@ -35,7 +35,7 @@ public class EntityBubbleFX extends EntityFX this.motionY *= 0.8500000238418579D; this.motionZ *= 0.8500000238418579D; - if (this.worldObj.getState(new BlockPos(this)).getBlock().getMaterial() != Material.water) + if (this.worldObj.getState(new BlockPos(this)).getBlock().getMaterial() != Material.WATER) { this.setDead(); } diff --git a/client/src/client/renderer/particle/EntityDownfallFX.java b/client/src/client/renderer/particle/EntityDownfallFX.java index 6b5191e..d8d69eb 100755 --- a/client/src/client/renderer/particle/EntityDownfallFX.java +++ b/client/src/client/renderer/particle/EntityDownfallFX.java @@ -1,8 +1,8 @@ package client.renderer.particle; import common.block.Block; +import common.block.Material; import common.block.liquid.BlockLiquid; -import common.material.Material; import common.util.BlockPos; import common.util.ExtMath; import common.world.State; diff --git a/client/src/client/renderer/particle/EntityDropParticleFX.java b/client/src/client/renderer/particle/EntityDropParticleFX.java index 6bed5e8..bce2874 100755 --- a/client/src/client/renderer/particle/EntityDropParticleFX.java +++ b/client/src/client/renderer/particle/EntityDropParticleFX.java @@ -1,7 +1,7 @@ package client.renderer.particle; +import common.block.Material; import common.block.liquid.BlockLiquid; -import common.material.Material; import common.model.ParticleType; import common.util.BlockPos; import common.util.ExtMath; @@ -21,7 +21,7 @@ public class EntityDropParticleFX extends EntityFX super(worldIn, xCoordIn, yCoordIn, zCoordIn, 0.0D, 0.0D, 0.0D); this.motionX = this.motionY = this.motionZ = 0.0D; - if (p_i1203_8_ == Material.water) + if (p_i1203_8_ == Material.WATER) { this.particleRed = 0.0F; this.particleGreen = 0.0F; @@ -45,7 +45,7 @@ public class EntityDropParticleFX extends EntityFX public int getBrightnessForRender(float partialTicks) { - return this.materialType == Material.water ? super.getBrightnessForRender(partialTicks) : 257; + return this.materialType == Material.WATER ? super.getBrightnessForRender(partialTicks) : 257; } /** @@ -53,7 +53,7 @@ public class EntityDropParticleFX extends EntityFX */ public float getBrightness(float partialTicks) { - return this.materialType == Material.water ? super.getBrightness(partialTicks) : 1.0F; + return this.materialType == Material.WATER ? super.getBrightness(partialTicks) : 1.0F; } /** @@ -65,7 +65,7 @@ public class EntityDropParticleFX extends EntityFX this.prevY = this.posY; this.prevZ = this.posZ; - if (this.materialType == Material.water) + if (this.materialType == Material.WATER) { this.particleRed = 0.2F; this.particleGreen = 0.3F; @@ -104,7 +104,7 @@ public class EntityDropParticleFX extends EntityFX if (this.onGround) { - if (this.materialType == Material.water) + if (this.materialType == Material.WATER) { this.setDead(); this.worldObj.spawnParticle(ParticleType.WATER_SPLASH, this.posX, this.posY, this.posZ, 0.0D, 0.0D, 0.0D); @@ -144,7 +144,7 @@ public class EntityDropParticleFX extends EntityFX { public EntityFX getEntityFX(int particleID, World worldIn, double xCoordIn, double yCoordIn, double zCoordIn, double xSpeedIn, double ySpeedIn, double zSpeedIn, int... p_178902_15_) { - return new EntityDropParticleFX(worldIn, xCoordIn, yCoordIn, zCoordIn, Material.lava); + return new EntityDropParticleFX(worldIn, xCoordIn, yCoordIn, zCoordIn, Material.LAVA); } } @@ -152,7 +152,7 @@ public class EntityDropParticleFX extends EntityFX { public EntityFX getEntityFX(int particleID, World worldIn, double xCoordIn, double yCoordIn, double zCoordIn, double xSpeedIn, double ySpeedIn, double zSpeedIn, int... p_178902_15_) { - return new EntityDropParticleFX(worldIn, xCoordIn, yCoordIn, zCoordIn, Material.water); + return new EntityDropParticleFX(worldIn, xCoordIn, yCoordIn, zCoordIn, Material.WATER); } } } diff --git a/client/src/client/renderer/particle/EntitySuspendFX.java b/client/src/client/renderer/particle/EntitySuspendFX.java index 4047b03..2e9893f 100755 --- a/client/src/client/renderer/particle/EntitySuspendFX.java +++ b/client/src/client/renderer/particle/EntitySuspendFX.java @@ -1,6 +1,6 @@ package client.renderer.particle; -import common.material.Material; +import common.block.Material; import common.util.BlockPos; import common.world.World; @@ -31,7 +31,7 @@ public class EntitySuspendFX extends EntityFX this.prevZ = this.posZ; this.moveEntity(this.motionX, this.motionY, this.motionZ); - if (this.worldObj.getState(new BlockPos(this)).getBlock().getMaterial() != Material.water) + if (this.worldObj.getState(new BlockPos(this)).getBlock().getMaterial() != Material.WATER) { this.setDead(); } diff --git a/common/src/common/ai/EntityAIDoorInteract.java b/common/src/common/ai/EntityAIDoorInteract.java index dc1d8e5..e98a1f4 100755 --- a/common/src/common/ai/EntityAIDoorInteract.java +++ b/common/src/common/ai/EntityAIDoorInteract.java @@ -1,9 +1,9 @@ package common.ai; import common.block.Block; +import common.block.Material; import common.block.artificial.BlockDoor; import common.entity.types.EntityLiving; -import common.material.Material; import common.pathfinding.PathEntity; import common.pathfinding.PathNavigateGround; import common.pathfinding.PathPoint; @@ -113,6 +113,6 @@ public abstract class EntityAIDoorInteract extends EntityAIBase private BlockDoor getBlockDoor(BlockPos pos) { Block block = this.theEntity.worldObj.getState(pos).getBlock(); - return block instanceof BlockDoor && block.getMaterial() == Material.wood ? (BlockDoor)block : null; + return block instanceof BlockDoor && block.getMaterial() == Material.WOOD ? (BlockDoor)block : null; } } diff --git a/common/src/common/block/Block.java b/common/src/common/block/Block.java index 94fc8bc..d25e4d7 100755 --- a/common/src/common/block/Block.java +++ b/common/src/common/block/Block.java @@ -29,7 +29,6 @@ import common.init.ItemRegistry; import common.item.CheatTab; import common.item.Item; import common.item.ItemStack; -import common.material.Material; import common.model.BlockLayer; import common.model.Model; import common.model.ModelProvider; @@ -265,9 +264,9 @@ public class Block { } public Block(Material material) { - this.miningLevel = (material == Material.rock || material == Material.iron || material == Material.anvil) ? 0 : -1; - this.axeHarvest = material == Material.wood || material == Material.plants || material == Material.vine || material == Material.gourd; - this.shearsEfficiency = (material == Material.leaves || material == Material.web) ? 3 : -1; + this.miningLevel = (material == Material.SOLID || material == Material.HEAVY) ? 0 : -1; + this.axeHarvest = material == Material.WOOD || material == Material.PLANT || material == Material.BUSH || material == Material.SOFT; + this.shearsEfficiency = (material == Material.LEAVES || material == Material.FLUFF) ? 3 : -1; this.sound = SoundType.STONE; this.slipperiness = 0.6F; this.material = material; @@ -495,10 +494,6 @@ public class Block { : !worldIn.getState(pos).getBlock().isOpaqueCube()))))); } - public boolean isBlockSolid(IBlockAccess worldIn, BlockPos pos, Facing side) { - return worldIn.getState(pos).getBlock().getMaterial().isSolid(); - } - public BoundingBox getSelectedBoundingBox(World worldIn, BlockPos pos) { return new BoundingBox((double)pos.getX() + this.minX, (double)pos.getY() + this.minY, (double)pos.getZ() + this.minZ, (double)pos.getX() + this.maxX, (double)pos.getY() + this.maxY, (double)pos.getZ() + this.maxZ); @@ -760,7 +755,7 @@ public class Block { } public boolean canPlaceBlockAt(World worldIn, BlockPos pos) { - return worldIn.getState(pos).getBlock().material.isReplaceable(); + return worldIn.getState(pos).getBlock().getMaterial().isReplaceable(); } public boolean onBlockActivated(World worldIn, BlockPos pos, State state, EntityNPC playerIn, Facing side, float hitX, float hitY, float hitZ) { @@ -887,7 +882,7 @@ public class Block { } public int getMobilityFlag() { - return this.material.getMaterialMobility(); + return this.material.getMobility(); } public float getAmbientOcclusionLightValue() { diff --git a/common/src/common/block/BlockAir.java b/common/src/common/block/BlockAir.java index a5177a8..588e87e 100755 --- a/common/src/common/block/BlockAir.java +++ b/common/src/common/block/BlockAir.java @@ -1,6 +1,5 @@ package common.block; -import common.material.MaterialTransparent; import common.util.BlockPos; import common.util.BoundingBox; import common.world.State; @@ -8,7 +7,7 @@ import common.world.World; public final class BlockAir extends Block { public BlockAir() { - super(new MaterialTransparent()); + super(Material.NONE); } public int getRenderType() { diff --git a/common/src/common/block/BlockColored.java b/common/src/common/block/BlockColored.java index ae9af9d..6ff3755 100755 --- a/common/src/common/block/BlockColored.java +++ b/common/src/common/block/BlockColored.java @@ -6,7 +6,6 @@ import common.color.DyeColor; import common.item.CheatTab; import common.item.Item; import common.item.ItemStack; -import common.material.Material; import common.model.Model; import common.model.ModelProvider; import common.properties.IProperty; @@ -19,7 +18,7 @@ public class BlockColored extends Block { public BlockColored(Material material) { super(material); this.setDefaultState(this.getBaseState().withProperty(COLOR, DyeColor.WHITE)); - this.setTab(CheatTab.tabBlocks); + this.setTab(CheatTab.BLOCKS); } public int damageDropped(State state) { diff --git a/common/src/common/block/BlockContainer.java b/common/src/common/block/BlockContainer.java index 8c1a06f..561a8a8 100755 --- a/common/src/common/block/BlockContainer.java +++ b/common/src/common/block/BlockContainer.java @@ -1,6 +1,5 @@ package common.block; -import common.material.Material; import common.tileentity.TileEntity; import common.util.BlockPos; import common.util.Facing; @@ -15,7 +14,7 @@ public abstract class BlockContainer extends Block implements ITileEntityProvide } protected boolean isInvalidNeighbor(World world, BlockPos pos, Facing face) { - return world.getState(pos.offset(face)).getBlock().getMaterial() == Material.cactus; + return world.getState(pos.offset(face)).getBlock().getMaterial() == Material.BLOCKING; } protected boolean hasInvalidNeighbor(World world, BlockPos pos) { diff --git a/common/src/common/block/BlockDirectional.java b/common/src/common/block/BlockDirectional.java index bd75e9c..0cb7a7a 100755 --- a/common/src/common/block/BlockDirectional.java +++ b/common/src/common/block/BlockDirectional.java @@ -1,6 +1,5 @@ package common.block; -import common.material.Material; import common.properties.PropertyDirection; import common.util.Facing; diff --git a/common/src/common/block/BlockFalling.java b/common/src/common/block/BlockFalling.java index 41ebf28..2643515 100755 --- a/common/src/common/block/BlockFalling.java +++ b/common/src/common/block/BlockFalling.java @@ -4,7 +4,6 @@ import common.block.natural.BlockFire; import common.entity.item.EntityFalling; import common.init.Blocks; import common.init.Config; -import common.material.Material; import common.rng.Random; import common.util.BlockPos; import common.world.State; @@ -16,7 +15,7 @@ public class BlockFalling extends Block { public static boolean canFallInto(World world, BlockPos pos) { Block block = world.getState(pos).getBlock(); - return block instanceof BlockFire || block == Blocks.air || block.material.isLiquid(); + return block instanceof BlockFire || block == Blocks.air || block.getMaterial().isLiquid(); } public BlockFalling(Material material) { diff --git a/common/src/common/block/BlockRotatedPillar.java b/common/src/common/block/BlockRotatedPillar.java index 3c72302..5071e8a 100755 --- a/common/src/common/block/BlockRotatedPillar.java +++ b/common/src/common/block/BlockRotatedPillar.java @@ -1,6 +1,5 @@ package common.block; -import common.material.Material; import common.model.Model; import common.model.ModelProvider; import common.model.ModelRotation; diff --git a/common/src/common/block/BlockTranslucent.java b/common/src/common/block/BlockTranslucent.java index d8466d4..e74012f 100755 --- a/common/src/common/block/BlockTranslucent.java +++ b/common/src/common/block/BlockTranslucent.java @@ -1,6 +1,5 @@ package common.block; -import common.material.Material; import common.model.BlockLayer; import common.util.BlockPos; import common.util.Facing; diff --git a/common/src/common/block/BlockTreasure.java b/common/src/common/block/BlockTreasure.java index d855f06..b5548e0 100755 --- a/common/src/common/block/BlockTreasure.java +++ b/common/src/common/block/BlockTreasure.java @@ -1,7 +1,5 @@ package common.block; -import common.material.Material; - public class BlockTreasure extends Block { public BlockTreasure(Material material) { super(material); diff --git a/common/src/common/block/Material.java b/common/src/common/block/Material.java new file mode 100755 index 0000000..5abbdb0 --- /dev/null +++ b/common/src/common/block/Material.java @@ -0,0 +1,192 @@ +package common.block; + +public enum Material { + NONE {{ + this.setNonSolid().setReplaceable(); + }}, + LOOSE {{ + ; + }}, + WOOD {{ + this.setBurning(); + }}, + SOLID {{ + this.setRequiresTool(); + }}, + DIGGABLE {{ // can harvest with shovel + this.setRequiresTool(); + }}, + TRANSLUCENT {{ + this.setTranslucent(); + }}, + BURNABLE {{ + this.setBurning(); + }}, + SOFT {{ // can break faster with sword, can't connect to fences+walls + this.setNoPushMobility(); + }}, + PISTON {{ + this.setImmovableMobility(); + }}, + HEAVY {{ + this.setRequiresTool().setImmovableMobility(); + }}, + PLANT {{ // can break faster with sword + this.setNonSolid().setNoPushMobility(); + }}, + SMALL {{ // can be placed more easily + this.setNonSolid().setNoPushMobility(); + }}, + FLEECE {{ + this.setNonSolid().setBurning(); + }}, + EXPLOSIVE {{ + this.setBurning().setTranslucent(); + }}, + BLOCKING {{ // can't be placed next to signs and banners + this.setTranslucent().setNoPushMobility(); + }}, + PORTAL {{ // not floodable by liquids + this.setNonSolid().setImmovableMobility(); + }}, + WATER {{ + this.setLiquid(false).setReplaceable().setNoPushMobility(); + }}, + COLD {{ + this.setLiquid(false).setReplaceable().setNoPushMobility(); + }}, + LAVA {{ + this.setLiquid(true).setReplaceable().setNoPushMobility(); + }}, + HOT {{ + this.setLiquid(true).setReplaceable().setNoPushMobility(); + }}, + LEAVES {{ // can break faster with sword, precipitation block, special treatment in some worldgen + this.setBurning().setTranslucent().setNoPushMobility(); + }}, + BUSH {{ // can break faster with sword, can be replaced by small tree leaves + this.setNonSolid().setBurning().setNoPushMobility().setReplaceable(); + }}, + FIRE {{ + this.setNonSolid().setReplaceable().setNoPushMobility(); + }}, + POWDER {{ // can harvest with shovel, precipitation block + this.setNonSolid().setReplaceable().setRequiresTool().setNoPushMobility(); + }}, + FLUFF {{ // can harvest with shears + this.setPassable().setRequiresTool().setNoPushMobility(); + }}; + + private boolean solid = true; + private boolean lightOpaque = true; + private boolean unpassable = true; + private boolean opaque = true; + private boolean liquid; + private boolean cold; + private boolean hot; + private boolean burnable; + private boolean replaceable; + private boolean requiresTool; + // 0 - normal; 1 - can't push other blocks; 2 - can't be pushed + private int mobility; + + protected Material setTranslucent() { + this.opaque = false; + return this; + } + + protected Material setNonSolid() { + this.solid = false; + this.lightOpaque = false; + this.unpassable = false; + this.opaque = false; + return this; + } + + protected Material setPassable() { + this.unpassable = false; + this.opaque = false; + return this; + } + + protected Material setLiquid(boolean hot) { + this.solid = false; + this.unpassable = false; + this.opaque = false; + this.liquid = true; + if(hot) + this.hot = true; + else + this.cold = true; + return this; + } + + protected Material setRequiresTool() { + this.requiresTool = true; + return this; + } + + protected Material setBurning() { + this.burnable = true; + return this; + } + + protected Material setReplaceable() { + this.replaceable = true; + return this; + } + + protected Material setNoPushMobility() { + this.mobility = 1; + return this; + } + + protected Material setImmovableMobility() { + this.mobility = 2; + return this; + } + + public boolean isLiquid() { + return this.liquid; + } + + public boolean isColdLiquid() { + return this.cold; + } + + public boolean isHotLiquid() { + return this.hot; + } + + public boolean isSolid() { + return this.solid; + } + + public boolean blocksLight() { + return this.lightOpaque; + } + + public boolean blocksMovement() { + return this.unpassable; + } + + public boolean getCanBurn() { + return this.burnable; + } + + public boolean isReplaceable() { + return this.replaceable; + } + + public boolean isOpaque() { + return this.opaque; + } + + public boolean isToolRequired() { + return this.requiresTool; + } + + public int getMobility() { + return this.mobility; + } +} diff --git a/common/src/common/block/artificial/BlockBed.java b/common/src/common/block/artificial/BlockBed.java index 057a671..371619d 100755 --- a/common/src/common/block/artificial/BlockBed.java +++ b/common/src/common/block/artificial/BlockBed.java @@ -2,12 +2,12 @@ package common.block.artificial; import common.block.Block; import common.block.BlockDirectional; +import common.block.Material; import common.color.DyeColor; import common.color.TextColor; import common.entity.npc.EntityNPC; import common.init.ItemRegistry; import common.item.Item; -import common.material.Material; import common.model.BlockLayer; import common.model.Model; import common.model.ModelProvider; @@ -50,7 +50,7 @@ public class BlockBed extends BlockDirectional { private final DyeColor color; public BlockBed(DyeColor color) { - super(Material.cloth); + super(Material.BURNABLE); this.color = color; this.setDefaultState(this.getBaseState().withProperty(PART, BlockBed.EnumPartType.FOOT)); this.setBedBounds(); diff --git a/common/src/common/block/artificial/BlockBookshelf.java b/common/src/common/block/artificial/BlockBookshelf.java index 1a05805..756f574 100755 --- a/common/src/common/block/artificial/BlockBookshelf.java +++ b/common/src/common/block/artificial/BlockBookshelf.java @@ -1,10 +1,10 @@ package common.block.artificial; import common.block.Block; +import common.block.Material; import common.init.Items; import common.item.CheatTab; import common.item.Item; -import common.material.Material; import common.model.Model; import common.model.ModelProvider; import common.rng.Random; @@ -14,8 +14,8 @@ public class BlockBookshelf extends Block { public BlockBookshelf() { - super(Material.wood); - this.setTab(CheatTab.tabDeco); + super(Material.WOOD); + this.setTab(CheatTab.DECORATION); } /** diff --git a/common/src/common/block/artificial/BlockCake.java b/common/src/common/block/artificial/BlockCake.java index 7416723..425c641 100755 --- a/common/src/common/block/artificial/BlockCake.java +++ b/common/src/common/block/artificial/BlockCake.java @@ -1,10 +1,10 @@ package common.block.artificial; import common.block.Block; +import common.block.Material; import common.entity.npc.EntityNPC; import common.init.Items; import common.item.Item; -import common.material.Material; import common.model.BlockLayer; import common.model.Model; import common.model.ModelProvider; @@ -90,7 +90,7 @@ public class BlockCake extends Block public BlockCake() { - super(Material.cake); + super(Material.SOFT); this.setDefaultState(this.getBaseState().withProperty(BITES, Integer.valueOf(0))); // this.setTickRandomly(true); } diff --git a/common/src/common/block/artificial/BlockCarpet.java b/common/src/common/block/artificial/BlockCarpet.java index b65b714..6deb687 100755 --- a/common/src/common/block/artificial/BlockCarpet.java +++ b/common/src/common/block/artificial/BlockCarpet.java @@ -3,11 +3,11 @@ package common.block.artificial; import java.util.List; import common.block.Block; +import common.block.Material; import common.color.DyeColor; import common.item.CheatTab; import common.item.Item; import common.item.ItemStack; -import common.material.Material; import common.model.Model; import common.model.ModelProvider; import common.model.Transforms; @@ -25,11 +25,11 @@ public class BlockCarpet extends Block public BlockCarpet() { - super(Material.carpet); + super(Material.FLEECE); this.setDefaultState(this.getBaseState().withProperty(COLOR, DyeColor.WHITE)); this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 0.0625F, 1.0F); // this.setTickRandomly(true); - this.setTab(CheatTab.tabDeco); + this.setTab(CheatTab.DECORATION); this.setBlockBoundsFromMeta(0); } diff --git a/common/src/common/block/artificial/BlockCompressedPowered.java b/common/src/common/block/artificial/BlockCompressedPowered.java index 94f5d1d..bd2af8d 100755 --- a/common/src/common/block/artificial/BlockCompressedPowered.java +++ b/common/src/common/block/artificial/BlockCompressedPowered.java @@ -1,7 +1,7 @@ package common.block.artificial; import common.block.Block; -import common.material.Material; +import common.block.Material; import common.util.BlockPos; import common.util.Facing; import common.world.IWorldAccess; diff --git a/common/src/common/block/artificial/BlockDoor.java b/common/src/common/block/artificial/BlockDoor.java index a57ff29..0747230 100755 --- a/common/src/common/block/artificial/BlockDoor.java +++ b/common/src/common/block/artificial/BlockDoor.java @@ -3,12 +3,12 @@ package common.block.artificial; import java.util.List; import common.block.Block; +import common.block.Material; import common.collect.Lists; import common.entity.npc.EntityNPC; import common.init.Blocks; import common.init.Items; import common.item.Item; -import common.material.Material; import common.model.BlockLayer; import common.model.Model; import common.model.ModelProvider; @@ -163,7 +163,7 @@ public class BlockDoor extends Block public boolean onBlockActivated(World worldIn, BlockPos pos, State state, EntityNPC playerIn, Facing side, float hitX, float hitY, float hitZ) { - if (this.material == Material.iron) + if (this.material == Material.SOLID) { return true; } diff --git a/common/src/common/block/artificial/BlockDragonEgg.java b/common/src/common/block/artificial/BlockDragonEgg.java index 505977d..4fb515b 100755 --- a/common/src/common/block/artificial/BlockDragonEgg.java +++ b/common/src/common/block/artificial/BlockDragonEgg.java @@ -2,11 +2,11 @@ package common.block.artificial; import common.block.Block; import common.block.BlockFalling; +import common.block.Material; import common.entity.item.EntityFalling; import common.entity.npc.EntityNPC; import common.init.Blocks; import common.init.Config; -import common.material.Material; import common.model.Model; import common.model.ModelProvider; import common.model.ParticleType; @@ -81,7 +81,7 @@ public class BlockDragonEgg extends Block public BlockDragonEgg() { - super(Material.dragonEgg); + super(Material.SOFT); this.setBlockBounds(0.0625F, 0.0F, 0.0625F, 0.9375F, 1.0F, 0.9375F); } diff --git a/common/src/common/block/artificial/BlockFence.java b/common/src/common/block/artificial/BlockFence.java index f13437d..dfd3cad 100755 --- a/common/src/common/block/artificial/BlockFence.java +++ b/common/src/common/block/artificial/BlockFence.java @@ -3,12 +3,12 @@ package common.block.artificial; import java.util.List; import common.block.Block; +import common.block.Material; import common.collect.Lists; import common.entity.Entity; import common.entity.npc.EntityNPC; import common.item.CheatTab; import common.item.ItemLead; -import common.material.Material; import common.model.Model; import common.model.ModelProvider; import common.model.ModelRotation; @@ -44,7 +44,7 @@ public class BlockFence extends Block { super(p_i46395_1_); this.setDefaultState(this.getBaseState().withProperty(NORTH, Boolean.valueOf(false)).withProperty(EAST, Boolean.valueOf(false)).withProperty(SOUTH, Boolean.valueOf(false)).withProperty(WEST, Boolean.valueOf(false))); - this.setTab(p_i46395_1_ == Material.wood ? CheatTab.tabWood : CheatTab.tabBlocks); + this.setTab(p_i46395_1_ == Material.WOOD ? CheatTab.WOOD : CheatTab.BLOCKS); this.texture = texture; FENCES.add(this); } @@ -166,7 +166,7 @@ public class BlockFence extends Block public boolean canConnectTo(IBlockAccess worldIn, BlockPos pos) { Block block = worldIn.getState(pos).getBlock(); - return ((!(block instanceof BlockFence) || block.getMaterial() != this.material) && !(block instanceof BlockFenceGate) ? (block.getMaterial().isOpaque() && block.isFullCube() ? block.getMaterial() != Material.gourd : false) : true); + return ((!(block instanceof BlockFence) || block.getMaterial() != this.material) && !(block instanceof BlockFenceGate) ? (block.getMaterial().isOpaque() && block.isFullCube() ? block.getMaterial() != Material.SOFT : false) : true); } public boolean shouldSideBeRendered(IWorldAccess worldIn, BlockPos pos, Facing side) diff --git a/common/src/common/block/artificial/BlockFenceGate.java b/common/src/common/block/artificial/BlockFenceGate.java index 41305d5..85314c9 100755 --- a/common/src/common/block/artificial/BlockFenceGate.java +++ b/common/src/common/block/artificial/BlockFenceGate.java @@ -2,12 +2,12 @@ package common.block.artificial; import common.block.Block; import common.block.BlockDirectional; +import common.block.Material; import common.entity.npc.EntityNPC; import common.entity.types.EntityLiving; import common.init.Blocks; import common.init.WoodType; import common.item.CheatTab; -import common.material.Material; import common.model.Model; import common.model.ModelProvider; import common.model.ModelRotation; @@ -32,9 +32,9 @@ public class BlockFenceGate extends BlockDirectional public BlockFenceGate(WoodType p_i46394_1_) { - super(Material.wood); // , p_i46394_1_.getMapColor()); + super(Material.WOOD); // , p_i46394_1_.getMapColor()); this.setDefaultState(this.getBaseState().withProperty(OPEN, Boolean.valueOf(false)).withProperty(POWERED, Boolean.valueOf(false)).withProperty(IN_WALL, Boolean.valueOf(false))); - this.setTab(CheatTab.tabWood); + this.setTab(CheatTab.WOOD); this.texture = p_i46394_1_.getName() + "_planks"; } diff --git a/common/src/common/block/artificial/BlockFloorPortal.java b/common/src/common/block/artificial/BlockFloorPortal.java index 7ae4afc..c9b3c33 100755 --- a/common/src/common/block/artificial/BlockFloorPortal.java +++ b/common/src/common/block/artificial/BlockFloorPortal.java @@ -5,10 +5,10 @@ import java.util.Map; import java.util.Set; import common.block.Block; +import common.block.Material; import common.collect.Sets; import common.entity.Entity; import common.item.Item; -import common.material.Material; import common.model.Model; import common.model.ModelProvider; import common.model.ParticleType; diff --git a/common/src/common/block/artificial/BlockFlowerPot.java b/common/src/common/block/artificial/BlockFlowerPot.java index 85884a6..6f68e0c 100755 --- a/common/src/common/block/artificial/BlockFlowerPot.java +++ b/common/src/common/block/artificial/BlockFlowerPot.java @@ -1,6 +1,7 @@ package common.block.artificial; import common.block.Block; +import common.block.Material; import common.block.foliage.BlockFlower; import common.entity.npc.EntityNPC; import common.init.Blocks; @@ -9,7 +10,6 @@ import common.init.Items; import common.item.Item; import common.item.ItemBlock; import common.item.ItemStack; -import common.material.Material; import common.model.BlockLayer; import common.model.Model; import common.model.ModelProvider; @@ -103,7 +103,7 @@ public class BlockFlowerPot extends Block // Container public BlockFlowerPot() { - super(Material.circuits); + super(Material.SMALL); this.setDefaultState(this.getBaseState().withProperty(CONTENTS, 0)); // .withProperty(LEGACY_DATA, Integer.valueOf(0))); this.setBlockBoundsForItemRender(); } diff --git a/common/src/common/block/artificial/BlockGlass.java b/common/src/common/block/artificial/BlockGlass.java index fb3fe69..feb69da 100755 --- a/common/src/common/block/artificial/BlockGlass.java +++ b/common/src/common/block/artificial/BlockGlass.java @@ -1,8 +1,8 @@ package common.block.artificial; import common.block.Block; +import common.block.Material; import common.item.CheatTab; -import common.material.Material; import common.model.BlockLayer; import common.rng.Random; import common.util.BlockPos; @@ -12,8 +12,8 @@ import common.world.State; public class BlockGlass extends Block { public BlockGlass() { - super(Material.glass); - this.setTab(CheatTab.tabBlocks); + super(Material.TRANSLUCENT); + this.setTab(CheatTab.BLOCKS); } public int quantityDropped(Random rand) { diff --git a/common/src/common/block/artificial/BlockHay.java b/common/src/common/block/artificial/BlockHay.java index e57d006..eefc04f 100755 --- a/common/src/common/block/artificial/BlockHay.java +++ b/common/src/common/block/artificial/BlockHay.java @@ -1,11 +1,11 @@ package common.block.artificial; import common.block.BlockRotatedPillar; +import common.block.Material; import common.entity.types.EntityLiving; import common.init.ItemRegistry; import common.item.CheatTab; import common.item.ItemStack; -import common.material.Material; import common.properties.IProperty; import common.util.BlockPos; import common.util.Facing; @@ -16,9 +16,9 @@ public class BlockHay extends BlockRotatedPillar { public BlockHay() { - super(Material.grass); + super(Material.LOOSE); this.setDefaultState(this.getBaseState().withProperty(AXIS, Facing.Axis.Y)); - this.setTab(CheatTab.tabBlocks); + this.setTab(CheatTab.BLOCKS); } /** diff --git a/common/src/common/block/artificial/BlockLadder.java b/common/src/common/block/artificial/BlockLadder.java index b858fa4..1400468 100755 --- a/common/src/common/block/artificial/BlockLadder.java +++ b/common/src/common/block/artificial/BlockLadder.java @@ -2,9 +2,9 @@ package common.block.artificial; import common.block.Block; import common.block.BlockDirectional; +import common.block.Material; import common.entity.types.EntityLiving; import common.item.CheatTab; -import common.material.Material; import common.model.BlockLayer; import common.model.Model; import common.model.ModelProvider; @@ -24,9 +24,9 @@ public class BlockLadder extends Block public BlockLadder() { - super(Material.circuits); + super(Material.SMALL); this.setDefaultState(this.getBaseState().withProperty(FACING, Facing.NORTH)); - this.setTab(CheatTab.tabWood); + this.setTab(CheatTab.WOOD); } public BoundingBox getCollisionBoundingBox(World worldIn, BlockPos pos, State state) diff --git a/common/src/common/block/artificial/BlockPane.java b/common/src/common/block/artificial/BlockPane.java index 7637b62..39e3da2 100755 --- a/common/src/common/block/artificial/BlockPane.java +++ b/common/src/common/block/artificial/BlockPane.java @@ -3,11 +3,11 @@ package common.block.artificial; import java.util.List; import common.block.Block; +import common.block.Material; import common.entity.Entity; import common.init.Blocks; import common.item.CheatTab; import common.item.Item; -import common.material.Material; import common.model.BlockLayer; import common.model.Model; import common.model.ModelProvider; @@ -35,7 +35,7 @@ public class BlockPane extends Block super(materialIn); this.setDefaultState(this.getBaseState().withProperty(NORTH, Boolean.valueOf(false)).withProperty(EAST, Boolean.valueOf(false)).withProperty(SOUTH, Boolean.valueOf(false)).withProperty(WEST, Boolean.valueOf(false))); this.canDrop = canDrop; - this.setTab(CheatTab.tabBlocks); + this.setTab(CheatTab.BLOCKS); } /** @@ -207,7 +207,7 @@ public class BlockPane extends Block } public boolean isMagnetic() { - return this.material == Material.iron; + return this.material == Material.SOLID; } protected String getPaneBase(State state) { diff --git a/common/src/common/block/artificial/BlockPortal.java b/common/src/common/block/artificial/BlockPortal.java index f072880..a140f4b 100755 --- a/common/src/common/block/artificial/BlockPortal.java +++ b/common/src/common/block/artificial/BlockPortal.java @@ -3,11 +3,11 @@ package common.block.artificial; import java.util.Map; import common.block.Block; +import common.block.Material; import common.block.natural.BlockFire; import common.entity.Entity; import common.init.Blocks; import common.item.Item; -import common.material.Material; import common.model.BlockLayer; import common.model.Model; import common.model.ModelProvider; @@ -34,7 +34,7 @@ public class BlockPortal extends Block public BlockPortal() { - super(Material.portal); + super(Material.PORTAL); this.setDefaultState(this.getBaseState().withProperty(AXIS, Facing.Axis.X).withProperty(DIM, 0)); // this.setTickRandomly(); } diff --git a/common/src/common/block/artificial/BlockPortalFrame.java b/common/src/common/block/artificial/BlockPortalFrame.java index 7be3dc0..0c5a300 100755 --- a/common/src/common/block/artificial/BlockPortalFrame.java +++ b/common/src/common/block/artificial/BlockPortalFrame.java @@ -3,6 +3,7 @@ package common.block.artificial; import java.util.List; import common.block.Block; +import common.block.Material; import common.entity.Entity; import common.entity.npc.EntityNPC; import common.entity.types.EntityLiving; @@ -11,7 +12,6 @@ import common.init.ItemRegistry; import common.init.Items; import common.item.Item; import common.item.ItemStack; -import common.material.Material; import common.model.Model; import common.model.ModelProvider; import common.model.ModelRotation; @@ -33,7 +33,7 @@ public class BlockPortalFrame extends Block public BlockPortalFrame() { - super(Material.rock); + super(Material.SOLID); this.setDefaultState(this.getBaseState().withProperty(FACING, Facing.NORTH).withProperty(ORB, Boolean.valueOf(false))); } diff --git a/common/src/common/block/artificial/BlockQuartz.java b/common/src/common/block/artificial/BlockQuartz.java index 8aa5018..5e78fc2 100755 --- a/common/src/common/block/artificial/BlockQuartz.java +++ b/common/src/common/block/artificial/BlockQuartz.java @@ -3,12 +3,12 @@ package common.block.artificial; import java.util.List; import common.block.Block; +import common.block.Material; import common.entity.types.EntityLiving; import common.init.ItemRegistry; import common.item.CheatTab; import common.item.Item; import common.item.ItemStack; -import common.material.Material; import common.model.Model; import common.model.ModelProvider; import common.model.ModelRotation; @@ -28,9 +28,9 @@ public class BlockQuartz extends Block public BlockQuartz(String prefix) { - super(Material.rock); + super(Material.SOLID); this.setDefaultState(this.getBaseState().withProperty(VARIANT, BlockQuartz.EnumType.DEFAULT)); - this.setTab(CheatTab.tabBlocks); + this.setTab(CheatTab.BLOCKS); this.prefix = prefix; } diff --git a/common/src/common/block/artificial/BlockSlab.java b/common/src/common/block/artificial/BlockSlab.java index 30c0ca2..223745c 100755 --- a/common/src/common/block/artificial/BlockSlab.java +++ b/common/src/common/block/artificial/BlockSlab.java @@ -3,13 +3,13 @@ package common.block.artificial; import java.util.List; import common.block.Block; +import common.block.Material; import common.collect.Lists; import common.entity.Entity; import common.entity.types.EntityLiving; import common.item.CheatTab; import common.item.Item; import common.item.ItemStack; -import common.material.Material; import common.model.Model; import common.model.ModelProvider; import common.properties.IProperty; @@ -44,7 +44,7 @@ public class BlockSlab extends Block super(materialIn); this.setDefaultState(this.getBaseState().withProperty(FACING, Facing.DOWN).withProperty(DOUBLE, false) .withProperty(SEAMLESS, false)); - this.setTab(materialIn == Material.wood ? CheatTab.tabWood : CheatTab.tabBlocks); + this.setTab(materialIn == Material.WOOD ? CheatTab.WOOD : CheatTab.BLOCKS); // this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, 0.5F); this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 0.5F, 1.0F); diff --git a/common/src/common/block/artificial/BlockStainedGlassPane.java b/common/src/common/block/artificial/BlockStainedGlassPane.java index 985dedd..9c29581 100755 --- a/common/src/common/block/artificial/BlockStainedGlassPane.java +++ b/common/src/common/block/artificial/BlockStainedGlassPane.java @@ -2,11 +2,11 @@ package common.block.artificial; import java.util.List; +import common.block.Material; import common.color.DyeColor; import common.item.CheatTab; import common.item.Item; import common.item.ItemStack; -import common.material.Material; import common.model.BlockLayer; import common.properties.IProperty; import common.properties.PropertyEnum; @@ -18,9 +18,9 @@ public class BlockStainedGlassPane extends BlockPane public BlockStainedGlassPane() { - super(Material.glass, false); + super(Material.TRANSLUCENT, false); this.setDefaultState(this.getBaseState().withProperty(NORTH, Boolean.valueOf(false)).withProperty(EAST, Boolean.valueOf(false)).withProperty(SOUTH, Boolean.valueOf(false)).withProperty(WEST, Boolean.valueOf(false)).withProperty(COLOR, DyeColor.WHITE)); - this.setTab(CheatTab.tabBlocks); + this.setTab(CheatTab.BLOCKS); } /** diff --git a/common/src/common/block/artificial/BlockStairs.java b/common/src/common/block/artificial/BlockStairs.java index 6631556..7eee78a 100755 --- a/common/src/common/block/artificial/BlockStairs.java +++ b/common/src/common/block/artificial/BlockStairs.java @@ -4,13 +4,13 @@ import java.util.Arrays; import java.util.List; import common.block.Block; +import common.block.Material; import common.entity.Entity; import common.entity.npc.EntityNPC; import common.entity.types.EntityLiving; import common.init.BlockRegistry; import common.init.Blocks; import common.item.CheatTab; -import common.material.Material; import common.model.BlockLayer; import common.model.Model; import common.model.ModelProvider; @@ -61,7 +61,7 @@ public class BlockStairs extends Block this.setResistance(this.modelBlock.getRawResistance() / 3.0F); this.setStepSound(this.modelBlock.sound); this.setLightOpacity(255); - this.setTab(modelState.getBlock().getMaterial() == Material.wood ? CheatTab.tabWood : CheatTab.tabBlocks); + this.setTab(modelState.getBlock().getMaterial() == Material.WOOD ? CheatTab.WOOD : CheatTab.BLOCKS); this.downTex = down; this.upTex = up; } diff --git a/common/src/common/block/artificial/BlockStoneBrick.java b/common/src/common/block/artificial/BlockStoneBrick.java index cf3b2e5..f0a7508 100755 --- a/common/src/common/block/artificial/BlockStoneBrick.java +++ b/common/src/common/block/artificial/BlockStoneBrick.java @@ -3,10 +3,10 @@ package common.block.artificial; import java.util.List; import common.block.Block; +import common.block.Material; import common.item.CheatTab; import common.item.Item; import common.item.ItemStack; -import common.material.Material; import common.model.Model; import common.model.ModelProvider; import common.properties.IProperty; @@ -24,9 +24,9 @@ public class BlockStoneBrick extends Block public BlockStoneBrick() { - super(Material.rock); + super(Material.SOLID); this.setDefaultState(this.getBaseState().withProperty(VARIANT, BlockStoneBrick.EnumType.DEFAULT)); - this.setTab(CheatTab.tabBlocks); + this.setTab(CheatTab.BLOCKS); } /** diff --git a/common/src/common/block/artificial/BlockTrapDoor.java b/common/src/common/block/artificial/BlockTrapDoor.java index ce757a3..3f970d6 100755 --- a/common/src/common/block/artificial/BlockTrapDoor.java +++ b/common/src/common/block/artificial/BlockTrapDoor.java @@ -1,11 +1,11 @@ package common.block.artificial; import common.block.Block; +import common.block.Material; import common.entity.npc.EntityNPC; import common.entity.types.EntityLiving; import common.init.Blocks; import common.item.CheatTab; -import common.material.Material; import common.model.BlockLayer; import common.model.Model; import common.model.ModelProvider; @@ -39,7 +39,7 @@ public class BlockTrapDoor extends Block float f = 0.5F; float f1 = 1.0F; this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F); - this.setTab(materialIn == Material.wood ? CheatTab.tabWood : CheatTab.tabTech); + this.setTab(materialIn == Material.WOOD ? CheatTab.WOOD : CheatTab.TECHNOLOGY); } /** @@ -131,7 +131,7 @@ public class BlockTrapDoor extends Block public boolean onBlockActivated(World worldIn, BlockPos pos, State state, EntityNPC playerIn, Facing side, float hitX, float hitY, float hitZ) { - if (this.material == Material.iron) + if (this.material == Material.SOLID) { return true; } @@ -293,7 +293,7 @@ public class BlockTrapDoor extends Block } public boolean isMagnetic() { - return this.material == Material.iron; + return this.material == Material.SOLID; } public Transforms getTransform() { diff --git a/common/src/common/block/artificial/BlockWall.java b/common/src/common/block/artificial/BlockWall.java index ad017d8..703eed4 100755 --- a/common/src/common/block/artificial/BlockWall.java +++ b/common/src/common/block/artificial/BlockWall.java @@ -3,11 +3,11 @@ package common.block.artificial; import java.util.List; import common.block.Block; +import common.block.Material; import common.init.Blocks; import common.item.CheatTab; import common.item.Item; import common.item.ItemStack; -import common.material.Material; import common.model.Model; import common.model.ModelProvider; import common.model.ModelRotation; @@ -39,7 +39,7 @@ public class BlockWall extends Block this.setHardness(modelBlock.getRawHardness()); this.setResistance(modelBlock.getRawResistance() / 3.0F); this.setStepSound(modelBlock.sound); - this.setTab(CheatTab.tabBlocks); + this.setTab(CheatTab.BLOCKS); } // /** @@ -126,7 +126,7 @@ public class BlockWall extends Block public boolean canConnectTo(IBlockAccess worldIn, BlockPos pos) { Block block = worldIn.getState(pos).getBlock(); - return (block != this && !(block instanceof BlockFenceGate) ? (block.getMaterial().isOpaque() && block.isFullCube() ? block.getMaterial() != Material.gourd : false) : true); + return (block != this && !(block instanceof BlockFenceGate) ? (block.getMaterial().isOpaque() && block.isFullCube() ? block.getMaterial() != Material.SOFT : false) : true); } /** diff --git a/common/src/common/block/foliage/BlockBlackenedSoil.java b/common/src/common/block/foliage/BlockBlackenedSoil.java index 03d9df4..2690e13 100644 --- a/common/src/common/block/foliage/BlockBlackenedSoil.java +++ b/common/src/common/block/foliage/BlockBlackenedSoil.java @@ -2,11 +2,11 @@ package common.block.foliage; import common.biome.Biome; import common.block.Block; +import common.block.Material; import common.init.Blocks; import common.init.Config; import common.item.CheatTab; import common.item.Item; -import common.material.Material; import common.model.Model; import common.model.ModelProvider; import common.rng.Random; @@ -18,9 +18,9 @@ public class BlockBlackenedSoil extends Block { public BlockBlackenedSoil() { - super(Material.grass); + super(Material.LOOSE); this.setTickRandomly(); - this.setTab(CheatTab.tabNature); + this.setTab(CheatTab.NATURE); } public void updateTick(AWorldServer worldIn, BlockPos pos, State state, Random rand) diff --git a/common/src/common/block/foliage/BlockBush.java b/common/src/common/block/foliage/BlockBush.java index 361bfeb..acc0c1b 100755 --- a/common/src/common/block/foliage/BlockBush.java +++ b/common/src/common/block/foliage/BlockBush.java @@ -1,9 +1,9 @@ package common.block.foliage; import common.block.Block; +import common.block.Material; import common.init.Blocks; import common.item.CheatTab; -import common.material.Material; import common.model.BlockLayer; import common.rng.Random; import common.util.BlockPos; @@ -16,7 +16,7 @@ public class BlockBush extends Block { public BlockBush() { - this(Material.plants); + this(Material.PLANT); } public BlockBush(Material p_i46452_1_) @@ -25,7 +25,7 @@ public class BlockBush extends Block this.setTickRandomly(); float f = 0.2F; this.setBlockBounds(0.5F - f, 0.0F, 0.5F - f, 0.5F + f, f * 3.0F, 0.5F + f); - this.setTab(CheatTab.tabPlants); + this.setTab(CheatTab.PLANTS); } public boolean canPlaceBlockAt(World worldIn, BlockPos pos) diff --git a/common/src/common/block/foliage/BlockCactus.java b/common/src/common/block/foliage/BlockCactus.java index 5504d57..5fe8b0b 100755 --- a/common/src/common/block/foliage/BlockCactus.java +++ b/common/src/common/block/foliage/BlockCactus.java @@ -1,12 +1,12 @@ package common.block.foliage; import common.block.Block; +import common.block.Material; import common.entity.DamageSource; import common.entity.Entity; import common.init.Blocks; import common.init.Config; import common.item.CheatTab; -import common.material.Material; import common.model.BlockLayer; import common.model.Model; import common.model.ModelProvider; @@ -38,10 +38,10 @@ public class BlockCactus extends Block public BlockCactus() { - super(Material.cactus); + super(Material.BLOCKING); this.setDefaultState(this.getBaseState().withProperty(AGE, Integer.valueOf(0))); this.setTickRandomly(); - this.setTab(CheatTab.tabPlants); + this.setTab(CheatTab.PLANTS); } public void updateTick(AWorldServer worldIn, BlockPos pos, State state, Random rand) diff --git a/common/src/common/block/foliage/BlockCocoa.java b/common/src/common/block/foliage/BlockCocoa.java index b8166d1..7c62bb9 100755 --- a/common/src/common/block/foliage/BlockCocoa.java +++ b/common/src/common/block/foliage/BlockCocoa.java @@ -2,6 +2,7 @@ package common.block.foliage; import common.block.Block; import common.block.BlockDirectional; +import common.block.Material; import common.color.DyeColor; import common.entity.types.EntityLiving; import common.init.Blocks; @@ -9,7 +10,6 @@ import common.init.Config; import common.init.Items; import common.item.Item; import common.item.ItemStack; -import common.material.Material; import common.model.BlockLayer; import common.model.Model; import common.model.ModelProvider; @@ -31,7 +31,7 @@ public class BlockCocoa extends BlockDirectional implements IGrowable public BlockCocoa() { - super(Material.plants); + super(Material.PLANT); this.setDefaultState(this.getBaseState().withProperty(FACING, Facing.NORTH).withProperty(AGE, Integer.valueOf(0))); this.setTickRandomly(); } diff --git a/common/src/common/block/foliage/BlockDeadBush.java b/common/src/common/block/foliage/BlockDeadBush.java index 87ae7aa..9e24f13 100755 --- a/common/src/common/block/foliage/BlockDeadBush.java +++ b/common/src/common/block/foliage/BlockDeadBush.java @@ -1,13 +1,13 @@ package common.block.foliage; import common.block.Block; +import common.block.Material; import common.entity.npc.EntityNPC; import common.init.Blocks; import common.init.Items; import common.item.Item; import common.item.ItemShears; import common.item.ItemStack; -import common.material.Material; import common.model.Model; import common.model.ModelProvider; import common.rng.Random; @@ -20,7 +20,7 @@ public class BlockDeadBush extends BlockBush { public BlockDeadBush() { - super(Material.vine); + super(Material.BUSH); float f = 0.4F; this.setBlockBounds(0.5F - f, 0.0F, 0.5F - f, 0.5F + f, 0.8F, 0.5F + f); } diff --git a/common/src/common/block/foliage/BlockDoublePlant.java b/common/src/common/block/foliage/BlockDoublePlant.java index b854fb7..fb4b135 100755 --- a/common/src/common/block/foliage/BlockDoublePlant.java +++ b/common/src/common/block/foliage/BlockDoublePlant.java @@ -4,6 +4,7 @@ import java.util.List; import common.block.Block; import common.block.BlockDirectional; +import common.block.Material; import common.block.SoundType; import common.color.Colorizer; import common.entity.npc.EntityNPC; @@ -16,7 +17,6 @@ import common.item.CheatTab; import common.item.Item; import common.item.ItemShears; import common.item.ItemStack; -import common.material.Material; import common.model.Model; import common.model.ModelProvider; import common.properties.IProperty; @@ -40,7 +40,7 @@ public class BlockDoublePlant extends BlockBush implements IGrowable public BlockDoublePlant() { - super(Material.vine); + super(Material.BUSH); this.setDefaultState(this.getBaseState().withProperty(VARIANT, BlockDoublePlant.EnumPlantType.SUNFLOWER).withProperty(HALF, BlockDoublePlant.EnumBlockHalf.LOWER).withProperty(FACING, Facing.NORTH)); this.setHardness(0.0F); this.setStepSound(SoundType.GRASS); diff --git a/common/src/common/block/foliage/BlockDryLeaves.java b/common/src/common/block/foliage/BlockDryLeaves.java index d0d363a..a227249 100755 --- a/common/src/common/block/foliage/BlockDryLeaves.java +++ b/common/src/common/block/foliage/BlockDryLeaves.java @@ -1,10 +1,10 @@ package common.block.foliage; +import common.block.Material; import common.block.SoundType; import common.init.Items; import common.item.CheatTab; import common.item.Item; -import common.material.Material; import common.rng.Random; import common.world.State; @@ -14,8 +14,8 @@ public class BlockDryLeaves extends BlockLeavesBase public BlockDryLeaves() { - super(Material.gourd); - this.setTab(CheatTab.tabPlants); + super(Material.SOFT); + this.setTab(CheatTab.PLANTS); this.setHardness(0.2F); this.setLightOpacity(1); this.setStepSound(SoundType.GRASS); diff --git a/common/src/common/block/foliage/BlockFarmland.java b/common/src/common/block/foliage/BlockFarmland.java index c195ff4..80dec93 100755 --- a/common/src/common/block/foliage/BlockFarmland.java +++ b/common/src/common/block/foliage/BlockFarmland.java @@ -1,6 +1,7 @@ package common.block.foliage; import common.block.Block; +import common.block.Material; import common.block.natural.BlockDirt; import common.entity.Entity; import common.entity.types.EntityLiving; @@ -8,7 +9,6 @@ import common.init.Blocks; import common.init.Config; import common.init.ItemRegistry; import common.item.Item; -import common.material.Material; import common.model.Model; import common.model.ModelProvider; import common.properties.IProperty; @@ -28,7 +28,7 @@ public class BlockFarmland extends Block public BlockFarmland() { - super(Material.ground); + super(Material.LOOSE); this.setDefaultState(this.getBaseState().withProperty(MOISTURE, Integer.valueOf(0))); this.setTickRandomly(); this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 0.9375F, 1.0F); @@ -103,7 +103,7 @@ public class BlockFarmland extends Block { for (BlockPos.MutableBlockPos blockpos$mutableblockpos : BlockPos.getAllInBoxMutable(pos.add(-4, 0, -4), pos.add(4, 1, 4))) { - if (worldIn.getState(blockpos$mutableblockpos).getBlock().getMaterial() == Material.water) + if (worldIn.getState(blockpos$mutableblockpos).getBlock().getMaterial() == Material.WATER) { return true; } diff --git a/common/src/common/block/foliage/BlockGrass.java b/common/src/common/block/foliage/BlockGrass.java index d121dd4..88f7c05 100755 --- a/common/src/common/block/foliage/BlockGrass.java +++ b/common/src/common/block/foliage/BlockGrass.java @@ -2,13 +2,13 @@ package common.block.foliage; import common.biome.IBiome; import common.block.Block; +import common.block.Material; import common.block.natural.BlockDirt; import common.color.Colorizer; import common.init.Blocks; import common.init.Config; import common.item.CheatTab; import common.item.Item; -import common.material.Material; import common.model.BlockLayer; import common.model.Model; import common.model.ModelProvider; @@ -27,10 +27,10 @@ public class BlockGrass extends Block implements IGrowable public BlockGrass() { - super(Material.grass); + super(Material.LOOSE); this.setDefaultState(this.getBaseState().withProperty(SNOWY, Boolean.valueOf(false))); this.setTickRandomly(); - this.setTab(CheatTab.tabNature); + this.setTab(CheatTab.NATURE); } /** diff --git a/common/src/common/block/foliage/BlockHugeMushroom.java b/common/src/common/block/foliage/BlockHugeMushroom.java index 57d8da5..873240b 100755 --- a/common/src/common/block/foliage/BlockHugeMushroom.java +++ b/common/src/common/block/foliage/BlockHugeMushroom.java @@ -1,10 +1,10 @@ package common.block.foliage; import common.block.Block; +import common.block.Material; import common.entity.types.EntityLiving; import common.init.ItemRegistry; import common.item.Item; -import common.material.Material; import common.model.Model; import common.model.ModelProvider; import common.properties.IProperty; diff --git a/common/src/common/block/foliage/BlockLeaves.java b/common/src/common/block/foliage/BlockLeaves.java index d3eaddb..a40c380 100755 --- a/common/src/common/block/foliage/BlockLeaves.java +++ b/common/src/common/block/foliage/BlockLeaves.java @@ -3,6 +3,7 @@ package common.block.foliage; import java.util.List; import common.block.Block; +import common.block.Material; import common.block.SoundType; import common.collect.Lists; import common.color.Colorizer; @@ -15,7 +16,6 @@ import common.item.CheatTab; import common.item.Item; import common.item.ItemShears; import common.item.ItemStack; -import common.material.Material; import common.model.Model; import common.model.ModelProvider; import common.model.ParticleType; @@ -43,11 +43,11 @@ public class BlockLeaves extends BlockLeavesBase public BlockLeaves(WoodType type) { - super(Material.leaves); + super(Material.LEAVES); this.type = type; this.setDefaultState(this.getBaseState().withProperty(TYPE, LeavesType.SPRING).withProperty(DECAY, Boolean.valueOf(true))); this.setTickRandomly(); - this.setTab(CheatTab.tabPlants); + this.setTab(CheatTab.PLANTS); this.setHardness(0.2F); this.setLightOpacity(1); this.setStepSound(SoundType.GRASS); @@ -88,7 +88,7 @@ public class BlockLeaves extends BlockLeavesBase BlockPos blockpos = pos.add(j1, k1, l1); State iblockstate = worldIn.getState(blockpos); - if (iblockstate.getBlock().getMaterial() == Material.leaves && !((Boolean)iblockstate.getValue(DECAY)).booleanValue()) + if (iblockstate.getBlock().getMaterial() == Material.LEAVES && !((Boolean)iblockstate.getValue(DECAY)).booleanValue()) { worldIn.setState(blockpos, iblockstate.withProperty(DECAY, Boolean.valueOf(true)), 4); } @@ -138,7 +138,7 @@ public class BlockLeaves extends BlockLeavesBase if (!(block instanceof BlockLog)) { - if (block.getMaterial() == Material.leaves) + if (block.getMaterial() == Material.LEAVES) { this.surroundings[(i2 + l1) * k1 + (j2 + l1) * j1 + k2 + l1] = -2; } diff --git a/common/src/common/block/foliage/BlockLeavesBase.java b/common/src/common/block/foliage/BlockLeavesBase.java index f2e8cad..1bf0fd0 100755 --- a/common/src/common/block/foliage/BlockLeavesBase.java +++ b/common/src/common/block/foliage/BlockLeavesBase.java @@ -1,7 +1,7 @@ package common.block.foliage; import common.block.Block; -import common.material.Material; +import common.block.Material; import common.model.BlockLayer; public class BlockLeavesBase extends Block diff --git a/common/src/common/block/foliage/BlockLilyPad.java b/common/src/common/block/foliage/BlockLilyPad.java index 42f22ba..c2273a7 100755 --- a/common/src/common/block/foliage/BlockLilyPad.java +++ b/common/src/common/block/foliage/BlockLilyPad.java @@ -30,7 +30,7 @@ public class BlockLilyPad extends BlockBush float f1 = 0.015625F; this.setBlockBounds(0.5F - f, 0.0F, 0.5F - f, 0.5F + f, f1, 0.5F + f); this.setDefaultState(this.getBaseState().withProperty(BlockDirectional.FACING, Facing.NORTH)); - this.setTab(CheatTab.tabPlants); + this.setTab(CheatTab.PLANTS); } public void addCollisionBoxesToList(World worldIn, BlockPos pos, State state, BoundingBox mask, List list, Entity collidingEntity) diff --git a/common/src/common/block/foliage/BlockLog.java b/common/src/common/block/foliage/BlockLog.java index 9397b97..8c9fbab 100755 --- a/common/src/common/block/foliage/BlockLog.java +++ b/common/src/common/block/foliage/BlockLog.java @@ -1,10 +1,10 @@ package common.block.foliage; import common.block.BlockRotatedPillar; +import common.block.Material; import common.block.SoundType; import common.entity.types.EntityLiving; import common.item.CheatTab; -import common.material.Material; import common.model.Model; import common.model.ModelProvider; import common.model.ModelRotation; @@ -23,9 +23,9 @@ public class BlockLog extends BlockRotatedPillar public BlockLog() { - super(Material.wood); + super(Material.WOOD); this.setDefaultState(this.getBaseState().withProperty(LOG_AXIS, BlockLog.EnumAxis.Y)); - this.setTab(CheatTab.tabWood); + this.setTab(CheatTab.WOOD); this.setHardness(2.0F); this.setStepSound(SoundType.WOOD); } @@ -41,7 +41,7 @@ public class BlockLog extends BlockRotatedPillar { State iblockstate = worldIn.getState(blockpos); - if (iblockstate.getBlock().getMaterial() == Material.leaves && !((Boolean)iblockstate.getValue(BlockLeaves.DECAY)).booleanValue()) + if (iblockstate.getBlock().getMaterial() == Material.LEAVES && !((Boolean)iblockstate.getValue(BlockLeaves.DECAY)).booleanValue()) { worldIn.setState(blockpos, iblockstate.withProperty(BlockLeaves.DECAY, Boolean.valueOf(true)), 4); } diff --git a/common/src/common/block/foliage/BlockMelon.java b/common/src/common/block/foliage/BlockMelon.java index 03988f0..ea81ba1 100755 --- a/common/src/common/block/foliage/BlockMelon.java +++ b/common/src/common/block/foliage/BlockMelon.java @@ -1,10 +1,10 @@ package common.block.foliage; import common.block.Block; +import common.block.Material; import common.init.Items; import common.item.CheatTab; import common.item.Item; -import common.material.Material; import common.model.Model; import common.model.ModelProvider; import common.rng.Random; @@ -14,8 +14,8 @@ public class BlockMelon extends Block { public BlockMelon() { - super(Material.gourd); - this.setTab(CheatTab.tabPlants); + super(Material.SOFT); + this.setTab(CheatTab.PLANTS); } /** diff --git a/common/src/common/block/foliage/BlockMycelium.java b/common/src/common/block/foliage/BlockMycelium.java index f1580ef..b4a6fa7 100755 --- a/common/src/common/block/foliage/BlockMycelium.java +++ b/common/src/common/block/foliage/BlockMycelium.java @@ -1,12 +1,12 @@ package common.block.foliage; import common.block.Block; +import common.block.Material; import common.block.natural.BlockDirt; import common.init.Blocks; import common.init.Config; import common.item.CheatTab; import common.item.Item; -import common.material.Material; import common.model.Model; import common.model.ModelProvider; import common.model.ParticleType; @@ -25,10 +25,10 @@ public class BlockMycelium extends Block public BlockMycelium() { - super(Material.grass); + super(Material.LOOSE); this.setDefaultState(this.getBaseState().withProperty(SNOWY, Boolean.valueOf(false))); this.setTickRandomly(); - this.setTab(CheatTab.tabNature); + this.setTab(CheatTab.NATURE); } /** diff --git a/common/src/common/block/foliage/BlockPumpkin.java b/common/src/common/block/foliage/BlockPumpkin.java index 49a23bd..302a14d 100755 --- a/common/src/common/block/foliage/BlockPumpkin.java +++ b/common/src/common/block/foliage/BlockPumpkin.java @@ -1,9 +1,9 @@ package common.block.foliage; import common.block.BlockDirectional; +import common.block.Material; import common.entity.types.EntityLiving; import common.item.CheatTab; -import common.material.Material; import common.model.Model; import common.model.ModelProvider; import common.model.ModelRotation; @@ -29,10 +29,10 @@ public class BlockPumpkin extends BlockDirectional public BlockPumpkin() { - super(Material.gourd); + super(Material.SOFT); this.setDefaultState(this.getBaseState().withProperty(FACING, Facing.NORTH)); // this.setTickRandomly(true); - this.setTab(CheatTab.tabPlants); + this.setTab(CheatTab.PLANTS); } // public void onBlockAdded(IWorldServer worldIn, BlockPos pos, IBlockState state) diff --git a/common/src/common/block/foliage/BlockReed.java b/common/src/common/block/foliage/BlockReed.java index 16a91e4..4b74a5c 100755 --- a/common/src/common/block/foliage/BlockReed.java +++ b/common/src/common/block/foliage/BlockReed.java @@ -1,11 +1,11 @@ package common.block.foliage; import common.block.Block; +import common.block.Material; import common.init.Blocks; import common.init.Config; import common.init.Items; import common.item.Item; -import common.material.Material; import common.model.BlockLayer; import common.model.Model; import common.model.ModelProvider; @@ -26,7 +26,7 @@ public class BlockReed extends Block public BlockReed() { - super(Material.plants); + super(Material.PLANT); this.setDefaultState(this.getBaseState().withProperty(AGE, Integer.valueOf(0))); float f = 0.375F; this.setBlockBounds(0.5F - f, 0.0F, 0.5F - f, 0.5F + f, 1.0F, 0.5F + f); @@ -85,7 +85,7 @@ public class BlockReed extends Block { for (Facing enumfacing : Facing.Plane.HORIZONTAL) { - if (worldIn.getState(pos.offset(enumfacing).down()).getBlock().getMaterial() == Material.water) + if (worldIn.getState(pos.offset(enumfacing).down()).getBlock().getMaterial() == Material.WATER) { return true; } diff --git a/common/src/common/block/foliage/BlockSapling.java b/common/src/common/block/foliage/BlockSapling.java index b2b4702..dfc718d 100755 --- a/common/src/common/block/foliage/BlockSapling.java +++ b/common/src/common/block/foliage/BlockSapling.java @@ -31,7 +31,7 @@ public class BlockSapling extends BlockBush implements IGrowable this.setDefaultState(this.getBaseState() /* .withProperty(TYPE, BlockPlanks.EnumType.OAK) */ .withProperty(STAGE, Integer.valueOf(0))); float f = 0.4F; this.setBlockBounds(0.5F - f, 0.0F, 0.5F - f, 0.5F + f, f * 2.0F, 0.5F + f); - this.setTab(CheatTab.tabPlants); + this.setTab(CheatTab.PLANTS); this.type = type; SAPLINGS.add(this); } diff --git a/common/src/common/block/foliage/BlockTallGrass.java b/common/src/common/block/foliage/BlockTallGrass.java index f7cf36d..b72c760 100755 --- a/common/src/common/block/foliage/BlockTallGrass.java +++ b/common/src/common/block/foliage/BlockTallGrass.java @@ -2,6 +2,7 @@ package common.block.foliage; import java.util.List; +import common.block.Material; import common.color.Colorizer; import common.entity.npc.EntityNPC; import common.init.Blocks; @@ -11,7 +12,6 @@ import common.item.CheatTab; import common.item.Item; import common.item.ItemShears; import common.item.ItemStack; -import common.material.Material; import common.model.Model; import common.model.ModelProvider; import common.properties.IProperty; @@ -31,7 +31,7 @@ public class BlockTallGrass extends BlockBush implements IGrowable public BlockTallGrass() { - super(Material.vine); + super(Material.BUSH); this.setDefaultState(this.getBaseState().withProperty(TYPE, BlockTallGrass.EnumType.DEAD_BUSH)); float f = 0.4F; this.setBlockBounds(0.5F - f, 0.0F, 0.5F - f, 0.5F + f, 0.8F, 0.5F + f); diff --git a/common/src/common/block/foliage/BlockTianSoil.java b/common/src/common/block/foliage/BlockTianSoil.java index de7465e..bf7aa44 100755 --- a/common/src/common/block/foliage/BlockTianSoil.java +++ b/common/src/common/block/foliage/BlockTianSoil.java @@ -1,10 +1,10 @@ package common.block.foliage; import common.block.Block; +import common.block.Material; import common.init.Blocks; import common.item.CheatTab; import common.item.Item; -import common.material.Material; import common.model.Model; import common.model.ModelProvider; import common.properties.IProperty; @@ -20,9 +20,9 @@ public class BlockTianSoil extends Block public BlockTianSoil() { - super(Material.rock); + super(Material.SOLID); this.setDefaultState(this.getBaseState().withProperty(SNOWY, Boolean.valueOf(false))); - this.setTab(CheatTab.tabNature); + this.setTab(CheatTab.NATURE); } public State getActualState(State state, IWorldAccess worldIn, BlockPos pos) diff --git a/common/src/common/block/foliage/BlockVine.java b/common/src/common/block/foliage/BlockVine.java index 7f2a9a1..fc0868e 100755 --- a/common/src/common/block/foliage/BlockVine.java +++ b/common/src/common/block/foliage/BlockVine.java @@ -1,6 +1,7 @@ package common.block.foliage; import common.block.Block; +import common.block.Material; import common.color.Colorizer; import common.entity.npc.EntityNPC; import common.entity.types.EntityLiving; @@ -10,7 +11,6 @@ import common.item.CheatTab; import common.item.Item; import common.item.ItemShears; import common.item.ItemStack; -import common.material.Material; import common.model.BlockLayer; import common.model.Model; import common.model.ModelProvider; @@ -38,10 +38,10 @@ public class BlockVine extends Block public BlockVine() { - super(Material.vine); + super(Material.BUSH); this.setDefaultState(this.getBaseState().withProperty(UP, Boolean.valueOf(false)).withProperty(NORTH, Boolean.valueOf(false)).withProperty(EAST, Boolean.valueOf(false)).withProperty(SOUTH, Boolean.valueOf(false)).withProperty(WEST, Boolean.valueOf(false))); this.setTickRandomly(); - this.setTab(CheatTab.tabPlants); + this.setTab(CheatTab.PLANTS); } /** diff --git a/common/src/common/block/foliage/BlockWart.java b/common/src/common/block/foliage/BlockWart.java index 7ac9919..72c7b1f 100755 --- a/common/src/common/block/foliage/BlockWart.java +++ b/common/src/common/block/foliage/BlockWart.java @@ -1,13 +1,13 @@ package common.block.foliage; import common.block.Block; +import common.block.Material; import common.init.Blocks; import common.init.Config; import common.init.Items; import common.item.CheatTab; import common.item.Item; import common.item.ItemStack; -import common.material.Material; import common.model.Model; import common.model.ModelProvider; import common.properties.IProperty; @@ -24,7 +24,7 @@ public class BlockWart extends BlockBush public BlockWart() { - super(Material.plants); + super(Material.PLANT); this.setDefaultState(this.getBaseState().withProperty(AGE, Integer.valueOf(0))); this.setTickRandomly(); float f = 0.5F; diff --git a/common/src/common/block/liquid/BlockDynamicLiquid.java b/common/src/common/block/liquid/BlockDynamicLiquid.java index 3684eec..a8bab57 100755 --- a/common/src/common/block/liquid/BlockDynamicLiquid.java +++ b/common/src/common/block/liquid/BlockDynamicLiquid.java @@ -4,10 +4,10 @@ import java.util.EnumSet; import java.util.Set; import common.block.Block; +import common.block.Material; import common.block.artificial.BlockDoor; import common.init.Blocks; import common.init.Config; -import common.material.Material; import common.rng.Random; import common.util.BlockPos; import common.util.Facing; @@ -76,10 +76,10 @@ public class BlockDynamicLiquid extends BlockLiquid } } - if (this.adjacentSourceBlocks >= 2 && ((Config.mergeWater && this.material == Material.water) - || (Config.mergeLava && this.material == Material.lava) - || (this.infinite && Config.mergeInfinite && this.material != Material.water && this.material != Material.lava) - || (!this.infinite && Config.mergeFinite && this.material != Material.water && this.material != Material.lava))) + if (this.adjacentSourceBlocks >= 2 && ((Config.mergeWater && this.material == Material.WATER) + || (Config.mergeLava && this.material == Material.LAVA) + || (this.infinite && Config.mergeInfinite && this.material != Material.WATER && this.material != Material.LAVA) + || (!this.infinite && Config.mergeFinite && this.material != Material.WATER && this.material != Material.LAVA))) { State iblockstate1 = worldIn.getState(pos.down()); @@ -128,7 +128,7 @@ public class BlockDynamicLiquid extends BlockLiquid if (this.canFlowInto(worldIn, pos.down(), iblockstate)) { - if (this.material == Material.lava && worldIn.getState(pos.down()).getBlock().getMaterial().isColdLiquid()) + if (this.material == Material.LAVA && worldIn.getState(pos.down()).getBlock().getMaterial().isColdLiquid()) { worldIn.setState(pos.down(), Blocks.stone.getState()); this.triggerMixEffects(worldIn, pos.down()); @@ -172,7 +172,7 @@ public class BlockDynamicLiquid extends BlockLiquid { if (state.getBlock() != Blocks.air) { - if (this.material == Material.lava) + if (this.material == Material.LAVA) { this.triggerMixEffects(worldIn, pos); } @@ -262,7 +262,7 @@ public class BlockDynamicLiquid extends BlockLiquid private boolean isBlocked(World worldIn, BlockPos pos, State state) { Block block = worldIn.getState(pos).getBlock(); - return !(block instanceof BlockDoor) && block != Blocks.sign && block != Blocks.ladder && block != Blocks.reeds ? (block.getMaterial() == Material.portal ? true : block.getMaterial().blocksMovement()) : true; + return !(block instanceof BlockDoor) && block != Blocks.sign && block != Blocks.ladder && block != Blocks.reeds ? (block.getMaterial() == Material.PORTAL ? true : block.getMaterial().blocksMovement()) : true; } protected int checkAdjacentBlock(World worldIn, BlockPos pos, int currentMinLevel) @@ -292,7 +292,7 @@ public class BlockDynamicLiquid extends BlockLiquid private boolean canFlowInto(World worldIn, BlockPos pos, State state) { Material material = state.getBlock().getMaterial(); - return material != this.material && material != Material.lava && !this.isBlocked(worldIn, pos, state); + return material != this.material && material != Material.LAVA && !this.isBlocked(worldIn, pos, state); } public void onBlockAdded(AWorldServer worldIn, BlockPos pos, State state) diff --git a/common/src/common/block/liquid/BlockLiquid.java b/common/src/common/block/liquid/BlockLiquid.java index 2b82174..c247744 100755 --- a/common/src/common/block/liquid/BlockLiquid.java +++ b/common/src/common/block/liquid/BlockLiquid.java @@ -1,6 +1,7 @@ package common.block.liquid; import common.block.Block; +import common.block.Material; import common.color.Colorizer; import common.entity.Entity; import common.init.Blocks; @@ -8,7 +9,6 @@ import common.init.Config; import common.init.FluidRegistry; import common.init.SoundEvent; import common.item.Item; -import common.material.Material; import common.model.BlockLayer; import common.model.ParticleType; import common.properties.IProperty; @@ -51,7 +51,7 @@ public abstract class BlockLiquid extends Block public int colorMultiplier(IWorldAccess worldIn, BlockPos pos, int renderPass) { - return this.material == Material.water ? Colorizer.getWaterColor(worldIn, pos) : 16777215; + return this.material == Material.WATER ? Colorizer.getWaterColor(worldIn, pos) : 16777215; } /** @@ -96,13 +96,10 @@ public abstract class BlockLiquid extends Block return liquid && ((Integer)state.getValue(LEVEL)).intValue() == 0; } - /** - * Whether this Block is solid on the given Side - */ public boolean isBlockSolid(IBlockAccess worldIn, BlockPos pos, Facing side) { - Material material = worldIn.getState(pos).getBlock().getMaterial(); - return material == this.material ? false : (side == Facing.UP ? true : (material == Material.ice ? false : super.isBlockSolid(worldIn, pos, side))); + Block block = worldIn.getState(pos).getBlock(); + return block.getMaterial() == this.material ? false : (side == Facing.UP ? true : (block != Blocks.ice && worldIn.getState(pos).getBlock().getMaterial().isSolid())); } public boolean shouldSideBeRendered(IWorldAccess worldIn, BlockPos pos, Facing side) @@ -241,7 +238,7 @@ public abstract class BlockLiquid extends Block double d1 = (double)pos.getY(); double d2 = (double)pos.getZ(); - if (this.material == Material.water) + if (this.material == Material.WATER) { int i = ((Integer)state.getValue(LEVEL)).intValue(); @@ -258,7 +255,7 @@ public abstract class BlockLiquid extends Block } } - if (this.material == Material.lava && worldIn.getState(pos.up()).getBlock() == Blocks.air && !worldIn.getState(pos.up()).getBlock().isOpaqueCube()) + if (this.material == Material.LAVA && worldIn.getState(pos.up()).getBlock() == Blocks.air && !worldIn.getState(pos.up()).getBlock().isOpaqueCube()) { if (rand.chance(100)) { @@ -285,7 +282,7 @@ public abstract class BlockLiquid extends Block double d5 = d1 - 1.05D; double d7 = d2 + (double)rand.floatv(); - if (this.material == Material.water) + if (this.material == Material.WATER) { worldIn.spawnParticle(ParticleType.DRIP_WATER, d3, d5, d7, 0.0D, 0.0D, 0.0D); } @@ -320,7 +317,7 @@ public abstract class BlockLiquid extends Block { if(worldIn.client || !Config.liquidPhysics) return true; - if (this.material == Material.lava) + if (this.material == Material.LAVA) { boolean flag = false; @@ -397,11 +394,11 @@ public abstract class BlockLiquid extends Block public static BlockDynamicLiquid getFlowingBlock(BlockStaticLiquid block) { - if (block.getMaterial() == Material.water) + if (block.getMaterial() == Material.WATER) { return Blocks.flowing_water; } - else if (block.getMaterial() == Material.lava) + else if (block.getMaterial() == Material.LAVA) { return Blocks.flowing_lava; } @@ -413,11 +410,11 @@ public abstract class BlockLiquid extends Block public static BlockStaticLiquid getStaticBlock(BlockDynamicLiquid block) { - if (block.getMaterial() == Material.water) + if (block.getMaterial() == Material.WATER) { return Blocks.water; } - else if (block.getMaterial() == Material.lava) + else if (block.getMaterial() == Material.LAVA) { return Blocks.lava; } diff --git a/common/src/common/block/liquid/BlockStaticLiquid.java b/common/src/common/block/liquid/BlockStaticLiquid.java index 5c7f069..f2770ca 100755 --- a/common/src/common/block/liquid/BlockStaticLiquid.java +++ b/common/src/common/block/liquid/BlockStaticLiquid.java @@ -1,9 +1,9 @@ package common.block.liquid; import common.block.Block; +import common.block.Material; import common.init.Blocks; import common.init.Config; -import common.material.Material; import common.rng.Random; import common.util.BlockPos; import common.util.Facing; @@ -15,7 +15,7 @@ public class BlockStaticLiquid extends BlockLiquid { public BlockStaticLiquid(Material materialIn, boolean opaque, int rate) { - super(materialIn, materialIn == Material.lava, opaque, rate); + super(materialIn, materialIn == Material.LAVA, opaque, rate); // this.setTickRandomly(false); // // if (materialIn == Material.lava) @@ -44,7 +44,7 @@ public class BlockStaticLiquid extends BlockLiquid public void updateTick(AWorldServer worldIn, BlockPos pos, State state, Random rand) { - if (Config.lavaFire && this.material == Material.lava) + if (Config.lavaFire && this.material == Material.LAVA) { if (Config.fire) { diff --git a/common/src/common/block/natural/BlockBedrock.java b/common/src/common/block/natural/BlockBedrock.java index 831e002..a1c0a9b 100755 --- a/common/src/common/block/natural/BlockBedrock.java +++ b/common/src/common/block/natural/BlockBedrock.java @@ -1,7 +1,7 @@ package common.block.natural; import common.block.Block; -import common.material.Material; +import common.block.Material; import common.model.ParticleType; import common.rng.Random; import common.util.BlockPos; @@ -10,7 +10,7 @@ import common.world.State; public class BlockBedrock extends Block { public BlockBedrock() { - super(Material.rock); + super(Material.SOLID); } public void randomDisplayTick(AWorldClient worldIn, BlockPos pos, State state, Random rand) diff --git a/common/src/common/block/natural/BlockBlackenedDirt.java b/common/src/common/block/natural/BlockBlackenedDirt.java index 6eff390..5cf0837 100644 --- a/common/src/common/block/natural/BlockBlackenedDirt.java +++ b/common/src/common/block/natural/BlockBlackenedDirt.java @@ -2,10 +2,10 @@ package common.block.natural; import common.biome.Biome; import common.block.Block; +import common.block.Material; import common.init.Blocks; import common.init.Config; import common.item.CheatTab; -import common.material.Material; import common.rng.Random; import common.util.BlockPos; import common.world.State; @@ -15,9 +15,9 @@ public class BlockBlackenedDirt extends Block { public BlockBlackenedDirt() { - super(Material.ground); + super(Material.LOOSE); this.setTickRandomly(); - this.setTab(CheatTab.tabNature); + this.setTab(CheatTab.NATURE); } public void updateTick(AWorldServer worldIn, BlockPos pos, State state, Random rand) diff --git a/common/src/common/block/natural/BlockBlackenedStone.java b/common/src/common/block/natural/BlockBlackenedStone.java index 6e8dec7..bf35ab6 100644 --- a/common/src/common/block/natural/BlockBlackenedStone.java +++ b/common/src/common/block/natural/BlockBlackenedStone.java @@ -1,18 +1,18 @@ package common.block.natural; import common.block.Block; +import common.block.Material; import common.init.Blocks; import common.init.ItemRegistry; import common.item.CheatTab; import common.item.Item; -import common.material.Material; import common.rng.Random; import common.world.State; public class BlockBlackenedStone extends Block { public BlockBlackenedStone() { - super(Material.rock); - this.setTab(CheatTab.tabNature); + super(Material.SOLID); + this.setTab(CheatTab.NATURE); } public Item getItemDropped(State state, Random rand, int fortune) { diff --git a/common/src/common/block/natural/BlockClay.java b/common/src/common/block/natural/BlockClay.java index 1e34ea9..9f15600 100755 --- a/common/src/common/block/natural/BlockClay.java +++ b/common/src/common/block/natural/BlockClay.java @@ -1,10 +1,10 @@ package common.block.natural; import common.block.Block; +import common.block.Material; import common.init.Items; import common.item.CheatTab; import common.item.Item; -import common.material.Material; import common.rng.Random; import common.world.State; @@ -12,8 +12,8 @@ public class BlockClay extends Block { public BlockClay() { - super(Material.clay); - this.setTab(CheatTab.tabNature); + super(Material.LOOSE); + this.setTab(CheatTab.NATURE); } /** diff --git a/common/src/common/block/natural/BlockDirt.java b/common/src/common/block/natural/BlockDirt.java index 682418e..f93a03c 100755 --- a/common/src/common/block/natural/BlockDirt.java +++ b/common/src/common/block/natural/BlockDirt.java @@ -3,11 +3,11 @@ package common.block.natural; import java.util.List; import common.block.Block; +import common.block.Material; import common.init.Blocks; import common.item.CheatTab; import common.item.Item; import common.item.ItemStack; -import common.material.Material; import common.model.Model; import common.model.ModelProvider; import common.properties.IProperty; @@ -26,9 +26,9 @@ public class BlockDirt extends Block public BlockDirt() { - super(Material.ground); + super(Material.LOOSE); this.setDefaultState(this.getBaseState().withProperty(VARIANT, BlockDirt.DirtType.DIRT).withProperty(SNOWY, Boolean.valueOf(false))); - this.setTab(CheatTab.tabNature); + this.setTab(CheatTab.NATURE); } // /** diff --git a/common/src/common/block/natural/BlockFire.java b/common/src/common/block/natural/BlockFire.java index bf1a0fe..fe048ea 100755 --- a/common/src/common/block/natural/BlockFire.java +++ b/common/src/common/block/natural/BlockFire.java @@ -3,11 +3,11 @@ package common.block.natural; import java.util.Map; import common.block.Block; +import common.block.Material; import common.init.Blocks; import common.init.Config; import common.init.FlammabilityRegistry; import common.init.SoundEvent; -import common.material.Material; import common.model.BlockLayer; import common.model.Model; import common.model.ModelProvider; @@ -69,7 +69,7 @@ public class BlockFire extends Block public BlockFire() { - super(Material.fire); + super(Material.FIRE); this.setDefaultState(this.getBaseState().withProperty(AGE, Integer.valueOf(0)).withProperty(FLIP, Boolean.valueOf(false)).withProperty(ALT, Boolean.valueOf(false)).withProperty(NORTH, Boolean.valueOf(false)).withProperty(EAST, Boolean.valueOf(false)).withProperty(SOUTH, Boolean.valueOf(false)).withProperty(WEST, Boolean.valueOf(false)).withProperty(UPPER, Integer.valueOf(0))); this.setTickRandomly(); } diff --git a/common/src/common/block/natural/BlockGlowstone.java b/common/src/common/block/natural/BlockGlowstone.java index acd4128..9e39e91 100755 --- a/common/src/common/block/natural/BlockGlowstone.java +++ b/common/src/common/block/natural/BlockGlowstone.java @@ -1,10 +1,10 @@ package common.block.natural; import common.block.Block; +import common.block.Material; import common.init.Items; import common.item.CheatTab; import common.item.Item; -import common.material.Material; import common.rng.Random; import common.util.ExtMath; import common.world.State; @@ -14,7 +14,7 @@ public class BlockGlowstone extends Block public BlockGlowstone(Material materialIn) { super(materialIn); - this.setTab(CheatTab.tabNature); + this.setTab(CheatTab.NATURE); } /** diff --git a/common/src/common/block/natural/BlockGravel.java b/common/src/common/block/natural/BlockGravel.java index 7324de7..4c0db73 100755 --- a/common/src/common/block/natural/BlockGravel.java +++ b/common/src/common/block/natural/BlockGravel.java @@ -1,20 +1,20 @@ package common.block.natural; import common.block.BlockFalling; +import common.block.Material; import common.init.Config; import common.init.ItemRegistry; import common.init.Items; import common.item.CheatTab; import common.item.Item; -import common.material.Material; import common.rng.Random; import common.world.State; public class BlockGravel extends BlockFalling { public BlockGravel() { - super(Material.sand); - this.setTab(CheatTab.tabNature); + super(Material.LOOSE); + this.setTab(CheatTab.NATURE); } public Item getItemDropped(State state, Random rand, int fortune) diff --git a/common/src/common/block/natural/BlockHardenedClay.java b/common/src/common/block/natural/BlockHardenedClay.java index ce20f4c..93e8b74 100755 --- a/common/src/common/block/natural/BlockHardenedClay.java +++ b/common/src/common/block/natural/BlockHardenedClay.java @@ -1,15 +1,15 @@ package common.block.natural; import common.block.Block; +import common.block.Material; import common.item.CheatTab; -import common.material.Material; public class BlockHardenedClay extends Block { public BlockHardenedClay() { - super(Material.rock); - this.setTab(CheatTab.tabNature); + super(Material.SOLID); + this.setTab(CheatTab.NATURE); } // /** diff --git a/common/src/common/block/natural/BlockHellRock.java b/common/src/common/block/natural/BlockHellRock.java index f381c4d..63c6b72 100755 --- a/common/src/common/block/natural/BlockHellRock.java +++ b/common/src/common/block/natural/BlockHellRock.java @@ -1,15 +1,15 @@ package common.block.natural; import common.block.Block; +import common.block.Material; import common.item.CheatTab; -import common.material.Material; public class BlockHellRock extends Block { public BlockHellRock() { - super(Material.rock); - this.setTab(CheatTab.tabNature); + super(Material.SOLID); + this.setTab(CheatTab.NATURE); } // /** diff --git a/common/src/common/block/natural/BlockIce.java b/common/src/common/block/natural/BlockIce.java index e63c36d..1662bd4 100755 --- a/common/src/common/block/natural/BlockIce.java +++ b/common/src/common/block/natural/BlockIce.java @@ -1,13 +1,13 @@ package common.block.natural; import common.block.BlockTranslucent; +import common.block.Material; import common.enchantment.EnchantmentHelper; import common.entity.npc.EntityNPC; import common.init.Blocks; import common.init.Config; import common.item.CheatTab; import common.item.ItemStack; -import common.material.Material; import common.rng.Random; import common.tileentity.TileEntity; import common.util.BlockPos; @@ -18,10 +18,10 @@ import common.world.AWorldServer; public class BlockIce extends BlockTranslucent { public BlockIce() { - super(Material.ice); + super(Material.TRANSLUCENT); this.slipperiness = 0.98F; this.setTickRandomly(); - this.setTab(CheatTab.tabNature); + this.setTab(CheatTab.NATURE); } public void harvestBlock(World world, EntityNPC player, BlockPos pos, State state, TileEntity tile) { diff --git a/common/src/common/block/natural/BlockObsidian.java b/common/src/common/block/natural/BlockObsidian.java index b8d60e9..97cdf05 100755 --- a/common/src/common/block/natural/BlockObsidian.java +++ b/common/src/common/block/natural/BlockObsidian.java @@ -1,11 +1,11 @@ package common.block.natural; import common.block.Block; +import common.block.Material; import common.init.Blocks; import common.init.ItemRegistry; import common.item.CheatTab; import common.item.Item; -import common.material.Material; import common.rng.Random; import common.world.State; @@ -13,8 +13,8 @@ public class BlockObsidian extends Block { public BlockObsidian() { - super(Material.rock); - this.setTab(CheatTab.tabNature); + super(Material.SOLID); + this.setTab(CheatTab.NATURE); } /** diff --git a/common/src/common/block/natural/BlockOre.java b/common/src/common/block/natural/BlockOre.java index 3b7c759..d4d6540 100755 --- a/common/src/common/block/natural/BlockOre.java +++ b/common/src/common/block/natural/BlockOre.java @@ -1,12 +1,12 @@ package common.block.natural; import common.block.Block; +import common.block.Material; import common.init.Config; import common.init.ItemRegistry; import common.item.CheatTab; import common.item.Item; import common.item.ItemStack; -import common.material.Material; import common.rng.Random; import common.util.BlockPos; import common.world.State; @@ -22,8 +22,8 @@ public class BlockOre extends Block public BlockOre() { - super(Material.rock); - this.setTab(CheatTab.tabGems); + super(Material.SOLID); + this.setTab(CheatTab.GEMS); } public void setDropItem(ItemStack item, int chance, int minXp) { diff --git a/common/src/common/block/natural/BlockPackedIce.java b/common/src/common/block/natural/BlockPackedIce.java index b79cee6..59ddc47 100755 --- a/common/src/common/block/natural/BlockPackedIce.java +++ b/common/src/common/block/natural/BlockPackedIce.java @@ -1,17 +1,17 @@ package common.block.natural; import common.block.Block; +import common.block.Material; import common.item.CheatTab; -import common.material.Material; import common.rng.Random; public class BlockPackedIce extends Block { public BlockPackedIce() { - super(Material.packedIce); + super(Material.LOOSE); this.slipperiness = 0.98F; - this.setTab(CheatTab.tabNature); + this.setTab(CheatTab.NATURE); } /** diff --git a/common/src/common/block/natural/BlockRedstoneOre.java b/common/src/common/block/natural/BlockRedstoneOre.java index 48f4345..f42bba2 100755 --- a/common/src/common/block/natural/BlockRedstoneOre.java +++ b/common/src/common/block/natural/BlockRedstoneOre.java @@ -1,6 +1,7 @@ package common.block.natural; import common.block.Block; +import common.block.Material; import common.entity.Entity; import common.entity.npc.EntityNPC; import common.init.Blocks; @@ -8,7 +9,6 @@ import common.init.ItemRegistry; import common.init.Items; import common.item.Item; import common.item.ItemStack; -import common.material.Material; import common.model.Model; import common.model.ModelProvider; import common.model.ParticleType; @@ -26,7 +26,7 @@ public class BlockRedstoneOre extends Block public BlockRedstoneOre(boolean isOn) { - super(Material.rock); + super(Material.SOLID); if (isOn) { diff --git a/common/src/common/block/natural/BlockRock.java b/common/src/common/block/natural/BlockRock.java index 83faa97..92b0352 100755 --- a/common/src/common/block/natural/BlockRock.java +++ b/common/src/common/block/natural/BlockRock.java @@ -3,10 +3,10 @@ package common.block.natural; import java.util.List; import common.block.Block; +import common.block.Material; import common.item.CheatTab; import common.item.Item; import common.item.ItemStack; -import common.material.Material; import common.model.Model; import common.model.ModelProvider; import common.properties.IProperty; @@ -17,9 +17,9 @@ public class BlockRock extends Block { public static final PropertyBool SMOOTH = PropertyBool.create("smooth"); public BlockRock() { - super(Material.rock); + super(Material.SOLID); this.setDefaultState(this.getBaseState().withProperty(SMOOTH, false)); - this.setTab(CheatTab.tabNature); + this.setTab(CheatTab.NATURE); } public int damageDropped(State state) { diff --git a/common/src/common/block/natural/BlockSand.java b/common/src/common/block/natural/BlockSand.java index d875ca4..ae5d6cb 100755 --- a/common/src/common/block/natural/BlockSand.java +++ b/common/src/common/block/natural/BlockSand.java @@ -3,10 +3,10 @@ package common.block.natural; import java.util.List; import common.block.BlockFalling; +import common.block.Material; import common.item.CheatTab; import common.item.Item; import common.item.ItemStack; -import common.material.Material; import common.model.Model; import common.model.ModelProvider; import common.properties.IProperty; @@ -20,9 +20,9 @@ public class BlockSand extends BlockFalling public BlockSand() { - super(Material.sand); + super(Material.LOOSE); this.setDefaultState(this.getBaseState().withProperty(VARIANT, BlockSand.EnumType.SAND)); - this.setTab(CheatTab.tabNature); + this.setTab(CheatTab.NATURE); } /** diff --git a/common/src/common/block/natural/BlockSandStone.java b/common/src/common/block/natural/BlockSandStone.java index 76ff781..ca1bcac 100755 --- a/common/src/common/block/natural/BlockSandStone.java +++ b/common/src/common/block/natural/BlockSandStone.java @@ -3,10 +3,10 @@ package common.block.natural; import java.util.List; import common.block.Block; +import common.block.Material; import common.item.CheatTab; import common.item.Item; import common.item.ItemStack; -import common.material.Material; import common.model.Model; import common.model.ModelProvider; import common.properties.IProperty; @@ -20,9 +20,9 @@ public class BlockSandStone extends Block public BlockSandStone() { - super(Material.rock); + super(Material.SOLID); this.setDefaultState(this.getBaseState().withProperty(TYPE, BlockSandStone.EnumType.DEFAULT)); - this.setTab(CheatTab.tabNature); + this.setTab(CheatTab.NATURE); } /** diff --git a/common/src/common/block/natural/BlockSlime.java b/common/src/common/block/natural/BlockSlime.java index 7ea4f3d..1d1f6f6 100755 --- a/common/src/common/block/natural/BlockSlime.java +++ b/common/src/common/block/natural/BlockSlime.java @@ -1,9 +1,9 @@ package common.block.natural; import common.block.BlockTranslucent; +import common.block.Material; import common.entity.Entity; import common.item.CheatTab; -import common.material.Material; import common.model.Model; import common.model.ModelProvider; import common.util.BlockPos; @@ -29,8 +29,8 @@ public class BlockSlime extends BlockTranslucent { ; public BlockSlime() { - super(Material.clay); - this.setTab(CheatTab.tabTech); + super(Material.LOOSE); + this.setTab(CheatTab.TECHNOLOGY); this.slipperiness = 0.8F; } diff --git a/common/src/common/block/natural/BlockSnow.java b/common/src/common/block/natural/BlockSnow.java index e87a6ed..2bbcf17 100755 --- a/common/src/common/block/natural/BlockSnow.java +++ b/common/src/common/block/natural/BlockSnow.java @@ -1,6 +1,7 @@ package common.block.natural; import common.block.Block; +import common.block.Material; import common.entity.npc.EntityNPC; import common.init.Blocks; import common.init.Config; @@ -8,7 +9,6 @@ import common.init.Items; import common.item.CheatTab; import common.item.Item; import common.item.ItemStack; -import common.material.Material; import common.model.Model; import common.model.ModelProvider; import common.model.Transforms; @@ -32,11 +32,11 @@ public class BlockSnow extends Block public BlockSnow() { - super(Material.snow); + super(Material.POWDER); this.setDefaultState(this.getBaseState().withProperty(LAYERS, Integer.valueOf(1))); this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 0.125F, 1.0F); this.setTickRandomly(); - this.setTab(CheatTab.tabDeco); + this.setTab(CheatTab.DECORATION); this.setBlockBoundsForItemRender(); } @@ -88,7 +88,7 @@ public class BlockSnow extends Block { State iblockstate = worldIn.getState(pos.down()); Block block = iblockstate.getBlock(); - return block != Blocks.ice && block != Blocks.packed_ice ? (block.getMaterial() == Material.leaves ? true : (block == this && ((Integer)iblockstate.getValue(LAYERS)).intValue() >= 7 ? true : block.isOpaqueCube() && block.getMaterial().blocksMovement())) : false; + return block != Blocks.ice && block != Blocks.packed_ice ? (block.getMaterial() == Material.LEAVES ? true : (block == this && ((Integer)iblockstate.getValue(LAYERS)).intValue() >= 7 ? true : block.isOpaqueCube() && block.getMaterial().blocksMovement())) : false; } /** diff --git a/common/src/common/block/natural/BlockSnowBlock.java b/common/src/common/block/natural/BlockSnowBlock.java index 6721f0f..405ea66 100755 --- a/common/src/common/block/natural/BlockSnowBlock.java +++ b/common/src/common/block/natural/BlockSnowBlock.java @@ -1,11 +1,11 @@ package common.block.natural; import common.block.Block; +import common.block.Material; import common.init.Config; import common.init.Items; import common.item.CheatTab; import common.item.Item; -import common.material.Material; import common.rng.Random; import common.util.BlockPos; import common.world.LightType; @@ -14,9 +14,9 @@ import common.world.AWorldServer; public class BlockSnowBlock extends Block { public BlockSnowBlock() { - super(Material.craftedSnow); + super(Material.DIGGABLE); this.setTickRandomly(); - this.setTab(CheatTab.tabNature); + this.setTab(CheatTab.NATURE); } public Item getItemDropped(State state, Random rand, int fortune) { diff --git a/common/src/common/block/natural/BlockSoulSand.java b/common/src/common/block/natural/BlockSoulSand.java index efce90e..e521c5f 100755 --- a/common/src/common/block/natural/BlockSoulSand.java +++ b/common/src/common/block/natural/BlockSoulSand.java @@ -1,9 +1,9 @@ package common.block.natural; import common.block.Block; +import common.block.Material; import common.entity.Entity; import common.item.CheatTab; -import common.material.Material; import common.util.BlockPos; import common.util.BoundingBox; import common.world.State; @@ -13,8 +13,8 @@ public class BlockSoulSand extends Block { public BlockSoulSand() { - super(Material.sand); - this.setTab(CheatTab.tabNature); + super(Material.LOOSE); + this.setTab(CheatTab.NATURE); } public BoundingBox getCollisionBoundingBox(World worldIn, BlockPos pos, State state) diff --git a/common/src/common/block/natural/BlockStone.java b/common/src/common/block/natural/BlockStone.java index b2fe230..7bb352a 100755 --- a/common/src/common/block/natural/BlockStone.java +++ b/common/src/common/block/natural/BlockStone.java @@ -1,18 +1,18 @@ package common.block.natural; import common.block.Block; +import common.block.Material; import common.init.Blocks; import common.init.ItemRegistry; import common.item.CheatTab; import common.item.Item; -import common.material.Material; import common.rng.Random; import common.world.State; public class BlockStone extends Block { public BlockStone() { - super(Material.rock); - this.setTab(CheatTab.tabNature); + super(Material.SOLID); + this.setTab(CheatTab.NATURE); } public Item getItemDropped(State state, Random rand, int fortune) { diff --git a/common/src/common/block/natural/BlockWeb.java b/common/src/common/block/natural/BlockWeb.java index 156da3d..4dbaf5d 100755 --- a/common/src/common/block/natural/BlockWeb.java +++ b/common/src/common/block/natural/BlockWeb.java @@ -1,11 +1,11 @@ package common.block.natural; import common.block.Block; +import common.block.Material; import common.entity.Entity; import common.init.Items; import common.item.CheatTab; import common.item.Item; -import common.material.Material; import common.model.BlockLayer; import common.model.Model; import common.model.ModelProvider; @@ -19,8 +19,8 @@ public class BlockWeb extends Block { public BlockWeb() { - super(Material.web); - this.setTab(CheatTab.tabDeco); + super(Material.FLUFF); + this.setTab(CheatTab.DECORATION); } /** diff --git a/common/src/common/block/tech/BlockAnvil.java b/common/src/common/block/tech/BlockAnvil.java index 34a19c9..8a00352 100755 --- a/common/src/common/block/tech/BlockAnvil.java +++ b/common/src/common/block/tech/BlockAnvil.java @@ -3,6 +3,7 @@ package common.block.tech; import java.util.List; import common.block.BlockFalling; +import common.block.Material; import common.entity.item.EntityFalling; import common.entity.npc.EntityNPC; import common.entity.types.EntityLiving; @@ -12,7 +13,6 @@ import common.inventory.InventoryPlayer; import common.item.CheatTab; import common.item.Item; import common.item.ItemStack; -import common.material.Material; import common.model.Model; import common.model.ModelProvider; import common.model.ModelRotation; @@ -34,10 +34,10 @@ public class BlockAnvil extends BlockFalling public BlockAnvil() { - super(Material.anvil); + super(Material.HEAVY); this.setDefaultState(this.getBaseState().withProperty(FACING, Facing.NORTH).withProperty(DAMAGE, Integer.valueOf(0))); this.setLightOpacity(0); - this.setTab(CheatTab.tabTech); + this.setTab(CheatTab.TECHNOLOGY); } public boolean isFullCube() diff --git a/common/src/common/block/tech/BlockBasePressurePlate.java b/common/src/common/block/tech/BlockBasePressurePlate.java index f0c48de..a920fbe 100755 --- a/common/src/common/block/tech/BlockBasePressurePlate.java +++ b/common/src/common/block/tech/BlockBasePressurePlate.java @@ -1,11 +1,11 @@ package common.block.tech; import common.block.Block; +import common.block.Material; import common.block.artificial.BlockFence; import common.entity.Entity; import common.init.SoundEvent; import common.item.CheatTab; -import common.material.Material; import common.model.Model; import common.model.ModelProvider; import common.rng.Random; @@ -23,7 +23,7 @@ public abstract class BlockBasePressurePlate extends Block public BlockBasePressurePlate(Material p_i46401_1_) { super(p_i46401_1_); - this.setTab(CheatTab.tabTech); + this.setTab(CheatTab.TECHNOLOGY); // this.setTickRandomly(true); } diff --git a/common/src/common/block/tech/BlockBeacon.java b/common/src/common/block/tech/BlockBeacon.java index 3a752a1..521e9ce 100755 --- a/common/src/common/block/tech/BlockBeacon.java +++ b/common/src/common/block/tech/BlockBeacon.java @@ -2,9 +2,9 @@ package common.block.tech; import common.block.Block; import common.block.BlockContainer; +import common.block.Material; import common.entity.npc.EntityNPC; import common.item.CheatTab; -import common.material.Material; import common.model.BlockLayer; import common.model.Model; import common.model.ModelProvider; @@ -43,9 +43,9 @@ public class BlockBeacon extends BlockContainer public BlockBeacon() { - super(Material.glass); + super(Material.TRANSLUCENT); this.setHardness(3.0F); - this.setTab(CheatTab.tabTech); + this.setTab(CheatTab.TECHNOLOGY); } /** diff --git a/common/src/common/block/tech/BlockBrewingStand.java b/common/src/common/block/tech/BlockBrewingStand.java index 036b238..bcde12f 100755 --- a/common/src/common/block/tech/BlockBrewingStand.java +++ b/common/src/common/block/tech/BlockBrewingStand.java @@ -3,6 +3,7 @@ package common.block.tech; import java.util.List; import common.block.BlockContainer; +import common.block.Material; import common.entity.Entity; import common.entity.npc.EntityNPC; import common.entity.types.EntityLiving; @@ -11,7 +12,6 @@ import common.inventory.Container; import common.inventory.InventoryHelper; import common.item.Item; import common.item.ItemStack; -import common.material.Material; import common.model.BlockLayer; import common.model.Model; import common.model.ModelProvider; @@ -352,7 +352,7 @@ public class BlockBrewingStand extends BlockContainer public BlockBrewingStand() { - super(Material.iron); + super(Material.SOLID); this.setDefaultState(this.getBaseState().withProperty(HAS_BOTTLE[0], Boolean.valueOf(false)).withProperty(HAS_BOTTLE[1], Boolean.valueOf(false)).withProperty(HAS_BOTTLE[2], Boolean.valueOf(false))); } diff --git a/common/src/common/block/tech/BlockButton.java b/common/src/common/block/tech/BlockButton.java index c0b60fb..956d0fe 100755 --- a/common/src/common/block/tech/BlockButton.java +++ b/common/src/common/block/tech/BlockButton.java @@ -3,6 +3,7 @@ package common.block.tech; import java.util.List; import common.block.Block; +import common.block.Material; import common.collect.Lists; import common.entity.Entity; import common.entity.npc.EntityNPC; @@ -10,7 +11,6 @@ import common.entity.projectile.EntityArrow; import common.entity.types.EntityLiving; import common.init.SoundEvent; import common.item.CheatTab; -import common.material.Material; import common.model.Model; import common.model.ModelProvider; import common.model.ModelRotation; @@ -39,10 +39,10 @@ public class BlockButton extends Block public BlockButton(boolean arrows, int onTime, String texture) { - super(Material.circuits); + super(Material.SMALL); this.setDefaultState(this.getBaseState().withProperty(FACING, Facing.NORTH).withProperty(POWERED, Boolean.valueOf(false))); // this.setTickRandomly(true); - this.setTab(CheatTab.tabTech); + this.setTab(CheatTab.TECHNOLOGY); this.checkArrows = arrows; this.onTime = onTime; this.texture = texture; diff --git a/common/src/common/block/tech/BlockCauldron.java b/common/src/common/block/tech/BlockCauldron.java index 75e05e8..d686055 100755 --- a/common/src/common/block/tech/BlockCauldron.java +++ b/common/src/common/block/tech/BlockCauldron.java @@ -3,6 +3,7 @@ package common.block.tech; import java.util.List; import common.block.Block; +import common.block.Material; import common.entity.Entity; import common.entity.item.EntityItem; import common.entity.npc.EntityNPC; @@ -13,7 +14,6 @@ import common.item.Item; import common.item.ItemArmor; import common.item.ItemBanner; import common.item.ItemStack; -import common.material.Material; import common.model.Model; import common.model.ModelProvider; import common.properties.IProperty; @@ -414,7 +414,7 @@ public class BlockCauldron extends Block public BlockCauldron() { - super(Material.iron); + super(Material.SOLID); this.setDefaultState(this.getBaseState().withProperty(LEVEL, Integer.valueOf(0))); } diff --git a/common/src/common/block/tech/BlockChest.java b/common/src/common/block/tech/BlockChest.java index 11c0e60..b4bcac3 100755 --- a/common/src/common/block/tech/BlockChest.java +++ b/common/src/common/block/tech/BlockChest.java @@ -2,6 +2,7 @@ package common.block.tech; import common.block.Block; import common.block.BlockContainer; +import common.block.Material; import common.color.TextColor; import common.entity.Entity; import common.entity.animal.EntityOcelot; @@ -16,7 +17,6 @@ import common.inventory.InventoryHelper; import common.inventory.InventoryLargeChest; import common.item.CheatTab; import common.item.ItemStack; -import common.material.Material; import common.packet.SPacketSoundEffect; import common.properties.IProperty; import common.properties.PropertyDirection; @@ -42,10 +42,10 @@ public class BlockChest extends BlockContainer public BlockChest(int type) { - super(Material.wood); + super(Material.WOOD); this.setDefaultState(this.getBaseState().withProperty(FACING, Facing.NORTH)); this.chestType = type; - this.setTab(CheatTab.tabTech); + this.setTab(CheatTab.TECHNOLOGY); this.setBlockBounds(0.0625F, 0.0F, 0.0625F, 0.9375F, 0.875F, 0.9375F); } diff --git a/common/src/common/block/tech/BlockCore.java b/common/src/common/block/tech/BlockCore.java index 3378fea..640fe9d 100755 --- a/common/src/common/block/tech/BlockCore.java +++ b/common/src/common/block/tech/BlockCore.java @@ -1,17 +1,17 @@ package common.block.tech; import common.block.Block; +import common.block.Material; import common.init.Config; import common.item.CheatTab; -import common.material.Material; import common.util.BlockPos; import common.world.State; import common.world.AWorldServer; public class BlockCore extends Block { public BlockCore() { - super(Material.iron); - this.setTab(CheatTab.tabTech); + super(Material.SOLID); + this.setTab(CheatTab.TECHNOLOGY); } public void onBlockRemoved(AWorldServer world, BlockPos pos, State state) diff --git a/common/src/common/block/tech/BlockDaylightDetector.java b/common/src/common/block/tech/BlockDaylightDetector.java index 9b6a91a..f35f530 100755 --- a/common/src/common/block/tech/BlockDaylightDetector.java +++ b/common/src/common/block/tech/BlockDaylightDetector.java @@ -3,6 +3,7 @@ package common.block.tech; import java.util.List; import common.block.BlockContainer; +import common.block.Material; import common.block.SoundType; import common.entity.npc.EntityNPC; import common.init.Blocks; @@ -10,7 +11,6 @@ import common.init.ItemRegistry; import common.item.CheatTab; import common.item.Item; import common.item.ItemStack; -import common.material.Material; import common.model.Model; import common.model.ModelProvider; import common.model.Transforms; @@ -35,11 +35,11 @@ public class BlockDaylightDetector extends BlockContainer public BlockDaylightDetector(boolean inverted) { - super(Material.wood); + super(Material.WOOD); this.inverted = inverted; this.setDefaultState(this.getBaseState().withProperty(POWER, Integer.valueOf(0))); this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 0.375F, 1.0F); - this.setTab(CheatTab.tabTech); + this.setTab(CheatTab.TECHNOLOGY); this.setHardness(0.2F); this.setStepSound(SoundType.WOOD); // this.setDisplay("daylightDetector"); diff --git a/common/src/common/block/tech/BlockDispenser.java b/common/src/common/block/tech/BlockDispenser.java index 15d1875..ed3cd28 100755 --- a/common/src/common/block/tech/BlockDispenser.java +++ b/common/src/common/block/tech/BlockDispenser.java @@ -2,6 +2,7 @@ package common.block.tech; import common.block.Block; import common.block.BlockContainer; +import common.block.Material; import common.dispenser.BehaviorDefaultDispenseItem; import common.dispenser.IBehaviorDispenseItem; import common.dispenser.IBlockSource; @@ -15,7 +16,6 @@ import common.inventory.InventoryHelper; import common.item.CheatTab; import common.item.Item; import common.item.ItemStack; -import common.material.Material; import common.model.Model; import common.model.ModelProvider; import common.model.ModelRotation; @@ -41,9 +41,9 @@ public class BlockDispenser extends BlockContainer public BlockDispenser() { - super(Material.rock); + super(Material.SOLID); this.setDefaultState(this.getBaseState().withProperty(FACING, Facing.NORTH).withProperty(TRIGGERED, Boolean.valueOf(false))); - this.setTab(CheatTab.tabTech); + this.setTab(CheatTab.TECHNOLOGY); } /** diff --git a/common/src/common/block/tech/BlockEnchantmentTable.java b/common/src/common/block/tech/BlockEnchantmentTable.java index 3c8b3da..d242f81 100755 --- a/common/src/common/block/tech/BlockEnchantmentTable.java +++ b/common/src/common/block/tech/BlockEnchantmentTable.java @@ -1,12 +1,12 @@ package common.block.tech; import common.block.BlockContainer; +import common.block.Material; import common.entity.npc.EntityNPC; import common.entity.types.EntityLiving; import common.init.Blocks; import common.item.CheatTab; import common.item.ItemStack; -import common.material.Material; import common.model.Model; import common.model.ModelProvider; import common.model.ParticleType; @@ -33,10 +33,10 @@ public class BlockEnchantmentTable extends BlockContainer public BlockEnchantmentTable() { - super(Material.rock); + super(Material.SOLID); this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 0.75F, 1.0F); this.setLightOpacity(0); - this.setTab(CheatTab.tabTech); + this.setTab(CheatTab.TECHNOLOGY); } public boolean isFullCube() diff --git a/common/src/common/block/tech/BlockFurnace.java b/common/src/common/block/tech/BlockFurnace.java index dfb8811..4a3d9fa 100755 --- a/common/src/common/block/tech/BlockFurnace.java +++ b/common/src/common/block/tech/BlockFurnace.java @@ -2,6 +2,7 @@ package common.block.tech; import common.block.Block; import common.block.BlockContainer; +import common.block.Material; import common.entity.npc.EntityNPC; import common.entity.types.EntityLiving; import common.init.Blocks; @@ -10,7 +11,6 @@ import common.inventory.Container; import common.inventory.InventoryHelper; import common.item.Item; import common.item.ItemStack; -import common.material.Material; import common.model.Model; import common.model.ModelProvider; import common.model.ModelRotation; @@ -35,7 +35,7 @@ public class BlockFurnace extends BlockContainer public BlockFurnace(boolean isBurning) { - super(Material.rock); + super(Material.SOLID); this.setDefaultState(this.getBaseState().withProperty(FACING, Facing.NORTH)); this.isBurning = isBurning; } diff --git a/common/src/common/block/tech/BlockHopper.java b/common/src/common/block/tech/BlockHopper.java index 729dfca..5690a9c 100755 --- a/common/src/common/block/tech/BlockHopper.java +++ b/common/src/common/block/tech/BlockHopper.java @@ -5,6 +5,7 @@ import java.util.function.Predicate; import common.block.Block; import common.block.BlockContainer; +import common.block.Material; import common.entity.Entity; import common.entity.npc.EntityNPC; import common.entity.types.EntityLiving; @@ -12,7 +13,6 @@ import common.inventory.Container; import common.inventory.InventoryHelper; import common.item.CheatTab; import common.item.ItemStack; -import common.material.Material; import common.model.BlockLayer; import common.model.Model; import common.model.ModelProvider; @@ -95,9 +95,9 @@ public class BlockHopper extends BlockContainer public BlockHopper() { - super(Material.iron); + super(Material.SOLID); this.setDefaultState(this.getBaseState().withProperty(FACING, Facing.DOWN).withProperty(ENABLED, Boolean.valueOf(true))); - this.setTab(CheatTab.tabTech); + this.setTab(CheatTab.TECHNOLOGY); this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F); } diff --git a/common/src/common/block/tech/BlockJukebox.java b/common/src/common/block/tech/BlockJukebox.java index fde7f5e..cfe625d 100755 --- a/common/src/common/block/tech/BlockJukebox.java +++ b/common/src/common/block/tech/BlockJukebox.java @@ -1,10 +1,10 @@ package common.block.tech; import common.block.Block; +import common.block.Material; import common.entity.npc.EntityNPC; import common.init.SoundEvent; import common.item.CheatTab; -import common.material.Material; import common.model.Model; import common.model.ModelProvider; import common.util.BlockPos; @@ -14,8 +14,8 @@ import common.world.World; public class BlockJukebox extends Block { public BlockJukebox() { - super(Material.wood); - this.setTab(CheatTab.tabTech); + super(Material.WOOD); + this.setTab(CheatTab.TECHNOLOGY); } public boolean onBlockActivated(World worldIn, BlockPos pos, State state, EntityNPC playerIn, Facing side, float hitX, float hitY, float hitZ) { diff --git a/common/src/common/block/tech/BlockLever.java b/common/src/common/block/tech/BlockLever.java index fef2544..369c363 100755 --- a/common/src/common/block/tech/BlockLever.java +++ b/common/src/common/block/tech/BlockLever.java @@ -1,11 +1,11 @@ package common.block.tech; import common.block.Block; +import common.block.Material; import common.entity.npc.EntityNPC; import common.entity.types.EntityLiving; import common.init.SoundEvent; import common.item.CheatTab; -import common.material.Material; import common.model.Model; import common.model.ModelProvider; import common.model.ModelRotation; @@ -28,9 +28,9 @@ public class BlockLever extends Block public BlockLever() { - super(Material.circuits); + super(Material.SMALL); this.setDefaultState(this.getBaseState().withProperty(FACING, BlockLever.EnumOrientation.NORTH).withProperty(POWERED, Boolean.valueOf(false))); - this.setTab(CheatTab.tabTech); + this.setTab(CheatTab.TECHNOLOGY); } public BoundingBox getCollisionBoundingBox(World worldIn, BlockPos pos, State state) diff --git a/common/src/common/block/tech/BlockMachine.java b/common/src/common/block/tech/BlockMachine.java index be00a26..3275f8d 100755 --- a/common/src/common/block/tech/BlockMachine.java +++ b/common/src/common/block/tech/BlockMachine.java @@ -3,12 +3,12 @@ package common.block.tech; import common.block.Block; import common.block.BlockDirectional; import common.block.ITileEntityProvider; +import common.block.Material; import common.entity.npc.EntityNPC; import common.entity.types.EntityLiving; import common.inventory.Container; import common.inventory.InventoryHelper; import common.item.CheatTab; -import common.material.Material; import common.properties.IProperty; import common.tileentity.TileEntity; import common.tileentity.TileEntityMachine; @@ -20,10 +20,10 @@ import common.world.AWorldServer; public abstract class BlockMachine extends BlockDirectional implements ITileEntityProvider { public BlockMachine() { - super(Material.iron); + super(Material.SOLID); this.hasTile = true; this.setDefaultState(this.getBaseState().withProperty(FACING, Facing.NORTH)); - this.setTab(CheatTab.tabTech); + this.setTab(CheatTab.TECHNOLOGY); } public abstract TileEntity createNewTileEntity(World worldIn); diff --git a/common/src/common/block/tech/BlockMobSpawner.java b/common/src/common/block/tech/BlockMobSpawner.java index acfbb2f..4a46f35 100755 --- a/common/src/common/block/tech/BlockMobSpawner.java +++ b/common/src/common/block/tech/BlockMobSpawner.java @@ -1,9 +1,9 @@ package common.block.tech; import common.block.BlockContainer; +import common.block.Material; import common.item.CheatTab; import common.item.Item; -import common.material.Material; import common.model.BlockLayer; import common.rng.Random; import common.tileentity.TileEntity; @@ -16,8 +16,8 @@ public class BlockMobSpawner extends BlockContainer { public BlockMobSpawner() { - super(Material.rock); - this.setTab(CheatTab.tabTech); + super(Material.SOLID); + this.setTab(CheatTab.TECHNOLOGY); } /** diff --git a/common/src/common/block/tech/BlockNote.java b/common/src/common/block/tech/BlockNote.java index 7d2f198..f89f2b1 100755 --- a/common/src/common/block/tech/BlockNote.java +++ b/common/src/common/block/tech/BlockNote.java @@ -2,10 +2,10 @@ package common.block.tech; import common.block.Block; import common.block.BlockContainer; +import common.block.Material; import common.entity.npc.EntityNPC; import common.init.SoundEvent; import common.item.CheatTab; -import common.material.Material; import common.model.ParticleType; import common.tileentity.TileEntity; import common.tileentity.TileEntityNote; @@ -20,8 +20,8 @@ public class BlockNote extends BlockContainer public BlockNote() { - super(Material.wood); - this.setTab(CheatTab.tabTech); + super(Material.WOOD); + this.setTab(CheatTab.TECHNOLOGY); } /** diff --git a/common/src/common/block/tech/BlockNuke.java b/common/src/common/block/tech/BlockNuke.java index add3c4c..1413eed 100755 --- a/common/src/common/block/tech/BlockNuke.java +++ b/common/src/common/block/tech/BlockNuke.java @@ -1,11 +1,11 @@ package common.block.tech; import common.block.Block; +import common.block.Material; import common.entity.item.EntityNuke; import common.init.Blocks; import common.init.SoundEvent; import common.item.CheatTab; -import common.material.Material; import common.model.Model; import common.model.ModelProvider; import common.util.BlockPos; @@ -18,8 +18,8 @@ public class BlockNuke extends Block { public BlockNuke() { - super(Material.tnt); - this.setTab(CheatTab.tabTech); + super(Material.EXPLOSIVE); + this.setTab(CheatTab.TECHNOLOGY); } public void onBlockAdded(AWorldServer worldIn, BlockPos pos, State state) diff --git a/common/src/common/block/tech/BlockPistonBase.java b/common/src/common/block/tech/BlockPistonBase.java index 313a9a2..e5a2db7 100755 --- a/common/src/common/block/tech/BlockPistonBase.java +++ b/common/src/common/block/tech/BlockPistonBase.java @@ -4,6 +4,7 @@ import java.util.List; import common.block.Block; import common.block.ITileEntityProvider; +import common.block.Material; import common.block.SoundType; import common.collect.Lists; import common.entity.Entity; @@ -13,7 +14,6 @@ import common.init.Config; import common.init.SoundEvent; import common.item.CheatTab; import common.item.ItemStack; -import common.material.Material; import common.model.Model; import common.model.ModelProvider; import common.model.ModelRotation; @@ -254,12 +254,12 @@ public class BlockPistonBase extends Block public BlockPistonBase(boolean isSticky) { - super(Material.piston); + super(Material.PISTON); this.setDefaultState(this.getBaseState().withProperty(FACING, Facing.NORTH).withProperty(EXTENDED, Boolean.valueOf(false))); this.isSticky = isSticky; this.setStepSound(SoundType.STONE); this.setHardness(0.5F); - this.setTab(CheatTab.tabTech); + this.setTab(CheatTab.TECHNOLOGY); } /** diff --git a/common/src/common/block/tech/BlockPistonHead.java b/common/src/common/block/tech/BlockPistonHead.java index ce55cce..21aa5e2 100755 --- a/common/src/common/block/tech/BlockPistonHead.java +++ b/common/src/common/block/tech/BlockPistonHead.java @@ -3,12 +3,12 @@ package common.block.tech; import java.util.List; import common.block.Block; +import common.block.Material; import common.block.SoundType; import common.entity.Entity; import common.init.Blocks; import common.init.ItemRegistry; import common.item.Item; -import common.material.Material; import common.model.Model; import common.model.ModelProvider; import common.model.ModelRotation; @@ -34,7 +34,7 @@ public class BlockPistonHead extends Block public BlockPistonHead() { - super(Material.piston); + super(Material.PISTON); this.setDefaultState(this.getBaseState().withProperty(FACING, Facing.NORTH).withProperty(TYPE, BlockPistonHead.EnumPistonType.DEFAULT).withProperty(SHORT, Boolean.valueOf(false))); this.setStepSound(SoundType.STONE); this.setHardness(0.5F); diff --git a/common/src/common/block/tech/BlockPistonMoving.java b/common/src/common/block/tech/BlockPistonMoving.java index 9da811e..666061d 100755 --- a/common/src/common/block/tech/BlockPistonMoving.java +++ b/common/src/common/block/tech/BlockPistonMoving.java @@ -2,10 +2,10 @@ package common.block.tech; import common.block.Block; import common.block.BlockContainer; +import common.block.Material; import common.entity.npc.EntityNPC; import common.init.Blocks; import common.item.Item; -import common.material.Material; import common.properties.IProperty; import common.properties.PropertyDirection; import common.properties.PropertyEnum; @@ -29,7 +29,7 @@ public class BlockPistonMoving extends BlockContainer public BlockPistonMoving() { - super(Material.piston); + super(Material.PISTON); this.setDefaultState(this.getBaseState().withProperty(FACING, Facing.NORTH).withProperty(TYPE, BlockPistonHead.EnumPistonType.DEFAULT)); this.setHardness(-1.0F); } diff --git a/common/src/common/block/tech/BlockPressurePlate.java b/common/src/common/block/tech/BlockPressurePlate.java index 677f88d..b17b4b0 100755 --- a/common/src/common/block/tech/BlockPressurePlate.java +++ b/common/src/common/block/tech/BlockPressurePlate.java @@ -2,9 +2,9 @@ package common.block.tech; import java.util.List; +import common.block.Material; import common.entity.Entity; import common.entity.types.EntityLiving; -import common.material.Material; import common.properties.IProperty; import common.properties.PropertyBool; import common.util.BlockPos; diff --git a/common/src/common/block/tech/BlockPressurePlateWeighted.java b/common/src/common/block/tech/BlockPressurePlateWeighted.java index 55e7b7c..eeac2ec 100755 --- a/common/src/common/block/tech/BlockPressurePlateWeighted.java +++ b/common/src/common/block/tech/BlockPressurePlateWeighted.java @@ -1,7 +1,7 @@ package common.block.tech; +import common.block.Material; import common.entity.Entity; -import common.material.Material; import common.properties.IProperty; import common.properties.PropertyInteger; import common.util.BlockPos; diff --git a/common/src/common/block/tech/BlockRailBase.java b/common/src/common/block/tech/BlockRailBase.java index 2ef7c4c..198c04e 100755 --- a/common/src/common/block/tech/BlockRailBase.java +++ b/common/src/common/block/tech/BlockRailBase.java @@ -3,10 +3,10 @@ package common.block.tech; import java.util.List; import common.block.Block; +import common.block.Material; import common.collect.Lists; import common.init.Blocks; import common.item.CheatTab; -import common.material.Material; import common.model.BlockLayer; import common.model.Model; import common.model.ModelProvider; @@ -40,10 +40,10 @@ public abstract class BlockRailBase extends Block public BlockRailBase(boolean isPowered) { - super(Material.circuits); + super(Material.SMALL); this.isPowered = isPowered; this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 0.125F, 1.0F); - this.setTab(CheatTab.tabTech); + this.setTab(CheatTab.TECHNOLOGY); } public BoundingBox getCollisionBoundingBox(World worldIn, BlockPos pos, State state) diff --git a/common/src/common/block/tech/BlockRedstoneDiode.java b/common/src/common/block/tech/BlockRedstoneDiode.java index 63cf8e9..5c61033 100755 --- a/common/src/common/block/tech/BlockRedstoneDiode.java +++ b/common/src/common/block/tech/BlockRedstoneDiode.java @@ -2,10 +2,10 @@ package common.block.tech; import common.block.Block; import common.block.BlockDirectional; +import common.block.Material; import common.entity.types.EntityLiving; import common.init.Blocks; import common.item.ItemStack; -import common.material.Material; import common.model.BlockLayer; import common.rng.Random; import common.util.BlockPos; @@ -22,7 +22,7 @@ public abstract class BlockRedstoneDiode extends BlockDirectional public BlockRedstoneDiode(boolean powered) { - super(Material.circuits); + super(Material.SMALL); this.isRepeaterPowered = powered; this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 0.125F, 1.0F); } diff --git a/common/src/common/block/tech/BlockRedstoneLight.java b/common/src/common/block/tech/BlockRedstoneLight.java index 4ca9c78..dad8d50 100755 --- a/common/src/common/block/tech/BlockRedstoneLight.java +++ b/common/src/common/block/tech/BlockRedstoneLight.java @@ -1,11 +1,11 @@ package common.block.tech; import common.block.Block; +import common.block.Material; import common.init.Blocks; import common.init.ItemRegistry; import common.item.Item; import common.item.ItemStack; -import common.material.Material; import common.rng.Random; import common.util.BlockPos; import common.world.State; @@ -18,7 +18,7 @@ public class BlockRedstoneLight extends Block public BlockRedstoneLight(boolean isOn) { - super(Material.redstoneLight); + super(Material.LOOSE); this.isOn = isOn; if (isOn) diff --git a/common/src/common/block/tech/BlockRedstoneWire.java b/common/src/common/block/tech/BlockRedstoneWire.java index ba4c65c..c461f4f 100755 --- a/common/src/common/block/tech/BlockRedstoneWire.java +++ b/common/src/common/block/tech/BlockRedstoneWire.java @@ -5,12 +5,12 @@ import java.util.List; import java.util.Set; import common.block.Block; +import common.block.Material; import common.collect.Lists; import common.collect.Sets; import common.init.Blocks; import common.init.Items; import common.item.Item; -import common.material.Material; import common.model.BlockLayer; import common.model.Model; import common.model.ModelProvider; @@ -369,7 +369,7 @@ public class BlockRedstoneWire extends Block public BlockRedstoneWire() { - super(Material.circuits); + super(Material.SMALL); this.setDefaultState(this.getBaseState().withProperty(NORTH, BlockRedstoneWire.EnumAttachPosition.NONE).withProperty(EAST, BlockRedstoneWire.EnumAttachPosition.NONE).withProperty(SOUTH, BlockRedstoneWire.EnumAttachPosition.NONE).withProperty(WEST, BlockRedstoneWire.EnumAttachPosition.NONE).withProperty(POWER, Integer.valueOf(0))); this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 0.0625F, 1.0F); } diff --git a/common/src/common/block/tech/BlockTNT.java b/common/src/common/block/tech/BlockTNT.java index a5f3769..6d595a3 100755 --- a/common/src/common/block/tech/BlockTNT.java +++ b/common/src/common/block/tech/BlockTNT.java @@ -3,6 +3,7 @@ package common.block.tech; import java.util.List; import common.block.Block; +import common.block.Material; import common.entity.Entity; import common.entity.item.EntityTnt; import common.entity.npc.EntityNPC; @@ -13,7 +14,6 @@ import common.init.SoundEvent; import common.item.CheatTab; import common.item.Item; import common.item.ItemStack; -import common.material.Material; import common.model.Model; import common.model.ModelProvider; import common.properties.IProperty; @@ -33,9 +33,9 @@ public class BlockTNT extends Block public BlockTNT() { - super(Material.tnt); + super(Material.EXPLOSIVE); this.setDefaultState(this.getBaseState().withProperty(EXPLODE, Boolean.valueOf(false))); - this.setTab(CheatTab.tabTech); + this.setTab(CheatTab.TECHNOLOGY); } public void onBlockAdded(AWorldServer worldIn, BlockPos pos, State state) diff --git a/common/src/common/block/tech/BlockTorch.java b/common/src/common/block/tech/BlockTorch.java index 090960c..eed80aa 100755 --- a/common/src/common/block/tech/BlockTorch.java +++ b/common/src/common/block/tech/BlockTorch.java @@ -4,11 +4,11 @@ import java.util.function.Predicate; import common.block.Block; import common.block.BlockDirectional; +import common.block.Material; import common.block.artificial.BlockFence; import common.entity.types.EntityLiving; import common.init.Blocks; import common.item.CheatTab; -import common.material.Material; import common.model.BlockLayer; import common.model.Model; import common.model.ModelProvider; @@ -46,10 +46,10 @@ public class BlockTorch extends Block public BlockTorch() { - super(Material.circuits); + super(Material.SMALL); this.setDefaultState(this.getBaseState().withProperty(FACING, Facing.UP)); // this.setTickRandomly(true); - this.setTab(CheatTab.tabTech); + this.setTab(CheatTab.TECHNOLOGY); } public BoundingBox getCollisionBoundingBox(World worldIn, BlockPos pos, State state) diff --git a/common/src/common/block/tech/BlockTripWire.java b/common/src/common/block/tech/BlockTripWire.java index 258db32..2ed4b05 100755 --- a/common/src/common/block/tech/BlockTripWire.java +++ b/common/src/common/block/tech/BlockTripWire.java @@ -3,13 +3,13 @@ package common.block.tech; import java.util.List; import common.block.Block; +import common.block.Material; import common.entity.Entity; import common.entity.npc.EntityNPC; import common.init.Blocks; import common.init.Items; import common.item.Item; import common.item.ItemShears; -import common.material.Material; import common.model.BlockLayer; import common.model.Model; import common.model.ModelProvider; @@ -39,7 +39,7 @@ public class BlockTripWire extends Block public BlockTripWire() { - super(Material.circuits); + super(Material.SMALL); this.setDefaultState(this.getBaseState().withProperty(POWERED, Boolean.valueOf(false)).withProperty(SUSPENDED, Boolean.valueOf(false)).withProperty(ATTACHED, Boolean.valueOf(false)).withProperty(DISARMED, Boolean.valueOf(false)).withProperty(NORTH, Boolean.valueOf(false)).withProperty(EAST, Boolean.valueOf(false)).withProperty(SOUTH, Boolean.valueOf(false)).withProperty(WEST, Boolean.valueOf(false))); this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 0.15625F, 1.0F); // this.setTickRandomly(true); diff --git a/common/src/common/block/tech/BlockTripWireHook.java b/common/src/common/block/tech/BlockTripWireHook.java index af7e37a..95cb387 100755 --- a/common/src/common/block/tech/BlockTripWireHook.java +++ b/common/src/common/block/tech/BlockTripWireHook.java @@ -1,12 +1,12 @@ package common.block.tech; import common.block.Block; +import common.block.Material; import common.entity.types.EntityLiving; import common.init.Blocks; import common.init.SoundEvent; import common.item.CheatTab; import common.item.ItemStack; -import common.material.Material; import common.model.BlockLayer; import common.model.Model; import common.model.ModelProvider; @@ -32,9 +32,9 @@ public class BlockTripWireHook extends Block public BlockTripWireHook() { - super(Material.circuits); + super(Material.SMALL); this.setDefaultState(this.getBaseState().withProperty(FACING, Facing.NORTH).withProperty(POWERED, Boolean.valueOf(false)).withProperty(ATTACHED, Boolean.valueOf(false)).withProperty(SUSPENDED, Boolean.valueOf(false))); - this.setTab(CheatTab.tabTech); + this.setTab(CheatTab.TECHNOLOGY); // this.setTickRandomly(true); } diff --git a/common/src/common/block/tech/BlockWarpChest.java b/common/src/common/block/tech/BlockWarpChest.java index d6270b7..e1cfa54 100755 --- a/common/src/common/block/tech/BlockWarpChest.java +++ b/common/src/common/block/tech/BlockWarpChest.java @@ -1,6 +1,7 @@ package common.block.tech; import common.block.Block; +import common.block.Material; import common.entity.npc.EntityNPC; import common.entity.types.EntityLiving; import common.init.Blocks; @@ -9,7 +10,6 @@ import common.inventory.InventoryWarpChest; import common.item.CheatTab; import common.item.Item; import common.item.ItemStack; -import common.material.Material; import common.model.Model; import common.model.ModelProvider; import common.model.ModelRotation; @@ -29,9 +29,9 @@ public class BlockWarpChest extends Block public BlockWarpChest() { - super(Material.rock); + super(Material.SOLID); this.setDefaultState(this.getBaseState().withProperty(FACING, Facing.NORTH)); - this.setTab(CheatTab.tabTech); + this.setTab(CheatTab.TECHNOLOGY); this.setBlockBounds(0.0625F, 0.0F, 0.0625F, 0.9375F, 0.875F, 0.9375F); } diff --git a/common/src/common/block/tech/BlockWorkbench.java b/common/src/common/block/tech/BlockWorkbench.java index fcaea1d..bc54d96 100755 --- a/common/src/common/block/tech/BlockWorkbench.java +++ b/common/src/common/block/tech/BlockWorkbench.java @@ -1,13 +1,13 @@ package common.block.tech; import common.block.Block; +import common.block.Material; import common.entity.npc.EntityNPC; import common.init.BlockRegistry; import common.inventory.Container; import common.inventory.ContainerWorkbench; import common.inventory.InventoryPlayer; import common.item.CheatTab; -import common.material.Material; import common.model.Model; import common.model.ModelProvider; import common.tileentity.IInteractionObject; @@ -22,8 +22,8 @@ public class BlockWorkbench extends Block public BlockWorkbench(int size) { - super(Material.wood); - this.setTab(CheatTab.tabTech); + super(Material.WOOD); + this.setTab(CheatTab.TECHNOLOGY); this.size = size; } diff --git a/common/src/common/block/tile/BlockBanner.java b/common/src/common/block/tile/BlockBanner.java index 78a419b..cec3815 100755 --- a/common/src/common/block/tile/BlockBanner.java +++ b/common/src/common/block/tile/BlockBanner.java @@ -2,11 +2,11 @@ package common.block.tile; import common.block.Block; import common.block.BlockContainer; +import common.block.Material; import common.entity.npc.EntityNPC; import common.init.Items; import common.item.Item; import common.item.ItemStack; -import common.material.Material; import common.model.Transforms; import common.nbt.NBTTagCompound; import common.properties.IProperty; @@ -30,7 +30,7 @@ public class BlockBanner extends BlockContainer public BlockBanner() { - super(Material.wood); + super(Material.WOOD); float f = 0.25F; float f1 = 1.0F; this.setBlockBounds(0.5F - f, 0.0F, 0.5F - f, 0.5F + f, f1, 0.5F + f); diff --git a/common/src/common/block/tile/BlockSign.java b/common/src/common/block/tile/BlockSign.java index 639a546..76fde3c 100755 --- a/common/src/common/block/tile/BlockSign.java +++ b/common/src/common/block/tile/BlockSign.java @@ -1,11 +1,11 @@ package common.block.tile; import common.block.BlockContainer; +import common.block.Material; import common.entity.npc.EntityNPC; import common.init.Config; import common.init.Items; import common.item.Item; -import common.material.Material; import common.rng.Random; import common.tileentity.TileEntity; import common.tileentity.TileEntitySign; @@ -20,7 +20,7 @@ public class BlockSign extends BlockContainer { public BlockSign() { - super(Material.wood); + super(Material.WOOD); float f = 0.25F; float f1 = 1.0F; this.setBlockBounds(0.5F - f, 0.0F, 0.5F - f, 0.5F + f, f1, 0.5F + f); diff --git a/common/src/common/block/tile/BlockSkull.java b/common/src/common/block/tile/BlockSkull.java index e85a740..e72d161 100755 --- a/common/src/common/block/tile/BlockSkull.java +++ b/common/src/common/block/tile/BlockSkull.java @@ -1,11 +1,11 @@ package common.block.tile; import common.block.BlockContainer; +import common.block.Material; import common.entity.types.EntityLiving; import common.init.Items; import common.item.Item; import common.item.ItemStack; -import common.material.Material; import common.model.Transforms; import common.properties.IProperty; import common.properties.PropertyDirection; @@ -26,7 +26,7 @@ public class BlockSkull extends BlockContainer public BlockSkull() { - super(Material.circuits); + super(Material.SMALL); this.setDefaultState(this.getBaseState().withProperty(FACING, Facing.NORTH)); this.setBlockBounds(0.25F, 0.0F, 0.25F, 0.75F, 0.5F, 0.75F); } diff --git a/common/src/common/entity/Entity.java b/common/src/common/entity/Entity.java index 890739c..d8bd638 100755 --- a/common/src/common/entity/Entity.java +++ b/common/src/common/entity/Entity.java @@ -3,6 +3,7 @@ package common.entity; import java.util.List; import common.block.Block; +import common.block.Material; import common.block.SoundType; import common.block.artificial.BlockFence; import common.block.artificial.BlockFenceGate; @@ -25,7 +26,6 @@ import common.init.SoundEvent; import common.init.UniverseRegistry; import common.item.Item; import common.item.ItemStack; -import common.material.Material; import common.model.ParticleType; import common.nbt.NBTTagCompound; import common.nbt.NBTTagDouble; @@ -1014,7 +1014,7 @@ public abstract class Entity this.worldObj.spawnParticle(ParticleType.WATER_BUBBLE, this.posX + (double)f2, (double)(f1 + 1.0F), this.posZ + (double)f3, this.motionX, this.motionY - (double)(this.rand.floatv() * 0.2F), this.motionZ); } - if(this.worldObj.getState(new BlockPos(this.posX, this.posY, this.posZ)).getBlock().getMaterial() == Material.water) { + if(this.worldObj.getState(new BlockPos(this.posX, this.posY, this.posZ)).getBlock().getMaterial() == Material.WATER) { for (int j = 0; (float)j < 1.0F + this.width * 20.0F; ++j) { float f4 = (this.rand.floatv() * 2.0F - 1.0F) * this.width; diff --git a/common/src/common/entity/item/EntityItem.java b/common/src/common/entity/item/EntityItem.java index 6b7abf7..82f47e4 100755 --- a/common/src/common/entity/item/EntityItem.java +++ b/common/src/common/entity/item/EntityItem.java @@ -1,5 +1,6 @@ package common.entity.item; +import common.block.Material; import common.color.TextColor; import common.entity.DamageSource; import common.entity.Entity; @@ -12,7 +13,6 @@ import common.init.ItemRegistry; import common.init.SoundEvent; import common.item.ItemStack; import common.log.Log; -import common.material.Material; import common.model.ParticleType; import common.nbt.NBTTagCompound; import common.util.BlockPos; @@ -125,7 +125,7 @@ public class EntityItem extends Entity if (flag || this.ticksExisted % 25 == 0) { - if (this.worldObj.getState(new BlockPos(this)).getBlock().getMaterial() == Material.lava) + if (this.worldObj.getState(new BlockPos(this)).getBlock().getMaterial() == Material.LAVA) { this.motionY = 0.20000000298023224D; this.motionX = (double)((this.rand.floatv() - this.rand.floatv()) * 0.2F); diff --git a/common/src/common/entity/item/EntityXp.java b/common/src/common/entity/item/EntityXp.java index 43a5e6a..a097b69 100755 --- a/common/src/common/entity/item/EntityXp.java +++ b/common/src/common/entity/item/EntityXp.java @@ -1,5 +1,6 @@ package common.entity.item; +import common.block.Material; import common.color.TextColor; import common.entity.DamageSource; import common.entity.Entity; @@ -8,7 +9,6 @@ import common.entity.npc.EntityNPC; import common.entity.types.IObjectData; import common.init.Config; import common.init.SoundEvent; -import common.material.Material; import common.model.ParticleType; import common.nbt.NBTTagCompound; import common.util.BlockPos; @@ -106,7 +106,7 @@ public class EntityXp extends Entity implements IObjectData this.prevZ = this.posZ; this.motionY -= 0.029999999329447746D; - if (this.worldObj.getState(new BlockPos(this)).getBlock().getMaterial() == Material.lava) + if (this.worldObj.getState(new BlockPos(this)).getBlock().getMaterial() == Material.LAVA) { this.motionY = 0.20000000298023224D; this.motionX = (double)((this.rand.floatv() - this.rand.floatv()) * 0.2F); diff --git a/common/src/common/init/BlockRegistry.java b/common/src/common/init/BlockRegistry.java index 036be1a..509cb19 100755 --- a/common/src/common/init/BlockRegistry.java +++ b/common/src/common/init/BlockRegistry.java @@ -126,7 +126,6 @@ import common.block.tile.BlockWallSign; import common.color.DyeColor; import common.init.FluidRegistry.LiquidType; import common.item.CheatTab; -import common.material.Material; import common.util.ObjectIntIdentityMap; import common.util.RegistryNamespacedDefaultedByKey; import common.world.State; @@ -271,19 +270,19 @@ public abstract class BlockRegistry { Block stone = (new BlockStone()).setHardness(1.5F).setResistance(10.0F).setStepSound(SoundType.STONE).setDisplay("Stein"); registerBlock(1, "stone", stone); registerBlock(2, "bedrock", (new BlockBedrock()).setHardness(1000.0F).setResistance(100000.0F).setStepSound(SoundType.STONE) - .setDisplay("Grundgestein").setTab(CheatTab.tabNature).setMiningLevel(6)); + .setDisplay("Grundgestein").setTab(CheatTab.NATURE).setMiningLevel(6)); registerBlock(3, "rock", (new BlockRock()).setHardness(2.0F).setResistance(15.0F).setStepSound(SoundType.STONE).setDisplay("Felsen")); registerBlock(4, "hellrock", (new BlockHellRock()).setHardness(0.4F).setStepSound(SoundType.STONE).setDisplay("Höllenstein")); - registerBlock(5, "cell_rock", (new Block(Material.clay)).setHardness(1.0F).setResistance(3.0F) - .setStepSound(SoundType.SLIME).setDisplay("Zellstein").setTab(CheatTab.tabNature)); - registerBlock(6, "moon_rock", (new Block(Material.rock)).setHardness(2.5F).setResistance(10.0F) - .setStepSound(SoundType.STONE).setDisplay("Mondgestein").setTab(CheatTab.tabNature)); - Block cobblestone = (new Block(Material.rock)).setHardness(2.0F).setResistance(10.0F).setStepSound(SoundType.STONE) - .setDisplay("Bruchstein").setTab(CheatTab.tabNature); + registerBlock(5, "cell_rock", (new Block(Material.LOOSE)).setHardness(1.0F).setResistance(3.0F) + .setStepSound(SoundType.SLIME).setDisplay("Zellstein").setTab(CheatTab.NATURE)); + registerBlock(6, "moon_rock", (new Block(Material.SOLID)).setHardness(2.5F).setResistance(10.0F) + .setStepSound(SoundType.STONE).setDisplay("Mondgestein").setTab(CheatTab.NATURE)); + Block cobblestone = (new Block(Material.SOLID)).setHardness(2.0F).setResistance(10.0F).setStepSound(SoundType.STONE) + .setDisplay("Bruchstein").setTab(CheatTab.NATURE); registerBlock(7, "cobblestone", cobblestone); - registerBlock(8, "mossy_cobblestone", (new Block(Material.rock)).setHardness(2.0F).setResistance(10.0F).setStepSound(SoundType.STONE) - .setDisplay("Bemooster Bruchstein").setTab(CheatTab.tabNature)); + registerBlock(8, "mossy_cobblestone", (new Block(Material.SOLID)).setHardness(2.0F).setResistance(10.0F).setStepSound(SoundType.STONE) + .setDisplay("Bemooster Bruchstein").setTab(CheatTab.NATURE)); Block sandstone = (new BlockSandStone()).setStepSound(SoundType.STONE).setHardness(0.8F).setDisplay("Sandstein"); registerBlock(9, "sandstone", sandstone); registerBlock(10, "obsidian", (new BlockObsidian()).setHardness(50.0F).setResistance(2000.0F).setStepSound(SoundType.STONE) @@ -292,16 +291,16 @@ public abstract class BlockRegistry { (new BlockClay()).setHardness(0.6F).setStepSound(SoundType.GRAVEL).setDisplay("Ton").setShovelHarvestable()); registerBlock(12, "hardened_clay", (new BlockHardenedClay()).setHardness(1.25F).setResistance(7.0F).setStepSound(SoundType.STONE).setDisplay("Gebrannter Ton")); - registerBlock(13, "stained_hardened_clay", (new BlockColored(Material.rock)).setHardness(1.25F).setResistance(7.0F) - .setStepSound(SoundType.STONE).setDisplay("gefärbter Ton").setTab(CheatTab.tabNature)); - registerBlock(14, "coal_block", (new Block(Material.rock)).setHardness(5.0F).setResistance(10.0F) - .setStepSound(SoundType.STONE).setDisplay("Kohleblock").setTab(CheatTab.tabNature)); + registerBlock(13, "stained_hardened_clay", (new BlockColored(Material.SOLID)).setHardness(1.25F).setResistance(7.0F) + .setStepSound(SoundType.STONE).setDisplay("gefärbter Ton").setTab(CheatTab.NATURE)); + registerBlock(14, "coal_block", (new Block(Material.SOLID)).setHardness(5.0F).setResistance(10.0F) + .setStepSound(SoundType.STONE).setDisplay("Kohleblock").setTab(CheatTab.NATURE)); registerBlock(15, "sand", (new BlockSand()).setHardness(0.5F).setStepSound(SoundType.SAND).setDisplay("Sand").setShovelHarvestable()); registerBlock(16, "gravel", (new BlockGravel()).setHardness(0.6F).setStepSound(SoundType.GRAVEL).setDisplay("Kies").setShovelHarvestable()); registerBlock(17, "ash", - (new Block(Material.sand)).setHardness(0.2F).setStepSound(SoundType.SAND).setDisplay("Asche") - .setTab(CheatTab.tabNature).setShovelHarvestable()); + (new Block(Material.LOOSE)).setHardness(0.2F).setStepSound(SoundType.SAND).setDisplay("Asche") + .setTab(CheatTab.NATURE).setShovelHarvestable()); registerBlock(18, "snow_layer", (new BlockSnow()).setHardness(0.1F).setStepSound(SoundType.SNOW).setDisplay("Schnee").setLightOpacity(0) .setShovelHarvestable()); registerBlock(19, "snow", @@ -312,11 +311,11 @@ public abstract class BlockRegistry { (new BlockPackedIce()).setHardness(0.5F).setStepSound(SoundType.GLASS).setDisplay("Packeis").setMiningLevel(0)); registerBlock(22, "soul_sand", (new BlockSoulSand()).setHardness(0.5F).setStepSound(SoundType.SAND).setDisplay("Seelensand").setShovelHarvestable()); - registerBlock(23, "glowstone", (new BlockGlowstone(Material.glass)).setHardness(0.3F).setStepSound(SoundType.GLASS).setLightLevel(1.0F) + registerBlock(23, "glowstone", (new BlockGlowstone(Material.TRANSLUCENT)).setHardness(0.3F).setStepSound(SoundType.GLASS).setLightLevel(1.0F) .setDisplay("Glowstone")); registerBlock(24, "blackened_stone", (new BlockBlackenedStone()).setHardness(1.5F).setResistance(10.0F).setStepSound(SoundType.STONE).setDisplay("Schwarzstein")); - registerBlock(25, "blackened_cobble", (new Block(Material.rock)).setHardness(2.0F).setResistance(10.0F).setStepSound(SoundType.STONE) - .setDisplay("Schwarzbruchstein").setTab(CheatTab.tabNature)); + registerBlock(25, "blackened_cobble", (new Block(Material.SOLID)).setHardness(2.0F).setResistance(10.0F).setStepSound(SoundType.STONE) + .setDisplay("Schwarzbruchstein").setTab(CheatTab.NATURE)); registerFluid(32, 33, "water", "Wasser", true, LiquidType.WATER, false, 0, 5, 0.0f, "water", "waterflow"); @@ -343,7 +342,7 @@ public abstract class BlockRegistry { .setDisplay("Schwarzes Quarzerz")); registerBlock(68, "redstone_ore", (new BlockRedstoneOre(false)).setHardness(3.0F).setResistance(5.0F).setStepSound(SoundType.STONE) - .setDisplay("Redstone-Erz").setTab(CheatTab.tabGems).setMiningLevel(2)); + .setDisplay("Redstone-Erz").setTab(CheatTab.GEMS).setMiningLevel(2)); registerBlock(69, "lit_redstone_ore", (new BlockRedstoneOre(true)).setLightLevel(0.625F).setHardness(3.0F).setResistance(5.0F) .setStepSound(SoundType.STONE).setDisplay("Redstone-Erz").setMiningLevel(2)); int bid = 70; @@ -369,12 +368,12 @@ public abstract class BlockRegistry { (new BlockGrass()).setHardness(0.6F).setStepSound(SoundType.GRASS).setDisplay("Gras").setShovelHarvestable()); registerBlock(130, "mycelium", (new BlockMycelium()).setHardness(0.6F).setStepSound(SoundType.GRASS).setDisplay("Myzel").setShovelHarvestable()); - registerBlock(131, "tian", (new Block(Material.rock)).setHardness(2.0F).setResistance(15.0F).setStepSound(SoundType.STONE) - .setDisplay("Tian").setTab(CheatTab.tabNature)); + registerBlock(131, "tian", (new Block(Material.SOLID)).setHardness(2.0F).setResistance(15.0F).setStepSound(SoundType.STONE) + .setDisplay("Tian").setTab(CheatTab.NATURE)); registerBlock(132, "tian_soil", (new BlockTianSoil()).setHardness(2.0F).setResistance(15.0F).setStepSound(SoundType.STONE) - .setDisplay("Tianerde").setTab(CheatTab.tabNature)); - registerBlock(133, "moon_cheese", (new BlockTreasure(Material.gourd)).setHardness(1.5F).setResistance(5.0F) - .setStepSound(SoundType.CLOTH).setDisplay("Mondkäse").setTab(CheatTab.tabNature)); + .setDisplay("Tianerde").setTab(CheatTab.NATURE)); + registerBlock(133, "moon_cheese", (new BlockTreasure(Material.SOFT)).setHardness(1.5F).setResistance(5.0F) + .setStepSound(SoundType.CLOTH).setDisplay("Mondkäse").setTab(CheatTab.NATURE)); registerBlock(134, "slime_block", (new BlockSlime()).setDisplay("Schleimblock").setStepSound(SoundType.SLIME)); registerBlock(135, "blackened_dirt", (new BlockBlackenedDirt()).setHardness(0.5F).setStepSound(SoundType.GRAVEL).setDisplay("Schwarzerde").setShovelHarvestable()); @@ -402,12 +401,12 @@ public abstract class BlockRegistry { Block brownMushroom = (new BlockMushroom()).setHardness(0.0F).setStepSound(SoundType.GRASS).setLightLevel(0.125F) .setDisplay("Pilz"); registerBlock(160, "brown_mushroom", brownMushroom); - registerBlock(161, "brown_mushroom_block", (new BlockHugeMushroom(Material.wood, brownMushroom)).setHardness(0.2F) - .setStepSound(SoundType.WOOD).setDisplay("Pilzblock").setTab(CheatTab.tabPlants)); + registerBlock(161, "brown_mushroom_block", (new BlockHugeMushroom(Material.WOOD, brownMushroom)).setHardness(0.2F) + .setStepSound(SoundType.WOOD).setDisplay("Pilzblock").setTab(CheatTab.PLANTS)); Block redMushrooom = (new BlockMushroom()).setHardness(0.0F).setStepSound(SoundType.GRASS).setDisplay("Pilz"); registerBlock(162, "red_mushroom", redMushrooom); - registerBlock(163, "red_mushroom_block", (new BlockHugeMushroom(Material.wood, redMushrooom)).setHardness(0.2F) - .setStepSound(SoundType.WOOD).setDisplay("Pilzblock").setTab(CheatTab.tabPlants)); + registerBlock(163, "red_mushroom_block", (new BlockHugeMushroom(Material.WOOD, redMushrooom)).setHardness(0.2F) + .setStepSound(SoundType.WOOD).setDisplay("Pilzblock").setTab(CheatTab.PLANTS)); registerBlock(164, "blue_mushroom", (new BlockBlueShroom()).setHardness(0.0F).setStepSound(SoundType.GRASS).setLightLevel(0.5F) .setDisplay("Tianpilz")); @@ -438,25 +437,25 @@ public abstract class BlockRegistry { - registerBlock(256, "lapis_block", (new Block(Material.iron)).setHardness(3.0F).setResistance(5.0F) - .setStepSound(SoundType.STONE).setDisplay("Lapislazuliblock").setTab(CheatTab.tabGems).setMiningLevel(1)); - registerBlock(257, "emerald_block", (new Block(Material.iron)).setHardness(5.0F).setResistance(10.0F) - .setStepSound(SoundType.STONE).setDisplay("Smaragdblock").setTab(CheatTab.tabGems).setMiningLevel(2)); - registerBlock(258, "redstone_block", (new BlockCompressedPowered(Material.iron)).setHardness(5.0F).setResistance(10.0F) - .setStepSound(SoundType.STONE).setDisplay("Redstone-Block").setTab(CheatTab.tabTech)); + registerBlock(256, "lapis_block", (new Block(Material.SOLID)).setHardness(3.0F).setResistance(5.0F) + .setStepSound(SoundType.STONE).setDisplay("Lapislazuliblock").setTab(CheatTab.GEMS).setMiningLevel(1)); + registerBlock(257, "emerald_block", (new Block(Material.SOLID)).setHardness(5.0F).setResistance(10.0F) + .setStepSound(SoundType.STONE).setDisplay("Smaragdblock").setTab(CheatTab.GEMS).setMiningLevel(2)); + registerBlock(258, "redstone_block", (new BlockCompressedPowered(Material.SOLID)).setHardness(5.0F).setResistance(10.0F) + .setStepSound(SoundType.STONE).setDisplay("Redstone-Block").setTab(CheatTab.TECHNOLOGY)); registerBlock(270, "glass", (new BlockGlass()).setHardness(0.3F).setStepSound(SoundType.GLASS).setDisplay("Glas")); registerBlock(271, "stained_glass", (new BlockStainedGlass()).setHardness(0.3F).setStepSound(SoundType.GLASS).setDisplay("gefärbtes Glas")); registerBlock(272, "glass_pane", - (new BlockPane(Material.glass, false)).setHardness(0.3F).setStepSound(SoundType.GLASS).setDisplay("Glasscheibe")); + (new BlockPane(Material.TRANSLUCENT, false)).setHardness(0.3F).setStepSound(SoundType.GLASS).setDisplay("Glasscheibe")); registerBlock(273, "stained_glass_pane", (new BlockStainedGlassPane()).setHardness(0.3F).setStepSound(SoundType.GLASS).setDisplay("gefärbte Glasscheibe")); - registerBlock(280, "wool", (new BlockColored(Material.cloth)).setHardness(0.8F).setStepSound(SoundType.CLOTH).setDisplay("Wolle") + registerBlock(280, "wool", (new BlockColored(Material.BURNABLE)).setHardness(0.8F).setStepSound(SoundType.CLOTH).setDisplay("Wolle") .setShearsEfficiency(1)); registerBlock(281, "carpet", (new BlockCarpet()).setHardness(0.1F).setStepSound(SoundType.CLOTH).setDisplay("Teppich").setLightOpacity(0)); @@ -469,20 +468,20 @@ public abstract class BlockRegistry { (new BlockLadder()).setHardness(0.4F).setStepSound(SoundType.LADDER).setDisplay("Leiter").setAxeHarvestable()); registerBlock(301, "torch", (new BlockTorch()).setHardness(0.0F).setLightLevel(0.9375F).setStepSound(SoundType.WOOD).setDisplay("Fackel")); - registerBlock(302, "lamp", (new Block(Material.glass)).setHardness(0.3F).setStepSound(SoundType.GLASS).setLightLevel(1.0F) - .setDisplay("Lampe").setTab(CheatTab.tabTech)); + registerBlock(302, "lamp", (new Block(Material.TRANSLUCENT)).setHardness(0.3F).setStepSound(SoundType.GLASS).setLightLevel(1.0F) + .setDisplay("Lampe").setTab(CheatTab.TECHNOLOGY)); registerBlock(304, "bookshelf", (new BlockBookshelf()).setHardness(1.5F).setStepSound(SoundType.WOOD).setDisplay("Bücherregal")); registerBlock(305, "cake", (new BlockCake()).setHardness(0.5F).setStepSound(SoundType.CLOTH).setDisplay("Kuchen")); registerBlock(306, "dragon_egg", (new BlockDragonEgg()).setHardness(3.0F).setResistance(15.0F).setStepSound(SoundType.STONE) - .setLightLevel(0.125F).setDisplay("Drachenei").setTab(CheatTab.tabDeco)); + .setLightLevel(0.125F).setDisplay("Drachenei").setTab(CheatTab.DECORATION)); registerBlock(307, "flower_pot", (new BlockFlowerPot()).setHardness(0.0F).setStepSound(SoundType.STONE).setDisplay("Blumentopf")); - registerBlock(308, "sponge", (new Block(Material.sponge)).setHardness(0.6F).setStepSound(SoundType.GRASS).setDisplay("Schwamm") - .setTab(CheatTab.tabDeco)); + registerBlock(308, "sponge", (new Block(Material.LOOSE)).setHardness(0.6F).setStepSound(SoundType.GRASS).setDisplay("Schwamm") + .setTab(CheatTab.DECORATION)); registerBlock(309, "skull", (new BlockSkull()).setHardness(1.0F).setStepSound(SoundType.STONE).setDisplay("Kopf")); registerBlock(310, "lit_pumpkin", (new BlockPumpkin()).setHardness(1.0F).setStepSound(SoundType.WOOD).setLightLevel(1.0F).setDisplay("Kürbislaterne")); registerBlock(311, "hay_block", (new BlockHay()).setHardness(0.5F).setStepSound(SoundType.GRASS).setDisplay("Strohballen") - .setTab(CheatTab.tabDeco)); + .setTab(CheatTab.DECORATION)); registerBlock(312, "sign", (new BlockStandingSign()).setHardness(1.0F).setStepSound(SoundType.WOOD).setDisplay("Schild")); registerBlock(313, "wall_sign", @@ -494,12 +493,12 @@ public abstract class BlockRegistry { registerBlock(390, "portal", (new BlockPortal()).setHardness(0.0F).setStepSound(SoundType.GLASS).setLightLevel(0.75F).setDisplay("Portal")); - registerBlock(391, "floor_portal", (new BlockFloorPortal(Material.portal)).setHardness(0.0F).setDisplay("Portal")); + registerBlock(391, "floor_portal", (new BlockFloorPortal(Material.PORTAL)).setHardness(0.0F).setDisplay("Portal")); registerBlock(392, "portal_frame", (new BlockPortalFrame()).setStepSound(SoundType.GLASS).setLightLevel(0.125F).setHardness(5.0F) - .setDisplay("Portalrahmen").setResistance(2000.0F).setTab(CheatTab.tabTech)); + .setDisplay("Portalrahmen").setResistance(2000.0F).setTab(CheatTab.TECHNOLOGY)); registerBlock(400, "farmland", (new BlockFarmland()).setHardness(0.6F).setStepSound(SoundType.GRAVEL).setDisplay("Ackerboden") - .setShovelHarvestable().setTab(CheatTab.tabPlants)); + .setShovelHarvestable().setTab(CheatTab.PLANTS)); registerBlock(401, "wheat", (new BlockCrops()).setDisplay("Getreide")); registerBlock(402, "carrot", (new BlockCarrot()).setDisplay("Karotten")); registerBlock(403, "potato", (new BlockPotato()).setDisplay("Kartoffeln")); @@ -512,16 +511,16 @@ public abstract class BlockRegistry { for(MetalType metal : MetalType.values()) { // String loc = metal.name.substring(0, 1).toUpperCase() + metal.name.substring(1); registerBlock(bid++, metal.name + "_block", - (new Block(Material.iron)).setHardness(5.0F).setResistance(10.0F).setStepSound(SoundType.STONE) - .setDisplay(metal.display + "block").setTab(CheatTab.tabGems).setMiningLevel(1) + (new Block(Material.SOLID)).setHardness(5.0F).setResistance(10.0F).setStepSound(SoundType.STONE) + .setDisplay(metal.display + "block").setTab(CheatTab.GEMS).setMiningLevel(1) .setLightLevel(metal.radioactivity > 0.0F ? 0.25F : 0.0F).setRadiation(metal.radioactivity * 2.0f)); } bid = 540; for(OreType ore : OreType.values()) { // String loc = ore.name.substring(0, 1).toUpperCase() + ore.name.substring(1); registerBlock(bid++, ore.name + "_block", - (new Block(Material.iron)).setHardness(5.0F).setResistance(10.0F).setStepSound(SoundType.STONE) - .setDisplay(ore.display + "block").setTab(CheatTab.tabGems) + (new Block(Material.SOLID)).setHardness(5.0F).setResistance(10.0F).setStepSound(SoundType.STONE) + .setDisplay(ore.display + "block").setTab(CheatTab.GEMS) .setMiningLevel(ore.material.getHarvestLevel() - 1)); } @@ -531,18 +530,18 @@ public abstract class BlockRegistry { registerBlock(600, "stone_slab", - (new BlockSlab(Material.rock, "stone_slab_side", "double_stone_top", "double_stone_top")) + (new BlockSlab(Material.SOLID, "stone_slab_side", "double_stone_top", "double_stone_top")) .setHardness(2.0F).setResistance(10.0F).setStepSound(SoundType.STONE).setDisplay("Steinstufe")); registerBlock(601, "stone_stairs", (new BlockStairs(stone.getState())).setDisplay("Steintreppe")); registerBlock(610, "cobblestone_slab", - (new BlockSlab(Material.rock, "cobblestone")) + (new BlockSlab(Material.SOLID, "cobblestone")) .setHardness(2.0F).setResistance(10.0F).setStepSound(SoundType.STONE).setDisplay("Bruchsteinstufe")); registerBlock(611, "cobblestone_stairs", (new BlockStairs(cobblestone.getState())).setDisplay("Bruchsteintreppe")); registerBlock(612, "cobblestone_wall", (new BlockWall(cobblestone)).setDisplay("Bruchsteinmauer")); registerBlock(620, "sandstone_slab", - (new BlockSlab(Material.rock, "sandstone_normal", "sandstone_bottom", "sandstone_all")) + (new BlockSlab(Material.SOLID, "sandstone_normal", "sandstone_bottom", "sandstone_all")) .setHardness(2.0F).setResistance(10.0F).setStepSound(SoundType.STONE).setDisplay("Sandsteinstufe")); registerBlock(621, "sandstone_stairs", (new BlockStairs(sandstone.getState().withProperty(BlockSandStone.TYPE, BlockSandStone.EnumType.DEFAULT), @@ -552,25 +551,25 @@ public abstract class BlockRegistry { Block quartz = (new BlockQuartz("")).setStepSound(SoundType.STONE).setHardness(0.8F).setDisplay("Quarzblock"); registerBlock(630, "quartz_block", quartz); registerBlock(631, "quartz_slab", - (new BlockSlab(Material.rock, "quartz_block_side", "quartz_block_bottom", "quartz_top")) + (new BlockSlab(Material.SOLID, "quartz_block_side", "quartz_block_bottom", "quartz_top")) .setHardness(2.0F).setResistance(10.0F).setStepSound(SoundType.STONE).setDisplay("Quarzstufe")); registerBlock(632, "quartz_stairs", (new BlockStairs(quartz.getState().withProperty(BlockQuartz.VARIANT, BlockQuartz.EnumType.DEFAULT), "quartz_block_bottom", "quartz_top")) .setDisplay("Quarztreppe")); - registerBlock(640, "iron_bars", (new BlockPane(Material.iron, true)).setHardness(5.0F).setResistance(10.0F).setStepSound(SoundType.STONE) + registerBlock(640, "iron_bars", (new BlockPane(Material.SOLID, true)).setHardness(5.0F).setResistance(10.0F).setStepSound(SoundType.STONE) .setDisplay("Eisengitter")); registerBlock(641, "iron_door", - (new BlockDoor(Material.iron)).setHardness(5.0F).setStepSound(SoundType.STONE).setDisplay("Eisentür")); + (new BlockDoor(Material.SOLID)).setHardness(5.0F).setStepSound(SoundType.STONE).setDisplay("Eisentür")); registerBlock(642, "iron_trapdoor", - (new BlockTrapDoor(Material.iron)).setHardness(5.0F).setStepSound(SoundType.STONE).setDisplay("Eisenfalltür")); + (new BlockTrapDoor(Material.SOLID)).setHardness(5.0F).setStepSound(SoundType.STONE).setDisplay("Eisenfalltür")); - Block brick = (new Block(Material.rock)).setHardness(2.0F).setResistance(10.0F).setStepSound(SoundType.STONE) - .setDisplay("Ziegelsteine").setTab(CheatTab.tabBlocks); + Block brick = (new Block(Material.SOLID)).setHardness(2.0F).setResistance(10.0F).setStepSound(SoundType.STONE) + .setDisplay("Ziegelsteine").setTab(CheatTab.BLOCKS); registerBlock(650, "brick_block", brick); registerBlock(651, "brick_slab", - (new BlockSlab(Material.rock, "brick_block")) + (new BlockSlab(Material.SOLID, "brick_block")) .setHardness(2.0F).setResistance(10.0F).setStepSound(SoundType.STONE).setDisplay("Ziegelstufe")); registerBlock(652, "brick_stairs", (new BlockStairs(brick.getState())).setDisplay("Ziegeltreppe")); @@ -578,38 +577,38 @@ public abstract class BlockRegistry { .setDisplay("Steinziegel"); registerBlock(660, "stonebrick", stonebrick); registerBlock(661, "stonebrick_slab", - (new BlockSlab(Material.rock, "stonebrick_default")) + (new BlockSlab(Material.SOLID, "stonebrick_default")) .setHardness(2.0F).setResistance(10.0F).setStepSound(SoundType.STONE).setDisplay("Steinziegelstufe")); registerBlock(662, "stonebrick_stairs", (new BlockStairs(stonebrick.getState().withProperty(BlockStoneBrick.VARIANT, BlockStoneBrick.EnumType.DEFAULT))) .setDisplay("Steinziegeltreppe")); - Block bloodBrick = (new Block(Material.rock)).setHardness(2.0F).setResistance(10.0F).setStepSound(SoundType.STONE) - .setDisplay("Blutrote Ziegel").setTab(CheatTab.tabBlocks); + Block bloodBrick = (new Block(Material.SOLID)).setHardness(2.0F).setResistance(10.0F).setStepSound(SoundType.STONE) + .setDisplay("Blutrote Ziegel").setTab(CheatTab.BLOCKS); registerBlock(670, "blood_brick", bloodBrick); registerBlock(671, "blood_brick_slab", - (new BlockSlab(Material.rock, "blood_brick")) + (new BlockSlab(Material.SOLID, "blood_brick")) .setHardness(2.0F).setResistance(10.0F).setStepSound(SoundType.STONE).setDisplay("Blutrote Ziegelstufe")); - registerBlock(672, "blood_brick_fence", (new BlockFence(Material.rock, "blood_brick")).setHardness(2.0F).setResistance(10.0F) + registerBlock(672, "blood_brick_fence", (new BlockFence(Material.SOLID, "blood_brick")).setHardness(2.0F).setResistance(10.0F) .setStepSound(SoundType.STONE).setDisplay("Blutroter Ziegelzaun")); registerBlock(673, "blood_brick_stairs", (new BlockStairs(bloodBrick.getState())).setDisplay("Blutrote Ziegeltreppe")); - Block blackBrick = (new Block(Material.rock)).setHardness(2.0F).setResistance(10.0F).setStepSound(SoundType.STONE) - .setDisplay("Schwarze Ziegel").setTab(CheatTab.tabBlocks); + Block blackBrick = (new Block(Material.SOLID)).setHardness(2.0F).setResistance(10.0F).setStepSound(SoundType.STONE) + .setDisplay("Schwarze Ziegel").setTab(CheatTab.BLOCKS); registerBlock(680, "black_brick", blackBrick); registerBlock(681, "black_brick_slab", - (new BlockSlab(Material.rock, "black_brick")) + (new BlockSlab(Material.SOLID, "black_brick")) .setHardness(2.0F).setResistance(10.0F).setStepSound(SoundType.STONE).setDisplay("Schwarze Ziegelstufe")); registerBlock(682, "black_brick_stairs", (new BlockStairs(blackBrick.getState())).setDisplay("Schwarze Ziegeltreppe")); - registerBlock(683, "black_brick_fence", (new BlockFence(Material.rock, "black_brick")).setHardness(2.0F).setResistance(10.0F) + registerBlock(683, "black_brick_fence", (new BlockFence(Material.SOLID, "black_brick")).setHardness(2.0F).setResistance(10.0F) .setStepSound(SoundType.STONE).setDisplay("Schwarzer Ziegelzaun")); Block bquartz = (new BlockQuartz("black_")).setStepSound(SoundType.STONE).setHardness(0.8F).setDisplay("Schwarzer Quarzblock"); registerBlock(690, "black_quartz_block", bquartz); registerBlock(691, "black_quartz_slab", - (new BlockSlab(Material.rock, "black_quartz_block_side", "black_quartz_block_bottom", "black_quartz_top")) + (new BlockSlab(Material.SOLID, "black_quartz_block_side", "black_quartz_block_bottom", "black_quartz_top")) .setHardness(2.0F).setResistance(10.0F).setStepSound(SoundType.STONE).setDisplay("Schwarze Quarzstufe")); registerBlock(692, "black_quartz_stairs", (new BlockStairs(bquartz.getState().withProperty(BlockQuartz.VARIANT, BlockQuartz.EnumType.DEFAULT), @@ -618,29 +617,29 @@ public abstract class BlockRegistry { bid = 700; for(DecoType deco : DecoType.values()) { - registerBlock(bid++, deco.name, (new Block(Material.rock)).setHardness(2.0F).setResistance(10.0F) - .setStepSound(SoundType.STONE).setDisplay(deco.display).setTab(CheatTab.tabBlocks)); + registerBlock(bid++, deco.name, (new Block(Material.SOLID)).setHardness(2.0F).setResistance(10.0F) + .setStepSound(SoundType.STONE).setDisplay(deco.display).setTab(CheatTab.BLOCKS)); } registerBlock(1000, "trapdoor", - (new BlockTrapDoor(Material.wood)).setHardness(3.0F).setStepSound(SoundType.WOOD).setDisplay("Holzfalltür")); + (new BlockTrapDoor(Material.WOOD)).setHardness(3.0F).setStepSound(SoundType.WOOD).setDisplay("Holzfalltür")); bid = 1100; for(WoodType wood : WoodType.values()) { - Block planks = (new Block(Material.wood)).setHardness(2.0F).setResistance(5.0F).setStepSound(SoundType.WOOD) - .setDisplay(wood.getDisplay() + "holzbretter").setTab(CheatTab.tabWood); + Block planks = (new Block(Material.WOOD)).setHardness(2.0F).setResistance(5.0F).setStepSound(SoundType.WOOD) + .setDisplay(wood.getDisplay() + "holzbretter").setTab(CheatTab.WOOD); registerBlock(bid++, wood.getName() + "_planks", planks); registerBlock(bid++, wood.getName() + "_stairs", (new BlockStairs(planks.getState())) .setDisplay(wood.getDisplay() + "holztreppe")); - registerBlock(bid++, wood.getName() + "_slab", (new BlockSlab(Material.wood, wood.getName() + "_planks")) + registerBlock(bid++, wood.getName() + "_slab", (new BlockSlab(Material.WOOD, wood.getName() + "_planks")) .setHardness(2.0F).setResistance(5.0F).setStepSound(SoundType.WOOD).setDisplay(wood.getDisplay() + "holzstufe")); - registerBlock(bid++, wood.getName() + "_fence", (new BlockFence(Material.wood, wood.getName() + "_planks")) + registerBlock(bid++, wood.getName() + "_fence", (new BlockFence(Material.WOOD, wood.getName() + "_planks")) .setHardness(2.0F).setResistance(5.0F).setStepSound(SoundType.WOOD).setDisplay(wood.getDisplay() + "holzzaun")); registerBlock(bid++, wood.getName() + "_fence_gate", (new BlockFenceGate(wood)).setHardness(2.0F).setResistance(5.0F) .setStepSound(SoundType.WOOD).setDisplay(wood.getDisplay() + "holzzauntor")); - registerBlock(bid++, wood.getName() + "_door", (new BlockDoor(Material.wood)).setHardness(3.0F).setStepSound(SoundType.WOOD) + registerBlock(bid++, wood.getName() + "_door", (new BlockDoor(Material.WOOD)).setHardness(3.0F).setStepSound(SoundType.WOOD) .setDisplay(wood.getDisplay() + "holztür")); } @@ -651,9 +650,9 @@ public abstract class BlockRegistry { (new BlockMobSpawner()).setHardness(5.0F).setStepSound(SoundType.STONE).setDisplay("Monsterspawner")); registerBlock(2002, "workbench", (new BlockWorkbench(3)).setHardness(2.5F).setStepSound(SoundType.WOOD).setDisplay("Werkbank")); registerBlock(2003, "furnace", (new BlockFurnace(false)).setHardness(3.5F).setStepSound(SoundType.STONE).setDisplay("Ofen") - .setTab(CheatTab.tabTech)); + .setTab(CheatTab.TECHNOLOGY)); registerBlock(2004, "lit_furnace", (new BlockFurnace(true)).setHardness(3.5F).setStepSound(SoundType.STONE).setLightLevel(0.875F) - .setDisplay("Ofen (Gefeuert)").setTab(CheatTab.tabTech)); + .setDisplay("Ofen (Gefeuert)").setTab(CheatTab.TECHNOLOGY)); registerBlock(2005, "anvil", (new BlockAnvil()).setHardness(5.0F).setStepSound(SoundType.ANVIL).setResistance(2000.0F).setDisplay("Amboss")); registerBlock(2006, "enchanting_table", @@ -696,13 +695,13 @@ public abstract class BlockRegistry { registerBlock(2500, "lever", (new BlockLever()).setHardness(0.5F).setStepSound(SoundType.WOOD).setDisplay("Hebel")); - registerBlock(2510, "stone_pressure_plate", (new BlockPressurePlate(Material.rock, BlockPressurePlate.Sensitivity.MOBS)).setHardness(0.5F) + registerBlock(2510, "stone_pressure_plate", (new BlockPressurePlate(Material.SOLID, BlockPressurePlate.Sensitivity.MOBS)).setHardness(0.5F) .setStepSound(SoundType.STONE).setDisplay("Steindruckplatte")); - registerBlock(2511, "wooden_pressure_plate", (new BlockPressurePlate(Material.wood, BlockPressurePlate.Sensitivity.EVERYTHING)) + registerBlock(2511, "wooden_pressure_plate", (new BlockPressurePlate(Material.WOOD, BlockPressurePlate.Sensitivity.EVERYTHING)) .setHardness(0.5F).setStepSound(SoundType.WOOD).setDisplay("Holzdruckplatte")); - registerBlock(2512, "light_weighted_pressure_plate", (new BlockPressurePlateWeighted(Material.iron, 15)).setHardness(0.5F) + registerBlock(2512, "light_weighted_pressure_plate", (new BlockPressurePlateWeighted(Material.SOLID, 15)).setHardness(0.5F) .setStepSound(SoundType.WOOD).setDisplay("Wägeplatte (niedrige Gewichte)")); - registerBlock(2513, "heavy_weighted_pressure_plate", (new BlockPressurePlateWeighted(Material.iron, 150)).setHardness(0.5F) + registerBlock(2513, "heavy_weighted_pressure_plate", (new BlockPressurePlateWeighted(Material.SOLID, 150)).setHardness(0.5F) .setStepSound(SoundType.WOOD).setDisplay("Wägeplatte (hohe Gewichte)")); registerBlock(2520, "stone_button", (new BlockButton(false, 20, "stone")).setHardness(0.5F).setStepSound(SoundType.STONE).setDisplay("Knopf")); @@ -714,7 +713,7 @@ public abstract class BlockRegistry { registerBlock(2601, "unlit_redstone_torch", (new BlockRedstoneTorch(false)).setHardness(0.0F).setStepSound(SoundType.WOOD).setDisplay("Redstone-Fackel")); registerBlock(2602, "redstone_torch", (new BlockRedstoneTorch(true)).setHardness(0.0F).setLightLevel(0.5F).setStepSound(SoundType.WOOD) - .setDisplay("Redstone-Fackel").setTab(CheatTab.tabTech)); + .setDisplay("Redstone-Fackel").setTab(CheatTab.TECHNOLOGY)); registerBlock(2603, "repeater", (new BlockRedstoneRepeater(false)).setHardness(0.0F).setStepSound(SoundType.WOOD).setDisplay("Redstone-Verstärker")); registerBlock(2604, "powered_repeater", @@ -724,7 +723,7 @@ public abstract class BlockRegistry { registerBlock(2606, "powered_comparator", (new BlockRedstoneComparator(true)).setHardness(0.0F).setLightLevel(0.625F) .setStepSound(SoundType.WOOD).setDisplay("Redstone-Komparator")); registerBlock(2607, "redstone_lamp", (new BlockRedstoneLight(false)).setHardness(0.3F).setStepSound(SoundType.GLASS) - .setDisplay("Redstone-Lampe").setTab(CheatTab.tabTech)); + .setDisplay("Redstone-Lampe").setTab(CheatTab.TECHNOLOGY)); registerBlock(2608, "lit_redstone_lamp", (new BlockRedstoneLight(true)).setHardness(0.3F).setStepSound(SoundType.GLASS).setDisplay("Redstone-Lampe")); registerBlock(2609, "daylight_detector", new BlockDaylightDetector(false).setDisplay("Tageslichtsensor")); diff --git a/common/src/common/init/DispenserRegistry.java b/common/src/common/init/DispenserRegistry.java index d4ef76d..7b1fcb2 100755 --- a/common/src/common/init/DispenserRegistry.java +++ b/common/src/common/init/DispenserRegistry.java @@ -1,6 +1,7 @@ package common.init; import common.block.Block; +import common.block.Material; import common.block.liquid.BlockDynamicLiquid; import common.block.liquid.BlockLiquid; import common.block.tech.BlockDispenser; @@ -32,7 +33,6 @@ import common.item.ItemDye; import common.item.ItemMonsterPlacer; import common.item.ItemPotion; import common.item.ItemStack; -import common.material.Material; import common.rng.Random; import common.tileentity.TileEntityDispenser; import common.util.BlockPos; diff --git a/common/src/common/init/FluidRegistry.java b/common/src/common/init/FluidRegistry.java index c808342..ad5b6ac 100755 --- a/common/src/common/init/FluidRegistry.java +++ b/common/src/common/init/FluidRegistry.java @@ -4,16 +4,16 @@ import java.util.List; import java.util.Map; import common.block.Block; +import common.block.Material; import common.block.liquid.BlockDynamicLiquid; import common.block.liquid.BlockLiquid; import common.block.liquid.BlockStaticLiquid; import common.collect.Lists; import common.collect.Maps; -import common.material.Material; public abstract class FluidRegistry { public static enum LiquidType { - COLD(Material.coldFluid), HOT(Material.hotFluid), WATER(Material.water), LAVA(Material.lava); + COLD(Material.COLD), HOT(Material.HOT), WATER(Material.WATER), LAVA(Material.LAVA); public final Material material; diff --git a/common/src/common/init/ItemRegistry.java b/common/src/common/init/ItemRegistry.java index d16839e..5c0a660 100755 --- a/common/src/common/init/ItemRegistry.java +++ b/common/src/common/init/ItemRegistry.java @@ -113,7 +113,7 @@ import common.item.ItemSnow; import common.item.ItemSnowball; import common.item.ItemSoup; import common.item.ItemSpaceNavigator; -import common.item.ItemSpade; +import common.item.ItemShovel; import common.item.ItemStack; import common.item.ItemStick; import common.item.ItemSword; @@ -188,7 +188,7 @@ public abstract class ItemRegistry { private static void registerTools(ToolMaterial material, String name, String prefix) { // String loc = name.substring(0, 1).toUpperCase() + name.substring(1); if(material.hasTools()) { - registerItem(name + "_shovel", (new ItemSpade(material)).setDisplay(prefix + "schaufel")); + registerItem(name + "_shovel", (new ItemShovel(material)).setDisplay(prefix + "schaufel")); registerItem(name + "_pickaxe", (new ItemPickaxe(material)).setDisplay(prefix + "spitzhacke")); registerItem(name + "_axe", (new ItemAxe(material)).setDisplay(prefix + "axt")); registerItem(name + "_hoe", (new ItemHoe(material)).setDisplay(prefix + "hacke")); @@ -386,15 +386,15 @@ public abstract class ItemRegistry { registerItem("wand", (new ItemEditWand()).setDisplay("Bearbeitungswerkzeug")); registerItem("info_wand", (new ItemInfoWand()).setDisplay("Infowerkzeug")); registerItem("lightning_wand", (new ItemLightning()).setDisplay("Geladenes Zepter")); - registerItem("banhammer", (new ItemBanHammer()).setDisplay("Hammer der Verbannung").setTab(CheatTab.tabTools)); - registerItem("key", (new ItemKey()).setDisplay("Schlüssel").setTab(CheatTab.tabTools).setMaxStackSize(128)); + registerItem("banhammer", (new ItemBanHammer()).setDisplay("Hammer der Verbannung").setTab(CheatTab.TOOLS)); + registerItem("key", (new ItemKey()).setDisplay("Schlüssel").setTab(CheatTab.TOOLS).setMaxStackSize(128)); registerItem("die", (new ItemDie()).setDisplay("Würfel").setMaxStackSize(128)); registerItem("chick_magnet", (new ItemMagnet(true)).setDisplay("Kükenmagnet")); registerItem("magnet", (new ItemMagnet(false)).setDisplay("Magnet")); - registerItem("camera", (new ItemCamera()).setDisplay("Kamera").setTab(CheatTab.tabTools)); + registerItem("camera", (new ItemCamera()).setDisplay("Kamera").setTab(CheatTab.TOOLS)); for(Weather weather : Weather.values()) { - registerItem("weather_token_" + weather.getName(), new ItemWeatherToken(weather).setDisplay("Wetterkristall").setTab(CheatTab.tabTools)); + registerItem("weather_token_" + weather.getName(), new ItemWeatherToken(weather).setDisplay("Wetterkristall").setTab(CheatTab.TOOLS)); } registerItem("flint_and_steel", (new ItemFlintAndSteel(Blocks.fire)).setDisplay("Feuerzeug")); @@ -404,19 +404,19 @@ public abstract class ItemRegistry { registerItem("bow", (new ItemBow()).setDisplay("Bogen")); registerItem("boltgun", (new ItemBoltgun()).setDisplay("Bolter")); registerItem("bolt", (new ItemAmmo(5, 1.0f, 128)).setDisplay("Bolter-Munition")); - registerItem("arrow", (new Item()).setDisplay("Pfeil").setTab(CheatTab.tabCombat).setMaxStackSize(128)); + registerItem("arrow", (new Item()).setDisplay("Pfeil").setTab(CheatTab.COMBAT).setMaxStackSize(128)); Item coal = (new ItemCoal()).setDisplay("Kohle"); registerItem("coal", coal); - registerItem("stick", (new ItemStick()).setDisplay("Stock").setTab(CheatTab.tabMaterials).setMaxStackSize(256)); - registerItem("bowl", (new ItemSmall()).setDisplay("Schüssel").setTab(CheatTab.tabMisc)); + registerItem("stick", (new ItemStick()).setDisplay("Stock").setTab(CheatTab.MATERIALS).setMaxStackSize(256)); + registerItem("bowl", (new ItemSmall()).setDisplay("Schüssel").setTab(CheatTab.MISC)); registerItem("mushroom_stew", (new ItemSoup(6)).setDisplay("Pilzsuppe")); - registerItem((new ItemReed(Blocks.string)).setDisplay("Faden").setTab(CheatTab.tabTech).setMaxStackSize(1024)); - registerItem("feather", (new Item()).setDisplay("Feder").setTab(CheatTab.tabMaterials).setMaxStackSize(512)); - registerItem("gunpowder", (new Item()).setDisplay("Schwarzpulver").setPotionEffect(PotionHelper.gunpowderEffect).setTab(CheatTab.tabMaterials).setMaxStackSize(256)); + registerItem((new ItemReed(Blocks.string)).setDisplay("Faden").setTab(CheatTab.TECHNOLOGY).setMaxStackSize(1024)); + registerItem("feather", (new Item()).setDisplay("Feder").setTab(CheatTab.MATERIALS).setMaxStackSize(512)); + registerItem("gunpowder", (new Item()).setDisplay("Schwarzpulver").setPotionEffect(PotionHelper.gunpowderEffect).setTab(CheatTab.MATERIALS).setMaxStackSize(256)); registerItem((new ItemSeeds(Blocks.wheat, Blocks.farmland)).setDisplay("Weizenkörner").setMaxStackSize(256)); - registerItem("wheats", (new Item()).setDisplay("Weizen").setTab(CheatTab.tabMaterials).setMaxStackSize(128)); + registerItem("wheats", (new Item()).setDisplay("Weizen").setTab(CheatTab.MATERIALS).setMaxStackSize(128)); registerItem("bread", (new ItemFood(5, false)).setDisplay("Brot")); - registerItem("flint", (new Item()).setDisplay("Feuerstein").setTab(CheatTab.tabMaterials).setMaxStackSize(128)); + registerItem("flint", (new Item()).setDisplay("Feuerstein").setTab(CheatTab.MATERIALS).setMaxStackSize(128)); registerItem("porkchop", (new ItemFood(3, true)).setDisplay("Rohes Schweinefleisch")); registerItem("cooked_porkchop", (new ItemFood(8, true)).setDisplay("Gebratenes Schweinefleisch")); registerItem("golden_apple", (new ItemAppleGold(4, false)).setPotionEffect(Potion.REGENERATION, 5, 1, 1.0F) @@ -429,27 +429,27 @@ public abstract class ItemRegistry { // registerItem("iron_door", (new ItemDoor(Blocks.iron_door)).setUnlocalizedName("doorIron")); registerItem((new ItemRedstone()).setDisplay("Redstone").setPotionEffect(PotionHelper.redstoneEffect).setMaxStackSize(256)); registerItem("snowball", (new ItemSnowball()).setDisplay("Schneeball").setMaxStackSize(128)); - registerItem("leather", (new Item()).setDisplay("Leder").setTab(CheatTab.tabMaterials)); - registerItem("brick", (new Item()).setDisplay("Ziegel").setTab(CheatTab.tabMaterials)); - registerItem("clay_ball", (new Item()).setDisplay("Ton").setTab(CheatTab.tabMaterials).setMaxStackSize(128)); - registerItem((new ItemReed(Blocks.reeds)).setDisplay("Zuckerrohr").setTab(CheatTab.tabPlants).setMaxStackSize(128)); - registerItem("paper", (new Item()).setDisplay("Papier").setTab(CheatTab.tabMaterials).setMaxStackSize(256)); - registerItem("book", (new ItemBook()).setDisplay("Buch").setTab(CheatTab.tabMisc)); - registerItem("slime_ball", (new Item()).setDisplay("Schleimball").setTab(CheatTab.tabMaterials).setMaxStackSize(128)); + registerItem("leather", (new Item()).setDisplay("Leder").setTab(CheatTab.MATERIALS)); + registerItem("brick", (new Item()).setDisplay("Ziegel").setTab(CheatTab.MATERIALS)); + registerItem("clay_ball", (new Item()).setDisplay("Ton").setTab(CheatTab.MATERIALS).setMaxStackSize(128)); + registerItem((new ItemReed(Blocks.reeds)).setDisplay("Zuckerrohr").setTab(CheatTab.PLANTS).setMaxStackSize(128)); + registerItem("paper", (new Item()).setDisplay("Papier").setTab(CheatTab.MATERIALS).setMaxStackSize(256)); + registerItem("book", (new ItemBook()).setDisplay("Buch").setTab(CheatTab.MISC)); + registerItem("slime_ball", (new Item()).setDisplay("Schleimball").setTab(CheatTab.MATERIALS).setMaxStackSize(128)); registerItem("egg", (new ItemEgg()).setDisplay("Ei").setMaxStackSize(128)); - registerItem("navigator", (new ItemSpaceNavigator()).setDisplay("Elektronischer Navigator").setTab(CheatTab.tabTools)); - registerItem("exterminator", (new ItemExterminator()).setDisplay("Weltenzerstörer").setTab(CheatTab.tabTools)); + registerItem("navigator", (new ItemSpaceNavigator()).setDisplay("Elektronischer Navigator").setTab(CheatTab.TOOLS)); + registerItem("exterminator", (new ItemExterminator()).setDisplay("Weltenzerstörer").setTab(CheatTab.TOOLS)); registerItem("fishing_rod", (new ItemFishingRod()).setDisplay("Angel")); registerItem("glowstone_dust", (new Item()).setDisplay("Glowstonestaub").setPotionEffect(PotionHelper.glowstoneEffect) - .setTab(CheatTab.tabMaterials).setMaxStackSize(256)); + .setTab(CheatTab.MATERIALS).setMaxStackSize(256)); registerItem("fish", (new ItemFishFood(false)).setDisplay("Fisch").setHasSubtypes(true)); registerItem("cooked_fish", (new ItemFishFood(true)).setDisplay("Fisch").setHasSubtypes(true)); Item dye = (new ItemDye()).setDisplay("Farbstoff").setMaxStackSize(512); registerItem("dye", dye); - registerItem("bone", (new ItemStick()).setDisplay("Knochen").setTab(CheatTab.tabMaterials).setMaxStackSize(128)); - registerItem("sugar", (new Item()).setDisplay("Zucker").setPotionEffect(PotionHelper.sugarEffect).setTab(CheatTab.tabMaterials).setMaxStackSize(512)); - registerItem((new ItemReed(Blocks.cake)).setMaxStackSize(1).setDisplay("Kuchen").setTab(CheatTab.tabDeco)); - registerItem((new ItemReed(Blocks.repeater)).setDisplay("Redstone-Verstärker").setTab(CheatTab.tabTech)); + registerItem("bone", (new ItemStick()).setDisplay("Knochen").setTab(CheatTab.MATERIALS).setMaxStackSize(128)); + registerItem("sugar", (new Item()).setDisplay("Zucker").setPotionEffect(PotionHelper.sugarEffect).setTab(CheatTab.MATERIALS).setMaxStackSize(512)); + registerItem((new ItemReed(Blocks.cake)).setMaxStackSize(1).setDisplay("Kuchen").setTab(CheatTab.DECORATION)); + registerItem((new ItemReed(Blocks.repeater)).setDisplay("Redstone-Verstärker").setTab(CheatTab.TECHNOLOGY)); registerItem("cookie", (new ItemFood(2, false)).setDisplay("Keks").setMaxStackSize(128)); registerItem("melon", (new ItemFood(2, false)).setDisplay("Melone")); registerItem((new ItemSeeds(Blocks.pumpkin_stem, Blocks.farmland)).setDisplay("Kürbiskerne").setMaxStackSize(256)); @@ -459,51 +459,51 @@ public abstract class ItemRegistry { registerItem("chicken", (new ItemFood(2, true)).setDisplay("Rohes Hühnchen")); registerItem("cooked_chicken", (new ItemFood(6, true)).setDisplay("Gebratenes Hühnchen")); registerItem("rotten_flesh", (new ItemFood(4, true)).setDisplay("Verrottetes Fleisch")); - registerItem("orb", (new ItemFragile()).setDisplay("Kugel").setTab(CheatTab.tabTools)); - registerItem("blaze_rod", (new ItemRod()).setDisplay("Lohenrute").setTab(CheatTab.tabMaterials).setMaxStackSize(256)); - registerItem("ghast_tear", (new ItemTiny()).setDisplay("Ghastträne").setPotionEffect(PotionHelper.ghastTearEffect).setTab(CheatTab.tabMaterials).setMaxStackSize(256)); - registerItem("gold_nugget", (new ItemNugget()).setDisplay("Goldnugget").setTab(CheatTab.tabMetals).setMaxStackSize(256)); + registerItem("orb", (new ItemFragile()).setDisplay("Kugel").setTab(CheatTab.TOOLS)); + registerItem("blaze_rod", (new ItemRod()).setDisplay("Lohenrute").setTab(CheatTab.MATERIALS).setMaxStackSize(256)); + registerItem("ghast_tear", (new ItemTiny()).setDisplay("Ghastträne").setPotionEffect(PotionHelper.ghastTearEffect).setTab(CheatTab.MATERIALS).setMaxStackSize(256)); + registerItem("gold_nugget", (new ItemNugget()).setDisplay("Goldnugget").setTab(CheatTab.METALS).setMaxStackSize(256)); registerItem((new ItemSeeds(Blocks.soul_wart, Blocks.soul_sand)).setDisplay("Seelenwarze").setPotionEffect("+4").setMaxStackSize(128)); registerItem("potion", (new ItemPotion()).setDisplay("Trank")); registerItem("glass_bottle", (new ItemGlassBottle()).setDisplay("Glasflasche")); registerItem("spider_eye", (new ItemFood(2, false)).setPotionEffect(Potion.POISON, 5, 0, 1.0F).setDisplay("Spinnenauge") .setPotionEffect(PotionHelper.spiderEyeEffect).setMaxStackSize(128)); registerItem("fermented_spider_eye", (new Item()).setDisplay("Fermentiertes Spinnenauge") - .setPotionEffect(PotionHelper.fermentedSpiderEyeEffect).setTab(CheatTab.tabMisc).setMaxStackSize(128)); + .setPotionEffect(PotionHelper.fermentedSpiderEyeEffect).setTab(CheatTab.MISC).setMaxStackSize(128)); registerItem("blaze_powder", (new Item()).setDisplay("Lohenstaub").setPotionEffect(PotionHelper.blazePowderEffect) - .setTab(CheatTab.tabMaterials).setMaxStackSize(256)); - registerItem("magma_cream", (new Item()).setDisplay("Magmacreme").setPotionEffect(PotionHelper.magmaCreamEffect).setTab(CheatTab.tabMaterials).setMaxStackSize(128)); - registerItem((new ItemReed(Blocks.brewing_stand)).setDisplay("Braustand").setTab(CheatTab.tabTech)); - registerItem((new ItemReed(Blocks.cauldron)).setDisplay("Kessel").setTab(CheatTab.tabTech)); + .setTab(CheatTab.MATERIALS).setMaxStackSize(256)); + registerItem("magma_cream", (new Item()).setDisplay("Magmacreme").setPotionEffect(PotionHelper.magmaCreamEffect).setTab(CheatTab.MATERIALS).setMaxStackSize(128)); + registerItem((new ItemReed(Blocks.brewing_stand)).setDisplay("Braustand").setTab(CheatTab.TECHNOLOGY)); + registerItem((new ItemReed(Blocks.cauldron)).setDisplay("Kessel").setTab(CheatTab.TECHNOLOGY)); registerItem("charged_orb", (new ItemChargedOrb()).setDisplay("Geladene Kugel")); registerItem("speckled_melon", (new Item()).setDisplay("Glitzernde Melone").setPotionEffect(PotionHelper.speckledMelonEffect) - .setTab(CheatTab.tabMisc)); + .setTab(CheatTab.MISC)); registerItem("experience_bottle", (new ItemExpBottle()).setDisplay("Erfahrungsfläschchen")); registerItem("fire_charge", (new ItemFireball()).setDisplay("Feuerkugel")); - registerItem("writable_book", (new Item()).setDisplay("Buch und Feder").setTab(CheatTab.tabTools)); - registerItem("written_book", (new Item()).setDisplay("Beschriebenes Buch").setTab(CheatTab.tabMisc)); - Item emerald = (new Item()).setDisplay("Smaragd").setTab(CheatTab.tabMetals); + registerItem("writable_book", (new Item()).setDisplay("Buch und Feder").setTab(CheatTab.TOOLS)); + registerItem("written_book", (new Item()).setDisplay("Beschriebenes Buch").setTab(CheatTab.MISC)); + Item emerald = (new Item()).setDisplay("Smaragd").setTab(CheatTab.METALS); registerItem("emerald", emerald); - registerItem((new ItemReed(Blocks.flower_pot)).setDisplay("Blumentopf").setTab(CheatTab.tabDeco)); + registerItem((new ItemReed(Blocks.flower_pot)).setDisplay("Blumentopf").setTab(CheatTab.DECORATION)); registerItem((new ItemSeedFood(3, Blocks.carrot, Blocks.farmland)).setDisplay("Karotte").setMaxStackSize(128)); registerItem((new ItemSeedFood(1, Blocks.potato, Blocks.farmland)).setDisplay("Kartoffel").setMaxStackSize(128)); registerItem("baked_potato", (new ItemFood(5, false)).setDisplay("Ofenkartoffel").setMaxStackSize(128)); registerItem("poisonous_potato", (new ItemFood(2, false)).setPotionEffect(Potion.POISON, 5, 0, 0.6F).setDisplay("Giftige Kartoffel").setMaxStackSize(128)); registerItem("golden_carrot", (new ItemFood(6, false)).setDisplay("Goldene Karotte") - .setPotionEffect(PotionHelper.goldenCarrotEffect).setTab(CheatTab.tabMisc)); + .setPotionEffect(PotionHelper.goldenCarrotEffect).setTab(CheatTab.MISC)); registerItem((new ItemSkull()).setDisplay("Kopf")); registerItem("carrot_on_a_stick", (new ItemCarrotOnAStick()).setDisplay("Karottenrute")); - registerItem("charge_crystal", (new ItemEffect()).setDisplay("Energiekristall").setTab(CheatTab.tabMisc).setColor(TextColor.DMAGENTA)); - registerItem("pumpkin_pie", (new ItemFood(8, false)).setDisplay("Kürbiskuchen").setTab(CheatTab.tabMisc)); + registerItem("charge_crystal", (new ItemEffect()).setDisplay("Energiekristall").setTab(CheatTab.MISC).setColor(TextColor.DMAGENTA)); + registerItem("pumpkin_pie", (new ItemFood(8, false)).setDisplay("Kürbiskuchen").setTab(CheatTab.MISC)); registerItem("fireworks", (new ItemFirework()).setDisplay("Feuerwerksrakete")); - registerItem("firework_charge", (new ItemFireworkCharge()).setDisplay("Feuerwerksstern").setTab(CheatTab.tabMaterials)); - registerItem("enchanted_book", (new ItemEnchantedBook()).setMaxStackSize(1).setDisplay("Verzaubertes Buch").setTab(CheatTab.tabMagic)); - registerItem((new ItemReed(Blocks.comparator)).setDisplay("Redstone-Komparator").setTab(CheatTab.tabTech)); - registerItem("bloodbrick", (new Item()).setDisplay("Blutroter Ziegel").setTab(CheatTab.tabMaterials)); - registerItem("blackbrick", (new Item()).setDisplay("Schwarzer Ziegel").setTab(CheatTab.tabMaterials)); - Item quartz = (new Item()).setDisplay("Quarz").setTab(CheatTab.tabMetals); + registerItem("firework_charge", (new ItemFireworkCharge()).setDisplay("Feuerwerksstern").setTab(CheatTab.MATERIALS)); + registerItem("enchanted_book", (new ItemEnchantedBook()).setMaxStackSize(1).setDisplay("Verzaubertes Buch").setTab(CheatTab.MAGIC)); + registerItem((new ItemReed(Blocks.comparator)).setDisplay("Redstone-Komparator").setTab(CheatTab.TECHNOLOGY)); + registerItem("bloodbrick", (new Item()).setDisplay("Blutroter Ziegel").setTab(CheatTab.MATERIALS)); + registerItem("blackbrick", (new Item()).setDisplay("Schwarzer Ziegel").setTab(CheatTab.MATERIALS)); + Item quartz = (new Item()).setDisplay("Quarz").setTab(CheatTab.METALS); registerItem("quartz", quartz); - Item bquartz = (new Item()).setDisplay("Schwarzes Quarz").setTab(CheatTab.tabMetals); + Item bquartz = (new Item()).setDisplay("Schwarzes Quarz").setTab(CheatTab.METALS); registerItem("black_quartz", bquartz); registerItem("lead", (new ItemLead()).setDisplay("Leine").setMaxStackSize(128)); registerItem("name_tag", (new ItemNameTag()).setDisplay("Namensschild")); @@ -516,14 +516,14 @@ public abstract class ItemRegistry { registerItem("dynamite", (new ItemDynamite()).setDisplay("Dynamit").setColor(TextColor.RED)); // registerItem("cherry_door", (new ItemDoor(Blocks.cherry_door)).setUnlocalizedName("doorCherry")); // registerItem("maple_door", (new ItemDoor(Blocks.maple_door)).setUnlocalizedName("doorMaple")); - registerItem("chain", (new ItemMagnetic()).setDisplay("Kette").setTab(CheatTab.tabMaterials)); + registerItem("chain", (new ItemMagnetic()).setDisplay("Kette").setTab(CheatTab.MATERIALS)); for(OreType ore : OreType.values()) { // String loc = ore.name.substring(0, 1).toUpperCase() + ore.name.substring(1); // registerItemBlock(BlockRegistry.getRegisteredBlock(ore.name + "_ore")); // registerItemBlock(BlockRegistry.getRegisteredBlock(ore.name + "_block")); // if(ore.gem != null) { - Item itm = (new Item()).setDisplay(ore.itemDisplay).setTab(CheatTab.tabMetals); + Item itm = (new Item()).setDisplay(ore.itemDisplay).setTab(CheatTab.METALS); registerItem(ore.item, itm); ((BlockOre)BlockRegistry.getRegisteredBlock(ore.name + "_ore")).setDropItem(new ItemStack(itm, ore.dropQuantity), ore.bonusChance, ore.experience); @@ -544,12 +544,12 @@ public abstract class ItemRegistry { ItemBlock block = new ItemMetalBlock(fullBlock, metal, false); registerBlock(fullBlock, block); if(metal.isPowder) { - Item itm = (new ItemMetal(metal)).setDisplay(metal.display + "pulver").setTab(CheatTab.tabMetals); + Item itm = (new ItemMetal(metal)).setDisplay(metal.display + "pulver").setTab(CheatTab.METALS); registerItem(metal.name + "_powder", itm); ((BlockOre)BlockRegistry.getRegisteredBlock(metal.name + "_ore")).setDropItem(new ItemStack(itm), 0, 2); } else { - Item itm = (new ItemMetal(metal)).setDisplay(metal.display + "barren").setTab(CheatTab.tabMetals); + Item itm = (new ItemMetal(metal)).setDisplay(metal.display + "barren").setTab(CheatTab.METALS); registerItem(metal.name + "_ingot", itm); ((BlockOre)BlockRegistry.getRegisteredBlock(metal.name + "_ore")).setSmeltItem(new ItemStack(itm)); } diff --git a/common/src/common/inventory/InventoryPlayer.java b/common/src/common/inventory/InventoryPlayer.java index 7b651c8..6dd9243 100755 --- a/common/src/common/inventory/InventoryPlayer.java +++ b/common/src/common/inventory/InventoryPlayer.java @@ -564,17 +564,11 @@ public class InventoryPlayer implements IInventory return ItemStack.MAX_SIZE; } - public boolean canHeldItemHarvest(Block blockIn) - { - if (blockIn.getMaterial().isToolNotRequired()) - { + public boolean canHeldItemHarvest(Block block) { + if(!block.getMaterial().isToolRequired()) return true; - } - else - { - ItemStack itemstack = this.getStackInSlot(this.currentItem); - return itemstack != null ? itemstack.canHarvestBlock(blockIn) : false; - } + ItemStack stack = this.getStackInSlot(this.currentItem); + return stack != null && stack.canHarvestBlock(block); } /** diff --git a/common/src/common/item/CheatTab.java b/common/src/common/item/CheatTab.java index 83729d0..b92c840 100755 --- a/common/src/common/item/CheatTab.java +++ b/common/src/common/item/CheatTab.java @@ -6,166 +6,116 @@ import common.init.Blocks; import common.init.ItemRegistry; import common.init.Items; -public enum CheatTab -{ - tabBlocks("Baumaterial") - { - protected Item getTabIconItem() - { - return ItemRegistry.getItemFromBlock(Blocks.glass); - } - }, - tabNature("Gestein und Natur") - { - protected Item getTabIconItem() - { - return ItemRegistry.getItemFromBlock(Blocks.grass); - } - }, - tabWood("Holz") - { - protected Item getTabIconItem() - { - return ItemRegistry.getItemFromBlock(Blocks.maple_planks); - } - }, - tabPlants("Pflanzen") - { - protected Item getTabIconItem() - { - return ItemRegistry.getItemFromBlock(Blocks.oak_leaves); - } - }, - tabDeco("Dekoration") - { - protected Item getTabIconItem() - { - return ItemRegistry.getItemFromBlock(Blocks.hay_block); - } - }, - tabTech("Redstone & Technik") - { - protected Item getTabIconItem() - { - return ItemRegistry.getItemFromBlock(Blocks.tnt); - } - }, - tabGems("Erze & Teure Blöcke") - { - protected Item getTabIconItem() - { - return ItemRegistry.getItemFromBlock(Blocks.diamond_block); - } - }, - tabSpawners("Mob & Itemspawner") - { - protected Item getTabIconItem() - { - return Items.minecart; - } - }, - tabTools("Werkzeug") - { - protected Item getTabIconItem() - { - return Items.flint_and_steel; - } - }, - tabLiquids("Flüssigkeiten") - { - protected Item getTabIconItem() - { - return Items.water_bucket; - } - }, - tabCombat("Kampf") - { - protected Item getTabIconItem() - { - return Items.bow; - } - }, - tabMagic("Tränke & Verzauberungen") - { - protected Item getTabIconItem() - { - return Items.potion; - } - protected int getIconItemDamage() - { - return 8261; - } - }, - tabMaterials("Werkstoffe") - { - protected Item getTabIconItem() - { - return Items.leather; - } - }, - tabMetals("Metalle und Juwelen") - { - protected Item getTabIconItem() - { - return Items.iron_ingot; - } - }, - tabMisc("Verschiedenes & Nahrung") - { - protected Item getTabIconItem() - { - return Items.charge_crystal; - } - }; - - private final String name; - private ItemStack iconItemStack; +public enum CheatTab { + BLOCKS("Baumaterial") { + protected Item getIconItem() { + return ItemRegistry.getItemFromBlock(Blocks.glass); + } + }, + NATURE("Gestein und Natur") { + protected Item getIconItem() { + return ItemRegistry.getItemFromBlock(Blocks.grass); + } + }, + WOOD("Holz") { + protected Item getIconItem() { + return ItemRegistry.getItemFromBlock(Blocks.maple_planks); + } + }, + PLANTS("Pflanzen") { + protected Item getIconItem() { + return ItemRegistry.getItemFromBlock(Blocks.oak_leaves); + } + }, + DECORATION("Dekoration") { + protected Item getIconItem() { + return ItemRegistry.getItemFromBlock(Blocks.hay_block); + } + }, + TECHNOLOGY("Redstone & Technik") { + protected Item getIconItem() { + return ItemRegistry.getItemFromBlock(Blocks.tnt); + } + }, + GEMS("Erze & Teure Blöcke") { + protected Item getIconItem() { + return ItemRegistry.getItemFromBlock(Blocks.diamond_block); + } + }, + SPAWNERS("Mob & Itemspawner") { + protected Item getIconItem() { + return Items.minecart; + } + }, + TOOLS("Werkzeug") { + protected Item getIconItem() { + return Items.flint_and_steel; + } + }, + LIQUIDS("Flüssigkeiten") { + protected Item getIconItem() { + return Items.water_bucket; + } + }, + COMBAT("Kampf") { + protected Item getIconItem() { + return Items.bow; + } + }, + MAGIC("Tränke & Verzauberungen") { + protected Item getIconItem() { + return Items.potion; + } + }, + MATERIALS("Werkstoffe") { + protected Item getIconItem() { + return Items.leather; + } + }, + METALS("Metalle und Juwelen") { + protected Item getIconItem() { + return Items.iron_ingot; + } + }, + MISC("Verschiedenes & Nahrung") { + protected Item getIconItem() { + return Items.charge_crystal; + } + }; - private CheatTab(String name) - { - this.name = name; - } + private final String name; - public int getHorizontal() - { - return this.ordinal() % 12; - } + private ItemStack icon; - public int getVertical() - { - return this.ordinal() / 12; - } - - public String getName() - { - return this.name; - } + private CheatTab(String name) { + this.name = name; + } - public ItemStack getIconItemStack() - { - if (this.iconItemStack == null) - { - this.iconItemStack = new ItemStack(this.getTabIconItem(), 1, this.getIconItemDamage()); - } + public int getHorizontal() { + return this.ordinal() % 12; + } - return this.iconItemStack; - } + public int getVertical() { + return this.ordinal() / 12; + } - protected abstract Item getTabIconItem(); + public String getName() { + return this.name; + } - protected int getIconItemDamage() - { - return 0; - } - - public void displayAllReleventItems(List list) - { - for (Item item : ItemRegistry.REGISTRY) - { - if (item != null && item.getTab() == this) - { - item.getSubItems(item, this, list); - } - } - } + public ItemStack getIcon() { + if(this.icon == null) + this.icon = new ItemStack(this.getIconItem()); + return this.icon; + } + + protected abstract Item getIconItem(); + + public void filter(List list) { + for(Item item : ItemRegistry.REGISTRY) { + if(item != null && item.getTab() == this) { + item.getSubItems(item, this, list); + } + } + } } diff --git a/common/src/common/item/ItemAmmo.java b/common/src/common/item/ItemAmmo.java index 9f1b64b..e76602a 100755 --- a/common/src/common/item/ItemAmmo.java +++ b/common/src/common/item/ItemAmmo.java @@ -6,7 +6,7 @@ public class ItemAmmo extends ItemMagnetic { public ItemAmmo(int damage, float explosion, int stack) { this.maxStackSize = stack; - this.setTab(CheatTab.tabCombat); + this.setTab(CheatTab.COMBAT); this.damage = damage; this.explosion = explosion; } diff --git a/common/src/common/item/ItemArmor.java b/common/src/common/item/ItemArmor.java index 9c2f2ab..20723b5 100755 --- a/common/src/common/item/ItemArmor.java +++ b/common/src/common/item/ItemArmor.java @@ -95,7 +95,7 @@ public class ItemArmor extends Item this.damageReduceAmount = material.getDamageReduction(armorType); this.setMaxDamage(material.getDurability(armorType)); this.maxStackSize = 1; - this.setTab(CheatTab.tabCombat); + this.setTab(CheatTab.COMBAT); DispenserRegistry.REGISTRY.putObject(this, dispenserBehavior); } diff --git a/common/src/common/item/ItemAxe.java b/common/src/common/item/ItemAxe.java index 2a2ccc6..d2230ed 100755 --- a/common/src/common/item/ItemAxe.java +++ b/common/src/common/item/ItemAxe.java @@ -3,20 +3,12 @@ package common.item; import common.block.Block; import common.init.ToolMaterial; -public class ItemAxe extends ItemTool -{ -// private static final Set EFFECTIVE_ON = Sets.newHashSet(new Block[] { -// Blocks.planks, Blocks.bookshelf, Blocks.log, Blocks.log2, Blocks.chest, Blocks.pumpkin, Blocks.lit_pumpkin, Blocks.melon_block, Blocks.ladder -// }); +public class ItemAxe extends ItemTool { + public ItemAxe(ToolMaterial material) { + super(3, material); + } - public ItemAxe(ToolMaterial material) - { - super(3, material); - } - - public boolean canUseOn(ItemStack stack, Block state) - { - return state.canAxeHarvest() /* state.getMaterial() != Material.wood && state.getMaterial() != Material.plants && state.getMaterial() != Material.vine ? - super.getStrVsBlock(stack, state) */; - } + public boolean canUseOn(ItemStack stack, Block block) { + return block.canAxeHarvest(); + } } diff --git a/common/src/common/item/ItemBanner.java b/common/src/common/item/ItemBanner.java index 32989a3..fd76926 100755 --- a/common/src/common/item/ItemBanner.java +++ b/common/src/common/item/ItemBanner.java @@ -24,7 +24,7 @@ public class ItemBanner extends ItemBlock public ItemBanner() { super(Blocks.banner); - this.setTab(CheatTab.tabDeco); + this.setTab(CheatTab.DECORATION); this.setHasSubtypes(true); this.setMaxDamage(0); } @@ -152,7 +152,7 @@ public class ItemBanner extends ItemBlock */ public CheatTab getTab() { - return CheatTab.tabDeco; + return CheatTab.DECORATION; } private DyeColor getBaseColor(ItemStack stack) diff --git a/common/src/common/item/ItemBed.java b/common/src/common/item/ItemBed.java index 403a0b0..5baaa20 100755 --- a/common/src/common/item/ItemBed.java +++ b/common/src/common/item/ItemBed.java @@ -16,7 +16,7 @@ public class ItemBed extends Item public ItemBed(BlockBed bedBlock) { this.bedBlock = bedBlock; - this.setTab(CheatTab.tabDeco); + this.setTab(CheatTab.DECORATION); } public Block getBlock() diff --git a/common/src/common/item/ItemBoat.java b/common/src/common/item/ItemBoat.java index 1aa2ae3..d6810ba 100755 --- a/common/src/common/item/ItemBoat.java +++ b/common/src/common/item/ItemBoat.java @@ -18,7 +18,7 @@ public class ItemBoat extends Item public ItemBoat() { this.maxStackSize = 1; - this.setTab(CheatTab.tabSpawners); + this.setTab(CheatTab.SPAWNERS); } /** diff --git a/common/src/common/item/ItemBow.java b/common/src/common/item/ItemBow.java index ddd477d..54b300d 100755 --- a/common/src/common/item/ItemBow.java +++ b/common/src/common/item/ItemBow.java @@ -19,7 +19,7 @@ public class ItemBow extends Item { this.maxStackSize = 1; this.setMaxDamage(384); - this.setTab(CheatTab.tabCombat); + this.setTab(CheatTab.COMBAT); } /** diff --git a/common/src/common/item/ItemBucket.java b/common/src/common/item/ItemBucket.java index d5e3ee9..a3aa306 100755 --- a/common/src/common/item/ItemBucket.java +++ b/common/src/common/item/ItemBucket.java @@ -8,6 +8,7 @@ import java.util.Queue; import java.util.Set; import common.block.Block; +import common.block.Material; import common.block.liquid.BlockDynamicLiquid; import common.block.liquid.BlockLiquid; import common.block.liquid.BlockStaticLiquid; @@ -19,7 +20,6 @@ import common.init.FluidRegistry; import common.init.ItemRegistry; import common.init.Items; import common.init.SoundEvent; -import common.material.Material; import common.model.Model; import common.model.ModelProvider; import common.model.ParticleType; @@ -104,7 +104,7 @@ public class ItemBucket extends Item this.maxStackSize = liquid == null ? 16 : 1; this.liquid = liquid; this.recursive = recursive; - this.setTab(liquid == null ? CheatTab.tabTools : CheatTab.tabLiquids); + this.setTab(liquid == null ? CheatTab.TOOLS : CheatTab.LIQUIDS); // if(!empty) // this.setHasSubtypes(true); } @@ -251,7 +251,7 @@ public class ItemBucket extends Item } else { - if (worldIn.doesWaterVaporize(pos) && this.liquid.getMaterial() == Material.water) + if (worldIn.doesWaterVaporize(pos) && this.liquid.getMaterial() == Material.WATER) { int i = pos.getX(); int j = pos.getY(); diff --git a/common/src/common/item/ItemBucketMilk.java b/common/src/common/item/ItemBucketMilk.java index 7eaecfa..0da249b 100755 --- a/common/src/common/item/ItemBucketMilk.java +++ b/common/src/common/item/ItemBucketMilk.java @@ -16,7 +16,7 @@ public class ItemBucketMilk extends Item public ItemBucketMilk() { this.setMaxStackSize(1); - this.setTab(CheatTab.tabTools); + this.setTab(CheatTab.TOOLS); } /** diff --git a/common/src/common/item/ItemCarrotOnAStick.java b/common/src/common/item/ItemCarrotOnAStick.java index 1a7983e..18290c5 100755 --- a/common/src/common/item/ItemCarrotOnAStick.java +++ b/common/src/common/item/ItemCarrotOnAStick.java @@ -10,7 +10,7 @@ public class ItemCarrotOnAStick extends Item { public ItemCarrotOnAStick() { - this.setTab(CheatTab.tabTools); + this.setTab(CheatTab.TOOLS); this.setMaxStackSize(1); this.setMaxDamage(25); } diff --git a/common/src/common/item/ItemChargedOrb.java b/common/src/common/item/ItemChargedOrb.java index 0016734..ba3a48e 100755 --- a/common/src/common/item/ItemChargedOrb.java +++ b/common/src/common/item/ItemChargedOrb.java @@ -18,7 +18,7 @@ public class ItemChargedOrb extends ItemFragile public ItemChargedOrb() { this.maxStackSize = 1; - this.setTab(CheatTab.tabTools); + this.setTab(CheatTab.TOOLS); this.setMaxDamage(16); this.setColor(TextColor.DMAGENTA); } diff --git a/common/src/common/item/ItemCoal.java b/common/src/common/item/ItemCoal.java index bef0689..aa192ae 100755 --- a/common/src/common/item/ItemCoal.java +++ b/common/src/common/item/ItemCoal.java @@ -11,7 +11,7 @@ public class ItemCoal extends Item { this.setHasSubtypes(true); this.setMaxDamage(0); - this.setTab(CheatTab.tabMetals); + this.setTab(CheatTab.METALS); } /** diff --git a/common/src/common/item/ItemDie.java b/common/src/common/item/ItemDie.java index 5565fb4..4976c5b 100755 --- a/common/src/common/item/ItemDie.java +++ b/common/src/common/item/ItemDie.java @@ -20,7 +20,7 @@ public class ItemDie extends Item public ItemDie() { - this.setTab(CheatTab.tabTools); + this.setTab(CheatTab.TOOLS); this.setMaxDamage(0); this.setHasSubtypes(true); } diff --git a/common/src/common/item/ItemDoor.java b/common/src/common/item/ItemDoor.java index 244bc09..996c573 100755 --- a/common/src/common/item/ItemDoor.java +++ b/common/src/common/item/ItemDoor.java @@ -1,10 +1,10 @@ package common.item; import common.block.Block; +import common.block.Material; import common.block.artificial.BlockDoor; import common.entity.npc.EntityNPC; import common.init.Blocks; -import common.material.Material; import common.util.BlockPos; import common.util.Facing; import common.world.State; @@ -17,7 +17,7 @@ public class ItemDoor extends Item public ItemDoor(Block block) { this.block = block; - this.setTab(block.getMaterial() == Material.wood ? CheatTab.tabWood : CheatTab.tabTech); + this.setTab(block.getMaterial() == Material.WOOD ? CheatTab.WOOD : CheatTab.TECHNOLOGY); } public Block getBlock() diff --git a/common/src/common/item/ItemDye.java b/common/src/common/item/ItemDye.java index 5013ce7..eb745f7 100755 --- a/common/src/common/item/ItemDye.java +++ b/common/src/common/item/ItemDye.java @@ -30,7 +30,7 @@ public class ItemDye extends Item { this.setHasSubtypes(true); this.setMaxDamage(0); - this.setTab(CheatTab.tabMaterials); + this.setTab(CheatTab.MATERIALS); } /** diff --git a/common/src/common/item/ItemDynamite.java b/common/src/common/item/ItemDynamite.java index 56a3d46..073d23a 100755 --- a/common/src/common/item/ItemDynamite.java +++ b/common/src/common/item/ItemDynamite.java @@ -16,7 +16,7 @@ public class ItemDynamite extends Item public ItemDynamite() { this.maxStackSize = 32; - this.setTab(CheatTab.tabTools); + this.setTab(CheatTab.TOOLS); this.setMaxDamage(0); this.setHasSubtypes(true); } diff --git a/common/src/common/item/ItemEditWand.java b/common/src/common/item/ItemEditWand.java index ca542f9..6d1baa9 100755 --- a/common/src/common/item/ItemEditWand.java +++ b/common/src/common/item/ItemEditWand.java @@ -8,7 +8,7 @@ import common.world.World; public class ItemEditWand extends Item { public ItemEditWand() { this.maxStackSize = 1; - this.setTab(CheatTab.tabTools); + this.setTab(CheatTab.TOOLS); } // public boolean canBreakBlocks() { diff --git a/common/src/common/item/ItemEgg.java b/common/src/common/item/ItemEgg.java index ec3c8ff..2d9d77c 100755 --- a/common/src/common/item/ItemEgg.java +++ b/common/src/common/item/ItemEgg.java @@ -9,7 +9,7 @@ public class ItemEgg extends Item { public ItemEgg() { - this.setTab(CheatTab.tabTools); + this.setTab(CheatTab.TOOLS); } /** diff --git a/common/src/common/item/ItemExpBottle.java b/common/src/common/item/ItemExpBottle.java index ce0b567..8c0ee7f 100755 --- a/common/src/common/item/ItemExpBottle.java +++ b/common/src/common/item/ItemExpBottle.java @@ -9,7 +9,7 @@ public class ItemExpBottle extends Item { public ItemExpBottle() { - this.setTab(CheatTab.tabTools); + this.setTab(CheatTab.TOOLS); } public boolean hasEffect(ItemStack stack) diff --git a/common/src/common/item/ItemFireball.java b/common/src/common/item/ItemFireball.java index 51cbe0a..86d6e01 100755 --- a/common/src/common/item/ItemFireball.java +++ b/common/src/common/item/ItemFireball.java @@ -11,7 +11,7 @@ public class ItemFireball extends Item { public ItemFireball() { - this.setTab(CheatTab.tabTools); + this.setTab(CheatTab.TOOLS); } /** diff --git a/common/src/common/item/ItemFishingRod.java b/common/src/common/item/ItemFishingRod.java index 91f0c75..f7278f8 100755 --- a/common/src/common/item/ItemFishingRod.java +++ b/common/src/common/item/ItemFishingRod.java @@ -16,7 +16,7 @@ public class ItemFishingRod extends Item { this.setMaxDamage(64); this.setMaxStackSize(1); - this.setTab(CheatTab.tabTools); + this.setTab(CheatTab.TOOLS); } // /** diff --git a/common/src/common/item/ItemFlintAndSteel.java b/common/src/common/item/ItemFlintAndSteel.java index e0096ae..55ff3be 100755 --- a/common/src/common/item/ItemFlintAndSteel.java +++ b/common/src/common/item/ItemFlintAndSteel.java @@ -17,7 +17,7 @@ public class ItemFlintAndSteel extends Item this.fireBlock = fireBlock; this.maxStackSize = 1; this.setMaxDamage(64); - this.setTab(CheatTab.tabTools); + this.setTab(CheatTab.TOOLS); } /** diff --git a/common/src/common/item/ItemFood.java b/common/src/common/item/ItemFood.java index cf71fa5..c7ee6bc 100755 --- a/common/src/common/item/ItemFood.java +++ b/common/src/common/item/ItemFood.java @@ -21,7 +21,7 @@ public class ItemFood extends Item this.itemUseDuration = 32; this.healAmount = amount; this.isWolfsFavoriteMeat = isWolfFood; - this.setTab(CheatTab.tabMisc); + this.setTab(CheatTab.MISC); } /** diff --git a/common/src/common/item/ItemGlassBottle.java b/common/src/common/item/ItemGlassBottle.java index aabb0ed..7f73248 100755 --- a/common/src/common/item/ItemGlassBottle.java +++ b/common/src/common/item/ItemGlassBottle.java @@ -1,8 +1,8 @@ package common.item; +import common.block.Material; import common.entity.npc.EntityNPC; import common.init.Items; -import common.material.Material; import common.model.Model; import common.model.ModelProvider; import common.util.BlockPos; @@ -13,7 +13,7 @@ public class ItemGlassBottle extends Item { public ItemGlassBottle() { - this.setTab(CheatTab.tabTools); + this.setTab(CheatTab.TOOLS); } /** @@ -43,7 +43,7 @@ public class ItemGlassBottle extends Item return itemStackIn; } - if (worldIn.getState(blockpos).getBlock().getMaterial() == Material.water) + if (worldIn.getState(blockpos).getBlock().getMaterial() == Material.WATER) { --itemStackIn.stackSize; // playerIn.triggerAchievement(StatRegistry.objectUseStats[ItemRegistry.getIdFromItem(this)]); diff --git a/common/src/common/item/ItemGunBase.java b/common/src/common/item/ItemGunBase.java index 26fbc81..d80d82c 100755 --- a/common/src/common/item/ItemGunBase.java +++ b/common/src/common/item/ItemGunBase.java @@ -17,7 +17,7 @@ public abstract class ItemGunBase extends Item { this.maxStackSize = 1; this.setMaxDamage(durability); - this.setTab(CheatTab.tabCombat); + this.setTab(CheatTab.COMBAT); } public ItemAction getItemPosition(ItemStack stack) diff --git a/common/src/common/item/ItemHoe.java b/common/src/common/item/ItemHoe.java index 7512f93..9e7b7b7 100755 --- a/common/src/common/item/ItemHoe.java +++ b/common/src/common/item/ItemHoe.java @@ -20,7 +20,7 @@ public class ItemHoe extends Item this.theToolMaterial = material; this.maxStackSize = 1; this.setMaxDamage(material.getDurability()); - this.setTab(CheatTab.tabTools); + this.setTab(CheatTab.TOOLS); } diff --git a/common/src/common/item/ItemHorseArmor.java b/common/src/common/item/ItemHorseArmor.java index a976e1a..3b60d1f 100755 --- a/common/src/common/item/ItemHorseArmor.java +++ b/common/src/common/item/ItemHorseArmor.java @@ -10,7 +10,7 @@ public class ItemHorseArmor extends Item { this.material = material; this.texture = texture; this.setMaxStackSize(1); - this.setTab(CheatTab.tabCombat); + this.setTab(CheatTab.COMBAT); } public boolean isMagnetic() { diff --git a/common/src/common/item/ItemLead.java b/common/src/common/item/ItemLead.java index 6ea2819..fc914a4 100755 --- a/common/src/common/item/ItemLead.java +++ b/common/src/common/item/ItemLead.java @@ -14,7 +14,7 @@ public class ItemLead extends Item { public ItemLead() { - this.setTab(CheatTab.tabTools); + this.setTab(CheatTab.TOOLS); } /** diff --git a/common/src/common/item/ItemMagnet.java b/common/src/common/item/ItemMagnet.java index c7dfa31..f2b8527 100755 --- a/common/src/common/item/ItemMagnet.java +++ b/common/src/common/item/ItemMagnet.java @@ -15,7 +15,7 @@ public class ItemMagnet extends Item { private final boolean chicken; public ItemMagnet(boolean chicken) { - this.setTab(CheatTab.tabTools); + this.setTab(CheatTab.TOOLS); this.setMaxStackSize(1); this.chicken = chicken; } diff --git a/common/src/common/item/ItemMinecart.java b/common/src/common/item/ItemMinecart.java index 25b0513..4146eb5 100755 --- a/common/src/common/item/ItemMinecart.java +++ b/common/src/common/item/ItemMinecart.java @@ -84,7 +84,7 @@ public class ItemMinecart extends Item { this.maxStackSize = 1; this.minecartType = type; - this.setTab(CheatTab.tabSpawners); + this.setTab(CheatTab.SPAWNERS); // if(type != EntityMinecart.EnumMinecartType.COMMAND_BLOCK) DispenserRegistry.REGISTRY.putObject(this, dispenserMinecartBehavior); } diff --git a/common/src/common/item/ItemMonsterPlacer.java b/common/src/common/item/ItemMonsterPlacer.java index 995adc8..e98d610 100755 --- a/common/src/common/item/ItemMonsterPlacer.java +++ b/common/src/common/item/ItemMonsterPlacer.java @@ -31,7 +31,7 @@ public class ItemMonsterPlacer extends Item public ItemMonsterPlacer(String entityId) { // this.setHasSubtypes(true); - this.setTab(CheatTab.tabSpawners); + this.setTab(CheatTab.SPAWNERS); this.entityId = entityId; } diff --git a/common/src/common/item/ItemNameTag.java b/common/src/common/item/ItemNameTag.java index 8b6d2dd..fd24634 100755 --- a/common/src/common/item/ItemNameTag.java +++ b/common/src/common/item/ItemNameTag.java @@ -7,7 +7,7 @@ public class ItemNameTag extends Item { public ItemNameTag() { - this.setTab(CheatTab.tabTools); + this.setTab(CheatTab.TOOLS); } /** diff --git a/common/src/common/item/ItemNpcSpawner.java b/common/src/common/item/ItemNpcSpawner.java index 934dbca..c0f707e 100755 --- a/common/src/common/item/ItemNpcSpawner.java +++ b/common/src/common/item/ItemNpcSpawner.java @@ -30,7 +30,7 @@ public class ItemNpcSpawner extends Item public ItemNpcSpawner(CharacterInfo spawned) { // this.setHasSubtypes(true); - this.setTab(CheatTab.tabSpawners); + this.setTab(CheatTab.SPAWNERS); this.spawned = spawned; } diff --git a/common/src/common/item/ItemPickaxe.java b/common/src/common/item/ItemPickaxe.java index 1abbc61..1a2c7ba 100755 --- a/common/src/common/item/ItemPickaxe.java +++ b/common/src/common/item/ItemPickaxe.java @@ -3,44 +3,16 @@ package common.item; import common.block.Block; import common.init.ToolMaterial; -public class ItemPickaxe extends ItemTool -{ -// private static final Set EFFECTIVE_ON = Sets.newHashSet(new Block[] { -// Blocks.activator_rail, Blocks.coal_ore, Blocks.cobblestone, Blocks.detector_rail, Blocks.diamond_block, Blocks.diamond_ore, Blocks.double_stone_slab, -// Blocks.golden_rail, Blocks.gold_block, Blocks.gold_ore, Blocks.ice, Blocks.iron_block, Blocks.iron_ore, Blocks.lapis_block, Blocks.lapis_ore, -// Blocks.lit_redstone_ore, Blocks.mossy_cobblestone, Blocks.netherrack, Blocks.packed_ice, Blocks.rail, Blocks.redstone_ore, Blocks.sandstone, -// Blocks.red_sandstone, Blocks.stone, Blocks.stone_slab -// }); +public class ItemPickaxe extends ItemTool { + public ItemPickaxe(ToolMaterial material) { + super(2, material); + } - public ItemPickaxe(ToolMaterial material) - { - super(2, material); - } - - public boolean canHarvestBlock(Block blockIn) - { - return blockIn.getMiningLevel() >= 0 && this.toolMaterial.getHarvestLevel() >= blockIn.getMiningLevel(); -// blockIn == Blocks.obsidian ? this.toolMaterial.getHarvestLevel() == 3 : -// (blockIn != Blocks.diamond_block && blockIn != Blocks.diamond_ore ? -// (blockIn != Blocks.emerald_ore && blockIn != Blocks.emerald_block ? -// (blockIn != Blocks.gold_block && blockIn != Blocks.gold_ore ? -// (blockIn != Blocks.iron_block && blockIn != Blocks.iron_ore ? -// (blockIn != Blocks.lapis_block && blockIn != Blocks.lapis_ore ? -// (blockIn != Blocks.redstone_ore && blockIn != Blocks.lit_redstone_ore ? -// (blockIn.getMaterial() == Material.rock ? true : -// (blockIn.getMaterial() == Material.iron ? true : -// blockIn.getMaterial() == Material.anvil)) : -// this.toolMaterial.getHarvestLevel() >= 2) : -// this.toolMaterial.getHarvestLevel() >= 1) : -// this.toolMaterial.getHarvestLevel() >= 1) : -// this.toolMaterial.getHarvestLevel() >= 2) : -// this.toolMaterial.getHarvestLevel() >= 2) : -// this.toolMaterial.getHarvestLevel() >= 2); - } + public boolean canHarvestBlock(Block block) { + return block.getMiningLevel() >= 0 && this.getToolMaterial().getHarvestLevel() >= block.getMiningLevel(); + } - public boolean canUseOn(ItemStack stack, Block state) - { - return state.getMiningLevel() >= 0 /* state.getMaterial() != Material.iron && state.getMaterial() != Material.anvil && state.getMaterial() != Material.rock - ? super.getStrVsBlock(stack, state) */; - } + public boolean canUseOn(ItemStack stack, Block block) { + return block.getMiningLevel() >= 0; + } } diff --git a/common/src/common/item/ItemPotion.java b/common/src/common/item/ItemPotion.java index a254127..c7dcbe1 100755 --- a/common/src/common/item/ItemPotion.java +++ b/common/src/common/item/ItemPotion.java @@ -34,7 +34,7 @@ public class ItemPotion extends Item this.setMaxStackSize(1); this.setHasSubtypes(true); this.setMaxDamage(0); - this.setTab(CheatTab.tabMagic); + this.setTab(CheatTab.MAGIC); this.setColor(TextColor.ORK); } diff --git a/common/src/common/item/ItemRecord.java b/common/src/common/item/ItemRecord.java index ae209bc..d43a90e 100755 --- a/common/src/common/item/ItemRecord.java +++ b/common/src/common/item/ItemRecord.java @@ -5,7 +5,7 @@ import common.model.ModelProvider; public class ItemRecord extends Item { public ItemRecord() { - this.setTab(CheatTab.tabMisc); + this.setTab(CheatTab.MISC); } public Model getModel(ModelProvider provider, String name, int meta) { diff --git a/common/src/common/item/ItemRedstone.java b/common/src/common/item/ItemRedstone.java index fa090d4..0abb535 100755 --- a/common/src/common/item/ItemRedstone.java +++ b/common/src/common/item/ItemRedstone.java @@ -12,7 +12,7 @@ public class ItemRedstone extends Item { public ItemRedstone() { - this.setTab(CheatTab.tabTech); + this.setTab(CheatTab.TECHNOLOGY); } public Block getBlock() diff --git a/common/src/common/item/ItemSaddle.java b/common/src/common/item/ItemSaddle.java index f872541..2ed413f 100755 --- a/common/src/common/item/ItemSaddle.java +++ b/common/src/common/item/ItemSaddle.java @@ -9,7 +9,7 @@ public class ItemSaddle extends Item public ItemSaddle() { this.maxStackSize = 1; - this.setTab(CheatTab.tabTools); + this.setTab(CheatTab.TOOLS); } /** diff --git a/common/src/common/item/ItemSeedFood.java b/common/src/common/item/ItemSeedFood.java index 7347a5c..09e565e 100755 --- a/common/src/common/item/ItemSeedFood.java +++ b/common/src/common/item/ItemSeedFood.java @@ -18,7 +18,7 @@ public class ItemSeedFood extends ItemFood super(healAmount, false); this.crops = crops; this.soilId = soil; - this.setTab(CheatTab.tabPlants); + this.setTab(CheatTab.PLANTS); } public Block getBlock() diff --git a/common/src/common/item/ItemSeeds.java b/common/src/common/item/ItemSeeds.java index 2bf6656..dc70608 100755 --- a/common/src/common/item/ItemSeeds.java +++ b/common/src/common/item/ItemSeeds.java @@ -18,7 +18,7 @@ public class ItemSeeds extends Item { this.crops = crops; this.soilBlockID = soil; - this.setTab(CheatTab.tabPlants); + this.setTab(CheatTab.PLANTS); } public Block getBlock() diff --git a/common/src/common/item/ItemShears.java b/common/src/common/item/ItemShears.java index 81c0b0a..b3e3556 100755 --- a/common/src/common/item/ItemShears.java +++ b/common/src/common/item/ItemShears.java @@ -1,10 +1,10 @@ package common.item; import common.block.Block; +import common.block.Material; import common.entity.types.EntityLiving; import common.init.Blocks; import common.init.ToolMaterial; -import common.material.Material; import common.util.BlockPos; import common.world.World; @@ -16,7 +16,7 @@ public class ItemShears extends Item { this.setMaxStackSize(1); this.setMaxDamage(material.getDurability() - 12); - this.setTab(CheatTab.tabTools); + this.setTab(CheatTab.TOOLS); this.material = material; } @@ -35,7 +35,7 @@ public class ItemShears extends Item public boolean canHarvestBlock(Block blockIn) { - return blockIn.getMaterial() == Material.web || blockIn == Blocks.redstone || blockIn == Blocks.string; + return blockIn.getMaterial() == Material.FLUFF || blockIn == Blocks.redstone || blockIn == Blocks.string; } public float getStrVsBlock(ItemStack stack, Block state) diff --git a/common/src/common/item/ItemShovel.java b/common/src/common/item/ItemShovel.java new file mode 100755 index 0000000..5419e23 --- /dev/null +++ b/common/src/common/item/ItemShovel.java @@ -0,0 +1,19 @@ +package common.item; + +import common.block.Block; +import common.block.Material; +import common.init.ToolMaterial; + +public class ItemShovel extends ItemTool { + public ItemShovel(ToolMaterial material) { + super(1, material); + } + + public boolean canUseOn(ItemStack stack, Block block) { + return block.canShovelHarvest(); + } + + public boolean canHarvestBlock(Block block) { + return block.getMaterial() == Material.POWDER || block.getMaterial() == Material.DIGGABLE; + } +} diff --git a/common/src/common/item/ItemSign.java b/common/src/common/item/ItemSign.java index 1708631..b8e8cdc 100755 --- a/common/src/common/item/ItemSign.java +++ b/common/src/common/item/ItemSign.java @@ -16,7 +16,7 @@ public class ItemSign extends Item { public ItemSign() { - this.setTab(CheatTab.tabDeco); + this.setTab(CheatTab.DECORATION); } public Block getBlock() diff --git a/common/src/common/item/ItemSkull.java b/common/src/common/item/ItemSkull.java index 20ee545..ac039ad 100755 --- a/common/src/common/item/ItemSkull.java +++ b/common/src/common/item/ItemSkull.java @@ -19,7 +19,7 @@ public class ItemSkull extends Item { public ItemSkull() { - this.setTab(CheatTab.tabDeco); + this.setTab(CheatTab.DECORATION); // this.setMaxDamage(0); // this.setHasSubtypes(true); } diff --git a/common/src/common/item/ItemSnowball.java b/common/src/common/item/ItemSnowball.java index efdf480..f048210 100755 --- a/common/src/common/item/ItemSnowball.java +++ b/common/src/common/item/ItemSnowball.java @@ -9,7 +9,7 @@ public class ItemSnowball extends Item { public ItemSnowball() { - this.setTab(CheatTab.tabTools); + this.setTab(CheatTab.TOOLS); } /** diff --git a/common/src/common/item/ItemSpade.java b/common/src/common/item/ItemSpade.java deleted file mode 100755 index f2633c7..0000000 --- a/common/src/common/item/ItemSpade.java +++ /dev/null @@ -1,28 +0,0 @@ -package common.item; - -import common.block.Block; -import common.init.ToolMaterial; -import common.material.Material; - -public class ItemSpade extends ItemTool -{ -// private static final Set EFFECTIVE_ON = Sets.newHashSet(new Block[] { -// Blocks.clay, Blocks.dirt, Blocks.farmland, Blocks.grass, Blocks.gravel, Blocks.mycelium, Blocks.sand, Blocks.snow, Blocks.snow_layer, Blocks.soul_sand -// }); - - public ItemSpade(ToolMaterial material) - { - super(1, material); - } - - public boolean canUseOn(ItemStack stack, Block state) - { - return state.canShovelHarvest(); - } - - public boolean canHarvestBlock(Block blockIn) - { -// return blockIn == Blocks.snow_layer ? true : blockIn == Blocks.snow; - return blockIn.getMaterial() == Material.snow ? true : blockIn.getMaterial() == Material.craftedSnow; - } -} diff --git a/common/src/common/item/ItemSword.java b/common/src/common/item/ItemSword.java index 1634327..43ce9a5 100755 --- a/common/src/common/item/ItemSword.java +++ b/common/src/common/item/ItemSword.java @@ -7,12 +7,12 @@ import common.attributes.Attribute; import common.attributes.AttributeModifier; import common.attributes.Attributes; import common.block.Block; +import common.block.Material; import common.collect.Sets; import common.entity.npc.EntityNPC; import common.entity.types.EntityLiving; import common.init.Blocks; import common.init.ToolMaterial; -import common.material.Material; import common.model.Transforms; import common.util.BlockPos; import common.world.World; @@ -27,7 +27,7 @@ public class ItemSword extends Item this.material = material; this.maxStackSize = 1; this.setMaxDamage(material.getDurability()); - this.setTab(CheatTab.tabCombat); + this.setTab(CheatTab.COMBAT); this.attackDamage = 4 + material.getDamage(); } @@ -53,7 +53,7 @@ public class ItemSword extends Item else { Material material = state.getMaterial(); - return material != Material.plants && material != Material.vine && material != Material.leaves && material != Material.gourd ? 1.0F : 1.5F; + return material != Material.PLANT && material != Material.BUSH && material != Material.LEAVES && material != Material.SOFT ? 1.0F : 1.5F; } } diff --git a/common/src/common/item/ItemTool.java b/common/src/common/item/ItemTool.java index 2e2f8b6..cd9f96a 100755 --- a/common/src/common/item/ItemTool.java +++ b/common/src/common/item/ItemTool.java @@ -14,113 +14,65 @@ import common.model.Transforms; import common.util.BlockPos; import common.world.World; -public abstract class ItemTool extends Item -{ -// private Set effectiveBlocks; - protected float efficiencyOnProperMaterial = 4.0F; +public abstract class ItemTool extends Item { + private final float efficiency; + private final int damage; + private final ToolMaterial material; - /** Damage versus entities. */ - private int damageVsEntity; + public ItemTool(int damage, ToolMaterial material) { + this.material = material; + this.maxStackSize = 1; + this.setMaxDamage(material.getDurability()); + this.efficiency = material.getEfficiency(); + this.damage = damage + material.getDamage(); + this.setTab(CheatTab.TOOLS); + } - /** The material this tool is made from. */ - protected ToolMaterial toolMaterial; + public abstract boolean canUseOn(ItemStack stack, Block block); - public ItemTool(int attackDamage, ToolMaterial material) - { - this.toolMaterial = material; -// this.effectiveBlocks = effectiveBlocks; - this.maxStackSize = 1; - this.setMaxDamage(material.getDurability()); - this.efficiencyOnProperMaterial = material.getEfficiency(); - this.damageVsEntity = attackDamage + material.getDamage(); - this.setTab(CheatTab.tabTools); - } - - public abstract boolean canUseOn(ItemStack stack, Block state); + public float getStrVsBlock(ItemStack stack, Block block) { + return !this.canUseOn(stack, block) ? 1.0F : this.efficiency; + } - public float getStrVsBlock(ItemStack stack, Block state) { - return !this.canUseOn(stack, state) ? 1.0F : this.efficiencyOnProperMaterial; - } -// { -// return this.effectiveBlocks.contains(state) ? this.efficiencyOnProperMaterial : 1.0F; -// } + public boolean hitEntity(ItemStack stack, EntityLiving target, EntityLiving attacker) { + stack.damageItem(2, attacker); + return true; + } - /** - * Current implementations of this method in child classes do not use the entry argument beside ev. They just raise - * the damage on the stack. - */ - public boolean hitEntity(ItemStack stack, EntityLiving target, EntityLiving attacker) - { - stack.damageItem(2, attacker); - return true; - } + public boolean onBlockDestroyed(ItemStack stack, World world, Block block, BlockPos pos, EntityLiving player) { + if(block.getBlockHardness(world, pos) != 0.0f) + stack.damageItem(1, player); + return true; + } - /** - * Called when a Block is destroyed using this Item. Return true to trigger the "Use Item" statistic. - */ - public boolean onBlockDestroyed(ItemStack stack, World worldIn, Block blockIn, BlockPos pos, EntityLiving playerIn) - { - if ((double)blockIn.getBlockHardness(worldIn, pos) != 0.0D) - { - stack.damageItem(1, playerIn); - } + public ToolMaterial getToolMaterial() { + return this.material; + } - return true; - } + public int getItemEnchantability() { + return this.material.getEnchantability(); + } -// /** -// * Returns True is the item is renderer in full 3D when hold. -// */ -// public boolean isFull3D() -// { -// return true; -// } + public boolean getIsRepairable(ItemStack stack, ItemStack repair) { + return this.material.isRepairItem(repair.getItem()) ? true : super.getIsRepairable(stack, repair); + } - public ToolMaterial getToolMaterial() - { - return this.toolMaterial; - } + public Map> getItemAttributeModifiers() { + Map> mods = super.getItemAttributeModifiers(); + mods.put(Attributes.ATTACK_DAMAGE, + Sets.newHashSet(new AttributeModifier(Attributes.ITEM_VAL_ID, "Tool modifier", this.damage, false))); + return mods; + } - /** - * Return the enchantability factor of the item, most of the time is based on material. - */ - public int getItemEnchantability() - { - return this.toolMaterial.getEnchantability(); - } + public boolean isMagnetic() { + return this.material.isMagnetic(); + } -// /** -// * Return the name for this tool's material. -// */ -// public String getToolMaterialName() -// { -// return this.toolMaterial.toString(); -// } + public Transforms getTransform() { + return Transforms.TOOL; + } - /** - * Return whether this item is repairable in an anvil. - */ - public boolean getIsRepairable(ItemStack toRepair, ItemStack repair) - { - return this.toolMaterial.isRepairItem(repair.getItem()) ? true : super.getIsRepairable(toRepair, repair); - } - - public Map> getItemAttributeModifiers() - { - Map> multimap = super.getItemAttributeModifiers(); - multimap.put(Attributes.ATTACK_DAMAGE, Sets.newHashSet(new AttributeModifier(Attributes.ITEM_VAL_ID, "Tool modifier", this.damageVsEntity, false))); - return multimap; - } - - public boolean isMagnetic() { - return this.toolMaterial.isMagnetic(); - } - - public Transforms getTransform() { - return Transforms.TOOL; - } - - public boolean canBeWielded() { - return true; - } + public boolean canBeWielded() { + return true; + } } diff --git a/common/src/common/item/ItemWand.java b/common/src/common/item/ItemWand.java index 8b69b69..f0a494d 100755 --- a/common/src/common/item/ItemWand.java +++ b/common/src/common/item/ItemWand.java @@ -15,7 +15,7 @@ import common.world.AWorldServer; public abstract class ItemWand extends Item { public ItemWand() { this.maxStackSize = 1; - this.setTab(CheatTab.tabTools); + this.setTab(CheatTab.TOOLS); } // public boolean canBreakBlocks() { diff --git a/common/src/common/material/Material.java b/common/src/common/material/Material.java deleted file mode 100755 index 28a2f84..0000000 --- a/common/src/common/material/Material.java +++ /dev/null @@ -1,228 +0,0 @@ -package common.material; - -public class Material -{ - public static final Material grass = new Material(); - public static final Material ground = new Material(); - public static final Material wood = (new Material()).setBurning(); - public static final Material rock = (new Material()).setRequiresTool(); - public static final Material iron = (new Material()).setRequiresTool(); - public static final Material anvil = (new Material()).setRequiresTool().setImmovableMobility(); - public static final Material water = (new MaterialColdFluid()).setNoPushMobility(); - public static final Material coldFluid = (new MaterialColdFluid()).setNoPushMobility(); - public static final Material lava = (new MaterialHotFluid()).setNoPushMobility(); - public static final Material hotFluid = (new MaterialHotFluid()).setNoPushMobility(); - public static final Material leaves = (new Material()).setBurning().setTranslucent().setNoPushMobility(); - public static final Material plants = (new MaterialLogic()).setNoPushMobility(); - public static final Material vine = (new MaterialLogic()).setBurning().setNoPushMobility().setReplaceable(); - public static final Material sponge = new Material(); - public static final Material cloth = (new Material()).setBurning(); - public static final Material fire = (new MaterialTransparent()).setNoPushMobility(); - public static final Material sand = new Material(); - public static final Material circuits = (new MaterialLogic()).setNoPushMobility(); - public static final Material carpet = (new MaterialLogic()).setBurning(); - public static final Material glass = (new Material()).setTranslucent(); - public static final Material redstoneLight = (new Material()); - public static final Material tnt = (new Material()).setBurning().setTranslucent(); - public static final Material ice = (new Material()).setTranslucent(); - public static final Material packedIce = (new Material()); - public static final Material snow = (new MaterialLogic()).setReplaceable().setTranslucent().setRequiresTool().setNoPushMobility(); - public static final Material craftedSnow = (new Material()).setRequiresTool(); - public static final Material cactus = (new Material()).setTranslucent().setNoPushMobility(); - public static final Material clay = new Material(); - public static final Material gourd = (new Material()).setNoPushMobility(); - public static final Material dragonEgg = (new Material()).setNoPushMobility(); - public static final Material portal = (new MaterialPortal()).setImmovableMobility(); - public static final Material cake = (new Material()).setNoPushMobility(); - public static final Material web = (new Material() - { - public boolean blocksMovement() - { - return false; - } - }).setRequiresTool().setNoPushMobility(); - public static final Material piston = (new Material()).setImmovableMobility(); - - /** Bool defining if the block can burn or not. */ - private boolean canBurn; - - /** - * Determines whether blocks with this material can be "overwritten" by other blocks when placed - eg snow, vines - * and tall grass. - */ - private boolean replaceable; - - /** Indicates if the material is translucent */ - private boolean isTranslucent; - -// /** The color index used to draw the blocks of this material on maps. */ -// private final MapColor materialMapColor; - - /** - * Determines if the material can be harvested without a tool (or with the wrong tool) - */ - private boolean requiresNoTool = true; - - /** - * Mobility information flag. 0 indicates that this block is normal, 1 indicates that it can't push other blocks, 2 - * indicates that it can't be pushed. - */ - private int mobilityFlag; -// private boolean isAdventureModeExempt; - -// public Material(MapColor color) -// { -//// this.materialMapColor = color; -// } - - /** - * Returns if blocks of these materials are liquids. - */ - public boolean isLiquid() - { - return false; - } - - public boolean isColdLiquid() - { - return false; - } - - public boolean isHotLiquid() - { - return false; - } - - /** - * Returns true if the block is a considered solid. This is true by default. - */ - public boolean isSolid() - { - return true; - } - - /** - * Will prevent grass from growing on dirt underneath and kill any grass below it if it returns true - */ - public boolean blocksLight() - { - return true; - } - - /** - * Returns if this material is considered solid or not - */ - public boolean blocksMovement() - { - return true; - } - - /** - * Marks the material as translucent - */ - private Material setTranslucent() - { - this.isTranslucent = true; - return this; - } - - /** - * Makes blocks with this material require the correct tool to be harvested. - */ - protected Material setRequiresTool() - { - this.requiresNoTool = false; - return this; - } - - /** - * Set the canBurn bool to True and return the current object. - */ - protected Material setBurning() - { - this.canBurn = true; - return this; - } - - /** - * Returns if the block can burn or not. - */ - public boolean getCanBurn() - { - return this.canBurn; - } - - /** - * Sets {@link #replaceable} to true. - */ - public Material setReplaceable() - { - this.replaceable = true; - return this; - } - - /** - * Returns whether the material can be replaced by other blocks when placed - eg snow, vines and tall grass. - */ - public boolean isReplaceable() - { - return this.replaceable; - } - - /** - * Indicate if the material is opaque - */ - public boolean isOpaque() - { - return this.isTranslucent ? false : this.blocksMovement(); - } - - /** - * Returns true if the material can be harvested without a tool (or with the wrong tool) - */ - public boolean isToolNotRequired() - { - return this.requiresNoTool; - } - - /** - * Returns the mobility information of the material, 0 = free, 1 = can't push but can move over, 2 = total - * immobility and stop pistons. - */ - public int getMaterialMobility() - { - return this.mobilityFlag; - } - - /** - * This type of material can't be pushed, but pistons can move over it. - */ - protected Material setNoPushMobility() - { - this.mobilityFlag = 1; - return this; - } - - /** - * This type of material can't be pushed, and pistons are blocked to move. - */ - protected Material setImmovableMobility() - { - this.mobilityFlag = 2; - return this; - } - -// protected Material setAdventureModeExempt() -// { -// this.isAdventureModeExempt = true; -// return this; -// } - -// /** -// * Retrieves the color index of the block. This is is the same color used by vanilla maps to represent this block. -// */ -// public MapColor getMaterialMapColor() -// { -// return this.materialMapColor; -// } -} diff --git a/common/src/common/material/MaterialColdFluid.java b/common/src/common/material/MaterialColdFluid.java deleted file mode 100755 index 9187ad2..0000000 --- a/common/src/common/material/MaterialColdFluid.java +++ /dev/null @@ -1,24 +0,0 @@ -package common.material; - -public class MaterialColdFluid extends Material { - public MaterialColdFluid() { - this.setReplaceable(); - this.setNoPushMobility(); - } - - public boolean isLiquid() { - return true; - } - - public boolean isColdLiquid() { - return true; - } - - public boolean blocksMovement() { - return false; - } - - public boolean isSolid() { - return false; - } -} diff --git a/common/src/common/material/MaterialHotFluid.java b/common/src/common/material/MaterialHotFluid.java deleted file mode 100755 index 03b6ca1..0000000 --- a/common/src/common/material/MaterialHotFluid.java +++ /dev/null @@ -1,24 +0,0 @@ -package common.material; - -public class MaterialHotFluid extends Material { - public MaterialHotFluid() { - this.setReplaceable(); - this.setNoPushMobility(); - } - - public boolean isLiquid() { - return true; - } - - public boolean isHotLiquid() { - return true; - } - - public boolean blocksMovement() { - return false; - } - - public boolean isSolid() { - return false; - } -} diff --git a/common/src/common/material/MaterialLogic.java b/common/src/common/material/MaterialLogic.java deleted file mode 100755 index 137eb9a..0000000 --- a/common/src/common/material/MaterialLogic.java +++ /dev/null @@ -1,28 +0,0 @@ -package common.material; - -public class MaterialLogic extends Material -{ - /** - * Returns true if the block is a considered solid. This is true by default. - */ - public boolean isSolid() - { - return false; - } - - /** - * Will prevent grass from growing on dirt underneath and kill any grass below it if it returns true - */ - public boolean blocksLight() - { - return false; - } - - /** - * Returns if this material is considered solid or not - */ - public boolean blocksMovement() - { - return false; - } -} diff --git a/common/src/common/material/MaterialPortal.java b/common/src/common/material/MaterialPortal.java deleted file mode 100755 index 778d739..0000000 --- a/common/src/common/material/MaterialPortal.java +++ /dev/null @@ -1,28 +0,0 @@ -package common.material; - -public class MaterialPortal extends Material -{ - /** - * Returns true if the block is a considered solid. This is true by default. - */ - public boolean isSolid() - { - return false; - } - - /** - * Will prevent grass from growing on dirt underneath and kill any grass below it if it returns true - */ - public boolean blocksLight() - { - return false; - } - - /** - * Returns if this material is considered solid or not - */ - public boolean blocksMovement() - { - return false; - } -} diff --git a/common/src/common/material/MaterialTransparent.java b/common/src/common/material/MaterialTransparent.java deleted file mode 100755 index 82af6d1..0000000 --- a/common/src/common/material/MaterialTransparent.java +++ /dev/null @@ -1,33 +0,0 @@ -package common.material; - -public class MaterialTransparent extends Material -{ - public MaterialTransparent() - { - this.setReplaceable(); - } - - /** - * Returns true if the block is a considered solid. This is true by default. - */ - public boolean isSolid() - { - return false; - } - - /** - * Will prevent grass from growing on dirt underneath and kill any grass below it if it returns true - */ - public boolean blocksLight() - { - return false; - } - - /** - * Returns if this material is considered solid or not - */ - public boolean blocksMovement() - { - return false; - } -} diff --git a/common/src/common/pathfinding/PathNavigateGround.java b/common/src/common/pathfinding/PathNavigateGround.java index 0ecbf86..7a6c5de 100755 --- a/common/src/common/pathfinding/PathNavigateGround.java +++ b/common/src/common/pathfinding/PathNavigateGround.java @@ -1,11 +1,11 @@ package common.pathfinding; import common.block.Block; +import common.block.Material; import common.entity.animal.EntityChicken; import common.entity.npc.EntityZombie; import common.entity.types.EntityLiving; import common.init.Blocks; -import common.material.Material; import common.util.BlockPos; import common.util.ExtMath; import common.util.Vec3; diff --git a/common/src/common/pathfinding/WalkNodeProcessor.java b/common/src/common/pathfinding/WalkNodeProcessor.java index 8ba5d42..cfe84a6 100755 --- a/common/src/common/pathfinding/WalkNodeProcessor.java +++ b/common/src/common/pathfinding/WalkNodeProcessor.java @@ -1,6 +1,7 @@ package common.pathfinding; import common.block.Block; +import common.block.Material; import common.block.artificial.BlockDoor; import common.block.artificial.BlockFence; import common.block.artificial.BlockFenceGate; @@ -8,7 +9,6 @@ import common.block.artificial.BlockWall; import common.block.tech.BlockRailBase; import common.entity.Entity; import common.init.Blocks; -import common.material.Material; import common.util.BlockPos; import common.util.ExtMath; import common.world.IBlockAccess; @@ -211,7 +211,7 @@ public class WalkNodeProcessor extends NodeProcessor { if (!block.getMaterial().isColdLiquid()) { - if (!enterDoors && block instanceof BlockDoor && block.getMaterial() == Material.wood) + if (!enterDoors && block instanceof BlockDoor && block.getMaterial() == Material.WOOD) { return 0; } @@ -238,7 +238,7 @@ public class WalkNodeProcessor extends NodeProcessor return -3; } } - else if (!block.isPassable(world, mpos) && (!breakDoors || !(block instanceof BlockDoor) || block.getMaterial() != Material.wood)) + else if (!block.isPassable(world, mpos) && (!breakDoors || !(block instanceof BlockDoor) || block.getMaterial() != Material.WOOD)) { if (block instanceof BlockFence || block instanceof BlockFenceGate || block instanceof BlockWall) { diff --git a/common/src/common/tileentity/TileEntityFurnace.java b/common/src/common/tileentity/TileEntityFurnace.java index 2f3a1f6..c103aa7 100755 --- a/common/src/common/tileentity/TileEntityFurnace.java +++ b/common/src/common/tileentity/TileEntityFurnace.java @@ -1,6 +1,7 @@ package common.tileentity; import common.block.Block; +import common.block.Material; import common.block.artificial.BlockSlab; import common.block.foliage.BlockSapling; import common.block.tech.BlockFurnace; @@ -22,7 +23,6 @@ import common.item.ItemHoe; import common.item.ItemStack; import common.item.ItemSword; import common.item.ItemTool; -import common.material.Material; import common.nbt.NBTTagCompound; import common.nbt.NBTTagList; import common.util.ExtMath; @@ -381,7 +381,7 @@ public class TileEntityFurnace extends TileEntityLockable implements ITickable, // return 150; // } - if (block.getMaterial() == Material.wood) + if (block.getMaterial() == Material.WOOD) { return block instanceof BlockSlab ? 150 : 300; } @@ -398,7 +398,7 @@ public class TileEntityFurnace extends TileEntityLockable implements ITickable, (item == Items.stick ? 100 : (item == Items.coal ? 1600 : (item instanceof ItemBucket && ((ItemBucket)item).getLiquid() != null && - ((ItemBucket)item).getLiquid().getMaterial() == Material.lava ? 20000 : + ((ItemBucket)item).getLiquid().getMaterial() == Material.LAVA ? 20000 : (item.getBlock() instanceof BlockSapling ? 100 : (item == Items.blaze_rod ? 2400 : 0))))))); } diff --git a/common/src/common/village/Village.java b/common/src/common/village/Village.java index 4a805dc..3801d4e 100755 --- a/common/src/common/village/Village.java +++ b/common/src/common/village/Village.java @@ -4,9 +4,9 @@ import java.util.Iterator; import java.util.List; import common.block.Block; +import common.block.Material; import common.block.artificial.BlockDoor; import common.collect.Lists; -import common.material.Material; import common.nbt.NBTTagCompound; import common.nbt.NBTTagList; import common.util.BlockPos; @@ -183,7 +183,7 @@ public class Village private boolean isWoodDoor(AWorldServer world, BlockPos pos) { Block block = world.getState(pos).getBlock(); - return block instanceof BlockDoor ? block.getMaterial() == Material.wood : false; + return block instanceof BlockDoor ? block.getMaterial() == Material.WOOD : false; } private void updatePosition() diff --git a/common/src/common/world/Chunk.java b/common/src/common/world/Chunk.java index 16af85a..359339a 100755 --- a/common/src/common/world/Chunk.java +++ b/common/src/common/world/Chunk.java @@ -9,12 +9,12 @@ import java.util.function.Predicate; import common.block.Block; import common.block.ITileEntityProvider; +import common.block.Material; import common.collect.Maps; import common.collect.Sets; import common.entity.Entity; import common.init.Blocks; import common.log.Log; -import common.material.Material; import common.tileentity.TileEntity; import common.util.BlockPos; import common.util.BoundingBox; @@ -645,8 +645,8 @@ public abstract class Chunk { Material mat = block.getMaterial(); if((!mat.blocksMovement() && !mat.isLiquid()) - || (mat == Material.leaves && ((mat = this.getBlock(loc.up()).getMaterial()) == Material.snow) - || mat == Material.leaves)) { + || (mat == Material.LEAVES && ((mat = this.getBlock(loc.up()).getMaterial()) == Material.POWDER) + || mat == Material.LEAVES)) { loc = loc.down(); } else { diff --git a/common/src/common/world/World.java b/common/src/common/world/World.java index 42a7f98..6bd37b7 100755 --- a/common/src/common/world/World.java +++ b/common/src/common/world/World.java @@ -8,6 +8,7 @@ import java.util.function.Predicate; import common.biome.Biome; import common.block.Block; +import common.block.Material; import common.block.artificial.BlockSlab; import common.block.artificial.BlockStairs; import common.block.foliage.LeavesType; @@ -24,7 +25,6 @@ import common.init.BlockRegistry; import common.init.Blocks; import common.init.SoundEvent; import common.item.ItemStack; -import common.material.Material; import common.model.ParticleType; import common.rng.Random; import common.tileentity.ITickable; @@ -1831,7 +1831,7 @@ public abstract class World implements IWorldAccess { Block block = this.getState(pos).getBlock(); BoundingBox axisalignedbb = p_175716_3_ ? null : blockIn.getCollisionBoundingBox(this, pos, blockIn.getState()); return axisalignedbb != null && !this.checkNoEntityCollision(axisalignedbb, entityIn) ? false - : (block.getMaterial() == Material.circuits && blockIn == Blocks.anvil ? true + : (block.getMaterial() == Material.SMALL && blockIn == Blocks.anvil ? true : block.getMaterial().isReplaceable() && blockIn.canReplace(this, pos, side, itemStackIn)); } diff --git a/server/src/server/biome/GenBiome.java b/server/src/server/biome/GenBiome.java index 4878746..4c563e0 100755 --- a/server/src/server/biome/GenBiome.java +++ b/server/src/server/biome/GenBiome.java @@ -4,6 +4,7 @@ import common.biome.Biome; import common.biome.IBiome; import common.block.Block; import common.block.BlockColored; +import common.block.Material; import common.block.foliage.BlockFlower; import common.block.foliage.BlockSapling; import common.block.foliage.BlockTallGrass; @@ -26,7 +27,6 @@ import common.entity.npc.EntityZombie; import common.init.Blocks; import common.init.WoodType; import common.log.Log; -import common.material.Material; import common.rng.PerlinGen; import common.rng.Random; import common.rng.WeightedList; @@ -554,7 +554,7 @@ public abstract class GenBiome implements IBiome { Block worldBlock = worldState.getBlock(); State worldAlt = worldIn.dimension.getAltFiller1(); State liquid = worldIn.getSurfaceLiquid(); - boolean freeze = liquid.getBlock().getMaterial() == Material.water; + boolean freeze = liquid.getBlock().getMaterial() == Material.WATER; State iblockstate = this.topBlock; State iblockstate1 = this.fillerBlock; int j = -1; diff --git a/server/src/server/village/VillageCollection.java b/server/src/server/village/VillageCollection.java index 59c9ccb..4e7b939 100755 --- a/server/src/server/village/VillageCollection.java +++ b/server/src/server/village/VillageCollection.java @@ -4,9 +4,9 @@ import java.util.Iterator; import java.util.List; import common.block.Block; +import common.block.Material; import common.block.artificial.BlockDoor; import common.collect.Lists; -import common.material.Material; import common.nbt.NBTTagCompound; import common.nbt.NBTTagList; import common.util.BlockPos; @@ -245,7 +245,7 @@ public class VillageCollection private boolean isWoodDoor(WorldServer world, BlockPos doorPos) { Block block = world.getState(doorPos).getBlock(); - return block instanceof BlockDoor ? block.getMaterial() == Material.wood : false; + return block instanceof BlockDoor ? block.getMaterial() == Material.WOOD : false; } public NBTTagCompound writeToNBT() diff --git a/server/src/server/world/WorldServer.java b/server/src/server/world/WorldServer.java index 6c9f485..7079f71 100755 --- a/server/src/server/world/WorldServer.java +++ b/server/src/server/world/WorldServer.java @@ -16,6 +16,7 @@ import java.util.function.Predicate; import common.biome.Biome; import common.block.Block; import common.block.BlockFalling; +import common.block.Material; import common.block.artificial.BlockDoor; import common.block.liquid.BlockLiquid; import common.block.natural.BlockSnow; @@ -38,7 +39,6 @@ import common.init.SoundEvent; import common.init.UniverseRegistry; import common.item.ItemDoor; import common.log.Log; -import common.material.Material; import common.model.ParticleType; import common.nbt.NBTLoader; import common.nbt.NBTTagCompound; @@ -2381,10 +2381,10 @@ public final class WorldServer extends AWorldServer { return true; } - boolean flag = this.getState(pos.west()).getBlock().getMaterial() == Material.water && - this.getState(pos.east()).getBlock().getMaterial() == Material.water && - this.getState(pos.north()).getBlock().getMaterial() == Material.water && - this.getState(pos.south()).getBlock().getMaterial() == Material.water; + boolean flag = this.getState(pos.west()).getBlock().getMaterial() == Material.WATER && + this.getState(pos.east()).getBlock().getMaterial() == Material.WATER && + this.getState(pos.north()).getBlock().getMaterial() == Material.WATER && + this.getState(pos.south()).getBlock().getMaterial() == Material.WATER; if(!flag) { return true; @@ -2435,7 +2435,7 @@ public final class WorldServer extends AWorldServer { blockpos1 = blockpos.down(); Material material = chunk.getBlock(blockpos1).getMaterial(); - if(material.blocksMovement() && material != Material.leaves) { + if(material.blocksMovement() && material != Material.LEAVES) { break; } } diff --git a/server/src/server/worldgen/FeatureDungeons.java b/server/src/server/worldgen/FeatureDungeons.java index 816c0d8..0ea7248 100755 --- a/server/src/server/worldgen/FeatureDungeons.java +++ b/server/src/server/worldgen/FeatureDungeons.java @@ -1,10 +1,10 @@ package server.worldgen; +import common.block.Material; import common.init.Blocks; import common.init.Items; import common.item.RngLoot; import common.log.Log; -import common.material.Material; import common.rng.Random; import common.rng.WeightedList; import common.tileentity.TileEntity; diff --git a/server/src/server/worldgen/FeatureLakes.java b/server/src/server/worldgen/FeatureLakes.java index 98fe8bd..2f6fa82 100755 --- a/server/src/server/worldgen/FeatureLakes.java +++ b/server/src/server/worldgen/FeatureLakes.java @@ -1,8 +1,8 @@ package server.worldgen; import common.block.Block; +import common.block.Material; import common.init.Blocks; -import common.material.Material; import common.rng.Random; import common.util.BlockPos; import common.world.LightType; @@ -199,7 +199,7 @@ public class FeatureLakes } } - if (this.block.getMaterial() == Material.water) + if (this.block.getMaterial() == Material.WATER) { for (int k2 = 0; k2 < 16; ++k2) { diff --git a/server/src/server/worldgen/feature/WorldGenAbandonedChest.java b/server/src/server/worldgen/feature/WorldGenAbandonedChest.java index c71efea..7e12f6b 100755 --- a/server/src/server/worldgen/feature/WorldGenAbandonedChest.java +++ b/server/src/server/worldgen/feature/WorldGenAbandonedChest.java @@ -1,9 +1,9 @@ package server.worldgen.feature; import common.block.Block; +import common.block.Material; import common.init.Blocks; import common.item.RngLoot; -import common.material.Material; import common.rng.Random; import common.rng.WeightedList; import common.tileentity.TileEntity; @@ -33,7 +33,7 @@ public class WorldGenAbandonedChest extends FeatureGenerator public boolean generate(WorldServer worldIn, Random rand, BlockPos position) { Block block; - while (((block = worldIn.getState(position).getBlock()) == Blocks.air || block.getMaterial() == Material.leaves) && position.getY() > 1) + while (((block = worldIn.getState(position).getBlock()) == Blocks.air || block.getMaterial() == Material.LEAVES) && position.getY() > 1) { position = position.down(); } diff --git a/server/src/server/worldgen/foliage/WorldGenBigMushroom.java b/server/src/server/worldgen/foliage/WorldGenBigMushroom.java index 450cd1a..15c3723 100755 --- a/server/src/server/worldgen/foliage/WorldGenBigMushroom.java +++ b/server/src/server/worldgen/foliage/WorldGenBigMushroom.java @@ -1,9 +1,9 @@ package server.worldgen.foliage; import common.block.Block; +import common.block.Material; import common.block.foliage.BlockHugeMushroom; import common.init.Blocks; -import common.material.Material; import common.rng.Random; import common.util.BlockPos; import server.world.WorldServer; @@ -56,7 +56,7 @@ public class WorldGenBigMushroom extends FeatureGenerator { Block block = worldIn.getState(blockpos$mutableblockpos.set(l, j, i1)).getBlock(); - if (block != Blocks.air && block.getMaterial() != Material.leaves) + if (block != Blocks.air && block.getMaterial() != Material.LEAVES) { flag = false; } diff --git a/server/src/server/worldgen/foliage/WorldGenDeadBush.java b/server/src/server/worldgen/foliage/WorldGenDeadBush.java index 422576f..ae5c9f7 100755 --- a/server/src/server/worldgen/foliage/WorldGenDeadBush.java +++ b/server/src/server/worldgen/foliage/WorldGenDeadBush.java @@ -1,8 +1,8 @@ package server.worldgen.foliage; import common.block.Block; +import common.block.Material; import common.init.Blocks; -import common.material.Material; import common.rng.Random; import common.util.BlockPos; import server.world.WorldServer; @@ -14,7 +14,7 @@ public class WorldGenDeadBush extends FeatureGenerator { Block block; - while (((block = worldIn.getState(position).getBlock()) == Blocks.air || block.getMaterial() == Material.leaves) && position.getY() > 0) + while (((block = worldIn.getState(position).getBlock()) == Blocks.air || block.getMaterial() == Material.LEAVES) && position.getY() > 0) { position = position.down(); } diff --git a/server/src/server/worldgen/foliage/WorldGenReed.java b/server/src/server/worldgen/foliage/WorldGenReed.java index 459216e..45be4d9 100755 --- a/server/src/server/worldgen/foliage/WorldGenReed.java +++ b/server/src/server/worldgen/foliage/WorldGenReed.java @@ -1,7 +1,7 @@ package server.worldgen.foliage; +import common.block.Material; import common.init.Blocks; -import common.material.Material; import common.rng.Random; import common.util.BlockPos; import server.world.WorldServer; @@ -19,7 +19,7 @@ public class WorldGenReed extends FeatureGenerator { BlockPos blockpos1 = blockpos.down(); - if (worldIn.getState(blockpos1.west()).getBlock().getMaterial() == Material.water || worldIn.getState(blockpos1.east()).getBlock().getMaterial() == Material.water || worldIn.getState(blockpos1.north()).getBlock().getMaterial() == Material.water || worldIn.getState(blockpos1.south()).getBlock().getMaterial() == Material.water) + if (worldIn.getState(blockpos1.west()).getBlock().getMaterial() == Material.WATER || worldIn.getState(blockpos1.east()).getBlock().getMaterial() == Material.WATER || worldIn.getState(blockpos1.north()).getBlock().getMaterial() == Material.WATER || worldIn.getState(blockpos1.south()).getBlock().getMaterial() == Material.WATER) { int j = 2 + rand.zrange(rand.zrange(3) + 1); diff --git a/server/src/server/worldgen/foliage/WorldGenShrub.java b/server/src/server/worldgen/foliage/WorldGenShrub.java index ec49a02..65d9376 100755 --- a/server/src/server/worldgen/foliage/WorldGenShrub.java +++ b/server/src/server/worldgen/foliage/WorldGenShrub.java @@ -1,9 +1,9 @@ package server.worldgen.foliage; import common.block.Block; +import common.block.Material; import common.block.foliage.BlockLeaves; import common.init.Blocks; -import common.material.Material; import common.rng.Random; import common.util.BlockPos; import common.world.State; @@ -26,7 +26,7 @@ public class WorldGenShrub extends WorldGenBaseTree { Block block; - while (((block = worldIn.getState(position).getBlock()) == Blocks.air || block.getMaterial() == Material.leaves) && position.getY() > 0) + while (((block = worldIn.getState(position).getBlock()) == Blocks.air || block.getMaterial() == Material.LEAVES) && position.getY() > 0) { position = position.down(); } diff --git a/server/src/server/worldgen/foliage/WorldGenTallGrass.java b/server/src/server/worldgen/foliage/WorldGenTallGrass.java index cd8d788..81a1d75 100755 --- a/server/src/server/worldgen/foliage/WorldGenTallGrass.java +++ b/server/src/server/worldgen/foliage/WorldGenTallGrass.java @@ -1,9 +1,9 @@ package server.worldgen.foliage; import common.block.Block; +import common.block.Material; import common.block.foliage.BlockTallGrass; import common.init.Blocks; -import common.material.Material; import common.rng.Random; import common.util.BlockPos; import common.world.State; @@ -23,7 +23,7 @@ public class WorldGenTallGrass extends FeatureGenerator { Block block; - while (((block = worldIn.getState(position).getBlock()) == Blocks.air || block.getMaterial() == Material.leaves) && position.getY() > 0) + while (((block = worldIn.getState(position).getBlock()) == Blocks.air || block.getMaterial() == Material.LEAVES) && position.getY() > 0) { position = position.down(); } diff --git a/server/src/server/worldgen/tree/WorldGenBaseTree.java b/server/src/server/worldgen/tree/WorldGenBaseTree.java index 43e2221..5858316 100755 --- a/server/src/server/worldgen/tree/WorldGenBaseTree.java +++ b/server/src/server/worldgen/tree/WorldGenBaseTree.java @@ -1,11 +1,11 @@ package server.worldgen.tree; import common.block.Block; +import common.block.Material; import common.block.foliage.BlockCocoa; import common.block.foliage.BlockLeaves; import common.block.foliage.BlockVine; import common.init.Blocks; -import common.material.Material; import common.properties.PropertyBool; import common.rng.Random; import common.util.BlockPos; @@ -116,7 +116,7 @@ public class WorldGenBaseTree extends WorldGenTree BlockPos blockpos = new BlockPos(k1, i3, i2); Block block = worldIn.getState(blockpos).getBlock(); - if (block == Blocks.air || block.getMaterial() == Material.leaves || block.getMaterial() == Material.vine) + if (block == Blocks.air || block.getMaterial() == Material.LEAVES || block.getMaterial() == Material.BUSH) { this.setBlockAndNotifyAdequately(worldIn, blockpos, this.metaLeaves.withProperty(BlockLeaves.TYPE, worldIn.getLeavesGen(blockpos))); } @@ -129,7 +129,7 @@ public class WorldGenBaseTree extends WorldGenTree { Block block2 = worldIn.getState(position.up(j3)).getBlock(); - if (block2 == Blocks.air || block2.getMaterial() == Material.leaves || block2.getMaterial() == Material.vine) + if (block2 == Blocks.air || block2.getMaterial() == Material.LEAVES || block2.getMaterial() == Material.BUSH) { this.setBlockAndNotifyAdequately(worldIn, position.up(j3), this.metaWood); @@ -172,7 +172,7 @@ public class WorldGenBaseTree extends WorldGenTree { blockpos$mutableblockpos1.set(l4, k3, i5); - if (worldIn.getState(blockpos$mutableblockpos1).getBlock().getMaterial() == Material.leaves) + if (worldIn.getState(blockpos$mutableblockpos1).getBlock().getMaterial() == Material.LEAVES) { BlockPos blockpos2 = blockpos$mutableblockpos1.west(); BlockPos blockpos3 = blockpos$mutableblockpos1.east(); diff --git a/server/src/server/worldgen/tree/WorldGenBigTree.java b/server/src/server/worldgen/tree/WorldGenBigTree.java index d9482a6..4daf686 100755 --- a/server/src/server/worldgen/tree/WorldGenBigTree.java +++ b/server/src/server/worldgen/tree/WorldGenBigTree.java @@ -3,11 +3,11 @@ package server.worldgen.tree; import java.util.List; import common.block.Block; +import common.block.Material; import common.block.foliage.BlockLeaves; import common.block.foliage.BlockLog; import common.collect.Lists; import common.init.Blocks; -import common.material.Material; import common.rng.Random; import common.util.BlockPos; import common.util.ExtMath; @@ -127,7 +127,7 @@ public class WorldGenBigTree extends WorldGenTree BlockPos blockpos = p_181631_1_.add(j, 0, k); Block block = this.world.getState(blockpos).getBlock(); - if (block == Blocks.air || block.getMaterial() == Material.leaves) + if (block == Blocks.air || block.getMaterial() == Material.LEAVES) { this.setBlockAndNotifyAdequately(this.world, blockpos, p_181631_3_); } diff --git a/server/src/server/worldgen/tree/WorldGenBirch.java b/server/src/server/worldgen/tree/WorldGenBirch.java index ba62e4c..58bdda1 100755 --- a/server/src/server/worldgen/tree/WorldGenBirch.java +++ b/server/src/server/worldgen/tree/WorldGenBirch.java @@ -1,9 +1,9 @@ package server.worldgen.tree; import common.block.Block; +import common.block.Material; import common.block.foliage.BlockLeaves; import common.init.Blocks; -import common.material.Material; import common.rng.Random; import common.util.BlockPos; import common.world.State; @@ -101,7 +101,7 @@ public class WorldGenBirch extends WorldGenTree BlockPos blockpos = new BlockPos(i3, i2, k1); Block block = worldIn.getState(blockpos).getBlock(); - if (block == Blocks.air || block.getMaterial() == Material.leaves) + if (block == Blocks.air || block.getMaterial() == Material.LEAVES) { this.setBlockAndNotifyAdequately(worldIn, blockpos, leavesBlock.withProperty(BlockLeaves.TYPE, worldIn.getLeavesGen(blockpos))); } @@ -114,7 +114,7 @@ public class WorldGenBirch extends WorldGenTree { Block block2 = worldIn.getState(position.up(j2)).getBlock(); - if (block2 == Blocks.air || block2.getMaterial() == Material.leaves) + if (block2 == Blocks.air || block2.getMaterial() == Material.LEAVES) { this.setBlockAndNotifyAdequately(worldIn, position.up(j2), logBlock); } diff --git a/server/src/server/worldgen/tree/WorldGenDarkOak.java b/server/src/server/worldgen/tree/WorldGenDarkOak.java index 51a021a..65286b2 100755 --- a/server/src/server/worldgen/tree/WorldGenDarkOak.java +++ b/server/src/server/worldgen/tree/WorldGenDarkOak.java @@ -1,9 +1,9 @@ package server.worldgen.tree; import common.block.Block; +import common.block.Material; import common.block.foliage.BlockLeaves; import common.init.Blocks; -import common.material.Material; import common.rng.Random; import common.util.BlockPos; import common.util.Facing; @@ -68,7 +68,7 @@ public class WorldGenDarkOak extends WorldGenTree BlockPos blockpos1 = new BlockPos(k1, k2, l1); Block block1 = worldIn.getState(blockpos1).getBlock(); - if (block1 == Blocks.air || block1.getMaterial() == Material.leaves) + if (block1 == Blocks.air || block1.getMaterial() == Material.LEAVES) { this.func_181639_b(worldIn, blockpos1); this.func_181639_b(worldIn, blockpos1.east()); diff --git a/server/src/server/worldgen/tree/WorldGenHugeTree.java b/server/src/server/worldgen/tree/WorldGenHugeTree.java index 24b9553..05ddd76 100755 --- a/server/src/server/worldgen/tree/WorldGenHugeTree.java +++ b/server/src/server/worldgen/tree/WorldGenHugeTree.java @@ -1,9 +1,9 @@ package server.worldgen.tree; import common.block.Block; +import common.block.Material; import common.block.foliage.BlockLeaves; import common.init.Blocks; -import common.material.Material; import common.rng.Random; import common.util.BlockPos; import common.world.State; @@ -121,7 +121,7 @@ public abstract class WorldGenHugeTree extends WorldGenTree BlockPos blockpos = p_175925_2_.add(j, 0, k); Block block = worldIn.getState(blockpos).getBlock(); - if (block == Blocks.air || block.getMaterial() == Material.leaves) + if (block == Blocks.air || block.getMaterial() == Material.LEAVES) { this.setBlockAndNotifyAdequately(worldIn, blockpos, this.leavesMetadata.withProperty(BlockLeaves.TYPE, worldIn.getLeavesGen(blockpos))); } @@ -143,7 +143,7 @@ public abstract class WorldGenHugeTree extends WorldGenTree BlockPos blockpos = p_175928_2_.add(j, 0, k); Block block = worldIn.getState(blockpos).getBlock(); - if (block == Blocks.air || block.getMaterial() == Material.leaves) + if (block == Blocks.air || block.getMaterial() == Material.LEAVES) { this.setBlockAndNotifyAdequately(worldIn, blockpos, this.leavesMetadata.withProperty(BlockLeaves.TYPE, worldIn.getLeavesGen(blockpos))); } diff --git a/server/src/server/worldgen/tree/WorldGenPine.java b/server/src/server/worldgen/tree/WorldGenPine.java index 497e880..26b9820 100755 --- a/server/src/server/worldgen/tree/WorldGenPine.java +++ b/server/src/server/worldgen/tree/WorldGenPine.java @@ -1,9 +1,9 @@ package server.worldgen.tree; import common.block.Block; +import common.block.Material; import common.block.natural.BlockDirt; import common.init.Blocks; -import common.material.Material; import common.rng.Random; import common.util.BlockPos; import common.util.ExtMath; @@ -39,7 +39,7 @@ public class WorldGenPine extends WorldGenHugeTree { Block block = worldIn.getState(position.up(j)).getBlock(); - if (block == Blocks.air || block.getMaterial() == Material.leaves) + if (block == Blocks.air || block.getMaterial() == Material.LEAVES) { this.setBlockAndNotifyAdequately(worldIn, position.up(j), this.woodMetadata); } @@ -48,21 +48,21 @@ public class WorldGenPine extends WorldGenHugeTree { block = worldIn.getState(position.add(1, j, 0)).getBlock(); - if (block == Blocks.air || block.getMaterial() == Material.leaves) + if (block == Blocks.air || block.getMaterial() == Material.LEAVES) { this.setBlockAndNotifyAdequately(worldIn, position.add(1, j, 0), this.woodMetadata); } block = worldIn.getState(position.add(1, j, 1)).getBlock(); - if (block == Blocks.air || block.getMaterial() == Material.leaves) + if (block == Blocks.air || block.getMaterial() == Material.LEAVES) { this.setBlockAndNotifyAdequately(worldIn, position.add(1, j, 1), this.woodMetadata); } block = worldIn.getState(position.add(0, j, 1)).getBlock(); - if (block == Blocks.air || block.getMaterial() == Material.leaves) + if (block == Blocks.air || block.getMaterial() == Material.LEAVES) { this.setBlockAndNotifyAdequately(worldIn, position.add(0, j, 1), this.woodMetadata); } diff --git a/server/src/server/worldgen/tree/WorldGenSavanna.java b/server/src/server/worldgen/tree/WorldGenSavanna.java index 7c85bee..dfd389b 100755 --- a/server/src/server/worldgen/tree/WorldGenSavanna.java +++ b/server/src/server/worldgen/tree/WorldGenSavanna.java @@ -1,9 +1,9 @@ package server.worldgen.tree; import common.block.Block; +import common.block.Material; import common.block.foliage.BlockLeaves; import common.init.Blocks; -import common.material.Material; import common.rng.Random; import common.util.BlockPos; import common.util.Facing; @@ -97,7 +97,7 @@ public class WorldGenSavanna extends WorldGenTree BlockPos blockpos = new BlockPos(i3, i2, j1); Block block1 = worldIn.getState(blockpos).getBlock(); - if (block1 == Blocks.air || block1.getMaterial() == Material.leaves) + if (block1 == Blocks.air || block1.getMaterial() == Material.LEAVES) { this.func_181642_b(worldIn, blockpos); k1 = i2; @@ -151,7 +151,7 @@ public class WorldGenSavanna extends WorldGenTree BlockPos blockpos1 = new BlockPos(i3, j2, j1); Block block1 = worldIn.getState(blockpos1).getBlock(); - if (block1 == Blocks.air || block1.getMaterial() == Material.leaves) + if (block1 == Blocks.air || block1.getMaterial() == Material.LEAVES) { this.func_181642_b(worldIn, blockpos1); k1 = j2; @@ -211,7 +211,7 @@ public class WorldGenSavanna extends WorldGenTree { Block block = worldIn.getState(p_175924_2_).getBlock(); - if (block == Blocks.air || block.getMaterial() == Material.leaves) + if (block == Blocks.air || block.getMaterial() == Material.LEAVES) { this.setBlockAndNotifyAdequately(worldIn, p_175924_2_, field_181644_b.withProperty(BlockLeaves.TYPE, worldIn.getLeavesGen(p_175924_2_))); } diff --git a/server/src/server/worldgen/tree/WorldGenSwamp.java b/server/src/server/worldgen/tree/WorldGenSwamp.java index 9773b8d..276ed3c 100755 --- a/server/src/server/worldgen/tree/WorldGenSwamp.java +++ b/server/src/server/worldgen/tree/WorldGenSwamp.java @@ -1,10 +1,10 @@ package server.worldgen.tree; import common.block.Block; +import common.block.Material; import common.block.foliage.BlockLeaves; import common.block.foliage.BlockVine; import common.init.Blocks; -import common.material.Material; import common.properties.PropertyBool; import common.rng.Random; import common.util.BlockPos; @@ -28,7 +28,7 @@ public class WorldGenSwamp extends WorldGenTree { int i; - for (i = rand.zrange(4) + 5; worldIn.getState(position.down()).getBlock().getMaterial() == Material.water; position = position.down()) + for (i = rand.zrange(4) + 5; worldIn.getState(position.down()).getBlock().getMaterial() == Material.WATER; position = position.down()) { ; } @@ -61,7 +61,7 @@ public class WorldGenSwamp extends WorldGenTree { Block block = worldIn.getState(blockpos$mutableblockpos.set(l, j, i1)).getBlock(); - if (block != Blocks.air && block.getMaterial() != Material.leaves) + if (block != Blocks.air && block.getMaterial() != Material.LEAVES) { if (block != Blocks.water && block != Blocks.flowing_water) { @@ -123,7 +123,7 @@ public class WorldGenSwamp extends WorldGenTree { Block block2 = worldIn.getState(position.up(i2)).getBlock(); - if (block2 == Blocks.air || block2.getMaterial() == Material.leaves || block2 == Blocks.flowing_water || block2 == Blocks.water) + if (block2 == Blocks.air || block2.getMaterial() == Material.LEAVES || block2 == Blocks.flowing_water || block2 == Blocks.water) { this.setBlockAndNotifyAdequately(worldIn, position.up(i2), field_181648_a); } @@ -141,7 +141,7 @@ public class WorldGenSwamp extends WorldGenTree { blockpos$mutableblockpos1.set(i4, j2, j4); - if (worldIn.getState(blockpos$mutableblockpos1).getBlock().getMaterial() == Material.leaves) + if (worldIn.getState(blockpos$mutableblockpos1).getBlock().getMaterial() == Material.LEAVES) { BlockPos blockpos3 = blockpos$mutableblockpos1.west(); BlockPos blockpos4 = blockpos$mutableblockpos1.east(); diff --git a/server/src/server/worldgen/tree/WorldGenTaiga1.java b/server/src/server/worldgen/tree/WorldGenTaiga1.java index 8774152..2ae3859 100755 --- a/server/src/server/worldgen/tree/WorldGenTaiga1.java +++ b/server/src/server/worldgen/tree/WorldGenTaiga1.java @@ -1,9 +1,9 @@ package server.worldgen.tree; import common.block.Block; +import common.block.Material; import common.block.foliage.BlockLeaves; import common.init.Blocks; -import common.material.Material; import common.rng.Random; import common.util.BlockPos; import common.world.State; @@ -115,7 +115,7 @@ public class WorldGenTaiga1 extends WorldGenTree { Block block1 = worldIn.getState(position.up(i3)).getBlock(); - if (block1 == Blocks.air || block1.getMaterial() == Material.leaves) + if (block1 == Blocks.air || block1.getMaterial() == Material.LEAVES) { this.setBlockAndNotifyAdequately(worldIn, position.up(i3), field_181636_a); } diff --git a/server/src/server/worldgen/tree/WorldGenTaiga2.java b/server/src/server/worldgen/tree/WorldGenTaiga2.java index a38208f..ba017a3 100755 --- a/server/src/server/worldgen/tree/WorldGenTaiga2.java +++ b/server/src/server/worldgen/tree/WorldGenTaiga2.java @@ -1,9 +1,9 @@ package server.worldgen.tree; import common.block.Block; +import common.block.Material; import common.block.foliage.BlockLeaves; import common.init.Blocks; -import common.material.Material; import common.rng.Random; import common.util.BlockPos; import common.world.State; @@ -55,7 +55,7 @@ public class WorldGenTaiga2 extends WorldGenTree { Block block = worldIn.getState(blockpos$mutableblockpos.set(k1, i1, l1)).getBlock(); - if (block != Blocks.air && block.getMaterial() != Material.leaves) + if (block != Blocks.air && block.getMaterial() != Material.LEAVES) { flag = false; } @@ -130,7 +130,7 @@ public class WorldGenTaiga2 extends WorldGenTree { Block block2 = worldIn.getState(position.up(k4)).getBlock(); - if (block2 == Blocks.air || block2.getMaterial() == Material.leaves) + if (block2 == Blocks.air || block2.getMaterial() == Material.LEAVES) { this.setBlockAndNotifyAdequately(worldIn, position.up(k4), field_181645_a); } diff --git a/server/src/server/worldgen/tree/WorldGenTree.java b/server/src/server/worldgen/tree/WorldGenTree.java index e444636..412f0e6 100755 --- a/server/src/server/worldgen/tree/WorldGenTree.java +++ b/server/src/server/worldgen/tree/WorldGenTree.java @@ -1,10 +1,10 @@ package server.worldgen.tree; import common.block.Block; +import common.block.Material; import common.block.foliage.BlockLog; import common.block.foliage.BlockSapling; import common.init.Blocks; -import common.material.Material; import common.rng.Random; import common.util.BlockPos; import server.world.WorldServer; @@ -19,7 +19,7 @@ public abstract class WorldGenTree extends FeatureGenerator protected boolean canBeReplaced(Block block) { - return block == Blocks.air || block.getMaterial() == Material.leaves || block == Blocks.grass || block == Blocks.dirt || block instanceof BlockLog || block instanceof BlockSapling || block == Blocks.vine; + return block == Blocks.air || block.getMaterial() == Material.LEAVES || block == Blocks.grass || block == Blocks.dirt || block instanceof BlockLog || block instanceof BlockSapling || block == Blocks.vine; } public void prepare() From d41ad4db012000463c13b3d302307def829c985e Mon Sep 17 00:00:00 2001 From: Sen Date: Sun, 25 May 2025 15:04:14 +0200 Subject: [PATCH 071/200] change fire type behaviour --- .../src/common/block/natural/BlockFire.java | 26 +++++++++---------- .../common/block/natural/BlockSoulFire.java | 18 +++++++++++++ common/src/common/init/BlockRegistry.java | 3 ++- 3 files changed, 33 insertions(+), 14 deletions(-) create mode 100644 common/src/common/block/natural/BlockSoulFire.java diff --git a/common/src/common/block/natural/BlockFire.java b/common/src/common/block/natural/BlockFire.java index fe048ea..cce8a47 100755 --- a/common/src/common/block/natural/BlockFire.java +++ b/common/src/common/block/natural/BlockFire.java @@ -125,7 +125,7 @@ public class BlockFire extends Block // flag = true; // } - if (!flag && worldIn.isRaining() && this.canDie(worldIn, pos)) + if (!flag && this.canDie(worldIn, pos)) { worldIn.setBlockToAir(pos); } @@ -205,7 +205,7 @@ public class BlockFire extends Block l1 /= 2; } - if (l1 > 0 && rand.zrange(j1) <= l1 && (!worldIn.isRaining() || !this.canDie(worldIn, blockpos))) + if (l1 > 0 && rand.zrange(j1) <= l1 && !this.canDie(worldIn, blockpos)) { int i2 = i + rand.zrange(5) / 4; @@ -225,9 +225,9 @@ public class BlockFire extends Block } } - protected boolean canDie(World worldIn, BlockPos pos) + protected boolean canDie(World world, BlockPos pos) { - return worldIn.isRainingAt(pos, true) || worldIn.isRainingAt(pos.west(), true) || worldIn.isRainingAt(pos.east(), true) || worldIn.isRainingAt(pos.north(), true) || worldIn.isRainingAt(pos.south(), true); + return world.isRaining() && (world.isRainingAt(pos, true) || world.isRainingAt(pos.west(), true) || world.isRainingAt(pos.east(), true) || world.isRainingAt(pos.north(), true) || world.isRainingAt(pos.south(), true)); } public boolean requiresUpdates() @@ -235,31 +235,31 @@ public class BlockFire extends Block return false; } - private void catchOnFire(World worldIn, BlockPos pos, int chance, Random random, int age) + protected void catchOnFire(World world, BlockPos pos, int chance, Random rand, int age) { - int i = FlammabilityRegistry.getFlammability(worldIn.getState(pos).getBlock()); + int i = FlammabilityRegistry.getFlammability(world.getState(pos).getBlock()); - if (random.zrange(chance) < i) + if (rand.zrange(chance) < i) { - State iblockstate = worldIn.getState(pos); + State iblockstate = world.getState(pos); - if (random.zrange(age + 10) < 5 && !worldIn.isRainingAt(pos, true)) + if (rand.zrange(age + 10) < 5 && !world.isRainingAt(pos, true)) { - int j = age + random.zrange(5) / 4; + int j = age + rand.zrange(5) / 4; if (j > 15) { j = 15; } - worldIn.setState(pos, this.getState().withProperty(AGE, Integer.valueOf(j)), 3); + world.setState(pos, this.getState().withProperty(AGE, Integer.valueOf(j)), 3); } else { - worldIn.setBlockToAir(pos); + world.setBlockToAir(pos); } - iblockstate.getBlock().onDestroyedByFire(worldIn, pos, iblockstate); + iblockstate.getBlock().onDestroyedByFire(world, pos, iblockstate); // if (iblockstate.getBlock() == Blocks.tnt) // { // Blocks.tnt.onBlockDestroyedByPlayer(worldIn, pos, iblockstate.withProperty(BlockTNT.EXPLODE, Boolean.valueOf(true))); diff --git a/common/src/common/block/natural/BlockSoulFire.java b/common/src/common/block/natural/BlockSoulFire.java new file mode 100644 index 0000000..9cacaeb --- /dev/null +++ b/common/src/common/block/natural/BlockSoulFire.java @@ -0,0 +1,18 @@ +package common.block.natural; + +import common.rng.Random; +import common.util.BlockPos; +import common.world.World; + +public class BlockSoulFire extends BlockTintedFire { + public BlockSoulFire() { + super(0x4010ff); + } + + protected void catchOnFire(World world, BlockPos pos, int chance, Random rand, int age) { + } + + protected boolean canDie(World world, BlockPos pos) { + return super.canDie(world, pos) || world.rand.chance(20); + } +} diff --git a/common/src/common/init/BlockRegistry.java b/common/src/common/init/BlockRegistry.java index 509cb19..357907b 100755 --- a/common/src/common/init/BlockRegistry.java +++ b/common/src/common/init/BlockRegistry.java @@ -77,6 +77,7 @@ import common.block.natural.BlockSandStone; import common.block.natural.BlockSlime; import common.block.natural.BlockSnow; import common.block.natural.BlockSnowBlock; +import common.block.natural.BlockSoulFire; import common.block.natural.BlockSoulSand; import common.block.natural.BlockStone; import common.block.natural.BlockTintedFire; @@ -428,7 +429,7 @@ public abstract class BlockRegistry { } registerBlock(252, "soul_fire", - (new BlockTintedFire(0x4010ff)).setHardness(0.0F).setLightLevel(1.0F).setStepSound(SoundType.CLOTH).setDisplay("Feuer der Seelen")); + (new BlockSoulFire()).setHardness(0.0F).setLightLevel(1.0F).setStepSound(SoundType.CLOTH).setDisplay("Feuer der Seelen")); registerBlock(253, "black_fire", (new BlockTintedFire(0x202020)).setHardness(0.0F).setLightLevel(1.0F).setStepSound(SoundType.CLOTH).setDisplay("Dunkles Feuer")); registerBlock(254, "web", (new BlockWeb()).setLightOpacity(1).setHardness(4.0F).setDisplay("Spinnennetz")); From 2cf7f0036d507d46725bed3a4fee365ce2b05cf7 Mon Sep 17 00:00:00 2001 From: Sen Date: Sun, 25 May 2025 15:25:38 +0200 Subject: [PATCH 072/200] cleanup player controller comments --- client/src/client/util/PlayerController.java | 280 ++----------------- 1 file changed, 21 insertions(+), 259 deletions(-) diff --git a/client/src/client/util/PlayerController.java b/client/src/client/util/PlayerController.java index 24e8a14..a489f4a 100755 --- a/client/src/client/util/PlayerController.java +++ b/client/src/client/util/PlayerController.java @@ -43,77 +43,8 @@ public class PlayerController this.netClientHandler = netHandler; } -// public static void clickBlockCreative(Game gmIn, PlayerController playerController, BlockPos pos, Facing facing) -// { -// if (!gmIn.theWorld.extinguishFire(gmIn.thePlayer, pos, facing)) -// { -// playerController.onPlayerDestroyBlock(pos, facing); -// } -// } - -// public void setPlayerCapabilities() -// { -// this.gm.thePlayer.flying &= this.gm.thePlayer.hasEffect(Potion.flying) || this.gm.thePlayer.noclip; -// } - -// public boolean isNoclip() -// { -// return this.gm.thePlayer.capabilities.noClip; -// } - -// public void setNoclip(boolean noclip) -// { -// this.noclip = noclip; -// } - -// public void setCheat(boolean cheat) -// { -// this.cheat = cheat; -// this.setPlayerCapabilities(); -// } - - - -// public boolean shouldDrawHUD() -// { -// return !this.creative; -// } - - /** - * Called when a player completes the destruction of a block - */ public boolean onPlayerDestroyBlock(BlockPos pos, Facing side) { -// if (this.gamemode.isAdventure()) -// { -// if (this.gamemode == Gamemode.SPECTATOR) -// { -// return false; -// } - -// if (!this.gm.thePlayer.isAllowEdit()) -// { -// Block block = this.gm.theWorld.getBlockState(pos).getBlock(); -// ItemStack itemstack = this.gm.thePlayer.getCurrentEquippedItem(); -// -// if (itemstack == null) -// { -// return false; -// } -// -// if (!itemstack.canDestroy(block)) -// { -// return false; -// } -// } -// } - -// if (this.gm.thePlayer.getHeldItem() != null && !this.gm.thePlayer.getHeldItem().getItem().canBreakBlocks()) -// { -// return false; -// } -// else -// { World world = this.gm.world; State iblockstate = world.getState(pos); Block block1 = iblockstate.getBlock(); @@ -134,8 +65,6 @@ public class PlayerController this.currentBlock = new BlockPos(this.currentBlock.getX(), -1, this.currentBlock.getZ()); -// if (!this.creative) -// { ItemStack itemstack1 = this.gm.player.getCurrentEquippedItem(); if (itemstack1 != null) @@ -147,42 +76,13 @@ public class PlayerController this.gm.player.destroyCurrentEquippedItem(); } } -// } return flag; } -// } } - /** - * Called when the player is hitting a block with an item. - */ public boolean clickBlock(BlockPos loc, Facing face) { -// if (this.gamemode.isAdventure()) -// { -// if (this.gamemode == Gamemode.SPECTATOR) -// { -// return false; -// } - -// if (!this.gm.thePlayer.isAllowEdit()) -// { -// Block block = this.gm.theWorld.getBlockState(loc).getBlock(); -// ItemStack itemstack = this.gm.thePlayer.getCurrentEquippedItem(); -// -// if (itemstack == null) -// { -// return false; -// } -// -// if (!itemstack.canDestroy(block)) -// { -// return false; -// } -// } -// } - if (!World.isValidXZ(loc)) { return false; @@ -195,13 +95,6 @@ public class PlayerController this.netClientHandler.addToSendQueue(new CPacketBreak(CPacketBreak.Action.START_DESTROY_BLOCK, loc, face)); return true; } -// if (this.creative) -// { -// this.netClientHandler.addToSendQueue(new CPacketBreak(CPacketBreak.Action.START_DESTROY_BLOCK, loc, face)); -// clickBlockCreative(this.gm, this, loc, face); -// this.blockHitDelay = 5; -// } -// else if (!this.isHittingBlock || !this.isHittingPosition(loc)) { if (this.isHittingBlock) @@ -221,8 +114,7 @@ public class PlayerController if (flag && block1.getPlayerRelativeBlockHardness(this.gm.player, this.gm.player.worldObj, loc) >= 1.0F) { this.onPlayerDestroyBlock(loc, face); -// if(this.cheat && block1.getPlayerRelativeBlockHardness(this.gm.thePlayer, this.gm.thePlayer.worldObj, loc) < 1.0F) - this.blockHitDelay = 3; + this.blockHitDelay = 3; } else { @@ -239,9 +131,6 @@ public class PlayerController } } - /** - * Resets current block damage and isHittingBlock - */ public void resetBlockRemoving() { if (this.isHittingBlock) @@ -269,13 +158,6 @@ public class PlayerController --this.blockHitDelay; return true; } -// else if (this.creative && World.isValidXZ(posBlock)) -// { -// this.blockHitDelay = 5; -// this.netClientHandler.addToSendQueue(new CPacketBreak(CPacketBreak.Action.START_DESTROY_BLOCK, posBlock, directionFacing)); -// clickBlockCreative(this.gm, this, posBlock, directionFacing); -// return true; -// } else if (this.isHittingPosition(posBlock)) { Block block = this.gm.world.getState(posBlock).getBlock(); @@ -316,14 +198,6 @@ public class PlayerController } } -// /** -// * player reach distance = 4F -// */ -// public float getBlockReachDistance() -// { -// return ; -// } - public void updateController() { this.syncCurrentPlayItem(); @@ -351,9 +225,6 @@ public class PlayerController return pos.equals(this.currentBlock) && flag; } - /** - * Syncs the current player item with the server - */ private void syncCurrentPlayItem() { int i = this.gm.player.inventory.currentItem; @@ -380,11 +251,9 @@ public class PlayerController else { if(heldStack == null || !heldStack.getItem().onAction(heldStack, player, worldIn, ItemControl.SECONDARY, hitPos)) { -// if (this.gamemode != Gamemode.SPECTATOR) -// { State iblockstate = worldIn.getState(hitPos); - if ((!player.isSneaking() || player.getHeldItem() == null) // && (player.getHeldItem() == null || !player.getHeldItem().getItem().ignoresBlocks()) + if ((!player.isSneaking() || player.getHeldItem() == null) && iblockstate.getBlock().onBlockActivated(worldIn, hitPos, iblockstate, player, side, f, f1, f2)) { flag = true; @@ -399,7 +268,6 @@ public class PlayerController return false; } } -// } } else { heldStack.getItem().onItemUse(heldStack, player, worldIn, hitPos, side, f, f1, f2); @@ -408,21 +276,12 @@ public class PlayerController this.netClientHandler.addToSendQueue(new CPacketPlace(hitPos, side.getIndex(), player.inventory.getCurrentItem(), f, f1, f2)); - if (!flag) // && this.gamemode != Gamemode.SPECTATOR) + if (!flag) { if (heldStack == null) { return false; } -// else if (this.creative) -// { -// int i = heldStack.getMetadata(); -// int j = heldStack.stackSize; -// boolean flag1 = heldStack.onItemUse(player, worldIn, hitPos, side, f, f1, f2); -// heldStack.setItemDamage(i); -// heldStack.stackSize = j; -// return flag1; -// } else { return heldStack.onItemUse(player, worldIn, hitPos, side, f, f1, f2); @@ -435,38 +294,28 @@ public class PlayerController } } - /** - * Notifies the server of things like consuming food, etc... - */ public boolean sendUseItem(EntityNPC playerIn, World worldIn, ItemStack itemStackIn) { -// if (this.gamemode == Gamemode.SPECTATOR) -// { -// return false; -// } -// else -// { - this.syncCurrentPlayItem(); - this.netClientHandler.addToSendQueue(new CPacketPlace(playerIn.inventory.getCurrentItem())); - int i = itemStackIn.stackSize; - ItemStack itemstack = itemStackIn.useItemRightClick(worldIn, playerIn); + this.syncCurrentPlayItem(); + this.netClientHandler.addToSendQueue(new CPacketPlace(playerIn.inventory.getCurrentItem())); + int i = itemStackIn.stackSize; + ItemStack itemstack = itemStackIn.useItemRightClick(worldIn, playerIn); - if (itemstack != itemStackIn || itemstack != null && itemstack.stackSize != i) + if (itemstack != itemStackIn || itemstack != null && itemstack.stackSize != i) + { + playerIn.inventory.mainInventory[playerIn.inventory.currentItem] = itemstack; + + if (itemstack.stackSize == 0) { - playerIn.inventory.mainInventory[playerIn.inventory.currentItem] = itemstack; - - if (itemstack.stackSize == 0) - { - playerIn.inventory.mainInventory[playerIn.inventory.currentItem] = null; - } - - return true; + playerIn.inventory.mainInventory[playerIn.inventory.currentItem] = null; } - else - { - return false; - } -// } + + return true; + } + else + { + return false; + } } public EntityNPC createPlayerEntity(WorldClient worldIn, int type) @@ -476,48 +325,20 @@ public class PlayerController return player; } - /** - * Attacks an entity - */ public void attackEntity(EntityNPC playerIn, Entity targetEntity) { this.syncCurrentPlayItem(); this.netClientHandler.addToSendQueue(new CPacketAction(CPacketAction.Action.ATTACK, targetEntity.getId())); - -// if (this.gamemode != Gamemode.SPECTATOR) -// { playerIn.attackTargetEntityWithCurrentItem(targetEntity); -// } } - /** - * Send packet to server - player is interacting with another entity (left click) - */ public boolean interactWithEntitySendPacket(EntityNPC playerIn, Entity targetEntity) { this.syncCurrentPlayItem(); this.netClientHandler.addToSendQueue(new CPacketAction(CPacketAction.Action.INTERACT, targetEntity.getId())); - return /* this.gamemode != Gamemode.SPECTATOR && */ playerIn.interactWith(targetEntity); + return playerIn.interactWith(targetEntity); } -// /** -// * Return true when the player rightclick on an entity -// * -// * @param player The player's instance -// * @param entityIn The entity clicked -// * @param movingObject The object clicked -// */ -// public boolean isPlayerRightClickingOnEntity(EntityNPC player, Entity entityIn, MovingObjectPosition movingObject) -// { -// this.syncCurrentPlayItem(); -// Vec3 vec3 = new Vec3(movingObject.hitVec.xCoord - entityIn.posX, movingObject.hitVec.yCoord - entityIn.posY, movingObject.hitVec.zCoord - entityIn.posZ); -// this.netClientHandler.addToSendQueue(new C02PacketUseEntity(entityIn, vec3)); -// return this.gamemode != Gamemode.SPECTATOR && entityIn.interactAt(player, vec3); -// } - - /** - * Handles slot clicks sends a packet to the server. - */ public ItemStack windowClick(int windowId, int slotId, int mouseButtonClicked, int mode, EntityNPC playerIn) { short short1 = playerIn.openContainer.getNextTransactionID(playerIn.inventory); @@ -526,36 +347,11 @@ public class PlayerController return itemstack; } - /** - * GuiEnchantment uses this during multiplayer to tell PlayerControllerMP to send a packet indicating the - * enchantment action the player has taken. - * - * @param windowID The ID of the current window - * @param button The button id (enchantment selected) - */ public void sendEnchantPacket(int windowID, int button) { this.netClientHandler.addToSendQueue(new CPacketAction(CPacketAction.Action.ENCHANT_ITEM, windowID | (button << 8))); } -// /** -// * Used in PlayerControllerMP to update the server with an ItemStack in a slot. -// */ -// public void sendCheatPacket(ItemStack itemStackIn, boolean full) -// { -// } - -// /** -// * Sends a Packet107 to the server to drop the item on the ground -// */ -// public void sendPacketDropItem(ItemStack itemStackIn) -// { -// if (this.creative && itemStackIn != null) -// { -// this.netClientHandler.addToSendQueue(new CPacketCreative(-1, itemStackIn)); -// } -// } - public void onStoppedUsingItem(EntityNPC playerIn) { this.syncCurrentPlayItem(); @@ -563,40 +359,6 @@ public class PlayerController playerIn.stopUsingItem(); } - - -// /** -// * Checks if the player is not creative, used for checking if it should break a block instantly -// */ -// public boolean isNotCreative() -// { -// return !this.creative; -// } - -// /** -// * returns true if player is in creative mode -// */ -// public boolean isCreative() -// { -// return this.creative; -// } - -// /** -// * Checks if the player is riding a horse, used to chose the GUI to open -// */ -// public boolean isRidingHorse() -// { -// return ; -// } - -// public Gamemode getGamemode() -// { -// return this.gamemode; -// } - - /** - * Return isHittingBlock - */ public boolean getIsHittingBlock() { return this.isHittingBlock; From 4a84f9e096774252995f68c8e23bd5b49bde76c3 Mon Sep 17 00:00:00 2001 From: Sen Date: Sun, 25 May 2025 15:26:14 +0200 Subject: [PATCH 073/200] format PlayerController --- client/src/client/util/PlayerController.java | 536 +++++++++---------- 1 file changed, 243 insertions(+), 293 deletions(-) diff --git a/client/src/client/util/PlayerController.java b/client/src/client/util/PlayerController.java index a489f4a..215c085 100755 --- a/client/src/client/util/PlayerController.java +++ b/client/src/client/util/PlayerController.java @@ -23,344 +23,294 @@ import common.util.Vec3; import common.world.State; import common.world.World; -public class PlayerController -{ - private final Client gm; - private final ClientPlayer netClientHandler; - private BlockPos currentBlock = new BlockPos(-1, -1, -1); - private ItemStack currentItemHittingBlock; - private float curBlockDamageMP; - private float stepSoundTickCounter; - private int blockHitDelay; - private boolean isHittingBlock; - private boolean noclip; - private int currentPlayerItem; - private boolean interacting; +public class PlayerController { + private final Client gm; + private final ClientPlayer netClientHandler; + private BlockPos currentBlock = new BlockPos(-1, -1, -1); + private ItemStack currentItemHittingBlock; + private float curBlockDamageMP; + private float stepSoundTickCounter; + private int blockHitDelay; + private boolean isHittingBlock; + private boolean noclip; + private int currentPlayerItem; + private boolean interacting; - public PlayerController(Client gmIn, ClientPlayer netHandler) - { - this.gm = gmIn; - this.netClientHandler = netHandler; - } + public PlayerController(Client gmIn, ClientPlayer netHandler) { + this.gm = gmIn; + this.netClientHandler = netHandler; + } - public boolean onPlayerDestroyBlock(BlockPos pos, Facing side) - { - World world = this.gm.world; - State iblockstate = world.getState(pos); - Block block1 = iblockstate.getBlock(); + public boolean onPlayerDestroyBlock(BlockPos pos, Facing side) { + World world = this.gm.world; + State iblockstate = world.getState(pos); + Block block1 = iblockstate.getBlock(); - if (block1 == Blocks.air) - { - return false; - } - else - { - world.playAuxSFX(2001, pos, BlockRegistry.getStateId(iblockstate)); - boolean flag = world.setBlockToAir(pos); + if(block1 == Blocks.air) { + return false; + } + else { + world.playAuxSFX(2001, pos, BlockRegistry.getStateId(iblockstate)); + boolean flag = world.setBlockToAir(pos); - if (flag) - { - block1.onBlockDestroyedByPlayer(world, pos, iblockstate); - } + if(flag) { + block1.onBlockDestroyedByPlayer(world, pos, iblockstate); + } - this.currentBlock = new BlockPos(this.currentBlock.getX(), -1, this.currentBlock.getZ()); + this.currentBlock = new BlockPos(this.currentBlock.getX(), -1, this.currentBlock.getZ()); - ItemStack itemstack1 = this.gm.player.getCurrentEquippedItem(); + ItemStack itemstack1 = this.gm.player.getCurrentEquippedItem(); - if (itemstack1 != null) - { - itemstack1.onBlockDestroyed(world, block1, pos, this.gm.player); + if(itemstack1 != null) { + itemstack1.onBlockDestroyed(world, block1, pos, this.gm.player); - if (itemstack1.stackSize == 0) - { - this.gm.player.destroyCurrentEquippedItem(); - } - } + if(itemstack1.stackSize == 0) { + this.gm.player.destroyCurrentEquippedItem(); + } + } - return flag; - } - } + return flag; + } + } - public boolean clickBlock(BlockPos loc, Facing face) - { - if (!World.isValidXZ(loc)) - { - return false; - } - else - { - ItemStack stack = this.gm.player.getHeldItem(); - if(stack != null && stack.getItem().onAction(stack, this.gm.player, this.gm.world, ItemControl.PRIMARY, loc)) { - this.interacting = true; - this.netClientHandler.addToSendQueue(new CPacketBreak(CPacketBreak.Action.START_DESTROY_BLOCK, loc, face)); - return true; - } - if (!this.isHittingBlock || !this.isHittingPosition(loc)) - { - if (this.isHittingBlock) - { - this.netClientHandler.addToSendQueue(new CPacketBreak(CPacketBreak.Action.ABORT_DESTROY_BLOCK, this.currentBlock, face)); - } + public boolean clickBlock(BlockPos loc, Facing face) { + if(!World.isValidXZ(loc)) { + return false; + } + else { + ItemStack stack = this.gm.player.getHeldItem(); + if(stack != null && stack.getItem().onAction(stack, this.gm.player, this.gm.world, ItemControl.PRIMARY, loc)) { + this.interacting = true; + this.netClientHandler.addToSendQueue(new CPacketBreak(CPacketBreak.Action.START_DESTROY_BLOCK, loc, face)); + return true; + } + if(!this.isHittingBlock || !this.isHittingPosition(loc)) { + if(this.isHittingBlock) { + this.netClientHandler.addToSendQueue(new CPacketBreak(CPacketBreak.Action.ABORT_DESTROY_BLOCK, this.currentBlock, face)); + } - this.netClientHandler.addToSendQueue(new CPacketBreak(CPacketBreak.Action.START_DESTROY_BLOCK, loc, face)); - Block block1 = this.gm.world.getState(loc).getBlock(); - boolean flag = block1 != Blocks.air; + this.netClientHandler.addToSendQueue(new CPacketBreak(CPacketBreak.Action.START_DESTROY_BLOCK, loc, face)); + Block block1 = this.gm.world.getState(loc).getBlock(); + boolean flag = block1 != Blocks.air; - if (flag && this.curBlockDamageMP == 0.0F) - { - block1.onBlockClicked(this.gm.world, loc, this.gm.player); - } + if(flag && this.curBlockDamageMP == 0.0F) { + block1.onBlockClicked(this.gm.world, loc, this.gm.player); + } - if (flag && block1.getPlayerRelativeBlockHardness(this.gm.player, this.gm.player.worldObj, loc) >= 1.0F) - { - this.onPlayerDestroyBlock(loc, face); - this.blockHitDelay = 3; - } - else - { - this.isHittingBlock = true; - this.currentBlock = loc; - this.currentItemHittingBlock = this.gm.player.getHeldItem(); - this.curBlockDamageMP = 0.0F; - this.stepSoundTickCounter = 0.0F; - this.gm.world.sendBlockBreakProgress(this.gm.player.getId(), this.currentBlock, (int)(this.curBlockDamageMP * 10.0F) - 1); - } - } + if(flag && block1.getPlayerRelativeBlockHardness(this.gm.player, this.gm.player.worldObj, loc) >= 1.0F) { + this.onPlayerDestroyBlock(loc, face); + this.blockHitDelay = 3; + } + else { + this.isHittingBlock = true; + this.currentBlock = loc; + this.currentItemHittingBlock = this.gm.player.getHeldItem(); + this.curBlockDamageMP = 0.0F; + this.stepSoundTickCounter = 0.0F; + this.gm.world.sendBlockBreakProgress(this.gm.player.getId(), this.currentBlock, (int)(this.curBlockDamageMP * 10.0F) - 1); + } + } - return true; - } - } + return true; + } + } - public void resetBlockRemoving() - { - if (this.isHittingBlock) - { - this.netClientHandler.addToSendQueue(new CPacketBreak(CPacketBreak.Action.ABORT_DESTROY_BLOCK, this.currentBlock, Facing.DOWN)); - this.isHittingBlock = false; - this.curBlockDamageMP = 0.0F; - this.gm.world.sendBlockBreakProgress(this.gm.player.getId(), this.currentBlock, -1); - } - } - - public void resetInteraction() - { - this.interacting = false; - } + public void resetBlockRemoving() { + if(this.isHittingBlock) { + this.netClientHandler.addToSendQueue(new CPacketBreak(CPacketBreak.Action.ABORT_DESTROY_BLOCK, this.currentBlock, Facing.DOWN)); + this.isHittingBlock = false; + this.curBlockDamageMP = 0.0F; + this.gm.world.sendBlockBreakProgress(this.gm.player.getId(), this.currentBlock, -1); + } + } - public boolean onPlayerDamageBlock(BlockPos posBlock, Facing directionFacing) - { - if(this.interacting) - return false; - this.syncCurrentPlayItem(); + public void resetInteraction() { + this.interacting = false; + } - if (this.blockHitDelay > 0) - { - --this.blockHitDelay; - return true; - } - else if (this.isHittingPosition(posBlock)) - { - Block block = this.gm.world.getState(posBlock).getBlock(); + public boolean onPlayerDamageBlock(BlockPos posBlock, Facing directionFacing) { + if(this.interacting) + return false; + this.syncCurrentPlayItem(); - if (block == Blocks.air) - { - this.isHittingBlock = false; - return false; - } - else - { - this.curBlockDamageMP += block.getPlayerRelativeBlockHardness(this.gm.player, this.gm.player.worldObj, posBlock); + if(this.blockHitDelay > 0) { + --this.blockHitDelay; + return true; + } + else if(this.isHittingPosition(posBlock)) { + Block block = this.gm.world.getState(posBlock).getBlock(); - if (this.stepSoundTickCounter % 4.0F == 0.0F && block.sound.getStepSound() != null) - { - this.gm.getSoundManager().playSound(new PositionedSound(block.sound.getStepSound(), 0.25F, /* block.sound.getFrequency() * 0.5F, */ (float)posBlock.getX() + 0.5F, (float)posBlock.getY() + 0.5F, (float)posBlock.getZ() + 0.5F)); - } + if(block == Blocks.air) { + this.isHittingBlock = false; + return false; + } + else { + this.curBlockDamageMP += block.getPlayerRelativeBlockHardness(this.gm.player, this.gm.player.worldObj, posBlock); - ++this.stepSoundTickCounter; + if(this.stepSoundTickCounter % 4.0F == 0.0F && block.sound.getStepSound() != null) { + this.gm.getSoundManager() + .playSound(new PositionedSound(block.sound.getStepSound(), 0.25F, + /* block.sound.getFrequency() * 0.5F, */ (float)posBlock.getX() + 0.5F, (float)posBlock.getY() + 0.5F, + (float)posBlock.getZ() + 0.5F)); + } - if (this.curBlockDamageMP >= 1.0F) - { - this.isHittingBlock = false; - this.netClientHandler.addToSendQueue(new CPacketBreak(CPacketBreak.Action.STOP_DESTROY_BLOCK, posBlock, directionFacing)); - this.onPlayerDestroyBlock(posBlock, directionFacing); - this.curBlockDamageMP = 0.0F; - this.stepSoundTickCounter = 0.0F; - this.blockHitDelay = 5; - } + ++this.stepSoundTickCounter; - this.gm.world.sendBlockBreakProgress(this.gm.player.getId(), this.currentBlock, (int)(this.curBlockDamageMP * 10.0F) - 1); - return true; - } - } - else - { - return this.clickBlock(posBlock, directionFacing); - } - } + if(this.curBlockDamageMP >= 1.0F) { + this.isHittingBlock = false; + this.netClientHandler.addToSendQueue(new CPacketBreak(CPacketBreak.Action.STOP_DESTROY_BLOCK, posBlock, directionFacing)); + this.onPlayerDestroyBlock(posBlock, directionFacing); + this.curBlockDamageMP = 0.0F; + this.stepSoundTickCounter = 0.0F; + this.blockHitDelay = 5; + } - public void updateController() - { - this.syncCurrentPlayItem(); + this.gm.world.sendBlockBreakProgress(this.gm.player.getId(), this.currentBlock, (int)(this.curBlockDamageMP * 10.0F) - 1); + return true; + } + } + else { + return this.clickBlock(posBlock, directionFacing); + } + } - if (this.netClientHandler.getNetworkManager().isChannelOpen()) - { - this.netClientHandler.getNetworkManager().processReceivedPackets(); - } - else - { - this.netClientHandler.getNetworkManager().checkDisconnected(); - } - } + public void updateController() { + this.syncCurrentPlayItem(); - private boolean isHittingPosition(BlockPos pos) - { - ItemStack itemstack = this.gm.player.getHeldItem(); - boolean flag = this.currentItemHittingBlock == null && itemstack == null; + if(this.netClientHandler.getNetworkManager().isChannelOpen()) { + this.netClientHandler.getNetworkManager().processReceivedPackets(); + } + else { + this.netClientHandler.getNetworkManager().checkDisconnected(); + } + } - if (this.currentItemHittingBlock != null && itemstack != null) - { - flag = itemstack.getItem() == this.currentItemHittingBlock.getItem() && ItemStack.areItemStackTagsEqual(itemstack, this.currentItemHittingBlock) && (itemstack.isItemStackDamageable() || itemstack.getMetadata() == this.currentItemHittingBlock.getMetadata()); - } + private boolean isHittingPosition(BlockPos pos) { + ItemStack itemstack = this.gm.player.getHeldItem(); + boolean flag = this.currentItemHittingBlock == null && itemstack == null; - return pos.equals(this.currentBlock) && flag; - } + if(this.currentItemHittingBlock != null && itemstack != null) { + flag = itemstack.getItem() == this.currentItemHittingBlock.getItem() + && ItemStack.areItemStackTagsEqual(itemstack, this.currentItemHittingBlock) + && (itemstack.isItemStackDamageable() || itemstack.getMetadata() == this.currentItemHittingBlock.getMetadata()); + } - private void syncCurrentPlayItem() - { - int i = this.gm.player.inventory.currentItem; + return pos.equals(this.currentBlock) && flag; + } - if (i != this.currentPlayerItem) - { - this.currentPlayerItem = i; - this.netClientHandler.addToSendQueue(new CPacketAction(CPacketAction.Action.SET_ITEMSLOT, this.currentPlayerItem)); - } - } + private void syncCurrentPlayItem() { + int i = this.gm.player.inventory.currentItem; - public boolean onPlayerRightClick(EntityNPC player, WorldClient worldIn, ItemStack heldStack, BlockPos hitPos, Facing side, Vec3 hitVec) - { - this.syncCurrentPlayItem(); - float f = (float)(hitVec.xCoord - (double)hitPos.getX()); - float f1 = (float)(hitVec.yCoord - (double)hitPos.getY()); - float f2 = (float)(hitVec.zCoord - (double)hitPos.getZ()); - boolean flag = false; + if(i != this.currentPlayerItem) { + this.currentPlayerItem = i; + this.netClientHandler.addToSendQueue(new CPacketAction(CPacketAction.Action.SET_ITEMSLOT, this.currentPlayerItem)); + } + } - if (!World.isValidXZ(hitPos)) - { - return false; - } - else - { - if(heldStack == null || !heldStack.getItem().onAction(heldStack, player, worldIn, ItemControl.SECONDARY, hitPos)) { - State iblockstate = worldIn.getState(hitPos); + public boolean onPlayerRightClick(EntityNPC player, WorldClient worldIn, ItemStack heldStack, BlockPos hitPos, Facing side, Vec3 hitVec) { + this.syncCurrentPlayItem(); + float f = (float)(hitVec.xCoord - (double)hitPos.getX()); + float f1 = (float)(hitVec.yCoord - (double)hitPos.getY()); + float f2 = (float)(hitVec.zCoord - (double)hitPos.getZ()); + boolean flag = false; - if ((!player.isSneaking() || player.getHeldItem() == null) - && iblockstate.getBlock().onBlockActivated(worldIn, hitPos, iblockstate, player, side, f, f1, f2)) - { - flag = true; - } + if(!World.isValidXZ(hitPos)) { + return false; + } + else { + if(heldStack == null || !heldStack.getItem().onAction(heldStack, player, worldIn, ItemControl.SECONDARY, hitPos)) { + State iblockstate = worldIn.getState(hitPos); - if (!flag && heldStack != null && heldStack.getItem() instanceof ItemBlock) - { - ItemBlock itemblock = (ItemBlock)heldStack.getItem(); + if((!player.isSneaking() || player.getHeldItem() == null) + && iblockstate.getBlock().onBlockActivated(worldIn, hitPos, iblockstate, player, side, f, f1, f2)) { + flag = true; + } - if (!itemblock.canPlaceBlockOnSide(worldIn, hitPos, side, player, heldStack)) - { - return false; - } - } - } - else { - heldStack.getItem().onItemUse(heldStack, player, worldIn, hitPos, side, f, f1, f2); - flag = true; - } + if(!flag && heldStack != null && heldStack.getItem() instanceof ItemBlock) { + ItemBlock itemblock = (ItemBlock)heldStack.getItem(); - this.netClientHandler.addToSendQueue(new CPacketPlace(hitPos, side.getIndex(), player.inventory.getCurrentItem(), f, f1, f2)); + if(!itemblock.canPlaceBlockOnSide(worldIn, hitPos, side, player, heldStack)) { + return false; + } + } + } + else { + heldStack.getItem().onItemUse(heldStack, player, worldIn, hitPos, side, f, f1, f2); + flag = true; + } - if (!flag) - { - if (heldStack == null) - { - return false; - } - else - { - return heldStack.onItemUse(player, worldIn, hitPos, side, f, f1, f2); - } - } - else - { - return true; - } - } - } + this.netClientHandler.addToSendQueue(new CPacketPlace(hitPos, side.getIndex(), player.inventory.getCurrentItem(), f, f1, f2)); - public boolean sendUseItem(EntityNPC playerIn, World worldIn, ItemStack itemStackIn) - { - this.syncCurrentPlayItem(); - this.netClientHandler.addToSendQueue(new CPacketPlace(playerIn.inventory.getCurrentItem())); - int i = itemStackIn.stackSize; - ItemStack itemstack = itemStackIn.useItemRightClick(worldIn, playerIn); + if(!flag) { + if(heldStack == null) { + return false; + } + else { + return heldStack.onItemUse(player, worldIn, hitPos, side, f, f1, f2); + } + } + else { + return true; + } + } + } - if (itemstack != itemStackIn || itemstack != null && itemstack.stackSize != i) - { - playerIn.inventory.mainInventory[playerIn.inventory.currentItem] = itemstack; + public boolean sendUseItem(EntityNPC playerIn, World worldIn, ItemStack itemStackIn) { + this.syncCurrentPlayItem(); + this.netClientHandler.addToSendQueue(new CPacketPlace(playerIn.inventory.getCurrentItem())); + int i = itemStackIn.stackSize; + ItemStack itemstack = itemStackIn.useItemRightClick(worldIn, playerIn); - if (itemstack.stackSize == 0) - { - playerIn.inventory.mainInventory[playerIn.inventory.currentItem] = null; - } + if(itemstack != itemStackIn || itemstack != null && itemstack.stackSize != i) { + playerIn.inventory.mainInventory[playerIn.inventory.currentItem] = itemstack; - return true; - } - else - { - return false; - } - } + if(itemstack.stackSize == 0) { + playerIn.inventory.mainInventory[playerIn.inventory.currentItem] = null; + } - public EntityNPC createPlayerEntity(WorldClient worldIn, int type) - { - EntityNPC player = (EntityNPC)EntityRegistry.createEntityByID(type, worldIn); - player.setClientPlayer(this.netClientHandler); - return player; - } + return true; + } + else { + return false; + } + } - public void attackEntity(EntityNPC playerIn, Entity targetEntity) - { - this.syncCurrentPlayItem(); - this.netClientHandler.addToSendQueue(new CPacketAction(CPacketAction.Action.ATTACK, targetEntity.getId())); - playerIn.attackTargetEntityWithCurrentItem(targetEntity); - } + public EntityNPC createPlayerEntity(WorldClient worldIn, int type) { + EntityNPC player = (EntityNPC)EntityRegistry.createEntityByID(type, worldIn); + player.setClientPlayer(this.netClientHandler); + return player; + } - public boolean interactWithEntitySendPacket(EntityNPC playerIn, Entity targetEntity) - { - this.syncCurrentPlayItem(); - this.netClientHandler.addToSendQueue(new CPacketAction(CPacketAction.Action.INTERACT, targetEntity.getId())); - return playerIn.interactWith(targetEntity); - } + public void attackEntity(EntityNPC playerIn, Entity targetEntity) { + this.syncCurrentPlayItem(); + this.netClientHandler.addToSendQueue(new CPacketAction(CPacketAction.Action.ATTACK, targetEntity.getId())); + playerIn.attackTargetEntityWithCurrentItem(targetEntity); + } - public ItemStack windowClick(int windowId, int slotId, int mouseButtonClicked, int mode, EntityNPC playerIn) - { - short short1 = playerIn.openContainer.getNextTransactionID(playerIn.inventory); - ItemStack itemstack = playerIn.openContainer.slotClick(slotId, mouseButtonClicked, mode, playerIn); - this.netClientHandler.addToSendQueue(new CPacketClick(windowId, slotId, mouseButtonClicked, mode, itemstack, short1)); - return itemstack; - } + public boolean interactWithEntitySendPacket(EntityNPC playerIn, Entity targetEntity) { + this.syncCurrentPlayItem(); + this.netClientHandler.addToSendQueue(new CPacketAction(CPacketAction.Action.INTERACT, targetEntity.getId())); + return playerIn.interactWith(targetEntity); + } - public void sendEnchantPacket(int windowID, int button) - { - this.netClientHandler.addToSendQueue(new CPacketAction(CPacketAction.Action.ENCHANT_ITEM, windowID | (button << 8))); - } + public ItemStack windowClick(int windowId, int slotId, int mouseButtonClicked, int mode, EntityNPC playerIn) { + short short1 = playerIn.openContainer.getNextTransactionID(playerIn.inventory); + ItemStack itemstack = playerIn.openContainer.slotClick(slotId, mouseButtonClicked, mode, playerIn); + this.netClientHandler.addToSendQueue(new CPacketClick(windowId, slotId, mouseButtonClicked, mode, itemstack, short1)); + return itemstack; + } - public void onStoppedUsingItem(EntityNPC playerIn) - { - this.syncCurrentPlayItem(); - this.netClientHandler.addToSendQueue(new CPacketBreak(CPacketBreak.Action.RELEASE_USE_ITEM, BlockPos.ORIGIN, Facing.DOWN)); - playerIn.stopUsingItem(); - } + public void sendEnchantPacket(int windowID, int button) { + this.netClientHandler.addToSendQueue(new CPacketAction(CPacketAction.Action.ENCHANT_ITEM, windowID | (button << 8))); + } - public boolean getIsHittingBlock() - { - return this.isHittingBlock; - } + public void onStoppedUsingItem(EntityNPC playerIn) { + this.syncCurrentPlayItem(); + this.netClientHandler.addToSendQueue(new CPacketBreak(CPacketBreak.Action.RELEASE_USE_ITEM, BlockPos.ORIGIN, Facing.DOWN)); + playerIn.stopUsingItem(); + } + + public boolean getIsHittingBlock() { + return this.isHittingBlock; + } } From 64b256c713e823d3322e705518467f5ad76493c0 Mon Sep 17 00:00:00 2001 From: Sen Date: Sun, 25 May 2025 15:27:36 +0200 Subject: [PATCH 074/200] cleanup player controller comment --- client/src/client/util/PlayerController.java | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/client/src/client/util/PlayerController.java b/client/src/client/util/PlayerController.java index 215c085..e67df49 100755 --- a/client/src/client/util/PlayerController.java +++ b/client/src/client/util/PlayerController.java @@ -148,10 +148,8 @@ public class PlayerController { this.curBlockDamageMP += block.getPlayerRelativeBlockHardness(this.gm.player, this.gm.player.worldObj, posBlock); if(this.stepSoundTickCounter % 4.0F == 0.0F && block.sound.getStepSound() != null) { - this.gm.getSoundManager() - .playSound(new PositionedSound(block.sound.getStepSound(), 0.25F, - /* block.sound.getFrequency() * 0.5F, */ (float)posBlock.getX() + 0.5F, (float)posBlock.getY() + 0.5F, - (float)posBlock.getZ() + 0.5F)); + this.gm.getSoundManager().playSound(new PositionedSound(block.sound.getStepSound(), 0.25F, + (float)posBlock.getX() + 0.5F, (float)posBlock.getY() + 0.5F, (float)posBlock.getZ() + 0.5F)); } ++this.stepSoundTickCounter; From 2bc84f0c66744ad4114b6e8be771c1da2c4292e9 Mon Sep 17 00:00:00 2001 From: Sen Date: Sun, 25 May 2025 15:38:12 +0200 Subject: [PATCH 075/200] cleanup player controller var names --- client/src/client/util/PlayerController.java | 248 +++++++++---------- 1 file changed, 124 insertions(+), 124 deletions(-) diff --git a/client/src/client/util/PlayerController.java b/client/src/client/util/PlayerController.java index e67df49..c95179c 100755 --- a/client/src/client/util/PlayerController.java +++ b/client/src/client/util/PlayerController.java @@ -25,46 +25,46 @@ import common.world.World; public class PlayerController { private final Client gm; - private final ClientPlayer netClientHandler; - private BlockPos currentBlock = new BlockPos(-1, -1, -1); - private ItemStack currentItemHittingBlock; - private float curBlockDamageMP; - private float stepSoundTickCounter; - private int blockHitDelay; - private boolean isHittingBlock; - private boolean noclip; - private int currentPlayerItem; + private final ClientPlayer handler; + + private BlockPos position = new BlockPos(-1, -World.MAX_SIZE_Y - 1, -1); + private ItemStack stack; + private float damage; + private float stepCounter; + private int delay; + private boolean hitting; + private int lastSelected; private boolean interacting; - public PlayerController(Client gmIn, ClientPlayer netHandler) { - this.gm = gmIn; - this.netClientHandler = netHandler; + public PlayerController(Client gm, ClientPlayer handler) { + this.gm = gm; + this.handler = handler; } public boolean onPlayerDestroyBlock(BlockPos pos, Facing side) { World world = this.gm.world; - State iblockstate = world.getState(pos); - Block block1 = iblockstate.getBlock(); + State state = world.getState(pos); + Block block = state.getBlock(); - if(block1 == Blocks.air) { + if(block == Blocks.air) { return false; } else { - world.playAuxSFX(2001, pos, BlockRegistry.getStateId(iblockstate)); + world.playAuxSFX(2001, pos, BlockRegistry.getStateId(state)); boolean flag = world.setBlockToAir(pos); if(flag) { - block1.onBlockDestroyedByPlayer(world, pos, iblockstate); + block.onBlockDestroyedByPlayer(world, pos, state); } - this.currentBlock = new BlockPos(this.currentBlock.getX(), -1, this.currentBlock.getZ()); + this.position = new BlockPos(this.position.getX(), -1, this.position.getZ()); - ItemStack itemstack1 = this.gm.player.getCurrentEquippedItem(); + ItemStack stack = this.gm.player.getCurrentEquippedItem(); - if(itemstack1 != null) { - itemstack1.onBlockDestroyed(world, block1, pos, this.gm.player); + if(stack != null) { + stack.onBlockDestroyed(world, block, pos, this.gm.player); - if(itemstack1.stackSize == 0) { + if(stack.stackSize == 0) { this.gm.player.destroyCurrentEquippedItem(); } } @@ -73,41 +73,41 @@ public class PlayerController { } } - public boolean clickBlock(BlockPos loc, Facing face) { - if(!World.isValidXZ(loc)) { + public boolean clickBlock(BlockPos pos, Facing face) { + if(!World.isValidXZ(pos)) { return false; } else { ItemStack stack = this.gm.player.getHeldItem(); - if(stack != null && stack.getItem().onAction(stack, this.gm.player, this.gm.world, ItemControl.PRIMARY, loc)) { + if(stack != null && stack.getItem().onAction(stack, this.gm.player, this.gm.world, ItemControl.PRIMARY, pos)) { this.interacting = true; - this.netClientHandler.addToSendQueue(new CPacketBreak(CPacketBreak.Action.START_DESTROY_BLOCK, loc, face)); + this.handler.addToSendQueue(new CPacketBreak(CPacketBreak.Action.START_DESTROY_BLOCK, pos, face)); return true; } - if(!this.isHittingBlock || !this.isHittingPosition(loc)) { - if(this.isHittingBlock) { - this.netClientHandler.addToSendQueue(new CPacketBreak(CPacketBreak.Action.ABORT_DESTROY_BLOCK, this.currentBlock, face)); + if(!this.hitting || !this.isHittingPosition(pos)) { + if(this.hitting) { + this.handler.addToSendQueue(new CPacketBreak(CPacketBreak.Action.ABORT_DESTROY_BLOCK, this.position, face)); } - this.netClientHandler.addToSendQueue(new CPacketBreak(CPacketBreak.Action.START_DESTROY_BLOCK, loc, face)); - Block block1 = this.gm.world.getState(loc).getBlock(); - boolean flag = block1 != Blocks.air; + this.handler.addToSendQueue(new CPacketBreak(CPacketBreak.Action.START_DESTROY_BLOCK, pos, face)); + Block block = this.gm.world.getState(pos).getBlock(); + boolean flag = block != Blocks.air; - if(flag && this.curBlockDamageMP == 0.0F) { - block1.onBlockClicked(this.gm.world, loc, this.gm.player); + if(flag && this.damage == 0.0F) { + block.onBlockClicked(this.gm.world, pos, this.gm.player); } - if(flag && block1.getPlayerRelativeBlockHardness(this.gm.player, this.gm.player.worldObj, loc) >= 1.0F) { - this.onPlayerDestroyBlock(loc, face); - this.blockHitDelay = 3; + if(flag && block.getPlayerRelativeBlockHardness(this.gm.player, this.gm.player.worldObj, pos) >= 1.0F) { + this.onPlayerDestroyBlock(pos, face); + this.delay = 3; } else { - this.isHittingBlock = true; - this.currentBlock = loc; - this.currentItemHittingBlock = this.gm.player.getHeldItem(); - this.curBlockDamageMP = 0.0F; - this.stepSoundTickCounter = 0.0F; - this.gm.world.sendBlockBreakProgress(this.gm.player.getId(), this.currentBlock, (int)(this.curBlockDamageMP * 10.0F) - 1); + this.hitting = true; + this.position = pos; + this.stack = this.gm.player.getHeldItem(); + this.damage = 0.0F; + this.stepCounter = 0.0F; + this.gm.world.sendBlockBreakProgress(this.gm.player.getId(), this.position, (int)(this.damage * 10.0F) - 1); } } @@ -116,11 +116,11 @@ public class PlayerController { } public void resetBlockRemoving() { - if(this.isHittingBlock) { - this.netClientHandler.addToSendQueue(new CPacketBreak(CPacketBreak.Action.ABORT_DESTROY_BLOCK, this.currentBlock, Facing.DOWN)); - this.isHittingBlock = false; - this.curBlockDamageMP = 0.0F; - this.gm.world.sendBlockBreakProgress(this.gm.player.getId(), this.currentBlock, -1); + if(this.hitting) { + this.handler.addToSendQueue(new CPacketBreak(CPacketBreak.Action.ABORT_DESTROY_BLOCK, this.position, Facing.DOWN)); + this.hitting = false; + this.damage = 0.0F; + this.gm.world.sendBlockBreakProgress(this.gm.player.getId(), this.position, -1); } } @@ -128,123 +128,123 @@ public class PlayerController { this.interacting = false; } - public boolean onPlayerDamageBlock(BlockPos posBlock, Facing directionFacing) { + public boolean onPlayerDamageBlock(BlockPos pos, Facing face) { if(this.interacting) return false; this.syncCurrentPlayItem(); - if(this.blockHitDelay > 0) { - --this.blockHitDelay; + if(this.delay > 0) { + --this.delay; return true; } - else if(this.isHittingPosition(posBlock)) { - Block block = this.gm.world.getState(posBlock).getBlock(); + else if(this.isHittingPosition(pos)) { + Block block = this.gm.world.getState(pos).getBlock(); if(block == Blocks.air) { - this.isHittingBlock = false; + this.hitting = false; return false; } else { - this.curBlockDamageMP += block.getPlayerRelativeBlockHardness(this.gm.player, this.gm.player.worldObj, posBlock); + this.damage += block.getPlayerRelativeBlockHardness(this.gm.player, this.gm.player.worldObj, pos); - if(this.stepSoundTickCounter % 4.0F == 0.0F && block.sound.getStepSound() != null) { + if(this.stepCounter % 4.0F == 0.0F && block.sound.getStepSound() != null) { this.gm.getSoundManager().playSound(new PositionedSound(block.sound.getStepSound(), 0.25F, - (float)posBlock.getX() + 0.5F, (float)posBlock.getY() + 0.5F, (float)posBlock.getZ() + 0.5F)); + (float)pos.getX() + 0.5F, (float)pos.getY() + 0.5F, (float)pos.getZ() + 0.5F)); } - ++this.stepSoundTickCounter; + ++this.stepCounter; - if(this.curBlockDamageMP >= 1.0F) { - this.isHittingBlock = false; - this.netClientHandler.addToSendQueue(new CPacketBreak(CPacketBreak.Action.STOP_DESTROY_BLOCK, posBlock, directionFacing)); - this.onPlayerDestroyBlock(posBlock, directionFacing); - this.curBlockDamageMP = 0.0F; - this.stepSoundTickCounter = 0.0F; - this.blockHitDelay = 5; + if(this.damage >= 1.0F) { + this.hitting = false; + this.handler.addToSendQueue(new CPacketBreak(CPacketBreak.Action.STOP_DESTROY_BLOCK, pos, face)); + this.onPlayerDestroyBlock(pos, face); + this.damage = 0.0F; + this.stepCounter = 0.0F; + this.delay = 5; } - this.gm.world.sendBlockBreakProgress(this.gm.player.getId(), this.currentBlock, (int)(this.curBlockDamageMP * 10.0F) - 1); + this.gm.world.sendBlockBreakProgress(this.gm.player.getId(), this.position, (int)(this.damage * 10.0F) - 1); return true; } } else { - return this.clickBlock(posBlock, directionFacing); + return this.clickBlock(pos, face); } } public void updateController() { this.syncCurrentPlayItem(); - if(this.netClientHandler.getNetworkManager().isChannelOpen()) { - this.netClientHandler.getNetworkManager().processReceivedPackets(); + if(this.handler.getNetworkManager().isChannelOpen()) { + this.handler.getNetworkManager().processReceivedPackets(); } else { - this.netClientHandler.getNetworkManager().checkDisconnected(); + this.handler.getNetworkManager().checkDisconnected(); } } private boolean isHittingPosition(BlockPos pos) { - ItemStack itemstack = this.gm.player.getHeldItem(); - boolean flag = this.currentItemHittingBlock == null && itemstack == null; + ItemStack stack = this.gm.player.getHeldItem(); + boolean flag = this.stack == null && stack == null; - if(this.currentItemHittingBlock != null && itemstack != null) { - flag = itemstack.getItem() == this.currentItemHittingBlock.getItem() - && ItemStack.areItemStackTagsEqual(itemstack, this.currentItemHittingBlock) - && (itemstack.isItemStackDamageable() || itemstack.getMetadata() == this.currentItemHittingBlock.getMetadata()); + if(this.stack != null && stack != null) { + flag = stack.getItem() == this.stack.getItem() + && ItemStack.areItemStackTagsEqual(stack, this.stack) + && (stack.isItemStackDamageable() || stack.getMetadata() == this.stack.getMetadata()); } - return pos.equals(this.currentBlock) && flag; + return pos.equals(this.position) && flag; } private void syncCurrentPlayItem() { - int i = this.gm.player.inventory.currentItem; + int slot = this.gm.player.inventory.currentItem; - if(i != this.currentPlayerItem) { - this.currentPlayerItem = i; - this.netClientHandler.addToSendQueue(new CPacketAction(CPacketAction.Action.SET_ITEMSLOT, this.currentPlayerItem)); + if(slot != this.lastSelected) { + this.lastSelected = slot; + this.handler.addToSendQueue(new CPacketAction(CPacketAction.Action.SET_ITEMSLOT, this.lastSelected)); } } - public boolean onPlayerRightClick(EntityNPC player, WorldClient worldIn, ItemStack heldStack, BlockPos hitPos, Facing side, Vec3 hitVec) { + public boolean onPlayerRightClick(EntityNPC player, WorldClient world, ItemStack stack, BlockPos pos, Facing side, Vec3 hit) { this.syncCurrentPlayItem(); - float f = (float)(hitVec.xCoord - (double)hitPos.getX()); - float f1 = (float)(hitVec.yCoord - (double)hitPos.getY()); - float f2 = (float)(hitVec.zCoord - (double)hitPos.getZ()); + float f = (float)(hit.xCoord - (double)pos.getX()); + float f1 = (float)(hit.yCoord - (double)pos.getY()); + float f2 = (float)(hit.zCoord - (double)pos.getZ()); boolean flag = false; - if(!World.isValidXZ(hitPos)) { + if(!World.isValidXZ(pos)) { return false; } else { - if(heldStack == null || !heldStack.getItem().onAction(heldStack, player, worldIn, ItemControl.SECONDARY, hitPos)) { - State iblockstate = worldIn.getState(hitPos); + if(stack == null || !stack.getItem().onAction(stack, player, world, ItemControl.SECONDARY, pos)) { + State iblockstate = world.getState(pos); if((!player.isSneaking() || player.getHeldItem() == null) - && iblockstate.getBlock().onBlockActivated(worldIn, hitPos, iblockstate, player, side, f, f1, f2)) { + && iblockstate.getBlock().onBlockActivated(world, pos, iblockstate, player, side, f, f1, f2)) { flag = true; } - if(!flag && heldStack != null && heldStack.getItem() instanceof ItemBlock) { - ItemBlock itemblock = (ItemBlock)heldStack.getItem(); + if(!flag && stack != null && stack.getItem() instanceof ItemBlock) { + ItemBlock itemblock = (ItemBlock)stack.getItem(); - if(!itemblock.canPlaceBlockOnSide(worldIn, hitPos, side, player, heldStack)) { + if(!itemblock.canPlaceBlockOnSide(world, pos, side, player, stack)) { return false; } } } else { - heldStack.getItem().onItemUse(heldStack, player, worldIn, hitPos, side, f, f1, f2); + stack.getItem().onItemUse(stack, player, world, pos, side, f, f1, f2); flag = true; } - this.netClientHandler.addToSendQueue(new CPacketPlace(hitPos, side.getIndex(), player.inventory.getCurrentItem(), f, f1, f2)); + this.handler.addToSendQueue(new CPacketPlace(pos, side.getIndex(), player.inventory.getCurrentItem(), f, f1, f2)); if(!flag) { - if(heldStack == null) { + if(stack == null) { return false; } else { - return heldStack.onItemUse(player, worldIn, hitPos, side, f, f1, f2); + return stack.onItemUse(player, world, pos, side, f, f1, f2); } } else { @@ -253,17 +253,17 @@ public class PlayerController { } } - public boolean sendUseItem(EntityNPC playerIn, World worldIn, ItemStack itemStackIn) { + public boolean sendUseItem(EntityNPC player, World world, ItemStack stack) { this.syncCurrentPlayItem(); - this.netClientHandler.addToSendQueue(new CPacketPlace(playerIn.inventory.getCurrentItem())); - int i = itemStackIn.stackSize; - ItemStack itemstack = itemStackIn.useItemRightClick(worldIn, playerIn); + this.handler.addToSendQueue(new CPacketPlace(player.inventory.getCurrentItem())); + int size = stack.stackSize; + ItemStack changed = stack.useItemRightClick(world, player); - if(itemstack != itemStackIn || itemstack != null && itemstack.stackSize != i) { - playerIn.inventory.mainInventory[playerIn.inventory.currentItem] = itemstack; + if(changed != stack || changed != null && changed.stackSize != size) { + player.inventory.mainInventory[player.inventory.currentItem] = changed; - if(itemstack.stackSize == 0) { - playerIn.inventory.mainInventory[playerIn.inventory.currentItem] = null; + if(changed.stackSize == 0) { + player.inventory.mainInventory[player.inventory.currentItem] = null; } return true; @@ -273,42 +273,42 @@ public class PlayerController { } } - public EntityNPC createPlayerEntity(WorldClient worldIn, int type) { - EntityNPC player = (EntityNPC)EntityRegistry.createEntityByID(type, worldIn); - player.setClientPlayer(this.netClientHandler); + public EntityNPC createPlayerEntity(WorldClient world, int type) { + EntityNPC player = (EntityNPC)EntityRegistry.createEntityByID(type, world); + player.setClientPlayer(this.handler); return player; } - public void attackEntity(EntityNPC playerIn, Entity targetEntity) { + public void attackEntity(EntityNPC player, Entity target) { this.syncCurrentPlayItem(); - this.netClientHandler.addToSendQueue(new CPacketAction(CPacketAction.Action.ATTACK, targetEntity.getId())); - playerIn.attackTargetEntityWithCurrentItem(targetEntity); + this.handler.addToSendQueue(new CPacketAction(CPacketAction.Action.ATTACK, target.getId())); + player.attackTargetEntityWithCurrentItem(target); } - public boolean interactWithEntitySendPacket(EntityNPC playerIn, Entity targetEntity) { + public boolean interactWithEntitySendPacket(EntityNPC player, Entity target) { this.syncCurrentPlayItem(); - this.netClientHandler.addToSendQueue(new CPacketAction(CPacketAction.Action.INTERACT, targetEntity.getId())); - return playerIn.interactWith(targetEntity); + this.handler.addToSendQueue(new CPacketAction(CPacketAction.Action.INTERACT, target.getId())); + return player.interactWith(target); } - public ItemStack windowClick(int windowId, int slotId, int mouseButtonClicked, int mode, EntityNPC playerIn) { - short short1 = playerIn.openContainer.getNextTransactionID(playerIn.inventory); - ItemStack itemstack = playerIn.openContainer.slotClick(slotId, mouseButtonClicked, mode, playerIn); - this.netClientHandler.addToSendQueue(new CPacketClick(windowId, slotId, mouseButtonClicked, mode, itemstack, short1)); - return itemstack; + public ItemStack windowClick(int window, int slot, int button, int mode, EntityNPC player) { + short id = player.openContainer.getNextTransactionID(player.inventory); + ItemStack stack = player.openContainer.slotClick(slot, button, mode, player); + this.handler.addToSendQueue(new CPacketClick(window, slot, button, mode, stack, id)); + return stack; } - public void sendEnchantPacket(int windowID, int button) { - this.netClientHandler.addToSendQueue(new CPacketAction(CPacketAction.Action.ENCHANT_ITEM, windowID | (button << 8))); + public void sendEnchantPacket(int window, int button) { + this.handler.addToSendQueue(new CPacketAction(CPacketAction.Action.ENCHANT_ITEM, window | (button << 8))); } - public void onStoppedUsingItem(EntityNPC playerIn) { + public void onStoppedUsingItem(EntityNPC player) { this.syncCurrentPlayItem(); - this.netClientHandler.addToSendQueue(new CPacketBreak(CPacketBreak.Action.RELEASE_USE_ITEM, BlockPos.ORIGIN, Facing.DOWN)); - playerIn.stopUsingItem(); + this.handler.addToSendQueue(new CPacketBreak(CPacketBreak.Action.RELEASE_USE_ITEM, BlockPos.ORIGIN, Facing.DOWN)); + player.stopUsingItem(); } public boolean getIsHittingBlock() { - return this.isHittingBlock; + return this.hitting; } } From 10fdaf0b1a6b79c2a6d0ad299d5a061389326662 Mon Sep 17 00:00:00 2001 From: Sen Date: Sun, 25 May 2025 15:41:41 +0200 Subject: [PATCH 076/200] cleanup player controller method names --- client/src/client/Client.java | 14 +++---- client/src/client/util/PlayerController.java | 42 ++++++++++---------- 2 files changed, 28 insertions(+), 28 deletions(-) diff --git a/client/src/client/Client.java b/client/src/client/Client.java index 3c249a0..1e6c919 100755 --- a/client/src/client/Client.java +++ b/client/src/client/Client.java @@ -698,7 +698,7 @@ public class Client implements IThreadListener { this.entityRenderer.getMouseOver(1.0F); if (/* !this.paused && */ this.world != null) { - this.controller.updateController(); + this.controller.update(); } this.textureMap.updateAnimations(); if (this.open != null) @@ -728,7 +728,7 @@ public class Client implements IThreadListener { { if (!Bind.SECONDARY.isDown()) { - this.controller.onStoppedUsingItem(this.player); + this.controller.stopUsing(this.player); } } else @@ -1267,7 +1267,7 @@ public class Client implements IThreadListener { { BlockPos blockpos = this.pointed.block; - if (this.world.getState(blockpos).getBlock() != Blocks.air && this.controller.onPlayerDamageBlock(blockpos, this.pointed.side)) + if (this.world.getState(blockpos).getBlock() != Blocks.air && this.controller.damageBlock(blockpos, this.pointed.side)) { this.effectRenderer.addBlockHitEffects(blockpos, this.pointed.side); this.player.swingItem(); @@ -1275,7 +1275,7 @@ public class Client implements IThreadListener { } else { - this.controller.resetBlockRemoving(); + this.controller.resetProgress(); } } } @@ -1328,7 +1328,7 @@ public class Client implements IThreadListener { private void secondary() { - if (!this.controller.getIsHittingBlock()) + if (!this.controller.isHittingBlock()) { this.rightClickTimer = 4; boolean flag = true; @@ -1360,7 +1360,7 @@ public class Client implements IThreadListener { // flag = false; // } // else - if (this.controller.interactWithEntitySendPacket(this.player, this.pointed.entity)) + if (this.controller.interact(this.player, this.pointed.entity)) { flag = false; } @@ -1374,7 +1374,7 @@ public class Client implements IThreadListener { { int i = itemstack != null ? itemstack.stackSize : 0; - if (this.controller.onPlayerRightClick(this.player, this.world, itemstack, blockpos, this.pointed.side, this.pointed.vec)) + if (this.controller.clickRight(this.player, this.world, itemstack, blockpos, this.pointed.side, this.pointed.vec)) { flag = false; this.player.swingItem(); diff --git a/client/src/client/util/PlayerController.java b/client/src/client/util/PlayerController.java index c95179c..b12f676 100755 --- a/client/src/client/util/PlayerController.java +++ b/client/src/client/util/PlayerController.java @@ -41,7 +41,7 @@ public class PlayerController { this.handler = handler; } - public boolean onPlayerDestroyBlock(BlockPos pos, Facing side) { + public boolean destroyBlock(BlockPos pos, Facing side) { World world = this.gm.world; State state = world.getState(pos); Block block = state.getBlock(); @@ -84,7 +84,7 @@ public class PlayerController { this.handler.addToSendQueue(new CPacketBreak(CPacketBreak.Action.START_DESTROY_BLOCK, pos, face)); return true; } - if(!this.hitting || !this.isHittingPosition(pos)) { + if(!this.hitting || !this.isHitting(pos)) { if(this.hitting) { this.handler.addToSendQueue(new CPacketBreak(CPacketBreak.Action.ABORT_DESTROY_BLOCK, this.position, face)); } @@ -98,7 +98,7 @@ public class PlayerController { } if(flag && block.getPlayerRelativeBlockHardness(this.gm.player, this.gm.player.worldObj, pos) >= 1.0F) { - this.onPlayerDestroyBlock(pos, face); + this.destroyBlock(pos, face); this.delay = 3; } else { @@ -115,7 +115,7 @@ public class PlayerController { } } - public void resetBlockRemoving() { + public void resetProgress() { if(this.hitting) { this.handler.addToSendQueue(new CPacketBreak(CPacketBreak.Action.ABORT_DESTROY_BLOCK, this.position, Facing.DOWN)); this.hitting = false; @@ -128,16 +128,16 @@ public class PlayerController { this.interacting = false; } - public boolean onPlayerDamageBlock(BlockPos pos, Facing face) { + public boolean damageBlock(BlockPos pos, Facing face) { if(this.interacting) return false; - this.syncCurrentPlayItem(); + this.syncItem(); if(this.delay > 0) { --this.delay; return true; } - else if(this.isHittingPosition(pos)) { + else if(this.isHitting(pos)) { Block block = this.gm.world.getState(pos).getBlock(); if(block == Blocks.air) { @@ -157,7 +157,7 @@ public class PlayerController { if(this.damage >= 1.0F) { this.hitting = false; this.handler.addToSendQueue(new CPacketBreak(CPacketBreak.Action.STOP_DESTROY_BLOCK, pos, face)); - this.onPlayerDestroyBlock(pos, face); + this.destroyBlock(pos, face); this.damage = 0.0F; this.stepCounter = 0.0F; this.delay = 5; @@ -172,8 +172,8 @@ public class PlayerController { } } - public void updateController() { - this.syncCurrentPlayItem(); + public void update() { + this.syncItem(); if(this.handler.getNetworkManager().isChannelOpen()) { this.handler.getNetworkManager().processReceivedPackets(); @@ -183,7 +183,7 @@ public class PlayerController { } } - private boolean isHittingPosition(BlockPos pos) { + private boolean isHitting(BlockPos pos) { ItemStack stack = this.gm.player.getHeldItem(); boolean flag = this.stack == null && stack == null; @@ -196,7 +196,7 @@ public class PlayerController { return pos.equals(this.position) && flag; } - private void syncCurrentPlayItem() { + private void syncItem() { int slot = this.gm.player.inventory.currentItem; if(slot != this.lastSelected) { @@ -205,8 +205,8 @@ public class PlayerController { } } - public boolean onPlayerRightClick(EntityNPC player, WorldClient world, ItemStack stack, BlockPos pos, Facing side, Vec3 hit) { - this.syncCurrentPlayItem(); + public boolean clickRight(EntityNPC player, WorldClient world, ItemStack stack, BlockPos pos, Facing side, Vec3 hit) { + this.syncItem(); float f = (float)(hit.xCoord - (double)pos.getX()); float f1 = (float)(hit.yCoord - (double)pos.getY()); float f2 = (float)(hit.zCoord - (double)pos.getZ()); @@ -254,7 +254,7 @@ public class PlayerController { } public boolean sendUseItem(EntityNPC player, World world, ItemStack stack) { - this.syncCurrentPlayItem(); + this.syncItem(); this.handler.addToSendQueue(new CPacketPlace(player.inventory.getCurrentItem())); int size = stack.stackSize; ItemStack changed = stack.useItemRightClick(world, player); @@ -280,13 +280,13 @@ public class PlayerController { } public void attackEntity(EntityNPC player, Entity target) { - this.syncCurrentPlayItem(); + this.syncItem(); this.handler.addToSendQueue(new CPacketAction(CPacketAction.Action.ATTACK, target.getId())); player.attackTargetEntityWithCurrentItem(target); } - public boolean interactWithEntitySendPacket(EntityNPC player, Entity target) { - this.syncCurrentPlayItem(); + public boolean interact(EntityNPC player, Entity target) { + this.syncItem(); this.handler.addToSendQueue(new CPacketAction(CPacketAction.Action.INTERACT, target.getId())); return player.interactWith(target); } @@ -302,13 +302,13 @@ public class PlayerController { this.handler.addToSendQueue(new CPacketAction(CPacketAction.Action.ENCHANT_ITEM, window | (button << 8))); } - public void onStoppedUsingItem(EntityNPC player) { - this.syncCurrentPlayItem(); + public void stopUsing(EntityNPC player) { + this.syncItem(); this.handler.addToSendQueue(new CPacketBreak(CPacketBreak.Action.RELEASE_USE_ITEM, BlockPos.ORIGIN, Facing.DOWN)); player.stopUsingItem(); } - public boolean getIsHittingBlock() { + public boolean isHittingBlock() { return this.hitting; } } From 77b5a34a33aded89d869508410e73659ca2091cb Mon Sep 17 00:00:00 2001 From: Sen Date: Sun, 25 May 2025 17:53:55 +0200 Subject: [PATCH 077/200] downgrade netty to old version to fix annoying network bugs WHYYYYYYYYYYYYYYYYYYYYY?!?!?!?! --- client/src/client/Client.java | 39 ++-- client/src/client/gui/GuiInfo.java | 2 +- .../client/network/ClientLoginHandler.java | 1 + .../src/client/util}/Message.java | 2 +- common/src/common/init/Registry.java | 3 - common/src/common/log/NettyLogger.java | 170 ------------------ common/src/common/network/ILoginHandler.java | 2 - common/src/common/network/NetConnection.java | 15 +- common/src/common/network/PacketDecoder.java | 1 - common/src/common/network/PacketEncoder.java | 1 - common/src/common/network/PacketRegistry.java | 2 - common/src/common/packet/LPacketLogin.java | 23 --- server/src/server/Server.java | 1 + .../src/server/network/HandshakeHandler.java | 4 +- server/src/server/network/LoginHandler.java | 5 +- 15 files changed, 51 insertions(+), 220 deletions(-) rename {common/src/common/log => client/src/client/util}/Message.java (89%) delete mode 100644 common/src/common/log/NettyLogger.java delete mode 100644 common/src/common/packet/LPacketLogin.java diff --git a/client/src/client/Client.java b/client/src/client/Client.java index 1e6c919..f6c01b8 100755 --- a/client/src/client/Client.java +++ b/client/src/client/Client.java @@ -71,6 +71,7 @@ import client.renderer.texture.EntityTexManager; import client.renderer.texture.TextureManager; import client.renderer.texture.TextureMap; import client.util.FileUtils; +import client.util.Message; import client.util.PerfSection; import client.util.PlayerController; import client.vars.BoolVar; @@ -129,19 +130,18 @@ import common.item.ItemControl; import common.item.ItemStack; import common.log.Log; import common.log.LogLevel; -import common.log.Message; import common.network.IThreadListener; import common.network.NetConnection; import common.network.PacketDecoder; import common.network.PacketEncoder; import common.network.PacketPrepender; +import common.network.PacketRegistry; import common.network.PacketSplitter; import common.network.NetHandler.ThreadQuickExitException; import common.packet.CPacketAction; import common.packet.CPacketCheat; import common.packet.CPacketMessage; import common.packet.HPacketHandshake; -import common.packet.LPacketLogin; import common.packet.CPacketAction.Action; import common.potion.Potion; import common.potion.PotionEffect; @@ -171,6 +171,8 @@ import io.netty.channel.ChannelOption; import io.netty.channel.nio.NioEventLoopGroup; import io.netty.channel.socket.nio.NioSocketChannel; import io.netty.handler.timeout.ReadTimeoutHandler; +import io.netty.util.concurrent.Future; +import io.netty.util.concurrent.GenericFutureListener; /* Een net ganz funktionierndes Programm ... @@ -513,13 +515,16 @@ public class Client implements IThreadListener { public void connect(String address, int port, String user, String pass, String access) { this.displayGuiScreen(GuiLoading.makeWaitTask("Verbinde zu " + (address == null ? "localhost" : address) + ":" + port + " ...")); Log.JNI.info("Verbinde zu " + (address == null ? "localhost" : address) + ":" + port); - NetConnection connection = null; + final NetConnection connection; try { connection = createNetworkManagerAndConnect(address == null ? InetAddress.getLoopbackAddress() : InetAddress.getByName(IDN.toASCII(address)), port); connection.setNetHandler(new ClientLoginHandler(connection, this, user, access, pass)); - connection.sendPacket(new HPacketHandshake(Config.PROTOCOL)); - connection.sendPacket(new LPacketLogin()); + connection.sendPacket(new HPacketHandshake(Config.PROTOCOL), new GenericFutureListener>() { + public void operationComplete(Future u) throws Exception { + connection.setConnectionState(PacketRegistry.LOGIN); + } + }); } catch (UnknownHostException u) { @@ -793,8 +798,10 @@ public class Client implements IThreadListener { } else if (this.connection != null) { - this.connection.processReceivedPackets(); - this.connection.checkDisconnected(); + if(this.connection.isChannelOpen()) + this.connection.processReceivedPackets(); + else + this.connection.checkDisconnected(); } } @@ -2649,9 +2656,21 @@ public class Client implements IThreadListener { }); this.registerDebug(Keysym.AE, "Programm sofort beenden und server beenden", new DebugRunner() { public void execute(Keysym key) { - if(Client.this.player != null) - Client.this.player.client.addToSendQueue(new CPacketMessage(CPacketMessage.Type.COMMAND, "shutdown")); - Client.this.interrupted = true; + if(Client.this.getNetHandler() != null) { + Client.this.getNetHandler().getNetworkManager().sendPacket(new CPacketMessage(CPacketMessage.Type.COMMAND, "shutdown"), new GenericFutureListener>() { + public void operationComplete(Future u) throws Exception { + try { + Thread.sleep(1000L); + } + catch(InterruptedException e) { + } + Client.this.interrupted = true; + } + }); + } + else { + Client.this.interrupted = true; + } } }); } diff --git a/client/src/client/gui/GuiInfo.java b/client/src/client/gui/GuiInfo.java index 5653efb..8c52e6c 100644 --- a/client/src/client/gui/GuiInfo.java +++ b/client/src/client/gui/GuiInfo.java @@ -18,7 +18,7 @@ public class GuiInfo extends Gui { private static final String[] LIBRARIES = { "LWJGL 3.3.6+1 (GLFW + OpenGL)", - "Netty 4.1.119-Final" + "Netty 4.0.23-Final" }; private static final String[] CODE = { "Albert Pham - WorldEdit (Snippets)", diff --git a/client/src/client/network/ClientLoginHandler.java b/client/src/client/network/ClientLoginHandler.java index cfda5c6..c4d9a18 100755 --- a/client/src/client/network/ClientLoginHandler.java +++ b/client/src/client/network/ClientLoginHandler.java @@ -45,6 +45,7 @@ public class ClientLoginHandler extends NetHandler implements IClientLoginHandle } public void handleEncrypt(RPacketRequestEncrypt packet) { + this.networkManager.setConnectionState(PacketRegistry.LOGIN); final SecretKey secret = EncryptUtil.createNewSharedKey(); PublicKey pubkey = packet.getKey(); this.networkManager.sendPacket(new LPacketStartEncrypt(secret, pubkey, packet.getToken()), new GenericFutureListener < Future > () { diff --git a/common/src/common/log/Message.java b/client/src/client/util/Message.java similarity index 89% rename from common/src/common/log/Message.java rename to client/src/client/util/Message.java index 939962d..441a7b0 100644 --- a/common/src/common/log/Message.java +++ b/client/src/client/util/Message.java @@ -1,4 +1,4 @@ -package common.log; +package client.util; public class Message { public final String message; diff --git a/common/src/common/init/Registry.java b/common/src/common/init/Registry.java index 4880af1..c70b9ce 100755 --- a/common/src/common/init/Registry.java +++ b/common/src/common/init/Registry.java @@ -14,8 +14,6 @@ import java.util.Locale; import javax.imageio.ImageIO; -import common.log.NettyLogger; - public abstract class Registry { private static boolean crashed; @@ -116,7 +114,6 @@ public abstract class Registry { timer.setDaemon(true); timer.start(); System.setProperty("java.net.preferIPv4Stack", "true"); - NettyLogger.init(); register(); } diff --git a/common/src/common/log/NettyLogger.java b/common/src/common/log/NettyLogger.java deleted file mode 100644 index 8371653..0000000 --- a/common/src/common/log/NettyLogger.java +++ /dev/null @@ -1,170 +0,0 @@ -package common.log; - -import java.io.PrintWriter; -import java.io.StringWriter; - -import io.netty.util.internal.logging.AbstractInternalLogger; -import io.netty.util.internal.logging.FormattingTuple; -import io.netty.util.internal.logging.InternalLogger; -import io.netty.util.internal.logging.InternalLoggerFactory; -import io.netty.util.internal.logging.MessageFormatter; - -public class NettyLogger extends AbstractInternalLogger { - public static void init() { - InternalLoggerFactory.setDefaultFactory(new InternalLoggerFactory() { - protected InternalLogger newInstance(String name) { - return new NettyLogger(name); - } - }); - } - - private NettyLogger(String name) { - super(name); - } - - public boolean isTraceEnabled() { - return Log.getLevel().ordinal() >= LogLevel.TRACE.ordinal(); - } - - public void trace(String msg) { - this.log(LogLevel.TRACE, msg, null); - } - - public void trace(String format, Object arg) { - FormattingTuple ft = MessageFormatter.format(format, arg); - this.log(LogLevel.TRACE, ft.getMessage(), ft.getThrowable()); - } - - public void trace(String format, Object argA, Object argB) { - FormattingTuple ft = MessageFormatter.format(format, argA, argB); - this.log(LogLevel.TRACE, ft.getMessage(), ft.getThrowable()); - } - - public void trace(String format, Object... argArray) { - FormattingTuple ft = MessageFormatter.arrayFormat(format, argArray); - this.log(LogLevel.TRACE, ft.getMessage(), ft.getThrowable()); - } - - public void trace(String msg, Throwable t) { - this.log(LogLevel.TRACE, msg, t); - } - - public boolean isDebugEnabled() { - return Log.getLevel().ordinal() >= LogLevel.DEBUG.ordinal(); - } - - public void debug(String msg) { - this.log(LogLevel.DEBUG, msg, null); - } - - public void debug(String format, Object arg) { - FormattingTuple ft = MessageFormatter.format(format, arg); - this.log(LogLevel.DEBUG, ft.getMessage(), ft.getThrowable()); - } - - public void debug(String format, Object argA, Object argB) { - FormattingTuple ft = MessageFormatter.format(format, argA, argB); - this.log(LogLevel.DEBUG, ft.getMessage(), ft.getThrowable()); - } - - public void debug(String format, Object... argArray) { - FormattingTuple ft = MessageFormatter.arrayFormat(format, argArray); - this.log(LogLevel.DEBUG, ft.getMessage(), ft.getThrowable()); - } - - public void debug(String msg, Throwable t) { - this.log(LogLevel.DEBUG, msg, t); - } - - public boolean isInfoEnabled() { - return Log.getLevel().ordinal() >= LogLevel.INFO.ordinal(); - } - - public void info(String msg) { - this.log(LogLevel.INFO, msg, null); - } - - public void info(String format, Object arg) { - FormattingTuple ft = MessageFormatter.format(format, arg); - this.log(LogLevel.INFO, ft.getMessage(), ft.getThrowable()); - } - - public void info(String format, Object argA, Object argB) { - FormattingTuple ft = MessageFormatter.format(format, argA, argB); - this.log(LogLevel.INFO, ft.getMessage(), ft.getThrowable()); - } - - public void info(String format, Object... argArray) { - FormattingTuple ft = MessageFormatter.arrayFormat(format, argArray); - this.log(LogLevel.INFO, ft.getMessage(), ft.getThrowable()); - } - - public void info(String msg, Throwable t) { - this.log(LogLevel.INFO, msg, t); - } - - public boolean isWarnEnabled() { - return Log.getLevel().ordinal() >= LogLevel.WARN.ordinal(); - } - - public void warn(String msg) { - this.log(LogLevel.WARN, msg, null); - } - - public void warn(String format, Object arg) { - FormattingTuple ft = MessageFormatter.format(format, arg); - this.log(LogLevel.WARN, ft.getMessage(), ft.getThrowable()); - } - - public void warn(String format, Object argA, Object argB) { - FormattingTuple ft = MessageFormatter.format(format, argA, argB); - this.log(LogLevel.WARN, ft.getMessage(), ft.getThrowable()); - } - - public void warn(String format, Object... argArray) { - FormattingTuple ft = MessageFormatter.arrayFormat(format, argArray); - this.log(LogLevel.WARN, ft.getMessage(), ft.getThrowable()); - } - - public void warn(String msg, Throwable t) { - this.log(LogLevel.WARN, msg, t); - } - - public boolean isErrorEnabled() { - return Log.getLevel().ordinal() >= LogLevel.ERROR.ordinal(); - } - - public void error(String msg) { - this.log(LogLevel.ERROR, msg, null); - } - - public void error(String format, Object arg) { - FormattingTuple ft = MessageFormatter.format(format, arg); - this.log(LogLevel.ERROR, ft.getMessage(), ft.getThrowable()); - } - - public void error(String format, Object argA, Object argB) { - FormattingTuple ft = MessageFormatter.format(format, argA, argB); - this.log(LogLevel.ERROR, ft.getMessage(), ft.getThrowable()); - } - - public void error(String format, Object... arguments) { - FormattingTuple ft = MessageFormatter.arrayFormat(format, arguments); - this.log(LogLevel.ERROR, ft.getMessage(), ft.getThrowable()); - } - - public void error(String msg, Throwable t) { - this.log(LogLevel.ERROR, msg, t); - } - - private void log(LogLevel level, String msg, Throwable t) { - Log.NETTY.log(level, msg); - if(t != null) { - StringWriter sw = new StringWriter(); - PrintWriter st = new PrintWriter(sw); - t.printStackTrace(st); - sw.flush(); - Log.NETTY.log(level, sw.toString().trim().replace('\t', ' ')); - } - } -} diff --git a/common/src/common/network/ILoginHandler.java b/common/src/common/network/ILoginHandler.java index b33bca6..7cc7ffb 100644 --- a/common/src/common/network/ILoginHandler.java +++ b/common/src/common/network/ILoginHandler.java @@ -1,11 +1,9 @@ package common.network; -import common.packet.LPacketLogin; import common.packet.LPacketPasswordResponse; import common.packet.LPacketStartEncrypt; public interface ILoginHandler { void processPasswordResponse(LPacketPasswordResponse packet); void processEncryption(LPacketStartEncrypt packet); - void processLogin(LPacketLogin packet); } diff --git a/common/src/common/network/NetConnection.java b/common/src/common/network/NetConnection.java index c430fdb..a18827f 100755 --- a/common/src/common/network/NetConnection.java +++ b/common/src/common/network/NetConnection.java @@ -24,6 +24,7 @@ import io.netty.util.concurrent.Future; import io.netty.util.concurrent.GenericFutureListener; public class NetConnection extends SimpleChannelInboundHandler { + private static final boolean DEBUG = System.getProperty("network.debug") != null; private static final Pattern IP_REPLACER = Pattern.compile("([0-9]*)\\.([0-9]*)\\.[0-9]*\\.[0-9]*"); public static final AttributeKey ATTR_STATE = AttributeKey.valueOf("protocol"); @@ -52,7 +53,8 @@ public class NetConnection extends SimpleChannelInboundHandler { public void setConnectionState(PacketRegistry newState) { this.channel.attr(ATTR_STATE).set(newState); this.channel.config().setAutoRead(true); -// Log.debug("Automatisches Lesen eingeschaltet"); + if(DEBUG) + Log.SYSTEM.info("Automatisches Lesen eingeschaltet"); } public void channelInactive(ChannelHandlerContext context) throws Exception { @@ -75,6 +77,8 @@ public class NetConnection extends SimpleChannelInboundHandler { } protected void channelRead0(ChannelHandlerContext context, Packet packet) throws Exception { + if(DEBUG) + Log.SYSTEM.info("EIN: [" + context.channel().attr(NetConnection.ATTR_STATE).get() + "] " + packet.getClass().getName()); if(this.channel.isOpen()) { try { packet.processPacket(this.handler); @@ -132,7 +136,8 @@ public class NetConnection extends SimpleChannelInboundHandler { final PacketRegistry current = this.channel.attr(ATTR_STATE).get(); if(current != state) { -// Log.debug("Automatisches Lesen ausgeschaltet"); + if(DEBUG) + Log.SYSTEM.info("Automatisches Lesen ausgeschaltet"); this.channel.config().setAutoRead(false); } @@ -141,6 +146,8 @@ public class NetConnection extends SimpleChannelInboundHandler { this.setConnectionState(state); } + if(DEBUG) + Log.SYSTEM.info("AUS: [" + this.channel.attr(NetConnection.ATTR_STATE).get() + "] " + packet.getClass().getName()); ChannelFuture future = this.channel.writeAndFlush(packet); if(listeners != null) { @@ -156,6 +163,8 @@ public class NetConnection extends SimpleChannelInboundHandler { NetConnection.this.setConnectionState(state); } + if(DEBUG) + Log.SYSTEM.info("AUS: [" + NetConnection.this.channel.attr(NetConnection.ATTR_STATE).get() + "] " + packet.getClass().getName()); ChannelFuture future = NetConnection.this.channel.writeAndFlush(packet); if(listeners != null) { @@ -190,6 +199,8 @@ public class NetConnection extends SimpleChannelInboundHandler { this.handler.update(); if(this.channel != null) this.channel.flush(); + if(DEBUG) + Log.SYSTEM.info("Pakete synchronisiert"); } public String getCutAddress() { diff --git a/common/src/common/network/PacketDecoder.java b/common/src/common/network/PacketDecoder.java index 9d5f1c3..e7e25bd 100755 --- a/common/src/common/network/PacketDecoder.java +++ b/common/src/common/network/PacketDecoder.java @@ -27,6 +27,5 @@ public class PacketDecoder extends ByteToMessageDecoder { throw new IOException("Paket " + ((PacketRegistry)context.channel().attr(NetConnection.ATTR_STATE).get()).ordinal() + "/" + id + " (" + packet.getClass() + ") war größer als erwartet, " + pbuf.readableBytes() + " weitere Bytes wurden beim Lesen von Paket " + id + " gefunden"); output.add(packet); -// common.log.Log.SYSTEM.info("EIN: [" + context.channel().attr(NetConnection.ATTR_STATE).get() + ":" + id + "] " + packet.getClass().getName()); } } diff --git a/common/src/common/network/PacketEncoder.java b/common/src/common/network/PacketEncoder.java index 26f1190..5a0a628 100755 --- a/common/src/common/network/PacketEncoder.java +++ b/common/src/common/network/PacketEncoder.java @@ -17,7 +17,6 @@ public class PacketEncoder extends MessageToByteEncoder { Integer id = context.channel().attr(NetConnection.ATTR_STATE).get().getId(this.client, packet); if(id == null) throw new IOException("Kann nicht registriertes Paket nicht serialisieren"); -// common.log.Log.SYSTEM.debug("AUS: [" + context.channel().attr(NetConnection.ATTR_STATE).get() + ":" + id + "] " + packet.getClass().getName()); PacketBuffer pbuf = new PacketBuffer(output); pbuf.writeVarInt(id); try { diff --git a/common/src/common/network/PacketRegistry.java b/common/src/common/network/PacketRegistry.java index e896dbb..6278291 100755 --- a/common/src/common/network/PacketRegistry.java +++ b/common/src/common/network/PacketRegistry.java @@ -22,7 +22,6 @@ import common.packet.CPacketPlayer; import common.packet.CPacketSign; import common.packet.CPacketSkin; import common.packet.HPacketHandshake; -import common.packet.LPacketLogin; import common.packet.LPacketPasswordResponse; import common.packet.LPacketStartEncrypt; import common.packet.RPacketDisconnect; @@ -105,7 +104,6 @@ public enum PacketRegistry { this.server(RPacketLoginSuccess.class); this.server(RPacketEnableCompression.class); - this.client(LPacketLogin.class); this.client(LPacketStartEncrypt.class); this.client(LPacketPasswordResponse.class); }}, diff --git a/common/src/common/packet/LPacketLogin.java b/common/src/common/packet/LPacketLogin.java deleted file mode 100644 index 50c647d..0000000 --- a/common/src/common/packet/LPacketLogin.java +++ /dev/null @@ -1,23 +0,0 @@ -package common.packet; - -import java.io.IOException; -import common.network.ILoginHandler; -import common.network.Packet; -import common.network.PacketBuffer; - -public class LPacketLogin implements Packet { - public LPacketLogin() { - } - - public void readPacketData(PacketBuffer buf) throws IOException { - buf.readString(16); - } - - public void writePacketData(PacketBuffer buf) throws IOException { - buf.writeString("TESTtestPlceHldr"); - } - - public void processPacket(ILoginHandler handler) { - handler.processLogin(this); - } -} diff --git a/server/src/server/Server.java b/server/src/server/Server.java index 96774ac..2928f08 100755 --- a/server/src/server/Server.java +++ b/server/src/server/Server.java @@ -663,6 +663,7 @@ public final class Server implements IThreadListener { this.saveAllWorlds(false); this.saveTimer = 0; } + Log.flushLog(); this.tickTimes[this.perfTimer++] = System.currentTimeMillis() - now; if(this.perfTimer == 100) { this.perfTimer = 0; diff --git a/server/src/server/network/HandshakeHandler.java b/server/src/server/network/HandshakeHandler.java index a3fc59e..718e66f 100755 --- a/server/src/server/network/HandshakeHandler.java +++ b/server/src/server/network/HandshakeHandler.java @@ -43,7 +43,9 @@ public class HandshakeHandler extends NetHandler implements IHandshakeHandler } else { - this.networkManager.setNetHandler(new LoginHandler(this.server, this.networkManager)); + LoginHandler handler = new LoginHandler(this.server, this.networkManager); + this.networkManager.setNetHandler(handler); + handler.sendLoginPacket(); } } } diff --git a/server/src/server/network/LoginHandler.java b/server/src/server/network/LoginHandler.java index d71d102..dad02f7 100755 --- a/server/src/server/network/LoginHandler.java +++ b/server/src/server/network/LoginHandler.java @@ -13,7 +13,6 @@ import common.network.ILoginHandler; import common.network.IPlayer; import common.network.NetConnection; import common.network.NetHandler; -import common.packet.LPacketLogin; import common.packet.LPacketPasswordResponse; import common.packet.LPacketStartEncrypt; import common.packet.RPacketDisconnect; @@ -105,9 +104,9 @@ public class LoginHandler extends NetHandler implements ILoginHandler this.state = LoginState.ACCEPTED; } - public void processLogin(LPacketLogin packet) { + public void sendLoginPacket() { if(this.state != LoginState.INIT) - throw new IllegalStateException("Unerwartetes Login-Paket"); + throw new IllegalStateException("Unerwartetes Handshake-Paket"); this.state = LoginState.ENCRYPT; this.loginToken = new byte[4]; TOKEN_RNG.nextBytes(this.loginToken); From bb6494992788249949de34c9542b274ec5e1d971 Mon Sep 17 00:00:00 2001 From: Sen Date: Sun, 25 May 2025 17:59:22 +0200 Subject: [PATCH 078/200] change logger (netconnection) --- common/src/common/log/Log.java | 2 +- common/src/common/network/NetConnection.java | 18 +++++++++--------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/common/src/common/log/Log.java b/common/src/common/log/Log.java index 04aa56c..712bd3d 100644 --- a/common/src/common/log/Log.java +++ b/common/src/common/log/Log.java @@ -18,7 +18,7 @@ public enum Log { TICK("Tick"), SOUND("Sound"), JNI("JNI"), - NETTY("Netty"); + NETWORK("Network"); private static class LogMessage { private final LogLevel level; diff --git a/common/src/common/network/NetConnection.java b/common/src/common/network/NetConnection.java index a18827f..fd9169c 100755 --- a/common/src/common/network/NetConnection.java +++ b/common/src/common/network/NetConnection.java @@ -46,7 +46,7 @@ public class NetConnection extends SimpleChannelInboundHandler { this.setConnectionState(PacketRegistry.HANDSHAKE); } catch(Throwable t) { - Log.JNI.error(t, "Fehler beim Aufbauen der Verbindung für Handshake"); + Log.NETWORK.error(t, "Fehler beim Aufbauen der Verbindung für Handshake"); } } @@ -54,7 +54,7 @@ public class NetConnection extends SimpleChannelInboundHandler { this.channel.attr(ATTR_STATE).set(newState); this.channel.config().setAutoRead(true); if(DEBUG) - Log.SYSTEM.info("Automatisches Lesen eingeschaltet"); + Log.NETWORK.info("Automatisches Lesen eingeschaltet"); } public void channelInactive(ChannelHandlerContext context) throws Exception { @@ -70,7 +70,7 @@ public class NetConnection extends SimpleChannelInboundHandler { else { comp = "Interner Fehler: " + throwable; if(!(throwable instanceof ClosedChannelException)) - Log.SYSTEM.error(throwable, "Fehler in der Verbindung mit %s", this.getCutAddress()); + Log.NETWORK.error(throwable, "Fehler in der Verbindung mit %s", this.getCutAddress()); } this.closeChannel(comp); @@ -78,7 +78,7 @@ public class NetConnection extends SimpleChannelInboundHandler { protected void channelRead0(ChannelHandlerContext context, Packet packet) throws Exception { if(DEBUG) - Log.SYSTEM.info("EIN: [" + context.channel().attr(NetConnection.ATTR_STATE).get() + "] " + packet.getClass().getName()); + Log.NETWORK.info("EIN: [" + context.channel().attr(NetConnection.ATTR_STATE).get() + "] " + packet.getClass().getName()); if(this.channel.isOpen()) { try { packet.processPacket(this.handler); @@ -137,7 +137,7 @@ public class NetConnection extends SimpleChannelInboundHandler { if(current != state) { if(DEBUG) - Log.SYSTEM.info("Automatisches Lesen ausgeschaltet"); + Log.NETWORK.info("Automatisches Lesen ausgeschaltet"); this.channel.config().setAutoRead(false); } @@ -147,7 +147,7 @@ public class NetConnection extends SimpleChannelInboundHandler { } if(DEBUG) - Log.SYSTEM.info("AUS: [" + this.channel.attr(NetConnection.ATTR_STATE).get() + "] " + packet.getClass().getName()); + Log.NETWORK.info("AUS: [" + this.channel.attr(NetConnection.ATTR_STATE).get() + "] " + packet.getClass().getName()); ChannelFuture future = this.channel.writeAndFlush(packet); if(listeners != null) { @@ -164,7 +164,7 @@ public class NetConnection extends SimpleChannelInboundHandler { } if(DEBUG) - Log.SYSTEM.info("AUS: [" + NetConnection.this.channel.attr(NetConnection.ATTR_STATE).get() + "] " + packet.getClass().getName()); + Log.NETWORK.info("AUS: [" + NetConnection.this.channel.attr(NetConnection.ATTR_STATE).get() + "] " + packet.getClass().getName()); ChannelFuture future = NetConnection.this.channel.writeAndFlush(packet); if(listeners != null) { @@ -200,7 +200,7 @@ public class NetConnection extends SimpleChannelInboundHandler { if(this.channel != null) this.channel.flush(); if(DEBUG) - Log.SYSTEM.info("Pakete synchronisiert"); + Log.NETWORK.info("Pakete synchronisiert"); } public String getCutAddress() { @@ -261,7 +261,7 @@ public class NetConnection extends SimpleChannelInboundHandler { this.handler.onDisconnect(this.exitReason != null ? this.exitReason : "Verbindung getrennt"); } else { - Log.JNI.warn("handleDisconnection() zweifach aufgerufen"); + Log.NETWORK.warn("handleDisconnection() zweifach aufgerufen"); } } } From 63c2a18c3a5227a416651198284b9c642a9b6c19 Mon Sep 17 00:00:00 2001 From: Sen Date: Sun, 25 May 2025 18:30:12 +0200 Subject: [PATCH 079/200] fix all logger names --- client/src/client/Client.java | 20 +++---- client/src/client/gui/character/GuiChar.java | 4 +- client/src/client/network/ClientPlayer.java | 6 +-- client/src/client/renderer/RenderBuffer.java | 2 +- client/src/client/renderer/VertexFormat.java | 2 +- .../client/renderer/VertexFormatElement.java | 2 +- .../renderer/blockmodel/ModelGenerator.java | 6 +-- .../renderer/chunk/ChunkRenderWorker.java | 8 +-- .../renderer/entity/RendererLivingEntity.java | 2 +- .../renderer/texture/EntityTexManager.java | 12 ++--- .../texture/LayeredColorMaskTexture.java | 2 +- .../renderer/texture/LayeredTexture.java | 2 +- .../renderer/texture/TextureManager.java | 4 +- .../client/renderer/texture/TextureMap.java | 8 +-- client/src/client/util/SkinConverter.java | 16 +++--- client/src/client/world/WorldClient.java | 2 +- common/src/common/attributes/Attributes.java | 4 +- common/src/common/biome/Biome.java | 4 +- .../src/common/entity/EntityTrackerEntry.java | 2 +- common/src/common/entity/item/EntityItem.java | 2 +- common/src/common/init/EntityRegistry.java | 6 +-- common/src/common/init/UniverseRegistry.java | 2 +- common/src/common/log/Log.java | 1 - common/src/common/nbt/NBTTagList.java | 10 ++-- common/src/common/potion/PotionEffect.java | 2 +- common/src/common/tileentity/TileEntity.java | 2 +- common/src/common/world/Chunk.java | 2 +- server/src/server/Server.java | 54 +++++++++---------- server/src/server/biome/GenBiome.java | 2 +- server/src/server/network/LoginHandler.java | 6 +-- server/src/server/network/Player.java | 6 +-- server/src/server/world/ChunkServer.java | 4 +- server/src/server/world/Converter.java | 42 +++++++-------- server/src/server/world/Region.java | 14 ++--- server/src/server/world/WorldServer.java | 34 ++++++------ .../src/server/worldgen/FeatureDungeons.java | 2 +- .../server/worldgen/layer/GenLayerHills.java | 2 +- .../worldgen/structure/MapGenStructureIO.java | 8 +-- 38 files changed, 154 insertions(+), 155 deletions(-) diff --git a/client/src/client/Client.java b/client/src/client/Client.java index f6c01b8..d4ae164 100755 --- a/client/src/client/Client.java +++ b/client/src/client/Client.java @@ -514,7 +514,7 @@ public class Client implements IThreadListener { public void connect(String address, int port, String user, String pass, String access) { this.displayGuiScreen(GuiLoading.makeWaitTask("Verbinde zu " + (address == null ? "localhost" : address) + ":" + port + " ...")); - Log.JNI.info("Verbinde zu " + (address == null ? "localhost" : address) + ":" + port); + Log.NETWORK.info("Verbinde zu " + (address == null ? "localhost" : address) + ":" + port); final NetConnection connection; try { @@ -528,13 +528,13 @@ public class Client implements IThreadListener { } catch (UnknownHostException u) { - Log.JNI.error(u, "Konnte nicht zu Server verbinden"); + Log.NETWORK.error(u, "Konnte nicht zu Server verbinden"); this.disconnected("Unbekannter Hostname: " + (address == null ? "localhost" : address)); return; } catch (Exception e) { - Log.JNI.error(e, "Konnte nicht zu Server verbinden"); + Log.NETWORK.error(e, "Konnte nicht zu Server verbinden"); this.disconnected(e.toString()); return; } @@ -620,10 +620,10 @@ public class Client implements IThreadListener { } catch(ExecutionException e1) { if(!(e1.getCause() instanceof ThreadQuickExitException)) - Log.JNI.error(e1, "Fehler beim Ausführen von Render-Task " + task); + Log.SYSTEM.error(e1, "Fehler beim Ausführen von Render-Task " + task); } catch(InterruptedException e2) { - Log.JNI.error(e2, "Fehler beim Ausführen von Render-Task " + task); + Log.SYSTEM.error(e2, "Fehler beim Ausführen von Render-Task " + task); } } } @@ -1294,7 +1294,7 @@ public class Client implements IThreadListener { if (this.pointed == null) { this.player.swingItem(); - Log.JNI.warn("Null zurückgegeben als 'hitResult', das sollte niemals passieren!"); + Log.TICK.warn("Null zurückgegeben als 'hitResult', das sollte niemals passieren!"); this.leftClickCounter = 10; } else @@ -1348,7 +1348,7 @@ public class Client implements IThreadListener { if (this.pointed == null) { - Log.JNI.warn("Null zurückgegeben als 'hitResult', das sollte niemals passieren!"); + Log.TICK.warn("Null zurückgegeben als 'hitResult', das sollte niemals passieren!"); } else { @@ -2270,7 +2270,7 @@ public class Client implements IThreadListener { // } public void disconnected(String msg) { - Log.SYSTEM.info("Getrennt: %s", msg); + Log.NETWORK.info("Getrennt: %s", msg); this.unload(true); this.displayGuiScreen(new GuiInfo("Von Server getrennt", TextColor.RED + "Verbindung zum Server wurde getrennt\n\n" + TextColor.RESET + msg)); } @@ -2888,7 +2888,7 @@ public class Client implements IThreadListener { data = FileUtils.read(config); } catch(IOException e) { - Log.CONSOLE.error(e, "Konnte Konfigurationsdatei nicht laden"); + Log.IO.error(e, "Konnte Konfigurationsdatei nicht laden"); return; } if(data == null) @@ -2925,7 +2925,7 @@ public class Client implements IThreadListener { FileUtils.write(config, sb.toString()); } catch(IOException e) { - Log.CONSOLE.error(e, "Konnte Konfigurationsdatei nicht speichern"); + Log.IO.error(e, "Konnte Konfigurationsdatei nicht speichern"); } } diff --git a/client/src/client/gui/character/GuiChar.java b/client/src/client/gui/character/GuiChar.java index 7ed4397..b361056 100755 --- a/client/src/client/gui/character/GuiChar.java +++ b/client/src/client/gui/character/GuiChar.java @@ -320,9 +320,9 @@ public class GuiChar extends GuiList } catch(Exception e) { if(e instanceof FileNotFoundException) - Log.JNI.warn("Textur ist nicht zum Kopieren vorhanden: " + EntityNPC.getSkinTexture(loc)); + Log.IO.warn("Textur ist nicht zum Kopieren vorhanden: " + EntityNPC.getSkinTexture(loc)); else - Log.JNI.error(e, "Konnte Textur nicht kopieren"); + Log.IO.error(e, "Konnte Textur nicht kopieren"); } finally { if(in != null) { diff --git a/client/src/client/network/ClientPlayer.java b/client/src/client/network/ClientPlayer.java index dfd828a..ba18df0 100755 --- a/client/src/client/network/ClientPlayer.java +++ b/client/src/client/network/ClientPlayer.java @@ -1855,7 +1855,7 @@ public class ClientPlayer extends NetHandler implements IClientPlayer } catch (Throwable var17) { - Log.JNI.warn("Konnte Partikel-Effekt " + packetIn.getParticleType() + " nicht erzeugen"); + Log.RENDER.warn("Konnte Partikel-Effekt " + packetIn.getParticleType() + " nicht erzeugen"); } } else @@ -1876,7 +1876,7 @@ public class ClientPlayer extends NetHandler implements IClientPlayer } catch (Throwable var16) { - Log.JNI.warn("Konnte Partikel-Effekt " + packetIn.getParticleType() + " nicht erzeugen"); + Log.RENDER.warn("Konnte Partikel-Effekt " + packetIn.getParticleType() + " nicht erzeugen"); return; } } @@ -1968,7 +1968,7 @@ public class ClientPlayer extends NetHandler implements IClientPlayer } catch (Exception exception) { - Log.JNI.error((Throwable)exception, (String)"Konnte Handel nicht laden"); + Log.TICK.error((Throwable)exception, (String)"Konnte Handel nicht laden"); } } diff --git a/client/src/client/renderer/RenderBuffer.java b/client/src/client/renderer/RenderBuffer.java index b5cb077..a6cde1d 100755 --- a/client/src/client/renderer/RenderBuffer.java +++ b/client/src/client/renderer/RenderBuffer.java @@ -46,7 +46,7 @@ public class RenderBuffer int i = this.byteBuffer.capacity(); int j = i % 2097152; int k = j + (((this.rawIntBuffer.position() + p_181670_1_) * 4 - j) / 2097152 + 1) * 2097152; - Log.JNI.warn("Musste Puffer vergrößern: Alte Größe " + i + " Bytes, neue Größe " + k + " Bytes."); + Log.RENDER.warn("Musste Puffer vergrößern: Alte Größe " + i + " Bytes, neue Größe " + k + " Bytes."); int l = this.rawIntBuffer.position(); ByteBuffer bytebuffer = ByteBuffer.allocateDirect(k).order(ByteOrder.nativeOrder()); this.byteBuffer.position(0); diff --git a/client/src/client/renderer/VertexFormat.java b/client/src/client/renderer/VertexFormat.java index d8c6e93..1091d82 100755 --- a/client/src/client/renderer/VertexFormat.java +++ b/client/src/client/renderer/VertexFormat.java @@ -53,7 +53,7 @@ public class VertexFormat { if (element.isPositionElement() && this.hasPosition()) { - Log.JNI.warn("VertexFormat-Fehler: Versuche eine Position vom Typ VertexFormatElement hinzuzufügen, während eine bereits existiert, ignoriere."); + Log.RENDER.warn("VertexFormat-Fehler: Versuche eine Position vom Typ VertexFormatElement hinzuzufügen, während eine bereits existiert, ignoriere."); return this; } else diff --git a/client/src/client/renderer/VertexFormatElement.java b/client/src/client/renderer/VertexFormatElement.java index 4ff2116..11d4e4e 100755 --- a/client/src/client/renderer/VertexFormatElement.java +++ b/client/src/client/renderer/VertexFormatElement.java @@ -15,7 +15,7 @@ public class VertexFormatElement { if (!this.isValid(indexIn, usageIn)) { - Log.JNI.warn("Mehrere Vertex-Elemente des gleichen Typs außer UVs sind nicht unterstützt. Erzwinge Typ UV."); + Log.RENDER.warn("Mehrere Vertex-Elemente des gleichen Typs außer UVs sind nicht unterstützt. Erzwinge Typ UV."); this.usage = VertexFormatElement.EnumUsage.UV; } else diff --git a/client/src/client/renderer/blockmodel/ModelGenerator.java b/client/src/client/renderer/blockmodel/ModelGenerator.java index 9e4ccc6..b487010 100755 --- a/client/src/client/renderer/blockmodel/ModelGenerator.java +++ b/client/src/client/renderer/blockmodel/ModelGenerator.java @@ -26,13 +26,13 @@ public abstract class ModelGenerator { } catch(Throwable e) { if(e instanceof FileNotFoundException) - Log.JNI.warn("Textur ist nicht zum Zusammenstellen vorhanden: " + textureLocation); + Log.IO.warn("Textur ist nicht zum Zusammenstellen vorhanden: " + textureLocation); else - Log.JNI.error(e, "Konnte Textur '" + textureLocation + "' nicht zum Zusammenstellen laden"); + Log.IO.error(e, "Konnte Textur '" + textureLocation + "' nicht zum Zusammenstellen laden"); return Lists.newArrayList(); } if(img.length < tw * th) { - Log.JNI.warn("Konnte Textur '" + textureLocation.toString() + "' nicht zum Zusammenstellen laden weil sie zu klein ist " + + Log.IO.warn("Konnte Textur '" + textureLocation.toString() + "' nicht zum Zusammenstellen laden weil sie zu klein ist " + "(benötige " + (tw*th) + " [" + tw + "x" + th + "], habe " + img.length + ")"); return Lists.newArrayList(); } diff --git a/client/src/client/renderer/chunk/ChunkRenderWorker.java b/client/src/client/renderer/chunk/ChunkRenderWorker.java index d685f68..0fe9a2b 100755 --- a/client/src/client/renderer/chunk/ChunkRenderWorker.java +++ b/client/src/client/renderer/chunk/ChunkRenderWorker.java @@ -62,7 +62,7 @@ public class ChunkRenderWorker implements Runnable { if (!generator.isFinished()) { - Log.JNI.warn("Chunk-Rendering-Aufgabe war " + generator.getStatus() + " wenn PENDING erwartet war; ignoriere Aufgabe"); + Log.RENDER.warn("Chunk-Rendering-Aufgabe war " + generator.getStatus() + " wenn PENDING erwartet war; ignoriere Aufgabe"); } return; @@ -106,7 +106,7 @@ public class ChunkRenderWorker implements Runnable { if (!generator.isFinished()) { - Log.JNI.warn("Chunk-Rendering-Aufgabe war " + generator.getStatus() + " wenn COMPILING erwartet war; breche Aufgabe ab"); + Log.RENDER.warn("Chunk-Rendering-Aufgabe war " + generator.getStatus() + " wenn COMPILING erwartet war; breche Aufgabe ab"); } this.freeRenderBuilder(generator); @@ -164,7 +164,7 @@ public class ChunkRenderWorker implements Runnable if (!generator.isFinished()) { - Log.JNI.warn("Chunk-Rendering-Aufgabe war " + generator.getStatus() + " wenn UPLOADING erwartet war; breche Aufgabe ab"); + Log.RENDER.warn("Chunk-Rendering-Aufgabe war " + generator.getStatus() + " wenn UPLOADING erwartet war; breche Aufgabe ab"); } } finally @@ -182,7 +182,7 @@ public class ChunkRenderWorker implements Runnable if (!(p_onFailure_1_ instanceof CancellationException) && !(p_onFailure_1_ instanceof InterruptedException)) { - Log.JNI.error(p_onFailure_1_, "Fehler beim Rendern des Chunks"); + Log.RENDER.error(p_onFailure_1_, "Fehler beim Rendern des Chunks"); } } }); diff --git a/client/src/client/renderer/entity/RendererLivingEntity.java b/client/src/client/renderer/entity/RendererLivingEntity.java index e8df489..26c5539 100755 --- a/client/src/client/renderer/entity/RendererLivingEntity.java +++ b/client/src/client/renderer/entity/RendererLivingEntity.java @@ -182,7 +182,7 @@ public abstract class RendererLivingEntity extends Rende } catch (Exception exception) { - Log.JNI.error((Throwable)exception, (String)"Konnte Objekt nicht rendern"); + Log.RENDER.error((Throwable)exception, (String)"Konnte Objekt nicht rendern"); } GlState.setActiveTexture(GL13.GL_TEXTURE1); diff --git a/client/src/client/renderer/texture/EntityTexManager.java b/client/src/client/renderer/texture/EntityTexManager.java index 1c0dcc6..8160703 100755 --- a/client/src/client/renderer/texture/EntityTexManager.java +++ b/client/src/client/renderer/texture/EntityTexManager.java @@ -46,17 +46,17 @@ public abstract class EntityTexManager } catch(IOException e) { if(e instanceof FileNotFoundException) - Log.JNI.warn("Textur ist nicht vorhanden: " + loc); + Log.IO.warn("Textur ist nicht vorhanden: " + loc); else - Log.JNI.error(e, "Konnte Textur nicht laden: " + loc); + Log.IO.error(e, "Konnte Textur nicht laden: " + loc); try { image = TextureUtil.readImage(FileUtils.getResource(getDefault(entry.getValue()))); } catch(IOException e2) { if(e2 instanceof FileNotFoundException) - Log.JNI.warn("Textur ist nicht vorhanden: " + loc); + Log.IO.warn("Textur ist nicht vorhanden: " + loc); else - Log.JNI.error(e2, "Konnte Textur nicht laden: " + loc); + Log.IO.error(e2, "Konnte Textur nicht laden: " + loc); image = new BufferedImage(64, 64, BufferedImage.TYPE_INT_ARGB); Graphics2D g = image.createGraphics(); g.setColor(Color.BLACK); @@ -98,9 +98,9 @@ public abstract class EntityTexManager } catch(IOException e) { if(e instanceof FileNotFoundException) - Log.JNI.warn("Textur ist nicht vorhanden: " + loc); + Log.IO.warn("Textur ist nicht vorhanden: " + loc); else - Log.JNI.error(e, "Konnte Textur nicht laden: " + loc); + Log.IO.error(e, "Konnte Textur nicht laden: " + loc); image = new BufferedImage(64, 32, BufferedImage.TYPE_INT_ARGB); Graphics2D g = image.createGraphics(); g.setColor(Color.BLACK); diff --git a/client/src/client/renderer/texture/LayeredColorMaskTexture.java b/client/src/client/renderer/texture/LayeredColorMaskTexture.java index 93e2a2c..dfb3312 100755 --- a/client/src/client/renderer/texture/LayeredColorMaskTexture.java +++ b/client/src/client/renderer/texture/LayeredColorMaskTexture.java @@ -92,7 +92,7 @@ public class LayeredColorMaskTexture extends Texture } catch (IOException ioexception) { - Log.JNI.error((Throwable)ioexception, (String)"Konnte Bild mit mehreren Schichten nicht laden"); + Log.IO.error((Throwable)ioexception, (String)"Konnte Bild mit mehreren Schichten nicht laden"); return; } diff --git a/client/src/client/renderer/texture/LayeredTexture.java b/client/src/client/renderer/texture/LayeredTexture.java index a6e29a3..26c5a96 100755 --- a/client/src/client/renderer/texture/LayeredTexture.java +++ b/client/src/client/renderer/texture/LayeredTexture.java @@ -44,7 +44,7 @@ public class LayeredTexture extends Texture } catch (IOException ioexception) { - Log.JNI.error((Throwable)ioexception, (String)"Konnte Bild mit mehreren Schichten nicht laden"); + Log.IO.error((Throwable)ioexception, (String)"Konnte Bild mit mehreren Schichten nicht laden"); return; } diff --git a/client/src/client/renderer/texture/TextureManager.java b/client/src/client/renderer/texture/TextureManager.java index 4bd6328..66f45fb 100755 --- a/client/src/client/renderer/texture/TextureManager.java +++ b/client/src/client/renderer/texture/TextureManager.java @@ -28,9 +28,9 @@ public class TextureManager { } catch(IOException e) { if(e instanceof FileNotFoundException) - Log.JNI.warn("Textur ist nicht vorhanden: " + res); + Log.IO.warn("Textur ist nicht vorhanden: " + res); else - Log.JNI.error(e, "Konnte Textur nicht laden: " + res); + Log.IO.error(e, "Konnte Textur nicht laden: " + res); tex = TextureUtil.MISSING; this.textures.put(res, tex); flag = false; diff --git a/client/src/client/renderer/texture/TextureMap.java b/client/src/client/renderer/texture/TextureMap.java index b975ff7..c85dd1b 100755 --- a/client/src/client/renderer/texture/TextureMap.java +++ b/client/src/client/renderer/texture/TextureMap.java @@ -115,17 +115,17 @@ public class TextureMap extends Texture } catch (RuntimeException runtimeexception) { - Log.JNI.error((Throwable)runtimeexception, (String)("Konnte Metadaten von " + name + " nicht laden")); + Log.IO.error((Throwable)runtimeexception, (String)("Konnte Metadaten von " + name + " nicht laden")); continue; } catch (FileNotFoundException f) { - Log.JNI.warn("Textur ist nicht vorhanden: " + name); + Log.IO.warn("Textur ist nicht vorhanden: " + name); continue; } catch (IOException ioexception1) { - Log.JNI.error((Throwable)ioexception1, (String)("Benutze Ersatztextur, konnte " + name + " nicht laden")); + Log.IO.error((Throwable)ioexception1, (String)("Benutze Ersatztextur, konnte " + name + " nicht laden")); continue; } @@ -167,7 +167,7 @@ public class TextureMap extends Texture throw stitcherexception; } - Log.JNI.info("Textur-Atlas in Größe " + stitcher.getCurrentWidth() + "x" + stitcher.getCurrentHeight() + " erstellt"); + Log.RENDER.info("Textur-Atlas in Größe " + stitcher.getCurrentWidth() + "x" + stitcher.getCurrentHeight() + " erstellt"); TextureUtil.allocateTexture(this.getGlTextureId(), stitcher.getCurrentWidth(), stitcher.getCurrentHeight()); Map map = Maps.newHashMap(this.mapRegisteredSprites); diff --git a/client/src/client/util/SkinConverter.java b/client/src/client/util/SkinConverter.java index 037b0ea..dffc049 100755 --- a/client/src/client/util/SkinConverter.java +++ b/client/src/client/util/SkinConverter.java @@ -171,20 +171,20 @@ public abstract class SkinConverter { img = ImageIO.read(source); } catch(IOException e) { - Log.JNI.error(e, "Konnte kein Bild von " + source + " laden"); + Log.IO.error(e, "Konnte kein Bild von " + source + " laden"); return false; } if(img == null) { - Log.JNI.warn("Konnte kein Bild von " + source + " laden"); + Log.IO.warn("Konnte kein Bild von " + source + " laden"); return false; } - Log.JNI.info("Bild von " + source + " geladen"); + Log.IO.info("Bild von " + source + " geladen"); if(img.getWidth() == 64 && img.getHeight() == 32) { img = convertSkin(img); - Log.JNI.info("Skin " + source + " konvertiert"); + Log.IO.info("Skin " + source + " konvertiert"); } else if(img.getWidth() != 64 || img.getHeight() != 64) { - Log.JNI.warn("Falsche Bildgröße von " + source + ": " + img.getWidth() + "x" + img.getHeight()); + Log.IO.warn("Falsche Bildgröße von " + source + ": " + img.getWidth() + "x" + img.getHeight()); return false; } String name = source.getName(); @@ -195,7 +195,7 @@ public abstract class SkinConverter { name = "skin"; if(slim) { img = convertSlim(img); - Log.JNI.info("Skin " + source + " von 'Slim' konvertiert"); + Log.IO.info("Skin " + source + " von 'Slim' konvertiert"); if(!name.startsWith("slim_")) name = "slim_" + name; } @@ -217,10 +217,10 @@ public abstract class SkinConverter { ImageIO.write(img, "png", file); } catch(Exception e) { - Log.JNI.error(e, "Konnte Bild nicht speichern"); + Log.IO.error(e, "Konnte Bild nicht speichern"); return false; } - Log.JNI.info("Skin " + source + " gespeichert als " + file.getName()); + Log.IO.info("Skin " + source + " gespeichert als " + file.getName()); return true; } diff --git a/client/src/client/world/WorldClient.java b/client/src/client/world/WorldClient.java index 332afa5..1874f1e 100755 --- a/client/src/client/world/WorldClient.java +++ b/client/src/client/world/WorldClient.java @@ -125,7 +125,7 @@ public class WorldClient extends AWorldClient } if (System.currentTimeMillis() - time > 100L) { - Log.JNI.info("Warnung: Render-Chunk-Tick dauerte " + (System.currentTimeMillis() - time) + " ms"); + Log.TICK.warn("Render-Chunk-Tick dauerte " + (System.currentTimeMillis() - time) + " ms"); } this.updateBlocks(); } diff --git a/common/src/common/attributes/Attributes.java b/common/src/common/attributes/Attributes.java index 6a1ccc6..3705099 100755 --- a/common/src/common/attributes/Attributes.java +++ b/common/src/common/attributes/Attributes.java @@ -107,7 +107,7 @@ public class Attributes } else { - Log.JNI.warn("Ignoriere unbekannte Attribute \'" + nbttagcompound.getString("Name") + "\'"); + Log.TICK.warn("Ignoriere unbekannte Attribute \'" + nbttagcompound.getString("Name") + "\'"); } } } @@ -154,7 +154,7 @@ public class Attributes } catch (Exception exception) { - Log.JNI.warn("Konnte Attribute nicht erstellen: " + exception.getMessage()); + Log.TICK.warn("Konnte Attribute nicht erstellen: " + exception.getMessage()); return null; } } diff --git a/common/src/common/biome/Biome.java b/common/src/common/biome/Biome.java index 2ae9bb6..b13fcab 100644 --- a/common/src/common/biome/Biome.java +++ b/common/src/common/biome/Biome.java @@ -121,7 +121,7 @@ public enum Biome { } else { - Log.JNI.warn("Biom-ID ist nicht im Bereich: " + id + ", verwende " + DEF_BIOME.id + " (" + DEF_BIOME.name + ")"); + Log.TICK.warn("Biom-ID ist nicht im Bereich: " + id + ", verwende " + DEF_BIOME.id + " (" + DEF_BIOME.name + ")"); return DEF_BIOME; } } @@ -135,7 +135,7 @@ public enum Biome { } else { - Log.JNI.warn("Biom-ID ist nicht im Bereich: " + id + ", verwende " + DEF_BIOME.id + " (" + DEF_BIOME.name + ")"); + Log.TICK.warn("Biom-ID ist nicht im Bereich: " + id + ", verwende " + DEF_BIOME.id + " (" + DEF_BIOME.name + ")"); return DEF_BIOME; } } diff --git a/common/src/common/entity/EntityTrackerEntry.java b/common/src/common/entity/EntityTrackerEntry.java index fdcfcb0..fa99ad1 100755 --- a/common/src/common/entity/EntityTrackerEntry.java +++ b/common/src/common/entity/EntityTrackerEntry.java @@ -388,7 +388,7 @@ public class EntityTrackerEntry { private Packet createSpawnPacket() { if(this.trackedEntity.dead) { - Log.JNI.warn("Erstelle Spawn-Paket für entferntes Objekt"); + Log.TICK.warn("Erstelle Spawn-Paket für entferntes Objekt"); } SPacketSpawnObject packet = null; diff --git a/common/src/common/entity/item/EntityItem.java b/common/src/common/entity/item/EntityItem.java index 82f47e4..513df22 100755 --- a/common/src/common/entity/item/EntityItem.java +++ b/common/src/common/entity/item/EntityItem.java @@ -507,7 +507,7 @@ public class EntityItem extends Entity { if (this.worldObj != null) { - Log.JNI.warn("Gegenstand-Objekt " + this.getId() + " hat kein Item?!"); + Log.TICK.warn("Gegenstand-Objekt " + this.getId() + " hat kein Item?!"); } return new ItemStack(Blocks.stone); diff --git a/common/src/common/init/EntityRegistry.java b/common/src/common/init/EntityRegistry.java index 7e58afe..d4c2695 100755 --- a/common/src/common/init/EntityRegistry.java +++ b/common/src/common/init/EntityRegistry.java @@ -140,7 +140,7 @@ public abstract class EntityRegistry { entity.readFromNBT(nbt); } else { - Log.JNI.warn("Ignoriere Objekt mit Name " + nbt.getString("id")); + Log.TICK.warn("Ignoriere Objekt mit Name " + nbt.getString("id")); } return entity; @@ -161,7 +161,7 @@ public abstract class EntityRegistry { } if(entity == null) { - Log.JNI.warn("Ignoriere Objekt mit ID " + entityID); + Log.TICK.warn("Ignoriere Objekt mit ID " + entityID); } return entity; @@ -195,7 +195,7 @@ public abstract class EntityRegistry { } if(entity == null) { - Log.JNI.warn("Ignoriere Objekt mit ID " + entityID); + Log.TICK.warn("Ignoriere Objekt mit ID " + entityID); } return entity; diff --git a/common/src/common/init/UniverseRegistry.java b/common/src/common/init/UniverseRegistry.java index 4fffd2f..a011345 100755 --- a/common/src/common/init/UniverseRegistry.java +++ b/common/src/common/init/UniverseRegistry.java @@ -144,7 +144,7 @@ public abstract class UniverseRegistry { for(int z = 0; z < list.tagCount(); z++) { NBTTagCompound link = list.getCompoundTagAt(z); if(!assign(link.getString("Celestial"), link.getString("Center"))) - Log.JNI.warn("Konnte '" + link.getString("Celestial") + "' nicht zu '" + link.getString("Center") + "' zuweisen"); + Log.TICK.warn("Konnte '" + link.getString("Celestial") + "' nicht zu '" + link.getString("Center") + "' zuweisen"); } } diff --git a/common/src/common/log/Log.java b/common/src/common/log/Log.java index 712bd3d..3bdb65a 100644 --- a/common/src/common/log/Log.java +++ b/common/src/common/log/Log.java @@ -17,7 +17,6 @@ public enum Log { CONSOLE("Console"), TICK("Tick"), SOUND("Sound"), - JNI("JNI"), NETWORK("Network"); private static class LogMessage { diff --git a/common/src/common/nbt/NBTTagList.java b/common/src/common/nbt/NBTTagList.java index c20a725..4052a77 100755 --- a/common/src/common/nbt/NBTTagList.java +++ b/common/src/common/nbt/NBTTagList.java @@ -106,7 +106,7 @@ public class NBTTagList extends NBTBase { if (nbt.getId() == 0) { - Log.JNI.warn("Ungültiger End-Tag zu Tag-Liste hinzugefügt"); + Log.IO.warn("Ungültiger End-Tag zu Tag-Liste hinzugefügt"); } else { @@ -116,7 +116,7 @@ public class NBTTagList extends NBTBase } else if (this.tagType != nbt.getId()) { - Log.JNI.warn("Füge ungleiche Tag-Typen zu Tag-Liste hinzu"); + Log.IO.warn("Füge ungleiche Tag-Typen zu Tag-Liste hinzu"); return; } @@ -131,7 +131,7 @@ public class NBTTagList extends NBTBase { if (nbt.getId() == 0) { - Log.JNI.warn("Ungültiger End-Tag zu Tag-Liste hinzugefügt"); + Log.IO.warn("Ungültiger End-Tag zu Tag-Liste hinzugefügt"); } else if (idx >= 0 && idx < this.tagList.size()) { @@ -141,7 +141,7 @@ public class NBTTagList extends NBTBase } else if (this.tagType != nbt.getId()) { - Log.JNI.warn("Füge ungleiche Tag-Typen zu Tag-Liste hinzu"); + Log.IO.warn("Füge ungleiche Tag-Typen zu Tag-Liste hinzu"); return; } @@ -149,7 +149,7 @@ public class NBTTagList extends NBTBase } else { - Log.JNI.warn("Index außerhalb des Bereiches um Tag in Tag-Liste zu setzen"); + Log.IO.warn("Index außerhalb des Bereiches um Tag in Tag-Liste zu setzen"); } } diff --git a/common/src/common/potion/PotionEffect.java b/common/src/common/potion/PotionEffect.java index ccbfae5..dd0357c 100755 --- a/common/src/common/potion/PotionEffect.java +++ b/common/src/common/potion/PotionEffect.java @@ -36,7 +36,7 @@ public class PotionEffect { public PotionEffect combine(PotionEffect other) { if(this.potion != other.potion) - Log.JNI.warn("PotionEffect.combine(): Diese Methode sollte nur für gleiche Effekte aufgerufen werden!"); + Log.TICK.warn("PotionEffect.combine(): Diese Methode sollte nur für gleiche Effekte aufgerufen werden!"); int duration = this.duration; int amplifier = this.amplifier; int remaining = this.remaining; diff --git a/common/src/common/tileentity/TileEntity.java b/common/src/common/tileentity/TileEntity.java index ce17bb0..e65d5d9 100755 --- a/common/src/common/tileentity/TileEntity.java +++ b/common/src/common/tileentity/TileEntity.java @@ -102,7 +102,7 @@ public abstract class TileEntity } else { - Log.JNI.warn("Ignoriere Block-Objekt mit ID " + nbt.getString("id")); + Log.TICK.warn("Ignoriere Block-Objekt mit ID " + nbt.getString("id")); } return tileentity; diff --git a/common/src/common/world/Chunk.java b/common/src/common/world/Chunk.java index 359339a..c70a379 100755 --- a/common/src/common/world/Chunk.java +++ b/common/src/common/world/Chunk.java @@ -475,7 +475,7 @@ public abstract class Chunk { int z = ExtMath.floord(entity.posZ / 16.0D); if(x != this.xPos || z != this.zPos) { - Log.JNI.warn("Falsche Position! (" + x + ", " + z + ") sollte (" + this.xPos + ", " + this.zPos + ") sein, " + entity); + Log.TICK.warn("Falsche Position! (" + x + ", " + z + ") sollte (" + this.xPos + ", " + this.zPos + ") sein, " + entity); entity.setDead(); } diff --git a/server/src/server/Server.java b/server/src/server/Server.java index 2928f08..7f77ed6 100755 --- a/server/src/server/Server.java +++ b/server/src/server/Server.java @@ -153,7 +153,7 @@ public final class Server implements IThreadListener { long time = System.currentTimeMillis(); Util.checkOs(); Registry.setup("Server thread"); - Log.JNI.info("Starte " + Config.NAME + " Server Version " + Config.VERSION); + Log.SYSTEM.info("Starte " + Config.NAME + " Server Version " + Config.VERSION); GenBiome.setAsProvider(); UniverseRegistry.register(); RotationRegistry.register(); @@ -287,7 +287,7 @@ public final class Server implements IThreadListener { } } catch(Exception e) { - Log.JNI.error(e, "Konnte Spielerdaten für " + user + " (offline) nicht laden"); + Log.IO.error(e, "Konnte Spielerdaten für " + user + " (offline) nicht laden"); } return tag; } @@ -305,7 +305,7 @@ public final class Server implements IThreadListener { tmp.renameTo(dat); } catch(Exception e) { - Log.JNI.error(e, "Konnte Spielerdaten für " + user + " (offline) nicht speichern"); + Log.IO.error(e, "Konnte Spielerdaten für " + user + " (offline) nicht speichern"); } } @@ -328,7 +328,7 @@ public final class Server implements IThreadListener { if(this.debug) return; if(message) - Log.JNI.info("Speichere Welt"); + Log.TICK.info("Speichere Welt"); this.saveWorldInfo(); for(WorldServer world : this.worlds) { world.saveAllChunks(); @@ -518,18 +518,18 @@ public final class Server implements IThreadListener { }, "Server console handler"); con.setDaemon(true); con.start(); - Log.JNI.info("Server gestartet in " + String.format("%.1f", (double)(System.currentTimeMillis() - time) / 1000.0) + " Sekunden"); + Log.SYSTEM.info("Server gestartet in " + String.format("%.1f", (double)(System.currentTimeMillis() - time) / 1000.0) + " Sekunden"); while(this.running) { this.currentTime = System.nanoTime() / 1000L; this.timePassed = this.currentTime - this.lastSchedule; this.lastSchedule = this.currentTime; if(this.timePassed < 0L) { - Log.JNI.warn("Zeit lief rückwärts! Hat sich die Systemzeit geändert?"); + Log.TICK.warn("Zeit lief rückwärts! Hat sich die Systemzeit geändert?"); this.timePassed = 0L; this.ticksTodo = 0L; } if(this.timePassed > 2000000L && this.currentTime - this.lastWarning >= 15000000L) { - Log.JNI.warn("Kann Server-Tick nicht aufrecht erhalten! Hat sich die Systemzeit geändert, oder ist der Server überlastet? " + + Log.TICK.warn("Kann Server-Tick nicht aufrecht erhalten! Hat sich die Systemzeit geändert, oder ist der Server überlastet? " + "Liege " + (this.timePassed / 1000L) + " ms zurück, überspringe " + ((this.timePassed * this.tpsTarget) / 1000000000L) + " Tick(s)"); this.timePassed = 0L; this.lastWarning = this.currentTime; @@ -553,11 +553,11 @@ public final class Server implements IThreadListener { this.stopped = true; } catch(Throwable e) { - Log.JNI.error(e, "Fehler beim Beenden des Servers"); + Log.SYSTEM.error(e, "Fehler beim Beenden des Servers"); } finally { this.stopped = true; - Log.JNI.info("Server wurde beendet"); + Log.SYSTEM.info("Server wurde beendet"); } } @@ -565,7 +565,7 @@ public final class Server implements IThreadListener { int done = 0; int total = Config.distance * 2 + 1; total *= total; - Log.JNI.info("Generiere und lade Welt"); + Log.TICK.info("Generiere und lade Welt"); // WorldServer world = this.getWorld(Config.spawnDim); // world = world == null ? this.space : world; bx = bx >> 4; @@ -575,7 +575,7 @@ public final class Server implements IThreadListener { for(int z = -Config.distance; z <= Config.distance; z++) { long time = System.currentTimeMillis(); if(time - last > 1000L) { - Log.JNI.info("Bereite Spawnbereich vor" + ": " + (done * 100 / total) + "%"); + Log.TICK.info("Bereite Spawnbereich vor" + ": " + (done * 100 / total) + "%"); last = time; } ++done; @@ -630,10 +630,10 @@ public final class Server implements IThreadListener { } catch(ExecutionException e1) { if(!(e1.getCause() instanceof ThreadQuickExitException)) - Log.JNI.error(e1, "Fehler beim Ausführen von Server-Task " + task); // throw new RuntimeException(e1); + Log.SYSTEM.error(e1, "Fehler beim Ausführen von Server-Task " + task); // throw new RuntimeException(e1); } catch(InterruptedException e2) { - Log.JNI.error(e2, "Fehler beim Ausführen von Server-Task " + task); + Log.SYSTEM.error(e2, "Fehler beim Ausführen von Server-Task " + task); } } } @@ -827,13 +827,13 @@ public final class Server implements IThreadListener { if(loginPass.length() < Config.minPassLength) return "Passwort ist zu kurz, mindestens " + Config.minPassLength + " Zeichen"; conn.setPassword(loginPass); - Log.JNI.info(loginUser + " registrierte sich mit Passwort"); + Log.NETWORK.info(loginUser + " registrierte sich mit Passwort"); } else if(!conn.getPassword().equals(loginPass)) { return "Falsches Passwort"; } else { - Log.JNI.info(loginUser + " loggte sich mit Passwort ein"); + Log.NETWORK.info(loginUser + " loggte sich mit Passwort ein"); } if(Config.compression >= 0) { connection.sendPacket(new RPacketEnableCompression(Config.compression), new ChannelFutureListener() { @@ -859,7 +859,7 @@ public final class Server implements IThreadListener { if(tag == null) /* this.movePlayerToSpawn(player); */ player.moveToBlockPosAndAngles(new BlockPos(0, 16384, 0), 0.0f, 0.0f); - Log.JNI.info(loginUser + "[" + connection.getCutAddress() + "] hat sich mit Objekt-ID " + Log.NETWORK.info(loginUser + "[" + connection.getCutAddress() + "] hat sich mit Objekt-ID " + player.getId() + " auf Level " + world.dimension.getDimensionId() + ": " + String.format("%.2f %.2f %.2f", player.posX, player.posY, player.posZ) + " verbunden (" + (tag == null ? "Charakter-Editor" : "'" + player.getCommandName() + "'") + ")"); @@ -922,7 +922,7 @@ public final class Server implements IThreadListener { } } catch(Exception e) { - Log.JNI.error(e, "Konnte Spielerdaten für " + user + " nicht laden"); + Log.IO.error(e, "Konnte Spielerdaten für " + user + " nicht laden"); } return tag; } @@ -952,7 +952,7 @@ public final class Server implements IThreadListener { tmp.renameTo(dat); } catch(Exception e) { - Log.JNI.error(e, "Konnte Spielerdaten für " + conn.getUser() + " nicht speichern"); + Log.IO.error(e, "Konnte Spielerdaten für " + conn.getUser() + " nicht speichern"); } } @@ -1162,7 +1162,7 @@ public final class Server implements IThreadListener { if(this.debug) return; if(message) { - Log.JNI.info("Speichere Spielerdaten"); + Log.TICK.info("Speichere Spielerdaten"); } for(Player conn : this.players) { this.writePlayer(conn); @@ -1192,13 +1192,13 @@ public final class Server implements IThreadListener { } synchronized(this.serverThread) { if(this.endpoint != null) { - Log.JNI.info("Schließe Port"); + Log.NETWORK.info("Schließe Port"); try { this.endpoint.channel().close().sync(); this.endpoint = null; } catch(InterruptedException e) { - Log.JNI.warn("Unterbrochen beim Schließen des Kanals"); + Log.NETWORK.warn("Unterbrochen beim Schließen des Kanals"); } } } @@ -1219,7 +1219,7 @@ public final class Server implements IThreadListener { manager.processReceivedPackets(); } catch(Exception e) { - Log.JNI.error(e, "Konnte Paket von " + manager.getCutAddress() + " nicht verarbeiten"); + Log.NETWORK.error(e, "Konnte Paket von " + manager.getCutAddress() + " nicht verarbeiten"); manager.sendPacket(new SPacketDisconnect(e.getMessage()), new GenericFutureListener>() { public void operationComplete(Future future) throws Exception { manager.closeChannel("Fehlerhaftes Datenpaket"); @@ -1243,12 +1243,12 @@ public final class Server implements IThreadListener { private void stopServer() { if(!this.stopped) { - Log.JNI.info("Beende Server"); + Log.SYSTEM.info("Beende Server"); this.terminateEndpoint(this.endMessage); if(this.started) { - Log.JNI.info("Speichere Spieler"); + Log.TICK.info("Speichere Spieler"); this.saveAllPlayerData(true); - Log.JNI.info("Speichere Welt"); + Log.TICK.info("Speichere Welt"); this.saveAllWorlds(true); Region.finishWrite(); } @@ -1262,7 +1262,7 @@ public final class Server implements IThreadListener { if(this.endpoint != null) this.terminateEndpoint("Wechsele auf Port " + port); // throw new IllegalStateException("Eingangspunkt bereits gesetzt"); - Log.JNI.info("Öffne Port %d auf 0.0.0.0 (Timeout %ds)", port, Config.timeout); + Log.NETWORK.info("Öffne Port %d auf 0.0.0.0 (Timeout %ds)", port, Config.timeout); this.endpoint = ((ServerBootstrap)((ServerBootstrap)(new ServerBootstrap()).channel(NioServerSocketChannel.class)).childHandler(new ChannelInitializer() { protected void initChannel(Channel channel) throws Exception { try { @@ -1283,7 +1283,7 @@ public final class Server implements IThreadListener { }).group(SERVER_NIO_EVENTLOOP.getValue()).localAddress((InetAddress)null, port)).bind().syncUninterruptibly(); } catch(Throwable e) { - Log.JNI.error(e, "**** KONNTE NICHT AN PORT " + port + " ANBINDEN!"); + Log.NETWORK.error(e, "**** KONNTE NICHT AN PORT " + port + " ANBINDEN!"); } } else { diff --git a/server/src/server/biome/GenBiome.java b/server/src/server/biome/GenBiome.java index 4c563e0..acd6bcc 100755 --- a/server/src/server/biome/GenBiome.java +++ b/server/src/server/biome/GenBiome.java @@ -173,7 +173,7 @@ public abstract class GenBiome implements IBiome { } else { - Log.JNI.warn("Biom-ID ist nicht im Bereich: " + id + ", verwende " + Biome.DEF_BIOME.id + " (" + Biome.DEF_BIOME.name + ")"); + Log.TICK.warn("Biom-ID ist nicht im Bereich: " + id + ", verwende " + Biome.DEF_BIOME.id + " (" + Biome.DEF_BIOME.name + ")"); return BIOMES[Biome.DEF_BIOME.id]; } } diff --git a/server/src/server/network/LoginHandler.java b/server/src/server/network/LoginHandler.java index dad02f7..eddcf77 100755 --- a/server/src/server/network/LoginHandler.java +++ b/server/src/server/network/LoginHandler.java @@ -46,19 +46,19 @@ public class LoginHandler extends NetHandler implements ILoginHandler { try { - Log.JNI.info("Trenne " + this.getConnectionInfo()); + Log.NETWORK.info("Trenne " + this.getConnectionInfo()); this.netManager.sendPacket(new RPacketDisconnect(reason)); this.netManager.closeChannel(reason); } catch (Exception exception) { - Log.JNI.error(exception, "Fehler beim Trennen des Spielers beim Login"); + Log.NETWORK.error(exception, "Fehler beim Trennen des Spielers beim Login"); } } public void onDisconnect(String reason) { - Log.JNI.info(this.getConnectionInfo() + " wurde beim Login getrennt: " + TextColor.stripCodes(reason)); + Log.NETWORK.info(this.getConnectionInfo() + " wurde beim Login getrennt: " + TextColor.stripCodes(reason)); } public String getConnectionInfo() diff --git a/server/src/server/network/Player.java b/server/src/server/network/Player.java index d1ca5d4..e8ce73a 100755 --- a/server/src/server/network/Player.java +++ b/server/src/server/network/Player.java @@ -1621,7 +1621,7 @@ public class Player extends NetHandler implements ICrafting, Executor, IPlayer public void disconnect(String message) { - Log.JNI.info("Trenne %s: %s", this.user, message); + Log.NETWORK.info("Trenne %s: %s", this.user, message); this.connection.sendPacket(new SPacketDisconnect(message), new GenericFutureListener < Future > () { public void operationComplete(Future p_operationComplete_1_) throws Exception @@ -1641,7 +1641,7 @@ public class Player extends NetHandler implements ICrafting, Executor, IPlayer public void onDisconnect(String reason) { - Log.JNI.info(this.user + " wurde getrennt: " + TextColor.stripCodes(reason)); + Log.NETWORK.info(this.user + " wurde getrennt: " + TextColor.stripCodes(reason)); this.server.sendPacket(new SPacketMessage(String.format("%s hat das Spiel verlassen", this.user), Type.FEED)); this.server.removePlayer(this); } @@ -2664,7 +2664,7 @@ public class Player extends NetHandler implements ICrafting, Executor, IPlayer } catch (Exception e) { - Log.JNI.error(e, "Konnte Handel nicht wählen"); + Log.TICK.error(e, "Konnte Handel nicht wählen"); } break; diff --git a/server/src/server/world/ChunkServer.java b/server/src/server/world/ChunkServer.java index 98ceb4d..f30ccc3 100644 --- a/server/src/server/world/ChunkServer.java +++ b/server/src/server/world/ChunkServer.java @@ -160,7 +160,7 @@ public class ChunkServer extends Chunk { public void setBiomes(byte[] biomes) { if(this.biomes.length != biomes.length) { - Log.JNI.warn("Konnte Biome des Chunks nicht setzen, Länge des Arrays ist " + biomes.length + " statt " + this.biomes.length); + Log.IO.warn("Konnte Biome des Chunks nicht setzen, Länge des Arrays ist " + biomes.length + " statt " + this.biomes.length); } else { for(int n = 0; n < this.biomes.length; ++n) { @@ -175,7 +175,7 @@ public class ChunkServer extends Chunk { public void setHeights(int[] map) { if(this.height.length != map.length) { - Log.JNI.warn("Konnte Höhen des Chunks nicht setzen, Länge des Arrays ist " + map.length + " statt " + this.height.length); + Log.IO.warn("Konnte Höhen des Chunks nicht setzen, Länge des Arrays ist " + map.length + " statt " + this.height.length); } else { for(int n = 0; n < this.height.length; ++n) { diff --git a/server/src/server/world/Converter.java b/server/src/server/world/Converter.java index 360288e..33f1ed6 100644 --- a/server/src/server/world/Converter.java +++ b/server/src/server/world/Converter.java @@ -193,7 +193,7 @@ public abstract class Converter { private static long postProgress(long start, int progress) { if(System.currentTimeMillis() - start >= 500L) { start = System.currentTimeMillis(); - Log.JNI.info("... " + progress + "%"); + Log.IO.info("... " + progress + "%"); } return start; } @@ -1006,7 +1006,7 @@ public abstract class Converter { int rx, rz; String[] reg = name.split("\\."); if(reg.length != 4) { - Log.JNI.warn("Unbekannte Region " + file); + Log.IO.warn("Unbekannte Region " + file); return start; } try { @@ -1014,7 +1014,7 @@ public abstract class Converter { rz = Integer.parseInt(reg[2]); } catch(NumberFormatException e) { - Log.JNI.warn("Unbekannte Region " + file); + Log.IO.warn("Unbekannte Region " + file); return start; } try { @@ -1031,7 +1031,7 @@ public abstract class Converter { } areas++; newreg = new Region(dir, rx * 4 + bx, rz * 4 + bz); - Log.JNI.info("Konvertiere " + file + " zu " + newreg.getFile() + " ..."); + Log.IO.info("Konvertiere " + file + " zu " + newreg.getFile() + " ..."); for(int nx = 0; nx < 8; nx++) { for(int nz = 0; nz < 8; nz++) { int x = bx << 3 | nx; @@ -1040,7 +1040,7 @@ public abstract class Converter { chunks++; DataInputStream in = oldreg.getInputStream(x, z); if(in == null) { - Log.JNI.warn("Konnte " + file.getPath() + "@" + x + "," + z + " nicht lesen"); + Log.IO.warn("Konnte " + file.getPath() + "@" + x + "," + z + " nicht lesen"); continue; } NBTTagCompound tag = NBTLoader.read(in); @@ -1063,7 +1063,7 @@ public abstract class Converter { } } oldreg.close(); - Log.JNI.info(file + ": " + areas + " Regionen, " + chunks + " Chunks"); + Log.IO.info(file + ": " + areas + " Regionen, " + chunks + " Chunks"); } catch(IOException e) { e.printStackTrace(); @@ -1080,13 +1080,13 @@ public abstract class Converter { ldat = new File("level.dat_old"); if(!ldat.exists()) return false; - Log.JNI.info("Welt wird konvertiert"); + Log.IO.info("Welt wird konvertiert"); NBTTagCompound nbt; try { nbt = NBTLoader.readGZip(ldat); } catch(Exception e) { - Log.JNI.error(e, "Fehler beim Lesen von level.dat"); + Log.IO.error(e, "Fehler beim Lesen von level.dat"); return false; } nbt = nbt.getCompoundTag("Data"); @@ -1103,44 +1103,44 @@ public abstract class Converter { Log.IO.info("Weltzeit: %d Ticks / %d Sekunden", wtime, wtime / 20L); Log.IO.info("Zuletzt geladen: %s", new SimpleDateFormat("dd.MM.yyyy HH:mm:ss").format(new Date(nbt.getLong("LastPlayed")))); if(ver != SaveVersion.RELEASE_1_13) { - Log.JNI.info("Konvertiere Chunk-Daten von region/*.mca,*.mcr"); + Log.IO.info("Konvertiere Chunk-Daten von region/*.mca,*.mcr"); File regionDir = new File("region"); if(regionDir.exists()) { File chunkDir = new File(new File("chunk"), "terra"); - Log.JNI.info("Konvertiere Welt nach '" + chunkDir + "' ..."); - Log.JNI.info("Durchsuche Ordner unter '" + regionDir + "' nach .mca- und .mcr-Dateien ..."); + Log.IO.info("Konvertiere Welt nach '" + chunkDir + "' ..."); + Log.IO.info("Durchsuche Ordner unter '" + regionDir + "' nach .mca- und .mcr-Dateien ..."); File[] files = regionDir.listFiles(new FilenameFilter() { public boolean accept(File file, String name) { return name.endsWith(".mca") || name.endsWith(".mcr"); } }); if(files.length == 0) { - Log.JNI.info("Keine .mca- oder .mcr-Dateien gefunden."); + Log.IO.info("Keine .mca- oder .mcr-Dateien gefunden."); } else { - Log.JNI.info("Ingesamt wurden " + files.length + " .mca-Dateien und .mcr-Dateien gefunden, konvertiere ..."); + Log.IO.info("Ingesamt wurden " + files.length + " .mca-Dateien und .mcr-Dateien gefunden, konvertiere ..."); if(ver == SaveVersion.RELEASE_1_9) - Log.JNI.info("Konvertiere von neuerer Version, dies wird Blöcke entfernen ..."); + Log.IO.info("Konvertiere von neuerer Version, dies wird Blöcke entfernen ..."); chunkDir.mkdirs(); int progress = 0; long time = System.currentTimeMillis(); long start = postProgress(time, 0); for(File file : files) { int percent = (int)Math.round(100.0D * (double)progress / (double)files.length); - Log.JNI.info("Konvertiere Chunk-Daten: " + file.getName() + " (" + progress + "/" + files.length + ")"); + Log.IO.info("Konvertiere Chunk-Daten: " + file.getName() + " (" + progress + "/" + files.length + ")"); start = convertChunks(chunkDir, file, start, progress, files.length); ++progress; start = postProgress(start, percent); } time = System.currentTimeMillis() - time; - Log.JNI.info("Fertig. Konversion dauerte " + ((time / 60000L) > 0 ? ((time / 60000L) + " Minuten und ") : "") + ((time / 1000L) % 60L) + " Sekunden."); + Log.IO.info("Fertig. Konversion dauerte " + ((time / 60000L) > 0 ? ((time / 60000L) + " Minuten und ") : "") + ((time / 1000L) % 60L) + " Sekunden."); } } } else { - Log.JNI.warn("Konvertiere keine Chunk-Daten, da Version zu neu"); + Log.IO.warn("Konvertiere keine Chunk-Daten, da Version zu neu"); } - Log.JNI.info("Konvertiere Daten von level.dat"); + Log.IO.info("Konvertiere Daten von level.dat"); Config.clear(); UniverseRegistry.clear(); if(nbt.hasKey("GameRules", 10)) { @@ -1150,19 +1150,19 @@ public abstract class Converter { Config.set(rule.getValue(), rules.getString(rule.getKey()), false); } } - Log.JNI.info("Speichere neue server.nbt ..."); + Log.IO.info("Speichere neue server.nbt ..."); Server.saveServerConfig(wtime); Weather weather = nbt.getBoolean("thundering") ? Weather.THUNDER : (nbt.getBoolean("raining") ? Weather.RAIN : Weather.CLEAR); if(weather != Weather.CLEAR) { NBTTagCompound dataTag = new NBTTagCompound(); dataTag.setString("Weather", weather.getName()); - Log.JNI.info("Speichere neue data.nbt ..."); + Log.IO.info("Speichere neue data.nbt ..."); File dataFile = new File(new File(new File("chunk"), "terra"), "data.nbt"); try { NBTLoader.writeGZip(dataTag, dataFile); } catch(Exception e) { - Log.JNI.error(e, "Konnte Weltdaten nicht speichern"); + Log.IO.error(e, "Konnte Weltdaten nicht speichern"); } } Log.IO.info("Welt wurde in %d Sekunden konvertiert", (System.currentTimeMillis() - cur) / 1000L); diff --git a/server/src/server/world/Region.java b/server/src/server/world/Region.java index 50921d6..3068116 100755 --- a/server/src/server/world/Region.java +++ b/server/src/server/world/Region.java @@ -153,14 +153,14 @@ public class Region { // this.file.seek((long)(512 + (x + z * 8) * 8192)); int size = this.sizes[x + z * 8]; // this.file.readShort(); if(size > 8192 /* - 2 */ || size < 0) { - Log.JNI.warn("Chunk-Region-Datei " + this.regFile + " hat eine ungültige Größe bei " + x + ", " + z + ", überspringe"); + Log.IO.warn("Chunk-Region-Datei " + this.regFile + " hat eine ungültige Größe bei " + x + ", " + z + ", überspringe"); return null; } byte[] data; if(size == 0) { File expand = getExpansionFile(this.folder, this.xPos * 8 + x, this.zPos * 8 + z); if(!expand.exists()) { - Log.JNI.warn("Chunk-Erweiterungs-Datei " + expand + " ist nicht vorhanden oder nicht lesbar, überspringe"); + Log.IO.warn("Chunk-Erweiterungs-Datei " + expand + " ist nicht vorhanden oder nicht lesbar, überspringe"); return null; } in = new FileInputStream(expand); @@ -183,7 +183,7 @@ public class Region { else { int pos = this.positions[x + z * 8] << 8; if(pos + size > this.file.length() - 512L || pos < 0) { - Log.JNI.warn("Chunk-Region-Datei " + this.regFile + " hat eine ungültige Position bei " + x + ", " + z + ", überspringe"); + Log.IO.warn("Chunk-Region-Datei " + this.regFile + " hat eine ungültige Position bei " + x + ", " + z + ", überspringe"); return null; } this.file.seek(512L + (long)pos); @@ -200,7 +200,7 @@ public class Region { } catch(IOException e1) { } - Log.JNI.error(e, "Fehler beim lesen von Chunk-Region-Datei " + this.regFile + " bei " + x + ", " + z + ", überspringe"); + Log.IO.error(e, "Fehler beim lesen von Chunk-Region-Datei " + this.regFile + " bei " + x + ", " + z + ", überspringe"); return null; } } @@ -366,7 +366,7 @@ public class Region { // } // tag = tag.getCompoundTag("Level"); if(!tag.hasKey("Sections", 9)) { - Log.JNI.warn("Chunk-Datei bei " + x + "," + z + " hat keine Block-Daten, überspringe"); + Log.IO.warn("Chunk-Datei bei " + x + "," + z + " hat keine Block-Daten, überspringe"); return null; } ChunkServer chunk = new ChunkServer(world, x, z); @@ -472,12 +472,12 @@ public class Region { tick.getInteger("t"), tick.getInteger("p")); } else if(invalid++ < 10) { - Log.JNI.warn("Unbekannter Block-Tick in Chunk " + x + "," + z + ": " + + Log.IO.warn("Unbekannter Block-Tick in Chunk " + x + "," + z + ": " + (tick.hasKey("i", 8) ? ("'" + tick.getString("i") + "'") : ("#" + tick.getInteger("i")))); } } if(invalid > 10) { - Log.JNI.warn((invalid - 10) + " weitere ..."); + Log.IO.warn((invalid - 10) + " weitere ..."); } } } diff --git a/server/src/server/world/WorldServer.java b/server/src/server/world/WorldServer.java index 7079f71..75633f8 100755 --- a/server/src/server/world/WorldServer.java +++ b/server/src/server/world/WorldServer.java @@ -305,7 +305,7 @@ public final class WorldServer extends AWorldServer { tag = NBTLoader.readGZip(dat); } catch(Exception e) { - Log.JNI.error(e, "Konnte Weltdaten nicht laden"); + Log.IO.error(e, "Konnte Weltdaten nicht laden"); } if(tag != null) { this.exterminated = tag.getBoolean("Exterminated"); @@ -447,7 +447,7 @@ public final class WorldServer extends AWorldServer { tag = NBTLoader.readGZip(dat); } catch(Exception e) { - Log.JNI.error(e, "Konnte Ladeliste nicht laden"); + Log.IO.error(e, "Konnte Ladeliste nicht laden"); } if(tag != null && tag.hasKey("Loaders", 9)) { NBTTagList list = tag.getTagList("Loaders", 10); @@ -483,7 +483,7 @@ public final class WorldServer extends AWorldServer { tag = NBTLoader.readGZip(dat); } catch(Exception e) { - Log.JNI.error(e, "Konnte Dorfliste nicht laden"); + Log.IO.error(e, "Konnte Dorfliste nicht laden"); } this.villageStorage = new VillageCollection(tag); } @@ -949,7 +949,7 @@ public final class WorldServer extends AWorldServer { tag = NBTLoader.readGZip(dat); } catch(Exception e) { - Log.JNI.error(e, "Konnte Warpliste nicht laden"); + Log.IO.error(e, "Konnte Warpliste nicht laden"); return; } if(tag != null && tag.hasKey("Warps", 9)) { @@ -993,7 +993,7 @@ public final class WorldServer extends AWorldServer { NBTLoader.writeGZip(tag, file); } catch(Exception e) { - Log.JNI.error(e, "Konnte Warpliste nicht speichern"); + Log.IO.error(e, "Konnte Warpliste nicht speichern"); } } } @@ -1002,21 +1002,21 @@ public final class WorldServer extends AWorldServer { private static boolean deleteFiles(File[] files) { if(files == null) { - Log.JNI.warn("Konnte Ordner nicht löschen"); + Log.IO.warn("Konnte Ordner nicht löschen"); return false; } for(int i = 0; i < files.length; ++i) { File file = files[i]; - Log.JNI.info("Lösche " + file); + Log.IO.info("Lösche " + file); if(file.isDirectory() && !deleteFiles(file.listFiles())) { - Log.JNI.warn("Konnte Ordner " + file + " nicht löschen"); + Log.IO.warn("Konnte Ordner " + file + " nicht löschen"); return false; } if(!file.delete()) { - Log.JNI.warn("Konnte Datei " + file + " nicht löschen"); + Log.IO.warn("Konnte Datei " + file + " nicht löschen"); return false; } } @@ -1050,7 +1050,7 @@ public final class WorldServer extends AWorldServer { NBTLoader.writeGZip(loaders, file); } catch(Exception e) { - Log.JNI.error(e, "Konnte Ladeliste nicht speichern"); + Log.IO.error(e, "Konnte Ladeliste nicht speichern"); } } } @@ -1071,7 +1071,7 @@ public final class WorldServer extends AWorldServer { NBTLoader.writeGZip(data, file); } catch(Exception e) { - Log.JNI.error(e, "Konnte Weltdaten nicht speichern"); + Log.IO.error(e, "Konnte Weltdaten nicht speichern"); } // } for(int i = 0; i < this.dataList.size(); ++i) { @@ -1088,7 +1088,7 @@ public final class WorldServer extends AWorldServer { NBTLoader.writeGZip(tag, dat); } catch(Exception e) { - Log.JNI.error(e, "Konnte Dorfliste nicht speichern"); + Log.IO.error(e, "Konnte Dorfliste nicht speichern"); } } List list = Lists.newArrayList(this.loaded); @@ -1435,7 +1435,7 @@ public final class WorldServer extends AWorldServer { return chunk; } catch(Exception e) { - Log.JNI.error(e, "Konnte Chunk nicht laden"); + Log.IO.error(e, "Konnte Chunk nicht laden"); return null; } } @@ -1455,7 +1455,7 @@ public final class WorldServer extends AWorldServer { Region.queueIO(this); } catch(Exception e) { - Log.JNI.error(e, "Konnte Chunk nicht speichern"); + Log.IO.error(e, "Konnte Chunk nicht speichern"); } // } // catch(SaveException e) { @@ -1485,7 +1485,7 @@ public final class WorldServer extends AWorldServer { Region.writeChunk(this.chunkDir, coord.x, coord.z, tag); } catch(Exception e) { - Log.JNI.error(e, "Konnte Chunk nicht speichern"); + Log.IO.error(e, "Konnte Chunk nicht speichern"); } } flag = true; @@ -2127,7 +2127,7 @@ public final class WorldServer extends AWorldServer { entitytrackerentry.updatePlayerEntities(this.players); } catch(Throwable throwable) { - Log.JNI.error((Throwable)throwable, (String)"Fange Objekt-Tracking-Fehler \"leise\" auf."); + Log.TICK.error((Throwable)throwable, (String)"Fange Objekt-Tracking-Fehler \"leise\" auf."); } } @@ -2824,7 +2824,7 @@ public final class WorldServer extends AWorldServer { public void addPlayer(EntityNPC player) { if(this.watching.contains(player)) { - Log.JNI.warn("Konnte Spieler nicht hinzufügen. #" + player.getId() + " ist bereits in Chunk " + this.position.x + ", " + Log.TICK.warn("Konnte Spieler nicht hinzufügen. #" + player.getId() + " ist bereits in Chunk " + this.position.x + ", " + this.position.z); } else { diff --git a/server/src/server/worldgen/FeatureDungeons.java b/server/src/server/worldgen/FeatureDungeons.java index 0ea7248..9eeb4e3 100755 --- a/server/src/server/worldgen/FeatureDungeons.java +++ b/server/src/server/worldgen/FeatureDungeons.java @@ -157,7 +157,7 @@ public class FeatureDungeons } else { - Log.JNI.warn("Konnte kein Mob-Spawner-Objekt bei (" + position.getX() + ", " + position.getY() + ", " + position.getZ() + ") erstellen"); + Log.TICK.warn("Konnte kein Mob-Spawner-Objekt bei (" + position.getX() + ", " + position.getY() + ", " + position.getZ() + ") erstellen"); } return true; diff --git a/server/src/server/worldgen/layer/GenLayerHills.java b/server/src/server/worldgen/layer/GenLayerHills.java index c92a1f0..c2865ae 100755 --- a/server/src/server/worldgen/layer/GenLayerHills.java +++ b/server/src/server/worldgen/layer/GenLayerHills.java @@ -37,7 +37,7 @@ public class GenLayerHills extends GenLayer if (k > 255) { - Log.JNI.warn("Altes Biom (" + k + ")!"); + Log.TICK.warn("Altes Biom (" + k + ")!"); } if (k != 0 && l >= 2 && (l - 2) % 29 == 1 && k < 128) diff --git a/server/src/server/worldgen/structure/MapGenStructureIO.java b/server/src/server/worldgen/structure/MapGenStructureIO.java index 7418618..16a2ab6 100755 --- a/server/src/server/worldgen/structure/MapGenStructureIO.java +++ b/server/src/server/worldgen/structure/MapGenStructureIO.java @@ -51,7 +51,7 @@ public class MapGenStructureIO } catch (Exception exception) { - Log.JNI.warn("Fehler bei Strukturanfang mit ID " + tagCompound.getString("id")); + Log.TICK.warn("Fehler bei Strukturanfang mit ID " + tagCompound.getString("id")); exception.printStackTrace(); } @@ -61,7 +61,7 @@ public class MapGenStructureIO } else { - Log.JNI.warn("Überspringe Struktur mit ID " + tagCompound.getString("id")); + Log.TICK.warn("Überspringe Struktur mit ID " + tagCompound.getString("id")); } return structurestart; @@ -82,7 +82,7 @@ public class MapGenStructureIO } catch (Exception exception) { - Log.JNI.warn("Fehler bei Strukturteil mit ID " + tagCompound.getString("id")); + Log.TICK.warn("Fehler bei Strukturteil mit ID " + tagCompound.getString("id")); exception.printStackTrace(); } @@ -92,7 +92,7 @@ public class MapGenStructureIO } else { - Log.JNI.warn("Überspringe Strukturteil mit ID " + tagCompound.getString("id")); + Log.TICK.warn("Überspringe Strukturteil mit ID " + tagCompound.getString("id")); } return structurecomponent; From 20abca12f2b4e6993f4cca90949dc1a116761a61 Mon Sep 17 00:00:00 2001 From: Sen Date: Sun, 25 May 2025 18:33:08 +0200 Subject: [PATCH 080/200] remove server stop double logging --- server/src/server/Server.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/server/src/server/Server.java b/server/src/server/Server.java index 7f77ed6..3b70321 100755 --- a/server/src/server/Server.java +++ b/server/src/server/Server.java @@ -1246,9 +1246,7 @@ public final class Server implements IThreadListener { Log.SYSTEM.info("Beende Server"); this.terminateEndpoint(this.endMessage); if(this.started) { - Log.TICK.info("Speichere Spieler"); this.saveAllPlayerData(true); - Log.TICK.info("Speichere Welt"); this.saveAllWorlds(true); Region.finishWrite(); } From e2ec9f0c84cf2f04982b3dfcf087845c8c203a9d Mon Sep 17 00:00:00 2001 From: Sen Date: Sun, 25 May 2025 18:40:34 +0200 Subject: [PATCH 081/200] test chunk array perf --- client/src/client/world/ChunkClient.java | 3 +++ common/src/common/world/Chunk.java | 8 ++++++-- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/client/src/client/world/ChunkClient.java b/client/src/client/world/ChunkClient.java index 8f59b89..29bae3e 100644 --- a/client/src/client/world/ChunkClient.java +++ b/client/src/client/world/ChunkClient.java @@ -1,5 +1,7 @@ package client.world; +import java.util.Arrays; + import common.biome.Biome; import common.block.Block; import common.init.Blocks; @@ -16,6 +18,7 @@ public class ChunkClient extends Chunk { } private void clearArrays() { + Arrays.fill(this.core, null); this.blocks.clearMap(); this.blockList.clear(); this.bottom = Integer.MAX_VALUE; diff --git a/common/src/common/world/Chunk.java b/common/src/common/world/Chunk.java index c70a379..dc95a7d 100755 --- a/common/src/common/world/Chunk.java +++ b/common/src/common/world/Chunk.java @@ -29,6 +29,7 @@ public abstract class Chunk { protected final World world; protected final State filler; protected final Block fillerBlock; + protected final BlockArray[] core = new BlockArray[32]; protected final IntHashMap blocks = new IntHashMap(); protected final Set blockList = Sets.newHashSet(); protected final byte[] biomes = new byte[256]; @@ -69,12 +70,15 @@ public abstract class Chunk { } public BlockArray getArray(int y) { - return this.blocks.lookup(y); + return y >= -16 && y < 16 ? this.core[y + 16] : this.blocks.lookup(y); } protected void setArray(BlockArray array) { int y = array.getY() >> 4; - this.blocks.addKey(y, array); + if(y >= -16 && y < 16) + this.core[y + 16] = array; + else + this.blocks.addKey(y, array); this.blockList.add(array); y <<= 4; this.bottom = y < this.bottom ? y : this.bottom; From 8fed598b5140844cfe925c2f6f94827d39311ee7 Mon Sep 17 00:00:00 2001 From: Sen Date: Sun, 25 May 2025 18:41:45 +0200 Subject: [PATCH 082/200] Revert "test chunk array perf" This reverts commit e2ec9f0c84cf2f04982b3dfcf087845c8c203a9d. --- client/src/client/world/ChunkClient.java | 3 --- common/src/common/world/Chunk.java | 8 ++------ 2 files changed, 2 insertions(+), 9 deletions(-) diff --git a/client/src/client/world/ChunkClient.java b/client/src/client/world/ChunkClient.java index 29bae3e..8f59b89 100644 --- a/client/src/client/world/ChunkClient.java +++ b/client/src/client/world/ChunkClient.java @@ -1,7 +1,5 @@ package client.world; -import java.util.Arrays; - import common.biome.Biome; import common.block.Block; import common.init.Blocks; @@ -18,7 +16,6 @@ public class ChunkClient extends Chunk { } private void clearArrays() { - Arrays.fill(this.core, null); this.blocks.clearMap(); this.blockList.clear(); this.bottom = Integer.MAX_VALUE; diff --git a/common/src/common/world/Chunk.java b/common/src/common/world/Chunk.java index dc95a7d..c70a379 100755 --- a/common/src/common/world/Chunk.java +++ b/common/src/common/world/Chunk.java @@ -29,7 +29,6 @@ public abstract class Chunk { protected final World world; protected final State filler; protected final Block fillerBlock; - protected final BlockArray[] core = new BlockArray[32]; protected final IntHashMap blocks = new IntHashMap(); protected final Set blockList = Sets.newHashSet(); protected final byte[] biomes = new byte[256]; @@ -70,15 +69,12 @@ public abstract class Chunk { } public BlockArray getArray(int y) { - return y >= -16 && y < 16 ? this.core[y + 16] : this.blocks.lookup(y); + return this.blocks.lookup(y); } protected void setArray(BlockArray array) { int y = array.getY() >> 4; - if(y >= -16 && y < 16) - this.core[y + 16] = array; - else - this.blocks.addKey(y, array); + this.blocks.addKey(y, array); this.blockList.add(array); y <<= 4; this.bottom = y < this.bottom ? y : this.bottom; From f1219070d2fb360b2216ef0f5312747b67587200 Mon Sep 17 00:00:00 2001 From: Sen Date: Sun, 25 May 2025 20:00:30 +0200 Subject: [PATCH 083/200] fix invalid chars in splashes --- client/src/client/gui/Splashes.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/client/src/client/gui/Splashes.java b/client/src/client/gui/Splashes.java index 78711ab..41a2160 100644 --- a/client/src/client/gui/Splashes.java +++ b/client/src/client/gui/Splashes.java @@ -290,11 +290,11 @@ public abstract class Splashes { "Technologisch!", "Funk Soul Bruder!", "Pumpa kungen!", - "Hallo Japan!", + "Hallo Japan!", "Hallo Korea!", "Hallo Wales!", "Hallo Polen!", - "Hallo China!", + "Hallo China!", "Hallo Russland!", "Hallo Griechenland!", "Mein Leben für Aiur!", From 09149c7b88ca3550e4001a1e667f253c45bd37a9 Mon Sep 17 00:00:00 2001 From: Sen Date: Sun, 25 May 2025 20:11:35 +0200 Subject: [PATCH 084/200] update splashes --- client/src/client/gui/Splashes.java | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/client/src/client/gui/Splashes.java b/client/src/client/gui/Splashes.java index 41a2160..b2dded2 100644 --- a/client/src/client/gui/Splashes.java +++ b/client/src/client/gui/Splashes.java @@ -11,7 +11,7 @@ public abstract class Splashes { "Sexy!", "Limitierte Edition!", "Blinkende Buchstaben!", - "Erstellt von Notch!", + "Erstellt von Satan!", "Es ist hier!", "Das Beste seiner Klasse!", "Es ist vollendet!", @@ -138,7 +138,7 @@ public abstract class Splashes { "Cogito ergo sum!", "4815162342 Zeilen Quellcode (287228 am 30.7.)!", "Ein Skelett fiel heraus!", - "Das Werk von Notch!", + "Das Werk von Luzifer!", "Die Summe seiner Teile!", "BTAF war mal gut!", "Ich vermisse ADOM!", @@ -226,14 +226,14 @@ public abstract class Splashes { "Es ist bahnbrechend!", "Lasst unsere Schlachten beginnen!", "Der Himmel ist die Grenze - oder auch nicht!", - "Jeb hat tolle Haare!", + "Dein PC hat tolle Haare, mach das Ding mal sauber!", "Ryan hat auch tolle Haare!", "Gelegentliches Spielen!", "Unbesiegt!", "Ein Bisschen wie Lemmings!", "Folge dem Zug, CJ!", "Macht von Synergie Verwendung!", - "Diese Nachricht wird niemals als Splash-Text erscheinen, ist das nicht komisch?", + "Diese Nachricht sollte niemals als Splash-Text erscheinen, ist das nicht komisch? Trololololol!", "DungeonQuest ist unfair!", "0815!", "666!", @@ -262,7 +262,7 @@ public abstract class Splashes { "Verschwende keine Zeit mit den Klonen!", "Kürbiskopf!", "Hobo humping slobo babe!", - "Erstellt von Jeb!", + "Erstellt von einer Katze!", "Hat kein Ende!", "Endlich vollständig!", "Voll mit Features!", @@ -409,6 +409,7 @@ public abstract class Splashes { "Eimer mit Wasser!", "Hergestellt in Deutschland!", "Hergestellt in China!", - "Jetzt mit Einzelspieler!" + "Jetzt ohne Einzelspieler!", + "Jetzt mit tieferen Schluchten!" }; } From 93d997c3c08170a857cd0d740f3e8c30697eab00 Mon Sep 17 00:00:00 2001 From: Sen Date: Sun, 25 May 2025 20:20:46 +0200 Subject: [PATCH 085/200] fix window position restoration on client startup --- client/src/client/window/Window.java | 1 + 1 file changed, 1 insertion(+) diff --git a/client/src/client/window/Window.java b/client/src/client/window/Window.java index 515c79c..a66933e 100644 --- a/client/src/client/window/Window.java +++ b/client/src/client/window/Window.java @@ -243,6 +243,7 @@ public abstract class Window { glfwShowWindow(window); // wcf_show(win, 1); // wcf_limits(win, 1, 1, -1, -1); + glfwSetWindowMonitor(window, NULL, xpos, ypos, xsize, ysize, GLFW_DONT_CARE); // set position twice to work around bugs in some tiling window managers } public static WindowEvent[] poll() { From a62dc2309dd690f715edc9f83fa7944c07bc01ee Mon Sep 17 00:00:00 2001 From: Sen Date: Sun, 25 May 2025 20:43:52 +0200 Subject: [PATCH 086/200] fix audio issues + potential crash --- client/src/client/Client.java | 2 +- client/src/client/audio/AudioInterface.java | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/client/src/client/Client.java b/client/src/client/Client.java index d4ae164..571da67 100755 --- a/client/src/client/Client.java +++ b/client/src/client/Client.java @@ -455,7 +455,7 @@ public class Client implements IThreadListener { @Variable(name = "snd_enabled", category = CVarCategory.SOUND, display = "Tonausgabe") public boolean soundEnabled = true; @Variable(name = "snd_buffer_size", category = CVarCategory.SOUND, min = 0, max = 1048576, display = "Puffergröße") - public int soundBufferSize = 2048; + public int soundBufferSize = 16384; @Variable(name = "snd_frame_size", category = CVarCategory.SOUND, min = 2, max = 8192, display = "PCM-Intervall") public int soundFrameSize = 32; diff --git a/client/src/client/audio/AudioInterface.java b/client/src/client/audio/AudioInterface.java index 2e7c105..075b5df 100644 --- a/client/src/client/audio/AudioInterface.java +++ b/client/src/client/audio/AudioInterface.java @@ -138,12 +138,12 @@ public class AudioInterface implements Runnable { public void run() { AudioFormat format = new AudioFormat(Encoding.PCM_SIGNED, 48000, 16, 2, 2 * 2, 48000, false); - Info info = new Info(SourceDataLine.class, format, this.devbufsize); + Info info = new Info(SourceDataLine.class, format, this.devbufsize == 0 ? AudioSystem.NOT_SPECIFIED : this.devbufsize); try { this.line = (SourceDataLine)AudioSystem.getLine(info); - this.line.open(format, this.devbufsize); + this.line.open(format, this.devbufsize == 0 ? AudioSystem.NOT_SPECIFIED : this.devbufsize); } - catch(LineUnavailableException e) { + catch(Exception e) { this.line = null; Log.SOUND.error(e, "Konnte Audiogerät nicht öffnen"); } From 1d0dfddf25818e4d8ede839b3c552f29b6775820 Mon Sep 17 00:00:00 2001 From: Sen Date: Sun, 25 May 2025 20:49:48 +0200 Subject: [PATCH 087/200] remove unused import --- client/src/client/audio/AudioInterface.java | 1 - 1 file changed, 1 deletion(-) diff --git a/client/src/client/audio/AudioInterface.java b/client/src/client/audio/AudioInterface.java index 075b5df..47dbefd 100644 --- a/client/src/client/audio/AudioInterface.java +++ b/client/src/client/audio/AudioInterface.java @@ -11,7 +11,6 @@ import javax.sound.sampled.DataLine.Info; import common.collect.Lists; import common.log.Log; -import javax.sound.sampled.LineUnavailableException; import javax.sound.sampled.SourceDataLine; public class AudioInterface implements Runnable { From c0369d14b8ab3704b4b63164cb70ac6cbc62d6f7 Mon Sep 17 00:00:00 2001 From: Sen Date: Sun, 25 May 2025 20:55:53 +0200 Subject: [PATCH 088/200] fix ore generation height limit --- server/src/server/worldgen/FeatureOres.java | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/server/src/server/worldgen/FeatureOres.java b/server/src/server/worldgen/FeatureOres.java index abac8a1..bd61fc6 100755 --- a/server/src/server/worldgen/FeatureOres.java +++ b/server/src/server/worldgen/FeatureOres.java @@ -5,6 +5,7 @@ import common.rng.Random; import common.util.BlockPos; import common.util.ExtMath; import common.world.State; +import common.world.World; import server.world.WorldServer; public class FeatureOres @@ -41,18 +42,18 @@ public class FeatureOres this.oreBlock = state; this.distributed = dist; if(this.distributed) { - min = min < 0 ? 0 : (min > 511 ? 511 : min); - max = max < 0 ? 0 : (max > 512 ? 512 : max); - if(min + max > 511) { - max = 512 - min; + min = min < -World.MAX_SIZE_Y ? -World.MAX_SIZE_Y : (min > World.MAX_SIZE_Y - 1 ? World.MAX_SIZE_Y - 1 : min); + max = max < -World.MAX_SIZE_Y ? -World.MAX_SIZE_Y : (max > World.MAX_SIZE_Y ? World.MAX_SIZE_Y : max); + if(min + max > World.MAX_SIZE_Y - 1) { + max = World.MAX_SIZE_Y - min; } if(min - max < 0) { max = min; } } else { - min = min < 0 ? 0 : (min > 512 ? 512 : min); - max = max < 0 ? 0 : (max > 512 ? 512 : max); + min = min < -World.MAX_SIZE_Y ? -World.MAX_SIZE_Y : (min > World.MAX_SIZE_Y ? World.MAX_SIZE_Y : min); + max = max < -World.MAX_SIZE_Y ? -World.MAX_SIZE_Y : (max > World.MAX_SIZE_Y ? World.MAX_SIZE_Y : max); if (max < min) { int i = min; @@ -61,7 +62,7 @@ public class FeatureOres } else if (max == min) { - if (min < 511) + if (min < World.MAX_SIZE_Y - 1) { ++max; } From e66758cd737ae5b9bb0f811423e3b12e6d24bc78 Mon Sep 17 00:00:00 2001 From: Sen Date: Sun, 25 May 2025 21:32:32 +0200 Subject: [PATCH 089/200] add cloud type and skybox enums --- common/src/common/dimension/Dimension.java | 58 +++++--------------- common/src/common/init/UniverseRegistry.java | 3 +- common/src/common/world/CloudType.java | 39 +++++++++++++ common/src/common/world/SkyboxType.java | 37 +++++++++++++ 4 files changed, 92 insertions(+), 45 deletions(-) create mode 100644 common/src/common/world/CloudType.java create mode 100644 common/src/common/world/SkyboxType.java diff --git a/common/src/common/dimension/Dimension.java b/common/src/common/dimension/Dimension.java index 315dc8f..9eee678 100755 --- a/common/src/common/dimension/Dimension.java +++ b/common/src/common/dimension/Dimension.java @@ -2,14 +2,11 @@ package common.dimension; import java.util.List; import java.util.Map; -import java.util.Set; - import common.biome.Biome; import common.biome.IBiome; import common.block.foliage.LeavesType; import common.collect.Lists; import common.collect.Maps; -import common.collect.Sets; import common.init.BlockRegistry; import common.init.Blocks; import common.init.MetalType; @@ -19,6 +16,8 @@ import common.nbt.NBTTagList; import common.nbt.NBTTagString; import common.util.ExtMath; import common.util.Vec3; +import common.world.CloudType; +import common.world.SkyboxType; import common.world.State; import common.world.Weather; @@ -196,19 +195,8 @@ public abstract class Dimension extends Nameable implements Comparable SAFE_CHARS = Sets.newHashSet(); - -// private static final FeatureOres[] DEFAULT_ORES; -// -// static { -// List ores = Lists.newArrayList(); -// OreRegistry.populateDefault(ores); -// DEFAULT_ORES = new FeatureOres[ores.size()]; -// for(int z = 0; z < DEFAULT_ORES.length; z++) { -// DEFAULT_ORES[z] = ores.get(z).createGenerator(); -// } -// } private final int id; private final String name; @@ -223,8 +211,8 @@ public abstract class Dimension extends Nameable implements Comparable 32) - return fallback; - for(int z = 0; z < name.length(); z++) { - if(!SAFE_CHARS.contains(name.charAt(z))) { - return fallback; - } - } - return name; - } - public Dimension(int id, String name) { this.id = id; this.name = name; @@ -599,7 +569,7 @@ public abstract class Dimension extends Nameable implements Comparable LOOKUP = Maps.newHashMap(); + + private final String name; + private final String texture; + + private CloudType(String name, String texture) { + this.name = name; + this.texture = texture; + } + + public String toString() { + return this.name; + } + + public String getTexture() { + return this.texture; + } + + public static CloudType getByName(String name) { + CloudType type = LOOKUP.get(name.toLowerCase()); + return type == null ? NORMAL : type; + } + + static { + for(CloudType type : values()) { + LOOKUP.put(type.name, type); + } + } +} \ No newline at end of file diff --git a/common/src/common/world/SkyboxType.java b/common/src/common/world/SkyboxType.java new file mode 100644 index 0000000..950989f --- /dev/null +++ b/common/src/common/world/SkyboxType.java @@ -0,0 +1,37 @@ +package common.world; + +import java.util.Map; + +import common.collect.Maps; + +public enum SkyboxType { + ; + + private static final Map LOOKUP = Maps.newHashMap(); + + private final String name; + private final String texture; + + private SkyboxType(String name, String texture) { + this.name = name; + this.texture = texture; + } + + public String toString() { + return this.name; + } + + public String getTexture() { + return this.texture; + } + + public static SkyboxType getByName(String name) { + return LOOKUP.get(name.toLowerCase()); + } + + static { + for(SkyboxType type : values()) { + LOOKUP.put(type.name, type); + } + } +} \ No newline at end of file From 0b2ad9f92ddf7346867077579d8717ce45c0f297 Mon Sep 17 00:00:00 2001 From: Sen Date: Sun, 25 May 2025 21:34:16 +0200 Subject: [PATCH 090/200] cleanup --- .../{world => dimension}/CloudType.java | 2 +- common/src/common/dimension/Dimension.java | 62 +------------------ .../{world => dimension}/SkyboxType.java | 2 +- common/src/common/init/UniverseRegistry.java | 2 +- 4 files changed, 4 insertions(+), 64 deletions(-) rename common/src/common/{world => dimension}/CloudType.java (96%) rename common/src/common/{world => dimension}/SkyboxType.java (95%) diff --git a/common/src/common/world/CloudType.java b/common/src/common/dimension/CloudType.java similarity index 96% rename from common/src/common/world/CloudType.java rename to common/src/common/dimension/CloudType.java index e3ccbd9..a3f1b14 100644 --- a/common/src/common/world/CloudType.java +++ b/common/src/common/dimension/CloudType.java @@ -1,4 +1,4 @@ -package common.world; +package common.dimension; import java.util.Map; diff --git a/common/src/common/dimension/Dimension.java b/common/src/common/dimension/Dimension.java index 9eee678..97302ef 100755 --- a/common/src/common/dimension/Dimension.java +++ b/common/src/common/dimension/Dimension.java @@ -16,8 +16,6 @@ import common.nbt.NBTTagList; import common.nbt.NBTTagString; import common.util.ExtMath; import common.util.Vec3; -import common.world.CloudType; -import common.world.SkyboxType; import common.world.State; import common.world.Weather; @@ -41,59 +39,6 @@ public abstract class Dimension extends Nameable implements Comparable Date: Sun, 25 May 2025 22:02:31 +0200 Subject: [PATCH 091/200] add ore min heights --- common/src/common/dimension/Dimension.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/common/src/common/dimension/Dimension.java b/common/src/common/dimension/Dimension.java index 97302ef..c4ac4e0 100755 --- a/common/src/common/dimension/Dimension.java +++ b/common/src/common/dimension/Dimension.java @@ -140,8 +140,8 @@ public abstract class Dimension extends Nameable implements Comparable Date: Mon, 26 May 2025 11:10:08 +0200 Subject: [PATCH 092/200] change netty to modified version from initial commit --- client/src/client/Client.java | 22 +- client/src/client/gui/GuiInfo.java | 2 +- .../client/network/ClientLoginHandler.java | 4 +- .../net/bootstrap/AbstractBootstrap.java | 474 +++++ .../src/common/net/bootstrap/Bootstrap.java | 233 ++ .../common/net/bootstrap/ChannelFactory.java | 29 + .../common/net/bootstrap/ServerBootstrap.java | 332 +++ .../common/net/buffer/AbstractByteBuf.java | 1190 +++++++++++ .../net/buffer/AbstractByteBufAllocator.java | 219 ++ .../net/buffer/AbstractDerivedByteBuf.java | 67 + .../AbstractReferenceCountedByteBuf.java | 140 ++ .../net/buffer/AdvancedLeakAwareByteBuf.java | 724 +++++++ common/src/common/net/buffer/ByteBuf.java | 1879 +++++++++++++++++ .../common/net/buffer/ByteBufAllocator.java | 128 ++ .../common/net/buffer/ByteBufInputStream.java | 257 +++ .../net/buffer/ByteBufOutputStream.java | 146 ++ .../common/net/buffer/ByteBufProcessor.java | 126 ++ common/src/common/net/buffer/ByteBufUtil.java | 483 +++++ .../common/net/buffer/CompositeByteBuf.java | 1602 ++++++++++++++ .../common/net/buffer/DuplicatedByteBuf.java | 305 +++ .../src/common/net/buffer/EmptyByteBuf.java | 870 ++++++++ common/src/common/net/buffer/PoolArena.java | 477 +++++ common/src/common/net/buffer/PoolChunk.java | 431 ++++ .../src/common/net/buffer/PoolChunkList.java | 129 ++ common/src/common/net/buffer/PoolSubpage.java | 213 ++ .../common/net/buffer/PoolThreadCache.java | 485 +++++ .../src/common/net/buffer/PooledByteBuf.java | 160 ++ .../net/buffer/PooledByteBufAllocator.java | 334 +++ .../net/buffer/PooledDirectByteBuf.java | 377 ++++ .../common/net/buffer/PooledHeapByteBuf.java | 307 +++ .../net/buffer/PooledUnsafeDirectByteBuf.java | 394 ++++ .../common/net/buffer/ReadOnlyByteBuf.java | 317 +++ .../net/buffer/ReadOnlyByteBufferBuf.java | 335 +++ .../buffer/ReadOnlyUnsafeDirectByteBuf.java | 138 ++ .../net/buffer/SimpleLeakAwareByteBuf.java | 79 + .../src/common/net/buffer/SlicedByteBuf.java | 296 +++ .../src/common/net/buffer/SwappedByteBuf.java | 852 ++++++++ common/src/common/net/buffer/Unpooled.java | 861 ++++++++ .../net/buffer/UnpooledByteBufAllocator.java | 62 + .../net/buffer/UnpooledDirectByteBuf.java | 604 ++++++ .../net/buffer/UnpooledHeapByteBuf.java | 449 ++++ .../buffer/UnpooledUnsafeDirectByteBuf.java | 524 +++++ .../net/buffer/UnreleasableByteBuf.java | 87 + .../buffer/UnsafeDirectSwappedByteBuf.java | 186 ++ .../src/common/net/buffer/WrappedByteBuf.java | 827 ++++++++ .../common/net/channel/AbstractChannel.java | 873 ++++++++ .../AbstractChannelHandlerContext.java | 1000 +++++++++ .../net/channel/AbstractServerChannel.java | 83 + .../channel/AdaptiveRecvByteBufAllocator.java | 182 ++ common/src/common/net/channel/Channel.java | 511 +++++ .../src/common/net/channel/ChannelConfig.java | 249 +++ .../common/net/channel/ChannelException.java | 51 + .../src/common/net/channel/ChannelFuture.java | 192 ++ .../net/channel/ChannelFutureListener.java | 74 + .../common/net/channel/ChannelHandler.java | 211 ++ .../net/channel/ChannelHandlerAdapter.java | 80 + .../net/channel/ChannelHandlerContext.java | 489 +++++ .../net/channel/ChannelInboundHandler.java | 74 + .../channel/ChannelInboundHandlerAdapter.java | 133 ++ .../net/channel/ChannelInitializer.java | 82 + .../common/net/channel/ChannelMetadata.java | 44 + .../src/common/net/channel/ChannelOption.java | 111 + .../net/channel/ChannelOutboundBuffer.java | 650 ++++++ .../net/channel/ChannelOutboundHandler.java | 99 + .../ChannelOutboundHandlerAdapter.java | 117 + .../common/net/channel/ChannelPipeline.java | 872 ++++++++ .../net/channel/ChannelPipelineException.java | 52 + .../channel/ChannelProgressivePromise.java | 86 + .../common/net/channel/ChannelPromise.java | 63 + .../net/channel/CompleteChannelFuture.java | 107 + .../net/channel/ConnectTimeoutException.java | 33 + .../net/channel/DefaultChannelConfig.java | 355 ++++ .../channel/DefaultChannelHandlerContext.java | 45 + .../net/channel/DefaultChannelPipeline.java | 1067 ++++++++++ .../net/channel/DefaultChannelPromise.java | 159 ++ .../channel/DefaultMessageSizeEstimator.java | 71 + common/src/common/net/channel/EventLoop.java | 30 + .../net/channel/EventLoopException.java | 41 + .../common/net/channel/EventLoopGroup.java | 43 + .../net/channel/FailedChannelFuture.java | 65 + .../net/channel/MessageSizeEstimator.java | 39 + .../channel/MultithreadEventLoopGroup.java | 71 + .../net/channel/RecvByteBufAllocator.java | 54 + .../src/common/net/channel/ServerChannel.java | 25 + .../channel/SimpleChannelInboundHandler.java | 129 ++ .../net/channel/SingleThreadEventLoop.java | 72 + .../net/channel/SucceededChannelFuture.java | 45 + .../net/channel/VoidChannelPromise.java | 205 ++ .../net/channel/local/LocalAddress.java | 94 + .../net/channel/local/LocalChannel.java | 383 ++++ .../channel/local/LocalChannelRegistry.java | 62 + .../net/channel/local/LocalEventLoop.java | 42 + .../channel/local/LocalEventLoopGroup.java | 59 + .../net/channel/local/LocalServerChannel.java | 164 ++ .../channel/nio/AbstractNioByteChannel.java | 347 +++ .../net/channel/nio/AbstractNioChannel.java | 460 ++++ .../nio/AbstractNioMessageChannel.java | 187 ++ .../common/net/channel/nio/NioEventLoop.java | 691 ++++++ .../net/channel/nio/NioEventLoopGroup.java | 87 + .../src/common/net/channel/nio/NioTask.java | 40 + .../channel/nio/SelectedSelectionKeySet.java | 110 + .../socket/ChannelInputShutdownEvent.java | 33 + .../DefaultServerSocketChannelConfig.java | 203 ++ .../socket/DefaultSocketChannelConfig.java | 348 +++ .../channel/socket/ServerSocketChannel.java | 32 + .../socket/ServerSocketChannelConfig.java | 104 + .../net/channel/socket/SocketChannel.java | 61 + .../channel/socket/SocketChannelConfig.java | 177 ++ .../socket/nio/NioServerSocketChannel.java | 197 ++ .../channel/socket/nio/NioSocketChannel.java | 320 +++ .../handler/codec/ByteToMessageDecoder.java | 306 +++ .../net/handler/codec/CodecException.java | 51 + .../codec/CorruptedFrameException.java | 52 + .../net/handler/codec/DecoderException.java | 51 + .../net/handler/codec/EncoderException.java | 51 + .../handler/codec/MessageToByteEncoder.java | 154 ++ .../codec/MessageToMessageDecoder.java | 115 + .../handler/timeout/ReadTimeoutException.java | 29 + .../handler/timeout/ReadTimeoutHandler.java | 218 ++ .../net/handler/timeout/TimeoutException.java | 34 + common/src/common/net/util/Attribute.java | 67 + common/src/common/net/util/AttributeKey.java | 49 + common/src/common/net/util/AttributeMap.java | 29 + common/src/common/net/util/CharsetUtil.java | 117 + .../common/net/util/DefaultAttributeMap.java | 179 ++ .../util/IllegalReferenceCountException.java | 48 + common/src/common/net/util/NetUtil.java | 614 ++++++ common/src/common/net/util/Recycler.java | 353 ++++ .../common/net/util/ReferenceCountUtil.java | 161 ++ .../src/common/net/util/ReferenceCounted.java | 63 + common/src/common/net/util/ResourceLeak.java | 32 + .../common/net/util/ResourceLeakDetector.java | 388 ++++ common/src/common/net/util/Signal.java | 77 + .../common/net/util/ThreadDeathWatcher.java | 241 +++ common/src/common/net/util/UniqueName.java | 117 + .../concurrent/AbstractEventExecutor.java | 157 ++ .../AbstractEventExecutorGroup.java | 116 + .../net/util/concurrent/AbstractFuture.java | 51 + .../BlockingOperationException.java | 41 + .../net/util/concurrent/CompleteFuture.java | 147 ++ .../util/concurrent/DefaultEventExecutor.java | 45 + .../concurrent/DefaultEventExecutorGroup.java | 48 + .../concurrent/DefaultFutureListeners.java | 86 + .../concurrent/DefaultProgressivePromise.java | 130 ++ .../net/util/concurrent/DefaultPromise.java | 876 ++++++++ .../util/concurrent/DefaultThreadFactory.java | 143 ++ .../net/util/concurrent/EventExecutor.java | 72 + .../util/concurrent/EventExecutorGroup.java | 112 + .../net/util/concurrent/FailedFuture.java | 69 + .../net/util/concurrent/FastThreadLocal.java | 244 +++ .../concurrent/FastThreadLocalThread.java | 72 + .../common/net/util/concurrent/Future.java | 168 ++ .../net/util/concurrent/FutureListener.java | 28 + .../concurrent/GenericFutureListener.java | 32 + .../GenericProgressiveFutureListener.java | 28 + .../util/concurrent/GlobalEventExecutor.java | 391 ++++ .../concurrent/ImmediateEventExecutor.java | 121 ++ .../util/concurrent/ImmediateExecutor.java | 37 + .../MultithreadEventExecutorGroup.java | 233 ++ .../util/concurrent/ProgressiveFuture.java | 47 + .../util/concurrent/ProgressivePromise.java | 65 + .../common/net/util/concurrent/Promise.java | 90 + .../net/util/concurrent/PromiseTask.java | 137 ++ .../net/util/concurrent/ScheduledFuture.java | 23 + .../util/concurrent/ScheduledFutureTask.java | 161 ++ .../concurrent/SingleThreadEventExecutor.java | 870 ++++++++ .../net/util/concurrent/SucceededFuture.java | 50 + .../common/net/util/internal/Cleaner0.java | 74 + .../common/net/util/internal/EmptyArrays.java | 39 + .../net/util/internal/IntegerHolder.java | 21 + .../util/internal/InternalThreadLocalMap.java | 309 +++ .../net/util/internal/MpscLinkedQueue.java | 397 ++++ .../util/internal/MpscLinkedQueueHeadRef.java | 54 + .../util/internal/MpscLinkedQueueNode.java | 65 + .../util/internal/MpscLinkedQueuePad0.java | 22 + .../util/internal/MpscLinkedQueuePad1.java | 25 + .../util/internal/MpscLinkedQueueTailRef.java | 54 + .../internal/NoOpTypeParameterMatcher.java | 24 + .../common/net/util/internal/OneTimeTask.java | 30 + .../net/util/internal/PlatformDependent.java | 844 ++++++++ .../net/util/internal/PlatformDependent0.java | 383 ++++ .../util/internal/RecyclableArrayList.java | 132 ++ .../RecyclableMpscLinkedQueueNode.java | 45 + .../common/net/util/internal/StringUtil.java | 274 +++ .../net/util/internal/SystemPropertyUtil.java | 223 ++ .../net/util/internal/ThreadLocalRandom.java | 336 +++ .../util/internal/TypeParameterMatcher.java | 177 ++ .../UnpaddedInternalThreadLocalMap.java | 55 + .../UnsafeAtomicIntegerFieldUpdater.java | 61 + .../UnsafeAtomicLongFieldUpdater.java | 61 + .../UnsafeAtomicReferenceFieldUpdater.java | 62 + .../logging/AbstractInternalLogger.java | 190 ++ .../internal/logging/FormattingTuple.java | 88 + .../internal/logging/InternalLogLevel.java | 42 + .../util/internal/logging/InternalLogger.java | 444 ++++ .../logging/InternalLoggerFactory.java | 91 + .../net/util/internal/logging/JdkLogger.java | 647 ++++++ .../internal/logging/JdkLoggerFactory.java | 32 + .../internal/logging/MessageFormatter.java | 427 ++++ .../common/network/CompressionDecoder.java | 10 +- .../common/network/CompressionEncoder.java | 6 +- .../src/common/network/EncryptionCodec.java | 5 +- .../src/common/network/EncryptionDecoder.java | 7 +- .../src/common/network/EncryptionEncoder.java | 7 +- common/src/common/network/NetConnection.java | 18 +- common/src/common/network/PacketBuffer.java | 10 +- common/src/common/network/PacketDecoder.java | 6 +- common/src/common/network/PacketEncoder.java | 6 +- .../src/common/network/PacketPrepender.java | 6 +- common/src/common/network/PacketSplitter.java | 10 +- server/src/server/Server.java | 26 +- server/src/server/network/Player.java | 4 +- 212 files changed, 45653 insertions(+), 73 deletions(-) create mode 100644 common/src/common/net/bootstrap/AbstractBootstrap.java create mode 100644 common/src/common/net/bootstrap/Bootstrap.java create mode 100644 common/src/common/net/bootstrap/ChannelFactory.java create mode 100644 common/src/common/net/bootstrap/ServerBootstrap.java create mode 100644 common/src/common/net/buffer/AbstractByteBuf.java create mode 100644 common/src/common/net/buffer/AbstractByteBufAllocator.java create mode 100644 common/src/common/net/buffer/AbstractDerivedByteBuf.java create mode 100644 common/src/common/net/buffer/AbstractReferenceCountedByteBuf.java create mode 100644 common/src/common/net/buffer/AdvancedLeakAwareByteBuf.java create mode 100644 common/src/common/net/buffer/ByteBuf.java create mode 100644 common/src/common/net/buffer/ByteBufAllocator.java create mode 100644 common/src/common/net/buffer/ByteBufInputStream.java create mode 100644 common/src/common/net/buffer/ByteBufOutputStream.java create mode 100644 common/src/common/net/buffer/ByteBufProcessor.java create mode 100644 common/src/common/net/buffer/ByteBufUtil.java create mode 100644 common/src/common/net/buffer/CompositeByteBuf.java create mode 100644 common/src/common/net/buffer/DuplicatedByteBuf.java create mode 100644 common/src/common/net/buffer/EmptyByteBuf.java create mode 100644 common/src/common/net/buffer/PoolArena.java create mode 100644 common/src/common/net/buffer/PoolChunk.java create mode 100644 common/src/common/net/buffer/PoolChunkList.java create mode 100644 common/src/common/net/buffer/PoolSubpage.java create mode 100644 common/src/common/net/buffer/PoolThreadCache.java create mode 100644 common/src/common/net/buffer/PooledByteBuf.java create mode 100644 common/src/common/net/buffer/PooledByteBufAllocator.java create mode 100644 common/src/common/net/buffer/PooledDirectByteBuf.java create mode 100644 common/src/common/net/buffer/PooledHeapByteBuf.java create mode 100644 common/src/common/net/buffer/PooledUnsafeDirectByteBuf.java create mode 100644 common/src/common/net/buffer/ReadOnlyByteBuf.java create mode 100644 common/src/common/net/buffer/ReadOnlyByteBufferBuf.java create mode 100644 common/src/common/net/buffer/ReadOnlyUnsafeDirectByteBuf.java create mode 100644 common/src/common/net/buffer/SimpleLeakAwareByteBuf.java create mode 100644 common/src/common/net/buffer/SlicedByteBuf.java create mode 100644 common/src/common/net/buffer/SwappedByteBuf.java create mode 100644 common/src/common/net/buffer/Unpooled.java create mode 100644 common/src/common/net/buffer/UnpooledByteBufAllocator.java create mode 100644 common/src/common/net/buffer/UnpooledDirectByteBuf.java create mode 100644 common/src/common/net/buffer/UnpooledHeapByteBuf.java create mode 100644 common/src/common/net/buffer/UnpooledUnsafeDirectByteBuf.java create mode 100644 common/src/common/net/buffer/UnreleasableByteBuf.java create mode 100644 common/src/common/net/buffer/UnsafeDirectSwappedByteBuf.java create mode 100644 common/src/common/net/buffer/WrappedByteBuf.java create mode 100644 common/src/common/net/channel/AbstractChannel.java create mode 100644 common/src/common/net/channel/AbstractChannelHandlerContext.java create mode 100644 common/src/common/net/channel/AbstractServerChannel.java create mode 100644 common/src/common/net/channel/AdaptiveRecvByteBufAllocator.java create mode 100644 common/src/common/net/channel/Channel.java create mode 100644 common/src/common/net/channel/ChannelConfig.java create mode 100644 common/src/common/net/channel/ChannelException.java create mode 100644 common/src/common/net/channel/ChannelFuture.java create mode 100644 common/src/common/net/channel/ChannelFutureListener.java create mode 100644 common/src/common/net/channel/ChannelHandler.java create mode 100644 common/src/common/net/channel/ChannelHandlerAdapter.java create mode 100644 common/src/common/net/channel/ChannelHandlerContext.java create mode 100644 common/src/common/net/channel/ChannelInboundHandler.java create mode 100644 common/src/common/net/channel/ChannelInboundHandlerAdapter.java create mode 100644 common/src/common/net/channel/ChannelInitializer.java create mode 100644 common/src/common/net/channel/ChannelMetadata.java create mode 100644 common/src/common/net/channel/ChannelOption.java create mode 100644 common/src/common/net/channel/ChannelOutboundBuffer.java create mode 100644 common/src/common/net/channel/ChannelOutboundHandler.java create mode 100644 common/src/common/net/channel/ChannelOutboundHandlerAdapter.java create mode 100644 common/src/common/net/channel/ChannelPipeline.java create mode 100644 common/src/common/net/channel/ChannelPipelineException.java create mode 100644 common/src/common/net/channel/ChannelProgressivePromise.java create mode 100644 common/src/common/net/channel/ChannelPromise.java create mode 100644 common/src/common/net/channel/CompleteChannelFuture.java create mode 100644 common/src/common/net/channel/ConnectTimeoutException.java create mode 100644 common/src/common/net/channel/DefaultChannelConfig.java create mode 100644 common/src/common/net/channel/DefaultChannelHandlerContext.java create mode 100644 common/src/common/net/channel/DefaultChannelPipeline.java create mode 100644 common/src/common/net/channel/DefaultChannelPromise.java create mode 100644 common/src/common/net/channel/DefaultMessageSizeEstimator.java create mode 100644 common/src/common/net/channel/EventLoop.java create mode 100644 common/src/common/net/channel/EventLoopException.java create mode 100644 common/src/common/net/channel/EventLoopGroup.java create mode 100644 common/src/common/net/channel/FailedChannelFuture.java create mode 100644 common/src/common/net/channel/MessageSizeEstimator.java create mode 100644 common/src/common/net/channel/MultithreadEventLoopGroup.java create mode 100644 common/src/common/net/channel/RecvByteBufAllocator.java create mode 100644 common/src/common/net/channel/ServerChannel.java create mode 100644 common/src/common/net/channel/SimpleChannelInboundHandler.java create mode 100644 common/src/common/net/channel/SingleThreadEventLoop.java create mode 100644 common/src/common/net/channel/SucceededChannelFuture.java create mode 100644 common/src/common/net/channel/VoidChannelPromise.java create mode 100644 common/src/common/net/channel/local/LocalAddress.java create mode 100644 common/src/common/net/channel/local/LocalChannel.java create mode 100644 common/src/common/net/channel/local/LocalChannelRegistry.java create mode 100644 common/src/common/net/channel/local/LocalEventLoop.java create mode 100644 common/src/common/net/channel/local/LocalEventLoopGroup.java create mode 100644 common/src/common/net/channel/local/LocalServerChannel.java create mode 100644 common/src/common/net/channel/nio/AbstractNioByteChannel.java create mode 100644 common/src/common/net/channel/nio/AbstractNioChannel.java create mode 100644 common/src/common/net/channel/nio/AbstractNioMessageChannel.java create mode 100644 common/src/common/net/channel/nio/NioEventLoop.java create mode 100644 common/src/common/net/channel/nio/NioEventLoopGroup.java create mode 100644 common/src/common/net/channel/nio/NioTask.java create mode 100644 common/src/common/net/channel/nio/SelectedSelectionKeySet.java create mode 100644 common/src/common/net/channel/socket/ChannelInputShutdownEvent.java create mode 100644 common/src/common/net/channel/socket/DefaultServerSocketChannelConfig.java create mode 100644 common/src/common/net/channel/socket/DefaultSocketChannelConfig.java create mode 100644 common/src/common/net/channel/socket/ServerSocketChannel.java create mode 100644 common/src/common/net/channel/socket/ServerSocketChannelConfig.java create mode 100644 common/src/common/net/channel/socket/SocketChannel.java create mode 100644 common/src/common/net/channel/socket/SocketChannelConfig.java create mode 100644 common/src/common/net/channel/socket/nio/NioServerSocketChannel.java create mode 100644 common/src/common/net/channel/socket/nio/NioSocketChannel.java create mode 100644 common/src/common/net/handler/codec/ByteToMessageDecoder.java create mode 100644 common/src/common/net/handler/codec/CodecException.java create mode 100644 common/src/common/net/handler/codec/CorruptedFrameException.java create mode 100644 common/src/common/net/handler/codec/DecoderException.java create mode 100644 common/src/common/net/handler/codec/EncoderException.java create mode 100644 common/src/common/net/handler/codec/MessageToByteEncoder.java create mode 100644 common/src/common/net/handler/codec/MessageToMessageDecoder.java create mode 100644 common/src/common/net/handler/timeout/ReadTimeoutException.java create mode 100644 common/src/common/net/handler/timeout/ReadTimeoutHandler.java create mode 100644 common/src/common/net/handler/timeout/TimeoutException.java create mode 100644 common/src/common/net/util/Attribute.java create mode 100644 common/src/common/net/util/AttributeKey.java create mode 100644 common/src/common/net/util/AttributeMap.java create mode 100644 common/src/common/net/util/CharsetUtil.java create mode 100644 common/src/common/net/util/DefaultAttributeMap.java create mode 100644 common/src/common/net/util/IllegalReferenceCountException.java create mode 100644 common/src/common/net/util/NetUtil.java create mode 100644 common/src/common/net/util/Recycler.java create mode 100644 common/src/common/net/util/ReferenceCountUtil.java create mode 100644 common/src/common/net/util/ReferenceCounted.java create mode 100644 common/src/common/net/util/ResourceLeak.java create mode 100644 common/src/common/net/util/ResourceLeakDetector.java create mode 100644 common/src/common/net/util/Signal.java create mode 100644 common/src/common/net/util/ThreadDeathWatcher.java create mode 100644 common/src/common/net/util/UniqueName.java create mode 100644 common/src/common/net/util/concurrent/AbstractEventExecutor.java create mode 100644 common/src/common/net/util/concurrent/AbstractEventExecutorGroup.java create mode 100644 common/src/common/net/util/concurrent/AbstractFuture.java create mode 100644 common/src/common/net/util/concurrent/BlockingOperationException.java create mode 100644 common/src/common/net/util/concurrent/CompleteFuture.java create mode 100644 common/src/common/net/util/concurrent/DefaultEventExecutor.java create mode 100644 common/src/common/net/util/concurrent/DefaultEventExecutorGroup.java create mode 100644 common/src/common/net/util/concurrent/DefaultFutureListeners.java create mode 100644 common/src/common/net/util/concurrent/DefaultProgressivePromise.java create mode 100644 common/src/common/net/util/concurrent/DefaultPromise.java create mode 100644 common/src/common/net/util/concurrent/DefaultThreadFactory.java create mode 100644 common/src/common/net/util/concurrent/EventExecutor.java create mode 100644 common/src/common/net/util/concurrent/EventExecutorGroup.java create mode 100644 common/src/common/net/util/concurrent/FailedFuture.java create mode 100644 common/src/common/net/util/concurrent/FastThreadLocal.java create mode 100644 common/src/common/net/util/concurrent/FastThreadLocalThread.java create mode 100644 common/src/common/net/util/concurrent/Future.java create mode 100644 common/src/common/net/util/concurrent/FutureListener.java create mode 100644 common/src/common/net/util/concurrent/GenericFutureListener.java create mode 100644 common/src/common/net/util/concurrent/GenericProgressiveFutureListener.java create mode 100644 common/src/common/net/util/concurrent/GlobalEventExecutor.java create mode 100644 common/src/common/net/util/concurrent/ImmediateEventExecutor.java create mode 100644 common/src/common/net/util/concurrent/ImmediateExecutor.java create mode 100644 common/src/common/net/util/concurrent/MultithreadEventExecutorGroup.java create mode 100644 common/src/common/net/util/concurrent/ProgressiveFuture.java create mode 100644 common/src/common/net/util/concurrent/ProgressivePromise.java create mode 100644 common/src/common/net/util/concurrent/Promise.java create mode 100644 common/src/common/net/util/concurrent/PromiseTask.java create mode 100644 common/src/common/net/util/concurrent/ScheduledFuture.java create mode 100644 common/src/common/net/util/concurrent/ScheduledFutureTask.java create mode 100644 common/src/common/net/util/concurrent/SingleThreadEventExecutor.java create mode 100644 common/src/common/net/util/concurrent/SucceededFuture.java create mode 100644 common/src/common/net/util/internal/Cleaner0.java create mode 100644 common/src/common/net/util/internal/EmptyArrays.java create mode 100644 common/src/common/net/util/internal/IntegerHolder.java create mode 100644 common/src/common/net/util/internal/InternalThreadLocalMap.java create mode 100644 common/src/common/net/util/internal/MpscLinkedQueue.java create mode 100644 common/src/common/net/util/internal/MpscLinkedQueueHeadRef.java create mode 100644 common/src/common/net/util/internal/MpscLinkedQueueNode.java create mode 100644 common/src/common/net/util/internal/MpscLinkedQueuePad0.java create mode 100644 common/src/common/net/util/internal/MpscLinkedQueuePad1.java create mode 100644 common/src/common/net/util/internal/MpscLinkedQueueTailRef.java create mode 100644 common/src/common/net/util/internal/NoOpTypeParameterMatcher.java create mode 100644 common/src/common/net/util/internal/OneTimeTask.java create mode 100644 common/src/common/net/util/internal/PlatformDependent.java create mode 100644 common/src/common/net/util/internal/PlatformDependent0.java create mode 100644 common/src/common/net/util/internal/RecyclableArrayList.java create mode 100644 common/src/common/net/util/internal/RecyclableMpscLinkedQueueNode.java create mode 100644 common/src/common/net/util/internal/StringUtil.java create mode 100644 common/src/common/net/util/internal/SystemPropertyUtil.java create mode 100644 common/src/common/net/util/internal/ThreadLocalRandom.java create mode 100644 common/src/common/net/util/internal/TypeParameterMatcher.java create mode 100644 common/src/common/net/util/internal/UnpaddedInternalThreadLocalMap.java create mode 100644 common/src/common/net/util/internal/UnsafeAtomicIntegerFieldUpdater.java create mode 100644 common/src/common/net/util/internal/UnsafeAtomicLongFieldUpdater.java create mode 100644 common/src/common/net/util/internal/UnsafeAtomicReferenceFieldUpdater.java create mode 100644 common/src/common/net/util/internal/logging/AbstractInternalLogger.java create mode 100644 common/src/common/net/util/internal/logging/FormattingTuple.java create mode 100644 common/src/common/net/util/internal/logging/InternalLogLevel.java create mode 100644 common/src/common/net/util/internal/logging/InternalLogger.java create mode 100644 common/src/common/net/util/internal/logging/InternalLoggerFactory.java create mode 100644 common/src/common/net/util/internal/logging/JdkLogger.java create mode 100644 common/src/common/net/util/internal/logging/JdkLoggerFactory.java create mode 100644 common/src/common/net/util/internal/logging/MessageFormatter.java diff --git a/client/src/client/Client.java b/client/src/client/Client.java index 571da67..7dcb511 100755 --- a/client/src/client/Client.java +++ b/client/src/client/Client.java @@ -130,6 +130,17 @@ import common.item.ItemControl; import common.item.ItemStack; import common.log.Log; import common.log.LogLevel; +import common.net.bootstrap.Bootstrap; +import common.net.channel.Channel; +import common.net.channel.ChannelException; +import common.net.channel.ChannelHandler; +import common.net.channel.ChannelInitializer; +import common.net.channel.ChannelOption; +import common.net.channel.nio.NioEventLoopGroup; +import common.net.channel.socket.nio.NioSocketChannel; +import common.net.handler.timeout.ReadTimeoutHandler; +import common.net.util.concurrent.Future; +import common.net.util.concurrent.GenericFutureListener; import common.network.IThreadListener; import common.network.NetConnection; import common.network.PacketDecoder; @@ -162,17 +173,6 @@ import common.util.HitPosition.ObjectType; import common.world.LightType; import common.world.State; import common.world.World; -import io.netty.bootstrap.Bootstrap; -import io.netty.channel.Channel; -import io.netty.channel.ChannelException; -import io.netty.channel.ChannelHandler; -import io.netty.channel.ChannelInitializer; -import io.netty.channel.ChannelOption; -import io.netty.channel.nio.NioEventLoopGroup; -import io.netty.channel.socket.nio.NioSocketChannel; -import io.netty.handler.timeout.ReadTimeoutHandler; -import io.netty.util.concurrent.Future; -import io.netty.util.concurrent.GenericFutureListener; /* Een net ganz funktionierndes Programm ... diff --git a/client/src/client/gui/GuiInfo.java b/client/src/client/gui/GuiInfo.java index 8c52e6c..8fe7c30 100644 --- a/client/src/client/gui/GuiInfo.java +++ b/client/src/client/gui/GuiInfo.java @@ -18,7 +18,7 @@ public class GuiInfo extends Gui { private static final String[] LIBRARIES = { "LWJGL 3.3.6+1 (GLFW + OpenGL)", - "Netty 4.0.23-Final" + "Netty 4.0.23-Final (modifiziert, verkleinert)" }; private static final String[] CODE = { "Albert Pham - WorldEdit (Snippets)", diff --git a/client/src/client/network/ClientLoginHandler.java b/client/src/client/network/ClientLoginHandler.java index c4d9a18..b0c4ed7 100755 --- a/client/src/client/network/ClientLoginHandler.java +++ b/client/src/client/network/ClientLoginHandler.java @@ -5,6 +5,8 @@ import java.security.PublicKey; import javax.crypto.SecretKey; import client.Client; +import common.net.util.concurrent.Future; +import common.net.util.concurrent.GenericFutureListener; import common.network.IClientLoginHandler; import common.network.NetConnection; import common.network.NetHandler; @@ -16,8 +18,6 @@ import common.packet.RPacketEnableCompression; import common.packet.RPacketLoginSuccess; import common.packet.RPacketRequestEncrypt; import common.util.EncryptUtil; -import io.netty.util.concurrent.Future; -import io.netty.util.concurrent.GenericFutureListener; public class ClientLoginHandler extends NetHandler implements IClientLoginHandler { private final Client gm; diff --git a/common/src/common/net/bootstrap/AbstractBootstrap.java b/common/src/common/net/bootstrap/AbstractBootstrap.java new file mode 100644 index 0000000..0bb9d8b --- /dev/null +++ b/common/src/common/net/bootstrap/AbstractBootstrap.java @@ -0,0 +1,474 @@ +/* + * Copyright 2012 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ + +package common.net.bootstrap; + +import java.net.InetAddress; +import java.net.InetSocketAddress; +import java.net.SocketAddress; +import java.util.LinkedHashMap; +import java.util.Map; + +import common.net.channel.Channel; +import common.net.channel.ChannelException; +import common.net.channel.ChannelFuture; +import common.net.channel.ChannelFutureListener; +import common.net.channel.ChannelHandler; +import common.net.channel.ChannelOption; +import common.net.channel.ChannelPromise; +import common.net.channel.DefaultChannelPromise; +import common.net.channel.EventLoopGroup; +import common.net.util.AttributeKey; +import common.net.util.concurrent.EventExecutor; +import common.net.util.concurrent.GlobalEventExecutor; +import common.net.util.internal.StringUtil; + +/** + * {@link AbstractBootstrap} is a helper class that makes it easy to bootstrap a {@link Channel}. It support + * method-chaining to provide an easy way to configure the {@link AbstractBootstrap}. + * + *

When not used in a {@link ServerBootstrap} context, the {@link #bind()} methods are useful for connectionless + * transports such as datagram (UDP).

+ */ +public abstract class AbstractBootstrap, C extends Channel> implements Cloneable { + + private volatile EventLoopGroup group; + private volatile ChannelFactory channelFactory; + private volatile SocketAddress localAddress; + private final Map, Object> options = new LinkedHashMap, Object>(); + private final Map, Object> attrs = new LinkedHashMap, Object>(); + private volatile ChannelHandler handler; + + AbstractBootstrap() { + // Disallow extending from a different package. + } + + AbstractBootstrap(AbstractBootstrap bootstrap) { + group = bootstrap.group; + channelFactory = bootstrap.channelFactory; + handler = bootstrap.handler; + localAddress = bootstrap.localAddress; + synchronized (bootstrap.options) { + options.putAll(bootstrap.options); + } + synchronized (bootstrap.attrs) { + attrs.putAll(bootstrap.attrs); + } + } + + /** + * The {@link EventLoopGroup} which is used to handle all the events for the to-be-creates + * {@link Channel} + */ + + public B group(EventLoopGroup group) { + if (group == null) { + throw new NullPointerException("group"); + } + if (this.group != null) { + throw new IllegalStateException("group set already"); + } + this.group = group; + return (B) this; + } + + /** + * The {@link Class} which is used to create {@link Channel} instances from. + * You either use this or {@link #channelFactory(ChannelFactory)} if your + * {@link Channel} implementation has no no-args constructor. + */ + public B channel(Class channelClass) { + if (channelClass == null) { + throw new NullPointerException("channelClass"); + } + return channelFactory(new BootstrapChannelFactory(channelClass)); + } + + /** + * {@link ChannelFactory} which is used to create {@link Channel} instances from + * when calling {@link #bind()}. This method is usually only used if {@link #channel(Class)} + * is not working for you because of some more complex needs. If your {@link Channel} implementation + * has a no-args constructor, its highly recommend to just use {@link #channel(Class)} for + * simplify your code. + */ + + public B channelFactory(ChannelFactory channelFactory) { + if (channelFactory == null) { + throw new NullPointerException("channelFactory"); + } + if (this.channelFactory != null) { + throw new IllegalStateException("channelFactory set already"); + } + + this.channelFactory = channelFactory; + return (B) this; + } + + /** + * The {@link SocketAddress} which is used to bind the local "end" to. + * + */ + + public B localAddress(SocketAddress localAddress) { + this.localAddress = localAddress; + return (B) this; + } + + /** + * @see {@link #localAddress(SocketAddress)} + */ + public B localAddress(int inetPort) { + return localAddress(new InetSocketAddress(inetPort)); + } + + /** + * @see {@link #localAddress(SocketAddress)} + */ + public B localAddress(String inetHost, int inetPort) { + return localAddress(new InetSocketAddress(inetHost, inetPort)); + } + + /** + * @see {@link #localAddress(SocketAddress)} + */ + public B localAddress(InetAddress inetHost, int inetPort) { + return localAddress(new InetSocketAddress(inetHost, inetPort)); + } + + /** + * Allow to specify a {@link ChannelOption} which is used for the {@link Channel} instances once they got + * created. Use a value of {@code null} to remove a previous set {@link ChannelOption}. + */ + + public B option(ChannelOption option, T value) { + if (option == null) { + throw new NullPointerException("option"); + } + if (value == null) { + synchronized (options) { + options.remove(option); + } + } else { + synchronized (options) { + options.put(option, value); + } + } + return (B) this; + } + + /** + * Allow to specify an initial attribute of the newly created {@link Channel}. If the {@code value} is + * {@code null}, the attribute of the specified {@code key} is removed. + */ + public B attr(AttributeKey key, T value) { + if (key == null) { + throw new NullPointerException("key"); + } + if (value == null) { + synchronized (attrs) { + attrs.remove(key); + } + } else { + synchronized (attrs) { + attrs.put(key, value); + } + } + + + B b = (B) this; + return b; + } + + /** + * Validate all the parameters. Sub-classes may override this, but should + * call the super method in that case. + */ + + public B validate() { + if (group == null) { + throw new IllegalStateException("group not set"); + } + if (channelFactory == null) { + throw new IllegalStateException("channel or channelFactory not set"); + } + return (B) this; + } + + /** + * Returns a deep clone of this bootstrap which has the identical configuration. This method is useful when making + * multiple {@link Channel}s with similar settings. Please note that this method does not clone the + * {@link EventLoopGroup} deeply but shallowly, making the group a shared resource. + */ + @Override + + public abstract B clone(); + + /** + * Create a new {@link Channel} and register it with an {@link EventLoop}. + */ + public ChannelFuture register() { + validate(); + return initAndRegister(); + } + + /** + * Create a new {@link Channel} and bind it. + */ + public ChannelFuture bind() { + validate(); + SocketAddress localAddress = this.localAddress; + if (localAddress == null) { + throw new IllegalStateException("localAddress not set"); + } + return doBind(localAddress); + } + + /** + * Create a new {@link Channel} and bind it. + */ + public ChannelFuture bind(int inetPort) { + return bind(new InetSocketAddress(inetPort)); + } + + /** + * Create a new {@link Channel} and bind it. + */ + public ChannelFuture bind(String inetHost, int inetPort) { + return bind(new InetSocketAddress(inetHost, inetPort)); + } + + /** + * Create a new {@link Channel} and bind it. + */ + public ChannelFuture bind(InetAddress inetHost, int inetPort) { + return bind(new InetSocketAddress(inetHost, inetPort)); + } + + /** + * Create a new {@link Channel} and bind it. + */ + public ChannelFuture bind(SocketAddress localAddress) { + validate(); + if (localAddress == null) { + throw new NullPointerException("localAddress"); + } + return doBind(localAddress); + } + + private ChannelFuture doBind(final SocketAddress localAddress) { + final ChannelFuture regFuture = initAndRegister(); + final Channel channel = regFuture.channel(); + if (regFuture.cause() != null) { + return regFuture; + } + + final ChannelPromise promise; + if (regFuture.isDone()) { + promise = channel.newPromise(); + doBind0(regFuture, channel, localAddress, promise); + } else { + // Registration future is almost always fulfilled already, but just in case it's not. + promise = new PendingRegistrationPromise(channel); + regFuture.addListener(new ChannelFutureListener() { + @Override + public void operationComplete(ChannelFuture future) throws Exception { + doBind0(regFuture, channel, localAddress, promise); + } + }); + } + + return promise; + } + + final ChannelFuture initAndRegister() { + final Channel channel = channelFactory().newChannel(); + try { + init(channel); + } catch (Throwable t) { + channel.unsafe().closeForcibly(); + // as the Channel is not registered yet we need to force the usage of the GlobalEventExecutor + return new DefaultChannelPromise(channel, GlobalEventExecutor.INSTANCE).setFailure(t); + } + + ChannelFuture regFuture = group().register(channel); + if (regFuture.cause() != null) { + if (channel.isRegistered()) { + channel.close(); + } else { + channel.unsafe().closeForcibly(); + } + } + + // If we are here and the promise is not failed, it's one of the following cases: + // 1) If we attempted registration from the event loop, the registration has been completed at this point. + // i.e. It's safe to attempt bind() or connect() now because the channel has been registered. + // 2) If we attempted registration from the other thread, the registration request has been successfully + // added to the event loop's task queue for later execution. + // i.e. It's safe to attempt bind() or connect() now: + // because bind() or connect() will be executed *after* the scheduled registration task is executed + // because register(), bind(), and connect() are all bound to the same thread. + + return regFuture; + } + + abstract void init(Channel channel) throws Exception; + + private static void doBind0( + final ChannelFuture regFuture, final Channel channel, + final SocketAddress localAddress, final ChannelPromise promise) { + + // This method is invoked before channelRegistered() is triggered. Give user handlers a chance to set up + // the pipeline in its channelRegistered() implementation. + channel.eventLoop().execute(new Runnable() { + @Override + public void run() { + if (regFuture.isSuccess()) { + channel.bind(localAddress, promise).addListener(ChannelFutureListener.CLOSE_ON_FAILURE); + } else { + promise.setFailure(regFuture.cause()); + } + } + }); + } + + /** + * the {@link ChannelHandler} to use for serving the requests. + */ + + public B handler(ChannelHandler handler) { + if (handler == null) { + throw new NullPointerException("handler"); + } + this.handler = handler; + return (B) this; + } + + final SocketAddress localAddress() { + return localAddress; + } + + final ChannelFactory channelFactory() { + return channelFactory; + } + + final ChannelHandler handler() { + return handler; + } + + /** + * Return the configured {@link EventLoopGroup} or {@code null} if non is configured yet. + */ + public final EventLoopGroup group() { + return group; + } + + final Map, Object> options() { + return options; + } + + final Map, Object> attrs() { + return attrs; + } + + @Override + public String toString() { + StringBuilder buf = new StringBuilder(); + buf.append(StringUtil.simpleClassName(this)); + buf.append('('); + if (group != null) { + buf.append("group: "); + buf.append(StringUtil.simpleClassName(group)); + buf.append(", "); + } + if (channelFactory != null) { + buf.append("channelFactory: "); + buf.append(channelFactory); + buf.append(", "); + } + if (localAddress != null) { + buf.append("localAddress: "); + buf.append(localAddress); + buf.append(", "); + } + synchronized (options) { + if (!options.isEmpty()) { + buf.append("options: "); + buf.append(options); + buf.append(", "); + } + } + synchronized (attrs) { + if (!attrs.isEmpty()) { + buf.append("attrs: "); + buf.append(attrs); + buf.append(", "); + } + } + if (handler != null) { + buf.append("handler: "); + buf.append(handler); + buf.append(", "); + } + if (buf.charAt(buf.length() - 1) == '(') { + buf.append(')'); + } else { + buf.setCharAt(buf.length() - 2, ')'); + buf.setLength(buf.length() - 1); + } + return buf.toString(); + } + + private static final class BootstrapChannelFactory implements ChannelFactory { + private final Class clazz; + + BootstrapChannelFactory(Class clazz) { + this.clazz = clazz; + } + + @Override + public T newChannel() { + try { + return clazz.newInstance(); + } catch (Throwable t) { + throw new ChannelException("Unable to create Channel from class " + clazz, t); + } + } + + @Override + public String toString() { + return StringUtil.simpleClassName(clazz) + ".class"; + } + } + + private static final class PendingRegistrationPromise extends DefaultChannelPromise { + private PendingRegistrationPromise(Channel channel) { + super(channel); + } + + @Override + protected EventExecutor executor() { + if (channel().isRegistered()) { + // If the registration was a success we can just call super.executor() which will return + // channel.eventLoop(). + // + // See https://github.com/netty/netty/issues/2586 + return super.executor(); + } + // The registration failed so we can only use the GlobalEventExecutor as last resort to notify. + return GlobalEventExecutor.INSTANCE; + } + } +} diff --git a/common/src/common/net/bootstrap/Bootstrap.java b/common/src/common/net/bootstrap/Bootstrap.java new file mode 100644 index 0000000..dd59fb0 --- /dev/null +++ b/common/src/common/net/bootstrap/Bootstrap.java @@ -0,0 +1,233 @@ +/* + * Copyright 2012 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ +package common.net.bootstrap; + +import java.net.InetAddress; +import java.net.InetSocketAddress; +import java.net.SocketAddress; +import java.util.Map; +import java.util.Map.Entry; + +import common.net.channel.Channel; +import common.net.channel.ChannelFuture; +import common.net.channel.ChannelFutureListener; +import common.net.channel.ChannelOption; +import common.net.channel.ChannelPipeline; +import common.net.channel.ChannelPromise; +import common.net.util.AttributeKey; +import common.net.util.internal.logging.InternalLogger; +import common.net.util.internal.logging.InternalLoggerFactory; + +/** + * A {@link Bootstrap} that makes it easy to bootstrap a {@link Channel} to use + * for clients. + * + *

The {@link #bind()} methods are useful in combination with connectionless transports such as datagram (UDP). + * For regular TCP connections, please use the provided {@link #connect()} methods.

+ */ +public final class Bootstrap extends AbstractBootstrap { + + private static final InternalLogger logger = InternalLoggerFactory.getInstance(Bootstrap.class); + + private volatile SocketAddress remoteAddress; + + public Bootstrap() { } + + private Bootstrap(Bootstrap bootstrap) { + super(bootstrap); + remoteAddress = bootstrap.remoteAddress; + } + + /** + * The {@link SocketAddress} to connect to once the {@link #connect()} method + * is called. + */ + public Bootstrap remoteAddress(SocketAddress remoteAddress) { + this.remoteAddress = remoteAddress; + return this; + } + + /** + * @see {@link #remoteAddress(SocketAddress)} + */ + public Bootstrap remoteAddress(String inetHost, int inetPort) { + remoteAddress = new InetSocketAddress(inetHost, inetPort); + return this; + } + + /** + * @see {@link #remoteAddress(SocketAddress)} + */ + public Bootstrap remoteAddress(InetAddress inetHost, int inetPort) { + remoteAddress = new InetSocketAddress(inetHost, inetPort); + return this; + } + + /** + * Connect a {@link Channel} to the remote peer. + */ + public ChannelFuture connect() { + validate(); + SocketAddress remoteAddress = this.remoteAddress; + if (remoteAddress == null) { + throw new IllegalStateException("remoteAddress not set"); + } + + return doConnect(remoteAddress, localAddress()); + } + + /** + * Connect a {@link Channel} to the remote peer. + */ + public ChannelFuture connect(String inetHost, int inetPort) { + return connect(new InetSocketAddress(inetHost, inetPort)); + } + + /** + * Connect a {@link Channel} to the remote peer. + */ + public ChannelFuture connect(InetAddress inetHost, int inetPort) { + return connect(new InetSocketAddress(inetHost, inetPort)); + } + + /** + * Connect a {@link Channel} to the remote peer. + */ + public ChannelFuture connect(SocketAddress remoteAddress) { + if (remoteAddress == null) { + throw new NullPointerException("remoteAddress"); + } + + validate(); + return doConnect(remoteAddress, localAddress()); + } + + /** + * Connect a {@link Channel} to the remote peer. + */ + public ChannelFuture connect(SocketAddress remoteAddress, SocketAddress localAddress) { + if (remoteAddress == null) { + throw new NullPointerException("remoteAddress"); + } + validate(); + return doConnect(remoteAddress, localAddress); + } + + /** + * @see {@link #connect()} + */ + private ChannelFuture doConnect(final SocketAddress remoteAddress, final SocketAddress localAddress) { + final ChannelFuture regFuture = initAndRegister(); + final Channel channel = regFuture.channel(); + if (regFuture.cause() != null) { + return regFuture; + } + + final ChannelPromise promise = channel.newPromise(); + if (regFuture.isDone()) { + doConnect0(regFuture, channel, remoteAddress, localAddress, promise); + } else { + regFuture.addListener(new ChannelFutureListener() { + @Override + public void operationComplete(ChannelFuture future) throws Exception { + doConnect0(regFuture, channel, remoteAddress, localAddress, promise); + } + }); + } + + return promise; + } + + private static void doConnect0( + final ChannelFuture regFuture, final Channel channel, + final SocketAddress remoteAddress, final SocketAddress localAddress, final ChannelPromise promise) { + + // This method is invoked before channelRegistered() is triggered. Give user handlers a chance to set up + // the pipeline in its channelRegistered() implementation. + channel.eventLoop().execute(new Runnable() { + @Override + public void run() { + if (regFuture.isSuccess()) { + if (localAddress == null) { + channel.connect(remoteAddress, promise); + } else { + channel.connect(remoteAddress, localAddress, promise); + } + promise.addListener(ChannelFutureListener.CLOSE_ON_FAILURE); + } else { + promise.setFailure(regFuture.cause()); + } + } + }); + } + + @Override + + void init(Channel channel) throws Exception { + ChannelPipeline p = channel.pipeline(); + p.addLast(handler()); + + final Map, Object> options = options(); + synchronized (options) { + for (Entry, Object> e: options.entrySet()) { + try { + if (!channel.config().setOption((ChannelOption) e.getKey(), e.getValue())) { + logger.warn("Unknown channel option: " + e); + } + } catch (Throwable t) { + logger.warn("Failed to set a channel option: " + channel, t); + } + } + } + + final Map, Object> attrs = attrs(); + synchronized (attrs) { + for (Entry, Object> e: attrs.entrySet()) { + channel.attr((AttributeKey) e.getKey()).set(e.getValue()); + } + } + } + + @Override + public Bootstrap validate() { + super.validate(); + if (handler() == null) { + throw new IllegalStateException("handler not set"); + } + return this; + } + + @Override + + public Bootstrap clone() { + return new Bootstrap(this); + } + + @Override + public String toString() { + if (remoteAddress == null) { + return super.toString(); + } + + StringBuilder buf = new StringBuilder(super.toString()); + buf.setLength(buf.length() - 1); + buf.append(", remoteAddress: "); + buf.append(remoteAddress); + buf.append(')'); + + return buf.toString(); + } +} diff --git a/common/src/common/net/bootstrap/ChannelFactory.java b/common/src/common/net/bootstrap/ChannelFactory.java new file mode 100644 index 0000000..d6e48e3 --- /dev/null +++ b/common/src/common/net/bootstrap/ChannelFactory.java @@ -0,0 +1,29 @@ +/* + * Copyright 2013 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ +package common.net.bootstrap; + +import common.net.channel.Channel; + +/** + * Factory that creates a new {@link Channel} on {@link Bootstrap#bind()}, {@link Bootstrap#connect()}, and + * {@link ServerBootstrap#bind()}. + */ +public interface ChannelFactory { + /** + * Creates a new channel. + */ + T newChannel(); +} diff --git a/common/src/common/net/bootstrap/ServerBootstrap.java b/common/src/common/net/bootstrap/ServerBootstrap.java new file mode 100644 index 0000000..96144f9 --- /dev/null +++ b/common/src/common/net/bootstrap/ServerBootstrap.java @@ -0,0 +1,332 @@ +/* + * Copyright 2012 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ +package common.net.bootstrap; + +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.Map.Entry; +import java.util.concurrent.TimeUnit; + +import common.net.channel.Channel; +import common.net.channel.ChannelConfig; +import common.net.channel.ChannelFuture; +import common.net.channel.ChannelFutureListener; +import common.net.channel.ChannelHandler; +import common.net.channel.ChannelHandlerContext; +import common.net.channel.ChannelInboundHandlerAdapter; +import common.net.channel.ChannelInitializer; +import common.net.channel.ChannelOption; +import common.net.channel.ChannelPipeline; +import common.net.channel.EventLoopGroup; +import common.net.channel.ServerChannel; +import common.net.util.AttributeKey; +import common.net.util.internal.StringUtil; +import common.net.util.internal.logging.InternalLogger; +import common.net.util.internal.logging.InternalLoggerFactory; + +/** + * {@link Bootstrap} sub-class which allows easy bootstrap of {@link ServerChannel} + * + */ +public final class ServerBootstrap extends AbstractBootstrap { + + private static final InternalLogger logger = InternalLoggerFactory.getInstance(ServerBootstrap.class); + + private final Map, Object> childOptions = new LinkedHashMap, Object>(); + private final Map, Object> childAttrs = new LinkedHashMap, Object>(); + private volatile EventLoopGroup childGroup; + private volatile ChannelHandler childHandler; + + public ServerBootstrap() { } + + private ServerBootstrap(ServerBootstrap bootstrap) { + super(bootstrap); + childGroup = bootstrap.childGroup; + childHandler = bootstrap.childHandler; + synchronized (bootstrap.childOptions) { + childOptions.putAll(bootstrap.childOptions); + } + synchronized (bootstrap.childAttrs) { + childAttrs.putAll(bootstrap.childAttrs); + } + } + + /** + * Specify the {@link EventLoopGroup} which is used for the parent (acceptor) and the child (client). + */ + @Override + public ServerBootstrap group(EventLoopGroup group) { + return group(group, group); + } + + /** + * Set the {@link EventLoopGroup} for the parent (acceptor) and the child (client). These + * {@link EventLoopGroup}'s are used to handle all the events and IO for {@link SocketChannel} and + * {@link Channel}'s. + */ + public ServerBootstrap group(EventLoopGroup parentGroup, EventLoopGroup childGroup) { + super.group(parentGroup); + if (childGroup == null) { + throw new NullPointerException("childGroup"); + } + if (this.childGroup != null) { + throw new IllegalStateException("childGroup set already"); + } + this.childGroup = childGroup; + return this; + } + + /** + * Allow to specify a {@link ChannelOption} which is used for the {@link Channel} instances once they get created + * (after the acceptor accepted the {@link Channel}). Use a value of {@code null} to remove a previous set + * {@link ChannelOption}. + */ + public ServerBootstrap childOption(ChannelOption childOption, T value) { + if (childOption == null) { + throw new NullPointerException("childOption"); + } + if (value == null) { + synchronized (childOptions) { + childOptions.remove(childOption); + } + } else { + synchronized (childOptions) { + childOptions.put(childOption, value); + } + } + return this; + } + + /** + * Set the specific {@link AttributeKey} with the given value on every child {@link Channel}. If the value is + * {@code null} the {@link AttributeKey} is removed + */ + public ServerBootstrap childAttr(AttributeKey childKey, T value) { + if (childKey == null) { + throw new NullPointerException("childKey"); + } + if (value == null) { + childAttrs.remove(childKey); + } else { + childAttrs.put(childKey, value); + } + return this; + } + + /** + * Set the {@link ChannelHandler} which is used to serve the request for the {@link Channel}'s. + */ + public ServerBootstrap childHandler(ChannelHandler childHandler) { + if (childHandler == null) { + throw new NullPointerException("childHandler"); + } + this.childHandler = childHandler; + return this; + } + + /** + * Return the configured {@link EventLoopGroup} which will be used for the child channels or {@code null} + * if non is configured yet. + */ + public EventLoopGroup childGroup() { + return childGroup; + } + + @Override + void init(Channel channel) throws Exception { + final Map, Object> options = options(); + synchronized (options) { + channel.config().setOptions(options); + } + + final Map, Object> attrs = attrs(); + synchronized (attrs) { + for (Entry, Object> e: attrs.entrySet()) { + + AttributeKey key = (AttributeKey) e.getKey(); + channel.attr(key).set(e.getValue()); + } + } + + ChannelPipeline p = channel.pipeline(); + if (handler() != null) { + p.addLast(handler()); + } + + final EventLoopGroup currentChildGroup = childGroup; + final ChannelHandler currentChildHandler = childHandler; + final Entry, Object>[] currentChildOptions; + final Entry, Object>[] currentChildAttrs; + synchronized (childOptions) { + currentChildOptions = childOptions.entrySet().toArray(newOptionArray(childOptions.size())); + } + synchronized (childAttrs) { + currentChildAttrs = childAttrs.entrySet().toArray(newAttrArray(childAttrs.size())); + } + + p.addLast(new ChannelInitializer() { + @Override + public void initChannel(Channel ch) throws Exception { + ch.pipeline().addLast(new ServerBootstrapAcceptor( + currentChildGroup, currentChildHandler, currentChildOptions, currentChildAttrs)); + } + }); + } + + @Override + public ServerBootstrap validate() { + super.validate(); + if (childHandler == null) { + throw new IllegalStateException("childHandler not set"); + } + if (childGroup == null) { + logger.warn("childGroup is not set. Using parentGroup instead."); + childGroup = group(); + } + return this; + } + + + private static Entry, Object>[] newOptionArray(int size) { + return new Entry[size]; + } + + + private static Entry, Object>[] newAttrArray(int size) { + return new Entry[size]; + } + + private static class ServerBootstrapAcceptor extends ChannelInboundHandlerAdapter { + + private final EventLoopGroup childGroup; + private final ChannelHandler childHandler; + private final Entry, Object>[] childOptions; + private final Entry, Object>[] childAttrs; + + ServerBootstrapAcceptor( + EventLoopGroup childGroup, ChannelHandler childHandler, + Entry, Object>[] childOptions, Entry, Object>[] childAttrs) { + this.childGroup = childGroup; + this.childHandler = childHandler; + this.childOptions = childOptions; + this.childAttrs = childAttrs; + } + + @Override + + public void channelRead(ChannelHandlerContext ctx, Object msg) { + final Channel child = (Channel) msg; + + child.pipeline().addLast(childHandler); + + for (Entry, Object> e: childOptions) { + try { + if (!child.config().setOption((ChannelOption) e.getKey(), e.getValue())) { + logger.warn("Unknown channel option: " + e); + } + } catch (Throwable t) { + logger.warn("Failed to set a channel option: " + child, t); + } + } + + for (Entry, Object> e: childAttrs) { + child.attr((AttributeKey) e.getKey()).set(e.getValue()); + } + + try { + childGroup.register(child).addListener(new ChannelFutureListener() { + @Override + public void operationComplete(ChannelFuture future) throws Exception { + if (!future.isSuccess()) { + forceClose(child, future.cause()); + } + } + }); + } catch (Throwable t) { + forceClose(child, t); + } + } + + private static void forceClose(Channel child, Throwable t) { + child.unsafe().closeForcibly(); + logger.warn("Failed to register an accepted channel: " + child, t); + } + + @Override + public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { + final ChannelConfig config = ctx.channel().config(); + if (config.isAutoRead()) { + // stop accept new connections for 1 second to allow the channel to recover + // See https://github.com/netty/netty/issues/1328 + config.setAutoRead(false); + ctx.channel().eventLoop().schedule(new Runnable() { + @Override + public void run() { + config.setAutoRead(true); + } + }, 1, TimeUnit.SECONDS); + } + // still let the exceptionCaught event flow through the pipeline to give the user + // a chance to do something with it + ctx.fireExceptionCaught(cause); + } + } + + @Override + + public ServerBootstrap clone() { + return new ServerBootstrap(this); + } + + @Override + public String toString() { + StringBuilder buf = new StringBuilder(super.toString()); + buf.setLength(buf.length() - 1); + buf.append(", "); + if (childGroup != null) { + buf.append("childGroup: "); + buf.append(StringUtil.simpleClassName(childGroup)); + buf.append(", "); + } + synchronized (childOptions) { + if (!childOptions.isEmpty()) { + buf.append("childOptions: "); + buf.append(childOptions); + buf.append(", "); + } + } + synchronized (childAttrs) { + if (!childAttrs.isEmpty()) { + buf.append("childAttrs: "); + buf.append(childAttrs); + buf.append(", "); + } + } + if (childHandler != null) { + buf.append("childHandler: "); + buf.append(childHandler); + buf.append(", "); + } + if (buf.charAt(buf.length() - 1) == '(') { + buf.append(')'); + } else { + buf.setCharAt(buf.length() - 2, ')'); + buf.setLength(buf.length() - 1); + } + + return buf.toString(); + } +} diff --git a/common/src/common/net/buffer/AbstractByteBuf.java b/common/src/common/net/buffer/AbstractByteBuf.java new file mode 100644 index 0000000..5f4f200 --- /dev/null +++ b/common/src/common/net/buffer/AbstractByteBuf.java @@ -0,0 +1,1190 @@ +/* + * Copyright 2012 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ +package common.net.buffer; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.nio.ByteBuffer; +import java.nio.ByteOrder; +import java.nio.channels.GatheringByteChannel; +import java.nio.channels.ScatteringByteChannel; +import java.nio.charset.Charset; + +import common.net.util.IllegalReferenceCountException; +import common.net.util.ResourceLeakDetector; +import common.net.util.internal.PlatformDependent; +import common.net.util.internal.StringUtil; + + +/** + * A skeletal implementation of a buffer. + */ +public abstract class AbstractByteBuf extends ByteBuf { + + static final ResourceLeakDetector leakDetector = new ResourceLeakDetector(ByteBuf.class); + + int readerIndex; + int writerIndex; + private int markedReaderIndex; + private int markedWriterIndex; + + private int maxCapacity; + + private SwappedByteBuf swappedBuf; + + protected AbstractByteBuf(int maxCapacity) { + if (maxCapacity < 0) { + throw new IllegalArgumentException("maxCapacity: " + maxCapacity + " (expected: >= 0)"); + } + this.maxCapacity = maxCapacity; + } + + @Override + public int maxCapacity() { + return maxCapacity; + } + + protected final void maxCapacity(int maxCapacity) { + this.maxCapacity = maxCapacity; + } + + @Override + public int readerIndex() { + return readerIndex; + } + + @Override + public ByteBuf readerIndex(int readerIndex) { + if (readerIndex < 0 || readerIndex > writerIndex) { + throw new IndexOutOfBoundsException(String.format( + "readerIndex: %d (expected: 0 <= readerIndex <= writerIndex(%d))", readerIndex, writerIndex)); + } + this.readerIndex = readerIndex; + return this; + } + + @Override + public int writerIndex() { + return writerIndex; + } + + @Override + public ByteBuf writerIndex(int writerIndex) { + if (writerIndex < readerIndex || writerIndex > capacity()) { + throw new IndexOutOfBoundsException(String.format( + "writerIndex: %d (expected: readerIndex(%d) <= writerIndex <= capacity(%d))", + writerIndex, readerIndex, capacity())); + } + this.writerIndex = writerIndex; + return this; + } + + @Override + public ByteBuf setIndex(int readerIndex, int writerIndex) { + if (readerIndex < 0 || readerIndex > writerIndex || writerIndex > capacity()) { + throw new IndexOutOfBoundsException(String.format( + "readerIndex: %d, writerIndex: %d (expected: 0 <= readerIndex <= writerIndex <= capacity(%d))", + readerIndex, writerIndex, capacity())); + } + this.readerIndex = readerIndex; + this.writerIndex = writerIndex; + return this; + } + + @Override + public ByteBuf clear() { + readerIndex = writerIndex = 0; + return this; + } + + @Override + public boolean isReadable() { + return writerIndex > readerIndex; + } + + @Override + public boolean isReadable(int numBytes) { + return writerIndex - readerIndex >= numBytes; + } + + @Override + public boolean isWritable() { + return capacity() > writerIndex; + } + + @Override + public boolean isWritable(int numBytes) { + return capacity() - writerIndex >= numBytes; + } + + @Override + public int readableBytes() { + return writerIndex - readerIndex; + } + + @Override + public int writableBytes() { + return capacity() - writerIndex; + } + + @Override + public int maxWritableBytes() { + return maxCapacity() - writerIndex; + } + + @Override + public ByteBuf markReaderIndex() { + markedReaderIndex = readerIndex; + return this; + } + + @Override + public ByteBuf resetReaderIndex() { + readerIndex(markedReaderIndex); + return this; + } + + @Override + public ByteBuf markWriterIndex() { + markedWriterIndex = writerIndex; + return this; + } + + @Override + public ByteBuf resetWriterIndex() { + writerIndex = markedWriterIndex; + return this; + } + + @Override + public ByteBuf discardReadBytes() { + ensureAccessible(); + if (readerIndex == 0) { + return this; + } + + if (readerIndex != writerIndex) { + setBytes(0, this, readerIndex, writerIndex - readerIndex); + writerIndex -= readerIndex; + adjustMarkers(readerIndex); + readerIndex = 0; + } else { + adjustMarkers(readerIndex); + writerIndex = readerIndex = 0; + } + return this; + } + + @Override + public ByteBuf discardSomeReadBytes() { + ensureAccessible(); + if (readerIndex == 0) { + return this; + } + + if (readerIndex == writerIndex) { + adjustMarkers(readerIndex); + writerIndex = readerIndex = 0; + return this; + } + + if (readerIndex >= capacity() >>> 1) { + setBytes(0, this, readerIndex, writerIndex - readerIndex); + writerIndex -= readerIndex; + adjustMarkers(readerIndex); + readerIndex = 0; + } + return this; + } + + protected final void adjustMarkers(int decrement) { + int markedReaderIndex = this.markedReaderIndex; + if (markedReaderIndex <= decrement) { + this.markedReaderIndex = 0; + int markedWriterIndex = this.markedWriterIndex; + if (markedWriterIndex <= decrement) { + this.markedWriterIndex = 0; + } else { + this.markedWriterIndex = markedWriterIndex - decrement; + } + } else { + this.markedReaderIndex = markedReaderIndex - decrement; + markedWriterIndex -= decrement; + } + } + + @Override + public ByteBuf ensureWritable(int minWritableBytes) { + if (minWritableBytes < 0) { + throw new IllegalArgumentException(String.format( + "minWritableBytes: %d (expected: >= 0)", minWritableBytes)); + } + + if (minWritableBytes <= writableBytes()) { + return this; + } + + if (minWritableBytes > maxCapacity - writerIndex) { + throw new IndexOutOfBoundsException(String.format( + "writerIndex(%d) + minWritableBytes(%d) exceeds maxCapacity(%d): %s", + writerIndex, minWritableBytes, maxCapacity, this)); + } + + // Normalize the current capacity to the power of 2. + int newCapacity = calculateNewCapacity(writerIndex + minWritableBytes); + + // Adjust to the new capacity. + capacity(newCapacity); + return this; + } + + @Override + public int ensureWritable(int minWritableBytes, boolean force) { + if (minWritableBytes < 0) { + throw new IllegalArgumentException(String.format( + "minWritableBytes: %d (expected: >= 0)", minWritableBytes)); + } + + if (minWritableBytes <= writableBytes()) { + return 0; + } + + if (minWritableBytes > maxCapacity - writerIndex) { + if (force) { + if (capacity() == maxCapacity()) { + return 1; + } + + capacity(maxCapacity()); + return 3; + } + } + + // Normalize the current capacity to the power of 2. + int newCapacity = calculateNewCapacity(writerIndex + minWritableBytes); + + // Adjust to the new capacity. + capacity(newCapacity); + return 2; + } + + private int calculateNewCapacity(int minNewCapacity) { + final int maxCapacity = this.maxCapacity; + final int threshold = 1048576 * 4; // 4 MiB page + + if (minNewCapacity == threshold) { + return threshold; + } + + // If over threshold, do not double but just increase by threshold. + if (minNewCapacity > threshold) { + int newCapacity = minNewCapacity / threshold * threshold; + if (newCapacity > maxCapacity - threshold) { + newCapacity = maxCapacity; + } else { + newCapacity += threshold; + } + return newCapacity; + } + + // Not over threshold. Double up to 4 MiB, starting from 64. + int newCapacity = 64; + while (newCapacity < minNewCapacity) { + newCapacity <<= 1; + } + + return Math.min(newCapacity, maxCapacity); + } + + @Override + public ByteBuf order(ByteOrder endianness) { + if (endianness == null) { + throw new NullPointerException("endianness"); + } + if (endianness == order()) { + return this; + } + + SwappedByteBuf swappedBuf = this.swappedBuf; + if (swappedBuf == null) { + this.swappedBuf = swappedBuf = newSwappedByteBuf(); + } + return swappedBuf; + } + + /** + * Creates a new {@link SwappedByteBuf} for this {@link ByteBuf} instance. + */ + protected SwappedByteBuf newSwappedByteBuf() { + return new SwappedByteBuf(this); + } + + @Override + public byte getByte(int index) { + checkIndex(index); + return _getByte(index); + } + + protected abstract byte _getByte(int index); + + @Override + public boolean getBoolean(int index) { + return getByte(index) != 0; + } + + @Override + public short getUnsignedByte(int index) { + return (short) (getByte(index) & 0xFF); + } + + @Override + public short getShort(int index) { + checkIndex(index, 2); + return _getShort(index); + } + + protected abstract short _getShort(int index); + + @Override + public int getUnsignedShort(int index) { + return getShort(index) & 0xFFFF; + } + + @Override + public int getUnsignedMedium(int index) { + checkIndex(index, 3); + return _getUnsignedMedium(index); + } + + protected abstract int _getUnsignedMedium(int index); + + @Override + public int getMedium(int index) { + int value = getUnsignedMedium(index); + if ((value & 0x800000) != 0) { + value |= 0xff000000; + } + return value; + } + + @Override + public int getInt(int index) { + checkIndex(index, 4); + return _getInt(index); + } + + protected abstract int _getInt(int index); + + @Override + public long getUnsignedInt(int index) { + return getInt(index) & 0xFFFFFFFFL; + } + + @Override + public long getLong(int index) { + checkIndex(index, 8); + return _getLong(index); + } + + protected abstract long _getLong(int index); + + @Override + public char getChar(int index) { + return (char) getShort(index); + } + + @Override + public float getFloat(int index) { + return Float.intBitsToFloat(getInt(index)); + } + + @Override + public double getDouble(int index) { + return Double.longBitsToDouble(getLong(index)); + } + + @Override + public ByteBuf getBytes(int index, byte[] dst) { + getBytes(index, dst, 0, dst.length); + return this; + } + + @Override + public ByteBuf getBytes(int index, ByteBuf dst) { + getBytes(index, dst, dst.writableBytes()); + return this; + } + + @Override + public ByteBuf getBytes(int index, ByteBuf dst, int length) { + getBytes(index, dst, dst.writerIndex(), length); + dst.writerIndex(dst.writerIndex() + length); + return this; + } + + @Override + public ByteBuf setByte(int index, int value) { + checkIndex(index); + _setByte(index, value); + return this; + } + + protected abstract void _setByte(int index, int value); + + @Override + public ByteBuf setBoolean(int index, boolean value) { + setByte(index, value ? 1 : 0); + return this; + } + + @Override + public ByteBuf setShort(int index, int value) { + checkIndex(index, 2); + _setShort(index, value); + return this; + } + + protected abstract void _setShort(int index, int value); + + @Override + public ByteBuf setChar(int index, int value) { + setShort(index, value); + return this; + } + + @Override + public ByteBuf setMedium(int index, int value) { + checkIndex(index, 3); + _setMedium(index, value); + return this; + } + + protected abstract void _setMedium(int index, int value); + + @Override + public ByteBuf setInt(int index, int value) { + checkIndex(index, 4); + _setInt(index, value); + return this; + } + + protected abstract void _setInt(int index, int value); + + @Override + public ByteBuf setFloat(int index, float value) { + setInt(index, Float.floatToRawIntBits(value)); + return this; + } + + @Override + public ByteBuf setLong(int index, long value) { + checkIndex(index, 8); + _setLong(index, value); + return this; + } + + protected abstract void _setLong(int index, long value); + + @Override + public ByteBuf setDouble(int index, double value) { + setLong(index, Double.doubleToRawLongBits(value)); + return this; + } + + @Override + public ByteBuf setBytes(int index, byte[] src) { + setBytes(index, src, 0, src.length); + return this; + } + + @Override + public ByteBuf setBytes(int index, ByteBuf src) { + setBytes(index, src, src.readableBytes()); + return this; + } + + @Override + public ByteBuf setBytes(int index, ByteBuf src, int length) { + checkIndex(index, length); + if (src == null) { + throw new NullPointerException("src"); + } + if (length > src.readableBytes()) { + throw new IndexOutOfBoundsException(String.format( + "length(%d) exceeds src.readableBytes(%d) where src is: %s", length, src.readableBytes(), src)); + } + + setBytes(index, src, src.readerIndex(), length); + src.readerIndex(src.readerIndex() + length); + return this; + } + + @Override + public ByteBuf setZero(int index, int length) { + if (length == 0) { + return this; + } + + checkIndex(index, length); + + int nLong = length >>> 3; + int nBytes = length & 7; + for (int i = nLong; i > 0; i --) { + setLong(index, 0); + index += 8; + } + if (nBytes == 4) { + setInt(index, 0); + } else if (nBytes < 4) { + for (int i = nBytes; i > 0; i --) { + setByte(index, (byte) 0); + index ++; + } + } else { + setInt(index, 0); + index += 4; + for (int i = nBytes - 4; i > 0; i --) { + setByte(index, (byte) 0); + index ++; + } + } + return this; + } + + @Override + public byte readByte() { + checkReadableBytes(1); + int i = readerIndex; + byte b = getByte(i); + readerIndex = i + 1; + return b; + } + + @Override + public boolean readBoolean() { + return readByte() != 0; + } + + @Override + public short readUnsignedByte() { + return (short) (readByte() & 0xFF); + } + + @Override + public short readShort() { + checkReadableBytes(2); + short v = _getShort(readerIndex); + readerIndex += 2; + return v; + } + + @Override + public int readUnsignedShort() { + return readShort() & 0xFFFF; + } + + @Override + public int readMedium() { + int value = readUnsignedMedium(); + if ((value & 0x800000) != 0) { + value |= 0xff000000; + } + return value; + } + + @Override + public int readUnsignedMedium() { + checkReadableBytes(3); + int v = _getUnsignedMedium(readerIndex); + readerIndex += 3; + return v; + } + + @Override + public int readInt() { + checkReadableBytes(4); + int v = _getInt(readerIndex); + readerIndex += 4; + return v; + } + + @Override + public long readUnsignedInt() { + return readInt() & 0xFFFFFFFFL; + } + + @Override + public long readLong() { + checkReadableBytes(8); + long v = _getLong(readerIndex); + readerIndex += 8; + return v; + } + + @Override + public char readChar() { + return (char) readShort(); + } + + @Override + public float readFloat() { + return Float.intBitsToFloat(readInt()); + } + + @Override + public double readDouble() { + return Double.longBitsToDouble(readLong()); + } + + @Override + public ByteBuf readBytes(int length) { + checkReadableBytes(length); + if (length == 0) { + return Unpooled.EMPTY_BUFFER; + } + + // Use an unpooled heap buffer because there's no way to mandate a user to free the returned buffer. + ByteBuf buf = Unpooled.buffer(length, maxCapacity); + buf.writeBytes(this, readerIndex, length); + readerIndex += length; + return buf; + } + + @Override + public ByteBuf readSlice(int length) { + ByteBuf slice = slice(readerIndex, length); + readerIndex += length; + return slice; + } + + @Override + public ByteBuf readBytes(byte[] dst, int dstIndex, int length) { + checkReadableBytes(length); + getBytes(readerIndex, dst, dstIndex, length); + readerIndex += length; + return this; + } + + @Override + public ByteBuf readBytes(byte[] dst) { + readBytes(dst, 0, dst.length); + return this; + } + + @Override + public ByteBuf readBytes(ByteBuf dst) { + readBytes(dst, dst.writableBytes()); + return this; + } + + @Override + public ByteBuf readBytes(ByteBuf dst, int length) { + if (length > dst.writableBytes()) { + throw new IndexOutOfBoundsException(String.format( + "length(%d) exceeds dst.writableBytes(%d) where dst is: %s", length, dst.writableBytes(), dst)); + } + readBytes(dst, dst.writerIndex(), length); + dst.writerIndex(dst.writerIndex() + length); + return this; + } + + @Override + public ByteBuf readBytes(ByteBuf dst, int dstIndex, int length) { + checkReadableBytes(length); + getBytes(readerIndex, dst, dstIndex, length); + readerIndex += length; + return this; + } + + @Override + public ByteBuf readBytes(ByteBuffer dst) { + int length = dst.remaining(); + checkReadableBytes(length); + getBytes(readerIndex, dst); + readerIndex += length; + return this; + } + + @Override + public int readBytes(GatheringByteChannel out, int length) + throws IOException { + checkReadableBytes(length); + int readBytes = getBytes(readerIndex, out, length); + readerIndex += readBytes; + return readBytes; + } + + @Override + public ByteBuf readBytes(OutputStream out, int length) throws IOException { + checkReadableBytes(length); + getBytes(readerIndex, out, length); + readerIndex += length; + return this; + } + + @Override + public ByteBuf skipBytes(int length) { + checkReadableBytes(length); + readerIndex += length; + return this; + } + + @Override + public ByteBuf writeBoolean(boolean value) { + writeByte(value ? 1 : 0); + return this; + } + + @Override + public ByteBuf writeByte(int value) { + ensureAccessible(); + ensureWritable(1); + _setByte(writerIndex++, value); + return this; + } + + @Override + public ByteBuf writeShort(int value) { + ensureAccessible(); + ensureWritable(2); + _setShort(writerIndex, value); + writerIndex += 2; + return this; + } + + @Override + public ByteBuf writeMedium(int value) { + ensureAccessible(); + ensureWritable(3); + _setMedium(writerIndex, value); + writerIndex += 3; + return this; + } + + @Override + public ByteBuf writeInt(int value) { + ensureAccessible(); + ensureWritable(4); + _setInt(writerIndex, value); + writerIndex += 4; + return this; + } + + @Override + public ByteBuf writeLong(long value) { + ensureAccessible(); + ensureWritable(8); + _setLong(writerIndex, value); + writerIndex += 8; + return this; + } + + @Override + public ByteBuf writeChar(int value) { + writeShort(value); + return this; + } + + @Override + public ByteBuf writeFloat(float value) { + writeInt(Float.floatToRawIntBits(value)); + return this; + } + + @Override + public ByteBuf writeDouble(double value) { + writeLong(Double.doubleToRawLongBits(value)); + return this; + } + + @Override + public ByteBuf writeBytes(byte[] src, int srcIndex, int length) { + ensureAccessible(); + ensureWritable(length); + setBytes(writerIndex, src, srcIndex, length); + writerIndex += length; + return this; + } + + @Override + public ByteBuf writeBytes(byte[] src) { + writeBytes(src, 0, src.length); + return this; + } + + @Override + public ByteBuf writeBytes(ByteBuf src) { + writeBytes(src, src.readableBytes()); + return this; + } + + @Override + public ByteBuf writeBytes(ByteBuf src, int length) { + if (length > src.readableBytes()) { + throw new IndexOutOfBoundsException(String.format( + "length(%d) exceeds src.readableBytes(%d) where src is: %s", length, src.readableBytes(), src)); + } + writeBytes(src, src.readerIndex(), length); + src.readerIndex(src.readerIndex() + length); + return this; + } + + @Override + public ByteBuf writeBytes(ByteBuf src, int srcIndex, int length) { + ensureAccessible(); + ensureWritable(length); + setBytes(writerIndex, src, srcIndex, length); + writerIndex += length; + return this; + } + + @Override + public ByteBuf writeBytes(ByteBuffer src) { + ensureAccessible(); + int length = src.remaining(); + ensureWritable(length); + setBytes(writerIndex, src); + writerIndex += length; + return this; + } + + @Override + public int writeBytes(InputStream in, int length) + throws IOException { + ensureAccessible(); + ensureWritable(length); + int writtenBytes = setBytes(writerIndex, in, length); + if (writtenBytes > 0) { + writerIndex += writtenBytes; + } + return writtenBytes; + } + + @Override + public int writeBytes(ScatteringByteChannel in, int length) throws IOException { + ensureAccessible(); + ensureWritable(length); + int writtenBytes = setBytes(writerIndex, in, length); + if (writtenBytes > 0) { + writerIndex += writtenBytes; + } + return writtenBytes; + } + + @Override + public ByteBuf writeZero(int length) { + if (length == 0) { + return this; + } + + ensureWritable(length); + checkIndex(writerIndex, length); + + int nLong = length >>> 3; + int nBytes = length & 7; + for (int i = nLong; i > 0; i --) { + writeLong(0); + } + if (nBytes == 4) { + writeInt(0); + } else if (nBytes < 4) { + for (int i = nBytes; i > 0; i --) { + writeByte((byte) 0); + } + } else { + writeInt(0); + for (int i = nBytes - 4; i > 0; i --) { + writeByte((byte) 0); + } + } + return this; + } + + @Override + public ByteBuf copy() { + return copy(readerIndex, readableBytes()); + } + + @Override + public ByteBuf duplicate() { + return new DuplicatedByteBuf(this); + } + + @Override + public ByteBuf slice() { + return slice(readerIndex, readableBytes()); + } + + @Override + public ByteBuf slice(int index, int length) { + if (length == 0) { + return Unpooled.EMPTY_BUFFER; + } + + return new SlicedByteBuf(this, index, length); + } + + @Override + public ByteBuffer nioBuffer() { + return nioBuffer(readerIndex, readableBytes()); + } + + @Override + public ByteBuffer[] nioBuffers() { + return nioBuffers(readerIndex, readableBytes()); + } + + @Override + public String toString(Charset charset) { + return toString(readerIndex, readableBytes(), charset); + } + + @Override + public String toString(int index, int length, Charset charset) { + if (length == 0) { + return ""; + } + + ByteBuffer nioBuffer; + if (nioBufferCount() == 1) { + nioBuffer = nioBuffer(index, length); + } else { + nioBuffer = ByteBuffer.allocate(length); + getBytes(index, nioBuffer); + nioBuffer.flip(); + } + + return ByteBufUtil.decodeString(nioBuffer, charset); + } + + @Override + public int indexOf(int fromIndex, int toIndex, byte value) { + return ByteBufUtil.indexOf(this, fromIndex, toIndex, value); + } + + @Override + public int bytesBefore(byte value) { + return bytesBefore(readerIndex(), readableBytes(), value); + } + + @Override + public int bytesBefore(int length, byte value) { + checkReadableBytes(length); + return bytesBefore(readerIndex(), length, value); + } + + @Override + public int bytesBefore(int index, int length, byte value) { + int endIndex = indexOf(index, index + length, value); + if (endIndex < 0) { + return -1; + } + return endIndex - index; + } + + @Override + public int forEachByte(ByteBufProcessor processor) { + int index = readerIndex; + int length = writerIndex - index; + ensureAccessible(); + return forEachByteAsc0(index, length, processor); + } + + @Override + public int forEachByte(int index, int length, ByteBufProcessor processor) { + checkIndex(index, length); + return forEachByteAsc0(index, length, processor); + } + + private int forEachByteAsc0(int index, int length, ByteBufProcessor processor) { + if (processor == null) { + throw new NullPointerException("processor"); + } + + if (length == 0) { + return -1; + } + + final int endIndex = index + length; + int i = index; + try { + do { + if (processor.process(_getByte(i))) { + i ++; + } else { + return i; + } + } while (i < endIndex); + } catch (Exception e) { + PlatformDependent.throwException(e); + } + + return -1; + } + + @Override + public int forEachByteDesc(ByteBufProcessor processor) { + int index = readerIndex; + int length = writerIndex - index; + ensureAccessible(); + return forEachByteDesc0(index, length, processor); + } + + @Override + public int forEachByteDesc(int index, int length, ByteBufProcessor processor) { + checkIndex(index, length); + + return forEachByteDesc0(index, length, processor); + } + + private int forEachByteDesc0(int index, int length, ByteBufProcessor processor) { + + if (processor == null) { + throw new NullPointerException("processor"); + } + + if (length == 0) { + return -1; + } + + int i = index + length - 1; + try { + do { + if (processor.process(_getByte(i))) { + i --; + } else { + return i; + } + } while (i >= index); + } catch (Exception e) { + PlatformDependent.throwException(e); + } + + return -1; + } + + @Override + public int hashCode() { + return ByteBufUtil.hashCode(this); + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o instanceof ByteBuf) { + return ByteBufUtil.equals(this, (ByteBuf) o); + } + return false; + } + + @Override + public int compareTo(ByteBuf that) { + return ByteBufUtil.compare(this, that); + } + + @Override + public String toString() { + if (refCnt() == 0) { + return StringUtil.simpleClassName(this) + "(freed)"; + } + + StringBuilder buf = new StringBuilder(); + buf.append(StringUtil.simpleClassName(this)); + buf.append("(ridx: "); + buf.append(readerIndex); + buf.append(", widx: "); + buf.append(writerIndex); + buf.append(", cap: "); + buf.append(capacity()); + if (maxCapacity != Integer.MAX_VALUE) { + buf.append('/'); + buf.append(maxCapacity); + } + + ByteBuf unwrapped = unwrap(); + if (unwrapped != null) { + buf.append(", unwrapped: "); + buf.append(unwrapped); + } + buf.append(')'); + return buf.toString(); + } + + protected final void checkIndex(int index) { + ensureAccessible(); + if (index < 0 || index >= capacity()) { + throw new IndexOutOfBoundsException(String.format( + "index: %d (expected: range(0, %d))", index, capacity())); + } + } + + protected final void checkIndex(int index, int fieldLength) { + ensureAccessible(); + if (fieldLength < 0) { + throw new IllegalArgumentException("length: " + fieldLength + " (expected: >= 0)"); + } + if (index < 0 || index > capacity() - fieldLength) { + throw new IndexOutOfBoundsException(String.format( + "index: %d, length: %d (expected: range(0, %d))", index, fieldLength, capacity())); + } + } + + protected final void checkSrcIndex(int index, int length, int srcIndex, int srcCapacity) { + checkIndex(index, length); + if (srcIndex < 0 || srcIndex > srcCapacity - length) { + throw new IndexOutOfBoundsException(String.format( + "srcIndex: %d, length: %d (expected: range(0, %d))", srcIndex, length, srcCapacity)); + } + } + + protected final void checkDstIndex(int index, int length, int dstIndex, int dstCapacity) { + checkIndex(index, length); + if (dstIndex < 0 || dstIndex > dstCapacity - length) { + throw new IndexOutOfBoundsException(String.format( + "dstIndex: %d, length: %d (expected: range(0, %d))", dstIndex, length, dstCapacity)); + } + } + + /** + * Throws an {@link IndexOutOfBoundsException} if the current + * {@linkplain #readableBytes() readable bytes} of this buffer is less + * than the specified value. + */ + protected final void checkReadableBytes(int minimumReadableBytes) { + ensureAccessible(); + if (minimumReadableBytes < 0) { + throw new IllegalArgumentException("minimumReadableBytes: " + minimumReadableBytes + " (expected: >= 0)"); + } + if (readerIndex > writerIndex - minimumReadableBytes) { + throw new IndexOutOfBoundsException(String.format( + "readerIndex(%d) + length(%d) exceeds writerIndex(%d): %s", + readerIndex, minimumReadableBytes, writerIndex, this)); + } + } + + /** + * Should be called by every method that tries to access the buffers content to check + * if the buffer was released before. + */ + protected final void ensureAccessible() { + if (refCnt() == 0) { + throw new IllegalReferenceCountException(0); + } + } +} diff --git a/common/src/common/net/buffer/AbstractByteBufAllocator.java b/common/src/common/net/buffer/AbstractByteBufAllocator.java new file mode 100644 index 0000000..821b772 --- /dev/null +++ b/common/src/common/net/buffer/AbstractByteBufAllocator.java @@ -0,0 +1,219 @@ +/* + * Copyright 2012 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ + +package common.net.buffer; + +import common.net.util.ResourceLeak; +import common.net.util.ResourceLeakDetector; +import common.net.util.internal.PlatformDependent; +import common.net.util.internal.StringUtil; + +/** + * Skeletal {@link ByteBufAllocator} implementation to extend. + */ +public abstract class AbstractByteBufAllocator implements ByteBufAllocator { + private static final int DEFAULT_INITIAL_CAPACITY = 256; + private static final int DEFAULT_MAX_COMPONENTS = 16; + + protected static ByteBuf toLeakAwareBuffer(ByteBuf buf) { + ResourceLeak leak; + switch (ResourceLeakDetector.getLevel()) { + case SIMPLE: + leak = AbstractByteBuf.leakDetector.open(buf); + if (leak != null) { + buf = new SimpleLeakAwareByteBuf(buf, leak); + } + break; + case ADVANCED: + case PARANOID: + leak = AbstractByteBuf.leakDetector.open(buf); + if (leak != null) { + buf = new AdvancedLeakAwareByteBuf(buf, leak); + } + break; + } + return buf; + } + + private final boolean directByDefault; + private final ByteBuf emptyBuf; + + /** + * Instance use heap buffers by default + */ + protected AbstractByteBufAllocator() { + this(false); + } + + /** + * Create new instance + * + * @param preferDirect {@code true} if {@link #buffer(int)} should try to allocate a direct buffer rather than + * a heap buffer + */ + protected AbstractByteBufAllocator(boolean preferDirect) { + directByDefault = preferDirect && PlatformDependent.hasUnsafe(); + emptyBuf = new EmptyByteBuf(this); + } + + @Override + public ByteBuf buffer() { + if (directByDefault) { + return directBuffer(); + } + return heapBuffer(); + } + + @Override + public ByteBuf buffer(int initialCapacity) { + if (directByDefault) { + return directBuffer(initialCapacity); + } + return heapBuffer(initialCapacity); + } + + @Override + public ByteBuf buffer(int initialCapacity, int maxCapacity) { + if (directByDefault) { + return directBuffer(initialCapacity, maxCapacity); + } + return heapBuffer(initialCapacity, maxCapacity); + } + + @Override + public ByteBuf ioBuffer() { + if (PlatformDependent.hasUnsafe()) { + return directBuffer(DEFAULT_INITIAL_CAPACITY); + } + return heapBuffer(DEFAULT_INITIAL_CAPACITY); + } + + @Override + public ByteBuf ioBuffer(int initialCapacity) { + if (PlatformDependent.hasUnsafe()) { + return directBuffer(initialCapacity); + } + return heapBuffer(initialCapacity); + } + + @Override + public ByteBuf ioBuffer(int initialCapacity, int maxCapacity) { + if (PlatformDependent.hasUnsafe()) { + return directBuffer(initialCapacity, maxCapacity); + } + return heapBuffer(initialCapacity, maxCapacity); + } + + @Override + public ByteBuf heapBuffer() { + return heapBuffer(DEFAULT_INITIAL_CAPACITY, Integer.MAX_VALUE); + } + + @Override + public ByteBuf heapBuffer(int initialCapacity) { + return heapBuffer(initialCapacity, Integer.MAX_VALUE); + } + + @Override + public ByteBuf heapBuffer(int initialCapacity, int maxCapacity) { + if (initialCapacity == 0 && maxCapacity == 0) { + return emptyBuf; + } + validate(initialCapacity, maxCapacity); + return newHeapBuffer(initialCapacity, maxCapacity); + } + + @Override + public ByteBuf directBuffer() { + return directBuffer(DEFAULT_INITIAL_CAPACITY, Integer.MAX_VALUE); + } + + @Override + public ByteBuf directBuffer(int initialCapacity) { + return directBuffer(initialCapacity, Integer.MAX_VALUE); + } + + @Override + public ByteBuf directBuffer(int initialCapacity, int maxCapacity) { + if (initialCapacity == 0 && maxCapacity == 0) { + return emptyBuf; + } + validate(initialCapacity, maxCapacity); + return newDirectBuffer(initialCapacity, maxCapacity); + } + + @Override + public CompositeByteBuf compositeBuffer() { + if (directByDefault) { + return compositeDirectBuffer(); + } + return compositeHeapBuffer(); + } + + @Override + public CompositeByteBuf compositeBuffer(int maxNumComponents) { + if (directByDefault) { + return compositeDirectBuffer(maxNumComponents); + } + return compositeHeapBuffer(maxNumComponents); + } + + @Override + public CompositeByteBuf compositeHeapBuffer() { + return compositeHeapBuffer(DEFAULT_MAX_COMPONENTS); + } + + @Override + public CompositeByteBuf compositeHeapBuffer(int maxNumComponents) { + return new CompositeByteBuf(this, false, maxNumComponents); + } + + @Override + public CompositeByteBuf compositeDirectBuffer() { + return compositeDirectBuffer(DEFAULT_MAX_COMPONENTS); + } + + @Override + public CompositeByteBuf compositeDirectBuffer(int maxNumComponents) { + return new CompositeByteBuf(this, true, maxNumComponents); + } + + private static void validate(int initialCapacity, int maxCapacity) { + if (initialCapacity < 0) { + throw new IllegalArgumentException("initialCapacity: " + initialCapacity + " (expectd: 0+)"); + } + if (initialCapacity > maxCapacity) { + throw new IllegalArgumentException(String.format( + "initialCapacity: %d (expected: not greater than maxCapacity(%d)", + initialCapacity, maxCapacity)); + } + } + + /** + * Create a heap {@link ByteBuf} with the given initialCapacity and maxCapacity. + */ + protected abstract ByteBuf newHeapBuffer(int initialCapacity, int maxCapacity); + + /** + * Create a direct {@link ByteBuf} with the given initialCapacity and maxCapacity. + */ + protected abstract ByteBuf newDirectBuffer(int initialCapacity, int maxCapacity); + + @Override + public String toString() { + return StringUtil.simpleClassName(this) + "(directByDefault: " + directByDefault + ')'; + } +} diff --git a/common/src/common/net/buffer/AbstractDerivedByteBuf.java b/common/src/common/net/buffer/AbstractDerivedByteBuf.java new file mode 100644 index 0000000..5fad3e7 --- /dev/null +++ b/common/src/common/net/buffer/AbstractDerivedByteBuf.java @@ -0,0 +1,67 @@ +/* + * Copyright 2013 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ + +package common.net.buffer; + +import java.nio.ByteBuffer; + +/** + * Abstract base class for {@link ByteBuf} implementations that wrap another + * {@link ByteBuf}. + */ +public abstract class AbstractDerivedByteBuf extends AbstractByteBuf { + + protected AbstractDerivedByteBuf(int maxCapacity) { + super(maxCapacity); + } + + @Override + public final int refCnt() { + return unwrap().refCnt(); + } + + @Override + public final ByteBuf retain() { + unwrap().retain(); + return this; + } + + @Override + public final ByteBuf retain(int increment) { + unwrap().retain(increment); + return this; + } + + @Override + public final boolean release() { + return unwrap().release(); + } + + @Override + public final boolean release(int decrement) { + return unwrap().release(decrement); + } + + @Override + public ByteBuffer internalNioBuffer(int index, int length) { + return nioBuffer(index, length); + } + + @Override + public ByteBuffer nioBuffer(int index, int length) { + return unwrap().nioBuffer(index, length); + } +} diff --git a/common/src/common/net/buffer/AbstractReferenceCountedByteBuf.java b/common/src/common/net/buffer/AbstractReferenceCountedByteBuf.java new file mode 100644 index 0000000..53ad03a --- /dev/null +++ b/common/src/common/net/buffer/AbstractReferenceCountedByteBuf.java @@ -0,0 +1,140 @@ +/* + * Copyright 2013 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ + +package common.net.buffer; + +import java.util.concurrent.atomic.AtomicIntegerFieldUpdater; + +import common.net.util.IllegalReferenceCountException; +import common.net.util.internal.PlatformDependent; + +/** + * Abstract base class for {@link ByteBuf} implementations that count references. + */ +public abstract class AbstractReferenceCountedByteBuf extends AbstractByteBuf { + + private static final AtomicIntegerFieldUpdater refCntUpdater; + + static { + AtomicIntegerFieldUpdater updater = + PlatformDependent.newAtomicIntegerFieldUpdater(AbstractReferenceCountedByteBuf.class, "refCnt"); + if (updater == null) { + updater = AtomicIntegerFieldUpdater.newUpdater(AbstractReferenceCountedByteBuf.class, "refCnt"); + } + refCntUpdater = updater; + } + + private volatile int refCnt = 1; + + protected AbstractReferenceCountedByteBuf(int maxCapacity) { + super(maxCapacity); + } + + @Override + public final int refCnt() { + return refCnt; + } + + /** + * An unsafe operation intended for use by a subclass that sets the reference count of the buffer directly + */ + protected final void setRefCnt(int refCnt) { + this.refCnt = refCnt; + } + + @Override + public ByteBuf retain() { + for (;;) { + int refCnt = this.refCnt; + if (refCnt == 0) { + throw new IllegalReferenceCountException(0, 1); + } + if (refCnt == Integer.MAX_VALUE) { + throw new IllegalReferenceCountException(Integer.MAX_VALUE, 1); + } + if (refCntUpdater.compareAndSet(this, refCnt, refCnt + 1)) { + break; + } + } + return this; + } + + @Override + public ByteBuf retain(int increment) { + if (increment <= 0) { + throw new IllegalArgumentException("increment: " + increment + " (expected: > 0)"); + } + + for (;;) { + int refCnt = this.refCnt; + if (refCnt == 0) { + throw new IllegalReferenceCountException(0, increment); + } + if (refCnt > Integer.MAX_VALUE - increment) { + throw new IllegalReferenceCountException(refCnt, increment); + } + if (refCntUpdater.compareAndSet(this, refCnt, refCnt + increment)) { + break; + } + } + return this; + } + + @Override + public final boolean release() { + for (;;) { + int refCnt = this.refCnt; + if (refCnt == 0) { + throw new IllegalReferenceCountException(0, -1); + } + + if (refCntUpdater.compareAndSet(this, refCnt, refCnt - 1)) { + if (refCnt == 1) { + deallocate(); + return true; + } + return false; + } + } + } + + @Override + public final boolean release(int decrement) { + if (decrement <= 0) { + throw new IllegalArgumentException("decrement: " + decrement + " (expected: > 0)"); + } + + for (;;) { + int refCnt = this.refCnt; + if (refCnt < decrement) { + throw new IllegalReferenceCountException(refCnt, -decrement); + } + + if (refCntUpdater.compareAndSet(this, refCnt, refCnt - decrement)) { + if (refCnt == decrement) { + deallocate(); + return true; + } + return false; + } + } + } + + /** + * Called once {@link #refCnt()} is equals 0. + */ + protected abstract void deallocate(); +} diff --git a/common/src/common/net/buffer/AdvancedLeakAwareByteBuf.java b/common/src/common/net/buffer/AdvancedLeakAwareByteBuf.java new file mode 100644 index 0000000..2cd77b6 --- /dev/null +++ b/common/src/common/net/buffer/AdvancedLeakAwareByteBuf.java @@ -0,0 +1,724 @@ +/* + * Copyright 2013 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ + +package common.net.buffer; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.nio.ByteBuffer; +import java.nio.ByteOrder; +import java.nio.channels.GatheringByteChannel; +import java.nio.channels.ScatteringByteChannel; +import java.nio.charset.Charset; + +import common.net.util.ResourceLeak; + +final class AdvancedLeakAwareByteBuf extends WrappedByteBuf { + + private final ResourceLeak leak; + + AdvancedLeakAwareByteBuf(ByteBuf buf, ResourceLeak leak) { + super(buf); + this.leak = leak; + } + + @Override + public boolean release() { + boolean deallocated = super.release(); + if (deallocated) { + leak.close(); + } else { + leak.record(); + } + return deallocated; + } + + @Override + public boolean release(int decrement) { + boolean deallocated = super.release(decrement); + if (deallocated) { + leak.close(); + } else { + leak.record(); + } + return deallocated; + } + + @Override + public ByteBuf order(ByteOrder endianness) { + leak.record(); + if (order() == endianness) { + return this; + } else { + return new AdvancedLeakAwareByteBuf(super.order(endianness), leak); + } + } + + @Override + public ByteBuf slice() { + leak.record(); + return new AdvancedLeakAwareByteBuf(super.slice(), leak); + } + + @Override + public ByteBuf slice(int index, int length) { + leak.record(); + return new AdvancedLeakAwareByteBuf(super.slice(index, length), leak); + } + + @Override + public ByteBuf duplicate() { + leak.record(); + return new AdvancedLeakAwareByteBuf(super.duplicate(), leak); + } + + @Override + public ByteBuf readSlice(int length) { + leak.record(); + return new AdvancedLeakAwareByteBuf(super.readSlice(length), leak); + } + + @Override + public ByteBuf discardReadBytes() { + leak.record(); + return super.discardReadBytes(); + } + + @Override + public ByteBuf discardSomeReadBytes() { + leak.record(); + return super.discardSomeReadBytes(); + } + + @Override + public ByteBuf ensureWritable(int minWritableBytes) { + leak.record(); + return super.ensureWritable(minWritableBytes); + } + + @Override + public int ensureWritable(int minWritableBytes, boolean force) { + leak.record(); + return super.ensureWritable(minWritableBytes, force); + } + + @Override + public boolean getBoolean(int index) { + leak.record(); + return super.getBoolean(index); + } + + @Override + public byte getByte(int index) { + leak.record(); + return super.getByte(index); + } + + @Override + public short getUnsignedByte(int index) { + leak.record(); + return super.getUnsignedByte(index); + } + + @Override + public short getShort(int index) { + leak.record(); + return super.getShort(index); + } + + @Override + public int getUnsignedShort(int index) { + leak.record(); + return super.getUnsignedShort(index); + } + + @Override + public int getMedium(int index) { + leak.record(); + return super.getMedium(index); + } + + @Override + public int getUnsignedMedium(int index) { + leak.record(); + return super.getUnsignedMedium(index); + } + + @Override + public int getInt(int index) { + leak.record(); + return super.getInt(index); + } + + @Override + public long getUnsignedInt(int index) { + leak.record(); + return super.getUnsignedInt(index); + } + + @Override + public long getLong(int index) { + leak.record(); + return super.getLong(index); + } + + @Override + public char getChar(int index) { + leak.record(); + return super.getChar(index); + } + + @Override + public float getFloat(int index) { + leak.record(); + return super.getFloat(index); + } + + @Override + public double getDouble(int index) { + leak.record(); + return super.getDouble(index); + } + + @Override + public ByteBuf getBytes(int index, ByteBuf dst) { + leak.record(); + return super.getBytes(index, dst); + } + + @Override + public ByteBuf getBytes(int index, ByteBuf dst, int length) { + leak.record(); + return super.getBytes(index, dst, length); + } + + @Override + public ByteBuf getBytes(int index, ByteBuf dst, int dstIndex, int length) { + leak.record(); + return super.getBytes(index, dst, dstIndex, length); + } + + @Override + public ByteBuf getBytes(int index, byte[] dst) { + leak.record(); + return super.getBytes(index, dst); + } + + @Override + public ByteBuf getBytes(int index, byte[] dst, int dstIndex, int length) { + leak.record(); + return super.getBytes(index, dst, dstIndex, length); + } + + @Override + public ByteBuf getBytes(int index, ByteBuffer dst) { + leak.record(); + return super.getBytes(index, dst); + } + + @Override + public ByteBuf getBytes(int index, OutputStream out, int length) throws IOException { + leak.record(); + return super.getBytes(index, out, length); + } + + @Override + public int getBytes(int index, GatheringByteChannel out, int length) throws IOException { + leak.record(); + return super.getBytes(index, out, length); + } + + @Override + public ByteBuf setBoolean(int index, boolean value) { + leak.record(); + return super.setBoolean(index, value); + } + + @Override + public ByteBuf setByte(int index, int value) { + leak.record(); + return super.setByte(index, value); + } + + @Override + public ByteBuf setShort(int index, int value) { + leak.record(); + return super.setShort(index, value); + } + + @Override + public ByteBuf setMedium(int index, int value) { + leak.record(); + return super.setMedium(index, value); + } + + @Override + public ByteBuf setInt(int index, int value) { + leak.record(); + return super.setInt(index, value); + } + + @Override + public ByteBuf setLong(int index, long value) { + leak.record(); + return super.setLong(index, value); + } + + @Override + public ByteBuf setChar(int index, int value) { + leak.record(); + return super.setChar(index, value); + } + + @Override + public ByteBuf setFloat(int index, float value) { + leak.record(); + return super.setFloat(index, value); + } + + @Override + public ByteBuf setDouble(int index, double value) { + leak.record(); + return super.setDouble(index, value); + } + + @Override + public ByteBuf setBytes(int index, ByteBuf src) { + leak.record(); + return super.setBytes(index, src); + } + + @Override + public ByteBuf setBytes(int index, ByteBuf src, int length) { + leak.record(); + return super.setBytes(index, src, length); + } + + @Override + public ByteBuf setBytes(int index, ByteBuf src, int srcIndex, int length) { + leak.record(); + return super.setBytes(index, src, srcIndex, length); + } + + @Override + public ByteBuf setBytes(int index, byte[] src) { + leak.record(); + return super.setBytes(index, src); + } + + @Override + public ByteBuf setBytes(int index, byte[] src, int srcIndex, int length) { + leak.record(); + return super.setBytes(index, src, srcIndex, length); + } + + @Override + public ByteBuf setBytes(int index, ByteBuffer src) { + leak.record(); + return super.setBytes(index, src); + } + + @Override + public int setBytes(int index, InputStream in, int length) throws IOException { + leak.record(); + return super.setBytes(index, in, length); + } + + @Override + public int setBytes(int index, ScatteringByteChannel in, int length) throws IOException { + leak.record(); + return super.setBytes(index, in, length); + } + + @Override + public ByteBuf setZero(int index, int length) { + leak.record(); + return super.setZero(index, length); + } + + @Override + public boolean readBoolean() { + leak.record(); + return super.readBoolean(); + } + + @Override + public byte readByte() { + leak.record(); + return super.readByte(); + } + + @Override + public short readUnsignedByte() { + leak.record(); + return super.readUnsignedByte(); + } + + @Override + public short readShort() { + leak.record(); + return super.readShort(); + } + + @Override + public int readUnsignedShort() { + leak.record(); + return super.readUnsignedShort(); + } + + @Override + public int readMedium() { + leak.record(); + return super.readMedium(); + } + + @Override + public int readUnsignedMedium() { + leak.record(); + return super.readUnsignedMedium(); + } + + @Override + public int readInt() { + leak.record(); + return super.readInt(); + } + + @Override + public long readUnsignedInt() { + leak.record(); + return super.readUnsignedInt(); + } + + @Override + public long readLong() { + leak.record(); + return super.readLong(); + } + + @Override + public char readChar() { + leak.record(); + return super.readChar(); + } + + @Override + public float readFloat() { + leak.record(); + return super.readFloat(); + } + + @Override + public double readDouble() { + leak.record(); + return super.readDouble(); + } + + @Override + public ByteBuf readBytes(int length) { + leak.record(); + return super.readBytes(length); + } + + @Override + public ByteBuf readBytes(ByteBuf dst) { + leak.record(); + return super.readBytes(dst); + } + + @Override + public ByteBuf readBytes(ByteBuf dst, int length) { + leak.record(); + return super.readBytes(dst, length); + } + + @Override + public ByteBuf readBytes(ByteBuf dst, int dstIndex, int length) { + leak.record(); + return super.readBytes(dst, dstIndex, length); + } + + @Override + public ByteBuf readBytes(byte[] dst) { + leak.record(); + return super.readBytes(dst); + } + + @Override + public ByteBuf readBytes(byte[] dst, int dstIndex, int length) { + leak.record(); + return super.readBytes(dst, dstIndex, length); + } + + @Override + public ByteBuf readBytes(ByteBuffer dst) { + leak.record(); + return super.readBytes(dst); + } + + @Override + public ByteBuf readBytes(OutputStream out, int length) throws IOException { + leak.record(); + return super.readBytes(out, length); + } + + @Override + public int readBytes(GatheringByteChannel out, int length) throws IOException { + leak.record(); + return super.readBytes(out, length); + } + + @Override + public ByteBuf skipBytes(int length) { + leak.record(); + return super.skipBytes(length); + } + + @Override + public ByteBuf writeBoolean(boolean value) { + leak.record(); + return super.writeBoolean(value); + } + + @Override + public ByteBuf writeByte(int value) { + leak.record(); + return super.writeByte(value); + } + + @Override + public ByteBuf writeShort(int value) { + leak.record(); + return super.writeShort(value); + } + + @Override + public ByteBuf writeMedium(int value) { + leak.record(); + return super.writeMedium(value); + } + + @Override + public ByteBuf writeInt(int value) { + leak.record(); + return super.writeInt(value); + } + + @Override + public ByteBuf writeLong(long value) { + leak.record(); + return super.writeLong(value); + } + + @Override + public ByteBuf writeChar(int value) { + leak.record(); + return super.writeChar(value); + } + + @Override + public ByteBuf writeFloat(float value) { + leak.record(); + return super.writeFloat(value); + } + + @Override + public ByteBuf writeDouble(double value) { + leak.record(); + return super.writeDouble(value); + } + + @Override + public ByteBuf writeBytes(ByteBuf src) { + leak.record(); + return super.writeBytes(src); + } + + @Override + public ByteBuf writeBytes(ByteBuf src, int length) { + leak.record(); + return super.writeBytes(src, length); + } + + @Override + public ByteBuf writeBytes(ByteBuf src, int srcIndex, int length) { + leak.record(); + return super.writeBytes(src, srcIndex, length); + } + + @Override + public ByteBuf writeBytes(byte[] src) { + leak.record(); + return super.writeBytes(src); + } + + @Override + public ByteBuf writeBytes(byte[] src, int srcIndex, int length) { + leak.record(); + return super.writeBytes(src, srcIndex, length); + } + + @Override + public ByteBuf writeBytes(ByteBuffer src) { + leak.record(); + return super.writeBytes(src); + } + + @Override + public int writeBytes(InputStream in, int length) throws IOException { + leak.record(); + return super.writeBytes(in, length); + } + + @Override + public int writeBytes(ScatteringByteChannel in, int length) throws IOException { + leak.record(); + return super.writeBytes(in, length); + } + + @Override + public ByteBuf writeZero(int length) { + leak.record(); + return super.writeZero(length); + } + + @Override + public int indexOf(int fromIndex, int toIndex, byte value) { + leak.record(); + return super.indexOf(fromIndex, toIndex, value); + } + + @Override + public int bytesBefore(byte value) { + leak.record(); + return super.bytesBefore(value); + } + + @Override + public int bytesBefore(int length, byte value) { + leak.record(); + return super.bytesBefore(length, value); + } + + @Override + public int bytesBefore(int index, int length, byte value) { + leak.record(); + return super.bytesBefore(index, length, value); + } + + @Override + public int forEachByte(ByteBufProcessor processor) { + leak.record(); + return super.forEachByte(processor); + } + + @Override + public int forEachByte(int index, int length, ByteBufProcessor processor) { + leak.record(); + return super.forEachByte(index, length, processor); + } + + @Override + public int forEachByteDesc(ByteBufProcessor processor) { + leak.record(); + return super.forEachByteDesc(processor); + } + + @Override + public int forEachByteDesc(int index, int length, ByteBufProcessor processor) { + leak.record(); + return super.forEachByteDesc(index, length, processor); + } + + @Override + public ByteBuf copy() { + leak.record(); + return super.copy(); + } + + @Override + public ByteBuf copy(int index, int length) { + leak.record(); + return super.copy(index, length); + } + + @Override + public int nioBufferCount() { + leak.record(); + return super.nioBufferCount(); + } + + @Override + public ByteBuffer nioBuffer() { + leak.record(); + return super.nioBuffer(); + } + + @Override + public ByteBuffer nioBuffer(int index, int length) { + leak.record(); + return super.nioBuffer(index, length); + } + + @Override + public ByteBuffer[] nioBuffers() { + leak.record(); + return super.nioBuffers(); + } + + @Override + public ByteBuffer[] nioBuffers(int index, int length) { + leak.record(); + return super.nioBuffers(index, length); + } + + @Override + public ByteBuffer internalNioBuffer(int index, int length) { + leak.record(); + return super.internalNioBuffer(index, length); + } + + @Override + public String toString(Charset charset) { + leak.record(); + return super.toString(charset); + } + + @Override + public String toString(int index, int length, Charset charset) { + leak.record(); + return super.toString(index, length, charset); + } + + @Override + public ByteBuf retain() { + leak.record(); + return super.retain(); + } + + @Override + public ByteBuf retain(int increment) { + leak.record(); + return super.retain(increment); + } + + @Override + public ByteBuf capacity(int newCapacity) { + leak.record(); + return super.capacity(newCapacity); + } +} diff --git a/common/src/common/net/buffer/ByteBuf.java b/common/src/common/net/buffer/ByteBuf.java new file mode 100644 index 0000000..664064e --- /dev/null +++ b/common/src/common/net/buffer/ByteBuf.java @@ -0,0 +1,1879 @@ +/* + * Copyright 2012 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ +package common.net.buffer; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.nio.ByteBuffer; +import java.nio.ByteOrder; +import java.nio.channels.GatheringByteChannel; +import java.nio.channels.ScatteringByteChannel; +import java.nio.charset.Charset; + +import common.net.util.ReferenceCounted; + +/** + * A random and sequential accessible sequence of zero or more bytes (octets). + * This interface provides an abstract view for one or more primitive byte + * arrays ({@code byte[]}) and {@linkplain ByteBuffer NIO buffers}. + * + *

Creation of a buffer

+ * + * It is recommended to create a new buffer using the helper methods in + * {@link Unpooled} rather than calling an individual implementation's + * constructor. + * + *

Random Access Indexing

+ * + * Just like an ordinary primitive byte array, {@link ByteBuf} uses + * zero-based indexing. + * It means the index of the first byte is always {@code 0} and the index of the last byte is + * always {@link #capacity() capacity - 1}. For example, to iterate all bytes of a buffer, you + * can do the following, regardless of its internal implementation: + * + *
+ * {@link ByteBuf} buffer = ...;
+ * for (int i = 0; i < buffer.capacity(); i ++) {
+ *     byte b = buffer.getByte(i);
+ *     System.out.println((char) b);
+ * }
+ * 
+ * + *

Sequential Access Indexing

+ * + * {@link ByteBuf} provides two pointer variables to support sequential + * read and write operations - {@link #readerIndex() readerIndex} for a read + * operation and {@link #writerIndex() writerIndex} for a write operation + * respectively. The following diagram shows how a buffer is segmented into + * three areas by the two pointers: + * + *
+ *      +-------------------+------------------+------------------+
+ *      | discardable bytes |  readable bytes  |  writable bytes  |
+ *      |                   |     (CONTENT)    |                  |
+ *      +-------------------+------------------+------------------+
+ *      |                   |                  |                  |
+ *      0      <=      readerIndex   <=   writerIndex    <=    capacity
+ * 
+ * + *

Readable bytes (the actual content)

+ * + * This segment is where the actual data is stored. Any operation whose name + * starts with {@code read} or {@code skip} will get or skip the data at the + * current {@link #readerIndex() readerIndex} and increase it by the number of + * read bytes. If the argument of the read operation is also a + * {@link ByteBuf} and no destination index is specified, the specified + * buffer's {@link #writerIndex() writerIndex} is increased together. + *

+ * If there's not enough content left, {@link IndexOutOfBoundsException} is + * raised. The default value of newly allocated, wrapped or copied buffer's + * {@link #readerIndex() readerIndex} is {@code 0}. + * + *

+ * // Iterates the readable bytes of a buffer.
+ * {@link ByteBuf} buffer = ...;
+ * while (buffer.readable()) {
+ *     System.out.println(buffer.readByte());
+ * }
+ * 
+ * + *

Writable bytes

+ * + * This segment is a undefined space which needs to be filled. Any operation + * whose name ends with {@code write} will write the data at the current + * {@link #writerIndex() writerIndex} and increase it by the number of written + * bytes. If the argument of the write operation is also a {@link ByteBuf}, + * and no source index is specified, the specified buffer's + * {@link #readerIndex() readerIndex} is increased together. + *

+ * If there's not enough writable bytes left, {@link IndexOutOfBoundsException} + * is raised. The default value of newly allocated buffer's + * {@link #writerIndex() writerIndex} is {@code 0}. The default value of + * wrapped or copied buffer's {@link #writerIndex() writerIndex} is the + * {@link #capacity() capacity} of the buffer. + * + *

+ * // Fills the writable bytes of a buffer with random integers.
+ * {@link ByteBuf} buffer = ...;
+ * while (buffer.maxWritableBytes() >= 4) {
+ *     buffer.writeInt(random.nextInt());
+ * }
+ * 
+ * + *

Discardable bytes

+ * + * This segment contains the bytes which were read already by a read operation. + * Initially, the size of this segment is {@code 0}, but its size increases up + * to the {@link #writerIndex() writerIndex} as read operations are executed. + * The read bytes can be discarded by calling {@link #discardReadBytes()} to + * reclaim unused area as depicted by the following diagram: + * + *
+ *  BEFORE discardReadBytes()
+ *
+ *      +-------------------+------------------+------------------+
+ *      | discardable bytes |  readable bytes  |  writable bytes  |
+ *      +-------------------+------------------+------------------+
+ *      |                   |                  |                  |
+ *      0      <=      readerIndex   <=   writerIndex    <=    capacity
+ *
+ *
+ *  AFTER discardReadBytes()
+ *
+ *      +------------------+--------------------------------------+
+ *      |  readable bytes  |    writable bytes (got more space)   |
+ *      +------------------+--------------------------------------+
+ *      |                  |                                      |
+ * readerIndex (0) <= writerIndex (decreased)        <=        capacity
+ * 
+ * + * Please note that there is no guarantee about the content of writable bytes + * after calling {@link #discardReadBytes()}. The writable bytes will not be + * moved in most cases and could even be filled with completely different data + * depending on the underlying buffer implementation. + * + *

Clearing the buffer indexes

+ * + * You can set both {@link #readerIndex() readerIndex} and + * {@link #writerIndex() writerIndex} to {@code 0} by calling {@link #clear()}. + * It does not clear the buffer content (e.g. filling with {@code 0}) but just + * clears the two pointers. Please also note that the semantic of this + * operation is different from {@link ByteBuffer#clear()}. + * + *
+ *  BEFORE clear()
+ *
+ *      +-------------------+------------------+------------------+
+ *      | discardable bytes |  readable bytes  |  writable bytes  |
+ *      +-------------------+------------------+------------------+
+ *      |                   |                  |                  |
+ *      0      <=      readerIndex   <=   writerIndex    <=    capacity
+ *
+ *
+ *  AFTER clear()
+ *
+ *      +---------------------------------------------------------+
+ *      |             writable bytes (got more space)             |
+ *      +---------------------------------------------------------+
+ *      |                                                         |
+ *      0 = readerIndex = writerIndex            <=            capacity
+ * 
+ * + *

Search operations

+ * + * For simple single-byte searches, use {@link #indexOf(int, int, byte)} and {@link #bytesBefore(int, int, byte)}. + * {@link #bytesBefore(byte)} is especially useful when you deal with a {@code NUL}-terminated string. + * For complicated searches, use {@link #forEachByte(int, int, ByteBufProcessor)} with a {@link ByteBufProcessor} + * implementation. + * + *

Mark and reset

+ * + * There are two marker indexes in every buffer. One is for storing + * {@link #readerIndex() readerIndex} and the other is for storing + * {@link #writerIndex() writerIndex}. You can always reposition one of the + * two indexes by calling a reset method. It works in a similar fashion to + * the mark and reset methods in {@link InputStream} except that there's no + * {@code readlimit}. + * + *

Derived buffers

+ * + * You can create a view of an existing buffer by calling either + * {@link #duplicate()}, {@link #slice()} or {@link #slice(int, int)}. + * A derived buffer will have an independent {@link #readerIndex() readerIndex}, + * {@link #writerIndex() writerIndex} and marker indexes, while it shares + * other internal data representation, just like a NIO buffer does. + *

+ * In case a completely fresh copy of an existing buffer is required, please + * call {@link #copy()} method instead. + * + *

Conversion to existing JDK types

+ * + *

Byte array

+ * + * If a {@link ByteBuf} is backed by a byte array (i.e. {@code byte[]}), + * you can access it directly via the {@link #array()} method. To determine + * if a buffer is backed by a byte array, {@link #hasArray()} should be used. + * + *

NIO Buffers

+ * + * If a {@link ByteBuf} can be converted into an NIO {@link ByteBuffer} which shares its + * content (i.e. view buffer), you can get it via the {@link #nioBuffer()} method. To determine + * if a buffer can be converted into an NIO buffer, use {@link #nioBufferCount()}. + * + *

Strings

+ * + * Various {@link #toString(Charset)} methods convert a {@link ByteBuf} + * into a {@link String}. Please note that {@link #toString()} is not a + * conversion method. + * + *

I/O Streams

+ * + * Please refer to {@link ByteBufInputStream} and + * {@link ByteBufOutputStream}. + */ + +public abstract class ByteBuf implements ReferenceCounted, Comparable { + + /** + * Returns the number of bytes (octets) this buffer can contain. + */ + public abstract int capacity(); + + /** + * Adjusts the capacity of this buffer. If the {@code newCapacity} is less than the current + * capacity, the content of this buffer is truncated. If the {@code newCapacity} is greater + * than the current capacity, the buffer is appended with unspecified data whose length is + * {@code (newCapacity - currentCapacity)}. + */ + public abstract ByteBuf capacity(int newCapacity); + + /** + * Returns the maximum allowed capacity of this buffer. If a user attempts to increase the + * capacity of this buffer beyond the maximum capacity using {@link #capacity(int)} or + * {@link #ensureWritable(int)}, those methods will raise an + * {@link IllegalArgumentException}. + */ + public abstract int maxCapacity(); + + /** + * Returns the {@link ByteBufAllocator} which created this buffer. + */ + public abstract ByteBufAllocator alloc(); + + /** + * Returns the endianness + * of this buffer. + */ + public abstract ByteOrder order(); + + /** + * Returns a buffer with the specified {@code endianness} which shares the whole region, + * indexes, and marks of this buffer. Modifying the content, the indexes, or the marks of the + * returned buffer or this buffer affects each other's content, indexes, and marks. If the + * specified {@code endianness} is identical to this buffer's byte order, this method can + * return {@code this}. This method does not modify {@code readerIndex} or {@code writerIndex} + * of this buffer. + */ + public abstract ByteBuf order(ByteOrder endianness); + + /** + * Return the underlying buffer instance if this buffer is a wrapper of another buffer. + * + * @return {@code null} if this buffer is not a wrapper + */ + public abstract ByteBuf unwrap(); + + /** + * Returns {@code true} if and only if this buffer is backed by an + * NIO direct buffer. + */ + public abstract boolean isDirect(); + + /** + * Returns the {@code readerIndex} of this buffer. + */ + public abstract int readerIndex(); + + /** + * Sets the {@code readerIndex} of this buffer. + * + * @throws IndexOutOfBoundsException + * if the specified {@code readerIndex} is + * less than {@code 0} or + * greater than {@code this.writerIndex} + */ + public abstract ByteBuf readerIndex(int readerIndex); + + /** + * Returns the {@code writerIndex} of this buffer. + */ + public abstract int writerIndex(); + + /** + * Sets the {@code writerIndex} of this buffer. + * + * @throws IndexOutOfBoundsException + * if the specified {@code writerIndex} is + * less than {@code this.readerIndex} or + * greater than {@code this.capacity} + */ + public abstract ByteBuf writerIndex(int writerIndex); + + /** + * Sets the {@code readerIndex} and {@code writerIndex} of this buffer + * in one shot. This method is useful when you have to worry about the + * invocation order of {@link #readerIndex(int)} and {@link #writerIndex(int)} + * methods. For example, the following code will fail: + * + *
+     * // Create a buffer whose readerIndex, writerIndex and capacity are
+     * // 0, 0 and 8 respectively.
+     * {@link ByteBuf} buf = {@link Unpooled}.buffer(8);
+     *
+     * // IndexOutOfBoundsException is thrown because the specified
+     * // readerIndex (2) cannot be greater than the current writerIndex (0).
+     * buf.readerIndex(2);
+     * buf.writerIndex(4);
+     * 
+ * + * The following code will also fail: + * + *
+     * // Create a buffer whose readerIndex, writerIndex and capacity are
+     * // 0, 8 and 8 respectively.
+     * {@link ByteBuf} buf = {@link Unpooled}.wrappedBuffer(new byte[8]);
+     *
+     * // readerIndex becomes 8.
+     * buf.readLong();
+     *
+     * // IndexOutOfBoundsException is thrown because the specified
+     * // writerIndex (4) cannot be less than the current readerIndex (8).
+     * buf.writerIndex(4);
+     * buf.readerIndex(2);
+     * 
+ * + * By contrast, this method guarantees that it never + * throws an {@link IndexOutOfBoundsException} as long as the specified + * indexes meet basic constraints, regardless what the current index + * values of the buffer are: + * + *
+     * // No matter what the current state of the buffer is, the following
+     * // call always succeeds as long as the capacity of the buffer is not
+     * // less than 4.
+     * buf.setIndex(2, 4);
+     * 
+ * + * @throws IndexOutOfBoundsException + * if the specified {@code readerIndex} is less than 0, + * if the specified {@code writerIndex} is less than the specified + * {@code readerIndex} or if the specified {@code writerIndex} is + * greater than {@code this.capacity} + */ + public abstract ByteBuf setIndex(int readerIndex, int writerIndex); + + /** + * Returns the number of readable bytes which is equal to + * {@code (this.writerIndex - this.readerIndex)}. + */ + public abstract int readableBytes(); + + /** + * Returns the number of writable bytes which is equal to + * {@code (this.capacity - this.writerIndex)}. + */ + public abstract int writableBytes(); + + /** + * Returns the maximum possible number of writable bytes, which is equal to + * {@code (this.maxCapacity - this.writerIndex)}. + */ + public abstract int maxWritableBytes(); + + /** + * Returns {@code true} + * if and only if {@code (this.writerIndex - this.readerIndex)} is greater + * than {@code 0}. + */ + public abstract boolean isReadable(); + + /** + * Returns {@code true} if and only if this buffer contains equal to or more than the specified number of elements. + */ + public abstract boolean isReadable(int size); + + /** + * Returns {@code true} + * if and only if {@code (this.capacity - this.writerIndex)} is greater + * than {@code 0}. + */ + public abstract boolean isWritable(); + + /** + * Returns {@code true} if and only if this buffer has enough room to allow writing the specified number of + * elements. + */ + public abstract boolean isWritable(int size); + + /** + * Sets the {@code readerIndex} and {@code writerIndex} of this buffer to + * {@code 0}. + * This method is identical to {@link #setIndex(int, int) setIndex(0, 0)}. + *

+ * Please note that the behavior of this method is different + * from that of NIO buffer, which sets the {@code limit} to + * the {@code capacity} of the buffer. + */ + public abstract ByteBuf clear(); + + /** + * Marks the current {@code readerIndex} in this buffer. You can + * reposition the current {@code readerIndex} to the marked + * {@code readerIndex} by calling {@link #resetReaderIndex()}. + * The initial value of the marked {@code readerIndex} is {@code 0}. + */ + public abstract ByteBuf markReaderIndex(); + + /** + * Repositions the current {@code readerIndex} to the marked + * {@code readerIndex} in this buffer. + * + * @throws IndexOutOfBoundsException + * if the current {@code writerIndex} is less than the marked + * {@code readerIndex} + */ + public abstract ByteBuf resetReaderIndex(); + + /** + * Marks the current {@code writerIndex} in this buffer. You can + * reposition the current {@code writerIndex} to the marked + * {@code writerIndex} by calling {@link #resetWriterIndex()}. + * The initial value of the marked {@code writerIndex} is {@code 0}. + */ + public abstract ByteBuf markWriterIndex(); + + /** + * Repositions the current {@code writerIndex} to the marked + * {@code writerIndex} in this buffer. + * + * @throws IndexOutOfBoundsException + * if the current {@code readerIndex} is greater than the marked + * {@code writerIndex} + */ + public abstract ByteBuf resetWriterIndex(); + + /** + * Discards the bytes between the 0th index and {@code readerIndex}. + * It moves the bytes between {@code readerIndex} and {@code writerIndex} + * to the 0th index, and sets {@code readerIndex} and {@code writerIndex} + * to {@code 0} and {@code oldWriterIndex - oldReaderIndex} respectively. + *

+ * Please refer to the class documentation for more detailed explanation. + */ + public abstract ByteBuf discardReadBytes(); + + /** + * Similar to {@link ByteBuf#discardReadBytes()} except that this method might discard + * some, all, or none of read bytes depending on its internal implementation to reduce + * overall memory bandwidth consumption at the cost of potentially additional memory + * consumption. + */ + public abstract ByteBuf discardSomeReadBytes(); + + /** + * Makes sure the number of {@linkplain #writableBytes() the writable bytes} + * is equal to or greater than the specified value. If there is enough + * writable bytes in this buffer, this method returns with no side effect. + * Otherwise, it raises an {@link IllegalArgumentException}. + * + * @param minWritableBytes + * the expected minimum number of writable bytes + * @throws IndexOutOfBoundsException + * if {@link #writerIndex()} + {@code minWritableBytes} > {@link #maxCapacity()} + */ + public abstract ByteBuf ensureWritable(int minWritableBytes); + + /** + * Tries to make sure the number of {@linkplain #writableBytes() the writable bytes} + * is equal to or greater than the specified value. Unlike {@link #ensureWritable(int)}, + * this method does not raise an exception but returns a code. + * + * @param minWritableBytes + * the expected minimum number of writable bytes + * @param force + * When {@link #writerIndex()} + {@code minWritableBytes} > {@link #maxCapacity()}: + *

    + *
  • {@code true} - the capacity of the buffer is expanded to {@link #maxCapacity()}
  • + *
  • {@code false} - the capacity of the buffer is unchanged
  • + *
+ * @return {@code 0} if the buffer has enough writable bytes, and its capacity is unchanged. + * {@code 1} if the buffer does not have enough bytes, and its capacity is unchanged. + * {@code 2} if the buffer has enough writable bytes, and its capacity has been increased. + * {@code 3} if the buffer does not have enough bytes, but its capacity has been + * increased to its maximum. + */ + public abstract int ensureWritable(int minWritableBytes, boolean force); + + /** + * Gets a boolean at the specified absolute (@code index) in this buffer. + * This method does not modify the {@code readerIndex} or {@code writerIndex} + * of this buffer. + * + * @throws IndexOutOfBoundsException + * if the specified {@code index} is less than {@code 0} or + * {@code index + 1} is greater than {@code this.capacity} + */ + public abstract boolean getBoolean(int index); + + /** + * Gets a byte at the specified absolute {@code index} in this buffer. + * This method does not modify {@code readerIndex} or {@code writerIndex} of + * this buffer. + * + * @throws IndexOutOfBoundsException + * if the specified {@code index} is less than {@code 0} or + * {@code index + 1} is greater than {@code this.capacity} + */ + public abstract byte getByte(int index); + + /** + * Gets an unsigned byte at the specified absolute {@code index} in this + * buffer. This method does not modify {@code readerIndex} or + * {@code writerIndex} of this buffer. + * + * @throws IndexOutOfBoundsException + * if the specified {@code index} is less than {@code 0} or + * {@code index + 1} is greater than {@code this.capacity} + */ + public abstract short getUnsignedByte(int index); + + /** + * Gets a 16-bit short integer at the specified absolute {@code index} in + * this buffer. This method does not modify {@code readerIndex} or + * {@code writerIndex} of this buffer. + * + * @throws IndexOutOfBoundsException + * if the specified {@code index} is less than {@code 0} or + * {@code index + 2} is greater than {@code this.capacity} + */ + public abstract short getShort(int index); + + /** + * Gets an unsigned 16-bit short integer at the specified absolute + * {@code index} in this buffer. This method does not modify + * {@code readerIndex} or {@code writerIndex} of this buffer. + * + * @throws IndexOutOfBoundsException + * if the specified {@code index} is less than {@code 0} or + * {@code index + 2} is greater than {@code this.capacity} + */ + public abstract int getUnsignedShort(int index); + + /** + * Gets a 24-bit medium integer at the specified absolute {@code index} in + * this buffer. This method does not modify {@code readerIndex} or + * {@code writerIndex} of this buffer. + * + * @throws IndexOutOfBoundsException + * if the specified {@code index} is less than {@code 0} or + * {@code index + 3} is greater than {@code this.capacity} + */ + public abstract int getMedium(int index); + + /** + * Gets an unsigned 24-bit medium integer at the specified absolute + * {@code index} in this buffer. This method does not modify + * {@code readerIndex} or {@code writerIndex} of this buffer. + * + * @throws IndexOutOfBoundsException + * if the specified {@code index} is less than {@code 0} or + * {@code index + 3} is greater than {@code this.capacity} + */ + public abstract int getUnsignedMedium(int index); + + /** + * Gets a 32-bit integer at the specified absolute {@code index} in + * this buffer. This method does not modify {@code readerIndex} or + * {@code writerIndex} of this buffer. + * + * @throws IndexOutOfBoundsException + * if the specified {@code index} is less than {@code 0} or + * {@code index + 4} is greater than {@code this.capacity} + */ + public abstract int getInt(int index); + + /** + * Gets an unsigned 32-bit integer at the specified absolute {@code index} + * in this buffer. This method does not modify {@code readerIndex} or + * {@code writerIndex} of this buffer. + * + * @throws IndexOutOfBoundsException + * if the specified {@code index} is less than {@code 0} or + * {@code index + 4} is greater than {@code this.capacity} + */ + public abstract long getUnsignedInt(int index); + + /** + * Gets a 64-bit long integer at the specified absolute {@code index} in + * this buffer. This method does not modify {@code readerIndex} or + * {@code writerIndex} of this buffer. + * + * @throws IndexOutOfBoundsException + * if the specified {@code index} is less than {@code 0} or + * {@code index + 8} is greater than {@code this.capacity} + */ + public abstract long getLong(int index); + + /** + * Gets a 2-byte UTF-16 character at the specified absolute + * {@code index} in this buffer. This method does not modify + * {@code readerIndex} or {@code writerIndex} of this buffer. + * + * @throws IndexOutOfBoundsException + * if the specified {@code index} is less than {@code 0} or + * {@code index + 2} is greater than {@code this.capacity} + */ + public abstract char getChar(int index); + + /** + * Gets a 32-bit floating point number at the specified absolute + * {@code index} in this buffer. This method does not modify + * {@code readerIndex} or {@code writerIndex} of this buffer. + * + * @throws IndexOutOfBoundsException + * if the specified {@code index} is less than {@code 0} or + * {@code index + 4} is greater than {@code this.capacity} + */ + public abstract float getFloat(int index); + + /** + * Gets a 64-bit floating point number at the specified absolute + * {@code index} in this buffer. This method does not modify + * {@code readerIndex} or {@code writerIndex} of this buffer. + * + * @throws IndexOutOfBoundsException + * if the specified {@code index} is less than {@code 0} or + * {@code index + 8} is greater than {@code this.capacity} + */ + public abstract double getDouble(int index); + + /** + * Transfers this buffer's data to the specified destination starting at + * the specified absolute {@code index} until the destination becomes + * non-writable. This method is basically same with + * {@link #getBytes(int, ByteBuf, int, int)}, except that this + * method increases the {@code writerIndex} of the destination by the + * number of the transferred bytes while + * {@link #getBytes(int, ByteBuf, int, int)} does not. + * This method does not modify {@code readerIndex} or {@code writerIndex} of + * the source buffer (i.e. {@code this}). + * + * @throws IndexOutOfBoundsException + * if the specified {@code index} is less than {@code 0} or + * if {@code index + dst.writableBytes} is greater than + * {@code this.capacity} + */ + public abstract ByteBuf getBytes(int index, ByteBuf dst); + + /** + * Transfers this buffer's data to the specified destination starting at + * the specified absolute {@code index}. This method is basically same + * with {@link #getBytes(int, ByteBuf, int, int)}, except that this + * method increases the {@code writerIndex} of the destination by the + * number of the transferred bytes while + * {@link #getBytes(int, ByteBuf, int, int)} does not. + * This method does not modify {@code readerIndex} or {@code writerIndex} of + * the source buffer (i.e. {@code this}). + * + * @param length the number of bytes to transfer + * + * @throws IndexOutOfBoundsException + * if the specified {@code index} is less than {@code 0}, + * if {@code index + length} is greater than + * {@code this.capacity}, or + * if {@code length} is greater than {@code dst.writableBytes} + */ + public abstract ByteBuf getBytes(int index, ByteBuf dst, int length); + + /** + * Transfers this buffer's data to the specified destination starting at + * the specified absolute {@code index}. + * This method does not modify {@code readerIndex} or {@code writerIndex} + * of both the source (i.e. {@code this}) and the destination. + * + * @param dstIndex the first index of the destination + * @param length the number of bytes to transfer + * + * @throws IndexOutOfBoundsException + * if the specified {@code index} is less than {@code 0}, + * if the specified {@code dstIndex} is less than {@code 0}, + * if {@code index + length} is greater than + * {@code this.capacity}, or + * if {@code dstIndex + length} is greater than + * {@code dst.capacity} + */ + public abstract ByteBuf getBytes(int index, ByteBuf dst, int dstIndex, int length); + + /** + * Transfers this buffer's data to the specified destination starting at + * the specified absolute {@code index}. + * This method does not modify {@code readerIndex} or {@code writerIndex} of + * this buffer + * + * @throws IndexOutOfBoundsException + * if the specified {@code index} is less than {@code 0} or + * if {@code index + dst.length} is greater than + * {@code this.capacity} + */ + public abstract ByteBuf getBytes(int index, byte[] dst); + + /** + * Transfers this buffer's data to the specified destination starting at + * the specified absolute {@code index}. + * This method does not modify {@code readerIndex} or {@code writerIndex} + * of this buffer. + * + * @param dstIndex the first index of the destination + * @param length the number of bytes to transfer + * + * @throws IndexOutOfBoundsException + * if the specified {@code index} is less than {@code 0}, + * if the specified {@code dstIndex} is less than {@code 0}, + * if {@code index + length} is greater than + * {@code this.capacity}, or + * if {@code dstIndex + length} is greater than + * {@code dst.length} + */ + public abstract ByteBuf getBytes(int index, byte[] dst, int dstIndex, int length); + + /** + * Transfers this buffer's data to the specified destination starting at + * the specified absolute {@code index} until the destination's position + * reaches its limit. + * This method does not modify {@code readerIndex} or {@code writerIndex} of + * this buffer while the destination's {@code position} will be increased. + * + * @throws IndexOutOfBoundsException + * if the specified {@code index} is less than {@code 0} or + * if {@code index + dst.remaining()} is greater than + * {@code this.capacity} + */ + public abstract ByteBuf getBytes(int index, ByteBuffer dst); + + /** + * Transfers this buffer's data to the specified stream starting at the + * specified absolute {@code index}. + * This method does not modify {@code readerIndex} or {@code writerIndex} of + * this buffer. + * + * @param length the number of bytes to transfer + * + * @throws IndexOutOfBoundsException + * if the specified {@code index} is less than {@code 0} or + * if {@code index + length} is greater than + * {@code this.capacity} + * @throws IOException + * if the specified stream threw an exception during I/O + */ + public abstract ByteBuf getBytes(int index, OutputStream out, int length) throws IOException; + + /** + * Transfers this buffer's data to the specified channel starting at the + * specified absolute {@code index}. + * This method does not modify {@code readerIndex} or {@code writerIndex} of + * this buffer. + * + * @param length the maximum number of bytes to transfer + * + * @return the actual number of bytes written out to the specified channel + * + * @throws IndexOutOfBoundsException + * if the specified {@code index} is less than {@code 0} or + * if {@code index + length} is greater than + * {@code this.capacity} + * @throws IOException + * if the specified channel threw an exception during I/O + */ + public abstract int getBytes(int index, GatheringByteChannel out, int length) throws IOException; + + /** + * Sets the specified boolean at the specified absolute {@code index} in this + * buffer. + * This method does not modify {@code readerIndex} or {@code writerIndex} of + * this buffer. + * + * @throws IndexOutOfBoundsException + * if the specified {@code index} is less than {@code 0} or + * {@code index + 1} is greater than {@code this.capacity} + */ + public abstract ByteBuf setBoolean(int index, boolean value); + + /** + * Sets the specified byte at the specified absolute {@code index} in this + * buffer. The 24 high-order bits of the specified value are ignored. + * This method does not modify {@code readerIndex} or {@code writerIndex} of + * this buffer. + * + * @throws IndexOutOfBoundsException + * if the specified {@code index} is less than {@code 0} or + * {@code index + 1} is greater than {@code this.capacity} + */ + public abstract ByteBuf setByte(int index, int value); + + /** + * Sets the specified 16-bit short integer at the specified absolute + * {@code index} in this buffer. The 16 high-order bits of the specified + * value are ignored. + * This method does not modify {@code readerIndex} or {@code writerIndex} of + * this buffer. + * + * @throws IndexOutOfBoundsException + * if the specified {@code index} is less than {@code 0} or + * {@code index + 2} is greater than {@code this.capacity} + */ + public abstract ByteBuf setShort(int index, int value); + + /** + * Sets the specified 24-bit medium integer at the specified absolute + * {@code index} in this buffer. Please note that the most significant + * byte is ignored in the specified value. + * This method does not modify {@code readerIndex} or {@code writerIndex} of + * this buffer. + * + * @throws IndexOutOfBoundsException + * if the specified {@code index} is less than {@code 0} or + * {@code index + 3} is greater than {@code this.capacity} + */ + public abstract ByteBuf setMedium(int index, int value); + + /** + * Sets the specified 32-bit integer at the specified absolute + * {@code index} in this buffer. + * This method does not modify {@code readerIndex} or {@code writerIndex} of + * this buffer. + * + * @throws IndexOutOfBoundsException + * if the specified {@code index} is less than {@code 0} or + * {@code index + 4} is greater than {@code this.capacity} + */ + public abstract ByteBuf setInt(int index, int value); + + /** + * Sets the specified 64-bit long integer at the specified absolute + * {@code index} in this buffer. + * This method does not modify {@code readerIndex} or {@code writerIndex} of + * this buffer. + * + * @throws IndexOutOfBoundsException + * if the specified {@code index} is less than {@code 0} or + * {@code index + 8} is greater than {@code this.capacity} + */ + public abstract ByteBuf setLong(int index, long value); + + /** + * Sets the specified 2-byte UTF-16 character at the specified absolute + * {@code index} in this buffer. + * The 16 high-order bits of the specified value are ignored. + * This method does not modify {@code readerIndex} or {@code writerIndex} of + * this buffer. + * + * @throws IndexOutOfBoundsException + * if the specified {@code index} is less than {@code 0} or + * {@code index + 2} is greater than {@code this.capacity} + */ + public abstract ByteBuf setChar(int index, int value); + + /** + * Sets the specified 32-bit floating-point number at the specified + * absolute {@code index} in this buffer. + * This method does not modify {@code readerIndex} or {@code writerIndex} of + * this buffer. + * + * @throws IndexOutOfBoundsException + * if the specified {@code index} is less than {@code 0} or + * {@code index + 4} is greater than {@code this.capacity} + */ + public abstract ByteBuf setFloat(int index, float value); + + /** + * Sets the specified 64-bit floating-point number at the specified + * absolute {@code index} in this buffer. + * This method does not modify {@code readerIndex} or {@code writerIndex} of + * this buffer. + * + * @throws IndexOutOfBoundsException + * if the specified {@code index} is less than {@code 0} or + * {@code index + 8} is greater than {@code this.capacity} + */ + public abstract ByteBuf setDouble(int index, double value); + + /** + * Transfers the specified source buffer's data to this buffer starting at + * the specified absolute {@code index} until the source buffer becomes + * unreadable. This method is basically same with + * {@link #setBytes(int, ByteBuf, int, int)}, except that this + * method increases the {@code readerIndex} of the source buffer by + * the number of the transferred bytes while + * {@link #setBytes(int, ByteBuf, int, int)} does not. + * This method does not modify {@code readerIndex} or {@code writerIndex} of + * the source buffer (i.e. {@code this}). + * + * @throws IndexOutOfBoundsException + * if the specified {@code index} is less than {@code 0} or + * if {@code index + src.readableBytes} is greater than + * {@code this.capacity} + */ + public abstract ByteBuf setBytes(int index, ByteBuf src); + + /** + * Transfers the specified source buffer's data to this buffer starting at + * the specified absolute {@code index}. This method is basically same + * with {@link #setBytes(int, ByteBuf, int, int)}, except that this + * method increases the {@code readerIndex} of the source buffer by + * the number of the transferred bytes while + * {@link #setBytes(int, ByteBuf, int, int)} does not. + * This method does not modify {@code readerIndex} or {@code writerIndex} of + * the source buffer (i.e. {@code this}). + * + * @param length the number of bytes to transfer + * + * @throws IndexOutOfBoundsException + * if the specified {@code index} is less than {@code 0}, + * if {@code index + length} is greater than + * {@code this.capacity}, or + * if {@code length} is greater than {@code src.readableBytes} + */ + public abstract ByteBuf setBytes(int index, ByteBuf src, int length); + + /** + * Transfers the specified source buffer's data to this buffer starting at + * the specified absolute {@code index}. + * This method does not modify {@code readerIndex} or {@code writerIndex} + * of both the source (i.e. {@code this}) and the destination. + * + * @param srcIndex the first index of the source + * @param length the number of bytes to transfer + * + * @throws IndexOutOfBoundsException + * if the specified {@code index} is less than {@code 0}, + * if the specified {@code srcIndex} is less than {@code 0}, + * if {@code index + length} is greater than + * {@code this.capacity}, or + * if {@code srcIndex + length} is greater than + * {@code src.capacity} + */ + public abstract ByteBuf setBytes(int index, ByteBuf src, int srcIndex, int length); + + /** + * Transfers the specified source array's data to this buffer starting at + * the specified absolute {@code index}. + * This method does not modify {@code readerIndex} or {@code writerIndex} of + * this buffer. + * + * @throws IndexOutOfBoundsException + * if the specified {@code index} is less than {@code 0} or + * if {@code index + src.length} is greater than + * {@code this.capacity} + */ + public abstract ByteBuf setBytes(int index, byte[] src); + + /** + * Transfers the specified source array's data to this buffer starting at + * the specified absolute {@code index}. + * This method does not modify {@code readerIndex} or {@code writerIndex} of + * this buffer. + * + * @throws IndexOutOfBoundsException + * if the specified {@code index} is less than {@code 0}, + * if the specified {@code srcIndex} is less than {@code 0}, + * if {@code index + length} is greater than + * {@code this.capacity}, or + * if {@code srcIndex + length} is greater than {@code src.length} + */ + public abstract ByteBuf setBytes(int index, byte[] src, int srcIndex, int length); + + /** + * Transfers the specified source buffer's data to this buffer starting at + * the specified absolute {@code index} until the source buffer's position + * reaches its limit. + * This method does not modify {@code readerIndex} or {@code writerIndex} of + * this buffer. + * + * @throws IndexOutOfBoundsException + * if the specified {@code index} is less than {@code 0} or + * if {@code index + src.remaining()} is greater than + * {@code this.capacity} + */ + public abstract ByteBuf setBytes(int index, ByteBuffer src); + + /** + * Transfers the content of the specified source stream to this buffer + * starting at the specified absolute {@code index}. + * This method does not modify {@code readerIndex} or {@code writerIndex} of + * this buffer. + * + * @param length the number of bytes to transfer + * + * @return the actual number of bytes read in from the specified channel. + * {@code -1} if the specified channel is closed. + * + * @throws IndexOutOfBoundsException + * if the specified {@code index} is less than {@code 0} or + * if {@code index + length} is greater than {@code this.capacity} + * @throws IOException + * if the specified stream threw an exception during I/O + */ + public abstract int setBytes(int index, InputStream in, int length) throws IOException; + + /** + * Transfers the content of the specified source channel to this buffer + * starting at the specified absolute {@code index}. + * This method does not modify {@code readerIndex} or {@code writerIndex} of + * this buffer. + * + * @param length the maximum number of bytes to transfer + * + * @return the actual number of bytes read in from the specified channel. + * {@code -1} if the specified channel is closed. + * + * @throws IndexOutOfBoundsException + * if the specified {@code index} is less than {@code 0} or + * if {@code index + length} is greater than {@code this.capacity} + * @throws IOException + * if the specified channel threw an exception during I/O + */ + public abstract int setBytes(int index, ScatteringByteChannel in, int length) throws IOException; + + /** + * Fills this buffer with NUL (0x00) starting at the specified + * absolute {@code index}. + * This method does not modify {@code readerIndex} or {@code writerIndex} of + * this buffer. + * + * @param length the number of NULs to write to the buffer + * + * @throws IndexOutOfBoundsException + * if the specified {@code index} is less than {@code 0} or + * if {@code index + length} is greater than {@code this.capacity} + */ + public abstract ByteBuf setZero(int index, int length); + + /** + * Gets a boolean at the current {@code readerIndex} and increases + * the {@code readerIndex} by {@code 1} in this buffer. + * + * @throws IndexOutOfBoundsException + * if {@code this.readableBytes} is less than {@code 1} + */ + public abstract boolean readBoolean(); + + /** + * Gets a byte at the current {@code readerIndex} and increases + * the {@code readerIndex} by {@code 1} in this buffer. + * + * @throws IndexOutOfBoundsException + * if {@code this.readableBytes} is less than {@code 1} + */ + public abstract byte readByte(); + + /** + * Gets an unsigned byte at the current {@code readerIndex} and increases + * the {@code readerIndex} by {@code 1} in this buffer. + * + * @throws IndexOutOfBoundsException + * if {@code this.readableBytes} is less than {@code 1} + */ + public abstract short readUnsignedByte(); + + /** + * Gets a 16-bit short integer at the current {@code readerIndex} + * and increases the {@code readerIndex} by {@code 2} in this buffer. + * + * @throws IndexOutOfBoundsException + * if {@code this.readableBytes} is less than {@code 2} + */ + public abstract short readShort(); + + /** + * Gets an unsigned 16-bit short integer at the current {@code readerIndex} + * and increases the {@code readerIndex} by {@code 2} in this buffer. + * + * @throws IndexOutOfBoundsException + * if {@code this.readableBytes} is less than {@code 2} + */ + public abstract int readUnsignedShort(); + + /** + * Gets a 24-bit medium integer at the current {@code readerIndex} + * and increases the {@code readerIndex} by {@code 3} in this buffer. + * + * @throws IndexOutOfBoundsException + * if {@code this.readableBytes} is less than {@code 3} + */ + public abstract int readMedium(); + + /** + * Gets an unsigned 24-bit medium integer at the current {@code readerIndex} + * and increases the {@code readerIndex} by {@code 3} in this buffer. + * + * @throws IndexOutOfBoundsException + * if {@code this.readableBytes} is less than {@code 3} + */ + public abstract int readUnsignedMedium(); + + /** + * Gets a 32-bit integer at the current {@code readerIndex} + * and increases the {@code readerIndex} by {@code 4} in this buffer. + * + * @throws IndexOutOfBoundsException + * if {@code this.readableBytes} is less than {@code 4} + */ + public abstract int readInt(); + + /** + * Gets an unsigned 32-bit integer at the current {@code readerIndex} + * and increases the {@code readerIndex} by {@code 4} in this buffer. + * + * @throws IndexOutOfBoundsException + * if {@code this.readableBytes} is less than {@code 4} + */ + public abstract long readUnsignedInt(); + + /** + * Gets a 64-bit integer at the current {@code readerIndex} + * and increases the {@code readerIndex} by {@code 8} in this buffer. + * + * @throws IndexOutOfBoundsException + * if {@code this.readableBytes} is less than {@code 8} + */ + public abstract long readLong(); + + /** + * Gets a 2-byte UTF-16 character at the current {@code readerIndex} + * and increases the {@code readerIndex} by {@code 2} in this buffer. + * + * @throws IndexOutOfBoundsException + * if {@code this.readableBytes} is less than {@code 2} + */ + public abstract char readChar(); + + /** + * Gets a 32-bit floating point number at the current {@code readerIndex} + * and increases the {@code readerIndex} by {@code 4} in this buffer. + * + * @throws IndexOutOfBoundsException + * if {@code this.readableBytes} is less than {@code 4} + */ + public abstract float readFloat(); + + /** + * Gets a 64-bit floating point number at the current {@code readerIndex} + * and increases the {@code readerIndex} by {@code 8} in this buffer. + * + * @throws IndexOutOfBoundsException + * if {@code this.readableBytes} is less than {@code 8} + */ + public abstract double readDouble(); + + /** + * Transfers this buffer's data to a newly created buffer starting at + * the current {@code readerIndex} and increases the {@code readerIndex} + * by the number of the transferred bytes (= {@code length}). + * The returned buffer's {@code readerIndex} and {@code writerIndex} are + * {@code 0} and {@code length} respectively. + * + * @param length the number of bytes to transfer + * + * @return the newly created buffer which contains the transferred bytes + * + * @throws IndexOutOfBoundsException + * if {@code length} is greater than {@code this.readableBytes} + */ + public abstract ByteBuf readBytes(int length); + + /** + * Returns a new slice of this buffer's sub-region starting at the current + * {@code readerIndex} and increases the {@code readerIndex} by the size + * of the new slice (= {@code length}). + * + * @param length the size of the new slice + * + * @return the newly created slice + * + * @throws IndexOutOfBoundsException + * if {@code length} is greater than {@code this.readableBytes} + */ + public abstract ByteBuf readSlice(int length); + + /** + * Transfers this buffer's data to the specified destination starting at + * the current {@code readerIndex} until the destination becomes + * non-writable, and increases the {@code readerIndex} by the number of the + * transferred bytes. This method is basically same with + * {@link #readBytes(ByteBuf, int, int)}, except that this method + * increases the {@code writerIndex} of the destination by the number of + * the transferred bytes while {@link #readBytes(ByteBuf, int, int)} + * does not. + * + * @throws IndexOutOfBoundsException + * if {@code dst.writableBytes} is greater than + * {@code this.readableBytes} + */ + public abstract ByteBuf readBytes(ByteBuf dst); + + /** + * Transfers this buffer's data to the specified destination starting at + * the current {@code readerIndex} and increases the {@code readerIndex} + * by the number of the transferred bytes (= {@code length}). This method + * is basically same with {@link #readBytes(ByteBuf, int, int)}, + * except that this method increases the {@code writerIndex} of the + * destination by the number of the transferred bytes (= {@code length}) + * while {@link #readBytes(ByteBuf, int, int)} does not. + * + * @throws IndexOutOfBoundsException + * if {@code length} is greater than {@code this.readableBytes} or + * if {@code length} is greater than {@code dst.writableBytes} + */ + public abstract ByteBuf readBytes(ByteBuf dst, int length); + + /** + * Transfers this buffer's data to the specified destination starting at + * the current {@code readerIndex} and increases the {@code readerIndex} + * by the number of the transferred bytes (= {@code length}). + * + * @param dstIndex the first index of the destination + * @param length the number of bytes to transfer + * + * @throws IndexOutOfBoundsException + * if the specified {@code dstIndex} is less than {@code 0}, + * if {@code length} is greater than {@code this.readableBytes}, or + * if {@code dstIndex + length} is greater than + * {@code dst.capacity} + */ + public abstract ByteBuf readBytes(ByteBuf dst, int dstIndex, int length); + + /** + * Transfers this buffer's data to the specified destination starting at + * the current {@code readerIndex} and increases the {@code readerIndex} + * by the number of the transferred bytes (= {@code dst.length}). + * + * @throws IndexOutOfBoundsException + * if {@code dst.length} is greater than {@code this.readableBytes} + */ + public abstract ByteBuf readBytes(byte[] dst); + + /** + * Transfers this buffer's data to the specified destination starting at + * the current {@code readerIndex} and increases the {@code readerIndex} + * by the number of the transferred bytes (= {@code length}). + * + * @param dstIndex the first index of the destination + * @param length the number of bytes to transfer + * + * @throws IndexOutOfBoundsException + * if the specified {@code dstIndex} is less than {@code 0}, + * if {@code length} is greater than {@code this.readableBytes}, or + * if {@code dstIndex + length} is greater than {@code dst.length} + */ + public abstract ByteBuf readBytes(byte[] dst, int dstIndex, int length); + + /** + * Transfers this buffer's data to the specified destination starting at + * the current {@code readerIndex} until the destination's position + * reaches its limit, and increases the {@code readerIndex} by the + * number of the transferred bytes. + * + * @throws IndexOutOfBoundsException + * if {@code dst.remaining()} is greater than + * {@code this.readableBytes} + */ + public abstract ByteBuf readBytes(ByteBuffer dst); + + /** + * Transfers this buffer's data to the specified stream starting at the + * current {@code readerIndex}. + * + * @param length the number of bytes to transfer + * + * @throws IndexOutOfBoundsException + * if {@code length} is greater than {@code this.readableBytes} + * @throws IOException + * if the specified stream threw an exception during I/O + */ + public abstract ByteBuf readBytes(OutputStream out, int length) throws IOException; + + /** + * Transfers this buffer's data to the specified stream starting at the + * current {@code readerIndex}. + * + * @param length the maximum number of bytes to transfer + * + * @return the actual number of bytes written out to the specified channel + * + * @throws IndexOutOfBoundsException + * if {@code length} is greater than {@code this.readableBytes} + * @throws IOException + * if the specified channel threw an exception during I/O + */ + public abstract int readBytes(GatheringByteChannel out, int length) throws IOException; + + /** + * Increases the current {@code readerIndex} by the specified + * {@code length} in this buffer. + * + * @throws IndexOutOfBoundsException + * if {@code length} is greater than {@code this.readableBytes} + */ + public abstract ByteBuf skipBytes(int length); + + /** + * Sets the specified boolean at the current {@code writerIndex} + * and increases the {@code writerIndex} by {@code 1} in this buffer. + * + * @throws IndexOutOfBoundsException + * if {@code this.writableBytes} is less than {@code 1} + */ + public abstract ByteBuf writeBoolean(boolean value); + + /** + * Sets the specified byte at the current {@code writerIndex} + * and increases the {@code writerIndex} by {@code 1} in this buffer. + * The 24 high-order bits of the specified value are ignored. + * + * @throws IndexOutOfBoundsException + * if {@code this.writableBytes} is less than {@code 1} + */ + public abstract ByteBuf writeByte(int value); + + /** + * Sets the specified 16-bit short integer at the current + * {@code writerIndex} and increases the {@code writerIndex} by {@code 2} + * in this buffer. The 16 high-order bits of the specified value are ignored. + * + * @throws IndexOutOfBoundsException + * if {@code this.writableBytes} is less than {@code 2} + */ + public abstract ByteBuf writeShort(int value); + + /** + * Sets the specified 24-bit medium integer at the current + * {@code writerIndex} and increases the {@code writerIndex} by {@code 3} + * in this buffer. + * + * @throws IndexOutOfBoundsException + * if {@code this.writableBytes} is less than {@code 3} + */ + public abstract ByteBuf writeMedium(int value); + + /** + * Sets the specified 32-bit integer at the current {@code writerIndex} + * and increases the {@code writerIndex} by {@code 4} in this buffer. + * + * @throws IndexOutOfBoundsException + * if {@code this.writableBytes} is less than {@code 4} + */ + public abstract ByteBuf writeInt(int value); + + /** + * Sets the specified 64-bit long integer at the current + * {@code writerIndex} and increases the {@code writerIndex} by {@code 8} + * in this buffer. + * + * @throws IndexOutOfBoundsException + * if {@code this.writableBytes} is less than {@code 8} + */ + public abstract ByteBuf writeLong(long value); + + /** + * Sets the specified 2-byte UTF-16 character at the current + * {@code writerIndex} and increases the {@code writerIndex} by {@code 2} + * in this buffer. The 16 high-order bits of the specified value are ignored. + * + * @throws IndexOutOfBoundsException + * if {@code this.writableBytes} is less than {@code 2} + */ + public abstract ByteBuf writeChar(int value); + + /** + * Sets the specified 32-bit floating point number at the current + * {@code writerIndex} and increases the {@code writerIndex} by {@code 4} + * in this buffer. + * + * @throws IndexOutOfBoundsException + * if {@code this.writableBytes} is less than {@code 4} + */ + public abstract ByteBuf writeFloat(float value); + + /** + * Sets the specified 64-bit floating point number at the current + * {@code writerIndex} and increases the {@code writerIndex} by {@code 8} + * in this buffer. + * + * @throws IndexOutOfBoundsException + * if {@code this.writableBytes} is less than {@code 8} + */ + public abstract ByteBuf writeDouble(double value); + + /** + * Transfers the specified source buffer's data to this buffer starting at + * the current {@code writerIndex} until the source buffer becomes + * unreadable, and increases the {@code writerIndex} by the number of + * the transferred bytes. This method is basically same with + * {@link #writeBytes(ByteBuf, int, int)}, except that this method + * increases the {@code readerIndex} of the source buffer by the number of + * the transferred bytes while {@link #writeBytes(ByteBuf, int, int)} + * does not. + * + * @throws IndexOutOfBoundsException + * if {@code src.readableBytes} is greater than + * {@code this.writableBytes} + */ + public abstract ByteBuf writeBytes(ByteBuf src); + + /** + * Transfers the specified source buffer's data to this buffer starting at + * the current {@code writerIndex} and increases the {@code writerIndex} + * by the number of the transferred bytes (= {@code length}). This method + * is basically same with {@link #writeBytes(ByteBuf, int, int)}, + * except that this method increases the {@code readerIndex} of the source + * buffer by the number of the transferred bytes (= {@code length}) while + * {@link #writeBytes(ByteBuf, int, int)} does not. + * + * @param length the number of bytes to transfer + * + * @throws IndexOutOfBoundsException + * if {@code length} is greater than {@code this.writableBytes} or + * if {@code length} is greater then {@code src.readableBytes} + */ + public abstract ByteBuf writeBytes(ByteBuf src, int length); + + /** + * Transfers the specified source buffer's data to this buffer starting at + * the current {@code writerIndex} and increases the {@code writerIndex} + * by the number of the transferred bytes (= {@code length}). + * + * @param srcIndex the first index of the source + * @param length the number of bytes to transfer + * + * @throws IndexOutOfBoundsException + * if the specified {@code srcIndex} is less than {@code 0}, + * if {@code srcIndex + length} is greater than + * {@code src.capacity}, or + * if {@code length} is greater than {@code this.writableBytes} + */ + public abstract ByteBuf writeBytes(ByteBuf src, int srcIndex, int length); + + /** + * Transfers the specified source array's data to this buffer starting at + * the current {@code writerIndex} and increases the {@code writerIndex} + * by the number of the transferred bytes (= {@code src.length}). + * + * @throws IndexOutOfBoundsException + * if {@code src.length} is greater than {@code this.writableBytes} + */ + public abstract ByteBuf writeBytes(byte[] src); + + /** + * Transfers the specified source array's data to this buffer starting at + * the current {@code writerIndex} and increases the {@code writerIndex} + * by the number of the transferred bytes (= {@code length}). + * + * @param srcIndex the first index of the source + * @param length the number of bytes to transfer + * + * @throws IndexOutOfBoundsException + * if the specified {@code srcIndex} is less than {@code 0}, + * if {@code srcIndex + length} is greater than + * {@code src.length}, or + * if {@code length} is greater than {@code this.writableBytes} + */ + public abstract ByteBuf writeBytes(byte[] src, int srcIndex, int length); + + /** + * Transfers the specified source buffer's data to this buffer starting at + * the current {@code writerIndex} until the source buffer's position + * reaches its limit, and increases the {@code writerIndex} by the + * number of the transferred bytes. + * + * @throws IndexOutOfBoundsException + * if {@code src.remaining()} is greater than + * {@code this.writableBytes} + */ + public abstract ByteBuf writeBytes(ByteBuffer src); + + /** + * Transfers the content of the specified stream to this buffer + * starting at the current {@code writerIndex} and increases the + * {@code writerIndex} by the number of the transferred bytes. + * + * @param length the number of bytes to transfer + * + * @return the actual number of bytes read in from the specified stream + * + * @throws IndexOutOfBoundsException + * if {@code length} is greater than {@code this.writableBytes} + * @throws IOException + * if the specified stream threw an exception during I/O + */ + public abstract int writeBytes(InputStream in, int length) throws IOException; + + /** + * Transfers the content of the specified channel to this buffer + * starting at the current {@code writerIndex} and increases the + * {@code writerIndex} by the number of the transferred bytes. + * + * @param length the maximum number of bytes to transfer + * + * @return the actual number of bytes read in from the specified channel + * + * @throws IndexOutOfBoundsException + * if {@code length} is greater than {@code this.writableBytes} + * @throws IOException + * if the specified channel threw an exception during I/O + */ + public abstract int writeBytes(ScatteringByteChannel in, int length) throws IOException; + + /** + * Fills this buffer with NUL (0x00) starting at the current + * {@code writerIndex} and increases the {@code writerIndex} by the + * specified {@code length}. + * + * @param length the number of NULs to write to the buffer + * + * @throws IndexOutOfBoundsException + * if {@code length} is greater than {@code this.writableBytes} + */ + public abstract ByteBuf writeZero(int length); + + /** + * Locates the first occurrence of the specified {@code value} in this + * buffer. The search takes place from the specified {@code fromIndex} + * (inclusive) to the specified {@code toIndex} (exclusive). + *

+ * If {@code fromIndex} is greater than {@code toIndex}, the search is + * performed in a reversed order. + *

+ * This method does not modify {@code readerIndex} or {@code writerIndex} of + * this buffer. + * + * @return the absolute index of the first occurrence if found. + * {@code -1} otherwise. + */ + public abstract int indexOf(int fromIndex, int toIndex, byte value); + + /** + * Locates the first occurrence of the specified {@code value} in this + * buffer. The search takes place from the current {@code readerIndex} + * (inclusive) to the current {@code writerIndex} (exclusive). + *

+ * This method does not modify {@code readerIndex} or {@code writerIndex} of + * this buffer. + * + * @return the number of bytes between the current {@code readerIndex} + * and the first occurrence if found. {@code -1} otherwise. + */ + public abstract int bytesBefore(byte value); + + /** + * Locates the first occurrence of the specified {@code value} in this + * buffer. The search starts from the current {@code readerIndex} + * (inclusive) and lasts for the specified {@code length}. + *

+ * This method does not modify {@code readerIndex} or {@code writerIndex} of + * this buffer. + * + * @return the number of bytes between the current {@code readerIndex} + * and the first occurrence if found. {@code -1} otherwise. + * + * @throws IndexOutOfBoundsException + * if {@code length} is greater than {@code this.readableBytes} + */ + public abstract int bytesBefore(int length, byte value); + + /** + * Locates the first occurrence of the specified {@code value} in this + * buffer. The search starts from the specified {@code index} (inclusive) + * and lasts for the specified {@code length}. + *

+ * This method does not modify {@code readerIndex} or {@code writerIndex} of + * this buffer. + * + * @return the number of bytes between the specified {@code index} + * and the first occurrence if found. {@code -1} otherwise. + * + * @throws IndexOutOfBoundsException + * if {@code index + length} is greater than {@code this.capacity} + */ + public abstract int bytesBefore(int index, int length, byte value); + + /** + * Iterates over the readable bytes of this buffer with the specified {@code processor} in ascending order. + * + * @return {@code -1} if the processor iterated to or beyond the end of the readable bytes. + * The last-visited index If the {@link ByteBufProcessor#process(byte)} returned {@code false}. + */ + public abstract int forEachByte(ByteBufProcessor processor); + + /** + * Iterates over the specified area of this buffer with the specified {@code processor} in ascending order. + * (i.e. {@code index}, {@code (index + 1)}, .. {@code (index + length - 1)}) + * + * @return {@code -1} if the processor iterated to or beyond the end of the specified area. + * The last-visited index If the {@link ByteBufProcessor#process(byte)} returned {@code false}. + */ + public abstract int forEachByte(int index, int length, ByteBufProcessor processor); + + /** + * Iterates over the readable bytes of this buffer with the specified {@code processor} in descending order. + * + * @return {@code -1} if the processor iterated to or beyond the beginning of the readable bytes. + * The last-visited index If the {@link ByteBufProcessor#process(byte)} returned {@code false}. + */ + public abstract int forEachByteDesc(ByteBufProcessor processor); + + /** + * Iterates over the specified area of this buffer with the specified {@code processor} in descending order. + * (i.e. {@code (index + length - 1)}, {@code (index + length - 2)}, ... {@code index}) + * + * + * @return {@code -1} if the processor iterated to or beyond the beginning of the specified area. + * The last-visited index If the {@link ByteBufProcessor#process(byte)} returned {@code false}. + */ + public abstract int forEachByteDesc(int index, int length, ByteBufProcessor processor); + + /** + * Returns a copy of this buffer's readable bytes. Modifying the content + * of the returned buffer or this buffer does not affect each other at all. + * This method is identical to {@code buf.copy(buf.readerIndex(), buf.readableBytes())}. + * This method does not modify {@code readerIndex} or {@code writerIndex} of + * this buffer. + */ + public abstract ByteBuf copy(); + + /** + * Returns a copy of this buffer's sub-region. Modifying the content of + * the returned buffer or this buffer does not affect each other at all. + * This method does not modify {@code readerIndex} or {@code writerIndex} of + * this buffer. + */ + public abstract ByteBuf copy(int index, int length); + + /** + * Returns a slice of this buffer's readable bytes. Modifying the content + * of the returned buffer or this buffer affects each other's content + * while they maintain separate indexes and marks. This method is + * identical to {@code buf.slice(buf.readerIndex(), buf.readableBytes())}. + * This method does not modify {@code readerIndex} or {@code writerIndex} of + * this buffer. + */ + public abstract ByteBuf slice(); + + /** + * Returns a slice of this buffer's sub-region. Modifying the content of + * the returned buffer or this buffer affects each other's content while + * they maintain separate indexes and marks. + * This method does not modify {@code readerIndex} or {@code writerIndex} of + * this buffer. + */ + public abstract ByteBuf slice(int index, int length); + + /** + * Returns a buffer which shares the whole region of this buffer. + * Modifying the content of the returned buffer or this buffer affects + * each other's content while they maintain separate indexes and marks. + * This method is identical to {@code buf.slice(0, buf.capacity())}. + * This method does not modify {@code readerIndex} or {@code writerIndex} of + * this buffer. + */ + public abstract ByteBuf duplicate(); + + /** + * Returns the maximum number of NIO {@link ByteBuffer}s that consist this buffer. Note that {@link #nioBuffers()} + * or {@link #nioBuffers(int, int)} might return a less number of {@link ByteBuffer}s. + * + * @return {@code -1} if this buffer has no underlying {@link ByteBuffer}. + * the number of the underlying {@link ByteBuffer}s if this buffer has at least one underlying + * {@link ByteBuffer}. Note that this method does not return {@code 0} to avoid confusion. + * + * @see #nioBuffer() + * @see #nioBuffer(int, int) + * @see #nioBuffers() + * @see #nioBuffers(int, int) + */ + public abstract int nioBufferCount(); + + /** + * Exposes this buffer's readable bytes as an NIO {@link ByteBuffer}. The returned buffer + * shares the content with this buffer, while changing the position and limit of the returned + * NIO buffer does not affect the indexes and marks of this buffer. This method is identical + * to {@code buf.nioBuffer(buf.readerIndex(), buf.readableBytes())}. This method does not + * modify {@code readerIndex} or {@code writerIndex} of this buffer. Please note that the + * returned NIO buffer will not see the changes of this buffer if this buffer is a dynamic + * buffer and it adjusted its capacity. + * + * @throws UnsupportedOperationException + * if this buffer cannot create a {@link ByteBuffer} that shares the content with itself + * + * @see #nioBufferCount() + * @see #nioBuffers() + * @see #nioBuffers(int, int) + */ + public abstract ByteBuffer nioBuffer(); + + /** + * Exposes this buffer's sub-region as an NIO {@link ByteBuffer}. The returned buffer + * shares the content with this buffer, while changing the position and limit of the returned + * NIO buffer does not affect the indexes and marks of this buffer. This method does not + * modify {@code readerIndex} or {@code writerIndex} of this buffer. Please note that the + * returned NIO buffer will not see the changes of this buffer if this buffer is a dynamic + * buffer and it adjusted its capacity. + * + * @throws UnsupportedOperationException + * if this buffer cannot create a {@link ByteBuffer} that shares the content with itself + * + * @see #nioBufferCount() + * @see #nioBuffers() + * @see #nioBuffers(int, int) + */ + public abstract ByteBuffer nioBuffer(int index, int length); + + /** + * Internal use only: Exposes the internal NIO buffer. + */ + public abstract ByteBuffer internalNioBuffer(int index, int length); + + /** + * Exposes this buffer's readable bytes as an NIO {@link ByteBuffer}'s. The returned buffer + * shares the content with this buffer, while changing the position and limit of the returned + * NIO buffer does not affect the indexes and marks of this buffer. This method does not + * modify {@code readerIndex} or {@code writerIndex} of this buffer. Please note that the + * returned NIO buffer will not see the changes of this buffer if this buffer is a dynamic + * buffer and it adjusted its capacity. + * + * + * @throws UnsupportedOperationException + * if this buffer cannot create a {@link ByteBuffer} that shares the content with itself + * + * @see #nioBufferCount() + * @see #nioBuffer() + * @see #nioBuffer(int, int) + */ + public abstract ByteBuffer[] nioBuffers(); + + /** + * Exposes this buffer's bytes as an NIO {@link ByteBuffer}'s for the specified index and length + * The returned buffer shares the content with this buffer, while changing the position and limit + * of the returned NIO buffer does not affect the indexes and marks of this buffer. This method does + * not modify {@code readerIndex} or {@code writerIndex} of this buffer. Please note that the + * returned NIO buffer will not see the changes of this buffer if this buffer is a dynamic + * buffer and it adjusted its capacity. + * + * @throws UnsupportedOperationException + * if this buffer cannot create a {@link ByteBuffer} that shares the content with itself + * + * @see #nioBufferCount() + * @see #nioBuffer() + * @see #nioBuffer(int, int) + */ + public abstract ByteBuffer[] nioBuffers(int index, int length); + + /** + * Returns {@code true} if and only if this buffer has a backing byte array. + * If this method returns true, you can safely call {@link #array()} and + * {@link #arrayOffset()}. + */ + public abstract boolean hasArray(); + + /** + * Returns the backing byte array of this buffer. + * + * @throws UnsupportedOperationException + * if there no accessible backing byte array + */ + public abstract byte[] array(); + + /** + * Returns the offset of the first byte within the backing byte array of + * this buffer. + * + * @throws UnsupportedOperationException + * if there no accessible backing byte array + */ + public abstract int arrayOffset(); + + /** + * Returns {@code true} if and only if this buffer has a reference to the low-level memory address that points + * to the backing data. + */ + public abstract boolean hasMemoryAddress(); + + /** + * Returns the low-level memory address that point to the first byte of ths backing data. + * + * @throws UnsupportedOperationException + * if this buffer does not support accessing the low-level memory address + */ + public abstract long memoryAddress(); + + /** + * Decodes this buffer's readable bytes into a string with the specified + * character set name. This method is identical to + * {@code buf.toString(buf.readerIndex(), buf.readableBytes(), charsetName)}. + * This method does not modify {@code readerIndex} or {@code writerIndex} of + * this buffer. + * + * @throws UnsupportedCharsetException + * if the specified character set name is not supported by the + * current VM + */ + public abstract String toString(Charset charset); + + /** + * Decodes this buffer's sub-region into a string with the specified + * character set. This method does not modify {@code readerIndex} or + * {@code writerIndex} of this buffer. + */ + public abstract String toString(int index, int length, Charset charset); + + /** + * Returns a hash code which was calculated from the content of this + * buffer. If there's a byte array which is + * {@linkplain #equals(Object) equal to} this array, both arrays should + * return the same value. + */ + @Override + public abstract int hashCode(); + + /** + * Determines if the content of the specified buffer is identical to the + * content of this array. 'Identical' here means: + *

    + *
  • the size of the contents of the two buffers are same and
  • + *
  • every single byte of the content of the two buffers are same.
  • + *
+ * Please note that it does not compare {@link #readerIndex()} nor + * {@link #writerIndex()}. This method also returns {@code false} for + * {@code null} and an object which is not an instance of + * {@link ByteBuf} type. + */ + @Override + public abstract boolean equals(Object obj); + + /** + * Compares the content of the specified buffer to the content of this + * buffer. Comparison is performed in the same manner with the string + * comparison functions of various languages such as {@code strcmp}, + * {@code memcmp} and {@link String#compareTo(String)}. + */ + @Override + public abstract int compareTo(ByteBuf buffer); + + /** + * Returns the string representation of this buffer. This method does not + * necessarily return the whole content of the buffer but returns + * the values of the key properties such as {@link #readerIndex()}, + * {@link #writerIndex()} and {@link #capacity()}. + */ + @Override + public abstract String toString(); + + @Override + public abstract ByteBuf retain(int increment); + + @Override + public abstract ByteBuf retain(); +} diff --git a/common/src/common/net/buffer/ByteBufAllocator.java b/common/src/common/net/buffer/ByteBufAllocator.java new file mode 100644 index 0000000..045f669 --- /dev/null +++ b/common/src/common/net/buffer/ByteBufAllocator.java @@ -0,0 +1,128 @@ +/* + * Copyright 2012 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ +package common.net.buffer; + +/** + * Implementations are responsible to allocate buffers. Implementations of this interface are expected to be + * thread-safe. + */ +public interface ByteBufAllocator { + + ByteBufAllocator DEFAULT = ByteBufUtil.DEFAULT_ALLOCATOR; + + /** + * Allocate a {@link ByteBuf}. If it is a direct or heap buffer + * depends on the actual implementation. + */ + ByteBuf buffer(); + + /** + * Allocate a {@link ByteBuf} with the given initial capacity. + * If it is a direct or heap buffer depends on the actual implementation. + */ + ByteBuf buffer(int initialCapacity); + + /** + * Allocate a {@link ByteBuf} with the given initial capacity and the given + * maximal capacity. If it is a direct or heap buffer depends on the actual + * implementation. + */ + ByteBuf buffer(int initialCapacity, int maxCapacity); + + /** + * Allocate a {@link ByteBuf}, preferably a direct buffer which is suitable for I/O. + */ + ByteBuf ioBuffer(); + + /** + * Allocate a {@link ByteBuf}, preferably a direct buffer which is suitable for I/O. + */ + ByteBuf ioBuffer(int initialCapacity); + + /** + * Allocate a {@link ByteBuf}, preferably a direct buffer which is suitable for I/O. + */ + ByteBuf ioBuffer(int initialCapacity, int maxCapacity); + + /** + * Allocate a heap {@link ByteBuf}. + */ + ByteBuf heapBuffer(); + + /** + * Allocate a heap {@link ByteBuf} with the given initial capacity. + */ + ByteBuf heapBuffer(int initialCapacity); + + /** + * Allocate a heap {@link ByteBuf} with the given initial capacity and the given + * maximal capacity. + */ + ByteBuf heapBuffer(int initialCapacity, int maxCapacity); + + /** + * Allocate a direct {@link ByteBuf}. + */ + ByteBuf directBuffer(); + + /** + * Allocate a direct {@link ByteBuf} with the given initial capacity. + */ + ByteBuf directBuffer(int initialCapacity); + + /** + * Allocate a direct {@link ByteBuf} with the given initial capacity and the given + * maximal capacity. + */ + ByteBuf directBuffer(int initialCapacity, int maxCapacity); + + /** + * Allocate a {@link CompositeByteBuf}. + * If it is a direct or heap buffer depends on the actual implementation. + */ + CompositeByteBuf compositeBuffer(); + + /** + * Allocate a {@link CompositeByteBuf} with the given maximum number of components that can be stored in it. + * If it is a direct or heap buffer depends on the actual implementation. + */ + CompositeByteBuf compositeBuffer(int maxNumComponents); + + /** + * Allocate a heap {@link CompositeByteBuf}. + */ + CompositeByteBuf compositeHeapBuffer(); + + /** + * Allocate a heap {@link CompositeByteBuf} with the given maximum number of components that can be stored in it. + */ + CompositeByteBuf compositeHeapBuffer(int maxNumComponents); + + /** + * Allocate a direct {@link CompositeByteBuf}. + */ + CompositeByteBuf compositeDirectBuffer(); + + /** + * Allocate a direct {@link CompositeByteBuf} with the given maximum number of components that can be stored in it. + */ + CompositeByteBuf compositeDirectBuffer(int maxNumComponents); + + /** + * Returns {@code true} if direct {@link ByteBuf}'s are pooled + */ + boolean isDirectBufferPooled(); +} diff --git a/common/src/common/net/buffer/ByteBufInputStream.java b/common/src/common/net/buffer/ByteBufInputStream.java new file mode 100644 index 0000000..70a0925 --- /dev/null +++ b/common/src/common/net/buffer/ByteBufInputStream.java @@ -0,0 +1,257 @@ +/* + * Copyright 2012 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ +package common.net.buffer; + +import java.io.DataInput; +import java.io.DataInputStream; +import java.io.EOFException; +import java.io.IOException; +import java.io.InputStream; + +/** + * An {@link InputStream} which reads data from a {@link ByteBuf}. + *

+ * A read operation against this stream will occur at the {@code readerIndex} + * of its underlying buffer and the {@code readerIndex} will increase during + * the read operation. Please note that it only reads up to the number of + * readable bytes determined at the moment of construction. Therefore, + * updating {@link ByteBuf#writerIndex()} will not affect the return + * value of {@link #available()}. + *

+ * This stream implements {@link DataInput} for your convenience. + * The endianness of the stream is not always big endian but depends on + * the endianness of the underlying buffer. + * + * @see ByteBufOutputStream + */ +public class ByteBufInputStream extends InputStream implements DataInput { + + private final ByteBuf buffer; + private final int startIndex; + private final int endIndex; + + /** + * Creates a new stream which reads data from the specified {@code buffer} + * starting at the current {@code readerIndex} and ending at the current + * {@code writerIndex}. + */ + public ByteBufInputStream(ByteBuf buffer) { + this(buffer, buffer.readableBytes()); + } + + /** + * Creates a new stream which reads data from the specified {@code buffer} + * starting at the current {@code readerIndex} and ending at + * {@code readerIndex + length}. + * + * @throws IndexOutOfBoundsException + * if {@code readerIndex + length} is greater than + * {@code writerIndex} + */ + public ByteBufInputStream(ByteBuf buffer, int length) { + if (buffer == null) { + throw new NullPointerException("buffer"); + } + if (length < 0) { + throw new IllegalArgumentException("length: " + length); + } + if (length > buffer.readableBytes()) { + throw new IndexOutOfBoundsException("Too many bytes to be read - Needs " + + length + ", maximum is " + buffer.readableBytes()); + } + + this.buffer = buffer; + startIndex = buffer.readerIndex(); + endIndex = startIndex + length; + buffer.markReaderIndex(); + } + + /** + * Returns the number of read bytes by this stream so far. + */ + public int readBytes() { + return buffer.readerIndex() - startIndex; + } + + @Override + public int available() throws IOException { + return endIndex - buffer.readerIndex(); + } + + @Override + public void mark(int readlimit) { + buffer.markReaderIndex(); + } + + @Override + public boolean markSupported() { + return true; + } + + @Override + public int read() throws IOException { + if (!buffer.isReadable()) { + return -1; + } + return buffer.readByte() & 0xff; + } + + @Override + public int read(byte[] b, int off, int len) throws IOException { + int available = available(); + if (available == 0) { + return -1; + } + + len = Math.min(available, len); + buffer.readBytes(b, off, len); + return len; + } + + @Override + public void reset() throws IOException { + buffer.resetReaderIndex(); + } + + @Override + public long skip(long n) throws IOException { + if (n > Integer.MAX_VALUE) { + return skipBytes(Integer.MAX_VALUE); + } else { + return skipBytes((int) n); + } + } + + @Override + public boolean readBoolean() throws IOException { + checkAvailable(1); + return read() != 0; + } + + @Override + public byte readByte() throws IOException { + if (!buffer.isReadable()) { + throw new EOFException(); + } + return buffer.readByte(); + } + + @Override + public char readChar() throws IOException { + return (char) readShort(); + } + + @Override + public double readDouble() throws IOException { + return Double.longBitsToDouble(readLong()); + } + + @Override + public float readFloat() throws IOException { + return Float.intBitsToFloat(readInt()); + } + + @Override + public void readFully(byte[] b) throws IOException { + readFully(b, 0, b.length); + } + + @Override + public void readFully(byte[] b, int off, int len) throws IOException { + checkAvailable(len); + buffer.readBytes(b, off, len); + } + + @Override + public int readInt() throws IOException { + checkAvailable(4); + return buffer.readInt(); + } + + private final StringBuilder lineBuf = new StringBuilder(); + + @Override + public String readLine() throws IOException { + lineBuf.setLength(0); + + loop: while (true) { + if (!buffer.isReadable()) { + return lineBuf.length() > 0 ? lineBuf.toString() : null; + } + + int c = buffer.readUnsignedByte(); + switch (c) { + case '\n': + break loop; + + case '\r': + if (buffer.isReadable() && (char) buffer.getUnsignedByte(buffer.readerIndex()) == '\n') { + buffer.skipBytes(1); + } + break loop; + + default: + lineBuf.append((char) c); + } + } + + return lineBuf.toString(); + } + + @Override + public long readLong() throws IOException { + checkAvailable(8); + return buffer.readLong(); + } + + @Override + public short readShort() throws IOException { + checkAvailable(2); + return buffer.readShort(); + } + + @Override + public String readUTF() throws IOException { + return DataInputStream.readUTF(this); + } + + @Override + public int readUnsignedByte() throws IOException { + return readByte() & 0xff; + } + + @Override + public int readUnsignedShort() throws IOException { + return readShort() & 0xffff; + } + + @Override + public int skipBytes(int n) throws IOException { + int nBytes = Math.min(available(), n); + buffer.skipBytes(nBytes); + return nBytes; + } + + private void checkAvailable(int fieldSize) throws IOException { + if (fieldSize < 0) { + throw new IndexOutOfBoundsException("fieldSize cannot be a negative number"); + } + if (fieldSize > available()) { + throw new EOFException("fieldSize is too long! Length is " + fieldSize + + ", but maximum is " + available()); + } + } +} diff --git a/common/src/common/net/buffer/ByteBufOutputStream.java b/common/src/common/net/buffer/ByteBufOutputStream.java new file mode 100644 index 0000000..81af491 --- /dev/null +++ b/common/src/common/net/buffer/ByteBufOutputStream.java @@ -0,0 +1,146 @@ +/* + * Copyright 2012 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ +package common.net.buffer; + +import java.io.DataOutput; +import java.io.DataOutputStream; +import java.io.IOException; +import java.io.OutputStream; + +/** + * An {@link OutputStream} which writes data to a {@link ByteBuf}. + *

+ * A write operation against this stream will occur at the {@code writerIndex} + * of its underlying buffer and the {@code writerIndex} will increase during + * the write operation. + *

+ * This stream implements {@link DataOutput} for your convenience. + * The endianness of the stream is not always big endian but depends on + * the endianness of the underlying buffer. + * + * @see ByteBufInputStream + */ +public class ByteBufOutputStream extends OutputStream implements DataOutput { + + private final ByteBuf buffer; + private final int startIndex; + private final DataOutputStream utf8out = new DataOutputStream(this); + + /** + * Creates a new stream which writes data to the specified {@code buffer}. + */ + public ByteBufOutputStream(ByteBuf buffer) { + if (buffer == null) { + throw new NullPointerException("buffer"); + } + this.buffer = buffer; + startIndex = buffer.writerIndex(); + } + + /** + * Returns the number of written bytes by this stream so far. + */ + public int writtenBytes() { + return buffer.writerIndex() - startIndex; + } + + @Override + public void write(byte[] b, int off, int len) throws IOException { + if (len == 0) { + return; + } + + buffer.writeBytes(b, off, len); + } + + @Override + public void write(byte[] b) throws IOException { + buffer.writeBytes(b); + } + + @Override + public void write(int b) throws IOException { + buffer.writeByte((byte) b); + } + + @Override + public void writeBoolean(boolean v) throws IOException { + write(v? (byte) 1 : (byte) 0); + } + + @Override + public void writeByte(int v) throws IOException { + write(v); + } + + @Override + public void writeBytes(String s) throws IOException { + int len = s.length(); + for (int i = 0; i < len; i ++) { + write((byte) s.charAt(i)); + } + } + + @Override + public void writeChar(int v) throws IOException { + writeShort((short) v); + } + + @Override + public void writeChars(String s) throws IOException { + int len = s.length(); + for (int i = 0 ; i < len ; i ++) { + writeChar(s.charAt(i)); + } + } + + @Override + public void writeDouble(double v) throws IOException { + writeLong(Double.doubleToLongBits(v)); + } + + @Override + public void writeFloat(float v) throws IOException { + writeInt(Float.floatToIntBits(v)); + } + + @Override + public void writeInt(int v) throws IOException { + buffer.writeInt(v); + } + + @Override + public void writeLong(long v) throws IOException { + buffer.writeLong(v); + } + + @Override + public void writeShort(int v) throws IOException { + buffer.writeShort((short) v); + } + + @Override + public void writeUTF(String s) throws IOException { + utf8out.writeUTF(s); + } + + /** + * Returns the buffer where this stream is writing data. + */ + public ByteBuf buffer() { + return buffer; + } +} diff --git a/common/src/common/net/buffer/ByteBufProcessor.java b/common/src/common/net/buffer/ByteBufProcessor.java new file mode 100644 index 0000000..67f4ad4 --- /dev/null +++ b/common/src/common/net/buffer/ByteBufProcessor.java @@ -0,0 +1,126 @@ +/* + * Copyright 2013 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ + +package common.net.buffer; + +public interface ByteBufProcessor { + + /** + * Aborts on a {@code NUL (0x00)}. + */ + ByteBufProcessor FIND_NUL = new ByteBufProcessor() { + @Override + public boolean process(byte value) throws Exception { + return value != 0; + } + }; + + /** + * Aborts on a non-{@code NUL (0x00)}. + */ + ByteBufProcessor FIND_NON_NUL = new ByteBufProcessor() { + @Override + public boolean process(byte value) throws Exception { + return value == 0; + } + }; + + /** + * Aborts on a {@code CR ('\r')}. + */ + ByteBufProcessor FIND_CR = new ByteBufProcessor() { + @Override + public boolean process(byte value) throws Exception { + return value != '\r'; + } + }; + + /** + * Aborts on a non-{@code CR ('\r')}. + */ + ByteBufProcessor FIND_NON_CR = new ByteBufProcessor() { + @Override + public boolean process(byte value) throws Exception { + return value == '\r'; + } + }; + + /** + * Aborts on a {@code LF ('\n')}. + */ + ByteBufProcessor FIND_LF = new ByteBufProcessor() { + @Override + public boolean process(byte value) throws Exception { + return value != '\n'; + } + }; + + /** + * Aborts on a non-{@code LF ('\n')}. + */ + ByteBufProcessor FIND_NON_LF = new ByteBufProcessor() { + @Override + public boolean process(byte value) throws Exception { + return value == '\n'; + } + }; + + /** + * Aborts on a {@code CR ('\r')} or a {@code LF ('\n')}. + */ + ByteBufProcessor FIND_CRLF = new ByteBufProcessor() { + @Override + public boolean process(byte value) throws Exception { + return value != '\r' && value != '\n'; + } + }; + + /** + * Aborts on a byte which is neither a {@code CR ('\r')} nor a {@code LF ('\n')}. + */ + ByteBufProcessor FIND_NON_CRLF = new ByteBufProcessor() { + @Override + public boolean process(byte value) throws Exception { + return value == '\r' || value == '\n'; + } + }; + + /** + * Aborts on a linear whitespace (a ({@code ' '} or a {@code '\t'}). + */ + ByteBufProcessor FIND_LINEAR_WHITESPACE = new ByteBufProcessor() { + @Override + public boolean process(byte value) throws Exception { + return value != ' ' && value != '\t'; + } + }; + + /** + * Aborts on a byte which is not a linear whitespace (neither {@code ' '} nor {@code '\t'}). + */ + ByteBufProcessor FIND_NON_LINEAR_WHITESPACE = new ByteBufProcessor() { + @Override + public boolean process(byte value) throws Exception { + return value == ' ' || value == '\t'; + } + }; + + /** + * @return {@code true} if the processor wants to continue the loop and handle the next byte in the buffer. + * {@code false} if the processor wants to stop handling bytes and abort the loop. + */ + boolean process(byte value) throws Exception; +} diff --git a/common/src/common/net/buffer/ByteBufUtil.java b/common/src/common/net/buffer/ByteBufUtil.java new file mode 100644 index 0000000..21b042f --- /dev/null +++ b/common/src/common/net/buffer/ByteBufUtil.java @@ -0,0 +1,483 @@ +/* + * Copyright 2012 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ +package common.net.buffer; + +import java.nio.ByteBuffer; +import java.nio.ByteOrder; +import java.nio.CharBuffer; +import java.nio.charset.CharacterCodingException; +import java.nio.charset.Charset; +import java.nio.charset.CharsetDecoder; +import java.nio.charset.CharsetEncoder; +import java.nio.charset.CoderResult; +import java.util.Locale; + +import common.net.util.CharsetUtil; +import common.net.util.Recycler; +import common.net.util.Recycler.Handle; +import common.net.util.internal.PlatformDependent; +import common.net.util.internal.SystemPropertyUtil; +import common.net.util.internal.logging.InternalLogger; +import common.net.util.internal.logging.InternalLoggerFactory; + +/** + * A collection of utility methods that is related with handling {@link ByteBuf}. + */ +public final class ByteBufUtil { + + private static final InternalLogger logger = InternalLoggerFactory.getInstance(ByteBufUtil.class); + + private static final char[] HEXDUMP_TABLE = new char[256 * 4]; + + static final ByteBufAllocator DEFAULT_ALLOCATOR; + + private static final int THREAD_LOCAL_BUFFER_SIZE; + + static { + final char[] DIGITS = "0123456789abcdef".toCharArray(); + for (int i = 0; i < 256; i ++) { + HEXDUMP_TABLE[ i << 1 ] = DIGITS[i >>> 4 & 0x0F]; + HEXDUMP_TABLE[(i << 1) + 1] = DIGITS[i & 0x0F]; + } + + String allocType = SystemPropertyUtil.get("game.net.allocator.type", "unpooled").toLowerCase(Locale.US).trim(); + ByteBufAllocator alloc; + if ("unpooled".equals(allocType)) { + alloc = UnpooledByteBufAllocator.DEFAULT; + logger.debug("-Dgame.net.allocator.type: {}", allocType); + } else if ("pooled".equals(allocType)) { + alloc = PooledByteBufAllocator.DEFAULT; + logger.debug("-Dgame.net.allocator.type: {}", allocType); + } else { + alloc = UnpooledByteBufAllocator.DEFAULT; + logger.debug("-Dgame.net.allocator.type: unpooled (unknown: {})", allocType); + } + + DEFAULT_ALLOCATOR = alloc; + + THREAD_LOCAL_BUFFER_SIZE = SystemPropertyUtil.getInt("game.net.threadLocalDirectBufferSize", 64 * 1024); + logger.debug("-Dgame.net.threadLocalDirectBufferSize: {}", THREAD_LOCAL_BUFFER_SIZE); + } + + /** + * Returns a hex dump + * of the specified buffer's readable bytes. + */ + public static String hexDump(ByteBuf buffer) { + return hexDump(buffer, buffer.readerIndex(), buffer.readableBytes()); + } + + /** + * Returns a hex dump + * of the specified buffer's sub-region. + */ + public static String hexDump(ByteBuf buffer, int fromIndex, int length) { + if (length < 0) { + throw new IllegalArgumentException("length: " + length); + } + if (length == 0) { + return ""; + } + + int endIndex = fromIndex + length; + char[] buf = new char[length << 1]; + + int srcIdx = fromIndex; + int dstIdx = 0; + for (; srcIdx < endIndex; srcIdx ++, dstIdx += 2) { + System.arraycopy( + HEXDUMP_TABLE, buffer.getUnsignedByte(srcIdx) << 1, + buf, dstIdx, 2); + } + + return new String(buf); + } + + /** + * Calculates the hash code of the specified buffer. This method is + * useful when implementing a new buffer type. + */ + public static int hashCode(ByteBuf buffer) { + final int aLen = buffer.readableBytes(); + final int intCount = aLen >>> 2; + final int byteCount = aLen & 3; + + int hashCode = 1; + int arrayIndex = buffer.readerIndex(); + if (buffer.order() == ByteOrder.BIG_ENDIAN) { + for (int i = intCount; i > 0; i --) { + hashCode = 31 * hashCode + buffer.getInt(arrayIndex); + arrayIndex += 4; + } + } else { + for (int i = intCount; i > 0; i --) { + hashCode = 31 * hashCode + swapInt(buffer.getInt(arrayIndex)); + arrayIndex += 4; + } + } + + for (int i = byteCount; i > 0; i --) { + hashCode = 31 * hashCode + buffer.getByte(arrayIndex ++); + } + + if (hashCode == 0) { + hashCode = 1; + } + + return hashCode; + } + + /** + * Returns {@code true} if and only if the two specified buffers are + * identical to each other as described in {@code ChannelBuffer#equals(Object)}. + * This method is useful when implementing a new buffer type. + */ + public static boolean equals(ByteBuf bufferA, ByteBuf bufferB) { + final int aLen = bufferA.readableBytes(); + if (aLen != bufferB.readableBytes()) { + return false; + } + + final int longCount = aLen >>> 3; + final int byteCount = aLen & 7; + + int aIndex = bufferA.readerIndex(); + int bIndex = bufferB.readerIndex(); + + if (bufferA.order() == bufferB.order()) { + for (int i = longCount; i > 0; i --) { + if (bufferA.getLong(aIndex) != bufferB.getLong(bIndex)) { + return false; + } + aIndex += 8; + bIndex += 8; + } + } else { + for (int i = longCount; i > 0; i --) { + if (bufferA.getLong(aIndex) != swapLong(bufferB.getLong(bIndex))) { + return false; + } + aIndex += 8; + bIndex += 8; + } + } + + for (int i = byteCount; i > 0; i --) { + if (bufferA.getByte(aIndex) != bufferB.getByte(bIndex)) { + return false; + } + aIndex ++; + bIndex ++; + } + + return true; + } + + /** + * Compares the two specified buffers as described in {@link ByteBuf#compareTo(ByteBuf)}. + * This method is useful when implementing a new buffer type. + */ + public static int compare(ByteBuf bufferA, ByteBuf bufferB) { + final int aLen = bufferA.readableBytes(); + final int bLen = bufferB.readableBytes(); + final int minLength = Math.min(aLen, bLen); + final int uintCount = minLength >>> 2; + final int byteCount = minLength & 3; + + int aIndex = bufferA.readerIndex(); + int bIndex = bufferB.readerIndex(); + + if (bufferA.order() == bufferB.order()) { + for (int i = uintCount; i > 0; i --) { + long va = bufferA.getUnsignedInt(aIndex); + long vb = bufferB.getUnsignedInt(bIndex); + if (va > vb) { + return 1; + } + if (va < vb) { + return -1; + } + aIndex += 4; + bIndex += 4; + } + } else { + for (int i = uintCount; i > 0; i --) { + long va = bufferA.getUnsignedInt(aIndex); + long vb = swapInt(bufferB.getInt(bIndex)) & 0xFFFFFFFFL; + if (va > vb) { + return 1; + } + if (va < vb) { + return -1; + } + aIndex += 4; + bIndex += 4; + } + } + + for (int i = byteCount; i > 0; i --) { + short va = bufferA.getUnsignedByte(aIndex); + short vb = bufferB.getUnsignedByte(bIndex); + if (va > vb) { + return 1; + } + if (va < vb) { + return -1; + } + aIndex ++; + bIndex ++; + } + + return aLen - bLen; + } + + /** + * The default implementation of {@link ByteBuf#indexOf(int, int, byte)}. + * This method is useful when implementing a new buffer type. + */ + public static int indexOf(ByteBuf buffer, int fromIndex, int toIndex, byte value) { + if (fromIndex <= toIndex) { + return firstIndexOf(buffer, fromIndex, toIndex, value); + } else { + return lastIndexOf(buffer, fromIndex, toIndex, value); + } + } + + /** + * Toggles the endianness of the specified 16-bit short integer. + */ + public static short swapShort(short value) { + return Short.reverseBytes(value); + } + + /** + * Toggles the endianness of the specified 24-bit medium integer. + */ + public static int swapMedium(int value) { + int swapped = value << 16 & 0xff0000 | value & 0xff00 | value >>> 16 & 0xff; + if ((swapped & 0x800000) != 0) { + swapped |= 0xff000000; + } + return swapped; + } + + /** + * Toggles the endianness of the specified 32-bit integer. + */ + public static int swapInt(int value) { + return Integer.reverseBytes(value); + } + + /** + * Toggles the endianness of the specified 64-bit long integer. + */ + public static long swapLong(long value) { + return Long.reverseBytes(value); + } + + /** + * Read the given amount of bytes into a new {@link ByteBuf} that is allocated from the {@link ByteBufAllocator}. + */ + public static ByteBuf readBytes(ByteBufAllocator alloc, ByteBuf buffer, int length) { + boolean release = true; + ByteBuf dst = alloc.buffer(length); + try { + buffer.readBytes(dst); + release = false; + return dst; + } finally { + if (release) { + dst.release(); + } + } + } + + private static int firstIndexOf(ByteBuf buffer, int fromIndex, int toIndex, byte value) { + fromIndex = Math.max(fromIndex, 0); + if (fromIndex >= toIndex || buffer.capacity() == 0) { + return -1; + } + + for (int i = fromIndex; i < toIndex; i ++) { + if (buffer.getByte(i) == value) { + return i; + } + } + + return -1; + } + + private static int lastIndexOf(ByteBuf buffer, int fromIndex, int toIndex, byte value) { + fromIndex = Math.min(fromIndex, buffer.capacity()); + if (fromIndex < 0 || buffer.capacity() == 0) { + return -1; + } + + for (int i = fromIndex - 1; i >= toIndex; i --) { + if (buffer.getByte(i) == value) { + return i; + } + } + + return -1; + } + + /** + * Encode the given {@link CharBuffer} using the given {@link Charset} into a new {@link ByteBuf} which + * is allocated via the {@link ByteBufAllocator}. + */ + public static ByteBuf encodeString(ByteBufAllocator alloc, CharBuffer src, Charset charset) { + return encodeString0(alloc, false, src, charset); + } + + static ByteBuf encodeString0(ByteBufAllocator alloc, boolean enforceHeap, CharBuffer src, Charset charset) { + final CharsetEncoder encoder = CharsetUtil.getEncoder(charset); + int length = (int) ((double) src.remaining() * encoder.maxBytesPerChar()); + boolean release = true; + final ByteBuf dst; + if (enforceHeap) { + dst = alloc.heapBuffer(length); + } else { + dst = alloc.buffer(length); + } + try { + final ByteBuffer dstBuf = dst.internalNioBuffer(0, length); + final int pos = dstBuf.position(); + CoderResult cr = encoder.encode(src, dstBuf, true); + if (!cr.isUnderflow()) { + cr.throwException(); + } + cr = encoder.flush(dstBuf); + if (!cr.isUnderflow()) { + cr.throwException(); + } + dst.writerIndex(dst.writerIndex() + dstBuf.position() - pos); + release = false; + return dst; + } catch (CharacterCodingException x) { + throw new IllegalStateException(x); + } finally { + if (release) { + dst.release(); + } + } + } + + static String decodeString(ByteBuffer src, Charset charset) { + final CharsetDecoder decoder = CharsetUtil.getDecoder(charset); + final CharBuffer dst = CharBuffer.allocate( + (int) ((double) src.remaining() * decoder.maxCharsPerByte())); + try { + CoderResult cr = decoder.decode(src, dst, true); + if (!cr.isUnderflow()) { + cr.throwException(); + } + cr = decoder.flush(dst); + if (!cr.isUnderflow()) { + cr.throwException(); + } + } catch (CharacterCodingException x) { + throw new IllegalStateException(x); + } + return dst.flip().toString(); + } + + /** + * Returns a cached thread-local direct buffer, if available. + * + * @return a cached thread-local direct buffer, if available. {@code null} otherwise. + */ + public static ByteBuf threadLocalDirectBuffer() { + if (THREAD_LOCAL_BUFFER_SIZE <= 0) { + return null; + } + + if (PlatformDependent.hasUnsafe()) { + return ThreadLocalUnsafeDirectByteBuf.newInstance(); + } else { + return ThreadLocalDirectByteBuf.newInstance(); + } + } + + static final class ThreadLocalUnsafeDirectByteBuf extends UnpooledUnsafeDirectByteBuf { + + private static final Recycler RECYCLER = + new Recycler() { + @Override + protected ThreadLocalUnsafeDirectByteBuf newObject(Handle handle) { + return new ThreadLocalUnsafeDirectByteBuf(handle); + } + }; + + static ThreadLocalUnsafeDirectByteBuf newInstance() { + ThreadLocalUnsafeDirectByteBuf buf = RECYCLER.get(); + buf.setRefCnt(1); + return buf; + } + + private final Handle handle; + + private ThreadLocalUnsafeDirectByteBuf(Handle handle) { + super(UnpooledByteBufAllocator.DEFAULT, 256, Integer.MAX_VALUE); + this.handle = handle; + } + + @Override + protected void deallocate() { + if (capacity() > THREAD_LOCAL_BUFFER_SIZE) { + super.deallocate(); + } else { + clear(); + RECYCLER.recycle(this, handle); + } + } + } + + static final class ThreadLocalDirectByteBuf extends UnpooledDirectByteBuf { + + private static final Recycler RECYCLER = new Recycler() { + @Override + protected ThreadLocalDirectByteBuf newObject(Handle handle) { + return new ThreadLocalDirectByteBuf(handle); + } + }; + + static ThreadLocalDirectByteBuf newInstance() { + ThreadLocalDirectByteBuf buf = RECYCLER.get(); + buf.setRefCnt(1); + return buf; + } + + private final Handle handle; + + private ThreadLocalDirectByteBuf(Handle handle) { + super(UnpooledByteBufAllocator.DEFAULT, 256, Integer.MAX_VALUE); + this.handle = handle; + } + + @Override + protected void deallocate() { + if (capacity() > THREAD_LOCAL_BUFFER_SIZE) { + super.deallocate(); + } else { + clear(); + RECYCLER.recycle(this, handle); + } + } + } + + private ByteBufUtil() { } +} diff --git a/common/src/common/net/buffer/CompositeByteBuf.java b/common/src/common/net/buffer/CompositeByteBuf.java new file mode 100644 index 0000000..1848209 --- /dev/null +++ b/common/src/common/net/buffer/CompositeByteBuf.java @@ -0,0 +1,1602 @@ +/* + * Copyright 2012 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ +package common.net.buffer; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.nio.ByteBuffer; +import java.nio.ByteOrder; +import java.nio.channels.GatheringByteChannel; +import java.nio.channels.ScatteringByteChannel; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.Iterator; +import java.util.List; +import java.util.ListIterator; + +import common.net.util.ResourceLeak; +import common.net.util.internal.EmptyArrays; + +/** + * A virtual buffer which shows multiple buffers as a single merged buffer. It is recommended to use + * {@link ByteBufAllocator#compositeBuffer()} or {@link Unpooled#wrappedBuffer(ByteBuf...)} instead of calling the + * constructor explicitly. + */ +public class CompositeByteBuf extends AbstractReferenceCountedByteBuf { + + private final ResourceLeak leak; + private final ByteBufAllocator alloc; + private final boolean direct; + private final List components = new ArrayList(); + private final int maxNumComponents; + private static final ByteBuffer FULL_BYTEBUFFER = (ByteBuffer) ByteBuffer.allocate(1).position(1); + + private boolean freed; + + public CompositeByteBuf(ByteBufAllocator alloc, boolean direct, int maxNumComponents) { + super(Integer.MAX_VALUE); + if (alloc == null) { + throw new NullPointerException("alloc"); + } + this.alloc = alloc; + this.direct = direct; + this.maxNumComponents = maxNumComponents; + leak = leakDetector.open(this); + } + + public CompositeByteBuf(ByteBufAllocator alloc, boolean direct, int maxNumComponents, ByteBuf... buffers) { + super(Integer.MAX_VALUE); + if (alloc == null) { + throw new NullPointerException("alloc"); + } + if (maxNumComponents < 2) { + throw new IllegalArgumentException( + "maxNumComponents: " + maxNumComponents + " (expected: >= 2)"); + } + + this.alloc = alloc; + this.direct = direct; + this.maxNumComponents = maxNumComponents; + + addComponents0(0, buffers); + consolidateIfNeeded(); + setIndex(0, capacity()); + leak = leakDetector.open(this); + } + + public CompositeByteBuf( + ByteBufAllocator alloc, boolean direct, int maxNumComponents, Iterable buffers) { + super(Integer.MAX_VALUE); + if (alloc == null) { + throw new NullPointerException("alloc"); + } + if (maxNumComponents < 2) { + throw new IllegalArgumentException( + "maxNumComponents: " + maxNumComponents + " (expected: >= 2)"); + } + + this.alloc = alloc; + this.direct = direct; + this.maxNumComponents = maxNumComponents; + addComponents0(0, buffers); + consolidateIfNeeded(); + setIndex(0, capacity()); + leak = leakDetector.open(this); + } + + /** + * Add the given {@link ByteBuf}. + * + * Be aware that this method does not increase the {@code writerIndex} of the {@link CompositeByteBuf}. + * If you need to have it increased you need to handle it by your own. + * + * @param buffer the {@link ByteBuf} to add + */ + public CompositeByteBuf addComponent(ByteBuf buffer) { + addComponent0(components.size(), buffer); + consolidateIfNeeded(); + return this; + } + + /** + * Add the given {@link ByteBuf}s. + * + * Be aware that this method does not increase the {@code writerIndex} of the {@link CompositeByteBuf}. + * If you need to have it increased you need to handle it by your own. + * + * @param buffers the {@link ByteBuf}s to add + */ + public CompositeByteBuf addComponents(ByteBuf... buffers) { + addComponents0(components.size(), buffers); + consolidateIfNeeded(); + return this; + } + + /** + * Add the given {@link ByteBuf}s. + * + * Be aware that this method does not increase the {@code writerIndex} of the {@link CompositeByteBuf}. + * If you need to have it increased you need to handle it by your own. + * + * @param buffers the {@link ByteBuf}s to add + */ + public CompositeByteBuf addComponents(Iterable buffers) { + addComponents0(components.size(), buffers); + consolidateIfNeeded(); + return this; + } + + /** + * Add the given {@link ByteBuf} on the specific index. + * + * Be aware that this method does not increase the {@code writerIndex} of the {@link CompositeByteBuf}. + * If you need to have it increased you need to handle it by your own. + * + * @param cIndex the index on which the {@link ByteBuf} will be added + * @param buffer the {@link ByteBuf} to add + */ + public CompositeByteBuf addComponent(int cIndex, ByteBuf buffer) { + addComponent0(cIndex, buffer); + consolidateIfNeeded(); + return this; + } + + private int addComponent0(int cIndex, ByteBuf buffer) { + checkComponentIndex(cIndex); + + if (buffer == null) { + throw new NullPointerException("buffer"); + } + + int readableBytes = buffer.readableBytes(); + if (readableBytes == 0) { + return cIndex; + } + + // No need to consolidate - just add a component to the list. + Component c = new Component(buffer.order(ByteOrder.BIG_ENDIAN).slice()); + if (cIndex == components.size()) { + components.add(c); + if (cIndex == 0) { + c.endOffset = readableBytes; + } else { + Component prev = components.get(cIndex - 1); + c.offset = prev.endOffset; + c.endOffset = c.offset + readableBytes; + } + } else { + components.add(cIndex, c); + updateComponentOffsets(cIndex); + } + return cIndex; + } + + /** + * Add the given {@link ByteBuf}s on the specific index + * + * Be aware that this method does not increase the {@code writerIndex} of the {@link CompositeByteBuf}. + * If you need to have it increased you need to handle it by your own. + * + * @param cIndex the index on which the {@link ByteBuf} will be added. + * @param buffers the {@link ByteBuf}s to add + */ + public CompositeByteBuf addComponents(int cIndex, ByteBuf... buffers) { + addComponents0(cIndex, buffers); + consolidateIfNeeded(); + return this; + } + + private int addComponents0(int cIndex, ByteBuf... buffers) { + checkComponentIndex(cIndex); + + if (buffers == null) { + throw new NullPointerException("buffers"); + } + + int readableBytes = 0; + for (ByteBuf b: buffers) { + if (b == null) { + break; + } + readableBytes += b.readableBytes(); + } + + if (readableBytes == 0) { + return cIndex; + } + + // No need for consolidation + for (ByteBuf b: buffers) { + if (b == null) { + break; + } + if (b.isReadable()) { + cIndex = addComponent0(cIndex, b) + 1; + int size = components.size(); + if (cIndex > size) { + cIndex = size; + } + } else { + b.release(); + } + } + return cIndex; + } + + /** + * Add the given {@link ByteBuf}s on the specific index + * + * Be aware that this method does not increase the {@code writerIndex} of the {@link CompositeByteBuf}. + * If you need to have it increased you need to handle it by your own. + * + * @param cIndex the index on which the {@link ByteBuf} will be added. + * @param buffers the {@link ByteBuf}s to add + */ + public CompositeByteBuf addComponents(int cIndex, Iterable buffers) { + addComponents0(cIndex, buffers); + consolidateIfNeeded(); + return this; + } + + private int addComponents0(int cIndex, Iterable buffers) { + if (buffers == null) { + throw new NullPointerException("buffers"); + } + + if (buffers instanceof ByteBuf) { + // If buffers also implements ByteBuf (e.g. CompositeByteBuf), it has to go to addComponent(ByteBuf). + return addComponent0(cIndex, (ByteBuf) buffers); + } + + if (!(buffers instanceof Collection)) { + List list = new ArrayList(); + for (ByteBuf b: buffers) { + list.add(b); + } + buffers = list; + } + + Collection col = (Collection) buffers; + return addComponents0(cIndex, col.toArray(new ByteBuf[col.size()])); + } + + /** + * This should only be called as last operation from a method as this may adjust the underlying + * array of components and so affect the index etc. + */ + private void consolidateIfNeeded() { + // Consolidate if the number of components will exceed the allowed maximum by the current + // operation. + final int numComponents = components.size(); + if (numComponents > maxNumComponents) { + final int capacity = components.get(numComponents - 1).endOffset; + + ByteBuf consolidated = allocBuffer(capacity); + + // We're not using foreach to avoid creating an iterator. + for (int i = 0; i < numComponents; i ++) { + Component c = components.get(i); + ByteBuf b = c.buf; + consolidated.writeBytes(b); + c.freeIfNecessary(); + } + Component c = new Component(consolidated); + c.endOffset = c.length; + components.clear(); + components.add(c); + } + } + + private void checkComponentIndex(int cIndex) { + ensureAccessible(); + if (cIndex < 0 || cIndex > components.size()) { + throw new IndexOutOfBoundsException(String.format( + "cIndex: %d (expected: >= 0 && <= numComponents(%d))", + cIndex, components.size())); + } + } + + private void checkComponentIndex(int cIndex, int numComponents) { + ensureAccessible(); + if (cIndex < 0 || cIndex + numComponents > components.size()) { + throw new IndexOutOfBoundsException(String.format( + "cIndex: %d, numComponents: %d " + + "(expected: cIndex >= 0 && cIndex + numComponents <= totalNumComponents(%d))", + cIndex, numComponents, components.size())); + } + } + + private void updateComponentOffsets(int cIndex) { + int size = components.size(); + if (size <= cIndex) { + return; + } + + Component c = components.get(cIndex); + if (cIndex == 0) { + c.offset = 0; + c.endOffset = c.length; + cIndex ++; + } + + for (int i = cIndex; i < size; i ++) { + Component prev = components.get(i - 1); + Component cur = components.get(i); + cur.offset = prev.endOffset; + cur.endOffset = cur.offset + cur.length; + } + } + + /** + * Remove the {@link ByteBuf} from the given index. + * + * @param cIndex the index on from which the {@link ByteBuf} will be remove + */ + public CompositeByteBuf removeComponent(int cIndex) { + checkComponentIndex(cIndex); + components.remove(cIndex).freeIfNecessary(); + updateComponentOffsets(cIndex); + return this; + } + + /** + * Remove the number of {@link ByteBuf}s starting from the given index. + * + * @param cIndex the index on which the {@link ByteBuf}s will be started to removed + * @param numComponents the number of components to remove + */ + public CompositeByteBuf removeComponents(int cIndex, int numComponents) { + checkComponentIndex(cIndex, numComponents); + + List toRemove = components.subList(cIndex, cIndex + numComponents); + for (Component c: toRemove) { + c.freeIfNecessary(); + } + toRemove.clear(); + + updateComponentOffsets(cIndex); + return this; + } + + public Iterator iterator() { + ensureAccessible(); + List list = new ArrayList(components.size()); + for (Component c: components) { + list.add(c.buf); + } + return list.iterator(); + } + + /** + * Same with {@link #slice(int, int)} except that this method returns a list. + */ + public List decompose(int offset, int length) { + checkIndex(offset, length); + if (length == 0) { + return Collections.emptyList(); + } + + int componentId = toComponentIndex(offset); + List slice = new ArrayList(components.size()); + + // The first component + Component firstC = components.get(componentId); + ByteBuf first = firstC.buf.duplicate(); + first.readerIndex(offset - firstC.offset); + + ByteBuf buf = first; + int bytesToSlice = length; + do { + int readableBytes = buf.readableBytes(); + if (bytesToSlice <= readableBytes) { + // Last component + buf.writerIndex(buf.readerIndex() + bytesToSlice); + slice.add(buf); + break; + } else { + // Not the last component + slice.add(buf); + bytesToSlice -= readableBytes; + componentId ++; + + // Fetch the next component. + buf = components.get(componentId).buf.duplicate(); + } + } while (bytesToSlice > 0); + + // Slice all components because only readable bytes are interesting. + for (int i = 0; i < slice.size(); i ++) { + slice.set(i, slice.get(i).slice()); + } + + return slice; + } + + @Override + public boolean isDirect() { + int size = components.size(); + if (size == 0) { + return false; + } + for (int i = 0; i < size; i++) { + if (!components.get(i).buf.isDirect()) { + return false; + } + } + return true; + } + + @Override + public boolean hasArray() { + if (components.size() == 1) { + return components.get(0).buf.hasArray(); + } + return false; + } + + @Override + public byte[] array() { + if (components.size() == 1) { + return components.get(0).buf.array(); + } + throw new UnsupportedOperationException(); + } + + @Override + public int arrayOffset() { + if (components.size() == 1) { + return components.get(0).buf.arrayOffset(); + } + throw new UnsupportedOperationException(); + } + + @Override + public boolean hasMemoryAddress() { + if (components.size() == 1) { + return components.get(0).buf.hasMemoryAddress(); + } + return false; + } + + @Override + public long memoryAddress() { + if (components.size() == 1) { + return components.get(0).buf.memoryAddress(); + } + throw new UnsupportedOperationException(); + } + + @Override + public int capacity() { + if (components.isEmpty()) { + return 0; + } + return components.get(components.size() - 1).endOffset; + } + + @Override + public CompositeByteBuf capacity(int newCapacity) { + ensureAccessible(); + if (newCapacity < 0 || newCapacity > maxCapacity()) { + throw new IllegalArgumentException("newCapacity: " + newCapacity); + } + + int oldCapacity = capacity(); + if (newCapacity > oldCapacity) { + final int paddingLength = newCapacity - oldCapacity; + ByteBuf padding; + int nComponents = components.size(); + if (nComponents < maxNumComponents) { + padding = allocBuffer(paddingLength); + padding.setIndex(0, paddingLength); + addComponent0(components.size(), padding); + } else { + padding = allocBuffer(paddingLength); + padding.setIndex(0, paddingLength); + // FIXME: No need to create a padding buffer and consolidate. + // Just create a big single buffer and put the current content there. + addComponent0(components.size(), padding); + consolidateIfNeeded(); + } + } else if (newCapacity < oldCapacity) { + int bytesToTrim = oldCapacity - newCapacity; + for (ListIterator i = components.listIterator(components.size()); i.hasPrevious();) { + Component c = i.previous(); + if (bytesToTrim >= c.length) { + bytesToTrim -= c.length; + i.remove(); + continue; + } + + // Replace the last component with the trimmed slice. + Component newC = new Component(c.buf.slice(0, c.length - bytesToTrim)); + newC.offset = c.offset; + newC.endOffset = newC.offset + newC.length; + i.set(newC); + break; + } + + if (readerIndex() > newCapacity) { + setIndex(newCapacity, newCapacity); + } else if (writerIndex() > newCapacity) { + writerIndex(newCapacity); + } + } + return this; + } + + @Override + public ByteBufAllocator alloc() { + return alloc; + } + + @Override + public ByteOrder order() { + return ByteOrder.BIG_ENDIAN; + } + + /** + * Return the current number of {@link ByteBuf}'s that are composed in this instance + */ + public int numComponents() { + return components.size(); + } + + /** + * Return the max number of {@link ByteBuf}'s that are composed in this instance + */ + public int maxNumComponents() { + return maxNumComponents; + } + + /** + * Return the index for the given offset + */ + public int toComponentIndex(int offset) { + checkIndex(offset); + + for (int low = 0, high = components.size(); low <= high;) { + int mid = low + high >>> 1; + Component c = components.get(mid); + if (offset >= c.endOffset) { + low = mid + 1; + } else if (offset < c.offset) { + high = mid - 1; + } else { + return mid; + } + } + + throw new Error("should not reach here"); + } + + public int toByteIndex(int cIndex) { + checkComponentIndex(cIndex); + return components.get(cIndex).offset; + } + + @Override + public byte getByte(int index) { + return _getByte(index); + } + + @Override + protected byte _getByte(int index) { + Component c = findComponent(index); + return c.buf.getByte(index - c.offset); + } + + @Override + protected short _getShort(int index) { + Component c = findComponent(index); + if (index + 2 <= c.endOffset) { + return c.buf.getShort(index - c.offset); + } else if (order() == ByteOrder.BIG_ENDIAN) { + return (short) ((_getByte(index) & 0xff) << 8 | _getByte(index + 1) & 0xff); + } else { + return (short) (_getByte(index) & 0xff | (_getByte(index + 1) & 0xff) << 8); + } + } + + @Override + protected int _getUnsignedMedium(int index) { + Component c = findComponent(index); + if (index + 3 <= c.endOffset) { + return c.buf.getUnsignedMedium(index - c.offset); + } else if (order() == ByteOrder.BIG_ENDIAN) { + return (_getShort(index) & 0xffff) << 8 | _getByte(index + 2) & 0xff; + } else { + return _getShort(index) & 0xFFFF | (_getByte(index + 2) & 0xFF) << 16; + } + } + + @Override + protected int _getInt(int index) { + Component c = findComponent(index); + if (index + 4 <= c.endOffset) { + return c.buf.getInt(index - c.offset); + } else if (order() == ByteOrder.BIG_ENDIAN) { + return (_getShort(index) & 0xffff) << 16 | _getShort(index + 2) & 0xffff; + } else { + return _getShort(index) & 0xFFFF | (_getShort(index + 2) & 0xFFFF) << 16; + } + } + + @Override + protected long _getLong(int index) { + Component c = findComponent(index); + if (index + 8 <= c.endOffset) { + return c.buf.getLong(index - c.offset); + } else if (order() == ByteOrder.BIG_ENDIAN) { + return (_getInt(index) & 0xffffffffL) << 32 | _getInt(index + 4) & 0xffffffffL; + } else { + return _getInt(index) & 0xFFFFFFFFL | (_getInt(index + 4) & 0xFFFFFFFFL) << 32; + } + } + + @Override + public CompositeByteBuf getBytes(int index, byte[] dst, int dstIndex, int length) { + checkDstIndex(index, length, dstIndex, dst.length); + if (length == 0) { + return this; + } + + int i = toComponentIndex(index); + while (length > 0) { + Component c = components.get(i); + ByteBuf s = c.buf; + int adjustment = c.offset; + int localLength = Math.min(length, s.capacity() - (index - adjustment)); + s.getBytes(index - adjustment, dst, dstIndex, localLength); + index += localLength; + dstIndex += localLength; + length -= localLength; + i ++; + } + return this; + } + + @Override + public CompositeByteBuf getBytes(int index, ByteBuffer dst) { + int limit = dst.limit(); + int length = dst.remaining(); + + checkIndex(index, length); + if (length == 0) { + return this; + } + + int i = toComponentIndex(index); + try { + while (length > 0) { + Component c = components.get(i); + ByteBuf s = c.buf; + int adjustment = c.offset; + int localLength = Math.min(length, s.capacity() - (index - adjustment)); + dst.limit(dst.position() + localLength); + s.getBytes(index - adjustment, dst); + index += localLength; + length -= localLength; + i ++; + } + } finally { + dst.limit(limit); + } + return this; + } + + @Override + public CompositeByteBuf getBytes(int index, ByteBuf dst, int dstIndex, int length) { + checkDstIndex(index, length, dstIndex, dst.capacity()); + if (length == 0) { + return this; + } + + int i = toComponentIndex(index); + while (length > 0) { + Component c = components.get(i); + ByteBuf s = c.buf; + int adjustment = c.offset; + int localLength = Math.min(length, s.capacity() - (index - adjustment)); + s.getBytes(index - adjustment, dst, dstIndex, localLength); + index += localLength; + dstIndex += localLength; + length -= localLength; + i ++; + } + return this; + } + + @Override + public int getBytes(int index, GatheringByteChannel out, int length) + throws IOException { + int count = nioBufferCount(); + if (count == 1) { + return out.write(internalNioBuffer(index, length)); + } else { + long writtenBytes = out.write(nioBuffers(index, length)); + if (writtenBytes > Integer.MAX_VALUE) { + return Integer.MAX_VALUE; + } else { + return (int) writtenBytes; + } + } + } + + @Override + public CompositeByteBuf getBytes(int index, OutputStream out, int length) throws IOException { + checkIndex(index, length); + if (length == 0) { + return this; + } + + int i = toComponentIndex(index); + while (length > 0) { + Component c = components.get(i); + ByteBuf s = c.buf; + int adjustment = c.offset; + int localLength = Math.min(length, s.capacity() - (index - adjustment)); + s.getBytes(index - adjustment, out, localLength); + index += localLength; + length -= localLength; + i ++; + } + return this; + } + + @Override + public CompositeByteBuf setByte(int index, int value) { + Component c = findComponent(index); + c.buf.setByte(index - c.offset, value); + return this; + } + + @Override + protected void _setByte(int index, int value) { + setByte(index, value); + } + + @Override + public CompositeByteBuf setShort(int index, int value) { + return (CompositeByteBuf) super.setShort(index, value); + } + + @Override + protected void _setShort(int index, int value) { + Component c = findComponent(index); + if (index + 2 <= c.endOffset) { + c.buf.setShort(index - c.offset, value); + } else if (order() == ByteOrder.BIG_ENDIAN) { + _setByte(index, (byte) (value >>> 8)); + _setByte(index + 1, (byte) value); + } else { + _setByte(index, (byte) value); + _setByte(index + 1, (byte) (value >>> 8)); + } + } + + @Override + public CompositeByteBuf setMedium(int index, int value) { + return (CompositeByteBuf) super.setMedium(index, value); + } + + @Override + protected void _setMedium(int index, int value) { + Component c = findComponent(index); + if (index + 3 <= c.endOffset) { + c.buf.setMedium(index - c.offset, value); + } else if (order() == ByteOrder.BIG_ENDIAN) { + _setShort(index, (short) (value >> 8)); + _setByte(index + 2, (byte) value); + } else { + _setShort(index, (short) value); + _setByte(index + 2, (byte) (value >>> 16)); + } + } + + @Override + public CompositeByteBuf setInt(int index, int value) { + return (CompositeByteBuf) super.setInt(index, value); + } + + @Override + protected void _setInt(int index, int value) { + Component c = findComponent(index); + if (index + 4 <= c.endOffset) { + c.buf.setInt(index - c.offset, value); + } else if (order() == ByteOrder.BIG_ENDIAN) { + _setShort(index, (short) (value >>> 16)); + _setShort(index + 2, (short) value); + } else { + _setShort(index, (short) value); + _setShort(index + 2, (short) (value >>> 16)); + } + } + + @Override + public CompositeByteBuf setLong(int index, long value) { + return (CompositeByteBuf) super.setLong(index, value); + } + + @Override + protected void _setLong(int index, long value) { + Component c = findComponent(index); + if (index + 8 <= c.endOffset) { + c.buf.setLong(index - c.offset, value); + } else if (order() == ByteOrder.BIG_ENDIAN) { + _setInt(index, (int) (value >>> 32)); + _setInt(index + 4, (int) value); + } else { + _setInt(index, (int) value); + _setInt(index + 4, (int) (value >>> 32)); + } + } + + @Override + public CompositeByteBuf setBytes(int index, byte[] src, int srcIndex, int length) { + checkSrcIndex(index, length, srcIndex, src.length); + if (length == 0) { + return this; + } + + int i = toComponentIndex(index); + while (length > 0) { + Component c = components.get(i); + ByteBuf s = c.buf; + int adjustment = c.offset; + int localLength = Math.min(length, s.capacity() - (index - adjustment)); + s.setBytes(index - adjustment, src, srcIndex, localLength); + index += localLength; + srcIndex += localLength; + length -= localLength; + i ++; + } + return this; + } + + @Override + public CompositeByteBuf setBytes(int index, ByteBuffer src) { + int limit = src.limit(); + int length = src.remaining(); + + checkIndex(index, length); + if (length == 0) { + return this; + } + + int i = toComponentIndex(index); + try { + while (length > 0) { + Component c = components.get(i); + ByteBuf s = c.buf; + int adjustment = c.offset; + int localLength = Math.min(length, s.capacity() - (index - adjustment)); + src.limit(src.position() + localLength); + s.setBytes(index - adjustment, src); + index += localLength; + length -= localLength; + i ++; + } + } finally { + src.limit(limit); + } + return this; + } + + @Override + public CompositeByteBuf setBytes(int index, ByteBuf src, int srcIndex, int length) { + checkSrcIndex(index, length, srcIndex, src.capacity()); + if (length == 0) { + return this; + } + + int i = toComponentIndex(index); + while (length > 0) { + Component c = components.get(i); + ByteBuf s = c.buf; + int adjustment = c.offset; + int localLength = Math.min(length, s.capacity() - (index - adjustment)); + s.setBytes(index - adjustment, src, srcIndex, localLength); + index += localLength; + srcIndex += localLength; + length -= localLength; + i ++; + } + return this; + } + + @Override + public int setBytes(int index, InputStream in, int length) throws IOException { + checkIndex(index, length); + if (length == 0) { + return in.read(EmptyArrays.EMPTY_BYTES); + } + + int i = toComponentIndex(index); + int readBytes = 0; + + do { + Component c = components.get(i); + ByteBuf s = c.buf; + int adjustment = c.offset; + int localLength = Math.min(length, s.capacity() - (index - adjustment)); + int localReadBytes = s.setBytes(index - adjustment, in, localLength); + if (localReadBytes < 0) { + if (readBytes == 0) { + return -1; + } else { + break; + } + } + + if (localReadBytes == localLength) { + index += localLength; + length -= localLength; + readBytes += localLength; + i ++; + } else { + index += localReadBytes; + length -= localReadBytes; + readBytes += localReadBytes; + } + } while (length > 0); + + return readBytes; + } + + @Override + public int setBytes(int index, ScatteringByteChannel in, int length) throws IOException { + checkIndex(index, length); + if (length == 0) { + return in.read(FULL_BYTEBUFFER); + } + + int i = toComponentIndex(index); + int readBytes = 0; + do { + Component c = components.get(i); + ByteBuf s = c.buf; + int adjustment = c.offset; + int localLength = Math.min(length, s.capacity() - (index - adjustment)); + int localReadBytes = s.setBytes(index - adjustment, in, localLength); + + if (localReadBytes == 0) { + break; + } + + if (localReadBytes < 0) { + if (readBytes == 0) { + return -1; + } else { + break; + } + } + + if (localReadBytes == localLength) { + index += localLength; + length -= localLength; + readBytes += localLength; + i ++; + } else { + index += localReadBytes; + length -= localReadBytes; + readBytes += localReadBytes; + } + } while (length > 0); + + return readBytes; + } + + @Override + public ByteBuf copy(int index, int length) { + checkIndex(index, length); + ByteBuf dst = Unpooled.buffer(length); + if (length != 0) { + copyTo(index, length, toComponentIndex(index), dst); + } + return dst; + } + + private void copyTo(int index, int length, int componentId, ByteBuf dst) { + int dstIndex = 0; + int i = componentId; + + while (length > 0) { + Component c = components.get(i); + ByteBuf s = c.buf; + int adjustment = c.offset; + int localLength = Math.min(length, s.capacity() - (index - adjustment)); + s.getBytes(index - adjustment, dst, dstIndex, localLength); + index += localLength; + dstIndex += localLength; + length -= localLength; + i ++; + } + + dst.writerIndex(dst.capacity()); + } + + /** + * Return the {@link ByteBuf} on the specified index + * + * @param cIndex the index for which the {@link ByteBuf} should be returned + * @return buf the {@link ByteBuf} on the specified index + */ + public ByteBuf component(int cIndex) { + return internalComponent(cIndex).duplicate(); + } + + /** + * Return the {@link ByteBuf} on the specified index + * + * @param offset the offset for which the {@link ByteBuf} should be returned + * @return the {@link ByteBuf} on the specified index + */ + public ByteBuf componentAtOffset(int offset) { + return internalComponentAtOffset(offset).duplicate(); + } + + /** + * Return the internal {@link ByteBuf} on the specified index. Note that updating the indexes of the returned + * buffer will lead to an undefined behavior of this buffer. + * + * @param cIndex the index for which the {@link ByteBuf} should be returned + */ + public ByteBuf internalComponent(int cIndex) { + checkComponentIndex(cIndex); + return components.get(cIndex).buf; + } + + /** + * Return the internal {@link ByteBuf} on the specified offset. Note that updating the indexes of the returned + * buffer will lead to an undefined behavior of this buffer. + * + * @param offset the offset for which the {@link ByteBuf} should be returned + */ + public ByteBuf internalComponentAtOffset(int offset) { + return findComponent(offset).buf; + } + + private Component findComponent(int offset) { + checkIndex(offset); + + for (int low = 0, high = components.size(); low <= high;) { + int mid = low + high >>> 1; + Component c = components.get(mid); + if (offset >= c.endOffset) { + low = mid + 1; + } else if (offset < c.offset) { + high = mid - 1; + } else { + return c; + } + } + + throw new Error("should not reach here"); + } + + @Override + public int nioBufferCount() { + if (components.size() == 1) { + return components.get(0).buf.nioBufferCount(); + } else { + int count = 0; + int componentsCount = components.size(); + for (int i = 0; i < componentsCount; i++) { + Component c = components.get(i); + count += c.buf.nioBufferCount(); + } + return count; + } + } + + @Override + public ByteBuffer internalNioBuffer(int index, int length) { + if (components.size() == 1) { + return components.get(0).buf.internalNioBuffer(index, length); + } + throw new UnsupportedOperationException(); + } + + @Override + public ByteBuffer nioBuffer(int index, int length) { + if (components.size() == 1) { + ByteBuf buf = components.get(0).buf; + if (buf.nioBufferCount() == 1) { + return components.get(0).buf.nioBuffer(index, length); + } + } + ByteBuffer merged = ByteBuffer.allocate(length).order(order()); + ByteBuffer[] buffers = nioBuffers(index, length); + + //noinspection ForLoopReplaceableByForEach + for (int i = 0; i < buffers.length; i++) { + merged.put(buffers[i]); + } + + merged.flip(); + return merged; + } + + @Override + public ByteBuffer[] nioBuffers(int index, int length) { + checkIndex(index, length); + if (length == 0) { + return EmptyArrays.EMPTY_BYTE_BUFFERS; + } + + List buffers = new ArrayList(components.size()); + int i = toComponentIndex(index); + while (length > 0) { + Component c = components.get(i); + ByteBuf s = c.buf; + int adjustment = c.offset; + int localLength = Math.min(length, s.capacity() - (index - adjustment)); + switch (s.nioBufferCount()) { + case 0: + throw new UnsupportedOperationException(); + case 1: + buffers.add(s.nioBuffer(index - adjustment, localLength)); + break; + default: + Collections.addAll(buffers, s.nioBuffers(index - adjustment, localLength)); + } + + index += localLength; + length -= localLength; + i ++; + } + + return buffers.toArray(new ByteBuffer[buffers.size()]); + } + + /** + * Consolidate the composed {@link ByteBuf}s + */ + public CompositeByteBuf consolidate() { + ensureAccessible(); + final int numComponents = numComponents(); + if (numComponents <= 1) { + return this; + } + + final Component last = components.get(numComponents - 1); + final int capacity = last.endOffset; + final ByteBuf consolidated = allocBuffer(capacity); + + for (int i = 0; i < numComponents; i ++) { + Component c = components.get(i); + ByteBuf b = c.buf; + consolidated.writeBytes(b); + c.freeIfNecessary(); + } + + components.clear(); + components.add(new Component(consolidated)); + updateComponentOffsets(0); + return this; + } + + /** + * Consolidate the composed {@link ByteBuf}s + * + * @param cIndex the index on which to start to compose + * @param numComponents the number of components to compose + */ + public CompositeByteBuf consolidate(int cIndex, int numComponents) { + checkComponentIndex(cIndex, numComponents); + if (numComponents <= 1) { + return this; + } + + final int endCIndex = cIndex + numComponents; + final Component last = components.get(endCIndex - 1); + final int capacity = last.endOffset - components.get(cIndex).offset; + final ByteBuf consolidated = allocBuffer(capacity); + + for (int i = cIndex; i < endCIndex; i ++) { + Component c = components.get(i); + ByteBuf b = c.buf; + consolidated.writeBytes(b); + c.freeIfNecessary(); + } + + components.subList(cIndex + 1, endCIndex).clear(); + components.set(cIndex, new Component(consolidated)); + updateComponentOffsets(cIndex); + return this; + } + + /** + * Discard all {@link ByteBuf}s which are read. + */ + public CompositeByteBuf discardReadComponents() { + ensureAccessible(); + final int readerIndex = readerIndex(); + if (readerIndex == 0) { + return this; + } + + // Discard everything if (readerIndex = writerIndex = capacity). + int writerIndex = writerIndex(); + if (readerIndex == writerIndex && writerIndex == capacity()) { + for (Component c: components) { + c.freeIfNecessary(); + } + components.clear(); + setIndex(0, 0); + adjustMarkers(readerIndex); + return this; + } + + // Remove read components. + int firstComponentId = toComponentIndex(readerIndex); + for (int i = 0; i < firstComponentId; i ++) { + components.get(i).freeIfNecessary(); + } + components.subList(0, firstComponentId).clear(); + + // Update indexes and markers. + Component first = components.get(0); + int offset = first.offset; + updateComponentOffsets(0); + setIndex(readerIndex - offset, writerIndex - offset); + adjustMarkers(offset); + return this; + } + + @Override + public CompositeByteBuf discardReadBytes() { + ensureAccessible(); + final int readerIndex = readerIndex(); + if (readerIndex == 0) { + return this; + } + + // Discard everything if (readerIndex = writerIndex = capacity). + int writerIndex = writerIndex(); + if (readerIndex == writerIndex && writerIndex == capacity()) { + for (Component c: components) { + c.freeIfNecessary(); + } + components.clear(); + setIndex(0, 0); + adjustMarkers(readerIndex); + return this; + } + + // Remove read components. + int firstComponentId = toComponentIndex(readerIndex); + for (int i = 0; i < firstComponentId; i ++) { + components.get(i).freeIfNecessary(); + } + components.subList(0, firstComponentId).clear(); + + // Remove or replace the first readable component with a new slice. + Component c = components.get(0); + int adjustment = readerIndex - c.offset; + if (adjustment == c.length) { + // new slice would be empty, so remove instead + components.remove(0); + } else { + Component newC = new Component(c.buf.slice(adjustment, c.length - adjustment)); + components.set(0, newC); + } + + // Update indexes and markers. + updateComponentOffsets(0); + setIndex(0, writerIndex - readerIndex); + adjustMarkers(readerIndex); + return this; + } + + private ByteBuf allocBuffer(int capacity) { + if (direct) { + return alloc().directBuffer(capacity); + } + return alloc().heapBuffer(capacity); + } + + @Override + public String toString() { + String result = super.toString(); + result = result.substring(0, result.length() - 1); + return result + ", components=" + components.size() + ')'; + } + + private static final class Component { + final ByteBuf buf; + final int length; + int offset; + int endOffset; + + Component(ByteBuf buf) { + this.buf = buf; + length = buf.readableBytes(); + } + + void freeIfNecessary() { + // Unwrap so that we can free slices, too. + buf.release(); // We should not get a NPE here. If so, it must be a bug. + } + } + + @Override + public CompositeByteBuf readerIndex(int readerIndex) { + return (CompositeByteBuf) super.readerIndex(readerIndex); + } + + @Override + public CompositeByteBuf writerIndex(int writerIndex) { + return (CompositeByteBuf) super.writerIndex(writerIndex); + } + + @Override + public CompositeByteBuf setIndex(int readerIndex, int writerIndex) { + return (CompositeByteBuf) super.setIndex(readerIndex, writerIndex); + } + + @Override + public CompositeByteBuf clear() { + return (CompositeByteBuf) super.clear(); + } + + @Override + public CompositeByteBuf markReaderIndex() { + return (CompositeByteBuf) super.markReaderIndex(); + } + + @Override + public CompositeByteBuf resetReaderIndex() { + return (CompositeByteBuf) super.resetReaderIndex(); + } + + @Override + public CompositeByteBuf markWriterIndex() { + return (CompositeByteBuf) super.markWriterIndex(); + } + + @Override + public CompositeByteBuf resetWriterIndex() { + return (CompositeByteBuf) super.resetWriterIndex(); + } + + @Override + public CompositeByteBuf ensureWritable(int minWritableBytes) { + return (CompositeByteBuf) super.ensureWritable(minWritableBytes); + } + + @Override + public CompositeByteBuf getBytes(int index, ByteBuf dst) { + return (CompositeByteBuf) super.getBytes(index, dst); + } + + @Override + public CompositeByteBuf getBytes(int index, ByteBuf dst, int length) { + return (CompositeByteBuf) super.getBytes(index, dst, length); + } + + @Override + public CompositeByteBuf getBytes(int index, byte[] dst) { + return (CompositeByteBuf) super.getBytes(index, dst); + } + + @Override + public CompositeByteBuf setBoolean(int index, boolean value) { + return (CompositeByteBuf) super.setBoolean(index, value); + } + + @Override + public CompositeByteBuf setChar(int index, int value) { + return (CompositeByteBuf) super.setChar(index, value); + } + + @Override + public CompositeByteBuf setFloat(int index, float value) { + return (CompositeByteBuf) super.setFloat(index, value); + } + + @Override + public CompositeByteBuf setDouble(int index, double value) { + return (CompositeByteBuf) super.setDouble(index, value); + } + + @Override + public CompositeByteBuf setBytes(int index, ByteBuf src) { + return (CompositeByteBuf) super.setBytes(index, src); + } + + @Override + public CompositeByteBuf setBytes(int index, ByteBuf src, int length) { + return (CompositeByteBuf) super.setBytes(index, src, length); + } + + @Override + public CompositeByteBuf setBytes(int index, byte[] src) { + return (CompositeByteBuf) super.setBytes(index, src); + } + + @Override + public CompositeByteBuf setZero(int index, int length) { + return (CompositeByteBuf) super.setZero(index, length); + } + + @Override + public CompositeByteBuf readBytes(ByteBuf dst) { + return (CompositeByteBuf) super.readBytes(dst); + } + + @Override + public CompositeByteBuf readBytes(ByteBuf dst, int length) { + return (CompositeByteBuf) super.readBytes(dst, length); + } + + @Override + public CompositeByteBuf readBytes(ByteBuf dst, int dstIndex, int length) { + return (CompositeByteBuf) super.readBytes(dst, dstIndex, length); + } + + @Override + public CompositeByteBuf readBytes(byte[] dst) { + return (CompositeByteBuf) super.readBytes(dst); + } + + @Override + public CompositeByteBuf readBytes(byte[] dst, int dstIndex, int length) { + return (CompositeByteBuf) super.readBytes(dst, dstIndex, length); + } + + @Override + public CompositeByteBuf readBytes(ByteBuffer dst) { + return (CompositeByteBuf) super.readBytes(dst); + } + + @Override + public CompositeByteBuf readBytes(OutputStream out, int length) throws IOException { + return (CompositeByteBuf) super.readBytes(out, length); + } + + @Override + public CompositeByteBuf skipBytes(int length) { + return (CompositeByteBuf) super.skipBytes(length); + } + + @Override + public CompositeByteBuf writeBoolean(boolean value) { + return (CompositeByteBuf) super.writeBoolean(value); + } + + @Override + public CompositeByteBuf writeByte(int value) { + return (CompositeByteBuf) super.writeByte(value); + } + + @Override + public CompositeByteBuf writeShort(int value) { + return (CompositeByteBuf) super.writeShort(value); + } + + @Override + public CompositeByteBuf writeMedium(int value) { + return (CompositeByteBuf) super.writeMedium(value); + } + + @Override + public CompositeByteBuf writeInt(int value) { + return (CompositeByteBuf) super.writeInt(value); + } + + @Override + public CompositeByteBuf writeLong(long value) { + return (CompositeByteBuf) super.writeLong(value); + } + + @Override + public CompositeByteBuf writeChar(int value) { + return (CompositeByteBuf) super.writeChar(value); + } + + @Override + public CompositeByteBuf writeFloat(float value) { + return (CompositeByteBuf) super.writeFloat(value); + } + + @Override + public CompositeByteBuf writeDouble(double value) { + return (CompositeByteBuf) super.writeDouble(value); + } + + @Override + public CompositeByteBuf writeBytes(ByteBuf src) { + return (CompositeByteBuf) super.writeBytes(src); + } + + @Override + public CompositeByteBuf writeBytes(ByteBuf src, int length) { + return (CompositeByteBuf) super.writeBytes(src, length); + } + + @Override + public CompositeByteBuf writeBytes(ByteBuf src, int srcIndex, int length) { + return (CompositeByteBuf) super.writeBytes(src, srcIndex, length); + } + + @Override + public CompositeByteBuf writeBytes(byte[] src) { + return (CompositeByteBuf) super.writeBytes(src); + } + + @Override + public CompositeByteBuf writeBytes(byte[] src, int srcIndex, int length) { + return (CompositeByteBuf) super.writeBytes(src, srcIndex, length); + } + + @Override + public CompositeByteBuf writeBytes(ByteBuffer src) { + return (CompositeByteBuf) super.writeBytes(src); + } + + @Override + public CompositeByteBuf writeZero(int length) { + return (CompositeByteBuf) super.writeZero(length); + } + + @Override + public CompositeByteBuf retain(int increment) { + return (CompositeByteBuf) super.retain(increment); + } + + @Override + public CompositeByteBuf retain() { + return (CompositeByteBuf) super.retain(); + } + + @Override + public ByteBuffer[] nioBuffers() { + return nioBuffers(readerIndex(), readableBytes()); + } + + @Override + public CompositeByteBuf discardSomeReadBytes() { + return discardReadComponents(); + } + + @Override + protected void deallocate() { + if (freed) { + return; + } + + freed = true; + int size = components.size(); + // We're not using foreach to avoid creating an iterator. + // see https://github.com/netty/netty/issues/2642 + for (int i = 0; i < size; i++) { + components.get(i).freeIfNecessary(); + } + + if (leak != null) { + leak.close(); + } + } + + @Override + public ByteBuf unwrap() { + return null; + } +} diff --git a/common/src/common/net/buffer/DuplicatedByteBuf.java b/common/src/common/net/buffer/DuplicatedByteBuf.java new file mode 100644 index 0000000..145631c --- /dev/null +++ b/common/src/common/net/buffer/DuplicatedByteBuf.java @@ -0,0 +1,305 @@ +/* + * Copyright 2012 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ +package common.net.buffer; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.nio.ByteBuffer; +import java.nio.ByteOrder; +import java.nio.channels.GatheringByteChannel; +import java.nio.channels.ScatteringByteChannel; + + +/** + * A derived buffer which simply forwards all data access requests to its + * parent. It is recommended to use {@link ByteBuf#duplicate()} instead + * of calling the constructor explicitly. + */ +public class DuplicatedByteBuf extends AbstractDerivedByteBuf { + + private final ByteBuf buffer; + + public DuplicatedByteBuf(ByteBuf buffer) { + super(buffer.maxCapacity()); + + if (buffer instanceof DuplicatedByteBuf) { + this.buffer = ((DuplicatedByteBuf) buffer).buffer; + } else { + this.buffer = buffer; + } + + setIndex(buffer.readerIndex(), buffer.writerIndex()); + } + + @Override + public ByteBuf unwrap() { + return buffer; + } + + @Override + public ByteBufAllocator alloc() { + return buffer.alloc(); + } + + @Override + public ByteOrder order() { + return buffer.order(); + } + + @Override + public boolean isDirect() { + return buffer.isDirect(); + } + + @Override + public int capacity() { + return buffer.capacity(); + } + + @Override + public ByteBuf capacity(int newCapacity) { + buffer.capacity(newCapacity); + return this; + } + + @Override + public boolean hasArray() { + return buffer.hasArray(); + } + + @Override + public byte[] array() { + return buffer.array(); + } + + @Override + public int arrayOffset() { + return buffer.arrayOffset(); + } + + @Override + public boolean hasMemoryAddress() { + return buffer.hasMemoryAddress(); + } + + @Override + public long memoryAddress() { + return buffer.memoryAddress(); + } + + @Override + public byte getByte(int index) { + return _getByte(index); + } + + @Override + protected byte _getByte(int index) { + return buffer.getByte(index); + } + + @Override + public short getShort(int index) { + return _getShort(index); + } + + @Override + protected short _getShort(int index) { + return buffer.getShort(index); + } + + @Override + public int getUnsignedMedium(int index) { + return _getUnsignedMedium(index); + } + + @Override + protected int _getUnsignedMedium(int index) { + return buffer.getUnsignedMedium(index); + } + + @Override + public int getInt(int index) { + return _getInt(index); + } + + @Override + protected int _getInt(int index) { + return buffer.getInt(index); + } + + @Override + public long getLong(int index) { + return _getLong(index); + } + + @Override + protected long _getLong(int index) { + return buffer.getLong(index); + } + + @Override + public ByteBuf copy(int index, int length) { + return buffer.copy(index, length); + } + + @Override + public ByteBuf slice(int index, int length) { + return buffer.slice(index, length); + } + + @Override + public ByteBuf getBytes(int index, ByteBuf dst, int dstIndex, int length) { + buffer.getBytes(index, dst, dstIndex, length); + return this; + } + + @Override + public ByteBuf getBytes(int index, byte[] dst, int dstIndex, int length) { + buffer.getBytes(index, dst, dstIndex, length); + return this; + } + + @Override + public ByteBuf getBytes(int index, ByteBuffer dst) { + buffer.getBytes(index, dst); + return this; + } + + @Override + public ByteBuf setByte(int index, int value) { + _setByte(index, value); + return this; + } + + @Override + protected void _setByte(int index, int value) { + buffer.setByte(index, value); + } + + @Override + public ByteBuf setShort(int index, int value) { + _setShort(index, value); + return this; + } + + @Override + protected void _setShort(int index, int value) { + buffer.setShort(index, value); + } + + @Override + public ByteBuf setMedium(int index, int value) { + _setMedium(index, value); + return this; + } + + @Override + protected void _setMedium(int index, int value) { + buffer.setMedium(index, value); + } + + @Override + public ByteBuf setInt(int index, int value) { + _setInt(index, value); + return this; + } + + @Override + protected void _setInt(int index, int value) { + buffer.setInt(index, value); + } + + @Override + public ByteBuf setLong(int index, long value) { + _setLong(index, value); + return this; + } + + @Override + protected void _setLong(int index, long value) { + buffer.setLong(index, value); + } + + @Override + public ByteBuf setBytes(int index, byte[] src, int srcIndex, int length) { + buffer.setBytes(index, src, srcIndex, length); + return this; + } + + @Override + public ByteBuf setBytes(int index, ByteBuf src, int srcIndex, int length) { + buffer.setBytes(index, src, srcIndex, length); + return this; + } + + @Override + public ByteBuf setBytes(int index, ByteBuffer src) { + buffer.setBytes(index, src); + return this; + } + + @Override + public ByteBuf getBytes(int index, OutputStream out, int length) + throws IOException { + buffer.getBytes(index, out, length); + return this; + } + + @Override + public int getBytes(int index, GatheringByteChannel out, int length) + throws IOException { + return buffer.getBytes(index, out, length); + } + + @Override + public int setBytes(int index, InputStream in, int length) + throws IOException { + return buffer.setBytes(index, in, length); + } + + @Override + public int setBytes(int index, ScatteringByteChannel in, int length) + throws IOException { + return buffer.setBytes(index, in, length); + } + + @Override + public int nioBufferCount() { + return buffer.nioBufferCount(); + } + + @Override + public ByteBuffer[] nioBuffers(int index, int length) { + return buffer.nioBuffers(index, length); + } + + @Override + public ByteBuffer internalNioBuffer(int index, int length) { + return nioBuffer(index, length); + } + + @Override + public int forEachByte(int index, int length, ByteBufProcessor processor) { + return buffer.forEachByte(index, length, processor); + } + + @Override + public int forEachByteDesc(int index, int length, ByteBufProcessor processor) { + return buffer.forEachByteDesc(index, length, processor); + } +} + diff --git a/common/src/common/net/buffer/EmptyByteBuf.java b/common/src/common/net/buffer/EmptyByteBuf.java new file mode 100644 index 0000000..1f1cb49 --- /dev/null +++ b/common/src/common/net/buffer/EmptyByteBuf.java @@ -0,0 +1,870 @@ +/* + * Copyright 2013 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ + +package common.net.buffer; + +import java.io.InputStream; +import java.io.OutputStream; +import java.nio.ByteBuffer; +import java.nio.ByteOrder; +import java.nio.ReadOnlyBufferException; +import java.nio.channels.GatheringByteChannel; +import java.nio.channels.ScatteringByteChannel; +import java.nio.charset.Charset; + +import common.net.util.internal.EmptyArrays; +import common.net.util.internal.PlatformDependent; +import common.net.util.internal.StringUtil; + +/** + * An empty {@link ByteBuf} whose capacity and maximum capacity are all {@code 0}. + */ +public final class EmptyByteBuf extends ByteBuf { + + private static final ByteBuffer EMPTY_BYTE_BUFFER = ByteBuffer.allocateDirect(0); + private static final long EMPTY_BYTE_BUFFER_ADDRESS; + + static { + long emptyByteBufferAddress = 0; + try { + if (PlatformDependent.hasUnsafe()) { + emptyByteBufferAddress = PlatformDependent.directBufferAddress(EMPTY_BYTE_BUFFER); + } + } catch (Throwable t) { + // Ignore + } + EMPTY_BYTE_BUFFER_ADDRESS = emptyByteBufferAddress; + } + + private final ByteBufAllocator alloc; + private final ByteOrder order; + private final String str; + private EmptyByteBuf swapped; + + public EmptyByteBuf(ByteBufAllocator alloc) { + this(alloc, ByteOrder.BIG_ENDIAN); + } + + private EmptyByteBuf(ByteBufAllocator alloc, ByteOrder order) { + if (alloc == null) { + throw new NullPointerException("alloc"); + } + + this.alloc = alloc; + this.order = order; + str = StringUtil.simpleClassName(this) + (order == ByteOrder.BIG_ENDIAN? "BE" : "LE"); + } + + @Override + public int capacity() { + return 0; + } + + @Override + public ByteBuf capacity(int newCapacity) { + throw new ReadOnlyBufferException(); + } + + @Override + public ByteBufAllocator alloc() { + return alloc; + } + + @Override + public ByteOrder order() { + return order; + } + + @Override + public ByteBuf unwrap() { + return null; + } + + @Override + public boolean isDirect() { + return true; + } + + @Override + public int maxCapacity() { + return 0; + } + + @Override + public ByteBuf order(ByteOrder endianness) { + if (endianness == null) { + throw new NullPointerException("endianness"); + } + if (endianness == order()) { + return this; + } + + EmptyByteBuf swapped = this.swapped; + if (swapped != null) { + return swapped; + } + + this.swapped = swapped = new EmptyByteBuf(alloc(), endianness); + return swapped; + } + + @Override + public int readerIndex() { + return 0; + } + + @Override + public ByteBuf readerIndex(int readerIndex) { + return checkIndex(readerIndex); + } + + @Override + public int writerIndex() { + return 0; + } + + @Override + public ByteBuf writerIndex(int writerIndex) { + return checkIndex(writerIndex); + } + + @Override + public ByteBuf setIndex(int readerIndex, int writerIndex) { + checkIndex(readerIndex); + checkIndex(writerIndex); + return this; + } + + @Override + public int readableBytes() { + return 0; + } + + @Override + public int writableBytes() { + return 0; + } + + @Override + public int maxWritableBytes() { + return 0; + } + + @Override + public boolean isReadable() { + return false; + } + + @Override + public boolean isWritable() { + return false; + } + + @Override + public ByteBuf clear() { + return this; + } + + @Override + public ByteBuf markReaderIndex() { + return this; + } + + @Override + public ByteBuf resetReaderIndex() { + return this; + } + + @Override + public ByteBuf markWriterIndex() { + return this; + } + + @Override + public ByteBuf resetWriterIndex() { + return this; + } + + @Override + public ByteBuf discardReadBytes() { + return this; + } + + @Override + public ByteBuf discardSomeReadBytes() { + return this; + } + + @Override + public ByteBuf ensureWritable(int minWritableBytes) { + if (minWritableBytes < 0) { + throw new IllegalArgumentException("minWritableBytes: " + minWritableBytes + " (expected: >= 0)"); + } + if (minWritableBytes != 0) { + throw new IndexOutOfBoundsException(); + } + return this; + } + + @Override + public int ensureWritable(int minWritableBytes, boolean force) { + if (minWritableBytes < 0) { + throw new IllegalArgumentException("minWritableBytes: " + minWritableBytes + " (expected: >= 0)"); + } + + if (minWritableBytes == 0) { + return 0; + } + + return 1; + } + + @Override + public boolean getBoolean(int index) { + throw new IndexOutOfBoundsException(); + } + + @Override + public byte getByte(int index) { + throw new IndexOutOfBoundsException(); + } + + @Override + public short getUnsignedByte(int index) { + throw new IndexOutOfBoundsException(); + } + + @Override + public short getShort(int index) { + throw new IndexOutOfBoundsException(); + } + + @Override + public int getUnsignedShort(int index) { + throw new IndexOutOfBoundsException(); + } + + @Override + public int getMedium(int index) { + throw new IndexOutOfBoundsException(); + } + + @Override + public int getUnsignedMedium(int index) { + throw new IndexOutOfBoundsException(); + } + + @Override + public int getInt(int index) { + throw new IndexOutOfBoundsException(); + } + + @Override + public long getUnsignedInt(int index) { + throw new IndexOutOfBoundsException(); + } + + @Override + public long getLong(int index) { + throw new IndexOutOfBoundsException(); + } + + @Override + public char getChar(int index) { + throw new IndexOutOfBoundsException(); + } + + @Override + public float getFloat(int index) { + throw new IndexOutOfBoundsException(); + } + + @Override + public double getDouble(int index) { + throw new IndexOutOfBoundsException(); + } + + @Override + public ByteBuf getBytes(int index, ByteBuf dst) { + return checkIndex(index, dst.writableBytes()); + } + + @Override + public ByteBuf getBytes(int index, ByteBuf dst, int length) { + return checkIndex(index, length); + } + + @Override + public ByteBuf getBytes(int index, ByteBuf dst, int dstIndex, int length) { + return checkIndex(index, length); + } + + @Override + public ByteBuf getBytes(int index, byte[] dst) { + return checkIndex(index, dst.length); + } + + @Override + public ByteBuf getBytes(int index, byte[] dst, int dstIndex, int length) { + return checkIndex(index, length); + } + + @Override + public ByteBuf getBytes(int index, ByteBuffer dst) { + return checkIndex(index, dst.remaining()); + } + + @Override + public ByteBuf getBytes(int index, OutputStream out, int length) { + return checkIndex(index, length); + } + + @Override + public int getBytes(int index, GatheringByteChannel out, int length) { + checkIndex(index, length); + return 0; + } + + @Override + public ByteBuf setBoolean(int index, boolean value) { + throw new IndexOutOfBoundsException(); + } + + @Override + public ByteBuf setByte(int index, int value) { + throw new IndexOutOfBoundsException(); + } + + @Override + public ByteBuf setShort(int index, int value) { + throw new IndexOutOfBoundsException(); + } + + @Override + public ByteBuf setMedium(int index, int value) { + throw new IndexOutOfBoundsException(); + } + + @Override + public ByteBuf setInt(int index, int value) { + throw new IndexOutOfBoundsException(); + } + + @Override + public ByteBuf setLong(int index, long value) { + throw new IndexOutOfBoundsException(); + } + + @Override + public ByteBuf setChar(int index, int value) { + throw new IndexOutOfBoundsException(); + } + + @Override + public ByteBuf setFloat(int index, float value) { + throw new IndexOutOfBoundsException(); + } + + @Override + public ByteBuf setDouble(int index, double value) { + throw new IndexOutOfBoundsException(); + } + + @Override + public ByteBuf setBytes(int index, ByteBuf src) { + throw new IndexOutOfBoundsException(); + } + + @Override + public ByteBuf setBytes(int index, ByteBuf src, int length) { + return checkIndex(index, length); + } + + @Override + public ByteBuf setBytes(int index, ByteBuf src, int srcIndex, int length) { + return checkIndex(index, length); + } + + @Override + public ByteBuf setBytes(int index, byte[] src) { + return checkIndex(index, src.length); + } + + @Override + public ByteBuf setBytes(int index, byte[] src, int srcIndex, int length) { + return checkIndex(index, length); + } + + @Override + public ByteBuf setBytes(int index, ByteBuffer src) { + return checkIndex(index, src.remaining()); + } + + @Override + public int setBytes(int index, InputStream in, int length) { + checkIndex(index, length); + return 0; + } + + @Override + public int setBytes(int index, ScatteringByteChannel in, int length) { + checkIndex(index, length); + return 0; + } + + @Override + public ByteBuf setZero(int index, int length) { + return checkIndex(index, length); + } + + @Override + public boolean readBoolean() { + throw new IndexOutOfBoundsException(); + } + + @Override + public byte readByte() { + throw new IndexOutOfBoundsException(); + } + + @Override + public short readUnsignedByte() { + throw new IndexOutOfBoundsException(); + } + + @Override + public short readShort() { + throw new IndexOutOfBoundsException(); + } + + @Override + public int readUnsignedShort() { + throw new IndexOutOfBoundsException(); + } + + @Override + public int readMedium() { + throw new IndexOutOfBoundsException(); + } + + @Override + public int readUnsignedMedium() { + throw new IndexOutOfBoundsException(); + } + + @Override + public int readInt() { + throw new IndexOutOfBoundsException(); + } + + @Override + public long readUnsignedInt() { + throw new IndexOutOfBoundsException(); + } + + @Override + public long readLong() { + throw new IndexOutOfBoundsException(); + } + + @Override + public char readChar() { + throw new IndexOutOfBoundsException(); + } + + @Override + public float readFloat() { + throw new IndexOutOfBoundsException(); + } + + @Override + public double readDouble() { + throw new IndexOutOfBoundsException(); + } + + @Override + public ByteBuf readBytes(int length) { + return checkLength(length); + } + + @Override + public ByteBuf readSlice(int length) { + return checkLength(length); + } + + @Override + public ByteBuf readBytes(ByteBuf dst) { + return checkLength(dst.writableBytes()); + } + + @Override + public ByteBuf readBytes(ByteBuf dst, int length) { + return checkLength(length); + } + + @Override + public ByteBuf readBytes(ByteBuf dst, int dstIndex, int length) { + return checkLength(length); + } + + @Override + public ByteBuf readBytes(byte[] dst) { + return checkLength(dst.length); + } + + @Override + public ByteBuf readBytes(byte[] dst, int dstIndex, int length) { + return checkLength(length); + } + + @Override + public ByteBuf readBytes(ByteBuffer dst) { + return checkLength(dst.remaining()); + } + + @Override + public ByteBuf readBytes(OutputStream out, int length) { + return checkLength(length); + } + + @Override + public int readBytes(GatheringByteChannel out, int length) { + checkLength(length); + return 0; + } + + @Override + public ByteBuf skipBytes(int length) { + return checkLength(length); + } + + @Override + public ByteBuf writeBoolean(boolean value) { + throw new IndexOutOfBoundsException(); + } + + @Override + public ByteBuf writeByte(int value) { + throw new IndexOutOfBoundsException(); + } + + @Override + public ByteBuf writeShort(int value) { + throw new IndexOutOfBoundsException(); + } + + @Override + public ByteBuf writeMedium(int value) { + throw new IndexOutOfBoundsException(); + } + + @Override + public ByteBuf writeInt(int value) { + throw new IndexOutOfBoundsException(); + } + + @Override + public ByteBuf writeLong(long value) { + throw new IndexOutOfBoundsException(); + } + + @Override + public ByteBuf writeChar(int value) { + throw new IndexOutOfBoundsException(); + } + + @Override + public ByteBuf writeFloat(float value) { + throw new IndexOutOfBoundsException(); + } + + @Override + public ByteBuf writeDouble(double value) { + throw new IndexOutOfBoundsException(); + } + + @Override + public ByteBuf writeBytes(ByteBuf src) { + throw new IndexOutOfBoundsException(); + } + + @Override + public ByteBuf writeBytes(ByteBuf src, int length) { + return checkLength(length); + } + + @Override + public ByteBuf writeBytes(ByteBuf src, int srcIndex, int length) { + return checkLength(length); + } + + @Override + public ByteBuf writeBytes(byte[] src) { + return checkLength(src.length); + } + + @Override + public ByteBuf writeBytes(byte[] src, int srcIndex, int length) { + return checkLength(length); + } + + @Override + public ByteBuf writeBytes(ByteBuffer src) { + return checkLength(src.remaining()); + } + + @Override + public int writeBytes(InputStream in, int length) { + checkLength(length); + return 0; + } + + @Override + public int writeBytes(ScatteringByteChannel in, int length) { + checkLength(length); + return 0; + } + + @Override + public ByteBuf writeZero(int length) { + return checkLength(length); + } + + @Override + public int indexOf(int fromIndex, int toIndex, byte value) { + checkIndex(fromIndex); + checkIndex(toIndex); + return -1; + } + + @Override + public int bytesBefore(byte value) { + return -1; + } + + @Override + public int bytesBefore(int length, byte value) { + checkLength(length); + return -1; + } + + @Override + public int bytesBefore(int index, int length, byte value) { + checkIndex(index, length); + return -1; + } + + @Override + public int forEachByte(ByteBufProcessor processor) { + return -1; + } + + @Override + public int forEachByte(int index, int length, ByteBufProcessor processor) { + checkIndex(index, length); + return -1; + } + + @Override + public int forEachByteDesc(ByteBufProcessor processor) { + return -1; + } + + @Override + public int forEachByteDesc(int index, int length, ByteBufProcessor processor) { + checkIndex(index, length); + return -1; + } + + @Override + public ByteBuf copy() { + return this; + } + + @Override + public ByteBuf copy(int index, int length) { + return checkIndex(index, length); + } + + @Override + public ByteBuf slice() { + return this; + } + + @Override + public ByteBuf slice(int index, int length) { + return checkIndex(index, length); + } + + @Override + public ByteBuf duplicate() { + return this; + } + + @Override + public int nioBufferCount() { + return 1; + } + + @Override + public ByteBuffer nioBuffer() { + return EMPTY_BYTE_BUFFER; + } + + @Override + public ByteBuffer nioBuffer(int index, int length) { + checkIndex(index, length); + return nioBuffer(); + } + + @Override + public ByteBuffer[] nioBuffers() { + return new ByteBuffer[] { EMPTY_BYTE_BUFFER }; + } + + @Override + public ByteBuffer[] nioBuffers(int index, int length) { + checkIndex(index, length); + return nioBuffers(); + } + + @Override + public ByteBuffer internalNioBuffer(int index, int length) { + return EMPTY_BYTE_BUFFER; + } + + @Override + public boolean hasArray() { + return true; + } + + @Override + public byte[] array() { + return EmptyArrays.EMPTY_BYTES; + } + + @Override + public int arrayOffset() { + return 0; + } + + @Override + public boolean hasMemoryAddress() { + return EMPTY_BYTE_BUFFER_ADDRESS != 0; + } + + @Override + public long memoryAddress() { + if (hasMemoryAddress()) { + return EMPTY_BYTE_BUFFER_ADDRESS; + } else { + throw new UnsupportedOperationException(); + } + } + + @Override + public String toString(Charset charset) { + return ""; + } + + @Override + public String toString(int index, int length, Charset charset) { + checkIndex(index, length); + return toString(charset); + } + + @Override + public int hashCode() { + return 0; + } + + @Override + public boolean equals(Object obj) { + return obj instanceof ByteBuf && !((ByteBuf) obj).isReadable(); + } + + @Override + public int compareTo(ByteBuf buffer) { + return buffer.isReadable()? -1 : 0; + } + + @Override + public String toString() { + return str; + } + + @Override + public boolean isReadable(int size) { + return false; + } + + @Override + public boolean isWritable(int size) { + return false; + } + + @Override + public int refCnt() { + return 1; + } + + @Override + public ByteBuf retain() { + return this; + } + + @Override + public ByteBuf retain(int increment) { + return this; + } + + @Override + public boolean release() { + return false; + } + + @Override + public boolean release(int decrement) { + return false; + } + + private ByteBuf checkIndex(int index) { + if (index != 0) { + throw new IndexOutOfBoundsException(); + } + return this; + } + + private ByteBuf checkIndex(int index, int length) { + if (length < 0) { + throw new IllegalArgumentException("length: " + length); + } + if (index != 0 || length != 0) { + throw new IndexOutOfBoundsException(); + } + return this; + } + + private ByteBuf checkLength(int length) { + if (length < 0) { + throw new IllegalArgumentException("length: " + length + " (expected: >= 0)"); + } + if (length != 0) { + throw new IndexOutOfBoundsException(); + } + return this; + } +} diff --git a/common/src/common/net/buffer/PoolArena.java b/common/src/common/net/buffer/PoolArena.java new file mode 100644 index 0000000..ac2c5f6 --- /dev/null +++ b/common/src/common/net/buffer/PoolArena.java @@ -0,0 +1,477 @@ +/* + * Copyright 2012 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ + +package common.net.buffer; + +import java.nio.ByteBuffer; + +import common.net.util.internal.PlatformDependent; +import common.net.util.internal.StringUtil; + +abstract class PoolArena { + + static final int numTinySubpagePools = 512 >>> 4; + + final PooledByteBufAllocator parent; + + private final int maxOrder; + final int pageSize; + final int pageShifts; + final int chunkSize; + final int subpageOverflowMask; + final int numSmallSubpagePools; + private final PoolSubpage[] tinySubpagePools; + private final PoolSubpage[] smallSubpagePools; + + private final PoolChunkList q050; + private final PoolChunkList q025; + private final PoolChunkList q000; + private final PoolChunkList qInit; + private final PoolChunkList q075; + private final PoolChunkList q100; + + // TODO: Test if adding padding helps under contention + //private long pad0, pad1, pad2, pad3, pad4, pad5, pad6, pad7; + + protected PoolArena(PooledByteBufAllocator parent, int pageSize, int maxOrder, int pageShifts, int chunkSize) { + this.parent = parent; + this.pageSize = pageSize; + this.maxOrder = maxOrder; + this.pageShifts = pageShifts; + this.chunkSize = chunkSize; + subpageOverflowMask = ~(pageSize - 1); + tinySubpagePools = newSubpagePoolArray(numTinySubpagePools); + for (int i = 0; i < tinySubpagePools.length; i ++) { + tinySubpagePools[i] = newSubpagePoolHead(pageSize); + } + + numSmallSubpagePools = pageShifts - 9; + smallSubpagePools = newSubpagePoolArray(numSmallSubpagePools); + for (int i = 0; i < smallSubpagePools.length; i ++) { + smallSubpagePools[i] = newSubpagePoolHead(pageSize); + } + + q100 = new PoolChunkList(this, null, 100, Integer.MAX_VALUE); + q075 = new PoolChunkList(this, q100, 75, 100); + q050 = new PoolChunkList(this, q075, 50, 100); + q025 = new PoolChunkList(this, q050, 25, 75); + q000 = new PoolChunkList(this, q025, 1, 50); + qInit = new PoolChunkList(this, q000, Integer.MIN_VALUE, 25); + + q100.prevList = q075; + q075.prevList = q050; + q050.prevList = q025; + q025.prevList = q000; + q000.prevList = null; + qInit.prevList = qInit; + } + + private PoolSubpage newSubpagePoolHead(int pageSize) { + PoolSubpage head = new PoolSubpage(pageSize); + head.prev = head; + head.next = head; + return head; + } + + + private PoolSubpage[] newSubpagePoolArray(int size) { + return new PoolSubpage[size]; + } + + abstract boolean isDirect(); + + PooledByteBuf allocate(PoolThreadCache cache, int reqCapacity, int maxCapacity) { + PooledByteBuf buf = newByteBuf(maxCapacity); + allocate(cache, buf, reqCapacity); + return buf; + } + + static int tinyIdx(int normCapacity) { + return normCapacity >>> 4; + } + + static int smallIdx(int normCapacity) { + int tableIdx = 0; + int i = normCapacity >>> 10; + while (i != 0) { + i >>>= 1; + tableIdx ++; + } + return tableIdx; + } + + // capacity < pageSize + boolean isTinyOrSmall(int normCapacity) { + return (normCapacity & subpageOverflowMask) == 0; + } + + // normCapacity < 512 + static boolean isTiny(int normCapacity) { + return (normCapacity & 0xFFFFFE00) == 0; + } + + private void allocate(PoolThreadCache cache, PooledByteBuf buf, final int reqCapacity) { + final int normCapacity = normalizeCapacity(reqCapacity); + if (isTinyOrSmall(normCapacity)) { // capacity < pageSize + int tableIdx; + PoolSubpage[] table; + if (isTiny(normCapacity)) { // < 512 + if (cache.allocateTiny(this, buf, reqCapacity, normCapacity)) { + // was able to allocate out of the cache so move on + return; + } + tableIdx = tinyIdx(normCapacity); + table = tinySubpagePools; + } else { + if (cache.allocateSmall(this, buf, reqCapacity, normCapacity)) { + // was able to allocate out of the cache so move on + return; + } + tableIdx = smallIdx(normCapacity); + table = smallSubpagePools; + } + + synchronized (this) { + final PoolSubpage head = table[tableIdx]; + final PoolSubpage s = head.next; + if (s != head) { + assert s.doNotDestroy && s.elemSize == normCapacity; + long handle = s.allocate(); + assert handle >= 0; + s.chunk.initBufWithSubpage(buf, handle, reqCapacity); + return; + } + } + } else if (normCapacity <= chunkSize) { + if (cache.allocateNormal(this, buf, reqCapacity, normCapacity)) { + // was able to allocate out of the cache so move on + return; + } + } else { + // Huge allocations are never served via the cache so just call allocateHuge + allocateHuge(buf, reqCapacity); + return; + } + allocateNormal(buf, reqCapacity, normCapacity); + } + + private synchronized void allocateNormal(PooledByteBuf buf, int reqCapacity, int normCapacity) { + if (q050.allocate(buf, reqCapacity, normCapacity) || q025.allocate(buf, reqCapacity, normCapacity) || + q000.allocate(buf, reqCapacity, normCapacity) || qInit.allocate(buf, reqCapacity, normCapacity) || + q075.allocate(buf, reqCapacity, normCapacity) || q100.allocate(buf, reqCapacity, normCapacity)) { + return; + } + + // Add a new chunk. + PoolChunk c = newChunk(pageSize, maxOrder, pageShifts, chunkSize); + long handle = c.allocate(normCapacity); + assert handle > 0; + c.initBuf(buf, handle, reqCapacity); + qInit.add(c); + } + + private void allocateHuge(PooledByteBuf buf, int reqCapacity) { + buf.initUnpooled(newUnpooledChunk(reqCapacity), reqCapacity); + } + + void free(PoolChunk chunk, long handle, int normCapacity) { + if (chunk.unpooled) { + destroyChunk(chunk); + } else { + PoolThreadCache cache = parent.threadCache.get(); + if (cache.add(this, chunk, handle, normCapacity)) { + // cached so not free it. + return; + } + synchronized (this) { + chunk.parent.free(chunk, handle); + } + } + } + + PoolSubpage findSubpagePoolHead(int elemSize) { + int tableIdx; + PoolSubpage[] table; + if (isTiny(elemSize)) { // < 512 + tableIdx = elemSize >>> 4; + table = tinySubpagePools; + } else { + tableIdx = 0; + elemSize >>>= 10; + while (elemSize != 0) { + elemSize >>>= 1; + tableIdx ++; + } + table = smallSubpagePools; + } + + return table[tableIdx]; + } + + int normalizeCapacity(int reqCapacity) { + if (reqCapacity < 0) { + throw new IllegalArgumentException("capacity: " + reqCapacity + " (expected: 0+)"); + } + if (reqCapacity >= chunkSize) { + return reqCapacity; + } + + if (!isTiny(reqCapacity)) { // >= 512 + // Doubled + + int normalizedCapacity = reqCapacity; + normalizedCapacity --; + normalizedCapacity |= normalizedCapacity >>> 1; + normalizedCapacity |= normalizedCapacity >>> 2; + normalizedCapacity |= normalizedCapacity >>> 4; + normalizedCapacity |= normalizedCapacity >>> 8; + normalizedCapacity |= normalizedCapacity >>> 16; + normalizedCapacity ++; + + if (normalizedCapacity < 0) { + normalizedCapacity >>>= 1; + } + + return normalizedCapacity; + } + + // Quantum-spaced + if ((reqCapacity & 15) == 0) { + return reqCapacity; + } + + return (reqCapacity & ~15) + 16; + } + + void reallocate(PooledByteBuf buf, int newCapacity, boolean freeOldMemory) { + if (newCapacity < 0 || newCapacity > buf.maxCapacity()) { + throw new IllegalArgumentException("newCapacity: " + newCapacity); + } + + int oldCapacity = buf.length; + if (oldCapacity == newCapacity) { + return; + } + + PoolChunk oldChunk = buf.chunk; + long oldHandle = buf.handle; + T oldMemory = buf.memory; + int oldOffset = buf.offset; + int oldMaxLength = buf.maxLength; + int readerIndex = buf.readerIndex(); + int writerIndex = buf.writerIndex(); + + allocate(parent.threadCache.get(), buf, newCapacity); + if (newCapacity > oldCapacity) { + memoryCopy( + oldMemory, oldOffset, + buf.memory, buf.offset, oldCapacity); + } else if (newCapacity < oldCapacity) { + if (readerIndex < newCapacity) { + if (writerIndex > newCapacity) { + writerIndex = newCapacity; + } + memoryCopy( + oldMemory, oldOffset + readerIndex, + buf.memory, buf.offset + readerIndex, writerIndex - readerIndex); + } else { + readerIndex = writerIndex = newCapacity; + } + } + + buf.setIndex(readerIndex, writerIndex); + + if (freeOldMemory) { + free(oldChunk, oldHandle, oldMaxLength); + } + } + + protected abstract PoolChunk newChunk(int pageSize, int maxOrder, int pageShifts, int chunkSize); + protected abstract PoolChunk newUnpooledChunk(int capacity); + protected abstract PooledByteBuf newByteBuf(int maxCapacity); + protected abstract void memoryCopy(T src, int srcOffset, T dst, int dstOffset, int length); + protected abstract void destroyChunk(PoolChunk chunk); + + public synchronized String toString() { + StringBuilder buf = new StringBuilder(); + buf.append("Chunk(s) at 0~25%:"); + buf.append(StringUtil.NEWLINE); + buf.append(qInit); + buf.append(StringUtil.NEWLINE); + buf.append("Chunk(s) at 0~50%:"); + buf.append(StringUtil.NEWLINE); + buf.append(q000); + buf.append(StringUtil.NEWLINE); + buf.append("Chunk(s) at 25~75%:"); + buf.append(StringUtil.NEWLINE); + buf.append(q025); + buf.append(StringUtil.NEWLINE); + buf.append("Chunk(s) at 50~100%:"); + buf.append(StringUtil.NEWLINE); + buf.append(q050); + buf.append(StringUtil.NEWLINE); + buf.append("Chunk(s) at 75~100%:"); + buf.append(StringUtil.NEWLINE); + buf.append(q075); + buf.append(StringUtil.NEWLINE); + buf.append("Chunk(s) at 100%:"); + buf.append(StringUtil.NEWLINE); + buf.append(q100); + buf.append(StringUtil.NEWLINE); + buf.append("tiny subpages:"); + for (int i = 1; i < tinySubpagePools.length; i ++) { + PoolSubpage head = tinySubpagePools[i]; + if (head.next == head) { + continue; + } + + buf.append(StringUtil.NEWLINE); + buf.append(i); + buf.append(": "); + PoolSubpage s = head.next; + for (;;) { + buf.append(s); + s = s.next; + if (s == head) { + break; + } + } + } + buf.append(StringUtil.NEWLINE); + buf.append("small subpages:"); + for (int i = 1; i < smallSubpagePools.length; i ++) { + PoolSubpage head = smallSubpagePools[i]; + if (head.next == head) { + continue; + } + + buf.append(StringUtil.NEWLINE); + buf.append(i); + buf.append(": "); + PoolSubpage s = head.next; + for (;;) { + buf.append(s); + s = s.next; + if (s == head) { + break; + } + } + } + buf.append(StringUtil.NEWLINE); + + return buf.toString(); + } + + static final class HeapArena extends PoolArena { + + HeapArena(PooledByteBufAllocator parent, int pageSize, int maxOrder, int pageShifts, int chunkSize) { + super(parent, pageSize, maxOrder, pageShifts, chunkSize); + } + + @Override + boolean isDirect() { + return false; + } + + @Override + protected PoolChunk newChunk(int pageSize, int maxOrder, int pageShifts, int chunkSize) { + return new PoolChunk(this, new byte[chunkSize], pageSize, maxOrder, pageShifts, chunkSize); + } + + @Override + protected PoolChunk newUnpooledChunk(int capacity) { + return new PoolChunk(this, new byte[capacity], capacity); + } + + @Override + protected void destroyChunk(PoolChunk chunk) { + // Rely on GC. + } + + @Override + protected PooledByteBuf newByteBuf(int maxCapacity) { + return PooledHeapByteBuf.newInstance(maxCapacity); + } + + @Override + protected void memoryCopy(byte[] src, int srcOffset, byte[] dst, int dstOffset, int length) { + if (length == 0) { + return; + } + + System.arraycopy(src, srcOffset, dst, dstOffset, length); + } + } + + static final class DirectArena extends PoolArena { + + private static final boolean HAS_UNSAFE = PlatformDependent.hasUnsafe(); + + DirectArena(PooledByteBufAllocator parent, int pageSize, int maxOrder, int pageShifts, int chunkSize) { + super(parent, pageSize, maxOrder, pageShifts, chunkSize); + } + + @Override + boolean isDirect() { + return true; + } + + @Override + protected PoolChunk newChunk(int pageSize, int maxOrder, int pageShifts, int chunkSize) { + return new PoolChunk( + this, ByteBuffer.allocateDirect(chunkSize), pageSize, maxOrder, pageShifts, chunkSize); + } + + @Override + protected PoolChunk newUnpooledChunk(int capacity) { + return new PoolChunk(this, ByteBuffer.allocateDirect(capacity), capacity); + } + + @Override + protected void destroyChunk(PoolChunk chunk) { + PlatformDependent.freeDirectBuffer(chunk.memory); + } + + @Override + protected PooledByteBuf newByteBuf(int maxCapacity) { + if (HAS_UNSAFE) { + return PooledUnsafeDirectByteBuf.newInstance(maxCapacity); + } else { + return PooledDirectByteBuf.newInstance(maxCapacity); + } + } + + @Override + protected void memoryCopy(ByteBuffer src, int srcOffset, ByteBuffer dst, int dstOffset, int length) { + if (length == 0) { + return; + } + + if (HAS_UNSAFE) { + PlatformDependent.copyMemory( + PlatformDependent.directBufferAddress(src) + srcOffset, + PlatformDependent.directBufferAddress(dst) + dstOffset, length); + } else { + // We must duplicate the NIO buffers because they may be accessed by other Netty buffers. + src = src.duplicate(); + dst = dst.duplicate(); + src.position(srcOffset).limit(srcOffset + length); + dst.position(dstOffset); + dst.put(src); + } + } + } +} diff --git a/common/src/common/net/buffer/PoolChunk.java b/common/src/common/net/buffer/PoolChunk.java new file mode 100644 index 0000000..87234ec --- /dev/null +++ b/common/src/common/net/buffer/PoolChunk.java @@ -0,0 +1,431 @@ +/* + * Copyright 2012 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ + +package common.net.buffer; + +/** + * Description of algorithm for PageRun/PoolSubpage allocation from PoolChunk + * + * Notation: The following terms are important to understand the code + * > page - a page is the smallest unit of memory chunk that can be allocated + * > chunk - a chunk is a collection of pages + * > in this code chunkSize = 2^{maxOrder} * pageSize + * + * To begin we allocate a byte array of size = chunkSize + * Whenever a ByteBuf of given size needs to be created we search for the first position + * in the byte array that has enough empty space to accommodate the requested size and + * return a (long) handle that encodes this offset information, (this memory segment is then + * marked as reserved so it is always used by exactly one ByteBuf and no more) + * + * For simplicity all sizes are normalized according to PoolArena#normalizeCapacity method + * This ensures that when we request for memory segments of size >= pageSize the normalizedCapacity + * equals the next nearest power of 2 + * + * To search for the first offset in chunk that has at least requested size available we construct a + * complete balanced binary tree and store it in an array (just like heaps) - memoryMap + * + * The tree looks like this (the size of each node being mentioned in the parenthesis) + * + * depth=0 1 node (chunkSize) + * depth=1 2 nodes (chunkSize/2) + * .. + * .. + * depth=d 2^d nodes (chunkSize/2^d) + * .. + * depth=maxOrder 2^maxOrder nodes (chunkSize/2^{maxOrder} = pageSize) + * + * depth=maxOrder is the last level and the leafs consist of pages + * + * With this tree available searching in chunkArray translates like this: + * To allocate a memory segment of size chunkSize/2^k we search for the first node (from left) at height k + * which is unused + * + * Algorithm: + * ---------- + * Encode the tree in memoryMap with the notation + * memoryMap[id] = x => in the subtree rooted at id, the first node that is free to be allocated + * is at depth x (counted from depth=0) i.e., at depths [depth_of_id, x), there is no node that is free + * + * As we allocate & free nodes, we update values stored in memoryMap so that the property is maintained + * + * Initialization - + * In the beginning we construct the memoryMap array by storing the depth of a node at each node + * i.e., memoryMap[id] = depth_of_id + * + * Observations: + * ------------- + * 1) memoryMap[id] = depth_of_id => it is free / unallocated + * 2) memoryMap[id] > depth_of_id => at least one of its child nodes is allocated, so we cannot allocate it, but + * some of its children can still be allocated based on their availability + * 3) memoryMap[id] = maxOrder + 1 => the node is fully allocated & thus none of its children can be allocated, it + * is thus marked as unusable + * + * Algorithm: [allocateNode(d) => we want to find the first node (from left) at height h that can be allocated] + * ---------- + * 1) start at root (i.e., depth = 0 or id = 1) + * 2) if memoryMap[1] > d => cannot be allocated from this chunk + * 3) if left node value <= h; we can allocate from left subtree so move to left and repeat until found + * 4) else try in right subtree + * + * Algorithm: [allocateRun(size)] + * ---------- + * 1) Compute d = log_2(chunkSize/size) + * 2) Return allocateNode(d) + * + * Algorithm: [allocateSubpage(size)] + * ---------- + * 1) use allocateNode(maxOrder) to find an empty (i.e., unused) leaf (i.e., page) + * 2) use this handle to construct the PoolSubpage object or if it already exists just call init(normCapacity) + * note that this PoolSubpage object is added to subpagesPool in the PoolArena when we init() it + * + * Note: + * ----- + * In the implementation for improving cache coherence, + * we store 2 pieces of information (i.e, 2 byte vals) as a short value in memoryMap + * + * memoryMap[id]= (depth_of_id, x) + * where as per convention defined above + * the second value (i.e, x) indicates that the first node which is free to be allocated is at depth x (from root) + */ + +final class PoolChunk { + + final PoolArena arena; + final T memory; + final boolean unpooled; + + private final byte[] memoryMap; + private final byte[] depthMap; + private final PoolSubpage[] subpages; + /** Used to determine if the requested capacity is equal to or greater than pageSize. */ + private final int subpageOverflowMask; + private final int pageSize; + private final int pageShifts; + private final int maxOrder; + private final int chunkSize; + private final int log2ChunkSize; + private final int maxSubpageAllocs; + /** Used to mark memory as unusable */ + private final byte unusable; + + private int freeBytes; + + PoolChunkList parent; + PoolChunk prev; + PoolChunk next; + + // TODO: Test if adding padding helps under contention + //private long pad0, pad1, pad2, pad3, pad4, pad5, pad6, pad7; + + PoolChunk(PoolArena arena, T memory, int pageSize, int maxOrder, int pageShifts, int chunkSize) { + unpooled = false; + this.arena = arena; + this.memory = memory; + this.pageSize = pageSize; + this.pageShifts = pageShifts; + this.maxOrder = maxOrder; + this.chunkSize = chunkSize; + unusable = (byte) (maxOrder + 1); + log2ChunkSize = log2(chunkSize); + subpageOverflowMask = ~(pageSize - 1); + freeBytes = chunkSize; + + assert maxOrder < 30 : "maxOrder should be < 30, but is: " + maxOrder; + maxSubpageAllocs = 1 << maxOrder; + + // Generate the memory map. + memoryMap = new byte[maxSubpageAllocs << 1]; + depthMap = new byte[memoryMap.length]; + int memoryMapIndex = 1; + for (int d = 0; d <= maxOrder; ++ d) { // move down the tree one level at a time + int depth = 1 << d; + for (int p = 0; p < depth; ++ p) { + // in each level traverse left to right and set value to the depth of subtree + memoryMap[memoryMapIndex] = (byte) d; + depthMap[memoryMapIndex] = (byte) d; + memoryMapIndex ++; + } + } + + subpages = newSubpageArray(maxSubpageAllocs); + } + + /** Creates a special chunk that is not pooled. */ + PoolChunk(PoolArena arena, T memory, int size) { + unpooled = true; + this.arena = arena; + this.memory = memory; + memoryMap = null; + depthMap = null; + subpages = null; + subpageOverflowMask = 0; + pageSize = 0; + pageShifts = 0; + maxOrder = 0; + unusable = (byte) (maxOrder + 1); + chunkSize = size; + log2ChunkSize = log2(chunkSize); + maxSubpageAllocs = 0; + } + + + private PoolSubpage[] newSubpageArray(int size) { + return new PoolSubpage[size]; + } + + int usage() { + final int freeBytes = this.freeBytes; + if (freeBytes == 0) { + return 100; + } + + int freePercentage = (int) (freeBytes * 100L / chunkSize); + if (freePercentage == 0) { + return 99; + } + return 100 - freePercentage; + } + + long allocate(int normCapacity) { + if ((normCapacity & subpageOverflowMask) != 0) { // >= pageSize + return allocateRun(normCapacity); + } else { + return allocateSubpage(normCapacity); + } + } + + /** + * Update method used by allocate + * This is triggered only when a successor is allocated and all its predecessors + * need to update their state + * The minimal depth at which subtree rooted at id has some free space + * + * @param id id + */ + private void updateParentsAlloc(int id) { + while (id > 1) { + int parentId = id >>> 1; + byte val1 = value(id); + byte val2 = value(id ^ 1); + byte val = val1 < val2 ? val1 : val2; + setValue(parentId, val); + id = parentId; + } + } + + /** + * Update method used by free + * This needs to handle the special case when both children are completely free + * in which case parent be directly allocated on request of size = child-size * 2 + * + * @param id id + */ + private void updateParentsFree(int id) { + int logChild = depth(id) + 1; + while (id > 1) { + int parentId = id >>> 1; + byte val1 = value(id); + byte val2 = value(id ^ 1); + logChild -= 1; // in first iteration equals log, subsequently reduce 1 from logChild as we traverse up + + if (val1 == logChild && val2 == logChild) { + setValue(parentId, (byte) (logChild - 1)); + } else { + byte val = val1 < val2 ? val1 : val2; + setValue(parentId, val); + } + + id = parentId; + } + } + + /** + * Algorithm to allocate an index in memoryMap when we query for a free node + * at depth d + * + * @param d depth + * @return index in memoryMap + */ + private int allocateNode(int d) { + int id = 1; + int initial = - (1 << d); // has last d bits = 0 and rest all = 1 + byte val = value(id); + if (val > d) { // unusable + return -1; + } + while (val < d || (id & initial) == 0) { // id & initial == 1 << d for all ids at depth d, for < d it is 0 + id <<= 1; + val = value(id); + if (val > d) { + id ^= 1; + val = value(id); + } + } + byte value = value(id); + assert value == d && (id & initial) == 1 << d : String.format("val = %d, id & initial = %d, d = %d", + value, id & initial, d); + setValue(id, unusable); // mark as unusable + updateParentsAlloc(id); + return id; + } + + /** + * Allocate a run of pages (>=1) + * + * @param normCapacity normalized capacity + * @return index in memoryMap + */ + private long allocateRun(int normCapacity) { + int d = maxOrder - (log2(normCapacity) - pageShifts); + int id = allocateNode(d); + if (id < 0) { + return id; + } + freeBytes -= runLength(id); + return id; + } + + /** + * Create/ initialize a new PoolSubpage of normCapacity + * Any PoolSubpage created/ initialized here is added to subpage pool in the PoolArena that owns this PoolChunk + * + * @param normCapacity normalized capacity + * @return index in memoryMap + */ + private long allocateSubpage(int normCapacity) { + int d = maxOrder; // subpages are only be allocated from pages i.e., leaves + int id = allocateNode(d); + if (id < 0) { + return id; + } + + final PoolSubpage[] subpages = this.subpages; + final int pageSize = this.pageSize; + + freeBytes -= pageSize; + + int subpageIdx = subpageIdx(id); + PoolSubpage subpage = subpages[subpageIdx]; + if (subpage == null) { + subpage = new PoolSubpage(this, id, runOffset(id), pageSize, normCapacity); + subpages[subpageIdx] = subpage; + } else { + subpage.init(normCapacity); + } + return subpage.allocate(); + } + + /** + * Free a subpage or a run of pages + * When a subpage is freed from PoolSubpage, it might be added back to subpage pool of the owning PoolArena + * If the subpage pool in PoolArena has at least one other PoolSubpage of given elemSize, we can + * completely free the owning Page so it is available for subsequent allocations + * + * @param handle handle to free + */ + void free(long handle) { + int memoryMapIdx = (int) handle; + int bitmapIdx = (int) (handle >>> Integer.SIZE); + + if (bitmapIdx != 0) { // free a subpage + PoolSubpage subpage = subpages[subpageIdx(memoryMapIdx)]; + assert subpage != null && subpage.doNotDestroy; + if (subpage.free(bitmapIdx & 0x3FFFFFFF)) { + return; + } + } + freeBytes += runLength(memoryMapIdx); + setValue(memoryMapIdx, depth(memoryMapIdx)); + updateParentsFree(memoryMapIdx); + } + + void initBuf(PooledByteBuf buf, long handle, int reqCapacity) { + int memoryMapIdx = (int) handle; + int bitmapIdx = (int) (handle >>> Integer.SIZE); + if (bitmapIdx == 0) { + byte val = value(memoryMapIdx); + assert val == unusable : String.valueOf(val); + buf.init(this, handle, runOffset(memoryMapIdx), reqCapacity, runLength(memoryMapIdx)); + } else { + initBufWithSubpage(buf, handle, bitmapIdx, reqCapacity); + } + } + + void initBufWithSubpage(PooledByteBuf buf, long handle, int reqCapacity) { + initBufWithSubpage(buf, handle, (int) (handle >>> Integer.SIZE), reqCapacity); + } + + private void initBufWithSubpage(PooledByteBuf buf, long handle, int bitmapIdx, int reqCapacity) { + assert bitmapIdx != 0; + + int memoryMapIdx = (int) handle; + + PoolSubpage subpage = subpages[subpageIdx(memoryMapIdx)]; + assert subpage.doNotDestroy; + assert reqCapacity <= subpage.elemSize; + + buf.init( + this, handle, + runOffset(memoryMapIdx) + (bitmapIdx & 0x3FFFFFFF) * subpage.elemSize, reqCapacity, subpage.elemSize); + } + + private byte value(int id) { + return memoryMap[id]; + } + + private void setValue(int id, byte val) { + memoryMap[id] = val; + } + + private byte depth(int id) { + return depthMap[id]; + } + + private static int log2(int val) { + // compute the (0-based, with lsb = 0) position of highest set bit i.e, log2 + return Integer.SIZE - 1 - Integer.numberOfLeadingZeros(val); + } + + private int runLength(int id) { + // represents the size in #bytes supported by node 'id' in the tree + return 1 << log2ChunkSize - depth(id); + } + + private int runOffset(int id) { + // represents the 0-based offset in #bytes from start of the byte-array chunk + int shift = id ^ 1 << depth(id); + return shift * runLength(id); + } + + private int subpageIdx(int memoryMapIdx) { + return memoryMapIdx ^ maxSubpageAllocs; // remove highest set bit, to get offset + } + + @Override + public String toString() { + StringBuilder buf = new StringBuilder(); + buf.append("Chunk("); + buf.append(Integer.toHexString(System.identityHashCode(this))); + buf.append(": "); + buf.append(usage()); + buf.append("%, "); + buf.append(chunkSize - freeBytes); + buf.append('/'); + buf.append(chunkSize); + buf.append(')'); + return buf.toString(); + } +} diff --git a/common/src/common/net/buffer/PoolChunkList.java b/common/src/common/net/buffer/PoolChunkList.java new file mode 100644 index 0000000..f0a5f40 --- /dev/null +++ b/common/src/common/net/buffer/PoolChunkList.java @@ -0,0 +1,129 @@ +/* + * Copyright 2012 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ + +package common.net.buffer; + +import common.net.util.internal.StringUtil; + +final class PoolChunkList { + private final PoolArena arena; + private final PoolChunkList nextList; + PoolChunkList prevList; + + private final int minUsage; + private final int maxUsage; + + private PoolChunk head; + + // TODO: Test if adding padding helps under contention + //private long pad0, pad1, pad2, pad3, pad4, pad5, pad6, pad7; + + PoolChunkList(PoolArena arena, PoolChunkList nextList, int minUsage, int maxUsage) { + this.arena = arena; + this.nextList = nextList; + this.minUsage = minUsage; + this.maxUsage = maxUsage; + } + + boolean allocate(PooledByteBuf buf, int reqCapacity, int normCapacity) { + if (head == null) { + return false; + } + + for (PoolChunk cur = head;;) { + long handle = cur.allocate(normCapacity); + if (handle < 0) { + cur = cur.next; + if (cur == null) { + return false; + } + } else { + cur.initBuf(buf, handle, reqCapacity); + if (cur.usage() >= maxUsage) { + remove(cur); + nextList.add(cur); + } + return true; + } + } + } + + void free(PoolChunk chunk, long handle) { + chunk.free(handle); + if (chunk.usage() < minUsage) { + remove(chunk); + if (prevList == null) { + assert chunk.usage() == 0; + arena.destroyChunk(chunk); + } else { + prevList.add(chunk); + } + } + } + + void add(PoolChunk chunk) { + if (chunk.usage() >= maxUsage) { + nextList.add(chunk); + return; + } + + chunk.parent = this; + if (head == null) { + head = chunk; + chunk.prev = null; + chunk.next = null; + } else { + chunk.prev = null; + chunk.next = head; + head.prev = chunk; + head = chunk; + } + } + + private void remove(PoolChunk cur) { + if (cur == head) { + head = cur.next; + if (head != null) { + head.prev = null; + } + } else { + PoolChunk next = cur.next; + cur.prev.next = next; + if (next != null) { + next.prev = cur.prev; + } + } + } + + @Override + public String toString() { + if (head == null) { + return "none"; + } + + StringBuilder buf = new StringBuilder(); + for (PoolChunk cur = head;;) { + buf.append(cur); + cur = cur.next; + if (cur == null) { + break; + } + buf.append(StringUtil.NEWLINE); + } + + return buf.toString(); + } +} diff --git a/common/src/common/net/buffer/PoolSubpage.java b/common/src/common/net/buffer/PoolSubpage.java new file mode 100644 index 0000000..ae643c7 --- /dev/null +++ b/common/src/common/net/buffer/PoolSubpage.java @@ -0,0 +1,213 @@ +/* + * Copyright 2012 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ + +package common.net.buffer; + +final class PoolSubpage { + + final PoolChunk chunk; + private final int memoryMapIdx; + private final int runOffset; + private final int pageSize; + private final long[] bitmap; + + PoolSubpage prev; + PoolSubpage next; + + boolean doNotDestroy; + int elemSize; + private int maxNumElems; + private int bitmapLength; + private int nextAvail; + private int numAvail; + + // TODO: Test if adding padding helps under contention + //private long pad0, pad1, pad2, pad3, pad4, pad5, pad6, pad7; + + /** Special constructor that creates a linked list head */ + PoolSubpage(int pageSize) { + chunk = null; + memoryMapIdx = -1; + runOffset = -1; + elemSize = -1; + this.pageSize = pageSize; + bitmap = null; + } + + PoolSubpage(PoolChunk chunk, int memoryMapIdx, int runOffset, int pageSize, int elemSize) { + this.chunk = chunk; + this.memoryMapIdx = memoryMapIdx; + this.runOffset = runOffset; + this.pageSize = pageSize; + bitmap = new long[pageSize >>> 10]; // pageSize / 16 / 64 + init(elemSize); + } + + void init(int elemSize) { + doNotDestroy = true; + this.elemSize = elemSize; + if (elemSize != 0) { + maxNumElems = numAvail = pageSize / elemSize; + nextAvail = 0; + bitmapLength = maxNumElems >>> 6; + if ((maxNumElems & 63) != 0) { + bitmapLength ++; + } + + for (int i = 0; i < bitmapLength; i ++) { + bitmap[i] = 0; + } + } + + addToPool(); + } + + /** + * Returns the bitmap index of the subpage allocation. + */ + long allocate() { + if (elemSize == 0) { + return toHandle(0); + } + + if (numAvail == 0 || !doNotDestroy) { + return -1; + } + + final int bitmapIdx = getNextAvail(); + int q = bitmapIdx >>> 6; + int r = bitmapIdx & 63; + assert (bitmap[q] >>> r & 1) == 0; + bitmap[q] |= 1L << r; + + if (-- numAvail == 0) { + removeFromPool(); + } + + return toHandle(bitmapIdx); + } + + /** + * @return {@code true} if this subpage is in use. + * {@code false} if this subpage is not used by its chunk and thus it's OK to be released. + */ + boolean free(int bitmapIdx) { + + if (elemSize == 0) { + return true; + } + + int q = bitmapIdx >>> 6; + int r = bitmapIdx & 63; + assert (bitmap[q] >>> r & 1) != 0; + bitmap[q] ^= 1L << r; + + setNextAvail(bitmapIdx); + + if (numAvail ++ == 0) { + addToPool(); + return true; + } + + if (numAvail != maxNumElems) { + return true; + } else { + // Subpage not in use (numAvail == maxNumElems) + if (prev == next) { + // Do not remove if this subpage is the only one left in the pool. + return true; + } + + // Remove this subpage from the pool if there are other subpages left in the pool. + doNotDestroy = false; + removeFromPool(); + return false; + } + } + + private void addToPool() { + PoolSubpage head = chunk.arena.findSubpagePoolHead(elemSize); + assert prev == null && next == null; + prev = head; + next = head.next; + next.prev = this; + head.next = this; + } + + private void removeFromPool() { + assert prev != null && next != null; + prev.next = next; + next.prev = prev; + next = null; + prev = null; + } + + private void setNextAvail(int bitmapIdx) { + nextAvail = bitmapIdx; + } + + private int getNextAvail() { + int nextAvail = this.nextAvail; + if (nextAvail >= 0) { + this.nextAvail = -1; + return nextAvail; + } + return findNextAvail(); + } + + private int findNextAvail() { + final long[] bitmap = this.bitmap; + final int bitmapLength = this.bitmapLength; + for (int i = 0; i < bitmapLength; i ++) { + long bits = bitmap[i]; + if (~bits != 0) { + return findNextAvail0(i, bits); + } + } + return -1; + } + + private int findNextAvail0(int i, long bits) { + final int maxNumElems = this.maxNumElems; + final int baseVal = i << 6; + + for (int j = 0; j < 64; j ++) { + if ((bits & 1) == 0) { + int val = baseVal | j; + if (val < maxNumElems) { + return val; + } else { + break; + } + } + bits >>>= 1; + } + return -1; + } + + private long toHandle(int bitmapIdx) { + return 0x4000000000000000L | (long) bitmapIdx << 32 | memoryMapIdx; + } + + public String toString() { + if (!doNotDestroy) { + return "(" + memoryMapIdx + ": not in use)"; + } + + return String.valueOf('(') + memoryMapIdx + ": " + (maxNumElems - numAvail) + '/' + maxNumElems + + ", offset: " + runOffset + ", length: " + pageSize + ", elemSize: " + elemSize + ')'; + } +} diff --git a/common/src/common/net/buffer/PoolThreadCache.java b/common/src/common/net/buffer/PoolThreadCache.java new file mode 100644 index 0000000..1a41c18 --- /dev/null +++ b/common/src/common/net/buffer/PoolThreadCache.java @@ -0,0 +1,485 @@ +/* + * Copyright 2012 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ + +package common.net.buffer; + + +import java.nio.ByteBuffer; + +import common.net.util.ThreadDeathWatcher; +import common.net.util.internal.logging.InternalLogger; +import common.net.util.internal.logging.InternalLoggerFactory; + +/** + * Acts a Thread cache for allocations. This implementation is moduled after + * jemalloc and the descripted + * technics of Scalable memory allocation using jemalloc. + */ +final class PoolThreadCache { + + private static final InternalLogger logger = InternalLoggerFactory.getInstance(PoolThreadCache.class); + + final PoolArena heapArena; + final PoolArena directArena; + + // Hold the caches for the different size classes, which are tiny, small and normal. + private final MemoryRegionCache[] tinySubPageHeapCaches; + private final MemoryRegionCache[] smallSubPageHeapCaches; + private final MemoryRegionCache[] tinySubPageDirectCaches; + private final MemoryRegionCache[] smallSubPageDirectCaches; + private final MemoryRegionCache[] normalHeapCaches; + private final MemoryRegionCache[] normalDirectCaches; + + // Used for bitshifting when calculate the index of normal caches later + private final int numShiftsNormalDirect; + private final int numShiftsNormalHeap; + private final int freeSweepAllocationThreshold; + + private int allocations; + + private final Thread thread = Thread.currentThread(); + private final Runnable freeTask = new Runnable() { + @Override + public void run() { + free0(); + } + }; + + // TODO: Test if adding padding helps under contention + //private long pad0, pad1, pad2, pad3, pad4, pad5, pad6, pad7; + + PoolThreadCache(PoolArena heapArena, PoolArena directArena, + int tinyCacheSize, int smallCacheSize, int normalCacheSize, + int maxCachedBufferCapacity, int freeSweepAllocationThreshold) { + if (maxCachedBufferCapacity < 0) { + throw new IllegalArgumentException("maxCachedBufferCapacity: " + + maxCachedBufferCapacity + " (expected: >= 0)"); + } + if (freeSweepAllocationThreshold < 1) { + throw new IllegalArgumentException("freeSweepAllocationThreshold: " + + maxCachedBufferCapacity + " (expected: > 0)"); + } + this.freeSweepAllocationThreshold = freeSweepAllocationThreshold; + this.heapArena = heapArena; + this.directArena = directArena; + if (directArena != null) { + tinySubPageDirectCaches = createSubPageCaches(tinyCacheSize, PoolArena.numTinySubpagePools); + smallSubPageDirectCaches = createSubPageCaches(smallCacheSize, directArena.numSmallSubpagePools); + + numShiftsNormalDirect = log2(directArena.pageSize); + normalDirectCaches = createNormalCaches( + normalCacheSize, maxCachedBufferCapacity, directArena); + } else { + // No directArea is configured so just null out all caches + tinySubPageDirectCaches = null; + smallSubPageDirectCaches = null; + normalDirectCaches = null; + numShiftsNormalDirect = -1; + } + if (heapArena != null) { + // Create the caches for the heap allocations + tinySubPageHeapCaches = createSubPageCaches(tinyCacheSize, PoolArena.numTinySubpagePools); + smallSubPageHeapCaches = createSubPageCaches(smallCacheSize, heapArena.numSmallSubpagePools); + + numShiftsNormalHeap = log2(heapArena.pageSize); + normalHeapCaches = createNormalCaches( + normalCacheSize, maxCachedBufferCapacity, heapArena); + } else { + // No heapArea is configured so just null out all caches + tinySubPageHeapCaches = null; + smallSubPageHeapCaches = null; + normalHeapCaches = null; + numShiftsNormalHeap = -1; + } + + // The thread-local cache will keep a list of pooled buffers which must be returned to + // the pool when the thread is not alive anymore. + ThreadDeathWatcher.watch(thread, freeTask); + } + + private static SubPageMemoryRegionCache[] createSubPageCaches(int cacheSize, int numCaches) { + if (cacheSize > 0) { + + SubPageMemoryRegionCache[] cache = new SubPageMemoryRegionCache[numCaches]; + for (int i = 0; i < cache.length; i++) { + // TODO: maybe use cacheSize / cache.length + cache[i] = new SubPageMemoryRegionCache(cacheSize); + } + return cache; + } else { + return null; + } + } + + private static NormalMemoryRegionCache[] createNormalCaches( + int cacheSize, int maxCachedBufferCapacity, PoolArena area) { + if (cacheSize > 0) { + int max = Math.min(area.chunkSize, maxCachedBufferCapacity); + int arraySize = Math.max(1, max / area.pageSize); + + + NormalMemoryRegionCache[] cache = new NormalMemoryRegionCache[arraySize]; + for (int i = 0; i < cache.length; i++) { + cache[i] = new NormalMemoryRegionCache(cacheSize); + } + return cache; + } else { + return null; + } + } + + private static int log2(int val) { + int res = 0; + while (val > 1) { + val >>= 1; + res++; + } + return res; + } + + /** + * Try to allocate a tiny buffer out of the cache. Returns {@code true} if successful {@code false} otherwise + */ + boolean allocateTiny(PoolArena area, PooledByteBuf buf, int reqCapacity, int normCapacity) { + return allocate(cacheForTiny(area, normCapacity), buf, reqCapacity); + } + + /** + * Try to allocate a small buffer out of the cache. Returns {@code true} if successful {@code false} otherwise + */ + boolean allocateSmall(PoolArena area, PooledByteBuf buf, int reqCapacity, int normCapacity) { + return allocate(cacheForSmall(area, normCapacity), buf, reqCapacity); + } + + /** + * Try to allocate a small buffer out of the cache. Returns {@code true} if successful {@code false} otherwise + */ + boolean allocateNormal(PoolArena area, PooledByteBuf buf, int reqCapacity, int normCapacity) { + return allocate(cacheForNormal(area, normCapacity), buf, reqCapacity); + } + + + private boolean allocate(MemoryRegionCache cache, PooledByteBuf buf, int reqCapacity) { + if (cache == null) { + // no cache found so just return false here + return false; + } + boolean allocated = cache.allocate(buf, reqCapacity); + if (++ allocations >= freeSweepAllocationThreshold) { + allocations = 0; + trim(); + } + return allocated; + } + + /** + * Add {@link PoolChunk} and {@code handle} to the cache if there is enough room. + * Returns {@code true} if it fit into the cache {@code false} otherwise. + */ + + boolean add(PoolArena area, PoolChunk chunk, long handle, int normCapacity) { + MemoryRegionCache cache; + if (area.isTinyOrSmall(normCapacity)) { + if (PoolArena.isTiny(normCapacity)) { + cache = cacheForTiny(area, normCapacity); + } else { + cache = cacheForSmall(area, normCapacity); + } + } else { + cache = cacheForNormal(area, normCapacity); + } + if (cache == null) { + return false; + } + return cache.add(chunk, handle); + } + + /** + * Should be called if the Thread that uses this cache is about to exist to release resources out of the cache + */ + void free() { + ThreadDeathWatcher.unwatch(thread, freeTask); + free0(); + } + + private void free0() { + int numFreed = free(tinySubPageDirectCaches) + + free(smallSubPageDirectCaches) + + free(normalDirectCaches) + + free(tinySubPageHeapCaches) + + free(smallSubPageHeapCaches) + + free(normalHeapCaches); + + if (numFreed > 0 && logger.isDebugEnabled()) { + logger.debug("Freed {} thread-local buffer(s) from thread: {}", numFreed, thread.getName()); + } + } + + private static int free(MemoryRegionCache[] caches) { + if (caches == null) { + return 0; + } + + int numFreed = 0; + for (MemoryRegionCache c: caches) { + numFreed += free(c); + } + return numFreed; + } + + private static int free(MemoryRegionCache cache) { + if (cache == null) { + return 0; + } + return cache.free(); + } + + void trim() { + trim(tinySubPageDirectCaches); + trim(smallSubPageDirectCaches); + trim(normalDirectCaches); + trim(tinySubPageHeapCaches); + trim(smallSubPageHeapCaches); + trim(normalHeapCaches); + } + + private static void trim(MemoryRegionCache[] caches) { + if (caches == null) { + return; + } + for (MemoryRegionCache c: caches) { + trim(c); + } + } + + private static void trim(MemoryRegionCache cache) { + if (cache == null) { + return; + } + cache.trim(); + } + + private MemoryRegionCache cacheForTiny(PoolArena area, int normCapacity) { + int idx = PoolArena.tinyIdx(normCapacity); + if (area.isDirect()) { + return cache(tinySubPageDirectCaches, idx); + } + return cache(tinySubPageHeapCaches, idx); + } + + private MemoryRegionCache cacheForSmall(PoolArena area, int normCapacity) { + int idx = PoolArena.smallIdx(normCapacity); + if (area.isDirect()) { + return cache(smallSubPageDirectCaches, idx); + } + return cache(smallSubPageHeapCaches, idx); + } + + private MemoryRegionCache cacheForNormal(PoolArena area, int normCapacity) { + if (area.isDirect()) { + int idx = log2(normCapacity >> numShiftsNormalDirect); + return cache(normalDirectCaches, idx); + } + int idx = log2(normCapacity >> numShiftsNormalHeap); + return cache(normalHeapCaches, idx); + } + + private static MemoryRegionCache cache(MemoryRegionCache[] cache, int idx) { + if (cache == null || idx > cache.length - 1) { + return null; + } + return cache[idx]; + } + + /** + * Cache used for buffers which are backed by TINY or SMALL size. + */ + private static final class SubPageMemoryRegionCache extends MemoryRegionCache { + SubPageMemoryRegionCache(int size) { + super(size); + } + + @Override + protected void initBuf( + PoolChunk chunk, long handle, PooledByteBuf buf, int reqCapacity) { + chunk.initBufWithSubpage(buf, handle, reqCapacity); + } + } + + /** + * Cache used for buffers which are backed by NORMAL size. + */ + private static final class NormalMemoryRegionCache extends MemoryRegionCache { + NormalMemoryRegionCache(int size) { + super(size); + } + + @Override + protected void initBuf( + PoolChunk chunk, long handle, PooledByteBuf buf, int reqCapacity) { + chunk.initBuf(buf, handle, reqCapacity); + } + } + + /** + * Cache of {@link PoolChunk} and handles which can be used to allocate a buffer without locking at all. + */ + private abstract static class MemoryRegionCache { + private final Entry[] entries; + private final int maxUnusedCached; + private int head; + private int tail; + private int maxEntriesInUse; + private int entriesInUse; + + + MemoryRegionCache(int size) { + entries = new Entry[powerOfTwo(size)]; + for (int i = 0; i < entries.length; i++) { + entries[i] = new Entry(); + } + maxUnusedCached = size / 2; + } + + private static int powerOfTwo(int res) { + if (res <= 2) { + return 2; + } + res--; + res |= res >> 1; + res |= res >> 2; + res |= res >> 4; + res |= res >> 8; + res |= res >> 16; + res++; + return res; + } + + /** + * Init the {@link PooledByteBuf} using the provided chunk and handle with the capacity restrictions. + */ + protected abstract void initBuf(PoolChunk chunk, long handle, + PooledByteBuf buf, int reqCapacity); + + /** + * Add to cache if not already full. + */ + public boolean add(PoolChunk chunk, long handle) { + Entry entry = entries[tail]; + if (entry.chunk != null) { + // cache is full + return false; + } + entriesInUse --; + + entry.chunk = chunk; + entry.handle = handle; + tail = nextIdx(tail); + return true; + } + + /** + * Allocate something out of the cache if possible and remove the entry from the cache. + */ + public boolean allocate(PooledByteBuf buf, int reqCapacity) { + Entry entry = entries[head]; + if (entry.chunk == null) { + return false; + } + + entriesInUse ++; + if (maxEntriesInUse < entriesInUse) { + maxEntriesInUse = entriesInUse; + } + initBuf(entry.chunk, entry.handle, buf, reqCapacity); + // only null out the chunk as we only use the chunk to check if the buffer is full or not. + entry.chunk = null; + head = nextIdx(head); + return true; + } + + /** + * Clear out this cache and free up all previous cached {@link PoolChunk}s and {@code handle}s. + */ + public int free() { + int numFreed = 0; + entriesInUse = 0; + maxEntriesInUse = 0; + for (int i = head;; i = nextIdx(i)) { + if (freeEntry(entries[i])) { + numFreed++; + } else { + // all cleared + return numFreed; + } + } + } + + /** + * Free up cached {@link PoolChunk}s if not allocated frequently enough. + */ + private void trim() { + int free = size() - maxEntriesInUse; + entriesInUse = 0; + maxEntriesInUse = 0; + + if (free <= maxUnusedCached) { + return; + } + + int i = head; + for (; free > 0; free--) { + if (!freeEntry(entries[i])) { + // all freed + return; + } + i = nextIdx(i); + } + } + + + private static boolean freeEntry(Entry entry) { + PoolChunk chunk = entry.chunk; + if (chunk == null) { + return false; + } + // need to synchronize on the area from which it was allocated before. + synchronized (chunk.arena) { + chunk.parent.free(chunk, entry.handle); + } + entry.chunk = null; + return true; + } + + /** + * Return the number of cached entries. + */ + private int size() { + return tail - head & entries.length - 1; + } + + private int nextIdx(int index) { + // use bitwise operation as this is faster as using modulo. + return index + 1 & entries.length - 1; + } + + private static final class Entry { + PoolChunk chunk; + long handle; + } + } +} diff --git a/common/src/common/net/buffer/PooledByteBuf.java b/common/src/common/net/buffer/PooledByteBuf.java new file mode 100644 index 0000000..34324d7 --- /dev/null +++ b/common/src/common/net/buffer/PooledByteBuf.java @@ -0,0 +1,160 @@ +/* + * Copyright 2012 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ + +package common.net.buffer; + +import java.nio.ByteBuffer; +import java.nio.ByteOrder; + +import common.net.util.Recycler; + +abstract class PooledByteBuf extends AbstractReferenceCountedByteBuf { + + private final Recycler.Handle recyclerHandle; + + protected PoolChunk chunk; + protected long handle; + protected T memory; + protected int offset; + protected int length; + int maxLength; + + private ByteBuffer tmpNioBuf; + + protected PooledByteBuf(Recycler.Handle recyclerHandle, int maxCapacity) { + super(maxCapacity); + this.recyclerHandle = recyclerHandle; + } + + void init(PoolChunk chunk, long handle, int offset, int length, int maxLength) { + assert handle >= 0; + assert chunk != null; + + this.chunk = chunk; + this.handle = handle; + memory = chunk.memory; + this.offset = offset; + this.length = length; + this.maxLength = maxLength; + setIndex(0, 0); + tmpNioBuf = null; + } + + void initUnpooled(PoolChunk chunk, int length) { + assert chunk != null; + + this.chunk = chunk; + handle = 0; + memory = chunk.memory; + offset = 0; + this.length = maxLength = length; + setIndex(0, 0); + tmpNioBuf = null; + } + + @Override + public final int capacity() { + return length; + } + + @Override + public final ByteBuf capacity(int newCapacity) { + ensureAccessible(); + + // If the request capacity does not require reallocation, just update the length of the memory. + if (chunk.unpooled) { + if (newCapacity == length) { + return this; + } + } else { + if (newCapacity > length) { + if (newCapacity <= maxLength) { + length = newCapacity; + return this; + } + } else if (newCapacity < length) { + if (newCapacity > maxLength >>> 1) { + if (maxLength <= 512) { + if (newCapacity > maxLength - 16) { + length = newCapacity; + setIndex(Math.min(readerIndex(), newCapacity), Math.min(writerIndex(), newCapacity)); + return this; + } + } else { // > 512 (i.e. >= 1024) + length = newCapacity; + setIndex(Math.min(readerIndex(), newCapacity), Math.min(writerIndex(), newCapacity)); + return this; + } + } + } else { + return this; + } + } + + // Reallocation required. + chunk.arena.reallocate(this, newCapacity, true); + return this; + } + + @Override + public final ByteBufAllocator alloc() { + return chunk.arena.parent; + } + + @Override + public final ByteOrder order() { + return ByteOrder.BIG_ENDIAN; + } + + @Override + public final ByteBuf unwrap() { + return null; + } + + protected final ByteBuffer internalNioBuffer() { + ByteBuffer tmpNioBuf = this.tmpNioBuf; + if (tmpNioBuf == null) { + this.tmpNioBuf = tmpNioBuf = newInternalNioBuffer(memory); + } + return tmpNioBuf; + } + + protected abstract ByteBuffer newInternalNioBuffer(T memory); + + @Override + protected final void deallocate() { + if (handle >= 0) { + final long handle = this.handle; + this.handle = -1; + memory = null; + chunk.arena.free(chunk, handle, maxLength); + recycle(); + } + } + + private void recycle() { + Recycler.Handle recyclerHandle = this.recyclerHandle; + if (recyclerHandle != null) { + ((Recycler) recycler()).recycle(this, recyclerHandle); + } + } + + protected abstract Recycler recycler(); + + protected final int idx(int index) { + return offset + index; + } +} diff --git a/common/src/common/net/buffer/PooledByteBufAllocator.java b/common/src/common/net/buffer/PooledByteBufAllocator.java new file mode 100644 index 0000000..4aaf1a0 --- /dev/null +++ b/common/src/common/net/buffer/PooledByteBufAllocator.java @@ -0,0 +1,334 @@ +/* + * Copyright 2012 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ + +package common.net.buffer; + +import java.nio.ByteBuffer; +import java.util.concurrent.atomic.AtomicInteger; + +import common.net.util.concurrent.FastThreadLocal; +import common.net.util.internal.PlatformDependent; +import common.net.util.internal.SystemPropertyUtil; +import common.net.util.internal.logging.InternalLogger; +import common.net.util.internal.logging.InternalLoggerFactory; + +public class PooledByteBufAllocator extends AbstractByteBufAllocator { + + private static final InternalLogger logger = InternalLoggerFactory.getInstance(PooledByteBufAllocator.class); + private static final int DEFAULT_NUM_HEAP_ARENA; + private static final int DEFAULT_NUM_DIRECT_ARENA; + + private static final int DEFAULT_PAGE_SIZE; + private static final int DEFAULT_MAX_ORDER; // 8192 << 11 = 16 MiB per chunk + private static final int DEFAULT_TINY_CACHE_SIZE; + private static final int DEFAULT_SMALL_CACHE_SIZE; + private static final int DEFAULT_NORMAL_CACHE_SIZE; + private static final int DEFAULT_MAX_CACHED_BUFFER_CAPACITY; + private static final int DEFAULT_CACHE_TRIM_INTERVAL; + + private static final int MIN_PAGE_SIZE = 4096; + private static final int MAX_CHUNK_SIZE = (int) (((long) Integer.MAX_VALUE + 1) / 2); + + static { + int defaultPageSize = SystemPropertyUtil.getInt("game.net.allocator.pageSize", 8192); + Throwable pageSizeFallbackCause = null; + try { + validateAndCalculatePageShifts(defaultPageSize); + } catch (Throwable t) { + pageSizeFallbackCause = t; + defaultPageSize = 8192; + } + DEFAULT_PAGE_SIZE = defaultPageSize; + + int defaultMaxOrder = SystemPropertyUtil.getInt("game.net.allocator.maxOrder", 11); + Throwable maxOrderFallbackCause = null; + try { + validateAndCalculateChunkSize(DEFAULT_PAGE_SIZE, defaultMaxOrder); + } catch (Throwable t) { + maxOrderFallbackCause = t; + defaultMaxOrder = 11; + } + DEFAULT_MAX_ORDER = defaultMaxOrder; + + // Determine reasonable default for nHeapArena and nDirectArena. + // Assuming each arena has 3 chunks, the pool should not consume more than 50% of max memory. + final Runtime runtime = Runtime.getRuntime(); + final int defaultChunkSize = DEFAULT_PAGE_SIZE << DEFAULT_MAX_ORDER; + DEFAULT_NUM_HEAP_ARENA = Math.max(0, + SystemPropertyUtil.getInt( + "game.net.allocator.numHeapArenas", + (int) Math.min( + runtime.availableProcessors(), + Runtime.getRuntime().maxMemory() / defaultChunkSize / 2 / 3))); + DEFAULT_NUM_DIRECT_ARENA = Math.max(0, + SystemPropertyUtil.getInt( + "game.net.allocator.numDirectArenas", + (int) Math.min( + runtime.availableProcessors(), + PlatformDependent.maxDirectMemory() / defaultChunkSize / 2 / 3))); + + // cache sizes + DEFAULT_TINY_CACHE_SIZE = SystemPropertyUtil.getInt("game.net.allocator.tinyCacheSize", 512); + DEFAULT_SMALL_CACHE_SIZE = SystemPropertyUtil.getInt("game.net.allocator.smallCacheSize", 256); + DEFAULT_NORMAL_CACHE_SIZE = SystemPropertyUtil.getInt("game.net.allocator.normalCacheSize", 64); + + // 32 kb is the default maximum capacity of the cached buffer. Similar to what is explained in + // 'Scalable memory allocation using jemalloc' + DEFAULT_MAX_CACHED_BUFFER_CAPACITY = SystemPropertyUtil.getInt( + "game.net.allocator.maxCachedBufferCapacity", 32 * 1024); + + // the number of threshold of allocations when cached entries will be freed up if not frequently used + DEFAULT_CACHE_TRIM_INTERVAL = SystemPropertyUtil.getInt( + "game.net.allocator.cacheTrimInterval", 8192); + + if (logger.isDebugEnabled()) { + logger.debug("-Dgame.net.allocator.numHeapArenas: {}", DEFAULT_NUM_HEAP_ARENA); + logger.debug("-Dgame.net.allocator.numDirectArenas: {}", DEFAULT_NUM_DIRECT_ARENA); + if (pageSizeFallbackCause == null) { + logger.debug("-Dgame.net.allocator.pageSize: {}", DEFAULT_PAGE_SIZE); + } else { + logger.debug("-Dgame.net.allocator.pageSize: {}", DEFAULT_PAGE_SIZE, pageSizeFallbackCause); + } + if (maxOrderFallbackCause == null) { + logger.debug("-Dgame.net.allocator.maxOrder: {}", DEFAULT_MAX_ORDER); + } else { + logger.debug("-Dgame.net.allocator.maxOrder: {}", DEFAULT_MAX_ORDER, maxOrderFallbackCause); + } + logger.debug("-Dgame.net.allocator.chunkSize: {}", DEFAULT_PAGE_SIZE << DEFAULT_MAX_ORDER); + logger.debug("-Dgame.net.allocator.tinyCacheSize: {}", DEFAULT_TINY_CACHE_SIZE); + logger.debug("-Dgame.net.allocator.smallCacheSize: {}", DEFAULT_SMALL_CACHE_SIZE); + logger.debug("-Dgame.net.allocator.normalCacheSize: {}", DEFAULT_NORMAL_CACHE_SIZE); + logger.debug("-Dgame.net.allocator.maxCachedBufferCapacity: {}", DEFAULT_MAX_CACHED_BUFFER_CAPACITY); + logger.debug("-Dgame.net.allocator.cacheTrimInterval: {}", DEFAULT_CACHE_TRIM_INTERVAL); + } + } + + public static final PooledByteBufAllocator DEFAULT = + new PooledByteBufAllocator(PlatformDependent.directBufferPreferred()); + + private final PoolArena[] heapArenas; + private final PoolArena[] directArenas; + private final int tinyCacheSize; + private final int smallCacheSize; + private final int normalCacheSize; + + final PoolThreadLocalCache threadCache; + + public PooledByteBufAllocator() { + this(false); + } + + public PooledByteBufAllocator(boolean preferDirect) { + this(preferDirect, DEFAULT_NUM_HEAP_ARENA, DEFAULT_NUM_DIRECT_ARENA, DEFAULT_PAGE_SIZE, DEFAULT_MAX_ORDER); + } + + public PooledByteBufAllocator(int nHeapArena, int nDirectArena, int pageSize, int maxOrder) { + this(false, nHeapArena, nDirectArena, pageSize, maxOrder); + } + + public PooledByteBufAllocator(boolean preferDirect, int nHeapArena, int nDirectArena, int pageSize, int maxOrder) { + this(preferDirect, nHeapArena, nDirectArena, pageSize, maxOrder, + DEFAULT_TINY_CACHE_SIZE, DEFAULT_SMALL_CACHE_SIZE, DEFAULT_NORMAL_CACHE_SIZE); + } + + public PooledByteBufAllocator(boolean preferDirect, int nHeapArena, int nDirectArena, int pageSize, int maxOrder, + int tinyCacheSize, int smallCacheSize, int normalCacheSize) { + super(preferDirect); + threadCache = new PoolThreadLocalCache(); + this.tinyCacheSize = tinyCacheSize; + this.smallCacheSize = smallCacheSize; + this.normalCacheSize = normalCacheSize; + final int chunkSize = validateAndCalculateChunkSize(pageSize, maxOrder); + + if (nHeapArena < 0) { + throw new IllegalArgumentException("nHeapArena: " + nHeapArena + " (expected: >= 0)"); + } + if (nDirectArena < 0) { + throw new IllegalArgumentException("nDirectArea: " + nDirectArena + " (expected: >= 0)"); + } + + int pageShifts = validateAndCalculatePageShifts(pageSize); + + if (nHeapArena > 0) { + heapArenas = newArenaArray(nHeapArena); + for (int i = 0; i < heapArenas.length; i ++) { + heapArenas[i] = new PoolArena.HeapArena(this, pageSize, maxOrder, pageShifts, chunkSize); + } + } else { + heapArenas = null; + } + + if (nDirectArena > 0) { + directArenas = newArenaArray(nDirectArena); + for (int i = 0; i < directArenas.length; i ++) { + directArenas[i] = new PoolArena.DirectArena(this, pageSize, maxOrder, pageShifts, chunkSize); + } + } else { + directArenas = null; + } + } + + @Deprecated + + public PooledByteBufAllocator(boolean preferDirect, int nHeapArena, int nDirectArena, int pageSize, int maxOrder, + int tinyCacheSize, int smallCacheSize, int normalCacheSize, + long cacheThreadAliveCheckInterval) { + this(preferDirect, nHeapArena, nDirectArena, pageSize, maxOrder, + tinyCacheSize, smallCacheSize, normalCacheSize); + } + + + private static PoolArena[] newArenaArray(int size) { + return new PoolArena[size]; + } + + private static int validateAndCalculatePageShifts(int pageSize) { + if (pageSize < MIN_PAGE_SIZE) { + throw new IllegalArgumentException("pageSize: " + pageSize + " (expected: " + MIN_PAGE_SIZE + "+)"); + } + + if ((pageSize & pageSize - 1) != 0) { + throw new IllegalArgumentException("pageSize: " + pageSize + " (expected: power of 2)"); + } + + // Logarithm base 2. At this point we know that pageSize is a power of two. + return Integer.SIZE - 1 - Integer.numberOfLeadingZeros(pageSize); + } + + private static int validateAndCalculateChunkSize(int pageSize, int maxOrder) { + if (maxOrder > 14) { + throw new IllegalArgumentException("maxOrder: " + maxOrder + " (expected: 0-14)"); + } + + // Ensure the resulting chunkSize does not overflow. + int chunkSize = pageSize; + for (int i = maxOrder; i > 0; i --) { + if (chunkSize > MAX_CHUNK_SIZE / 2) { + throw new IllegalArgumentException(String.format( + "pageSize (%d) << maxOrder (%d) must not exceed %d", pageSize, maxOrder, MAX_CHUNK_SIZE)); + } + chunkSize <<= 1; + } + return chunkSize; + } + + @Override + protected ByteBuf newHeapBuffer(int initialCapacity, int maxCapacity) { + PoolThreadCache cache = threadCache.get(); + PoolArena heapArena = cache.heapArena; + + ByteBuf buf; + if (heapArena != null) { + buf = heapArena.allocate(cache, initialCapacity, maxCapacity); + } else { + buf = new UnpooledHeapByteBuf(this, initialCapacity, maxCapacity); + } + + return toLeakAwareBuffer(buf); + } + + @Override + protected ByteBuf newDirectBuffer(int initialCapacity, int maxCapacity) { + PoolThreadCache cache = threadCache.get(); + PoolArena directArena = cache.directArena; + + ByteBuf buf; + if (directArena != null) { + buf = directArena.allocate(cache, initialCapacity, maxCapacity); + } else { + if (PlatformDependent.hasUnsafe()) { + buf = new UnpooledUnsafeDirectByteBuf(this, initialCapacity, maxCapacity); + } else { + buf = new UnpooledDirectByteBuf(this, initialCapacity, maxCapacity); + } + } + + return toLeakAwareBuffer(buf); + } + + @Override + public boolean isDirectBufferPooled() { + return directArenas != null; + } + + /** + * Returns {@code true} if the calling {@link Thread} has a {@link ThreadLocal} cache for the allocated + * buffers. + */ + @Deprecated + public boolean hasThreadLocalCache() { + return threadCache.isSet(); + } + + /** + * Free all cached buffers for the calling {@link Thread}. + */ + @Deprecated + public void freeThreadLocalCache() { + threadCache.remove(); + } + + final class PoolThreadLocalCache extends FastThreadLocal { + private final AtomicInteger index = new AtomicInteger(); + + @Override + protected PoolThreadCache initialValue() { + final int idx = index.getAndIncrement(); + final PoolArena heapArena; + final PoolArena directArena; + + if (heapArenas != null) { + heapArena = heapArenas[Math.abs(idx % heapArenas.length)]; + } else { + heapArena = null; + } + + if (directArenas != null) { + directArena = directArenas[Math.abs(idx % directArenas.length)]; + } else { + directArena = null; + } + + return new PoolThreadCache( + heapArena, directArena, tinyCacheSize, smallCacheSize, normalCacheSize, + DEFAULT_MAX_CACHED_BUFFER_CAPACITY, DEFAULT_CACHE_TRIM_INTERVAL); + } + + @Override + protected void onRemoval(PoolThreadCache value) { + value.free(); + } + } + +// Too noisy at the moment. +// +// public String toString() { +// StringBuilder buf = new StringBuilder(); +// buf.append(heapArenas.length); +// buf.append(" heap arena(s):"); +// buf.append(StringUtil.NEWLINE); +// for (PoolArena a: heapArenas) { +// buf.append(a); +// } +// buf.append(directArenas.length); +// buf.append(" direct arena(s):"); +// buf.append(StringUtil.NEWLINE); +// for (PoolArena a: directArenas) { +// buf.append(a); +// } +// return buf.toString(); +// } +} diff --git a/common/src/common/net/buffer/PooledDirectByteBuf.java b/common/src/common/net/buffer/PooledDirectByteBuf.java new file mode 100644 index 0000000..74b7e55 --- /dev/null +++ b/common/src/common/net/buffer/PooledDirectByteBuf.java @@ -0,0 +1,377 @@ +/* + * Copyright 2012 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ + +package common.net.buffer; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.nio.ByteBuffer; +import java.nio.channels.ClosedChannelException; +import java.nio.channels.GatheringByteChannel; +import java.nio.channels.ScatteringByteChannel; + +import common.net.util.Recycler; + +final class PooledDirectByteBuf extends PooledByteBuf { + + private static final Recycler RECYCLER = new Recycler() { + @Override + protected PooledDirectByteBuf newObject(Handle handle) { + return new PooledDirectByteBuf(handle, 0); + } + }; + + static PooledDirectByteBuf newInstance(int maxCapacity) { + PooledDirectByteBuf buf = RECYCLER.get(); + buf.setRefCnt(1); + buf.maxCapacity(maxCapacity); + return buf; + } + + private PooledDirectByteBuf(Recycler.Handle recyclerHandle, int maxCapacity) { + super(recyclerHandle, maxCapacity); + } + + @Override + protected ByteBuffer newInternalNioBuffer(ByteBuffer memory) { + return memory.duplicate(); + } + + @Override + public boolean isDirect() { + return true; + } + + @Override + protected byte _getByte(int index) { + return memory.get(idx(index)); + } + + @Override + protected short _getShort(int index) { + return memory.getShort(idx(index)); + } + + @Override + protected int _getUnsignedMedium(int index) { + index = idx(index); + return (memory.get(index) & 0xff) << 16 | (memory.get(index + 1) & 0xff) << 8 | memory.get(index + 2) & 0xff; + } + + @Override + protected int _getInt(int index) { + return memory.getInt(idx(index)); + } + + @Override + protected long _getLong(int index) { + return memory.getLong(idx(index)); + } + + @Override + public ByteBuf getBytes(int index, ByteBuf dst, int dstIndex, int length) { + checkDstIndex(index, length, dstIndex, dst.capacity()); + if (dst.hasArray()) { + getBytes(index, dst.array(), dst.arrayOffset() + dstIndex, length); + } else if (dst.nioBufferCount() > 0) { + for (ByteBuffer bb: dst.nioBuffers(dstIndex, length)) { + int bbLen = bb.remaining(); + getBytes(index, bb); + index += bbLen; + } + } else { + dst.setBytes(dstIndex, this, index, length); + } + return this; + } + + @Override + public ByteBuf getBytes(int index, byte[] dst, int dstIndex, int length) { + getBytes(index, dst, dstIndex, length, false); + return this; + } + + private void getBytes(int index, byte[] dst, int dstIndex, int length, boolean internal) { + checkDstIndex(index, length, dstIndex, dst.length); + ByteBuffer tmpBuf; + if (internal) { + tmpBuf = internalNioBuffer(); + } else { + tmpBuf = memory.duplicate(); + } + index = idx(index); + tmpBuf.clear().position(index).limit(index + length); + tmpBuf.get(dst, dstIndex, length); + } + + @Override + public ByteBuf readBytes(byte[] dst, int dstIndex, int length) { + checkReadableBytes(length); + getBytes(readerIndex, dst, dstIndex, length, true); + readerIndex += length; + return this; + } + + @Override + public ByteBuf getBytes(int index, ByteBuffer dst) { + getBytes(index, dst, false); + return this; + } + + private void getBytes(int index, ByteBuffer dst, boolean internal) { + checkIndex(index); + int bytesToCopy = Math.min(capacity() - index, dst.remaining()); + ByteBuffer tmpBuf; + if (internal) { + tmpBuf = internalNioBuffer(); + } else { + tmpBuf = memory.duplicate(); + } + index = idx(index); + tmpBuf.clear().position(index).limit(index + bytesToCopy); + dst.put(tmpBuf); + } + + @Override + public ByteBuf readBytes(ByteBuffer dst) { + int length = dst.remaining(); + checkReadableBytes(length); + getBytes(readerIndex, dst, true); + readerIndex += length; + return this; + } + + @Override + public ByteBuf getBytes(int index, OutputStream out, int length) throws IOException { + getBytes(index, out, length, false); + return this; + } + + private void getBytes(int index, OutputStream out, int length, boolean internal) throws IOException { + checkIndex(index, length); + if (length == 0) { + return; + } + + byte[] tmp = new byte[length]; + ByteBuffer tmpBuf; + if (internal) { + tmpBuf = internalNioBuffer(); + } else { + tmpBuf = memory.duplicate(); + } + tmpBuf.clear().position(idx(index)); + tmpBuf.get(tmp); + out.write(tmp); + } + + @Override + public ByteBuf readBytes(OutputStream out, int length) throws IOException { + checkReadableBytes(length); + getBytes(readerIndex, out, length, true); + readerIndex += length; + return this; + } + + @Override + public int getBytes(int index, GatheringByteChannel out, int length) throws IOException { + return getBytes(index, out, length, false); + } + + private int getBytes(int index, GatheringByteChannel out, int length, boolean internal) throws IOException { + checkIndex(index, length); + if (length == 0) { + return 0; + } + + ByteBuffer tmpBuf; + if (internal) { + tmpBuf = internalNioBuffer(); + } else { + tmpBuf = memory.duplicate(); + } + index = idx(index); + tmpBuf.clear().position(index).limit(index + length); + return out.write(tmpBuf); + } + + @Override + public int readBytes(GatheringByteChannel out, int length) throws IOException { + checkReadableBytes(length); + int readBytes = getBytes(readerIndex, out, length, true); + readerIndex += readBytes; + return readBytes; + } + + @Override + protected void _setByte(int index, int value) { + memory.put(idx(index), (byte) value); + } + + @Override + protected void _setShort(int index, int value) { + memory.putShort(idx(index), (short) value); + } + + @Override + protected void _setMedium(int index, int value) { + index = idx(index); + memory.put(index, (byte) (value >>> 16)); + memory.put(index + 1, (byte) (value >>> 8)); + memory.put(index + 2, (byte) value); + } + + @Override + protected void _setInt(int index, int value) { + memory.putInt(idx(index), value); + } + + @Override + protected void _setLong(int index, long value) { + memory.putLong(idx(index), value); + } + + @Override + public ByteBuf setBytes(int index, ByteBuf src, int srcIndex, int length) { + checkSrcIndex(index, length, srcIndex, src.capacity()); + if (src.hasArray()) { + setBytes(index, src.array(), src.arrayOffset() + srcIndex, length); + } else if (src.nioBufferCount() > 0) { + for (ByteBuffer bb: src.nioBuffers(srcIndex, length)) { + int bbLen = bb.remaining(); + setBytes(index, bb); + index += bbLen; + } + } else { + src.getBytes(srcIndex, this, index, length); + } + return this; + } + + @Override + public ByteBuf setBytes(int index, byte[] src, int srcIndex, int length) { + checkSrcIndex(index, length, srcIndex, src.length); + ByteBuffer tmpBuf = internalNioBuffer(); + index = idx(index); + tmpBuf.clear().position(index).limit(index + length); + tmpBuf.put(src, srcIndex, length); + return this; + } + + @Override + public ByteBuf setBytes(int index, ByteBuffer src) { + checkIndex(index, src.remaining()); + ByteBuffer tmpBuf = internalNioBuffer(); + if (src == tmpBuf) { + src = src.duplicate(); + } + + index = idx(index); + tmpBuf.clear().position(index).limit(index + src.remaining()); + tmpBuf.put(src); + return this; + } + + @Override + public int setBytes(int index, InputStream in, int length) throws IOException { + checkIndex(index, length); + byte[] tmp = new byte[length]; + int readBytes = in.read(tmp); + if (readBytes <= 0) { + return readBytes; + } + ByteBuffer tmpBuf = internalNioBuffer(); + tmpBuf.clear().position(idx(index)); + tmpBuf.put(tmp, 0, readBytes); + return readBytes; + } + + @Override + public int setBytes(int index, ScatteringByteChannel in, int length) throws IOException { + checkIndex(index, length); + ByteBuffer tmpBuf = internalNioBuffer(); + index = idx(index); + tmpBuf.clear().position(index).limit(index + length); + try { + return in.read(tmpBuf); + } catch (ClosedChannelException ignored) { + return -1; + } + } + + @Override + public ByteBuf copy(int index, int length) { + checkIndex(index, length); + ByteBuf copy = alloc().directBuffer(length, maxCapacity()); + copy.writeBytes(this, index, length); + return copy; + } + + @Override + public int nioBufferCount() { + return 1; + } + + @Override + public ByteBuffer nioBuffer(int index, int length) { + checkIndex(index, length); + index = idx(index); + return ((ByteBuffer) memory.duplicate().position(index).limit(index + length)).slice(); + } + + @Override + public ByteBuffer[] nioBuffers(int index, int length) { + return new ByteBuffer[] { nioBuffer(index, length) }; + } + + @Override + public ByteBuffer internalNioBuffer(int index, int length) { + checkIndex(index, length); + index = idx(index); + return (ByteBuffer) internalNioBuffer().clear().position(index).limit(index + length); + } + + @Override + public boolean hasArray() { + return false; + } + + @Override + public byte[] array() { + throw new UnsupportedOperationException("direct buffer"); + } + + @Override + public int arrayOffset() { + throw new UnsupportedOperationException("direct buffer"); + } + + @Override + public boolean hasMemoryAddress() { + return false; + } + + @Override + public long memoryAddress() { + throw new UnsupportedOperationException(); + } + + @Override + protected Recycler recycler() { + return RECYCLER; + } +} diff --git a/common/src/common/net/buffer/PooledHeapByteBuf.java b/common/src/common/net/buffer/PooledHeapByteBuf.java new file mode 100644 index 0000000..33e0ec6 --- /dev/null +++ b/common/src/common/net/buffer/PooledHeapByteBuf.java @@ -0,0 +1,307 @@ +/* + * Copyright 2012 The Netty Project + * + * The Netty Project licenses this file tothe License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ + +package common.net.buffer; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.nio.ByteBuffer; +import java.nio.channels.ClosedChannelException; +import java.nio.channels.GatheringByteChannel; +import java.nio.channels.ScatteringByteChannel; + +import common.net.util.Recycler; +import common.net.util.internal.PlatformDependent; + +final class PooledHeapByteBuf extends PooledByteBuf { + + private static final Recycler RECYCLER = new Recycler() { + @Override + protected PooledHeapByteBuf newObject(Handle handle) { + return new PooledHeapByteBuf(handle, 0); + } + }; + + static PooledHeapByteBuf newInstance(int maxCapacity) { + PooledHeapByteBuf buf = RECYCLER.get(); + buf.setRefCnt(1); + buf.maxCapacity(maxCapacity); + return buf; + } + + private PooledHeapByteBuf(Recycler.Handle recyclerHandle, int maxCapacity) { + super(recyclerHandle, maxCapacity); + } + + @Override + public boolean isDirect() { + return false; + } + + @Override + protected byte _getByte(int index) { + return memory[idx(index)]; + } + + @Override + protected short _getShort(int index) { + index = idx(index); + return (short) (memory[index] << 8 | memory[index + 1] & 0xFF); + } + + @Override + protected int _getUnsignedMedium(int index) { + index = idx(index); + return (memory[index] & 0xff) << 16 | + (memory[index + 1] & 0xff) << 8 | + memory[index + 2] & 0xff; + } + + @Override + protected int _getInt(int index) { + index = idx(index); + return (memory[index] & 0xff) << 24 | + (memory[index + 1] & 0xff) << 16 | + (memory[index + 2] & 0xff) << 8 | + memory[index + 3] & 0xff; + } + + @Override + protected long _getLong(int index) { + index = idx(index); + return ((long) memory[index] & 0xff) << 56 | + ((long) memory[index + 1] & 0xff) << 48 | + ((long) memory[index + 2] & 0xff) << 40 | + ((long) memory[index + 3] & 0xff) << 32 | + ((long) memory[index + 4] & 0xff) << 24 | + ((long) memory[index + 5] & 0xff) << 16 | + ((long) memory[index + 6] & 0xff) << 8 | + (long) memory[index + 7] & 0xff; + } + + @Override + public ByteBuf getBytes(int index, ByteBuf dst, int dstIndex, int length) { + checkDstIndex(index, length, dstIndex, dst.capacity()); + if (dst.hasMemoryAddress()) { + PlatformDependent.copyMemory(memory, idx(index), dst.memoryAddress() + dstIndex, length); + } else if (dst.hasArray()) { + getBytes(index, dst.array(), dst.arrayOffset() + dstIndex, length); + } else { + dst.setBytes(dstIndex, memory, idx(index), length); + } + return this; + } + + @Override + public ByteBuf getBytes(int index, byte[] dst, int dstIndex, int length) { + checkDstIndex(index, length, dstIndex, dst.length); + System.arraycopy(memory, idx(index), dst, dstIndex, length); + return this; + } + + @Override + public ByteBuf getBytes(int index, ByteBuffer dst) { + checkIndex(index); + dst.put(memory, idx(index), Math.min(capacity() - index, dst.remaining())); + return this; + } + + @Override + public ByteBuf getBytes(int index, OutputStream out, int length) throws IOException { + checkIndex(index, length); + out.write(memory, idx(index), length); + return this; + } + + @Override + public int getBytes(int index, GatheringByteChannel out, int length) throws IOException { + return getBytes(index, out, length, false); + } + + private int getBytes(int index, GatheringByteChannel out, int length, boolean internal) throws IOException { + checkIndex(index, length); + index = idx(index); + ByteBuffer tmpBuf; + if (internal) { + tmpBuf = internalNioBuffer(); + } else { + tmpBuf = ByteBuffer.wrap(memory); + } + return out.write((ByteBuffer) tmpBuf.clear().position(index).limit(index + length)); + } + + @Override + public int readBytes(GatheringByteChannel out, int length) throws IOException { + checkReadableBytes(length); + int readBytes = getBytes(readerIndex, out, length, true); + readerIndex += readBytes; + return readBytes; + } + + @Override + protected void _setByte(int index, int value) { + memory[idx(index)] = (byte) value; + } + + @Override + protected void _setShort(int index, int value) { + index = idx(index); + memory[index] = (byte) (value >>> 8); + memory[index + 1] = (byte) value; + } + + @Override + protected void _setMedium(int index, int value) { + index = idx(index); + memory[index] = (byte) (value >>> 16); + memory[index + 1] = (byte) (value >>> 8); + memory[index + 2] = (byte) value; + } + + @Override + protected void _setInt(int index, int value) { + index = idx(index); + memory[index] = (byte) (value >>> 24); + memory[index + 1] = (byte) (value >>> 16); + memory[index + 2] = (byte) (value >>> 8); + memory[index + 3] = (byte) value; + } + + @Override + protected void _setLong(int index, long value) { + index = idx(index); + memory[index] = (byte) (value >>> 56); + memory[index + 1] = (byte) (value >>> 48); + memory[index + 2] = (byte) (value >>> 40); + memory[index + 3] = (byte) (value >>> 32); + memory[index + 4] = (byte) (value >>> 24); + memory[index + 5] = (byte) (value >>> 16); + memory[index + 6] = (byte) (value >>> 8); + memory[index + 7] = (byte) value; + } + + @Override + public ByteBuf setBytes(int index, ByteBuf src, int srcIndex, int length) { + checkSrcIndex(index, length, srcIndex, src.capacity()); + if (src.hasMemoryAddress()) { + PlatformDependent.copyMemory(src.memoryAddress() + srcIndex, memory, idx(index), length); + } else if (src.hasArray()) { + setBytes(index, src.array(), src.arrayOffset() + srcIndex, length); + } else { + src.getBytes(srcIndex, memory, idx(index), length); + } + return this; + } + + @Override + public ByteBuf setBytes(int index, byte[] src, int srcIndex, int length) { + checkSrcIndex(index, length, srcIndex, src.length); + System.arraycopy(src, srcIndex, memory, idx(index), length); + return this; + } + + @Override + public ByteBuf setBytes(int index, ByteBuffer src) { + int length = src.remaining(); + checkIndex(index, length); + src.get(memory, idx(index), length); + return this; + } + + @Override + public int setBytes(int index, InputStream in, int length) throws IOException { + checkIndex(index, length); + return in.read(memory, idx(index), length); + } + + @Override + public int setBytes(int index, ScatteringByteChannel in, int length) throws IOException { + checkIndex(index, length); + index = idx(index); + try { + return in.read((ByteBuffer) internalNioBuffer().clear().position(index).limit(index + length)); + } catch (ClosedChannelException ignored) { + return -1; + } + } + + @Override + public ByteBuf copy(int index, int length) { + checkIndex(index, length); + ByteBuf copy = alloc().heapBuffer(length, maxCapacity()); + copy.writeBytes(memory, idx(index), length); + return copy; + } + + @Override + public int nioBufferCount() { + return 1; + } + + @Override + public ByteBuffer[] nioBuffers(int index, int length) { + return new ByteBuffer[] { nioBuffer(index, length) }; + } + + @Override + public ByteBuffer nioBuffer(int index, int length) { + checkIndex(index, length); + index = idx(index); + ByteBuffer buf = ByteBuffer.wrap(memory, index, length); + return buf.slice(); + } + + @Override + public ByteBuffer internalNioBuffer(int index, int length) { + checkIndex(index, length); + index = idx(index); + return (ByteBuffer) internalNioBuffer().clear().position(index).limit(index + length); + } + + @Override + public boolean hasArray() { + return true; + } + + @Override + public byte[] array() { + return memory; + } + + @Override + public int arrayOffset() { + return offset; + } + + @Override + public boolean hasMemoryAddress() { + return false; + } + + @Override + public long memoryAddress() { + throw new UnsupportedOperationException(); + } + + @Override + protected ByteBuffer newInternalNioBuffer(byte[] memory) { + return ByteBuffer.wrap(memory); + } + + @Override + protected Recycler recycler() { + return RECYCLER; + } +} diff --git a/common/src/common/net/buffer/PooledUnsafeDirectByteBuf.java b/common/src/common/net/buffer/PooledUnsafeDirectByteBuf.java new file mode 100644 index 0000000..e28103f --- /dev/null +++ b/common/src/common/net/buffer/PooledUnsafeDirectByteBuf.java @@ -0,0 +1,394 @@ +/* + * Copyright 2013 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ + +package common.net.buffer; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.nio.ByteBuffer; +import java.nio.ByteOrder; +import java.nio.channels.ClosedChannelException; +import java.nio.channels.GatheringByteChannel; +import java.nio.channels.ScatteringByteChannel; + +import common.net.util.Recycler; +import common.net.util.internal.PlatformDependent; + +final class PooledUnsafeDirectByteBuf extends PooledByteBuf { + + private static final boolean NATIVE_ORDER = ByteOrder.nativeOrder() == ByteOrder.BIG_ENDIAN; + + private static final Recycler RECYCLER = new Recycler() { + @Override + protected PooledUnsafeDirectByteBuf newObject(Handle handle) { + return new PooledUnsafeDirectByteBuf(handle, 0); + } + }; + + static PooledUnsafeDirectByteBuf newInstance(int maxCapacity) { + PooledUnsafeDirectByteBuf buf = RECYCLER.get(); + buf.setRefCnt(1); + buf.maxCapacity(maxCapacity); + return buf; + } + + private long memoryAddress; + + private PooledUnsafeDirectByteBuf(Recycler.Handle recyclerHandle, int maxCapacity) { + super(recyclerHandle, maxCapacity); + } + + @Override + void init(PoolChunk chunk, long handle, int offset, int length, int maxLength) { + super.init(chunk, handle, offset, length, maxLength); + initMemoryAddress(); + } + + @Override + void initUnpooled(PoolChunk chunk, int length) { + super.initUnpooled(chunk, length); + initMemoryAddress(); + } + + private void initMemoryAddress() { + memoryAddress = PlatformDependent.directBufferAddress(memory) + offset; + } + + @Override + protected ByteBuffer newInternalNioBuffer(ByteBuffer memory) { + return memory.duplicate(); + } + + @Override + public boolean isDirect() { + return true; + } + + @Override + protected byte _getByte(int index) { + return PlatformDependent.getByte(addr(index)); + } + + @Override + protected short _getShort(int index) { + short v = PlatformDependent.getShort(addr(index)); + return NATIVE_ORDER? v : Short.reverseBytes(v); + } + + @Override + protected int _getUnsignedMedium(int index) { + long addr = addr(index); + return (PlatformDependent.getByte(addr) & 0xff) << 16 | + (PlatformDependent.getByte(addr + 1) & 0xff) << 8 | + PlatformDependent.getByte(addr + 2) & 0xff; + } + + @Override + protected int _getInt(int index) { + int v = PlatformDependent.getInt(addr(index)); + return NATIVE_ORDER? v : Integer.reverseBytes(v); + } + + @Override + protected long _getLong(int index) { + long v = PlatformDependent.getLong(addr(index)); + return NATIVE_ORDER? v : Long.reverseBytes(v); + } + + @Override + public ByteBuf getBytes(int index, ByteBuf dst, int dstIndex, int length) { + checkIndex(index, length); + if (dst == null) { + throw new NullPointerException("dst"); + } + if (dstIndex < 0 || dstIndex > dst.capacity() - length) { + throw new IndexOutOfBoundsException("dstIndex: " + dstIndex); + } + + if (length != 0) { + if (dst.hasMemoryAddress()) { + PlatformDependent.copyMemory(addr(index), dst.memoryAddress() + dstIndex, length); + } else if (dst.hasArray()) { + PlatformDependent.copyMemory(addr(index), dst.array(), dst.arrayOffset() + dstIndex, length); + } else { + dst.setBytes(dstIndex, this, index, length); + } + } + return this; + } + + @Override + public ByteBuf getBytes(int index, byte[] dst, int dstIndex, int length) { + checkIndex(index, length); + if (dst == null) { + throw new NullPointerException("dst"); + } + if (dstIndex < 0 || dstIndex > dst.length - length) { + throw new IndexOutOfBoundsException("dstIndex: " + dstIndex); + } + if (length != 0) { + PlatformDependent.copyMemory(addr(index), dst, dstIndex, length); + } + return this; + } + + @Override + public ByteBuf getBytes(int index, ByteBuffer dst) { + getBytes(index, dst, false); + return this; + } + + private void getBytes(int index, ByteBuffer dst, boolean internal) { + checkIndex(index); + int bytesToCopy = Math.min(capacity() - index, dst.remaining()); + ByteBuffer tmpBuf; + if (internal) { + tmpBuf = internalNioBuffer(); + } else { + tmpBuf = memory.duplicate(); + } + index = idx(index); + tmpBuf.clear().position(index).limit(index + bytesToCopy); + dst.put(tmpBuf); + } + + @Override + public ByteBuf readBytes(ByteBuffer dst) { + int length = dst.remaining(); + checkReadableBytes(length); + getBytes(readerIndex, dst, true); + readerIndex += length; + return this; + } + + @Override + public ByteBuf getBytes(int index, OutputStream out, int length) throws IOException { + checkIndex(index, length); + if (length != 0) { + byte[] tmp = new byte[length]; + PlatformDependent.copyMemory(addr(index), tmp, 0, length); + out.write(tmp); + } + return this; + } + + @Override + public int getBytes(int index, GatheringByteChannel out, int length) throws IOException { + return getBytes(index, out, length, false); + } + + private int getBytes(int index, GatheringByteChannel out, int length, boolean internal) throws IOException { + checkIndex(index, length); + if (length == 0) { + return 0; + } + + ByteBuffer tmpBuf; + if (internal) { + tmpBuf = internalNioBuffer(); + } else { + tmpBuf = memory.duplicate(); + } + index = idx(index); + tmpBuf.clear().position(index).limit(index + length); + return out.write(tmpBuf); + } + + @Override + public int readBytes(GatheringByteChannel out, int length) + throws IOException { + checkReadableBytes(length); + int readBytes = getBytes(readerIndex, out, length, true); + readerIndex += readBytes; + return readBytes; + } + + @Override + protected void _setByte(int index, int value) { + PlatformDependent.putByte(addr(index), (byte) value); + } + + @Override + protected void _setShort(int index, int value) { + PlatformDependent.putShort(addr(index), NATIVE_ORDER ? (short) value : Short.reverseBytes((short) value)); + } + + @Override + protected void _setMedium(int index, int value) { + long addr = addr(index); + PlatformDependent.putByte(addr, (byte) (value >>> 16)); + PlatformDependent.putByte(addr + 1, (byte) (value >>> 8)); + PlatformDependent.putByte(addr + 2, (byte) value); + } + + @Override + protected void _setInt(int index, int value) { + PlatformDependent.putInt(addr(index), NATIVE_ORDER ? value : Integer.reverseBytes(value)); + } + + @Override + protected void _setLong(int index, long value) { + PlatformDependent.putLong(addr(index), NATIVE_ORDER ? value : Long.reverseBytes(value)); + } + + @Override + public ByteBuf setBytes(int index, ByteBuf src, int srcIndex, int length) { + checkIndex(index, length); + if (src == null) { + throw new NullPointerException("src"); + } + if (srcIndex < 0 || srcIndex > src.capacity() - length) { + throw new IndexOutOfBoundsException("srcIndex: " + srcIndex); + } + + if (length != 0) { + if (src.hasMemoryAddress()) { + PlatformDependent.copyMemory(src.memoryAddress() + srcIndex, addr(index), length); + } else if (src.hasArray()) { + PlatformDependent.copyMemory(src.array(), src.arrayOffset() + srcIndex, addr(index), length); + } else { + src.getBytes(srcIndex, this, index, length); + } + } + return this; + } + + @Override + public ByteBuf setBytes(int index, byte[] src, int srcIndex, int length) { + checkIndex(index, length); + if (length != 0) { + PlatformDependent.copyMemory(src, srcIndex, addr(index), length); + } + return this; + } + + @Override + public ByteBuf setBytes(int index, ByteBuffer src) { + checkIndex(index, src.remaining()); + ByteBuffer tmpBuf = internalNioBuffer(); + if (src == tmpBuf) { + src = src.duplicate(); + } + + index = idx(index); + tmpBuf.clear().position(index).limit(index + src.remaining()); + tmpBuf.put(src); + return this; + } + + @Override + public int setBytes(int index, InputStream in, int length) throws IOException { + checkIndex(index, length); + byte[] tmp = new byte[length]; + int readBytes = in.read(tmp); + if (readBytes > 0) { + PlatformDependent.copyMemory(tmp, 0, addr(index), readBytes); + } + return readBytes; + } + + @Override + public int setBytes(int index, ScatteringByteChannel in, int length) throws IOException { + checkIndex(index, length); + ByteBuffer tmpBuf = internalNioBuffer(); + index = idx(index); + tmpBuf.clear().position(index).limit(index + length); + try { + return in.read(tmpBuf); + } catch (ClosedChannelException ignored) { + return -1; + } + } + + @Override + public ByteBuf copy(int index, int length) { + checkIndex(index, length); + ByteBuf copy = alloc().directBuffer(length, maxCapacity()); + if (length != 0) { + if (copy.hasMemoryAddress()) { + PlatformDependent.copyMemory(addr(index), copy.memoryAddress(), length); + copy.setIndex(0, length); + } else { + copy.writeBytes(this, index, length); + } + } + return copy; + } + + @Override + public int nioBufferCount() { + return 1; + } + + @Override + public ByteBuffer[] nioBuffers(int index, int length) { + return new ByteBuffer[] { nioBuffer(index, length) }; + } + + @Override + public ByteBuffer nioBuffer(int index, int length) { + checkIndex(index, length); + index = idx(index); + return ((ByteBuffer) memory.duplicate().position(index).limit(index + length)).slice(); + } + + @Override + public ByteBuffer internalNioBuffer(int index, int length) { + checkIndex(index, length); + index = idx(index); + return (ByteBuffer) internalNioBuffer().clear().position(index).limit(index + length); + } + + @Override + public boolean hasArray() { + return false; + } + + @Override + public byte[] array() { + throw new UnsupportedOperationException("direct buffer"); + } + + @Override + public int arrayOffset() { + throw new UnsupportedOperationException("direct buffer"); + } + + @Override + public boolean hasMemoryAddress() { + return true; + } + + @Override + public long memoryAddress() { + return memoryAddress; + } + + private long addr(int index) { + return memoryAddress + index; + } + + @Override + protected Recycler recycler() { + return RECYCLER; + } + + @Override + protected SwappedByteBuf newSwappedByteBuf() { + return new UnsafeDirectSwappedByteBuf(this); + } +} diff --git a/common/src/common/net/buffer/ReadOnlyByteBuf.java b/common/src/common/net/buffer/ReadOnlyByteBuf.java new file mode 100644 index 0000000..17a80ac --- /dev/null +++ b/common/src/common/net/buffer/ReadOnlyByteBuf.java @@ -0,0 +1,317 @@ +/* + * Copyright 2012 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ +package common.net.buffer; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.nio.ByteBuffer; +import java.nio.ByteOrder; +import java.nio.ReadOnlyBufferException; +import java.nio.channels.GatheringByteChannel; +import java.nio.channels.ScatteringByteChannel; + +/** + * A derived buffer which forbids any write requests to its parent. It is + * recommended to use {@link Unpooled#unmodifiableBuffer(ByteBuf)} + * instead of calling the constructor explicitly. + */ +public class ReadOnlyByteBuf extends AbstractDerivedByteBuf { + + private final ByteBuf buffer; + + public ReadOnlyByteBuf(ByteBuf buffer) { + super(buffer.maxCapacity()); + + if (buffer instanceof ReadOnlyByteBuf || buffer instanceof DuplicatedByteBuf) { + this.buffer = buffer.unwrap(); + } else { + this.buffer = buffer; + } + setIndex(buffer.readerIndex(), buffer.writerIndex()); + } + + @Override + public boolean isWritable() { + return false; + } + + @Override + public boolean isWritable(int numBytes) { + return false; + } + + @Override + public ByteBuf unwrap() { + return buffer; + } + + @Override + public ByteBufAllocator alloc() { + return buffer.alloc(); + } + + @Override + public ByteOrder order() { + return buffer.order(); + } + + @Override + public boolean isDirect() { + return buffer.isDirect(); + } + + @Override + public boolean hasArray() { + return false; + } + + @Override + public byte[] array() { + throw new ReadOnlyBufferException(); + } + + @Override + public int arrayOffset() { + throw new ReadOnlyBufferException(); + } + + @Override + public boolean hasMemoryAddress() { + return false; + } + + @Override + public long memoryAddress() { + throw new ReadOnlyBufferException(); + } + + @Override + public ByteBuf discardReadBytes() { + throw new ReadOnlyBufferException(); + } + + @Override + public ByteBuf setBytes(int index, ByteBuf src, int srcIndex, int length) { + throw new ReadOnlyBufferException(); + } + + @Override + public ByteBuf setBytes(int index, byte[] src, int srcIndex, int length) { + throw new ReadOnlyBufferException(); + } + + @Override + public ByteBuf setBytes(int index, ByteBuffer src) { + throw new ReadOnlyBufferException(); + } + + @Override + public ByteBuf setByte(int index, int value) { + throw new ReadOnlyBufferException(); + } + + @Override + protected void _setByte(int index, int value) { + throw new ReadOnlyBufferException(); + } + + @Override + public ByteBuf setShort(int index, int value) { + throw new ReadOnlyBufferException(); + } + + @Override + protected void _setShort(int index, int value) { + throw new ReadOnlyBufferException(); + } + + @Override + public ByteBuf setMedium(int index, int value) { + throw new ReadOnlyBufferException(); + } + + @Override + protected void _setMedium(int index, int value) { + throw new ReadOnlyBufferException(); + } + + @Override + public ByteBuf setInt(int index, int value) { + throw new ReadOnlyBufferException(); + } + + @Override + protected void _setInt(int index, int value) { + throw new ReadOnlyBufferException(); + } + + @Override + public ByteBuf setLong(int index, long value) { + throw new ReadOnlyBufferException(); + } + + @Override + protected void _setLong(int index, long value) { + throw new ReadOnlyBufferException(); + } + + @Override + public int setBytes(int index, InputStream in, int length) { + throw new ReadOnlyBufferException(); + } + + @Override + public int setBytes(int index, ScatteringByteChannel in, int length) { + throw new ReadOnlyBufferException(); + } + + @Override + public int getBytes(int index, GatheringByteChannel out, int length) + throws IOException { + return buffer.getBytes(index, out, length); + } + + @Override + public ByteBuf getBytes(int index, OutputStream out, int length) + throws IOException { + buffer.getBytes(index, out, length); + return this; + } + + @Override + public ByteBuf getBytes(int index, byte[] dst, int dstIndex, int length) { + buffer.getBytes(index, dst, dstIndex, length); + return this; + } + + @Override + public ByteBuf getBytes(int index, ByteBuf dst, int dstIndex, int length) { + buffer.getBytes(index, dst, dstIndex, length); + return this; + } + + @Override + public ByteBuf getBytes(int index, ByteBuffer dst) { + buffer.getBytes(index, dst); + return this; + } + + @Override + public ByteBuf duplicate() { + return new ReadOnlyByteBuf(this); + } + + @Override + public ByteBuf copy(int index, int length) { + return buffer.copy(index, length); + } + + @Override + public ByteBuf slice(int index, int length) { + return Unpooled.unmodifiableBuffer(buffer.slice(index, length)); + } + + @Override + public byte getByte(int index) { + return _getByte(index); + } + + @Override + protected byte _getByte(int index) { + return buffer.getByte(index); + } + + @Override + public short getShort(int index) { + return _getShort(index); + } + + @Override + protected short _getShort(int index) { + return buffer.getShort(index); + } + + @Override + public int getUnsignedMedium(int index) { + return _getUnsignedMedium(index); + } + + @Override + protected int _getUnsignedMedium(int index) { + return buffer.getUnsignedMedium(index); + } + + @Override + public int getInt(int index) { + return _getInt(index); + } + + @Override + protected int _getInt(int index) { + return buffer.getInt(index); + } + + @Override + public long getLong(int index) { + return _getLong(index); + } + + @Override + protected long _getLong(int index) { + return buffer.getLong(index); + } + + @Override + public int nioBufferCount() { + return buffer.nioBufferCount(); + } + + @Override + public ByteBuffer nioBuffer(int index, int length) { + return buffer.nioBuffer(index, length).asReadOnlyBuffer(); + } + + @Override + public ByteBuffer[] nioBuffers(int index, int length) { + return buffer.nioBuffers(index, length); + } + + @Override + public ByteBuffer internalNioBuffer(int index, int length) { + return nioBuffer(index, length); + } + + @Override + public int forEachByte(int index, int length, ByteBufProcessor processor) { + return buffer.forEachByte(index, length, processor); + } + + @Override + public int forEachByteDesc(int index, int length, ByteBufProcessor processor) { + return buffer.forEachByteDesc(index, length, processor); + } + + @Override + public int capacity() { + return buffer.capacity(); + } + + @Override + public ByteBuf capacity(int newCapacity) { + throw new ReadOnlyBufferException(); + } +} diff --git a/common/src/common/net/buffer/ReadOnlyByteBufferBuf.java b/common/src/common/net/buffer/ReadOnlyByteBufferBuf.java new file mode 100644 index 0000000..4d158b7 --- /dev/null +++ b/common/src/common/net/buffer/ReadOnlyByteBufferBuf.java @@ -0,0 +1,335 @@ +/* + * Copyright 2013 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ +package common.net.buffer; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.nio.ByteBuffer; +import java.nio.ByteOrder; +import java.nio.ReadOnlyBufferException; +import java.nio.channels.GatheringByteChannel; +import java.nio.channels.ScatteringByteChannel; + +import common.net.util.internal.StringUtil; + + +/** + * Read-only ByteBuf which wraps a read-only ByteBuffer. + */ +class ReadOnlyByteBufferBuf extends AbstractReferenceCountedByteBuf { + + protected final ByteBuffer buffer; + private final ByteBufAllocator allocator; + private ByteBuffer tmpNioBuf; + + ReadOnlyByteBufferBuf(ByteBufAllocator allocator, ByteBuffer buffer) { + super(buffer.remaining()); + if (!buffer.isReadOnly()) { + throw new IllegalArgumentException("must be a readonly buffer: " + StringUtil.simpleClassName(buffer)); + } + + this.allocator = allocator; + this.buffer = buffer.slice().order(ByteOrder.BIG_ENDIAN); + writerIndex(this.buffer.limit()); + } + + @Override + protected void deallocate() { } + + @Override + public byte getByte(int index) { + ensureAccessible(); + return _getByte(index); + } + + @Override + protected byte _getByte(int index) { + return buffer.get(index); + } + + @Override + public short getShort(int index) { + ensureAccessible(); + return _getShort(index); + } + + @Override + protected short _getShort(int index) { + return buffer.getShort(index); + } + + @Override + public int getUnsignedMedium(int index) { + ensureAccessible(); + return _getUnsignedMedium(index); + } + + @Override + protected int _getUnsignedMedium(int index) { + return (getByte(index) & 0xff) << 16 | (getByte(index + 1) & 0xff) << 8 | getByte(index + 2) & 0xff; + } + + @Override + public int getInt(int index) { + ensureAccessible(); + return _getInt(index); + } + + @Override + protected int _getInt(int index) { + return buffer.getInt(index); + } + + @Override + public long getLong(int index) { + ensureAccessible(); + return _getLong(index); + } + + @Override + protected long _getLong(int index) { + return buffer.getLong(index); + } + + @Override + public ByteBuf getBytes(int index, ByteBuf dst, int dstIndex, int length) { + checkDstIndex(index, length, dstIndex, dst.capacity()); + if (dst.hasArray()) { + getBytes(index, dst.array(), dst.arrayOffset() + dstIndex, length); + } else if (dst.nioBufferCount() > 0) { + for (ByteBuffer bb: dst.nioBuffers(dstIndex, length)) { + int bbLen = bb.remaining(); + getBytes(index, bb); + index += bbLen; + } + } else { + dst.setBytes(dstIndex, this, index, length); + } + return this; + } + + @Override + public ByteBuf getBytes(int index, byte[] dst, int dstIndex, int length) { + checkDstIndex(index, length, dstIndex, dst.length); + + if (dstIndex < 0 || dstIndex > dst.length - length) { + throw new IndexOutOfBoundsException(String.format( + "dstIndex: %d, length: %d (expected: range(0, %d))", dstIndex, length, dst.length)); + } + + ByteBuffer tmpBuf = internalNioBuffer(); + tmpBuf.clear().position(index).limit(index + length); + tmpBuf.get(dst, dstIndex, length); + return this; + } + + @Override + public ByteBuf getBytes(int index, ByteBuffer dst) { + checkIndex(index); + if (dst == null) { + throw new NullPointerException("dst"); + } + + int bytesToCopy = Math.min(capacity() - index, dst.remaining()); + ByteBuffer tmpBuf = internalNioBuffer(); + tmpBuf.clear().position(index).limit(index + bytesToCopy); + dst.put(tmpBuf); + return this; + } + + @Override + protected void _setByte(int index, int value) { + throw new ReadOnlyBufferException(); + } + + @Override + protected void _setShort(int index, int value) { + throw new ReadOnlyBufferException(); + } + + @Override + protected void _setMedium(int index, int value) { + throw new ReadOnlyBufferException(); + } + + @Override + protected void _setInt(int index, int value) { + throw new ReadOnlyBufferException(); + } + + @Override + protected void _setLong(int index, long value) { + throw new ReadOnlyBufferException(); + } + + @Override + public int capacity() { + return maxCapacity(); + } + + @Override + public ByteBuf capacity(int newCapacity) { + throw new ReadOnlyBufferException(); + } + + @Override + public ByteBufAllocator alloc() { + return allocator; + } + + @Override + public ByteOrder order() { + return ByteOrder.BIG_ENDIAN; + } + + @Override + public ByteBuf unwrap() { + return null; + } + + @Override + public boolean isDirect() { + return buffer.isDirect(); + } + + @Override + public ByteBuf getBytes(int index, OutputStream out, int length) throws IOException { + ensureAccessible(); + if (length == 0) { + return this; + } + + if (buffer.hasArray()) { + out.write(buffer.array(), index + buffer.arrayOffset(), length); + } else { + byte[] tmp = new byte[length]; + ByteBuffer tmpBuf = internalNioBuffer(); + tmpBuf.clear().position(index); + tmpBuf.get(tmp); + out.write(tmp); + } + return this; + } + + @Override + public int getBytes(int index, GatheringByteChannel out, int length) throws IOException { + ensureAccessible(); + if (length == 0) { + return 0; + } + + ByteBuffer tmpBuf = internalNioBuffer(); + tmpBuf.clear().position(index).limit(index + length); + return out.write(tmpBuf); + } + + @Override + public ByteBuf setBytes(int index, ByteBuf src, int srcIndex, int length) { + throw new ReadOnlyBufferException(); + } + + @Override + public ByteBuf setBytes(int index, byte[] src, int srcIndex, int length) { + throw new ReadOnlyBufferException(); + } + + @Override + public ByteBuf setBytes(int index, ByteBuffer src) { + throw new ReadOnlyBufferException(); + } + + @Override + public int setBytes(int index, InputStream in, int length) throws IOException { + throw new ReadOnlyBufferException(); + } + + @Override + public int setBytes(int index, ScatteringByteChannel in, int length) throws IOException { + throw new ReadOnlyBufferException(); + } + + protected final ByteBuffer internalNioBuffer() { + ByteBuffer tmpNioBuf = this.tmpNioBuf; + if (tmpNioBuf == null) { + this.tmpNioBuf = tmpNioBuf = buffer.duplicate(); + } + return tmpNioBuf; + } + + @Override + public ByteBuf copy(int index, int length) { + ensureAccessible(); + ByteBuffer src; + try { + src = (ByteBuffer) internalNioBuffer().clear().position(index).limit(index + length); + } catch (IllegalArgumentException ignored) { + throw new IndexOutOfBoundsException("Too many bytes to read - Need " + (index + length)); + } + + ByteBuffer dst = ByteBuffer.allocateDirect(length); + dst.put(src); + dst.order(order()); + dst.clear(); + return new UnpooledDirectByteBuf(alloc(), dst, maxCapacity()); + } + + @Override + public int nioBufferCount() { + return 1; + } + + @Override + public ByteBuffer[] nioBuffers(int index, int length) { + return new ByteBuffer[] { nioBuffer(index, length) }; + } + + @Override + public ByteBuffer nioBuffer(int index, int length) { + return (ByteBuffer) buffer.duplicate().position(index).limit(index + length); + } + + @Override + public ByteBuffer internalNioBuffer(int index, int length) { + ensureAccessible(); + return (ByteBuffer) internalNioBuffer().clear().position(index).limit(index + length); + } + + @Override + public boolean hasArray() { + return buffer.hasArray(); + } + + @Override + public byte[] array() { + return buffer.array(); + } + + @Override + public int arrayOffset() { + return buffer.arrayOffset(); + } + + @Override + public boolean hasMemoryAddress() { + return false; + } + + @Override + public long memoryAddress() { + throw new UnsupportedOperationException(); + } +} diff --git a/common/src/common/net/buffer/ReadOnlyUnsafeDirectByteBuf.java b/common/src/common/net/buffer/ReadOnlyUnsafeDirectByteBuf.java new file mode 100644 index 0000000..6b8981c --- /dev/null +++ b/common/src/common/net/buffer/ReadOnlyUnsafeDirectByteBuf.java @@ -0,0 +1,138 @@ +/* + * Copyright 2013 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ +package common.net.buffer; + + +import java.nio.ByteBuffer; +import java.nio.ByteOrder; + +import common.net.util.internal.PlatformDependent; + + + +/** + * Read-only ByteBuf which wraps a read-only direct ByteBuffer and use unsafe for best performance. + */ +final class ReadOnlyUnsafeDirectByteBuf extends ReadOnlyByteBufferBuf { + private static final boolean NATIVE_ORDER = ByteOrder.nativeOrder() == ByteOrder.BIG_ENDIAN; + private final long memoryAddress; + + ReadOnlyUnsafeDirectByteBuf(ByteBufAllocator allocator, ByteBuffer buffer) { + super(allocator, buffer); + memoryAddress = PlatformDependent.directBufferAddress(buffer); + } + + @Override + protected byte _getByte(int index) { + return PlatformDependent.getByte(addr(index)); + } + + @Override + protected short _getShort(int index) { + short v = PlatformDependent.getShort(addr(index)); + return NATIVE_ORDER? v : Short.reverseBytes(v); + } + + @Override + protected int _getUnsignedMedium(int index) { + long addr = addr(index); + return (PlatformDependent.getByte(addr) & 0xff) << 16 | + (PlatformDependent.getByte(addr + 1) & 0xff) << 8 | + PlatformDependent.getByte(addr + 2) & 0xff; + } + + @Override + protected int _getInt(int index) { + int v = PlatformDependent.getInt(addr(index)); + return NATIVE_ORDER? v : Integer.reverseBytes(v); + } + + @Override + protected long _getLong(int index) { + long v = PlatformDependent.getLong(addr(index)); + return NATIVE_ORDER? v : Long.reverseBytes(v); + } + + @Override + public ByteBuf getBytes(int index, ByteBuf dst, int dstIndex, int length) { + checkIndex(index, length); + if (dst == null) { + throw new NullPointerException("dst"); + } + if (dstIndex < 0 || dstIndex > dst.capacity() - length) { + throw new IndexOutOfBoundsException("dstIndex: " + dstIndex); + } + + if (dst.hasMemoryAddress()) { + PlatformDependent.copyMemory(addr(index), dst.memoryAddress() + dstIndex, length); + } else if (dst.hasArray()) { + PlatformDependent.copyMemory(addr(index), dst.array(), dst.arrayOffset() + dstIndex, length); + } else { + dst.setBytes(dstIndex, this, index, length); + } + return this; + } + + @Override + public ByteBuf getBytes(int index, byte[] dst, int dstIndex, int length) { + checkIndex(index, length); + if (dst == null) { + throw new NullPointerException("dst"); + } + if (dstIndex < 0 || dstIndex > dst.length - length) { + throw new IndexOutOfBoundsException(String.format( + "dstIndex: %d, length: %d (expected: range(0, %d))", dstIndex, length, dst.length)); + } + + if (length != 0) { + PlatformDependent.copyMemory(addr(index), dst, dstIndex, length); + } + return this; + } + + @Override + public ByteBuf getBytes(int index, ByteBuffer dst) { + checkIndex(index); + if (dst == null) { + throw new NullPointerException("dst"); + } + + int bytesToCopy = Math.min(capacity() - index, dst.remaining()); + ByteBuffer tmpBuf = internalNioBuffer(); + tmpBuf.clear().position(index).limit(index + bytesToCopy); + dst.put(tmpBuf); + return this; + } + + @Override + public ByteBuf copy(int index, int length) { + checkIndex(index, length); + ByteBuf copy = alloc().directBuffer(length, maxCapacity()); + if (length != 0) { + if (copy.hasMemoryAddress()) { + PlatformDependent.copyMemory(addr(index), copy.memoryAddress(), length); + copy.setIndex(0, length); + } else { + copy.writeBytes(this, index, length); + } + } + return copy; + } + + private long addr(int index) { + return memoryAddress + index; + } +} diff --git a/common/src/common/net/buffer/SimpleLeakAwareByteBuf.java b/common/src/common/net/buffer/SimpleLeakAwareByteBuf.java new file mode 100644 index 0000000..688af60 --- /dev/null +++ b/common/src/common/net/buffer/SimpleLeakAwareByteBuf.java @@ -0,0 +1,79 @@ +/* + * Copyright 2013 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ + +package common.net.buffer; + +import java.nio.ByteOrder; + +import common.net.util.ResourceLeak; + +final class SimpleLeakAwareByteBuf extends WrappedByteBuf { + + private final ResourceLeak leak; + + SimpleLeakAwareByteBuf(ByteBuf buf, ResourceLeak leak) { + super(buf); + this.leak = leak; + } + + @Override + public boolean release() { + boolean deallocated = super.release(); + if (deallocated) { + leak.close(); + } + return deallocated; + } + + @Override + public boolean release(int decrement) { + boolean deallocated = super.release(decrement); + if (deallocated) { + leak.close(); + } + return deallocated; + } + + @Override + public ByteBuf order(ByteOrder endianness) { + leak.record(); + if (order() == endianness) { + return this; + } else { + return new SimpleLeakAwareByteBuf(super.order(endianness), leak); + } + } + + @Override + public ByteBuf slice() { + return new SimpleLeakAwareByteBuf(super.slice(), leak); + } + + @Override + public ByteBuf slice(int index, int length) { + return new SimpleLeakAwareByteBuf(super.slice(index, length), leak); + } + + @Override + public ByteBuf duplicate() { + return new SimpleLeakAwareByteBuf(super.duplicate(), leak); + } + + @Override + public ByteBuf readSlice(int length) { + return new SimpleLeakAwareByteBuf(super.readSlice(length), leak); + } +} diff --git a/common/src/common/net/buffer/SlicedByteBuf.java b/common/src/common/net/buffer/SlicedByteBuf.java new file mode 100644 index 0000000..0e7a208 --- /dev/null +++ b/common/src/common/net/buffer/SlicedByteBuf.java @@ -0,0 +1,296 @@ +/* + * Copyright 2012 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ +package common.net.buffer; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.nio.ByteBuffer; +import java.nio.ByteOrder; +import java.nio.channels.GatheringByteChannel; +import java.nio.channels.ScatteringByteChannel; + + +/** + * A derived buffer which exposes its parent's sub-region only. It is + * recommended to use {@link ByteBuf#slice()} and + * {@link ByteBuf#slice(int, int)} instead of calling the constructor + * explicitly. + */ +public class SlicedByteBuf extends AbstractDerivedByteBuf { + + private final ByteBuf buffer; + private final int adjustment; + private final int length; + + public SlicedByteBuf(ByteBuf buffer, int index, int length) { + super(length); + if (index < 0 || index > buffer.capacity() - length) { + throw new IndexOutOfBoundsException(buffer + ".slice(" + index + ", " + length + ')'); + } + + if (buffer instanceof SlicedByteBuf) { + this.buffer = ((SlicedByteBuf) buffer).buffer; + adjustment = ((SlicedByteBuf) buffer).adjustment + index; + } else if (buffer instanceof DuplicatedByteBuf) { + this.buffer = buffer.unwrap(); + adjustment = index; + } else { + this.buffer = buffer; + adjustment = index; + } + this.length = length; + + writerIndex(length); + } + + @Override + public ByteBuf unwrap() { + return buffer; + } + + @Override + public ByteBufAllocator alloc() { + return buffer.alloc(); + } + + @Override + public ByteOrder order() { + return buffer.order(); + } + + @Override + public boolean isDirect() { + return buffer.isDirect(); + } + + @Override + public int capacity() { + return length; + } + + @Override + public ByteBuf capacity(int newCapacity) { + throw new UnsupportedOperationException("sliced buffer"); + } + + @Override + public boolean hasArray() { + return buffer.hasArray(); + } + + @Override + public byte[] array() { + return buffer.array(); + } + + @Override + public int arrayOffset() { + return buffer.arrayOffset() + adjustment; + } + + @Override + public boolean hasMemoryAddress() { + return buffer.hasMemoryAddress(); + } + + @Override + public long memoryAddress() { + return buffer.memoryAddress() + adjustment; + } + + @Override + protected byte _getByte(int index) { + return buffer.getByte(index + adjustment); + } + + @Override + protected short _getShort(int index) { + return buffer.getShort(index + adjustment); + } + + @Override + protected int _getUnsignedMedium(int index) { + return buffer.getUnsignedMedium(index + adjustment); + } + + @Override + protected int _getInt(int index) { + return buffer.getInt(index + adjustment); + } + + @Override + protected long _getLong(int index) { + return buffer.getLong(index + adjustment); + } + + @Override + public ByteBuf duplicate() { + ByteBuf duplicate = buffer.slice(adjustment, length); + duplicate.setIndex(readerIndex(), writerIndex()); + return duplicate; + } + + @Override + public ByteBuf copy(int index, int length) { + checkIndex(index, length); + return buffer.copy(index + adjustment, length); + } + + @Override + public ByteBuf slice(int index, int length) { + checkIndex(index, length); + if (length == 0) { + return Unpooled.EMPTY_BUFFER; + } + return buffer.slice(index + adjustment, length); + } + + @Override + public ByteBuf getBytes(int index, ByteBuf dst, int dstIndex, int length) { + checkIndex(index, length); + buffer.getBytes(index + adjustment, dst, dstIndex, length); + return this; + } + + @Override + public ByteBuf getBytes(int index, byte[] dst, int dstIndex, int length) { + checkIndex(index, length); + buffer.getBytes(index + adjustment, dst, dstIndex, length); + return this; + } + + @Override + public ByteBuf getBytes(int index, ByteBuffer dst) { + checkIndex(index, dst.remaining()); + buffer.getBytes(index + adjustment, dst); + return this; + } + + @Override + protected void _setByte(int index, int value) { + buffer.setByte(index + adjustment, value); + } + + @Override + protected void _setShort(int index, int value) { + buffer.setShort(index + adjustment, value); + } + + @Override + protected void _setMedium(int index, int value) { + buffer.setMedium(index + adjustment, value); + } + + @Override + protected void _setInt(int index, int value) { + buffer.setInt(index + adjustment, value); + } + + @Override + protected void _setLong(int index, long value) { + buffer.setLong(index + adjustment, value); + } + + @Override + public ByteBuf setBytes(int index, byte[] src, int srcIndex, int length) { + checkIndex(index, length); + buffer.setBytes(index + adjustment, src, srcIndex, length); + return this; + } + + @Override + public ByteBuf setBytes(int index, ByteBuf src, int srcIndex, int length) { + checkIndex(index, length); + buffer.setBytes(index + adjustment, src, srcIndex, length); + return this; + } + + @Override + public ByteBuf setBytes(int index, ByteBuffer src) { + checkIndex(index, src.remaining()); + buffer.setBytes(index + adjustment, src); + return this; + } + + @Override + public ByteBuf getBytes(int index, OutputStream out, int length) throws IOException { + checkIndex(index, length); + buffer.getBytes(index + adjustment, out, length); + return this; + } + + @Override + public int getBytes(int index, GatheringByteChannel out, int length) throws IOException { + checkIndex(index, length); + return buffer.getBytes(index + adjustment, out, length); + } + + @Override + public int setBytes(int index, InputStream in, int length) throws IOException { + checkIndex(index, length); + return buffer.setBytes(index + adjustment, in, length); + } + + @Override + public int setBytes(int index, ScatteringByteChannel in, int length) throws IOException { + checkIndex(index, length); + return buffer.setBytes(index + adjustment, in, length); + } + + @Override + public int nioBufferCount() { + return buffer.nioBufferCount(); + } + + @Override + public ByteBuffer nioBuffer(int index, int length) { + checkIndex(index, length); + return buffer.nioBuffer(index + adjustment, length); + } + + @Override + public ByteBuffer[] nioBuffers(int index, int length) { + checkIndex(index, length); + return buffer.nioBuffers(index + adjustment, length); + } + + @Override + public ByteBuffer internalNioBuffer(int index, int length) { + checkIndex(index, length); + return nioBuffer(index, length); + } + + @Override + public int forEachByte(int index, int length, ByteBufProcessor processor) { + int ret = buffer.forEachByte(index + adjustment, length, processor); + if (ret >= adjustment) { + return ret - adjustment; + } else { + return -1; + } + } + + @Override + public int forEachByteDesc(int index, int length, ByteBufProcessor processor) { + int ret = buffer.forEachByteDesc(index + adjustment, length, processor); + if (ret >= adjustment) { + return ret - adjustment; + } else { + return -1; + } + } +} diff --git a/common/src/common/net/buffer/SwappedByteBuf.java b/common/src/common/net/buffer/SwappedByteBuf.java new file mode 100644 index 0000000..88b4478 --- /dev/null +++ b/common/src/common/net/buffer/SwappedByteBuf.java @@ -0,0 +1,852 @@ +/* + * Copyright 2012 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ +package common.net.buffer; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.nio.ByteBuffer; +import java.nio.ByteOrder; +import java.nio.channels.GatheringByteChannel; +import java.nio.channels.ScatteringByteChannel; +import java.nio.charset.Charset; + +/** + * Wrapper which swap the {@link ByteOrder} of a {@link ByteBuf}. + */ +public class SwappedByteBuf extends ByteBuf { + + private final ByteBuf buf; + private final ByteOrder order; + + public SwappedByteBuf(ByteBuf buf) { + if (buf == null) { + throw new NullPointerException("buf"); + } + this.buf = buf; + if (buf.order() == ByteOrder.BIG_ENDIAN) { + order = ByteOrder.LITTLE_ENDIAN; + } else { + order = ByteOrder.BIG_ENDIAN; + } + } + + @Override + public ByteOrder order() { + return order; + } + + @Override + public ByteBuf order(ByteOrder endianness) { + if (endianness == null) { + throw new NullPointerException("endianness"); + } + if (endianness == order) { + return this; + } + return buf; + } + + @Override + public ByteBuf unwrap() { + return buf.unwrap(); + } + + @Override + public ByteBufAllocator alloc() { + return buf.alloc(); + } + + @Override + public int capacity() { + return buf.capacity(); + } + + @Override + public ByteBuf capacity(int newCapacity) { + buf.capacity(newCapacity); + return this; + } + + @Override + public int maxCapacity() { + return buf.maxCapacity(); + } + + @Override + public boolean isDirect() { + return buf.isDirect(); + } + + @Override + public int readerIndex() { + return buf.readerIndex(); + } + + @Override + public ByteBuf readerIndex(int readerIndex) { + buf.readerIndex(readerIndex); + return this; + } + + @Override + public int writerIndex() { + return buf.writerIndex(); + } + + @Override + public ByteBuf writerIndex(int writerIndex) { + buf.writerIndex(writerIndex); + return this; + } + + @Override + public ByteBuf setIndex(int readerIndex, int writerIndex) { + buf.setIndex(readerIndex, writerIndex); + return this; + } + + @Override + public int readableBytes() { + return buf.readableBytes(); + } + + @Override + public int writableBytes() { + return buf.writableBytes(); + } + + @Override + public int maxWritableBytes() { + return buf.maxWritableBytes(); + } + + @Override + public boolean isReadable() { + return buf.isReadable(); + } + + @Override + public boolean isReadable(int size) { + return buf.isReadable(size); + } + + @Override + public boolean isWritable() { + return buf.isWritable(); + } + + @Override + public boolean isWritable(int size) { + return buf.isWritable(size); + } + + @Override + public ByteBuf clear() { + buf.clear(); + return this; + } + + @Override + public ByteBuf markReaderIndex() { + buf.markReaderIndex(); + return this; + } + + @Override + public ByteBuf resetReaderIndex() { + buf.resetReaderIndex(); + return this; + } + + @Override + public ByteBuf markWriterIndex() { + buf.markWriterIndex(); + return this; + } + + @Override + public ByteBuf resetWriterIndex() { + buf.resetWriterIndex(); + return this; + } + + @Override + public ByteBuf discardReadBytes() { + buf.discardReadBytes(); + return this; + } + + @Override + public ByteBuf discardSomeReadBytes() { + buf.discardSomeReadBytes(); + return this; + } + + @Override + public ByteBuf ensureWritable(int writableBytes) { + buf.ensureWritable(writableBytes); + return this; + } + + @Override + public int ensureWritable(int minWritableBytes, boolean force) { + return buf.ensureWritable(minWritableBytes, force); + } + + @Override + public boolean getBoolean(int index) { + return buf.getBoolean(index); + } + + @Override + public byte getByte(int index) { + return buf.getByte(index); + } + + @Override + public short getUnsignedByte(int index) { + return buf.getUnsignedByte(index); + } + + @Override + public short getShort(int index) { + return ByteBufUtil.swapShort(buf.getShort(index)); + } + + @Override + public int getUnsignedShort(int index) { + return getShort(index) & 0xFFFF; + } + + @Override + public int getMedium(int index) { + return ByteBufUtil.swapMedium(buf.getMedium(index)); + } + + @Override + public int getUnsignedMedium(int index) { + return getMedium(index) & 0xFFFFFF; + } + + @Override + public int getInt(int index) { + return ByteBufUtil.swapInt(buf.getInt(index)); + } + + @Override + public long getUnsignedInt(int index) { + return getInt(index) & 0xFFFFFFFFL; + } + + @Override + public long getLong(int index) { + return ByteBufUtil.swapLong(buf.getLong(index)); + } + + @Override + public char getChar(int index) { + return (char) getShort(index); + } + + @Override + public float getFloat(int index) { + return Float.intBitsToFloat(getInt(index)); + } + + @Override + public double getDouble(int index) { + return Double.longBitsToDouble(getLong(index)); + } + + @Override + public ByteBuf getBytes(int index, ByteBuf dst) { + buf.getBytes(index, dst); + return this; + } + + @Override + public ByteBuf getBytes(int index, ByteBuf dst, int length) { + buf.getBytes(index, dst, length); + return this; + } + + @Override + public ByteBuf getBytes(int index, ByteBuf dst, int dstIndex, int length) { + buf.getBytes(index, dst, dstIndex, length); + return this; + } + + @Override + public ByteBuf getBytes(int index, byte[] dst) { + buf.getBytes(index, dst); + return this; + } + + @Override + public ByteBuf getBytes(int index, byte[] dst, int dstIndex, int length) { + buf.getBytes(index, dst, dstIndex, length); + return this; + } + + @Override + public ByteBuf getBytes(int index, ByteBuffer dst) { + buf.getBytes(index, dst); + return this; + } + + @Override + public ByteBuf getBytes(int index, OutputStream out, int length) throws IOException { + buf.getBytes(index, out, length); + return this; + } + + @Override + public int getBytes(int index, GatheringByteChannel out, int length) throws IOException { + return buf.getBytes(index, out, length); + } + + @Override + public ByteBuf setBoolean(int index, boolean value) { + buf.setBoolean(index, value); + return this; + } + + @Override + public ByteBuf setByte(int index, int value) { + buf.setByte(index, value); + return this; + } + + @Override + public ByteBuf setShort(int index, int value) { + buf.setShort(index, ByteBufUtil.swapShort((short) value)); + return this; + } + + @Override + public ByteBuf setMedium(int index, int value) { + buf.setMedium(index, ByteBufUtil.swapMedium(value)); + return this; + } + + @Override + public ByteBuf setInt(int index, int value) { + buf.setInt(index, ByteBufUtil.swapInt(value)); + return this; + } + + @Override + public ByteBuf setLong(int index, long value) { + buf.setLong(index, ByteBufUtil.swapLong(value)); + return this; + } + + @Override + public ByteBuf setChar(int index, int value) { + setShort(index, value); + return this; + } + + @Override + public ByteBuf setFloat(int index, float value) { + setInt(index, Float.floatToRawIntBits(value)); + return this; + } + + @Override + public ByteBuf setDouble(int index, double value) { + setLong(index, Double.doubleToRawLongBits(value)); + return this; + } + + @Override + public ByteBuf setBytes(int index, ByteBuf src) { + buf.setBytes(index, src); + return this; + } + + @Override + public ByteBuf setBytes(int index, ByteBuf src, int length) { + buf.setBytes(index, src, length); + return this; + } + + @Override + public ByteBuf setBytes(int index, ByteBuf src, int srcIndex, int length) { + buf.setBytes(index, src, srcIndex, length); + return this; + } + + @Override + public ByteBuf setBytes(int index, byte[] src) { + buf.setBytes(index, src); + return this; + } + + @Override + public ByteBuf setBytes(int index, byte[] src, int srcIndex, int length) { + buf.setBytes(index, src, srcIndex, length); + return this; + } + + @Override + public ByteBuf setBytes(int index, ByteBuffer src) { + buf.setBytes(index, src); + return this; + } + + @Override + public int setBytes(int index, InputStream in, int length) throws IOException { + return buf.setBytes(index, in, length); + } + + @Override + public int setBytes(int index, ScatteringByteChannel in, int length) throws IOException { + return buf.setBytes(index, in, length); + } + + @Override + public ByteBuf setZero(int index, int length) { + buf.setZero(index, length); + return this; + } + + @Override + public boolean readBoolean() { + return buf.readBoolean(); + } + + @Override + public byte readByte() { + return buf.readByte(); + } + + @Override + public short readUnsignedByte() { + return buf.readUnsignedByte(); + } + + @Override + public short readShort() { + return ByteBufUtil.swapShort(buf.readShort()); + } + + @Override + public int readUnsignedShort() { + return readShort() & 0xFFFF; + } + + @Override + public int readMedium() { + return ByteBufUtil.swapMedium(buf.readMedium()); + } + + @Override + public int readUnsignedMedium() { + return readMedium() & 0xFFFFFF; + } + + @Override + public int readInt() { + return ByteBufUtil.swapInt(buf.readInt()); + } + + @Override + public long readUnsignedInt() { + return readInt() & 0xFFFFFFFFL; + } + + @Override + public long readLong() { + return ByteBufUtil.swapLong(buf.readLong()); + } + + @Override + public char readChar() { + return (char) readShort(); + } + + @Override + public float readFloat() { + return Float.intBitsToFloat(readInt()); + } + + @Override + public double readDouble() { + return Double.longBitsToDouble(readLong()); + } + + @Override + public ByteBuf readBytes(int length) { + return buf.readBytes(length).order(order()); + } + + @Override + public ByteBuf readSlice(int length) { + return buf.readSlice(length).order(order); + } + + @Override + public ByteBuf readBytes(ByteBuf dst) { + buf.readBytes(dst); + return this; + } + + @Override + public ByteBuf readBytes(ByteBuf dst, int length) { + buf.readBytes(dst, length); + return this; + } + + @Override + public ByteBuf readBytes(ByteBuf dst, int dstIndex, int length) { + buf.readBytes(dst, dstIndex, length); + return this; + } + + @Override + public ByteBuf readBytes(byte[] dst) { + buf.readBytes(dst); + return this; + } + + @Override + public ByteBuf readBytes(byte[] dst, int dstIndex, int length) { + buf.readBytes(dst, dstIndex, length); + return this; + } + + @Override + public ByteBuf readBytes(ByteBuffer dst) { + buf.readBytes(dst); + return this; + } + + @Override + public ByteBuf readBytes(OutputStream out, int length) throws IOException { + buf.readBytes(out, length); + return this; + } + + @Override + public int readBytes(GatheringByteChannel out, int length) throws IOException { + return buf.readBytes(out, length); + } + + @Override + public ByteBuf skipBytes(int length) { + buf.skipBytes(length); + return this; + } + + @Override + public ByteBuf writeBoolean(boolean value) { + buf.writeBoolean(value); + return this; + } + + @Override + public ByteBuf writeByte(int value) { + buf.writeByte(value); + return this; + } + + @Override + public ByteBuf writeShort(int value) { + buf.writeShort(ByteBufUtil.swapShort((short) value)); + return this; + } + + @Override + public ByteBuf writeMedium(int value) { + buf.writeMedium(ByteBufUtil.swapMedium(value)); + return this; + } + + @Override + public ByteBuf writeInt(int value) { + buf.writeInt(ByteBufUtil.swapInt(value)); + return this; + } + + @Override + public ByteBuf writeLong(long value) { + buf.writeLong(ByteBufUtil.swapLong(value)); + return this; + } + + @Override + public ByteBuf writeChar(int value) { + writeShort(value); + return this; + } + + @Override + public ByteBuf writeFloat(float value) { + writeInt(Float.floatToRawIntBits(value)); + return this; + } + + @Override + public ByteBuf writeDouble(double value) { + writeLong(Double.doubleToRawLongBits(value)); + return this; + } + + @Override + public ByteBuf writeBytes(ByteBuf src) { + buf.writeBytes(src); + return this; + } + + @Override + public ByteBuf writeBytes(ByteBuf src, int length) { + buf.writeBytes(src, length); + return this; + } + + @Override + public ByteBuf writeBytes(ByteBuf src, int srcIndex, int length) { + buf.writeBytes(src, srcIndex, length); + return this; + } + + @Override + public ByteBuf writeBytes(byte[] src) { + buf.writeBytes(src); + return this; + } + + @Override + public ByteBuf writeBytes(byte[] src, int srcIndex, int length) { + buf.writeBytes(src, srcIndex, length); + return this; + } + + @Override + public ByteBuf writeBytes(ByteBuffer src) { + buf.writeBytes(src); + return this; + } + + @Override + public int writeBytes(InputStream in, int length) throws IOException { + return buf.writeBytes(in, length); + } + + @Override + public int writeBytes(ScatteringByteChannel in, int length) throws IOException { + return buf.writeBytes(in, length); + } + + @Override + public ByteBuf writeZero(int length) { + buf.writeZero(length); + return this; + } + + @Override + public int indexOf(int fromIndex, int toIndex, byte value) { + return buf.indexOf(fromIndex, toIndex, value); + } + + @Override + public int bytesBefore(byte value) { + return buf.bytesBefore(value); + } + + @Override + public int bytesBefore(int length, byte value) { + return buf.bytesBefore(length, value); + } + + @Override + public int bytesBefore(int index, int length, byte value) { + return buf.bytesBefore(index, length, value); + } + + @Override + public int forEachByte(ByteBufProcessor processor) { + return buf.forEachByte(processor); + } + + @Override + public int forEachByte(int index, int length, ByteBufProcessor processor) { + return buf.forEachByte(index, length, processor); + } + + @Override + public int forEachByteDesc(ByteBufProcessor processor) { + return buf.forEachByteDesc(processor); + } + + @Override + public int forEachByteDesc(int index, int length, ByteBufProcessor processor) { + return buf.forEachByteDesc(index, length, processor); + } + + @Override + public ByteBuf copy() { + return buf.copy().order(order); + } + + @Override + public ByteBuf copy(int index, int length) { + return buf.copy(index, length).order(order); + } + + @Override + public ByteBuf slice() { + return buf.slice().order(order); + } + + @Override + public ByteBuf slice(int index, int length) { + return buf.slice(index, length).order(order); + } + + @Override + public ByteBuf duplicate() { + return buf.duplicate().order(order); + } + + @Override + public int nioBufferCount() { + return buf.nioBufferCount(); + } + + @Override + public ByteBuffer nioBuffer() { + return buf.nioBuffer().order(order); + } + + @Override + public ByteBuffer nioBuffer(int index, int length) { + return buf.nioBuffer(index, length).order(order); + } + + @Override + public ByteBuffer internalNioBuffer(int index, int length) { + return nioBuffer(index, length); + } + + @Override + public ByteBuffer[] nioBuffers() { + ByteBuffer[] nioBuffers = buf.nioBuffers(); + for (int i = 0; i < nioBuffers.length; i++) { + nioBuffers[i] = nioBuffers[i].order(order); + } + return nioBuffers; + } + + @Override + public ByteBuffer[] nioBuffers(int index, int length) { + ByteBuffer[] nioBuffers = buf.nioBuffers(index, length); + for (int i = 0; i < nioBuffers.length; i++) { + nioBuffers[i] = nioBuffers[i].order(order); + } + return nioBuffers; + } + + @Override + public boolean hasArray() { + return buf.hasArray(); + } + + @Override + public byte[] array() { + return buf.array(); + } + + @Override + public int arrayOffset() { + return buf.arrayOffset(); + } + + @Override + public boolean hasMemoryAddress() { + return buf.hasMemoryAddress(); + } + + @Override + public long memoryAddress() { + return buf.memoryAddress(); + } + + @Override + public String toString(Charset charset) { + return buf.toString(charset); + } + + @Override + public String toString(int index, int length, Charset charset) { + return buf.toString(index, length, charset); + } + + @Override + public int refCnt() { + return buf.refCnt(); + } + + @Override + public ByteBuf retain() { + buf.retain(); + return this; + } + + @Override + public ByteBuf retain(int increment) { + buf.retain(increment); + return this; + } + + @Override + public boolean release() { + return buf.release(); + } + + @Override + public boolean release(int decrement) { + return buf.release(decrement); + } + + @Override + public int hashCode() { + return buf.hashCode(); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj instanceof ByteBuf) { + return ByteBufUtil.equals(this, (ByteBuf) obj); + } + return false; + } + + @Override + public int compareTo(ByteBuf buffer) { + return ByteBufUtil.compare(this, buffer); + } + + @Override + public String toString() { + return "Swapped(" + buf.toString() + ')'; + } +} diff --git a/common/src/common/net/buffer/Unpooled.java b/common/src/common/net/buffer/Unpooled.java new file mode 100644 index 0000000..8bb2d67 --- /dev/null +++ b/common/src/common/net/buffer/Unpooled.java @@ -0,0 +1,861 @@ +/* + * Copyright 2012 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ +package common.net.buffer; + +import java.nio.ByteBuffer; +import java.nio.ByteOrder; +import java.nio.CharBuffer; +import java.nio.charset.Charset; +import java.util.ArrayList; +import java.util.List; + +import common.net.util.internal.PlatformDependent; + + +/** + * Creates a new {@link ByteBuf} by allocating new space or by wrapping + * or copying existing byte arrays, byte buffers and a string. + * + *

Use static import

+ * This classes is intended to be used with Java 5 static import statement: + * + *
+ * import static game.net.buffer.{@link Unpooled}.*;
+ *
+ * {@link ByteBuf} heapBuffer    = buffer(128);
+ * {@link ByteBuf} directBuffer  = directBuffer(256);
+ * {@link ByteBuf} wrappedBuffer = wrappedBuffer(new byte[128], new byte[256]);
+ * {@link ByteBuf} copiedBuffe r = copiedBuffer({@link ByteBuffer}.allocate(128));
+ * 
+ * + *

Allocating a new buffer

+ * + * Three buffer types are provided out of the box. + * + *
    + *
  • {@link #buffer(int)} allocates a new fixed-capacity heap buffer.
  • + *
  • {@link #directBuffer(int)} allocates a new fixed-capacity direct buffer.
  • + *
+ * + *

Creating a wrapped buffer

+ * + * Wrapped buffer is a buffer which is a view of one or more existing + * byte arrays and byte buffers. Any changes in the content of the original + * array or buffer will be visible in the wrapped buffer. Various wrapper + * methods are provided and their name is all {@code wrappedBuffer()}. + * You might want to take a look at the methods that accept varargs closely if + * you want to create a buffer which is composed of more than one array to + * reduce the number of memory copy. + * + *

Creating a copied buffer

+ * + * Copied buffer is a deep copy of one or more existing byte arrays, byte + * buffers or a string. Unlike a wrapped buffer, there's no shared data + * between the original data and the copied buffer. Various copy methods are + * provided and their name is all {@code copiedBuffer()}. It is also convenient + * to use this operation to merge multiple buffers into one buffer. + * + *

Miscellaneous utility methods

+ * + * This class also provides various utility methods to help implementation + * of a new buffer type, generation of hex dump and swapping an integer's + * byte order. + */ +public final class Unpooled { + + private static final ByteBufAllocator ALLOC = UnpooledByteBufAllocator.DEFAULT; + + /** + * Big endian byte order. + */ + public static final ByteOrder BIG_ENDIAN = ByteOrder.BIG_ENDIAN; + + /** + * Little endian byte order. + */ + public static final ByteOrder LITTLE_ENDIAN = ByteOrder.LITTLE_ENDIAN; + + /** + * A buffer whose capacity is {@code 0}. + */ + public static final ByteBuf EMPTY_BUFFER = ALLOC.buffer(0, 0); + + /** + * Creates a new big-endian Java heap buffer with reasonably small initial capacity, which + * expands its capacity boundlessly on demand. + */ + public static ByteBuf buffer() { + return ALLOC.heapBuffer(); + } + + /** + * Creates a new big-endian direct buffer with reasonably small initial capacity, which + * expands its capacity boundlessly on demand. + */ + public static ByteBuf directBuffer() { + return ALLOC.directBuffer(); + } + + /** + * Creates a new big-endian Java heap buffer with the specified {@code capacity}, which + * expands its capacity boundlessly on demand. The new buffer's {@code readerIndex} and + * {@code writerIndex} are {@code 0}. + */ + public static ByteBuf buffer(int initialCapacity) { + return ALLOC.heapBuffer(initialCapacity); + } + + /** + * Creates a new big-endian direct buffer with the specified {@code capacity}, which + * expands its capacity boundlessly on demand. The new buffer's {@code readerIndex} and + * {@code writerIndex} are {@code 0}. + */ + public static ByteBuf directBuffer(int initialCapacity) { + return ALLOC.directBuffer(initialCapacity); + } + + /** + * Creates a new big-endian Java heap buffer with the specified + * {@code initialCapacity}, that may grow up to {@code maxCapacity} + * The new buffer's {@code readerIndex} and {@code writerIndex} are + * {@code 0}. + */ + public static ByteBuf buffer(int initialCapacity, int maxCapacity) { + return ALLOC.heapBuffer(initialCapacity, maxCapacity); + } + + /** + * Creates a new big-endian direct buffer with the specified + * {@code initialCapacity}, that may grow up to {@code maxCapacity}. + * The new buffer's {@code readerIndex} and {@code writerIndex} are + * {@code 0}. + */ + public static ByteBuf directBuffer(int initialCapacity, int maxCapacity) { + return ALLOC.directBuffer(initialCapacity, maxCapacity); + } + + /** + * Creates a new big-endian buffer which wraps the specified {@code array}. + * A modification on the specified array's content will be visible to the + * returned buffer. + */ + public static ByteBuf wrappedBuffer(byte[] array) { + if (array.length == 0) { + return EMPTY_BUFFER; + } + return new UnpooledHeapByteBuf(ALLOC, array, array.length); + } + + /** + * Creates a new big-endian buffer which wraps the sub-region of the + * specified {@code array}. A modification on the specified array's + * content will be visible to the returned buffer. + */ + public static ByteBuf wrappedBuffer(byte[] array, int offset, int length) { + if (length == 0) { + return EMPTY_BUFFER; + } + + if (offset == 0 && length == array.length) { + return wrappedBuffer(array); + } + + return wrappedBuffer(array).slice(offset, length); + } + + /** + * Creates a new buffer which wraps the specified NIO buffer's current + * slice. A modification on the specified buffer's content will be + * visible to the returned buffer. + */ + public static ByteBuf wrappedBuffer(ByteBuffer buffer) { + if (!buffer.hasRemaining()) { + return EMPTY_BUFFER; + } + if (buffer.hasArray()) { + return wrappedBuffer( + buffer.array(), + buffer.arrayOffset() + buffer.position(), + buffer.remaining()).order(buffer.order()); + } else if (PlatformDependent.hasUnsafe()) { + if (buffer.isReadOnly()) { + if (buffer.isDirect()) { + return new ReadOnlyUnsafeDirectByteBuf(ALLOC, buffer); + } else { + return new ReadOnlyByteBufferBuf(ALLOC, buffer); + } + } else { + return new UnpooledUnsafeDirectByteBuf(ALLOC, buffer, buffer.remaining()); + } + } else { + if (buffer.isReadOnly()) { + return new ReadOnlyByteBufferBuf(ALLOC, buffer); + } else { + return new UnpooledDirectByteBuf(ALLOC, buffer, buffer.remaining()); + } + } + } + + /** + * Creates a new buffer which wraps the specified buffer's readable bytes. + * A modification on the specified buffer's content will be visible to the + * returned buffer. + */ + public static ByteBuf wrappedBuffer(ByteBuf buffer) { + if (buffer.isReadable()) { + return buffer.slice(); + } else { + return EMPTY_BUFFER; + } + } + + /** + * Creates a new big-endian composite buffer which wraps the specified + * arrays without copying them. A modification on the specified arrays' + * content will be visible to the returned buffer. + */ + public static ByteBuf wrappedBuffer(byte[]... arrays) { + return wrappedBuffer(16, arrays); + } + + /** + * Creates a new big-endian composite buffer which wraps the readable bytes of the + * specified buffers without copying them. A modification on the content + * of the specified buffers will be visible to the returned buffer. + */ + public static ByteBuf wrappedBuffer(ByteBuf... buffers) { + return wrappedBuffer(16, buffers); + } + + /** + * Creates a new big-endian composite buffer which wraps the slices of the specified + * NIO buffers without copying them. A modification on the content of the + * specified buffers will be visible to the returned buffer. + */ + public static ByteBuf wrappedBuffer(ByteBuffer... buffers) { + return wrappedBuffer(16, buffers); + } + + /** + * Creates a new big-endian composite buffer which wraps the specified + * arrays without copying them. A modification on the specified arrays' + * content will be visible to the returned buffer. + */ + public static ByteBuf wrappedBuffer(int maxNumComponents, byte[]... arrays) { + switch (arrays.length) { + case 0: + break; + case 1: + if (arrays[0].length != 0) { + return wrappedBuffer(arrays[0]); + } + break; + default: + // Get the list of the component, while guessing the byte order. + final List components = new ArrayList(arrays.length); + for (byte[] a: arrays) { + if (a == null) { + break; + } + if (a.length > 0) { + components.add(wrappedBuffer(a)); + } + } + + if (!components.isEmpty()) { + return new CompositeByteBuf(ALLOC, false, maxNumComponents, components); + } + } + + return EMPTY_BUFFER; + } + + /** + * Creates a new big-endian composite buffer which wraps the readable bytes of the + * specified buffers without copying them. A modification on the content + * of the specified buffers will be visible to the returned buffer. + */ + public static ByteBuf wrappedBuffer(int maxNumComponents, ByteBuf... buffers) { + switch (buffers.length) { + case 0: + break; + case 1: + if (buffers[0].isReadable()) { + return wrappedBuffer(buffers[0].order(BIG_ENDIAN)); + } + break; + default: + for (ByteBuf b: buffers) { + if (b.isReadable()) { + return new CompositeByteBuf(ALLOC, false, maxNumComponents, buffers); + } + } + } + return EMPTY_BUFFER; + } + + /** + * Creates a new big-endian composite buffer which wraps the slices of the specified + * NIO buffers without copying them. A modification on the content of the + * specified buffers will be visible to the returned buffer. + */ + public static ByteBuf wrappedBuffer(int maxNumComponents, ByteBuffer... buffers) { + switch (buffers.length) { + case 0: + break; + case 1: + if (buffers[0].hasRemaining()) { + return wrappedBuffer(buffers[0].order(BIG_ENDIAN)); + } + break; + default: + // Get the list of the component, while guessing the byte order. + final List components = new ArrayList(buffers.length); + for (ByteBuffer b: buffers) { + if (b == null) { + break; + } + if (b.remaining() > 0) { + components.add(wrappedBuffer(b.order(BIG_ENDIAN))); + } + } + + if (!components.isEmpty()) { + return new CompositeByteBuf(ALLOC, false, maxNumComponents, components); + } + } + + return EMPTY_BUFFER; + } + + /** + * Returns a new big-endian composite buffer with no components. + */ + public static CompositeByteBuf compositeBuffer() { + return compositeBuffer(16); + } + + /** + * Returns a new big-endian composite buffer with no components. + */ + public static CompositeByteBuf compositeBuffer(int maxNumComponents) { + return new CompositeByteBuf(ALLOC, false, maxNumComponents); + } + + /** + * Creates a new big-endian buffer whose content is a copy of the + * specified {@code array}. The new buffer's {@code readerIndex} and + * {@code writerIndex} are {@code 0} and {@code array.length} respectively. + */ + public static ByteBuf copiedBuffer(byte[] array) { + if (array.length == 0) { + return EMPTY_BUFFER; + } + return wrappedBuffer(array.clone()); + } + + /** + * Creates a new big-endian buffer whose content is a copy of the + * specified {@code array}'s sub-region. The new buffer's + * {@code readerIndex} and {@code writerIndex} are {@code 0} and + * the specified {@code length} respectively. + */ + public static ByteBuf copiedBuffer(byte[] array, int offset, int length) { + if (length == 0) { + return EMPTY_BUFFER; + } + byte[] copy = new byte[length]; + System.arraycopy(array, offset, copy, 0, length); + return wrappedBuffer(copy); + } + + /** + * Creates a new buffer whose content is a copy of the specified + * {@code buffer}'s current slice. The new buffer's {@code readerIndex} + * and {@code writerIndex} are {@code 0} and {@code buffer.remaining} + * respectively. + */ + public static ByteBuf copiedBuffer(ByteBuffer buffer) { + int length = buffer.remaining(); + if (length == 0) { + return EMPTY_BUFFER; + } + byte[] copy = new byte[length]; + int position = buffer.position(); + try { + buffer.get(copy); + } finally { + buffer.position(position); + } + return wrappedBuffer(copy).order(buffer.order()); + } + + /** + * Creates a new buffer whose content is a copy of the specified + * {@code buffer}'s readable bytes. The new buffer's {@code readerIndex} + * and {@code writerIndex} are {@code 0} and {@code buffer.readableBytes} + * respectively. + */ + public static ByteBuf copiedBuffer(ByteBuf buffer) { + int readable = buffer.readableBytes(); + if (readable > 0) { + ByteBuf copy = buffer(readable); + copy.writeBytes(buffer, buffer.readerIndex(), readable); + return copy; + } else { + return EMPTY_BUFFER; + } + } + + /** + * Creates a new big-endian buffer whose content is a merged copy of + * the specified {@code arrays}. The new buffer's {@code readerIndex} + * and {@code writerIndex} are {@code 0} and the sum of all arrays' + * {@code length} respectively. + */ + public static ByteBuf copiedBuffer(byte[]... arrays) { + switch (arrays.length) { + case 0: + return EMPTY_BUFFER; + case 1: + if (arrays[0].length == 0) { + return EMPTY_BUFFER; + } else { + return copiedBuffer(arrays[0]); + } + } + + // Merge the specified arrays into one array. + int length = 0; + for (byte[] a: arrays) { + if (Integer.MAX_VALUE - length < a.length) { + throw new IllegalArgumentException( + "The total length of the specified arrays is too big."); + } + length += a.length; + } + + if (length == 0) { + return EMPTY_BUFFER; + } + + byte[] mergedArray = new byte[length]; + for (int i = 0, j = 0; i < arrays.length; i ++) { + byte[] a = arrays[i]; + System.arraycopy(a, 0, mergedArray, j, a.length); + j += a.length; + } + + return wrappedBuffer(mergedArray); + } + + /** + * Creates a new buffer whose content is a merged copy of the specified + * {@code buffers}' readable bytes. The new buffer's {@code readerIndex} + * and {@code writerIndex} are {@code 0} and the sum of all buffers' + * {@code readableBytes} respectively. + * + * @throws IllegalArgumentException + * if the specified buffers' endianness are different from each + * other + */ + public static ByteBuf copiedBuffer(ByteBuf... buffers) { + switch (buffers.length) { + case 0: + return EMPTY_BUFFER; + case 1: + return copiedBuffer(buffers[0]); + } + + // Merge the specified buffers into one buffer. + ByteOrder order = null; + int length = 0; + for (ByteBuf b: buffers) { + int bLen = b.readableBytes(); + if (bLen <= 0) { + continue; + } + if (Integer.MAX_VALUE - length < bLen) { + throw new IllegalArgumentException( + "The total length of the specified buffers is too big."); + } + length += bLen; + if (order != null) { + if (!order.equals(b.order())) { + throw new IllegalArgumentException("inconsistent byte order"); + } + } else { + order = b.order(); + } + } + + if (length == 0) { + return EMPTY_BUFFER; + } + + byte[] mergedArray = new byte[length]; + for (int i = 0, j = 0; i < buffers.length; i ++) { + ByteBuf b = buffers[i]; + int bLen = b.readableBytes(); + b.getBytes(b.readerIndex(), mergedArray, j, bLen); + j += bLen; + } + + return wrappedBuffer(mergedArray).order(order); + } + + /** + * Creates a new buffer whose content is a merged copy of the specified + * {@code buffers}' slices. The new buffer's {@code readerIndex} and + * {@code writerIndex} are {@code 0} and the sum of all buffers' + * {@code remaining} respectively. + * + * @throws IllegalArgumentException + * if the specified buffers' endianness are different from each + * other + */ + public static ByteBuf copiedBuffer(ByteBuffer... buffers) { + switch (buffers.length) { + case 0: + return EMPTY_BUFFER; + case 1: + return copiedBuffer(buffers[0]); + } + + // Merge the specified buffers into one buffer. + ByteOrder order = null; + int length = 0; + for (ByteBuffer b: buffers) { + int bLen = b.remaining(); + if (bLen <= 0) { + continue; + } + if (Integer.MAX_VALUE - length < bLen) { + throw new IllegalArgumentException( + "The total length of the specified buffers is too big."); + } + length += bLen; + if (order != null) { + if (!order.equals(b.order())) { + throw new IllegalArgumentException("inconsistent byte order"); + } + } else { + order = b.order(); + } + } + + if (length == 0) { + return EMPTY_BUFFER; + } + + byte[] mergedArray = new byte[length]; + for (int i = 0, j = 0; i < buffers.length; i ++) { + ByteBuffer b = buffers[i]; + int bLen = b.remaining(); + int oldPos = b.position(); + b.get(mergedArray, j, bLen); + b.position(oldPos); + j += bLen; + } + + return wrappedBuffer(mergedArray).order(order); + } + + /** + * Creates a new big-endian buffer whose content is the specified + * {@code string} encoded in the specified {@code charset}. + * The new buffer's {@code readerIndex} and {@code writerIndex} are + * {@code 0} and the length of the encoded string respectively. + */ + public static ByteBuf copiedBuffer(CharSequence string, Charset charset) { + if (string == null) { + throw new NullPointerException("string"); + } + + if (string instanceof CharBuffer) { + return copiedBuffer((CharBuffer) string, charset); + } + + return copiedBuffer(CharBuffer.wrap(string), charset); + } + + /** + * Creates a new big-endian buffer whose content is a subregion of + * the specified {@code string} encoded in the specified {@code charset}. + * The new buffer's {@code readerIndex} and {@code writerIndex} are + * {@code 0} and the length of the encoded string respectively. + */ + public static ByteBuf copiedBuffer( + CharSequence string, int offset, int length, Charset charset) { + if (string == null) { + throw new NullPointerException("string"); + } + if (length == 0) { + return EMPTY_BUFFER; + } + + if (string instanceof CharBuffer) { + CharBuffer buf = (CharBuffer) string; + if (buf.hasArray()) { + return copiedBuffer( + buf.array(), + buf.arrayOffset() + buf.position() + offset, + length, charset); + } + + buf = buf.slice(); + buf.limit(length); + buf.position(offset); + return copiedBuffer(buf, charset); + } + + return copiedBuffer(CharBuffer.wrap(string, offset, offset + length), charset); + } + + /** + * Creates a new big-endian buffer whose content is the specified + * {@code array} encoded in the specified {@code charset}. + * The new buffer's {@code readerIndex} and {@code writerIndex} are + * {@code 0} and the length of the encoded string respectively. + */ + public static ByteBuf copiedBuffer(char[] array, Charset charset) { + if (array == null) { + throw new NullPointerException("array"); + } + return copiedBuffer(array, 0, array.length, charset); + } + + /** + * Creates a new big-endian buffer whose content is a subregion of + * the specified {@code array} encoded in the specified {@code charset}. + * The new buffer's {@code readerIndex} and {@code writerIndex} are + * {@code 0} and the length of the encoded string respectively. + */ + public static ByteBuf copiedBuffer(char[] array, int offset, int length, Charset charset) { + if (array == null) { + throw new NullPointerException("array"); + } + if (length == 0) { + return EMPTY_BUFFER; + } + return copiedBuffer(CharBuffer.wrap(array, offset, length), charset); + } + + private static ByteBuf copiedBuffer(CharBuffer buffer, Charset charset) { + return ByteBufUtil.encodeString0(ALLOC, true, buffer, charset); + } + + /** + * Creates a read-only buffer which disallows any modification operations + * on the specified {@code buffer}. The new buffer has the same + * {@code readerIndex} and {@code writerIndex} with the specified + * {@code buffer}. + */ + public static ByteBuf unmodifiableBuffer(ByteBuf buffer) { + ByteOrder endianness = buffer.order(); + if (endianness == BIG_ENDIAN) { + return new ReadOnlyByteBuf(buffer); + } + + return new ReadOnlyByteBuf(buffer.order(BIG_ENDIAN)).order(LITTLE_ENDIAN); + } + + /** + * Creates a new 4-byte big-endian buffer that holds the specified 32-bit integer. + */ + public static ByteBuf copyInt(int value) { + ByteBuf buf = buffer(4); + buf.writeInt(value); + return buf; + } + + /** + * Create a big-endian buffer that holds a sequence of the specified 32-bit integers. + */ + public static ByteBuf copyInt(int... values) { + if (values == null || values.length == 0) { + return EMPTY_BUFFER; + } + ByteBuf buffer = buffer(values.length * 4); + for (int v: values) { + buffer.writeInt(v); + } + return buffer; + } + + /** + * Creates a new 2-byte big-endian buffer that holds the specified 16-bit integer. + */ + public static ByteBuf copyShort(int value) { + ByteBuf buf = buffer(2); + buf.writeShort(value); + return buf; + } + + /** + * Create a new big-endian buffer that holds a sequence of the specified 16-bit integers. + */ + public static ByteBuf copyShort(short... values) { + if (values == null || values.length == 0) { + return EMPTY_BUFFER; + } + ByteBuf buffer = buffer(values.length * 2); + for (int v: values) { + buffer.writeShort(v); + } + return buffer; + } + + /** + * Create a new big-endian buffer that holds a sequence of the specified 16-bit integers. + */ + public static ByteBuf copyShort(int... values) { + if (values == null || values.length == 0) { + return EMPTY_BUFFER; + } + ByteBuf buffer = buffer(values.length * 2); + for (int v: values) { + buffer.writeShort(v); + } + return buffer; + } + + /** + * Creates a new 3-byte big-endian buffer that holds the specified 24-bit integer. + */ + public static ByteBuf copyMedium(int value) { + ByteBuf buf = buffer(3); + buf.writeMedium(value); + return buf; + } + + /** + * Create a new big-endian buffer that holds a sequence of the specified 24-bit integers. + */ + public static ByteBuf copyMedium(int... values) { + if (values == null || values.length == 0) { + return EMPTY_BUFFER; + } + ByteBuf buffer = buffer(values.length * 3); + for (int v: values) { + buffer.writeMedium(v); + } + return buffer; + } + + /** + * Creates a new 8-byte big-endian buffer that holds the specified 64-bit integer. + */ + public static ByteBuf copyLong(long value) { + ByteBuf buf = buffer(8); + buf.writeLong(value); + return buf; + } + + /** + * Create a new big-endian buffer that holds a sequence of the specified 64-bit integers. + */ + public static ByteBuf copyLong(long... values) { + if (values == null || values.length == 0) { + return EMPTY_BUFFER; + } + ByteBuf buffer = buffer(values.length * 8); + for (long v: values) { + buffer.writeLong(v); + } + return buffer; + } + + /** + * Creates a new single-byte big-endian buffer that holds the specified boolean value. + */ + public static ByteBuf copyBoolean(boolean value) { + ByteBuf buf = buffer(1); + buf.writeBoolean(value); + return buf; + } + + /** + * Create a new big-endian buffer that holds a sequence of the specified boolean values. + */ + public static ByteBuf copyBoolean(boolean... values) { + if (values == null || values.length == 0) { + return EMPTY_BUFFER; + } + ByteBuf buffer = buffer(values.length); + for (boolean v: values) { + buffer.writeBoolean(v); + } + return buffer; + } + + /** + * Creates a new 4-byte big-endian buffer that holds the specified 32-bit floating point number. + */ + public static ByteBuf copyFloat(float value) { + ByteBuf buf = buffer(4); + buf.writeFloat(value); + return buf; + } + + /** + * Create a new big-endian buffer that holds a sequence of the specified 32-bit floating point numbers. + */ + public static ByteBuf copyFloat(float... values) { + if (values == null || values.length == 0) { + return EMPTY_BUFFER; + } + ByteBuf buffer = buffer(values.length * 4); + for (float v: values) { + buffer.writeFloat(v); + } + return buffer; + } + + /** + * Creates a new 8-byte big-endian buffer that holds the specified 64-bit floating point number. + */ + public static ByteBuf copyDouble(double value) { + ByteBuf buf = buffer(8); + buf.writeDouble(value); + return buf; + } + + /** + * Create a new big-endian buffer that holds a sequence of the specified 64-bit floating point numbers. + */ + public static ByteBuf copyDouble(double... values) { + if (values == null || values.length == 0) { + return EMPTY_BUFFER; + } + ByteBuf buffer = buffer(values.length * 8); + for (double v: values) { + buffer.writeDouble(v); + } + return buffer; + } + + /** + * Return a unreleasable view on the given {@link ByteBuf} which will just ignore release and retain calls. + */ + public static ByteBuf unreleasableBuffer(ByteBuf buf) { + return new UnreleasableByteBuf(buf); + } + + private Unpooled() { + // Unused + } +} diff --git a/common/src/common/net/buffer/UnpooledByteBufAllocator.java b/common/src/common/net/buffer/UnpooledByteBufAllocator.java new file mode 100644 index 0000000..8b6183d --- /dev/null +++ b/common/src/common/net/buffer/UnpooledByteBufAllocator.java @@ -0,0 +1,62 @@ +/* + * Copyright 2012 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ +package common.net.buffer; + +import common.net.util.internal.PlatformDependent; + +/** + * Simplistic {@link ByteBufAllocator} implementation that does not pool anything. + */ +public final class UnpooledByteBufAllocator extends AbstractByteBufAllocator { + + /** + * Default instance + */ + public static final UnpooledByteBufAllocator DEFAULT = + new UnpooledByteBufAllocator(PlatformDependent.directBufferPreferred()); + + /** + * Create a new instance + * + * @param preferDirect {@code true} if {@link #buffer(int)} should try to allocate a direct buffer rather than + * a heap buffer + */ + public UnpooledByteBufAllocator(boolean preferDirect) { + super(preferDirect); + } + + @Override + protected ByteBuf newHeapBuffer(int initialCapacity, int maxCapacity) { + return new UnpooledHeapByteBuf(this, initialCapacity, maxCapacity); + } + + @Override + protected ByteBuf newDirectBuffer(int initialCapacity, int maxCapacity) { + ByteBuf buf; + if (PlatformDependent.hasUnsafe()) { + buf = new UnpooledUnsafeDirectByteBuf(this, initialCapacity, maxCapacity); + } else { + buf = new UnpooledDirectByteBuf(this, initialCapacity, maxCapacity); + } + + return toLeakAwareBuffer(buf); + } + + @Override + public boolean isDirectBufferPooled() { + return false; + } +} diff --git a/common/src/common/net/buffer/UnpooledDirectByteBuf.java b/common/src/common/net/buffer/UnpooledDirectByteBuf.java new file mode 100644 index 0000000..76a738a --- /dev/null +++ b/common/src/common/net/buffer/UnpooledDirectByteBuf.java @@ -0,0 +1,604 @@ +/* + * Copyright 2012 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ +package common.net.buffer; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.nio.ByteBuffer; +import java.nio.ByteOrder; +import java.nio.channels.ClosedChannelException; +import java.nio.channels.GatheringByteChannel; +import java.nio.channels.ScatteringByteChannel; + +import common.net.util.internal.PlatformDependent; + +/** + * A NIO {@link ByteBuffer} based buffer. It is recommended to use {@link Unpooled#directBuffer(int)} + * and {@link Unpooled#wrappedBuffer(ByteBuffer)} instead of calling the + * constructor explicitly. + */ +public class UnpooledDirectByteBuf extends AbstractReferenceCountedByteBuf { + + private final ByteBufAllocator alloc; + + private ByteBuffer buffer; + private ByteBuffer tmpNioBuf; + private int capacity; + private boolean doNotFree; + + /** + * Creates a new direct buffer. + * + * @param initialCapacity the initial capacity of the underlying direct buffer + * @param maxCapacity the maximum capacity of the underlying direct buffer + */ + protected UnpooledDirectByteBuf(ByteBufAllocator alloc, int initialCapacity, int maxCapacity) { + super(maxCapacity); + if (alloc == null) { + throw new NullPointerException("alloc"); + } + if (initialCapacity < 0) { + throw new IllegalArgumentException("initialCapacity: " + initialCapacity); + } + if (maxCapacity < 0) { + throw new IllegalArgumentException("maxCapacity: " + maxCapacity); + } + if (initialCapacity > maxCapacity) { + throw new IllegalArgumentException(String.format( + "initialCapacity(%d) > maxCapacity(%d)", initialCapacity, maxCapacity)); + } + + this.alloc = alloc; + setByteBuffer(ByteBuffer.allocateDirect(initialCapacity)); + } + + /** + * Creates a new direct buffer by wrapping the specified initial buffer. + * + * @param maxCapacity the maximum capacity of the underlying direct buffer + */ + protected UnpooledDirectByteBuf(ByteBufAllocator alloc, ByteBuffer initialBuffer, int maxCapacity) { + super(maxCapacity); + if (alloc == null) { + throw new NullPointerException("alloc"); + } + if (initialBuffer == null) { + throw new NullPointerException("initialBuffer"); + } + if (!initialBuffer.isDirect()) { + throw new IllegalArgumentException("initialBuffer is not a direct buffer."); + } + if (initialBuffer.isReadOnly()) { + throw new IllegalArgumentException("initialBuffer is a read-only buffer."); + } + + int initialCapacity = initialBuffer.remaining(); + if (initialCapacity > maxCapacity) { + throw new IllegalArgumentException(String.format( + "initialCapacity(%d) > maxCapacity(%d)", initialCapacity, maxCapacity)); + } + + this.alloc = alloc; + doNotFree = true; + setByteBuffer(initialBuffer.slice().order(ByteOrder.BIG_ENDIAN)); + writerIndex(initialCapacity); + } + + /** + * Allocate a new direct {@link ByteBuffer} with the given initialCapacity. + */ + protected ByteBuffer allocateDirect(int initialCapacity) { + return ByteBuffer.allocateDirect(initialCapacity); + } + + /** + * Free a direct {@link ByteBuffer} + */ + protected void freeDirect(ByteBuffer buffer) { + PlatformDependent.freeDirectBuffer(buffer); + } + + private void setByteBuffer(ByteBuffer buffer) { + ByteBuffer oldBuffer = this.buffer; + if (oldBuffer != null) { + if (doNotFree) { + doNotFree = false; + } else { + freeDirect(oldBuffer); + } + } + + this.buffer = buffer; + tmpNioBuf = null; + capacity = buffer.remaining(); + } + + @Override + public boolean isDirect() { + return true; + } + + @Override + public int capacity() { + return capacity; + } + + @Override + public ByteBuf capacity(int newCapacity) { + ensureAccessible(); + if (newCapacity < 0 || newCapacity > maxCapacity()) { + throw new IllegalArgumentException("newCapacity: " + newCapacity); + } + + int readerIndex = readerIndex(); + int writerIndex = writerIndex(); + + int oldCapacity = capacity; + if (newCapacity > oldCapacity) { + ByteBuffer oldBuffer = buffer; + ByteBuffer newBuffer = allocateDirect(newCapacity); + oldBuffer.position(0).limit(oldBuffer.capacity()); + newBuffer.position(0).limit(oldBuffer.capacity()); + newBuffer.put(oldBuffer); + newBuffer.clear(); + setByteBuffer(newBuffer); + } else if (newCapacity < oldCapacity) { + ByteBuffer oldBuffer = buffer; + ByteBuffer newBuffer = allocateDirect(newCapacity); + if (readerIndex < newCapacity) { + if (writerIndex > newCapacity) { + writerIndex(writerIndex = newCapacity); + } + oldBuffer.position(readerIndex).limit(writerIndex); + newBuffer.position(readerIndex).limit(writerIndex); + newBuffer.put(oldBuffer); + newBuffer.clear(); + } else { + setIndex(newCapacity, newCapacity); + } + setByteBuffer(newBuffer); + } + return this; + } + + @Override + public ByteBufAllocator alloc() { + return alloc; + } + + @Override + public ByteOrder order() { + return ByteOrder.BIG_ENDIAN; + } + + @Override + public boolean hasArray() { + return false; + } + + @Override + public byte[] array() { + throw new UnsupportedOperationException("direct buffer"); + } + + @Override + public int arrayOffset() { + throw new UnsupportedOperationException("direct buffer"); + } + + @Override + public boolean hasMemoryAddress() { + return false; + } + + @Override + public long memoryAddress() { + throw new UnsupportedOperationException(); + } + + @Override + public byte getByte(int index) { + ensureAccessible(); + return _getByte(index); + } + + @Override + protected byte _getByte(int index) { + return buffer.get(index); + } + + @Override + public short getShort(int index) { + ensureAccessible(); + return _getShort(index); + } + + @Override + protected short _getShort(int index) { + return buffer.getShort(index); + } + + @Override + public int getUnsignedMedium(int index) { + ensureAccessible(); + return _getUnsignedMedium(index); + } + + @Override + protected int _getUnsignedMedium(int index) { + return (getByte(index) & 0xff) << 16 | (getByte(index + 1) & 0xff) << 8 | getByte(index + 2) & 0xff; + } + + @Override + public int getInt(int index) { + ensureAccessible(); + return _getInt(index); + } + + @Override + protected int _getInt(int index) { + return buffer.getInt(index); + } + + @Override + public long getLong(int index) { + ensureAccessible(); + return _getLong(index); + } + + @Override + protected long _getLong(int index) { + return buffer.getLong(index); + } + + @Override + public ByteBuf getBytes(int index, ByteBuf dst, int dstIndex, int length) { + checkDstIndex(index, length, dstIndex, dst.capacity()); + if (dst.hasArray()) { + getBytes(index, dst.array(), dst.arrayOffset() + dstIndex, length); + } else if (dst.nioBufferCount() > 0) { + for (ByteBuffer bb: dst.nioBuffers(dstIndex, length)) { + int bbLen = bb.remaining(); + getBytes(index, bb); + index += bbLen; + } + } else { + dst.setBytes(dstIndex, this, index, length); + } + return this; + } + + @Override + public ByteBuf getBytes(int index, byte[] dst, int dstIndex, int length) { + getBytes(index, dst, dstIndex, length, false); + return this; + } + + private void getBytes(int index, byte[] dst, int dstIndex, int length, boolean internal) { + checkDstIndex(index, length, dstIndex, dst.length); + + if (dstIndex < 0 || dstIndex > dst.length - length) { + throw new IndexOutOfBoundsException(String.format( + "dstIndex: %d, length: %d (expected: range(0, %d))", dstIndex, length, dst.length)); + } + + ByteBuffer tmpBuf; + if (internal) { + tmpBuf = internalNioBuffer(); + } else { + tmpBuf = buffer.duplicate(); + } + tmpBuf.clear().position(index).limit(index + length); + tmpBuf.get(dst, dstIndex, length); + } + + @Override + public ByteBuf readBytes(byte[] dst, int dstIndex, int length) { + checkReadableBytes(length); + getBytes(readerIndex, dst, dstIndex, length, true); + readerIndex += length; + return this; + } + + @Override + public ByteBuf getBytes(int index, ByteBuffer dst) { + getBytes(index, dst, false); + return this; + } + + private void getBytes(int index, ByteBuffer dst, boolean internal) { + checkIndex(index); + if (dst == null) { + throw new NullPointerException("dst"); + } + + int bytesToCopy = Math.min(capacity() - index, dst.remaining()); + ByteBuffer tmpBuf; + if (internal) { + tmpBuf = internalNioBuffer(); + } else { + tmpBuf = buffer.duplicate(); + } + tmpBuf.clear().position(index).limit(index + bytesToCopy); + dst.put(tmpBuf); + } + + @Override + public ByteBuf readBytes(ByteBuffer dst) { + int length = dst.remaining(); + checkReadableBytes(length); + getBytes(readerIndex, dst, true); + readerIndex += length; + return this; + } + + @Override + public ByteBuf setByte(int index, int value) { + ensureAccessible(); + _setByte(index, value); + return this; + } + + @Override + protected void _setByte(int index, int value) { + buffer.put(index, (byte) value); + } + + @Override + public ByteBuf setShort(int index, int value) { + ensureAccessible(); + _setShort(index, value); + return this; + } + + @Override + protected void _setShort(int index, int value) { + buffer.putShort(index, (short) value); + } + + @Override + public ByteBuf setMedium(int index, int value) { + ensureAccessible(); + _setMedium(index, value); + return this; + } + + @Override + protected void _setMedium(int index, int value) { + setByte(index, (byte) (value >>> 16)); + setByte(index + 1, (byte) (value >>> 8)); + setByte(index + 2, (byte) value); + } + + @Override + public ByteBuf setInt(int index, int value) { + ensureAccessible(); + _setInt(index, value); + return this; + } + + @Override + protected void _setInt(int index, int value) { + buffer.putInt(index, value); + } + + @Override + public ByteBuf setLong(int index, long value) { + ensureAccessible(); + _setLong(index, value); + return this; + } + + @Override + protected void _setLong(int index, long value) { + buffer.putLong(index, value); + } + + @Override + public ByteBuf setBytes(int index, ByteBuf src, int srcIndex, int length) { + checkSrcIndex(index, length, srcIndex, src.capacity()); + if (src.nioBufferCount() > 0) { + for (ByteBuffer bb: src.nioBuffers(srcIndex, length)) { + int bbLen = bb.remaining(); + setBytes(index, bb); + index += bbLen; + } + } else { + src.getBytes(srcIndex, this, index, length); + } + return this; + } + + @Override + public ByteBuf setBytes(int index, byte[] src, int srcIndex, int length) { + checkSrcIndex(index, length, srcIndex, src.length); + ByteBuffer tmpBuf = internalNioBuffer(); + tmpBuf.clear().position(index).limit(index + length); + tmpBuf.put(src, srcIndex, length); + return this; + } + + @Override + public ByteBuf setBytes(int index, ByteBuffer src) { + ensureAccessible(); + ByteBuffer tmpBuf = internalNioBuffer(); + if (src == tmpBuf) { + src = src.duplicate(); + } + + tmpBuf.clear().position(index).limit(index + src.remaining()); + tmpBuf.put(src); + return this; + } + + @Override + public ByteBuf getBytes(int index, OutputStream out, int length) throws IOException { + getBytes(index, out, length, false); + return this; + } + + private void getBytes(int index, OutputStream out, int length, boolean internal) throws IOException { + ensureAccessible(); + if (length == 0) { + return; + } + + if (buffer.hasArray()) { + out.write(buffer.array(), index + buffer.arrayOffset(), length); + } else { + byte[] tmp = new byte[length]; + ByteBuffer tmpBuf; + if (internal) { + tmpBuf = internalNioBuffer(); + } else { + tmpBuf = buffer.duplicate(); + } + tmpBuf.clear().position(index); + tmpBuf.get(tmp); + out.write(tmp); + } + } + + @Override + public ByteBuf readBytes(OutputStream out, int length) throws IOException { + checkReadableBytes(length); + getBytes(readerIndex, out, length, true); + readerIndex += length; + return this; + } + + @Override + public int getBytes(int index, GatheringByteChannel out, int length) throws IOException { + return getBytes(index, out, length, false); + } + + private int getBytes(int index, GatheringByteChannel out, int length, boolean internal) throws IOException { + ensureAccessible(); + if (length == 0) { + return 0; + } + + ByteBuffer tmpBuf; + if (internal) { + tmpBuf = internalNioBuffer(); + } else { + tmpBuf = buffer.duplicate(); + } + tmpBuf.clear().position(index).limit(index + length); + return out.write(tmpBuf); + } + + @Override + public int readBytes(GatheringByteChannel out, int length) throws IOException { + checkReadableBytes(length); + int readBytes = getBytes(readerIndex, out, length, true); + readerIndex += readBytes; + return readBytes; + } + + @Override + public int setBytes(int index, InputStream in, int length) throws IOException { + ensureAccessible(); + if (buffer.hasArray()) { + return in.read(buffer.array(), buffer.arrayOffset() + index, length); + } else { + byte[] tmp = new byte[length]; + int readBytes = in.read(tmp); + if (readBytes <= 0) { + return readBytes; + } + ByteBuffer tmpBuf = internalNioBuffer(); + tmpBuf.clear().position(index); + tmpBuf.put(tmp, 0, readBytes); + return readBytes; + } + } + + @Override + public int setBytes(int index, ScatteringByteChannel in, int length) throws IOException { + ensureAccessible(); + ByteBuffer tmpBuf = internalNioBuffer(); + tmpBuf.clear().position(index).limit(index + length); + try { + return in.read(tmpNioBuf); + } catch (ClosedChannelException ignored) { + return -1; + } + } + + @Override + public int nioBufferCount() { + return 1; + } + + @Override + public ByteBuffer[] nioBuffers(int index, int length) { + return new ByteBuffer[] { nioBuffer(index, length) }; + } + + @Override + public ByteBuf copy(int index, int length) { + ensureAccessible(); + ByteBuffer src; + try { + src = (ByteBuffer) buffer.duplicate().clear().position(index).limit(index + length); + } catch (IllegalArgumentException ignored) { + throw new IndexOutOfBoundsException("Too many bytes to read - Need " + (index + length)); + } + + return alloc().directBuffer(length, maxCapacity()).writeBytes(src); + } + + @Override + public ByteBuffer internalNioBuffer(int index, int length) { + checkIndex(index, length); + return (ByteBuffer) internalNioBuffer().clear().position(index).limit(index + length); + } + + private ByteBuffer internalNioBuffer() { + ByteBuffer tmpNioBuf = this.tmpNioBuf; + if (tmpNioBuf == null) { + this.tmpNioBuf = tmpNioBuf = buffer.duplicate(); + } + return tmpNioBuf; + } + + @Override + public ByteBuffer nioBuffer(int index, int length) { + checkIndex(index, length); + return ((ByteBuffer) buffer.duplicate().position(index).limit(index + length)).slice(); + } + + @Override + protected void deallocate() { + ByteBuffer buffer = this.buffer; + if (buffer == null) { + return; + } + + this.buffer = null; + + if (!doNotFree) { + freeDirect(buffer); + } + } + + @Override + public ByteBuf unwrap() { + return null; + } +} diff --git a/common/src/common/net/buffer/UnpooledHeapByteBuf.java b/common/src/common/net/buffer/UnpooledHeapByteBuf.java new file mode 100644 index 0000000..e56951f --- /dev/null +++ b/common/src/common/net/buffer/UnpooledHeapByteBuf.java @@ -0,0 +1,449 @@ +/* + * Copyright 2012 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ +package common.net.buffer; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.nio.ByteBuffer; +import java.nio.ByteOrder; +import java.nio.channels.ClosedChannelException; +import java.nio.channels.GatheringByteChannel; +import java.nio.channels.ScatteringByteChannel; + +import common.net.util.internal.PlatformDependent; + +/** + * Big endian Java heap buffer implementation. + */ +public class UnpooledHeapByteBuf extends AbstractReferenceCountedByteBuf { + + private final ByteBufAllocator alloc; + private byte[] array; + private ByteBuffer tmpNioBuf; + + /** + * Creates a new heap buffer with a newly allocated byte array. + * + * @param initialCapacity the initial capacity of the underlying byte array + * @param maxCapacity the max capacity of the underlying byte array + */ + protected UnpooledHeapByteBuf(ByteBufAllocator alloc, int initialCapacity, int maxCapacity) { + this(alloc, new byte[initialCapacity], 0, 0, maxCapacity); + } + + /** + * Creates a new heap buffer with an existing byte array. + * + * @param initialArray the initial underlying byte array + * @param maxCapacity the max capacity of the underlying byte array + */ + protected UnpooledHeapByteBuf(ByteBufAllocator alloc, byte[] initialArray, int maxCapacity) { + this(alloc, initialArray, 0, initialArray.length, maxCapacity); + } + + private UnpooledHeapByteBuf( + ByteBufAllocator alloc, byte[] initialArray, int readerIndex, int writerIndex, int maxCapacity) { + + super(maxCapacity); + + if (alloc == null) { + throw new NullPointerException("alloc"); + } + if (initialArray == null) { + throw new NullPointerException("initialArray"); + } + if (initialArray.length > maxCapacity) { + throw new IllegalArgumentException(String.format( + "initialCapacity(%d) > maxCapacity(%d)", initialArray.length, maxCapacity)); + } + + this.alloc = alloc; + setArray(initialArray); + setIndex(readerIndex, writerIndex); + } + + private void setArray(byte[] initialArray) { + array = initialArray; + tmpNioBuf = null; + } + + @Override + public ByteBufAllocator alloc() { + return alloc; + } + + @Override + public ByteOrder order() { + return ByteOrder.BIG_ENDIAN; + } + + @Override + public boolean isDirect() { + return false; + } + + @Override + public int capacity() { + ensureAccessible(); + return array.length; + } + + @Override + public ByteBuf capacity(int newCapacity) { + ensureAccessible(); + if (newCapacity < 0 || newCapacity > maxCapacity()) { + throw new IllegalArgumentException("newCapacity: " + newCapacity); + } + + int oldCapacity = array.length; + if (newCapacity > oldCapacity) { + byte[] newArray = new byte[newCapacity]; + System.arraycopy(array, 0, newArray, 0, array.length); + setArray(newArray); + } else if (newCapacity < oldCapacity) { + byte[] newArray = new byte[newCapacity]; + int readerIndex = readerIndex(); + if (readerIndex < newCapacity) { + int writerIndex = writerIndex(); + if (writerIndex > newCapacity) { + writerIndex(writerIndex = newCapacity); + } + System.arraycopy(array, readerIndex, newArray, readerIndex, writerIndex - readerIndex); + } else { + setIndex(newCapacity, newCapacity); + } + setArray(newArray); + } + return this; + } + + @Override + public boolean hasArray() { + return true; + } + + @Override + public byte[] array() { + ensureAccessible(); + return array; + } + + @Override + public int arrayOffset() { + return 0; + } + + @Override + public boolean hasMemoryAddress() { + return false; + } + + @Override + public long memoryAddress() { + throw new UnsupportedOperationException(); + } + + @Override + public ByteBuf getBytes(int index, ByteBuf dst, int dstIndex, int length) { + checkDstIndex(index, length, dstIndex, dst.capacity()); + if (dst.hasMemoryAddress()) { + PlatformDependent.copyMemory(array, index, dst.memoryAddress() + dstIndex, length); + } else if (dst.hasArray()) { + getBytes(index, dst.array(), dst.arrayOffset() + dstIndex, length); + } else { + dst.setBytes(dstIndex, array, index, length); + } + return this; + } + + @Override + public ByteBuf getBytes(int index, byte[] dst, int dstIndex, int length) { + checkDstIndex(index, length, dstIndex, dst.length); + System.arraycopy(array, index, dst, dstIndex, length); + return this; + } + + @Override + public ByteBuf getBytes(int index, ByteBuffer dst) { + ensureAccessible(); + dst.put(array, index, Math.min(capacity() - index, dst.remaining())); + return this; + } + + @Override + public ByteBuf getBytes(int index, OutputStream out, int length) throws IOException { + ensureAccessible(); + out.write(array, index, length); + return this; + } + + @Override + public int getBytes(int index, GatheringByteChannel out, int length) throws IOException { + ensureAccessible(); + return getBytes(index, out, length, false); + } + + private int getBytes(int index, GatheringByteChannel out, int length, boolean internal) throws IOException { + ensureAccessible(); + ByteBuffer tmpBuf; + if (internal) { + tmpBuf = internalNioBuffer(); + } else { + tmpBuf = ByteBuffer.wrap(array); + } + return out.write((ByteBuffer) tmpBuf.clear().position(index).limit(index + length)); + } + + @Override + public int readBytes(GatheringByteChannel out, int length) throws IOException { + checkReadableBytes(length); + int readBytes = getBytes(readerIndex, out, length, true); + readerIndex += readBytes; + return readBytes; + } + + @Override + public ByteBuf setBytes(int index, ByteBuf src, int srcIndex, int length) { + checkSrcIndex(index, length, srcIndex, src.capacity()); + if (src.hasMemoryAddress()) { + PlatformDependent.copyMemory(src.memoryAddress() + srcIndex, array, index, length); + } else if (src.hasArray()) { + setBytes(index, src.array(), src.arrayOffset() + srcIndex, length); + } else { + src.getBytes(srcIndex, array, index, length); + } + return this; + } + + @Override + public ByteBuf setBytes(int index, byte[] src, int srcIndex, int length) { + checkSrcIndex(index, length, srcIndex, src.length); + System.arraycopy(src, srcIndex, array, index, length); + return this; + } + + @Override + public ByteBuf setBytes(int index, ByteBuffer src) { + ensureAccessible(); + src.get(array, index, src.remaining()); + return this; + } + + @Override + public int setBytes(int index, InputStream in, int length) throws IOException { + ensureAccessible(); + return in.read(array, index, length); + } + + @Override + public int setBytes(int index, ScatteringByteChannel in, int length) throws IOException { + ensureAccessible(); + try { + return in.read((ByteBuffer) internalNioBuffer().clear().position(index).limit(index + length)); + } catch (ClosedChannelException ignored) { + return -1; + } + } + + @Override + public int nioBufferCount() { + return 1; + } + + @Override + public ByteBuffer nioBuffer(int index, int length) { + ensureAccessible(); + return ByteBuffer.wrap(array, index, length).slice(); + } + + @Override + public ByteBuffer[] nioBuffers(int index, int length) { + return new ByteBuffer[] { nioBuffer(index, length) }; + } + + @Override + public ByteBuffer internalNioBuffer(int index, int length) { + checkIndex(index, length); + return (ByteBuffer) internalNioBuffer().clear().position(index).limit(index + length); + } + + @Override + public byte getByte(int index) { + ensureAccessible(); + return _getByte(index); + } + + @Override + protected byte _getByte(int index) { + return array[index]; + } + + @Override + public short getShort(int index) { + ensureAccessible(); + return _getShort(index); + } + + @Override + protected short _getShort(int index) { + return (short) (array[index] << 8 | array[index + 1] & 0xFF); + } + + @Override + public int getUnsignedMedium(int index) { + ensureAccessible(); + return _getUnsignedMedium(index); + } + + @Override + protected int _getUnsignedMedium(int index) { + return (array[index] & 0xff) << 16 | + (array[index + 1] & 0xff) << 8 | + array[index + 2] & 0xff; + } + + @Override + public int getInt(int index) { + ensureAccessible(); + return _getInt(index); + } + + @Override + protected int _getInt(int index) { + return (array[index] & 0xff) << 24 | + (array[index + 1] & 0xff) << 16 | + (array[index + 2] & 0xff) << 8 | + array[index + 3] & 0xff; + } + + @Override + public long getLong(int index) { + ensureAccessible(); + return _getLong(index); + } + + @Override + protected long _getLong(int index) { + return ((long) array[index] & 0xff) << 56 | + ((long) array[index + 1] & 0xff) << 48 | + ((long) array[index + 2] & 0xff) << 40 | + ((long) array[index + 3] & 0xff) << 32 | + ((long) array[index + 4] & 0xff) << 24 | + ((long) array[index + 5] & 0xff) << 16 | + ((long) array[index + 6] & 0xff) << 8 | + (long) array[index + 7] & 0xff; + } + + @Override + public ByteBuf setByte(int index, int value) { + ensureAccessible(); + _setByte(index, value); + return this; + } + + @Override + protected void _setByte(int index, int value) { + array[index] = (byte) value; + } + + @Override + public ByteBuf setShort(int index, int value) { + ensureAccessible(); + _setShort(index, value); + return this; + } + + @Override + protected void _setShort(int index, int value) { + array[index] = (byte) (value >>> 8); + array[index + 1] = (byte) value; + } + + @Override + public ByteBuf setMedium(int index, int value) { + ensureAccessible(); + _setMedium(index, value); + return this; + } + + @Override + protected void _setMedium(int index, int value) { + array[index] = (byte) (value >>> 16); + array[index + 1] = (byte) (value >>> 8); + array[index + 2] = (byte) value; + } + + @Override + public ByteBuf setInt(int index, int value) { + ensureAccessible(); + _setInt(index, value); + return this; + } + + @Override + protected void _setInt(int index, int value) { + array[index] = (byte) (value >>> 24); + array[index + 1] = (byte) (value >>> 16); + array[index + 2] = (byte) (value >>> 8); + array[index + 3] = (byte) value; + } + + @Override + public ByteBuf setLong(int index, long value) { + ensureAccessible(); + _setLong(index, value); + return this; + } + + @Override + protected void _setLong(int index, long value) { + array[index] = (byte) (value >>> 56); + array[index + 1] = (byte) (value >>> 48); + array[index + 2] = (byte) (value >>> 40); + array[index + 3] = (byte) (value >>> 32); + array[index + 4] = (byte) (value >>> 24); + array[index + 5] = (byte) (value >>> 16); + array[index + 6] = (byte) (value >>> 8); + array[index + 7] = (byte) value; + } + + @Override + public ByteBuf copy(int index, int length) { + checkIndex(index, length); + byte[] copiedArray = new byte[length]; + System.arraycopy(array, index, copiedArray, 0, length); + return new UnpooledHeapByteBuf(alloc(), copiedArray, maxCapacity()); + } + + private ByteBuffer internalNioBuffer() { + ByteBuffer tmpNioBuf = this.tmpNioBuf; + if (tmpNioBuf == null) { + this.tmpNioBuf = tmpNioBuf = ByteBuffer.wrap(array); + } + return tmpNioBuf; + } + + @Override + protected void deallocate() { + array = null; + } + + @Override + public ByteBuf unwrap() { + return null; + } +} diff --git a/common/src/common/net/buffer/UnpooledUnsafeDirectByteBuf.java b/common/src/common/net/buffer/UnpooledUnsafeDirectByteBuf.java new file mode 100644 index 0000000..a098a1a --- /dev/null +++ b/common/src/common/net/buffer/UnpooledUnsafeDirectByteBuf.java @@ -0,0 +1,524 @@ +/* + * Copyright 2012 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ +package common.net.buffer; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.nio.ByteBuffer; +import java.nio.ByteOrder; +import java.nio.channels.ClosedChannelException; +import java.nio.channels.GatheringByteChannel; +import java.nio.channels.ScatteringByteChannel; + +import common.net.util.internal.PlatformDependent; + +/** + * A NIO {@link ByteBuffer} based buffer. It is recommended to use {@link Unpooled#directBuffer(int)} + * and {@link Unpooled#wrappedBuffer(ByteBuffer)} instead of calling the + * constructor explicitly. + */ +public class UnpooledUnsafeDirectByteBuf extends AbstractReferenceCountedByteBuf { + + private static final boolean NATIVE_ORDER = ByteOrder.nativeOrder() == ByteOrder.BIG_ENDIAN; + + private final ByteBufAllocator alloc; + + private long memoryAddress; + private ByteBuffer buffer; + private ByteBuffer tmpNioBuf; + private int capacity; + private boolean doNotFree; + + /** + * Creates a new direct buffer. + * + * @param initialCapacity the initial capacity of the underlying direct buffer + * @param maxCapacity the maximum capacity of the underlying direct buffer + */ + protected UnpooledUnsafeDirectByteBuf(ByteBufAllocator alloc, int initialCapacity, int maxCapacity) { + super(maxCapacity); + if (alloc == null) { + throw new NullPointerException("alloc"); + } + if (initialCapacity < 0) { + throw new IllegalArgumentException("initialCapacity: " + initialCapacity); + } + if (maxCapacity < 0) { + throw new IllegalArgumentException("maxCapacity: " + maxCapacity); + } + if (initialCapacity > maxCapacity) { + throw new IllegalArgumentException(String.format( + "initialCapacity(%d) > maxCapacity(%d)", initialCapacity, maxCapacity)); + } + + this.alloc = alloc; + setByteBuffer(allocateDirect(initialCapacity)); + } + + /** + * Creates a new direct buffer by wrapping the specified initial buffer. + * + * @param maxCapacity the maximum capacity of the underlying direct buffer + */ + protected UnpooledUnsafeDirectByteBuf(ByteBufAllocator alloc, ByteBuffer initialBuffer, int maxCapacity) { + super(maxCapacity); + if (alloc == null) { + throw new NullPointerException("alloc"); + } + if (initialBuffer == null) { + throw new NullPointerException("initialBuffer"); + } + if (!initialBuffer.isDirect()) { + throw new IllegalArgumentException("initialBuffer is not a direct buffer."); + } + if (initialBuffer.isReadOnly()) { + throw new IllegalArgumentException("initialBuffer is a read-only buffer."); + } + + int initialCapacity = initialBuffer.remaining(); + if (initialCapacity > maxCapacity) { + throw new IllegalArgumentException(String.format( + "initialCapacity(%d) > maxCapacity(%d)", initialCapacity, maxCapacity)); + } + + this.alloc = alloc; + doNotFree = true; + setByteBuffer(initialBuffer.slice().order(ByteOrder.BIG_ENDIAN)); + writerIndex(initialCapacity); + } + + /** + * Allocate a new direct {@link ByteBuffer} with the given initialCapacity. + */ + protected ByteBuffer allocateDirect(int initialCapacity) { + return ByteBuffer.allocateDirect(initialCapacity); + } + + /** + * Free a direct {@link ByteBuffer} + */ + protected void freeDirect(ByteBuffer buffer) { + PlatformDependent.freeDirectBuffer(buffer); + } + + private void setByteBuffer(ByteBuffer buffer) { + ByteBuffer oldBuffer = this.buffer; + if (oldBuffer != null) { + if (doNotFree) { + doNotFree = false; + } else { + freeDirect(oldBuffer); + } + } + + this.buffer = buffer; + memoryAddress = PlatformDependent.directBufferAddress(buffer); + tmpNioBuf = null; + capacity = buffer.remaining(); + } + + @Override + public boolean isDirect() { + return true; + } + + @Override + public int capacity() { + return capacity; + } + + @Override + public ByteBuf capacity(int newCapacity) { + ensureAccessible(); + if (newCapacity < 0 || newCapacity > maxCapacity()) { + throw new IllegalArgumentException("newCapacity: " + newCapacity); + } + + int readerIndex = readerIndex(); + int writerIndex = writerIndex(); + + int oldCapacity = capacity; + if (newCapacity > oldCapacity) { + ByteBuffer oldBuffer = buffer; + ByteBuffer newBuffer = allocateDirect(newCapacity); + oldBuffer.position(0).limit(oldBuffer.capacity()); + newBuffer.position(0).limit(oldBuffer.capacity()); + newBuffer.put(oldBuffer); + newBuffer.clear(); + setByteBuffer(newBuffer); + } else if (newCapacity < oldCapacity) { + ByteBuffer oldBuffer = buffer; + ByteBuffer newBuffer = allocateDirect(newCapacity); + if (readerIndex < newCapacity) { + if (writerIndex > newCapacity) { + writerIndex(writerIndex = newCapacity); + } + oldBuffer.position(readerIndex).limit(writerIndex); + newBuffer.position(readerIndex).limit(writerIndex); + newBuffer.put(oldBuffer); + newBuffer.clear(); + } else { + setIndex(newCapacity, newCapacity); + } + setByteBuffer(newBuffer); + } + return this; + } + + @Override + public ByteBufAllocator alloc() { + return alloc; + } + + @Override + public ByteOrder order() { + return ByteOrder.BIG_ENDIAN; + } + + @Override + public boolean hasArray() { + return false; + } + + @Override + public byte[] array() { + throw new UnsupportedOperationException("direct buffer"); + } + + @Override + public int arrayOffset() { + throw new UnsupportedOperationException("direct buffer"); + } + + @Override + public boolean hasMemoryAddress() { + return true; + } + + @Override + public long memoryAddress() { + return memoryAddress; + } + + @Override + protected byte _getByte(int index) { + return PlatformDependent.getByte(addr(index)); + } + + @Override + protected short _getShort(int index) { + short v = PlatformDependent.getShort(addr(index)); + return NATIVE_ORDER? v : Short.reverseBytes(v); + } + + @Override + protected int _getUnsignedMedium(int index) { + long addr = addr(index); + return (PlatformDependent.getByte(addr) & 0xff) << 16 | + (PlatformDependent.getByte(addr + 1) & 0xff) << 8 | + PlatformDependent.getByte(addr + 2) & 0xff; + } + + @Override + protected int _getInt(int index) { + int v = PlatformDependent.getInt(addr(index)); + return NATIVE_ORDER? v : Integer.reverseBytes(v); + } + + @Override + protected long _getLong(int index) { + long v = PlatformDependent.getLong(addr(index)); + return NATIVE_ORDER? v : Long.reverseBytes(v); + } + + @Override + public ByteBuf getBytes(int index, ByteBuf dst, int dstIndex, int length) { + checkIndex(index, length); + if (dst == null) { + throw new NullPointerException("dst"); + } + if (dstIndex < 0 || dstIndex > dst.capacity() - length) { + throw new IndexOutOfBoundsException("dstIndex: " + dstIndex); + } + + if (dst.hasMemoryAddress()) { + PlatformDependent.copyMemory(addr(index), dst.memoryAddress() + dstIndex, length); + } else if (dst.hasArray()) { + PlatformDependent.copyMemory(addr(index), dst.array(), dst.arrayOffset() + dstIndex, length); + } else { + dst.setBytes(dstIndex, this, index, length); + } + return this; + } + + @Override + public ByteBuf getBytes(int index, byte[] dst, int dstIndex, int length) { + checkIndex(index, length); + if (dst == null) { + throw new NullPointerException("dst"); + } + if (dstIndex < 0 || dstIndex > dst.length - length) { + throw new IndexOutOfBoundsException(String.format( + "dstIndex: %d, length: %d (expected: range(0, %d))", dstIndex, length, dst.length)); + } + + if (length != 0) { + PlatformDependent.copyMemory(addr(index), dst, dstIndex, length); + } + return this; + } + + @Override + public ByteBuf getBytes(int index, ByteBuffer dst) { + getBytes(index, dst, false); + return this; + } + + private void getBytes(int index, ByteBuffer dst, boolean internal) { + checkIndex(index); + if (dst == null) { + throw new NullPointerException("dst"); + } + + int bytesToCopy = Math.min(capacity() - index, dst.remaining()); + ByteBuffer tmpBuf; + if (internal) { + tmpBuf = internalNioBuffer(); + } else { + tmpBuf = buffer.duplicate(); + } + tmpBuf.clear().position(index).limit(index + bytesToCopy); + dst.put(tmpBuf); + } + + @Override + public ByteBuf readBytes(ByteBuffer dst) { + int length = dst.remaining(); + checkReadableBytes(length); + getBytes(readerIndex, dst, true); + readerIndex += length; + return this; + } + + @Override + protected void _setByte(int index, int value) { + PlatformDependent.putByte(addr(index), (byte) value); + } + + @Override + protected void _setShort(int index, int value) { + PlatformDependent.putShort(addr(index), NATIVE_ORDER ? (short) value : Short.reverseBytes((short) value)); + } + + @Override + protected void _setMedium(int index, int value) { + long addr = addr(index); + PlatformDependent.putByte(addr, (byte) (value >>> 16)); + PlatformDependent.putByte(addr + 1, (byte) (value >>> 8)); + PlatformDependent.putByte(addr + 2, (byte) value); + } + + @Override + protected void _setInt(int index, int value) { + PlatformDependent.putInt(addr(index), NATIVE_ORDER ? value : Integer.reverseBytes(value)); + } + + @Override + protected void _setLong(int index, long value) { + PlatformDependent.putLong(addr(index), NATIVE_ORDER ? value : Long.reverseBytes(value)); + } + + @Override + public ByteBuf setBytes(int index, ByteBuf src, int srcIndex, int length) { + checkIndex(index, length); + if (src == null) { + throw new NullPointerException("src"); + } + if (srcIndex < 0 || srcIndex > src.capacity() - length) { + throw new IndexOutOfBoundsException("srcIndex: " + srcIndex); + } + + if (length != 0) { + if (src.hasMemoryAddress()) { + PlatformDependent.copyMemory(src.memoryAddress() + srcIndex, addr(index), length); + } else if (src.hasArray()) { + PlatformDependent.copyMemory(src.array(), src.arrayOffset() + srcIndex, addr(index), length); + } else { + src.getBytes(srcIndex, this, index, length); + } + } + return this; + } + + @Override + public ByteBuf setBytes(int index, byte[] src, int srcIndex, int length) { + checkIndex(index, length); + if (length != 0) { + PlatformDependent.copyMemory(src, srcIndex, addr(index), length); + } + return this; + } + + @Override + public ByteBuf setBytes(int index, ByteBuffer src) { + ensureAccessible(); + ByteBuffer tmpBuf = internalNioBuffer(); + if (src == tmpBuf) { + src = src.duplicate(); + } + + tmpBuf.clear().position(index).limit(index + src.remaining()); + tmpBuf.put(src); + return this; + } + + @Override + public ByteBuf getBytes(int index, OutputStream out, int length) throws IOException { + ensureAccessible(); + if (length != 0) { + byte[] tmp = new byte[length]; + PlatformDependent.copyMemory(addr(index), tmp, 0, length); + out.write(tmp); + } + return this; + } + + @Override + public int getBytes(int index, GatheringByteChannel out, int length) throws IOException { + return getBytes(index, out, length, false); + } + + private int getBytes(int index, GatheringByteChannel out, int length, boolean internal) throws IOException { + ensureAccessible(); + if (length == 0) { + return 0; + } + + ByteBuffer tmpBuf; + if (internal) { + tmpBuf = internalNioBuffer(); + } else { + tmpBuf = buffer.duplicate(); + } + tmpBuf.clear().position(index).limit(index + length); + return out.write(tmpBuf); + } + + @Override + public int readBytes(GatheringByteChannel out, int length) throws IOException { + checkReadableBytes(length); + int readBytes = getBytes(readerIndex, out, length, true); + readerIndex += readBytes; + return readBytes; + } + + @Override + public int setBytes(int index, InputStream in, int length) throws IOException { + checkIndex(index, length); + byte[] tmp = new byte[length]; + int readBytes = in.read(tmp); + if (readBytes > 0) { + PlatformDependent.copyMemory(tmp, 0, addr(index), readBytes); + } + return readBytes; + } + + @Override + public int setBytes(int index, ScatteringByteChannel in, int length) throws IOException { + ensureAccessible(); + ByteBuffer tmpBuf = internalNioBuffer(); + tmpBuf.clear().position(index).limit(index + length); + try { + return in.read(tmpBuf); + } catch (ClosedChannelException ignored) { + return -1; + } + } + + @Override + public int nioBufferCount() { + return 1; + } + + @Override + public ByteBuffer[] nioBuffers(int index, int length) { + return new ByteBuffer[] { nioBuffer(index, length) }; + } + + @Override + public ByteBuf copy(int index, int length) { + checkIndex(index, length); + ByteBuf copy = alloc().directBuffer(length, maxCapacity()); + if (length != 0) { + if (copy.hasMemoryAddress()) { + PlatformDependent.copyMemory(addr(index), copy.memoryAddress(), length); + copy.setIndex(0, length); + } else { + copy.writeBytes(this, index, length); + } + } + return copy; + } + + @Override + public ByteBuffer internalNioBuffer(int index, int length) { + checkIndex(index, length); + return (ByteBuffer) internalNioBuffer().clear().position(index).limit(index + length); + } + + private ByteBuffer internalNioBuffer() { + ByteBuffer tmpNioBuf = this.tmpNioBuf; + if (tmpNioBuf == null) { + this.tmpNioBuf = tmpNioBuf = buffer.duplicate(); + } + return tmpNioBuf; + } + + @Override + public ByteBuffer nioBuffer(int index, int length) { + checkIndex(index, length); + return ((ByteBuffer) buffer.duplicate().position(index).limit(index + length)).slice(); + } + + @Override + protected void deallocate() { + ByteBuffer buffer = this.buffer; + if (buffer == null) { + return; + } + + this.buffer = null; + + if (!doNotFree) { + freeDirect(buffer); + } + } + + @Override + public ByteBuf unwrap() { + return null; + } + + long addr(int index) { + return memoryAddress + index; + } + + @Override + protected SwappedByteBuf newSwappedByteBuf() { + return new UnsafeDirectSwappedByteBuf(this); + } +} diff --git a/common/src/common/net/buffer/UnreleasableByteBuf.java b/common/src/common/net/buffer/UnreleasableByteBuf.java new file mode 100644 index 0000000..3a677ba --- /dev/null +++ b/common/src/common/net/buffer/UnreleasableByteBuf.java @@ -0,0 +1,87 @@ +/* + * Copyright 2013 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ +package common.net.buffer; + +import java.nio.ByteOrder; + +/** + * A {@link ByteBuf} implementation that wraps another buffer to prevent a user from increasing or decreasing the + * wrapped buffer's reference count. + */ +final class UnreleasableByteBuf extends WrappedByteBuf { + + private SwappedByteBuf swappedBuf; + + UnreleasableByteBuf(ByteBuf buf) { + super(buf); + } + + @Override + public ByteBuf order(ByteOrder endianness) { + if (endianness == null) { + throw new NullPointerException("endianness"); + } + if (endianness == order()) { + return this; + } + + SwappedByteBuf swappedBuf = this.swappedBuf; + if (swappedBuf == null) { + this.swappedBuf = swappedBuf = new SwappedByteBuf(this); + } + return swappedBuf; + } + + @Override + public ByteBuf readSlice(int length) { + return new UnreleasableByteBuf(buf.readSlice(length)); + } + + @Override + public ByteBuf slice() { + return new UnreleasableByteBuf(buf.slice()); + } + + @Override + public ByteBuf slice(int index, int length) { + return new UnreleasableByteBuf(buf.slice(index, length)); + } + + @Override + public ByteBuf duplicate() { + return new UnreleasableByteBuf(buf.duplicate()); + } + + @Override + public ByteBuf retain(int increment) { + return this; + } + + @Override + public ByteBuf retain() { + return this; + } + + @Override + public boolean release() { + return false; + } + + @Override + public boolean release(int decrement) { + return false; + } +} diff --git a/common/src/common/net/buffer/UnsafeDirectSwappedByteBuf.java b/common/src/common/net/buffer/UnsafeDirectSwappedByteBuf.java new file mode 100644 index 0000000..8d5f55c --- /dev/null +++ b/common/src/common/net/buffer/UnsafeDirectSwappedByteBuf.java @@ -0,0 +1,186 @@ +/* +* Copyright 2014 The Netty Project +* +* The Netty Project licenses this file to you under the Apache License, +* version 2.0 (the "License"); you may not use this file except in compliance +* with the License. You may obtain a copy of the License at: +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +* License for the specific language governing permissions and limitations +* under the License. +*/ + +package common.net.buffer; + +import java.nio.ByteOrder; + +import common.net.util.internal.PlatformDependent; + +/** + * Special {@link SwappedByteBuf} for {@link ByteBuf}s that are backed by a {@code memoryAddress}. + */ +final class UnsafeDirectSwappedByteBuf extends SwappedByteBuf { + private static final boolean NATIVE_ORDER = ByteOrder.nativeOrder() == ByteOrder.BIG_ENDIAN; + private final boolean nativeByteOrder; + private final AbstractByteBuf wrapped; + + UnsafeDirectSwappedByteBuf(AbstractByteBuf buf) { + super(buf); + wrapped = buf; + nativeByteOrder = NATIVE_ORDER == (order() == ByteOrder.BIG_ENDIAN); + } + + private long addr(int index) { + // We need to call wrapped.memoryAddress() everytime and NOT cache it as it may change if the buffer expand. + // See: + // - https://github.com/netty/netty/issues/2587 + // - https://github.com/netty/netty/issues/2580 + return wrapped.memoryAddress() + index; + } + + @Override + public long getLong(int index) { + wrapped.checkIndex(index, 8); + long v = PlatformDependent.getLong(addr(index)); + return nativeByteOrder? v : Long.reverseBytes(v); + } + + @Override + public float getFloat(int index) { + return Float.intBitsToFloat(getInt(index)); + } + + @Override + public double getDouble(int index) { + return Double.longBitsToDouble(getLong(index)); + } + + @Override + public char getChar(int index) { + return (char) getShort(index); + } + + @Override + public long getUnsignedInt(int index) { + return getInt(index) & 0xFFFFFFFFL; + } + + @Override + public int getInt(int index) { + wrapped.checkIndex(index, 4); + int v = PlatformDependent.getInt(addr(index)); + return nativeByteOrder? v : Integer.reverseBytes(v); + } + + @Override + public int getUnsignedShort(int index) { + return getShort(index) & 0xFFFF; + } + + @Override + public short getShort(int index) { + wrapped.checkIndex(index, 2); + short v = PlatformDependent.getShort(addr(index)); + return nativeByteOrder? v : Short.reverseBytes(v); + } + + @Override + public ByteBuf setShort(int index, int value) { + wrapped.checkIndex(index, 2); + _setShort(index, value); + return this; + } + + @Override + public ByteBuf setInt(int index, int value) { + wrapped.checkIndex(index, 4); + _setInt(index, value); + return this; + } + + @Override + public ByteBuf setLong(int index, long value) { + wrapped.checkIndex(index, 8); + _setLong(index, value); + return this; + } + + @Override + public ByteBuf setChar(int index, int value) { + setShort(index, value); + return this; + } + + @Override + public ByteBuf setFloat(int index, float value) { + setInt(index, Float.floatToRawIntBits(value)); + return this; + } + + @Override + public ByteBuf setDouble(int index, double value) { + setLong(index, Double.doubleToRawLongBits(value)); + return this; + } + + @Override + public ByteBuf writeShort(int value) { + wrapped.ensureAccessible(); + wrapped.ensureWritable(2); + _setShort(wrapped.writerIndex, value); + wrapped.writerIndex += 2; + return this; + } + + @Override + public ByteBuf writeInt(int value) { + wrapped.ensureAccessible(); + wrapped.ensureWritable(4); + _setInt(wrapped.writerIndex, value); + wrapped.writerIndex += 4; + return this; + } + + @Override + public ByteBuf writeLong(long value) { + wrapped.ensureAccessible(); + wrapped.ensureWritable(8); + _setLong(wrapped.writerIndex, value); + wrapped.writerIndex += 8; + return this; + } + + @Override + public ByteBuf writeChar(int value) { + writeShort(value); + return this; + } + + @Override + public ByteBuf writeFloat(float value) { + writeInt(Float.floatToRawIntBits(value)); + return this; + } + + @Override + public ByteBuf writeDouble(double value) { + writeLong(Double.doubleToRawLongBits(value)); + return this; + } + + private void _setShort(int index, int value) { + PlatformDependent.putShort(addr(index), nativeByteOrder ? (short) value : Short.reverseBytes((short) value)); + } + + private void _setInt(int index, int value) { + PlatformDependent.putInt(addr(index), nativeByteOrder ? value : Integer.reverseBytes(value)); + } + + private void _setLong(int index, long value) { + PlatformDependent.putLong(addr(index), nativeByteOrder ? value : Long.reverseBytes(value)); + } +} diff --git a/common/src/common/net/buffer/WrappedByteBuf.java b/common/src/common/net/buffer/WrappedByteBuf.java new file mode 100644 index 0000000..c135c77 --- /dev/null +++ b/common/src/common/net/buffer/WrappedByteBuf.java @@ -0,0 +1,827 @@ +/* + * Copyright 2013 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ + +package common.net.buffer; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.nio.ByteBuffer; +import java.nio.ByteOrder; +import java.nio.channels.GatheringByteChannel; +import java.nio.channels.ScatteringByteChannel; +import java.nio.charset.Charset; + +import common.net.util.internal.StringUtil; + +class WrappedByteBuf extends ByteBuf { + + protected final ByteBuf buf; + + protected WrappedByteBuf(ByteBuf buf) { + if (buf == null) { + throw new NullPointerException("buf"); + } + this.buf = buf; + } + + @Override + public boolean hasMemoryAddress() { + return buf.hasMemoryAddress(); + } + + @Override + public long memoryAddress() { + return buf.memoryAddress(); + } + + @Override + public int capacity() { + return buf.capacity(); + } + + @Override + public ByteBuf capacity(int newCapacity) { + buf.capacity(newCapacity); + return this; + } + + @Override + public int maxCapacity() { + return buf.maxCapacity(); + } + + @Override + public ByteBufAllocator alloc() { + return buf.alloc(); + } + + @Override + public ByteOrder order() { + return buf.order(); + } + + @Override + public ByteBuf order(ByteOrder endianness) { + return buf.order(endianness); + } + + @Override + public ByteBuf unwrap() { + return buf; + } + + @Override + public boolean isDirect() { + return buf.isDirect(); + } + + @Override + public int readerIndex() { + return buf.readerIndex(); + } + + @Override + public ByteBuf readerIndex(int readerIndex) { + buf.readerIndex(readerIndex); + return this; + } + + @Override + public int writerIndex() { + return buf.writerIndex(); + } + + @Override + public ByteBuf writerIndex(int writerIndex) { + buf.writerIndex(writerIndex); + return this; + } + + @Override + public ByteBuf setIndex(int readerIndex, int writerIndex) { + buf.setIndex(readerIndex, writerIndex); + return this; + } + + @Override + public int readableBytes() { + return buf.readableBytes(); + } + + @Override + public int writableBytes() { + return buf.writableBytes(); + } + + @Override + public int maxWritableBytes() { + return buf.maxWritableBytes(); + } + + @Override + public boolean isReadable() { + return buf.isReadable(); + } + + @Override + public boolean isWritable() { + return buf.isWritable(); + } + + @Override + public ByteBuf clear() { + buf.clear(); + return this; + } + + @Override + public ByteBuf markReaderIndex() { + buf.markReaderIndex(); + return this; + } + + @Override + public ByteBuf resetReaderIndex() { + buf.resetReaderIndex(); + return this; + } + + @Override + public ByteBuf markWriterIndex() { + buf.markWriterIndex(); + return this; + } + + @Override + public ByteBuf resetWriterIndex() { + buf.resetWriterIndex(); + return this; + } + + @Override + public ByteBuf discardReadBytes() { + buf.discardReadBytes(); + return this; + } + + @Override + public ByteBuf discardSomeReadBytes() { + buf.discardSomeReadBytes(); + return this; + } + + @Override + public ByteBuf ensureWritable(int minWritableBytes) { + buf.ensureWritable(minWritableBytes); + return this; + } + + @Override + public int ensureWritable(int minWritableBytes, boolean force) { + return buf.ensureWritable(minWritableBytes, force); + } + + @Override + public boolean getBoolean(int index) { + return buf.getBoolean(index); + } + + @Override + public byte getByte(int index) { + return buf.getByte(index); + } + + @Override + public short getUnsignedByte(int index) { + return buf.getUnsignedByte(index); + } + + @Override + public short getShort(int index) { + return buf.getShort(index); + } + + @Override + public int getUnsignedShort(int index) { + return buf.getUnsignedShort(index); + } + + @Override + public int getMedium(int index) { + return buf.getMedium(index); + } + + @Override + public int getUnsignedMedium(int index) { + return buf.getUnsignedMedium(index); + } + + @Override + public int getInt(int index) { + return buf.getInt(index); + } + + @Override + public long getUnsignedInt(int index) { + return buf.getUnsignedInt(index); + } + + @Override + public long getLong(int index) { + return buf.getLong(index); + } + + @Override + public char getChar(int index) { + return buf.getChar(index); + } + + @Override + public float getFloat(int index) { + return buf.getFloat(index); + } + + @Override + public double getDouble(int index) { + return buf.getDouble(index); + } + + @Override + public ByteBuf getBytes(int index, ByteBuf dst) { + buf.getBytes(index, dst); + return this; + } + + @Override + public ByteBuf getBytes(int index, ByteBuf dst, int length) { + buf.getBytes(index, dst, length); + return this; + } + + @Override + public ByteBuf getBytes(int index, ByteBuf dst, int dstIndex, int length) { + buf.getBytes(index, dst, dstIndex, length); + return this; + } + + @Override + public ByteBuf getBytes(int index, byte[] dst) { + buf.getBytes(index, dst); + return this; + } + + @Override + public ByteBuf getBytes(int index, byte[] dst, int dstIndex, int length) { + buf.getBytes(index, dst, dstIndex, length); + return this; + } + + @Override + public ByteBuf getBytes(int index, ByteBuffer dst) { + buf.getBytes(index, dst); + return this; + } + + @Override + public ByteBuf getBytes(int index, OutputStream out, int length) throws IOException { + buf.getBytes(index, out, length); + return this; + } + + @Override + public int getBytes(int index, GatheringByteChannel out, int length) throws IOException { + return buf.getBytes(index, out, length); + } + + @Override + public ByteBuf setBoolean(int index, boolean value) { + buf.setBoolean(index, value); + return this; + } + + @Override + public ByteBuf setByte(int index, int value) { + buf.setByte(index, value); + return this; + } + + @Override + public ByteBuf setShort(int index, int value) { + buf.setShort(index, value); + return this; + } + + @Override + public ByteBuf setMedium(int index, int value) { + buf.setMedium(index, value); + return this; + } + + @Override + public ByteBuf setInt(int index, int value) { + buf.setInt(index, value); + return this; + } + + @Override + public ByteBuf setLong(int index, long value) { + buf.setLong(index, value); + return this; + } + + @Override + public ByteBuf setChar(int index, int value) { + buf.setChar(index, value); + return this; + } + + @Override + public ByteBuf setFloat(int index, float value) { + buf.setFloat(index, value); + return this; + } + + @Override + public ByteBuf setDouble(int index, double value) { + buf.setDouble(index, value); + return this; + } + + @Override + public ByteBuf setBytes(int index, ByteBuf src) { + buf.setBytes(index, src); + return this; + } + + @Override + public ByteBuf setBytes(int index, ByteBuf src, int length) { + buf.setBytes(index, src, length); + return this; + } + + @Override + public ByteBuf setBytes(int index, ByteBuf src, int srcIndex, int length) { + buf.setBytes(index, src, srcIndex, length); + return this; + } + + @Override + public ByteBuf setBytes(int index, byte[] src) { + buf.setBytes(index, src); + return this; + } + + @Override + public ByteBuf setBytes(int index, byte[] src, int srcIndex, int length) { + buf.setBytes(index, src, srcIndex, length); + return this; + } + + @Override + public ByteBuf setBytes(int index, ByteBuffer src) { + buf.setBytes(index, src); + return this; + } + + @Override + public int setBytes(int index, InputStream in, int length) throws IOException { + return buf.setBytes(index, in, length); + } + + @Override + public int setBytes(int index, ScatteringByteChannel in, int length) throws IOException { + return buf.setBytes(index, in, length); + } + + @Override + public ByteBuf setZero(int index, int length) { + buf.setZero(index, length); + return this; + } + + @Override + public boolean readBoolean() { + return buf.readBoolean(); + } + + @Override + public byte readByte() { + return buf.readByte(); + } + + @Override + public short readUnsignedByte() { + return buf.readUnsignedByte(); + } + + @Override + public short readShort() { + return buf.readShort(); + } + + @Override + public int readUnsignedShort() { + return buf.readUnsignedShort(); + } + + @Override + public int readMedium() { + return buf.readMedium(); + } + + @Override + public int readUnsignedMedium() { + return buf.readUnsignedMedium(); + } + + @Override + public int readInt() { + return buf.readInt(); + } + + @Override + public long readUnsignedInt() { + return buf.readUnsignedInt(); + } + + @Override + public long readLong() { + return buf.readLong(); + } + + @Override + public char readChar() { + return buf.readChar(); + } + + @Override + public float readFloat() { + return buf.readFloat(); + } + + @Override + public double readDouble() { + return buf.readDouble(); + } + + @Override + public ByteBuf readBytes(int length) { + return buf.readBytes(length); + } + + @Override + public ByteBuf readSlice(int length) { + return buf.readSlice(length); + } + + @Override + public ByteBuf readBytes(ByteBuf dst) { + buf.readBytes(dst); + return this; + } + + @Override + public ByteBuf readBytes(ByteBuf dst, int length) { + buf.readBytes(dst, length); + return this; + } + + @Override + public ByteBuf readBytes(ByteBuf dst, int dstIndex, int length) { + buf.readBytes(dst, dstIndex, length); + return this; + } + + @Override + public ByteBuf readBytes(byte[] dst) { + buf.readBytes(dst); + return this; + } + + @Override + public ByteBuf readBytes(byte[] dst, int dstIndex, int length) { + buf.readBytes(dst, dstIndex, length); + return this; + } + + @Override + public ByteBuf readBytes(ByteBuffer dst) { + buf.readBytes(dst); + return this; + } + + @Override + public ByteBuf readBytes(OutputStream out, int length) throws IOException { + buf.readBytes(out, length); + return this; + } + + @Override + public int readBytes(GatheringByteChannel out, int length) throws IOException { + return buf.readBytes(out, length); + } + + @Override + public ByteBuf skipBytes(int length) { + buf.skipBytes(length); + return this; + } + + @Override + public ByteBuf writeBoolean(boolean value) { + buf.writeBoolean(value); + return this; + } + + @Override + public ByteBuf writeByte(int value) { + buf.writeByte(value); + return this; + } + + @Override + public ByteBuf writeShort(int value) { + buf.writeShort(value); + return this; + } + + @Override + public ByteBuf writeMedium(int value) { + buf.writeMedium(value); + return this; + } + + @Override + public ByteBuf writeInt(int value) { + buf.writeInt(value); + return this; + } + + @Override + public ByteBuf writeLong(long value) { + buf.writeLong(value); + return this; + } + + @Override + public ByteBuf writeChar(int value) { + buf.writeChar(value); + return this; + } + + @Override + public ByteBuf writeFloat(float value) { + buf.writeFloat(value); + return this; + } + + @Override + public ByteBuf writeDouble(double value) { + buf.writeDouble(value); + return this; + } + + @Override + public ByteBuf writeBytes(ByteBuf src) { + buf.writeBytes(src); + return this; + } + + @Override + public ByteBuf writeBytes(ByteBuf src, int length) { + buf.writeBytes(src, length); + return this; + } + + @Override + public ByteBuf writeBytes(ByteBuf src, int srcIndex, int length) { + buf.writeBytes(src, srcIndex, length); + return this; + } + + @Override + public ByteBuf writeBytes(byte[] src) { + buf.writeBytes(src); + return this; + } + + @Override + public ByteBuf writeBytes(byte[] src, int srcIndex, int length) { + buf.writeBytes(src, srcIndex, length); + return this; + } + + @Override + public ByteBuf writeBytes(ByteBuffer src) { + buf.writeBytes(src); + return this; + } + + @Override + public int writeBytes(InputStream in, int length) throws IOException { + return buf.writeBytes(in, length); + } + + @Override + public int writeBytes(ScatteringByteChannel in, int length) throws IOException { + return buf.writeBytes(in, length); + } + + @Override + public ByteBuf writeZero(int length) { + buf.writeZero(length); + return this; + } + + @Override + public int indexOf(int fromIndex, int toIndex, byte value) { + return buf.indexOf(fromIndex, toIndex, value); + } + + @Override + public int bytesBefore(byte value) { + return buf.bytesBefore(value); + } + + @Override + public int bytesBefore(int length, byte value) { + return buf.bytesBefore(length, value); + } + + @Override + public int bytesBefore(int index, int length, byte value) { + return buf.bytesBefore(index, length, value); + } + + @Override + public int forEachByte(ByteBufProcessor processor) { + return buf.forEachByte(processor); + } + + @Override + public int forEachByte(int index, int length, ByteBufProcessor processor) { + return buf.forEachByte(index, length, processor); + } + + @Override + public int forEachByteDesc(ByteBufProcessor processor) { + return buf.forEachByteDesc(processor); + } + + @Override + public int forEachByteDesc(int index, int length, ByteBufProcessor processor) { + return buf.forEachByteDesc(index, length, processor); + } + + @Override + public ByteBuf copy() { + return buf.copy(); + } + + @Override + public ByteBuf copy(int index, int length) { + return buf.copy(index, length); + } + + @Override + public ByteBuf slice() { + return buf.slice(); + } + + @Override + public ByteBuf slice(int index, int length) { + return buf.slice(index, length); + } + + @Override + public ByteBuf duplicate() { + return buf.duplicate(); + } + + @Override + public int nioBufferCount() { + return buf.nioBufferCount(); + } + + @Override + public ByteBuffer nioBuffer() { + return buf.nioBuffer(); + } + + @Override + public ByteBuffer nioBuffer(int index, int length) { + return buf.nioBuffer(index, length); + } + + @Override + public ByteBuffer[] nioBuffers() { + return buf.nioBuffers(); + } + + @Override + public ByteBuffer[] nioBuffers(int index, int length) { + return buf.nioBuffers(index, length); + } + + @Override + public ByteBuffer internalNioBuffer(int index, int length) { + return buf.internalNioBuffer(index, length); + } + + @Override + public boolean hasArray() { + return buf.hasArray(); + } + + @Override + public byte[] array() { + return buf.array(); + } + + @Override + public int arrayOffset() { + return buf.arrayOffset(); + } + + @Override + public String toString(Charset charset) { + return buf.toString(charset); + } + + @Override + public String toString(int index, int length, Charset charset) { + return buf.toString(index, length, charset); + } + + @Override + public int hashCode() { + return buf.hashCode(); + } + + @Override + + public boolean equals(Object obj) { + return buf.equals(obj); + } + + @Override + public int compareTo(ByteBuf buffer) { + return buf.compareTo(buffer); + } + + @Override + public String toString() { + return StringUtil.simpleClassName(this) + '(' + buf.toString() + ')'; + } + + @Override + public ByteBuf retain(int increment) { + buf.retain(increment); + return this; + } + + @Override + public ByteBuf retain() { + buf.retain(); + return this; + } + + @Override + public boolean isReadable(int size) { + return buf.isReadable(size); + } + + @Override + public boolean isWritable(int size) { + return buf.isWritable(size); + } + + @Override + public int refCnt() { + return buf.refCnt(); + } + + @Override + public boolean release() { + return buf.release(); + } + + @Override + public boolean release(int decrement) { + return buf.release(decrement); + } +} diff --git a/common/src/common/net/channel/AbstractChannel.java b/common/src/common/net/channel/AbstractChannel.java new file mode 100644 index 0000000..031f273 --- /dev/null +++ b/common/src/common/net/channel/AbstractChannel.java @@ -0,0 +1,873 @@ +/* + * Copyright 2012 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ +package common.net.channel; + +import java.io.IOException; +import java.net.InetSocketAddress; +import java.net.SocketAddress; +import java.nio.channels.ClosedChannelException; +import java.nio.channels.NotYetConnectedException; +import java.util.concurrent.RejectedExecutionException; + +import common.net.buffer.ByteBufAllocator; +import common.net.util.DefaultAttributeMap; +import common.net.util.ReferenceCountUtil; +import common.net.util.internal.EmptyArrays; +import common.net.util.internal.OneTimeTask; +import common.net.util.internal.PlatformDependent; +import common.net.util.internal.ThreadLocalRandom; +import common.net.util.internal.logging.InternalLogger; +import common.net.util.internal.logging.InternalLoggerFactory; + +/** + * A skeletal {@link Channel} implementation. + */ +public abstract class AbstractChannel extends DefaultAttributeMap implements Channel { + + private static final InternalLogger logger = InternalLoggerFactory.getInstance(AbstractChannel.class); + + static final ClosedChannelException CLOSED_CHANNEL_EXCEPTION = new ClosedChannelException(); + static final NotYetConnectedException NOT_YET_CONNECTED_EXCEPTION = new NotYetConnectedException(); + + static { + CLOSED_CHANNEL_EXCEPTION.setStackTrace(EmptyArrays.EMPTY_STACK_TRACE); + NOT_YET_CONNECTED_EXCEPTION.setStackTrace(EmptyArrays.EMPTY_STACK_TRACE); + } + + private MessageSizeEstimator.Handle estimatorHandle; + + private final Channel parent; + private final long hashCode = ThreadLocalRandom.current().nextLong(); + private final Unsafe unsafe; + private final DefaultChannelPipeline pipeline; + private final ChannelFuture succeededFuture = new SucceededChannelFuture(this, null); + private final VoidChannelPromise voidPromise = new VoidChannelPromise(this, true); + private final VoidChannelPromise unsafeVoidPromise = new VoidChannelPromise(this, false); + private final CloseFuture closeFuture = new CloseFuture(this); + + private volatile SocketAddress localAddress; + private volatile SocketAddress remoteAddress; + private volatile EventLoop eventLoop; + private volatile boolean registered; + + /** Cache for the string representation of this channel */ + private boolean strValActive; + private String strVal; + + /** + * Creates a new instance. + * + * @param parent + * the parent of this channel. {@code null} if there's no parent. + */ + protected AbstractChannel(Channel parent) { + this.parent = parent; + unsafe = newUnsafe(); + pipeline = new DefaultChannelPipeline(this); + } + + @Override + public boolean isWritable() { + ChannelOutboundBuffer buf = unsafe.outboundBuffer(); + return buf != null && buf.isWritable(); + } + + @Override + public Channel parent() { + return parent; + } + + @Override + public ChannelPipeline pipeline() { + return pipeline; + } + + @Override + public ByteBufAllocator alloc() { + return config().getAllocator(); + } + + @Override + public EventLoop eventLoop() { + EventLoop eventLoop = this.eventLoop; + if (eventLoop == null) { + throw new IllegalStateException("channel not registered to an event loop"); + } + return eventLoop; + } + + @Override + public SocketAddress localAddress() { + SocketAddress localAddress = this.localAddress; + if (localAddress == null) { + try { + this.localAddress = localAddress = unsafe().localAddress(); + } catch (Throwable t) { + // Sometimes fails on a closed socket in Windows. + return null; + } + } + return localAddress; + } + + protected void invalidateLocalAddress() { + localAddress = null; + } + + @Override + public SocketAddress remoteAddress() { + SocketAddress remoteAddress = this.remoteAddress; + if (remoteAddress == null) { + try { + this.remoteAddress = remoteAddress = unsafe().remoteAddress(); + } catch (Throwable t) { + // Sometimes fails on a closed socket in Windows. + return null; + } + } + return remoteAddress; + } + + /** + * Reset the stored remoteAddress + */ + protected void invalidateRemoteAddress() { + remoteAddress = null; + } + + @Override + public boolean isRegistered() { + return registered; + } + + @Override + public ChannelFuture bind(SocketAddress localAddress) { + return pipeline.bind(localAddress); + } + + @Override + public ChannelFuture connect(SocketAddress remoteAddress) { + return pipeline.connect(remoteAddress); + } + + @Override + public ChannelFuture connect(SocketAddress remoteAddress, SocketAddress localAddress) { + return pipeline.connect(remoteAddress, localAddress); + } + + @Override + public ChannelFuture disconnect() { + return pipeline.disconnect(); + } + + @Override + public ChannelFuture close() { + return pipeline.close(); + } + + @Override + public ChannelFuture deregister() { + return pipeline.deregister(); + } + + @Override + public Channel flush() { + pipeline.flush(); + return this; + } + + @Override + public ChannelFuture bind(SocketAddress localAddress, ChannelPromise promise) { + return pipeline.bind(localAddress, promise); + } + + @Override + public ChannelFuture connect(SocketAddress remoteAddress, ChannelPromise promise) { + return pipeline.connect(remoteAddress, promise); + } + + @Override + public ChannelFuture connect(SocketAddress remoteAddress, SocketAddress localAddress, ChannelPromise promise) { + return pipeline.connect(remoteAddress, localAddress, promise); + } + + @Override + public ChannelFuture disconnect(ChannelPromise promise) { + return pipeline.disconnect(promise); + } + + @Override + public ChannelFuture close(ChannelPromise promise) { + return pipeline.close(promise); + } + + @Override + public ChannelFuture deregister(ChannelPromise promise) { + return pipeline.deregister(promise); + } + + @Override + public Channel read() { + pipeline.read(); + return this; + } + + @Override + public ChannelFuture write(Object msg) { + return pipeline.write(msg); + } + + @Override + public ChannelFuture write(Object msg, ChannelPromise promise) { + return pipeline.write(msg, promise); + } + + @Override + public ChannelFuture writeAndFlush(Object msg) { + return pipeline.writeAndFlush(msg); + } + + @Override + public ChannelFuture writeAndFlush(Object msg, ChannelPromise promise) { + return pipeline.writeAndFlush(msg, promise); + } + + @Override + public ChannelPromise newPromise() { + return new DefaultChannelPromise(this); + } + +// @Override +// public ChannelProgressivePromise newProgressivePromise() { +// return new DefaultChannelProgressivePromise(this); +// } + + @Override + public ChannelFuture newSucceededFuture() { + return succeededFuture; + } + + @Override + public ChannelFuture newFailedFuture(Throwable cause) { + return new FailedChannelFuture(this, null, cause); + } + + @Override + public ChannelFuture closeFuture() { + return closeFuture; + } + + @Override + public Unsafe unsafe() { + return unsafe; + } + + /** + * Create a new {@link AbstractUnsafe} instance which will be used for the life-time of the {@link Channel} + */ + protected abstract AbstractUnsafe newUnsafe(); + + /** + * Returns the ID of this channel. + */ + @Override + public final int hashCode() { + return (int) hashCode; + } + + /** + * Returns {@code true} if and only if the specified object is identical + * with this channel (i.e: {@code this == o}). + */ + @Override + public final boolean equals(Object o) { + return this == o; + } + + @Override + public final int compareTo(Channel o) { + if (this == o) { + return 0; + } + + long ret = hashCode - o.hashCode(); + if (ret > 0) { + return 1; + } + if (ret < 0) { + return -1; + } + + ret = System.identityHashCode(this) - System.identityHashCode(o); + if (ret != 0) { + return (int) ret; + } + + // Jackpot! - different objects with same hashes + throw new Error(); + } + + /** + * Returns the {@link String} representation of this channel. The returned + * string contains the {@linkplain #hashCode()} ID}, {@linkplain #localAddress() local address}, + * and {@linkplain #remoteAddress() remote address} of this channel for + * easier identification. + */ + @Override + public String toString() { + boolean active = isActive(); + if (strValActive == active && strVal != null) { + return strVal; + } + + SocketAddress remoteAddr = remoteAddress(); + SocketAddress localAddr = localAddress(); + if (remoteAddr != null) { + SocketAddress srcAddr; + SocketAddress dstAddr; + if (parent == null) { + srcAddr = localAddr; + dstAddr = remoteAddr; + } else { + srcAddr = remoteAddr; + dstAddr = localAddr; + } + strVal = String.format("[id: 0x%08x, %s %s %s]", (int) hashCode, srcAddr, active? "=>" : ":>", dstAddr); + } else if (localAddr != null) { + strVal = String.format("[id: 0x%08x, %s]", (int) hashCode, localAddr); + } else { + strVal = String.format("[id: 0x%08x]", (int) hashCode); + } + + strValActive = active; + return strVal; + } + + @Override + public final ChannelPromise voidPromise() { + return voidPromise; + } + + final MessageSizeEstimator.Handle estimatorHandle() { + if (estimatorHandle == null) { + estimatorHandle = config().getMessageSizeEstimator().newHandle(); + } + return estimatorHandle; + } + + /** + * {@link Unsafe} implementation which sub-classes must extend and use. + */ + protected abstract class AbstractUnsafe implements Unsafe { + + private ChannelOutboundBuffer outboundBuffer = new ChannelOutboundBuffer(AbstractChannel.this); + private boolean inFlush0; + + @Override + public final ChannelOutboundBuffer outboundBuffer() { + return outboundBuffer; + } + + @Override + public final SocketAddress localAddress() { + return localAddress0(); + } + + @Override + public final SocketAddress remoteAddress() { + return remoteAddress0(); + } + + @Override + public final void register(EventLoop eventLoop, final ChannelPromise promise) { + if (eventLoop == null) { + throw new NullPointerException("eventLoop"); + } + if (isRegistered()) { + promise.setFailure(new IllegalStateException("registered to an event loop already")); + return; + } + if (!isCompatible(eventLoop)) { + promise.setFailure( + new IllegalStateException("incompatible event loop type: " + eventLoop.getClass().getName())); + return; + } + + AbstractChannel.this.eventLoop = eventLoop; + + if (eventLoop.inEventLoop()) { + register0(promise); + } else { + try { + eventLoop.execute(new OneTimeTask() { + @Override + public void run() { + register0(promise); + } + }); + } catch (Throwable t) { + logger.warn( + "Force-closing a channel whose registration task was not accepted by an event loop: {}", + AbstractChannel.this, t); + closeForcibly(); + closeFuture.setClosed(); + safeSetFailure(promise, t); + } + } + } + + private void register0(ChannelPromise promise) { + try { + // check if the channel is still open as it could be closed in the mean time when the register + // call was outside of the eventLoop + if (!promise.setUncancellable() || !ensureOpen(promise)) { + return; + } + doRegister(); + registered = true; + safeSetSuccess(promise); + pipeline.fireChannelRegistered(); + if (isActive()) { + pipeline.fireChannelActive(); + } + } catch (Throwable t) { + // Close the channel directly to avoid FD leak. + closeForcibly(); + closeFuture.setClosed(); + safeSetFailure(promise, t); + } + } + + @Override + public final void bind(final SocketAddress localAddress, final ChannelPromise promise) { + if (!promise.setUncancellable() || !ensureOpen(promise)) { + return; + } + + // See: https://github.com/netty/netty/issues/576 + if (!PlatformDependent.isWindows() && !PlatformDependent.isRoot() && + Boolean.TRUE.equals(config().getOption(ChannelOption.SO_BROADCAST)) && + localAddress instanceof InetSocketAddress && + !((InetSocketAddress) localAddress).getAddress().isAnyLocalAddress()) { + // Warn a user about the fact that a non-root user can't receive a + // broadcast packet on *nix if the socket is bound on non-wildcard address. + logger.warn( + "A non-root user can't receive a broadcast packet if the socket " + + "is not bound to a wildcard address; binding to a non-wildcard " + + "address (" + localAddress + ") anyway as requested."); + } + + boolean wasActive = isActive(); + try { + doBind(localAddress); + } catch (Throwable t) { + safeSetFailure(promise, t); + closeIfClosed(); + return; + } + + if (!wasActive && isActive()) { + invokeLater(new OneTimeTask() { + @Override + public void run() { + pipeline.fireChannelActive(); + } + }); + } + + safeSetSuccess(promise); + } + + @Override + public final void disconnect(final ChannelPromise promise) { + if (!promise.setUncancellable()) { + return; + } + + boolean wasActive = isActive(); + try { + doDisconnect(); + } catch (Throwable t) { + safeSetFailure(promise, t); + closeIfClosed(); + return; + } + + if (wasActive && !isActive()) { + invokeLater(new OneTimeTask() { + @Override + public void run() { + pipeline.fireChannelInactive(); + } + }); + } + + safeSetSuccess(promise); + closeIfClosed(); // doDisconnect() might have closed the channel + } + + @Override + public final void close(final ChannelPromise promise) { + if (!promise.setUncancellable()) { + return; + } + + if (inFlush0) { + invokeLater(new OneTimeTask() { + @Override + public void run() { + close(promise); + } + }); + return; + } + + if (closeFuture.isDone()) { + // Closed already. + safeSetSuccess(promise); + return; + } + + boolean wasActive = isActive(); + ChannelOutboundBuffer outboundBuffer = this.outboundBuffer; + this.outboundBuffer = null; // Disallow adding any messages and flushes to outboundBuffer. + + try { + doClose(); + closeFuture.setClosed(); + safeSetSuccess(promise); + } catch (Throwable t) { + closeFuture.setClosed(); + safeSetFailure(promise, t); + } + + // Fail all the queued messages + try { + outboundBuffer.failFlushed(CLOSED_CHANNEL_EXCEPTION); + outboundBuffer.close(CLOSED_CHANNEL_EXCEPTION); + } finally { + + if (wasActive && !isActive()) { + invokeLater(new OneTimeTask() { + @Override + public void run() { + pipeline.fireChannelInactive(); + } + }); + } + + deregister(voidPromise()); + } + } + + @Override + public final void closeForcibly() { + try { + doClose(); + } catch (Exception e) { + logger.warn("Failed to close a channel.", e); + } + } + + @Override + public final void deregister(final ChannelPromise promise) { + if (!promise.setUncancellable()) { + return; + } + + if (!registered) { + safeSetSuccess(promise); + return; + } + + try { + doDeregister(); + } catch (Throwable t) { + logger.warn("Unexpected exception occurred while deregistering a channel.", t); + } finally { + if (registered) { + registered = false; + invokeLater(new OneTimeTask() { + @Override + public void run() { + pipeline.fireChannelUnregistered(); + } + }); + safeSetSuccess(promise); + } else { + // Some transports like local and AIO does not allow the deregistration of + // an open channel. Their doDeregister() calls close(). Consequently, + // close() calls deregister() again - no need to fire channelUnregistered. + safeSetSuccess(promise); + } + } + } + + @Override + public final void beginRead() { + if (!isActive()) { + return; + } + + try { + doBeginRead(); + } catch (final Exception e) { + invokeLater(new OneTimeTask() { + @Override + public void run() { + pipeline.fireExceptionCaught(e); + } + }); + close(voidPromise()); + } + } + + @Override + public final void write(Object msg, ChannelPromise promise) { + ChannelOutboundBuffer outboundBuffer = this.outboundBuffer; + if (outboundBuffer == null) { + // If the outboundBuffer is null we know the channel was closed and so + // need to fail the future right away. If it is not null the handling of the rest + // will be done in flush0() + // See https://github.com/netty/netty/issues/2362 + safeSetFailure(promise, CLOSED_CHANNEL_EXCEPTION); + // release message now to prevent resource-leak + ReferenceCountUtil.release(msg); + return; + } + + int size; + try { + msg = filterOutboundMessage(msg); + size = estimatorHandle().size(msg); + if (size < 0) { + size = 0; + } + } catch (Throwable t) { + safeSetFailure(promise, t); + ReferenceCountUtil.release(msg); + return; + } + + outboundBuffer.addMessage(msg, size, promise); + } + + @Override + public final void flush() { + ChannelOutboundBuffer outboundBuffer = this.outboundBuffer; + if (outboundBuffer == null) { + return; + } + + outboundBuffer.addFlush(); + flush0(); + } + + protected void flush0() { + if (inFlush0) { + // Avoid re-entrance + return; + } + + final ChannelOutboundBuffer outboundBuffer = this.outboundBuffer; + if (outboundBuffer == null || outboundBuffer.isEmpty()) { + return; + } + + inFlush0 = true; + + // Mark all pending write requests as failure if the channel is inactive. + if (!isActive()) { + try { + if (isOpen()) { + outboundBuffer.failFlushed(NOT_YET_CONNECTED_EXCEPTION); + } else { + outboundBuffer.failFlushed(CLOSED_CHANNEL_EXCEPTION); + } + } finally { + inFlush0 = false; + } + return; + } + + try { + doWrite(outboundBuffer); + } catch (Throwable t) { + outboundBuffer.failFlushed(t); + if (t instanceof IOException && config().isAutoClose()) { + close(voidPromise()); + } + } finally { + inFlush0 = false; + } + } + + @Override + public final ChannelPromise voidPromise() { + return unsafeVoidPromise; + } + + protected final boolean ensureOpen(ChannelPromise promise) { + if (isOpen()) { + return true; + } + + safeSetFailure(promise, CLOSED_CHANNEL_EXCEPTION); + return false; + } + + /** + * Marks the specified {@code promise} as success. If the {@code promise} is done already, log a message. + */ + protected final void safeSetSuccess(ChannelPromise promise) { + if (!(promise instanceof VoidChannelPromise) && !promise.trySuccess()) { + logger.warn("Failed to mark a promise as success because it is done already: {}", promise); + } + } + + /** + * Marks the specified {@code promise} as failure. If the {@code promise} is done already, log a message. + */ + protected final void safeSetFailure(ChannelPromise promise, Throwable cause) { + if (!(promise instanceof VoidChannelPromise) && !promise.tryFailure(cause)) { + logger.warn("Failed to mark a promise as failure because it's done already: {}", promise, cause); + } + } + + protected final void closeIfClosed() { + if (isOpen()) { + return; + } + close(voidPromise()); + } + + private void invokeLater(Runnable task) { + try { + // This method is used by outbound operation implementations to trigger an inbound event later. + // They do not trigger an inbound event immediately because an outbound operation might have been + // triggered by another inbound event handler method. If fired immediately, the call stack + // will look like this for example: + // + // handlerA.inboundBufferUpdated() - (1) an inbound handler method closes a connection. + // -> handlerA.ctx.close() + // -> channel.unsafe.close() + // -> handlerA.channelInactive() - (2) another inbound handler method called while in (1) yet + // + // which means the execution of two inbound handler methods of the same handler overlap undesirably. + eventLoop().execute(task); + } catch (RejectedExecutionException e) { + logger.warn("Can't invoke task later as EventLoop rejected it", e); + } + } + } + + /** + * Return {@code true} if the given {@link EventLoop} is compatible with this instance. + */ + protected abstract boolean isCompatible(EventLoop loop); + + /** + * Returns the {@link SocketAddress} which is bound locally. + */ + protected abstract SocketAddress localAddress0(); + + /** + * Return the {@link SocketAddress} which the {@link Channel} is connected to. + */ + protected abstract SocketAddress remoteAddress0(); + + /** + * Is called after the {@link Channel} is registered with its {@link EventLoop} as part of the register process. + * + * Sub-classes may override this method + */ + protected void doRegister() throws Exception { + // NOOP + } + + /** + * Bind the {@link Channel} to the {@link SocketAddress} + */ + protected abstract void doBind(SocketAddress localAddress) throws Exception; + + /** + * Disconnect this {@link Channel} from its remote peer + */ + protected abstract void doDisconnect() throws Exception; + + /** + * Close the {@link Channel} + */ + protected abstract void doClose() throws Exception; + + /** + * Deregister the {@link Channel} from its {@link EventLoop}. + * + * Sub-classes may override this method + */ + protected void doDeregister() throws Exception { + // NOOP + } + + /** + * Schedule a read operation. + */ + protected abstract void doBeginRead() throws Exception; + + /** + * Flush the content of the given buffer to the remote peer. + */ + protected abstract void doWrite(ChannelOutboundBuffer in) throws Exception; + + /** + * Invoked when a new message is added to a {@link ChannelOutboundBuffer} of this {@link AbstractChannel}, so that + * the {@link Channel} implementation converts the message to another. (e.g. heap buffer -> direct buffer) + */ + protected Object filterOutboundMessage(Object msg) throws Exception { + return msg; + } + + static final class CloseFuture extends DefaultChannelPromise { + + CloseFuture(AbstractChannel ch) { + super(ch); + } + + @Override + public ChannelPromise setSuccess() { + throw new IllegalStateException(); + } + + @Override + public ChannelPromise setFailure(Throwable cause) { + throw new IllegalStateException(); + } + + @Override + public boolean trySuccess() { + throw new IllegalStateException(); + } + + @Override + public boolean tryFailure(Throwable cause) { + throw new IllegalStateException(); + } + + boolean setClosed() { + return super.trySuccess(); + } + } +} diff --git a/common/src/common/net/channel/AbstractChannelHandlerContext.java b/common/src/common/net/channel/AbstractChannelHandlerContext.java new file mode 100644 index 0000000..204bd7a --- /dev/null +++ b/common/src/common/net/channel/AbstractChannelHandlerContext.java @@ -0,0 +1,1000 @@ +/* + * Copyright 2012 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ +package common.net.channel; + +import static common.net.channel.DefaultChannelPipeline.logger; + +import java.net.SocketAddress; + +import common.net.buffer.ByteBufAllocator; +import common.net.util.DefaultAttributeMap; +import common.net.util.Recycler; +import common.net.util.ReferenceCountUtil; +import common.net.util.concurrent.EventExecutor; +import common.net.util.concurrent.EventExecutorGroup; +import common.net.util.internal.OneTimeTask; +import common.net.util.internal.RecyclableMpscLinkedQueueNode; +import common.net.util.internal.StringUtil; + +abstract class AbstractChannelHandlerContext extends DefaultAttributeMap implements ChannelHandlerContext { + + volatile AbstractChannelHandlerContext next; + volatile AbstractChannelHandlerContext prev; + + private final boolean inbound; + private final boolean outbound; + private final AbstractChannel channel; + private final DefaultChannelPipeline pipeline; + private final String name; + private boolean removed; + + // Will be set to null if no child executor should be used, otherwise it will be set to the + // child executor. + final EventExecutor executor; + private ChannelFuture succeededFuture; + + // Lazily instantiated tasks used to trigger events to a handler with different executor. + // These needs to be volatile as otherwise an other Thread may see an half initialized instance. + // See the JMM for more details + private volatile Runnable invokeChannelReadCompleteTask; + private volatile Runnable invokeReadTask; + private volatile Runnable invokeChannelWritableStateChangedTask; + private volatile Runnable invokeFlushTask; + + AbstractChannelHandlerContext(DefaultChannelPipeline pipeline, EventExecutorGroup group, String name, + boolean inbound, boolean outbound) { + + if (name == null) { + throw new NullPointerException("name"); + } + + channel = pipeline.channel; + this.pipeline = pipeline; + this.name = name; + + if (group != null) { + // Pin one of the child executors once and remember it so that the same child executor + // is used to fire events for the same channel. + EventExecutor childExecutor = pipeline.childExecutors.get(group); + if (childExecutor == null) { + childExecutor = group.next(); + pipeline.childExecutors.put(group, childExecutor); + } + executor = childExecutor; + } else { + executor = null; + } + + this.inbound = inbound; + this.outbound = outbound; + } + + /** Invocation initiated by {@link DefaultChannelPipeline#teardownAll()}}. */ + void teardown() { + EventExecutor executor = executor(); + if (executor.inEventLoop()) { + teardown0(); + } else { + executor.execute(new Runnable() { + @Override + public void run() { + teardown0(); + } + }); + } + } + + private void teardown0() { + AbstractChannelHandlerContext prev = this.prev; + if (prev != null) { + synchronized (pipeline) { + pipeline.remove0(this); + } + prev.teardown(); + } + } + + @Override + public Channel channel() { + return channel; + } + + @Override + public ChannelPipeline pipeline() { + return pipeline; + } + + @Override + public ByteBufAllocator alloc() { + return channel().config().getAllocator(); + } + + @Override + public EventExecutor executor() { + if (executor == null) { + return channel().eventLoop(); + } else { + return executor; + } + } + + @Override + public String name() { + return name; + } + + @Override + public ChannelHandlerContext fireChannelRegistered() { + final AbstractChannelHandlerContext next = findContextInbound(); + EventExecutor executor = next.executor(); + if (executor.inEventLoop()) { + next.invokeChannelRegistered(); + } else { + executor.execute(new OneTimeTask() { + @Override + public void run() { + next.invokeChannelRegistered(); + } + }); + } + return this; + } + + private void invokeChannelRegistered() { + try { + ((ChannelInboundHandler) handler()).channelRegistered(this); + } catch (Throwable t) { + notifyHandlerException(t); + } + } + + @Override + public ChannelHandlerContext fireChannelUnregistered() { + final AbstractChannelHandlerContext next = findContextInbound(); + EventExecutor executor = next.executor(); + if (executor.inEventLoop()) { + next.invokeChannelUnregistered(); + } else { + executor.execute(new OneTimeTask() { + @Override + public void run() { + next.invokeChannelUnregistered(); + } + }); + } + return this; + } + + private void invokeChannelUnregistered() { + try { + ((ChannelInboundHandler) handler()).channelUnregistered(this); + } catch (Throwable t) { + notifyHandlerException(t); + } + } + + @Override + public ChannelHandlerContext fireChannelActive() { + final AbstractChannelHandlerContext next = findContextInbound(); + EventExecutor executor = next.executor(); + if (executor.inEventLoop()) { + next.invokeChannelActive(); + } else { + executor.execute(new OneTimeTask() { + @Override + public void run() { + next.invokeChannelActive(); + } + }); + } + return this; + } + + private void invokeChannelActive() { + try { + ((ChannelInboundHandler) handler()).channelActive(this); + } catch (Throwable t) { + notifyHandlerException(t); + } + } + + @Override + public ChannelHandlerContext fireChannelInactive() { + final AbstractChannelHandlerContext next = findContextInbound(); + EventExecutor executor = next.executor(); + if (executor.inEventLoop()) { + next.invokeChannelInactive(); + } else { + executor.execute(new OneTimeTask() { + @Override + public void run() { + next.invokeChannelInactive(); + } + }); + } + return this; + } + + private void invokeChannelInactive() { + try { + ((ChannelInboundHandler) handler()).channelInactive(this); + } catch (Throwable t) { + notifyHandlerException(t); + } + } + + @Override + public ChannelHandlerContext fireExceptionCaught(final Throwable cause) { + if (cause == null) { + throw new NullPointerException("cause"); + } + + final AbstractChannelHandlerContext next = this.next; + + EventExecutor executor = next.executor(); + if (executor.inEventLoop()) { + next.invokeExceptionCaught(cause); + } else { + try { + executor.execute(new OneTimeTask() { + @Override + public void run() { + next.invokeExceptionCaught(cause); + } + }); + } catch (Throwable t) { + if (logger.isWarnEnabled()) { + logger.warn("Failed to submit an exceptionCaught() event.", t); + logger.warn("The exceptionCaught() event that was failed to submit was:", cause); + } + } + } + + return this; + } + + private void invokeExceptionCaught(final Throwable cause) { + try { + handler().exceptionCaught(this, cause); + } catch (Throwable t) { + if (logger.isWarnEnabled()) { + logger.warn( + "An exception was thrown by a user handler's " + + "exceptionCaught() method while handling the following exception:", cause); + } + } + } + + @Override + public ChannelHandlerContext fireUserEventTriggered(final Object event) { + if (event == null) { + throw new NullPointerException("event"); + } + + final AbstractChannelHandlerContext next = findContextInbound(); + EventExecutor executor = next.executor(); + if (executor.inEventLoop()) { + next.invokeUserEventTriggered(event); + } else { + executor.execute(new OneTimeTask() { + @Override + public void run() { + next.invokeUserEventTriggered(event); + } + }); + } + return this; + } + + private void invokeUserEventTriggered(Object event) { + try { + ((ChannelInboundHandler) handler()).userEventTriggered(this, event); + } catch (Throwable t) { + notifyHandlerException(t); + } + } + + @Override + public ChannelHandlerContext fireChannelRead(final Object msg) { + if (msg == null) { + throw new NullPointerException("msg"); + } + + final AbstractChannelHandlerContext next = findContextInbound(); + EventExecutor executor = next.executor(); + if (executor.inEventLoop()) { + next.invokeChannelRead(msg); + } else { + executor.execute(new OneTimeTask() { + @Override + public void run() { + next.invokeChannelRead(msg); + } + }); + } + return this; + } + + private void invokeChannelRead(Object msg) { + try { + ((ChannelInboundHandler) handler()).channelRead(this, msg); + } catch (Throwable t) { + notifyHandlerException(t); + } + } + + @Override + public ChannelHandlerContext fireChannelReadComplete() { + final AbstractChannelHandlerContext next = findContextInbound(); + EventExecutor executor = next.executor(); + if (executor.inEventLoop()) { + next.invokeChannelReadComplete(); + } else { + Runnable task = next.invokeChannelReadCompleteTask; + if (task == null) { + next.invokeChannelReadCompleteTask = task = new Runnable() { + @Override + public void run() { + next.invokeChannelReadComplete(); + } + }; + } + executor.execute(task); + } + return this; + } + + private void invokeChannelReadComplete() { + try { + ((ChannelInboundHandler) handler()).channelReadComplete(this); + } catch (Throwable t) { + notifyHandlerException(t); + } + } + + @Override + public ChannelHandlerContext fireChannelWritabilityChanged() { + final AbstractChannelHandlerContext next = findContextInbound(); + EventExecutor executor = next.executor(); + if (executor.inEventLoop()) { + next.invokeChannelWritabilityChanged(); + } else { + Runnable task = next.invokeChannelWritableStateChangedTask; + if (task == null) { + next.invokeChannelWritableStateChangedTask = task = new Runnable() { + @Override + public void run() { + next.invokeChannelWritabilityChanged(); + } + }; + } + executor.execute(task); + } + return this; + } + + private void invokeChannelWritabilityChanged() { + try { + ((ChannelInboundHandler) handler()).channelWritabilityChanged(this); + } catch (Throwable t) { + notifyHandlerException(t); + } + } + + @Override + public ChannelFuture bind(SocketAddress localAddress) { + return bind(localAddress, newPromise()); + } + + @Override + public ChannelFuture connect(SocketAddress remoteAddress) { + return connect(remoteAddress, newPromise()); + } + + @Override + public ChannelFuture connect(SocketAddress remoteAddress, SocketAddress localAddress) { + return connect(remoteAddress, localAddress, newPromise()); + } + + @Override + public ChannelFuture disconnect() { + return disconnect(newPromise()); + } + + @Override + public ChannelFuture close() { + return close(newPromise()); + } + + @Override + public ChannelFuture deregister() { + return deregister(newPromise()); + } + + @Override + public ChannelFuture bind(final SocketAddress localAddress, final ChannelPromise promise) { + if (localAddress == null) { + throw new NullPointerException("localAddress"); + } + if (!validatePromise(promise, false)) { + // cancelled + return promise; + } + + final AbstractChannelHandlerContext next = findContextOutbound(); + EventExecutor executor = next.executor(); + if (executor.inEventLoop()) { + next.invokeBind(localAddress, promise); + } else { + safeExecute(executor, new OneTimeTask() { + @Override + public void run() { + next.invokeBind(localAddress, promise); + } + }, promise, null); + } + + return promise; + } + + private void invokeBind(SocketAddress localAddress, ChannelPromise promise) { + try { + ((ChannelOutboundHandler) handler()).bind(this, localAddress, promise); + } catch (Throwable t) { + notifyOutboundHandlerException(t, promise); + } + } + + @Override + public ChannelFuture connect(SocketAddress remoteAddress, ChannelPromise promise) { + return connect(remoteAddress, null, promise); + } + + @Override + public ChannelFuture connect( + final SocketAddress remoteAddress, final SocketAddress localAddress, final ChannelPromise promise) { + + if (remoteAddress == null) { + throw new NullPointerException("remoteAddress"); + } + if (!validatePromise(promise, false)) { + // cancelled + return promise; + } + + final AbstractChannelHandlerContext next = findContextOutbound(); + EventExecutor executor = next.executor(); + if (executor.inEventLoop()) { + next.invokeConnect(remoteAddress, localAddress, promise); + } else { + safeExecute(executor, new OneTimeTask() { + @Override + public void run() { + next.invokeConnect(remoteAddress, localAddress, promise); + } + }, promise, null); + } + + return promise; + } + + private void invokeConnect(SocketAddress remoteAddress, SocketAddress localAddress, ChannelPromise promise) { + try { + ((ChannelOutboundHandler) handler()).connect(this, remoteAddress, localAddress, promise); + } catch (Throwable t) { + notifyOutboundHandlerException(t, promise); + } + } + + @Override + public ChannelFuture disconnect(final ChannelPromise promise) { + if (!validatePromise(promise, false)) { + // cancelled + return promise; + } + + final AbstractChannelHandlerContext next = findContextOutbound(); + EventExecutor executor = next.executor(); + if (executor.inEventLoop()) { + // Translate disconnect to close if the channel has no notion of disconnect-reconnect. + // So far, UDP/IP is the only transport that has such behavior. + if (!channel().metadata().hasDisconnect()) { + next.invokeClose(promise); + } else { + next.invokeDisconnect(promise); + } + } else { + safeExecute(executor, new OneTimeTask() { + @Override + public void run() { + if (!channel().metadata().hasDisconnect()) { + next.invokeClose(promise); + } else { + next.invokeDisconnect(promise); + } + } + }, promise, null); + } + + return promise; + } + + private void invokeDisconnect(ChannelPromise promise) { + try { + ((ChannelOutboundHandler) handler()).disconnect(this, promise); + } catch (Throwable t) { + notifyOutboundHandlerException(t, promise); + } + } + + @Override + public ChannelFuture close(final ChannelPromise promise) { + if (!validatePromise(promise, false)) { + // cancelled + return promise; + } + + final AbstractChannelHandlerContext next = findContextOutbound(); + EventExecutor executor = next.executor(); + if (executor.inEventLoop()) { + next.invokeClose(promise); + } else { + safeExecute(executor, new OneTimeTask() { + @Override + public void run() { + next.invokeClose(promise); + } + }, promise, null); + } + + return promise; + } + + private void invokeClose(ChannelPromise promise) { + try { + ((ChannelOutboundHandler) handler()).close(this, promise); + } catch (Throwable t) { + notifyOutboundHandlerException(t, promise); + } + } + + @Override + public ChannelFuture deregister(final ChannelPromise promise) { + if (!validatePromise(promise, false)) { + // cancelled + return promise; + } + + final AbstractChannelHandlerContext next = findContextOutbound(); + EventExecutor executor = next.executor(); + if (executor.inEventLoop()) { + next.invokeDeregister(promise); + } else { + safeExecute(executor, new OneTimeTask() { + @Override + public void run() { + next.invokeDeregister(promise); + } + }, promise, null); + } + + return promise; + } + + private void invokeDeregister(ChannelPromise promise) { + try { + ((ChannelOutboundHandler) handler()).deregister(this, promise); + } catch (Throwable t) { + notifyOutboundHandlerException(t, promise); + } + } + + @Override + public ChannelHandlerContext read() { + final AbstractChannelHandlerContext next = findContextOutbound(); + EventExecutor executor = next.executor(); + if (executor.inEventLoop()) { + next.invokeRead(); + } else { + Runnable task = next.invokeReadTask; + if (task == null) { + next.invokeReadTask = task = new Runnable() { + @Override + public void run() { + next.invokeRead(); + } + }; + } + executor.execute(task); + } + + return this; + } + + private void invokeRead() { + try { + ((ChannelOutboundHandler) handler()).read(this); + } catch (Throwable t) { + notifyHandlerException(t); + } + } + + @Override + public ChannelFuture write(Object msg) { + return write(msg, newPromise()); + } + + @Override + public ChannelFuture write(final Object msg, final ChannelPromise promise) { + if (msg == null) { + throw new NullPointerException("msg"); + } + + if (!validatePromise(promise, true)) { + ReferenceCountUtil.release(msg); + // cancelled + return promise; + } + write(msg, false, promise); + + return promise; + } + + private void invokeWrite(Object msg, ChannelPromise promise) { + try { + ((ChannelOutboundHandler) handler()).write(this, msg, promise); + } catch (Throwable t) { + notifyOutboundHandlerException(t, promise); + } + } + + @Override + public ChannelHandlerContext flush() { + final AbstractChannelHandlerContext next = findContextOutbound(); + EventExecutor executor = next.executor(); + if (executor.inEventLoop()) { + next.invokeFlush(); + } else { + Runnable task = next.invokeFlushTask; + if (task == null) { + next.invokeFlushTask = task = new Runnable() { + @Override + public void run() { + next.invokeFlush(); + } + }; + } + safeExecute(executor, task, channel.voidPromise(), null); + } + + return this; + } + + private void invokeFlush() { + try { + ((ChannelOutboundHandler) handler()).flush(this); + } catch (Throwable t) { + notifyHandlerException(t); + } + } + + @Override + public ChannelFuture writeAndFlush(Object msg, ChannelPromise promise) { + if (msg == null) { + throw new NullPointerException("msg"); + } + + if (!validatePromise(promise, true)) { + ReferenceCountUtil.release(msg); + // cancelled + return promise; + } + + write(msg, true, promise); + + return promise; + } + + private void write(Object msg, boolean flush, ChannelPromise promise) { + + AbstractChannelHandlerContext next = findContextOutbound(); + EventExecutor executor = next.executor(); + if (executor.inEventLoop()) { + next.invokeWrite(msg, promise); + if (flush) { + next.invokeFlush(); + } + } else { + int size = channel.estimatorHandle().size(msg); + if (size > 0) { + ChannelOutboundBuffer buffer = channel.unsafe().outboundBuffer(); + // Check for null as it may be set to null if the channel is closed already + if (buffer != null) { + buffer.incrementPendingOutboundBytes(size); + } + } + Runnable task; + if (flush) { + task = WriteAndFlushTask.newInstance(next, msg, size, promise); + } else { + task = WriteTask.newInstance(next, msg, size, promise); + } + safeExecute(executor, task, promise, msg); + } + } + + @Override + public ChannelFuture writeAndFlush(Object msg) { + return writeAndFlush(msg, newPromise()); + } + + private static void notifyOutboundHandlerException(Throwable cause, ChannelPromise promise) { + // only try to fail the promise if its not a VoidChannelPromise, as + // the VoidChannelPromise would also fire the cause through the pipeline + if (promise instanceof VoidChannelPromise) { + return; + } + + if (!promise.tryFailure(cause)) { + if (logger.isWarnEnabled()) { + logger.warn("Failed to fail the promise because it's done already: {}", promise, cause); + } + } + } + + private void notifyHandlerException(Throwable cause) { + if (inExceptionCaught(cause)) { + if (logger.isWarnEnabled()) { + logger.warn( + "An exception was thrown by a user handler " + + "while handling an exceptionCaught event", cause); + } + return; + } + + invokeExceptionCaught(cause); + } + + private static boolean inExceptionCaught(Throwable cause) { + do { + StackTraceElement[] trace = cause.getStackTrace(); + if (trace != null) { + for (StackTraceElement t : trace) { + if (t == null) { + break; + } + if ("exceptionCaught".equals(t.getMethodName())) { + return true; + } + } + } + + cause = cause.getCause(); + } while (cause != null); + + return false; + } + + @Override + public ChannelPromise newPromise() { + return new DefaultChannelPromise(channel(), executor()); + } + +// @Override +// public ChannelProgressivePromise newProgressivePromise() { +// return new DefaultChannelProgressivePromise(channel(), executor()); +// } + + @Override + public ChannelFuture newSucceededFuture() { + ChannelFuture succeededFuture = this.succeededFuture; + if (succeededFuture == null) { + this.succeededFuture = succeededFuture = new SucceededChannelFuture(channel(), executor()); + } + return succeededFuture; + } + + @Override + public ChannelFuture newFailedFuture(Throwable cause) { + return new FailedChannelFuture(channel(), executor(), cause); + } + + private boolean validatePromise(ChannelPromise promise, boolean allowVoidPromise) { + if (promise == null) { + throw new NullPointerException("promise"); + } + + if (promise.isDone()) { + // Check if the promise was cancelled and if so signal that the processing of the operation + // should not be performed. + // + // See https://github.com/netty/netty/issues/2349 + if (promise.isCancelled()) { + return false; + } + throw new IllegalArgumentException("promise already done: " + promise); + } + + if (promise.channel() != channel()) { + throw new IllegalArgumentException(String.format( + "promise.channel does not match: %s (expected: %s)", promise.channel(), channel())); + } + + if (promise.getClass() == DefaultChannelPromise.class) { + return true; + } + + if (!allowVoidPromise && promise instanceof VoidChannelPromise) { + throw new IllegalArgumentException( + StringUtil.simpleClassName(VoidChannelPromise.class) + " not allowed for this operation"); + } + + if (promise instanceof AbstractChannel.CloseFuture) { + throw new IllegalArgumentException( + StringUtil.simpleClassName(AbstractChannel.CloseFuture.class) + " not allowed in a pipeline"); + } + return true; + } + + private AbstractChannelHandlerContext findContextInbound() { + AbstractChannelHandlerContext ctx = this; + do { + ctx = ctx.next; + } while (!ctx.inbound); + return ctx; + } + + private AbstractChannelHandlerContext findContextOutbound() { + AbstractChannelHandlerContext ctx = this; + do { + ctx = ctx.prev; + } while (!ctx.outbound); + return ctx; + } + + @Override + public ChannelPromise voidPromise() { + return channel.voidPromise(); + } + + void setRemoved() { + removed = true; + } + + @Override + public boolean isRemoved() { + return removed; + } + + private static void safeExecute(EventExecutor executor, Runnable runnable, ChannelPromise promise, Object msg) { + try { + executor.execute(runnable); + } catch (Throwable cause) { + try { + promise.setFailure(cause); + } finally { + if (msg != null) { + ReferenceCountUtil.release(msg); + } + } + } + } + + abstract static class AbstractWriteTask extends RecyclableMpscLinkedQueueNode implements Runnable { + private AbstractChannelHandlerContext ctx; + private Object msg; + private ChannelPromise promise; + private int size; + + private AbstractWriteTask(Recycler.Handle handle) { + super(handle); + } + + protected static void init(AbstractWriteTask task, AbstractChannelHandlerContext ctx, + Object msg, int size, ChannelPromise promise) { + task.ctx = ctx; + task.msg = msg; + task.promise = promise; + task.size = size; + } + + @Override + public final void run() { + try { + if (size > 0) { + ChannelOutboundBuffer buffer = ctx.channel.unsafe().outboundBuffer(); + // Check for null as it may be set to null if the channel is closed already + if (buffer != null) { + buffer.decrementPendingOutboundBytes(size); + } + } + write(ctx, msg, promise); + } finally { + // Set to null so the GC can collect them directly + ctx = null; + msg = null; + promise = null; + } + } + + @Override + public Runnable value() { + return this; + } + + protected void write(AbstractChannelHandlerContext ctx, Object msg, ChannelPromise promise) { + ctx.invokeWrite(msg, promise); + } + } + + static final class WriteTask extends AbstractWriteTask implements SingleThreadEventLoop.NonWakeupRunnable { + + private static final Recycler RECYCLER = new Recycler() { + @Override + protected WriteTask newObject(Handle handle) { + return new WriteTask(handle); + } + }; + + private static WriteTask newInstance( + AbstractChannelHandlerContext ctx, Object msg, int size, ChannelPromise promise) { + WriteTask task = RECYCLER.get(); + init(task, ctx, msg, size, promise); + return task; + } + + private WriteTask(Recycler.Handle handle) { + super(handle); + } + + @Override + protected void recycle(Recycler.Handle handle) { + RECYCLER.recycle(this, handle); + } + } + + static final class WriteAndFlushTask extends AbstractWriteTask { + + private static final Recycler RECYCLER = new Recycler() { + @Override + protected WriteAndFlushTask newObject(Handle handle) { + return new WriteAndFlushTask(handle); + } + }; + + private static WriteAndFlushTask newInstance( + AbstractChannelHandlerContext ctx, Object msg, int size, ChannelPromise promise) { + WriteAndFlushTask task = RECYCLER.get(); + init(task, ctx, msg, size, promise); + return task; + } + + private WriteAndFlushTask(Recycler.Handle handle) { + super(handle); + } + + @Override + public void write(AbstractChannelHandlerContext ctx, Object msg, ChannelPromise promise) { + super.write(ctx, msg, promise); + ctx.invokeFlush(); + } + + @Override + protected void recycle(Recycler.Handle handle) { + RECYCLER.recycle(this, handle); + } + } +} diff --git a/common/src/common/net/channel/AbstractServerChannel.java b/common/src/common/net/channel/AbstractServerChannel.java new file mode 100644 index 0000000..ae1bd45 --- /dev/null +++ b/common/src/common/net/channel/AbstractServerChannel.java @@ -0,0 +1,83 @@ +/* + * Copyright 2012 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ +package common.net.channel; + +import java.net.SocketAddress; + +/** + * A skeletal server-side {@link Channel} implementation. A server-side + * {@link Channel} does not allow the following operations: + *
    + *
  • {@link #connect(SocketAddress, ChannelPromise)}
  • + *
  • {@link #disconnect(ChannelPromise)}
  • + *
  • {@link #write(Object, ChannelPromise)}
  • + *
  • {@link #flush()}
  • + *
  • and the shortcut methods which calls the methods mentioned above + *
+ */ +public abstract class AbstractServerChannel extends AbstractChannel implements ServerChannel { + + private static final ChannelMetadata METADATA = new ChannelMetadata(false); + + /** + * Creates a new instance. + */ + protected AbstractServerChannel() { + super(null); + } + + @Override + public ChannelMetadata metadata() { + return METADATA; + } + + @Override + public SocketAddress remoteAddress() { + return null; + } + + @Override + protected SocketAddress remoteAddress0() { + return null; + } + + @Override + protected void doDisconnect() throws Exception { + throw new UnsupportedOperationException(); + } + + @Override + protected AbstractUnsafe newUnsafe() { + return new DefaultServerUnsafe(); + } + + @Override + protected void doWrite(ChannelOutboundBuffer in) throws Exception { + throw new UnsupportedOperationException(); + } + + @Override + protected final Object filterOutboundMessage(Object msg) { + throw new UnsupportedOperationException(); + } + + private final class DefaultServerUnsafe extends AbstractUnsafe { + @Override + public void connect(SocketAddress remoteAddress, SocketAddress localAddress, ChannelPromise promise) { + safeSetFailure(promise, new UnsupportedOperationException()); + } + } +} diff --git a/common/src/common/net/channel/AdaptiveRecvByteBufAllocator.java b/common/src/common/net/channel/AdaptiveRecvByteBufAllocator.java new file mode 100644 index 0000000..f1eb52d --- /dev/null +++ b/common/src/common/net/channel/AdaptiveRecvByteBufAllocator.java @@ -0,0 +1,182 @@ +/* + * Copyright 2012 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ +package common.net.channel; + +import java.util.ArrayList; +import java.util.List; + +import common.net.buffer.ByteBuf; +import common.net.buffer.ByteBufAllocator; + +/** + * The {@link RecvByteBufAllocator} that automatically increases and + * decreases the predicted buffer size on feed back. + *

+ * It gradually increases the expected number of readable bytes if the previous + * read fully filled the allocated buffer. It gradually decreases the expected + * number of readable bytes if the read operation was not able to fill a certain + * amount of the allocated buffer two times consecutively. Otherwise, it keeps + * returning the same prediction. + */ +public class AdaptiveRecvByteBufAllocator implements RecvByteBufAllocator { + + static final int DEFAULT_MINIMUM = 64; + static final int DEFAULT_INITIAL = 1024; + static final int DEFAULT_MAXIMUM = 65536; + + private static final int INDEX_INCREMENT = 4; + private static final int INDEX_DECREMENT = 1; + + private static final int[] SIZE_TABLE; + + static { + List sizeTable = new ArrayList(); + for (int i = 16; i < 512; i += 16) { + sizeTable.add(i); + } + + for (int i = 512; i > 0; i <<= 1) { + sizeTable.add(i); + } + + SIZE_TABLE = new int[sizeTable.size()]; + for (int i = 0; i < SIZE_TABLE.length; i ++) { + SIZE_TABLE[i] = sizeTable.get(i); + } + } + + public static final AdaptiveRecvByteBufAllocator DEFAULT = new AdaptiveRecvByteBufAllocator(); + + private static int getSizeTableIndex(final int size) { + for (int low = 0, high = SIZE_TABLE.length - 1;;) { + if (high < low) { + return low; + } + if (high == low) { + return high; + } + + int mid = low + high >>> 1; + int a = SIZE_TABLE[mid]; + int b = SIZE_TABLE[mid + 1]; + if (size > b) { + low = mid + 1; + } else if (size < a) { + high = mid - 1; + } else if (size == a) { + return mid; + } else { + return mid + 1; + } + } + } + + private static final class HandleImpl implements Handle { + private final int minIndex; + private final int maxIndex; + private int index; + private int nextReceiveBufferSize; + private boolean decreaseNow; + + HandleImpl(int minIndex, int maxIndex, int initial) { + this.minIndex = minIndex; + this.maxIndex = maxIndex; + + index = getSizeTableIndex(initial); + nextReceiveBufferSize = SIZE_TABLE[index]; + } + + @Override + public ByteBuf allocate(ByteBufAllocator alloc) { + return alloc.ioBuffer(nextReceiveBufferSize); + } + + @Override + public int guess() { + return nextReceiveBufferSize; + } + + @Override + public void record(int actualReadBytes) { + if (actualReadBytes <= SIZE_TABLE[Math.max(0, index - INDEX_DECREMENT - 1)]) { + if (decreaseNow) { + index = Math.max(index - INDEX_DECREMENT, minIndex); + nextReceiveBufferSize = SIZE_TABLE[index]; + decreaseNow = false; + } else { + decreaseNow = true; + } + } else if (actualReadBytes >= nextReceiveBufferSize) { + index = Math.min(index + INDEX_INCREMENT, maxIndex); + nextReceiveBufferSize = SIZE_TABLE[index]; + decreaseNow = false; + } + } + } + + private final int minIndex; + private final int maxIndex; + private final int initial; + + /** + * Creates a new predictor with the default parameters. With the default + * parameters, the expected buffer size starts from {@code 1024}, does not + * go down below {@code 64}, and does not go up above {@code 65536}. + */ + private AdaptiveRecvByteBufAllocator() { + this(DEFAULT_MINIMUM, DEFAULT_INITIAL, DEFAULT_MAXIMUM); + } + + /** + * Creates a new predictor with the specified parameters. + * + * @param minimum the inclusive lower bound of the expected buffer size + * @param initial the initial buffer size when no feed back was received + * @param maximum the inclusive upper bound of the expected buffer size + */ + public AdaptiveRecvByteBufAllocator(int minimum, int initial, int maximum) { + if (minimum <= 0) { + throw new IllegalArgumentException("minimum: " + minimum); + } + if (initial < minimum) { + throw new IllegalArgumentException("initial: " + initial); + } + if (maximum < initial) { + throw new IllegalArgumentException("maximum: " + maximum); + } + + int minIndex = getSizeTableIndex(minimum); + if (SIZE_TABLE[minIndex] < minimum) { + this.minIndex = minIndex + 1; + } else { + this.minIndex = minIndex; + } + + int maxIndex = getSizeTableIndex(maximum); + if (SIZE_TABLE[maxIndex] > maximum) { + this.maxIndex = maxIndex - 1; + } else { + this.maxIndex = maxIndex; + } + + this.initial = initial; + } + + @Override + public Handle newHandle() { + return new HandleImpl(minIndex, maxIndex, initial); + } +} diff --git a/common/src/common/net/channel/Channel.java b/common/src/common/net/channel/Channel.java new file mode 100644 index 0000000..464bbff --- /dev/null +++ b/common/src/common/net/channel/Channel.java @@ -0,0 +1,511 @@ +/* + * Copyright 2012 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ +package common.net.channel; + +import java.net.SocketAddress; + +import common.net.buffer.ByteBufAllocator; +import common.net.util.AttributeMap; + + +/** + * A nexus to a network socket or a component which is capable of I/O + * operations such as read, write, connect, and bind. + *

+ * A channel provides a user: + *

    + *
  • the current state of the channel (e.g. is it open? is it connected?),
  • + *
  • the {@linkplain ChannelConfig configuration parameters} of the channel (e.g. receive buffer size),
  • + *
  • the I/O operations that the channel supports (e.g. read, write, connect, and bind), and
  • + *
  • the {@link ChannelPipeline} which handles all I/O events and requests + * associated with the channel.
  • + *
+ * + *

All I/O operations are asynchronous.

+ *

+ * All I/O operations in Netty are asynchronous. It means any I/O calls will + * return immediately with no guarantee that the requested I/O operation has + * been completed at the end of the call. Instead, you will be returned with + * a {@link ChannelFuture} instance which will notify you when the requested I/O + * operation has succeeded, failed, or canceled. + * + *

Channels are hierarchical

+ *

+ * A {@link Channel} can have a {@linkplain #parent() parent} depending on + * how it was created. For instance, a {@link SocketChannel}, that was accepted + * by {@link ServerSocketChannel}, will return the {@link ServerSocketChannel} + * as its parent on {@link #parent()}. + *

+ * The semantics of the hierarchical structure depends on the transport + * implementation where the {@link Channel} belongs to. For example, you could + * write a new {@link Channel} implementation that creates the sub-channels that + * share one socket connection, as BEEP and + * SSH do. + * + *

Downcast to access transport-specific operations

+ *

+ * Some transports exposes additional operations that is specific to the + * transport. Down-cast the {@link Channel} to sub-type to invoke such + * operations. For example, with the old I/O datagram transport, multicast + * join / leave operations are provided by {@link DatagramChannel}. + * + *

Release resources

+ *

+ * It is important to call {@link #close()} or {@link #close(ChannelPromise)} to release all + * resources once you are done with the {@link Channel}. This ensures all resources are + * released in a proper way, i.e. filehandles. + */ +public interface Channel extends AttributeMap, Comparable { + + /** + * Return the {@link EventLoop} this {@link Channel} was registered too. + */ + EventLoop eventLoop(); + + /** + * Returns the parent of this channel. + * + * @return the parent channel. + * {@code null} if this channel does not have a parent channel. + */ + Channel parent(); + + /** + * Returns the configuration of this channel. + */ + ChannelConfig config(); + + /** + * Returns {@code true} if the {@link Channel} is open an may get active later + */ + boolean isOpen(); + + /** + * Returns {@code true} if the {@link Channel} is registered with an {@link EventLoop}. + */ + boolean isRegistered(); + + /** + * Return {@code true} if the {@link Channel} is active and so connected. + */ + boolean isActive(); + + /** + * Return the {@link ChannelMetadata} of the {@link Channel} which describe the nature of the {@link Channel}. + */ + ChannelMetadata metadata(); + + /** + * Returns the local address where this channel is bound to. The returned + * {@link SocketAddress} is supposed to be down-cast into more concrete + * type such as {@link InetSocketAddress} to retrieve the detailed + * information. + * + * @return the local address of this channel. + * {@code null} if this channel is not bound. + */ + SocketAddress localAddress(); + + /** + * Returns the remote address where this channel is connected to. The + * returned {@link SocketAddress} is supposed to be down-cast into more + * concrete type such as {@link InetSocketAddress} to retrieve the detailed + * information. + * + * @return the remote address of this channel. + * {@code null} if this channel is not connected. + * If this channel is not connected but it can receive messages + * from arbitrary remote addresses (e.g. {@link DatagramChannel}, + * use {@link DatagramPacket#recipient()} to determine + * the origination of the received message as this method will + * return {@code null}. + */ + SocketAddress remoteAddress(); + + /** + * Returns the {@link ChannelFuture} which will be notified when this + * channel is closed. This method always returns the same future instance. + */ + ChannelFuture closeFuture(); + + /** + * Returns {@code true} if and only if the I/O thread will perform the + * requested write operation immediately. Any write requests made when + * this method returns {@code false} are queued until the I/O thread is + * ready to process the queued write requests. + */ + boolean isWritable(); + + /** + * Returns an internal-use-only object that provides unsafe operations. + */ + Unsafe unsafe(); + + /** + * Return the assigned {@link ChannelPipeline} + */ + ChannelPipeline pipeline(); + + /** + * Return the assigned {@link ByteBufAllocator} which will be used to allocate {@link ByteBuf}s. + */ + ByteBufAllocator alloc(); + + /** + * Return a new {@link ChannelPromise}. + */ + ChannelPromise newPromise(); + + /** + * Return an new {@link ChannelProgressivePromise} + */ +// ChannelProgressivePromise newProgressivePromise(); + + /** + * Create a new {@link ChannelFuture} which is marked as succeeded already. So {@link ChannelFuture#isSuccess()} + * will return {@code true}. All {@link FutureListener} added to it will be notified directly. Also + * every call of blocking methods will just return without blocking. + */ + ChannelFuture newSucceededFuture(); + + /** + * Create a new {@link ChannelFuture} which is marked as failed already. So {@link ChannelFuture#isSuccess()} + * will return {@code false}. All {@link FutureListener} added to it will be notified directly. Also + * every call of blocking methods will just return without blocking. + */ + ChannelFuture newFailedFuture(Throwable cause); + + /** + * Return a special ChannelPromise which can be reused for different operations. + *

+ * It's only supported to use + * it for {@link Channel#write(Object, ChannelPromise)}. + *

+ *

+ * Be aware that the returned {@link ChannelPromise} will not support most operations and should only be used + * if you want to save an object allocation for every write operation. You will not be able to detect if the + * operation was complete, only if it failed as the implementation will call + * {@link ChannelPipeline#fireExceptionCaught(Throwable)} in this case. + *

+ * Be aware this is an expert feature and should be used with care! + */ + ChannelPromise voidPromise(); + + /** + * Request to bind to the given {@link SocketAddress} and notify the {@link ChannelFuture} once the operation + * completes, either because the operation was successful or because of an error. + *

+ * This will result in having the + * {@link ChannelOutboundHandler#bind(ChannelHandlerContext, SocketAddress, ChannelPromise)} method + * called of the next {@link ChannelOutboundHandler} contained in the {@link ChannelPipeline} of the + * {@link Channel}. + */ + ChannelFuture bind(SocketAddress localAddress); + + /** + * Request to connect to the given {@link SocketAddress} and notify the {@link ChannelFuture} once the operation + * completes, either because the operation was successful or because of an error. + *

+ * If the connection fails because of a connection timeout, the {@link ChannelFuture} will get failed with + * a {@link ConnectTimeoutException}. If it fails because of connection refused a {@link ConnectException} + * will be used. + *

+ * This will result in having the + * {@link ChannelOutboundHandler#connect(ChannelHandlerContext, SocketAddress, SocketAddress, ChannelPromise)} + * method called of the next {@link ChannelOutboundHandler} contained in the {@link ChannelPipeline} of the + * {@link Channel}. + */ + ChannelFuture connect(SocketAddress remoteAddress); + + /** + * Request to connect to the given {@link SocketAddress} while bind to the localAddress and notify the + * {@link ChannelFuture} once the operation completes, either because the operation was successful or because of + * an error. + *

+ * This will result in having the + * {@link ChannelOutboundHandler#connect(ChannelHandlerContext, SocketAddress, SocketAddress, ChannelPromise)} + * method called of the next {@link ChannelOutboundHandler} contained in the {@link ChannelPipeline} of the + * {@link Channel}. + */ + ChannelFuture connect(SocketAddress remoteAddress, SocketAddress localAddress); + + /** + * Request to disconnect from the remote peer and notify the {@link ChannelFuture} once the operation completes, + * either because the operation was successful or because of an error. + *

+ * This will result in having the + * {@link ChannelOutboundHandler#disconnect(ChannelHandlerContext, ChannelPromise)} + * method called of the next {@link ChannelOutboundHandler} contained in the {@link ChannelPipeline} of the + * {@link Channel}. + */ + ChannelFuture disconnect(); + + /** + * Request to close this {@link Channel} and notify the {@link ChannelFuture} once the operation completes, + * either because the operation was successful or because of + * an error. + * + * After it is closed it is not possible to reuse it again. + *

+ * This will result in having the + * {@link ChannelOutboundHandler#close(ChannelHandlerContext, ChannelPromise)} + * method called of the next {@link ChannelOutboundHandler} contained in the {@link ChannelPipeline} of the + * {@link Channel}. + */ + ChannelFuture close(); + + /** + * Request to deregister this {@link Channel} from the previous assigned {@link EventExecutor} and notify the + * {@link ChannelFuture} once the operation completes, either because the operation was successful or because of + * an error. + *

+ * This will result in having the + * {@link ChannelOutboundHandler#deregister(ChannelHandlerContext, ChannelPromise)} + * method called of the next {@link ChannelOutboundHandler} contained in the {@link ChannelPipeline} of the + * {@link Channel}. + * + */ + ChannelFuture deregister(); + + /** + * Request to bind to the given {@link SocketAddress} and notify the {@link ChannelFuture} once the operation + * completes, either because the operation was successful or because of an error. + * + * The given {@link ChannelPromise} will be notified. + *

+ * This will result in having the + * {@link ChannelOutboundHandler#bind(ChannelHandlerContext, SocketAddress, ChannelPromise)} method + * called of the next {@link ChannelOutboundHandler} contained in the {@link ChannelPipeline} of the + * {@link Channel}. + */ + ChannelFuture bind(SocketAddress localAddress, ChannelPromise promise); + + /** + * Request to connect to the given {@link SocketAddress} and notify the {@link ChannelFuture} once the operation + * completes, either because the operation was successful or because of an error. + * + * The given {@link ChannelFuture} will be notified. + * + *

+ * If the connection fails because of a connection timeout, the {@link ChannelFuture} will get failed with + * a {@link ConnectTimeoutException}. If it fails because of connection refused a {@link ConnectException} + * will be used. + *

+ * This will result in having the + * {@link ChannelOutboundHandler#connect(ChannelHandlerContext, SocketAddress, SocketAddress, ChannelPromise)} + * method called of the next {@link ChannelOutboundHandler} contained in the {@link ChannelPipeline} of the + * {@link Channel}. + */ + ChannelFuture connect(SocketAddress remoteAddress, ChannelPromise promise); + + /** + * Request to connect to the given {@link SocketAddress} while bind to the localAddress and notify the + * {@link ChannelFuture} once the operation completes, either because the operation was successful or because of + * an error. + * + * The given {@link ChannelPromise} will be notified and also returned. + *

+ * This will result in having the + * {@link ChannelOutboundHandler#connect(ChannelHandlerContext, SocketAddress, SocketAddress, ChannelPromise)} + * method called of the next {@link ChannelOutboundHandler} contained in the {@link ChannelPipeline} of the + * {@link Channel}. + */ + ChannelFuture connect(SocketAddress remoteAddress, SocketAddress localAddress, ChannelPromise promise); + + /** + * Request to disconnect from the remote peer and notify the {@link ChannelFuture} once the operation completes, + * either because the operation was successful or because of an error. + * + * The given {@link ChannelPromise} will be notified. + *

+ * This will result in having the + * {@link ChannelOutboundHandler#disconnect(ChannelHandlerContext, ChannelPromise)} + * method called of the next {@link ChannelOutboundHandler} contained in the {@link ChannelPipeline} of the + * {@link Channel}. + */ + ChannelFuture disconnect(ChannelPromise promise); + + /** + * Request to close this {@link Channel} and notify the {@link ChannelFuture} once the operation completes, + * either because the operation was successful or because of + * an error. + * + * After it is closed it is not possible to reuse it again. + * The given {@link ChannelPromise} will be notified. + *

+ * This will result in having the + * {@link ChannelOutboundHandler#close(ChannelHandlerContext, ChannelPromise)} + * method called of the next {@link ChannelOutboundHandler} contained in the {@link ChannelPipeline} of the + * {@link Channel}. + */ + ChannelFuture close(ChannelPromise promise); + + /** + * Request to deregister this {@link Channel} from the previous assigned {@link EventExecutor} and notify the + * {@link ChannelFuture} once the operation completes, either because the operation was successful or because of + * an error. + * + * The given {@link ChannelPromise} will be notified. + *

+ * This will result in having the + * {@link ChannelOutboundHandler#deregister(ChannelHandlerContext, ChannelPromise)} + * method called of the next {@link ChannelOutboundHandler} contained in the {@link ChannelPipeline} of the + * {@link Channel}. + */ + ChannelFuture deregister(ChannelPromise promise); + + /** + * Request to Read data from the {@link Channel} into the first inbound buffer, triggers an + * {@link ChannelInboundHandler#channelRead(ChannelHandlerContext, Object)} event if data was + * read, and triggers a + * {@link ChannelInboundHandler#channelReadComplete(ChannelHandlerContext) channelReadComplete} event so the + * handler can decide to continue reading. If there's a pending read operation already, this method does nothing. + *

+ * This will result in having the + * {@link ChannelOutboundHandler#read(ChannelHandlerContext)} + * method called of the next {@link ChannelOutboundHandler} contained in the {@link ChannelPipeline} of the + * {@link Channel}. + */ + Channel read(); + + /** + * Request to write a message via this {@link Channel} through the {@link ChannelPipeline}. + * This method will not request to actual flush, so be sure to call {@link #flush()} + * once you want to request to flush all pending data to the actual transport. + */ + ChannelFuture write(Object msg); + + /** + * Request to write a message via this {@link Channel} through the {@link ChannelPipeline}. + * This method will not request to actual flush, so be sure to call {@link #flush()} + * once you want to request to flush all pending data to the actual transport. + */ + ChannelFuture write(Object msg, ChannelPromise promise); + + /** + * Request to flush all pending messages. + */ + Channel flush(); + + /** + * Shortcut for call {@link #write(Object, ChannelPromise)} and {@link #flush()}. + */ + ChannelFuture writeAndFlush(Object msg, ChannelPromise promise); + + /** + * Shortcut for call {@link #write(Object)} and {@link #flush()}. + */ + ChannelFuture writeAndFlush(Object msg); + + /** + * Unsafe operations that should never be called from user-code. These methods + * are only provided to implement the actual transport, and must be invoked from an I/O thread except for the + * following methods: + *

    + *
  • {@link #localAddress()}
  • + *
  • {@link #remoteAddress()}
  • + *
  • {@link #closeForcibly()}
  • + *
  • {@link #register(EventLoop, ChannelPromise)}
  • + *
  • {@link #voidPromise()}
  • + *
+ */ + interface Unsafe { + /** + * Return the {@link SocketAddress} to which is bound local or + * {@code null} if none. + */ + SocketAddress localAddress(); + + /** + * Return the {@link SocketAddress} to which is bound remote or + * {@code null} if none is bound yet. + */ + SocketAddress remoteAddress(); + + /** + * Register the {@link Channel} of the {@link ChannelPromise} with the {@link EventLoop} and notify + * the {@link ChannelFuture} once the registration was complete. + */ + void register(EventLoop eventLoop, ChannelPromise promise); + + /** + * Bind the {@link SocketAddress} to the {@link Channel} of the {@link ChannelPromise} and notify + * it once its done. + */ + void bind(SocketAddress localAddress, ChannelPromise promise); + + /** + * Connect the {@link Channel} of the given {@link ChannelFuture} with the given remote {@link SocketAddress}. + * If a specific local {@link SocketAddress} should be used it need to be given as argument. Otherwise just + * pass {@code null} to it. + * + * The {@link ChannelPromise} will get notified once the connect operation was complete. + */ + void connect(SocketAddress remoteAddress, SocketAddress localAddress, ChannelPromise promise); + + /** + * Disconnect the {@link Channel} of the {@link ChannelFuture} and notify the {@link ChannelPromise} once the + * operation was complete. + */ + void disconnect(ChannelPromise promise); + + /** + * Close the {@link Channel} of the {@link ChannelPromise} and notify the {@link ChannelPromise} once the + * operation was complete. + */ + void close(ChannelPromise promise); + + /** + * Closes the {@link Channel} immediately without firing any events. Probably only useful + * when registration attempt failed. + */ + void closeForcibly(); + + /** + * Deregister the {@link Channel} of the {@link ChannelPromise} from {@link EventLoop} and notify the + * {@link ChannelPromise} once the operation was complete. + */ + void deregister(ChannelPromise promise); + + /** + * Schedules a read operation that fills the inbound buffer of the first {@link ChannelInboundHandler} in the + * {@link ChannelPipeline}. If there's already a pending read operation, this method does nothing. + */ + void beginRead(); + + /** + * Schedules a write operation. + */ + void write(Object msg, ChannelPromise promise); + + /** + * Flush out all write operations scheduled via {@link #write(Object, ChannelPromise)}. + */ + void flush(); + + /** + * Return a special ChannelPromise which can be reused and passed to the operations in {@link Unsafe}. + * It will never be notified of a success or error and so is only a placeholder for operations + * that take a {@link ChannelPromise} as argument but for which you not want to get notified. + */ + ChannelPromise voidPromise(); + + /** + * Returns the {@link ChannelOutboundBuffer} of the {@link Channel} where the pending write requests are stored. + */ + ChannelOutboundBuffer outboundBuffer(); + } +} diff --git a/common/src/common/net/channel/ChannelConfig.java b/common/src/common/net/channel/ChannelConfig.java new file mode 100644 index 0000000..9204cd1 --- /dev/null +++ b/common/src/common/net/channel/ChannelConfig.java @@ -0,0 +1,249 @@ +/* + * Copyright 2012 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ +package common.net.channel; + +import java.util.Map; + +import common.net.buffer.ByteBufAllocator; + +/** + * A set of configuration properties of a {@link Channel}. + *

+ * Please down-cast to more specific configuration type such as + * {@link SocketChannelConfig} or use {@link #setOptions(Map)} to set the + * transport-specific properties: + *

+ * {@link Channel} ch = ...;
+ * {@link SocketChannelConfig} cfg = ({@link SocketChannelConfig}) ch.getConfig();
+ * cfg.setTcpNoDelay(false);
+ * 
+ * + *

Option map

+ * + * An option map property is a dynamic write-only property which allows + * the configuration of a {@link Channel} without down-casting its associated + * {@link ChannelConfig}. To update an option map, please call {@link #setOptions(Map)}. + *

+ * All {@link ChannelConfig} has the following options: + * + * + * + * + * + * + * + * + * + * + * + * + * + *
NameAssociated setter method
{@link ChannelOption#CONNECT_TIMEOUT_MILLIS}{@link #setConnectTimeoutMillis(int)}
{@link ChannelOption#WRITE_SPIN_COUNT}{@link #setWriteSpinCount(int)}
{@link ChannelOption#ALLOCATOR}{@link #setAllocator(ByteBufAllocator)}
{@link ChannelOption#AUTO_READ}{@link #setAutoRead(boolean)}
+ *

+ * More options are available in the sub-types of {@link ChannelConfig}. For + * example, you can configure the parameters which are specific to a TCP/IP + * socket as explained in {@link SocketChannelConfig}. + */ +public interface ChannelConfig { + + /** + * Return all set {@link ChannelOption}'s. + */ + Map, Object> getOptions(); + + /** + * Sets the configuration properties from the specified {@link Map}. + */ + boolean setOptions(Map, ?> options); + + /** + * Return the value of the given {@link ChannelOption} + */ + T getOption(ChannelOption option); + + /** + * Sets a configuration property with the specified name and value. + * To override this method properly, you must call the super class: + *

+     * public boolean setOption(ChannelOption<T> option, T value) {
+     *     if (super.setOption(option, value)) {
+     *         return true;
+     *     }
+     *
+     *     if (option.equals(additionalOption)) {
+     *         ....
+     *         return true;
+     *     }
+     *
+     *     return false;
+     * }
+     * 
+ * + * @return {@code true} if and only if the property has been set + */ + boolean setOption(ChannelOption option, T value); + + /** + * Returns the connect timeout of the channel in milliseconds. If the + * {@link Channel} does not support connect operation, this property is not + * used at all, and therefore will be ignored. + * + * @return the connect timeout in milliseconds. {@code 0} if disabled. + */ + int getConnectTimeoutMillis(); + + /** + * Sets the connect timeout of the channel in milliseconds. If the + * {@link Channel} does not support connect operation, this property is not + * used at all, and therefore will be ignored. + * + * @param connectTimeoutMillis the connect timeout in milliseconds. + * {@code 0} to disable. + */ + ChannelConfig setConnectTimeoutMillis(int connectTimeoutMillis); + + /** + * Returns the maximum number of messages to read per read loop. + * a {@link ChannelInboundHandler#channelRead(ChannelHandlerContext, Object) channelRead()} event. + * If this value is greater than 1, an event loop might attempt to read multiple times to procure multiple messages. + */ + int getMaxMessagesPerRead(); + + /** + * Sets the maximum number of messages to read per read loop. + * If this value is greater than 1, an event loop might attempt to read multiple times to procure multiple messages. + */ + ChannelConfig setMaxMessagesPerRead(int maxMessagesPerRead); + + /** + * Returns the maximum loop count for a write operation until + * {@link WritableByteChannel#write(ByteBuffer)} returns a non-zero value. + * It is similar to what a spin lock is used for in concurrency programming. + * It improves memory utilization and write throughput depending on + * the platform that JVM runs on. The default value is {@code 16}. + */ + int getWriteSpinCount(); + + /** + * Sets the maximum loop count for a write operation until + * {@link WritableByteChannel#write(ByteBuffer)} returns a non-zero value. + * It is similar to what a spin lock is used for in concurrency programming. + * It improves memory utilization and write throughput depending on + * the platform that JVM runs on. The default value is {@code 16}. + * + * @throws IllegalArgumentException + * if the specified value is {@code 0} or less than {@code 0} + */ + ChannelConfig setWriteSpinCount(int writeSpinCount); + + /** + * Returns {@link ByteBufAllocator} which is used for the channel + * to allocate buffers. + */ + ByteBufAllocator getAllocator(); + + /** + * Set the {@link ByteBufAllocator} which is used for the channel + * to allocate buffers. + */ + ChannelConfig setAllocator(ByteBufAllocator allocator); + + /** + * Returns {@link RecvByteBufAllocator} which is used for the channel + * to allocate receive buffers. + */ + RecvByteBufAllocator getRecvByteBufAllocator(); + + /** + * Set the {@link ByteBufAllocator} which is used for the channel + * to allocate receive buffers. + */ + ChannelConfig setRecvByteBufAllocator(RecvByteBufAllocator allocator); + + /** + * Returns {@code true} if and only if {@link ChannelHandlerContext#read()} will be invoked automatically so that + * a user application doesn't need to call it at all. The default value is {@code true}. + */ + boolean isAutoRead(); + + /** + * Sets if {@link ChannelHandlerContext#read()} will be invoked automatically so that a user application doesn't + * need to call it at all. The default value is {@code true}. + */ + ChannelConfig setAutoRead(boolean autoRead); + + /** + * @deprecated From version 5.0, {@link Channel} will not be closed on write failure. + * + * Returns {@code true} if and only if the {@link Channel} will be closed automatically and immediately on + * write failure. The default is {@code false}. + */ + @Deprecated + boolean isAutoClose(); + + /** + * @deprecated From version 5.0, {@link Channel} will not be closed on write failure. + * + * Sets whether the {@link Channel} should be closed automatically and immediately on write faillure. + * The default is {@code false}. + */ + @Deprecated + ChannelConfig setAutoClose(boolean autoClose); + + /** + * Returns the high water mark of the write buffer. If the number of bytes + * queued in the write buffer exceeds this value, {@link Channel#isWritable()} + * will start to return {@code false}. + */ + int getWriteBufferHighWaterMark(); + + /** + * Sets the high water mark of the write buffer. If the number of bytes + * queued in the write buffer exceeds this value, {@link Channel#isWritable()} + * will start to return {@code false}. + */ + ChannelConfig setWriteBufferHighWaterMark(int writeBufferHighWaterMark); + + /** + * Returns the low water mark of the write buffer. Once the number of bytes + * queued in the write buffer exceeded the + * {@linkplain #setWriteBufferHighWaterMark(int) high water mark} and then + * dropped down below this value, {@link Channel#isWritable()} will start to return + * {@code true} again. + */ + int getWriteBufferLowWaterMark(); + + /** + * Sets the low water mark of the write buffer. Once the number of bytes + * queued in the write buffer exceeded the + * {@linkplain #setWriteBufferHighWaterMark(int) high water mark} and then + * dropped down below this value, {@link Channel#isWritable()} will start to return + * {@code true} again. + */ + ChannelConfig setWriteBufferLowWaterMark(int writeBufferLowWaterMark); + + /** + * Returns {@link MessageSizeEstimator} which is used for the channel + * to detect the size of a message. + */ + MessageSizeEstimator getMessageSizeEstimator(); + + /** + * Set the {@link ByteBufAllocator} which is used for the channel + * to detect the size of a message. + */ + ChannelConfig setMessageSizeEstimator(MessageSizeEstimator estimator); +} diff --git a/common/src/common/net/channel/ChannelException.java b/common/src/common/net/channel/ChannelException.java new file mode 100644 index 0000000..721d03f --- /dev/null +++ b/common/src/common/net/channel/ChannelException.java @@ -0,0 +1,51 @@ +/* + * Copyright 2012 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ +package common.net.channel; + +/** + * A {@link RuntimeException} which is thrown when an I/O operation fails. + */ +public class ChannelException extends RuntimeException { + + private static final long serialVersionUID = 2908618315971075004L; + + /** + * Creates a new exception. + */ + public ChannelException() { + } + + /** + * Creates a new exception. + */ + public ChannelException(String message, Throwable cause) { + super(message, cause); + } + + /** + * Creates a new exception. + */ + public ChannelException(String message) { + super(message); + } + + /** + * Creates a new exception. + */ + public ChannelException(Throwable cause) { + super(cause); + } +} diff --git a/common/src/common/net/channel/ChannelFuture.java b/common/src/common/net/channel/ChannelFuture.java new file mode 100644 index 0000000..e849ad5 --- /dev/null +++ b/common/src/common/net/channel/ChannelFuture.java @@ -0,0 +1,192 @@ +/* + * Copyright 2012 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ +package common.net.channel; + +import common.net.util.concurrent.Future; +import common.net.util.concurrent.GenericFutureListener; + + +/** + * The result of an asynchronous {@link Channel} I/O operation. + *

+ * All I/O operations in Netty are asynchronous. It means any I/O calls will + * return immediately with no guarantee that the requested I/O operation has + * been completed at the end of the call. Instead, you will be returned with + * a {@link ChannelFuture} instance which gives you the information about the + * result or status of the I/O operation. + *

+ * A {@link ChannelFuture} is either uncompleted or completed. + * When an I/O operation begins, a new future object is created. The new future + * is uncompleted initially - it is neither succeeded, failed, nor cancelled + * because the I/O operation is not finished yet. If the I/O operation is + * finished either successfully, with failure, or by cancellation, the future is + * marked as completed with more specific information, such as the cause of the + * failure. Please note that even failure and cancellation belong to the + * completed state. + *

+ *                                      +---------------------------+
+ *                                      | Completed successfully    |
+ *                                      +---------------------------+
+ *                                 +---->      isDone() = true      |
+ * +--------------------------+    |    |   isSuccess() = true      |
+ * |        Uncompleted       |    |    +===========================+
+ * +--------------------------+    |    | Completed with failure    |
+ * |      isDone() = false    |    |    +---------------------------+
+ * |   isSuccess() = false    |----+---->   isDone() = true         |
+ * | isCancelled() = false    |    |    | cause() = non-null     |
+ * |    cause() = null     |    |    +===========================+
+ * +--------------------------+    |    | Completed by cancellation |
+ *                                 |    +---------------------------+
+ *                                 +---->      isDone() = true      |
+ *                                      | isCancelled() = true      |
+ *                                      +---------------------------+
+ * 
+ * + * Various methods are provided to let you check if the I/O operation has been + * completed, wait for the completion, and retrieve the result of the I/O + * operation. It also allows you to add {@link ChannelFutureListener}s so you + * can get notified when the I/O operation is completed. + * + *

Prefer {@link #addListener(GenericFutureListener)} to {@link #await()}

+ * + * It is recommended to prefer {@link #addListener(GenericFutureListener)} to + * {@link #await()} wherever possible to get notified when an I/O operation is + * done and to do any follow-up tasks. + *

+ * {@link #addListener(GenericFutureListener)} is non-blocking. It simply adds + * the specified {@link ChannelFutureListener} to the {@link ChannelFuture}, and + * I/O thread will notify the listeners when the I/O operation associated with + * the future is done. {@link ChannelFutureListener} yields the best + * performance and resource utilization because it does not block at all, but + * it could be tricky to implement a sequential logic if you are not used to + * event-driven programming. + *

+ * By contrast, {@link #await()} is a blocking operation. Once called, the + * caller thread blocks until the operation is done. It is easier to implement + * a sequential logic with {@link #await()}, but the caller thread blocks + * unnecessarily until the I/O operation is done and there's relatively + * expensive cost of inter-thread notification. Moreover, there's a chance of + * dead lock in a particular circumstance, which is described below. + * + *

Do not call {@link #await()} inside {@link ChannelHandler}

+ *

+ * The event handler methods in {@link ChannelHandler} is usually called by + * an I/O thread. If {@link #await()} is called by an event handler + * method, which is called by the I/O thread, the I/O operation it is waiting + * for might never be complete because {@link #await()} can block the I/O + * operation it is waiting for, which is a dead lock. + *

+ * // BAD - NEVER DO THIS
+ * {@code @Override}
+ * public void channelRead({@link ChannelHandlerContext} ctx, GoodByeMessage msg) {
+ *     {@link ChannelFuture} future = ctx.channel().close();
+ *     future.awaitUninterruptibly();
+ *     // Perform post-closure operation
+ *     // ...
+ * }
+ *
+ * // GOOD
+ * {@code @Override}
+ * public void channelRead({@link ChannelHandlerContext} ctx,  GoodByeMessage msg) {
+ *     {@link ChannelFuture} future = ctx.channel().close();
+ *     future.addListener(new {@link ChannelFutureListener}() {
+ *         public void operationComplete({@link ChannelFuture} future) {
+ *             // Perform post-closure operation
+ *             // ...
+ *         }
+ *     });
+ * }
+ * 
+ *

+ * In spite of the disadvantages mentioned above, there are certainly the cases + * where it is more convenient to call {@link #await()}. In such a case, please + * make sure you do not call {@link #await()} in an I/O thread. Otherwise, + * {@link BlockingOperationException} will be raised to prevent a dead lock. + * + *

Do not confuse I/O timeout and await timeout

+ * + * The timeout value you specify with {@link #await(long)}, + * {@link #await(long, TimeUnit)}, {@link #awaitUninterruptibly(long)}, or + * {@link #awaitUninterruptibly(long, TimeUnit)} are not related with I/O + * timeout at all. If an I/O operation times out, the future will be marked as + * 'completed with failure,' as depicted in the diagram above. For example, + * connect timeout should be configured via a transport-specific option: + *
+ * // BAD - NEVER DO THIS
+ * {@link Bootstrap} b = ...;
+ * {@link ChannelFuture} f = b.connect(...);
+ * f.awaitUninterruptibly(10, TimeUnit.SECONDS);
+ * if (f.isCancelled()) {
+ *     // Connection attempt cancelled by user
+ * } else if (!f.isSuccess()) {
+ *     // You might get a NullPointerException here because the future
+ *     // might not be completed yet.
+ *     f.cause().printStackTrace();
+ * } else {
+ *     // Connection established successfully
+ * }
+ *
+ * // GOOD
+ * {@link Bootstrap} b = ...;
+ * // Configure the connect timeout option.
+ * b.option({@link ChannelOption}.CONNECT_TIMEOUT_MILLIS, 10000);
+ * {@link ChannelFuture} f = b.connect(...);
+ * f.awaitUninterruptibly();
+ *
+ * // Now we are sure the future is completed.
+ * assert f.isDone();
+ *
+ * if (f.isCancelled()) {
+ *     // Connection attempt cancelled by user
+ * } else if (!f.isSuccess()) {
+ *     f.cause().printStackTrace();
+ * } else {
+ *     // Connection established successfully
+ * }
+ * 
+ */ +public interface ChannelFuture extends Future { + + /** + * Returns a channel where the I/O operation associated with this + * future takes place. + */ + Channel channel(); + + @Override + ChannelFuture addListener(GenericFutureListener> listener); + + @Override + ChannelFuture addListeners(GenericFutureListener>... listeners); + + @Override + ChannelFuture removeListener(GenericFutureListener> listener); + + @Override + ChannelFuture removeListeners(GenericFutureListener>... listeners); + + @Override + ChannelFuture sync() throws InterruptedException; + + @Override + ChannelFuture syncUninterruptibly(); + + @Override + ChannelFuture await() throws InterruptedException; + + @Override + ChannelFuture awaitUninterruptibly(); +} diff --git a/common/src/common/net/channel/ChannelFutureListener.java b/common/src/common/net/channel/ChannelFutureListener.java new file mode 100644 index 0000000..ec088b6 --- /dev/null +++ b/common/src/common/net/channel/ChannelFutureListener.java @@ -0,0 +1,74 @@ +/* + * Copyright 2012 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ +package common.net.channel; + +import common.net.util.concurrent.GenericFutureListener; + + +/** + * Listens to the result of a {@link ChannelFuture}. The result of the + * asynchronous {@link Channel} I/O operation is notified once this listener + * is added by calling {@link ChannelFuture#addListener(GenericFutureListener)}. + * + *

Return the control to the caller quickly

+ * + * {@link #operationComplete(Future)} is directly called by an I/O + * thread. Therefore, performing a time consuming task or a blocking operation + * in the handler method can cause an unexpected pause during I/O. If you need + * to perform a blocking operation on I/O completion, try to execute the + * operation in a different thread using a thread pool. + */ +public interface ChannelFutureListener extends GenericFutureListener { + + /** + * A {@link ChannelFutureListener} that closes the {@link Channel} which is + * associated with the specified {@link ChannelFuture}. + */ + ChannelFutureListener CLOSE = new ChannelFutureListener() { + @Override + public void operationComplete(ChannelFuture future) { + future.channel().close(); + } + }; + + /** + * A {@link ChannelFutureListener} that closes the {@link Channel} when the + * operation ended up with a failure or cancellation rather than a success. + */ + ChannelFutureListener CLOSE_ON_FAILURE = new ChannelFutureListener() { + @Override + public void operationComplete(ChannelFuture future) { + if (!future.isSuccess()) { + future.channel().close(); + } + } + }; + + /** + * A {@link ChannelFutureListener} that forwards the {@link Throwable} of the {@link ChannelFuture} into the + * {@link ChannelPipeline}. This mimics the old behavior of Netty 3. + */ + ChannelFutureListener FIRE_EXCEPTION_ON_FAILURE = new ChannelFutureListener() { + @Override + public void operationComplete(ChannelFuture future) { + if (!future.isSuccess()) { + future.channel().pipeline().fireExceptionCaught(future.cause()); + } + } + }; + + // Just a type alias +} diff --git a/common/src/common/net/channel/ChannelHandler.java b/common/src/common/net/channel/ChannelHandler.java new file mode 100644 index 0000000..4b78cde --- /dev/null +++ b/common/src/common/net/channel/ChannelHandler.java @@ -0,0 +1,211 @@ +/* + * Copyright 2012 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ +package common.net.channel; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Inherited; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * Handles or intercepts a {@link ChannelInboundInvoker} or {@link ChannelOutboundInvoker} operation, and forwards it + * to the next handler in a {@link ChannelPipeline}. + * + *

Sub-types

+ *

+ * {@link ChannelHandler} itself does not provide many methods. To handle a + * a {@link ChannelInboundInvoker} or {@link ChannelOutboundInvoker} operation + * you need to implement its sub-interfaces. There are many different sub-interfaces + * which handles inbound and outbound operations. + * + * But the most useful for developers may be: + *

    + *
  • {@link ChannelInboundHandlerAdapter} handles and intercepts inbound operations
  • + *
  • {@link ChannelOutboundHandlerAdapter} handles and intercepts outbound operations
  • + *
+ * + * You will also find more detailed explanation from the documentation of + * each sub-interface on how an event is interpreted when it goes upstream and + * downstream respectively. + * + *

The context object

+ *

+ * A {@link ChannelHandler} is provided with a {@link ChannelHandlerContext} + * object. A {@link ChannelHandler} is supposed to interact with the + * {@link ChannelPipeline} it belongs to via a context object. Using the + * context object, the {@link ChannelHandler} can pass events upstream or + * downstream, modify the pipeline dynamically, or store the information + * (using {@link AttributeKey}s) which is specific to the handler. + * + *

State management

+ * + * A {@link ChannelHandler} often needs to store some stateful information. + * The simplest and recommended approach is to use member variables: + *
+ * public interface Message {
+ *     // your methods here
+ * }
+ *
+ * public class DataServerHandler extends {@link SimpleChannelInboundHandler}<Message> {
+ *
+ *     private boolean loggedIn;
+ *
+ *     {@code @Override}
+ *     public void channelRead0({@link ChannelHandlerContext} ctx, Message message) {
+ *         {@link Channel} ch = e.getChannel();
+ *         if (message instanceof LoginMessage) {
+ *             authenticate((LoginMessage) message);
+ *             loggedIn = true;
+ *         } else (message instanceof GetDataMessage) {
+ *             if (loggedIn) {
+ *                 ch.write(fetchSecret((GetDataMessage) message));
+ *             } else {
+ *                 fail();
+ *             }
+ *         }
+ *     }
+ *     ...
+ * }
+ * 
+ * Because the handler instance has a state variable which is dedicated to + * one connection, you have to create a new handler instance for each new + * channel to avoid a race condition where a unauthenticated client can get + * the confidential information: + *
+ * // Create a new handler instance per channel.
+ * // See {@link ChannelInitializer#initChannel(Channel)}.
+ * public class DataServerInitializer extends {@link ChannelInitializer}<{@link Channel}> {
+ *     {@code @Override}
+ *     public void initChannel({@link Channel} channel) {
+ *         channel.pipeline().addLast("handler", new DataServerHandler());
+ *     }
+ * }
+ *
+ * 
+ * + *

Using {@link AttributeKey}

+ * + * Although it's recommended to use member variables to store the state of a + * handler, for some reason you might not want to create many handler instances. + * In such a case, you can use {@link AttributeKey}s which is provided by + * {@link ChannelHandlerContext}: + *
+ * public interface Message {
+ *     // your methods here
+ * }
+ *
+ * {@code @Sharable}
+ * public class DataServerHandler extends {@link SimpleChannelInboundHandler}<Message> {
+ *     private final {@link AttributeKey}<{@link Boolean}> auth =
+ *           {@link AttributeKey#valueOf(String) AttributeKey.valueOf("auth")};
+ *
+ *     {@code @Override}
+ *     public void channelRead({@link ChannelHandlerContext} ctx, Message message) {
+ *         {@link Attribute}<{@link Boolean}> attr = ctx.attr(auth);
+ *         {@link Channel} ch = ctx.channel();
+ *         if (message instanceof LoginMessage) {
+ *             authenticate((LoginMessage) o);
+ *             attr.set(true);
+ *         } else (message instanceof GetDataMessage) {
+ *             if (Boolean.TRUE.equals(attr.get())) {
+ *                 ch.write(fetchSecret((GetDataMessage) o));
+ *             } else {
+ *                 fail();
+ *             }
+ *         }
+ *     }
+ *     ...
+ * }
+ * 
+ * Now that the state of the handler isattached to the {@link ChannelHandlerContext}, you can add the + * same handler instance to different pipelines: + *
+ * public class DataServerInitializer extends {@link ChannelInitializer}<{@link Channel}> {
+ *
+ *     private static final DataServerHandler SHARED = new DataServerHandler();
+ *
+ *     {@code @Override}
+ *     public void initChannel({@link Channel} channel) {
+ *         channel.pipeline().addLast("handler", SHARED);
+ *     }
+ * }
+ * 
+ * + * + *

The {@code @Sharable} annotation

+ *

+ * In the example above which used an {@link AttributeKey}, + * you might have noticed the {@code @Sharable} annotation. + *

+ * If a {@link ChannelHandler} is annotated with the {@code @Sharable} + * annotation, it means you can create an instance of the handler just once and + * add it to one or more {@link ChannelPipeline}s multiple times without + * a race condition. + *

+ * If this annotation is not specified, you have to create a new handler + * instance every time you add it to a pipeline because it has unshared state + * such as member variables. + *

+ * This annotation is provided for documentation purpose, just like + * the JCIP annotations. + * + *

Additional resources worth reading

+ *

+ * Please refer to the {@link ChannelHandler}, and + * {@link ChannelPipeline} to find out more about inbound and outbound operations, + * what fundamental differences they have, how they flow in a pipeline, and how to handle + * the operation in your application. + */ +public interface ChannelHandler { + + /** + * Gets called after the {@link ChannelHandler} was added to the actual context and it's ready to handle events. + */ + void handlerAdded(ChannelHandlerContext ctx) throws Exception; + + /** + * Gets called after the {@link ChannelHandler} was removed from the actual context and it doesn't handle events + * anymore. + */ + void handlerRemoved(ChannelHandlerContext ctx) throws Exception; + + /** + * Gets called if a {@link Throwable} was thrown. + */ + void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception; + + /** + * Indicates that the same instance of the annotated {@link ChannelHandler} + * can be added to one or more {@link ChannelPipeline}s multiple times + * without a race condition. + *

+ * If this annotation is not specified, you have to create a new handler + * instance every time you add it to a pipeline because it has unshared + * state such as member variables. + *

+ * This annotation is provided for documentation purpose, just like + * the JCIP annotations. + */ + @Inherited + @Documented + @Target(ElementType.TYPE) + @Retention(RetentionPolicy.RUNTIME) + @interface Sharable { + // no value + } +} diff --git a/common/src/common/net/channel/ChannelHandlerAdapter.java b/common/src/common/net/channel/ChannelHandlerAdapter.java new file mode 100644 index 0000000..7137333 --- /dev/null +++ b/common/src/common/net/channel/ChannelHandlerAdapter.java @@ -0,0 +1,80 @@ +/* + * Copyright 2013 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ + +package common.net.channel; + +import java.util.Map; + +import common.net.util.internal.InternalThreadLocalMap; + +/** + * Skelton implementation of a {@link ChannelHandler}. + */ +public abstract class ChannelHandlerAdapter implements ChannelHandler { + + // Not using volatile because it's used only for a sanity check. + boolean added; + + /** + * Return {@code true} if the implementation is {@link Sharable} and so can be added + * to different {@link ChannelPipeline}s. + */ + public boolean isSharable() { + /** + * Cache the result of {@link Sharable} annotation detection to workaround a condition. We use a + * {@link ThreadLocal} and {@link WeakHashMap} to eliminate the volatile write/reads. Using different + * {@link WeakHashMap} instances per {@link Thread} is good enough for us and the number of + * {@link Thread}s are quite limited anyway. + * + * See #2289. + */ + Class clazz = getClass(); + Map, Boolean> cache = InternalThreadLocalMap.get().handlerSharableCache(); + Boolean sharable = cache.get(clazz); + if (sharable == null) { + sharable = clazz.isAnnotationPresent(Sharable.class); + cache.put(clazz, sharable); + } + return sharable; + } + + /** + * Do nothing by default, sub-classes may override this method. + */ + @Override + public void handlerAdded(ChannelHandlerContext ctx) throws Exception { + // NOOP + } + + /** + * Do nothing by default, sub-classes may override this method. + */ + @Override + public void handlerRemoved(ChannelHandlerContext ctx) throws Exception { + // NOOP + } + + /** + * Calls {@link ChannelHandlerContext#fireExceptionCaught(Throwable)} to forward + * to the next {@link ChannelHandler} in the {@link ChannelPipeline}. + * + * Sub-classes may override this method to change behavior. + */ + @Override + public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { + ctx.fireExceptionCaught(cause); + } +} diff --git a/common/src/common/net/channel/ChannelHandlerContext.java b/common/src/common/net/channel/ChannelHandlerContext.java new file mode 100644 index 0000000..81da8c7 --- /dev/null +++ b/common/src/common/net/channel/ChannelHandlerContext.java @@ -0,0 +1,489 @@ +/* + * Copyright 2012 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ +package common.net.channel; + + +import java.net.SocketAddress; + +import common.net.buffer.ByteBufAllocator; +import common.net.util.AttributeMap; +import common.net.util.concurrent.EventExecutor; + +/** + * Enables a {@link ChannelHandler} to interact with its {@link ChannelPipeline} + * and other handlers. A handler can notify the next {@link ChannelHandler} in the {@link ChannelPipeline}, + * modify the {@link ChannelPipeline} it belongs to dynamically. + * + *

Notify

+ * + * You can notify the closest handler in the + * same {@link ChannelPipeline} by calling one of the various methods provided here. + * Please refer to {@link ChannelPipeline} to understand how an event flows. + * + *

Modifying a pipeline

+ * + * You can get the {@link ChannelPipeline} your handler belongs to by calling + * {@link #pipeline()}. A non-trivial application could insert, remove, or + * replace handlers in the pipeline dynamically at runtime. + * + *

Retrieving for later use

+ * + * You can keep the {@link ChannelHandlerContext} for later use, such as + * triggering an event outside the handler methods, even from a different thread. + *
+ * public class MyHandler extends {@link ChannelDuplexHandler} {
+ *
+ *     private {@link ChannelHandlerContext} ctx;
+ *
+ *     public void beforeAdd({@link ChannelHandlerContext} ctx) {
+ *         this.ctx = ctx;
+ *     }
+ *
+ *     public void login(String username, password) {
+ *         ctx.write(new LoginMessage(username, password));
+ *     }
+ *     ...
+ * }
+ * 
+ * + *

Storing stateful information

+ * + * {@link #attr(AttributeKey)} allow you to + * store and access stateful information that is related with a handler and its + * context. Please refer to {@link ChannelHandler} to learn various recommended + * ways to manage stateful information. + * + *

A handler can have more than one context

+ * + * Please note that a {@link ChannelHandler} instance can be added to more than + * one {@link ChannelPipeline}. It means a single {@link ChannelHandler} + * instance can have more than one {@link ChannelHandlerContext} and therefore + * the single instance can be invoked with different + * {@link ChannelHandlerContext}s if it is added to one or more + * {@link ChannelPipeline}s more than once. + *

+ * For example, the following handler will have as many independent {@link AttributeKey}s + * as how many times it is added to pipelines, regardless if it is added to the + * same pipeline multiple times or added to different pipelines multiple times: + *

+ * public class FactorialHandler extends {@link ChannelInboundHandlerAdapter}<{@link Integer}> {
+ *
+ *   private final {@link AttributeKey}<{@link Integer}> counter =
+ *           new {@link AttributeKey}<{@link Integer}>("counter");
+ *
+ *   // This handler will receive a sequence of increasing integers starting
+ *   // from 1.
+ *   {@code @Override}
+ *   public void channelRead({@link ChannelHandlerContext} ctx, {@link Integer} integer) {
+ *     {@link Attribute}<{@link Integer}> attr = ctx.getAttr(counter);
+ *     Integer a = ctx.getAttr(counter).get();
+ *
+ *     if (a == null) {
+ *       a = 1;
+ *     }
+ *
+ *     attr.set(a * integer));
+ *   }
+ * }
+ *
+ * // Different context objects are given to "f1", "f2", "f3", and "f4" even if
+ * // they refer to the same handler instance.  Because the FactorialHandler
+ * // stores its state in a context object (as an (using an {@link AttributeKey}), the factorial is
+ * // calculated correctly 4 times once the two pipelines (p1 and p2) are active.
+ * FactorialHandler fh = new FactorialHandler();
+ *
+ * {@link ChannelPipeline} p1 = {@link Channels}.pipeline();
+ * p1.addLast("f1", fh);
+ * p1.addLast("f2", fh);
+ *
+ * {@link ChannelPipeline} p2 = {@link Channels}.pipeline();
+ * p2.addLast("f3", fh);
+ * p2.addLast("f4", fh);
+ * 
+ * + *

Additional resources worth reading

+ *

+ * Please refer to the {@link ChannelHandler}, and + * {@link ChannelPipeline} to find out more about inbound and outbound operations, + * what fundamental differences they have, how they flow in a pipeline, and how to handle + * the operation in your application. + */ +public interface ChannelHandlerContext + extends AttributeMap { + + /** + * Return the {@link Channel} which is bound to the {@link ChannelHandlerContext}. + */ + Channel channel(); + + /** + * The {@link EventExecutor} that is used to dispatch the events. This can also be used to directly + * submit tasks that get executed in the event loop. For more information please refer to the + * {@link EventExecutor} javadoc. + */ + EventExecutor executor(); + + /** + * The unique name of the {@link ChannelHandlerContext}.The name was used when then {@link ChannelHandler} + * was added to the {@link ChannelPipeline}. This name can also be used to access the registered + * {@link ChannelHandler} from the {@link ChannelPipeline}. + */ + String name(); + + /** + * The {@link ChannelHandler} that is bound this {@link ChannelHandlerContext}. + */ + ChannelHandler handler(); + + /** + * Return {@code true} if the {@link ChannelHandler} which belongs to this {@link ChannelHandler} was removed + * from the {@link ChannelPipeline}. Note that this method is only meant to be called from with in the + * {@link EventLoop}. + */ + boolean isRemoved(); + + /** + * A {@link Channel} was registered to its {@link EventLoop}. + * + * This will result in having the {@link ChannelInboundHandler#channelRegistered(ChannelHandlerContext)} method + * called of the next {@link ChannelInboundHandler} contained in the {@link ChannelPipeline} of the + * {@link Channel}. + */ + ChannelHandlerContext fireChannelRegistered(); + + /** + * A {@link Channel} was unregistered from its {@link EventLoop}. + * + * This will result in having the {@link ChannelInboundHandler#channelUnregistered(ChannelHandlerContext)} method + * called of the next {@link ChannelInboundHandler} contained in the {@link ChannelPipeline} of the + * {@link Channel}. + */ + ChannelHandlerContext fireChannelUnregistered(); + + /** + * A {@link Channel} is active now, which means it is connected. + * + * This will result in having the {@link ChannelInboundHandler#channelActive(ChannelHandlerContext)} method + * called of the next {@link ChannelInboundHandler} contained in the {@link ChannelPipeline} of the + * {@link Channel}. + */ + ChannelHandlerContext fireChannelActive(); + + /** + * A {@link Channel} is inactive now, which means it is closed. + * + * This will result in having the {@link ChannelInboundHandler#channelInactive(ChannelHandlerContext)} method + * called of the next {@link ChannelInboundHandler} contained in the {@link ChannelPipeline} of the + * {@link Channel}. + */ + ChannelHandlerContext fireChannelInactive(); + + /** + * A {@link Channel} received an {@link Throwable} in one of its inbound operations. + * + * This will result in having the {@link ChannelInboundHandler#exceptionCaught(ChannelHandlerContext, Throwable)} + * method called of the next {@link ChannelInboundHandler} contained in the {@link ChannelPipeline} of the + * {@link Channel}. + */ + ChannelHandlerContext fireExceptionCaught(Throwable cause); + + /** + * A {@link Channel} received an user defined event. + * + * This will result in having the {@link ChannelInboundHandler#userEventTriggered(ChannelHandlerContext, Object)} + * method called of the next {@link ChannelInboundHandler} contained in the {@link ChannelPipeline} of the + * {@link Channel}. + */ + ChannelHandlerContext fireUserEventTriggered(Object event); + + /** + * A {@link Channel} received a message. + * + * This will result in having the {@link ChannelInboundHandler#channelRead(ChannelHandlerContext, Object)} + * method called of the next {@link ChannelInboundHandler} contained in the {@link ChannelPipeline} of the + * {@link Channel}. + */ + ChannelHandlerContext fireChannelRead(Object msg); + + /** + * Triggers an {@link ChannelInboundHandler#channelWritabilityChanged(ChannelHandlerContext)} + * event to the next {@link ChannelInboundHandler} in the {@link ChannelPipeline}. + */ + ChannelHandlerContext fireChannelReadComplete(); + + /** + * Triggers an {@link ChannelInboundHandler#channelWritabilityChanged(ChannelHandlerContext)} + * event to the next {@link ChannelInboundHandler} in the {@link ChannelPipeline}. + */ + ChannelHandlerContext fireChannelWritabilityChanged(); + + /** + * Request to bind to the given {@link SocketAddress} and notify the {@link ChannelFuture} once the operation + * completes, either because the operation was successful or because of an error. + *

+ * This will result in having the + * {@link ChannelOutboundHandler#bind(ChannelHandlerContext, SocketAddress, ChannelPromise)} method + * called of the next {@link ChannelOutboundHandler} contained in the {@link ChannelPipeline} of the + * {@link Channel}. + */ + ChannelFuture bind(SocketAddress localAddress); + + /** + * Request to connect to the given {@link SocketAddress} and notify the {@link ChannelFuture} once the operation + * completes, either because the operation was successful or because of an error. + *

+ * If the connection fails because of a connection timeout, the {@link ChannelFuture} will get failed with + * a {@link ConnectTimeoutException}. If it fails because of connection refused a {@link ConnectException} + * will be used. + *

+ * This will result in having the + * {@link ChannelOutboundHandler#connect(ChannelHandlerContext, SocketAddress, SocketAddress, ChannelPromise)} + * method called of the next {@link ChannelOutboundHandler} contained in the {@link ChannelPipeline} of the + * {@link Channel}. + */ + ChannelFuture connect(SocketAddress remoteAddress); + + /** + * Request to connect to the given {@link SocketAddress} while bind to the localAddress and notify the + * {@link ChannelFuture} once the operation completes, either because the operation was successful or because of + * an error. + *

+ * This will result in having the + * {@link ChannelOutboundHandler#connect(ChannelHandlerContext, SocketAddress, SocketAddress, ChannelPromise)} + * method called of the next {@link ChannelOutboundHandler} contained in the {@link ChannelPipeline} of the + * {@link Channel}. + */ + ChannelFuture connect(SocketAddress remoteAddress, SocketAddress localAddress); + + /** + * Request to disconnect from the remote peer and notify the {@link ChannelFuture} once the operation completes, + * either because the operation was successful or because of an error. + *

+ * This will result in having the + * {@link ChannelOutboundHandler#disconnect(ChannelHandlerContext, ChannelPromise)} + * method called of the next {@link ChannelOutboundHandler} contained in the {@link ChannelPipeline} of the + * {@link Channel}. + */ + ChannelFuture disconnect(); + + /** + * Request to close the {@link Channel} and notify the {@link ChannelFuture} once the operation completes, + * either because the operation was successful or because of + * an error. + * + * After it is closed it is not possible to reuse it again. + *

+ * This will result in having the + * {@link ChannelOutboundHandler#close(ChannelHandlerContext, ChannelPromise)} + * method called of the next {@link ChannelOutboundHandler} contained in the {@link ChannelPipeline} of the + * {@link Channel}. + */ + ChannelFuture close(); + + /** + * Request to deregister from the previous assigned {@link EventExecutor} and notify the + * {@link ChannelFuture} once the operation completes, either because the operation was successful or because of + * an error. + *

+ * This will result in having the + * {@link ChannelOutboundHandler#deregister(ChannelHandlerContext, ChannelPromise)} + * method called of the next {@link ChannelOutboundHandler} contained in the {@link ChannelPipeline} of the + * {@link Channel}. + * + */ + ChannelFuture deregister(); + + /** + * Request to bind to the given {@link SocketAddress} and notify the {@link ChannelFuture} once the operation + * completes, either because the operation was successful or because of an error. + * + * The given {@link ChannelPromise} will be notified. + *

+ * This will result in having the + * {@link ChannelOutboundHandler#bind(ChannelHandlerContext, SocketAddress, ChannelPromise)} method + * called of the next {@link ChannelOutboundHandler} contained in the {@link ChannelPipeline} of the + * {@link Channel}. + */ + ChannelFuture bind(SocketAddress localAddress, ChannelPromise promise); + + /** + * Request to connect to the given {@link SocketAddress} and notify the {@link ChannelFuture} once the operation + * completes, either because the operation was successful or because of an error. + * + * The given {@link ChannelFuture} will be notified. + * + *

+ * If the connection fails because of a connection timeout, the {@link ChannelFuture} will get failed with + * a {@link ConnectTimeoutException}. If it fails because of connection refused a {@link ConnectException} + * will be used. + *

+ * This will result in having the + * {@link ChannelOutboundHandler#connect(ChannelHandlerContext, SocketAddress, SocketAddress, ChannelPromise)} + * method called of the next {@link ChannelOutboundHandler} contained in the {@link ChannelPipeline} of the + * {@link Channel}. + */ + ChannelFuture connect(SocketAddress remoteAddress, ChannelPromise promise); + + /** + * Request to connect to the given {@link SocketAddress} while bind to the localAddress and notify the + * {@link ChannelFuture} once the operation completes, either because the operation was successful or because of + * an error. + * + * The given {@link ChannelPromise} will be notified and also returned. + *

+ * This will result in having the + * {@link ChannelOutboundHandler#connect(ChannelHandlerContext, SocketAddress, SocketAddress, ChannelPromise)} + * method called of the next {@link ChannelOutboundHandler} contained in the {@link ChannelPipeline} of the + * {@link Channel}. + */ + ChannelFuture connect(SocketAddress remoteAddress, SocketAddress localAddress, ChannelPromise promise); + + /** + * Request to disconnect from the remote peer and notify the {@link ChannelFuture} once the operation completes, + * either because the operation was successful or because of an error. + * + * The given {@link ChannelPromise} will be notified. + *

+ * This will result in having the + * {@link ChannelOutboundHandler#disconnect(ChannelHandlerContext, ChannelPromise)} + * method called of the next {@link ChannelOutboundHandler} contained in the {@link ChannelPipeline} of the + * {@link Channel}. + */ + ChannelFuture disconnect(ChannelPromise promise); + + /** + * Request to close the {@link Channel} and notify the {@link ChannelFuture} once the operation completes, + * either because the operation was successful or because of + * an error. + * + * After it is closed it is not possible to reuse it again. + * The given {@link ChannelPromise} will be notified. + *

+ * This will result in having the + * {@link ChannelOutboundHandler#close(ChannelHandlerContext, ChannelPromise)} + * method called of the next {@link ChannelOutboundHandler} contained in the {@link ChannelPipeline} of the + * {@link Channel}. + */ + ChannelFuture close(ChannelPromise promise); + + /** + * Request to deregister from the previous assigned {@link EventExecutor} and notify the + * {@link ChannelFuture} once the operation completes, either because the operation was successful or because of + * an error. + * + * The given {@link ChannelPromise} will be notified. + *

+ * This will result in having the + * {@link ChannelOutboundHandler#deregister(ChannelHandlerContext, ChannelPromise)} + * method called of the next {@link ChannelOutboundHandler} contained in the {@link ChannelPipeline} of the + * {@link Channel}. + */ + ChannelFuture deregister(ChannelPromise promise); + + /** + * Request to Read data from the {@link Channel} into the first inbound buffer, triggers an + * {@link ChannelInboundHandler#channelRead(ChannelHandlerContext, Object)} event if data was + * read, and triggers a + * {@link ChannelInboundHandler#channelReadComplete(ChannelHandlerContext) channelReadComplete} event so the + * handler can decide to continue reading. If there's a pending read operation already, this method does nothing. + *

+ * This will result in having the + * {@link ChannelOutboundHandler#read(ChannelHandlerContext)} + * method called of the next {@link ChannelOutboundHandler} contained in the {@link ChannelPipeline} of the + * {@link Channel}. + */ + ChannelHandlerContext read(); + + /** + * Request to write a message via this {@link ChannelHandlerContext} through the {@link ChannelPipeline}. + * This method will not request to actual flush, so be sure to call {@link #flush()} + * once you want to request to flush all pending data to the actual transport. + */ + ChannelFuture write(Object msg); + + /** + * Request to write a message via this {@link ChannelHandlerContext} through the {@link ChannelPipeline}. + * This method will not request to actual flush, so be sure to call {@link #flush()} + * once you want to request to flush all pending data to the actual transport. + */ + ChannelFuture write(Object msg, ChannelPromise promise); + + /** + * Request to flush all pending messages via this ChannelOutboundInvoker. + */ + ChannelHandlerContext flush(); + + /** + * Shortcut for call {@link #write(Object, ChannelPromise)} and {@link #flush()}. + */ + ChannelFuture writeAndFlush(Object msg, ChannelPromise promise); + + /** + * Shortcut for call {@link #write(Object)} and {@link #flush()}. + */ + ChannelFuture writeAndFlush(Object msg); + + /** + * Return the assigned {@link ChannelPipeline} + */ + ChannelPipeline pipeline(); + + /** + * Return the assigned {@link ByteBufAllocator} which will be used to allocate {@link ByteBuf}s. + */ + ByteBufAllocator alloc(); + + /** + * Return a new {@link ChannelPromise}. + */ + ChannelPromise newPromise(); + + /** + * Return an new {@link ChannelProgressivePromise} + */ +// ChannelProgressivePromise newProgressivePromise(); + + /** + * Create a new {@link ChannelFuture} which is marked as succeeded already. So {@link ChannelFuture#isSuccess()} + * will return {@code true}. All {@link FutureListener} added to it will be notified directly. Also + * every call of blocking methods will just return without blocking. + */ + ChannelFuture newSucceededFuture(); + + /** + * Create a new {@link ChannelFuture} which is marked as failed already. So {@link ChannelFuture#isSuccess()} + * will return {@code false}. All {@link FutureListener} added to it will be notified directly. Also + * every call of blocking methods will just return without blocking. + */ + ChannelFuture newFailedFuture(Throwable cause); + + /** + * Return a special ChannelPromise which can be reused for different operations. + *

+ * It's only supported to use + * it for {@link ChannelHandlerContext#write(Object, ChannelPromise)}. + *

+ *

+ * Be aware that the returned {@link ChannelPromise} will not support most operations and should only be used + * if you want to save an object allocation for every write operation. You will not be able to detect if the + * operation was complete, only if it failed as the implementation will call + * {@link ChannelPipeline#fireExceptionCaught(Throwable)} in this case. + *

+ * Be aware this is an expert feature and should be used with care! + */ + ChannelPromise voidPromise(); + +} diff --git a/common/src/common/net/channel/ChannelInboundHandler.java b/common/src/common/net/channel/ChannelInboundHandler.java new file mode 100644 index 0000000..97c9691 --- /dev/null +++ b/common/src/common/net/channel/ChannelInboundHandler.java @@ -0,0 +1,74 @@ +/* + * Copyright 2012 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ +package common.net.channel; + +/** + * {@link ChannelHandler} which adds callbacks for state changes. This allows the user + * to hook in to state changes easily. + */ +public interface ChannelInboundHandler extends ChannelHandler { + + /** + * The {@link Channel} of the {@link ChannelHandlerContext} was registered with its {@link EventLoop} + */ + void channelRegistered(ChannelHandlerContext ctx) throws Exception; + + /** + * The {@link Channel} of the {@link ChannelHandlerContext} was unregistered from its {@link EventLoop} + */ + void channelUnregistered(ChannelHandlerContext ctx) throws Exception; + + /** + * The {@link Channel} of the {@link ChannelHandlerContext} is now active + */ + void channelActive(ChannelHandlerContext ctx) throws Exception; + + /** + * The {@link Channel} of the {@link ChannelHandlerContext} was registered is now inactive and reached its + * end of lifetime. + */ + void channelInactive(ChannelHandlerContext ctx) throws Exception; + + /** + * Invoked when the current {@link Channel} has read a message from the peer. + */ + void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception; + + /** + * Invoked when the last message read by the current read operation has been consumed by + * {@link #channelRead(ChannelHandlerContext, Object)}. If {@link ChannelOption#AUTO_READ} is off, no further + * attempt to read an inbound data from the current {@link Channel} will be made until + * {@link ChannelHandlerContext#read()} is called. + */ + void channelReadComplete(ChannelHandlerContext ctx) throws Exception; + + /** + * Gets called if an user event was triggered. + */ + void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception; + + /** + * Gets called once the writable state of a {@link Channel} changed. You can check the state with + * {@link Channel#isWritable()}. + */ + void channelWritabilityChanged(ChannelHandlerContext ctx) throws Exception; + + /** + * Gets called if a {@link Throwable} was thrown. + */ + @Override + void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception; +} diff --git a/common/src/common/net/channel/ChannelInboundHandlerAdapter.java b/common/src/common/net/channel/ChannelInboundHandlerAdapter.java new file mode 100644 index 0000000..7f6e8a2 --- /dev/null +++ b/common/src/common/net/channel/ChannelInboundHandlerAdapter.java @@ -0,0 +1,133 @@ +/* + * Copyright 2012 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ +package common.net.channel; + +/** + * Abstract base class for {@link ChannelInboundHandler} implementations which provide + * implementations of all of their methods. + * + *

+ * This implementation just forward the operation to the next {@link ChannelHandler} in the + * {@link ChannelPipeline}. Sub-classes may override a method implementation to change this. + *

+ *

+ * Be aware that messages are not released after the {@link #channelRead(ChannelHandlerContext, Object)} + * method returns automatically. If you are looking for a {@link ChannelInboundHandler} implementation that + * releases the received messages automatically, please see {@link SimpleChannelInboundHandler}. + *

+ */ +public class ChannelInboundHandlerAdapter extends ChannelHandlerAdapter implements ChannelInboundHandler { + + /** + * Calls {@link ChannelHandlerContext#fireChannelRegistered()} to forward + * to the next {@link ChannelInboundHandler} in the {@link ChannelPipeline}. + * + * Sub-classes may override this method to change behavior. + */ + @Override + public void channelRegistered(ChannelHandlerContext ctx) throws Exception { + ctx.fireChannelRegistered(); + } + + /** + * Calls {@link ChannelHandlerContext#fireChannelUnregistered()} to forward + * to the next {@link ChannelInboundHandler} in the {@link ChannelPipeline}. + * + * Sub-classes may override this method to change behavior. + */ + @Override + public void channelUnregistered(ChannelHandlerContext ctx) throws Exception { + ctx.fireChannelUnregistered(); + } + + /** + * Calls {@link ChannelHandlerContext#fireChannelActive()} to forward + * to the next {@link ChannelInboundHandler} in the {@link ChannelPipeline}. + * + * Sub-classes may override this method to change behavior. + */ + @Override + public void channelActive(ChannelHandlerContext ctx) throws Exception { + ctx.fireChannelActive(); + } + + /** + * Calls {@link ChannelHandlerContext#fireChannelInactive()} to forward + * to the next {@link ChannelInboundHandler} in the {@link ChannelPipeline}. + * + * Sub-classes may override this method to change behavior. + */ + @Override + public void channelInactive(ChannelHandlerContext ctx) throws Exception { + ctx.fireChannelInactive(); + } + + /** + * Calls {@link ChannelHandlerContext#fireChannelRead(Object)} to forward + * to the next {@link ChannelInboundHandler} in the {@link ChannelPipeline}. + * + * Sub-classes may override this method to change behavior. + */ + @Override + public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { + ctx.fireChannelRead(msg); + } + + /** + * Calls {@link ChannelHandlerContext#fireChannelReadComplete()} to forward + * to the next {@link ChannelInboundHandler} in the {@link ChannelPipeline}. + * + * Sub-classes may override this method to change behavior. + */ + @Override + public void channelReadComplete(ChannelHandlerContext ctx) throws Exception { + ctx.fireChannelReadComplete(); + } + + /** + * Calls {@link ChannelHandlerContext#fireUserEventTriggered(Object)} to forward + * to the next {@link ChannelInboundHandler} in the {@link ChannelPipeline}. + * + * Sub-classes may override this method to change behavior. + */ + @Override + public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception { + ctx.fireUserEventTriggered(evt); + } + + /** + * Calls {@link ChannelHandlerContext#fireChannelWritabilityChanged()} to forward + * to the next {@link ChannelInboundHandler} in the {@link ChannelPipeline}. + * + * Sub-classes may override this method to change behavior. + */ + @Override + public void channelWritabilityChanged(ChannelHandlerContext ctx) throws Exception { + ctx.fireChannelWritabilityChanged(); + } + + /** + * Calls {@link ChannelHandlerContext#fireExceptionCaught(Throwable)} to forward + * to the next {@link ChannelHandler} in the {@link ChannelPipeline}. + * + * Sub-classes may override this method to change behavior. + */ + @Override + public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) + throws Exception { + ctx.fireExceptionCaught(cause); + } +} diff --git a/common/src/common/net/channel/ChannelInitializer.java b/common/src/common/net/channel/ChannelInitializer.java new file mode 100644 index 0000000..31ad3ab --- /dev/null +++ b/common/src/common/net/channel/ChannelInitializer.java @@ -0,0 +1,82 @@ +/* + * Copyright 2012 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ +package common.net.channel; + +import common.net.channel.ChannelHandler.Sharable; +import common.net.util.internal.logging.InternalLogger; +import common.net.util.internal.logging.InternalLoggerFactory; + +/** + * A special {@link ChannelInboundHandler} which offers an easy way to initialize a {@link Channel} once it was + * registered to its {@link EventLoop}. + * + * Implementations are most often used in the context of {@link Bootstrap#handler(ChannelHandler)} , + * {@link ServerBootstrap#handler(ChannelHandler)} and {@link ServerBootstrap#childHandler(ChannelHandler)} to + * setup the {@link ChannelPipeline} of a {@link Channel}. + * + *
+ *
+ * public class MyChannelInitializer extends {@link ChannelInitializer} {
+ *     public void initChannel({@link Channel} channel) {
+ *         channel.pipeline().addLast("myHandler", new MyHandler());
+ *     }
+ * }
+ *
+ * {@link ServerBootstrap} bootstrap = ...;
+ * ...
+ * bootstrap.childHandler(new MyChannelInitializer());
+ * ...
+ * 
+ * Be aware that this class is marked as {@link Sharable} and so the implementation must be safe to be re-used. + * + * @param A sub-type of {@link Channel} + */ +@Sharable +public abstract class ChannelInitializer extends ChannelInboundHandlerAdapter { + + private static final InternalLogger logger = InternalLoggerFactory.getInstance(ChannelInitializer.class); + + /** + * This method will be called once the {@link Channel} was registered. After the method returns this instance + * will be removed from the {@link ChannelPipeline} of the {@link Channel}. + * + * @param ch the {@link Channel} which was registered. + * @throws Exception is thrown if an error occurs. In that case the {@link Channel} will be closed. + */ + protected abstract void initChannel(C ch) throws Exception; + + @Override + + public final void channelRegistered(ChannelHandlerContext ctx) throws Exception { + ChannelPipeline pipeline = ctx.pipeline(); + boolean success = false; + try { + initChannel((C) ctx.channel()); + pipeline.remove(this); + ctx.fireChannelRegistered(); + success = true; + } catch (Throwable t) { + logger.warn("Failed to initialize a channel. Closing: " + ctx.channel(), t); + } finally { + if (pipeline.context(this) != null) { + pipeline.remove(this); + } + if (!success) { + ctx.close(); + } + } + } +} diff --git a/common/src/common/net/channel/ChannelMetadata.java b/common/src/common/net/channel/ChannelMetadata.java new file mode 100644 index 0000000..375acb9 --- /dev/null +++ b/common/src/common/net/channel/ChannelMetadata.java @@ -0,0 +1,44 @@ +/* + * Copyright 2012 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ +package common.net.channel; + +/** + * Represents the properties of a {@link Channel} implementation. + */ +public final class ChannelMetadata { + + private final boolean hasDisconnect; + + /** + * Create a new instance + * + * @param hasDisconnect {@code true} if and only if the channel has the {@code disconnect()} operation + * that allows a user to disconnect and then call {@link Channel#connect(SocketAddress)} + * again, such as UDP/IP. + */ + public ChannelMetadata(boolean hasDisconnect) { + this.hasDisconnect = hasDisconnect; + } + + /** + * Returns {@code true} if and only if the channel has the {@code disconnect()} operation + * that allows a user to disconnect and then call {@link Channel#connect(SocketAddress)} again, + * such as UDP/IP. + */ + public boolean hasDisconnect() { + return hasDisconnect; + } +} diff --git a/common/src/common/net/channel/ChannelOption.java b/common/src/common/net/channel/ChannelOption.java new file mode 100644 index 0000000..040213f --- /dev/null +++ b/common/src/common/net/channel/ChannelOption.java @@ -0,0 +1,111 @@ +/* + * Copyright 2012 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ +package common.net.channel; + +import java.net.InetAddress; +import java.net.NetworkInterface; +import java.util.concurrent.ConcurrentMap; + +import common.net.buffer.ByteBufAllocator; +import common.net.util.UniqueName; +import common.net.util.internal.PlatformDependent; + +/** + * A {@link ChannelOption} allows to configure a {@link ChannelConfig} in a type-safe + * way. Which {@link ChannelOption} is supported depends on the actual implementation + * of {@link ChannelConfig} and may depend on the nature of the transport it belongs + * to. + * + * @param the type of the value which is valid for the {@link ChannelOption} + */ + +public class ChannelOption extends UniqueName { + + private static final ConcurrentMap names = PlatformDependent.newConcurrentHashMap(); + + public static final ChannelOption ALLOCATOR = valueOf("ALLOCATOR"); + public static final ChannelOption RCVBUF_ALLOCATOR = valueOf("RCVBUF_ALLOCATOR"); + public static final ChannelOption MESSAGE_SIZE_ESTIMATOR = valueOf("MESSAGE_SIZE_ESTIMATOR"); + + public static final ChannelOption CONNECT_TIMEOUT_MILLIS = valueOf("CONNECT_TIMEOUT_MILLIS"); + public static final ChannelOption MAX_MESSAGES_PER_READ = valueOf("MAX_MESSAGES_PER_READ"); + public static final ChannelOption WRITE_SPIN_COUNT = valueOf("WRITE_SPIN_COUNT"); + public static final ChannelOption WRITE_BUFFER_HIGH_WATER_MARK = valueOf("WRITE_BUFFER_HIGH_WATER_MARK"); + public static final ChannelOption WRITE_BUFFER_LOW_WATER_MARK = valueOf("WRITE_BUFFER_LOW_WATER_MARK"); + + public static final ChannelOption ALLOW_HALF_CLOSURE = valueOf("ALLOW_HALF_CLOSURE"); + public static final ChannelOption AUTO_READ = valueOf("AUTO_READ"); + + /** + * @deprecated From version 5.0, {@link Channel} will not be closed on write failure. + * + * {@code true} if and only if the {@link Channel} is closed automatically and immediately on write failure. + * The default is {@code false}. + */ + @Deprecated + public static final ChannelOption AUTO_CLOSE = valueOf("AUTO_CLOSE"); + + public static final ChannelOption SO_BROADCAST = valueOf("SO_BROADCAST"); + public static final ChannelOption SO_KEEPALIVE = valueOf("SO_KEEPALIVE"); + public static final ChannelOption SO_SNDBUF = valueOf("SO_SNDBUF"); + public static final ChannelOption SO_RCVBUF = valueOf("SO_RCVBUF"); + public static final ChannelOption SO_REUSEADDR = valueOf("SO_REUSEADDR"); + public static final ChannelOption SO_LINGER = valueOf("SO_LINGER"); + public static final ChannelOption SO_BACKLOG = valueOf("SO_BACKLOG"); + public static final ChannelOption SO_TIMEOUT = valueOf("SO_TIMEOUT"); + + public static final ChannelOption IP_TOS = valueOf("IP_TOS"); + public static final ChannelOption IP_MULTICAST_ADDR = valueOf("IP_MULTICAST_ADDR"); + public static final ChannelOption IP_MULTICAST_IF = valueOf("IP_MULTICAST_IF"); + public static final ChannelOption IP_MULTICAST_TTL = valueOf("IP_MULTICAST_TTL"); + public static final ChannelOption IP_MULTICAST_LOOP_DISABLED = valueOf("IP_MULTICAST_LOOP_DISABLED"); + + public static final ChannelOption TCP_NODELAY = valueOf("TCP_NODELAY"); + + @Deprecated + public static final ChannelOption AIO_READ_TIMEOUT = valueOf("AIO_READ_TIMEOUT"); + @Deprecated + public static final ChannelOption AIO_WRITE_TIMEOUT = valueOf("AIO_WRITE_TIMEOUT"); + + @Deprecated + public static final ChannelOption DATAGRAM_CHANNEL_ACTIVE_ON_REGISTRATION = + valueOf("DATAGRAM_CHANNEL_ACTIVE_ON_REGISTRATION"); + + /** + * Creates a new {@link ChannelOption} with the specified {@code name}. + */ + public static ChannelOption valueOf(String name) { + return new ChannelOption(name); + } + + /** + * @deprecated Use {@link #valueOf(String)} instead. + */ + @Deprecated + protected ChannelOption(String name) { + super(names, name); + } + + /** + * Validate the value which is set for the {@link ChannelOption}. Sub-classes + * may override this for special checks. + */ + public void validate(T value) { + if (value == null) { + throw new NullPointerException("value"); + } + } +} diff --git a/common/src/common/net/channel/ChannelOutboundBuffer.java b/common/src/common/net/channel/ChannelOutboundBuffer.java new file mode 100644 index 0000000..c072d25 --- /dev/null +++ b/common/src/common/net/channel/ChannelOutboundBuffer.java @@ -0,0 +1,650 @@ +/* + * Copyright 2013 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ +package common.net.channel; + +import java.nio.ByteBuffer; +import java.nio.channels.ClosedChannelException; +import java.util.concurrent.atomic.AtomicIntegerFieldUpdater; +import java.util.concurrent.atomic.AtomicLongFieldUpdater; + +import common.net.buffer.ByteBuf; +import common.net.buffer.Unpooled; +import common.net.util.Recycler; +import common.net.util.ReferenceCountUtil; +import common.net.util.Recycler.Handle; +import common.net.util.concurrent.FastThreadLocal; +import common.net.util.internal.InternalThreadLocalMap; +import common.net.util.internal.PlatformDependent; +import common.net.util.internal.logging.InternalLogger; +import common.net.util.internal.logging.InternalLoggerFactory; + +/** + * (Transport implementors only) an internal data structure used by {@link AbstractChannel} to store its pending + * outbound write requests. + * + * All the methods should only be called by the {@link EventLoop} of the {@link Channel}. + */ +public final class ChannelOutboundBuffer { + + private static final InternalLogger logger = InternalLoggerFactory.getInstance(ChannelOutboundBuffer.class); + + private static final FastThreadLocal NIO_BUFFERS = new FastThreadLocal() { + @Override + protected ByteBuffer[] initialValue() throws Exception { + return new ByteBuffer[1024]; + } + }; + + private final Channel channel; + + // Entry(flushedEntry) --> ... Entry(unflushedEntry) --> ... Entry(tailEntry) + // + // The Entry that is the first in the linked-list structure that was flushed + private Entry flushedEntry; + // The Entry which is the first unflushed in the linked-list structure + private Entry unflushedEntry; + // The Entry which represents the tail of the buffer + private Entry tailEntry; + // The number of flushed entries that are not written yet + private int flushed; + + private int nioBufferCount; + private long nioBufferSize; + + private boolean inFail; + + private static final AtomicLongFieldUpdater TOTAL_PENDING_SIZE_UPDATER; + + + private volatile long totalPendingSize; + + private static final AtomicIntegerFieldUpdater WRITABLE_UPDATER; + + + private volatile int writable = 1; + + static { + AtomicIntegerFieldUpdater writableUpdater = + PlatformDependent.newAtomicIntegerFieldUpdater(ChannelOutboundBuffer.class, "writable"); + if (writableUpdater == null) { + writableUpdater = AtomicIntegerFieldUpdater.newUpdater(ChannelOutboundBuffer.class, "writable"); + } + WRITABLE_UPDATER = writableUpdater; + + AtomicLongFieldUpdater pendingSizeUpdater = + PlatformDependent.newAtomicLongFieldUpdater(ChannelOutboundBuffer.class, "totalPendingSize"); + if (pendingSizeUpdater == null) { + pendingSizeUpdater = AtomicLongFieldUpdater.newUpdater(ChannelOutboundBuffer.class, "totalPendingSize"); + } + TOTAL_PENDING_SIZE_UPDATER = pendingSizeUpdater; + } + + ChannelOutboundBuffer(AbstractChannel channel) { + this.channel = channel; + } + + /** + * Add given message to this {@link ChannelOutboundBuffer}. The given {@link ChannelPromise} will be notified once + * the message was written. + */ + public void addMessage(Object msg, int size, ChannelPromise promise) { + Entry entry = Entry.newInstance(msg, size, total(msg), promise); + if (tailEntry == null) { + flushedEntry = null; + tailEntry = entry; + } else { + Entry tail = tailEntry; + tail.next = entry; + tailEntry = entry; + } + if (unflushedEntry == null) { + unflushedEntry = entry; + } + + // increment pending bytes after adding message to the unflushed arrays. + // See https://github.com/netty/netty/issues/1619 + incrementPendingOutboundBytes(size); + } + + /** + * Add a flush to this {@link ChannelOutboundBuffer}. This means all previous added messages are marked as flushed + * and so you will be able to handle them. + */ + public void addFlush() { + // There is no need to process all entries if there was already a flush before and no new messages + // where added in the meantime. + // + // See https://github.com/netty/netty/issues/2577 + Entry entry = unflushedEntry; + if (entry != null) { + if (flushedEntry == null) { + // there is no flushedEntry yet, so start with the entry + flushedEntry = entry; + } + do { + flushed ++; + if (!entry.promise.setUncancellable()) { + // Was cancelled so make sure we free up memory and notify about the freed bytes + int pending = entry.cancel(); + decrementPendingOutboundBytes(pending); + } + entry = entry.next; + } while (entry != null); + + // All flushed so reset unflushedEntry + unflushedEntry = null; + } + } + + /** + * Increment the pending bytes which will be written at some point. + * This method is thread-safe! + */ + void incrementPendingOutboundBytes(long size) { + if (size == 0) { + return; + } + + long newWriteBufferSize = TOTAL_PENDING_SIZE_UPDATER.addAndGet(this, size); + if (newWriteBufferSize > channel.config().getWriteBufferHighWaterMark()) { + if (WRITABLE_UPDATER.compareAndSet(this, 1, 0)) { + channel.pipeline().fireChannelWritabilityChanged(); + } + } + } + + /** + * Decrement the pending bytes which will be written at some point. + * This method is thread-safe! + */ + void decrementPendingOutboundBytes(long size) { + if (size == 0) { + return; + } + + long newWriteBufferSize = TOTAL_PENDING_SIZE_UPDATER.addAndGet(this, -size); + if (newWriteBufferSize == 0 || newWriteBufferSize < channel.config().getWriteBufferLowWaterMark()) { + if (WRITABLE_UPDATER.compareAndSet(this, 0, 1)) { + channel.pipeline().fireChannelWritabilityChanged(); + } + } + } + + private static long total(Object msg) { + if (msg instanceof ByteBuf) { + return ((ByteBuf) msg).readableBytes(); + } +// if (msg instanceof FileRegion) { +// return ((FileRegion) msg).count(); +// } +// if (msg instanceof ByteBufHolder) { +// return ((ByteBufHolder) msg).content().readableBytes(); +// } + return -1; + } + + /** + * Return the current message to write or {@code null} if nothing was flushed before and so is ready to be written. + */ + public Object current() { + Entry entry = flushedEntry; + if (entry == null) { + return null; + } + + return entry.msg; + } + + /** + * Notify the {@link ChannelPromise} of the current message about writing progress. + */ + public void progress(long amount) { + Entry e = flushedEntry; + assert e != null; + ChannelPromise p = e.promise; + if (p instanceof ChannelProgressivePromise) { + long progress = e.progress + amount; + e.progress = progress; + ((ChannelProgressivePromise) p).tryProgress(progress, e.total); + } + } + + /** + * Will remove the current message, mark its {@link ChannelPromise} as success and return {@code true}. If no + * flushed message exists at the time this method is called it will return {@code false} to signal that no more + * messages are ready to be handled. + */ + public boolean remove() { + Entry e = flushedEntry; + if (e == null) { + return false; + } + Object msg = e.msg; + + ChannelPromise promise = e.promise; + int size = e.pendingSize; + + removeEntry(e); + + if (!e.cancelled) { + // only release message, notify and decrement if it was not canceled before. + ReferenceCountUtil.safeRelease(msg); + safeSuccess(promise); + decrementPendingOutboundBytes(size); + } + + // recycle the entry + e.recycle(); + + return true; + } + + /** + * Will remove the current message, mark its {@link ChannelPromise} as failure using the given {@link Throwable} + * and return {@code true}. If no flushed message exists at the time this method is called it will return + * {@code false} to signal that no more messages are ready to be handled. + */ + public boolean remove(Throwable cause) { + Entry e = flushedEntry; + if (e == null) { + return false; + } + Object msg = e.msg; + + ChannelPromise promise = e.promise; + int size = e.pendingSize; + + removeEntry(e); + + if (!e.cancelled) { + // only release message, fail and decrement if it was not canceled before. + ReferenceCountUtil.safeRelease(msg); + + safeFail(promise, cause); + decrementPendingOutboundBytes(size); + } + + // recycle the entry + e.recycle(); + + return true; + } + + private void removeEntry(Entry e) { + if (-- flushed == 0) { + // processed everything + flushedEntry = null; + if (e == tailEntry) { + tailEntry = null; + unflushedEntry = null; + } + } else { + flushedEntry = e.next; + } + } + + /** + * Removes the fully written entries and update the reader index of the partially written entry. + * This operation assumes all messages in this buffer is {@link ByteBuf}. + */ + public void removeBytes(long writtenBytes) { + for (;;) { + Object msg = current(); + if (!(msg instanceof ByteBuf)) { + assert writtenBytes == 0; + break; + } + + final ByteBuf buf = (ByteBuf) msg; + final int readerIndex = buf.readerIndex(); + final int readableBytes = buf.writerIndex() - readerIndex; + + if (readableBytes <= writtenBytes) { + if (writtenBytes != 0) { + progress(readableBytes); + writtenBytes -= readableBytes; + } + remove(); + } else { // readableBytes > writtenBytes + if (writtenBytes != 0) { + buf.readerIndex(readerIndex + (int) writtenBytes); + progress(writtenBytes); + } + break; + } + } + } + + /** + * Returns an array of direct NIO buffers if the currently pending messages are made of {@link ByteBuf} only. + * {@link #nioBufferCount()} and {@link #nioBufferSize()} will return the number of NIO buffers in the returned + * array and the total number of readable bytes of the NIO buffers respectively. + *

+ * Note that the returned array is reused and thus should not escape + * {@link AbstractChannel#doWrite(ChannelOutboundBuffer)}. + * Refer to {@link NioSocketChannel#doWrite(ChannelOutboundBuffer)} for an example. + *

+ */ + public ByteBuffer[] nioBuffers() { + long nioBufferSize = 0; + int nioBufferCount = 0; + final InternalThreadLocalMap threadLocalMap = InternalThreadLocalMap.get(); + ByteBuffer[] nioBuffers = NIO_BUFFERS.get(threadLocalMap); + Entry entry = flushedEntry; + while (isFlushedEntry(entry) && entry.msg instanceof ByteBuf) { + if (!entry.cancelled) { + ByteBuf buf = (ByteBuf) entry.msg; + final int readerIndex = buf.readerIndex(); + final int readableBytes = buf.writerIndex() - readerIndex; + + if (readableBytes > 0) { + nioBufferSize += readableBytes; + int count = entry.count; + if (count == -1) { + //noinspection ConstantValueVariableUse + entry.count = count = buf.nioBufferCount(); + } + int neededSpace = nioBufferCount + count; + if (neededSpace > nioBuffers.length) { + nioBuffers = expandNioBufferArray(nioBuffers, neededSpace, nioBufferCount); + NIO_BUFFERS.set(threadLocalMap, nioBuffers); + } + if (count == 1) { + ByteBuffer nioBuf = entry.buf; + if (nioBuf == null) { + // cache ByteBuffer as it may need to create a new ByteBuffer instance if its a + // derived buffer + entry.buf = nioBuf = buf.internalNioBuffer(readerIndex, readableBytes); + } + nioBuffers[nioBufferCount ++] = nioBuf; + } else { + ByteBuffer[] nioBufs = entry.bufs; + if (nioBufs == null) { + // cached ByteBuffers as they may be expensive to create in terms + // of Object allocation + entry.bufs = nioBufs = buf.nioBuffers(); + } + nioBufferCount = fillBufferArray(nioBufs, nioBuffers, nioBufferCount); + } + } + } + entry = entry.next; + } + this.nioBufferCount = nioBufferCount; + this.nioBufferSize = nioBufferSize; + + return nioBuffers; + } + + private static int fillBufferArray(ByteBuffer[] nioBufs, ByteBuffer[] nioBuffers, int nioBufferCount) { + for (ByteBuffer nioBuf: nioBufs) { + if (nioBuf == null) { + break; + } + nioBuffers[nioBufferCount ++] = nioBuf; + } + return nioBufferCount; + } + + private static ByteBuffer[] expandNioBufferArray(ByteBuffer[] array, int neededSpace, int size) { + int newCapacity = array.length; + do { + // double capacity until it is big enough + // See https://github.com/netty/netty/issues/1890 + newCapacity <<= 1; + + if (newCapacity < 0) { + throw new IllegalStateException(); + } + + } while (neededSpace > newCapacity); + + ByteBuffer[] newArray = new ByteBuffer[newCapacity]; + System.arraycopy(array, 0, newArray, 0, size); + + return newArray; + } + + /** + * Returns the number of {@link ByteBuffer} that can be written out of the {@link ByteBuffer} array that was + * obtained via {@link #nioBuffers()}. This method MUST be called after {@link #nioBuffers()} + * was called. + */ + public int nioBufferCount() { + return nioBufferCount; + } + + /** + * Returns the number of bytes that can be written out of the {@link ByteBuffer} array that was + * obtained via {@link #nioBuffers()}. This method MUST be called after {@link #nioBuffers()} + * was called. + */ + public long nioBufferSize() { + return nioBufferSize; + } + + boolean isWritable() { + return writable != 0; + } + + /** + * Returns the number of flushed messages in this {@link ChannelOutboundBuffer}. + */ + public int size() { + return flushed; + } + + /** + * Returns {@code true} if there are flushed messages in this {@link ChannelOutboundBuffer} or {@code false} + * otherwise. + */ + public boolean isEmpty() { + return flushed == 0; + } + + void failFlushed(Throwable cause) { + // Make sure that this method does not reenter. A listener added to the current promise can be notified by the + // current thread in the tryFailure() call of the loop below, and the listener can trigger another fail() call + // indirectly (usually by closing the channel.) + // + // See https://github.com/netty/netty/issues/1501 + if (inFail) { + return; + } + + try { + inFail = true; + for (;;) { + if (!remove(cause)) { + break; + } + } + } finally { + inFail = false; + } + } + + void close(final ClosedChannelException cause) { + if (inFail) { + channel.eventLoop().execute(new Runnable() { + @Override + public void run() { + close(cause); + } + }); + return; + } + + inFail = true; + + if (channel.isOpen()) { + throw new IllegalStateException("close() must be invoked after the channel is closed."); + } + + if (!isEmpty()) { + throw new IllegalStateException("close() must be invoked after all flushed writes are handled."); + } + + // Release all unflushed messages. + try { + Entry e = unflushedEntry; + while (e != null) { + // Just decrease; do not trigger any events via decrementPendingOutboundBytes() + int size = e.pendingSize; + TOTAL_PENDING_SIZE_UPDATER.addAndGet(this, -size); + + if (!e.cancelled) { + ReferenceCountUtil.safeRelease(e.msg); + safeFail(e.promise, cause); + } + e = e.recycleAndGetNext(); + } + } finally { + inFail = false; + } + } + + private static void safeSuccess(ChannelPromise promise) { + if (!(promise instanceof VoidChannelPromise) && !promise.trySuccess()) { + logger.warn("Failed to mark a promise as success because it is done already: {}", promise); + } + } + + private static void safeFail(ChannelPromise promise, Throwable cause) { + if (!(promise instanceof VoidChannelPromise) && !promise.tryFailure(cause)) { + logger.warn("Failed to mark a promise as failure because it's done already: {}", promise, cause); + } + } + + @Deprecated + public void recycle() { + // NOOP + } + + public long totalPendingWriteBytes() { + return totalPendingSize; + } + + /** + * Call {@link MessageProcessor#processMessage(Object)} for each flushed message + * in this {@link ChannelOutboundBuffer} until {@link MessageProcessor#processMessage(Object)} + * returns {@code false} or there are no more flushed messages to process. + */ + public void forEachFlushedMessage(MessageProcessor processor) throws Exception { + if (processor == null) { + throw new NullPointerException("processor"); + } + + Entry entry = flushedEntry; + if (entry == null) { + return; + } + + do { + if (!entry.cancelled) { + if (!processor.processMessage(entry.msg)) { + return; + } + } + entry = entry.next; + } while (isFlushedEntry(entry)); + } + + private boolean isFlushedEntry(Entry e) { + return e != null && e != unflushedEntry; + } + + public interface MessageProcessor { + /** + * Will be called for each flushed message until it either there are no more flushed messages or this + * method returns {@code false}. + */ + boolean processMessage(Object msg) throws Exception; + } + + static final class Entry { + private static final Recycler RECYCLER = new Recycler() { + @Override + protected Entry newObject(Handle handle) { + return new Entry(handle); + } + }; + + private final Handle handle; + Entry next; + Object msg; + ByteBuffer[] bufs; + ByteBuffer buf; + ChannelPromise promise; + long progress; + long total; + int pendingSize; + int count = -1; + boolean cancelled; + + private Entry(Handle handle) { + this.handle = handle; + } + + static Entry newInstance(Object msg, int size, long total, ChannelPromise promise) { + Entry entry = RECYCLER.get(); + entry.msg = msg; + entry.pendingSize = size; + entry.total = total; + entry.promise = promise; + return entry; + } + + int cancel() { + if (!cancelled) { + cancelled = true; + int pSize = pendingSize; + + // release message and replace with an empty buffer + ReferenceCountUtil.safeRelease(msg); + msg = Unpooled.EMPTY_BUFFER; + + pendingSize = 0; + total = 0; + progress = 0; + bufs = null; + buf = null; + return pSize; + } + return 0; + } + + void recycle() { + next = null; + bufs = null; + buf = null; + msg = null; + promise = null; + progress = 0; + total = 0; + pendingSize = 0; + count = -1; + cancelled = false; + RECYCLER.recycle(this, handle); + } + + Entry recycleAndGetNext() { + Entry next = this.next; + recycle(); + return next; + } + } +} diff --git a/common/src/common/net/channel/ChannelOutboundHandler.java b/common/src/common/net/channel/ChannelOutboundHandler.java new file mode 100644 index 0000000..9cce0d7 --- /dev/null +++ b/common/src/common/net/channel/ChannelOutboundHandler.java @@ -0,0 +1,99 @@ +/* + * Copyright 2012 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ +package common.net.channel; + +import java.net.SocketAddress; + +/** + * {@link ChannelHandler} which will get notified for IO-outbound-operations. + */ +public interface ChannelOutboundHandler extends ChannelHandler { + /** + * Called once a bind operation is made. + * + * @param ctx the {@link ChannelHandlerContext} for which the bind operation is made + * @param localAddress the {@link SocketAddress} to which it should bound + * @param promise the {@link ChannelPromise} to notify once the operation completes + * @throws Exception thrown if an error accour + */ + void bind(ChannelHandlerContext ctx, SocketAddress localAddress, ChannelPromise promise) throws Exception; + + /** + * Called once a connect operation is made. + * + * @param ctx the {@link ChannelHandlerContext} for which the connect operation is made + * @param remoteAddress the {@link SocketAddress} to which it should connect + * @param localAddress the {@link SocketAddress} which is used as source on connect + * @param promise the {@link ChannelPromise} to notify once the operation completes + * @throws Exception thrown if an error accour + */ + void connect( + ChannelHandlerContext ctx, SocketAddress remoteAddress, + SocketAddress localAddress, ChannelPromise promise) throws Exception; + + /** + * Called once a disconnect operation is made. + * + * @param ctx the {@link ChannelHandlerContext} for which the disconnect operation is made + * @param promise the {@link ChannelPromise} to notify once the operation completes + * @throws Exception thrown if an error accour + */ + void disconnect(ChannelHandlerContext ctx, ChannelPromise promise) throws Exception; + + /** + * Called once a close operation is made. + * + * @param ctx the {@link ChannelHandlerContext} for which the close operation is made + * @param promise the {@link ChannelPromise} to notify once the operation completes + * @throws Exception thrown if an error accour + */ + void close(ChannelHandlerContext ctx, ChannelPromise promise) throws Exception; + + /** + * Called once a deregister operation is made from the current registered {@link EventLoop}. + * + * @param ctx the {@link ChannelHandlerContext} for which the close operation is made + * @param promise the {@link ChannelPromise} to notify once the operation completes + * @throws Exception thrown if an error accour + */ + void deregister(ChannelHandlerContext ctx, ChannelPromise promise) throws Exception; + + /** + * Intercepts {@link ChannelHandlerContext#read()}. + */ + void read(ChannelHandlerContext ctx) throws Exception; + + /** + * Called once a write operation is made. The write operation will write the messages through the + * {@link ChannelPipeline}. Those are then ready to be flushed to the actual {@link Channel} once + * {@link Channel#flush()} is called + * + * @param ctx the {@link ChannelHandlerContext} for which the write operation is made + * @param msg the message to write + * @param promise the {@link ChannelPromise} to notify once the operation completes + * @throws Exception thrown if an error accour + */ + void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception; + + /** + * Called once a flush operation is made. The flush operation will try to flush out all previous written messages + * that are pending. + * + * @param ctx the {@link ChannelHandlerContext} for which the flush operation is made + * @throws Exception thrown if an error accour + */ + void flush(ChannelHandlerContext ctx) throws Exception; +} diff --git a/common/src/common/net/channel/ChannelOutboundHandlerAdapter.java b/common/src/common/net/channel/ChannelOutboundHandlerAdapter.java new file mode 100644 index 0000000..0ce2ac8 --- /dev/null +++ b/common/src/common/net/channel/ChannelOutboundHandlerAdapter.java @@ -0,0 +1,117 @@ +/* + * Copyright 2012 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ +package common.net.channel; + +import java.net.SocketAddress; + +/** + * Skelton implementation of a {@link ChannelOutboundHandler}. This implementation just forwards each method call via + * the {@link ChannelHandlerContext}. + */ +public class ChannelOutboundHandlerAdapter extends ChannelHandlerAdapter implements ChannelOutboundHandler { + + /** + * Calls {@link ChannelHandlerContext#bind(SocketAddress, ChannelPromise)} to forward + * to the next {@link ChannelOutboundHandler} in the {@link ChannelPipeline}. + * + * Sub-classes may override this method to change behavior. + */ + @Override + public void bind(ChannelHandlerContext ctx, SocketAddress localAddress, + ChannelPromise promise) throws Exception { + ctx.bind(localAddress, promise); + } + + /** + * Calls {@link ChannelHandlerContext#connect(SocketAddress, SocketAddress, ChannelPromise)} to forward + * to the next {@link ChannelOutboundHandler} in the {@link ChannelPipeline}. + * + * Sub-classes may override this method to change behavior. + */ + @Override + public void connect(ChannelHandlerContext ctx, SocketAddress remoteAddress, + SocketAddress localAddress, ChannelPromise promise) throws Exception { + ctx.connect(remoteAddress, localAddress, promise); + } + + /** + * Calls {@link ChannelHandlerContext#disconnect(ChannelPromise)} to forward + * to the next {@link ChannelOutboundHandler} in the {@link ChannelPipeline}. + * + * Sub-classes may override this method to change behavior. + */ + @Override + public void disconnect(ChannelHandlerContext ctx, ChannelPromise promise) + throws Exception { + ctx.disconnect(promise); + } + + /** + * Calls {@link ChannelHandlerContext#close(ChannelPromise)} to forward + * to the next {@link ChannelOutboundHandler} in the {@link ChannelPipeline}. + * + * Sub-classes may override this method to change behavior. + */ + @Override + public void close(ChannelHandlerContext ctx, ChannelPromise promise) + throws Exception { + ctx.close(promise); + } + + /** + * Calls {@link ChannelHandlerContext#close(ChannelPromise)} to forward + * to the next {@link ChannelOutboundHandler} in the {@link ChannelPipeline}. + * + * Sub-classes may override this method to change behavior. + */ + @Override + public void deregister(ChannelHandlerContext ctx, ChannelPromise promise) throws Exception { + ctx.deregister(promise); + } + + /** + * Calls {@link ChannelHandlerContext#read()} to forward + * to the next {@link ChannelOutboundHandler} in the {@link ChannelPipeline}. + * + * Sub-classes may override this method to change behavior. + */ + @Override + public void read(ChannelHandlerContext ctx) throws Exception { + ctx.read(); + } + + /** + * Calls {@link ChannelHandlerContext#write(Object)} to forward + * to the next {@link ChannelOutboundHandler} in the {@link ChannelPipeline}. + * + * Sub-classes may override this method to change behavior. + */ + @Override + public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception { + ctx.write(msg, promise); + } + + /** + * Calls {@link ChannelHandlerContext#flush()} to forward + * to the next {@link ChannelOutboundHandler} in the {@link ChannelPipeline}. + * + * Sub-classes may override this method to change behavior. + */ + @Override + public void flush(ChannelHandlerContext ctx) throws Exception { + ctx.flush(); + } +} diff --git a/common/src/common/net/channel/ChannelPipeline.java b/common/src/common/net/channel/ChannelPipeline.java new file mode 100644 index 0000000..ed5ac6f --- /dev/null +++ b/common/src/common/net/channel/ChannelPipeline.java @@ -0,0 +1,872 @@ +/* + * Copyright 2012 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ +package common.net.channel; + +import java.net.SocketAddress; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; + +import common.net.util.concurrent.EventExecutorGroup; + + +/** + * A list of {@link ChannelHandler}s which handles or intercepts inbound events and outbound operations of a + * {@link Channel}. {@link ChannelPipeline} implements an advanced form of the + * Intercepting Filter pattern + * to give a user full control over how an event is handled and how the {@link ChannelHandler}s in a pipeline + * interact with each other. + * + *

Creation of a pipeline

+ * + * Each channel has its own pipeline and it is created automatically when a new channel is created. + * + *

How an event flows in a pipeline

+ * + * The following diagram describes how I/O events are processed by {@link ChannelHandler}s in a {@link ChannelPipeline} + * typically. An I/O event is handled by either a {@link ChannelInboundHandler} or a {@link ChannelOutboundHandler} + * and be forwarded to its closest handler by calling the event propagation methods defined in + * {@link ChannelHandlerContext}, such as {@link ChannelHandlerContext#fireChannelRead(Object)} and + * {@link ChannelHandlerContext#write(Object)}. + * + *
+ *                                                 I/O Request
+ *                                            via {@link Channel} or
+ *                                        {@link ChannelHandlerContext}
+ *                                                      |
+ *  +---------------------------------------------------+---------------+
+ *  |                           ChannelPipeline         |               |
+ *  |                                                  \|/              |
+ *  |    +---------------------+            +-----------+----------+    |
+ *  |    | Inbound Handler  N  |            | Outbound Handler  1  |    |
+ *  |    +----------+----------+            +-----------+----------+    |
+ *  |              /|\                                  |               |
+ *  |               |                                  \|/              |
+ *  |    +----------+----------+            +-----------+----------+    |
+ *  |    | Inbound Handler N-1 |            | Outbound Handler  2  |    |
+ *  |    +----------+----------+            +-----------+----------+    |
+ *  |              /|\                                  .               |
+ *  |               .                                   .               |
+ *  | ChannelHandlerContext.fireIN_EVT() ChannelHandlerContext.OUT_EVT()|
+ *  |        [ method call]                       [method call]         |
+ *  |               .                                   .               |
+ *  |               .                                  \|/              |
+ *  |    +----------+----------+            +-----------+----------+    |
+ *  |    | Inbound Handler  2  |            | Outbound Handler M-1 |    |
+ *  |    +----------+----------+            +-----------+----------+    |
+ *  |              /|\                                  |               |
+ *  |               |                                  \|/              |
+ *  |    +----------+----------+            +-----------+----------+    |
+ *  |    | Inbound Handler  1  |            | Outbound Handler  M  |    |
+ *  |    +----------+----------+            +-----------+----------+    |
+ *  |              /|\                                  |               |
+ *  +---------------+-----------------------------------+---------------+
+ *                  |                                  \|/
+ *  +---------------+-----------------------------------+---------------+
+ *  |               |                                   |               |
+ *  |       [ Socket.read() ]                    [ Socket.write() ]     |
+ *  |                                                                   |
+ *  |  Netty Internal I/O Threads (Transport Implementation)            |
+ *  +-------------------------------------------------------------------+
+ * 
+ * An inbound event is handled by the inbound handlers in the bottom-up direction as shown on the left side of the + * diagram. An inbound handler usually handles the inbound data generated by the I/O thread on the bottom of the + * diagram. The inbound data is often read from a remote peer via the actual input operation such as + * {@link SocketChannel#read(ByteBuffer)}. If an inbound event goes beyond the top inbound handler, it is discarded + * silently, or logged if it needs your attention. + *

+ * An outbound event is handled by the outbound handler in the top-down direction as shown on the right side of the + * diagram. An outbound handler usually generates or transforms the outbound traffic such as write requests. + * If an outbound event goes beyond the bottom outbound handler, it is handled by an I/O thread associated with the + * {@link Channel}. The I/O thread often performs the actual output operation such as + * {@link SocketChannel#write(ByteBuffer)}. + *

+ * For example, let us assume that we created the following pipeline: + *

+ * {@link ChannelPipeline} p = ...;
+ * p.addLast("1", new InboundHandlerA());
+ * p.addLast("2", new InboundHandlerB());
+ * p.addLast("3", new OutboundHandlerA());
+ * p.addLast("4", new OutboundHandlerB());
+ * p.addLast("5", new InboundOutboundHandlerX());
+ * 
+ * In the example above, the class whose name starts with {@code Inbound} means it is an inbound handler. + * The class whose name starts with {@code Outbound} means it is a outbound handler. + *

+ * In the given example configuration, the handler evaluation order is 1, 2, 3, 4, 5 when an event goes inbound. + * When an event goes outbound, the order is 5, 4, 3, 2, 1. On top of this principle, {@link ChannelPipeline} skips + * the evaluation of certain handlers to shorten the stack depth: + *

    + *
  • 3 and 4 don't implement {@link ChannelInboundHandler}, and therefore the actual evaluation order of an inbound + * event will be: 1, 2, and 5.
  • + *
  • 1 and 2 don't implement {@link ChannelOutboundHandler}, and therefore the actual evaluation order of a + * outbound event will be: 5, 4, and 3.
  • + *
  • If 5 implements both {@link ChannelInboundHandler} and {@link ChannelOutboundHandler}, the evaluation order of + * an inbound and a outbound event could be 125 and 543 respectively.
  • + *
+ * + *

Forwarding an event to the next handler

+ * + * As you might noticed in the diagram shows, a handler has to invoke the event propagation methods in + * {@link ChannelHandlerContext} to forward an event to its next handler. Those methods include: + *
    + *
  • Inbound event propagation methods: + *
      + *
    • {@link ChannelHandlerContext#fireChannelRegistered()}
    • + *
    • {@link ChannelHandlerContext#fireChannelActive()}
    • + *
    • {@link ChannelHandlerContext#fireChannelRead(Object)}
    • + *
    • {@link ChannelHandlerContext#fireChannelReadComplete()}
    • + *
    • {@link ChannelHandlerContext#fireExceptionCaught(Throwable)}
    • + *
    • {@link ChannelHandlerContext#fireUserEventTriggered(Object)}
    • + *
    • {@link ChannelHandlerContext#fireChannelWritabilityChanged()}
    • + *
    • {@link ChannelHandlerContext#fireChannelInactive()}
    • + *
    • {@link ChannelHandlerContext#fireChannelUnregistered()}
    • + *
    + *
  • + *
  • Outbound event propagation methods: + *
      + *
    • {@link ChannelHandlerContext#bind(SocketAddress, ChannelPromise)}
    • + *
    • {@link ChannelHandlerContext#connect(SocketAddress, SocketAddress, ChannelPromise)}
    • + *
    • {@link ChannelHandlerContext#write(Object, ChannelPromise)}
    • + *
    • {@link ChannelHandlerContext#flush()}
    • + *
    • {@link ChannelHandlerContext#read()}
    • + *
    • {@link ChannelHandlerContext#disconnect(ChannelPromise)}
    • + *
    • {@link ChannelHandlerContext#close(ChannelPromise)}
    • + *
    • {@link ChannelHandlerContext#deregister(ChannelPromise)}
    • + *
    + *
  • + *
+ * + * and the following example shows how the event propagation is usually done: + * + *
+ * public class MyInboundHandler extends {@link ChannelInboundHandlerAdapter} {
+ *     {@code @Override}
+ *     public void channelActive({@link ChannelHandlerContext} ctx) {
+ *         System.out.println("Connected!");
+ *         ctx.fireChannelActive();
+ *     }
+ * }
+ *
+ * public clas MyOutboundHandler extends {@link ChannelOutboundHandlerAdapter} {
+ *     {@code @Override}
+ *     public void close({@link ChannelHandlerContext} ctx, {@link ChannelPromise} promise) {
+ *         System.out.println("Closing ..");
+ *         ctx.close(promise);
+ *     }
+ * }
+ * 
+ * + *

Building a pipeline

+ *

+ * A user is supposed to have one or more {@link ChannelHandler}s in a pipeline to receive I/O events (e.g. read) and + * to request I/O operations (e.g. write and close). For example, a typical server will have the following handlers + * in each channel's pipeline, but your mileage may vary depending on the complexity and characteristics of the + * protocol and business logic: + * + *

    + *
  1. Protocol Decoder - translates binary data (e.g. {@link ByteBuf}) into a Java object.
  2. + *
  3. Protocol Encoder - translates a Java object into binary data.
  4. + *
  5. Business Logic Handler - performs the actual business logic (e.g. database access).
  6. + *
+ * + * and it could be represented as shown in the following example: + * + *
+ * static final {@link EventExecutorGroup} group = new {@link DefaultEventExecutorGroup}(16);
+ * ...
+ *
+ * {@link ChannelPipeline} pipeline = ch.pipeline();
+ *
+ * pipeline.addLast("decoder", new MyProtocolDecoder());
+ * pipeline.addLast("encoder", new MyProtocolEncoder());
+ *
+ * // Tell the pipeline to run MyBusinessLogicHandler's event handler methods
+ * // in a different thread than an I/O thread so that the I/O thread is not blocked by
+ * // a time-consuming task.
+ * // If your business logic is fully asynchronous or finished very quickly, you don't
+ * // need to specify a group.
+ * pipeline.addLast(group, "handler", new MyBusinessLogicHandler());
+ * 
+ * + *

Thread safety

+ *

+ * A {@link ChannelHandler} can be added or removed at any time because a {@link ChannelPipeline} is thread safe. + * For example, you can insert an encryption handler when sensitive information is about to be exchanged, and remove it + * after the exchange. + */ +public interface ChannelPipeline + extends Iterable> { + + /** + * Inserts a {@link ChannelHandler} at the first position of this pipeline. + * + * @param name the name of the handler to insert first + * @param handler the handler to insert first + * + * @throws IllegalArgumentException + * if there's an entry with the same name already in the pipeline + * @throws NullPointerException + * if the specified name or handler is {@code null} + */ + ChannelPipeline addFirst(String name, ChannelHandler handler); + + /** + * Inserts a {@link ChannelHandler} at the first position of this pipeline. + * + * @param group the {@link EventExecutorGroup} which will be used to execute the {@link ChannelHandler} + * methods + * @param name the name of the handler to insert first + * @param handler the handler to insert first + * + * @throws IllegalArgumentException + * if there's an entry with the same name already in the pipeline + * @throws NullPointerException + * if the specified name or handler is {@code null} + */ + ChannelPipeline addFirst(EventExecutorGroup group, String name, ChannelHandler handler); + + /** + * Appends a {@link ChannelHandler} at the last position of this pipeline. + * + * @param name the name of the handler to append + * @param handler the handler to append + * + * @throws IllegalArgumentException + * if there's an entry with the same name already in the pipeline + * @throws NullPointerException + * if the specified name or handler is {@code null} + */ + ChannelPipeline addLast(String name, ChannelHandler handler); + + /** + * Appends a {@link ChannelHandler} at the last position of this pipeline. + * + * @param group the {@link EventExecutorGroup} which will be used to execute the {@link ChannelHandler} + * methods + * @param name the name of the handler to append + * @param handler the handler to append + * + * @throws IllegalArgumentException + * if there's an entry with the same name already in the pipeline + * @throws NullPointerException + * if the specified name or handler is {@code null} + */ + ChannelPipeline addLast(EventExecutorGroup group, String name, ChannelHandler handler); + + /** + * Inserts a {@link ChannelHandler} before an existing handler of this + * pipeline. + * + * @param baseName the name of the existing handler + * @param name the name of the handler to insert before + * @param handler the handler to insert before + * + * @throws NoSuchElementException + * if there's no such entry with the specified {@code baseName} + * @throws IllegalArgumentException + * if there's an entry with the same name already in the pipeline + * @throws NullPointerException + * if the specified baseName, name, or handler is {@code null} + */ + ChannelPipeline addBefore(String baseName, String name, ChannelHandler handler); + + /** + * Inserts a {@link ChannelHandler} before an existing handler of this + * pipeline. + * + * @param group the {@link EventExecutorGroup} which will be used to execute the {@link ChannelHandler} + * methods + * @param baseName the name of the existing handler + * @param name the name of the handler to insert before + * @param handler the handler to insert before + * + * @throws NoSuchElementException + * if there's no such entry with the specified {@code baseName} + * @throws IllegalArgumentException + * if there's an entry with the same name already in the pipeline + * @throws NullPointerException + * if the specified baseName, name, or handler is {@code null} + */ + ChannelPipeline addBefore(EventExecutorGroup group, String baseName, String name, ChannelHandler handler); + + /** + * Inserts a {@link ChannelHandler} after an existing handler of this + * pipeline. + * + * @param baseName the name of the existing handler + * @param name the name of the handler to insert after + * @param handler the handler to insert after + * + * @throws NoSuchElementException + * if there's no such entry with the specified {@code baseName} + * @throws IllegalArgumentException + * if there's an entry with the same name already in the pipeline + * @throws NullPointerException + * if the specified baseName, name, or handler is {@code null} + */ + ChannelPipeline addAfter(String baseName, String name, ChannelHandler handler); + + /** + * Inserts a {@link ChannelHandler} after an existing handler of this + * pipeline. + * + * @param group the {@link EventExecutorGroup} which will be used to execute the {@link ChannelHandler} + * methods + * @param baseName the name of the existing handler + * @param name the name of the handler to insert after + * @param handler the handler to insert after + * + * @throws NoSuchElementException + * if there's no such entry with the specified {@code baseName} + * @throws IllegalArgumentException + * if there's an entry with the same name already in the pipeline + * @throws NullPointerException + * if the specified baseName, name, or handler is {@code null} + */ + ChannelPipeline addAfter(EventExecutorGroup group, String baseName, String name, ChannelHandler handler); + + /** + * Inserts a {@link ChannelHandler}s at the first position of this pipeline. + * + * @param handlers the handlers to insert first + * + */ + ChannelPipeline addFirst(ChannelHandler... handlers); + + /** + * Inserts a {@link ChannelHandler}s at the first position of this pipeline. + * + * @param group the {@link EventExecutorGroup} which will be used to execute the {@link ChannelHandler}s + * methods. + * @param handlers the handlers to insert first + * + */ + ChannelPipeline addFirst(EventExecutorGroup group, ChannelHandler... handlers); + + /** + * Inserts a {@link ChannelHandler}s at the last position of this pipeline. + * + * @param handlers the handlers to insert last + * + */ + ChannelPipeline addLast(ChannelHandler... handlers); + + /** + * Inserts a {@link ChannelHandler}s at the last position of this pipeline. + * + * @param group the {@link EventExecutorGroup} which will be used to execute the {@link ChannelHandler}s + * methods. + * @param handlers the handlers to insert last + * + */ + ChannelPipeline addLast(EventExecutorGroup group, ChannelHandler... handlers); + + /** + * Removes the specified {@link ChannelHandler} from this pipeline. + * + * @param handler the {@link ChannelHandler} to remove + * + * @throws NoSuchElementException + * if there's no such handler in this pipeline + * @throws NullPointerException + * if the specified handler is {@code null} + */ + ChannelPipeline remove(ChannelHandler handler); + + /** + * Removes the {@link ChannelHandler} with the specified name from this pipeline. + * + * @param name the name under which the {@link ChannelHandler} was stored. + * + * @return the removed handler + * + * @throws NoSuchElementException + * if there's no such handler with the specified name in this pipeline + * @throws NullPointerException + * if the specified name is {@code null} + */ + ChannelHandler remove(String name); + + /** + * Removes the {@link ChannelHandler} of the specified type from this pipeline. + * + * @param the type of the handler + * @param handlerType the type of the handler + * + * @return the removed handler + * + * @throws NoSuchElementException + * if there's no such handler of the specified type in this pipeline + * @throws NullPointerException + * if the specified handler type is {@code null} + */ + T remove(Class handlerType); + + /** + * Removes the first {@link ChannelHandler} in this pipeline. + * + * @return the removed handler + * + * @throws NoSuchElementException + * if this pipeline is empty + */ + ChannelHandler removeFirst(); + + /** + * Removes the last {@link ChannelHandler} in this pipeline. + * + * @return the removed handler + * + * @throws NoSuchElementException + * if this pipeline is empty + */ + ChannelHandler removeLast(); + + /** + * Replaces the specified {@link ChannelHandler} with a new handler in this pipeline. + * + * @param oldHandler the {@link ChannelHandler} to be replaced + * @param newName the name under which the replacement should be added + * @param newHandler the {@link ChannelHandler} which is used as replacement + * + * @return itself + + * @throws NoSuchElementException + * if the specified old handler does not exist in this pipeline + * @throws IllegalArgumentException + * if a handler with the specified new name already exists in this + * pipeline, except for the handler to be replaced + * @throws NullPointerException + * if the specified old handler, new name, or new handler is + * {@code null} + */ + ChannelPipeline replace(ChannelHandler oldHandler, String newName, ChannelHandler newHandler); + + /** + * Replaces the {@link ChannelHandler} of the specified name with a new handler in this pipeline. + * + * @param oldName the name of the {@link ChannelHandler} to be replaced + * @param newName the name under which the replacement should be added + * @param newHandler the {@link ChannelHandler} which is used as replacement + * + * @return the removed handler + * + * @throws NoSuchElementException + * if the handler with the specified old name does not exist in this pipeline + * @throws IllegalArgumentException + * if a handler with the specified new name already exists in this + * pipeline, except for the handler to be replaced + * @throws NullPointerException + * if the specified old handler, new name, or new handler is + * {@code null} + */ + ChannelHandler replace(String oldName, String newName, ChannelHandler newHandler); + + /** + * Replaces the {@link ChannelHandler} of the specified type with a new handler in this pipeline. + * + * @param oldHandlerType the type of the handler to be removed + * @param newName the name under which the replacement should be added + * @param newHandler the {@link ChannelHandler} which is used as replacement + * + * @return the removed handler + * + * @throws NoSuchElementException + * if the handler of the specified old handler type does not exist + * in this pipeline + * @throws IllegalArgumentException + * if a handler with the specified new name already exists in this + * pipeline, except for the handler to be replaced + * @throws NullPointerException + * if the specified old handler, new name, or new handler is + * {@code null} + */ + T replace(Class oldHandlerType, String newName, + ChannelHandler newHandler); + + /** + * Returns the first {@link ChannelHandler} in this pipeline. + * + * @return the first handler. {@code null} if this pipeline is empty. + */ + ChannelHandler first(); + + /** + * Returns the context of the first {@link ChannelHandler} in this pipeline. + * + * @return the context of the first handler. {@code null} if this pipeline is empty. + */ + ChannelHandlerContext firstContext(); + + /** + * Returns the last {@link ChannelHandler} in this pipeline. + * + * @return the last handler. {@code null} if this pipeline is empty. + */ + ChannelHandler last(); + + /** + * Returns the context of the last {@link ChannelHandler} in this pipeline. + * + * @return the context of the last handler. {@code null} if this pipeline is empty. + */ + ChannelHandlerContext lastContext(); + + /** + * Returns the {@link ChannelHandler} with the specified name in this + * pipeline. + * + * @return the handler with the specified name. + * {@code null} if there's no such handler in this pipeline. + */ + ChannelHandler get(String name); + + /** + * Returns the {@link ChannelHandler} of the specified type in this + * pipeline. + * + * @return the handler of the specified handler type. + * {@code null} if there's no such handler in this pipeline. + */ + T get(Class handlerType); + + /** + * Returns the context object of the specified {@link ChannelHandler} in + * this pipeline. + * + * @return the context object of the specified handler. + * {@code null} if there's no such handler in this pipeline. + */ + ChannelHandlerContext context(ChannelHandler handler); + + /** + * Returns the context object of the {@link ChannelHandler} with the + * specified name in this pipeline. + * + * @return the context object of the handler with the specified name. + * {@code null} if there's no such handler in this pipeline. + */ + ChannelHandlerContext context(String name); + + /** + * Returns the context object of the {@link ChannelHandler} of the + * specified type in this pipeline. + * + * @return the context object of the handler of the specified type. + * {@code null} if there's no such handler in this pipeline. + */ + ChannelHandlerContext context(Class handlerType); + + /** + * Returns the {@link Channel} that this pipeline is attached to. + * + * @return the channel. {@code null} if this pipeline is not attached yet. + */ + Channel channel(); + + /** + * Returns the {@link List} of the handler names. + */ + List names(); + + /** + * Converts this pipeline into an ordered {@link Map} whose keys are + * handler names and whose values are handlers. + */ + Map toMap(); + + /** + * A {@link Channel} was registered to its {@link EventLoop}. + * + * This will result in having the {@link ChannelInboundHandler#channelRegistered(ChannelHandlerContext)} method + * called of the next {@link ChannelInboundHandler} contained in the {@link ChannelPipeline} of the + * {@link Channel}. + */ + ChannelPipeline fireChannelRegistered(); + + /** + * A {@link Channel} was unregistered from its {@link EventLoop}. + * + * This will result in having the {@link ChannelInboundHandler#channelUnregistered(ChannelHandlerContext)} method + * called of the next {@link ChannelInboundHandler} contained in the {@link ChannelPipeline} of the + * {@link Channel}. + */ + ChannelPipeline fireChannelUnregistered(); + + /** + * A {@link Channel} is active now, which means it is connected. + * + * This will result in having the {@link ChannelInboundHandler#channelActive(ChannelHandlerContext)} method + * called of the next {@link ChannelInboundHandler} contained in the {@link ChannelPipeline} of the + * {@link Channel}. + */ + ChannelPipeline fireChannelActive(); + + /** + * A {@link Channel} is inactive now, which means it is closed. + * + * This will result in having the {@link ChannelInboundHandler#channelInactive(ChannelHandlerContext)} method + * called of the next {@link ChannelInboundHandler} contained in the {@link ChannelPipeline} of the + * {@link Channel}. + */ + ChannelPipeline fireChannelInactive(); + + /** + * A {@link Channel} received an {@link Throwable} in one of its inbound operations. + * + * This will result in having the {@link ChannelInboundHandler#exceptionCaught(ChannelHandlerContext, Throwable)} + * method called of the next {@link ChannelInboundHandler} contained in the {@link ChannelPipeline} of the + * {@link Channel}. + */ + ChannelPipeline fireExceptionCaught(Throwable cause); + + /** + * A {@link Channel} received an user defined event. + * + * This will result in having the {@link ChannelInboundHandler#userEventTriggered(ChannelHandlerContext, Object)} + * method called of the next {@link ChannelInboundHandler} contained in the {@link ChannelPipeline} of the + * {@link Channel}. + */ + ChannelPipeline fireUserEventTriggered(Object event); + + /** + * A {@link Channel} received a message. + * + * This will result in having the {@link ChannelInboundHandler#channelRead(ChannelHandlerContext, Object)} + * method called of the next {@link ChannelInboundHandler} contained in the {@link ChannelPipeline} of the + * {@link Channel}. + */ + ChannelPipeline fireChannelRead(Object msg); + + /** + * Triggers an {@link ChannelInboundHandler#channelWritabilityChanged(ChannelHandlerContext)} + * event to the next {@link ChannelInboundHandler} in the {@link ChannelPipeline}. + */ + ChannelPipeline fireChannelReadComplete(); + + /** + * Triggers an {@link ChannelInboundHandler#channelWritabilityChanged(ChannelHandlerContext)} + * event to the next {@link ChannelInboundHandler} in the {@link ChannelPipeline}. + */ + ChannelPipeline fireChannelWritabilityChanged(); + + /** + * Request to bind to the given {@link SocketAddress} and notify the {@link ChannelFuture} once the operation + * completes, either because the operation was successful or because of an error. + *

+ * This will result in having the + * {@link ChannelOutboundHandler#bind(ChannelHandlerContext, SocketAddress, ChannelPromise)} method + * called of the next {@link ChannelOutboundHandler} contained in the {@link ChannelPipeline} of the + * {@link Channel}. + */ + ChannelFuture bind(SocketAddress localAddress); + + /** + * Request to connect to the given {@link SocketAddress} and notify the {@link ChannelFuture} once the operation + * completes, either because the operation was successful or because of an error. + *

+ * If the connection fails because of a connection timeout, the {@link ChannelFuture} will get failed with + * a {@link ConnectTimeoutException}. If it fails because of connection refused a {@link ConnectException} + * will be used. + *

+ * This will result in having the + * {@link ChannelOutboundHandler#connect(ChannelHandlerContext, SocketAddress, SocketAddress, ChannelPromise)} + * method called of the next {@link ChannelOutboundHandler} contained in the {@link ChannelPipeline} of the + * {@link Channel}. + */ + ChannelFuture connect(SocketAddress remoteAddress); + + /** + * Request to connect to the given {@link SocketAddress} while bind to the localAddress and notify the + * {@link ChannelFuture} once the operation completes, either because the operation was successful or because of + * an error. + *

+ * This will result in having the + * {@link ChannelOutboundHandler#connect(ChannelHandlerContext, SocketAddress, SocketAddress, ChannelPromise)} + * method called of the next {@link ChannelOutboundHandler} contained in the {@link ChannelPipeline} of the + * {@link Channel}. + */ + ChannelFuture connect(SocketAddress remoteAddress, SocketAddress localAddress); + + /** + * Request to disconnect from the remote peer and notify the {@link ChannelFuture} once the operation completes, + * either because the operation was successful or because of an error. + *

+ * This will result in having the + * {@link ChannelOutboundHandler#disconnect(ChannelHandlerContext, ChannelPromise)} + * method called of the next {@link ChannelOutboundHandler} contained in the {@link ChannelPipeline} of the + * {@link Channel}. + */ + ChannelFuture disconnect(); + + /** + * Request to close the {@link Channel} and notify the {@link ChannelFuture} once the operation completes, + * either because the operation was successful or because of + * an error. + * + * After it is closed it is not possible to reuse it again. + *

+ * This will result in having the + * {@link ChannelOutboundHandler#close(ChannelHandlerContext, ChannelPromise)} + * method called of the next {@link ChannelOutboundHandler} contained in the {@link ChannelPipeline} of the + * {@link Channel}. + */ + ChannelFuture close(); + + /** + * Request to deregister the {@link Channel} from the previous assigned {@link EventExecutor} and notify the + * {@link ChannelFuture} once the operation completes, either because the operation was successful or because of + * an error. + *

+ * This will result in having the + * {@link ChannelOutboundHandler#deregister(ChannelHandlerContext, ChannelPromise)} + * method called of the next {@link ChannelOutboundHandler} contained in the {@link ChannelPipeline} of the + * {@link Channel}. + * + */ + ChannelFuture deregister(); + + /** + * Request to bind to the given {@link SocketAddress} and notify the {@link ChannelFuture} once the operation + * completes, either because the operation was successful or because of an error. + * + * The given {@link ChannelPromise} will be notified. + *

+ * This will result in having the + * {@link ChannelOutboundHandler#bind(ChannelHandlerContext, SocketAddress, ChannelPromise)} method + * called of the next {@link ChannelOutboundHandler} contained in the {@link ChannelPipeline} of the + * {@link Channel}. + */ + ChannelFuture bind(SocketAddress localAddress, ChannelPromise promise); + + /** + * Request to connect to the given {@link SocketAddress} and notify the {@link ChannelFuture} once the operation + * completes, either because the operation was successful or because of an error. + * + * The given {@link ChannelFuture} will be notified. + * + *

+ * If the connection fails because of a connection timeout, the {@link ChannelFuture} will get failed with + * a {@link ConnectTimeoutException}. If it fails because of connection refused a {@link ConnectException} + * will be used. + *

+ * This will result in having the + * {@link ChannelOutboundHandler#connect(ChannelHandlerContext, SocketAddress, SocketAddress, ChannelPromise)} + * method called of the next {@link ChannelOutboundHandler} contained in the {@link ChannelPipeline} of the + * {@link Channel}. + */ + ChannelFuture connect(SocketAddress remoteAddress, ChannelPromise promise); + + /** + * Request to connect to the given {@link SocketAddress} while bind to the localAddress and notify the + * {@link ChannelFuture} once the operation completes, either because the operation was successful or because of + * an error. + * + * The given {@link ChannelPromise} will be notified and also returned. + *

+ * This will result in having the + * {@link ChannelOutboundHandler#connect(ChannelHandlerContext, SocketAddress, SocketAddress, ChannelPromise)} + * method called of the next {@link ChannelOutboundHandler} contained in the {@link ChannelPipeline} of the + * {@link Channel}. + */ + ChannelFuture connect(SocketAddress remoteAddress, SocketAddress localAddress, ChannelPromise promise); + + /** + * Request to disconnect from the remote peer and notify the {@link ChannelFuture} once the operation completes, + * either because the operation was successful or because of an error. + * + * The given {@link ChannelPromise} will be notified. + *

+ * This will result in having the + * {@link ChannelOutboundHandler#disconnect(ChannelHandlerContext, ChannelPromise)} + * method called of the next {@link ChannelOutboundHandler} contained in the {@link ChannelPipeline} of the + * {@link Channel}. + */ + ChannelFuture disconnect(ChannelPromise promise); + + /** + * Request to close the {@link Channel} bound to this {@link ChannelPipeline} and notify the {@link ChannelFuture} + * once the operation completes, either because the operation was successful or because of + * an error. + * + * After it is closed it is not possible to reuse it again. + * The given {@link ChannelPromise} will be notified. + *

+ * This will result in having the + * {@link ChannelOutboundHandler#close(ChannelHandlerContext, ChannelPromise)} + * method called of the next {@link ChannelOutboundHandler} contained in the {@link ChannelPipeline} of the + * {@link Channel}. + */ + ChannelFuture close(ChannelPromise promise); + + /** + * Request to deregister the {@link Channel} bound this {@link ChannelPipeline} from the previous assigned + * {@link EventExecutor} and notify the {@link ChannelFuture} once the operation completes, either because the + * operation was successful or because of an error. + * + * The given {@link ChannelPromise} will be notified. + *

+ * This will result in having the + * {@link ChannelOutboundHandler#deregister(ChannelHandlerContext, ChannelPromise)} + * method called of the next {@link ChannelOutboundHandler} contained in the {@link ChannelPipeline} of the + * {@link Channel}. + */ + ChannelFuture deregister(ChannelPromise promise); + + /** + * Request to Read data from the {@link Channel} into the first inbound buffer, triggers an + * {@link ChannelInboundHandler#channelRead(ChannelHandlerContext, Object)} event if data was + * read, and triggers a + * {@link ChannelInboundHandler#channelReadComplete(ChannelHandlerContext) channelReadComplete} event so the + * handler can decide to continue reading. If there's a pending read operation already, this method does nothing. + *

+ * This will result in having the + * {@link ChannelOutboundHandler#read(ChannelHandlerContext)} + * method called of the next {@link ChannelOutboundHandler} contained in the {@link ChannelPipeline} of the + * {@link Channel}. + */ + ChannelPipeline read(); + + /** + * Request to write a message via this {@link ChannelPipeline}. + * This method will not request to actual flush, so be sure to call {@link #flush()} + * once you want to request to flush all pending data to the actual transport. + */ + ChannelFuture write(Object msg); + + /** + * Request to write a message via this {@link ChannelPipeline}. + * This method will not request to actual flush, so be sure to call {@link #flush()} + * once you want to request to flush all pending data to the actual transport. + */ + ChannelFuture write(Object msg, ChannelPromise promise); + + /** + * Request to flush all pending messages. + */ + ChannelPipeline flush(); + + /** + * Shortcut for call {@link #write(Object, ChannelPromise)} and {@link #flush()}. + */ + ChannelFuture writeAndFlush(Object msg, ChannelPromise promise); + + /** + * Shortcut for call {@link #write(Object)} and {@link #flush()}. + */ + ChannelFuture writeAndFlush(Object msg); +} diff --git a/common/src/common/net/channel/ChannelPipelineException.java b/common/src/common/net/channel/ChannelPipelineException.java new file mode 100644 index 0000000..d1f8628 --- /dev/null +++ b/common/src/common/net/channel/ChannelPipelineException.java @@ -0,0 +1,52 @@ +/* + * Copyright 2012 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ +package common.net.channel; + +/** + * A {@link ChannelException} which is thrown when a {@link ChannelPipeline} + * failed to execute an operation. + */ +public class ChannelPipelineException extends ChannelException { + + private static final long serialVersionUID = 3379174210419885980L; + + /** + * Creates a new instance. + */ + public ChannelPipelineException() { + } + + /** + * Creates a new instance. + */ + public ChannelPipelineException(String message, Throwable cause) { + super(message, cause); + } + + /** + * Creates a new instance. + */ + public ChannelPipelineException(String message) { + super(message); + } + + /** + * Creates a new instance. + */ + public ChannelPipelineException(Throwable cause) { + super(cause); + } +} diff --git a/common/src/common/net/channel/ChannelProgressivePromise.java b/common/src/common/net/channel/ChannelProgressivePromise.java new file mode 100644 index 0000000..530e252 --- /dev/null +++ b/common/src/common/net/channel/ChannelProgressivePromise.java @@ -0,0 +1,86 @@ +/* + * Copyright 2013 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ +package common.net.channel; + +import common.net.util.concurrent.Future; +import common.net.util.concurrent.GenericFutureListener; +import common.net.util.concurrent.ProgressiveFuture; +import common.net.util.concurrent.ProgressivePromise; + +/** + * Special {@link ChannelPromise} which will be notified once the associated bytes is transferring. + */ +public interface ChannelProgressivePromise extends ProgressivePromise, ChannelFuture, ProgressiveFuture, ChannelPromise { +// @Override +// ChannelProgressiveFuture addListener(GenericFutureListener> listener); +// +// @Override +// ChannelProgressiveFuture addListeners(GenericFutureListener>... listeners); +// +// @Override +// ChannelProgressiveFuture removeListener(GenericFutureListener> listener); +// +// @Override +// ChannelProgressiveFuture removeListeners(GenericFutureListener>... listeners); +// +// @Override +// ChannelProgressiveFuture sync() throws InterruptedException; +// +// @Override +// ChannelProgressiveFuture syncUninterruptibly(); +// +// @Override +// ChannelProgressiveFuture await() throws InterruptedException; +// +// @Override +// ChannelProgressiveFuture awaitUninterruptibly(); + + @Override + ChannelProgressivePromise addListener(GenericFutureListener> listener); + + @Override + ChannelProgressivePromise addListeners(GenericFutureListener>... listeners); + + @Override + ChannelProgressivePromise removeListener(GenericFutureListener> listener); + + @Override + ChannelProgressivePromise removeListeners(GenericFutureListener>... listeners); + + @Override + ChannelProgressivePromise sync() throws InterruptedException; + + @Override + ChannelProgressivePromise syncUninterruptibly(); + + @Override + ChannelProgressivePromise await() throws InterruptedException; + + @Override + ChannelProgressivePromise awaitUninterruptibly(); + + @Override + ChannelProgressivePromise setSuccess(Void result); + + @Override + ChannelProgressivePromise setSuccess(); + + @Override + ChannelProgressivePromise setFailure(Throwable cause); + + @Override + ChannelProgressivePromise setProgress(long progress, long total); +} diff --git a/common/src/common/net/channel/ChannelPromise.java b/common/src/common/net/channel/ChannelPromise.java new file mode 100644 index 0000000..fda7072 --- /dev/null +++ b/common/src/common/net/channel/ChannelPromise.java @@ -0,0 +1,63 @@ +/* + * Copyright 2012 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ +package common.net.channel; + +import common.net.util.concurrent.Future; +import common.net.util.concurrent.GenericFutureListener; +import common.net.util.concurrent.Promise; + +/** + * Special {@link ChannelFuture} which is writable. + */ +public interface ChannelPromise extends ChannelFuture, Promise { + + @Override + Channel channel(); + + @Override + ChannelPromise setSuccess(Void result); + + ChannelPromise setSuccess(); + + boolean trySuccess(); + + @Override + ChannelPromise setFailure(Throwable cause); + + @Override + ChannelPromise addListener(GenericFutureListener> listener); + + @Override + ChannelPromise addListeners(GenericFutureListener>... listeners); + + @Override + ChannelPromise removeListener(GenericFutureListener> listener); + + @Override + ChannelPromise removeListeners(GenericFutureListener>... listeners); + + @Override + ChannelPromise sync() throws InterruptedException; + + @Override + ChannelPromise syncUninterruptibly(); + + @Override + ChannelPromise await() throws InterruptedException; + + @Override + ChannelPromise awaitUninterruptibly(); +} diff --git a/common/src/common/net/channel/CompleteChannelFuture.java b/common/src/common/net/channel/CompleteChannelFuture.java new file mode 100644 index 0000000..2e8dac6 --- /dev/null +++ b/common/src/common/net/channel/CompleteChannelFuture.java @@ -0,0 +1,107 @@ +/* + * Copyright 2012 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ +package common.net.channel; + +import common.net.util.concurrent.CompleteFuture; +import common.net.util.concurrent.EventExecutor; +import common.net.util.concurrent.Future; +import common.net.util.concurrent.GenericFutureListener; + +/** + * A skeletal {@link ChannelFuture} implementation which represents a + * {@link ChannelFuture} which has been completed already. + */ +abstract class CompleteChannelFuture extends CompleteFuture implements ChannelFuture { + + private final Channel channel; + + /** + * Creates a new instance. + * + * @param channel the {@link Channel} associated with this future + */ + protected CompleteChannelFuture(Channel channel, EventExecutor executor) { + super(executor); + if (channel == null) { + throw new NullPointerException("channel"); + } + this.channel = channel; + } + + @Override + protected EventExecutor executor() { + EventExecutor e = super.executor(); + if (e == null) { + return channel().eventLoop(); + } else { + return e; + } + } + + @Override + public ChannelFuture addListener(GenericFutureListener> listener) { + super.addListener(listener); + return this; + } + + @Override + public ChannelFuture addListeners(GenericFutureListener>... listeners) { + super.addListeners(listeners); + return this; + } + + @Override + public ChannelFuture removeListener(GenericFutureListener> listener) { + super.removeListener(listener); + return this; + } + + @Override + public ChannelFuture removeListeners(GenericFutureListener>... listeners) { + super.removeListeners(listeners); + return this; + } + + @Override + public ChannelFuture syncUninterruptibly() { + return this; + } + + @Override + public ChannelFuture sync() throws InterruptedException { + return this; + } + + @Override + public ChannelFuture await() throws InterruptedException { + return this; + } + + @Override + public ChannelFuture awaitUninterruptibly() { + return this; + } + + @Override + public Channel channel() { + return channel; + } + + @Override + public Void getNow() { + return null; + } +} diff --git a/common/src/common/net/channel/ConnectTimeoutException.java b/common/src/common/net/channel/ConnectTimeoutException.java new file mode 100644 index 0000000..831cbe6 --- /dev/null +++ b/common/src/common/net/channel/ConnectTimeoutException.java @@ -0,0 +1,33 @@ +/* + * Copyright 2013 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ +package common.net.channel; + +import java.net.ConnectException; + +/** + * {@link ConnectException} which will be thrown if a connection could + * not be established because of a connection timeout. + */ +public class ConnectTimeoutException extends ConnectException { + private static final long serialVersionUID = 2317065249988317463L; + + public ConnectTimeoutException(String msg) { + super(msg); + } + + public ConnectTimeoutException() { + } +} diff --git a/common/src/common/net/channel/DefaultChannelConfig.java b/common/src/common/net/channel/DefaultChannelConfig.java new file mode 100644 index 0000000..6985206 --- /dev/null +++ b/common/src/common/net/channel/DefaultChannelConfig.java @@ -0,0 +1,355 @@ +/* + * Copyright 2012 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ +package common.net.channel; + +import static common.net.channel.ChannelOption.ALLOCATOR; +import static common.net.channel.ChannelOption.AUTO_CLOSE; +import static common.net.channel.ChannelOption.AUTO_READ; +import static common.net.channel.ChannelOption.CONNECT_TIMEOUT_MILLIS; +import static common.net.channel.ChannelOption.MAX_MESSAGES_PER_READ; +import static common.net.channel.ChannelOption.MESSAGE_SIZE_ESTIMATOR; +import static common.net.channel.ChannelOption.RCVBUF_ALLOCATOR; +import static common.net.channel.ChannelOption.WRITE_BUFFER_HIGH_WATER_MARK; +import static common.net.channel.ChannelOption.WRITE_BUFFER_LOW_WATER_MARK; +import static common.net.channel.ChannelOption.WRITE_SPIN_COUNT; + +import java.util.IdentityHashMap; +import java.util.Map; +import java.util.Map.Entry; + +import common.net.buffer.ByteBufAllocator; +import common.net.channel.nio.AbstractNioByteChannel; + +/** + * The default {@link SocketChannelConfig} implementation. + */ +public class DefaultChannelConfig implements ChannelConfig { + + private static final RecvByteBufAllocator DEFAULT_RCVBUF_ALLOCATOR = AdaptiveRecvByteBufAllocator.DEFAULT; + private static final MessageSizeEstimator DEFAULT_MSG_SIZE_ESTIMATOR = DefaultMessageSizeEstimator.DEFAULT; + + private static final int DEFAULT_CONNECT_TIMEOUT = 30000; + + protected final Channel channel; + + private volatile ByteBufAllocator allocator = ByteBufAllocator.DEFAULT; + private volatile RecvByteBufAllocator rcvBufAllocator = DEFAULT_RCVBUF_ALLOCATOR; + private volatile MessageSizeEstimator msgSizeEstimator = DEFAULT_MSG_SIZE_ESTIMATOR; + + private volatile int connectTimeoutMillis = DEFAULT_CONNECT_TIMEOUT; + private volatile int maxMessagesPerRead; + private volatile int writeSpinCount = 16; + private volatile boolean autoRead = true; + private volatile boolean autoClose = true; + private volatile int writeBufferHighWaterMark = 64 * 1024; + private volatile int writeBufferLowWaterMark = 32 * 1024; + + public DefaultChannelConfig(Channel channel) { + if (channel == null) { + throw new NullPointerException("channel"); + } + this.channel = channel; + + if (channel instanceof ServerChannel || channel instanceof AbstractNioByteChannel) { + // Server channels: Accept as many incoming connections as possible. + // NIO byte channels: Implemented to reduce unnecessary system calls even if it's > 1. + // See https://github.com/netty/netty/issues/2079 + // TODO: Add some property to ChannelMetadata so we can remove the ugly instanceof + maxMessagesPerRead = 16; + } else { + maxMessagesPerRead = 1; + } + } + + @Override + + public Map, Object> getOptions() { + return getOptions( + null, + CONNECT_TIMEOUT_MILLIS, MAX_MESSAGES_PER_READ, WRITE_SPIN_COUNT, + ALLOCATOR, AUTO_READ, AUTO_CLOSE, RCVBUF_ALLOCATOR, WRITE_BUFFER_HIGH_WATER_MARK, + WRITE_BUFFER_LOW_WATER_MARK, MESSAGE_SIZE_ESTIMATOR); + } + + protected Map, Object> getOptions( + Map, Object> result, ChannelOption... options) { + if (result == null) { + result = new IdentityHashMap, Object>(); + } + for (ChannelOption o: options) { + result.put(o, getOption(o)); + } + return result; + } + + + @Override + public boolean setOptions(Map, ?> options) { + if (options == null) { + throw new NullPointerException("options"); + } + + boolean setAllOptions = true; + for (Entry, ?> e: options.entrySet()) { + if (!setOption((ChannelOption) e.getKey(), e.getValue())) { + setAllOptions = false; + } + } + + return setAllOptions; + } + + @Override + + public T getOption(ChannelOption option) { + if (option == null) { + throw new NullPointerException("option"); + } + + if (option == CONNECT_TIMEOUT_MILLIS) { + return (T) Integer.valueOf(getConnectTimeoutMillis()); + } + if (option == MAX_MESSAGES_PER_READ) { + return (T) Integer.valueOf(getMaxMessagesPerRead()); + } + if (option == WRITE_SPIN_COUNT) { + return (T) Integer.valueOf(getWriteSpinCount()); + } + if (option == ALLOCATOR) { + return (T) getAllocator(); + } + if (option == RCVBUF_ALLOCATOR) { + return (T) getRecvByteBufAllocator(); + } + if (option == AUTO_READ) { + return (T) Boolean.valueOf(isAutoRead()); + } + if (option == AUTO_CLOSE) { + return (T) Boolean.valueOf(isAutoClose()); + } + if (option == WRITE_BUFFER_HIGH_WATER_MARK) { + return (T) Integer.valueOf(getWriteBufferHighWaterMark()); + } + if (option == WRITE_BUFFER_LOW_WATER_MARK) { + return (T) Integer.valueOf(getWriteBufferLowWaterMark()); + } + if (option == MESSAGE_SIZE_ESTIMATOR) { + return (T) getMessageSizeEstimator(); + } + return null; + } + + @Override + + public boolean setOption(ChannelOption option, T value) { + validate(option, value); + + if (option == CONNECT_TIMEOUT_MILLIS) { + setConnectTimeoutMillis((Integer) value); + } else if (option == MAX_MESSAGES_PER_READ) { + setMaxMessagesPerRead((Integer) value); + } else if (option == WRITE_SPIN_COUNT) { + setWriteSpinCount((Integer) value); + } else if (option == ALLOCATOR) { + setAllocator((ByteBufAllocator) value); + } else if (option == RCVBUF_ALLOCATOR) { + setRecvByteBufAllocator((RecvByteBufAllocator) value); + } else if (option == AUTO_READ) { + setAutoRead((Boolean) value); + } else if (option == AUTO_CLOSE) { + setAutoClose((Boolean) value); + } else if (option == WRITE_BUFFER_HIGH_WATER_MARK) { + setWriteBufferHighWaterMark((Integer) value); + } else if (option == WRITE_BUFFER_LOW_WATER_MARK) { + setWriteBufferLowWaterMark((Integer) value); + } else if (option == MESSAGE_SIZE_ESTIMATOR) { + setMessageSizeEstimator((MessageSizeEstimator) value); + } else { + return false; + } + + return true; + } + + protected void validate(ChannelOption option, T value) { + if (option == null) { + throw new NullPointerException("option"); + } + option.validate(value); + } + + @Override + public int getConnectTimeoutMillis() { + return connectTimeoutMillis; + } + + @Override + public ChannelConfig setConnectTimeoutMillis(int connectTimeoutMillis) { + if (connectTimeoutMillis < 0) { + throw new IllegalArgumentException(String.format( + "connectTimeoutMillis: %d (expected: >= 0)", connectTimeoutMillis)); + } + this.connectTimeoutMillis = connectTimeoutMillis; + return this; + } + + @Override + public int getMaxMessagesPerRead() { + return maxMessagesPerRead; + } + + @Override + public ChannelConfig setMaxMessagesPerRead(int maxMessagesPerRead) { + if (maxMessagesPerRead <= 0) { + throw new IllegalArgumentException("maxMessagesPerRead: " + maxMessagesPerRead + " (expected: > 0)"); + } + this.maxMessagesPerRead = maxMessagesPerRead; + return this; + } + + @Override + public int getWriteSpinCount() { + return writeSpinCount; + } + + @Override + public ChannelConfig setWriteSpinCount(int writeSpinCount) { + if (writeSpinCount <= 0) { + throw new IllegalArgumentException( + "writeSpinCount must be a positive integer."); + } + this.writeSpinCount = writeSpinCount; + return this; + } + + @Override + public ByteBufAllocator getAllocator() { + return allocator; + } + + @Override + public ChannelConfig setAllocator(ByteBufAllocator allocator) { + if (allocator == null) { + throw new NullPointerException("allocator"); + } + this.allocator = allocator; + return this; + } + + @Override + public RecvByteBufAllocator getRecvByteBufAllocator() { + return rcvBufAllocator; + } + + @Override + public ChannelConfig setRecvByteBufAllocator(RecvByteBufAllocator allocator) { + if (allocator == null) { + throw new NullPointerException("allocator"); + } + rcvBufAllocator = allocator; + return this; + } + + @Override + public boolean isAutoRead() { + return autoRead; + } + + @Override + public ChannelConfig setAutoRead(boolean autoRead) { + boolean oldAutoRead = this.autoRead; + this.autoRead = autoRead; + if (autoRead && !oldAutoRead) { + channel.read(); + } else if (!autoRead && oldAutoRead) { + autoReadCleared(); + } + return this; + } + + /** + * Is called once {@link #setAutoRead(boolean)} is called with {@code false} and {@link #isAutoRead()} was + * {@code true} before. + */ + protected void autoReadCleared() { } + + @Override + public boolean isAutoClose() { + return autoClose; + } + + @Override + public ChannelConfig setAutoClose(boolean autoClose) { + this.autoClose = autoClose; + return this; + } + + @Override + public int getWriteBufferHighWaterMark() { + return writeBufferHighWaterMark; + } + + @Override + public ChannelConfig setWriteBufferHighWaterMark(int writeBufferHighWaterMark) { + if (writeBufferHighWaterMark < getWriteBufferLowWaterMark()) { + throw new IllegalArgumentException( + "writeBufferHighWaterMark cannot be less than " + + "writeBufferLowWaterMark (" + getWriteBufferLowWaterMark() + "): " + + writeBufferHighWaterMark); + } + if (writeBufferHighWaterMark < 0) { + throw new IllegalArgumentException( + "writeBufferHighWaterMark must be >= 0"); + } + this.writeBufferHighWaterMark = writeBufferHighWaterMark; + return this; + } + + @Override + public int getWriteBufferLowWaterMark() { + return writeBufferLowWaterMark; + } + + @Override + public ChannelConfig setWriteBufferLowWaterMark(int writeBufferLowWaterMark) { + if (writeBufferLowWaterMark > getWriteBufferHighWaterMark()) { + throw new IllegalArgumentException( + "writeBufferLowWaterMark cannot be greater than " + + "writeBufferHighWaterMark (" + getWriteBufferHighWaterMark() + "): " + + writeBufferLowWaterMark); + } + if (writeBufferLowWaterMark < 0) { + throw new IllegalArgumentException( + "writeBufferLowWaterMark must be >= 0"); + } + this.writeBufferLowWaterMark = writeBufferLowWaterMark; + return this; + } + + @Override + public MessageSizeEstimator getMessageSizeEstimator() { + return msgSizeEstimator; + } + + @Override + public ChannelConfig setMessageSizeEstimator(MessageSizeEstimator estimator) { + if (estimator == null) { + throw new NullPointerException("estimator"); + } + msgSizeEstimator = estimator; + return this; + } +} diff --git a/common/src/common/net/channel/DefaultChannelHandlerContext.java b/common/src/common/net/channel/DefaultChannelHandlerContext.java new file mode 100644 index 0000000..9c24e1e --- /dev/null +++ b/common/src/common/net/channel/DefaultChannelHandlerContext.java @@ -0,0 +1,45 @@ +/* +* Copyright 2014 The Netty Project +* +* The Netty Project licenses this file to you under the Apache License, +* version 2.0 (the "License"); you may not use this file except in compliance +* with the License. You may obtain a copy of the License at: +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +* License for the specific language governing permissions and limitations +* under the License. +*/ +package common.net.channel; + +import common.net.util.concurrent.EventExecutorGroup; + +final class DefaultChannelHandlerContext extends AbstractChannelHandlerContext { + + private final ChannelHandler handler; + + DefaultChannelHandlerContext( + DefaultChannelPipeline pipeline, EventExecutorGroup group, String name, ChannelHandler handler) { + super(pipeline, group, name, isInbound(handler), isOutbound(handler)); + if (handler == null) { + throw new NullPointerException("handler"); + } + this.handler = handler; + } + + @Override + public ChannelHandler handler() { + return handler; + } + + private static boolean isInbound(ChannelHandler handler) { + return handler instanceof ChannelInboundHandler; + } + + private static boolean isOutbound(ChannelHandler handler) { + return handler instanceof ChannelOutboundHandler; + } +} diff --git a/common/src/common/net/channel/DefaultChannelPipeline.java b/common/src/common/net/channel/DefaultChannelPipeline.java new file mode 100644 index 0000000..73e66c9 --- /dev/null +++ b/common/src/common/net/channel/DefaultChannelPipeline.java @@ -0,0 +1,1067 @@ +/* + * Copyright 2012 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ +package common.net.channel; + +import java.net.SocketAddress; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.IdentityHashMap; +import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.NoSuchElementException; +import java.util.WeakHashMap; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.Future; + +import common.net.channel.Channel.Unsafe; +import common.net.util.ReferenceCountUtil; +import common.net.util.concurrent.EventExecutor; +import common.net.util.concurrent.EventExecutorGroup; +import common.net.util.internal.PlatformDependent; +import common.net.util.internal.StringUtil; +import common.net.util.internal.logging.InternalLogger; +import common.net.util.internal.logging.InternalLoggerFactory; + +/** + * The default {@link ChannelPipeline} implementation. It is usually created + * by a {@link Channel} implementation when the {@link Channel} is created. + */ +final class DefaultChannelPipeline implements ChannelPipeline { + + static final InternalLogger logger = InternalLoggerFactory.getInstance(DefaultChannelPipeline.class); + + + private static final WeakHashMap, String>[] nameCaches = + new WeakHashMap[Runtime.getRuntime().availableProcessors()]; + + static { + for (int i = 0; i < nameCaches.length; i ++) { + nameCaches[i] = new WeakHashMap, String>(); + } + } + + final AbstractChannel channel; + + final AbstractChannelHandlerContext head; + final AbstractChannelHandlerContext tail; + + private final Map name2ctx = + new HashMap(4); + + final Map childExecutors = + new IdentityHashMap(); + + public DefaultChannelPipeline(AbstractChannel channel) { + if (channel == null) { + throw new NullPointerException("channel"); + } + this.channel = channel; + + tail = new TailContext(this); + head = new HeadContext(this); + + head.next = tail; + tail.prev = head; + } + + @Override + public Channel channel() { + return channel; + } + + @Override + public ChannelPipeline addFirst(String name, ChannelHandler handler) { + return addFirst(null, name, handler); + } + + @Override + public ChannelPipeline addFirst(EventExecutorGroup group, final String name, ChannelHandler handler) { + synchronized (this) { + checkDuplicateName(name); + AbstractChannelHandlerContext newCtx = new DefaultChannelHandlerContext(this, group, name, handler); + addFirst0(name, newCtx); + } + + return this; + } + + private void addFirst0(String name, AbstractChannelHandlerContext newCtx) { + checkMultiplicity(newCtx); + + AbstractChannelHandlerContext nextCtx = head.next; + newCtx.prev = head; + newCtx.next = nextCtx; + head.next = newCtx; + nextCtx.prev = newCtx; + + name2ctx.put(name, newCtx); + + callHandlerAdded(newCtx); + } + + @Override + public ChannelPipeline addLast(String name, ChannelHandler handler) { + return addLast(null, name, handler); + } + + @Override + public ChannelPipeline addLast(EventExecutorGroup group, final String name, ChannelHandler handler) { + synchronized (this) { + checkDuplicateName(name); + + AbstractChannelHandlerContext newCtx = new DefaultChannelHandlerContext(this, group, name, handler); + addLast0(name, newCtx); + } + + return this; + } + + private void addLast0(final String name, AbstractChannelHandlerContext newCtx) { + checkMultiplicity(newCtx); + + AbstractChannelHandlerContext prev = tail.prev; + newCtx.prev = prev; + newCtx.next = tail; + prev.next = newCtx; + tail.prev = newCtx; + + name2ctx.put(name, newCtx); + + callHandlerAdded(newCtx); + } + + @Override + public ChannelPipeline addBefore(String baseName, String name, ChannelHandler handler) { + return addBefore(null, baseName, name, handler); + } + + @Override + public ChannelPipeline addBefore( + EventExecutorGroup group, String baseName, final String name, ChannelHandler handler) { + synchronized (this) { + AbstractChannelHandlerContext ctx = getContextOrDie(baseName); + checkDuplicateName(name); + AbstractChannelHandlerContext newCtx = new DefaultChannelHandlerContext(this, group, name, handler); + addBefore0(name, ctx, newCtx); + } + return this; + } + + private void addBefore0( + final String name, AbstractChannelHandlerContext ctx, AbstractChannelHandlerContext newCtx) { + checkMultiplicity(newCtx); + + newCtx.prev = ctx.prev; + newCtx.next = ctx; + ctx.prev.next = newCtx; + ctx.prev = newCtx; + + name2ctx.put(name, newCtx); + + callHandlerAdded(newCtx); + } + + @Override + public ChannelPipeline addAfter(String baseName, String name, ChannelHandler handler) { + return addAfter(null, baseName, name, handler); + } + + @Override + public ChannelPipeline addAfter( + EventExecutorGroup group, String baseName, final String name, ChannelHandler handler) { + synchronized (this) { + AbstractChannelHandlerContext ctx = getContextOrDie(baseName); + checkDuplicateName(name); + AbstractChannelHandlerContext newCtx = new DefaultChannelHandlerContext(this, group, name, handler); + + addAfter0(name, ctx, newCtx); + } + + return this; + } + + private void addAfter0(final String name, AbstractChannelHandlerContext ctx, AbstractChannelHandlerContext newCtx) { + checkDuplicateName(name); + checkMultiplicity(newCtx); + + newCtx.prev = ctx; + newCtx.next = ctx.next; + ctx.next.prev = newCtx; + ctx.next = newCtx; + + name2ctx.put(name, newCtx); + + callHandlerAdded(newCtx); + } + + @Override + public ChannelPipeline addFirst(ChannelHandler... handlers) { + return addFirst(null, handlers); + } + + @Override + public ChannelPipeline addFirst(EventExecutorGroup executor, ChannelHandler... handlers) { + if (handlers == null) { + throw new NullPointerException("handlers"); + } + if (handlers.length == 0 || handlers[0] == null) { + return this; + } + + int size; + for (size = 1; size < handlers.length; size ++) { + if (handlers[size] == null) { + break; + } + } + + for (int i = size - 1; i >= 0; i --) { + ChannelHandler h = handlers[i]; + addFirst(executor, generateName(h), h); + } + + return this; + } + + @Override + public ChannelPipeline addLast(ChannelHandler... handlers) { + return addLast(null, handlers); + } + + @Override + public ChannelPipeline addLast(EventExecutorGroup executor, ChannelHandler... handlers) { + if (handlers == null) { + throw new NullPointerException("handlers"); + } + + for (ChannelHandler h: handlers) { + if (h == null) { + break; + } + addLast(executor, generateName(h), h); + } + + return this; + } + + private String generateName(ChannelHandler handler) { + WeakHashMap, String> cache = nameCaches[(int) (Thread.currentThread().getId() % nameCaches.length)]; + Class handlerType = handler.getClass(); + String name; + synchronized (cache) { + name = cache.get(handlerType); + if (name == null) { + name = generateName0(handlerType); + cache.put(handlerType, name); + } + } + + synchronized (this) { + // It's not very likely for a user to put more than one handler of the same type, but make sure to avoid + // any name conflicts. Note that we don't cache the names generated here. + if (name2ctx.containsKey(name)) { + String baseName = name.substring(0, name.length() - 1); // Strip the trailing '0'. + for (int i = 1;; i ++) { + String newName = baseName + i; + if (!name2ctx.containsKey(newName)) { + name = newName; + break; + } + } + } + } + + return name; + } + + private static String generateName0(Class handlerType) { + return StringUtil.simpleClassName(handlerType) + "#0"; + } + + @Override + public ChannelPipeline remove(ChannelHandler handler) { + remove(getContextOrDie(handler)); + return this; + } + + @Override + public ChannelHandler remove(String name) { + return remove(getContextOrDie(name)).handler(); + } + + + @Override + public T remove(Class handlerType) { + return (T) remove(getContextOrDie(handlerType)).handler(); + } + + private AbstractChannelHandlerContext remove(final AbstractChannelHandlerContext ctx) { + assert ctx != head && ctx != tail; + + AbstractChannelHandlerContext context; + Future future; + + synchronized (this) { + if (!ctx.channel().isRegistered() || ctx.executor().inEventLoop()) { + remove0(ctx); + return ctx; + } else { + future = ctx.executor().submit(new Runnable() { + @Override + public void run() { + synchronized (DefaultChannelPipeline.this) { + remove0(ctx); + } + } + }); + context = ctx; + } + } + + // Run the following 'waiting' code outside of the above synchronized block + // in order to avoid deadlock + + waitForFuture(future); + + return context; + } + + void remove0(AbstractChannelHandlerContext ctx) { + AbstractChannelHandlerContext prev = ctx.prev; + AbstractChannelHandlerContext next = ctx.next; + prev.next = next; + next.prev = prev; + name2ctx.remove(ctx.name()); + callHandlerRemoved(ctx); + } + + @Override + public ChannelHandler removeFirst() { + if (head.next == tail) { + throw new NoSuchElementException(); + } + return remove(head.next).handler(); + } + + @Override + public ChannelHandler removeLast() { + if (head.next == tail) { + throw new NoSuchElementException(); + } + return remove(tail.prev).handler(); + } + + @Override + public ChannelPipeline replace(ChannelHandler oldHandler, String newName, ChannelHandler newHandler) { + replace(getContextOrDie(oldHandler), newName, newHandler); + return this; + } + + @Override + public ChannelHandler replace(String oldName, String newName, ChannelHandler newHandler) { + return replace(getContextOrDie(oldName), newName, newHandler); + } + + @Override + + public T replace( + Class oldHandlerType, String newName, ChannelHandler newHandler) { + return (T) replace(getContextOrDie(oldHandlerType), newName, newHandler); + } + + private ChannelHandler replace( + final AbstractChannelHandlerContext ctx, final String newName, + ChannelHandler newHandler) { + + assert ctx != head && ctx != tail; + + Future future; + synchronized (this) { + boolean sameName = ctx.name().equals(newName); + if (!sameName) { + checkDuplicateName(newName); + } + + final AbstractChannelHandlerContext newCtx = + new DefaultChannelHandlerContext(this, ctx.executor, newName, newHandler); + + if (!newCtx.channel().isRegistered() || newCtx.executor().inEventLoop()) { + replace0(ctx, newName, newCtx); + return ctx.handler(); + } else { + future = newCtx.executor().submit(new Runnable() { + @Override + public void run() { + synchronized (DefaultChannelPipeline.this) { + replace0(ctx, newName, newCtx); + } + } + }); + } + } + + // Run the following 'waiting' code outside of the above synchronized block + // in order to avoid deadlock + + waitForFuture(future); + + return ctx.handler(); + } + + private void replace0(AbstractChannelHandlerContext oldCtx, String newName, + AbstractChannelHandlerContext newCtx) { + checkMultiplicity(newCtx); + + AbstractChannelHandlerContext prev = oldCtx.prev; + AbstractChannelHandlerContext next = oldCtx.next; + newCtx.prev = prev; + newCtx.next = next; + + // Finish the replacement of oldCtx with newCtx in the linked list. + // Note that this doesn't mean events will be sent to the new handler immediately + // because we are currently at the event handler thread and no more than one handler methods can be invoked + // at the same time (we ensured that in replace().) + prev.next = newCtx; + next.prev = newCtx; + + if (!oldCtx.name().equals(newName)) { + name2ctx.remove(oldCtx.name()); + } + name2ctx.put(newName, newCtx); + + // update the reference to the replacement so forward of buffered content will work correctly + oldCtx.prev = newCtx; + oldCtx.next = newCtx; + + // Invoke newHandler.handlerAdded() first (i.e. before oldHandler.handlerRemoved() is invoked) + // because callHandlerRemoved() will trigger inboundBufferUpdated() or flush() on newHandler and those + // event handlers must be called after handlerAdded(). + callHandlerAdded(newCtx); + callHandlerRemoved(oldCtx); + } + + private static void checkMultiplicity(ChannelHandlerContext ctx) { + ChannelHandler handler = ctx.handler(); + if (handler instanceof ChannelHandlerAdapter) { + ChannelHandlerAdapter h = (ChannelHandlerAdapter) handler; + if (!h.isSharable() && h.added) { + throw new ChannelPipelineException( + h.getClass().getName() + + " is not a @Sharable handler, so can't be added or removed multiple times."); + } + h.added = true; + } + } + + private void callHandlerAdded(final ChannelHandlerContext ctx) { + if (ctx.channel().isRegistered() && !ctx.executor().inEventLoop()) { + ctx.executor().execute(new Runnable() { + @Override + public void run() { + callHandlerAdded0(ctx); + } + }); + return; + } + callHandlerAdded0(ctx); + } + + private void callHandlerAdded0(final ChannelHandlerContext ctx) { + try { + ctx.handler().handlerAdded(ctx); + } catch (Throwable t) { + boolean removed = false; + try { + remove((AbstractChannelHandlerContext) ctx); + removed = true; + } catch (Throwable t2) { + if (logger.isWarnEnabled()) { + logger.warn("Failed to remove a handler: " + ctx.name(), t2); + } + } + + if (removed) { + fireExceptionCaught(new ChannelPipelineException( + ctx.handler().getClass().getName() + + ".handlerAdded() has thrown an exception; removed.", t)); + } else { + fireExceptionCaught(new ChannelPipelineException( + ctx.handler().getClass().getName() + + ".handlerAdded() has thrown an exception; also failed to remove.", t)); + } + } + } + + private void callHandlerRemoved(final AbstractChannelHandlerContext ctx) { + if (ctx.channel().isRegistered() && !ctx.executor().inEventLoop()) { + ctx.executor().execute(new Runnable() { + @Override + public void run() { + callHandlerRemoved0(ctx); + } + }); + return; + } + callHandlerRemoved0(ctx); + } + + private void callHandlerRemoved0(final AbstractChannelHandlerContext ctx) { + // Notify the complete removal. + try { + ctx.handler().handlerRemoved(ctx); + ctx.setRemoved(); + } catch (Throwable t) { + fireExceptionCaught(new ChannelPipelineException( + ctx.handler().getClass().getName() + ".handlerRemoved() has thrown an exception.", t)); + } + } + + /** + * Waits for a future to finish. If the task is interrupted, then the current thread will be interrupted. + * It is expected that the task performs any appropriate locking. + *

+ * If the internal call throws a {@link Throwable}, but it is not an instance of {@link Error} or + * {@link RuntimeException}, then it is wrapped inside a {@link ChannelPipelineException} and that is + * thrown instead.

+ * + * @param future wait for this future + * @see Future#get() + * @throws Error if the task threw this. + * @throws RuntimeException if the task threw this. + * @throws ChannelPipelineException with a {@link Throwable} as a cause, if the task threw another type of + * {@link Throwable}. + */ + private static void waitForFuture(Future future) { + try { + future.get(); + } catch (ExecutionException ex) { + // In the arbitrary case, we can throw Error, RuntimeException, and Exception + PlatformDependent.throwException(ex.getCause()); + } catch (InterruptedException ex) { + // Interrupt the calling thread (note that this method is not called from the event loop) + Thread.currentThread().interrupt(); + } + } + + @Override + public ChannelHandler first() { + ChannelHandlerContext first = firstContext(); + if (first == null) { + return null; + } + return first.handler(); + } + + @Override + public ChannelHandlerContext firstContext() { + AbstractChannelHandlerContext first = head.next; + if (first == tail) { + return null; + } + return head.next; + } + + @Override + public ChannelHandler last() { + AbstractChannelHandlerContext last = tail.prev; + if (last == head) { + return null; + } + return last.handler(); + } + + @Override + public ChannelHandlerContext lastContext() { + AbstractChannelHandlerContext last = tail.prev; + if (last == head) { + return null; + } + return last; + } + + @Override + public ChannelHandler get(String name) { + ChannelHandlerContext ctx = context(name); + if (ctx == null) { + return null; + } else { + return ctx.handler(); + } + } + + + @Override + public T get(Class handlerType) { + ChannelHandlerContext ctx = context(handlerType); + if (ctx == null) { + return null; + } else { + return (T) ctx.handler(); + } + } + + @Override + public ChannelHandlerContext context(String name) { + if (name == null) { + throw new NullPointerException("name"); + } + + synchronized (this) { + return name2ctx.get(name); + } + } + + @Override + public ChannelHandlerContext context(ChannelHandler handler) { + if (handler == null) { + throw new NullPointerException("handler"); + } + + AbstractChannelHandlerContext ctx = head.next; + for (;;) { + + if (ctx == null) { + return null; + } + + if (ctx.handler() == handler) { + return ctx; + } + + ctx = ctx.next; + } + } + + @Override + public ChannelHandlerContext context(Class handlerType) { + if (handlerType == null) { + throw new NullPointerException("handlerType"); + } + + AbstractChannelHandlerContext ctx = head.next; + for (;;) { + if (ctx == null) { + return null; + } + if (handlerType.isAssignableFrom(ctx.handler().getClass())) { + return ctx; + } + ctx = ctx.next; + } + } + + @Override + public List names() { + List list = new ArrayList(); + AbstractChannelHandlerContext ctx = head.next; + for (;;) { + if (ctx == null) { + return list; + } + list.add(ctx.name()); + ctx = ctx.next; + } + } + + @Override + public Map toMap() { + Map map = new LinkedHashMap(); + AbstractChannelHandlerContext ctx = head.next; + for (;;) { + if (ctx == tail) { + return map; + } + map.put(ctx.name(), ctx.handler()); + ctx = ctx.next; + } + } + + @Override + public Iterator> iterator() { + return toMap().entrySet().iterator(); + } + + /** + * Returns the {@link String} representation of this pipeline. + */ + @Override + public String toString() { + StringBuilder buf = new StringBuilder(); + buf.append(StringUtil.simpleClassName(this)); + buf.append('{'); + AbstractChannelHandlerContext ctx = head.next; + for (;;) { + if (ctx == tail) { + break; + } + + buf.append('('); + buf.append(ctx.name()); + buf.append(" = "); + buf.append(ctx.handler().getClass().getName()); + buf.append(')'); + + ctx = ctx.next; + if (ctx == tail) { + break; + } + + buf.append(", "); + } + buf.append('}'); + return buf.toString(); + } + + @Override + public ChannelPipeline fireChannelRegistered() { + head.fireChannelRegistered(); + return this; + } + + @Override + public ChannelPipeline fireChannelUnregistered() { + head.fireChannelUnregistered(); + + // Remove all handlers sequentially if channel is closed and unregistered. + if (!channel.isOpen()) { + teardownAll(); + } + return this; + } + + /** + * Removes all handlers from the pipeline one by one from tail (exclusive) to head (inclusive) to trigger + * handlerRemoved(). Note that the tail handler is excluded because it's neither an outbound handler nor it + * does anything in handlerRemoved(). + */ + private void teardownAll() { + tail.prev.teardown(); + } + + @Override + public ChannelPipeline fireChannelActive() { + head.fireChannelActive(); + + if (channel.config().isAutoRead()) { + channel.read(); + } + + return this; + } + + @Override + public ChannelPipeline fireChannelInactive() { + head.fireChannelInactive(); + return this; + } + + @Override + public ChannelPipeline fireExceptionCaught(Throwable cause) { + head.fireExceptionCaught(cause); + return this; + } + + @Override + public ChannelPipeline fireUserEventTriggered(Object event) { + head.fireUserEventTriggered(event); + return this; + } + + @Override + public ChannelPipeline fireChannelRead(Object msg) { + head.fireChannelRead(msg); + return this; + } + + @Override + public ChannelPipeline fireChannelReadComplete() { + head.fireChannelReadComplete(); + if (channel.config().isAutoRead()) { + read(); + } + return this; + } + + @Override + public ChannelPipeline fireChannelWritabilityChanged() { + head.fireChannelWritabilityChanged(); + return this; + } + + @Override + public ChannelFuture bind(SocketAddress localAddress) { + return tail.bind(localAddress); + } + + @Override + public ChannelFuture connect(SocketAddress remoteAddress) { + return tail.connect(remoteAddress); + } + + @Override + public ChannelFuture connect(SocketAddress remoteAddress, SocketAddress localAddress) { + return tail.connect(remoteAddress, localAddress); + } + + @Override + public ChannelFuture disconnect() { + return tail.disconnect(); + } + + @Override + public ChannelFuture close() { + return tail.close(); + } + + @Override + public ChannelFuture deregister() { + return tail.deregister(); + } + + @Override + public ChannelPipeline flush() { + tail.flush(); + return this; + } + + @Override + public ChannelFuture bind(SocketAddress localAddress, ChannelPromise promise) { + return tail.bind(localAddress, promise); + } + + @Override + public ChannelFuture connect(SocketAddress remoteAddress, ChannelPromise promise) { + return tail.connect(remoteAddress, promise); + } + + @Override + public ChannelFuture connect(SocketAddress remoteAddress, SocketAddress localAddress, ChannelPromise promise) { + return tail.connect(remoteAddress, localAddress, promise); + } + + @Override + public ChannelFuture disconnect(ChannelPromise promise) { + return tail.disconnect(promise); + } + + @Override + public ChannelFuture close(ChannelPromise promise) { + return tail.close(promise); + } + + @Override + public ChannelFuture deregister(final ChannelPromise promise) { + return tail.deregister(promise); + } + + @Override + public ChannelPipeline read() { + tail.read(); + return this; + } + + @Override + public ChannelFuture write(Object msg) { + return tail.write(msg); + } + + @Override + public ChannelFuture write(Object msg, ChannelPromise promise) { + return tail.write(msg, promise); + } + + @Override + public ChannelFuture writeAndFlush(Object msg, ChannelPromise promise) { + return tail.writeAndFlush(msg, promise); + } + + @Override + public ChannelFuture writeAndFlush(Object msg) { + return tail.writeAndFlush(msg); + } + + private void checkDuplicateName(String name) { + if (name2ctx.containsKey(name)) { + throw new IllegalArgumentException("Duplicate handler name: " + name); + } + } + + private AbstractChannelHandlerContext getContextOrDie(String name) { + AbstractChannelHandlerContext ctx = (AbstractChannelHandlerContext) context(name); + if (ctx == null) { + throw new NoSuchElementException(name); + } else { + return ctx; + } + } + + private AbstractChannelHandlerContext getContextOrDie(ChannelHandler handler) { + AbstractChannelHandlerContext ctx = (AbstractChannelHandlerContext) context(handler); + if (ctx == null) { + throw new NoSuchElementException(handler.getClass().getName()); + } else { + return ctx; + } + } + + private AbstractChannelHandlerContext getContextOrDie(Class handlerType) { + AbstractChannelHandlerContext ctx = (AbstractChannelHandlerContext) context(handlerType); + if (ctx == null) { + throw new NoSuchElementException(handlerType.getName()); + } else { + return ctx; + } + } + + // A special catch-all handler that handles both bytes and messages. + static final class TailContext extends AbstractChannelHandlerContext implements ChannelInboundHandler { + + private static final String TAIL_NAME = generateName0(TailContext.class); + + TailContext(DefaultChannelPipeline pipeline) { + super(pipeline, null, TAIL_NAME, true, false); + } + + @Override + public ChannelHandler handler() { + return this; + } + + @Override + public void channelRegistered(ChannelHandlerContext ctx) throws Exception { } + + @Override + public void channelUnregistered(ChannelHandlerContext ctx) throws Exception { } + + @Override + public void channelActive(ChannelHandlerContext ctx) throws Exception { } + + @Override + public void channelInactive(ChannelHandlerContext ctx) throws Exception { } + + @Override + public void channelWritabilityChanged(ChannelHandlerContext ctx) throws Exception { } + + @Override + public void handlerAdded(ChannelHandlerContext ctx) throws Exception { } + + @Override + public void handlerRemoved(ChannelHandlerContext ctx) throws Exception { } + + @Override + public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception { } + + @Override + public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { + logger.warn( + "An exceptionCaught() event was fired, and it reached at the tail of the pipeline. " + + "It usually means the last handler in the pipeline did not handle the exception.", cause); + } + + @Override + public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { + try { + logger.debug( + "Discarded inbound message {} that reached at the tail of the pipeline. " + + "Please check your pipeline configuration.", msg); + } finally { + ReferenceCountUtil.release(msg); + } + } + + @Override + public void channelReadComplete(ChannelHandlerContext ctx) throws Exception { } + } + + static final class HeadContext extends AbstractChannelHandlerContext implements ChannelOutboundHandler { + + private static final String HEAD_NAME = generateName0(HeadContext.class); + + protected final Unsafe unsafe; + + HeadContext(DefaultChannelPipeline pipeline) { + super(pipeline, null, HEAD_NAME, false, true); + unsafe = pipeline.channel().unsafe(); + } + + @Override + public ChannelHandler handler() { + return this; + } + + @Override + public void handlerAdded(ChannelHandlerContext ctx) throws Exception { + // NOOP + } + + @Override + public void handlerRemoved(ChannelHandlerContext ctx) throws Exception { + // NOOP + } + + @Override + public void bind( + ChannelHandlerContext ctx, SocketAddress localAddress, ChannelPromise promise) + throws Exception { + unsafe.bind(localAddress, promise); + } + + @Override + public void connect( + ChannelHandlerContext ctx, + SocketAddress remoteAddress, SocketAddress localAddress, + ChannelPromise promise) throws Exception { + unsafe.connect(remoteAddress, localAddress, promise); + } + + @Override + public void disconnect(ChannelHandlerContext ctx, ChannelPromise promise) throws Exception { + unsafe.disconnect(promise); + } + + @Override + public void close(ChannelHandlerContext ctx, ChannelPromise promise) throws Exception { + unsafe.close(promise); + } + + @Override + public void deregister(ChannelHandlerContext ctx, ChannelPromise promise) throws Exception { + unsafe.deregister(promise); + } + + @Override + public void read(ChannelHandlerContext ctx) { + unsafe.beginRead(); + } + + @Override + public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception { + unsafe.write(msg, promise); + } + + @Override + public void flush(ChannelHandlerContext ctx) throws Exception { + unsafe.flush(); + } + + @Override + public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { + ctx.fireExceptionCaught(cause); + } + } +} diff --git a/common/src/common/net/channel/DefaultChannelPromise.java b/common/src/common/net/channel/DefaultChannelPromise.java new file mode 100644 index 0000000..02cc235 --- /dev/null +++ b/common/src/common/net/channel/DefaultChannelPromise.java @@ -0,0 +1,159 @@ +/* + * Copyright 2012 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ +package common.net.channel; + +import common.net.util.concurrent.DefaultPromise; +import common.net.util.concurrent.EventExecutor; +import common.net.util.concurrent.Future; +import common.net.util.concurrent.GenericFutureListener; + +/** + * The default {@link ChannelPromise} implementation. It is recommended to use {@link Channel#newPromise()} to create + * a new {@link ChannelPromise} rather than calling the constructor explicitly. + */ +public class DefaultChannelPromise extends DefaultPromise implements ChannelPromise { + + private final Channel channel; +// private long checkpoint; + + /** + * Creates a new instance. + * + * @param channel + * the {@link Channel} associated with this future + */ + public DefaultChannelPromise(Channel channel) { + this.channel = channel; + } + + /** + * Creates a new instance. + * + * @param channel + * the {@link Channel} associated with this future + */ + public DefaultChannelPromise(Channel channel, EventExecutor executor) { + super(executor); + this.channel = channel; + } + + @Override + protected EventExecutor executor() { + EventExecutor e = super.executor(); + if (e == null) { + return channel().eventLoop(); + } else { + return e; + } + } + + @Override + public Channel channel() { + return channel; + } + + @Override + public ChannelPromise setSuccess() { + return setSuccess(null); + } + + @Override + public ChannelPromise setSuccess(Void result) { + super.setSuccess(result); + return this; + } + + @Override + public boolean trySuccess() { + return trySuccess(null); + } + + @Override + public ChannelPromise setFailure(Throwable cause) { + super.setFailure(cause); + return this; + } + + @Override + public ChannelPromise addListener(GenericFutureListener> listener) { + super.addListener(listener); + return this; + } + + @Override + public ChannelPromise addListeners(GenericFutureListener>... listeners) { + super.addListeners(listeners); + return this; + } + + @Override + public ChannelPromise removeListener(GenericFutureListener> listener) { + super.removeListener(listener); + return this; + } + + @Override + public ChannelPromise removeListeners(GenericFutureListener>... listeners) { + super.removeListeners(listeners); + return this; + } + + @Override + public ChannelPromise sync() throws InterruptedException { + super.sync(); + return this; + } + + @Override + public ChannelPromise syncUninterruptibly() { + super.syncUninterruptibly(); + return this; + } + + @Override + public ChannelPromise await() throws InterruptedException { + super.await(); + return this; + } + + @Override + public ChannelPromise awaitUninterruptibly() { + super.awaitUninterruptibly(); + return this; + } + +// @Override +// public long flushCheckpoint() { +// return checkpoint; +// } + +// @Override +// public void flushCheckpoint(long checkpoint) { +// this.checkpoint = checkpoint; +// } + +// @Override +// public ChannelPromise promise() { +// return this; +// } + + @Override + protected void checkDeadLock() { + if (channel().isRegistered()) { + super.checkDeadLock(); + } + } +} diff --git a/common/src/common/net/channel/DefaultMessageSizeEstimator.java b/common/src/common/net/channel/DefaultMessageSizeEstimator.java new file mode 100644 index 0000000..0862e96 --- /dev/null +++ b/common/src/common/net/channel/DefaultMessageSizeEstimator.java @@ -0,0 +1,71 @@ +/* + * Copyright 2013 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ +package common.net.channel; + +import common.net.buffer.ByteBuf; + +/** + * Default {@link MessageSizeEstimator} implementation which supports the estimation of the size of + * {@link ByteBuf}, {@link ByteBufHolder} and {@link FileRegion}. + */ +public final class DefaultMessageSizeEstimator implements MessageSizeEstimator { + + private static final class HandleImpl implements Handle { + private final int unknownSize; + + private HandleImpl(int unknownSize) { + this.unknownSize = unknownSize; + } + + @Override + public int size(Object msg) { + if (msg instanceof ByteBuf) { + return ((ByteBuf) msg).readableBytes(); + } +// if (msg instanceof ByteBufHolder) { +// return ((ByteBufHolder) msg).content().readableBytes(); +// } +// if (msg instanceof FileRegion) { +// return 0; +// } + return unknownSize; + } + } + + /** + * Return the default implementation which returns {@code -1} for unknown messages. + */ + public static final MessageSizeEstimator DEFAULT = new DefaultMessageSizeEstimator(0); + + private final Handle handle; + + /** + * Create a new instance + * + * @param unknownSize The size which is returned for unknown messages. + */ + public DefaultMessageSizeEstimator(int unknownSize) { + if (unknownSize < 0) { + throw new IllegalArgumentException("unknownSize: " + unknownSize + " (expected: >= 0)"); + } + handle = new HandleImpl(unknownSize); + } + + @Override + public Handle newHandle() { + return handle; + } +} diff --git a/common/src/common/net/channel/EventLoop.java b/common/src/common/net/channel/EventLoop.java new file mode 100644 index 0000000..8daea7a --- /dev/null +++ b/common/src/common/net/channel/EventLoop.java @@ -0,0 +1,30 @@ +/* + * Copyright 2012 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ +package common.net.channel; + +import common.net.util.concurrent.EventExecutor; + +/** + * Will handle all the I/O-Operations for a {@link Channel} once it was registered. + * + * One {@link EventLoop} instance will usually handle more then one {@link Channel} but this may depend on + * implementation details and internals. + * + */ +public interface EventLoop extends EventExecutor, EventLoopGroup { + @Override + EventLoopGroup parent(); +} diff --git a/common/src/common/net/channel/EventLoopException.java b/common/src/common/net/channel/EventLoopException.java new file mode 100644 index 0000000..02f9ffa --- /dev/null +++ b/common/src/common/net/channel/EventLoopException.java @@ -0,0 +1,41 @@ +/* + * Copyright 2012 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ +package common.net.channel; + +/** + * Special {@link ChannelException} which will be thrown by {@link EventLoop} and {@link EventLoopGroup} + * implementations when an error occurs. + */ +public class EventLoopException extends ChannelException { + + private static final long serialVersionUID = -8969100344583703616L; + + public EventLoopException() { + } + + public EventLoopException(String message, Throwable cause) { + super(message, cause); + } + + public EventLoopException(String message) { + super(message); + } + + public EventLoopException(Throwable cause) { + super(cause); + } + +} diff --git a/common/src/common/net/channel/EventLoopGroup.java b/common/src/common/net/channel/EventLoopGroup.java new file mode 100644 index 0000000..e058491 --- /dev/null +++ b/common/src/common/net/channel/EventLoopGroup.java @@ -0,0 +1,43 @@ +/* + * Copyright 2012 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ +package common.net.channel; + +import common.net.util.concurrent.EventExecutorGroup; + +/** + * Special {@link EventExecutorGroup} which allows to register {@link Channel}'s that get + * processed for later selection during the event loop. + * + */ +public interface EventLoopGroup extends EventExecutorGroup { + /** + * Return the next {@link EventLoop} to use + */ + @Override + EventLoop next(); + + /** + * Register a {@link Channel} with this {@link EventLoop}. The returned {@link ChannelFuture} + * will get notified once the registration was complete. + */ + ChannelFuture register(Channel channel); + + /** + * Register a {@link Channel} with this {@link EventLoop}. The passed {@link ChannelFuture} + * will get notified once the registration was complete and also will get returned. + */ + ChannelFuture register(Channel channel, ChannelPromise promise); +} diff --git a/common/src/common/net/channel/FailedChannelFuture.java b/common/src/common/net/channel/FailedChannelFuture.java new file mode 100644 index 0000000..b36b461 --- /dev/null +++ b/common/src/common/net/channel/FailedChannelFuture.java @@ -0,0 +1,65 @@ +/* + * Copyright 2012 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ +package common.net.channel; + +import common.net.util.concurrent.EventExecutor; +import common.net.util.internal.PlatformDependent; + +/** + * The {@link CompleteChannelFuture} which is failed already. It is + * recommended to use {@link Channel#newFailedFuture(Throwable)} + * instead of calling the constructor of this future. + */ +final class FailedChannelFuture extends CompleteChannelFuture { + + private final Throwable cause; + + /** + * Creates a new instance. + * + * @param channel the {@link Channel} associated with this future + * @param cause the cause of failure + */ + FailedChannelFuture(Channel channel, EventExecutor executor, Throwable cause) { + super(channel, executor); + if (cause == null) { + throw new NullPointerException("cause"); + } + this.cause = cause; + } + + @Override + public Throwable cause() { + return cause; + } + + @Override + public boolean isSuccess() { + return false; + } + + @Override + public ChannelFuture sync() { + PlatformDependent.throwException(cause); + return this; + } + + @Override + public ChannelFuture syncUninterruptibly() { + PlatformDependent.throwException(cause); + return this; + } +} diff --git a/common/src/common/net/channel/MessageSizeEstimator.java b/common/src/common/net/channel/MessageSizeEstimator.java new file mode 100644 index 0000000..cdefc87 --- /dev/null +++ b/common/src/common/net/channel/MessageSizeEstimator.java @@ -0,0 +1,39 @@ +/* + * Copyright 2013 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ +package common.net.channel; + +/** + * Responsible to estimate size of a message. The size represent how much memory the message will ca. reserve in + * memory. + */ +public interface MessageSizeEstimator { + + /** + * Creates a new handle. The handle provides the actual operations. + */ + Handle newHandle(); + + interface Handle { + + /** + * Calculate the size of the given message. + * + * @param msg The message for which the size should be calculated + * @return size The size in bytes. The returned size must be >= 0 + */ + int size(Object msg); + } +} diff --git a/common/src/common/net/channel/MultithreadEventLoopGroup.java b/common/src/common/net/channel/MultithreadEventLoopGroup.java new file mode 100644 index 0000000..0a5f4e1 --- /dev/null +++ b/common/src/common/net/channel/MultithreadEventLoopGroup.java @@ -0,0 +1,71 @@ +/* + * Copyright 2012 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ +package common.net.channel; + +import java.util.concurrent.ThreadFactory; + +import common.net.util.concurrent.DefaultThreadFactory; +import common.net.util.concurrent.MultithreadEventExecutorGroup; +import common.net.util.internal.SystemPropertyUtil; +import common.net.util.internal.logging.InternalLogger; +import common.net.util.internal.logging.InternalLoggerFactory; + +/** + * Abstract base class for {@link EventLoopGroup} implementations that handles their tasks with multiple threads at + * the same time. + */ +public abstract class MultithreadEventLoopGroup extends MultithreadEventExecutorGroup implements EventLoopGroup { + + private static final InternalLogger logger = InternalLoggerFactory.getInstance(MultithreadEventLoopGroup.class); + + private static final int DEFAULT_EVENT_LOOP_THREADS; + + static { + DEFAULT_EVENT_LOOP_THREADS = Math.max(1, SystemPropertyUtil.getInt( + "game.net.eventLoopThreads", Runtime.getRuntime().availableProcessors() * 2)); + + if (logger.isDebugEnabled()) { + logger.debug("-Dgame.net.eventLoopThreads: {}", DEFAULT_EVENT_LOOP_THREADS); + } + } + + /** + * @see {@link MultithreadEventExecutorGroup#MultithreadEventExecutorGroup(int, ThreadFactory, Object...)} + */ + protected MultithreadEventLoopGroup(int nThreads, ThreadFactory threadFactory, Object... args) { + super(nThreads == 0? DEFAULT_EVENT_LOOP_THREADS : nThreads, threadFactory, args); + } + + @Override + protected ThreadFactory newDefaultThreadFactory() { + return new DefaultThreadFactory(getClass(), Thread.MAX_PRIORITY); + } + + @Override + public EventLoop next() { + return (EventLoop) super.next(); + } + + @Override + public ChannelFuture register(Channel channel) { + return next().register(channel); + } + + @Override + public ChannelFuture register(Channel channel, ChannelPromise promise) { + return next().register(channel, promise); + } +} diff --git a/common/src/common/net/channel/RecvByteBufAllocator.java b/common/src/common/net/channel/RecvByteBufAllocator.java new file mode 100644 index 0000000..f90ff3f --- /dev/null +++ b/common/src/common/net/channel/RecvByteBufAllocator.java @@ -0,0 +1,54 @@ +/* + * Copyright 2012 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ +package common.net.channel; + +import common.net.buffer.ByteBuf; +import common.net.buffer.ByteBufAllocator; + +/** + * Allocates a new receive buffer whose capacity is probably large enough to read all inbound data and small enough + * not to waste its space. + */ +public interface RecvByteBufAllocator { + + /** + * Creates a new handle. The handle provides the actual operations and keeps the internal information which is + * required for predicting an optimal buffer capacity. + */ + Handle newHandle(); + + interface Handle { + /** + * Creates a new receive buffer whose capacity is probably large enough to read all inbound data and small + * enough not to waste its space. + */ + ByteBuf allocate(ByteBufAllocator alloc); + + /** + * Similar to {@link #allocate(ByteBufAllocator)} except that it does not allocate anything but just tells the + * capacity. + */ + int guess(); + + /** + * Records the the actual number of read bytes in the previous read operation so that the allocator allocates + * the buffer with potentially more correct capacity. + * + * @param actualReadBytes the actual number of read bytes in the previous read operation + */ + void record(int actualReadBytes); + } +} diff --git a/common/src/common/net/channel/ServerChannel.java b/common/src/common/net/channel/ServerChannel.java new file mode 100644 index 0000000..7dedcaa --- /dev/null +++ b/common/src/common/net/channel/ServerChannel.java @@ -0,0 +1,25 @@ +/* + * Copyright 2012 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ +package common.net.channel; + +/** + * A {@link Channel} that accepts an incoming connection attempt and creates + * its child {@link Channel}s by accepting them. {@link ServerSocketChannel} is + * a good example. + */ +public interface ServerChannel extends Channel { + // This is a tag interface. +} diff --git a/common/src/common/net/channel/SimpleChannelInboundHandler.java b/common/src/common/net/channel/SimpleChannelInboundHandler.java new file mode 100644 index 0000000..68b003e --- /dev/null +++ b/common/src/common/net/channel/SimpleChannelInboundHandler.java @@ -0,0 +1,129 @@ +/* + * Copyright 2013 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ +package common.net.channel; + +import common.net.util.ReferenceCountUtil; +import common.net.util.internal.TypeParameterMatcher; + +/** + * {@link ChannelInboundHandlerAdapter} which allows to explicit only handle a specific type of messages. + * + * For example here is an implementation which only handle {@link String} messages. + * + *
+ *     public class StringHandler extends
+ *             {@link SimpleChannelInboundHandler}<{@link String}> {
+ *
+ *         {@code @Override}
+ *         protected void channelRead0({@link ChannelHandlerContext} ctx, {@link String} message)
+ *                 throws {@link Exception} {
+ *             System.out.println(message);
+ *         }
+ *     }
+ * 
+ * + * Be aware that depending of the constructor parameters it will release all handled messages by pass them to + * {@link ReferenceCountUtil#release(Object)}. In this case you may need to use + * {@link ReferenceCountUtil#retain(Object)} if you pass the object to the next handler in the {@link ChannelPipeline}. + * + *

Forward compatibility notice

+ *

+ * Please keep in mind that {@link #channelRead0(ChannelHandlerContext, I)} will be renamed to + * {@code messageReceived(ChannelHandlerContext, I)} in 5.0. + *

+ */ +public abstract class SimpleChannelInboundHandler extends ChannelInboundHandlerAdapter { + + private final TypeParameterMatcher matcher; + private final boolean autoRelease; + + /** + * @see {@link #SimpleChannelInboundHandler(boolean)} with {@code true} as boolean parameter. + */ + protected SimpleChannelInboundHandler() { + this(true); + } + + /** + * Create a new instance which will try to detect the types to match out of the type parameter of the class. + * + * @param autoRelease {@code true} if handled messages should be released automatically by pass them to + * {@link ReferenceCountUtil#release(Object)}. + */ + protected SimpleChannelInboundHandler(boolean autoRelease) { + matcher = TypeParameterMatcher.find(this, SimpleChannelInboundHandler.class, "I"); + this.autoRelease = autoRelease; + } + + /** + * @see {@link #SimpleChannelInboundHandler(Class, boolean)} with {@code true} as boolean value. + */ + protected SimpleChannelInboundHandler(Class inboundMessageType) { + this(inboundMessageType, true); + } + + /** + * Create a new instance + * + * @param inboundMessageType The type of messages to match + * @param autoRelease {@code true} if handled messages should be released automatically by pass them to + * {@link ReferenceCountUtil#release(Object)}. + */ + protected SimpleChannelInboundHandler(Class inboundMessageType, boolean autoRelease) { + matcher = TypeParameterMatcher.get(inboundMessageType); + this.autoRelease = autoRelease; + } + + /** + * Returns {@code true} if the given message should be handled. If {@code false} it will be passed to the next + * {@link ChannelInboundHandler} in the {@link ChannelPipeline}. + */ + public boolean acceptInboundMessage(Object msg) throws Exception { + return matcher.match(msg); + } + + @Override + public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { + boolean release = true; + try { + if (acceptInboundMessage(msg)) { + + I imsg = (I) msg; + channelRead0(ctx, imsg); + } else { + release = false; + ctx.fireChannelRead(msg); + } + } finally { + if (autoRelease && release) { + ReferenceCountUtil.release(msg); + } + } + } + + /** + * Please keep in mind that this method will be renamed to + * {@code messageReceived(ChannelHandlerContext, I)} in 5.0. + * + * Is called for each message of type {@link I}. + * + * @param ctx the {@link ChannelHandlerContext} which this {@link SimpleChannelInboundHandler} + * belongs to + * @param msg the message to handle + * @throws Exception is thrown if an error occurred + */ + protected abstract void channelRead0(ChannelHandlerContext ctx, I msg) throws Exception; +} diff --git a/common/src/common/net/channel/SingleThreadEventLoop.java b/common/src/common/net/channel/SingleThreadEventLoop.java new file mode 100644 index 0000000..ed45956 --- /dev/null +++ b/common/src/common/net/channel/SingleThreadEventLoop.java @@ -0,0 +1,72 @@ +/* + * Copyright 2012 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ +package common.net.channel; + +import java.util.concurrent.ThreadFactory; + +import common.net.util.concurrent.SingleThreadEventExecutor; + +/** + * Abstract base class for {@link EventLoop}'s that execute all its submitted tasks in a single thread. + * + */ +public abstract class SingleThreadEventLoop extends SingleThreadEventExecutor implements EventLoop { + + /** + * @see {@link SingleThreadEventExecutor#SingleThreadEventExecutor(EventExecutorGroup, ThreadFactory, boolean)} + */ + protected SingleThreadEventLoop(EventLoopGroup parent, ThreadFactory threadFactory, boolean addTaskWakesUp) { + super(parent, threadFactory, addTaskWakesUp); + } + + @Override + public EventLoopGroup parent() { + return (EventLoopGroup) super.parent(); + } + + @Override + public EventLoop next() { + return (EventLoop) super.next(); + } + + @Override + public ChannelFuture register(Channel channel) { + return register(channel, new DefaultChannelPromise(channel, this)); + } + + @Override + public ChannelFuture register(final Channel channel, final ChannelPromise promise) { + if (channel == null) { + throw new NullPointerException("channel"); + } + if (promise == null) { + throw new NullPointerException("promise"); + } + + channel.unsafe().register(this, promise); + return promise; + } + + @Override + protected boolean wakesUpForTask(Runnable task) { + return !(task instanceof NonWakeupRunnable); + } + + /** + * Marker interface for {@linkRunnable} that will not trigger an {@link #wakeup(boolean)} in all cases. + */ + interface NonWakeupRunnable extends Runnable { } +} diff --git a/common/src/common/net/channel/SucceededChannelFuture.java b/common/src/common/net/channel/SucceededChannelFuture.java new file mode 100644 index 0000000..f2fafea --- /dev/null +++ b/common/src/common/net/channel/SucceededChannelFuture.java @@ -0,0 +1,45 @@ +/* + * Copyright 2012 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ +package common.net.channel; + +import common.net.util.concurrent.EventExecutor; + +/** + * The {@link CompleteChannelFuture} which is succeeded already. It is + * recommended to use {@link Channel#newSucceededFuture()} instead of + * calling the constructor of this future. + */ +final class SucceededChannelFuture extends CompleteChannelFuture { + + /** + * Creates a new instance. + * + * @param channel the {@link Channel} associated with this future + */ + SucceededChannelFuture(Channel channel, EventExecutor executor) { + super(channel, executor); + } + + @Override + public Throwable cause() { + return null; + } + + @Override + public boolean isSuccess() { + return true; + } +} diff --git a/common/src/common/net/channel/VoidChannelPromise.java b/common/src/common/net/channel/VoidChannelPromise.java new file mode 100644 index 0000000..1fcbb12 --- /dev/null +++ b/common/src/common/net/channel/VoidChannelPromise.java @@ -0,0 +1,205 @@ +/* + * Copyright 2012 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ +package common.net.channel; + +import java.util.concurrent.TimeUnit; + +import common.net.util.concurrent.AbstractFuture; +import common.net.util.concurrent.Future; +import common.net.util.concurrent.GenericFutureListener; + +final class VoidChannelPromise extends AbstractFuture implements ChannelPromise { + + private final Channel channel; + private final boolean fireException; + + /** + * Creates a new instance. + * + * @param channel the {@link Channel} associated with this future + */ + VoidChannelPromise(Channel channel, boolean fireException) { + if (channel == null) { + throw new NullPointerException("channel"); + } + this.channel = channel; + this.fireException = fireException; + } + + @Override + public VoidChannelPromise addListener(GenericFutureListener> listener) { + fail(); + return this; + } + + @Override + public VoidChannelPromise addListeners(GenericFutureListener>... listeners) { + fail(); + return this; + } + + @Override + public VoidChannelPromise removeListener(GenericFutureListener> listener) { + // NOOP + return this; + } + + @Override + public VoidChannelPromise removeListeners(GenericFutureListener>... listeners) { + // NOOP + return this; + } + + @Override + public VoidChannelPromise await() throws InterruptedException { + if (Thread.interrupted()) { + throw new InterruptedException(); + } + return this; + } + + @Override + public boolean await(long timeout, TimeUnit unit) { + fail(); + return false; + } + + @Override + public boolean await(long timeoutMillis) { + fail(); + return false; + } + + @Override + public VoidChannelPromise awaitUninterruptibly() { + fail(); + return this; + } + + @Override + public boolean awaitUninterruptibly(long timeout, TimeUnit unit) { + fail(); + return false; + } + + @Override + public boolean awaitUninterruptibly(long timeoutMillis) { + fail(); + return false; + } + + @Override + public Channel channel() { + return channel; + } + + @Override + public boolean isDone() { + return false; + } + + @Override + public boolean isSuccess() { + return false; + } + + @Override + public boolean setUncancellable() { + return true; + } + + @Override + public boolean isCancellable() { + return false; + } + + @Override + public boolean isCancelled() { + return false; + } + + @Override + public Throwable cause() { + return null; + } + + @Override + public VoidChannelPromise sync() { + fail(); + return this; + } + + @Override + public VoidChannelPromise syncUninterruptibly() { + fail(); + return this; + } + @Override + public VoidChannelPromise setFailure(Throwable cause) { + fireException(cause); + return this; + } + + @Override + public VoidChannelPromise setSuccess() { + return this; + } + + @Override + public boolean tryFailure(Throwable cause) { + fireException(cause); + return false; + } + + @Override + public boolean cancel(boolean mayInterruptIfRunning) { + return false; + } + + @Override + public boolean trySuccess() { + return false; + } + + private static void fail() { + throw new IllegalStateException("void future"); + } + + @Override + public VoidChannelPromise setSuccess(Void result) { + return this; + } + + @Override + public boolean trySuccess(Void result) { + return false; + } + + @Override + public Void getNow() { + return null; + } + + private void fireException(Throwable cause) { + // Only fire the exception if the channel is open and registered + // if not the pipeline is not setup and so it would hit the tail + // of the pipeline. + // See https://github.com/netty/netty/issues/1517 + if (fireException && channel.isRegistered()) { + channel.pipeline().fireExceptionCaught(cause); + } + } +} diff --git a/common/src/common/net/channel/local/LocalAddress.java b/common/src/common/net/channel/local/LocalAddress.java new file mode 100644 index 0000000..95f6e43 --- /dev/null +++ b/common/src/common/net/channel/local/LocalAddress.java @@ -0,0 +1,94 @@ +/* + * Copyright 2012 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ +package common.net.channel.local; + +import java.net.SocketAddress; + +import common.net.channel.Channel; + +/** + * An endpoint in the local transport. Each endpoint is identified by a unique + * case-insensitive string. + */ +public final class LocalAddress extends SocketAddress implements Comparable { + + private static final long serialVersionUID = 4644331421130916435L; + + public static final LocalAddress ANY = new LocalAddress("ANY"); + + private final String id; + private final String strVal; + + /** + * Creates a new ephemeral port based on the ID of the specified channel. + * Note that we prepend an upper-case character so that it never conflicts with + * the addresses created by a user, which are always lower-cased on construction time. + */ + LocalAddress(Channel channel) { + StringBuilder buf = new StringBuilder(16); + buf.append("local:E"); + buf.append(Long.toHexString(channel.hashCode() & 0xFFFFFFFFL | 0x100000000L)); + buf.setCharAt(7, ':'); + id = buf.substring(6); + strVal = buf.toString(); + } + + /** + * Creates a new instance with the specified ID. + */ + public LocalAddress(String id) { + if (id == null) { + throw new NullPointerException("id"); + } + id = id.trim().toLowerCase(); + if (id.isEmpty()) { + throw new IllegalArgumentException("empty id"); + } + this.id = id; + strVal = "local:" + id; + } + + /** + * Returns the ID of this address. + */ + public String id() { + return id; + } + + @Override + public int hashCode() { + return id.hashCode(); + } + + @Override + public boolean equals(Object o) { + if (!(o instanceof LocalAddress)) { + return false; + } + + return id.equals(((LocalAddress) o).id); + } + + @Override + public int compareTo(LocalAddress o) { + return id.compareTo(o.id); + } + + @Override + public String toString() { + return strVal; + } +} diff --git a/common/src/common/net/channel/local/LocalChannel.java b/common/src/common/net/channel/local/LocalChannel.java new file mode 100644 index 0000000..c5590c9 --- /dev/null +++ b/common/src/common/net/channel/local/LocalChannel.java @@ -0,0 +1,383 @@ +/* + * Copyright 2012 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ +package common.net.channel.local; + +import java.net.SocketAddress; +import java.nio.channels.AlreadyConnectedException; +import java.nio.channels.ClosedChannelException; +import java.nio.channels.ConnectionPendingException; +import java.nio.channels.NotYetConnectedException; +import java.util.ArrayDeque; +import java.util.Collections; +import java.util.Queue; + +import common.net.channel.AbstractChannel; +import common.net.channel.Channel; +import common.net.channel.ChannelConfig; +import common.net.channel.ChannelException; +import common.net.channel.ChannelMetadata; +import common.net.channel.ChannelOutboundBuffer; +import common.net.channel.ChannelPipeline; +import common.net.channel.ChannelPromise; +import common.net.channel.DefaultChannelConfig; +import common.net.channel.EventLoop; +import common.net.channel.SingleThreadEventLoop; +import common.net.util.ReferenceCountUtil; +import common.net.util.concurrent.SingleThreadEventExecutor; +import common.net.util.internal.InternalThreadLocalMap; + +/** + * A {@link Channel} for the local transport. + */ +public class LocalChannel extends AbstractChannel { + + private static final ChannelMetadata METADATA = new ChannelMetadata(false); + + private static final int MAX_READER_STACK_DEPTH = 8; + + private final ChannelConfig config = new DefaultChannelConfig(this); + private final Queue inboundBuffer = new ArrayDeque(); + private final Runnable readTask = new Runnable() { + @Override + public void run() { + ChannelPipeline pipeline = pipeline(); + for (;;) { + Object m = inboundBuffer.poll(); + if (m == null) { + break; + } + pipeline.fireChannelRead(m); + } + pipeline.fireChannelReadComplete(); + } + }; + + private final Runnable shutdownHook = new Runnable() { + @Override + public void run() { + unsafe().close(unsafe().voidPromise()); + } + }; + + private volatile int state; // 0 - open, 1 - bound, 2 - connected, 3 - closed + private volatile LocalChannel peer; + private volatile LocalAddress localAddress; + private volatile LocalAddress remoteAddress; + private volatile ChannelPromise connectPromise; + private volatile boolean readInProgress; + private volatile boolean registerInProgress; + + public LocalChannel() { + super(null); + } + + LocalChannel(LocalServerChannel parent, LocalChannel peer) { + super(parent); + this.peer = peer; + localAddress = parent.localAddress(); + remoteAddress = peer.localAddress(); + } + + @Override + public ChannelMetadata metadata() { + return METADATA; + } + + @Override + public ChannelConfig config() { + return config; + } + + @Override + public LocalServerChannel parent() { + return (LocalServerChannel) super.parent(); + } + + @Override + public LocalAddress localAddress() { + return (LocalAddress) super.localAddress(); + } + + @Override + public LocalAddress remoteAddress() { + return (LocalAddress) super.remoteAddress(); + } + + @Override + public boolean isOpen() { + return state < 3; + } + + @Override + public boolean isActive() { + return state == 2; + } + + @Override + protected AbstractUnsafe newUnsafe() { + return new LocalUnsafe(); + } + + @Override + protected boolean isCompatible(EventLoop loop) { + return loop instanceof SingleThreadEventLoop; + } + + @Override + protected SocketAddress localAddress0() { + return localAddress; + } + + @Override + protected SocketAddress remoteAddress0() { + return remoteAddress; + } + + @Override + protected void doRegister() throws Exception { + // Check if both peer and parent are non-null because this channel was created by a LocalServerChannel. + // This is needed as a peer may not be null also if a LocalChannel was connected before and + // deregistered / registered later again. + // + // See https://github.com/netty/netty/issues/2400 + if (peer != null && parent() != null) { + // Store the peer in a local variable as it may be set to null if doClose() is called. + // Because of this we also set registerInProgress to true as we check for this in doClose() and make sure + // we delay the fireChannelInactive() to be fired after the fireChannelActive() and so keep the correct + // order of events. + // + // See https://github.com/netty/netty/issues/2144 + final LocalChannel peer = this.peer; + registerInProgress = true; + state = 2; + + peer.remoteAddress = parent().localAddress(); + peer.state = 2; + + // Always call peer.eventLoop().execute() even if peer.eventLoop().inEventLoop() is true. + // This ensures that if both channels are on the same event loop, the peer's channelActive + // event is triggered *after* this channel's channelRegistered event, so that this channel's + // pipeline is fully initialized by ChannelInitializer before any channelRead events. + peer.eventLoop().execute(new Runnable() { + @Override + public void run() { + registerInProgress = false; + peer.pipeline().fireChannelActive(); + peer.connectPromise.setSuccess(); + } + }); + } + ((SingleThreadEventExecutor) eventLoop()).addShutdownHook(shutdownHook); + } + + @Override + protected void doBind(SocketAddress localAddress) throws Exception { + this.localAddress = + LocalChannelRegistry.register(this, this.localAddress, + localAddress); + state = 1; + } + + @Override + protected void doDisconnect() throws Exception { + doClose(); + } + + @Override + protected void doClose() throws Exception { + if (state <= 2) { + // Update all internal state before the closeFuture is notified. + if (localAddress != null) { + if (parent() == null) { + LocalChannelRegistry.unregister(localAddress); + } + localAddress = null; + } + state = 3; + } + + final LocalChannel peer = this.peer; + if (peer != null && peer.isActive()) { + // Need to execute the close in the correct EventLoop + // See https://github.com/netty/netty/issues/1777 + EventLoop eventLoop = peer.eventLoop(); + + // Also check if the registration was not done yet. In this case we submit the close to the EventLoop + // to make sure it is run after the registration completes. + // + // See https://github.com/netty/netty/issues/2144 + if (eventLoop.inEventLoop() && !registerInProgress) { + peer.unsafe().close(unsafe().voidPromise()); + } else { + peer.eventLoop().execute(new Runnable() { + @Override + public void run() { + peer.unsafe().close(unsafe().voidPromise()); + } + }); + } + this.peer = null; + } + } + + @Override + protected void doDeregister() throws Exception { + // Just remove the shutdownHook as this Channel may be closed later or registered to another EventLoop + ((SingleThreadEventExecutor) eventLoop()).removeShutdownHook(shutdownHook); + } + + @Override + protected void doBeginRead() throws Exception { + if (readInProgress) { + return; + } + + ChannelPipeline pipeline = pipeline(); + Queue inboundBuffer = this.inboundBuffer; + if (inboundBuffer.isEmpty()) { + readInProgress = true; + return; + } + + final InternalThreadLocalMap threadLocals = InternalThreadLocalMap.get(); + final Integer stackDepth = threadLocals.localChannelReaderStackDepth(); + if (stackDepth < MAX_READER_STACK_DEPTH) { + threadLocals.setLocalChannelReaderStackDepth(stackDepth + 1); + try { + for (;;) { + Object received = inboundBuffer.poll(); + if (received == null) { + break; + } + pipeline.fireChannelRead(received); + } + pipeline.fireChannelReadComplete(); + } finally { + threadLocals.setLocalChannelReaderStackDepth(stackDepth); + } + } else { + eventLoop().execute(readTask); + } + } + + @Override + protected void doWrite(ChannelOutboundBuffer in) throws Exception { + if (state < 2) { + throw new NotYetConnectedException(); + } + if (state > 2) { + throw new ClosedChannelException(); + } + + final LocalChannel peer = this.peer; + final ChannelPipeline peerPipeline = peer.pipeline(); + final EventLoop peerLoop = peer.eventLoop(); + + if (peerLoop == eventLoop()) { + for (;;) { + Object msg = in.current(); + if (msg == null) { + break; + } + peer.inboundBuffer.add(msg); + ReferenceCountUtil.retain(msg); + in.remove(); + } + finishPeerRead(peer, peerPipeline); + } else { + // Use a copy because the original msgs will be recycled by AbstractChannel. + final Object[] msgsCopy = new Object[in.size()]; + for (int i = 0; i < msgsCopy.length; i ++) { + msgsCopy[i] = ReferenceCountUtil.retain(in.current()); + in.remove(); + } + + peerLoop.execute(new Runnable() { + @Override + public void run() { + Collections.addAll(peer.inboundBuffer, msgsCopy); + finishPeerRead(peer, peerPipeline); + } + }); + } + } + + private static void finishPeerRead(LocalChannel peer, ChannelPipeline peerPipeline) { + if (peer.readInProgress) { + peer.readInProgress = false; + for (;;) { + Object received = peer.inboundBuffer.poll(); + if (received == null) { + break; + } + peerPipeline.fireChannelRead(received); + } + peerPipeline.fireChannelReadComplete(); + } + } + + private class LocalUnsafe extends AbstractUnsafe { + + @Override + public void connect(final SocketAddress remoteAddress, + SocketAddress localAddress, final ChannelPromise promise) { + if (!promise.setUncancellable() || !ensureOpen(promise)) { + return; + } + + if (state == 2) { + Exception cause = new AlreadyConnectedException(); + safeSetFailure(promise, cause); + pipeline().fireExceptionCaught(cause); + return; + } + + if (connectPromise != null) { + throw new ConnectionPendingException(); + } + + connectPromise = promise; + + if (state != 1) { + // Not bound yet and no localAddress specified - get one. + if (localAddress == null) { + localAddress = new LocalAddress(LocalChannel.this); + } + } + + if (localAddress != null) { + try { + doBind(localAddress); + } catch (Throwable t) { + safeSetFailure(promise, t); + close(voidPromise()); + return; + } + } + + Channel boundChannel = LocalChannelRegistry.get(remoteAddress); + if (!(boundChannel instanceof LocalServerChannel)) { + Exception cause = new ChannelException("connection refused"); + safeSetFailure(promise, cause); + close(voidPromise()); + return; + } + + LocalServerChannel serverChannel = (LocalServerChannel) boundChannel; + peer = serverChannel.serve(LocalChannel.this); + } + } +} diff --git a/common/src/common/net/channel/local/LocalChannelRegistry.java b/common/src/common/net/channel/local/LocalChannelRegistry.java new file mode 100644 index 0000000..6af42eb --- /dev/null +++ b/common/src/common/net/channel/local/LocalChannelRegistry.java @@ -0,0 +1,62 @@ +/* + * Copyright 2012 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ +package common.net.channel.local; + +import java.net.SocketAddress; +import java.util.concurrent.ConcurrentMap; + +import common.net.channel.Channel; +import common.net.channel.ChannelException; +import common.net.util.internal.PlatformDependent; +import common.net.util.internal.StringUtil; + +final class LocalChannelRegistry { + + private static final ConcurrentMap boundChannels = PlatformDependent.newConcurrentHashMap(); + + static LocalAddress register( + Channel channel, LocalAddress oldLocalAddress, SocketAddress localAddress) { + if (oldLocalAddress != null) { + throw new ChannelException("already bound"); + } + if (!(localAddress instanceof LocalAddress)) { + throw new ChannelException("unsupported address type: " + StringUtil.simpleClassName(localAddress)); + } + + LocalAddress addr = (LocalAddress) localAddress; + if (LocalAddress.ANY.equals(addr)) { + addr = new LocalAddress(channel); + } + + Channel boundChannel = boundChannels.putIfAbsent(addr, channel); + if (boundChannel != null) { + throw new ChannelException("address already in use by: " + boundChannel); + } + return addr; + } + + static Channel get(SocketAddress localAddress) { + return boundChannels.get(localAddress); + } + + static void unregister(LocalAddress localAddress) { + boundChannels.remove(localAddress); + } + + private LocalChannelRegistry() { + // Unused + } +} diff --git a/common/src/common/net/channel/local/LocalEventLoop.java b/common/src/common/net/channel/local/LocalEventLoop.java new file mode 100644 index 0000000..4bf1b89 --- /dev/null +++ b/common/src/common/net/channel/local/LocalEventLoop.java @@ -0,0 +1,42 @@ +/* + * Copyright 2012 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ +package common.net.channel.local; + +import java.util.concurrent.ThreadFactory; + +import common.net.channel.SingleThreadEventLoop; + +final class LocalEventLoop extends SingleThreadEventLoop { + + LocalEventLoop(LocalEventLoopGroup parent, ThreadFactory threadFactory) { + super(parent, threadFactory, true); + } + + @Override + protected void run() { + for (;;) { + Runnable task = takeTask(); + if (task != null) { + task.run(); + updateLastExecutionTime(); + } + + if (confirmShutdown()) { + break; + } + } + } +} diff --git a/common/src/common/net/channel/local/LocalEventLoopGroup.java b/common/src/common/net/channel/local/LocalEventLoopGroup.java new file mode 100644 index 0000000..7f58c98 --- /dev/null +++ b/common/src/common/net/channel/local/LocalEventLoopGroup.java @@ -0,0 +1,59 @@ +/* + * Copyright 2012 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ +package common.net.channel.local; + +import java.util.concurrent.ThreadFactory; + +import common.net.channel.MultithreadEventLoopGroup; +import common.net.util.concurrent.EventExecutor; + +/** + * {@link MultithreadEventLoopGroup} which must be used for the local transport. + */ +public class LocalEventLoopGroup extends MultithreadEventLoopGroup { + + /** + * Create a new instance with the default number of threads. + */ + public LocalEventLoopGroup() { + this(0); + } + + /** + * Create a new instance + * + * @param nThreads the number of threads to use + */ + public LocalEventLoopGroup(int nThreads) { + this(nThreads, null); + } + + /** + * Create a new instance + * + * @param nThreads the number of threads to use + * @param threadFactory the {@link ThreadFactory} or {@code null} to use the default + */ + public LocalEventLoopGroup(int nThreads, ThreadFactory threadFactory) { + super(nThreads, threadFactory); + } + + @Override + protected EventExecutor newChild( + ThreadFactory threadFactory, Object... args) throws Exception { + return new LocalEventLoop(this, threadFactory); + } +} diff --git a/common/src/common/net/channel/local/LocalServerChannel.java b/common/src/common/net/channel/local/LocalServerChannel.java new file mode 100644 index 0000000..557f526 --- /dev/null +++ b/common/src/common/net/channel/local/LocalServerChannel.java @@ -0,0 +1,164 @@ +/* + * Copyright 2012 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ +package common.net.channel.local; + +import java.net.SocketAddress; +import java.util.ArrayDeque; +import java.util.Queue; + +import common.net.channel.AbstractServerChannel; +import common.net.channel.ChannelConfig; +import common.net.channel.ChannelPipeline; +import common.net.channel.DefaultChannelConfig; +import common.net.channel.EventLoop; +import common.net.channel.SingleThreadEventLoop; +import common.net.util.concurrent.SingleThreadEventExecutor; + +/** + * A {@link ServerChannel} for the local transport which allows in VM communication. + */ +public class LocalServerChannel extends AbstractServerChannel { + + private final ChannelConfig config = new DefaultChannelConfig(this); + private final Queue inboundBuffer = new ArrayDeque(); + private final Runnable shutdownHook = new Runnable() { + @Override + public void run() { + unsafe().close(unsafe().voidPromise()); + } + }; + + private volatile int state; // 0 - open, 1 - active, 2 - closed + private volatile LocalAddress localAddress; + private volatile boolean acceptInProgress; + + @Override + public ChannelConfig config() { + return config; + } + + @Override + public LocalAddress localAddress() { + return (LocalAddress) super.localAddress(); + } + + @Override + public LocalAddress remoteAddress() { + return (LocalAddress) super.remoteAddress(); + } + + @Override + public boolean isOpen() { + return state < 2; + } + + @Override + public boolean isActive() { + return state == 1; + } + + @Override + protected boolean isCompatible(EventLoop loop) { + return loop instanceof SingleThreadEventLoop; + } + + @Override + protected SocketAddress localAddress0() { + return localAddress; + } + + @Override + protected void doRegister() throws Exception { + ((SingleThreadEventExecutor) eventLoop()).addShutdownHook(shutdownHook); + } + + @Override + protected void doBind(SocketAddress localAddress) throws Exception { + this.localAddress = LocalChannelRegistry.register(this, this.localAddress, localAddress); + state = 1; + } + + @Override + protected void doClose() throws Exception { + if (state <= 1) { + // Update all internal state before the closeFuture is notified. + if (localAddress != null) { + LocalChannelRegistry.unregister(localAddress); + localAddress = null; + } + state = 2; + } + } + + @Override + protected void doDeregister() throws Exception { + ((SingleThreadEventExecutor) eventLoop()).removeShutdownHook(shutdownHook); + } + + @Override + protected void doBeginRead() throws Exception { + if (acceptInProgress) { + return; + } + + Queue inboundBuffer = this.inboundBuffer; + if (inboundBuffer.isEmpty()) { + acceptInProgress = true; + return; + } + + ChannelPipeline pipeline = pipeline(); + for (;;) { + Object m = inboundBuffer.poll(); + if (m == null) { + break; + } + pipeline.fireChannelRead(m); + } + pipeline.fireChannelReadComplete(); + } + + LocalChannel serve(final LocalChannel peer) { + final LocalChannel child = new LocalChannel(this, peer); + if (eventLoop().inEventLoop()) { + serve0(child); + } else { + eventLoop().execute(new Runnable() { + @Override + public void run() { + serve0(child); + } + }); + } + return child; + } + + private void serve0(final LocalChannel child) { + inboundBuffer.add(child); + if (acceptInProgress) { + acceptInProgress = false; + ChannelPipeline pipeline = pipeline(); + for (;;) { + Object m = inboundBuffer.poll(); + if (m == null) { + break; + } + pipeline.fireChannelRead(m); + } + pipeline.fireChannelReadComplete(); + } + } +} diff --git a/common/src/common/net/channel/nio/AbstractNioByteChannel.java b/common/src/common/net/channel/nio/AbstractNioByteChannel.java new file mode 100644 index 0000000..ac4cc89 --- /dev/null +++ b/common/src/common/net/channel/nio/AbstractNioByteChannel.java @@ -0,0 +1,347 @@ +/* + * Copyright 2012 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ +package common.net.channel.nio; + +import java.io.IOException; +import java.nio.channels.SelectableChannel; +import java.nio.channels.SelectionKey; + +import common.net.buffer.ByteBuf; +import common.net.buffer.ByteBufAllocator; +import common.net.channel.Channel; +import common.net.channel.ChannelConfig; +import common.net.channel.ChannelOption; +import common.net.channel.ChannelOutboundBuffer; +import common.net.channel.ChannelPipeline; +import common.net.channel.RecvByteBufAllocator; +import common.net.channel.socket.ChannelInputShutdownEvent; +import common.net.util.internal.StringUtil; + +/** + * {@link AbstractNioChannel} base class for {@link Channel}s that operate on bytes. + */ +public abstract class AbstractNioByteChannel extends AbstractNioChannel { + + private static final String EXPECTED_TYPES = + " (expected: " + StringUtil.simpleClassName(ByteBuf.class) + ')'; // ", " + +// StringUtil.simpleClassName(FileRegion.class) + ')'; + + private Runnable flushTask; + + /** + * Create a new instance + * + * @param parent the parent {@link Channel} by which this instance was created. May be {@code null} + * @param ch the underlying {@link SelectableChannel} on which it operates + */ + protected AbstractNioByteChannel(Channel parent, SelectableChannel ch) { + super(parent, ch, SelectionKey.OP_READ); + } + + @Override + protected AbstractNioUnsafe newUnsafe() { + return new NioByteUnsafe(); + } + + private final class NioByteUnsafe extends AbstractNioUnsafe { + private RecvByteBufAllocator.Handle allocHandle; + + private void closeOnRead(ChannelPipeline pipeline) { + SelectionKey key = selectionKey(); + setInputShutdown(); + if (isOpen()) { + if (Boolean.TRUE.equals(config().getOption(ChannelOption.ALLOW_HALF_CLOSURE))) { + key.interestOps(key.interestOps() & ~readInterestOp); + pipeline.fireUserEventTriggered(ChannelInputShutdownEvent.INSTANCE); + } else { + close(voidPromise()); + } + } + } + + private void handleReadException(ChannelPipeline pipeline, + ByteBuf byteBuf, Throwable cause, boolean close) { + if (byteBuf != null) { + if (byteBuf.isReadable()) { + setReadPending(false); + pipeline.fireChannelRead(byteBuf); + } else { + byteBuf.release(); + } + } + pipeline.fireChannelReadComplete(); + pipeline.fireExceptionCaught(cause); + if (close || cause instanceof IOException) { + closeOnRead(pipeline); + } + } + + @Override + public void read() { + final ChannelConfig config = config(); + if (!config.isAutoRead() && !isReadPending()) { + // ChannelConfig.setAutoRead(false) was called in the meantime + removeReadOp(); + return; + } + + final ChannelPipeline pipeline = pipeline(); + final ByteBufAllocator allocator = config.getAllocator(); + final int maxMessagesPerRead = config.getMaxMessagesPerRead(); + RecvByteBufAllocator.Handle allocHandle = this.allocHandle; + if (allocHandle == null) { + this.allocHandle = allocHandle = config.getRecvByteBufAllocator().newHandle(); + } + + ByteBuf byteBuf = null; + int messages = 0; + boolean close = false; + try { + int totalReadAmount = 0; + boolean readPendingReset = false; + do { + byteBuf = allocHandle.allocate(allocator); + int writable = byteBuf.writableBytes(); + int localReadAmount = doReadBytes(byteBuf); + if (localReadAmount <= 0) { + // not was read release the buffer + byteBuf.release(); + close = localReadAmount < 0; + break; + } + if (!readPendingReset) { + readPendingReset = true; + setReadPending(false); + } + pipeline.fireChannelRead(byteBuf); + byteBuf = null; + + if (totalReadAmount >= Integer.MAX_VALUE - localReadAmount) { + // Avoid overflow. + totalReadAmount = Integer.MAX_VALUE; + break; + } + + totalReadAmount += localReadAmount; + + // stop reading + if (!config.isAutoRead()) { + break; + } + + if (localReadAmount < writable) { + // Read less than what the buffer can hold, + // which might mean we drained the recv buffer completely. + break; + } + } while (++ messages < maxMessagesPerRead); + + pipeline.fireChannelReadComplete(); + allocHandle.record(totalReadAmount); + + if (close) { + closeOnRead(pipeline); + close = false; + } + } catch (Throwable t) { + handleReadException(pipeline, byteBuf, t, close); + } finally { + // Check if there is a readPending which was not processed yet. + // This could be for two reasons: + // * The user called Channel.read() or ChannelHandlerContext.read() in channelRead(...) method + // * The user called Channel.read() or ChannelHandlerContext.read() in channelReadComplete(...) method + // + // See https://github.com/netty/netty/issues/2254 + if (!config.isAutoRead() && !isReadPending()) { + removeReadOp(); + } + } + } + } + + @Override + protected void doWrite(ChannelOutboundBuffer in) throws Exception { + int writeSpinCount = -1; + + for (;;) { + Object msg = in.current(); + if (msg == null) { + // Wrote all messages. + clearOpWrite(); + break; + } + + if (msg instanceof ByteBuf) { + ByteBuf buf = (ByteBuf) msg; + int readableBytes = buf.readableBytes(); + if (readableBytes == 0) { + in.remove(); + continue; + } + + boolean setOpWrite = false; + boolean done = false; + long flushedAmount = 0; + if (writeSpinCount == -1) { + writeSpinCount = config().getWriteSpinCount(); + } + for (int i = writeSpinCount - 1; i >= 0; i --) { + int localFlushedAmount = doWriteBytes(buf); + if (localFlushedAmount == 0) { + setOpWrite = true; + break; + } + + flushedAmount += localFlushedAmount; + if (!buf.isReadable()) { + done = true; + break; + } + } + + in.progress(flushedAmount); + + if (done) { + in.remove(); + } else { + incompleteWrite(setOpWrite); + break; + } + } +// else if (msg instanceof FileRegion) { +// FileRegion region = (FileRegion) msg; +// boolean setOpWrite = false; +// boolean done = false; +// long flushedAmount = 0; +// if (writeSpinCount == -1) { +// writeSpinCount = config().getWriteSpinCount(); +// } +// for (int i = writeSpinCount - 1; i >= 0; i --) { +// long localFlushedAmount = doWriteFileRegion(region); +// if (localFlushedAmount == 0) { +// setOpWrite = true; +// break; +// } +// +// flushedAmount += localFlushedAmount; +// if (region.transfered() >= region.count()) { +// done = true; +// break; +// } +// } +// +// in.progress(flushedAmount); +// +// if (done) { +// in.remove(); +// } else { +// incompleteWrite(setOpWrite); +// break; +// } +// } + else { + // Should not reach here. + throw new Error(); + } + } + } + + @Override + protected final Object filterOutboundMessage(Object msg) { + if (msg instanceof ByteBuf) { + ByteBuf buf = (ByteBuf) msg; + if (buf.isDirect()) { + return msg; + } + + return newDirectBuffer(buf); + } + +// if (msg instanceof FileRegion) { +// return msg; +// } + + throw new UnsupportedOperationException( + "unsupported message type: " + StringUtil.simpleClassName(msg) + EXPECTED_TYPES); + } + + protected final void incompleteWrite(boolean setOpWrite) { + // Did not write completely. + if (setOpWrite) { + setOpWrite(); + } else { + // Schedule flush again later so other tasks can be picked up in the meantime + Runnable flushTask = this.flushTask; + if (flushTask == null) { + flushTask = this.flushTask = new Runnable() { + @Override + public void run() { + flush(); + } + }; + } + eventLoop().execute(flushTask); + } + } + + /** + * Write a {@link FileRegion} + * + * @param region the {@link FileRegion} from which the bytes should be written + * @return amount the amount of written bytes + */ +// protected abstract long doWriteFileRegion(FileRegion region) throws Exception; + + /** + * Read bytes into the given {@link ByteBuf} and return the amount. + */ + protected abstract int doReadBytes(ByteBuf buf) throws Exception; + + /** + * Write bytes form the given {@link ByteBuf} to the underlying {@link java.nio.channels.Channel}. + * @param buf the {@link ByteBuf} from which the bytes should be written + * @return amount the amount of written bytes + */ + protected abstract int doWriteBytes(ByteBuf buf) throws Exception; + + protected final void setOpWrite() { + final SelectionKey key = selectionKey(); + // Check first if the key is still valid as it may be canceled as part of the deregistration + // from the EventLoop + // See https://github.com/netty/netty/issues/2104 + if (!key.isValid()) { + return; + } + final int interestOps = key.interestOps(); + if ((interestOps & SelectionKey.OP_WRITE) == 0) { + key.interestOps(interestOps | SelectionKey.OP_WRITE); + } + } + + protected final void clearOpWrite() { + final SelectionKey key = selectionKey(); + // Check first if the key is still valid as it may be canceled as part of the deregistration + // from the EventLoop + // See https://github.com/netty/netty/issues/2104 + if (!key.isValid()) { + return; + } + final int interestOps = key.interestOps(); + if ((interestOps & SelectionKey.OP_WRITE) != 0) { + key.interestOps(interestOps & ~SelectionKey.OP_WRITE); + } + } +} diff --git a/common/src/common/net/channel/nio/AbstractNioChannel.java b/common/src/common/net/channel/nio/AbstractNioChannel.java new file mode 100644 index 0000000..214f1de --- /dev/null +++ b/common/src/common/net/channel/nio/AbstractNioChannel.java @@ -0,0 +1,460 @@ +/* + * Copyright 2012 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ +package common.net.channel.nio; + +import java.io.IOException; +import java.net.ConnectException; +import java.net.SocketAddress; +import java.nio.channels.CancelledKeyException; +import java.nio.channels.SelectableChannel; +import java.nio.channels.SelectionKey; +import java.util.concurrent.ScheduledFuture; +import java.util.concurrent.TimeUnit; + +import common.net.buffer.ByteBuf; +import common.net.buffer.ByteBufAllocator; +import common.net.buffer.ByteBufUtil; +import common.net.buffer.Unpooled; +import common.net.channel.AbstractChannel; +import common.net.channel.Channel; +import common.net.channel.ChannelException; +import common.net.channel.ChannelFuture; +import common.net.channel.ChannelFutureListener; +import common.net.channel.ChannelPromise; +import common.net.channel.ConnectTimeoutException; +import common.net.channel.EventLoop; +import common.net.util.ReferenceCountUtil; +import common.net.util.ReferenceCounted; +import common.net.util.internal.OneTimeTask; +import common.net.util.internal.logging.InternalLogger; +import common.net.util.internal.logging.InternalLoggerFactory; + +/** + * Abstract base class for {@link Channel} implementations which use a Selector based approach. + */ +public abstract class AbstractNioChannel extends AbstractChannel { + + private static final InternalLogger logger = + InternalLoggerFactory.getInstance(AbstractNioChannel.class); + + private final SelectableChannel ch; + protected final int readInterestOp; + volatile SelectionKey selectionKey; + private volatile boolean inputShutdown; + private volatile boolean readPending; + + /** + * The future of the current connection attempt. If not null, subsequent + * connection attempts will fail. + */ + private ChannelPromise connectPromise; + private ScheduledFuture connectTimeoutFuture; + private SocketAddress requestedRemoteAddress; + + /** + * Create a new instance + * + * @param parent the parent {@link Channel} by which this instance was created. May be {@code null} + * @param ch the underlying {@link SelectableChannel} on which it operates + * @param readInterestOp the ops to set to receive data from the {@link SelectableChannel} + */ + protected AbstractNioChannel(Channel parent, SelectableChannel ch, int readInterestOp) { + super(parent); + this.ch = ch; + this.readInterestOp = readInterestOp; + try { + ch.configureBlocking(false); + } catch (IOException e) { + try { + ch.close(); + } catch (IOException e2) { + if (logger.isWarnEnabled()) { + logger.warn( + "Failed to close a partially initialized socket.", e2); + } + } + + throw new ChannelException("Failed to enter non-blocking mode.", e); + } + } + + @Override + public boolean isOpen() { + return ch.isOpen(); + } + + @Override + public NioUnsafe unsafe() { + return (NioUnsafe) super.unsafe(); + } + + protected SelectableChannel javaChannel() { + return ch; + } + + @Override + public NioEventLoop eventLoop() { + return (NioEventLoop) super.eventLoop(); + } + + /** + * Return the current {@link SelectionKey} + */ + protected SelectionKey selectionKey() { + assert selectionKey != null; + return selectionKey; + } + + protected boolean isReadPending() { + return readPending; + } + + protected void setReadPending(boolean readPending) { + this.readPending = readPending; + } + + /** + * Return {@code true} if the input of this {@link Channel} is shutdown + */ + protected boolean isInputShutdown() { + return inputShutdown; + } + + /** + * Shutdown the input of this {@link Channel}. + */ + void setInputShutdown() { + inputShutdown = true; + } + + /** + * Special {@link Unsafe} sub-type which allows to access the underlying {@link SelectableChannel} + */ + public interface NioUnsafe extends Unsafe { + /** + * Return underlying {@link SelectableChannel} + */ + SelectableChannel ch(); + + /** + * Finish connect + */ + void finishConnect(); + + /** + * Read from underlying {@link SelectableChannel} + */ + void read(); + + void forceFlush(); + } + + protected abstract class AbstractNioUnsafe extends AbstractUnsafe implements NioUnsafe { + + protected final void removeReadOp() { + SelectionKey key = selectionKey(); + // Check first if the key is still valid as it may be canceled as part of the deregistration + // from the EventLoop + // See https://github.com/netty/netty/issues/2104 + if (!key.isValid()) { + return; + } + int interestOps = key.interestOps(); + if ((interestOps & readInterestOp) != 0) { + // only remove readInterestOp if needed + key.interestOps(interestOps & ~readInterestOp); + } + } + + @Override + public final SelectableChannel ch() { + return javaChannel(); + } + + @Override + public final void connect( + final SocketAddress remoteAddress, final SocketAddress localAddress, final ChannelPromise promise) { + if (!promise.setUncancellable() || !ensureOpen(promise)) { + return; + } + + try { + if (connectPromise != null) { + throw new IllegalStateException("connection attempt already made"); + } + + boolean wasActive = isActive(); + if (doConnect(remoteAddress, localAddress)) { + fulfillConnectPromise(promise, wasActive); + } else { + connectPromise = promise; + requestedRemoteAddress = remoteAddress; + + // Schedule connect timeout. + int connectTimeoutMillis = config().getConnectTimeoutMillis(); + if (connectTimeoutMillis > 0) { + connectTimeoutFuture = eventLoop().schedule(new OneTimeTask() { + @Override + public void run() { + ChannelPromise connectPromise = AbstractNioChannel.this.connectPromise; + ConnectTimeoutException cause = + new ConnectTimeoutException("connection timed out: " + remoteAddress); + if (connectPromise != null && connectPromise.tryFailure(cause)) { + close(voidPromise()); + } + } + }, connectTimeoutMillis, TimeUnit.MILLISECONDS); + } + + promise.addListener(new ChannelFutureListener() { + @Override + public void operationComplete(ChannelFuture future) throws Exception { + if (future.isCancelled()) { + if (connectTimeoutFuture != null) { + connectTimeoutFuture.cancel(false); + } + connectPromise = null; + close(voidPromise()); + } + } + }); + } + } catch (Throwable t) { + if (t instanceof ConnectException) { + Throwable newT = new ConnectException(t.getMessage() + ": " + remoteAddress); + newT.setStackTrace(t.getStackTrace()); + t = newT; + } + promise.tryFailure(t); + closeIfClosed(); + } + } + + private void fulfillConnectPromise(ChannelPromise promise, boolean wasActive) { + if (promise == null) { + // Closed via cancellation and the promise has been notified already. + return; + } + + // trySuccess() will return false if a user cancelled the connection attempt. + boolean promiseSet = promise.trySuccess(); + + // Regardless if the connection attempt was cancelled, channelActive() event should be triggered, + // because what happened is what happened. + if (!wasActive && isActive()) { + pipeline().fireChannelActive(); + } + + // If a user cancelled the connection attempt, close the channel, which is followed by channelInactive(). + if (!promiseSet) { + close(voidPromise()); + } + } + + private void fulfillConnectPromise(ChannelPromise promise, Throwable cause) { + if (promise == null) { + // Closed via cancellation and the promise has been notified already. + return; + } + + // Use tryFailure() instead of setFailure() to avoid the race against cancel(). + promise.tryFailure(cause); + closeIfClosed(); + } + + @Override + public final void finishConnect() { + // Note this method is invoked by the event loop only if the connection attempt was + // neither cancelled nor timed out. + + assert eventLoop().inEventLoop(); + + try { + boolean wasActive = isActive(); + doFinishConnect(); + fulfillConnectPromise(connectPromise, wasActive); + } catch (Throwable t) { + if (t instanceof ConnectException) { + Throwable newT = new ConnectException(t.getMessage() + ": " + requestedRemoteAddress); + newT.setStackTrace(t.getStackTrace()); + t = newT; + } + + fulfillConnectPromise(connectPromise, t); + } finally { + // Check for null as the connectTimeoutFuture is only created if a connectTimeoutMillis > 0 is used + // See https://github.com/netty/netty/issues/1770 + if (connectTimeoutFuture != null) { + connectTimeoutFuture.cancel(false); + } + connectPromise = null; + } + } + + @Override + protected final void flush0() { + // Flush immediately only when there's no pending flush. + // If there's a pending flush operation, event loop will call forceFlush() later, + // and thus there's no need to call it now. + if (isFlushPending()) { + return; + } + super.flush0(); + } + + @Override + public final void forceFlush() { + // directly call super.flush0() to force a flush now + super.flush0(); + } + + private boolean isFlushPending() { + SelectionKey selectionKey = selectionKey(); + return selectionKey.isValid() && (selectionKey.interestOps() & SelectionKey.OP_WRITE) != 0; + } + } + + @Override + protected boolean isCompatible(EventLoop loop) { + return loop instanceof NioEventLoop; + } + + @Override + protected void doRegister() throws Exception { + boolean selected = false; + for (;;) { + try { + selectionKey = javaChannel().register(eventLoop().selector, 0, this); + return; + } catch (CancelledKeyException e) { + if (!selected) { + // Force the Selector to select now as the "canceled" SelectionKey may still be + // cached and not removed because no Select.select(..) operation was called yet. + eventLoop().selectNow(); + selected = true; + } else { + // We forced a select operation on the selector before but the SelectionKey is still cached + // for whatever reason. JDK bug ? + throw e; + } + } + } + } + + @Override + protected void doDeregister() throws Exception { + eventLoop().cancel(selectionKey()); + } + + @Override + protected void doBeginRead() throws Exception { + // Channel.read() or ChannelHandlerContext.read() was called + if (inputShutdown) { + return; + } + + final SelectionKey selectionKey = this.selectionKey; + if (!selectionKey.isValid()) { + return; + } + + readPending = true; + + final int interestOps = selectionKey.interestOps(); + if ((interestOps & readInterestOp) == 0) { + selectionKey.interestOps(interestOps | readInterestOp); + } + } + + /** + * Connect to the remote peer + */ + protected abstract boolean doConnect(SocketAddress remoteAddress, SocketAddress localAddress) throws Exception; + + /** + * Finish the connect + */ + protected abstract void doFinishConnect() throws Exception; + + /** + * Returns an off-heap copy of the specified {@link ByteBuf}, and releases the original one. + * Note that this method does not create an off-heap copy if the allocation / deallocation cost is too high, + * but just returns the original {@link ByteBuf}.. + */ + protected final ByteBuf newDirectBuffer(ByteBuf buf) { + final int readableBytes = buf.readableBytes(); + if (readableBytes == 0) { + ReferenceCountUtil.safeRelease(buf); + return Unpooled.EMPTY_BUFFER; + } + + final ByteBufAllocator alloc = alloc(); + if (alloc.isDirectBufferPooled()) { + ByteBuf directBuf = alloc.directBuffer(readableBytes); + directBuf.writeBytes(buf, buf.readerIndex(), readableBytes); + ReferenceCountUtil.safeRelease(buf); + return directBuf; + } + + final ByteBuf directBuf = ByteBufUtil.threadLocalDirectBuffer(); + if (directBuf != null) { + directBuf.writeBytes(buf, buf.readerIndex(), readableBytes); + ReferenceCountUtil.safeRelease(buf); + return directBuf; + } + + // Allocating and deallocating an unpooled direct buffer is very expensive; give up. + return buf; + } + + /** + * Returns an off-heap copy of the specified {@link ByteBuf}, and releases the specified holder. + * The caller must ensure that the holder releases the original {@link ByteBuf} when the holder is released by + * this method. Note that this method does not create an off-heap copy if the allocation / deallocation cost is + * too high, but just returns the original {@link ByteBuf}.. + */ + protected final ByteBuf newDirectBuffer(ReferenceCounted holder, ByteBuf buf) { + final int readableBytes = buf.readableBytes(); + if (readableBytes == 0) { + ReferenceCountUtil.safeRelease(holder); + return Unpooled.EMPTY_BUFFER; + } + + final ByteBufAllocator alloc = alloc(); + if (alloc.isDirectBufferPooled()) { + ByteBuf directBuf = alloc.directBuffer(readableBytes); + directBuf.writeBytes(buf, buf.readerIndex(), readableBytes); + ReferenceCountUtil.safeRelease(holder); + return directBuf; + } + + final ByteBuf directBuf = ByteBufUtil.threadLocalDirectBuffer(); + if (directBuf != null) { + directBuf.writeBytes(buf, buf.readerIndex(), readableBytes); + ReferenceCountUtil.safeRelease(holder); + return directBuf; + } + + // Allocating and deallocating an unpooled direct buffer is very expensive; give up. + if (holder != buf) { + // Ensure to call holder.release() to give the holder a chance to release other resources than its content. + buf.retain(); + ReferenceCountUtil.safeRelease(holder); + } + + return buf; + } +} diff --git a/common/src/common/net/channel/nio/AbstractNioMessageChannel.java b/common/src/common/net/channel/nio/AbstractNioMessageChannel.java new file mode 100644 index 0000000..3153d17 --- /dev/null +++ b/common/src/common/net/channel/nio/AbstractNioMessageChannel.java @@ -0,0 +1,187 @@ +/* + * Copyright 2012 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ +package common.net.channel.nio; + +import java.io.IOException; +import java.nio.channels.SelectableChannel; +import java.nio.channels.SelectionKey; +import java.util.ArrayList; +import java.util.List; + +import common.net.channel.Channel; +import common.net.channel.ChannelConfig; +import common.net.channel.ChannelOutboundBuffer; +import common.net.channel.ChannelPipeline; +import common.net.channel.ServerChannel; + +/** + * {@link AbstractNioChannel} base class for {@link Channel}s that operate on messages. + */ +public abstract class AbstractNioMessageChannel extends AbstractNioChannel { + + /** + * @see {@link AbstractNioChannel#AbstractNioChannel(Channel, SelectableChannel, int)} + */ + protected AbstractNioMessageChannel(Channel parent, SelectableChannel ch, int readInterestOp) { + super(parent, ch, readInterestOp); + } + + @Override + protected AbstractNioUnsafe newUnsafe() { + return new NioMessageUnsafe(); + } + + private final class NioMessageUnsafe extends AbstractNioUnsafe { + + private final List readBuf = new ArrayList(); + + @Override + public void read() { + assert eventLoop().inEventLoop(); + final ChannelConfig config = config(); + if (!config.isAutoRead() && !isReadPending()) { + // ChannelConfig.setAutoRead(false) was called in the meantime + removeReadOp(); + return; + } + + final int maxMessagesPerRead = config.getMaxMessagesPerRead(); + final ChannelPipeline pipeline = pipeline(); + boolean closed = false; + Throwable exception = null; + try { + try { + for (;;) { + int localRead = doReadMessages(readBuf); + if (localRead == 0) { + break; + } + if (localRead < 0) { + closed = true; + break; + } + + // stop reading and remove op + if (!config.isAutoRead()) { + break; + } + + if (readBuf.size() >= maxMessagesPerRead) { + break; + } + } + } catch (Throwable t) { + exception = t; + } + setReadPending(false); + int size = readBuf.size(); + for (int i = 0; i < size; i ++) { + pipeline.fireChannelRead(readBuf.get(i)); + } + + readBuf.clear(); + pipeline.fireChannelReadComplete(); + + if (exception != null) { + if (exception instanceof IOException) { + // ServerChannel should not be closed even on IOException because it can often continue + // accepting incoming connections. (e.g. too many open files) + closed = !(AbstractNioMessageChannel.this instanceof ServerChannel); + } + + pipeline.fireExceptionCaught(exception); + } + + if (closed) { + if (isOpen()) { + close(voidPromise()); + } + } + } finally { + // Check if there is a readPending which was not processed yet. + // This could be for two reasons: + // * The user called Channel.read() or ChannelHandlerContext.read() in channelRead(...) method + // * The user called Channel.read() or ChannelHandlerContext.read() in channelReadComplete(...) method + // + // See https://github.com/netty/netty/issues/2254 + if (!config.isAutoRead() && !isReadPending()) { + removeReadOp(); + } + } + } + } + + @Override + protected void doWrite(ChannelOutboundBuffer in) throws Exception { + final SelectionKey key = selectionKey(); + final int interestOps = key.interestOps(); + + for (;;) { + Object msg = in.current(); + if (msg == null) { + // Wrote all messages. + if ((interestOps & SelectionKey.OP_WRITE) != 0) { + key.interestOps(interestOps & ~SelectionKey.OP_WRITE); + } + break; + } + try { + boolean done = false; + for (int i = config().getWriteSpinCount() - 1; i >= 0; i--) { + if (doWriteMessage(msg, in)) { + done = true; + break; + } + } + + if (done) { + in.remove(); + } else { + // Did not write all messages. + if ((interestOps & SelectionKey.OP_WRITE) == 0) { + key.interestOps(interestOps | SelectionKey.OP_WRITE); + } + break; + } + } catch (IOException e) { + if (continueOnWriteError()) { + in.remove(e); + } else { + throw e; + } + } + } + } + + /** + * Returns {@code true} if we should continue the write loop on a write error. + */ + protected boolean continueOnWriteError() { + return false; + } + + /** + * Read messages into the given array and return the amount which was read. + */ + protected abstract int doReadMessages(List buf) throws Exception; + + /** + * Write a message to the underlying {@link java.nio.channels.Channel}. + * + * @return {@code true} if and only if the message has been written + */ + protected abstract boolean doWriteMessage(Object msg, ChannelOutboundBuffer in) throws Exception; +} diff --git a/common/src/common/net/channel/nio/NioEventLoop.java b/common/src/common/net/channel/nio/NioEventLoop.java new file mode 100644 index 0000000..a2b75f9 --- /dev/null +++ b/common/src/common/net/channel/nio/NioEventLoop.java @@ -0,0 +1,691 @@ +/* + * Copyright 2012 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ +package common.net.channel.nio; + + +import java.io.IOException; +import java.lang.reflect.Field; +import java.nio.channels.CancelledKeyException; +import java.nio.channels.SelectableChannel; +import java.nio.channels.SelectionKey; +import java.nio.channels.Selector; +import java.nio.channels.spi.SelectorProvider; +import java.util.ArrayList; +import java.util.Collection; +import java.util.ConcurrentModificationException; +import java.util.Iterator; +import java.util.Queue; +import java.util.Set; +import java.util.concurrent.ThreadFactory; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicBoolean; + +import common.net.channel.ChannelException; +import common.net.channel.EventLoopException; +import common.net.channel.SingleThreadEventLoop; +import common.net.channel.nio.AbstractNioChannel.NioUnsafe; +import common.net.util.internal.PlatformDependent; +import common.net.util.internal.SystemPropertyUtil; +import common.net.util.internal.logging.InternalLogger; +import common.net.util.internal.logging.InternalLoggerFactory; + +/** + * {@link SingleThreadEventLoop} implementation which register the {@link Channel}'s to a + * {@link Selector} and so does the multi-plexing of these in the event loop. + * + */ +public final class NioEventLoop extends SingleThreadEventLoop { + + private static final InternalLogger logger = InternalLoggerFactory.getInstance(NioEventLoop.class); + + private static final int CLEANUP_INTERVAL = 256; // XXX Hard-coded value, but won't need customization. + + private static final boolean DISABLE_KEYSET_OPTIMIZATION = + SystemPropertyUtil.getBoolean("game.net.noKeySetOptimization", false); + + private static final int MIN_PREMATURE_SELECTOR_RETURNS = 3; + private static final int SELECTOR_AUTO_REBUILD_THRESHOLD; + + // Workaround for JDK NIO bug. + // + // See: + // - http://bugs.sun.com/view_bug.do?bug_id=6427854 + // - https://github.com/netty/netty/issues/203 + static { + String key = "sun.nio.ch.bugLevel"; + try { + String buglevel = SystemPropertyUtil.get(key); + if (buglevel == null) { + System.setProperty(key, ""); + } + } catch (SecurityException e) { + if (logger.isDebugEnabled()) { + logger.debug("Unable to get/set System Property: {}", key, e); + } + } + + int selectorAutoRebuildThreshold = SystemPropertyUtil.getInt("game.net.selectorAutoRebuildThreshold", 512); + if (selectorAutoRebuildThreshold < MIN_PREMATURE_SELECTOR_RETURNS) { + selectorAutoRebuildThreshold = 0; + } + + SELECTOR_AUTO_REBUILD_THRESHOLD = selectorAutoRebuildThreshold; + + if (logger.isDebugEnabled()) { + logger.debug("-Dgame.net.noKeySetOptimization: {}", DISABLE_KEYSET_OPTIMIZATION); + logger.debug("-Dgame.net.selectorAutoRebuildThreshold: {}", SELECTOR_AUTO_REBUILD_THRESHOLD); + } + } + + /** + * The NIO {@link Selector}. + */ + Selector selector; + private SelectedSelectionKeySet selectedKeys; + + private final SelectorProvider provider; + + /** + * Boolean that controls determines if a blocked Selector.select should + * break out of its selection process. In our case we use a timeout for + * the select method and the select method will block for that time unless + * waken up. + */ + private final AtomicBoolean wakenUp = new AtomicBoolean(); + + private volatile int ioRatio = 50; + private int cancelledKeys; + private boolean needsToSelectAgain; + + NioEventLoop(NioEventLoopGroup parent, ThreadFactory threadFactory, SelectorProvider selectorProvider) { + super(parent, threadFactory, false); + if (selectorProvider == null) { + throw new NullPointerException("selectorProvider"); + } + provider = selectorProvider; + selector = openSelector(); + } + + private Selector openSelector() { + final Selector selector; + try { + selector = provider.openSelector(); + } catch (IOException e) { + throw new ChannelException("failed to open a new selector", e); + } + + if (DISABLE_KEYSET_OPTIMIZATION) { + return selector; + } + + try { + SelectedSelectionKeySet selectedKeySet = new SelectedSelectionKeySet(); + + Class selectorImplClass = + Class.forName("sun.nio.ch.SelectorImpl", false, PlatformDependent.getSystemClassLoader()); + + // Ensure the current selector implementation is what we can instrument. + if (!selectorImplClass.isAssignableFrom(selector.getClass())) { + return selector; + } + + Field selectedKeysField = selectorImplClass.getDeclaredField("selectedKeys"); + Field publicSelectedKeysField = selectorImplClass.getDeclaredField("publicSelectedKeys"); + + selectedKeysField.setAccessible(true); + publicSelectedKeysField.setAccessible(true); + + selectedKeysField.set(selector, selectedKeySet); + publicSelectedKeysField.set(selector, selectedKeySet); + + selectedKeys = selectedKeySet; + logger.trace("Instrumented an optimized java.util.Set into: {}", selector); + } catch (Throwable t) { + selectedKeys = null; + logger.trace("Failed to instrument an optimized java.util.Set into: {}", selector, t); + } + + return selector; + } + + @Override + protected Queue newTaskQueue() { + // This event loop never calls takeTask() + return PlatformDependent.newMpscQueue(); + } + + /** + * Registers an arbitrary {@link SelectableChannel}, not necessarily created by Netty, to the {@link Selector} + * of this event loop. Once the specified {@link SelectableChannel} is registered, the specified {@code task} will + * be executed by this event loop when the {@link SelectableChannel} is ready. + */ + public void register(final SelectableChannel ch, final int interestOps, final NioTask task) { + if (ch == null) { + throw new NullPointerException("ch"); + } + if (interestOps == 0) { + throw new IllegalArgumentException("interestOps must be non-zero."); + } + if ((interestOps & ~ch.validOps()) != 0) { + throw new IllegalArgumentException( + "invalid interestOps: " + interestOps + "(validOps: " + ch.validOps() + ')'); + } + if (task == null) { + throw new NullPointerException("task"); + } + + if (isShutdown()) { + throw new IllegalStateException("event loop shut down"); + } + + try { + ch.register(selector, interestOps, task); + } catch (Exception e) { + throw new EventLoopException("failed to register a channel", e); + } + } + + /** + * Returns the percentage of the desired amount of time spent for I/O in the event loop. + */ + public int getIoRatio() { + return ioRatio; + } + + /** + * Sets the percentage of the desired amount of time spent for I/O in the event loop. The default value is + * {@code 50}, which means the event loop will try to spend the same amount of time for I/O as for non-I/O tasks. + */ + public void setIoRatio(int ioRatio) { + if (ioRatio <= 0 || ioRatio > 100) { + throw new IllegalArgumentException("ioRatio: " + ioRatio + " (expected: 0 < ioRatio <= 100)"); + } + this.ioRatio = ioRatio; + } + + /** + * Replaces the current {@link Selector} of this event loop with newly created {@link Selector}s to work + * around the infamous epoll 100% CPU bug. + */ + public void rebuildSelector() { + if (!inEventLoop()) { + execute(new Runnable() { + @Override + public void run() { + rebuildSelector(); + } + }); + return; + } + + final Selector oldSelector = selector; + final Selector newSelector; + + if (oldSelector == null) { + return; + } + + try { + newSelector = openSelector(); + } catch (Exception e) { + logger.warn("Failed to create a new Selector.", e); + return; + } + + // Register all channels to the new Selector. + int nChannels = 0; + for (;;) { + try { + for (SelectionKey key: oldSelector.keys()) { + Object a = key.attachment(); + try { + if (!key.isValid() || key.channel().keyFor(newSelector) != null) { + continue; + } + + int interestOps = key.interestOps(); + key.cancel(); + SelectionKey newKey = key.channel().register(newSelector, interestOps, a); + if (a instanceof AbstractNioChannel) { + // Update SelectionKey + ((AbstractNioChannel) a).selectionKey = newKey; + } + nChannels ++; + } catch (Exception e) { + logger.warn("Failed to re-register a Channel to the new Selector.", e); + if (a instanceof AbstractNioChannel) { + AbstractNioChannel ch = (AbstractNioChannel) a; + ch.unsafe().close(ch.unsafe().voidPromise()); + } else { + + NioTask task = (NioTask) a; + invokeChannelUnregistered(task, key, e); + } + } + } + } catch (ConcurrentModificationException e) { + // Probably due to concurrent modification of the key set. + continue; + } + + break; + } + + selector = newSelector; + + try { + // time to close the old selector as everything else is registered to the new one + oldSelector.close(); + } catch (Throwable t) { + if (logger.isWarnEnabled()) { + logger.warn("Failed to close the old Selector.", t); + } + } + + logger.info("Migrated " + nChannels + " channel(s) to the new Selector."); + } + + @Override + protected void run() { + for (;;) { + boolean oldWakenUp = wakenUp.getAndSet(false); + try { + if (hasTasks()) { + selectNow(); + } else { + select(oldWakenUp); + + // 'wakenUp.compareAndSet(false, true)' is always evaluated + // before calling 'selector.wakeup()' to reduce the wake-up + // overhead. (Selector.wakeup() is an expensive operation.) + // + // However, there is a race condition in this approach. + // The race condition is triggered when 'wakenUp' is set to + // true too early. + // + // 'wakenUp' is set to true too early if: + // 1) Selector is waken up between 'wakenUp.set(false)' and + // 'selector.select(...)'. (BAD) + // 2) Selector is waken up between 'selector.select(...)' and + // 'if (wakenUp.get()) { ... }'. (OK) + // + // In the first case, 'wakenUp' is set to true and the + // following 'selector.select(...)' will wake up immediately. + // Until 'wakenUp' is set to false again in the next round, + // 'wakenUp.compareAndSet(false, true)' will fail, and therefore + // any attempt to wake up the Selector will fail, too, causing + // the following 'selector.select(...)' call to block + // unnecessarily. + // + // To fix this problem, we wake up the selector again if wakenUp + // is true immediately after selector.select(...). + // It is inefficient in that it wakes up the selector for both + // the first case (BAD - wake-up required) and the second case + // (OK - no wake-up required). + + if (wakenUp.get()) { + selector.wakeup(); + } + } + + cancelledKeys = 0; + needsToSelectAgain = false; + final int ioRatio = this.ioRatio; + if (ioRatio == 100) { + processSelectedKeys(); + runAllTasks(); + } else { + final long ioStartTime = System.nanoTime(); + + processSelectedKeys(); + + final long ioTime = System.nanoTime() - ioStartTime; + runAllTasks(ioTime * (100 - ioRatio) / ioRatio); + } + + if (isShuttingDown()) { + closeAll(); + if (confirmShutdown()) { + break; + } + } + } catch (Throwable t) { + logger.warn("Unexpected exception in the selector loop.", t); + + // Prevent possible consecutive immediate failures that lead to + // excessive CPU consumption. + try { + Thread.sleep(1000); + } catch (InterruptedException e) { + // Ignore. + } + } + } + } + + private void processSelectedKeys() { + if (selectedKeys != null) { + processSelectedKeysOptimized(selectedKeys.flip()); + } else { + processSelectedKeysPlain(selector.selectedKeys()); + } + } + + @Override + protected void cleanup() { + try { + selector.close(); + } catch (IOException e) { + logger.warn("Failed to close a selector.", e); + } + } + + void cancel(SelectionKey key) { + key.cancel(); + cancelledKeys ++; + if (cancelledKeys >= CLEANUP_INTERVAL) { + cancelledKeys = 0; + needsToSelectAgain = true; + } + } + + @Override + protected Runnable pollTask() { + Runnable task = super.pollTask(); + if (needsToSelectAgain) { + selectAgain(); + } + return task; + } + + private void processSelectedKeysPlain(Set selectedKeys) { + // check if the set is empty and if so just return to not create garbage by + // creating a new Iterator every time even if there is nothing to process. + // See https://github.com/netty/netty/issues/597 + if (selectedKeys.isEmpty()) { + return; + } + + Iterator i = selectedKeys.iterator(); + for (;;) { + final SelectionKey k = i.next(); + final Object a = k.attachment(); + i.remove(); + + if (a instanceof AbstractNioChannel) { + processSelectedKey(k, (AbstractNioChannel) a); + } else { + + NioTask task = (NioTask) a; + processSelectedKey(k, task); + } + + if (!i.hasNext()) { + break; + } + + if (needsToSelectAgain) { + selectAgain(); + selectedKeys = selector.selectedKeys(); + + // Create the iterator again to avoid ConcurrentModificationException + if (selectedKeys.isEmpty()) { + break; + } else { + i = selectedKeys.iterator(); + } + } + } + } + + private void processSelectedKeysOptimized(SelectionKey[] selectedKeys) { + for (int i = 0;; i ++) { + final SelectionKey k = selectedKeys[i]; + if (k == null) { + break; + } + // null out entry in the array to allow to have it GC'ed once the Channel close + // See https://github.com/netty/netty/issues/2363 + selectedKeys[i] = null; + + final Object a = k.attachment(); + + if (a instanceof AbstractNioChannel) { + processSelectedKey(k, (AbstractNioChannel) a); + } else { + + NioTask task = (NioTask) a; + processSelectedKey(k, task); + } + + if (needsToSelectAgain) { + // null out entries in the array to allow to have it GC'ed once the Channel close + // See https://github.com/netty/netty/issues/2363 + for (;;) { + if (selectedKeys[i] == null) { + break; + } + selectedKeys[i] = null; + i++; + } + + selectAgain(); + // Need to flip the optimized selectedKeys to get the right reference to the array + // and reset the index to -1 which will then set to 0 on the for loop + // to start over again. + // + // See https://github.com/netty/netty/issues/1523 + selectedKeys = this.selectedKeys.flip(); + i = -1; + } + } + } + + private static void processSelectedKey(SelectionKey k, AbstractNioChannel ch) { + final NioUnsafe unsafe = ch.unsafe(); + if (!k.isValid()) { + // close the channel if the key is not valid anymore + unsafe.close(unsafe.voidPromise()); + return; + } + + try { + int readyOps = k.readyOps(); + // Also check for readOps of 0 to workaround possible JDK bug which may otherwise lead + // to a spin loop + if ((readyOps & (SelectionKey.OP_READ | SelectionKey.OP_ACCEPT)) != 0 || readyOps == 0) { + unsafe.read(); + if (!ch.isOpen()) { + // Connection already closed - no need to handle write. + return; + } + } + if ((readyOps & SelectionKey.OP_WRITE) != 0) { + // Call forceFlush which will also take care of clear the OP_WRITE once there is nothing left to write + ch.unsafe().forceFlush(); + } + if ((readyOps & SelectionKey.OP_CONNECT) != 0) { + // remove OP_CONNECT as otherwise Selector.select(..) will always return without blocking + // See https://github.com/netty/netty/issues/924 + int ops = k.interestOps(); + ops &= ~SelectionKey.OP_CONNECT; + k.interestOps(ops); + + unsafe.finishConnect(); + } + } catch (CancelledKeyException ignored) { + unsafe.close(unsafe.voidPromise()); + } + } + + private static void processSelectedKey(SelectionKey k, NioTask task) { + int state = 0; + try { + task.channelReady(k.channel(), k); + state = 1; + } catch (Exception e) { + k.cancel(); + invokeChannelUnregistered(task, k, e); + state = 2; + } finally { + switch (state) { + case 0: + k.cancel(); + invokeChannelUnregistered(task, k, null); + break; + case 1: + if (!k.isValid()) { // Cancelled by channelReady() + invokeChannelUnregistered(task, k, null); + } + break; + } + } + } + + private void closeAll() { + selectAgain(); + Set keys = selector.keys(); + Collection channels = new ArrayList(keys.size()); + for (SelectionKey k: keys) { + Object a = k.attachment(); + if (a instanceof AbstractNioChannel) { + channels.add((AbstractNioChannel) a); + } else { + k.cancel(); + + NioTask task = (NioTask) a; + invokeChannelUnregistered(task, k, null); + } + } + + for (AbstractNioChannel ch: channels) { + ch.unsafe().close(ch.unsafe().voidPromise()); + } + } + + private static void invokeChannelUnregistered(NioTask task, SelectionKey k, Throwable cause) { + try { + task.channelUnregistered(k.channel(), cause); + } catch (Exception e) { + logger.warn("Unexpected exception while running NioTask.channelUnregistered()", e); + } + } + + @Override + protected void wakeup(boolean inEventLoop) { + if (!inEventLoop && wakenUp.compareAndSet(false, true)) { + selector.wakeup(); + } + } + + void selectNow() throws IOException { + try { + selector.selectNow(); + } finally { + // restore wakup state if needed + if (wakenUp.get()) { + selector.wakeup(); + } + } + } + + private void select(boolean oldWakenUp) throws IOException { + Selector selector = this.selector; + try { + int selectCnt = 0; + long currentTimeNanos = System.nanoTime(); + long selectDeadLineNanos = currentTimeNanos + delayNanos(currentTimeNanos); + for (;;) { + long timeoutMillis = (selectDeadLineNanos - currentTimeNanos + 500000L) / 1000000L; + if (timeoutMillis <= 0) { + if (selectCnt == 0) { + selector.selectNow(); + selectCnt = 1; + } + break; + } + + int selectedKeys = selector.select(timeoutMillis); + selectCnt ++; + + if (selectedKeys != 0 || oldWakenUp || wakenUp.get() || hasTasks() || hasScheduledTasks()) { + // - Selected something, + // - waken up by user, or + // - the task queue has a pending task. + // - a scheduled task is ready for processing + break; + } + if (Thread.interrupted()) { + // Thread was interrupted so reset selected keys and break so we not run into a busy loop. + // As this is most likely a bug in the handler of the user or it's client library we will + // also log it. + // + // See https://github.com/netty/netty/issues/2426 + if (logger.isDebugEnabled()) { + logger.debug("Selector.select() returned prematurely because " + + "Thread.currentThread().interrupt() was called. Use " + + "NioEventLoop.shutdownGracefully() to shutdown the NioEventLoop."); + } + selectCnt = 1; + break; + } + + long time = System.nanoTime(); + if (time - TimeUnit.MILLISECONDS.toNanos(timeoutMillis) >= currentTimeNanos) { + // timeoutMillis elapsed without anything selected. + selectCnt = 1; + } else if (SELECTOR_AUTO_REBUILD_THRESHOLD > 0 && + selectCnt >= SELECTOR_AUTO_REBUILD_THRESHOLD) { + // The selector returned prematurely many times in a row. + // Rebuild the selector to work around the problem. + logger.warn( + "Selector.select() returned prematurely {} times in a row; rebuilding selector.", + selectCnt); + + rebuildSelector(); + selector = this.selector; + + // Select again to populate selectedKeys. + selector.selectNow(); + selectCnt = 1; + break; + } + + currentTimeNanos = time; + } + + if (selectCnt > MIN_PREMATURE_SELECTOR_RETURNS) { + if (logger.isDebugEnabled()) { + logger.debug("Selector.select() returned prematurely {} times in a row.", selectCnt - 1); + } + } + } catch (CancelledKeyException e) { + if (logger.isDebugEnabled()) { + logger.debug(CancelledKeyException.class.getSimpleName() + " raised by a Selector - JDK bug?", e); + } + // Harmless exception - log anyway + } + } + + private void selectAgain() { + needsToSelectAgain = false; + try { + selector.selectNow(); + } catch (Throwable t) { + logger.warn("Failed to update SelectionKeys.", t); + } + } +} diff --git a/common/src/common/net/channel/nio/NioEventLoopGroup.java b/common/src/common/net/channel/nio/NioEventLoopGroup.java new file mode 100644 index 0000000..926efc8 --- /dev/null +++ b/common/src/common/net/channel/nio/NioEventLoopGroup.java @@ -0,0 +1,87 @@ +/* + * Copyright 2012 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ +package common.net.channel.nio; + +import java.nio.channels.spi.SelectorProvider; +import java.util.concurrent.ThreadFactory; + +import common.net.channel.MultithreadEventLoopGroup; +import common.net.util.concurrent.EventExecutor; + +/** + * {@link MultithreadEventLoopGroup} implementations which is used for NIO {@link Selector} based {@link Channel}s. + */ +public class NioEventLoopGroup extends MultithreadEventLoopGroup { + + /** + * Create a new instance using the default number of threads, the default {@link ThreadFactory} and + * the {@link SelectorProvider} which is returned by {@link SelectorProvider#provider()}. + */ + public NioEventLoopGroup() { + this(0); + } + + /** + * Create a new instance using the specified number of threads, {@link ThreadFactory} and the + * {@link SelectorProvider} which is returned by {@link SelectorProvider#provider()}. + */ + public NioEventLoopGroup(int nThreads) { + this(nThreads, null); + } + + /** + * Create a new instance using the specified number of threads, the given {@link ThreadFactory} and the + * {@link SelectorProvider} which is returned by {@link SelectorProvider#provider()}. + */ + public NioEventLoopGroup(int nThreads, ThreadFactory threadFactory) { + this(nThreads, threadFactory, SelectorProvider.provider()); + } + + /** + * Create a new instance using the specified number of threads, the given {@link ThreadFactory} and the given + * {@link SelectorProvider}. + */ + public NioEventLoopGroup( + int nThreads, ThreadFactory threadFactory, final SelectorProvider selectorProvider) { + super(nThreads, threadFactory, selectorProvider); + } + + /** + * Sets the percentage of the desired amount of time spent for I/O in the child event loops. The default value is + * {@code 50}, which means the event loop will try to spend the same amount of time for I/O as for non-I/O tasks. + */ + public void setIoRatio(int ioRatio) { + for (EventExecutor e: children()) { + ((NioEventLoop) e).setIoRatio(ioRatio); + } + } + + /** + * Replaces the current {@link Selector}s of the child event loops with newly created {@link Selector}s to work + * around the infamous epoll 100% CPU bug. + */ + public void rebuildSelectors() { + for (EventExecutor e: children()) { + ((NioEventLoop) e).rebuildSelector(); + } + } + + @Override + protected EventExecutor newChild( + ThreadFactory threadFactory, Object... args) throws Exception { + return new NioEventLoop(this, threadFactory, (SelectorProvider) args[0]); + } +} diff --git a/common/src/common/net/channel/nio/NioTask.java b/common/src/common/net/channel/nio/NioTask.java new file mode 100644 index 0000000..43dea6b --- /dev/null +++ b/common/src/common/net/channel/nio/NioTask.java @@ -0,0 +1,40 @@ +/* + * Copyright 2012 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ +package common.net.channel.nio; + +import java.nio.channels.SelectableChannel; +import java.nio.channels.SelectionKey; + +/** + * An arbitrary task that can be executed by {@link NioEventLoop} when a {@link SelectableChannel} becomes ready. + * + * @see NioEventLoop#register(SelectableChannel, int, NioTask) + */ +public interface NioTask { + /** + * Invoked when the {@link SelectableChannel} has been selected by the {@link Selector}. + */ + void channelReady(C ch, SelectionKey key) throws Exception; + + /** + * Invoked when the {@link SelectionKey} of the specified {@link SelectableChannel} has been cancelled and thus + * this {@link NioTask} will not be notified anymore. + * + * @param cause the cause of the unregistration. {@code null} if a user called {@link SelectionKey#cancel()} or + * the event loop has been shut down. + */ + void channelUnregistered(C ch, Throwable cause) throws Exception; +} diff --git a/common/src/common/net/channel/nio/SelectedSelectionKeySet.java b/common/src/common/net/channel/nio/SelectedSelectionKeySet.java new file mode 100644 index 0000000..8d7cfd8 --- /dev/null +++ b/common/src/common/net/channel/nio/SelectedSelectionKeySet.java @@ -0,0 +1,110 @@ +/* + * Copyright 2013 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ + +package common.net.channel.nio; + +import java.nio.channels.SelectionKey; +import java.util.AbstractSet; +import java.util.Iterator; + +final class SelectedSelectionKeySet extends AbstractSet { + + private SelectionKey[] keysA; + private int keysASize; + private SelectionKey[] keysB; + private int keysBSize; + private boolean isA = true; + + SelectedSelectionKeySet() { + keysA = new SelectionKey[1024]; + keysB = keysA.clone(); + } + + @Override + public boolean add(SelectionKey o) { + if (o == null) { + return false; + } + + if (isA) { + int size = keysASize; + keysA[size ++] = o; + keysASize = size; + if (size == keysA.length) { + doubleCapacityA(); + } + } else { + int size = keysBSize; + keysB[size ++] = o; + keysBSize = size; + if (size == keysB.length) { + doubleCapacityB(); + } + } + + return true; + } + + private void doubleCapacityA() { + SelectionKey[] newKeysA = new SelectionKey[keysA.length << 1]; + System.arraycopy(keysA, 0, newKeysA, 0, keysASize); + keysA = newKeysA; + } + + private void doubleCapacityB() { + SelectionKey[] newKeysB = new SelectionKey[keysB.length << 1]; + System.arraycopy(keysB, 0, newKeysB, 0, keysBSize); + keysB = newKeysB; + } + + SelectionKey[] flip() { + if (isA) { + isA = false; + keysA[keysASize] = null; + keysBSize = 0; + return keysA; + } else { + isA = true; + keysB[keysBSize] = null; + keysASize = 0; + return keysB; + } + } + + @Override + public int size() { + if (isA) { + return keysASize; + } else { + return keysBSize; + } + } + + @Override + public boolean remove(Object o) { + return false; + } + + @Override + public boolean contains(Object o) { + return false; + } + + @Override + public Iterator iterator() { + throw new UnsupportedOperationException(); + } +} diff --git a/common/src/common/net/channel/socket/ChannelInputShutdownEvent.java b/common/src/common/net/channel/socket/ChannelInputShutdownEvent.java new file mode 100644 index 0000000..3886008 --- /dev/null +++ b/common/src/common/net/channel/socket/ChannelInputShutdownEvent.java @@ -0,0 +1,33 @@ +/* + * Copyright 2012 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ +package common.net.channel.socket; + +/** + * Special event which will be fired and passed to the + * {@link ChannelInboundHandler#userEventTriggered(ChannelHandlerContext, Object)} methods once the input of + * a {@link SocketChannel} was shutdown and the {@link SocketChannelConfig#isAllowHalfClosure()} method returns + * {@code true}. + */ +public final class ChannelInputShutdownEvent { + + /** + * Instance to use + */ + + public static final ChannelInputShutdownEvent INSTANCE = new ChannelInputShutdownEvent(); + + private ChannelInputShutdownEvent() { } +} diff --git a/common/src/common/net/channel/socket/DefaultServerSocketChannelConfig.java b/common/src/common/net/channel/socket/DefaultServerSocketChannelConfig.java new file mode 100644 index 0000000..52db912 --- /dev/null +++ b/common/src/common/net/channel/socket/DefaultServerSocketChannelConfig.java @@ -0,0 +1,203 @@ +/* + * Copyright 2012 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ +package common.net.channel.socket; + +import static common.net.channel.ChannelOption.SO_BACKLOG; +import static common.net.channel.ChannelOption.SO_RCVBUF; +import static common.net.channel.ChannelOption.SO_REUSEADDR; + +import java.net.ServerSocket; +import java.net.SocketException; +import java.util.Map; + +import common.net.buffer.ByteBufAllocator; +import common.net.channel.ChannelException; +import common.net.channel.ChannelOption; +import common.net.channel.DefaultChannelConfig; +import common.net.channel.MessageSizeEstimator; +import common.net.channel.RecvByteBufAllocator; +import common.net.util.NetUtil; + +/** + * The default {@link ServerSocketChannelConfig} implementation. + */ +public class DefaultServerSocketChannelConfig extends DefaultChannelConfig + implements ServerSocketChannelConfig { + + protected final ServerSocket javaSocket; + private volatile int backlog = NetUtil.SOMAXCONN; + + /** + * Creates a new instance. + */ + public DefaultServerSocketChannelConfig(ServerSocketChannel channel, ServerSocket javaSocket) { + super(channel); + if (javaSocket == null) { + throw new NullPointerException("javaSocket"); + } + this.javaSocket = javaSocket; + } + + @Override + public Map, Object> getOptions() { + return getOptions(super.getOptions(), SO_RCVBUF, SO_REUSEADDR, SO_BACKLOG); + } + + + @Override + public T getOption(ChannelOption option) { + if (option == SO_RCVBUF) { + return (T) Integer.valueOf(getReceiveBufferSize()); + } + if (option == SO_REUSEADDR) { + return (T) Boolean.valueOf(isReuseAddress()); + } + if (option == SO_BACKLOG) { + return (T) Integer.valueOf(getBacklog()); + } + + return super.getOption(option); + } + + @Override + public boolean setOption(ChannelOption option, T value) { + validate(option, value); + + if (option == SO_RCVBUF) { + setReceiveBufferSize((Integer) value); + } else if (option == SO_REUSEADDR) { + setReuseAddress((Boolean) value); + } else if (option == SO_BACKLOG) { + setBacklog((Integer) value); + } else { + return super.setOption(option, value); + } + + return true; + } + + @Override + public boolean isReuseAddress() { + try { + return javaSocket.getReuseAddress(); + } catch (SocketException e) { + throw new ChannelException(e); + } + } + + @Override + public ServerSocketChannelConfig setReuseAddress(boolean reuseAddress) { + try { + javaSocket.setReuseAddress(reuseAddress); + } catch (SocketException e) { + throw new ChannelException(e); + } + return this; + } + + @Override + public int getReceiveBufferSize() { + try { + return javaSocket.getReceiveBufferSize(); + } catch (SocketException e) { + throw new ChannelException(e); + } + } + + @Override + public ServerSocketChannelConfig setReceiveBufferSize(int receiveBufferSize) { + try { + javaSocket.setReceiveBufferSize(receiveBufferSize); + } catch (SocketException e) { + throw new ChannelException(e); + } + return this; + } + + @Override + public ServerSocketChannelConfig setPerformancePreferences(int connectionTime, int latency, int bandwidth) { + javaSocket.setPerformancePreferences(connectionTime, latency, bandwidth); + return this; + } + + @Override + public int getBacklog() { + return backlog; + } + + @Override + public ServerSocketChannelConfig setBacklog(int backlog) { + if (backlog < 0) { + throw new IllegalArgumentException("backlog: " + backlog); + } + this.backlog = backlog; + return this; + } + + @Override + public ServerSocketChannelConfig setConnectTimeoutMillis(int connectTimeoutMillis) { + super.setConnectTimeoutMillis(connectTimeoutMillis); + return this; + } + + @Override + public ServerSocketChannelConfig setMaxMessagesPerRead(int maxMessagesPerRead) { + super.setMaxMessagesPerRead(maxMessagesPerRead); + return this; + } + + @Override + public ServerSocketChannelConfig setWriteSpinCount(int writeSpinCount) { + super.setWriteSpinCount(writeSpinCount); + return this; + } + + @Override + public ServerSocketChannelConfig setAllocator(ByteBufAllocator allocator) { + super.setAllocator(allocator); + return this; + } + + @Override + public ServerSocketChannelConfig setRecvByteBufAllocator(RecvByteBufAllocator allocator) { + super.setRecvByteBufAllocator(allocator); + return this; + } + + @Override + public ServerSocketChannelConfig setAutoRead(boolean autoRead) { + super.setAutoRead(autoRead); + return this; + } + + @Override + public ServerSocketChannelConfig setWriteBufferHighWaterMark(int writeBufferHighWaterMark) { + super.setWriteBufferHighWaterMark(writeBufferHighWaterMark); + return this; + } + + @Override + public ServerSocketChannelConfig setWriteBufferLowWaterMark(int writeBufferLowWaterMark) { + super.setWriteBufferLowWaterMark(writeBufferLowWaterMark); + return this; + } + + @Override + public ServerSocketChannelConfig setMessageSizeEstimator(MessageSizeEstimator estimator) { + super.setMessageSizeEstimator(estimator); + return this; + } +} diff --git a/common/src/common/net/channel/socket/DefaultSocketChannelConfig.java b/common/src/common/net/channel/socket/DefaultSocketChannelConfig.java new file mode 100644 index 0000000..dce2ffb --- /dev/null +++ b/common/src/common/net/channel/socket/DefaultSocketChannelConfig.java @@ -0,0 +1,348 @@ +/* + * Copyright 2012 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ +package common.net.channel.socket; + +import static common.net.channel.ChannelOption.ALLOW_HALF_CLOSURE; +import static common.net.channel.ChannelOption.IP_TOS; +import static common.net.channel.ChannelOption.SO_KEEPALIVE; +import static common.net.channel.ChannelOption.SO_LINGER; +import static common.net.channel.ChannelOption.SO_RCVBUF; +import static common.net.channel.ChannelOption.SO_REUSEADDR; +import static common.net.channel.ChannelOption.SO_SNDBUF; +import static common.net.channel.ChannelOption.TCP_NODELAY; + +import java.net.Socket; +import java.net.SocketException; +import java.util.Map; + +import common.net.buffer.ByteBufAllocator; +import common.net.channel.ChannelException; +import common.net.channel.ChannelOption; +import common.net.channel.DefaultChannelConfig; +import common.net.channel.MessageSizeEstimator; +import common.net.channel.RecvByteBufAllocator; +import common.net.util.internal.PlatformDependent; + +/** + * The default {@link SocketChannelConfig} implementation. + */ +public class DefaultSocketChannelConfig extends DefaultChannelConfig + implements SocketChannelConfig { + + protected final Socket javaSocket; + private volatile boolean allowHalfClosure; + + /** + * Creates a new instance. + */ + public DefaultSocketChannelConfig(SocketChannel channel, Socket javaSocket) { + super(channel); + if (javaSocket == null) { + throw new NullPointerException("javaSocket"); + } + this.javaSocket = javaSocket; + + // Enable TCP_NODELAY by default if possible. + if (PlatformDependent.canEnableTcpNoDelayByDefault()) { + try { + setTcpNoDelay(true); + } catch (Exception e) { + // Ignore. + } + } + } + + @Override + public Map, Object> getOptions() { + return getOptions( + super.getOptions(), + SO_RCVBUF, SO_SNDBUF, TCP_NODELAY, SO_KEEPALIVE, SO_REUSEADDR, SO_LINGER, IP_TOS, + ALLOW_HALF_CLOSURE); + } + + + @Override + public T getOption(ChannelOption option) { + if (option == SO_RCVBUF) { + return (T) Integer.valueOf(getReceiveBufferSize()); + } + if (option == SO_SNDBUF) { + return (T) Integer.valueOf(getSendBufferSize()); + } + if (option == TCP_NODELAY) { + return (T) Boolean.valueOf(isTcpNoDelay()); + } + if (option == SO_KEEPALIVE) { + return (T) Boolean.valueOf(isKeepAlive()); + } + if (option == SO_REUSEADDR) { + return (T) Boolean.valueOf(isReuseAddress()); + } + if (option == SO_LINGER) { + return (T) Integer.valueOf(getSoLinger()); + } + if (option == IP_TOS) { + return (T) Integer.valueOf(getTrafficClass()); + } + if (option == ALLOW_HALF_CLOSURE) { + return (T) Boolean.valueOf(isAllowHalfClosure()); + } + + return super.getOption(option); + } + + @Override + public boolean setOption(ChannelOption option, T value) { + validate(option, value); + + if (option == SO_RCVBUF) { + setReceiveBufferSize((Integer) value); + } else if (option == SO_SNDBUF) { + setSendBufferSize((Integer) value); + } else if (option == TCP_NODELAY) { + setTcpNoDelay((Boolean) value); + } else if (option == SO_KEEPALIVE) { + setKeepAlive((Boolean) value); + } else if (option == SO_REUSEADDR) { + setReuseAddress((Boolean) value); + } else if (option == SO_LINGER) { + setSoLinger((Integer) value); + } else if (option == IP_TOS) { + setTrafficClass((Integer) value); + } else if (option == ALLOW_HALF_CLOSURE) { + setAllowHalfClosure((Boolean) value); + } else { + return super.setOption(option, value); + } + + return true; + } + + @Override + public int getReceiveBufferSize() { + try { + return javaSocket.getReceiveBufferSize(); + } catch (SocketException e) { + throw new ChannelException(e); + } + } + + @Override + public int getSendBufferSize() { + try { + return javaSocket.getSendBufferSize(); + } catch (SocketException e) { + throw new ChannelException(e); + } + } + + @Override + public int getSoLinger() { + try { + return javaSocket.getSoLinger(); + } catch (SocketException e) { + throw new ChannelException(e); + } + } + + @Override + public int getTrafficClass() { + try { + return javaSocket.getTrafficClass(); + } catch (SocketException e) { + throw new ChannelException(e); + } + } + + @Override + public boolean isKeepAlive() { + try { + return javaSocket.getKeepAlive(); + } catch (SocketException e) { + throw new ChannelException(e); + } + } + + @Override + public boolean isReuseAddress() { + try { + return javaSocket.getReuseAddress(); + } catch (SocketException e) { + throw new ChannelException(e); + } + } + + @Override + public boolean isTcpNoDelay() { + try { + return javaSocket.getTcpNoDelay(); + } catch (SocketException e) { + throw new ChannelException(e); + } + } + + @Override + public SocketChannelConfig setKeepAlive(boolean keepAlive) { + try { + javaSocket.setKeepAlive(keepAlive); + } catch (SocketException e) { + throw new ChannelException(e); + } + return this; + } + + @Override + public SocketChannelConfig setPerformancePreferences( + int connectionTime, int latency, int bandwidth) { + javaSocket.setPerformancePreferences(connectionTime, latency, bandwidth); + return this; + } + + @Override + public SocketChannelConfig setReceiveBufferSize(int receiveBufferSize) { + try { + javaSocket.setReceiveBufferSize(receiveBufferSize); + } catch (SocketException e) { + throw new ChannelException(e); + } + return this; + } + + @Override + public SocketChannelConfig setReuseAddress(boolean reuseAddress) { + try { + javaSocket.setReuseAddress(reuseAddress); + } catch (SocketException e) { + throw new ChannelException(e); + } + return this; + } + + @Override + public SocketChannelConfig setSendBufferSize(int sendBufferSize) { + try { + javaSocket.setSendBufferSize(sendBufferSize); + } catch (SocketException e) { + throw new ChannelException(e); + } + return this; + } + + @Override + public SocketChannelConfig setSoLinger(int soLinger) { + try { + if (soLinger < 0) { + javaSocket.setSoLinger(false, 0); + } else { + javaSocket.setSoLinger(true, soLinger); + } + } catch (SocketException e) { + throw new ChannelException(e); + } + return this; + } + + @Override + public SocketChannelConfig setTcpNoDelay(boolean tcpNoDelay) { + try { + javaSocket.setTcpNoDelay(tcpNoDelay); + } catch (SocketException e) { + throw new ChannelException(e); + } + return this; + } + + @Override + public SocketChannelConfig setTrafficClass(int trafficClass) { + try { + javaSocket.setTrafficClass(trafficClass); + } catch (SocketException e) { + throw new ChannelException(e); + } + return this; + } + + @Override + public boolean isAllowHalfClosure() { + return allowHalfClosure; + } + + @Override + public SocketChannelConfig setAllowHalfClosure(boolean allowHalfClosure) { + this.allowHalfClosure = allowHalfClosure; + return this; + } + + @Override + public SocketChannelConfig setConnectTimeoutMillis(int connectTimeoutMillis) { + super.setConnectTimeoutMillis(connectTimeoutMillis); + return this; + } + + @Override + public SocketChannelConfig setMaxMessagesPerRead(int maxMessagesPerRead) { + super.setMaxMessagesPerRead(maxMessagesPerRead); + return this; + } + + @Override + public SocketChannelConfig setWriteSpinCount(int writeSpinCount) { + super.setWriteSpinCount(writeSpinCount); + return this; + } + + @Override + public SocketChannelConfig setAllocator(ByteBufAllocator allocator) { + super.setAllocator(allocator); + return this; + } + + @Override + public SocketChannelConfig setRecvByteBufAllocator(RecvByteBufAllocator allocator) { + super.setRecvByteBufAllocator(allocator); + return this; + } + + @Override + public SocketChannelConfig setAutoRead(boolean autoRead) { + super.setAutoRead(autoRead); + return this; + } + + @Override + public SocketChannelConfig setAutoClose(boolean autoClose) { + super.setAutoClose(autoClose); + return this; + } + + @Override + public SocketChannelConfig setWriteBufferHighWaterMark(int writeBufferHighWaterMark) { + super.setWriteBufferHighWaterMark(writeBufferHighWaterMark); + return this; + } + + @Override + public SocketChannelConfig setWriteBufferLowWaterMark(int writeBufferLowWaterMark) { + super.setWriteBufferLowWaterMark(writeBufferLowWaterMark); + return this; + } + + @Override + public SocketChannelConfig setMessageSizeEstimator(MessageSizeEstimator estimator) { + super.setMessageSizeEstimator(estimator); + return this; + } +} diff --git a/common/src/common/net/channel/socket/ServerSocketChannel.java b/common/src/common/net/channel/socket/ServerSocketChannel.java new file mode 100644 index 0000000..8808778 --- /dev/null +++ b/common/src/common/net/channel/socket/ServerSocketChannel.java @@ -0,0 +1,32 @@ +/* + * Copyright 2012 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ +package common.net.channel.socket; + +import java.net.InetSocketAddress; + +import common.net.channel.ServerChannel; + +/** + * A TCP/IP {@link ServerChannel} which accepts incoming TCP/IP connections. + */ +public interface ServerSocketChannel extends ServerChannel { + @Override + ServerSocketChannelConfig config(); + @Override + InetSocketAddress localAddress(); + @Override + InetSocketAddress remoteAddress(); +} diff --git a/common/src/common/net/channel/socket/ServerSocketChannelConfig.java b/common/src/common/net/channel/socket/ServerSocketChannelConfig.java new file mode 100644 index 0000000..56138d6 --- /dev/null +++ b/common/src/common/net/channel/socket/ServerSocketChannelConfig.java @@ -0,0 +1,104 @@ +/* + * Copyright 2012 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ +package common.net.channel.socket; + +import common.net.buffer.ByteBufAllocator; +import common.net.channel.ChannelConfig; +import common.net.channel.MessageSizeEstimator; +import common.net.channel.RecvByteBufAllocator; + +/** + * A {@link ChannelConfig} for a {@link ServerSocketChannel}. + * + *

Available options

+ * + * In addition to the options provided by {@link ChannelConfig}, + * {@link ServerSocketChannelConfig} allows the following options in the + * option map: + * + * + * + * + * + * + * + * + * + * + * + *
NameAssociated setter method
{@code "backlog"}{@link #setBacklog(int)}
{@code "reuseAddress"}{@link #setReuseAddress(boolean)}
{@code "receiveBufferSize"}{@link #setReceiveBufferSize(int)}
+ */ +public interface ServerSocketChannelConfig extends ChannelConfig { + + /** + * Gets the backlog value to specify when the channel binds to a local + * address. + */ + int getBacklog(); + + /** + * Sets the backlog value to specify when the channel binds to a local + * address. + */ + ServerSocketChannelConfig setBacklog(int backlog); + + /** + * Gets the {@link StandardSocketOptions#SO_REUSEADDR} option. + */ + boolean isReuseAddress(); + + /** + * Sets the {@link StandardSocketOptions#SO_REUSEADDR} option. + */ + ServerSocketChannelConfig setReuseAddress(boolean reuseAddress); + + /** + * Gets the {@link StandardSocketOptions#SO_RCVBUF} option. + */ + int getReceiveBufferSize(); + + /** + * Gets the {@link StandardSocketOptions#SO_SNDBUF} option. + */ + ServerSocketChannelConfig setReceiveBufferSize(int receiveBufferSize); + + /** + * Sets the performance preferences as specified in + * {@link ServerSocket#setPerformancePreferences(int, int, int)}. + */ + ServerSocketChannelConfig setPerformancePreferences(int connectionTime, int latency, int bandwidth); + + @Override + ServerSocketChannelConfig setConnectTimeoutMillis(int connectTimeoutMillis); + + @Override + ServerSocketChannelConfig setMaxMessagesPerRead(int maxMessagesPerRead); + + @Override + ServerSocketChannelConfig setWriteSpinCount(int writeSpinCount); + + @Override + ServerSocketChannelConfig setAllocator(ByteBufAllocator allocator); + + @Override + ServerSocketChannelConfig setRecvByteBufAllocator(RecvByteBufAllocator allocator); + + @Override + ServerSocketChannelConfig setAutoRead(boolean autoRead); + + @Override + ServerSocketChannelConfig setMessageSizeEstimator(MessageSizeEstimator estimator); +} diff --git a/common/src/common/net/channel/socket/SocketChannel.java b/common/src/common/net/channel/socket/SocketChannel.java new file mode 100644 index 0000000..f2b3006 --- /dev/null +++ b/common/src/common/net/channel/socket/SocketChannel.java @@ -0,0 +1,61 @@ +/* + * Copyright 2012 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ +package common.net.channel.socket; + +import java.net.InetSocketAddress; + +import common.net.channel.Channel; +import common.net.channel.ChannelFuture; +import common.net.channel.ChannelPromise; + +/** + * A TCP/IP socket {@link Channel}. + */ +public interface SocketChannel extends Channel { + @Override + ServerSocketChannel parent(); + + @Override + SocketChannelConfig config(); + @Override + InetSocketAddress localAddress(); + @Override + InetSocketAddress remoteAddress(); + + /** + * Returns {@code true} if and only if the remote peer shut down its output so that no more + * data is received from this channel. Note that the semantic of this method is different from + * that of {@link Socket#shutdownInput()} and {@link Socket#isInputShutdown()}. + */ + boolean isInputShutdown(); + + /** + * @see Socket#isOutputShutdown() + */ + boolean isOutputShutdown(); + + /** + * @see Socket#shutdownOutput() + */ + ChannelFuture shutdownOutput(); + + /** + * @see Socket#shutdownOutput() + * + * Will notify the given {@link ChannelPromise} + */ + ChannelFuture shutdownOutput(ChannelPromise future); +} diff --git a/common/src/common/net/channel/socket/SocketChannelConfig.java b/common/src/common/net/channel/socket/SocketChannelConfig.java new file mode 100644 index 0000000..044f91e --- /dev/null +++ b/common/src/common/net/channel/socket/SocketChannelConfig.java @@ -0,0 +1,177 @@ +/* + * Copyright 2012 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ +package common.net.channel.socket; + +import common.net.buffer.ByteBufAllocator; +import common.net.channel.ChannelConfig; +import common.net.channel.MessageSizeEstimator; +import common.net.channel.RecvByteBufAllocator; + +/** + * A {@link ChannelConfig} for a {@link SocketChannel}. + * + *

Available options

+ * + * In addition to the options provided by {@link ChannelConfig}, + * {@link SocketChannelConfig} allows the following options in the option map: + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
NameAssociated setter method
{@link ChannelOption#SO_KEEPALIVE}{@link #setKeepAlive(boolean)}
{@link ChannelOption#SO_REUSEADDR}{@link #setReuseAddress(boolean)}
{@link ChannelOption#SO_LINGER}{@link #setSoLinger(int)}
{@link ChannelOption#TCP_NODELAY}{@link #setTcpNoDelay(boolean)}
{@link ChannelOption#SO_RCVBUF}{@link #setReceiveBufferSize(int)}
{@link ChannelOption#SO_SNDBUF}{@link #setSendBufferSize(int)}
{@link ChannelOption#IP_TOS}{@link #setTrafficClass(int)}
{@link ChannelOption#ALLOW_HALF_CLOSURE}{@link #setAllowHalfClosure(boolean)}
+ */ +public interface SocketChannelConfig extends ChannelConfig { + + /** + * Gets the {@link StandardSocketOptions#TCP_NODELAY} option. Please note that the default value of this option + * is {@code true} unlike the operating system default ({@code false}). However, for some buggy platforms, such as + * Android, that shows erratic behavior with Nagle's algorithm disabled, the default value remains to be + * {@code false}. + */ + boolean isTcpNoDelay(); + + /** + * Sets the {@link StandardSocketOptions#TCP_NODELAY} option. Please note that the default value of this option + * is {@code true} unlike the operating system default ({@code false}). However, for some buggy platforms, such as + * Android, that shows erratic behavior with Nagle's algorithm disabled, the default value remains to be + * {@code false}. + */ + SocketChannelConfig setTcpNoDelay(boolean tcpNoDelay); + + /** + * Gets the {@link StandardSocketOptions#SO_LINGER} option. + */ + int getSoLinger(); + + /** + * Sets the {@link StandardSocketOptions#SO_LINGER} option. + */ + SocketChannelConfig setSoLinger(int soLinger); + + /** + * Gets the {@link StandardSocketOptions#SO_SNDBUF} option. + */ + int getSendBufferSize(); + + /** + * Sets the {@link StandardSocketOptions#SO_SNDBUF} option. + */ + SocketChannelConfig setSendBufferSize(int sendBufferSize); + + /** + * Gets the {@link StandardSocketOptions#SO_RCVBUF} option. + */ + int getReceiveBufferSize(); + + /** + * Sets the {@link StandardSocketOptions#SO_RCVBUF} option. + */ + SocketChannelConfig setReceiveBufferSize(int receiveBufferSize); + + /** + * Gets the {@link StandardSocketOptions#SO_KEEPALIVE} option. + */ + boolean isKeepAlive(); + + /** + * Sets the {@link StandardSocketOptions#SO_KEEPALIVE} option. + */ + SocketChannelConfig setKeepAlive(boolean keepAlive); + + /** + * Gets the {@link StandardSocketOptions#IP_TOS} option. + */ + int getTrafficClass(); + + /** + * Sets the {@link StandardSocketOptions#IP_TOS} option. + */ + SocketChannelConfig setTrafficClass(int trafficClass); + + /** + * Gets the {@link StandardSocketOptions#SO_REUSEADDR} option. + */ + boolean isReuseAddress(); + + /** + * Sets the {@link StandardSocketOptions#SO_REUSEADDR} option. + */ + SocketChannelConfig setReuseAddress(boolean reuseAddress); + + /** + * Sets the performance preferences as specified in + * {@link Socket#setPerformancePreferences(int, int, int)}. + */ + SocketChannelConfig setPerformancePreferences(int connectionTime, int latency, int bandwidth); + + /** + * Returns {@code true} if and only if the channel should not close itself when its remote + * peer shuts down output to make the connection half-closed. If {@code false}, the connection + * is closed automatically when the remote peer shuts down output. + */ + boolean isAllowHalfClosure(); + + /** + * Sets whether the channel should not close itself when its remote peer shuts down output to + * make the connection half-closed. If {@code true} the connection is not closed when the + * remote peer shuts down output. Instead, + * {@link ChannelInboundHandler#userEventTriggered(ChannelHandlerContext, Object)} + * is invoked with a {@link ChannelInputShutdownEvent} object. If {@code false}, the connection + * is closed automatically. + */ + SocketChannelConfig setAllowHalfClosure(boolean allowHalfClosure); + + @Override + SocketChannelConfig setConnectTimeoutMillis(int connectTimeoutMillis); + + @Override + SocketChannelConfig setMaxMessagesPerRead(int maxMessagesPerRead); + + @Override + SocketChannelConfig setWriteSpinCount(int writeSpinCount); + + @Override + SocketChannelConfig setAllocator(ByteBufAllocator allocator); + + @Override + SocketChannelConfig setRecvByteBufAllocator(RecvByteBufAllocator allocator); + + @Override + SocketChannelConfig setAutoRead(boolean autoRead); + + @Override + SocketChannelConfig setAutoClose(boolean autoClose); + + @Override + SocketChannelConfig setMessageSizeEstimator(MessageSizeEstimator estimator); +} diff --git a/common/src/common/net/channel/socket/nio/NioServerSocketChannel.java b/common/src/common/net/channel/socket/nio/NioServerSocketChannel.java new file mode 100644 index 0000000..b006e1f --- /dev/null +++ b/common/src/common/net/channel/socket/nio/NioServerSocketChannel.java @@ -0,0 +1,197 @@ +/* + * Copyright 2012 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ +package common.net.channel.socket.nio; + +import java.io.IOException; +import java.net.InetSocketAddress; +import java.net.ServerSocket; +import java.net.SocketAddress; +import java.nio.channels.SelectionKey; +import java.nio.channels.ServerSocketChannel; +import java.nio.channels.SocketChannel; +import java.nio.channels.spi.SelectorProvider; +import java.util.List; + +import common.net.channel.ChannelException; +import common.net.channel.ChannelMetadata; +import common.net.channel.ChannelOutboundBuffer; +import common.net.channel.nio.AbstractNioMessageChannel; +import common.net.channel.socket.DefaultServerSocketChannelConfig; +import common.net.channel.socket.ServerSocketChannelConfig; +import common.net.util.internal.logging.InternalLogger; +import common.net.util.internal.logging.InternalLoggerFactory; + +/** + * A {@link game.net.channel.socket.ServerSocketChannel} implementation which uses + * NIO selector based implementation to accept new connections. + */ +public class NioServerSocketChannel extends AbstractNioMessageChannel + implements common.net.channel.socket.ServerSocketChannel { + + private static final ChannelMetadata METADATA = new ChannelMetadata(false); + private static final SelectorProvider DEFAULT_SELECTOR_PROVIDER = SelectorProvider.provider(); + + private static final InternalLogger logger = InternalLoggerFactory.getInstance(NioServerSocketChannel.class); + + private static ServerSocketChannel newSocket(SelectorProvider provider) { + try { + /** + * Use the {@link SelectorProvider} to open {@link SocketChannel} and so remove condition in + * {@link SelectorProvider#provider()} which is called by each ServerSocketChannel.open() otherwise. + * + * See #2308. + */ + return provider.openServerSocketChannel(); + } catch (IOException e) { + throw new ChannelException( + "Failed to open a server socket.", e); + } + } + + private final ServerSocketChannelConfig config; + + /** + * Create a new instance + */ + public NioServerSocketChannel() { + this(newSocket(DEFAULT_SELECTOR_PROVIDER)); + } + + /** + * Create a new instance using the given {@link SelectorProvider}. + */ + public NioServerSocketChannel(SelectorProvider provider) { + this(newSocket(provider)); + } + + /** + * Create a new instance using the given {@link ServerSocketChannel}. + */ + public NioServerSocketChannel(ServerSocketChannel channel) { + super(null, channel, SelectionKey.OP_ACCEPT); + config = new NioServerSocketChannelConfig(this, javaChannel().socket()); + } + + @Override + public InetSocketAddress localAddress() { + return (InetSocketAddress) super.localAddress(); + } + + @Override + public ChannelMetadata metadata() { + return METADATA; + } + + @Override + public ServerSocketChannelConfig config() { + return config; + } + + @Override + public boolean isActive() { + return javaChannel().socket().isBound(); + } + + @Override + public InetSocketAddress remoteAddress() { + return null; + } + + @Override + protected ServerSocketChannel javaChannel() { + return (ServerSocketChannel) super.javaChannel(); + } + + @Override + protected SocketAddress localAddress0() { + return javaChannel().socket().getLocalSocketAddress(); + } + + @Override + protected void doBind(SocketAddress localAddress) throws Exception { + javaChannel().socket().bind(localAddress, config.getBacklog()); + } + + @Override + protected void doClose() throws Exception { + javaChannel().close(); + } + + @Override + protected int doReadMessages(List buf) throws Exception { + SocketChannel ch = javaChannel().accept(); + + try { + if (ch != null) { + buf.add(new NioSocketChannel(this, ch)); + return 1; + } + } catch (Throwable t) { + logger.warn("Failed to create a new channel from an accepted socket.", t); + + try { + ch.close(); + } catch (Throwable t2) { + logger.warn("Failed to close a socket.", t2); + } + } + + return 0; + } + + // Unnecessary stuff + @Override + protected boolean doConnect( + SocketAddress remoteAddress, SocketAddress localAddress) throws Exception { + throw new UnsupportedOperationException(); + } + + @Override + protected void doFinishConnect() throws Exception { + throw new UnsupportedOperationException(); + } + + @Override + protected SocketAddress remoteAddress0() { + return null; + } + + @Override + protected void doDisconnect() throws Exception { + throw new UnsupportedOperationException(); + } + + @Override + protected boolean doWriteMessage(Object msg, ChannelOutboundBuffer in) throws Exception { + throw new UnsupportedOperationException(); + } + + @Override + protected final Object filterOutboundMessage(Object msg) throws Exception { + throw new UnsupportedOperationException(); + } + + private final class NioServerSocketChannelConfig extends DefaultServerSocketChannelConfig { + private NioServerSocketChannelConfig(NioServerSocketChannel channel, ServerSocket javaSocket) { + super(channel, javaSocket); + } + + @Override + protected void autoReadCleared() { + setReadPending(false); + } + } +} diff --git a/common/src/common/net/channel/socket/nio/NioSocketChannel.java b/common/src/common/net/channel/socket/nio/NioSocketChannel.java new file mode 100644 index 0000000..1ce8c3b --- /dev/null +++ b/common/src/common/net/channel/socket/nio/NioSocketChannel.java @@ -0,0 +1,320 @@ +/* + * Copyright 2012 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ +package common.net.channel.socket.nio; + +import java.io.IOException; +import java.net.InetSocketAddress; +import java.net.Socket; +import java.net.SocketAddress; +import java.nio.ByteBuffer; +import java.nio.channels.SelectionKey; +import java.nio.channels.SocketChannel; +import java.nio.channels.spi.SelectorProvider; + +import common.net.buffer.ByteBuf; +import common.net.channel.Channel; +import common.net.channel.ChannelException; +import common.net.channel.ChannelFuture; +import common.net.channel.ChannelMetadata; +import common.net.channel.ChannelOutboundBuffer; +import common.net.channel.ChannelPromise; +import common.net.channel.EventLoop; +import common.net.channel.nio.AbstractNioByteChannel; +import common.net.channel.socket.DefaultSocketChannelConfig; +import common.net.channel.socket.ServerSocketChannel; +import common.net.channel.socket.SocketChannelConfig; +import common.net.util.internal.OneTimeTask; + +/** + * {@link game.net.channel.socket.SocketChannel} which uses NIO selector based implementation. + */ +public class NioSocketChannel extends AbstractNioByteChannel implements common.net.channel.socket.SocketChannel { + + private static final ChannelMetadata METADATA = new ChannelMetadata(false); + private static final SelectorProvider DEFAULT_SELECTOR_PROVIDER = SelectorProvider.provider(); + + private static SocketChannel newSocket(SelectorProvider provider) { + try { + /** + * Use the {@link SelectorProvider} to open {@link SocketChannel} and so remove condition in + * {@link SelectorProvider#provider()} which is called by each SocketChannel.open() otherwise. + * + * See #2308. + */ + return provider.openSocketChannel(); + } catch (IOException e) { + throw new ChannelException("Failed to open a socket.", e); + } + } + + private final SocketChannelConfig config; + + /** + * Create a new instance + */ + public NioSocketChannel() { + this(newSocket(DEFAULT_SELECTOR_PROVIDER)); + } + + /** + * Create a new instance using the given {@link SelectorProvider}. + */ + public NioSocketChannel(SelectorProvider provider) { + this(newSocket(provider)); + } + + /** + * Create a new instance using the given {@link SocketChannel}. + */ + public NioSocketChannel(SocketChannel socket) { + this(null, socket); + } + + /** + * Create a new instance + * + * @param parent the {@link Channel} which created this instance or {@code null} if it was created by the user + * @param socket the {@link SocketChannel} which will be used + */ + public NioSocketChannel(Channel parent, SocketChannel socket) { + super(parent, socket); + config = new NioSocketChannelConfig(this, socket.socket()); + } + + @Override + public ServerSocketChannel parent() { + return (ServerSocketChannel) super.parent(); + } + + @Override + public ChannelMetadata metadata() { + return METADATA; + } + + @Override + public SocketChannelConfig config() { + return config; + } + + @Override + protected SocketChannel javaChannel() { + return (SocketChannel) super.javaChannel(); + } + + @Override + public boolean isActive() { + SocketChannel ch = javaChannel(); + return ch.isOpen() && ch.isConnected(); + } + + @Override + public boolean isInputShutdown() { + return super.isInputShutdown(); + } + + @Override + public InetSocketAddress localAddress() { + return (InetSocketAddress) super.localAddress(); + } + + @Override + public InetSocketAddress remoteAddress() { + return (InetSocketAddress) super.remoteAddress(); + } + + @Override + public boolean isOutputShutdown() { + return javaChannel().socket().isOutputShutdown() || !isActive(); + } + + @Override + public ChannelFuture shutdownOutput() { + return shutdownOutput(newPromise()); + } + + @Override + public ChannelFuture shutdownOutput(final ChannelPromise promise) { + EventLoop loop = eventLoop(); + if (loop.inEventLoop()) { + try { + javaChannel().socket().shutdownOutput(); + promise.setSuccess(); + } catch (Throwable t) { + promise.setFailure(t); + } + } else { + loop.execute(new OneTimeTask() { + @Override + public void run() { + shutdownOutput(promise); + } + }); + } + return promise; + } + + @Override + protected SocketAddress localAddress0() { + return javaChannel().socket().getLocalSocketAddress(); + } + + @Override + protected SocketAddress remoteAddress0() { + return javaChannel().socket().getRemoteSocketAddress(); + } + + @Override + protected void doBind(SocketAddress localAddress) throws Exception { + javaChannel().socket().bind(localAddress); + } + + @Override + protected boolean doConnect(SocketAddress remoteAddress, SocketAddress localAddress) throws Exception { + if (localAddress != null) { + javaChannel().socket().bind(localAddress); + } + + boolean success = false; + try { + boolean connected = javaChannel().connect(remoteAddress); + if (!connected) { + selectionKey().interestOps(SelectionKey.OP_CONNECT); + } + success = true; + return connected; + } finally { + if (!success) { + doClose(); + } + } + } + + @Override + protected void doFinishConnect() throws Exception { + if (!javaChannel().finishConnect()) { + throw new Error(); + } + } + + @Override + protected void doDisconnect() throws Exception { + doClose(); + } + + @Override + protected void doClose() throws Exception { + javaChannel().close(); + } + + @Override + protected int doReadBytes(ByteBuf byteBuf) throws Exception { + return byteBuf.writeBytes(javaChannel(), byteBuf.writableBytes()); + } + + @Override + protected int doWriteBytes(ByteBuf buf) throws Exception { + final int expectedWrittenBytes = buf.readableBytes(); + return buf.readBytes(javaChannel(), expectedWrittenBytes); + } + +// @Override +// protected long doWriteFileRegion(FileRegion region) throws Exception { +// final long position = region.transfered(); +// return region.transferTo(javaChannel(), position); +// } + + @Override + protected void doWrite(ChannelOutboundBuffer in) throws Exception { + for (;;) { + int size = in.size(); + if (size == 0) { + // All written so clear OP_WRITE + clearOpWrite(); + break; + } + long writtenBytes = 0; + boolean done = false; + boolean setOpWrite = false; + + // Ensure the pending writes are made of ByteBufs only. + ByteBuffer[] nioBuffers = in.nioBuffers(); + int nioBufferCnt = in.nioBufferCount(); + long expectedWrittenBytes = in.nioBufferSize(); + SocketChannel ch = javaChannel(); + + // Always us nioBuffers() to workaround data-corruption. + // See https://github.com/netty/netty/issues/2761 + switch (nioBufferCnt) { + case 0: + // We have something else beside ByteBuffers to write so fallback to normal writes. + super.doWrite(in); + return; + case 1: + // Only one ByteBuf so use non-gathering write + ByteBuffer nioBuffer = nioBuffers[0]; + for (int i = config().getWriteSpinCount() - 1; i >= 0; i --) { + final int localWrittenBytes = ch.write(nioBuffer); + if (localWrittenBytes == 0) { + setOpWrite = true; + break; + } + expectedWrittenBytes -= localWrittenBytes; + writtenBytes += localWrittenBytes; + if (expectedWrittenBytes == 0) { + done = true; + break; + } + } + break; + default: + for (int i = config().getWriteSpinCount() - 1; i >= 0; i --) { + final long localWrittenBytes = ch.write(nioBuffers, 0, nioBufferCnt); + if (localWrittenBytes == 0) { + setOpWrite = true; + break; + } + expectedWrittenBytes -= localWrittenBytes; + writtenBytes += localWrittenBytes; + if (expectedWrittenBytes == 0) { + done = true; + break; + } + } + break; + } + + // Release the fully written buffers, and update the indexes of the partially written buffer. + in.removeBytes(writtenBytes); + + if (!done) { + // Did not write all buffers completely. + incompleteWrite(setOpWrite); + break; + } + } + } + + private final class NioSocketChannelConfig extends DefaultSocketChannelConfig { + private NioSocketChannelConfig(NioSocketChannel channel, Socket javaSocket) { + super(channel, javaSocket); + } + + @Override + protected void autoReadCleared() { + setReadPending(false); + } + } +} diff --git a/common/src/common/net/handler/codec/ByteToMessageDecoder.java b/common/src/common/net/handler/codec/ByteToMessageDecoder.java new file mode 100644 index 0000000..9957e17 --- /dev/null +++ b/common/src/common/net/handler/codec/ByteToMessageDecoder.java @@ -0,0 +1,306 @@ +/* + * Copyright 2012 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ +package common.net.handler.codec; + +import java.util.List; + +import common.net.buffer.ByteBuf; +import common.net.buffer.Unpooled; +import common.net.channel.ChannelHandlerContext; +import common.net.channel.ChannelInboundHandlerAdapter; +import common.net.util.internal.RecyclableArrayList; +import common.net.util.internal.StringUtil; + +/** + * {@link ChannelInboundHandlerAdapter} which decodes bytes in a stream-like fashion from one {@link ByteBuf} to an + * other Message type. + * + * For example here is an implementation which reads all readable bytes from + * the input {@link ByteBuf} and create a new {@link ByteBuf}. + * + *
+ *     public class SquareDecoder extends {@link ByteToMessageDecoder} {
+ *         {@code @Override}
+ *         public void decode({@link ChannelHandlerContext} ctx, {@link ByteBuf} in, List<Object> out)
+ *                 throws {@link Exception} {
+ *             out.add(in.readBytes(in.readableBytes()));
+ *         }
+ *     }
+ * 
+ * + * Be aware that sub-classes of {@link ByteToMessageDecoder} MUST NOT + * annotated with {@link @Sharable}. + */ +public abstract class ByteToMessageDecoder extends ChannelInboundHandlerAdapter { + + ByteBuf cumulation; + private boolean singleDecode; + private boolean decodeWasNull; + private boolean first; + + protected ByteToMessageDecoder() { + if (isSharable()) { + throw new IllegalStateException("@Sharable annotation is not allowed"); + } + } + + /** + * If set then only one message is decoded on each {@link #channelRead(ChannelHandlerContext, Object)} + * call. This may be useful if you need to do some protocol upgrade and want to make sure nothing is mixed up. + * + * Default is {@code false} as this has performance impacts. + */ + public void setSingleDecode(boolean singleDecode) { + this.singleDecode = singleDecode; + } + + /** + * If {@code true} then only one message is decoded on each + * {@link #channelRead(ChannelHandlerContext, Object)} call. + * + * Default is {@code false} as this has performance impacts. + */ + public boolean isSingleDecode() { + return singleDecode; + } + + /** + * Returns the actual number of readable bytes in the internal cumulative + * buffer of this decoder. You usually do not need to rely on this value + * to write a decoder. Use it only when you must use it at your own risk. + * This method is a shortcut to {@link #internalBuffer() internalBuffer().readableBytes()}. + */ + protected int actualReadableBytes() { + return internalBuffer().readableBytes(); + } + + /** + * Returns the internal cumulative buffer of this decoder. You usually + * do not need to access the internal buffer directly to write a decoder. + * Use it only when you must use it at your own risk. + */ + protected ByteBuf internalBuffer() { + if (cumulation != null) { + return cumulation; + } else { + return Unpooled.EMPTY_BUFFER; + } + } + + @Override + public final void handlerRemoved(ChannelHandlerContext ctx) throws Exception { + ByteBuf buf = internalBuffer(); + int readable = buf.readableBytes(); + if (buf.isReadable()) { + ByteBuf bytes = buf.readBytes(readable); + buf.release(); + ctx.fireChannelRead(bytes); + } else { + buf.release(); + } + cumulation = null; + ctx.fireChannelReadComplete(); + handlerRemoved0(ctx); + } + + /** + * Gets called after the {@link ByteToMessageDecoder} was removed from the actual context and it doesn't handle + * events anymore. + */ + protected void handlerRemoved0(ChannelHandlerContext ctx) throws Exception { } + + @Override + public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { + if (msg instanceof ByteBuf) { + RecyclableArrayList out = RecyclableArrayList.newInstance(); + try { + ByteBuf data = (ByteBuf) msg; + first = cumulation == null; + if (first) { + cumulation = data; + } else { + if (cumulation.writerIndex() > cumulation.maxCapacity() - data.readableBytes() + || cumulation.refCnt() > 1) { + // Expand cumulation (by replace it) when either there is not more room in the buffer + // or if the refCnt is greater then 1 which may happen when the user use slice().retain() or + // duplicate().retain(). + // + // See: + // - https://github.com/netty/netty/issues/2327 + // - https://github.com/netty/netty/issues/1764 + expandCumulation(ctx, data.readableBytes()); + } + cumulation.writeBytes(data); + data.release(); + } + callDecode(ctx, cumulation, out); + } catch (DecoderException e) { + throw e; + } catch (Throwable t) { + throw new DecoderException(t); + } finally { + if (cumulation != null && !cumulation.isReadable()) { + cumulation.release(); + cumulation = null; + } + int size = out.size(); + decodeWasNull = size == 0; + + for (int i = 0; i < size; i ++) { + ctx.fireChannelRead(out.get(i)); + } + out.recycle(); + } + } else { + ctx.fireChannelRead(msg); + } + } + + private void expandCumulation(ChannelHandlerContext ctx, int readable) { + ByteBuf oldCumulation = cumulation; + cumulation = ctx.alloc().buffer(oldCumulation.readableBytes() + readable); + cumulation.writeBytes(oldCumulation); + oldCumulation.release(); + } + + @Override + public void channelReadComplete(ChannelHandlerContext ctx) throws Exception { + if (cumulation != null && !first && cumulation.refCnt() == 1) { + // discard some bytes if possible to make more room in the + // buffer but only if the refCnt == 1 as otherwise the user may have + // used slice().retain() or duplicate().retain(). + // + // See: + // - https://github.com/netty/netty/issues/2327 + // - https://github.com/netty/netty/issues/1764 + cumulation.discardSomeReadBytes(); + } + if (decodeWasNull) { + decodeWasNull = false; + if (!ctx.channel().config().isAutoRead()) { + ctx.read(); + } + } + ctx.fireChannelReadComplete(); + } + + @Override + public void channelInactive(ChannelHandlerContext ctx) throws Exception { + RecyclableArrayList out = RecyclableArrayList.newInstance(); + try { + if (cumulation != null) { + callDecode(ctx, cumulation, out); + decodeLast(ctx, cumulation, out); + } else { + decodeLast(ctx, Unpooled.EMPTY_BUFFER, out); + } + } catch (DecoderException e) { + throw e; + } catch (Exception e) { + throw new DecoderException(e); + } finally { + try { + if (cumulation != null) { + cumulation.release(); + cumulation = null; + } + int size = out.size(); + for (int i = 0; i < size; i++) { + ctx.fireChannelRead(out.get(i)); + } + if (size > 0) { + // Something was read, call fireChannelReadComplete() + ctx.fireChannelReadComplete(); + } + ctx.fireChannelInactive(); + } finally { + // recycle in all cases + out.recycle(); + } + } + } + + /** + * Called once data should be decoded from the given {@link ByteBuf}. This method will call + * {@link #decode(ChannelHandlerContext, ByteBuf, List)} as long as decoding should take place. + * + * @param ctx the {@link ChannelHandlerContext} which this {@link ByteToMessageDecoder} belongs to + * @param in the {@link ByteBuf} from which to read data + * @param out the {@link List} to which decoded messages should be added + */ + protected void callDecode(ChannelHandlerContext ctx, ByteBuf in, List out) { + try { + while (in.isReadable()) { + int outSize = out.size(); + int oldInputLength = in.readableBytes(); + decode(ctx, in, out); + + // Check if this handler was removed before continuing the loop. + // If it was removed, it is not safe to continue to operate on the buffer. + // + // See https://github.com/netty/netty/issues/1664 + if (ctx.isRemoved()) { + break; + } + + if (outSize == out.size()) { + if (oldInputLength == in.readableBytes()) { + break; + } else { + continue; + } + } + + if (oldInputLength == in.readableBytes()) { + throw new DecoderException( + StringUtil.simpleClassName(getClass()) + + ".decode() did not read anything but decoded a message."); + } + + if (isSingleDecode()) { + break; + } + } + } catch (DecoderException e) { + throw e; + } catch (Throwable cause) { + throw new DecoderException(cause); + } + } + + /** + * Decode the from one {@link ByteBuf} to an other. This method will be called till either the input + * {@link ByteBuf} has nothing to read when return from this method or till nothing was read from the input + * {@link ByteBuf}. + * + * @param ctx the {@link ChannelHandlerContext} which this {@link ByteToMessageDecoder} belongs to + * @param in the {@link ByteBuf} from which to read data + * @param out the {@link List} to which decoded messages should be added + * @throws Exception is thrown if an error accour + */ + protected abstract void decode(ChannelHandlerContext ctx, ByteBuf in, List out) throws Exception; + + /** + * Is called one last time when the {@link ChannelHandlerContext} goes in-active. Which means the + * {@link #channelInactive(ChannelHandlerContext)} was triggered. + * + * By default this will just call {@link #decode(ChannelHandlerContext, ByteBuf, List)} but sub-classes may + * override this for some special cleanup operation. + */ + protected void decodeLast(ChannelHandlerContext ctx, ByteBuf in, List out) throws Exception { + decode(ctx, in, out); + } +} diff --git a/common/src/common/net/handler/codec/CodecException.java b/common/src/common/net/handler/codec/CodecException.java new file mode 100644 index 0000000..e024083 --- /dev/null +++ b/common/src/common/net/handler/codec/CodecException.java @@ -0,0 +1,51 @@ +/* + * Copyright 2012 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ +package common.net.handler.codec; + +/** + * An {@link Exception} which is thrown by a codec. + */ +public class CodecException extends RuntimeException { + + private static final long serialVersionUID = -1464830400709348473L; + + /** + * Creates a new instance. + */ + public CodecException() { + } + + /** + * Creates a new instance. + */ + public CodecException(String message, Throwable cause) { + super(message, cause); + } + + /** + * Creates a new instance. + */ + public CodecException(String message) { + super(message); + } + + /** + * Creates a new instance. + */ + public CodecException(Throwable cause) { + super(cause); + } +} diff --git a/common/src/common/net/handler/codec/CorruptedFrameException.java b/common/src/common/net/handler/codec/CorruptedFrameException.java new file mode 100644 index 0000000..d62f750 --- /dev/null +++ b/common/src/common/net/handler/codec/CorruptedFrameException.java @@ -0,0 +1,52 @@ +/* + * Copyright 2012 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ +package common.net.handler.codec; + +/** + * An {@link DecoderException} which is thrown when the received frame data could not be decoded by + * an inbound handler. + */ +public class CorruptedFrameException extends DecoderException { + + private static final long serialVersionUID = 3918052232492988408L; + + /** + * Creates a new instance. + */ + public CorruptedFrameException() { + } + + /** + * Creates a new instance. + */ + public CorruptedFrameException(String message, Throwable cause) { + super(message, cause); + } + + /** + * Creates a new instance. + */ + public CorruptedFrameException(String message) { + super(message); + } + + /** + * Creates a new instance. + */ + public CorruptedFrameException(Throwable cause) { + super(cause); + } +} diff --git a/common/src/common/net/handler/codec/DecoderException.java b/common/src/common/net/handler/codec/DecoderException.java new file mode 100644 index 0000000..35f2beb --- /dev/null +++ b/common/src/common/net/handler/codec/DecoderException.java @@ -0,0 +1,51 @@ +/* + * Copyright 2012 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ +package common.net.handler.codec; + +/** + * An {@link CodecException} which is thrown by a dencoder. + */ +public class DecoderException extends CodecException { + + private static final long serialVersionUID = 6926716840699621852L; + + /** + * Creates a new instance. + */ + public DecoderException() { + } + + /** + * Creates a new instance. + */ + public DecoderException(String message, Throwable cause) { + super(message, cause); + } + + /** + * Creates a new instance. + */ + public DecoderException(String message) { + super(message); + } + + /** + * Creates a new instance. + */ + public DecoderException(Throwable cause) { + super(cause); + } +} diff --git a/common/src/common/net/handler/codec/EncoderException.java b/common/src/common/net/handler/codec/EncoderException.java new file mode 100644 index 0000000..549455d --- /dev/null +++ b/common/src/common/net/handler/codec/EncoderException.java @@ -0,0 +1,51 @@ +/* + * Copyright 2012 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ +package common.net.handler.codec; + +/** + * An {@link CodecException} which is thrown by an encoder. + */ +public class EncoderException extends CodecException { + + private static final long serialVersionUID = -5086121160476476774L; + + /** + * Creates a new instance. + */ + public EncoderException() { + } + + /** + * Creates a new instance. + */ + public EncoderException(String message, Throwable cause) { + super(message, cause); + } + + /** + * Creates a new instance. + */ + public EncoderException(String message) { + super(message); + } + + /** + * Creates a new instance. + */ + public EncoderException(Throwable cause) { + super(cause); + } +} diff --git a/common/src/common/net/handler/codec/MessageToByteEncoder.java b/common/src/common/net/handler/codec/MessageToByteEncoder.java new file mode 100644 index 0000000..9cb059d --- /dev/null +++ b/common/src/common/net/handler/codec/MessageToByteEncoder.java @@ -0,0 +1,154 @@ +/* + * Copyright 2012 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ +package common.net.handler.codec; + +import common.net.buffer.ByteBuf; +import common.net.buffer.Unpooled; +import common.net.channel.ChannelHandlerContext; +import common.net.channel.ChannelOutboundHandlerAdapter; +import common.net.channel.ChannelPromise; +import common.net.util.ReferenceCountUtil; +import common.net.util.internal.TypeParameterMatcher; + + +/** + * {@link ChannelOutboundHandlerAdapter} which encodes message in a stream-like fashion from one message to an + * {@link ByteBuf}. + * + * + * Example implementation which encodes {@link Integer}s to a {@link ByteBuf}. + * + *
+ *     public class IntegerEncoder extends {@link MessageToByteEncoder}<{@link Integer}> {
+ *         {@code @Override}
+ *         public void encode({@link ChannelHandlerContext} ctx, {@link Integer} msg, {@link ByteBuf} out)
+ *                 throws {@link Exception} {
+ *             out.writeInt(msg);
+ *         }
+ *     }
+ * 
+ */ +public abstract class MessageToByteEncoder extends ChannelOutboundHandlerAdapter { + + private final TypeParameterMatcher matcher; + private final boolean preferDirect; + + /** + * @see {@link #MessageToByteEncoder(boolean)} with {@code true} as boolean parameter. + */ + protected MessageToByteEncoder() { + this(true); + } + + /** + * @see {@link #MessageToByteEncoder(Class, boolean)} with {@code true} as boolean value. + */ + protected MessageToByteEncoder(Class outboundMessageType) { + this(outboundMessageType, true); + } + + /** + * Create a new instance which will try to detect the types to match out of the type parameter of the class. + * + * @param preferDirect {@code true} if a direct {@link ByteBuf} should be tried to be used as target for + * the encoded messages. If {@code false} is used it will allocate a heap + * {@link ByteBuf}, which is backed by an byte array. + */ + protected MessageToByteEncoder(boolean preferDirect) { + matcher = TypeParameterMatcher.find(this, MessageToByteEncoder.class, "I"); + this.preferDirect = preferDirect; + } + + /** + * Create a new instance + * + * @param outboundMessageType The tpye of messages to match + * @param preferDirect {@code true} if a direct {@link ByteBuf} should be tried to be used as target for + * the encoded messages. If {@code false} is used it will allocate a heap + * {@link ByteBuf}, which is backed by an byte array. + */ + protected MessageToByteEncoder(Class outboundMessageType, boolean preferDirect) { + matcher = TypeParameterMatcher.get(outboundMessageType); + this.preferDirect = preferDirect; + } + + /** + * Returns {@code true} if the given message should be handled. If {@code false} it will be passed to the next + * {@link ChannelOutboundHandler} in the {@link ChannelPipeline}. + */ + public boolean acceptOutboundMessage(Object msg) throws Exception { + return matcher.match(msg); + } + + @Override + public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception { + ByteBuf buf = null; + try { + if (acceptOutboundMessage(msg)) { + + I cast = (I) msg; + buf = allocateBuffer(ctx, cast, preferDirect); + try { + encode(ctx, cast, buf); + } finally { + ReferenceCountUtil.release(cast); + } + + if (buf.isReadable()) { + ctx.write(buf, promise); + } else { + buf.release(); + ctx.write(Unpooled.EMPTY_BUFFER, promise); + } + buf = null; + } else { + ctx.write(msg, promise); + } + } catch (EncoderException e) { + throw e; + } catch (Throwable e) { + throw new EncoderException(e); + } finally { + if (buf != null) { + buf.release(); + } + } + } + + /** + * Allocate a {@link ByteBuf} which will be used as argument of {@link #encode(ChannelHandlerContext, I, ByteBuf)}. + * Sub-classes may override this method to returna {@link ByteBuf} with a perfect matching {@code initialCapacity}. + */ + protected ByteBuf allocateBuffer(ChannelHandlerContext ctx, I msg, + boolean preferDirect) throws Exception { + if (preferDirect) { + return ctx.alloc().ioBuffer(); + } else { + return ctx.alloc().heapBuffer(); + } + } + + /** + * Encode a message into a {@link ByteBuf}. This method will be called for each written message that can be handled + * by this encoder. + * + * @param ctx the {@link ChannelHandlerContext} which this {@link MessageToByteEncoder} belongs to + * @param msg the message to encode + * @param out the {@link ByteBuf} into which the encoded message will be written + * @throws Exception is thrown if an error accour + */ + protected abstract void encode(ChannelHandlerContext ctx, I msg, ByteBuf out) throws Exception; +} diff --git a/common/src/common/net/handler/codec/MessageToMessageDecoder.java b/common/src/common/net/handler/codec/MessageToMessageDecoder.java new file mode 100644 index 0000000..6b6c2eb --- /dev/null +++ b/common/src/common/net/handler/codec/MessageToMessageDecoder.java @@ -0,0 +1,115 @@ +/* + * Copyright 2012 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ +package common.net.handler.codec; + +import java.util.List; + +import common.net.channel.ChannelHandlerContext; +import common.net.channel.ChannelInboundHandlerAdapter; +import common.net.util.ReferenceCountUtil; +import common.net.util.internal.RecyclableArrayList; +import common.net.util.internal.TypeParameterMatcher; + +/** + * {@link ChannelInboundHandlerAdapter} which decodes from one message to an other message. + * + * + * For example here is an implementation which decodes a {@link String} to an {@link Integer} which represent + * the length of the {@link String}. + * + *
+ *     public class StringToIntegerDecoder extends
+ *             {@link MessageToMessageDecoder}<{@link String}> {
+ *
+ *         {@code @Override}
+ *         public void decode({@link ChannelHandlerContext} ctx, {@link String} message,
+ *                            List<Object> out) throws {@link Exception} {
+ *             out.add(message.length());
+ *         }
+ *     }
+ * 
+ * + * Be aware that you need to call {@link ReferenceCounted#retain()} on messages that are just passed through if they + * are of type {@link ReferenceCounted}. This is needed as the {@link MessageToMessageDecoder} will call + * {@link ReferenceCounted#release()} on decoded messages. + * + */ +public abstract class MessageToMessageDecoder extends ChannelInboundHandlerAdapter { + + private final TypeParameterMatcher matcher; + + /** + * Create a new instance which will try to detect the types to match out of the type parameter of the class. + */ + protected MessageToMessageDecoder() { + matcher = TypeParameterMatcher.find(this, MessageToMessageDecoder.class, "I"); + } + + /** + * Create a new instance + * + * @param inboundMessageType The type of messages to match and so decode + */ + protected MessageToMessageDecoder(Class inboundMessageType) { + matcher = TypeParameterMatcher.get(inboundMessageType); + } + + /** + * Returns {@code true} if the given message should be handled. If {@code false} it will be passed to the next + * {@link ChannelInboundHandler} in the {@link ChannelPipeline}. + */ + public boolean acceptInboundMessage(Object msg) throws Exception { + return matcher.match(msg); + } + + @Override + public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { + RecyclableArrayList out = RecyclableArrayList.newInstance(); + try { + if (acceptInboundMessage(msg)) { + I cast = (I) msg; + try { + decode(ctx, cast, out); + } finally { + ReferenceCountUtil.release(cast); + } + } else { + out.add(msg); + } + } catch (DecoderException e) { + throw e; + } catch (Exception e) { + throw new DecoderException(e); + } finally { + int size = out.size(); + for (int i = 0; i < size; i ++) { + ctx.fireChannelRead(out.get(i)); + } + out.recycle(); + } + } + + /** + * Decode from one message to an other. This method will be called for each written message that can be handled + * by this encoder. + * + * @param ctx the {@link ChannelHandlerContext} which this {@link MessageToMessageDecoder} belongs to + * @param msg the message to decode to an other one + * @param out the {@link List} to which decoded messages should be added + * @throws Exception is thrown if an error accour + */ + protected abstract void decode(ChannelHandlerContext ctx, I msg, List out) throws Exception; +} diff --git a/common/src/common/net/handler/timeout/ReadTimeoutException.java b/common/src/common/net/handler/timeout/ReadTimeoutException.java new file mode 100644 index 0000000..3216773 --- /dev/null +++ b/common/src/common/net/handler/timeout/ReadTimeoutException.java @@ -0,0 +1,29 @@ +/* + * Copyright 2012 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ +package common.net.handler.timeout; + +/** + * A {@link TimeoutException} raised by {@link ReadTimeoutHandler} when no data + * was read within a certain period of time. + */ +public final class ReadTimeoutException extends TimeoutException { + + private static final long serialVersionUID = 169287984113283421L; + + public static final ReadTimeoutException INSTANCE = new ReadTimeoutException(); + + private ReadTimeoutException() { } +} diff --git a/common/src/common/net/handler/timeout/ReadTimeoutHandler.java b/common/src/common/net/handler/timeout/ReadTimeoutHandler.java new file mode 100644 index 0000000..d21019c --- /dev/null +++ b/common/src/common/net/handler/timeout/ReadTimeoutHandler.java @@ -0,0 +1,218 @@ +/* + * Copyright 2012 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ +package common.net.handler.timeout; + +import java.util.concurrent.ScheduledFuture; +import java.util.concurrent.TimeUnit; + +import common.net.channel.ChannelHandlerContext; +import common.net.channel.ChannelInboundHandlerAdapter; + +/** + * Raises a {@link ReadTimeoutException} when no data was read within a certain + * period of time. + * + *
+ * // The connection is closed when there is no inbound traffic
+ * // for 30 seconds.
+ *
+ * public class MyChannelInitializer extends {@link ChannelInitializer}<{@link Channel}> {
+ *     public void initChannel({@link Channel} channel) {
+ *         channel.pipeline().addLast("readTimeoutHandler", new {@link ReadTimeoutHandler}(30);
+ *         channel.pipeline().addLast("myHandler", new MyHandler());
+ *     }
+ * }
+ *
+ * // Handler should handle the {@link ReadTimeoutException}.
+ * public class MyHandler extends {@link ChannelDuplexHandler} {
+ *     {@code @Override}
+ *     public void exceptionCaught({@link ChannelHandlerContext} ctx, {@link Throwable} cause)
+ *             throws {@link Exception} {
+ *         if (cause instanceof {@link ReadTimeoutException}) {
+ *             // do something
+ *         } else {
+ *             super.exceptionCaught(ctx, cause);
+ *         }
+ *     }
+ * }
+ *
+ * {@link ServerBootstrap} bootstrap = ...;
+ * ...
+ * bootstrap.childHandler(new MyChannelInitializer());
+ * ...
+ * 
+ * @see WriteTimeoutHandler + * @see IdleStateHandler + */ +public class ReadTimeoutHandler extends ChannelInboundHandlerAdapter { + private static final long MIN_TIMEOUT_NANOS = TimeUnit.MILLISECONDS.toNanos(1); + + private final long timeoutNanos; + + private volatile ScheduledFuture timeout; + private volatile long lastReadTime; + + private volatile int state; // 0 - none, 1 - Initialized, 2 - Destroyed; + + private boolean closed; + + /** + * Creates a new instance. + * + * @param timeoutSeconds + * read timeout in seconds + */ + public ReadTimeoutHandler(int timeoutSeconds) { + this(timeoutSeconds, TimeUnit.SECONDS); + } + + /** + * Creates a new instance. + * + * @param timeout + * read timeout + * @param unit + * the {@link TimeUnit} of {@code timeout} + */ + public ReadTimeoutHandler(long timeout, TimeUnit unit) { + if (unit == null) { + throw new NullPointerException("unit"); + } + + if (timeout <= 0) { + timeoutNanos = 0; + } else { + timeoutNanos = Math.max(unit.toNanos(timeout), MIN_TIMEOUT_NANOS); + } + } + + @Override + public void handlerAdded(ChannelHandlerContext ctx) throws Exception { + if (ctx.channel().isActive() && ctx.channel().isRegistered()) { + // channelActvie() event has been fired already, which means this.channelActive() will + // not be invoked. We have to initialize here instead. + initialize(ctx); + } else { + // channelActive() event has not been fired yet. this.channelActive() will be invoked + // and initialization will occur there. + } + } + + @Override + public void handlerRemoved(ChannelHandlerContext ctx) throws Exception { + destroy(); + } + + @Override + public void channelRegistered(ChannelHandlerContext ctx) throws Exception { + // Initialize early if channel is active already. + if (ctx.channel().isActive()) { + initialize(ctx); + } + super.channelRegistered(ctx); + } + + @Override + public void channelActive(ChannelHandlerContext ctx) throws Exception { + // This method will be invoked only if this handler was added + // before channelActive() event is fired. If a user adds this handler + // after the channelActive() event, initialize() will be called by beforeAdd(). + initialize(ctx); + super.channelActive(ctx); + } + + @Override + public void channelInactive(ChannelHandlerContext ctx) throws Exception { + destroy(); + super.channelInactive(ctx); + } + + @Override + public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { + lastReadTime = System.nanoTime(); + ctx.fireChannelRead(msg); + } + + private void initialize(ChannelHandlerContext ctx) { + // Avoid the case where destroy() is called before scheduling timeouts. + // See: https://github.com/netty/netty/issues/143 + switch (state) { + case 1: + case 2: + return; + } + + state = 1; + + lastReadTime = System.nanoTime(); + if (timeoutNanos > 0) { + timeout = ctx.executor().schedule( + new ReadTimeoutTask(ctx), + timeoutNanos, TimeUnit.NANOSECONDS); + } + } + + private void destroy() { + state = 2; + + if (timeout != null) { + timeout.cancel(false); + timeout = null; + } + } + + /** + * Is called when a read timeout was detected. + */ + protected void readTimedOut(ChannelHandlerContext ctx) throws Exception { + if (!closed) { + ctx.fireExceptionCaught(ReadTimeoutException.INSTANCE); + ctx.close(); + closed = true; + } + } + + private final class ReadTimeoutTask implements Runnable { + + private final ChannelHandlerContext ctx; + + ReadTimeoutTask(ChannelHandlerContext ctx) { + this.ctx = ctx; + } + + @Override + public void run() { + if (!ctx.channel().isOpen()) { + return; + } + + long currentTime = System.nanoTime(); + long nextDelay = timeoutNanos - (currentTime - lastReadTime); + if (nextDelay <= 0) { + // Read timed out - set a new timeout and notify the callback. + timeout = ctx.executor().schedule(this, timeoutNanos, TimeUnit.NANOSECONDS); + try { + readTimedOut(ctx); + } catch (Throwable t) { + ctx.fireExceptionCaught(t); + } + } else { + // Read occurred before the timeout - set a new timeout with shorter delay. + timeout = ctx.executor().schedule(this, nextDelay, TimeUnit.NANOSECONDS); + } + } + } +} diff --git a/common/src/common/net/handler/timeout/TimeoutException.java b/common/src/common/net/handler/timeout/TimeoutException.java new file mode 100644 index 0000000..491f161 --- /dev/null +++ b/common/src/common/net/handler/timeout/TimeoutException.java @@ -0,0 +1,34 @@ +/* + * Copyright 2012 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ +package common.net.handler.timeout; + +import common.net.channel.ChannelException; + +/** + * A {@link TimeoutException} when no data was either read or written within a + * certain period of time. + */ +public class TimeoutException extends ChannelException { + + private static final long serialVersionUID = 4673641882869672533L; + + TimeoutException() { } + + @Override + public Throwable fillInStackTrace() { + return this; + } +} diff --git a/common/src/common/net/util/Attribute.java b/common/src/common/net/util/Attribute.java new file mode 100644 index 0000000..56075ee --- /dev/null +++ b/common/src/common/net/util/Attribute.java @@ -0,0 +1,67 @@ +/* + * Copyright 2012 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ +package common.net.util; + +/** + * An attribute which allows to store a value reference. It may be updated atomically and so is thread-safe. + * + * @param the type of the value it holds. + */ +public interface Attribute { + + /** + * Returns the key of this attribute. + */ + AttributeKey key(); + + /** + * Returns the current value, which may be {@code null} + */ + T get(); + + /** + * Sets the value + */ + void set(T value); + + /** + * Atomically sets to the given value and returns the old value which may be {@code null} if non was set before. + */ + T getAndSet(T value); + + /** + * Atomically sets to the given value if this {@link Attribute} does not contain a value at the moment. + * If it was not possible to set the value as it contains a value it will just return the current value. + */ + T setIfAbsent(T value); + + /** + * Removes this attribute from the {@link AttributeMap} and returns the old value.. Subsequent {@link #get()} + * calls will return @{code null}. + */ + T getAndRemove(); + + /** + * Atomically sets the value to the given updated value if the current value == the expected value. + * If it the set was successful it returns {@code true} otherwise {@code false}. + */ + boolean compareAndSet(T oldValue, T newValue); + + /** + * Removes this attribute from the {@link AttributeMap}. Subsequent {@link #get()} calls will return @{code null}. + */ + void remove(); +} diff --git a/common/src/common/net/util/AttributeKey.java b/common/src/common/net/util/AttributeKey.java new file mode 100644 index 0000000..9db2217 --- /dev/null +++ b/common/src/common/net/util/AttributeKey.java @@ -0,0 +1,49 @@ +/* + * Copyright 2012 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ +package common.net.util; + +import java.util.concurrent.ConcurrentMap; + +import common.net.util.internal.PlatformDependent; + +/** + * Key which can be used to access {@link Attribute} out of the {@link AttributeMap}. Be aware that it is not be + * possible to have multiple keys with the same name. + * + * + * @param the type of the {@link Attribute} which can be accessed via this {@link AttributeKey}. + */ + // 'T' is used only at compile time +public final class AttributeKey extends UniqueName { + + private static final ConcurrentMap names = PlatformDependent.newConcurrentHashMap(); + + /** + * Creates a new {@link AttributeKey} with the specified {@code name}. + */ + + public static AttributeKey valueOf(String name) { + return new AttributeKey(name); + } + + /** + * @deprecated Use {@link #valueOf(String)} instead. + */ + @Deprecated + public AttributeKey(String name) { + super(names, name); + } +} diff --git a/common/src/common/net/util/AttributeMap.java b/common/src/common/net/util/AttributeMap.java new file mode 100644 index 0000000..2a1e85a --- /dev/null +++ b/common/src/common/net/util/AttributeMap.java @@ -0,0 +1,29 @@ +/* + * Copyright 2012 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ +package common.net.util; + +/** + * Holds {@link Attribute}s which can be accessed via {@link AttributeKey}. + * + * Implementations must be Thread-safe. + */ +public interface AttributeMap { + /** + * Get the {@link Attribute} for the given {@link AttributeKey}. This method will never return null, but may return + * an {@link Attribute} which does not have a value set yet. + */ + Attribute attr(AttributeKey key); +} diff --git a/common/src/common/net/util/CharsetUtil.java b/common/src/common/net/util/CharsetUtil.java new file mode 100644 index 0000000..5e69ad3 --- /dev/null +++ b/common/src/common/net/util/CharsetUtil.java @@ -0,0 +1,117 @@ +/* + * Copyright 2012 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ +package common.net.util; + +import java.nio.charset.Charset; +import java.nio.charset.CharsetDecoder; +import java.nio.charset.CharsetEncoder; +import java.nio.charset.CodingErrorAction; +import java.util.Map; + +import common.net.util.internal.InternalThreadLocalMap; + +/** + * A utility class that provides various common operations and constants + * related with {@link Charset} and its relevant classes. + */ +public final class CharsetUtil { + + /** + * 16-bit UTF (UCS Transformation Format) whose byte order is identified by + * an optional byte-order mark + */ + public static final Charset UTF_16 = Charset.forName("UTF-16"); + + /** + * 16-bit UTF (UCS Transformation Format) whose byte order is big-endian + */ + public static final Charset UTF_16BE = Charset.forName("UTF-16BE"); + + /** + * 16-bit UTF (UCS Transformation Format) whose byte order is little-endian + */ + public static final Charset UTF_16LE = Charset.forName("UTF-16LE"); + + /** + * 8-bit UTF (UCS Transformation Format) + */ + public static final Charset UTF_8 = Charset.forName("UTF-8"); + + /** + * ISO Latin Alphabet No. 1, as known as ISO-LATIN-1 + */ + public static final Charset ISO_8859_1 = Charset.forName("ISO-8859-1"); + + /** + * 7-bit ASCII, as known as ISO646-US or the Basic Latin block of the + * Unicode character set + */ + public static final Charset US_ASCII = Charset.forName("US-ASCII"); + + /** + * Returns a cached thread-local {@link CharsetEncoder} for the specified + * charset. + */ + public static CharsetEncoder getEncoder(Charset charset) { + if (charset == null) { + throw new NullPointerException("charset"); + } + + Map map = InternalThreadLocalMap.get().charsetEncoderCache(); + CharsetEncoder e = map.get(charset); + if (e != null) { + e.reset(); + e.onMalformedInput(CodingErrorAction.REPLACE); + e.onUnmappableCharacter(CodingErrorAction.REPLACE); + return e; + } + + e = charset.newEncoder(); + e.onMalformedInput(CodingErrorAction.REPLACE); + e.onUnmappableCharacter(CodingErrorAction.REPLACE); + map.put(charset, e); + return e; + } + + /** + * Returns a cached thread-local {@link CharsetDecoder} for the specified + * charset. + */ + public static CharsetDecoder getDecoder(Charset charset) { + if (charset == null) { + throw new NullPointerException("charset"); + } + + Map map = InternalThreadLocalMap.get().charsetDecoderCache(); + CharsetDecoder d = map.get(charset); + if (d != null) { + d.reset(); + d.onMalformedInput(CodingErrorAction.REPLACE); + d.onUnmappableCharacter(CodingErrorAction.REPLACE); + return d; + } + + d = charset.newDecoder(); + d.onMalformedInput(CodingErrorAction.REPLACE); + d.onUnmappableCharacter(CodingErrorAction.REPLACE); + map.put(charset, d); + return d; + } + + private CharsetUtil() { + // Unused + } +} diff --git a/common/src/common/net/util/DefaultAttributeMap.java b/common/src/common/net/util/DefaultAttributeMap.java new file mode 100644 index 0000000..605849a --- /dev/null +++ b/common/src/common/net/util/DefaultAttributeMap.java @@ -0,0 +1,179 @@ +/* + * Copyright 2012 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ +package common.net.util; + +import java.util.concurrent.atomic.AtomicReference; +import java.util.concurrent.atomic.AtomicReferenceArray; +import java.util.concurrent.atomic.AtomicReferenceFieldUpdater; + +import common.net.util.internal.PlatformDependent; + +/** + * Default {@link AttributeMap} implementation which use simple synchronization per bucket to keep the memory overhead + * as low as possible. + */ +public class DefaultAttributeMap implements AttributeMap { + + + private static final AtomicReferenceFieldUpdater updater; + + static { + + AtomicReferenceFieldUpdater referenceFieldUpdater = + PlatformDependent.newAtomicReferenceFieldUpdater(DefaultAttributeMap.class, "attributes"); + if (referenceFieldUpdater == null) { + referenceFieldUpdater = AtomicReferenceFieldUpdater + .newUpdater(DefaultAttributeMap.class, AtomicReferenceArray.class, "attributes"); + } + updater = referenceFieldUpdater; + } + + private static final int BUCKET_SIZE = 4; + private static final int MASK = BUCKET_SIZE - 1; + + // Initialize lazily to reduce memory consumption; updated by AtomicReferenceFieldUpdater above. + + private volatile AtomicReferenceArray> attributes; + + + @Override + public Attribute attr(AttributeKey key) { + if (key == null) { + throw new NullPointerException("key"); + } + AtomicReferenceArray> attributes = this.attributes; + if (attributes == null) { + // Not using ConcurrentHashMap due to high memory consumption. + attributes = new AtomicReferenceArray>(BUCKET_SIZE); + + if (!updater.compareAndSet(this, null, attributes)) { + attributes = this.attributes; + } + } + + int i = index(key); + DefaultAttribute head = attributes.get(i); + if (head == null) { + // No head exists yet which means we may be able to add the attribute without synchronization and just + // use compare and set. At worst we need to fallback to synchronization + head = new DefaultAttribute(key); + if (attributes.compareAndSet(i, null, head)) { + // we were able to add it so return the head right away + return (Attribute) head; + } else { + head = attributes.get(i); + } + } + + synchronized (head) { + DefaultAttribute curr = head; + for (;;) { + if (!curr.removed && curr.key == key) { + return (Attribute) curr; + } + + DefaultAttribute next = curr.next; + if (next == null) { + DefaultAttribute attr = new DefaultAttribute(head, key); + curr.next = attr; + attr.prev = curr; + return attr; + } else { + curr = next; + } + } + } + } + + private static int index(AttributeKey key) { + return key.id() & MASK; + } + + + private static final class DefaultAttribute extends AtomicReference implements Attribute { + + private static final long serialVersionUID = -2661411462200283011L; + + // The head of the linked-list this attribute belongs to, which may be itself + private final DefaultAttribute head; + private final AttributeKey key; + + // Double-linked list to prev and next node to allow fast removal + private DefaultAttribute prev; + private DefaultAttribute next; + + // Will be set to true one the attribute is removed via getAndRemove() or remove() + private volatile boolean removed; + + DefaultAttribute(DefaultAttribute head, AttributeKey key) { + this.head = head; + this.key = key; + } + + DefaultAttribute(AttributeKey key) { + head = this; + this.key = key; + } + + @Override + public AttributeKey key() { + return key; + } + + @Override + public T setIfAbsent(T value) { + while (!compareAndSet(null, value)) { + T old = get(); + if (old != null) { + return old; + } + } + return null; + } + + @Override + public T getAndRemove() { + removed = true; + T oldValue = getAndSet(null); + remove0(); + return oldValue; + } + + @Override + public void remove() { + removed = true; + set(null); + remove0(); + } + + private void remove0() { + synchronized (head) { + // We only update the linked-list structure if prev != null because if it is null this + // DefaultAttribute acts also as head. The head must never be removed completely and just be + // marked as removed as all synchronization is done on the head itself for each bucket. + // The head itself will be GC'ed once the DefaultAttributeMap is GC'ed. So at most 5 heads will + // be removed lazy as the array size is 5. + if (prev != null) { + prev.next = next; + + if (next != null) { + next.prev = prev; + } + } + } + } + } +} diff --git a/common/src/common/net/util/IllegalReferenceCountException.java b/common/src/common/net/util/IllegalReferenceCountException.java new file mode 100644 index 0000000..eed5aa7 --- /dev/null +++ b/common/src/common/net/util/IllegalReferenceCountException.java @@ -0,0 +1,48 @@ +/* + * Copyright 2012 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ + +package common.net.util; + +/** + * An {@link IllegalStateException} which is raised when a user attempts to access a {@link ReferenceCounted} whose + * reference count has been decreased to 0 (and consequently freed). + */ +public class IllegalReferenceCountException extends IllegalStateException { + + private static final long serialVersionUID = -2507492394288153468L; + + public IllegalReferenceCountException() { } + + public IllegalReferenceCountException(int refCnt) { + this("refCnt: " + refCnt); + } + + public IllegalReferenceCountException(int refCnt, int increment) { + this("refCnt: " + refCnt + ", " + (increment > 0? "increment: " + increment : "decrement: " + -increment)); + } + + public IllegalReferenceCountException(String message) { + super(message); + } + + public IllegalReferenceCountException(String message, Throwable cause) { + super(message, cause); + } + + public IllegalReferenceCountException(Throwable cause) { + super(cause); + } +} diff --git a/common/src/common/net/util/NetUtil.java b/common/src/common/net/util/NetUtil.java new file mode 100644 index 0000000..0fd6f0e --- /dev/null +++ b/common/src/common/net/util/NetUtil.java @@ -0,0 +1,614 @@ +/* + * Copyright 2012 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ +package common.net.util; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileReader; +import java.net.Inet4Address; +import java.net.Inet6Address; +import java.net.InetAddress; +import java.net.NetworkInterface; +import java.net.SocketException; +import java.util.ArrayList; +import java.util.Enumeration; +import java.util.List; +import java.util.StringTokenizer; + +import common.net.util.internal.PlatformDependent; +import common.net.util.internal.logging.InternalLogger; +import common.net.util.internal.logging.InternalLoggerFactory; + +/** + * A class that holds a number of network-related constants. + *

+ * This class borrowed some of its methods from a modified fork of the + * Inet6Util class which was part of Apache Harmony. + */ +public final class NetUtil { + + /** + * The {@link Inet4Address} that represents the IPv4 loopback address '127.0.0.1' + */ + public static final Inet4Address LOCALHOST4; + + /** + * The {@link Inet6Address} that represents the IPv6 loopback address '::1' + */ + public static final Inet6Address LOCALHOST6; + + /** + * The {@link InetAddress} that represents the loopback address. If IPv6 stack is available, it will refer to + * {@link #LOCALHOST6}. Otherwise, {@link #LOCALHOST4}. + */ + public static final InetAddress LOCALHOST; + + /** + * The loopback {@link NetworkInterface} of the current machine + */ + public static final NetworkInterface LOOPBACK_IF; + + /** + * The SOMAXCONN value of the current machine. If failed to get the value, 3072 is used as a + * default value. + */ + public static final int SOMAXCONN; + + /** + * The logger being used by this class + */ + private static final InternalLogger logger = InternalLoggerFactory.getInstance(NetUtil.class); + + static { + byte[] LOCALHOST4_BYTES = {127, 0, 0, 1}; + byte[] LOCALHOST6_BYTES = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}; + + // Create IPv4 loopback address. + Inet4Address localhost4 = null; + try { + localhost4 = (Inet4Address) InetAddress.getByAddress(LOCALHOST4_BYTES); + } catch (Exception e) { + // We should not get here as long as the length of the address is correct. + PlatformDependent.throwException(e); + } + LOCALHOST4 = localhost4; + + // Create IPv6 loopback address. + Inet6Address localhost6 = null; + try { + localhost6 = (Inet6Address) InetAddress.getByAddress(LOCALHOST6_BYTES); + } catch (Exception e) { + // We should not get here as long as the length of the address is correct. + PlatformDependent.throwException(e); + } + LOCALHOST6 = localhost6; + + // Retrieve the list of available network interfaces. + List ifaces = new ArrayList(); + try { + for (Enumeration i = NetworkInterface.getNetworkInterfaces(); i.hasMoreElements();) { + NetworkInterface iface = i.nextElement(); + // Use the interface with proper INET addresses only. + if (iface.getInetAddresses().hasMoreElements()) { + ifaces.add(iface); + } + } + } catch (SocketException e) { + logger.warn("Failed to retrieve the list of available network interfaces", e); + } + + // Find the first loopback interface available from its INET address (127.0.0.1 or ::1) + // Note that we do not use NetworkInterface.isLoopback() in the first place because it takes long time + // on a certain environment. (e.g. Windows with -Djava.net.preferIPv4Stack=true) + NetworkInterface loopbackIface = null; + InetAddress loopbackAddr = null; + loop: for (NetworkInterface iface: ifaces) { + for (Enumeration i = iface.getInetAddresses(); i.hasMoreElements();) { + InetAddress addr = i.nextElement(); + if (addr.isLoopbackAddress()) { + // Found + loopbackIface = iface; + loopbackAddr = addr; + break loop; + } + } + } + + // If failed to find the loopback interface from its INET address, fall back to isLoopback(). + if (loopbackIface == null) { + try { + for (NetworkInterface iface: ifaces) { + if (iface.isLoopback()) { + Enumeration i = iface.getInetAddresses(); + if (i.hasMoreElements()) { + // Found the one with INET address. + loopbackIface = iface; + loopbackAddr = i.nextElement(); + break; + } + } + } + + if (loopbackIface == null) { + logger.warn("Failed to find the loopback interface"); + } + } catch (SocketException e) { + logger.warn("Failed to find the loopback interface", e); + } + } + + if (loopbackIface != null) { + // Found the loopback interface with an INET address. + logger.debug( + "Loopback interface: {} ({}, {})", + loopbackIface.getName(), loopbackIface.getDisplayName(), loopbackAddr.getHostAddress()); + } else { + // Could not find the loopback interface, but we can't leave LOCALHOST as null. + // Use LOCALHOST6 or LOCALHOST4, preferably the IPv6 one. + if (loopbackAddr == null) { + try { + if (NetworkInterface.getByInetAddress(LOCALHOST6) != null) { + logger.debug("Using hard-coded IPv6 localhost address: {}", localhost6); + loopbackAddr = localhost6; + } + } catch (Exception e) { + // Ignore + } finally { + if (loopbackAddr == null) { + logger.debug("Using hard-coded IPv4 localhost address: {}", localhost4); + loopbackAddr = localhost4; + } + } + } + } + + LOOPBACK_IF = loopbackIface; + LOCALHOST = loopbackAddr; + + // Determine the default somaxconn (server socket backlog) value of the platform. + // The known defaults: + // - Windows NT Server 4.0+: 200 + // - Linux and Mac OS X: 128 + int somaxconn = PlatformDependent.isWindows() ? 200 : 128; + File file = new File("/proc/sys/net/core/somaxconn"); + if (file.exists()) { + BufferedReader in = null; + try { + in = new BufferedReader(new FileReader(file)); + somaxconn = Integer.parseInt(in.readLine()); + if (logger.isDebugEnabled()) { + logger.debug("{}: {}", file, somaxconn); + } + } catch (Exception e) { + logger.debug("Failed to get SOMAXCONN from: {}", file, e); + } finally { + if (in != null) { + try { + in.close(); + } catch (Exception e) { + // Ignored. + } + } + } + } else { + if (logger.isDebugEnabled()) { + logger.debug("{}: {} (non-existent)", file, somaxconn); + } + } + + SOMAXCONN = somaxconn; + } + + /** + * Creates an byte[] based on an ipAddressString. No error handling is + * performed here. + */ + public static byte[] createByteArrayFromIpAddressString(String ipAddressString) { + + if (isValidIpV4Address(ipAddressString)) { + StringTokenizer tokenizer = new StringTokenizer(ipAddressString, "."); + String token; + int tempInt; + byte[] byteAddress = new byte[4]; + for (int i = 0; i < 4; i ++) { + token = tokenizer.nextToken(); + tempInt = Integer.parseInt(token); + byteAddress[i] = (byte) tempInt; + } + + return byteAddress; + } + + if (isValidIpV6Address(ipAddressString)) { + if (ipAddressString.charAt(0) == '[') { + ipAddressString = ipAddressString.substring(1, ipAddressString.length() - 1); + } + + StringTokenizer tokenizer = new StringTokenizer(ipAddressString, ":.", true); + ArrayList hexStrings = new ArrayList(); + ArrayList decStrings = new ArrayList(); + String token = ""; + String prevToken = ""; + int doubleColonIndex = -1; // If a double colon exists, we need to + // insert 0s. + + // Go through the tokens, including the seperators ':' and '.' + // When we hit a : or . the previous token will be added to either + // the hex list or decimal list. In the case where we hit a :: + // we will save the index of the hexStrings so we can add zeros + // in to fill out the string + while (tokenizer.hasMoreTokens()) { + prevToken = token; + token = tokenizer.nextToken(); + + if (":".equals(token)) { + if (":".equals(prevToken)) { + doubleColonIndex = hexStrings.size(); + } else if (!prevToken.isEmpty()) { + hexStrings.add(prevToken); + } + } else if (".".equals(token)) { + decStrings.add(prevToken); + } + } + + if (":".equals(prevToken)) { + if (":".equals(token)) { + doubleColonIndex = hexStrings.size(); + } else { + hexStrings.add(token); + } + } else if (".".equals(prevToken)) { + decStrings.add(token); + } + + // figure out how many hexStrings we should have + // also check if it is a IPv4 address + int hexStringsLength = 8; + + // If we have an IPv4 address tagged on at the end, subtract + // 4 bytes, or 2 hex words from the total + if (!decStrings.isEmpty()) { + hexStringsLength -= 2; + } + + // if we hit a double Colon add the appropriate hex strings + if (doubleColonIndex != -1) { + int numberToInsert = hexStringsLength - hexStrings.size(); + for (int i = 0; i < numberToInsert; i ++) { + hexStrings.add(doubleColonIndex, "0"); + } + } + + byte[] ipByteArray = new byte[16]; + + // Finally convert these strings to bytes... + for (int i = 0; i < hexStrings.size(); i ++) { + convertToBytes(hexStrings.get(i), ipByteArray, i * 2); + } + + // Now if there are any decimal values, we know where they go... + for (int i = 0; i < decStrings.size(); i ++) { + ipByteArray[i + 12] = (byte) (Integer.parseInt(decStrings.get(i)) & 255); + } + return ipByteArray; + } + return null; + } + + /** + * Converts a 4 character hex word into a 2 byte word equivalent + */ + private static void convertToBytes(String hexWord, byte[] ipByteArray, int byteIndex) { + + int hexWordLength = hexWord.length(); + int hexWordIndex = 0; + ipByteArray[byteIndex] = 0; + ipByteArray[byteIndex + 1] = 0; + int charValue; + + // high order 4 bits of first byte + if (hexWordLength > 3) { + charValue = getIntValue(hexWord.charAt(hexWordIndex ++)); + ipByteArray[byteIndex] |= charValue << 4; + } + + // low order 4 bits of the first byte + if (hexWordLength > 2) { + charValue = getIntValue(hexWord.charAt(hexWordIndex ++)); + ipByteArray[byteIndex] |= charValue; + } + + // high order 4 bits of second byte + if (hexWordLength > 1) { + charValue = getIntValue(hexWord.charAt(hexWordIndex ++)); + ipByteArray[byteIndex + 1] |= charValue << 4; + } + + // low order 4 bits of the first byte + charValue = getIntValue(hexWord.charAt(hexWordIndex)); + ipByteArray[byteIndex + 1] |= charValue & 15; + } + + static int getIntValue(char c) { + + switch (c) { + case '0': + return 0; + case '1': + return 1; + case '2': + return 2; + case '3': + return 3; + case '4': + return 4; + case '5': + return 5; + case '6': + return 6; + case '7': + return 7; + case '8': + return 8; + case '9': + return 9; + } + + c = Character.toLowerCase(c); + switch (c) { + case 'a': + return 10; + case 'b': + return 11; + case 'c': + return 12; + case 'd': + return 13; + case 'e': + return 14; + case 'f': + return 15; + } + return 0; + } + + public static boolean isValidIpV6Address(String ipAddress) { + int length = ipAddress.length(); + boolean doubleColon = false; + int numberOfColons = 0; + int numberOfPeriods = 0; + int numberOfPercent = 0; + StringBuilder word = new StringBuilder(); + char c = 0; + char prevChar; + int offset = 0; // offset for [] ip addresses + + if (length < 2) { + return false; + } + + for (int i = 0; i < length; i ++) { + prevChar = c; + c = ipAddress.charAt(i); + switch (c) { + + // case for an open bracket [x:x:x:...x] + case '[': + if (i != 0) { + return false; // must be first character + } + if (ipAddress.charAt(length - 1) != ']') { + return false; // must have a close ] + } + offset = 1; + if (length < 4) { + return false; + } + break; + + // case for a closed bracket at end of IP [x:x:x:...x] + case ']': + if (i != length - 1) { + return false; // must be last charcter + } + if (ipAddress.charAt(0) != '[') { + return false; // must have a open [ + } + break; + + // case for the last 32-bits represented as IPv4 x:x:x:x:x:x:d.d.d.d + case '.': + numberOfPeriods ++; + if (numberOfPeriods > 3) { + return false; + } + if (!isValidIp4Word(word.toString())) { + return false; + } + if (numberOfColons != 6 && !doubleColon) { + return false; + } + // a special case ::1:2:3:4:5:d.d.d.d allows 7 colons with an + // IPv4 ending, otherwise 7 :'s is bad + if (numberOfColons == 7 && ipAddress.charAt(offset) != ':' && + ipAddress.charAt(1 + offset) != ':') { + return false; + } + word.delete(0, word.length()); + break; + + case ':': + // FIX "IP6 mechanism syntax #ip6-bad1" + // An IPV6 address cannot start with a single ":". + // Either it can starti with "::" or with a number. + if (i == offset && (ipAddress.length() <= i || ipAddress.charAt(i + 1) != ':')) { + return false; + } + // END FIX "IP6 mechanism syntax #ip6-bad1" + numberOfColons ++; + if (numberOfColons > 7) { + return false; + } + if (numberOfPeriods > 0) { + return false; + } + if (prevChar == ':') { + if (doubleColon) { + return false; + } + doubleColon = true; + } + word.delete(0, word.length()); + break; + case '%': + if (numberOfColons == 0) { + return false; + } + numberOfPercent ++; + + // validate that the stuff after the % is valid + if (i + 1 >= length) { + // in this case the percent is there but no number is + // available + return false; + } + try { + if (Integer.parseInt(ipAddress.substring(i + 1)) < 0) { + return false; + } + } catch (NumberFormatException e) { + // right now we just support an integer after the % so if + // this is not + // what is there then return + return false; + } + break; + + default: + if (numberOfPercent == 0) { + if (word != null && word.length() > 3) { + return false; + } + if (!isValidHexChar(c)) { + return false; + } + } + word.append(c); + } + } + + // Check if we have an IPv4 ending + if (numberOfPeriods > 0) { + // There is a test case with 7 colons and valid ipv4 this should resolve it + if (numberOfPeriods != 3 || !(isValidIp4Word(word.toString()) && numberOfColons < 7)) { + return false; + } + } else { + // If we're at then end and we haven't had 7 colons then there is a + // problem unless we encountered a doubleColon + if (numberOfColons != 7 && !doubleColon) { + return false; + } + + // If we have an empty word at the end, it means we ended in either + // a : or a . + // If we did not end in :: then this is invalid + if (numberOfPercent == 0) { + if (word.length() == 0 && ipAddress.charAt(length - 1 - offset) == ':' && + ipAddress.charAt(length - 2 - offset) != ':') { + return false; + } + } + } + + return true; + } + + public static boolean isValidIp4Word(String word) { + char c; + if (word.length() < 1 || word.length() > 3) { + return false; + } + for (int i = 0; i < word.length(); i ++) { + c = word.charAt(i); + if (!(c >= '0' && c <= '9')) { + return false; + } + } + return Integer.parseInt(word) <= 255; + } + + static boolean isValidHexChar(char c) { + return c >= '0' && c <= '9' || c >= 'A' && c <= 'F' || c >= 'a' && c <= 'f'; + } + + /** + * Takes a string and parses it to see if it is a valid IPV4 address. + * + * @return true, if the string represents an IPV4 address in dotted + * notation, false otherwise + */ + public static boolean isValidIpV4Address(String value) { + + int periods = 0; + int i; + int length = value.length(); + + if (length > 15) { + return false; + } + char c; + StringBuilder word = new StringBuilder(); + for (i = 0; i < length; i ++) { + c = value.charAt(i); + if (c == '.') { + periods ++; + if (periods > 3) { + return false; + } + if (word.length() == 0) { + return false; + } + if (Integer.parseInt(word.toString()) > 255) { + return false; + } + word.delete(0, word.length()); + } else if (!Character.isDigit(c)) { + return false; + } else { + if (word.length() > 2) { + return false; + } + word.append(c); + } + } + + if (word.length() == 0 || Integer.parseInt(word.toString()) > 255) { + return false; + } + + return periods == 3; + } + + /** + * A constructor to stop this class being constructed. + */ + private NetUtil() { + // Unused + } +} diff --git a/common/src/common/net/util/Recycler.java b/common/src/common/net/util/Recycler.java new file mode 100644 index 0000000..9fb120d --- /dev/null +++ b/common/src/common/net/util/Recycler.java @@ -0,0 +1,353 @@ +/* + * Copyright 2013 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ + +package common.net.util; + +import java.lang.ref.WeakReference; +import java.util.Arrays; +import java.util.Map; +import java.util.WeakHashMap; +import java.util.concurrent.atomic.AtomicInteger; + +import common.net.util.concurrent.FastThreadLocal; +import common.net.util.internal.SystemPropertyUtil; +import common.net.util.internal.logging.InternalLogger; +import common.net.util.internal.logging.InternalLoggerFactory; + +/** + * Light-weight object pool based on a thread-local stack. + * + * @param the type of the pooled object + */ +public abstract class Recycler { + + private static final InternalLogger logger = InternalLoggerFactory.getInstance(Recycler.class); + + private static final AtomicInteger ID_GENERATOR = new AtomicInteger(Integer.MIN_VALUE); + private static final int OWN_THREAD_ID = ID_GENERATOR.getAndIncrement(); + private static final int DEFAULT_MAX_CAPACITY; + private static final int INITIAL_CAPACITY; + + static { + // In the future, we might have different maxCapacity for different object types. + // e.g. game.net.recycler.maxCapacity.writeTask + // game.net.recycler.maxCapacity.outboundBuffer + int maxCapacity = SystemPropertyUtil.getInt("game.net.recycler.maxCapacity.default", 0); + if (maxCapacity <= 0) { + // TODO: Some arbitrary large number - should adjust as we get more production experience. + maxCapacity = 262144; + } + + DEFAULT_MAX_CAPACITY = maxCapacity; + if (logger.isDebugEnabled()) { + logger.debug("-Dgame.net.recycler.maxCapacity.default: {}", DEFAULT_MAX_CAPACITY); + } + + INITIAL_CAPACITY = Math.min(DEFAULT_MAX_CAPACITY, 256); + } + + private final int maxCapacity; + private final FastThreadLocal> threadLocal = new FastThreadLocal>() { + @Override + protected Stack initialValue() { + return new Stack(Recycler.this, Thread.currentThread(), maxCapacity); + } + }; + + protected Recycler() { + this(DEFAULT_MAX_CAPACITY); + } + + protected Recycler(int maxCapacity) { + this.maxCapacity = Math.max(0, maxCapacity); + } + + + public final T get() { + Stack stack = threadLocal.get(); + DefaultHandle handle = stack.pop(); + if (handle == null) { + handle = stack.newHandle(); + handle.value = newObject(handle); + } + return (T) handle.value; + } + + public final boolean recycle(T o, Handle handle) { + DefaultHandle h = (DefaultHandle) handle; + if (h.stack.parent != this) { + return false; + } + if (o != h.value) { + throw new IllegalArgumentException("o does not belong to handle"); + } + h.recycle(); + return true; + } + + protected abstract T newObject(Handle handle); + + public interface Handle { } + + static final class DefaultHandle implements Handle { + private int lastRecycledId; + private int recycleId; + + private Stack stack; + private Object value; + + DefaultHandle(Stack stack) { + this.stack = stack; + } + + public void recycle() { + Thread thread = Thread.currentThread(); + if (thread == stack.thread) { + stack.push(this); + return; + } + // we don't want to have a ref to the queue as the value in our weak map + // so we null it out; to ensure there are no races with restoring it later + // we impose a memory ordering here (no-op on x86) + Map, WeakOrderQueue> delayedRecycled = DELAYED_RECYCLED.get(); + WeakOrderQueue queue = delayedRecycled.get(stack); + if (queue == null) { + delayedRecycled.put(stack, queue = new WeakOrderQueue(stack, thread)); + } + queue.add(this); + } + } + + private static final FastThreadLocal, WeakOrderQueue>> DELAYED_RECYCLED = + new FastThreadLocal, WeakOrderQueue>>() { + @Override + protected Map, WeakOrderQueue> initialValue() { + return new WeakHashMap, WeakOrderQueue>(); + } + }; + + // a queue that makes only moderate guarantees about visibility: items are seen in the correct order, + // but we aren't absolutely guaranteed to ever see anything at all, thereby keeping the queue cheap to maintain + private static final class WeakOrderQueue { + private static final int LINK_CAPACITY = 16; + + // Let Link extend AtomicInteger for intrinsics. The Link itself will be used as writerIndex. + + private static final class Link extends AtomicInteger { + private final DefaultHandle[] elements = new DefaultHandle[LINK_CAPACITY]; + + private int readIndex; + private Link next; + } + + // chain of data items + private Link head, tail; + // pointer to another queue of delayed items for the same stack + private WeakOrderQueue next; + private final WeakReference owner; + private final int id = ID_GENERATOR.getAndIncrement(); + + WeakOrderQueue(Stack stack, Thread thread) { + head = tail = new Link(); + owner = new WeakReference(thread); + synchronized (stack) { + next = stack.head; + stack.head = this; + } + } + + void add(DefaultHandle handle) { + handle.lastRecycledId = id; + + Link tail = this.tail; + int writeIndex; + if ((writeIndex = tail.get()) == LINK_CAPACITY) { + this.tail = tail = tail.next = new Link(); + writeIndex = tail.get(); + } + tail.elements[writeIndex] = handle; + handle.stack = null; + // we lazy set to ensure that setting stack to null appears before we unnull it in the owning thread; + // this also means we guarantee visibility of an element in the queue if we see the index updated + tail.lazySet(writeIndex + 1); + } + + boolean hasFinalData() { + return tail.readIndex != tail.get(); + } + + // transfer as many items as we can from this queue to the stack, returning true if any were transferred + + boolean transfer(Stack to) { + + Link head = this.head; + if (head == null) { + return false; + } + + if (head.readIndex == LINK_CAPACITY) { + if (head.next == null) { + return false; + } + this.head = head = head.next; + } + + int start = head.readIndex; + int end = head.get(); + if (start == end) { + return false; + } + + int count = end - start; + if (to.size + count > to.elements.length) { + to.elements = Arrays.copyOf(to.elements, (to.size + count) * 2); + } + + DefaultHandle[] src = head.elements; + DefaultHandle[] trg = to.elements; + int size = to.size; + while (start < end) { + DefaultHandle element = src[start]; + if (element.recycleId == 0) { + element.recycleId = element.lastRecycledId; + } else if (element.recycleId != element.lastRecycledId) { + throw new IllegalStateException("recycled already"); + } + element.stack = to; + trg[size++] = element; + src[start++] = null; + } + to.size = size; + + if (end == LINK_CAPACITY && head.next != null) { + this.head = head.next; + } + + head.readIndex = end; + return true; + } + } + + static final class Stack { + + // we keep a queue of per-thread queues, which is appended to once only, each time a new thread other + // than the stack owner recycles: when we run out of items in our stack we iterate this collection + // to scavenge those that can be reused. this permits us to incur minimal thread synchronisation whilst + // still recycling all items. + final Recycler parent; + final Thread thread; + private DefaultHandle[] elements; + private final int maxCapacity; + private int size; + + private volatile WeakOrderQueue head; + private WeakOrderQueue cursor, prev; + + Stack(Recycler parent, Thread thread, int maxCapacity) { + this.parent = parent; + this.thread = thread; + this.maxCapacity = maxCapacity; + elements = new DefaultHandle[INITIAL_CAPACITY]; + } + + DefaultHandle pop() { + int size = this.size; + if (size == 0) { + if (!scavenge()) { + return null; + } + size = this.size; + } + size --; + DefaultHandle ret = elements[size]; + if (ret.lastRecycledId != ret.recycleId) { + throw new IllegalStateException("recycled multiple times"); + } + ret.recycleId = 0; + ret.lastRecycledId = 0; + this.size = size; + return ret; + } + + boolean scavenge() { + // continue an existing scavenge, if any + if (scavengeSome()) { + return true; + } + + // reset our scavenge cursor + prev = null; + cursor = head; + return false; + } + + boolean scavengeSome() { + boolean success = false; + WeakOrderQueue cursor = this.cursor, prev = this.prev; + while (cursor != null) { + if (cursor.transfer(this)) { + success = true; + break; + } + WeakOrderQueue next = cursor.next; + if (cursor.owner.get() == null) { + // if the thread associated with the queue is gone, unlink it, after + // performing a volatile read to confirm there is no data left to collect + // we never unlink the first queue, as we don't want to synchronize on updating the head + if (cursor.hasFinalData()) { + for (;;) { + if (!cursor.transfer(this)) { + break; + } + } + } + if (prev != null) { + prev.next = next; + } + } else { + prev = cursor; + } + cursor = next; + } + this.prev = prev; + this.cursor = cursor; + return success; + } + + void push(DefaultHandle item) { + if ((item.recycleId | item.lastRecycledId) != 0) { + throw new IllegalStateException("recycled already"); + } + item.recycleId = item.lastRecycledId = OWN_THREAD_ID; + + int size = this.size; + if (size == elements.length) { + if (size == maxCapacity) { + // Hit the maximum capacity - drop the possibly youngest object. + return; + } + elements = Arrays.copyOf(elements, size << 1); + } + + elements[size] = item; + this.size = size + 1; + } + + DefaultHandle newHandle() { + return new DefaultHandle(this); + } + } +} diff --git a/common/src/common/net/util/ReferenceCountUtil.java b/common/src/common/net/util/ReferenceCountUtil.java new file mode 100644 index 0000000..7c55c48 --- /dev/null +++ b/common/src/common/net/util/ReferenceCountUtil.java @@ -0,0 +1,161 @@ +/* + * Copyright 2013 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ +package common.net.util; + +import common.net.util.internal.StringUtil; +import common.net.util.internal.logging.InternalLogger; +import common.net.util.internal.logging.InternalLoggerFactory; + +/** + * Collection of method to handle objects that may implement {@link ReferenceCounted}. + */ +public final class ReferenceCountUtil { + + private static final InternalLogger logger = InternalLoggerFactory.getInstance(ReferenceCountUtil.class); + + /** + * Try to call {@link ReferenceCounted#retain()} if the specified message implements {@link ReferenceCounted}. + * If the specified message doesn't implement {@link ReferenceCounted}, this method does nothing. + */ + + public static T retain(T msg) { + if (msg instanceof ReferenceCounted) { + return (T) ((ReferenceCounted) msg).retain(); + } + return msg; + } + + /** + * Try to call {@link ReferenceCounted#retain()} if the specified message implements {@link ReferenceCounted}. + * If the specified message doesn't implement {@link ReferenceCounted}, this method does nothing. + */ + + public static T retain(T msg, int increment) { + if (msg instanceof ReferenceCounted) { + return (T) ((ReferenceCounted) msg).retain(increment); + } + return msg; + } + + /** + * Try to call {@link ReferenceCounted#release()} if the specified message implements {@link ReferenceCounted}. + * If the specified message doesn't implement {@link ReferenceCounted}, this method does nothing. + */ + public static boolean release(Object msg) { + if (msg instanceof ReferenceCounted) { + return ((ReferenceCounted) msg).release(); + } + return false; + } + + /** + * Try to call {@link ReferenceCounted#release(int)} if the specified message implements {@link ReferenceCounted}. + * If the specified message doesn't implement {@link ReferenceCounted}, this method does nothing. + */ + public static boolean release(Object msg, int decrement) { + if (msg instanceof ReferenceCounted) { + return ((ReferenceCounted) msg).release(decrement); + } + return false; + } + + /** + * Try to call {@link ReferenceCounted#release()} if the specified message implements {@link ReferenceCounted}. + * If the specified message doesn't implement {@link ReferenceCounted}, this method does nothing. + * Unlike {@link #release(Object)} this method catches an exception raised by {@link ReferenceCounted#release()} + * and logs it, rather than rethrowing it to the caller. It is usually recommended to use {@link #release(Object)} + * instead, unless you absolutely need to swallow an exception. + */ + public static void safeRelease(Object msg) { + try { + release(msg); + } catch (Throwable t) { + logger.warn("Failed to release a message: {}", msg, t); + } + } + + /** + * Try to call {@link ReferenceCounted#release(int)} if the specified message implements {@link ReferenceCounted}. + * If the specified message doesn't implement {@link ReferenceCounted}, this method does nothing. + * Unlike {@link #release(Object)} this method catches an exception raised by {@link ReferenceCounted#release(int)} + * and logs it, rather than rethrowing it to the caller. It is usually recommended to use + * {@link #release(Object, int)} instead, unless you absolutely need to swallow an exception. + */ + public static void safeRelease(Object msg, int decrement) { + try { + release(msg, decrement); + } catch (Throwable t) { + if (logger.isWarnEnabled()) { + logger.warn("Failed to release a message: {} (decrement: {})", msg, decrement, t); + } + } + } + + /** + * Schedules the specified object to be released when the caller thread terminates. Note that this operation is + * intended to simplify reference counting of ephemeral objects during unit tests. Do not use it beyond the + * intended use case. + */ + public static T releaseLater(T msg) { + return releaseLater(msg, 1); + } + + /** + * Schedules the specified object to be released when the caller thread terminates. Note that this operation is + * intended to simplify reference counting of ephemeral objects during unit tests. Do not use it beyond the + * intended use case. + */ + public static T releaseLater(T msg, int decrement) { + if (msg instanceof ReferenceCounted) { + ThreadDeathWatcher.watch(Thread.currentThread(), new ReleasingTask((ReferenceCounted) msg, decrement)); + } + return msg; + } + + /** + * Releases the objects when the thread that called {@link #releaseLater(Object)} has been terminated. + */ + private static final class ReleasingTask implements Runnable { + + private final ReferenceCounted obj; + private final int decrement; + + ReleasingTask(ReferenceCounted obj, int decrement) { + this.obj = obj; + this.decrement = decrement; + } + + @Override + public void run() { + try { + if (!obj.release(decrement)) { + logger.warn("Non-zero refCnt: {}", this); + } else { + logger.debug("Released: {}", this); + } + } catch (Exception ex) { + logger.warn("Failed to release an object: {}", obj, ex); + } + } + + @Override + public String toString() { + return StringUtil.simpleClassName(obj) + ".release(" + decrement + ") refCnt: " + obj.refCnt(); + } + } + + private ReferenceCountUtil() { } +} diff --git a/common/src/common/net/util/ReferenceCounted.java b/common/src/common/net/util/ReferenceCounted.java new file mode 100644 index 0000000..33d6097 --- /dev/null +++ b/common/src/common/net/util/ReferenceCounted.java @@ -0,0 +1,63 @@ +/* + * Copyright 2013 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ +package common.net.util; + +/** + * A reference-counted object that requires explicit deallocation. + *

+ * When a new {@link ReferenceCounted} is instantiated, it starts with the reference count of {@code 1}. + * {@link #retain()} increases the reference count, and {@link #release()} decreases the reference count. + * If the reference count is decreased to {@code 0}, the object will be deallocated explicitly, and accessing + * the deallocated object will usually result in an access violation. + *

+ *

+ * If an object that implements {@link ReferenceCounted} is a container of other objects that implement + * {@link ReferenceCounted}, the contained objects will also be released via {@link #release()} when the container's + * reference count becomes 0. + *

+ */ +public interface ReferenceCounted { + /** + * Returns the reference count of this object. If {@code 0}, it means this object has been deallocated. + */ + int refCnt(); + + /** + * Increases the reference count by {@code 1}. + */ + ReferenceCounted retain(); + + /** + * Increases the reference count by the specified {@code increment}. + */ + ReferenceCounted retain(int increment); + + /** + * Decreases the reference count by {@code 1} and deallocates this object if the reference count reaches at + * {@code 0}. + * + * @return {@code true} if and only if the reference count became {@code 0} and this object has been deallocated + */ + boolean release(); + + /** + * Decreases the reference count by the specified {@code decrement} and deallocates this object if the reference + * count reaches at {@code 0}. + * + * @return {@code true} if and only if the reference count became {@code 0} and this object has been deallocated + */ + boolean release(int decrement); +} diff --git a/common/src/common/net/util/ResourceLeak.java b/common/src/common/net/util/ResourceLeak.java new file mode 100644 index 0000000..00064a7 --- /dev/null +++ b/common/src/common/net/util/ResourceLeak.java @@ -0,0 +1,32 @@ +/* + * Copyright 2013 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ + +package common.net.util; + +public interface ResourceLeak { + /** + * Records the caller's current stack trace so that the {@link ResourceLeakDetector} can tell where the leaked + * resource was accessed lastly. + */ + void record(); + + /** + * Close the leak so that {@link ResourceLeakDetector} does not warn about leaked resources. + * + * @return {@code true} if called first time, {@code false} if called already + */ + boolean close(); +} diff --git a/common/src/common/net/util/ResourceLeakDetector.java b/common/src/common/net/util/ResourceLeakDetector.java new file mode 100644 index 0000000..e5e4e96 --- /dev/null +++ b/common/src/common/net/util/ResourceLeakDetector.java @@ -0,0 +1,388 @@ +/* + * Copyright 2013 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ + +package common.net.util; + +import static common.net.util.internal.StringUtil.NEWLINE; +import static common.net.util.internal.StringUtil.simpleClassName; + +import java.lang.ref.PhantomReference; +import java.lang.ref.ReferenceQueue; +import java.util.ArrayDeque; +import java.util.Deque; +import java.util.EnumSet; +import java.util.concurrent.ConcurrentMap; +import java.util.concurrent.atomic.AtomicBoolean; + +import common.net.util.internal.PlatformDependent; +import common.net.util.internal.SystemPropertyUtil; +import common.net.util.internal.logging.InternalLogger; +import common.net.util.internal.logging.InternalLoggerFactory; + +public final class ResourceLeakDetector { + + private static final String PROP_LEVEL = "game.net.leakDetectionLevel"; + private static final Level DEFAULT_LEVEL = Level.SIMPLE; + + /** + * Represents the level of resource leak detection. + */ + public enum Level { + /** + * Disables resource leak detection. + */ + DISABLED, + /** + * Enables simplistic sampling resource leak detection which reports there is a leak or not, + * at the cost of small overhead (default). + */ + SIMPLE, + /** + * Enables advanced sampling resource leak detection which reports where the leaked object was accessed + * recently at the cost of high overhead. + */ + ADVANCED, + /** + * Enables paranoid resource leak detection which reports where the leaked object was accessed recently, + * at the cost of the highest possible overhead (for testing purposes only). + */ + PARANOID + } + + private static Level level; + + private static final InternalLogger logger = InternalLoggerFactory.getInstance(ResourceLeakDetector.class); + + static { + final boolean disabled; + if (SystemPropertyUtil.get("game.net.noResourceLeakDetection") != null) { + disabled = SystemPropertyUtil.getBoolean("game.net.noResourceLeakDetection", false); + logger.debug("-Dgame.net.noResourceLeakDetection: {}", disabled); + logger.warn( + "-Dgame.net.noResourceLeakDetection is deprecated. Use '-D{}={}' instead.", + PROP_LEVEL, DEFAULT_LEVEL.name().toLowerCase()); + } else { + disabled = false; + } + + Level defaultLevel = disabled? Level.DISABLED : DEFAULT_LEVEL; + String levelStr = SystemPropertyUtil.get(PROP_LEVEL, defaultLevel.name()).trim().toUpperCase(); + Level level = DEFAULT_LEVEL; + for (Level l: EnumSet.allOf(Level.class)) { + if (levelStr.equals(l.name()) || levelStr.equals(String.valueOf(l.ordinal()))) { + level = l; + } + } + + ResourceLeakDetector.level = level; + if (logger.isDebugEnabled()) { + logger.debug("-D{}: {}", PROP_LEVEL, level.name().toLowerCase()); + } + } + + private static final int DEFAULT_SAMPLING_INTERVAL = 113; + + /** + * @deprecated Use {@link #setLevel(Level)} instead. + */ + @Deprecated + public static void setEnabled(boolean enabled) { + setLevel(enabled? Level.SIMPLE : Level.DISABLED); + } + + /** + * Returns {@code true} if resource leak detection is enabled. + */ + public static boolean isEnabled() { + return getLevel().ordinal() > Level.DISABLED.ordinal(); + } + + /** + * Sets the resource leak detection level. + */ + public static void setLevel(Level level) { + if (level == null) { + throw new NullPointerException("level"); + } + ResourceLeakDetector.level = level; + } + + /** + * Returns the current resource leak detection level. + */ + public static Level getLevel() { + return level; + } + + /** the linked list of active resources */ + private final DefaultResourceLeak head = new DefaultResourceLeak(null); + private final DefaultResourceLeak tail = new DefaultResourceLeak(null); + + private final ReferenceQueue refQueue = new ReferenceQueue(); + private final ConcurrentMap reportedLeaks = PlatformDependent.newConcurrentHashMap(); + + private final String resourceType; + private final int samplingInterval; + private final long maxActive; + private long active; + private final AtomicBoolean loggedTooManyActive = new AtomicBoolean(); + + private long leakCheckCnt; + + public ResourceLeakDetector(Class resourceType) { + this(simpleClassName(resourceType)); + } + + public ResourceLeakDetector(String resourceType) { + this(resourceType, DEFAULT_SAMPLING_INTERVAL, Long.MAX_VALUE); + } + + public ResourceLeakDetector(Class resourceType, int samplingInterval, long maxActive) { + this(simpleClassName(resourceType), samplingInterval, maxActive); + } + + public ResourceLeakDetector(String resourceType, int samplingInterval, long maxActive) { + if (resourceType == null) { + throw new NullPointerException("resourceType"); + } + if (samplingInterval <= 0) { + throw new IllegalArgumentException("samplingInterval: " + samplingInterval + " (expected: 1+)"); + } + if (maxActive <= 0) { + throw new IllegalArgumentException("maxActive: " + maxActive + " (expected: 1+)"); + } + + this.resourceType = resourceType; + this.samplingInterval = samplingInterval; + this.maxActive = maxActive; + + head.next = tail; + tail.prev = head; + } + + /** + * Creates a new {@link ResourceLeak} which is expected to be closed via {@link ResourceLeak#close()} when the + * related resource is deallocated. + * + * @return the {@link ResourceLeak} or {@code null} + */ + public ResourceLeak open(T obj) { + Level level = ResourceLeakDetector.level; + if (level == Level.DISABLED) { + return null; + } + + if (level.ordinal() < Level.PARANOID.ordinal()) { + if (leakCheckCnt ++ % samplingInterval == 0) { + reportLeak(level); + return new DefaultResourceLeak(obj); + } else { + return null; + } + } else { + reportLeak(level); + return new DefaultResourceLeak(obj); + } + } + + private void reportLeak(Level level) { + if (!logger.isErrorEnabled()) { + for (;;) { + + DefaultResourceLeak ref = (DefaultResourceLeak) refQueue.poll(); + if (ref == null) { + break; + } + ref.close(); + } + return; + } + + // Report too many instances. + int samplingInterval = level == Level.PARANOID? 1 : this.samplingInterval; + if (active * samplingInterval > maxActive && loggedTooManyActive.compareAndSet(false, true)) { + logger.error("LEAK: You are creating too many " + resourceType + " instances. " + + resourceType + " is a shared resource that must be reused across the JVM," + + "so that only a few instances are created."); + } + + // Detect and report previous leaks. + for (;;) { + + DefaultResourceLeak ref = (DefaultResourceLeak) refQueue.poll(); + if (ref == null) { + break; + } + + ref.clear(); + + if (!ref.close()) { + continue; + } + + String records = ref.toString(); + if (reportedLeaks.putIfAbsent(records, Boolean.TRUE) == null) { + if (records.isEmpty()) { + logger.error("LEAK: {}.release() was not called before it's garbage-collected. " + + "Enable advanced leak reporting to find out where the leak occurred. " + + "To enable advanced leak reporting, " + + "specify the JVM option '-D{}={}' or call {}.setLevel()", + resourceType, PROP_LEVEL, Level.ADVANCED.name().toLowerCase(), simpleClassName(this)); + } else { + logger.error( + "LEAK: {}.release() was not called before it's garbage-collected.{}", + resourceType, records); + } + } + } + } + + private final class DefaultResourceLeak extends PhantomReference implements ResourceLeak { + + private static final int MAX_RECORDS = 4; + + private final String creationRecord; + private final Deque lastRecords = new ArrayDeque(); + private final AtomicBoolean freed; + private DefaultResourceLeak prev; + private DefaultResourceLeak next; + + DefaultResourceLeak(Object referent) { + super(referent, referent != null? refQueue : null); + + if (referent != null) { + Level level = getLevel(); + if (level.ordinal() >= Level.ADVANCED.ordinal()) { + creationRecord = newRecord(3); + } else { + creationRecord = null; + } + + // TODO: Use CAS to update the list. + synchronized (head) { + prev = head; + next = head.next; + head.next.prev = this; + head.next = this; + active ++; + } + freed = new AtomicBoolean(); + } else { + creationRecord = null; + freed = new AtomicBoolean(true); + } + } + + @Override + public void record() { + if (creationRecord != null) { + String value = newRecord(2); + + synchronized (lastRecords) { + int size = lastRecords.size(); + if (size == 0 || !lastRecords.getLast().equals(value)) { + lastRecords.add(value); + } + if (size > MAX_RECORDS) { + lastRecords.removeFirst(); + } + } + } + } + + @Override + public boolean close() { + if (freed.compareAndSet(false, true)) { + synchronized (head) { + active --; + prev.next = next; + next.prev = prev; + prev = null; + next = null; + } + return true; + } + return false; + } + + public String toString() { + if (creationRecord == null) { + return ""; + } + + Object[] array; + synchronized (lastRecords) { + array = lastRecords.toArray(); + } + + StringBuilder buf = new StringBuilder(16384); + buf.append(NEWLINE); + buf.append("Recent access records: "); + buf.append(array.length); + buf.append(NEWLINE); + + if (array.length > 0) { + for (int i = array.length - 1; i >= 0; i --) { + buf.append('#'); + buf.append(i + 1); + buf.append(':'); + buf.append(NEWLINE); + buf.append(array[i]); + } + } + + buf.append("Created at:"); + buf.append(NEWLINE); + buf.append(creationRecord); + buf.setLength(buf.length() - NEWLINE.length()); + + return buf.toString(); + } + } + + private static final String[] STACK_TRACE_ELEMENT_EXCLUSIONS = { + "game.net.buffer.AbstractByteBufAllocator.toLeakAwareBuffer(", + }; + + static String newRecord(int recordsToSkip) { + StringBuilder buf = new StringBuilder(4096); + StackTraceElement[] array = new Throwable().getStackTrace(); + for (StackTraceElement e: array) { + if (recordsToSkip > 0) { + recordsToSkip --; + } else { + String estr = e.toString(); + + // Strip the noisy stack trace elements. + boolean excluded = false; + for (String exclusion: STACK_TRACE_ELEMENT_EXCLUSIONS) { + if (estr.startsWith(exclusion)) { + excluded = true; + break; + } + } + + if (!excluded) { + buf.append('\t'); + buf.append(estr); + buf.append(NEWLINE); + } + } + } + + return buf.toString(); + } +} diff --git a/common/src/common/net/util/Signal.java b/common/src/common/net/util/Signal.java new file mode 100644 index 0000000..eec3fd1 --- /dev/null +++ b/common/src/common/net/util/Signal.java @@ -0,0 +1,77 @@ +/* + * Copyright 2012 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ +package common.net.util; + + +import java.util.concurrent.ConcurrentMap; + +import common.net.util.internal.PlatformDependent; + +/** + * A special {@link Error} which is used to signal some state or request by throwing it. + * {@link Signal} has an empty stack trace and has no cause to save the instantiation overhead. + */ +public final class Signal extends Error { + + private static final long serialVersionUID = -221145131122459977L; + + private static final ConcurrentMap map = PlatformDependent.newConcurrentHashMap(); + + + private final UniqueName uname; + + /** + * Creates a new {@link Signal} with the specified {@code name}. + */ + + public static Signal valueOf(String name) { + return new Signal(name); + } + + /** + * @deprecated Use {@link #valueOf(String)} instead. + */ + @Deprecated + public Signal(String name) { + super(name); + uname = new UniqueName(map, name); + } + + /** + * Check if the given {@link Signal} is the same as this instance. If not an {@link IllegalStateException} will + * be thrown. + */ + public void expect(Signal signal) { + if (this != signal) { + throw new IllegalStateException("unexpected signal: " + signal); + } + } + + @Override + public Throwable initCause(Throwable cause) { + return this; + } + + @Override + public Throwable fillInStackTrace() { + return this; + } + + @Override + public String toString() { + return uname.name(); + } +} diff --git a/common/src/common/net/util/ThreadDeathWatcher.java b/common/src/common/net/util/ThreadDeathWatcher.java new file mode 100644 index 0000000..af972be --- /dev/null +++ b/common/src/common/net/util/ThreadDeathWatcher.java @@ -0,0 +1,241 @@ +/* + * Copyright 2014 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ + +package common.net.util; + +import java.util.ArrayList; +import java.util.List; +import java.util.Queue; +import java.util.concurrent.ThreadFactory; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicBoolean; + +import common.net.util.concurrent.DefaultThreadFactory; +import common.net.util.internal.MpscLinkedQueueNode; +import common.net.util.internal.PlatformDependent; +import common.net.util.internal.logging.InternalLogger; +import common.net.util.internal.logging.InternalLoggerFactory; + +/** + * Checks if a thread is alive periodically and runs a task when a thread dies. + *

+ * This thread starts a daemon thread to check the state of the threads being watched and to invoke their + * associated {@link Runnable}s. When there is no thread to watch (i.e. all threads are dead), the daemon thread + * will terminate itself, and a new daemon thread will be started again when a new watch is added. + *

+ */ +public final class ThreadDeathWatcher { + + private static final InternalLogger logger = InternalLoggerFactory.getInstance(ThreadDeathWatcher.class); + private static final ThreadFactory threadFactory = + new DefaultThreadFactory(ThreadDeathWatcher.class, true, Thread.MIN_PRIORITY); + + private static final Queue pendingEntries = PlatformDependent.newMpscQueue(); + private static final Watcher watcher = new Watcher(); + private static final AtomicBoolean started = new AtomicBoolean(); + private static volatile Thread watcherThread; + + /** + * Schedules the specified {@code task} to run when the specified {@code thread} dies. + * + * @param thread the {@link Thread} to watch + * @param task the {@link Runnable} to run when the {@code thread} dies + * + * @throws IllegalArgumentException if the specified {@code thread} is not alive + */ + public static void watch(Thread thread, Runnable task) { + if (thread == null) { + throw new NullPointerException("thread"); + } + if (task == null) { + throw new NullPointerException("task"); + } + if (!thread.isAlive()) { + throw new IllegalArgumentException("thread must be alive."); + } + + schedule(thread, task, true); + } + + /** + * Cancels the task scheduled via {@link #watch(Thread, Runnable)}. + */ + public static void unwatch(Thread thread, Runnable task) { + if (thread == null) { + throw new NullPointerException("thread"); + } + if (task == null) { + throw new NullPointerException("task"); + } + + schedule(thread, task, false); + } + + private static void schedule(Thread thread, Runnable task, boolean isWatch) { + pendingEntries.add(new Entry(thread, task, isWatch)); + + if (started.compareAndSet(false, true)) { + Thread watcherThread = threadFactory.newThread(watcher); + watcherThread.start(); + ThreadDeathWatcher.watcherThread = watcherThread; + } + } + + /** + * Waits until the thread of this watcher has no threads to watch and terminates itself. + * Because a new watcher thread will be started again on {@link #watch(Thread, Runnable)}, + * this operation is only useful when you want to ensure that the watcher thread is terminated + * after your application is shut down and there's no chance of calling + * {@link #watch(Thread, Runnable)} afterwards. + * + * @return {@code true} if and only if the watcher thread has been terminated + */ + public static boolean awaitInactivity(long timeout, TimeUnit unit) throws InterruptedException { + if (unit == null) { + throw new NullPointerException("unit"); + } + + Thread watcherThread = ThreadDeathWatcher.watcherThread; + if (watcherThread != null) { + watcherThread.join(unit.toMillis(timeout)); + return !watcherThread.isAlive(); + } else { + return true; + } + } + + private ThreadDeathWatcher() { } + + private static final class Watcher implements Runnable { + + private final List watchees = new ArrayList(); + + @Override + public void run() { + for (;;) { + fetchWatchees(); + notifyWatchees(); + + // Try once again just in case notifyWatchees() triggered watch() or unwatch(). + fetchWatchees(); + notifyWatchees(); + + try { + Thread.sleep(1000); + } catch (InterruptedException ignore) { + // Ignore the interrupt; do not terminate until all tasks are run. + } + + if (watchees.isEmpty() && pendingEntries.isEmpty()) { + + // Mark the current worker thread as stopped. + // The following CAS must always success and must be uncontended, + // because only one watcher thread should be running at the same time. + boolean stopped = started.compareAndSet(true, false); + assert stopped; + + // Check if there are pending entries added by watch() while we do CAS above. + if (pendingEntries.isEmpty()) { + // A) watch() was not invoked and thus there's nothing to handle + // -> safe to terminate because there's nothing left to do + // B) a new watcher thread started and handled them all + // -> safe to terminate the new watcher thread will take care the rest + break; + } + + // There are pending entries again, added by watch() + if (!started.compareAndSet(false, true)) { + // watch() started a new watcher thread and set 'started' to true. + // -> terminate this thread so that the new watcher reads from pendingEntries exclusively. + break; + } + + // watch() added an entry, but this worker was faster to set 'started' to true. + // i.e. a new watcher thread was not started + // -> keep this thread alive to handle the newly added entries. + } + } + } + + private void fetchWatchees() { + for (;;) { + Entry e = pendingEntries.poll(); + if (e == null) { + break; + } + + if (e.isWatch) { + watchees.add(e); + } else { + watchees.remove(e); + } + } + } + + private void notifyWatchees() { + List watchees = this.watchees; + for (int i = 0; i < watchees.size();) { + Entry e = watchees.get(i); + if (!e.thread.isAlive()) { + watchees.remove(i); + try { + e.task.run(); + } catch (Throwable t) { + logger.warn("Thread death watcher task raised an exception:", t); + } + } else { + i ++; + } + } + } + } + + private static final class Entry extends MpscLinkedQueueNode { + final Thread thread; + final Runnable task; + final boolean isWatch; + + Entry(Thread thread, Runnable task, boolean isWatch) { + this.thread = thread; + this.task = task; + this.isWatch = isWatch; + } + + @Override + public Entry value() { + return this; + } + + @Override + public int hashCode() { + return thread.hashCode() ^ task.hashCode(); + } + + @Override + public boolean equals(Object obj) { + if (obj == this) { + return true; + } + + if (!(obj instanceof Entry)) { + return false; + } + + Entry that = (Entry) obj; + return thread == that.thread && task == that.task; + } + } +} diff --git a/common/src/common/net/util/UniqueName.java b/common/src/common/net/util/UniqueName.java new file mode 100644 index 0000000..706670e --- /dev/null +++ b/common/src/common/net/util/UniqueName.java @@ -0,0 +1,117 @@ +/* + * Copyright 2012 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ +package common.net.util; + +import java.util.concurrent.ConcurrentMap; +import java.util.concurrent.atomic.AtomicInteger; + +/** + * @deprecated Known to have problems with class loaders. + * + * Defines a name that must be unique in the map that is provided during construction. + */ +@Deprecated +public class UniqueName implements Comparable { + + private static final AtomicInteger nextId = new AtomicInteger(); + + private final int id; + private final String name; + + /** + * Constructs a new {@link UniqueName} + * + * @param map the map of names to compare with + * @param name the name of this {@link UniqueName} + * @param args the arguments to process + */ + public UniqueName(ConcurrentMap map, String name, Object... args) { + if (map == null) { + throw new NullPointerException("map"); + } + if (name == null) { + throw new NullPointerException("name"); + } + if (args != null && args.length > 0) { + validateArgs(args); + } + + if (map.putIfAbsent(name, Boolean.TRUE) != null) { + throw new IllegalArgumentException(String.format("'%s' is already in use", name)); + } + + id = nextId.incrementAndGet(); + this.name = name; + } + + /** + * Validates the given arguments. This method does not do anything on its own, but must be + * overridden by its subclasses. + * + * @param args arguments to validate + */ + + protected void validateArgs(Object... args) { + // Subclasses will override. + } + + /** + * Returns this {@link UniqueName}'s name + * + * @return the name + */ + public final String name() { + return name; + } + + /** + * Returns this {@link UniqueName}'s ID + * + * @return the id + */ + public final int id() { + return id; + } + + @Override + public final int hashCode() { + return super.hashCode(); + } + + @Override + public final boolean equals(Object o) { + return super.equals(o); + } + + @Override + public int compareTo(UniqueName other) { + if (this == other) { + return 0; + } + + int returnCode = name.compareTo(other.name); + if (returnCode != 0) { + return returnCode; + } + + return ((Integer) id).compareTo(other.id); + } + + @Override + public String toString() { + return name(); + } +} diff --git a/common/src/common/net/util/concurrent/AbstractEventExecutor.java b/common/src/common/net/util/concurrent/AbstractEventExecutor.java new file mode 100644 index 0000000..1392ed6 --- /dev/null +++ b/common/src/common/net/util/concurrent/AbstractEventExecutor.java @@ -0,0 +1,157 @@ +/* + * Copyright 2013 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ +package common.net.util.concurrent; + +import java.util.Collections; +import java.util.Iterator; +import java.util.List; +import java.util.NoSuchElementException; +import java.util.concurrent.AbstractExecutorService; +import java.util.concurrent.Callable; +import java.util.concurrent.RunnableFuture; +import java.util.concurrent.TimeUnit; + +/** + * Abstract base class for {@link EventExecutor} implementations. + */ +public abstract class AbstractEventExecutor extends AbstractExecutorService implements EventExecutor { + + @Override + public EventExecutor next() { + return this; + } + + @Override + public boolean inEventLoop() { + return inEventLoop(Thread.currentThread()); + } + + @Override + public Iterator iterator() { + return new EventExecutorIterator(); + } + + @Override + public Future shutdownGracefully() { + return shutdownGracefully(2, 15, TimeUnit.SECONDS); + } + + /** + * @deprecated {@link #shutdownGracefully(long, long, TimeUnit)} or {@link #shutdownGracefully()} instead. + */ + @Override + @Deprecated + public abstract void shutdown(); + + /** + * @deprecated {@link #shutdownGracefully(long, long, TimeUnit)} or {@link #shutdownGracefully()} instead. + */ + @Override + @Deprecated + public List shutdownNow() { + shutdown(); + return Collections.emptyList(); + } + + @Override + public Promise newPromise() { + return new DefaultPromise(this); + } + + @Override + public ProgressivePromise newProgressivePromise() { + return new DefaultProgressivePromise(this); + } + + @Override + public Future newSucceededFuture(V result) { + return new SucceededFuture(this, result); + } + + @Override + public Future newFailedFuture(Throwable cause) { + return new FailedFuture(this, cause); + } + + @Override + public Future submit(Runnable task) { + return (Future) super.submit(task); + } + + @Override + public Future submit(Runnable task, T result) { + return (Future) super.submit(task, result); + } + + @Override + public Future submit(Callable task) { + return (Future) super.submit(task); + } + + @Override + protected final RunnableFuture newTaskFor(Runnable runnable, T value) { + return new PromiseTask(this, runnable, value); + } + + @Override + protected final RunnableFuture newTaskFor(Callable callable) { + return new PromiseTask(this, callable); + } + + @Override + public ScheduledFuture schedule(Runnable command, long delay, + TimeUnit unit) { + throw new UnsupportedOperationException(); + } + + @Override + public ScheduledFuture schedule(Callable callable, long delay, TimeUnit unit) { + throw new UnsupportedOperationException(); + } + + @Override + public ScheduledFuture scheduleAtFixedRate(Runnable command, long initialDelay, long period, TimeUnit unit) { + throw new UnsupportedOperationException(); + } + + @Override + public ScheduledFuture scheduleWithFixedDelay(Runnable command, long initialDelay, long delay, TimeUnit unit) { + throw new UnsupportedOperationException(); + } + + private final class EventExecutorIterator implements Iterator { + private boolean nextCalled; + + @Override + public boolean hasNext() { + return !nextCalled; + } + + @Override + public EventExecutor next() { + if (!hasNext()) { + throw new NoSuchElementException(); + } + nextCalled = true; + return AbstractEventExecutor.this; + } + + @Override + public void remove() { + throw new UnsupportedOperationException("read-only"); + } + } +} diff --git a/common/src/common/net/util/concurrent/AbstractEventExecutorGroup.java b/common/src/common/net/util/concurrent/AbstractEventExecutorGroup.java new file mode 100644 index 0000000..8c1b768 --- /dev/null +++ b/common/src/common/net/util/concurrent/AbstractEventExecutorGroup.java @@ -0,0 +1,116 @@ +/* + * Copyright 2013 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ +package common.net.util.concurrent; + +import java.util.Collection; +import java.util.Collections; +import java.util.List; +import java.util.concurrent.Callable; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; + + +/** + * Abstract base class for {@link EventExecutorGroup} implementations. + */ +public abstract class AbstractEventExecutorGroup implements EventExecutorGroup { + + @Override + public Future submit(Runnable task) { + return next().submit(task); + } + + @Override + public Future submit(Runnable task, T result) { + return next().submit(task, result); + } + + @Override + public Future submit(Callable task) { + return next().submit(task); + } + + @Override + public ScheduledFuture schedule(Runnable command, long delay, TimeUnit unit) { + return next().schedule(command, delay, unit); + } + + @Override + public ScheduledFuture schedule(Callable callable, long delay, TimeUnit unit) { + return next().schedule(callable, delay, unit); + } + + @Override + public ScheduledFuture scheduleAtFixedRate(Runnable command, long initialDelay, long period, TimeUnit unit) { + return next().scheduleAtFixedRate(command, initialDelay, period, unit); + } + + @Override + public ScheduledFuture scheduleWithFixedDelay(Runnable command, long initialDelay, long delay, TimeUnit unit) { + return next().scheduleWithFixedDelay(command, initialDelay, delay, unit); + } + + @Override + public Future shutdownGracefully() { + return shutdownGracefully(2, 15, TimeUnit.SECONDS); + } + + /** + * @deprecated {@link #shutdownGracefully(long, long, TimeUnit)} or {@link #shutdownGracefully()} instead. + */ + @Override + @Deprecated + public abstract void shutdown(); + + /** + * @deprecated {@link #shutdownGracefully(long, long, TimeUnit)} or {@link #shutdownGracefully()} instead. + */ + @Override + @Deprecated + public List shutdownNow() { + shutdown(); + return Collections.emptyList(); + } + + @Override + public List> invokeAll(Collection> tasks) + throws InterruptedException { + return next().invokeAll(tasks); + } + + @Override + public List> invokeAll( + Collection> tasks, long timeout, TimeUnit unit) throws InterruptedException { + return next().invokeAll(tasks, timeout, unit); + } + + @Override + public T invokeAny(Collection> tasks) throws InterruptedException, ExecutionException { + return next().invokeAny(tasks); + } + + @Override + public T invokeAny(Collection> tasks, long timeout, TimeUnit unit) + throws InterruptedException, ExecutionException, TimeoutException { + return next().invokeAny(tasks, timeout, unit); + } + + @Override + public void execute(Runnable command) { + next().execute(command); + } +} diff --git a/common/src/common/net/util/concurrent/AbstractFuture.java b/common/src/common/net/util/concurrent/AbstractFuture.java new file mode 100644 index 0000000..e288643 --- /dev/null +++ b/common/src/common/net/util/concurrent/AbstractFuture.java @@ -0,0 +1,51 @@ +/* + * Copyright 2013 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ +package common.net.util.concurrent; + +import java.util.concurrent.ExecutionException; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; + +/** + * Abstract {@link Future} implementation which does not allow for cancellation. + * + * @param + */ +public abstract class AbstractFuture implements Future { + + @Override + public V get() throws InterruptedException, ExecutionException { + await(); + + Throwable cause = cause(); + if (cause == null) { + return getNow(); + } + throw new ExecutionException(cause); + } + + @Override + public V get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException { + if (await(timeout, unit)) { + Throwable cause = cause(); + if (cause == null) { + return getNow(); + } + throw new ExecutionException(cause); + } + throw new TimeoutException(); + } +} diff --git a/common/src/common/net/util/concurrent/BlockingOperationException.java b/common/src/common/net/util/concurrent/BlockingOperationException.java new file mode 100644 index 0000000..725b524 --- /dev/null +++ b/common/src/common/net/util/concurrent/BlockingOperationException.java @@ -0,0 +1,41 @@ +/* + * Copyright 2012 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ +package common.net.util.concurrent; + +/** + * An {@link IllegalStateException} which is raised when a user performed a blocking operation + * when the user is in an event loop thread. If a blocking operation is performed in an event loop + * thread, the blocking operation will most likely enter a dead lock state, hence throwing this + * exception. + */ +public class BlockingOperationException extends IllegalStateException { + + private static final long serialVersionUID = 2462223247762460301L; + + public BlockingOperationException() { } + + public BlockingOperationException(String s) { + super(s); + } + + public BlockingOperationException(Throwable cause) { + super(cause); + } + + public BlockingOperationException(String message, Throwable cause) { + super(message, cause); + } +} diff --git a/common/src/common/net/util/concurrent/CompleteFuture.java b/common/src/common/net/util/concurrent/CompleteFuture.java new file mode 100644 index 0000000..2761a6e --- /dev/null +++ b/common/src/common/net/util/concurrent/CompleteFuture.java @@ -0,0 +1,147 @@ +/* + * Copyright 2013 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ + +package common.net.util.concurrent; + +import java.util.concurrent.TimeUnit; + +/** + * A skeletal {@link Future} implementation which represents a {@link Future} which has been completed already. + */ +public abstract class CompleteFuture extends AbstractFuture { + + private final EventExecutor executor; + + /** + * Creates a new instance. + * + * @param executor the {@link EventExecutor} associated with this future + */ + protected CompleteFuture(EventExecutor executor) { + this.executor = executor; + } + + /** + * Return the {@link EventExecutor} which is used by this {@link CompleteFuture}. + */ + protected EventExecutor executor() { + return executor; + } + + @Override + public Future addListener(GenericFutureListener> listener) { + if (listener == null) { + throw new NullPointerException("listener"); + } + DefaultPromise.notifyListener(executor(), this, listener); + return this; + } + + @Override + public Future addListeners(GenericFutureListener>... listeners) { + if (listeners == null) { + throw new NullPointerException("listeners"); + } + for (GenericFutureListener> l: listeners) { + if (l == null) { + break; + } + DefaultPromise.notifyListener(executor(), this, l); + } + return this; + } + + @Override + public Future removeListener(GenericFutureListener> listener) { + // NOOP + return this; + } + + @Override + public Future removeListeners(GenericFutureListener>... listeners) { + // NOOP + return this; + } + + @Override + public Future await() throws InterruptedException { + if (Thread.interrupted()) { + throw new InterruptedException(); + } + return this; + } + + @Override + public boolean await(long timeout, TimeUnit unit) throws InterruptedException { + if (Thread.interrupted()) { + throw new InterruptedException(); + } + return true; + } + + @Override + public Future sync() throws InterruptedException { + return this; + } + + @Override + public Future syncUninterruptibly() { + return this; + } + + @Override + public boolean await(long timeoutMillis) throws InterruptedException { + if (Thread.interrupted()) { + throw new InterruptedException(); + } + return true; + } + + @Override + public Future awaitUninterruptibly() { + return this; + } + + @Override + public boolean awaitUninterruptibly(long timeout, TimeUnit unit) { + return true; + } + + @Override + public boolean awaitUninterruptibly(long timeoutMillis) { + return true; + } + + @Override + public boolean isDone() { + return true; + } + + @Override + public boolean isCancellable() { + return false; + } + + @Override + public boolean isCancelled() { + return false; + } + + @Override + public boolean cancel(boolean mayInterruptIfRunning) { + return false; + } +} diff --git a/common/src/common/net/util/concurrent/DefaultEventExecutor.java b/common/src/common/net/util/concurrent/DefaultEventExecutor.java new file mode 100644 index 0000000..7f7c611 --- /dev/null +++ b/common/src/common/net/util/concurrent/DefaultEventExecutor.java @@ -0,0 +1,45 @@ +/* + * Copyright 2012 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ +package common.net.util.concurrent; + +import java.util.concurrent.ThreadFactory; + +/** + * Default {@link SingleThreadEventExecutor} implementation which just execute all submitted task in a + * serial fashion + * + */ +final class DefaultEventExecutor extends SingleThreadEventExecutor { + + DefaultEventExecutor(DefaultEventExecutorGroup parent, ThreadFactory threadFactory) { + super(parent, threadFactory, true); + } + + @Override + protected void run() { + for (;;) { + Runnable task = takeTask(); + if (task != null) { + task.run(); + updateLastExecutionTime(); + } + + if (confirmShutdown()) { + break; + } + } + } +} diff --git a/common/src/common/net/util/concurrent/DefaultEventExecutorGroup.java b/common/src/common/net/util/concurrent/DefaultEventExecutorGroup.java new file mode 100644 index 0000000..10c165a --- /dev/null +++ b/common/src/common/net/util/concurrent/DefaultEventExecutorGroup.java @@ -0,0 +1,48 @@ +/* + * Copyright 2012 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ +package common.net.util.concurrent; + +import java.util.concurrent.ThreadFactory; + +/** + * Default implementation of {@link MultithreadEventExecutorGroup} which will use {@link DefaultEventExecutor} instances + * to handle the tasks. + */ +public class DefaultEventExecutorGroup extends MultithreadEventExecutorGroup { + + /** + * @see {@link #DefaultEventExecutorGroup(int, ThreadFactory)} + */ + public DefaultEventExecutorGroup(int nThreads) { + this(nThreads, null); + } + + /** + * Create a new instance. + * + * @param nThreads the number of threads that will be used by this instance. + * @param threadFactory the ThreadFactory to use, or {@code null} if the default should be used. + */ + public DefaultEventExecutorGroup(int nThreads, ThreadFactory threadFactory) { + super(nThreads, threadFactory); + } + + @Override + protected EventExecutor newChild( + ThreadFactory threadFactory, Object... args) throws Exception { + return new DefaultEventExecutor(this, threadFactory); + } +} diff --git a/common/src/common/net/util/concurrent/DefaultFutureListeners.java b/common/src/common/net/util/concurrent/DefaultFutureListeners.java new file mode 100644 index 0000000..37a830e --- /dev/null +++ b/common/src/common/net/util/concurrent/DefaultFutureListeners.java @@ -0,0 +1,86 @@ +/* + * Copyright 2013 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ +package common.net.util.concurrent; + +import java.util.Arrays; + +final class DefaultFutureListeners { + + private GenericFutureListener>[] listeners; + private int size; + private int progressiveSize; // the number of progressive listeners + + + DefaultFutureListeners( + GenericFutureListener> first, GenericFutureListener> second) { + listeners = new GenericFutureListener[2]; + listeners[0] = first; + listeners[1] = second; + size = 2; + if (first instanceof GenericProgressiveFutureListener) { + progressiveSize ++; + } + if (second instanceof GenericProgressiveFutureListener) { + progressiveSize ++; + } + } + + public void add(GenericFutureListener> l) { + GenericFutureListener>[] listeners = this.listeners; + final int size = this.size; + if (size == listeners.length) { + this.listeners = listeners = Arrays.copyOf(listeners, size << 1); + } + listeners[size] = l; + this.size = size + 1; + + if (l instanceof GenericProgressiveFutureListener) { + progressiveSize ++; + } + } + + public void remove(GenericFutureListener> l) { + final GenericFutureListener>[] listeners = this.listeners; + int size = this.size; + for (int i = 0; i < size; i ++) { + if (listeners[i] == l) { + int listenersToMove = size - i - 1; + if (listenersToMove > 0) { + System.arraycopy(listeners, i + 1, listeners, i, listenersToMove); + } + listeners[-- size] = null; + this.size = size; + + if (l instanceof GenericProgressiveFutureListener) { + progressiveSize --; + } + return; + } + } + } + + public GenericFutureListener>[] listeners() { + return listeners; + } + + public int size() { + return size; + } + + public int progressiveSize() { + return progressiveSize; + } +} diff --git a/common/src/common/net/util/concurrent/DefaultProgressivePromise.java b/common/src/common/net/util/concurrent/DefaultProgressivePromise.java new file mode 100644 index 0000000..57d908a --- /dev/null +++ b/common/src/common/net/util/concurrent/DefaultProgressivePromise.java @@ -0,0 +1,130 @@ +/* + * Copyright 2013 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ + +package common.net.util.concurrent; + +public class DefaultProgressivePromise extends DefaultPromise implements ProgressivePromise { + + /** + * Creates a new instance. + * + * It is preferable to use {@link EventExecutor#newProgressivePromise()} to create a new progressive promise + * + * @param executor + * the {@link EventExecutor} which is used to notify the promise when it progresses or it is complete + */ + public DefaultProgressivePromise(EventExecutor executor) { + super(executor); + } + + protected DefaultProgressivePromise() { /* only for subclasses */ } + + @Override + public ProgressivePromise setProgress(long progress, long total) { + if (total < 0) { + // total unknown + total = -1; // normalize + if (progress < 0) { + throw new IllegalArgumentException("progress: " + progress + " (expected: >= 0)"); + } + } else if (progress < 0 || progress > total) { + throw new IllegalArgumentException( + "progress: " + progress + " (expected: 0 <= progress <= total (" + total + "))"); + } + + if (isDone()) { + throw new IllegalStateException("complete already"); + } + + notifyProgressiveListeners(progress, total); + return this; + } + + @Override + public boolean tryProgress(long progress, long total) { + if (total < 0) { + total = -1; + if (progress < 0 || isDone()) { + return false; + } + } else if (progress < 0 || progress > total || isDone()) { + return false; + } + + notifyProgressiveListeners(progress, total); + return true; + } + + @Override + public ProgressivePromise addListener(GenericFutureListener> listener) { + super.addListener(listener); + return this; + } + + @Override + public ProgressivePromise addListeners(GenericFutureListener>... listeners) { + super.addListeners(listeners); + return this; + } + + @Override + public ProgressivePromise removeListener(GenericFutureListener> listener) { + super.removeListener(listener); + return this; + } + + @Override + public ProgressivePromise removeListeners(GenericFutureListener>... listeners) { + super.removeListeners(listeners); + return this; + } + + @Override + public ProgressivePromise sync() throws InterruptedException { + super.sync(); + return this; + } + + @Override + public ProgressivePromise syncUninterruptibly() { + super.syncUninterruptibly(); + return this; + } + + @Override + public ProgressivePromise await() throws InterruptedException { + super.await(); + return this; + } + + @Override + public ProgressivePromise awaitUninterruptibly() { + super.awaitUninterruptibly(); + return this; + } + + @Override + public ProgressivePromise setSuccess(V result) { + super.setSuccess(result); + return this; + } + + @Override + public ProgressivePromise setFailure(Throwable cause) { + super.setFailure(cause); + return this; + } +} diff --git a/common/src/common/net/util/concurrent/DefaultPromise.java b/common/src/common/net/util/concurrent/DefaultPromise.java new file mode 100644 index 0000000..eb38442 --- /dev/null +++ b/common/src/common/net/util/concurrent/DefaultPromise.java @@ -0,0 +1,876 @@ +/* + * Copyright 2013 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ +package common.net.util.concurrent; + +import static java.util.concurrent.TimeUnit.MILLISECONDS; + +import java.util.ArrayDeque; +import java.util.concurrent.CancellationException; +import java.util.concurrent.TimeUnit; + +import common.net.util.Signal; +import common.net.util.internal.EmptyArrays; +import common.net.util.internal.InternalThreadLocalMap; +import common.net.util.internal.PlatformDependent; +import common.net.util.internal.StringUtil; +import common.net.util.internal.logging.InternalLogger; +import common.net.util.internal.logging.InternalLoggerFactory; + +public class DefaultPromise extends AbstractFuture implements Promise { + + private static final InternalLogger logger = InternalLoggerFactory.getInstance(DefaultPromise.class); + private static final InternalLogger rejectedExecutionLogger = + InternalLoggerFactory.getInstance(DefaultPromise.class.getName() + ".rejectedExecution"); + + private static final int MAX_LISTENER_STACK_DEPTH = 8; + private static final Signal SUCCESS = Signal.valueOf(DefaultPromise.class.getName() + ".SUCCESS"); + private static final Signal UNCANCELLABLE = Signal.valueOf(DefaultPromise.class.getName() + ".UNCANCELLABLE"); + private static final CauseHolder CANCELLATION_CAUSE_HOLDER = new CauseHolder(new CancellationException()); + + static { + CANCELLATION_CAUSE_HOLDER.cause.setStackTrace(EmptyArrays.EMPTY_STACK_TRACE); + } + + private final EventExecutor executor; + + private volatile Object result; + + /** + * One or more listeners. Can be a {@link GenericFutureListener} or a {@link DefaultFutureListeners}. + * If {@code null}, it means either 1) no listeners were added yet or 2) all listeners were notified. + */ + private Object listeners; + + /** + * The list of the listeners that were added after the promise is done. Initially {@code null} and lazily + * instantiated when the late listener is scheduled to be notified later. Also used as a cached {@link Runnable} + * that performs the notification of the listeners it contains. + */ + private LateListeners lateListeners; + + private short waiters; + + /** + * Creates a new instance. + * + * It is preferable to use {@link EventExecutor#newPromise()} to create a new promise + * + * @param executor + * the {@link EventExecutor} which is used to notify the promise once it is complete + */ + public DefaultPromise(EventExecutor executor) { + if (executor == null) { + throw new NullPointerException("executor"); + } + this.executor = executor; + } + + protected DefaultPromise() { + // only for subclasses + executor = null; + } + + protected EventExecutor executor() { + return executor; + } + + @Override + public boolean isCancelled() { + return isCancelled0(result); + } + + private static boolean isCancelled0(Object result) { + return result instanceof CauseHolder && ((CauseHolder) result).cause instanceof CancellationException; + } + + @Override + public boolean isCancellable() { + return result == null; + } + + @Override + public boolean isDone() { + return isDone0(result); + } + + private static boolean isDone0(Object result) { + return result != null && result != UNCANCELLABLE; + } + + @Override + public boolean isSuccess() { + Object result = this.result; + if (result == null || result == UNCANCELLABLE) { + return false; + } + return !(result instanceof CauseHolder); + } + + @Override + public Throwable cause() { + Object result = this.result; + if (result instanceof CauseHolder) { + return ((CauseHolder) result).cause; + } + return null; + } + + @Override + public Promise addListener(GenericFutureListener> listener) { + if (listener == null) { + throw new NullPointerException("listener"); + } + + if (isDone()) { + notifyLateListener(listener); + return this; + } + + synchronized (this) { + if (!isDone()) { + if (listeners == null) { + listeners = listener; + } else { + if (listeners instanceof DefaultFutureListeners) { + ((DefaultFutureListeners) listeners).add(listener); + } else { + final GenericFutureListener> firstListener = + (GenericFutureListener>) listeners; + listeners = new DefaultFutureListeners(firstListener, listener); + } + } + return this; + } + } + + notifyLateListener(listener); + return this; + } + + @Override + public Promise addListeners(GenericFutureListener>... listeners) { + if (listeners == null) { + throw new NullPointerException("listeners"); + } + + for (GenericFutureListener> l: listeners) { + if (l == null) { + break; + } + addListener(l); + } + return this; + } + + @Override + public Promise removeListener(GenericFutureListener> listener) { + if (listener == null) { + throw new NullPointerException("listener"); + } + + if (isDone()) { + return this; + } + + synchronized (this) { + if (!isDone()) { + if (listeners instanceof DefaultFutureListeners) { + ((DefaultFutureListeners) listeners).remove(listener); + } else if (listeners == listener) { + listeners = null; + } + } + } + + return this; + } + + @Override + public Promise removeListeners(GenericFutureListener>... listeners) { + if (listeners == null) { + throw new NullPointerException("listeners"); + } + + for (GenericFutureListener> l: listeners) { + if (l == null) { + break; + } + removeListener(l); + } + return this; + } + + @Override + public Promise sync() throws InterruptedException { + await(); + rethrowIfFailed(); + return this; + } + + @Override + public Promise syncUninterruptibly() { + awaitUninterruptibly(); + rethrowIfFailed(); + return this; + } + + private void rethrowIfFailed() { + Throwable cause = cause(); + if (cause == null) { + return; + } + + PlatformDependent.throwException(cause); + } + + @Override + public Promise await() throws InterruptedException { + if (isDone()) { + return this; + } + + if (Thread.interrupted()) { + throw new InterruptedException(toString()); + } + + synchronized (this) { + while (!isDone()) { + checkDeadLock(); + incWaiters(); + try { + wait(); + } finally { + decWaiters(); + } + } + } + return this; + } + + @Override + public boolean await(long timeout, TimeUnit unit) + throws InterruptedException { + return await0(unit.toNanos(timeout), true); + } + + @Override + public boolean await(long timeoutMillis) throws InterruptedException { + return await0(MILLISECONDS.toNanos(timeoutMillis), true); + } + + @Override + public Promise awaitUninterruptibly() { + if (isDone()) { + return this; + } + + boolean interrupted = false; + synchronized (this) { + while (!isDone()) { + checkDeadLock(); + incWaiters(); + try { + wait(); + } catch (InterruptedException e) { + // Interrupted while waiting. + interrupted = true; + } finally { + decWaiters(); + } + } + } + + if (interrupted) { + Thread.currentThread().interrupt(); + } + + return this; + } + + @Override + public boolean awaitUninterruptibly(long timeout, TimeUnit unit) { + try { + return await0(unit.toNanos(timeout), false); + } catch (InterruptedException e) { + // Should not be raised at all. + throw new InternalError(); + } + } + + @Override + public boolean awaitUninterruptibly(long timeoutMillis) { + try { + return await0(MILLISECONDS.toNanos(timeoutMillis), false); + } catch (InterruptedException e) { + // Should not be raised at all. + throw new InternalError(); + } + } + + private boolean await0(long timeoutNanos, boolean interruptable) throws InterruptedException { + if (isDone()) { + return true; + } + + if (timeoutNanos <= 0) { + return isDone(); + } + + if (interruptable && Thread.interrupted()) { + throw new InterruptedException(toString()); + } + + long startTime = System.nanoTime(); + long waitTime = timeoutNanos; + boolean interrupted = false; + + try { + synchronized (this) { + if (isDone()) { + return true; + } + + if (waitTime <= 0) { + return isDone(); + } + + checkDeadLock(); + incWaiters(); + try { + for (;;) { + try { + wait(waitTime / 1000000, (int) (waitTime % 1000000)); + } catch (InterruptedException e) { + if (interruptable) { + throw e; + } else { + interrupted = true; + } + } + + if (isDone()) { + return true; + } else { + waitTime = timeoutNanos - (System.nanoTime() - startTime); + if (waitTime <= 0) { + return isDone(); + } + } + } + } finally { + decWaiters(); + } + } + } finally { + if (interrupted) { + Thread.currentThread().interrupt(); + } + } + } + + /** + * Do deadlock checks + */ + protected void checkDeadLock() { + EventExecutor e = executor(); + if (e != null && e.inEventLoop()) { + throw new BlockingOperationException(toString()); + } + } + + @Override + public Promise setSuccess(V result) { + if (setSuccess0(result)) { + notifyListeners(); + return this; + } + throw new IllegalStateException("complete already: " + this); + } + + @Override + public boolean trySuccess(V result) { + if (setSuccess0(result)) { + notifyListeners(); + return true; + } + return false; + } + + @Override + public Promise setFailure(Throwable cause) { + if (setFailure0(cause)) { + notifyListeners(); + return this; + } + throw new IllegalStateException("complete already: " + this, cause); + } + + @Override + public boolean tryFailure(Throwable cause) { + if (setFailure0(cause)) { + notifyListeners(); + return true; + } + return false; + } + + @Override + public boolean cancel(boolean mayInterruptIfRunning) { + Object result = this.result; + if (isDone0(result) || result == UNCANCELLABLE) { + return false; + } + + synchronized (this) { + // Allow only once. + result = this.result; + if (isDone0(result) || result == UNCANCELLABLE) { + return false; + } + + this.result = CANCELLATION_CAUSE_HOLDER; + if (hasWaiters()) { + notifyAll(); + } + } + + notifyListeners(); + return true; + } + + @Override + public boolean setUncancellable() { + Object result = this.result; + if (isDone0(result)) { + return !isCancelled0(result); + } + + synchronized (this) { + // Allow only once. + result = this.result; + if (isDone0(result)) { + return !isCancelled0(result); + } + + this.result = UNCANCELLABLE; + } + return true; + } + + private boolean setFailure0(Throwable cause) { + if (cause == null) { + throw new NullPointerException("cause"); + } + + if (isDone()) { + return false; + } + + synchronized (this) { + // Allow only once. + if (isDone()) { + return false; + } + + result = new CauseHolder(cause); + if (hasWaiters()) { + notifyAll(); + } + } + return true; + } + + private boolean setSuccess0(V result) { + if (isDone()) { + return false; + } + + synchronized (this) { + // Allow only once. + if (isDone()) { + return false; + } + if (result == null) { + this.result = SUCCESS; + } else { + this.result = result; + } + if (hasWaiters()) { + notifyAll(); + } + } + return true; + } + + @Override + + public V getNow() { + Object result = this.result; + if (result instanceof CauseHolder || result == SUCCESS) { + return null; + } + return (V) result; + } + + private boolean hasWaiters() { + return waiters > 0; + } + + private void incWaiters() { + if (waiters == Short.MAX_VALUE) { + throw new IllegalStateException("too many waiters: " + this); + } + waiters ++; + } + + private void decWaiters() { + waiters --; + } + + private void notifyListeners() { + // This method doesn't need synchronization because: + // 1) This method is always called after synchronized (this) block. + // Hence any listener list modification happens-before this method. + // 2) This method is called only when 'done' is true. Once 'done' + // becomes true, the listener list is never modified - see add/removeListener() + + Object listeners = this.listeners; + if (listeners == null) { + return; + } + + EventExecutor executor = executor(); + if (executor.inEventLoop()) { + final InternalThreadLocalMap threadLocals = InternalThreadLocalMap.get(); + final int stackDepth = threadLocals.futureListenerStackDepth(); + if (stackDepth < MAX_LISTENER_STACK_DEPTH) { + threadLocals.setFutureListenerStackDepth(stackDepth + 1); + try { + if (listeners instanceof DefaultFutureListeners) { + notifyListeners0(this, (DefaultFutureListeners) listeners); + } else { + final GenericFutureListener> l = + (GenericFutureListener>) listeners; + notifyListener0(this, l); + } + } finally { + this.listeners = null; + threadLocals.setFutureListenerStackDepth(stackDepth); + } + return; + } + } + + if (listeners instanceof DefaultFutureListeners) { + final DefaultFutureListeners dfl = (DefaultFutureListeners) listeners; + execute(executor, new Runnable() { + @Override + public void run() { + notifyListeners0(DefaultPromise.this, dfl); + DefaultPromise.this.listeners = null; + } + }); + } else { + final GenericFutureListener> l = + (GenericFutureListener>) listeners; + execute(executor, new Runnable() { + @Override + public void run() { + notifyListener0(DefaultPromise.this, l); + DefaultPromise.this.listeners = null; + } + }); + } + } + + private static void notifyListeners0(Future future, DefaultFutureListeners listeners) { + final GenericFutureListener[] a = listeners.listeners(); + final int size = listeners.size(); + for (int i = 0; i < size; i ++) { + notifyListener0(future, a[i]); + } + } + + /** + * Notifies the specified listener which were added after this promise is already done. + * This method ensures that the specified listener is not notified until {@link #listeners} becomes {@code null} + * to avoid the case where the late listeners are notified even before the early listeners are notified. + */ + private void notifyLateListener(final GenericFutureListener l) { + final EventExecutor executor = executor(); + if (executor.inEventLoop()) { + if (listeners == null && lateListeners == null) { + final InternalThreadLocalMap threadLocals = InternalThreadLocalMap.get(); + final int stackDepth = threadLocals.futureListenerStackDepth(); + if (stackDepth < MAX_LISTENER_STACK_DEPTH) { + threadLocals.setFutureListenerStackDepth(stackDepth + 1); + try { + notifyListener0(this, l); + } finally { + threadLocals.setFutureListenerStackDepth(stackDepth); + } + return; + } + } else { + LateListeners lateListeners = this.lateListeners; + if (lateListeners == null) { + this.lateListeners = lateListeners = new LateListeners(); + } + lateListeners.add(l); + execute(executor, lateListeners); + return; + } + } + + // Add the late listener to lateListeners in the executor thread for thread safety. + // We could just make LateListeners extend ConcurrentLinkedQueue, but it's an overkill considering + // that most asynchronous applications won't execute this code path. + execute(executor, new LateListenerNotifier(l)); + } + + protected static void notifyListener( + final EventExecutor eventExecutor, final Future future, final GenericFutureListener l) { + + if (eventExecutor.inEventLoop()) { + final InternalThreadLocalMap threadLocals = InternalThreadLocalMap.get(); + final int stackDepth = threadLocals.futureListenerStackDepth(); + if (stackDepth < MAX_LISTENER_STACK_DEPTH) { + threadLocals.setFutureListenerStackDepth(stackDepth + 1); + try { + notifyListener0(future, l); + } finally { + threadLocals.setFutureListenerStackDepth(stackDepth); + } + return; + } + } + + execute(eventExecutor, new Runnable() { + @Override + public void run() { + notifyListener0(future, l); + } + }); + } + + private static void execute(EventExecutor executor, Runnable task) { + try { + executor.execute(task); + } catch (Throwable t) { + rejectedExecutionLogger.error("Failed to submit a listener notification task. Event loop shut down?", t); + } + } + + + static void notifyListener0(Future future, GenericFutureListener l) { + try { + l.operationComplete(future); + } catch (Throwable t) { + if (logger.isWarnEnabled()) { + logger.warn("An exception was thrown by " + l.getClass().getName() + ".operationComplete()", t); + } + } + } + + /** + * Returns a {@link GenericProgressiveFutureListener}, an array of {@link GenericProgressiveFutureListener}, or + * {@code null}. + */ + private synchronized Object progressiveListeners() { + Object listeners = this.listeners; + if (listeners == null) { + // No listeners added + return null; + } + + if (listeners instanceof DefaultFutureListeners) { + // Copy DefaultFutureListeners into an array of listeners. + DefaultFutureListeners dfl = (DefaultFutureListeners) listeners; + int progressiveSize = dfl.progressiveSize(); + switch (progressiveSize) { + case 0: + return null; + case 1: + for (GenericFutureListener l: dfl.listeners()) { + if (l instanceof GenericProgressiveFutureListener) { + return l; + } + } + return null; + } + + GenericFutureListener[] array = dfl.listeners(); + GenericProgressiveFutureListener[] copy = new GenericProgressiveFutureListener[progressiveSize]; + for (int i = 0, j = 0; j < progressiveSize; i ++) { + GenericFutureListener l = array[i]; + if (l instanceof GenericProgressiveFutureListener) { + copy[j ++] = (GenericProgressiveFutureListener) l; + } + } + + return copy; + } else if (listeners instanceof GenericProgressiveFutureListener) { + return listeners; + } else { + // Only one listener was added and it's not a progressive listener. + return null; + } + } + + + void notifyProgressiveListeners(final long progress, final long total) { + final Object listeners = progressiveListeners(); + if (listeners == null) { + return; + } + + final ProgressiveFuture self = (ProgressiveFuture) this; + + EventExecutor executor = executor(); + if (executor.inEventLoop()) { + if (listeners instanceof GenericProgressiveFutureListener[]) { + notifyProgressiveListeners0( + self, (GenericProgressiveFutureListener[]) listeners, progress, total); + } else { + notifyProgressiveListener0( + self, (GenericProgressiveFutureListener>) listeners, progress, total); + } + } else { + if (listeners instanceof GenericProgressiveFutureListener[]) { + final GenericProgressiveFutureListener[] array = + (GenericProgressiveFutureListener[]) listeners; + execute(executor, new Runnable() { + @Override + public void run() { + notifyProgressiveListeners0(self, array, progress, total); + } + }); + } else { + final GenericProgressiveFutureListener> l = + (GenericProgressiveFutureListener>) listeners; + execute(executor, new Runnable() { + @Override + public void run() { + notifyProgressiveListener0(self, l, progress, total); + } + }); + } + } + } + + private static void notifyProgressiveListeners0( + ProgressiveFuture future, GenericProgressiveFutureListener[] listeners, long progress, long total) { + for (GenericProgressiveFutureListener l: listeners) { + if (l == null) { + break; + } + notifyProgressiveListener0(future, l, progress, total); + } + } + + + private static void notifyProgressiveListener0( + ProgressiveFuture future, GenericProgressiveFutureListener l, long progress, long total) { + try { + l.operationProgressed(future, progress, total); + } catch (Throwable t) { + if (logger.isWarnEnabled()) { + logger.warn("An exception was thrown by " + l.getClass().getName() + ".operationProgressed()", t); + } + } + } + + private static final class CauseHolder { + final Throwable cause; + CauseHolder(Throwable cause) { + this.cause = cause; + } + } + + @Override + public String toString() { + return toStringBuilder().toString(); + } + + protected StringBuilder toStringBuilder() { + StringBuilder buf = new StringBuilder(64); + buf.append(StringUtil.simpleClassName(this)); + buf.append('@'); + buf.append(Integer.toHexString(hashCode())); + + Object result = this.result; + if (result == SUCCESS) { + buf.append("(success)"); + } else if (result == UNCANCELLABLE) { + buf.append("(uncancellable)"); + } else if (result instanceof CauseHolder) { + buf.append("(failure("); + buf.append(((CauseHolder) result).cause); + buf.append(')'); + } else { + buf.append("(incomplete)"); + } + return buf; + } + + private final class LateListeners extends ArrayDeque> implements Runnable { + + private static final long serialVersionUID = -687137418080392244L; + + LateListeners() { + super(2); + } + + @Override + public void run() { + if (listeners == null) { + for (;;) { + GenericFutureListener l = poll(); + if (l == null) { + break; + } + notifyListener0(DefaultPromise.this, l); + } + } else { + // Reschedule until the initial notification is done to avoid the race condition + // where the notification is made in an incorrect order. + execute(executor(), this); + } + } + } + + private final class LateListenerNotifier implements Runnable { + private GenericFutureListener l; + + LateListenerNotifier(GenericFutureListener l) { + this.l = l; + } + + @Override + public void run() { + LateListeners lateListeners = DefaultPromise.this.lateListeners; + if (l != null) { + if (lateListeners == null) { + DefaultPromise.this.lateListeners = lateListeners = new LateListeners(); + } + lateListeners.add(l); + l = null; + } + + lateListeners.run(); + } + } +} diff --git a/common/src/common/net/util/concurrent/DefaultThreadFactory.java b/common/src/common/net/util/concurrent/DefaultThreadFactory.java new file mode 100644 index 0000000..8dc939d --- /dev/null +++ b/common/src/common/net/util/concurrent/DefaultThreadFactory.java @@ -0,0 +1,143 @@ +/* + * Copyright 2013 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ + +package common.net.util.concurrent; + +import java.util.Locale; +import java.util.concurrent.ThreadFactory; +import java.util.concurrent.atomic.AtomicInteger; + +import common.net.util.internal.StringUtil; + +/** + * A {@link ThreadFactory} implementation with a simple naming rule. + */ +public class DefaultThreadFactory implements ThreadFactory { + + private static final AtomicInteger poolId = new AtomicInteger(); + + private final AtomicInteger nextId = new AtomicInteger(); + private final String prefix; + private final boolean daemon; + private final int priority; + + public DefaultThreadFactory(Class poolType) { + this(poolType, false, Thread.NORM_PRIORITY); + } + + public DefaultThreadFactory(String poolName) { + this(poolName, false, Thread.NORM_PRIORITY); + } + + public DefaultThreadFactory(Class poolType, boolean daemon) { + this(poolType, daemon, Thread.NORM_PRIORITY); + } + + public DefaultThreadFactory(String poolName, boolean daemon) { + this(poolName, daemon, Thread.NORM_PRIORITY); + } + + public DefaultThreadFactory(Class poolType, int priority) { + this(poolType, false, priority); + } + + public DefaultThreadFactory(String poolName, int priority) { + this(poolName, false, priority); + } + + public DefaultThreadFactory(Class poolType, boolean daemon, int priority) { + this(toPoolName(poolType), daemon, priority); + } + + private static String toPoolName(Class poolType) { + if (poolType == null) { + throw new NullPointerException("poolType"); + } + + String poolName = StringUtil.simpleClassName(poolType); + switch (poolName.length()) { + case 0: + return "unknown"; + case 1: + return poolName.toLowerCase(Locale.US); + default: + if (Character.isUpperCase(poolName.charAt(0)) && Character.isLowerCase(poolName.charAt(1))) { + return Character.toLowerCase(poolName.charAt(0)) + poolName.substring(1); + } else { + return poolName; + } + } + } + + public DefaultThreadFactory(String poolName, boolean daemon, int priority) { + if (poolName == null) { + throw new NullPointerException("poolName"); + } + if (priority < Thread.MIN_PRIORITY || priority > Thread.MAX_PRIORITY) { + throw new IllegalArgumentException( + "priority: " + priority + " (expected: Thread.MIN_PRIORITY <= priority <= Thread.MAX_PRIORITY)"); + } + + prefix = poolName + '-' + poolId.incrementAndGet() + '-'; + this.daemon = daemon; + this.priority = priority; + } + + @Override + public Thread newThread(Runnable r) { + Thread t = newThread(new DefaultRunnableDecorator(r), prefix + nextId.incrementAndGet()); + try { + if (t.isDaemon()) { + if (!daemon) { + t.setDaemon(false); + } + } else { + if (daemon) { + t.setDaemon(true); + } + } + + if (t.getPriority() != priority) { + t.setPriority(priority); + } + } catch (Exception ignored) { + // Doesn't matter even if failed to set. + } + return t; + } + + protected Thread newThread(Runnable r, String name) { + return new FastThreadLocalThread(r, name); + } + + private static final class DefaultRunnableDecorator implements Runnable { + + private final Runnable r; + + DefaultRunnableDecorator(Runnable r) { + this.r = r; + } + + @Override + public void run() { + try { + r.run(); + } finally { + FastThreadLocal.removeAll(); + } + } + } +} diff --git a/common/src/common/net/util/concurrent/EventExecutor.java b/common/src/common/net/util/concurrent/EventExecutor.java new file mode 100644 index 0000000..e145548 --- /dev/null +++ b/common/src/common/net/util/concurrent/EventExecutor.java @@ -0,0 +1,72 @@ +/* + * Copyright 2012 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ +package common.net.util.concurrent; + +/** + * The {@link EventExecutor} is a special {@link EventExecutorGroup} which comes + * with some handy methods to see if a {@link Thread} is executed in a event loop. + * Beside this it also extends the {@link EventExecutorGroup} to allow a generic way to + * access methods. + * + */ +public interface EventExecutor extends EventExecutorGroup { + + /** + * Returns a reference to itself. + */ + @Override + EventExecutor next(); + + /** + * Return the {@link EventExecutorGroup} which is the parent of this {@link EventExecutor}, + */ + EventExecutorGroup parent(); + + /** + * Calls {@link #inEventLoop(Thread)} with {@link Thread#currentThread()} as argument + */ + boolean inEventLoop(); + + /** + * Return {@code true} if the given {@link Thread} is executed in the event loop, + * {@code false} otherwise. + */ + boolean inEventLoop(Thread thread); + + /** + * Return a new {@link Promise}. + */ + Promise newPromise(); + + /** + * Create a new {@link ProgressivePromise}. + */ + ProgressivePromise newProgressivePromise(); + + /** + * Create a new {@link Future} which is marked as successes already. So {@link Future#isSuccess()} + * will return {@code true}. All {@link FutureListener} added to it will be notified directly. Also + * every call of blocking methods will just return without blocking. + */ + Future newSucceededFuture(V result); + + /** + * Create a new {@link Future} which is marked as fakued already. So {@link Future#isSuccess()} + * will return {@code false}. All {@link FutureListener} added to it will be notified directly. Also + * every call of blocking methods will just return without blocking. + */ + Future newFailedFuture(Throwable cause); +} diff --git a/common/src/common/net/util/concurrent/EventExecutorGroup.java b/common/src/common/net/util/concurrent/EventExecutorGroup.java new file mode 100644 index 0000000..16da3f8 --- /dev/null +++ b/common/src/common/net/util/concurrent/EventExecutorGroup.java @@ -0,0 +1,112 @@ +/* + * Copyright 2012 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ +package common.net.util.concurrent; + +import java.util.Iterator; +import java.util.List; +import java.util.concurrent.Callable; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeUnit; + +/** + * The {@link EventExecutorGroup} is responsible to provide {@link EventExecutor}'s to use via its + * {@link #next()} method. Beside this it also is responsible to handle their live-cycle and allows + * to shut them down in a global fashion. + * + */ +public interface EventExecutorGroup extends ScheduledExecutorService, Iterable { + + /** + * Returns {@code true} if and only if this executor was started to be + * {@linkplain #shutdownGracefully() shut down gracefuclly} or was {@linkplain #isShutdown() shut down}. + */ + boolean isShuttingDown(); + + /** + * Shortcut method for {@link #shutdownGracefully(long, long, TimeUnit)} with sensible default values. + * + * @return the {@link #terminationFuture()} + */ + Future shutdownGracefully(); + + /** + * Signals this executor that the caller wants the executor to be shut down. Once this method is called, + * {@link #isShuttingDown()} starts to return {@code true}, and the executor prepares to shut itself down. + * Unlike {@link #shutdown()}, graceful shutdown ensures that no tasks are submitted for 'the quiet period' + * (usually a couple seconds) before it shuts itself down. If a task is submitted during the quiet period, + * it is guaranteed to be accepted and the quiet period will start over. + * + * @param quietPeriod the quiet period as described in the documentation + * @param timeout the maximum amount of time to wait until the executor is {@linkplain #shutdown()} + * regardless if a task was submitted during the quiet period + * @param unit the unit of {@code quietPeriod} and {@code timeout} + * + * @return the {@link #terminationFuture()} + */ + Future shutdownGracefully(long quietPeriod, long timeout, TimeUnit unit); + + /** + * Returns the {@link Future} which is notified when this executor has been terminated. + */ + Future terminationFuture(); + + /** + * @deprecated {@link #shutdownGracefully(long, long, TimeUnit)} or {@link #shutdownGracefully()} instead. + */ + @Override + @Deprecated + void shutdown(); + + /** + * @deprecated {@link #shutdownGracefully(long, long, TimeUnit)} or {@link #shutdownGracefully()} instead. + */ + @Override + @Deprecated + List shutdownNow(); + + /** + * Returns one of the {@link EventExecutor}s that belong to this group. + */ + EventExecutor next(); + + /** + * Returns a read-only {@link Iterator} over all {@link EventExecutor}, which are handled by this + * {@link EventExecutorGroup} at the time of invoke this method. + */ + @Override + Iterator iterator(); + + @Override + Future submit(Runnable task); + + @Override + Future submit(Runnable task, T result); + + @Override + Future submit(Callable task); + + @Override + ScheduledFuture schedule(Runnable command, long delay, TimeUnit unit); + + @Override + ScheduledFuture schedule(Callable callable, long delay, TimeUnit unit); + + @Override + ScheduledFuture scheduleAtFixedRate(Runnable command, long initialDelay, long period, TimeUnit unit); + + @Override + ScheduledFuture scheduleWithFixedDelay(Runnable command, long initialDelay, long delay, TimeUnit unit); +} diff --git a/common/src/common/net/util/concurrent/FailedFuture.java b/common/src/common/net/util/concurrent/FailedFuture.java new file mode 100644 index 0000000..72780ba --- /dev/null +++ b/common/src/common/net/util/concurrent/FailedFuture.java @@ -0,0 +1,69 @@ +/* + * Copyright 2012 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ +package common.net.util.concurrent; + +import common.net.util.internal.PlatformDependent; + +/** + * The {@link CompleteFuture} which is failed already. It is + * recommended to use {@link EventExecutor#newFailedFuture(Throwable)} + * instead of calling the constructor of this future. + */ +public final class FailedFuture extends CompleteFuture { + + private final Throwable cause; + + /** + * Creates a new instance. + * + * @param executor the {@link EventExecutor} associated with this future + * @param cause the cause of failure + */ + public FailedFuture(EventExecutor executor, Throwable cause) { + super(executor); + if (cause == null) { + throw new NullPointerException("cause"); + } + this.cause = cause; + } + + @Override + public Throwable cause() { + return cause; + } + + @Override + public boolean isSuccess() { + return false; + } + + @Override + public Future sync() { + PlatformDependent.throwException(cause); + return this; + } + + @Override + public Future syncUninterruptibly() { + PlatformDependent.throwException(cause); + return this; + } + + @Override + public V getNow() { + return null; + } +} diff --git a/common/src/common/net/util/concurrent/FastThreadLocal.java b/common/src/common/net/util/concurrent/FastThreadLocal.java new file mode 100644 index 0000000..05ea6b5 --- /dev/null +++ b/common/src/common/net/util/concurrent/FastThreadLocal.java @@ -0,0 +1,244 @@ +/* + * Copyright 2014 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ +package common.net.util.concurrent; + +import java.util.Collections; +import java.util.IdentityHashMap; +import java.util.Set; + +import common.net.util.internal.InternalThreadLocalMap; +import common.net.util.internal.PlatformDependent; + +/** + * A special variant of {@link ThreadLocal} that yields higher access performan when accessed from a + * {@link FastThreadLocalThread}. + *

+ * Internally, a {@link FastThreadLocal} uses a constant index in an array, instead of using hash code and hash table, + * to look for a variable. Although seemingly very subtle, it yields slight performance advantage over using a hash + * table, and it is useful when accessed frequently. + *

+ * To take advantage of this thread-local variable, your thread must be a {@link FastThreadLocalThread} or its subtype. + * By default, all threads created by {@link DefaultThreadFactory} are {@link FastThreadLocalThread} due to this reason. + *

+ * Note that the fast path is only possible on threads that extend {@link FastThreadLocalThread}, because it requires + * a special field to store the necessary state. An access by any other kind of thread falls back to a regular + * {@link ThreadLocal}. + *

+ * + * @param the type of the thread-local variable + * @see ThreadLocal + */ +public class FastThreadLocal { + + private static final int variablesToRemoveIndex = InternalThreadLocalMap.nextVariableIndex(); + + /** + * Removes all {@link FastThreadLocal} variables bound to the current thread. This operation is useful when you + * are in a container environment, and you don't want to leave the thread local variables in the threads you do not + * manage. + */ + public static void removeAll() { + InternalThreadLocalMap threadLocalMap = InternalThreadLocalMap.getIfSet(); + if (threadLocalMap == null) { + return; + } + + try { + Object v = threadLocalMap.indexedVariable(variablesToRemoveIndex); + if (v != null && v != InternalThreadLocalMap.UNSET) { + + Set> variablesToRemove = (Set>) v; + FastThreadLocal[] variablesToRemoveArray = + variablesToRemove.toArray(new FastThreadLocal[variablesToRemove.size()]); + for (FastThreadLocal tlv: variablesToRemoveArray) { + tlv.remove(threadLocalMap); + } + } + } finally { + InternalThreadLocalMap.remove(); + } + } + + /** + * Returns the number of thread local variables bound to the current thread. + */ + public static int size() { + InternalThreadLocalMap threadLocalMap = InternalThreadLocalMap.getIfSet(); + if (threadLocalMap == null) { + return 0; + } else { + return threadLocalMap.size(); + } + } + + /** + * Destroys the data structure that keeps all {@link FastThreadLocal} variables accessed from + * non-{@link FastThreadLocalThread}s. This operation is useful when you are in a container environment, and you + * do not want to leave the thread local variables in the threads you do not manage. Call this method when your + * application is being unloaded from the container. + */ + public static void destroy() { + InternalThreadLocalMap.destroy(); + } + + + private static void addToVariablesToRemove(InternalThreadLocalMap threadLocalMap, FastThreadLocal variable) { + Object v = threadLocalMap.indexedVariable(variablesToRemoveIndex); + Set> variablesToRemove; + if (v == InternalThreadLocalMap.UNSET || v == null) { + variablesToRemove = Collections.newSetFromMap(new IdentityHashMap, Boolean>()); + threadLocalMap.setIndexedVariable(variablesToRemoveIndex, variablesToRemove); + } else { + variablesToRemove = (Set>) v; + } + + variablesToRemove.add(variable); + } + + private static void removeFromVariablesToRemove( + InternalThreadLocalMap threadLocalMap, FastThreadLocal variable) { + + Object v = threadLocalMap.indexedVariable(variablesToRemoveIndex); + + if (v == InternalThreadLocalMap.UNSET || v == null) { + return; + } + + + Set> variablesToRemove = (Set>) v; + variablesToRemove.remove(variable); + } + + private final int index; + + public FastThreadLocal() { + index = InternalThreadLocalMap.nextVariableIndex(); + } + + /** + * Returns the current value for the current thread + */ + public final V get() { + return get(InternalThreadLocalMap.get()); + } + + /** + * Returns the current value for the specified thread local map. + * The specified thread local map must be for the current thread. + */ + + public final V get(InternalThreadLocalMap threadLocalMap) { + Object v = threadLocalMap.indexedVariable(index); + if (v != InternalThreadLocalMap.UNSET) { + return (V) v; + } + + return initialize(threadLocalMap); + } + + private V initialize(InternalThreadLocalMap threadLocalMap) { + V v = null; + try { + v = initialValue(); + } catch (Exception e) { + PlatformDependent.throwException(e); + } + + threadLocalMap.setIndexedVariable(index, v); + addToVariablesToRemove(threadLocalMap, this); + return v; + } + + /** + * Set the value for the current thread. + */ + public final void set(V value) { + if (value != InternalThreadLocalMap.UNSET) { + set(InternalThreadLocalMap.get(), value); + } else { + remove(); + } + } + + /** + * Set the value for the specified thread local map. The specified thread local map must be for the current thread. + */ + public final void set(InternalThreadLocalMap threadLocalMap, V value) { + if (value != InternalThreadLocalMap.UNSET) { + if (threadLocalMap.setIndexedVariable(index, value)) { + addToVariablesToRemove(threadLocalMap, this); + } + } else { + remove(threadLocalMap); + } + } + + /** + * Returns {@code true} if and only if this thread-local variable is set. + */ + public final boolean isSet() { + return isSet(InternalThreadLocalMap.getIfSet()); + } + + /** + * Returns {@code true} if and only if this thread-local variable is set. + * The specified thread local map must be for the current thread. + */ + public final boolean isSet(InternalThreadLocalMap threadLocalMap) { + return threadLocalMap != null && threadLocalMap.isIndexedVariableSet(index); + } + /** + * Sets the value to uninitialized; a proceeding call to get() will trigger a call to initialValue(). + */ + public final void remove() { + remove(InternalThreadLocalMap.getIfSet()); + } + + /** + * Sets the value to uninitialized for the specified thread local map; + * a proceeding call to get() will trigger a call to initialValue(). + * The specified thread local map must be for the current thread. + */ + + public final void remove(InternalThreadLocalMap threadLocalMap) { + if (threadLocalMap == null) { + return; + } + + Object v = threadLocalMap.removeIndexedVariable(index); + removeFromVariablesToRemove(threadLocalMap, this); + + if (v != InternalThreadLocalMap.UNSET) { + try { + onRemoval((V) v); + } catch (Exception e) { + PlatformDependent.throwException(e); + } + } + } + + /** + * Returns the initial value for this thread-local variable. + */ + protected V initialValue() throws Exception { + return null; + } + + /** + * Invoked when this thread local variable is removed by {@link #remove()}. + */ + protected void onRemoval( V value) throws Exception { } +} diff --git a/common/src/common/net/util/concurrent/FastThreadLocalThread.java b/common/src/common/net/util/concurrent/FastThreadLocalThread.java new file mode 100644 index 0000000..e81083f --- /dev/null +++ b/common/src/common/net/util/concurrent/FastThreadLocalThread.java @@ -0,0 +1,72 @@ +/* +* Copyright 2014 The Netty Project +* +* The Netty Project licenses this file to you under the Apache License, +* version 2.0 (the "License"); you may not use this file except in compliance +* with the License. You may obtain a copy of the License at: +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +* License for the specific language governing permissions and limitations +* under the License. +*/ +package common.net.util.concurrent; + +import common.net.util.internal.InternalThreadLocalMap; + +/** + * A special {@link Thread} that provides fast access to {@link FastThreadLocal} variables. + */ +public class FastThreadLocalThread extends Thread { + + private InternalThreadLocalMap threadLocalMap; + + public FastThreadLocalThread() { } + + public FastThreadLocalThread(Runnable target) { + super(target); + } + + public FastThreadLocalThread(ThreadGroup group, Runnable target) { + super(group, target); + } + + public FastThreadLocalThread(String name) { + super(name); + } + + public FastThreadLocalThread(ThreadGroup group, String name) { + super(group, name); + } + + public FastThreadLocalThread(Runnable target, String name) { + super(target, name); + } + + public FastThreadLocalThread(ThreadGroup group, Runnable target, String name) { + super(group, target, name); + } + + public FastThreadLocalThread(ThreadGroup group, Runnable target, String name, long stackSize) { + super(group, target, name, stackSize); + } + + /** + * Returns the internal data structure that keeps the thread-local variables bound to this thread. + * Note that this method is for internal use only, and thus is subject to change at any time. + */ + public final InternalThreadLocalMap threadLocalMap() { + return threadLocalMap; + } + + /** + * Sets the internal data structure that keeps the thread-local variables bound to this thread. + * Note that this method is for internal use only, and thus is subject to change at any time. + */ + public final void setThreadLocalMap(InternalThreadLocalMap threadLocalMap) { + this.threadLocalMap = threadLocalMap; + } +} diff --git a/common/src/common/net/util/concurrent/Future.java b/common/src/common/net/util/concurrent/Future.java new file mode 100644 index 0000000..37748cd --- /dev/null +++ b/common/src/common/net/util/concurrent/Future.java @@ -0,0 +1,168 @@ +/* + * Copyright 2013 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ +package common.net.util.concurrent; + +import java.util.concurrent.TimeUnit; + + +/** + * The result of an asynchronous operation. + */ + +public interface Future extends java.util.concurrent.Future { + + /** + * Returns {@code true} if and only if the I/O operation was completed + * successfully. + */ + boolean isSuccess(); + + /** + * returns {@code true} if and only if the operation can be cancelled via {@link #cancel(boolean)}. + */ + boolean isCancellable(); + + /** + * Returns the cause of the failed I/O operation if the I/O operation has + * failed. + * + * @return the cause of the failure. + * {@code null} if succeeded or this future is not + * completed yet. + */ + Throwable cause(); + + /** + * Adds the specified listener to this future. The + * specified listener is notified when this future is + * {@linkplain #isDone() done}. If this future is already + * completed, the specified listener is notified immediately. + */ + Future addListener(GenericFutureListener> listener); + + /** + * Adds the specified listeners to this future. The + * specified listeners are notified when this future is + * {@linkplain #isDone() done}. If this future is already + * completed, the specified listeners are notified immediately. + */ + Future addListeners(GenericFutureListener>... listeners); + + /** + * Removes the specified listener from this future. + * The specified listener is no longer notified when this + * future is {@linkplain #isDone() done}. If the specified + * listener is not associated with this future, this method + * does nothing and returns silently. + */ + Future removeListener(GenericFutureListener> listener); + + /** + * Removes the specified listeners from this future. + * The specified listeners are no longer notified when this + * future is {@linkplain #isDone() done}. If the specified + * listeners are not associated with this future, this method + * does nothing and returns silently. + */ + Future removeListeners(GenericFutureListener>... listeners); + + /** + * Waits for this future until it is done, and rethrows the cause of the failure if this future + * failed. + */ + Future sync() throws InterruptedException; + + /** + * Waits for this future until it is done, and rethrows the cause of the failure if this future + * failed. + */ + Future syncUninterruptibly(); + + /** + * Waits for this future to be completed. + * + * @throws InterruptedException + * if the current thread was interrupted + */ + Future await() throws InterruptedException; + + /** + * Waits for this future to be completed without + * interruption. This method catches an {@link InterruptedException} and + * discards it silently. + */ + Future awaitUninterruptibly(); + + /** + * Waits for this future to be completed within the + * specified time limit. + * + * @return {@code true} if and only if the future was completed within + * the specified time limit + * + * @throws InterruptedException + * if the current thread was interrupted + */ + boolean await(long timeout, TimeUnit unit) throws InterruptedException; + + /** + * Waits for this future to be completed within the + * specified time limit. + * + * @return {@code true} if and only if the future was completed within + * the specified time limit + * + * @throws InterruptedException + * if the current thread was interrupted + */ + boolean await(long timeoutMillis) throws InterruptedException; + + /** + * Waits for this future to be completed within the + * specified time limit without interruption. This method catches an + * {@link InterruptedException} and discards it silently. + * + * @return {@code true} if and only if the future was completed within + * the specified time limit + */ + boolean awaitUninterruptibly(long timeout, TimeUnit unit); + + /** + * Waits for this future to be completed within the + * specified time limit without interruption. This method catches an + * {@link InterruptedException} and discards it silently. + * + * @return {@code true} if and only if the future was completed within + * the specified time limit + */ + boolean awaitUninterruptibly(long timeoutMillis); + + /** + * Return the result without blocking. If the future is not done yet this will return {@code null}. + * + * As it is possible that a {@code null} value is used to mark the future as successful you also need to check + * if the future is really done with {@link #isDone()} and not relay on the returned {@code null} value. + */ + V getNow(); + + /** + * {@inheritDoc} + * + * If the cancellation was successful it will fail the future with an {@link CancellationException}. + */ + @Override + boolean cancel(boolean mayInterruptIfRunning); +} diff --git a/common/src/common/net/util/concurrent/FutureListener.java b/common/src/common/net/util/concurrent/FutureListener.java new file mode 100644 index 0000000..8d5a690 --- /dev/null +++ b/common/src/common/net/util/concurrent/FutureListener.java @@ -0,0 +1,28 @@ +/* + * Copyright 2013 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ + +package common.net.util.concurrent; + +/** + * A subtype of {@link GenericFutureListener} that hides type parameter for convenience. + *
+ * Future f = new DefaultPromise(..);
+ * f.addListener(new FutureListener() {
+ *     public void operationComplete(Future f) { .. }
+ * });
+ * 
+ */ +public interface FutureListener extends GenericFutureListener> { } diff --git a/common/src/common/net/util/concurrent/GenericFutureListener.java b/common/src/common/net/util/concurrent/GenericFutureListener.java new file mode 100644 index 0000000..a5d46cc --- /dev/null +++ b/common/src/common/net/util/concurrent/GenericFutureListener.java @@ -0,0 +1,32 @@ +/* + * Copyright 2013 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ +package common.net.util.concurrent; + +import java.util.EventListener; + +/** + * Listens to the result of a {@link Future}. The result of the asynchronous operation is notified once this listener + * is added by calling {@link Future#addListener(GenericFutureListener)}. + */ +public interface GenericFutureListener> extends EventListener { + + /** + * Invoked when the operation associated with the {@link Future} has been completed. + * + * @param future the source {@link Future} which called this callback + */ + void operationComplete(F future) throws Exception; +} diff --git a/common/src/common/net/util/concurrent/GenericProgressiveFutureListener.java b/common/src/common/net/util/concurrent/GenericProgressiveFutureListener.java new file mode 100644 index 0000000..8da4cbb --- /dev/null +++ b/common/src/common/net/util/concurrent/GenericProgressiveFutureListener.java @@ -0,0 +1,28 @@ +/* + * Copyright 2013 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ + +package common.net.util.concurrent; + +public interface GenericProgressiveFutureListener> extends GenericFutureListener { + /** + * Invoked when the operation has progressed. + * + * @param progress the progress of the operation so far (cumulative) + * @param total the number that signifies the end of the operation when {@code progress} reaches at it. + * {@code -1} if the end of operation is unknown. + */ + void operationProgressed(F future, long progress, long total) throws Exception; +} diff --git a/common/src/common/net/util/concurrent/GlobalEventExecutor.java b/common/src/common/net/util/concurrent/GlobalEventExecutor.java new file mode 100644 index 0000000..103143b --- /dev/null +++ b/common/src/common/net/util/concurrent/GlobalEventExecutor.java @@ -0,0 +1,391 @@ +/* + * Copyright 2012 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ +package common.net.util.concurrent; + +import java.util.Iterator; +import java.util.PriorityQueue; +import java.util.Queue; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.Callable; +import java.util.concurrent.Executors; +import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.ThreadFactory; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicBoolean; + +import common.net.util.internal.logging.InternalLogger; +import common.net.util.internal.logging.InternalLoggerFactory; + +/** + * Single-thread singleton {@link EventExecutor}. It starts the thread automatically and stops it when there is no + * task pending in the task queue for 1 second. Please note it is not scalable to schedule large number of tasks to + * this executor; use a dedicated executor. + */ +public final class GlobalEventExecutor extends AbstractEventExecutor { + + private static final InternalLogger logger = InternalLoggerFactory.getInstance(GlobalEventExecutor.class); + + private static final long SCHEDULE_PURGE_INTERVAL = TimeUnit.SECONDS.toNanos(1); + + public static final GlobalEventExecutor INSTANCE = new GlobalEventExecutor(); + + final BlockingQueue taskQueue = new LinkedBlockingQueue(); + final Queue> delayedTaskQueue = new PriorityQueue>(); + final ScheduledFutureTask purgeTask = new ScheduledFutureTask( + this, delayedTaskQueue, Executors.callable(new PurgeTask(), null), + ScheduledFutureTask.deadlineNanos(SCHEDULE_PURGE_INTERVAL), -SCHEDULE_PURGE_INTERVAL); + + private final ThreadFactory threadFactory = new DefaultThreadFactory(getClass()); + private final TaskRunner taskRunner = new TaskRunner(); + private final AtomicBoolean started = new AtomicBoolean(); + volatile Thread thread; + + private final Future terminationFuture = new FailedFuture(this, new UnsupportedOperationException()); + + private GlobalEventExecutor() { + delayedTaskQueue.add(purgeTask); + } + + @Override + public EventExecutorGroup parent() { + return null; + } + + /** + * Take the next {@link Runnable} from the task queue and so will block if no task is currently present. + * + * @return {@code null} if the executor thread has been interrupted or waken up. + */ + Runnable takeTask() { + BlockingQueue taskQueue = this.taskQueue; + for (;;) { + ScheduledFutureTask delayedTask = delayedTaskQueue.peek(); + if (delayedTask == null) { + Runnable task = null; + try { + task = taskQueue.take(); + } catch (InterruptedException e) { + // Ignore + } + return task; + } else { + long delayNanos = delayedTask.delayNanos(); + Runnable task; + if (delayNanos > 0) { + try { + task = taskQueue.poll(delayNanos, TimeUnit.NANOSECONDS); + } catch (InterruptedException e) { + return null; + } + } else { + task = taskQueue.poll(); + } + + if (task == null) { + fetchFromDelayedQueue(); + task = taskQueue.poll(); + } + + if (task != null) { + return task; + } + } + } + } + + private void fetchFromDelayedQueue() { + long nanoTime = 0L; + for (;;) { + ScheduledFutureTask delayedTask = delayedTaskQueue.peek(); + if (delayedTask == null) { + break; + } + + if (nanoTime == 0L) { + nanoTime = ScheduledFutureTask.nanoTime(); + } + + if (delayedTask.deadlineNanos() <= nanoTime) { + delayedTaskQueue.remove(); + taskQueue.add(delayedTask); + } else { + break; + } + } + } + + /** + * Return the number of tasks that are pending for processing. + * + * Be aware that this operation may be expensive as it depends on the internal implementation of the + * SingleThreadEventExecutor. So use it was care! + */ + public int pendingTasks() { + return taskQueue.size(); + } + + /** + * Add a task to the task queue, or throws a {@link RejectedExecutionException} if this instance was shutdown + * before. + */ + private void addTask(Runnable task) { + if (task == null) { + throw new NullPointerException("task"); + } + taskQueue.add(task); + } + + @Override + public boolean inEventLoop(Thread thread) { + return thread == this.thread; + } + + @Override + public Future shutdownGracefully(long quietPeriod, long timeout, TimeUnit unit) { + return terminationFuture(); + } + + @Override + public Future terminationFuture() { + return terminationFuture; + } + + @Override + @Deprecated + public void shutdown() { + throw new UnsupportedOperationException(); + } + + @Override + public boolean isShuttingDown() { + return false; + } + + @Override + public boolean isShutdown() { + return false; + } + + @Override + public boolean isTerminated() { + return false; + } + + @Override + public boolean awaitTermination(long timeout, TimeUnit unit) { + return false; + } + + /** + * Waits until the worker thread of this executor has no tasks left in its task queue and terminates itself. + * Because a new worker thread will be started again when a new task is submitted, this operation is only useful + * when you want to ensure that the worker thread is terminated after your application is shut + * down and there's no chance of submitting a new task afterwards. + * + * @return {@code true} if and only if the worker thread has been terminated + */ + public boolean awaitInactivity(long timeout, TimeUnit unit) throws InterruptedException { + if (unit == null) { + throw new NullPointerException("unit"); + } + + final Thread thread = this.thread; + if (thread == null) { + throw new IllegalStateException("thread was not started"); + } + thread.join(unit.toMillis(timeout)); + return !thread.isAlive(); + } + + @Override + public void execute(Runnable task) { + if (task == null) { + throw new NullPointerException("task"); + } + + addTask(task); + if (!inEventLoop()) { + startThread(); + } + } + + // ScheduledExecutorService implementation + + @Override + public ScheduledFuture schedule(Runnable command, long delay, TimeUnit unit) { + if (command == null) { + throw new NullPointerException("command"); + } + if (unit == null) { + throw new NullPointerException("unit"); + } + if (delay < 0) { + throw new IllegalArgumentException( + String.format("delay: %d (expected: >= 0)", delay)); + } + return schedule(new ScheduledFutureTask( + this, delayedTaskQueue, command, null, ScheduledFutureTask.deadlineNanos(unit.toNanos(delay)))); + } + + @Override + public ScheduledFuture schedule(Callable callable, long delay, TimeUnit unit) { + if (callable == null) { + throw new NullPointerException("callable"); + } + if (unit == null) { + throw new NullPointerException("unit"); + } + if (delay < 0) { + throw new IllegalArgumentException( + String.format("delay: %d (expected: >= 0)", delay)); + } + return schedule(new ScheduledFutureTask( + this, delayedTaskQueue, callable, ScheduledFutureTask.deadlineNanos(unit.toNanos(delay)))); + } + + @Override + public ScheduledFuture scheduleAtFixedRate(Runnable command, long initialDelay, long period, TimeUnit unit) { + if (command == null) { + throw new NullPointerException("command"); + } + if (unit == null) { + throw new NullPointerException("unit"); + } + if (initialDelay < 0) { + throw new IllegalArgumentException( + String.format("initialDelay: %d (expected: >= 0)", initialDelay)); + } + if (period <= 0) { + throw new IllegalArgumentException( + String.format("period: %d (expected: > 0)", period)); + } + + return schedule(new ScheduledFutureTask( + this, delayedTaskQueue, Executors.callable(command, null), + ScheduledFutureTask.deadlineNanos(unit.toNanos(initialDelay)), unit.toNanos(period))); + } + + @Override + public ScheduledFuture scheduleWithFixedDelay(Runnable command, long initialDelay, long delay, TimeUnit unit) { + if (command == null) { + throw new NullPointerException("command"); + } + if (unit == null) { + throw new NullPointerException("unit"); + } + if (initialDelay < 0) { + throw new IllegalArgumentException( + String.format("initialDelay: %d (expected: >= 0)", initialDelay)); + } + if (delay <= 0) { + throw new IllegalArgumentException( + String.format("delay: %d (expected: > 0)", delay)); + } + + return schedule(new ScheduledFutureTask( + this, delayedTaskQueue, Executors.callable(command, null), + ScheduledFutureTask.deadlineNanos(unit.toNanos(initialDelay)), -unit.toNanos(delay))); + } + + private ScheduledFuture schedule(final ScheduledFutureTask task) { + if (task == null) { + throw new NullPointerException("task"); + } + + if (inEventLoop()) { + delayedTaskQueue.add(task); + } else { + execute(new Runnable() { + @Override + public void run() { + delayedTaskQueue.add(task); + } + }); + } + + return task; + } + + private void startThread() { + if (started.compareAndSet(false, true)) { + Thread t = threadFactory.newThread(taskRunner); + t.start(); + thread = t; + } + } + + final class TaskRunner implements Runnable { + @Override + public void run() { + for (;;) { + Runnable task = takeTask(); + if (task != null) { + try { + task.run(); + } catch (Throwable t) { + logger.warn("Unexpected exception from the global event executor: ", t); + } + + if (task != purgeTask) { + continue; + } + } + + // Terminate if there is no task in the queue (except the purge task). + if (taskQueue.isEmpty() && delayedTaskQueue.size() == 1) { + // Mark the current thread as stopped. + // The following CAS must always success and must be uncontended, + // because only one thread should be running at the same time. + boolean stopped = started.compareAndSet(true, false); + assert stopped; + + // Check if there are pending entries added by execute() or schedule*() while we do CAS above. + if (taskQueue.isEmpty() && delayedTaskQueue.size() == 1) { + // A) No new task was added and thus there's nothing to handle + // -> safe to terminate because there's nothing left to do + // B) A new thread started and handled all the new tasks. + // -> safe to terminate the new thread will take care the rest + break; + } + + // There are pending tasks added again. + if (!started.compareAndSet(false, true)) { + // startThread() started a new thread and set 'started' to true. + // -> terminate this thread so that the new thread reads from taskQueue exclusively. + break; + } + + // New tasks were added, but this worker was faster to set 'started' to true. + // i.e. a new worker thread was not started by startThread(). + // -> keep this thread alive to handle the newly added entries. + } + } + } + } + + private final class PurgeTask implements Runnable { + @Override + public void run() { + Iterator> i = delayedTaskQueue.iterator(); + while (i.hasNext()) { + ScheduledFutureTask task = i.next(); + if (task.isCancelled()) { + i.remove(); + } + } + } + } +} diff --git a/common/src/common/net/util/concurrent/ImmediateEventExecutor.java b/common/src/common/net/util/concurrent/ImmediateEventExecutor.java new file mode 100644 index 0000000..6b8fddb --- /dev/null +++ b/common/src/common/net/util/concurrent/ImmediateEventExecutor.java @@ -0,0 +1,121 @@ +/* + * Copyright 2013 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ +package common.net.util.concurrent; + +import java.util.concurrent.TimeUnit; + +/** + * {@link AbstractEventExecutor} which execute tasks in the callers thread. + */ +public final class ImmediateEventExecutor extends AbstractEventExecutor { + public static final ImmediateEventExecutor INSTANCE = new ImmediateEventExecutor(); + + private final Future terminationFuture = new FailedFuture( + GlobalEventExecutor.INSTANCE, new UnsupportedOperationException()); + + private ImmediateEventExecutor() { + // use static instance + } + + @Override + public EventExecutorGroup parent() { + return null; + } + + @Override + public boolean inEventLoop() { + return true; + } + + @Override + public boolean inEventLoop(Thread thread) { + return true; + } + + @Override + public Future shutdownGracefully(long quietPeriod, long timeout, TimeUnit unit) { + return terminationFuture(); + } + + @Override + public Future terminationFuture() { + return terminationFuture; + } + + @Override + @Deprecated + public void shutdown() { } + + @Override + public boolean isShuttingDown() { + return false; + } + + @Override + public boolean isShutdown() { + return false; + } + + @Override + public boolean isTerminated() { + return false; + } + + @Override + public boolean awaitTermination(long timeout, TimeUnit unit) { + return false; + } + + @Override + public void execute(Runnable command) { + if (command == null) { + throw new NullPointerException("command"); + } + command.run(); + } + + @Override + public Promise newPromise() { + return new ImmediatePromise(this); + } + + @Override + public ProgressivePromise newProgressivePromise() { + return new ImmediateProgressivePromise(this); + } + + static class ImmediatePromise extends DefaultPromise { + ImmediatePromise(EventExecutor executor) { + super(executor); + } + + @Override + protected void checkDeadLock() { + // No check + } + } + + static class ImmediateProgressivePromise extends DefaultProgressivePromise { + ImmediateProgressivePromise(EventExecutor executor) { + super(executor); + } + + @Override + protected void checkDeadLock() { + // No check + } + } +} diff --git a/common/src/common/net/util/concurrent/ImmediateExecutor.java b/common/src/common/net/util/concurrent/ImmediateExecutor.java new file mode 100644 index 0000000..6660c6d --- /dev/null +++ b/common/src/common/net/util/concurrent/ImmediateExecutor.java @@ -0,0 +1,37 @@ +/* + * Copyright 2013 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ +package common.net.util.concurrent; + +import java.util.concurrent.Executor; + +/** + * {@link Executor} which execute tasks in the callers thread. + */ +public final class ImmediateExecutor implements Executor { + public static final ImmediateExecutor INSTANCE = new ImmediateExecutor(); + + private ImmediateExecutor() { + // use static instance + } + + @Override + public void execute(Runnable command) { + if (command == null) { + throw new NullPointerException("command"); + } + command.run(); + } +} diff --git a/common/src/common/net/util/concurrent/MultithreadEventExecutorGroup.java b/common/src/common/net/util/concurrent/MultithreadEventExecutorGroup.java new file mode 100644 index 0000000..39a72c3 --- /dev/null +++ b/common/src/common/net/util/concurrent/MultithreadEventExecutorGroup.java @@ -0,0 +1,233 @@ +/* + * Copyright 2012 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ +package common.net.util.concurrent; + +import java.util.Collections; +import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.Set; +import java.util.concurrent.ThreadFactory; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicInteger; + +/** + * Abstract base class for {@link EventExecutorGroup} implementations that handles their tasks with multiple threads at + * the same time. + */ +public abstract class MultithreadEventExecutorGroup extends AbstractEventExecutorGroup { + + private final EventExecutor[] children; + private final AtomicInteger childIndex = new AtomicInteger(); + private final AtomicInteger terminatedChildren = new AtomicInteger(); + private final Promise terminationFuture = new DefaultPromise(GlobalEventExecutor.INSTANCE); + private final EventExecutorChooser chooser; + + /** + * Create a new instance. + * + * @param nThreads the number of threads that will be used by this instance. + * @param threadFactory the ThreadFactory to use, or {@code null} if the default should be used. + * @param args arguments which will passed to each {@link #newChild(ThreadFactory, Object...)} call + */ + protected MultithreadEventExecutorGroup(int nThreads, ThreadFactory threadFactory, Object... args) { + if (nThreads <= 0) { + throw new IllegalArgumentException(String.format("nThreads: %d (expected: > 0)", nThreads)); + } + + if (threadFactory == null) { + threadFactory = newDefaultThreadFactory(); + } + + children = new SingleThreadEventExecutor[nThreads]; + if (isPowerOfTwo(children.length)) { + chooser = new PowerOfTwoEventExecutorChooser(); + } else { + chooser = new GenericEventExecutorChooser(); + } + + for (int i = 0; i < nThreads; i ++) { + boolean success = false; + try { + children[i] = newChild(threadFactory, args); + success = true; + } catch (Exception e) { + // TODO: Think about if this is a good exception type + throw new IllegalStateException("failed to create a child event loop", e); + } finally { + if (!success) { + for (int j = 0; j < i; j ++) { + children[j].shutdownGracefully(); + } + + for (int j = 0; j < i; j ++) { + EventExecutor e = children[j]; + try { + while (!e.isTerminated()) { + e.awaitTermination(Integer.MAX_VALUE, TimeUnit.SECONDS); + } + } catch (InterruptedException interrupted) { + Thread.currentThread().interrupt(); + break; + } + } + } + } + } + + final FutureListener terminationListener = new FutureListener() { + @Override + public void operationComplete(Future future) throws Exception { + if (terminatedChildren.incrementAndGet() == children.length) { + terminationFuture.setSuccess(null); + } + } + }; + + for (EventExecutor e: children) { + e.terminationFuture().addListener(terminationListener); + } + } + + protected ThreadFactory newDefaultThreadFactory() { + return new DefaultThreadFactory(getClass()); + } + + @Override + public EventExecutor next() { + return chooser.next(); + } + + @Override + public Iterator iterator() { + return children().iterator(); + } + + /** + * Return the number of {@link EventExecutor} this implementation uses. This number is the maps + * 1:1 to the threads it use. + */ + public final int executorCount() { + return children.length; + } + + /** + * Return a safe-copy of all of the children of this group. + */ + protected Set children() { + Set children = Collections.newSetFromMap(new LinkedHashMap()); + Collections.addAll(children, this.children); + return children; + } + + /** + * Create a new EventExecutor which will later then accessible via the {@link #next()} method. This method will be + * called for each thread that will serve this {@link MultithreadEventExecutorGroup}. + * + */ + protected abstract EventExecutor newChild( + ThreadFactory threadFactory, Object... args) throws Exception; + + @Override + public Future shutdownGracefully(long quietPeriod, long timeout, TimeUnit unit) { + for (EventExecutor l: children) { + l.shutdownGracefully(quietPeriod, timeout, unit); + } + return terminationFuture(); + } + + @Override + public Future terminationFuture() { + return terminationFuture; + } + + @Override + @Deprecated + public void shutdown() { + for (EventExecutor l: children) { + l.shutdown(); + } + } + + @Override + public boolean isShuttingDown() { + for (EventExecutor l: children) { + if (!l.isShuttingDown()) { + return false; + } + } + return true; + } + + @Override + public boolean isShutdown() { + for (EventExecutor l: children) { + if (!l.isShutdown()) { + return false; + } + } + return true; + } + + @Override + public boolean isTerminated() { + for (EventExecutor l: children) { + if (!l.isTerminated()) { + return false; + } + } + return true; + } + + @Override + public boolean awaitTermination(long timeout, TimeUnit unit) + throws InterruptedException { + long deadline = System.nanoTime() + unit.toNanos(timeout); + loop: for (EventExecutor l: children) { + for (;;) { + long timeLeft = deadline - System.nanoTime(); + if (timeLeft <= 0) { + break loop; + } + if (l.awaitTermination(timeLeft, TimeUnit.NANOSECONDS)) { + break; + } + } + } + return isTerminated(); + } + + private static boolean isPowerOfTwo(int val) { + return (val & -val) == val; + } + + private interface EventExecutorChooser { + EventExecutor next(); + } + + private final class PowerOfTwoEventExecutorChooser implements EventExecutorChooser { + @Override + public EventExecutor next() { + return children[childIndex.getAndIncrement() & children.length - 1]; + } + } + + private final class GenericEventExecutorChooser implements EventExecutorChooser { + @Override + public EventExecutor next() { + return children[Math.abs(childIndex.getAndIncrement() % children.length)]; + } + } +} diff --git a/common/src/common/net/util/concurrent/ProgressiveFuture.java b/common/src/common/net/util/concurrent/ProgressiveFuture.java new file mode 100644 index 0000000..71c7134 --- /dev/null +++ b/common/src/common/net/util/concurrent/ProgressiveFuture.java @@ -0,0 +1,47 @@ +/* + * Copyright 2013 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ + +package common.net.util.concurrent; + +/** + * A {@link Future} which is used to indicate the progress of an operation. + */ +public interface ProgressiveFuture extends Future { + + @Override + ProgressiveFuture addListener(GenericFutureListener> listener); + + @Override + ProgressiveFuture addListeners(GenericFutureListener>... listeners); + + @Override + ProgressiveFuture removeListener(GenericFutureListener> listener); + + @Override + ProgressiveFuture removeListeners(GenericFutureListener>... listeners); + + @Override + ProgressiveFuture sync() throws InterruptedException; + + @Override + ProgressiveFuture syncUninterruptibly(); + + @Override + ProgressiveFuture await() throws InterruptedException; + + @Override + ProgressiveFuture awaitUninterruptibly(); +} diff --git a/common/src/common/net/util/concurrent/ProgressivePromise.java b/common/src/common/net/util/concurrent/ProgressivePromise.java new file mode 100644 index 0000000..e6a2e35 --- /dev/null +++ b/common/src/common/net/util/concurrent/ProgressivePromise.java @@ -0,0 +1,65 @@ +/* + * Copyright 2013 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ +package common.net.util.concurrent; + +/** + * Special {@link ProgressiveFuture} which is writable. + */ +public interface ProgressivePromise extends Promise, ProgressiveFuture { + + /** + * Sets the current progress of the operation and notifies the listeners that implement + * {@link GenericProgressiveFutureListener}. + */ + ProgressivePromise setProgress(long progress, long total); + + /** + * Tries to set the current progress of the operation and notifies the listeners that implement + * {@link GenericProgressiveFutureListener}. If the operation is already complete or the progress is out of range, + * this method does nothing but returning {@code false}. + */ + boolean tryProgress(long progress, long total); + + @Override + ProgressivePromise setSuccess(V result); + + @Override + ProgressivePromise setFailure(Throwable cause); + + @Override + ProgressivePromise addListener(GenericFutureListener> listener); + + @Override + ProgressivePromise addListeners(GenericFutureListener>... listeners); + + @Override + ProgressivePromise removeListener(GenericFutureListener> listener); + + @Override + ProgressivePromise removeListeners(GenericFutureListener>... listeners); + + @Override + ProgressivePromise await() throws InterruptedException; + + @Override + ProgressivePromise awaitUninterruptibly(); + + @Override + ProgressivePromise sync() throws InterruptedException; + + @Override + ProgressivePromise syncUninterruptibly(); +} diff --git a/common/src/common/net/util/concurrent/Promise.java b/common/src/common/net/util/concurrent/Promise.java new file mode 100644 index 0000000..252d895 --- /dev/null +++ b/common/src/common/net/util/concurrent/Promise.java @@ -0,0 +1,90 @@ +/* + * Copyright 2013 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ +package common.net.util.concurrent; + +/** + * Special {@link Future} which is writable. + */ +public interface Promise extends Future { + + /** + * Marks this future as a success and notifies all + * listeners. + * + * If it is success or failed already it will throw an {@link IllegalStateException}. + */ + Promise setSuccess(V result); + + /** + * Marks this future as a success and notifies all + * listeners. + * + * @return {@code true} if and only if successfully marked this future as + * a success. Otherwise {@code false} because this future is + * already marked as either a success or a failure. + */ + boolean trySuccess(V result); + + /** + * Marks this future as a failure and notifies all + * listeners. + * + * If it is success or failed already it will throw an {@link IllegalStateException}. + */ + Promise setFailure(Throwable cause); + + /** + * Marks this future as a failure and notifies all + * listeners. + * + * @return {@code true} if and only if successfully marked this future as + * a failure. Otherwise {@code false} because this future is + * already marked as either a success or a failure. + */ + boolean tryFailure(Throwable cause); + + /** + * Make this future impossible to cancel. + * + * @return {@code true} if and only if successfully marked this future as uncancellable or it is already done + * without being cancelled. {@code false} if this future has been cancelled already. + */ + boolean setUncancellable(); + + @Override + Promise addListener(GenericFutureListener> listener); + + @Override + Promise addListeners(GenericFutureListener>... listeners); + + @Override + Promise removeListener(GenericFutureListener> listener); + + @Override + Promise removeListeners(GenericFutureListener>... listeners); + + @Override + Promise await() throws InterruptedException; + + @Override + Promise awaitUninterruptibly(); + + @Override + Promise sync() throws InterruptedException; + + @Override + Promise syncUninterruptibly(); +} diff --git a/common/src/common/net/util/concurrent/PromiseTask.java b/common/src/common/net/util/concurrent/PromiseTask.java new file mode 100644 index 0000000..8a897ad --- /dev/null +++ b/common/src/common/net/util/concurrent/PromiseTask.java @@ -0,0 +1,137 @@ +/* + * Copyright 2013 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ +package common.net.util.concurrent; + +import java.util.concurrent.Callable; +import java.util.concurrent.RunnableFuture; + +class PromiseTask extends DefaultPromise implements RunnableFuture { + + static Callable toCallable(Runnable runnable, T result) { + return new RunnableAdapter(runnable, result); + } + + private static final class RunnableAdapter implements Callable { + final Runnable task; + final T result; + + RunnableAdapter(Runnable task, T result) { + this.task = task; + this.result = result; + } + + @Override + public T call() { + task.run(); + return result; + } + + @Override + public String toString() { + return "Callable(task: " + task + ", result: " + result + ')'; + } + } + + protected final Callable task; + + PromiseTask(EventExecutor executor, Runnable runnable, V result) { + this(executor, toCallable(runnable, result)); + } + + PromiseTask(EventExecutor executor, Callable callable) { + super(executor); + task = callable; + } + + @Override + public final int hashCode() { + return System.identityHashCode(this); + } + + @Override + public final boolean equals(Object obj) { + return this == obj; + } + + @Override + public void run() { + try { + if (setUncancellableInternal()) { + V result = task.call(); + setSuccessInternal(result); + } + } catch (Throwable e) { + setFailureInternal(e); + } + } + + @Override + public final Promise setFailure(Throwable cause) { + throw new IllegalStateException(); + } + + protected final Promise setFailureInternal(Throwable cause) { + super.setFailure(cause); + return this; + } + + @Override + public final boolean tryFailure(Throwable cause) { + return false; + } + + protected final boolean tryFailureInternal(Throwable cause) { + return super.tryFailure(cause); + } + + @Override + public final Promise setSuccess(V result) { + throw new IllegalStateException(); + } + + protected final Promise setSuccessInternal(V result) { + super.setSuccess(result); + return this; + } + + @Override + public final boolean trySuccess(V result) { + return false; + } + + protected final boolean trySuccessInternal(V result) { + return super.trySuccess(result); + } + + @Override + public final boolean setUncancellable() { + throw new IllegalStateException(); + } + + protected final boolean setUncancellableInternal() { + return super.setUncancellable(); + } + + @Override + protected StringBuilder toStringBuilder() { + StringBuilder buf = super.toStringBuilder(); + buf.setCharAt(buf.length() - 1, ','); + buf.append(" task: "); + buf.append(task); + buf.append(')'); + return buf; + } +} diff --git a/common/src/common/net/util/concurrent/ScheduledFuture.java b/common/src/common/net/util/concurrent/ScheduledFuture.java new file mode 100644 index 0000000..3498b13 --- /dev/null +++ b/common/src/common/net/util/concurrent/ScheduledFuture.java @@ -0,0 +1,23 @@ +/* + * Copyright 2013 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ +package common.net.util.concurrent; + +/** + * The result of an scheduled asynchronous operation. + */ + +public interface ScheduledFuture extends Future, java.util.concurrent.ScheduledFuture { +} diff --git a/common/src/common/net/util/concurrent/ScheduledFutureTask.java b/common/src/common/net/util/concurrent/ScheduledFutureTask.java new file mode 100644 index 0000000..83f64b3 --- /dev/null +++ b/common/src/common/net/util/concurrent/ScheduledFutureTask.java @@ -0,0 +1,161 @@ +/* + * Copyright 2013 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ + +package common.net.util.concurrent; + +import java.util.Queue; +import java.util.concurrent.Callable; +import java.util.concurrent.Delayed; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicLong; + + +final class ScheduledFutureTask extends PromiseTask implements ScheduledFuture { + private static final AtomicLong nextTaskId = new AtomicLong(); + private static final long START_TIME = System.nanoTime(); + + static long nanoTime() { + return System.nanoTime() - START_TIME; + } + + static long deadlineNanos(long delay) { + return nanoTime() + delay; + } + + private final long id = nextTaskId.getAndIncrement(); + private final Queue> delayedTaskQueue; + private long deadlineNanos; + /* 0 - no repeat, >0 - repeat at fixed rate, <0 - repeat with fixed delay */ + private final long periodNanos; + + ScheduledFutureTask( + EventExecutor executor, Queue> delayedTaskQueue, + Runnable runnable, V result, long nanoTime) { + + this(executor, delayedTaskQueue, toCallable(runnable, result), nanoTime); + } + + ScheduledFutureTask( + EventExecutor executor, Queue> delayedTaskQueue, + Callable callable, long nanoTime, long period) { + + super(executor, callable); + if (period == 0) { + throw new IllegalArgumentException("period: 0 (expected: != 0)"); + } + this.delayedTaskQueue = delayedTaskQueue; + deadlineNanos = nanoTime; + periodNanos = period; + } + + ScheduledFutureTask( + EventExecutor executor, Queue> delayedTaskQueue, + Callable callable, long nanoTime) { + + super(executor, callable); + this.delayedTaskQueue = delayedTaskQueue; + deadlineNanos = nanoTime; + periodNanos = 0; + } + + @Override + protected EventExecutor executor() { + return super.executor(); + } + + public long deadlineNanos() { + return deadlineNanos; + } + + public long delayNanos() { + return Math.max(0, deadlineNanos() - nanoTime()); + } + + public long delayNanos(long currentTimeNanos) { + return Math.max(0, deadlineNanos() - (currentTimeNanos - START_TIME)); + } + + @Override + public long getDelay(TimeUnit unit) { + return unit.convert(delayNanos(), TimeUnit.NANOSECONDS); + } + + @Override + public int compareTo(Delayed o) { + if (this == o) { + return 0; + } + + ScheduledFutureTask that = (ScheduledFutureTask) o; + long d = deadlineNanos() - that.deadlineNanos(); + if (d < 0) { + return -1; + } else if (d > 0) { + return 1; + } else if (id < that.id) { + return -1; + } else if (id == that.id) { + throw new Error(); + } else { + return 1; + } + } + + @Override + public void run() { + assert executor().inEventLoop(); + try { + if (periodNanos == 0) { + if (setUncancellableInternal()) { + V result = task.call(); + setSuccessInternal(result); + } + } else { + // check if is done as it may was cancelled + if (!isCancelled()) { + task.call(); + if (!executor().isShutdown()) { + long p = periodNanos; + if (p > 0) { + deadlineNanos += p; + } else { + deadlineNanos = nanoTime() - p; + } + if (!isCancelled()) { + delayedTaskQueue.add(this); + } + } + } + } + } catch (Throwable cause) { + setFailureInternal(cause); + } + } + + @Override + protected StringBuilder toStringBuilder() { + StringBuilder buf = super.toStringBuilder(); + buf.setCharAt(buf.length() - 1, ','); + buf.append(" id: "); + buf.append(id); + buf.append(", deadline: "); + buf.append(deadlineNanos); + buf.append(", period: "); + buf.append(periodNanos); + buf.append(')'); + return buf; + } +} diff --git a/common/src/common/net/util/concurrent/SingleThreadEventExecutor.java b/common/src/common/net/util/concurrent/SingleThreadEventExecutor.java new file mode 100644 index 0000000..4a635d1 --- /dev/null +++ b/common/src/common/net/util/concurrent/SingleThreadEventExecutor.java @@ -0,0 +1,870 @@ +/* + * Copyright 2012 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ +package common.net.util.concurrent; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.PriorityQueue; +import java.util.Queue; +import java.util.Set; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.Callable; +import java.util.concurrent.Executors; +import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.RejectedExecutionException; +import java.util.concurrent.Semaphore; +import java.util.concurrent.ThreadFactory; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicIntegerFieldUpdater; + +import common.net.util.internal.PlatformDependent; +import common.net.util.internal.logging.InternalLogger; +import common.net.util.internal.logging.InternalLoggerFactory; + +/** + * Abstract base class for {@link EventExecutor}'s that execute all its submitted tasks in a single thread. + * + */ +public abstract class SingleThreadEventExecutor extends AbstractEventExecutor { + + private static final InternalLogger logger = + InternalLoggerFactory.getInstance(SingleThreadEventExecutor.class); + + private static final int ST_NOT_STARTED = 1; + private static final int ST_STARTED = 2; + private static final int ST_SHUTTING_DOWN = 3; + private static final int ST_SHUTDOWN = 4; + private static final int ST_TERMINATED = 5; + + private static final Runnable WAKEUP_TASK = new Runnable() { + @Override + public void run() { + // Do nothing. + } + }; + + private static final AtomicIntegerFieldUpdater STATE_UPDATER; + + static { + AtomicIntegerFieldUpdater updater = + PlatformDependent.newAtomicIntegerFieldUpdater(SingleThreadEventExecutor.class, "state"); + if (updater == null) { + updater = AtomicIntegerFieldUpdater.newUpdater(SingleThreadEventExecutor.class, "state"); + } + STATE_UPDATER = updater; + } + + private final EventExecutorGroup parent; + private final Queue taskQueue; + final Queue> delayedTaskQueue = new PriorityQueue>(); + + private final Thread thread; + private final Semaphore threadLock = new Semaphore(0); + private final Set shutdownHooks = new LinkedHashSet(); + private final boolean addTaskWakesUp; + + private long lastExecutionTime; + + + private volatile int state = ST_NOT_STARTED; + + private volatile long gracefulShutdownQuietPeriod; + private volatile long gracefulShutdownTimeout; + private long gracefulShutdownStartTime; + + private final Promise terminationFuture = new DefaultPromise(GlobalEventExecutor.INSTANCE); + + /** + * Create a new instance + * + * @param parent the {@link EventExecutorGroup} which is the parent of this instance and belongs to it + * @param threadFactory the {@link ThreadFactory} which will be used for the used {@link Thread} + * @param addTaskWakesUp {@code true} if and only if invocation of {@link #addTask(Runnable)} will wake up the + * executor thread + */ + protected SingleThreadEventExecutor( + EventExecutorGroup parent, ThreadFactory threadFactory, boolean addTaskWakesUp) { + + if (threadFactory == null) { + throw new NullPointerException("threadFactory"); + } + + this.parent = parent; + this.addTaskWakesUp = addTaskWakesUp; + + thread = threadFactory.newThread(new Runnable() { + @Override + public void run() { + boolean success = false; + updateLastExecutionTime(); + try { + SingleThreadEventExecutor.this.run(); + success = true; + } catch (Throwable t) { + logger.warn("Unexpected exception from an event executor: ", t); + } finally { + for (;;) { + int oldState = STATE_UPDATER.get(SingleThreadEventExecutor.this); + if (oldState >= ST_SHUTTING_DOWN || STATE_UPDATER.compareAndSet( + SingleThreadEventExecutor.this, oldState, ST_SHUTTING_DOWN)) { + break; + } + } + // Check if confirmShutdown() was called at the end of the loop. + if (success && gracefulShutdownStartTime == 0) { + logger.error( + "Buggy " + EventExecutor.class.getSimpleName() + " implementation; " + + SingleThreadEventExecutor.class.getSimpleName() + ".confirmShutdown() must be called " + + "before run() implementation terminates."); + } + + try { + // Run all remaining tasks and shutdown hooks. + for (;;) { + if (confirmShutdown()) { + break; + } + } + } finally { + try { + cleanup(); + } finally { + STATE_UPDATER.set(SingleThreadEventExecutor.this, ST_TERMINATED); + threadLock.release(); + if (!taskQueue.isEmpty()) { + logger.warn( + "An event executor terminated with " + + "non-empty task queue (" + taskQueue.size() + ')'); + } + + terminationFuture.setSuccess(null); + } + } + } + } + }); + + taskQueue = newTaskQueue(); + } + + /** + * Create a new {@link Queue} which will holds the tasks to execute. This default implementation will return a + * {@link LinkedBlockingQueue} but if your sub-class of {@link SingleThreadEventExecutor} will not do any blocking + * calls on the this {@link Queue} it may make sense to {@code @Override} this and return some more performant + * implementation that does not support blocking operations at all. + */ + protected Queue newTaskQueue() { + return new LinkedBlockingQueue(); + } + + @Override + public EventExecutorGroup parent() { + return parent; + } + + /** + * Interrupt the current running {@link Thread}. + */ + protected void interruptThread() { + thread.interrupt(); + } + + /** + * @see {@link Queue#poll()} + */ + protected Runnable pollTask() { + assert inEventLoop(); + for (;;) { + Runnable task = taskQueue.poll(); + if (task == WAKEUP_TASK) { + continue; + } + return task; + } + } + + /** + * Take the next {@link Runnable} from the task queue and so will block if no task is currently present. + *

+ * Be aware that this method will throw an {@link UnsupportedOperationException} if the task queue, which was + * created via {@link #newTaskQueue()}, does not implement {@link BlockingQueue}. + *

+ * + * @return {@code null} if the executor thread has been interrupted or waken up. + */ + protected Runnable takeTask() { + assert inEventLoop(); + if (!(taskQueue instanceof BlockingQueue)) { + throw new UnsupportedOperationException(); + } + + BlockingQueue taskQueue = (BlockingQueue) this.taskQueue; + for (;;) { + ScheduledFutureTask delayedTask = delayedTaskQueue.peek(); + if (delayedTask == null) { + Runnable task = null; + try { + task = taskQueue.take(); + if (task == WAKEUP_TASK) { + task = null; + } + } catch (InterruptedException e) { + // Ignore + } + return task; + } else { + long delayNanos = delayedTask.delayNanos(); + Runnable task = null; + if (delayNanos > 0) { + try { + task = taskQueue.poll(delayNanos, TimeUnit.NANOSECONDS); + } catch (InterruptedException e) { + return null; + } + } + if (task == null) { + // We need to fetch the delayed tasks now as otherwise there may be a chance that + // delayed tasks are never executed if there is always one task in the taskQueue. + // This is for example true for the read task of OIO Transport + // See https://github.com/netty/netty/issues/1614 + fetchFromDelayedQueue(); + task = taskQueue.poll(); + } + + if (task != null) { + return task; + } + } + } + } + + private void fetchFromDelayedQueue() { + long nanoTime = 0L; + for (;;) { + ScheduledFutureTask delayedTask = delayedTaskQueue.peek(); + if (delayedTask == null) { + break; + } + + if (nanoTime == 0L) { + nanoTime = ScheduledFutureTask.nanoTime(); + } + + if (delayedTask.deadlineNanos() <= nanoTime) { + delayedTaskQueue.remove(); + taskQueue.add(delayedTask); + } else { + break; + } + } + } + + /** + * @see {@link Queue#peek()} + */ + protected Runnable peekTask() { + assert inEventLoop(); + return taskQueue.peek(); + } + + /** + * @see {@link Queue#isEmpty()} + */ + protected boolean hasTasks() { + assert inEventLoop(); + return !taskQueue.isEmpty(); + } + + /** + * Returns {@code true} if a scheduled task is ready for processing by {@link #runAllTasks()} or + * {@link #runAllTasks(long)}. + */ + protected boolean hasScheduledTasks() { + assert inEventLoop(); + ScheduledFutureTask delayedTask = delayedTaskQueue.peek(); + return delayedTask != null && delayedTask.deadlineNanos() <= ScheduledFutureTask.nanoTime(); + } + + /** + * Return the number of tasks that are pending for processing. + * + * Be aware that this operation may be expensive as it depends on the internal implementation of the + * SingleThreadEventExecutor. So use it was care! + */ + public final int pendingTasks() { + return taskQueue.size(); + } + + /** + * Add a task to the task queue, or throws a {@link RejectedExecutionException} if this instance was shutdown + * before. + */ + protected void addTask(Runnable task) { + if (task == null) { + throw new NullPointerException("task"); + } + if (isShutdown()) { + reject(); + } + taskQueue.add(task); + } + + /** + * @see {@link Queue#remove(Object)} + */ + protected boolean removeTask(Runnable task) { + if (task == null) { + throw new NullPointerException("task"); + } + return taskQueue.remove(task); + } + + /** + * Poll all tasks from the task queue and run them via {@link Runnable#run()} method. + * + * @return {@code true} if and only if at least one task was run + */ + protected boolean runAllTasks() { + fetchFromDelayedQueue(); + Runnable task = pollTask(); + if (task == null) { + return false; + } + + for (;;) { + try { + task.run(); + } catch (Throwable t) { + logger.warn("A task raised an exception.", t); + } + + task = pollTask(); + if (task == null) { + lastExecutionTime = ScheduledFutureTask.nanoTime(); + return true; + } + } + } + + /** + * Poll all tasks from the task queue and run them via {@link Runnable#run()} method. This method stops running + * the tasks in the task queue and returns if it ran longer than {@code timeoutNanos}. + */ + protected boolean runAllTasks(long timeoutNanos) { + fetchFromDelayedQueue(); + Runnable task = pollTask(); + if (task == null) { + return false; + } + + final long deadline = ScheduledFutureTask.nanoTime() + timeoutNanos; + long runTasks = 0; + long lastExecutionTime; + for (;;) { + try { + task.run(); + } catch (Throwable t) { + logger.warn("A task raised an exception.", t); + } + + runTasks ++; + + // Check timeout every 64 tasks because nanoTime() is relatively expensive. + // XXX: Hard-coded value - will make it configurable if it is really a problem. + if ((runTasks & 0x3F) == 0) { + lastExecutionTime = ScheduledFutureTask.nanoTime(); + if (lastExecutionTime >= deadline) { + break; + } + } + + task = pollTask(); + if (task == null) { + lastExecutionTime = ScheduledFutureTask.nanoTime(); + break; + } + } + + this.lastExecutionTime = lastExecutionTime; + return true; + } + + /** + * Returns the amount of time left until the scheduled task with the closest dead line is executed. + */ + protected long delayNanos(long currentTimeNanos) { + ScheduledFutureTask delayedTask = delayedTaskQueue.peek(); + if (delayedTask == null) { + return SCHEDULE_PURGE_INTERVAL; + } + + return delayedTask.delayNanos(currentTimeNanos); + } + + /** + * Updates the internal timestamp that tells when a submitted task was executed most recently. + * {@link #runAllTasks()} and {@link #runAllTasks(long)} updates this timestamp automatically, and thus there's + * usually no need to call this method. However, if you take the tasks manually using {@link #takeTask()} or + * {@link #pollTask()}, you have to call this method at the end of task execution loop for accurate quiet period + * checks. + */ + protected void updateLastExecutionTime() { + lastExecutionTime = ScheduledFutureTask.nanoTime(); + } + + /** + * + */ + protected abstract void run(); + + /** + * Do nothing, sub-classes may override + */ + protected void cleanup() { + // NOOP + } + + protected void wakeup(boolean inEventLoop) { + if (!inEventLoop || STATE_UPDATER.get(this) == ST_SHUTTING_DOWN) { + taskQueue.add(WAKEUP_TASK); + } + } + + @Override + public boolean inEventLoop(Thread thread) { + return thread == this.thread; + } + + /** + * Add a {@link Runnable} which will be executed on shutdown of this instance + */ + public void addShutdownHook(final Runnable task) { + if (inEventLoop()) { + shutdownHooks.add(task); + } else { + execute(new Runnable() { + @Override + public void run() { + shutdownHooks.add(task); + } + }); + } + } + + /** + * Remove a previous added {@link Runnable} as a shutdown hook + */ + public void removeShutdownHook(final Runnable task) { + if (inEventLoop()) { + shutdownHooks.remove(task); + } else { + execute(new Runnable() { + @Override + public void run() { + shutdownHooks.remove(task); + } + }); + } + } + + private boolean runShutdownHooks() { + boolean ran = false; + // Note shutdown hooks can add / remove shutdown hooks. + while (!shutdownHooks.isEmpty()) { + List copy = new ArrayList(shutdownHooks); + shutdownHooks.clear(); + for (Runnable task: copy) { + try { + task.run(); + } catch (Throwable t) { + logger.warn("Shutdown hook raised an exception.", t); + } finally { + ran = true; + } + } + } + + if (ran) { + lastExecutionTime = ScheduledFutureTask.nanoTime(); + } + + return ran; + } + + @Override + public Future shutdownGracefully(long quietPeriod, long timeout, TimeUnit unit) { + if (quietPeriod < 0) { + throw new IllegalArgumentException("quietPeriod: " + quietPeriod + " (expected >= 0)"); + } + if (timeout < quietPeriod) { + throw new IllegalArgumentException( + "timeout: " + timeout + " (expected >= quietPeriod (" + quietPeriod + "))"); + } + if (unit == null) { + throw new NullPointerException("unit"); + } + + if (isShuttingDown()) { + return terminationFuture(); + } + + boolean inEventLoop = inEventLoop(); + boolean wakeup; + int oldState; + for (;;) { + if (isShuttingDown()) { + return terminationFuture(); + } + int newState; + wakeup = true; + oldState = STATE_UPDATER.get(this); + if (inEventLoop) { + newState = ST_SHUTTING_DOWN; + } else { + switch (oldState) { + case ST_NOT_STARTED: + case ST_STARTED: + newState = ST_SHUTTING_DOWN; + break; + default: + newState = oldState; + wakeup = false; + } + } + if (STATE_UPDATER.compareAndSet(this, oldState, newState)) { + break; + } + } + gracefulShutdownQuietPeriod = unit.toNanos(quietPeriod); + gracefulShutdownTimeout = unit.toNanos(timeout); + + if (oldState == ST_NOT_STARTED) { + thread.start(); + } + + if (wakeup) { + wakeup(inEventLoop); + } + + return terminationFuture(); + } + + @Override + public Future terminationFuture() { + return terminationFuture; + } + + @Override + @Deprecated + public void shutdown() { + if (isShutdown()) { + return; + } + + boolean inEventLoop = inEventLoop(); + boolean wakeup; + int oldState; + for (;;) { + if (isShuttingDown()) { + return; + } + int newState; + wakeup = true; + oldState = STATE_UPDATER.get(this); + if (inEventLoop) { + newState = ST_SHUTDOWN; + } else { + switch (oldState) { + case ST_NOT_STARTED: + case ST_STARTED: + case ST_SHUTTING_DOWN: + newState = ST_SHUTDOWN; + break; + default: + newState = oldState; + wakeup = false; + } + } + if (STATE_UPDATER.compareAndSet(this, oldState, newState)) { + break; + } + } + + if (oldState == ST_NOT_STARTED) { + thread.start(); + } + + if (wakeup) { + wakeup(inEventLoop); + } + } + + @Override + public boolean isShuttingDown() { + return STATE_UPDATER.get(this) >= ST_SHUTTING_DOWN; + } + + @Override + public boolean isShutdown() { + return STATE_UPDATER.get(this) >= ST_SHUTDOWN; + } + + @Override + public boolean isTerminated() { + return STATE_UPDATER.get(this) == ST_TERMINATED; + } + + /** + * Confirm that the shutdown if the instance should be done now! + */ + protected boolean confirmShutdown() { + if (!isShuttingDown()) { + return false; + } + + if (!inEventLoop()) { + throw new IllegalStateException("must be invoked from an event loop"); + } + + cancelDelayedTasks(); + + if (gracefulShutdownStartTime == 0) { + gracefulShutdownStartTime = ScheduledFutureTask.nanoTime(); + } + + if (runAllTasks() || runShutdownHooks()) { + if (isShutdown()) { + // Executor shut down - no new tasks anymore. + return true; + } + + // There were tasks in the queue. Wait a little bit more until no tasks are queued for the quiet period. + wakeup(true); + return false; + } + + final long nanoTime = ScheduledFutureTask.nanoTime(); + + if (isShutdown() || nanoTime - gracefulShutdownStartTime > gracefulShutdownTimeout) { + return true; + } + + if (nanoTime - lastExecutionTime <= gracefulShutdownQuietPeriod) { + // Check if any tasks were added to the queue every 100ms. + // TODO: Change the behavior of takeTask() so that it returns on timeout. + wakeup(true); + try { + Thread.sleep(100); + } catch (InterruptedException e) { + // Ignore + } + + return false; + } + + // No tasks were added for last quiet period - hopefully safe to shut down. + // (Hopefully because we really cannot make a guarantee that there will be no execute() calls by a user.) + return true; + } + + private void cancelDelayedTasks() { + if (delayedTaskQueue.isEmpty()) { + return; + } + + final ScheduledFutureTask[] delayedTasks = + delayedTaskQueue.toArray(new ScheduledFutureTask[delayedTaskQueue.size()]); + + for (ScheduledFutureTask task: delayedTasks) { + task.cancel(false); + } + + delayedTaskQueue.clear(); + } + + @Override + public boolean awaitTermination(long timeout, TimeUnit unit) throws InterruptedException { + if (unit == null) { + throw new NullPointerException("unit"); + } + + if (inEventLoop()) { + throw new IllegalStateException("cannot await termination of the current thread"); + } + + if (threadLock.tryAcquire(timeout, unit)) { + threadLock.release(); + } + + return isTerminated(); + } + + @Override + public void execute(Runnable task) { + if (task == null) { + throw new NullPointerException("task"); + } + + boolean inEventLoop = inEventLoop(); + if (inEventLoop) { + addTask(task); + } else { + startThread(); + addTask(task); + if (isShutdown() && removeTask(task)) { + reject(); + } + } + + if (!addTaskWakesUp && wakesUpForTask(task)) { + wakeup(inEventLoop); + } + } + + + protected boolean wakesUpForTask(Runnable task) { + return true; + } + + protected static void reject() { + throw new RejectedExecutionException("event executor terminated"); + } + + // ScheduledExecutorService implementation + + private static final long SCHEDULE_PURGE_INTERVAL = TimeUnit.SECONDS.toNanos(1); + + @Override + public ScheduledFuture schedule(Runnable command, long delay, TimeUnit unit) { + if (command == null) { + throw new NullPointerException("command"); + } + if (unit == null) { + throw new NullPointerException("unit"); + } + if (delay < 0) { + throw new IllegalArgumentException( + String.format("delay: %d (expected: >= 0)", delay)); + } + return schedule(new ScheduledFutureTask( + this, delayedTaskQueue, command, null, ScheduledFutureTask.deadlineNanos(unit.toNanos(delay)))); + } + + @Override + public ScheduledFuture schedule(Callable callable, long delay, TimeUnit unit) { + if (callable == null) { + throw new NullPointerException("callable"); + } + if (unit == null) { + throw new NullPointerException("unit"); + } + if (delay < 0) { + throw new IllegalArgumentException( + String.format("delay: %d (expected: >= 0)", delay)); + } + return schedule(new ScheduledFutureTask( + this, delayedTaskQueue, callable, ScheduledFutureTask.deadlineNanos(unit.toNanos(delay)))); + } + + @Override + public ScheduledFuture scheduleAtFixedRate(Runnable command, long initialDelay, long period, TimeUnit unit) { + if (command == null) { + throw new NullPointerException("command"); + } + if (unit == null) { + throw new NullPointerException("unit"); + } + if (initialDelay < 0) { + throw new IllegalArgumentException( + String.format("initialDelay: %d (expected: >= 0)", initialDelay)); + } + if (period <= 0) { + throw new IllegalArgumentException( + String.format("period: %d (expected: > 0)", period)); + } + + return schedule(new ScheduledFutureTask( + this, delayedTaskQueue, Executors.callable(command, null), + ScheduledFutureTask.deadlineNanos(unit.toNanos(initialDelay)), unit.toNanos(period))); + } + + @Override + public ScheduledFuture scheduleWithFixedDelay(Runnable command, long initialDelay, long delay, TimeUnit unit) { + if (command == null) { + throw new NullPointerException("command"); + } + if (unit == null) { + throw new NullPointerException("unit"); + } + if (initialDelay < 0) { + throw new IllegalArgumentException( + String.format("initialDelay: %d (expected: >= 0)", initialDelay)); + } + if (delay <= 0) { + throw new IllegalArgumentException( + String.format("delay: %d (expected: > 0)", delay)); + } + + return schedule(new ScheduledFutureTask( + this, delayedTaskQueue, Executors.callable(command, null), + ScheduledFutureTask.deadlineNanos(unit.toNanos(initialDelay)), -unit.toNanos(delay))); + } + + private ScheduledFuture schedule(final ScheduledFutureTask task) { + if (task == null) { + throw new NullPointerException("task"); + } + + if (inEventLoop()) { + delayedTaskQueue.add(task); + } else { + execute(new Runnable() { + @Override + public void run() { + delayedTaskQueue.add(task); + } + }); + } + + return task; + } + + private void startThread() { + if (STATE_UPDATER.get(this) == ST_NOT_STARTED) { + if (STATE_UPDATER.compareAndSet(this, ST_NOT_STARTED, ST_STARTED)) { + delayedTaskQueue.add(new ScheduledFutureTask( + this, delayedTaskQueue, Executors.callable(new PurgeTask(), null), + ScheduledFutureTask.deadlineNanos(SCHEDULE_PURGE_INTERVAL), -SCHEDULE_PURGE_INTERVAL)); + thread.start(); + } + } + } + + private final class PurgeTask implements Runnable { + @Override + public void run() { + Iterator> i = delayedTaskQueue.iterator(); + while (i.hasNext()) { + ScheduledFutureTask task = i.next(); + if (task.isCancelled()) { + i.remove(); + } + } + } + } +} diff --git a/common/src/common/net/util/concurrent/SucceededFuture.java b/common/src/common/net/util/concurrent/SucceededFuture.java new file mode 100644 index 0000000..ddcd86f --- /dev/null +++ b/common/src/common/net/util/concurrent/SucceededFuture.java @@ -0,0 +1,50 @@ +/* + * Copyright 2012 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ +package common.net.util.concurrent; + +/** + * The {@link CompleteFuture} which is succeeded already. It is + * recommended to use {@link EventExecutor#newSucceededFuture(Object)} instead of + * calling the constructor of this future. + */ +public final class SucceededFuture extends CompleteFuture { + private final V result; + + /** + * Creates a new instance. + * + * @param executor the {@link EventExecutor} associated with this future + */ + public SucceededFuture(EventExecutor executor, V result) { + super(executor); + this.result = result; + } + + @Override + public Throwable cause() { + return null; + } + + @Override + public boolean isSuccess() { + return true; + } + + @Override + public V getNow() { + return result; + } +} diff --git a/common/src/common/net/util/internal/Cleaner0.java b/common/src/common/net/util/internal/Cleaner0.java new file mode 100644 index 0000000..ceb3aeb --- /dev/null +++ b/common/src/common/net/util/internal/Cleaner0.java @@ -0,0 +1,74 @@ +/* +* Copyright 2014 The Netty Project +* +* The Netty Project licenses this file to you under the Apache License, +* version 2.0 (the "License"); you may not use this file except in compliance +* with the License. You may obtain a copy of the License at: +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +* License for the specific language governing permissions and limitations +* under the License. +*/ +package common.net.util.internal; + +import java.lang.reflect.Field; +import java.nio.ByteBuffer; + +import common.net.util.internal.logging.InternalLogger; +import common.net.util.internal.logging.InternalLoggerFactory; +import sun.misc.Cleaner; + + +/** + * Allows to free direct {@link ByteBuffer} by using {@link Cleaner}. This is encapsulated in an extra class to be able + * to use {@link PlatformDependent0} on Android without problems. + * + * For more details see #2604. + */ +final class Cleaner0 { + private static final long CLEANER_FIELD_OFFSET; + private static final InternalLogger logger = InternalLoggerFactory.getInstance(Cleaner0.class); + + static { + ByteBuffer direct = ByteBuffer.allocateDirect(1); + Field cleanerField; + long fieldOffset = -1; + if (PlatformDependent0.hasUnsafe()) { + try { + cleanerField = direct.getClass().getDeclaredField("cleaner"); + cleanerField.setAccessible(true); + Cleaner cleaner = (Cleaner) cleanerField.get(direct); + cleaner.clean(); + fieldOffset = PlatformDependent0.objectFieldOffset(cleanerField); + } catch (Throwable t) { + // We don't have ByteBuffer.cleaner(). + fieldOffset = -1; + } + } + logger.debug("java.nio.ByteBuffer.cleaner(): {}", fieldOffset != -1? "available" : "unavailable"); + CLEANER_FIELD_OFFSET = fieldOffset; + + // free buffer if possible + freeDirectBuffer(direct); + } + + static void freeDirectBuffer(ByteBuffer buffer) { + if (CLEANER_FIELD_OFFSET == -1 || !buffer.isDirect()) { + return; + } + try { + Cleaner cleaner = (Cleaner) PlatformDependent0.getObject(buffer, CLEANER_FIELD_OFFSET); + if (cleaner != null) { + cleaner.clean(); + } + } catch (Throwable t) { + // Nothing we can do here. + } + } + + private Cleaner0() { } +} diff --git a/common/src/common/net/util/internal/EmptyArrays.java b/common/src/common/net/util/internal/EmptyArrays.java new file mode 100644 index 0000000..e5fac07 --- /dev/null +++ b/common/src/common/net/util/internal/EmptyArrays.java @@ -0,0 +1,39 @@ +/* + * Copyright 2013 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ + +package common.net.util.internal; + +import java.nio.ByteBuffer; +import java.security.cert.X509Certificate; + +public final class EmptyArrays { + + public static final byte[] EMPTY_BYTES = new byte[0]; + public static final boolean[] EMPTY_BOOLEANS = new boolean[0]; + public static final double[] EMPTY_DOUBLES = new double[0]; + public static final float[] EMPTY_FLOATS = new float[0]; + public static final int[] EMPTY_INTS = new int[0]; + public static final short[] EMPTY_SHORTS = new short[0]; + public static final long[] EMPTY_LONGS = new long[0]; + public static final Object[] EMPTY_OBJECTS = new Object[0]; + public static final Class[] EMPTY_CLASSES = new Class[0]; + public static final String[] EMPTY_STRINGS = new String[0]; + public static final StackTraceElement[] EMPTY_STACK_TRACE = new StackTraceElement[0]; + public static final ByteBuffer[] EMPTY_BYTE_BUFFERS = new ByteBuffer[0]; + public static final X509Certificate[] EMPTY_X509_CERTIFICATES = new X509Certificate[0]; + + private EmptyArrays() { } +} diff --git a/common/src/common/net/util/internal/IntegerHolder.java b/common/src/common/net/util/internal/IntegerHolder.java new file mode 100644 index 0000000..992a27c --- /dev/null +++ b/common/src/common/net/util/internal/IntegerHolder.java @@ -0,0 +1,21 @@ +/* + * Copyright 2014 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ + +package common.net.util.internal; + +public final class IntegerHolder { + public int value; +} diff --git a/common/src/common/net/util/internal/InternalThreadLocalMap.java b/common/src/common/net/util/internal/InternalThreadLocalMap.java new file mode 100644 index 0000000..85565f0 --- /dev/null +++ b/common/src/common/net/util/internal/InternalThreadLocalMap.java @@ -0,0 +1,309 @@ +/* + * Copyright 2014 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ + +package common.net.util.internal; + +import java.nio.charset.Charset; +import java.nio.charset.CharsetDecoder; +import java.nio.charset.CharsetEncoder; +import java.util.Arrays; +import java.util.IdentityHashMap; +import java.util.Map; +import java.util.WeakHashMap; + +import common.net.util.concurrent.FastThreadLocalThread; + +/** + * The internal data structure that stores the thread-local variables for Netty and all {@link FastThreadLocal}s. + * Note that this class is for internal use only and is subject to change at any time. Use {@link FastThreadLocal} + * unless you know what you are doing. + */ +public final class InternalThreadLocalMap extends UnpaddedInternalThreadLocalMap { + + public static final Object UNSET = new Object(); + + public static InternalThreadLocalMap getIfSet() { + Thread thread = Thread.currentThread(); + InternalThreadLocalMap threadLocalMap; + if (thread instanceof FastThreadLocalThread) { + threadLocalMap = ((FastThreadLocalThread) thread).threadLocalMap(); + } else { + ThreadLocal slowThreadLocalMap = UnpaddedInternalThreadLocalMap.slowThreadLocalMap; + if (slowThreadLocalMap == null) { + threadLocalMap = null; + } else { + threadLocalMap = slowThreadLocalMap.get(); + } + } + return threadLocalMap; + } + + public static InternalThreadLocalMap get() { + Thread thread = Thread.currentThread(); + if (thread instanceof FastThreadLocalThread) { + return fastGet((FastThreadLocalThread) thread); + } else { + return slowGet(); + } + } + + private static InternalThreadLocalMap fastGet(FastThreadLocalThread thread) { + InternalThreadLocalMap threadLocalMap = thread.threadLocalMap(); + if (threadLocalMap == null) { + thread.setThreadLocalMap(threadLocalMap = new InternalThreadLocalMap()); + } + return threadLocalMap; + } + + private static InternalThreadLocalMap slowGet() { + ThreadLocal slowThreadLocalMap = UnpaddedInternalThreadLocalMap.slowThreadLocalMap; + if (slowThreadLocalMap == null) { + UnpaddedInternalThreadLocalMap.slowThreadLocalMap = + slowThreadLocalMap = new ThreadLocal(); + } + + InternalThreadLocalMap ret = slowThreadLocalMap.get(); + if (ret == null) { + ret = new InternalThreadLocalMap(); + slowThreadLocalMap.set(ret); + } + return ret; + } + + public static void remove() { + Thread thread = Thread.currentThread(); + if (thread instanceof FastThreadLocalThread) { + ((FastThreadLocalThread) thread).setThreadLocalMap(null); + } else { + ThreadLocal slowThreadLocalMap = UnpaddedInternalThreadLocalMap.slowThreadLocalMap; + if (slowThreadLocalMap != null) { + slowThreadLocalMap.remove(); + } + } + } + + public static void destroy() { + slowThreadLocalMap = null; + } + + public static int nextVariableIndex() { + int index = nextIndex.getAndIncrement(); + if (index < 0) { + nextIndex.decrementAndGet(); + throw new IllegalStateException("too many thread-local indexed variables"); + } + return index; + } + + public static int lastVariableIndex() { + return nextIndex.get() - 1; + } + + // Cache line padding (must be public) + // With CompressedOops enabled, an instance of this class should occupy at least 128 bytes. + public long rp1, rp2, rp3, rp4, rp5, rp6, rp7, rp8, rp9; + + private InternalThreadLocalMap() { + super(newIndexedVariableTable()); + } + + private static Object[] newIndexedVariableTable() { + Object[] array = new Object[32]; + Arrays.fill(array, UNSET); + return array; + } + + public int size() { + int count = 0; + + if (futureListenerStackDepth != 0) { + count ++; + } + if (localChannelReaderStackDepth != 0) { + count ++; + } + if (handlerSharableCache != null) { + count ++; + } + if (counterHashCode != null) { + count ++; + } + if (random != null) { + count ++; + } + if (typeParameterMatcherGetCache != null) { + count ++; + } + if (typeParameterMatcherFindCache != null) { + count ++; + } + if (stringBuilder != null) { + count ++; + } + if (charsetEncoderCache != null) { + count ++; + } + if (charsetDecoderCache != null) { + count ++; + } + + for (Object o: indexedVariables) { + if (o != UNSET) { + count ++; + } + } + + // We should subtract 1 from the count because the first element in 'indexedVariables' is reserved + // by 'FastThreadLocal' to keep the list of 'FastThreadLocal's to remove on 'FastThreadLocal.removeAll()'. + return count - 1; + } + + public StringBuilder stringBuilder() { + StringBuilder builder = stringBuilder; + if (builder == null) { + stringBuilder = builder = new StringBuilder(512); + } else { + builder.setLength(0); + } + return builder; + } + + public Map charsetEncoderCache() { + Map cache = charsetEncoderCache; + if (cache == null) { + charsetEncoderCache = cache = new IdentityHashMap(); + } + return cache; + } + + public Map charsetDecoderCache() { + Map cache = charsetDecoderCache; + if (cache == null) { + charsetDecoderCache = cache = new IdentityHashMap(); + } + return cache; + } + + public int futureListenerStackDepth() { + return futureListenerStackDepth; + } + + public void setFutureListenerStackDepth(int futureListenerStackDepth) { + this.futureListenerStackDepth = futureListenerStackDepth; + } + + public ThreadLocalRandom random() { + ThreadLocalRandom r = random; + if (r == null) { + random = r = new ThreadLocalRandom(); + } + return r; + } + + public Map, TypeParameterMatcher> typeParameterMatcherGetCache() { + Map, TypeParameterMatcher> cache = typeParameterMatcherGetCache; + if (cache == null) { + typeParameterMatcherGetCache = cache = new IdentityHashMap, TypeParameterMatcher>(); + } + return cache; + } + + public Map, Map> typeParameterMatcherFindCache() { + Map, Map> cache = typeParameterMatcherFindCache; + if (cache == null) { + typeParameterMatcherFindCache = cache = new IdentityHashMap, Map>(); + } + return cache; + } + + public IntegerHolder counterHashCode() { + return counterHashCode; + } + + public void setCounterHashCode(IntegerHolder counterHashCode) { + this.counterHashCode = counterHashCode; + } + + public Map, Boolean> handlerSharableCache() { + Map, Boolean> cache = handlerSharableCache; + if (cache == null) { + // Start with small capacity to keep memory overhead as low as possible. + handlerSharableCache = cache = new WeakHashMap, Boolean>(4); + } + return cache; + } + + public int localChannelReaderStackDepth() { + return localChannelReaderStackDepth; + } + + public void setLocalChannelReaderStackDepth(int localChannelReaderStackDepth) { + this.localChannelReaderStackDepth = localChannelReaderStackDepth; + } + + public Object indexedVariable(int index) { + Object[] lookup = indexedVariables; + return index < lookup.length? lookup[index] : UNSET; + } + + /** + * @return {@code true} if and only if a new thread-local variable has been created + */ + public boolean setIndexedVariable(int index, Object value) { + Object[] lookup = indexedVariables; + if (index < lookup.length) { + Object oldValue = lookup[index]; + lookup[index] = value; + return oldValue == UNSET; + } else { + expandIndexedVariableTableAndSet(index, value); + return true; + } + } + + private void expandIndexedVariableTableAndSet(int index, Object value) { + Object[] oldArray = indexedVariables; + final int oldCapacity = oldArray.length; + int newCapacity = index; + newCapacity |= newCapacity >>> 1; + newCapacity |= newCapacity >>> 2; + newCapacity |= newCapacity >>> 4; + newCapacity |= newCapacity >>> 8; + newCapacity |= newCapacity >>> 16; + newCapacity ++; + + Object[] newArray = Arrays.copyOf(oldArray, newCapacity); + Arrays.fill(newArray, oldCapacity, newArray.length, UNSET); + newArray[index] = value; + indexedVariables = newArray; + } + + public Object removeIndexedVariable(int index) { + Object[] lookup = indexedVariables; + if (index < lookup.length) { + Object v = lookup[index]; + lookup[index] = UNSET; + return v; + } else { + return UNSET; + } + } + + public boolean isIndexedVariableSet(int index) { + Object[] lookup = indexedVariables; + return index < lookup.length && lookup[index] != UNSET; + } +} diff --git a/common/src/common/net/util/internal/MpscLinkedQueue.java b/common/src/common/net/util/internal/MpscLinkedQueue.java new file mode 100644 index 0000000..1b32c49 --- /dev/null +++ b/common/src/common/net/util/internal/MpscLinkedQueue.java @@ -0,0 +1,397 @@ +/* + * Copyright 2014 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ +/** + * Copyright (C) 2009-2013 Typesafe Inc. + */ +package common.net.util.internal; + +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.lang.reflect.Array; +import java.util.Arrays; +import java.util.Collection; +import java.util.Iterator; +import java.util.NoSuchElementException; +import java.util.Queue; + +/** + * A lock-free concurrent single-consumer multi-producer {@link Queue}. + * It allows multiple producer threads to perform the following operations simultaneously: + *
    + *
  • {@link #offer(Object)}, {@link #add(Object)}, and {@link #addAll(Collection)}
  • + *
  • All other read-only operations: + *
      + *
    • {@link #contains(Object)} and {@link #containsAll(Collection)}
    • + *
    • {@link #element()}, {@link #peek()}
    • + *
    • {@link #size()} and {@link #isEmpty()}
    • + *
    • {@link #iterator()} (except {@link Iterator#remove()}
    • + *
    • {@link #toArray()} and {@link #toArray(Object[])}
    • + *
    + *
  • + *
+ * .. while only one consumer thread is allowed to perform the following operations exclusively: + *
    + *
  • {@link #poll()} and {@link #remove()}
  • + *
  • {@link #remove(Object)}, {@link #removeAll(Collection)}, and {@link #retainAll(Collection)}
  • + *
  • {@link #clear()}
  • {@link #} + *
+ * + * The behavior of this implementation is undefined if you perform the operations for a consumer thread only + * from multiple threads. + * + * The initial implementation is based on: + * + * and adopted padded head node changes from: + * + * data structure modified to avoid false sharing between head and tail Ref as per implementation of MpscLinkedQueue + * on JCTools project. + */ +final class MpscLinkedQueue extends MpscLinkedQueueTailRef implements Queue { + + private static final long serialVersionUID = -1878402552271506449L; + + long p00, p01, p02, p03, p04, p05, p06, p07; + long p30, p31, p32, p33, p34, p35, p36, p37; + + // offer() occurs at the tail of the linked list. + // poll() occurs at the head of the linked list. + // + // Resulting layout is: + // + // head --next--> 1st element --next--> 2nd element --next--> ... tail (last element) + // + // where the head is a dummy node whose value is null. + // + // offer() appends a new node next to the tail using AtomicReference.getAndSet() + // poll() removes head from the linked list and promotes the 1st element to the head, + // setting its value to null if possible. + // + // Also note that this class extends AtomicReference for the "tail" slot (which is the one that is appended to) + // since Unsafe does not expose XCHG operation intrinsically. + MpscLinkedQueue() { + MpscLinkedQueueNode tombstone = new DefaultNode(null); + setHeadRef(tombstone); + setTailRef(tombstone); + } + + /** + * Returns the node right next to the head, which contains the first element of this queue. + */ + private MpscLinkedQueueNode peekNode() { + for (;;) { + final MpscLinkedQueueNode head = headRef(); + final MpscLinkedQueueNode next = head.next(); + if (next != null) { + return next; + } + if (head == tailRef()) { + return null; + } + + // If we are here, it means: + // * offer() is adding the first element, and + // * it's between replaceTail(newTail) and oldTail.setNext(newTail). + // (i.e. next == oldTail and oldTail.next == null and head == oldTail != newTail) + } + } + + @Override + + public boolean offer(E value) { + if (value == null) { + throw new NullPointerException("value"); + } + + final MpscLinkedQueueNode newTail; + if (value instanceof MpscLinkedQueueNode) { + newTail = (MpscLinkedQueueNode) value; + newTail.setNext(null); + } else { + newTail = new DefaultNode(value); + } + + MpscLinkedQueueNode oldTail = getAndSetTailRef(newTail); + oldTail.setNext(newTail); + return true; + } + + @Override + public E poll() { + final MpscLinkedQueueNode next = peekNode(); + if (next == null) { + return null; + } + + // next becomes a new head. + MpscLinkedQueueNode oldHead = headRef(); + // Similar to 'headRef.node = next', but slightly faster (storestore vs loadstore) + // See: http://robsjava.blogspot.com/2013/06/a-faster-volatile.html + // See: http://psy-lob-saw.blogspot.com/2012/12/atomiclazyset-is-performance-win-for.html + lazySetHeadRef(next); + + // Break the linkage between the old head and the new head. + oldHead.unlink(); + + return next.clearMaybe(); + } + + @Override + public E peek() { + final MpscLinkedQueueNode next = peekNode(); + if (next == null) { + return null; + } + return next.value(); + } + + @Override + public int size() { + int count = 0; + MpscLinkedQueueNode n = peekNode(); + for (;;) { + if (n == null) { + break; + } + count ++; + n = n.next(); + } + return count; + } + + @Override + public boolean isEmpty() { + return peekNode() == null; + } + + @Override + public boolean contains(Object o) { + MpscLinkedQueueNode n = peekNode(); + for (;;) { + if (n == null) { + break; + } + if (n.value() == o) { + return true; + } + n = n.next(); + } + return false; + } + + @Override + public Iterator iterator() { + return new Iterator() { + private MpscLinkedQueueNode node = peekNode(); + + @Override + public boolean hasNext() { + return node != null; + } + + @Override + public E next() { + MpscLinkedQueueNode node = this.node; + if (node == null) { + throw new NoSuchElementException(); + } + E value = node.value(); + this.node = node.next(); + return value; + } + + @Override + public void remove() { + throw new UnsupportedOperationException(); + } + }; + } + + @Override + public boolean add(E e) { + if (offer(e)) { + return true; + } + throw new IllegalStateException("queue full"); + } + + @Override + public E remove() { + E e = poll(); + if (e != null) { + return e; + } + throw new NoSuchElementException(); + } + + @Override + public E element() { + E e = peek(); + if (e != null) { + return e; + } + throw new NoSuchElementException(); + } + + @Override + public Object[] toArray() { + final Object[] array = new Object[size()]; + final Iterator it = iterator(); + for (int i = 0; i < array.length; i ++) { + if (it.hasNext()) { + array[i] = it.next(); + } else { + return Arrays.copyOf(array, i); + } + } + return array; + } + + @Override + + public T[] toArray(T[] a) { + final int size = size(); + final T[] array; + if (a.length >= size) { + array = a; + } else { + array = (T[]) Array.newInstance(a.getClass().getComponentType(), size); + } + + final Iterator it = iterator(); + for (int i = 0; i < array.length; i++) { + if (it.hasNext()) { + array[i] = (T) it.next(); + } else { + if (a == array) { + array[i] = null; + return array; + } + + if (a.length < i) { + return Arrays.copyOf(array, i); + } + + System.arraycopy(array, 0, a, 0, i); + if (a.length > i) { + a[i] = null; + } + return a; + } + } + return array; + } + + @Override + public boolean remove(Object o) { + throw new UnsupportedOperationException(); + } + + @Override + public boolean containsAll(Collection c) { + for (Object e: c) { + if (!contains(e)) { + return false; + } + } + return true; + } + + @Override + public boolean addAll(Collection c) { + if (c == null) { + throw new NullPointerException("c"); + } + if (c == this) { + throw new IllegalArgumentException("c == this"); + } + + boolean modified = false; + for (E e: c) { + add(e); + modified = true; + } + return modified; + } + + @Override + public boolean removeAll(Collection c) { + throw new UnsupportedOperationException(); + } + + @Override + public boolean retainAll(Collection c) { + throw new UnsupportedOperationException(); + } + + @Override + public void clear() { + while (poll() != null) { + continue; + } + } + + private void writeObject(ObjectOutputStream out) throws IOException { + out.defaultWriteObject(); + for (E e: this) { + out.writeObject(e); + } + out.writeObject(null); + } + + private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException { + in.defaultReadObject(); + + final MpscLinkedQueueNode tombstone = new DefaultNode(null); + setHeadRef(tombstone); + setTailRef(tombstone); + + for (;;) { + + E e = (E) in.readObject(); + if (e == null) { + break; + } + add(e); + } + } + + private static final class DefaultNode extends MpscLinkedQueueNode { + + private T value; + + DefaultNode(T value) { + this.value = value; + } + + @Override + public T value() { + return value; + } + + @Override + protected T clearMaybe() { + T value = this.value; + this.value = null; + return value; + } + } +} diff --git a/common/src/common/net/util/internal/MpscLinkedQueueHeadRef.java b/common/src/common/net/util/internal/MpscLinkedQueueHeadRef.java new file mode 100644 index 0000000..9b4d089 --- /dev/null +++ b/common/src/common/net/util/internal/MpscLinkedQueueHeadRef.java @@ -0,0 +1,54 @@ +/* + * Copyright 2014 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ + +package common.net.util.internal; + +import java.io.Serializable; +import java.util.concurrent.atomic.AtomicReferenceFieldUpdater; + + +abstract class MpscLinkedQueueHeadRef extends MpscLinkedQueuePad0 implements Serializable { + + private static final long serialVersionUID = 8467054865577874285L; + + + private static final AtomicReferenceFieldUpdater UPDATER; + + static { + + AtomicReferenceFieldUpdater updater; + updater = PlatformDependent.newAtomicReferenceFieldUpdater(MpscLinkedQueueHeadRef.class, "headRef"); + if (updater == null) { + updater = AtomicReferenceFieldUpdater.newUpdater( + MpscLinkedQueueHeadRef.class, MpscLinkedQueueNode.class, "headRef"); + } + UPDATER = updater; + } + + private transient volatile MpscLinkedQueueNode headRef; + + protected final MpscLinkedQueueNode headRef() { + return headRef; + } + + protected final void setHeadRef(MpscLinkedQueueNode headRef) { + this.headRef = headRef; + } + + protected final void lazySetHeadRef(MpscLinkedQueueNode headRef) { + UPDATER.lazySet(this, headRef); + } +} diff --git a/common/src/common/net/util/internal/MpscLinkedQueueNode.java b/common/src/common/net/util/internal/MpscLinkedQueueNode.java new file mode 100644 index 0000000..1c3f007 --- /dev/null +++ b/common/src/common/net/util/internal/MpscLinkedQueueNode.java @@ -0,0 +1,65 @@ +/* + * Copyright 2014 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ + +package common.net.util.internal; + +import java.util.concurrent.atomic.AtomicReferenceFieldUpdater; + +public abstract class MpscLinkedQueueNode { + + + private static final AtomicReferenceFieldUpdater nextUpdater; + + static { + + AtomicReferenceFieldUpdater u; + + u = PlatformDependent.newAtomicReferenceFieldUpdater(MpscLinkedQueueNode.class, "next"); + if (u == null) { + u = AtomicReferenceFieldUpdater.newUpdater(MpscLinkedQueueNode.class, MpscLinkedQueueNode.class, "next"); + } + nextUpdater = u; + } + + + private volatile MpscLinkedQueueNode next; + + final MpscLinkedQueueNode next() { + return next; + } + + final void setNext(final MpscLinkedQueueNode newNext) { + // Similar to 'next = newNext', but slightly faster (storestore vs loadstore) + // See: http://robsjava.blogspot.com/2013/06/a-faster-volatile.html + nextUpdater.lazySet(this, newNext); + } + + public abstract T value(); + + /** + * Sets the element this node contains to {@code null} so that the node can be used as a tombstone. + */ + protected T clearMaybe() { + return value(); + } + + /** + * Unlink to allow GC'ed + */ + void unlink() { + setNext(null); + } +} diff --git a/common/src/common/net/util/internal/MpscLinkedQueuePad0.java b/common/src/common/net/util/internal/MpscLinkedQueuePad0.java new file mode 100644 index 0000000..0fe9e45 --- /dev/null +++ b/common/src/common/net/util/internal/MpscLinkedQueuePad0.java @@ -0,0 +1,22 @@ +/* + * Copyright 2014 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ + +package common.net.util.internal; + +abstract class MpscLinkedQueuePad0 { + long p00, p01, p02, p03, p04, p05, p06, p07; + long p30, p31, p32, p33, p34, p35, p36, p37; +} diff --git a/common/src/common/net/util/internal/MpscLinkedQueuePad1.java b/common/src/common/net/util/internal/MpscLinkedQueuePad1.java new file mode 100644 index 0000000..6cfd53f --- /dev/null +++ b/common/src/common/net/util/internal/MpscLinkedQueuePad1.java @@ -0,0 +1,25 @@ +/* + * Copyright 2014 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ + +package common.net.util.internal; + +abstract class MpscLinkedQueuePad1 extends MpscLinkedQueueHeadRef { + + private static final long serialVersionUID = 2886694927079691637L; + + long p00, p01, p02, p03, p04, p05, p06, p07; + long p30, p31, p32, p33, p34, p35, p36, p37; +} diff --git a/common/src/common/net/util/internal/MpscLinkedQueueTailRef.java b/common/src/common/net/util/internal/MpscLinkedQueueTailRef.java new file mode 100644 index 0000000..fa2a36c --- /dev/null +++ b/common/src/common/net/util/internal/MpscLinkedQueueTailRef.java @@ -0,0 +1,54 @@ +/* + * Copyright 2014 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ + +package common.net.util.internal; + +import java.util.concurrent.atomic.AtomicReferenceFieldUpdater; + +abstract class MpscLinkedQueueTailRef extends MpscLinkedQueuePad1 { + + private static final long serialVersionUID = 8717072462993327429L; + + + private static final AtomicReferenceFieldUpdater UPDATER; + + static { + + AtomicReferenceFieldUpdater updater; + updater = PlatformDependent.newAtomicReferenceFieldUpdater(MpscLinkedQueueTailRef.class, "tailRef"); + if (updater == null) { + updater = AtomicReferenceFieldUpdater.newUpdater( + MpscLinkedQueueTailRef.class, MpscLinkedQueueNode.class, "tailRef"); + } + UPDATER = updater; + } + + private transient volatile MpscLinkedQueueNode tailRef; + + protected final MpscLinkedQueueNode tailRef() { + return tailRef; + } + + protected final void setTailRef(MpscLinkedQueueNode tailRef) { + this.tailRef = tailRef; + } + + + protected final MpscLinkedQueueNode getAndSetTailRef(MpscLinkedQueueNode tailRef) { + // LOCK XCHG in JDK8, a CAS loop in JDK 7/6 + return (MpscLinkedQueueNode) UPDATER.getAndSet(this, tailRef); + } +} diff --git a/common/src/common/net/util/internal/NoOpTypeParameterMatcher.java b/common/src/common/net/util/internal/NoOpTypeParameterMatcher.java new file mode 100644 index 0000000..fe4d34f --- /dev/null +++ b/common/src/common/net/util/internal/NoOpTypeParameterMatcher.java @@ -0,0 +1,24 @@ +/* + * Copyright 2013 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ + +package common.net.util.internal; + +public final class NoOpTypeParameterMatcher extends TypeParameterMatcher { + @Override + public boolean match(Object msg) { + return true; + } +} diff --git a/common/src/common/net/util/internal/OneTimeTask.java b/common/src/common/net/util/internal/OneTimeTask.java new file mode 100644 index 0000000..7fdb8ae --- /dev/null +++ b/common/src/common/net/util/internal/OneTimeTask.java @@ -0,0 +1,30 @@ +/* + * Copyright 2014 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ +package common.net.util.internal; + +/** + * {@link Runnable} which represent a one time task which may allow the {@link EventExecutor} to reduce the amount of + * produced garbage when queue it for execution. + * + * It is important this will not be reused. After submitted it is not allowed to get submitted again! + */ +public abstract class OneTimeTask extends MpscLinkedQueueNode implements Runnable { + + @Override + public Runnable value() { + return this; + } +} diff --git a/common/src/common/net/util/internal/PlatformDependent.java b/common/src/common/net/util/internal/PlatformDependent.java new file mode 100644 index 0000000..70db87e --- /dev/null +++ b/common/src/common/net/util/internal/PlatformDependent.java @@ -0,0 +1,844 @@ +/* + * Copyright 2012 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ +package common.net.util.internal; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.net.InetSocketAddress; +import java.net.ServerSocket; +import java.nio.ByteBuffer; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.Queue; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; +import java.util.concurrent.atomic.AtomicIntegerFieldUpdater; +import java.util.concurrent.atomic.AtomicLongFieldUpdater; +import java.util.concurrent.atomic.AtomicReferenceFieldUpdater; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import common.net.util.CharsetUtil; +import common.net.util.internal.logging.InternalLogger; +import common.net.util.internal.logging.InternalLoggerFactory; + + +/** + * Utility that detects various properties specific to the current runtime + * environment, such as Java version and the availability of the + * {@code sun.misc.Unsafe} object. + *

+ * You can disable the use of {@code sun.misc.Unsafe} if you specify + * the system property game.net.noUnsafe. + */ +public final class PlatformDependent { + + private static final InternalLogger logger = InternalLoggerFactory.getInstance(PlatformDependent.class); + + private static final Pattern MAX_DIRECT_MEMORY_SIZE_ARG_PATTERN = Pattern.compile( + "\\s*-XX:MaxDirectMemorySize\\s*=\\s*([0-9]+)\\s*([kKmMgG]?)\\s*$"); + + private static final boolean IS_ANDROID = isAndroid0(); + private static final boolean IS_WINDOWS = isWindows0(); + private static final boolean IS_ROOT = isRoot0(); + + private static final int JAVA_VERSION = javaVersion0(); + + private static final boolean CAN_ENABLE_TCP_NODELAY_BY_DEFAULT = !isAndroid(); + + private static final boolean HAS_UNSAFE = hasUnsafe0(); +// private static final boolean CAN_USE_CHM_V8 = HAS_UNSAFE && JAVA_VERSION < 8; + private static final boolean DIRECT_BUFFER_PREFERRED = + HAS_UNSAFE && !SystemPropertyUtil.getBoolean("game.net.noPreferDirect", false); + private static final long MAX_DIRECT_MEMORY = maxDirectMemory0(); + + private static final long ARRAY_BASE_OFFSET = arrayBaseOffset0(); + +// private static final boolean HAS_JAVASSIST = hasJavassist0(); + +// private static final File TMPDIR = tmpdir0(); +// +// private static final int BIT_MODE = bitMode0(); +// +// private static final int ADDRESS_SIZE = addressSize0(); + + static { + if (logger.isDebugEnabled()) { + logger.debug("-Dgame.net.noPreferDirect: {}", !DIRECT_BUFFER_PREFERRED); + } + + if (!hasUnsafe() && !isAndroid()) { + logger.info( + "Your platform does not provide complete low-level API for accessing direct buffers reliably. " + + "Unless explicitly requested, heap buffer will always be preferred to avoid potential system " + + "unstability."); + } + } + + /** + * Returns {@code true} if and only if the current platform is Android + */ + public static boolean isAndroid() { + return IS_ANDROID; + } + + /** + * Return {@code true} if the JVM is running on Windows + */ + public static boolean isWindows() { + return IS_WINDOWS; + } + + /** + * Return {@code true} if the current user is root. Note that this method returns + * {@code false} if on Windows. + */ + public static boolean isRoot() { + return IS_ROOT; + } + + /** + * Return the version of Java under which this library is used. + */ + public static int javaVersion() { + return JAVA_VERSION; + } + + /** + * Returns {@code true} if and only if it is fine to enable TCP_NODELAY socket option by default. + */ + public static boolean canEnableTcpNoDelayByDefault() { + return CAN_ENABLE_TCP_NODELAY_BY_DEFAULT; + } + + /** + * Return {@code true} if {@code sun.misc.Unsafe} was found on the classpath and can be used for acclerated + * direct memory access. + */ + public static boolean hasUnsafe() { + return HAS_UNSAFE; + } + + /** + * Returns {@code true} if the platform has reliable low-level direct buffer access API and a user specified + * {@code -Dgame.net.preferDirect} option. + */ + public static boolean directBufferPreferred() { + return DIRECT_BUFFER_PREFERRED; + } + + /** + * Returns the maximum memory reserved for direct buffer allocation. + */ + public static long maxDirectMemory() { + return MAX_DIRECT_MEMORY; + } + + /** + * Returns {@code true} if and only if Javassist is available. + */ +// public static boolean hasJavassist() { +// return HAS_JAVASSIST; +// } + + /** + * Returns the temporary directory. + */ +// public static File tmpdir() { +// return TMPDIR; +// } + + /** + * Returns the bit mode of the current VM (usually 32 or 64.) + */ +// public static int bitMode() { +// return BIT_MODE; +// } + + /** + * Return the address size of the OS. + * 4 (for 32 bits systems ) and 8 (for 64 bits systems). + */ +// public static int addressSize() { +// return ADDRESS_SIZE; +// } + +// public static long allocateMemory(long size) { +// return PlatformDependent0.allocateMemory(size); +// } + +// public static void freeMemory(long address) { +// PlatformDependent0.freeMemory(address); +// } + + /** + * Raises an exception bypassing compiler checks for checked exceptions. + */ + public static void throwException(Throwable t) { + if (hasUnsafe()) { + PlatformDependent0.throwException(t); + } else { + PlatformDependent.throwException0(t); + } + } + + + private static void throwException0(Throwable t) throws E { + throw (E) t; + } + + /** + * Creates a new fastest {@link ConcurrentMap} implementaion for the current platform. + */ + public static ConcurrentMap newConcurrentHashMap() { +// if (CAN_USE_CHM_V8) { +// return new ConcurrentHashMapV8(); +// } else { + return new ConcurrentHashMap(); +// } + } + + /** + * Creates a new fastest {@link ConcurrentMap} implementaion for the current platform. + */ + public static ConcurrentMap newConcurrentHashMap(int initialCapacity) { +// if (CAN_USE_CHM_V8) { +// return new ConcurrentHashMapV8(initialCapacity); +// } else { + return new ConcurrentHashMap(initialCapacity); +// } + } + + /** + * Creates a new fastest {@link ConcurrentMap} implementaion for the current platform. + */ + public static ConcurrentMap newConcurrentHashMap(int initialCapacity, float loadFactor) { +// if (CAN_USE_CHM_V8) { +// return new ConcurrentHashMapV8(initialCapacity, loadFactor); +// } else { + return new ConcurrentHashMap(initialCapacity, loadFactor); +// } + } + + /** + * Creates a new fastest {@link ConcurrentMap} implementaion for the current platform. + */ + public static ConcurrentMap newConcurrentHashMap( + int initialCapacity, float loadFactor, int concurrencyLevel) { +// if (CAN_USE_CHM_V8) { +// return new ConcurrentHashMapV8(initialCapacity, loadFactor, concurrencyLevel); +// } else { + return new ConcurrentHashMap(initialCapacity, loadFactor, concurrencyLevel); +// } + } + + /** + * Creates a new fastest {@link ConcurrentMap} implementaion for the current platform. + */ + public static ConcurrentMap newConcurrentHashMap(Map map) { +// if (CAN_USE_CHM_V8) { +// return new ConcurrentHashMapV8(map); +// } else { + return new ConcurrentHashMap(map); +// } + } + + /** + * Try to deallocate the specified direct {@link ByteBuffer}. Please note this method does nothing if + * the current platform does not support this operation or the specified buffer is not a direct buffer. + */ + public static void freeDirectBuffer(ByteBuffer buffer) { + if (hasUnsafe() && !isAndroid()) { + // only direct to method if we are not running on android. + // See https://github.com/netty/netty/issues/2604 + PlatformDependent0.freeDirectBuffer(buffer); + } + } + + public static long directBufferAddress(ByteBuffer buffer) { + return PlatformDependent0.directBufferAddress(buffer); + } + + public static Object getObject(Object object, long fieldOffset) { + return PlatformDependent0.getObject(object, fieldOffset); + } + + public static Object getObjectVolatile(Object object, long fieldOffset) { + return PlatformDependent0.getObjectVolatile(object, fieldOffset); + } + + public static int getInt(Object object, long fieldOffset) { + return PlatformDependent0.getInt(object, fieldOffset); + } + + public static long objectFieldOffset(Field field) { + return PlatformDependent0.objectFieldOffset(field); + } + + public static byte getByte(long address) { + return PlatformDependent0.getByte(address); + } + + public static short getShort(long address) { + return PlatformDependent0.getShort(address); + } + + public static int getInt(long address) { + return PlatformDependent0.getInt(address); + } + + public static long getLong(long address) { + return PlatformDependent0.getLong(address); + } + + public static void putOrderedObject(Object object, long address, Object value) { + PlatformDependent0.putOrderedObject(object, address, value); + } + + public static void putByte(long address, byte value) { + PlatformDependent0.putByte(address, value); + } + + public static void putShort(long address, short value) { + PlatformDependent0.putShort(address, value); + } + + public static void putInt(long address, int value) { + PlatformDependent0.putInt(address, value); + } + + public static void putLong(long address, long value) { + PlatformDependent0.putLong(address, value); + } + + public static void copyMemory(long srcAddr, long dstAddr, long length) { + PlatformDependent0.copyMemory(srcAddr, dstAddr, length); + } + + public static void copyMemory(byte[] src, int srcIndex, long dstAddr, long length) { + PlatformDependent0.copyMemory(src, ARRAY_BASE_OFFSET + srcIndex, null, dstAddr, length); + } + + public static void copyMemory(long srcAddr, byte[] dst, int dstIndex, long length) { + PlatformDependent0.copyMemory(null, srcAddr, dst, ARRAY_BASE_OFFSET + dstIndex, length); + } + + /** + * Create a new optimized {@link AtomicReferenceFieldUpdater} or {@code null} if it + * could not be created. Because of this the caller need to check for {@code null} and if {@code null} is returned + * use {@link AtomicReferenceFieldUpdater#newUpdater(Class, Class, String)} as fallback. + */ + public static AtomicReferenceFieldUpdater newAtomicReferenceFieldUpdater( + Class tclass, String fieldName) { + if (hasUnsafe()) { + try { + return PlatformDependent0.newAtomicReferenceFieldUpdater(tclass, fieldName); + } catch (Throwable ignore) { + // ignore + } + } + return null; + } + + /** + * Create a new optimized {@link AtomicIntegerFieldUpdater} or {@code null} if it + * could not be created. Because of this the caller need to check for {@code null} and if {@code null} is returned + * use {@link AtomicIntegerFieldUpdater#newUpdater(Class, String)} as fallback. + */ + public static AtomicIntegerFieldUpdater newAtomicIntegerFieldUpdater( + Class tclass, String fieldName) { + if (hasUnsafe()) { + try { + return PlatformDependent0.newAtomicIntegerFieldUpdater(tclass, fieldName); + } catch (Throwable ignore) { + // ignore + } + } + return null; + } + + /** + * Create a new optimized {@link AtomicLongFieldUpdater} or {@code null} if it + * could not be created. Because of this the caller need to check for {@code null} and if {@code null} is returned + * use {@link AtomicLongFieldUpdater#newUpdater(Class, String)} as fallback. + */ + public static AtomicLongFieldUpdater newAtomicLongFieldUpdater( + Class tclass, String fieldName) { + if (hasUnsafe()) { + try { + return PlatformDependent0.newAtomicLongFieldUpdater(tclass, fieldName); + } catch (Throwable ignore) { + // ignore + } + } + return null; + } + + /** + * Create a new {@link Queue} which is safe to use for multiple producers (different threads) and a single + * consumer (one thread!). + */ + public static Queue newMpscQueue() { + return new MpscLinkedQueue(); + } + + /** + * Return the {@link ClassLoader} for the given {@link Class}. + */ + public static ClassLoader getClassLoader(final Class clazz) { + return PlatformDependent0.getClassLoader(clazz); + } + + /** + * Return the context {@link ClassLoader} for the current {@link Thread}. + */ + public static ClassLoader getContextClassLoader() { + return PlatformDependent0.getContextClassLoader(); + } + + /** + * Return the system {@link ClassLoader}. + */ + public static ClassLoader getSystemClassLoader() { + return PlatformDependent0.getSystemClassLoader(); + } + + private static boolean isAndroid0() { + boolean android; + try { + Class.forName("android.app.Application", false, getSystemClassLoader()); + android = true; + } catch (Exception e) { + // Failed to load the class uniquely available in Android. + android = false; + } + + if (android) { + logger.debug("Platform: Android"); + } + return android; + } + + private static boolean isWindows0() { + boolean windows = SystemPropertyUtil.get("os.name", "").toLowerCase(Locale.US).contains("win"); + if (windows) { + logger.debug("Platform: Windows"); + } + return windows; + } + + private static boolean isRoot0() { + if (isWindows()) { + return false; + } + + String[] ID_COMMANDS = { "/usr/bin/id", "/bin/id", "id", "/usr/xpg4/bin/id"}; + Pattern UID_PATTERN = Pattern.compile("^(?:0|[1-9][0-9]*)$"); + for (String idCmd: ID_COMMANDS) { + Process p = null; + BufferedReader in = null; + String uid = null; + try { + p = Runtime.getRuntime().exec(new String[] { idCmd, "-u" }); + in = new BufferedReader(new InputStreamReader(p.getInputStream(), CharsetUtil.US_ASCII)); + uid = in.readLine(); + in.close(); + + for (;;) { + try { + int exitCode = p.waitFor(); + if (exitCode != 0) { + uid = null; + } + break; + } catch (InterruptedException e) { + // Ignore + } + } + } catch (Exception e) { + // Failed to run the command. + uid = null; + } finally { + if (in != null) { + try { + in.close(); + } catch (IOException e) { + // Ignore + } + } + if (p != null) { + try { + p.destroy(); + } catch (Exception e) { + // Android sometimes triggers an ErrnoException. + } + } + } + + if (uid != null && UID_PATTERN.matcher(uid).matches()) { + logger.debug("UID: {}", uid); + return "0".equals(uid); + } + } + + logger.debug("Could not determine the current UID using /usr/bin/id; attempting to bind at privileged ports."); + + Pattern PERMISSION_DENIED = Pattern.compile(".*(?:denied|not.*permitted).*"); + for (int i = 1023; i > 0; i --) { + ServerSocket ss = null; + try { + ss = new ServerSocket(); + ss.setReuseAddress(true); + ss.bind(new InetSocketAddress(i)); + if (logger.isDebugEnabled()) { + logger.debug("UID: 0 (succeded to bind at port {})", i); + } + return true; + } catch (Exception e) { + // Failed to bind. + // Check the error message so that we don't always need to bind 1023 times. + String message = e.getMessage(); + if (message == null) { + message = ""; + } + message = message.toLowerCase(); + if (PERMISSION_DENIED.matcher(message).matches()) { + break; + } + } finally { + if (ss != null) { + try { + ss.close(); + } catch (Exception e) { + // Ignore. + } + } + } + } + + logger.debug("UID: non-root (failed to bind at any privileged ports)"); + return false; + } + + + private static int javaVersion0() { + int javaVersion; + + // Not really a loop + for (;;) { + // Android + if (isAndroid()) { + javaVersion = 6; + break; + } + + try { + Class.forName("java.time.Clock", false, getClassLoader(Object.class)); + javaVersion = 8; + break; + } catch (Exception e) { + // Ignore + } + + try { + Class.forName("java.util.concurrent.LinkedTransferQueue", false, getClassLoader(BlockingQueue.class)); + javaVersion = 7; + break; + } catch (Exception e) { + // Ignore + } + + javaVersion = 6; + break; + } + + if (logger.isDebugEnabled()) { + logger.debug("Java version: {}", javaVersion); + } + return javaVersion; + } + + private static boolean hasUnsafe0() { + boolean noUnsafe = SystemPropertyUtil.getBoolean("game.net.noUnsafe", false); + logger.debug("-Dgame.net.noUnsafe: {}", noUnsafe); + + if (isAndroid()) { + logger.debug("sun.misc.Unsafe: unavailable (Android)"); + return false; + } + + if (noUnsafe) { + logger.debug("sun.misc.Unsafe: unavailable (game.net.noUnsafe)"); + return false; + } + + // Legacy properties + boolean tryUnsafe; + if (SystemPropertyUtil.contains("game.net.tryUnsafe")) { + tryUnsafe = SystemPropertyUtil.getBoolean("game.net.tryUnsafe", true); + } else { + tryUnsafe = SystemPropertyUtil.getBoolean("org.jboss.netty.tryUnsafe", true); + } + + if (!tryUnsafe) { + logger.debug("sun.misc.Unsafe: unavailable (game.net.tryUnsafe/org.jboss.netty.tryUnsafe)"); + return false; + } + + try { + boolean hasUnsafe = PlatformDependent0.hasUnsafe(); + logger.debug("sun.misc.Unsafe: {}", hasUnsafe ? "available" : "unavailable"); + return hasUnsafe; + } catch (Throwable t) { + // Probably failed to initialize PlatformDependent0. + return false; + } + } + + private static long arrayBaseOffset0() { + if (!hasUnsafe()) { + return -1; + } + + return PlatformDependent0.arrayBaseOffset(); + } + + private static long maxDirectMemory0() { + long maxDirectMemory = 0; + try { + // Try to get from sun.misc.VM.maxDirectMemory() which should be most accurate. + Class vmClass = Class.forName("sun.misc.VM", true, getSystemClassLoader()); + Method m = vmClass.getDeclaredMethod("maxDirectMemory"); + maxDirectMemory = ((Number) m.invoke(null)).longValue(); + } catch (Throwable t) { + // Ignore + } + + if (maxDirectMemory > 0) { + return maxDirectMemory; + } + + try { + // Now try to get the JVM option (-XX:MaxDirectMemorySize) and parse it. + // Note that we are using reflection because Android doesn't have these classes. + Class mgmtFactoryClass = Class.forName( + "java.lang.management.ManagementFactory", true, getSystemClassLoader()); + Class runtimeClass = Class.forName( + "java.lang.management.RuntimeMXBean", true, getSystemClassLoader()); + + Object runtime = mgmtFactoryClass.getDeclaredMethod("getRuntimeMXBean").invoke(null); + + + List vmArgs = (List) runtimeClass.getDeclaredMethod("getInputArguments").invoke(runtime); + for (int i = vmArgs.size() - 1; i >= 0; i --) { + Matcher m = MAX_DIRECT_MEMORY_SIZE_ARG_PATTERN.matcher(vmArgs.get(i)); + if (!m.matches()) { + continue; + } + + maxDirectMemory = Long.parseLong(m.group(1)); + switch (m.group(2).charAt(0)) { + case 'k': case 'K': + maxDirectMemory *= 1024; + break; + case 'm': case 'M': + maxDirectMemory *= 1024 * 1024; + break; + case 'g': case 'G': + maxDirectMemory *= 1024 * 1024 * 1024; + break; + } + break; + } + } catch (Throwable t) { + // Ignore + } + + if (maxDirectMemory <= 0) { + maxDirectMemory = Runtime.getRuntime().maxMemory(); + logger.debug("maxDirectMemory: {} bytes (maybe)", maxDirectMemory); + } else { + logger.debug("maxDirectMemory: {} bytes", maxDirectMemory); + } + + return maxDirectMemory; + } + +// private static boolean hasJavassist0() { +// if (isAndroid()) { +// return false; +// } +// +// boolean noJavassist = SystemPropertyUtil.getBoolean("game.net.noJavassist", false); +// logger.debug("-Dgame.net.noJavassist: {}", noJavassist); +// +// if (noJavassist) { +// logger.debug("Javassist: unavailable (game.net.noJavassist)"); +// return false; +// } +// +// try { +// JavassistTypeParameterMatcherGenerator.generate(Object.class, getClassLoader(PlatformDependent.class)); +// logger.debug("Javassist: available"); +// return true; +// } catch (Throwable t) { +// // Failed to generate a Javassist-based matcher. +// logger.debug("Javassist: unavailable"); +// logger.debug( +// "You don't have Javassist in your class path or you don't have enough permission " + +// "to load dynamically generated classes. Please check the configuration for better performance."); +// return false; +// } +// } + +// private static File tmpdir0() { +// File f; +// try { +// f = toDirectory(SystemPropertyUtil.get("game.net.tmpdir")); +// if (f != null) { +// logger.debug("-Dgame.net.tmpdir: {}", f); +// return f; +// } +// +// f = toDirectory(SystemPropertyUtil.get("java.io.tmpdir")); +// if (f != null) { +// logger.debug("-Dgame.net.tmpdir: {} (java.io.tmpdir)", f); +// return f; +// } +// +// // This shouldn't happen, but just in case .. +// if (isWindows()) { +// f = toDirectory(System.getenv("TEMP")); +// if (f != null) { +// logger.debug("-Dgame.net.tmpdir: {} (%TEMP%)", f); +// return f; +// } +// +// String userprofile = System.getenv("USERPROFILE"); +// if (userprofile != null) { +// f = toDirectory(userprofile + "\\AppData\\Local\\Temp"); +// if (f != null) { +// logger.debug("-Dgame.net.tmpdir: {} (%USERPROFILE%\\AppData\\Local\\Temp)", f); +// return f; +// } +// +// f = toDirectory(userprofile + "\\Local Settings\\Temp"); +// if (f != null) { +// logger.debug("-Dgame.net.tmpdir: {} (%USERPROFILE%\\Local Settings\\Temp)", f); +// return f; +// } +// } +// } else { +// f = toDirectory(System.getenv("TMPDIR")); +// if (f != null) { +// logger.debug("-Dgame.net.tmpdir: {} ($TMPDIR)", f); +// return f; +// } +// } +// } catch (Exception ignored) { +// // Environment variable inaccessible +// } +// +// // Last resort. +// if (isWindows()) { +// f = new File("C:\\Windows\\Temp"); +// } else { +// f = new File("/tmp"); +// } +// +// logger.warn("Failed to get the temporary directory; falling back to: {}", f); +// return f; +// } +// +// +// private static File toDirectory(String path) { +// if (path == null) { +// return null; +// } +// +// File f = new File(path); +// f.mkdirs(); +// +// if (!f.isDirectory()) { +// return null; +// } +// +// try { +// return f.getAbsoluteFile(); +// } catch (Exception ignored) { +// return f; +// } +// } + +// private static int bitMode0() { +// // Check user-specified bit mode first. +// int bitMode = SystemPropertyUtil.getInt("game.net.bitMode", 0); +// if (bitMode > 0) { +// logger.debug("-Dgame.net.bitMode: {}", bitMode); +// return bitMode; +// } +// +// // And then the vendor specific ones which is probably most reliable. +// bitMode = SystemPropertyUtil.getInt("sun.arch.data.model", 0); +// if (bitMode > 0) { +// logger.debug("-Dgame.net.bitMode: {} (sun.arch.data.model)", bitMode); +// return bitMode; +// } +// bitMode = SystemPropertyUtil.getInt("com.ibm.vm.bitmode", 0); +// if (bitMode > 0) { +// logger.debug("-Dgame.net.bitMode: {} (com.ibm.vm.bitmode)", bitMode); +// return bitMode; +// } +// +// // os.arch also gives us a good hint. +// String arch = SystemPropertyUtil.get("os.arch", "").toLowerCase(Locale.US).trim(); +// if ("amd64".equals(arch) || "x86_64".equals(arch)) { +// bitMode = 64; +// } else if ("i386".equals(arch) || "i486".equals(arch) || "i586".equals(arch) || "i686".equals(arch)) { +// bitMode = 32; +// } +// +// if (bitMode > 0) { +// logger.debug("-Dgame.net.bitMode: {} (os.arch: {})", bitMode, arch); +// } +// +// // Last resort: guess from VM name and then fall back to most common 64-bit mode. +// String vm = SystemPropertyUtil.get("java.vm.name", "").toLowerCase(Locale.US); +// Pattern BIT_PATTERN = Pattern.compile("([1-9][0-9]+)-?bit"); +// Matcher m = BIT_PATTERN.matcher(vm); +// if (m.find()) { +// return Integer.parseInt(m.group(1)); +// } else { +// return 64; +// } +// } + +// private static int addressSize0() { +// if (!hasUnsafe()) { +// return -1; +// } +// return PlatformDependent0.addressSize(); +// } + + private PlatformDependent() { + // only static method supported + } +} diff --git a/common/src/common/net/util/internal/PlatformDependent0.java b/common/src/common/net/util/internal/PlatformDependent0.java new file mode 100644 index 0000000..ce3c3cc --- /dev/null +++ b/common/src/common/net/util/internal/PlatformDependent0.java @@ -0,0 +1,383 @@ +/* + * Copyright 2013 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ +package common.net.util.internal; + +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.nio.Buffer; +import java.nio.ByteBuffer; +import java.nio.ByteOrder; +import java.security.AccessController; +import java.security.PrivilegedAction; +import java.util.concurrent.atomic.AtomicIntegerFieldUpdater; +import java.util.concurrent.atomic.AtomicLongFieldUpdater; +import java.util.concurrent.atomic.AtomicReferenceFieldUpdater; + +import common.net.util.internal.logging.InternalLogger; +import common.net.util.internal.logging.InternalLoggerFactory; +import sun.misc.Unsafe; + +/** + * The {@link PlatformDependent} operations which requires access to {@code sun.misc.*}. + */ +final class PlatformDependent0 { + + private static final InternalLogger logger = InternalLoggerFactory.getInstance(PlatformDependent0.class); + private static final Unsafe UNSAFE; + private static final boolean BIG_ENDIAN = ByteOrder.nativeOrder() == ByteOrder.BIG_ENDIAN; + private static final long ADDRESS_FIELD_OFFSET; + + /** + * Limits the number of bytes to copy per {@link Unsafe#copyMemory(long, long, long)} to allow safepoint polling + * during a large copy. + */ + private static final long UNSAFE_COPY_THRESHOLD = 1024L * 1024L; + + /** + * {@code true} if and only if the platform supports unaligned access. + * + * @see Wikipedia on segfault + */ + private static final boolean UNALIGNED; + + static { + ByteBuffer direct = ByteBuffer.allocateDirect(1); + Field addressField; + try { + addressField = Buffer.class.getDeclaredField("address"); + addressField.setAccessible(true); + if (addressField.getLong(ByteBuffer.allocate(1)) != 0) { + // A heap buffer must have 0 address. + addressField = null; + } else { + if (addressField.getLong(direct) == 0) { + // A direct buffer must have non-zero address. + addressField = null; + } + } + } catch (Throwable t) { + // Failed to access the address field. + addressField = null; + } + logger.debug("java.nio.Buffer.address: {}", addressField != null? "available" : "unavailable"); + + Unsafe unsafe; + if (addressField != null) { + try { + Field unsafeField = Unsafe.class.getDeclaredField("theUnsafe"); + unsafeField.setAccessible(true); + unsafe = (Unsafe) unsafeField.get(null); + logger.debug("sun.misc.Unsafe.theUnsafe: {}", unsafe != null ? "available" : "unavailable"); + + // Ensure the unsafe supports all necessary methods to work around the mistake in the latest OpenJDK. + // https://github.com/netty/netty/issues/1061 + // http://www.mail-archive.com/jdk6-dev@openjdk.java.net/msg00698.html + try { + if (unsafe != null) { + unsafe.getClass().getDeclaredMethod( + "copyMemory", Object.class, long.class, Object.class, long.class, long.class); + logger.debug("sun.misc.Unsafe.copyMemory: available"); + } + } catch (NoSuchMethodError t) { + logger.debug("sun.misc.Unsafe.copyMemory: unavailable"); + throw t; + } catch (NoSuchMethodException e) { + logger.debug("sun.misc.Unsafe.copyMemory: unavailable"); + throw e; + } + } catch (Throwable cause) { + // Unsafe.copyMemory(Object, long, Object, long, long) unavailable. + unsafe = null; + } + } else { + // If we cannot access the address of a direct buffer, there's no point of using unsafe. + // Let's just pretend unsafe is unavailable for overall simplicity. + unsafe = null; + } + + UNSAFE = unsafe; + + if (unsafe == null) { + ADDRESS_FIELD_OFFSET = -1; + UNALIGNED = false; + } else { + ADDRESS_FIELD_OFFSET = objectFieldOffset(addressField); + boolean unaligned; + try { + Class bitsClass = Class.forName("java.nio.Bits", false, ClassLoader.getSystemClassLoader()); + Method unalignedMethod = bitsClass.getDeclaredMethod("unaligned"); + unalignedMethod.setAccessible(true); + unaligned = Boolean.TRUE.equals(unalignedMethod.invoke(null)); + } catch (Throwable t) { + // We at least know x86 and x64 support unaligned access. + String arch = SystemPropertyUtil.get("os.arch", ""); + //noinspection DynamicRegexReplaceableByCompiledPattern + unaligned = arch.matches("^(i[3-6]86|x86(_64)?|x64|amd64)$"); + } + + UNALIGNED = unaligned; + logger.debug("java.nio.Bits.unaligned: {}", UNALIGNED); + } + } + + static boolean hasUnsafe() { + return UNSAFE != null; + } + + static void throwException(Throwable t) { + UNSAFE.throwException(t); + } + + static void freeDirectBuffer(ByteBuffer buffer) { + // Delegate to other class to not break on android + // See https://github.com/netty/netty/issues/2604 + Cleaner0.freeDirectBuffer(buffer); + } + + static long directBufferAddress(ByteBuffer buffer) { + return getLong(buffer, ADDRESS_FIELD_OFFSET); + } + + static long arrayBaseOffset() { + return UNSAFE.arrayBaseOffset(byte[].class); + } + + static Object getObject(Object object, long fieldOffset) { + return UNSAFE.getObject(object, fieldOffset); + } + + static Object getObjectVolatile(Object object, long fieldOffset) { + return UNSAFE.getObjectVolatile(object, fieldOffset); + } + + static int getInt(Object object, long fieldOffset) { + return UNSAFE.getInt(object, fieldOffset); + } + + private static long getLong(Object object, long fieldOffset) { + return UNSAFE.getLong(object, fieldOffset); + } + + static long objectFieldOffset(Field field) { + return UNSAFE.objectFieldOffset(field); + } + + static byte getByte(long address) { + return UNSAFE.getByte(address); + } + + static short getShort(long address) { + if (UNALIGNED) { + return UNSAFE.getShort(address); + } else if (BIG_ENDIAN) { + return (short) (getByte(address) << 8 | getByte(address + 1) & 0xff); + } else { + return (short) (getByte(address + 1) << 8 | getByte(address) & 0xff); + } + } + + static int getInt(long address) { + if (UNALIGNED) { + return UNSAFE.getInt(address); + } else if (BIG_ENDIAN) { + return getByte(address) << 24 | + (getByte(address + 1) & 0xff) << 16 | + (getByte(address + 2) & 0xff) << 8 | + getByte(address + 3) & 0xff; + } else { + return getByte(address + 3) << 24 | + (getByte(address + 2) & 0xff) << 16 | + (getByte(address + 1) & 0xff) << 8 | + getByte(address) & 0xff; + } + } + + static long getLong(long address) { + if (UNALIGNED) { + return UNSAFE.getLong(address); + } else if (BIG_ENDIAN) { + return (long) getByte(address) << 56 | + ((long) getByte(address + 1) & 0xff) << 48 | + ((long) getByte(address + 2) & 0xff) << 40 | + ((long) getByte(address + 3) & 0xff) << 32 | + ((long) getByte(address + 4) & 0xff) << 24 | + ((long) getByte(address + 5) & 0xff) << 16 | + ((long) getByte(address + 6) & 0xff) << 8 | + (long) getByte(address + 7) & 0xff; + } else { + return (long) getByte(address + 7) << 56 | + ((long) getByte(address + 6) & 0xff) << 48 | + ((long) getByte(address + 5) & 0xff) << 40 | + ((long) getByte(address + 4) & 0xff) << 32 | + ((long) getByte(address + 3) & 0xff) << 24 | + ((long) getByte(address + 2) & 0xff) << 16 | + ((long) getByte(address + 1) & 0xff) << 8 | + (long) getByte(address) & 0xff; + } + } + + static void putOrderedObject(Object object, long address, Object value) { + UNSAFE.putOrderedObject(object, address, value); + } + + static void putByte(long address, byte value) { + UNSAFE.putByte(address, value); + } + + static void putShort(long address, short value) { + if (UNALIGNED) { + UNSAFE.putShort(address, value); + } else if (BIG_ENDIAN) { + putByte(address, (byte) (value >>> 8)); + putByte(address + 1, (byte) value); + } else { + putByte(address + 1, (byte) (value >>> 8)); + putByte(address, (byte) value); + } + } + + static void putInt(long address, int value) { + if (UNALIGNED) { + UNSAFE.putInt(address, value); + } else if (BIG_ENDIAN) { + putByte(address, (byte) (value >>> 24)); + putByte(address + 1, (byte) (value >>> 16)); + putByte(address + 2, (byte) (value >>> 8)); + putByte(address + 3, (byte) value); + } else { + putByte(address + 3, (byte) (value >>> 24)); + putByte(address + 2, (byte) (value >>> 16)); + putByte(address + 1, (byte) (value >>> 8)); + putByte(address, (byte) value); + } + } + + static void putLong(long address, long value) { + if (UNALIGNED) { + UNSAFE.putLong(address, value); + } else if (BIG_ENDIAN) { + putByte(address, (byte) (value >>> 56)); + putByte(address + 1, (byte) (value >>> 48)); + putByte(address + 2, (byte) (value >>> 40)); + putByte(address + 3, (byte) (value >>> 32)); + putByte(address + 4, (byte) (value >>> 24)); + putByte(address + 5, (byte) (value >>> 16)); + putByte(address + 6, (byte) (value >>> 8)); + putByte(address + 7, (byte) value); + } else { + putByte(address + 7, (byte) (value >>> 56)); + putByte(address + 6, (byte) (value >>> 48)); + putByte(address + 5, (byte) (value >>> 40)); + putByte(address + 4, (byte) (value >>> 32)); + putByte(address + 3, (byte) (value >>> 24)); + putByte(address + 2, (byte) (value >>> 16)); + putByte(address + 1, (byte) (value >>> 8)); + putByte(address, (byte) value); + } + } + + static void copyMemory(long srcAddr, long dstAddr, long length) { + //UNSAFE.copyMemory(srcAddr, dstAddr, length); + while (length > 0) { + long size = Math.min(length, UNSAFE_COPY_THRESHOLD); + UNSAFE.copyMemory(srcAddr, dstAddr, size); + length -= size; + srcAddr += size; + dstAddr += size; + } + } + + static void copyMemory(Object src, long srcOffset, Object dst, long dstOffset, long length) { + //UNSAFE.copyMemory(src, srcOffset, dst, dstOffset, length); + while (length > 0) { + long size = Math.min(length, UNSAFE_COPY_THRESHOLD); + UNSAFE.copyMemory(src, srcOffset, dst, dstOffset, size); + length -= size; + srcOffset += size; + dstOffset += size; + } + } + + static AtomicReferenceFieldUpdater newAtomicReferenceFieldUpdater( + Class tclass, String fieldName) throws Exception { + return new UnsafeAtomicReferenceFieldUpdater(UNSAFE, tclass, fieldName); + } + + static AtomicIntegerFieldUpdater newAtomicIntegerFieldUpdater( + Class tclass, String fieldName) throws Exception { + return new UnsafeAtomicIntegerFieldUpdater(UNSAFE, tclass, fieldName); + } + + static AtomicLongFieldUpdater newAtomicLongFieldUpdater( + Class tclass, String fieldName) throws Exception { + return new UnsafeAtomicLongFieldUpdater(UNSAFE, tclass, fieldName); + } + + static ClassLoader getClassLoader(final Class clazz) { + if (System.getSecurityManager() == null) { + return clazz.getClassLoader(); + } else { + return AccessController.doPrivileged(new PrivilegedAction() { + @Override + public ClassLoader run() { + return clazz.getClassLoader(); + } + }); + } + } + + static ClassLoader getContextClassLoader() { + if (System.getSecurityManager() == null) { + return Thread.currentThread().getContextClassLoader(); + } else { + return AccessController.doPrivileged(new PrivilegedAction() { + @Override + public ClassLoader run() { + return Thread.currentThread().getContextClassLoader(); + } + }); + } + } + + static ClassLoader getSystemClassLoader() { + if (System.getSecurityManager() == null) { + return ClassLoader.getSystemClassLoader(); + } else { + return AccessController.doPrivileged(new PrivilegedAction() { + @Override + public ClassLoader run() { + return ClassLoader.getSystemClassLoader(); + } + }); + } + } + + static int addressSize() { + return UNSAFE.addressSize(); + } + + static long allocateMemory(long size) { + return UNSAFE.allocateMemory(size); + } + + static void freeMemory(long address) { + UNSAFE.freeMemory(address); + } + + private PlatformDependent0() { + } + +} diff --git a/common/src/common/net/util/internal/RecyclableArrayList.java b/common/src/common/net/util/internal/RecyclableArrayList.java new file mode 100644 index 0000000..739a077 --- /dev/null +++ b/common/src/common/net/util/internal/RecyclableArrayList.java @@ -0,0 +1,132 @@ +/* + * Copyright 2013 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ + +package common.net.util.internal; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.RandomAccess; + +import common.net.util.Recycler; +import common.net.util.Recycler.Handle; + +/** + * A simple list which is reyclable. This implementation does not allow {@code null} elements to be added. + */ +public final class RecyclableArrayList extends ArrayList { + + private static final long serialVersionUID = -8605125654176467947L; + + private static final int DEFAULT_INITIAL_CAPACITY = 8; + + private static final Recycler RECYCLER = new Recycler() { + @Override + protected RecyclableArrayList newObject(Handle handle) { + return new RecyclableArrayList(handle); + } + }; + + /** + * Create a new empty {@link RecyclableArrayList} instance + */ + public static RecyclableArrayList newInstance() { + return newInstance(DEFAULT_INITIAL_CAPACITY); + } + + /** + * Create a new empty {@link RecyclableArrayList} instance with the given capacity. + */ + public static RecyclableArrayList newInstance(int minCapacity) { + RecyclableArrayList ret = RECYCLER.get(); + ret.ensureCapacity(minCapacity); + return ret; + } + + private final Handle handle; + + private RecyclableArrayList(Handle handle) { + this(handle, DEFAULT_INITIAL_CAPACITY); + } + + private RecyclableArrayList(Handle handle, int initialCapacity) { + super(initialCapacity); + this.handle = handle; + } + + @Override + public boolean addAll(Collection c) { + checkNullElements(c); + return super.addAll(c); + } + + @Override + public boolean addAll(int index, Collection c) { + checkNullElements(c); + return super.addAll(index, c); + } + + private static void checkNullElements(Collection c) { + if (c instanceof RandomAccess && c instanceof List) { + // produce less garbage + List list = (List) c; + int size = list.size(); + for (int i = 0; i < size; i++) { + if (list.get(i) == null) { + throw new IllegalArgumentException("c contains null values"); + } + } + } else { + for (Object element: c) { + if (element == null) { + throw new IllegalArgumentException("c contains null values"); + } + } + } + } + + @Override + public boolean add(Object element) { + if (element == null) { + throw new NullPointerException("element"); + } + return super.add(element); + } + + @Override + public void add(int index, Object element) { + if (element == null) { + throw new NullPointerException("element"); + } + super.add(index, element); + } + + @Override + public Object set(int index, Object element) { + if (element == null) { + throw new NullPointerException("element"); + } + return super.set(index, element); + } + + /** + * Clear and recycle this instance. + */ + public boolean recycle() { + clear(); + return RECYCLER.recycle(this, handle); + } +} diff --git a/common/src/common/net/util/internal/RecyclableMpscLinkedQueueNode.java b/common/src/common/net/util/internal/RecyclableMpscLinkedQueueNode.java new file mode 100644 index 0000000..a037070 --- /dev/null +++ b/common/src/common/net/util/internal/RecyclableMpscLinkedQueueNode.java @@ -0,0 +1,45 @@ +/* +* Copyright 2014 The Netty Project +* +* The Netty Project licenses this file to you under the Apache License, +* version 2.0 (the "License"); you may not use this file except in compliance +* with the License. You may obtain a copy of the License at: +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +* License for the specific language governing permissions and limitations +* under the License. +*/ + +package common.net.util.internal; + +import common.net.util.Recycler; + +/** + * {@link MpscLinkedQueueNode} that will automatically call {@link #recycle(Recycler.Handle)} when the node was + * unlinked. + */ +public abstract class RecyclableMpscLinkedQueueNode extends MpscLinkedQueueNode { + private final Recycler.Handle handle; + + protected RecyclableMpscLinkedQueueNode(Recycler.Handle handle) { + if (handle == null) { + throw new NullPointerException("handle"); + } + this.handle = handle; + } + + @Override + final void unlink() { + super.unlink(); + recycle(handle); + } + + /** + * Called once unliked and so ready to recycled. + */ + protected abstract void recycle(Recycler.Handle handle); +} diff --git a/common/src/common/net/util/internal/StringUtil.java b/common/src/common/net/util/internal/StringUtil.java new file mode 100644 index 0000000..a7e971f --- /dev/null +++ b/common/src/common/net/util/internal/StringUtil.java @@ -0,0 +1,274 @@ +/* + * Copyright 2012 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ +package common.net.util.internal; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Formatter; +import java.util.List; + +/** + * String utility class. + */ +public final class StringUtil { + + public static final String NEWLINE; + + private static final String[] BYTE2HEX_PAD = new String[256]; + private static final String[] BYTE2HEX_NOPAD = new String[256]; + private static final String EMPTY_STRING = ""; + + static { + // Determine the newline character of the current platform. + String newLine; + Formatter formatter = null; + + try { + formatter = new Formatter(); + newLine = formatter.format("%n").toString(); + } catch (Exception e) { + // Should not reach here, but just in case. + newLine = "\n"; + } + finally { + if(formatter != null) { + try { + formatter.close(); + } + catch(Throwable e) { + } + } + } + + NEWLINE = newLine; + + // Generate the lookup table that converts a byte into a 2-digit hexadecimal integer. + int i; + for (i = 0; i < 10; i ++) { + StringBuilder buf = new StringBuilder(2); + buf.append('0'); + buf.append(i); + BYTE2HEX_PAD[i] = buf.toString(); + BYTE2HEX_NOPAD[i] = String.valueOf(i); + } + for (; i < 16; i ++) { + StringBuilder buf = new StringBuilder(2); + char c = (char) ('a' + i - 10); + buf.append('0'); + buf.append(c); + BYTE2HEX_PAD[i] = buf.toString(); + BYTE2HEX_NOPAD[i] = String.valueOf(c); + } + for (; i < BYTE2HEX_PAD.length; i ++) { + StringBuilder buf = new StringBuilder(2); + buf.append(Integer.toHexString(i)); + String str = buf.toString(); + BYTE2HEX_PAD[i] = str; + BYTE2HEX_NOPAD[i] = str; + } + } + + /** + * Splits the specified {@link String} with the specified delimiter. This operation is a simplified and optimized + * version of {@link String#split(String)}. + */ + public static String[] split(String value, char delim) { + final int end = value.length(); + final List res = new ArrayList(); + + int start = 0; + for (int i = 0; i < end; i ++) { + if (value.charAt(i) == delim) { + if (start == i) { + res.add(EMPTY_STRING); + } else { + res.add(value.substring(start, i)); + } + start = i + 1; + } + } + + if (start == 0) { // If no delimiter was found in the value + res.add(value); + } else { + if (start != end) { + // Add the last element if it's not empty. + res.add(value.substring(start, end)); + } else { + // Truncate trailing empty elements. + for (int i = res.size() - 1; i >= 0; i --) { + if (res.get(i).isEmpty()) { + res.remove(i); + } else { + break; + } + } + } + } + + return res.toArray(new String[res.size()]); + } + + /** + * Converts the specified byte value into a 2-digit hexadecimal integer. + */ + public static String byteToHexStringPadded(int value) { + return BYTE2HEX_PAD[value & 0xff]; + } + + /** + * Converts the specified byte value into a 2-digit hexadecimal integer and appends it to the specified buffer. + */ + public static T byteToHexStringPadded(T buf, int value) { + try { + buf.append(byteToHexStringPadded(value)); + } catch (IOException e) { + PlatformDependent.throwException(e); + } + return buf; + } + + /** + * Converts the specified byte array into a hexadecimal value. + */ + public static String toHexStringPadded(byte[] src) { + return toHexStringPadded(src, 0, src.length); + } + + /** + * Converts the specified byte array into a hexadecimal value. + */ + public static String toHexStringPadded(byte[] src, int offset, int length) { + return toHexStringPadded(new StringBuilder(length << 1), src, offset, length).toString(); + } + + /** + * Converts the specified byte array into a hexadecimal value and appends it to the specified buffer. + */ + public static T toHexStringPadded(T dst, byte[] src) { + return toHexStringPadded(dst, src, 0, src.length); + } + + /** + * Converts the specified byte array into a hexadecimal value and appends it to the specified buffer. + */ + public static T toHexStringPadded(T dst, byte[] src, int offset, int length) { + final int end = offset + length; + for (int i = offset; i < end; i ++) { + byteToHexStringPadded(dst, src[i]); + } + return dst; + } + + /** + * Converts the specified byte value into a hexadecimal integer. + */ + public static String byteToHexString(int value) { + return BYTE2HEX_NOPAD[value & 0xff]; + } + + /** + * Converts the specified byte value into a hexadecimal integer and appends it to the specified buffer. + */ + public static T byteToHexString(T buf, int value) { + try { + buf.append(byteToHexString(value)); + } catch (IOException e) { + PlatformDependent.throwException(e); + } + return buf; + } + + /** + * Converts the specified byte array into a hexadecimal value. + */ + public static String toHexString(byte[] src) { + return toHexString(src, 0, src.length); + } + + /** + * Converts the specified byte array into a hexadecimal value. + */ + public static String toHexString(byte[] src, int offset, int length) { + return toHexString(new StringBuilder(length << 1), src, offset, length).toString(); + } + + /** + * Converts the specified byte array into a hexadecimal value and appends it to the specified buffer. + */ + public static T toHexString(T dst, byte[] src) { + return toHexString(dst, src, 0, src.length); + } + + /** + * Converts the specified byte array into a hexadecimal value and appends it to the specified buffer. + */ + public static T toHexString(T dst, byte[] src, int offset, int length) { + assert length >= 0; + if (length == 0) { + return dst; + } + + final int end = offset + length; + final int endMinusOne = end - 1; + int i; + + // Skip preceding zeroes. + for (i = offset; i < endMinusOne; i ++) { + if (src[i] != 0) { + break; + } + } + + byteToHexString(dst, src[i ++]); + int remaining = end - i; + toHexStringPadded(dst, src, i, remaining); + + return dst; + } + + /** + * The shortcut to {@link #simpleClassName(Class) simpleClassName(o.getClass())}. + */ + public static String simpleClassName(Object o) { + if (o == null) { + return "null_object"; + } else { + return simpleClassName(o.getClass()); + } + } + + /** + * Generates a simplified name from a {@link Class}. Similar to {@link Class#getSimpleName()}, but it works fine + * with anonymous classes. + */ + public static String simpleClassName(Class clazz) { + if (clazz == null) { + return "null_class"; + } + + Package pkg = clazz.getPackage(); + if (pkg != null) { + return clazz.getName().substring(pkg.getName().length() + 1); + } else { + return clazz.getName(); + } + } + + private StringUtil() { + // Unused. + } +} diff --git a/common/src/common/net/util/internal/SystemPropertyUtil.java b/common/src/common/net/util/internal/SystemPropertyUtil.java new file mode 100644 index 0000000..0aea0e4 --- /dev/null +++ b/common/src/common/net/util/internal/SystemPropertyUtil.java @@ -0,0 +1,223 @@ +/* + * Copyright 2012 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ +package common.net.util.internal; + +import java.security.AccessController; +import java.security.PrivilegedAction; +import java.util.logging.Level; +import java.util.logging.Logger; +import java.util.regex.Pattern; + +import common.net.util.internal.logging.InternalLogger; +import common.net.util.internal.logging.InternalLoggerFactory; + +/** + * A collection of utility methods to retrieve and parse the values of the Java system properties. + */ +public final class SystemPropertyUtil { + + private static boolean initializedLogger; + private static final InternalLogger logger; + private static boolean loggedException; + + static { + initializedLogger = false; + logger = InternalLoggerFactory.getInstance(SystemPropertyUtil.class); + initializedLogger = true; + } + + /** + * Returns {@code true} if and only if the system property with the specified {@code key} + * exists. + */ + public static boolean contains(String key) { + return get(key) != null; + } + + /** + * Returns the value of the Java system property with the specified + * {@code key}, while falling back to {@code null} if the property access fails. + * + * @return the property value or {@code null} + */ + public static String get(String key) { + return get(key, null); + } + + /** + * Returns the value of the Java system property with the specified + * {@code key}, while falling back to the specified default value if + * the property access fails. + * + * @return the property value. + * {@code def} if there's no such property or if an access to the + * specified property is not allowed. + */ + public static String get(final String key, String def) { + if (key == null) { + throw new NullPointerException("key"); + } + if (key.isEmpty()) { + throw new IllegalArgumentException("key must not be empty."); + } + + String value = null; + try { + if (System.getSecurityManager() == null) { + value = System.getProperty(key); + } else { + value = AccessController.doPrivileged(new PrivilegedAction() { + @Override + public String run() { + return System.getProperty(key); + } + }); + } + } catch (Exception e) { + if (!loggedException) { + log("Unable to retrieve a system property '" + key + "'; default values will be used.", e); + loggedException = true; + } + } + + if (value == null) { + return def; + } + + return value; + } + + /** + * Returns the value of the Java system property with the specified + * {@code key}, while falling back to the specified default value if + * the property access fails. + * + * @return the property value. + * {@code def} if there's no such property or if an access to the + * specified property is not allowed. + */ + public static boolean getBoolean(String key, boolean def) { + String value = get(key); + if (value == null) { + return def; + } + + value = value.trim().toLowerCase(); + if (value.isEmpty()) { + return true; + } + + if ("true".equals(value) || "yes".equals(value) || "1".equals(value)) { + return true; + } + + if ("false".equals(value) || "no".equals(value) || "0".equals(value)) { + return false; + } + + log( + "Unable to parse the boolean system property '" + key + "':" + value + " - " + + "using the default value: " + def); + + return def; + } + + private static final Pattern INTEGER_PATTERN = Pattern.compile("-?[0-9]+"); + + /** + * Returns the value of the Java system property with the specified + * {@code key}, while falling back to the specified default value if + * the property access fails. + * + * @return the property value. + * {@code def} if there's no such property or if an access to the + * specified property is not allowed. + */ + public static int getInt(String key, int def) { + String value = get(key); + if (value == null) { + return def; + } + + value = value.trim().toLowerCase(); + if (INTEGER_PATTERN.matcher(value).matches()) { + try { + return Integer.parseInt(value); + } catch (Exception e) { + // Ignore + } + } + + log( + "Unable to parse the integer system property '" + key + "':" + value + " - " + + "using the default value: " + def); + + return def; + } + + /** + * Returns the value of the Java system property with the specified + * {@code key}, while falling back to the specified default value if + * the property access fails. + * + * @return the property value. + * {@code def} if there's no such property or if an access to the + * specified property is not allowed. + */ + public static long getLong(String key, long def) { + String value = get(key); + if (value == null) { + return def; + } + + value = value.trim().toLowerCase(); + if (INTEGER_PATTERN.matcher(value).matches()) { + try { + return Long.parseLong(value); + } catch (Exception e) { + // Ignore + } + } + + log( + "Unable to parse the long integer system property '" + key + "':" + value + " - " + + "using the default value: " + def); + + return def; + } + + private static void log(String msg) { + if (initializedLogger) { + logger.warn(msg); + } else { + // Use JDK logging if logger was not initialized yet. + Logger.getLogger(SystemPropertyUtil.class.getName()).log(Level.WARNING, msg); + } + } + + private static void log(String msg, Exception e) { + if (initializedLogger) { + logger.warn(msg, e); + } else { + // Use JDK logging if logger was not initialized yet. + Logger.getLogger(SystemPropertyUtil.class.getName()).log(Level.WARNING, msg, e); + } + } + + private SystemPropertyUtil() { + // Unused + } +} diff --git a/common/src/common/net/util/internal/ThreadLocalRandom.java b/common/src/common/net/util/internal/ThreadLocalRandom.java new file mode 100644 index 0000000..0ad7360 --- /dev/null +++ b/common/src/common/net/util/internal/ThreadLocalRandom.java @@ -0,0 +1,336 @@ +/* + * Copyright 2014 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ + +/* + * Written by Doug Lea with assistance from members of JCP JSR-166 + * Expert Group and released to the public domain, as explained at + * http://creativecommons.org/publicdomain/zero/1.0/ + */ + +package common.net.util.internal; + +import java.lang.Thread.UncaughtExceptionHandler; +import java.security.SecureRandom; +import java.util.Random; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicLong; + +import common.net.util.internal.logging.InternalLogger; +import common.net.util.internal.logging.InternalLoggerFactory; + +/** + * A random number generator isolated to the current thread. Like the + * global {@link java.util.Random} generator used by the {@link + * java.lang.Math} class, a {@code ThreadLocalRandom} is initialized + * with an internally generated seed that may not otherwise be + * modified. When applicable, use of {@code ThreadLocalRandom} rather + * than shared {@code Random} objects in concurrent programs will + * typically encounter much less overhead and contention. Use of + * {@code ThreadLocalRandom} is particularly appropriate when multiple + * tasks (for example, each a {@link game.net.util.internal.chmv8.ForkJoinTask}) use random numbers + * in parallel in thread pools. + * + *

Usages of this class should typically be of the form: + * {@code ThreadLocalRandom.current().nextX(...)} (where + * {@code X} is {@code Int}, {@code Long}, etc). + * When all usages are of this form, it is never possible to + * accidently share a {@code ThreadLocalRandom} across multiple threads. + * + *

This class also provides additional commonly used bounded random + * generation methods. + * + * //since 1.7 + * //author Doug Lea + */ + +public final class ThreadLocalRandom extends Random { + + private static final InternalLogger logger = InternalLoggerFactory.getInstance(ThreadLocalRandom.class); + + private static final AtomicLong seedUniquifier = new AtomicLong(); + + private static volatile long initialSeedUniquifier; + + public static void setInitialSeedUniquifier(long initialSeedUniquifier) { + ThreadLocalRandom.initialSeedUniquifier = initialSeedUniquifier; + } + + public static synchronized long getInitialSeedUniquifier() { + // Use the value set via the setter. + long initialSeedUniquifier = ThreadLocalRandom.initialSeedUniquifier; + if (initialSeedUniquifier == 0) { + // Use the system property value. + ThreadLocalRandom.initialSeedUniquifier = initialSeedUniquifier = + SystemPropertyUtil.getLong("game.net.initialSeedUniquifier", 0); + } + + // Otherwise, generate one. + if (initialSeedUniquifier == 0) { + // Try to generate a real random number from /dev/random. + // Get from a different thread to avoid blocking indefinitely on a machine without much entrophy. + final BlockingQueue queue = new LinkedBlockingQueue(); + Thread generatorThread = new Thread("initialSeedUniquifierGenerator") { + @Override + public void run() { + SecureRandom random = new SecureRandom(); // Get the real random seed from /dev/random + queue.add(random.generateSeed(8)); + } + }; + generatorThread.setDaemon(true); + generatorThread.start(); + generatorThread.setUncaughtExceptionHandler(new UncaughtExceptionHandler() { + @Override + public void uncaughtException(Thread t, Throwable e) { + logger.debug("An exception has been raised by {}", t.getName(), e); + } + }); + + // Get the random seed from the thread with timeout. + final long timeoutSeconds = 3; + final long deadLine = System.nanoTime() + TimeUnit.SECONDS.toNanos(timeoutSeconds); + boolean interrupted = false; + for (;;) { + long waitTime = deadLine - System.nanoTime(); + if (waitTime <= 0) { + generatorThread.interrupt(); + logger.warn( + "Failed to generate a seed from SecureRandom within {} seconds. " + + "Not enough entrophy?", timeoutSeconds + ); + break; + } + + try { + byte[] seed = queue.poll(waitTime, TimeUnit.NANOSECONDS); + if (seed != null) { + initialSeedUniquifier = + ((long) seed[0] & 0xff) << 56 | + ((long) seed[1] & 0xff) << 48 | + ((long) seed[2] & 0xff) << 40 | + ((long) seed[3] & 0xff) << 32 | + ((long) seed[4] & 0xff) << 24 | + ((long) seed[5] & 0xff) << 16 | + ((long) seed[6] & 0xff) << 8 | + (long) seed[7] & 0xff; + break; + } + } catch (InterruptedException e) { + interrupted = true; + logger.warn("Failed to generate a seed from SecureRandom due to an InterruptedException."); + break; + } + } + + // Just in case the initialSeedUniquifier is zero or some other constant + initialSeedUniquifier ^= 0x3255ecdc33bae119L; // just a meaningless random number + initialSeedUniquifier ^= Long.reverse(System.nanoTime()); + + ThreadLocalRandom.initialSeedUniquifier = initialSeedUniquifier; + + if (interrupted) { + // Restore the interrupt status because we don't know how to/don't need to handle it here. + Thread.currentThread().interrupt(); + + // Interrupt the generator thread if it's still running, + // in the hope that the SecureRandom provider raises an exception on interruption. + generatorThread.interrupt(); + } + } + + return initialSeedUniquifier; + } + + private static long newSeed() { + final long startTime = System.nanoTime(); + for (;;) { + final long current = seedUniquifier.get(); + final long actualCurrent = current != 0? current : getInitialSeedUniquifier(); + + // L'Ecuyer, "Tables of Linear Congruential Generators of Different Sizes and Good Lattice Structure", 1999 + final long next = actualCurrent * 181783497276652981L; + + if (seedUniquifier.compareAndSet(current, next)) { + if (current == 0 && logger.isDebugEnabled()) { + logger.debug(String.format( + "-Dgame.net.initialSeedUniquifier: 0x%016x (took %d ms)", + actualCurrent, TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - startTime))); + } + return next ^ System.nanoTime(); + } + } + } + + // same constants as Random, but must be redeclared because private + private static final long multiplier = 0x5DEECE66DL; + private static final long addend = 0xBL; + private static final long mask = (1L << 48) - 1; + + /** + * The random seed. We can't use super.seed. + */ + private long rnd; + + /** + * Initialization flag to permit calls to setSeed to succeed only + * while executing the Random constructor. We can't allow others + * since it would cause setting seed in one part of a program to + * unintentionally impact other usages by the thread. + */ + boolean initialized; + + // Padding to help avoid memory contention among seed updates in + // different TLRs in the common case that they are located near + // each other. + private long pad0, pad1, pad2, pad3, pad4, pad5, pad6, pad7; + + /** + * Constructor called only by localRandom.initialValue. + */ + ThreadLocalRandom() { + super(newSeed()); + initialized = true; + } + + /** + * Returns the current thread's {@code ThreadLocalRandom}. + * + * @return the current thread's {@code ThreadLocalRandom} + */ + public static ThreadLocalRandom current() { + return InternalThreadLocalMap.get().random(); + } + + /** + * Throws {@code UnsupportedOperationException}. Setting seeds in + * this generator is not supported. + * + * @throws UnsupportedOperationException always + */ + public void setSeed(long seed) { + if (initialized) { + throw new UnsupportedOperationException(); + } + rnd = (seed ^ multiplier) & mask; + } + + protected int next(int bits) { + rnd = (rnd * multiplier + addend) & mask; + return (int) (rnd >>> (48 - bits)); + } + + /** + * Returns a pseudorandom, uniformly distributed value between the + * given least value (inclusive) and bound (exclusive). + * + * @param least the least value returned + * @param bound the upper bound (exclusive) + * @throws IllegalArgumentException if least greater than or equal + * to bound + * @return the next value + */ + public int nextInt(int least, int bound) { + if (least >= bound) { + throw new IllegalArgumentException(); + } + return nextInt(bound - least) + least; + } + + /** + * Returns a pseudorandom, uniformly distributed value + * between 0 (inclusive) and the specified value (exclusive). + * + * @param n the bound on the random number to be returned. Must be + * positive. + * @return the next value + * @throws IllegalArgumentException if n is not positive + */ + public long nextLong(long n) { + if (n <= 0) { + throw new IllegalArgumentException("n must be positive"); + } + + // Divide n by two until small enough for nextInt. On each + // iteration (at most 31 of them but usually much less), + // randomly choose both whether to include high bit in result + // (offset) and whether to continue with the lower vs upper + // half (which makes a difference only if odd). + long offset = 0; + while (n >= Integer.MAX_VALUE) { + int bits = next(2); + long half = n >>> 1; + long nextn = ((bits & 2) == 0) ? half : n - half; + if ((bits & 1) == 0) { + offset += n - nextn; + } + n = nextn; + } + return offset + nextInt((int) n); + } + + /** + * Returns a pseudorandom, uniformly distributed value between the + * given least value (inclusive) and bound (exclusive). + * + * @param least the least value returned + * @param bound the upper bound (exclusive) + * @return the next value + * @throws IllegalArgumentException if least greater than or equal + * to bound + */ + public long nextLong(long least, long bound) { + if (least >= bound) { + throw new IllegalArgumentException(); + } + return nextLong(bound - least) + least; + } + + /** + * Returns a pseudorandom, uniformly distributed {@code double} value + * between 0 (inclusive) and the specified value (exclusive). + * + * @param n the bound on the random number to be returned. Must be + * positive. + * @return the next value + * @throws IllegalArgumentException if n is not positive + */ + public double nextDouble(double n) { + if (n <= 0) { + throw new IllegalArgumentException("n must be positive"); + } + return nextDouble() * n; + } + + /** + * Returns a pseudorandom, uniformly distributed value between the + * given least value (inclusive) and bound (exclusive). + * + * @param least the least value returned + * @param bound the upper bound (exclusive) + * @return the next value + * @throws IllegalArgumentException if least greater than or equal + * to bound + */ + public double nextDouble(double least, double bound) { + if (least >= bound) { + throw new IllegalArgumentException(); + } + return nextDouble() * (bound - least) + least; + } + + private static final long serialVersionUID = -5851777807851030925L; +} diff --git a/common/src/common/net/util/internal/TypeParameterMatcher.java b/common/src/common/net/util/internal/TypeParameterMatcher.java new file mode 100644 index 0000000..76ba1b2 --- /dev/null +++ b/common/src/common/net/util/internal/TypeParameterMatcher.java @@ -0,0 +1,177 @@ +/* + * Copyright 2013 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ + +package common.net.util.internal; + +import java.lang.reflect.Array; +import java.lang.reflect.GenericArrayType; +import java.lang.reflect.ParameterizedType; +import java.lang.reflect.Type; +import java.lang.reflect.TypeVariable; +import java.util.HashMap; +import java.util.Map; + +public abstract class TypeParameterMatcher { + + private static final TypeParameterMatcher NOOP = new NoOpTypeParameterMatcher(); + private static final Object TEST_OBJECT = new Object(); + + public static TypeParameterMatcher get(final Class parameterType) { + final Map, TypeParameterMatcher> getCache = + InternalThreadLocalMap.get().typeParameterMatcherGetCache(); + + TypeParameterMatcher matcher = getCache.get(parameterType); + if (matcher == null) { + if (parameterType == Object.class) { + matcher = NOOP; + } +// else if (PlatformDependent.hasJavassist()) { +// try { +// matcher = JavassistTypeParameterMatcherGenerator.generate(parameterType); +// matcher.match(TEST_OBJECT); +// } catch (IllegalAccessError e) { +// // Happens if parameterType is not public. +// matcher = null; +// } catch (Exception e) { +// // Will not usually happen, but just in case. +// matcher = null; +// } +// } + + if (matcher == null) { + matcher = new ReflectiveMatcher(parameterType); + } + + getCache.put(parameterType, matcher); + } + + return matcher; + } + + public static TypeParameterMatcher find( + final Object object, final Class parameterizedSuperclass, final String typeParamName) { + + final Map, Map> findCache = + InternalThreadLocalMap.get().typeParameterMatcherFindCache(); + final Class thisClass = object.getClass(); + + Map map = findCache.get(thisClass); + if (map == null) { + map = new HashMap(); + findCache.put(thisClass, map); + } + + TypeParameterMatcher matcher = map.get(typeParamName); + if (matcher == null) { + matcher = get(find0(object, parameterizedSuperclass, typeParamName)); + map.put(typeParamName, matcher); + } + + return matcher; + } + + private static Class find0( + final Object object, Class parameterizedSuperclass, String typeParamName) { + + final Class thisClass = object.getClass(); + Class currentClass = thisClass; + for (;;) { + if (currentClass.getSuperclass() == parameterizedSuperclass) { + int typeParamIndex = -1; + TypeVariable[] typeParams = currentClass.getSuperclass().getTypeParameters(); + for (int i = 0; i < typeParams.length; i ++) { + if (typeParamName.equals(typeParams[i].getName())) { + typeParamIndex = i; + break; + } + } + + if (typeParamIndex < 0) { + throw new IllegalStateException( + "unknown type parameter '" + typeParamName + "': " + parameterizedSuperclass); + } + + Type genericSuperType = currentClass.getGenericSuperclass(); + if (!(genericSuperType instanceof ParameterizedType)) { + return Object.class; + } + + Type[] actualTypeParams = ((ParameterizedType) genericSuperType).getActualTypeArguments(); + + Type actualTypeParam = actualTypeParams[typeParamIndex]; + if (actualTypeParam instanceof ParameterizedType) { + actualTypeParam = ((ParameterizedType) actualTypeParam).getRawType(); + } + if (actualTypeParam instanceof Class) { + return (Class) actualTypeParam; + } + if (actualTypeParam instanceof GenericArrayType) { + Type componentType = ((GenericArrayType) actualTypeParam).getGenericComponentType(); + if (componentType instanceof ParameterizedType) { + componentType = ((ParameterizedType) componentType).getRawType(); + } + if (componentType instanceof Class) { + return Array.newInstance((Class) componentType, 0).getClass(); + } + } + if (actualTypeParam instanceof TypeVariable) { + // Resolved type parameter points to another type parameter. + TypeVariable v = (TypeVariable) actualTypeParam; + currentClass = thisClass; + if (!(v.getGenericDeclaration() instanceof Class)) { + return Object.class; + } + + parameterizedSuperclass = (Class) v.getGenericDeclaration(); + typeParamName = v.getName(); + if (parameterizedSuperclass.isAssignableFrom(thisClass)) { + continue; + } else { + return Object.class; + } + } + + return fail(thisClass, typeParamName); + } + currentClass = currentClass.getSuperclass(); + if (currentClass == null) { + return fail(thisClass, typeParamName); + } + } + } + + private static Class fail(Class type, String typeParamName) { + throw new IllegalStateException( + "cannot determine the type of the type parameter '" + typeParamName + "': " + type); + } + + public abstract boolean match(Object msg); + + private static final class ReflectiveMatcher extends TypeParameterMatcher { + private final Class type; + + ReflectiveMatcher(Class type) { + this.type = type; + } + + @Override + public boolean match(Object msg) { + return type.isInstance(msg); + } + } + + protected TypeParameterMatcher() { } +} diff --git a/common/src/common/net/util/internal/UnpaddedInternalThreadLocalMap.java b/common/src/common/net/util/internal/UnpaddedInternalThreadLocalMap.java new file mode 100644 index 0000000..689202d --- /dev/null +++ b/common/src/common/net/util/internal/UnpaddedInternalThreadLocalMap.java @@ -0,0 +1,55 @@ +/* + * Copyright 2014 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ + +package common.net.util.internal; + +import java.nio.charset.Charset; +import java.nio.charset.CharsetDecoder; +import java.nio.charset.CharsetEncoder; +import java.util.Map; +import java.util.concurrent.atomic.AtomicInteger; + +/** + * The internal data structure that stores the thread-local variables for Netty and all {@link FastThreadLocal}s. + * Note that this class is for internal use only and is subject to change at any time. Use {@link FastThreadLocal} + * unless you know what you are doing. + */ +class UnpaddedInternalThreadLocalMap { + + static ThreadLocal slowThreadLocalMap; + static final AtomicInteger nextIndex = new AtomicInteger(); + + /** Used by {@link FastThreadLocal} */ + Object[] indexedVariables; + + // Core thread-locals + int futureListenerStackDepth; + int localChannelReaderStackDepth; + Map, Boolean> handlerSharableCache; + IntegerHolder counterHashCode; + ThreadLocalRandom random; + Map, TypeParameterMatcher> typeParameterMatcherGetCache; + Map, Map> typeParameterMatcherFindCache; + + // String-related thread-locals + StringBuilder stringBuilder; + Map charsetEncoderCache; + Map charsetDecoderCache; + + UnpaddedInternalThreadLocalMap(Object[] indexedVariables) { + this.indexedVariables = indexedVariables; + } +} diff --git a/common/src/common/net/util/internal/UnsafeAtomicIntegerFieldUpdater.java b/common/src/common/net/util/internal/UnsafeAtomicIntegerFieldUpdater.java new file mode 100644 index 0000000..69e3a37 --- /dev/null +++ b/common/src/common/net/util/internal/UnsafeAtomicIntegerFieldUpdater.java @@ -0,0 +1,61 @@ +/* + * Copyright 2014 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ +package common.net.util.internal; + +import java.lang.reflect.Field; +import java.lang.reflect.Modifier; +import java.util.concurrent.atomic.AtomicIntegerFieldUpdater; + +import sun.misc.Unsafe; + +final class UnsafeAtomicIntegerFieldUpdater extends AtomicIntegerFieldUpdater { + private final long offset; + private final Unsafe unsafe; + + UnsafeAtomicIntegerFieldUpdater(Unsafe unsafe, Class tClass, String fieldName) throws NoSuchFieldException { + Field field = tClass.getDeclaredField(fieldName); + if (!Modifier.isVolatile(field.getModifiers())) { + throw new IllegalArgumentException("Must be volatile"); + } + this.unsafe = unsafe; + offset = unsafe.objectFieldOffset(field); + } + + @Override + public boolean compareAndSet(T obj, int expect, int update) { + return unsafe.compareAndSwapInt(obj, offset, expect, update); + } + + @Override + public boolean weakCompareAndSet(T obj, int expect, int update) { + return unsafe.compareAndSwapInt(obj, offset, expect, update); + } + + @Override + public void set(T obj, int newValue) { + unsafe.putIntVolatile(obj, offset, newValue); + } + + @Override + public void lazySet(T obj, int newValue) { + unsafe.putOrderedInt(obj, offset, newValue); + } + + @Override + public int get(T obj) { + return unsafe.getIntVolatile(obj, offset); + } +} diff --git a/common/src/common/net/util/internal/UnsafeAtomicLongFieldUpdater.java b/common/src/common/net/util/internal/UnsafeAtomicLongFieldUpdater.java new file mode 100644 index 0000000..ad5b0f8 --- /dev/null +++ b/common/src/common/net/util/internal/UnsafeAtomicLongFieldUpdater.java @@ -0,0 +1,61 @@ +/* + * Copyright 2014 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ +package common.net.util.internal; + +import java.lang.reflect.Field; +import java.lang.reflect.Modifier; +import java.util.concurrent.atomic.AtomicLongFieldUpdater; + +import sun.misc.Unsafe; + +final class UnsafeAtomicLongFieldUpdater extends AtomicLongFieldUpdater { + private final long offset; + private final Unsafe unsafe; + + UnsafeAtomicLongFieldUpdater(Unsafe unsafe, Class tClass, String fieldName) throws NoSuchFieldException { + Field field = tClass.getDeclaredField(fieldName); + if (!Modifier.isVolatile(field.getModifiers())) { + throw new IllegalArgumentException("Must be volatile"); + } + this.unsafe = unsafe; + offset = unsafe.objectFieldOffset(field); + } + + @Override + public boolean compareAndSet(T obj, long expect, long update) { + return unsafe.compareAndSwapLong(obj, offset, expect, update); + } + + @Override + public boolean weakCompareAndSet(T obj, long expect, long update) { + return unsafe.compareAndSwapLong(obj, offset, expect, update); + } + + @Override + public void set(T obj, long newValue) { + unsafe.putLongVolatile(obj, offset, newValue); + } + + @Override + public void lazySet(T obj, long newValue) { + unsafe.putOrderedLong(obj, offset, newValue); + } + + @Override + public long get(T obj) { + return unsafe.getLongVolatile(obj, offset); + } +} diff --git a/common/src/common/net/util/internal/UnsafeAtomicReferenceFieldUpdater.java b/common/src/common/net/util/internal/UnsafeAtomicReferenceFieldUpdater.java new file mode 100644 index 0000000..66ddd3d --- /dev/null +++ b/common/src/common/net/util/internal/UnsafeAtomicReferenceFieldUpdater.java @@ -0,0 +1,62 @@ +/* + * Copyright 2014 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ +package common.net.util.internal; + +import java.lang.reflect.Field; +import java.lang.reflect.Modifier; +import java.util.concurrent.atomic.AtomicReferenceFieldUpdater; + +import sun.misc.Unsafe; + +final class UnsafeAtomicReferenceFieldUpdater extends AtomicReferenceFieldUpdater { + private final long offset; + private final Unsafe unsafe; + + UnsafeAtomicReferenceFieldUpdater(Unsafe unsafe, Class tClass, String fieldName) throws NoSuchFieldException { + Field field = tClass.getDeclaredField(fieldName); + if (!Modifier.isVolatile(field.getModifiers())) { + throw new IllegalArgumentException("Must be volatile"); + } + this.unsafe = unsafe; + offset = unsafe.objectFieldOffset(field); + } + + @Override + public boolean compareAndSet(U obj, M expect, M update) { + return unsafe.compareAndSwapObject(obj, offset, expect, update); + } + + @Override + public boolean weakCompareAndSet(U obj, M expect, M update) { + return unsafe.compareAndSwapObject(obj, offset, expect, update); + } + + @Override + public void set(U obj, M newValue) { + unsafe.putObjectVolatile(obj, offset, newValue); + } + + @Override + public void lazySet(U obj, M newValue) { + unsafe.putOrderedObject(obj, offset, newValue); + } + + + @Override + public M get(U obj) { + return (M) unsafe.getObjectVolatile(obj, offset); + } +} diff --git a/common/src/common/net/util/internal/logging/AbstractInternalLogger.java b/common/src/common/net/util/internal/logging/AbstractInternalLogger.java new file mode 100644 index 0000000..2ebbf8a --- /dev/null +++ b/common/src/common/net/util/internal/logging/AbstractInternalLogger.java @@ -0,0 +1,190 @@ +/* + * Copyright 2012 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ +package common.net.util.internal.logging; + +import java.io.ObjectStreamException; +import java.io.Serializable; + +import common.net.util.internal.StringUtil; + +/** + * A skeletal implementation of {@link InternalLogger}. This class implements + * all methods that have a {@link InternalLogLevel} parameter by default to call + * specific logger methods such as {@link #info(String)} or {@link #isInfoEnabled()}. + */ +public abstract class AbstractInternalLogger implements InternalLogger, Serializable { + + private static final long serialVersionUID = -6382972526573193470L; + + private final String name; + + /** + * Creates a new instance. + */ + protected AbstractInternalLogger(String name) { + if (name == null) { + throw new NullPointerException("name"); + } + this.name = name; + } + + @Override + public String name() { + return name; + } + + @Override + public boolean isEnabled(InternalLogLevel level) { + switch (level) { + case TRACE: + return isTraceEnabled(); + case DEBUG: + return isDebugEnabled(); + case INFO: + return isInfoEnabled(); + case WARN: + return isWarnEnabled(); + case ERROR: + return isErrorEnabled(); + default: + throw new Error(); + } + } + + @Override + public void log(InternalLogLevel level, String msg, Throwable cause) { + switch (level) { + case TRACE: + trace(msg, cause); + break; + case DEBUG: + debug(msg, cause); + break; + case INFO: + info(msg, cause); + break; + case WARN: + warn(msg, cause); + break; + case ERROR: + error(msg, cause); + break; + default: + throw new Error(); + } + } + + @Override + public void log(InternalLogLevel level, String msg) { + switch (level) { + case TRACE: + trace(msg); + break; + case DEBUG: + debug(msg); + break; + case INFO: + info(msg); + break; + case WARN: + warn(msg); + break; + case ERROR: + error(msg); + break; + default: + throw new Error(); + } + } + + @Override + public void log(InternalLogLevel level, String format, Object arg) { + switch (level) { + case TRACE: + trace(format, arg); + break; + case DEBUG: + debug(format, arg); + break; + case INFO: + info(format, arg); + break; + case WARN: + warn(format, arg); + break; + case ERROR: + error(format, arg); + break; + default: + throw new Error(); + } + } + + @Override + public void log(InternalLogLevel level, String format, Object argA, Object argB) { + switch (level) { + case TRACE: + trace(format, argA, argB); + break; + case DEBUG: + debug(format, argA, argB); + break; + case INFO: + info(format, argA, argB); + break; + case WARN: + warn(format, argA, argB); + break; + case ERROR: + error(format, argA, argB); + break; + default: + throw new Error(); + } + } + + @Override + public void log(InternalLogLevel level, String format, Object... arguments) { + switch (level) { + case TRACE: + trace(format, arguments); + break; + case DEBUG: + debug(format, arguments); + break; + case INFO: + info(format, arguments); + break; + case WARN: + warn(format, arguments); + break; + case ERROR: + error(format, arguments); + break; + default: + throw new Error(); + } + } + + protected Object readResolve() throws ObjectStreamException { + return InternalLoggerFactory.getInstance(name()); + } + + @Override + public String toString() { + return StringUtil.simpleClassName(this) + '(' + name() + ')'; + } +} diff --git a/common/src/common/net/util/internal/logging/FormattingTuple.java b/common/src/common/net/util/internal/logging/FormattingTuple.java new file mode 100644 index 0000000..c87a8e7 --- /dev/null +++ b/common/src/common/net/util/internal/logging/FormattingTuple.java @@ -0,0 +1,88 @@ +/* + * Copyright 2013 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ +/** + * Copyright (c) 2004-2011 QOS.ch + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ +package common.net.util.internal.logging; + +/** + * Holds the results of formatting done by {@link MessageFormatter}. + */ +class FormattingTuple { + + static final FormattingTuple NULL = new FormattingTuple(null); + + private final String message; + private final Throwable throwable; + private final Object[] argArray; + + FormattingTuple(String message) { + this(message, null, null); + } + + FormattingTuple(String message, Object[] argArray, Throwable throwable) { + this.message = message; + this.throwable = throwable; + if (throwable == null) { + this.argArray = argArray; + } else { + this.argArray = trimmedCopy(argArray); + } + } + + static Object[] trimmedCopy(Object[] argArray) { + if (argArray == null || argArray.length == 0) { + throw new IllegalStateException("non-sensical empty or null argument array"); + } + final int trimemdLen = argArray.length - 1; + Object[] trimmed = new Object[trimemdLen]; + System.arraycopy(argArray, 0, trimmed, 0, trimemdLen); + return trimmed; + } + + public String getMessage() { + return message; + } + + public Object[] getArgArray() { + return argArray; + } + + public Throwable getThrowable() { + return throwable; + } +} diff --git a/common/src/common/net/util/internal/logging/InternalLogLevel.java b/common/src/common/net/util/internal/logging/InternalLogLevel.java new file mode 100644 index 0000000..108c2f5 --- /dev/null +++ b/common/src/common/net/util/internal/logging/InternalLogLevel.java @@ -0,0 +1,42 @@ +/* + * Copyright 2012 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ +package common.net.util.internal.logging; + +/** + * The log level that {@link InternalLogger} can log at. + */ +public enum InternalLogLevel { + /** + * 'TRACE' log level. + */ + TRACE, + /** + * 'DEBUG' log level. + */ + DEBUG, + /** + * 'INFO' log level. + */ + INFO, + /** + * 'WARN' log level. + */ + WARN, + /** + * 'ERROR' log level. + */ + ERROR +} diff --git a/common/src/common/net/util/internal/logging/InternalLogger.java b/common/src/common/net/util/internal/logging/InternalLogger.java new file mode 100644 index 0000000..1c2b953 --- /dev/null +++ b/common/src/common/net/util/internal/logging/InternalLogger.java @@ -0,0 +1,444 @@ +/* + * Copyright 2012 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ +/** + * Copyright (c) 2004-2011 QOS.ch + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ +package common.net.util.internal.logging; + +/** + * Internal-use-only logger used by Netty. DO NOT + * access this class outside of Netty. + */ +public interface InternalLogger { + + /** + * Return the name of this {@link InternalLogger} instance. + * + * @return name of this logger instance + */ + String name(); + + /** + * Is the logger instance enabled for the TRACE level? + * + * @return True if this Logger is enabled for the TRACE level, + * false otherwise. + */ + boolean isTraceEnabled(); + + /** + * Log a message at the TRACE level. + * + * @param msg the message string to be logged + */ + void trace(String msg); + + /** + * Log a message at the TRACE level according to the specified format + * and argument. + *

+ *

This form avoids superfluous object creation when the logger + * is disabled for the TRACE level.

+ * + * @param format the format string + * @param arg the argument + */ + void trace(String format, Object arg); + + /** + * Log a message at the TRACE level according to the specified format + * and arguments. + *

+ *

This form avoids superfluous object creation when the logger + * is disabled for the TRACE level.

+ * + * @param format the format string + * @param argA the first argument + * @param argB the second argument + */ + void trace(String format, Object argA, Object argB); + + /** + * Log a message at the TRACE level according to the specified format + * and arguments. + *

+ *

This form avoids superfluous string concatenation when the logger + * is disabled for the TRACE level. However, this variant incurs the hidden + * (and relatively small) cost of creating an {@code Object[]} before invoking the method, + * even if this logger is disabled for TRACE. The variants taking {@link #trace(String, Object) one} and + * {@link #trace(String, Object, Object) two} arguments exist solely in order to avoid this hidden cost.

+ * + * @param format the format string + * @param arguments a list of 3 or more arguments + */ + void trace(String format, Object... arguments); + + /** + * Log an exception (throwable) at the TRACE level with an + * accompanying message. + * + * @param msg the message accompanying the exception + * @param t the exception (throwable) to log + */ + void trace(String msg, Throwable t); + + /** + * Is the logger instance enabled for the DEBUG level? + * + * @return True if this Logger is enabled for the DEBUG level, + * false otherwise. + */ + boolean isDebugEnabled(); + + /** + * Log a message at the DEBUG level. + * + * @param msg the message string to be logged + */ + void debug(String msg); + + /** + * Log a message at the DEBUG level according to the specified format + * and argument. + *

+ *

This form avoids superfluous object creation when the logger + * is disabled for the DEBUG level.

+ * + * @param format the format string + * @param arg the argument + */ + void debug(String format, Object arg); + + /** + * Log a message at the DEBUG level according to the specified format + * and arguments. + *

+ *

This form avoids superfluous object creation when the logger + * is disabled for the DEBUG level.

+ * + * @param format the format string + * @param argA the first argument + * @param argB the second argument + */ + void debug(String format, Object argA, Object argB); + + /** + * Log a message at the DEBUG level according to the specified format + * and arguments. + *

+ *

This form avoids superfluous string concatenation when the logger + * is disabled for the DEBUG level. However, this variant incurs the hidden + * (and relatively small) cost of creating an {@code Object[]} before invoking the method, + * even if this logger is disabled for DEBUG. The variants taking + * {@link #debug(String, Object) one} and {@link #debug(String, Object, Object) two} + * arguments exist solely in order to avoid this hidden cost.

+ * + * @param format the format string + * @param arguments a list of 3 or more arguments + */ + void debug(String format, Object... arguments); + + /** + * Log an exception (throwable) at the DEBUG level with an + * accompanying message. + * + * @param msg the message accompanying the exception + * @param t the exception (throwable) to log + */ + void debug(String msg, Throwable t); + + /** + * Is the logger instance enabled for the INFO level? + * + * @return True if this Logger is enabled for the INFO level, + * false otherwise. + */ + boolean isInfoEnabled(); + + /** + * Log a message at the INFO level. + * + * @param msg the message string to be logged + */ + void info(String msg); + + /** + * Log a message at the INFO level according to the specified format + * and argument. + *

+ *

This form avoids superfluous object creation when the logger + * is disabled for the INFO level.

+ * + * @param format the format string + * @param arg the argument + */ + void info(String format, Object arg); + + /** + * Log a message at the INFO level according to the specified format + * and arguments. + *

+ *

This form avoids superfluous object creation when the logger + * is disabled for the INFO level.

+ * + * @param format the format string + * @param argA the first argument + * @param argB the second argument + */ + void info(String format, Object argA, Object argB); + + /** + * Log a message at the INFO level according to the specified format + * and arguments. + *

+ *

This form avoids superfluous string concatenation when the logger + * is disabled for the INFO level. However, this variant incurs the hidden + * (and relatively small) cost of creating an {@code Object[]} before invoking the method, + * even if this logger is disabled for INFO. The variants taking + * {@link #info(String, Object) one} and {@link #info(String, Object, Object) two} + * arguments exist solely in order to avoid this hidden cost.

+ * + * @param format the format string + * @param arguments a list of 3 or more arguments + */ + void info(String format, Object... arguments); + + /** + * Log an exception (throwable) at the INFO level with an + * accompanying message. + * + * @param msg the message accompanying the exception + * @param t the exception (throwable) to log + */ + void info(String msg, Throwable t); + + /** + * Is the logger instance enabled for the WARN level? + * + * @return True if this Logger is enabled for the WARN level, + * false otherwise. + */ + boolean isWarnEnabled(); + + /** + * Log a message at the WARN level. + * + * @param msg the message string to be logged + */ + void warn(String msg); + + /** + * Log a message at the WARN level according to the specified format + * and argument. + *

+ *

This form avoids superfluous object creation when the logger + * is disabled for the WARN level.

+ * + * @param format the format string + * @param arg the argument + */ + void warn(String format, Object arg); + + /** + * Log a message at the WARN level according to the specified format + * and arguments. + *

+ *

This form avoids superfluous string concatenation when the logger + * is disabled for the WARN level. However, this variant incurs the hidden + * (and relatively small) cost of creating an {@code Object[]} before invoking the method, + * even if this logger is disabled for WARN. The variants taking + * {@link #warn(String, Object) one} and {@link #warn(String, Object, Object) two} + * arguments exist solely in order to avoid this hidden cost.

+ * + * @param format the format string + * @param arguments a list of 3 or more arguments + */ + void warn(String format, Object... arguments); + + /** + * Log a message at the WARN level according to the specified format + * and arguments. + *

+ *

This form avoids superfluous object creation when the logger + * is disabled for the WARN level.

+ * + * @param format the format string + * @param argA the first argument + * @param argB the second argument + */ + void warn(String format, Object argA, Object argB); + + /** + * Log an exception (throwable) at the WARN level with an + * accompanying message. + * + * @param msg the message accompanying the exception + * @param t the exception (throwable) to log + */ + void warn(String msg, Throwable t); + + /** + * Is the logger instance enabled for the ERROR level? + * + * @return True if this Logger is enabled for the ERROR level, + * false otherwise. + */ + boolean isErrorEnabled(); + + /** + * Log a message at the ERROR level. + * + * @param msg the message string to be logged + */ + void error(String msg); + + /** + * Log a message at the ERROR level according to the specified format + * and argument. + *

+ *

This form avoids superfluous object creation when the logger + * is disabled for the ERROR level.

+ * + * @param format the format string + * @param arg the argument + */ + void error(String format, Object arg); + + /** + * Log a message at the ERROR level according to the specified format + * and arguments. + *

+ *

This form avoids superfluous object creation when the logger + * is disabled for the ERROR level.

+ * + * @param format the format string + * @param argA the first argument + * @param argB the second argument + */ + void error(String format, Object argA, Object argB); + + /** + * Log a message at the ERROR level according to the specified format + * and arguments. + *

+ *

This form avoids superfluous string concatenation when the logger + * is disabled for the ERROR level. However, this variant incurs the hidden + * (and relatively small) cost of creating an {@code Object[]} before invoking the method, + * even if this logger is disabled for ERROR. The variants taking + * {@link #error(String, Object) one} and {@link #error(String, Object, Object) two} + * arguments exist solely in order to avoid this hidden cost.

+ * + * @param format the format string + * @param arguments a list of 3 or more arguments + */ + void error(String format, Object... arguments); + + /** + * Log an exception (throwable) at the ERROR level with an + * accompanying message. + * + * @param msg the message accompanying the exception + * @param t the exception (throwable) to log + */ + void error(String msg, Throwable t); + + /** + * Is the logger instance enabled for the specified {@code level}? + * + * @return True if this Logger is enabled for the specified {@code level}, + * false otherwise. + */ + boolean isEnabled(InternalLogLevel level); + + /** + * Log a message at the specified {@code level}. + * + * @param msg the message string to be logged + */ + void log(InternalLogLevel level, String msg); + + /** + * Log a message at the specified {@code level} according to the specified format + * and argument. + *

+ *

This form avoids superfluous object creation when the logger + * is disabled for the specified {@code level}.

+ * + * @param format the format string + * @param arg the argument + */ + void log(InternalLogLevel level, String format, Object arg); + + /** + * Log a message at the specified {@code level} according to the specified format + * and arguments. + *

+ *

This form avoids superfluous object creation when the logger + * is disabled for the specified {@code level}.

+ * + * @param format the format string + * @param argA the first argument + * @param argB the second argument + */ + void log(InternalLogLevel level, String format, Object argA, Object argB); + + /** + * Log a message at the specified {@code level} according to the specified format + * and arguments. + *

+ *

This form avoids superfluous string concatenation when the logger + * is disabled for the specified {@code level}. However, this variant incurs the hidden + * (and relatively small) cost of creating an {@code Object[]} before invoking the method, + * even if this logger is disabled for the specified {@code level}. The variants taking + * {@link #log(InternalLogLevel, String, Object) one} and + * {@link #log(InternalLogLevel, String, Object, Object) two} arguments exist solely + * in order to avoid this hidden cost.

+ * + * @param format the format string + * @param arguments a list of 3 or more arguments + */ + void log(InternalLogLevel level, String format, Object... arguments); + + /** + * Log an exception (throwable) at the specified {@code level} with an + * accompanying message. + * + * @param msg the message accompanying the exception + * @param t the exception (throwable) to log + */ + void log(InternalLogLevel level, String msg, Throwable t); +} diff --git a/common/src/common/net/util/internal/logging/InternalLoggerFactory.java b/common/src/common/net/util/internal/logging/InternalLoggerFactory.java new file mode 100644 index 0000000..e6d10ff --- /dev/null +++ b/common/src/common/net/util/internal/logging/InternalLoggerFactory.java @@ -0,0 +1,91 @@ +/* + * Copyright 2012 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ +package common.net.util.internal.logging; + +/** + * Creates an {@link InternalLogger} or changes the default factory + * implementation. This factory allows you to choose what logging framework + * Netty should use. The default factory is {@link Slf4JLoggerFactory}. If SLF4J + * is not available, {@link Log4JLoggerFactory} is used. If Log4J is not available, + * {@link JdkLoggerFactory} is used. You can change it to your preferred + * logging framework before other Netty classes are loaded: + *
+ * {@link InternalLoggerFactory}.setDefaultFactory(new {@link Log4JLoggerFactory}());
+ * 
+ * Please note that the new default factory is effective only for the classes + * which were loaded after the default factory is changed. Therefore, + * {@link #setDefaultFactory(InternalLoggerFactory)} should be called as early + * as possible and shouldn't be called more than once. + */ +public abstract class InternalLoggerFactory { + private static volatile InternalLoggerFactory defaultFactory = + newDefaultFactory(InternalLoggerFactory.class.getName()); + +// + private static InternalLoggerFactory newDefaultFactory(String name) { + InternalLoggerFactory f; +// try { +// f = new Slf4JLoggerFactory(true); +// f.newInstance(name).debug("Using SLF4J as the default logging framework"); +// } catch (Throwable t1) { +// try { +// f = new Log4JLoggerFactory(); +// f.newInstance(name).debug("Using Log4J as the default logging framework"); +// } catch (Throwable t2) { + f = new JdkLoggerFactory(); + f.newInstance(name).debug("Using java.util.logging as the default logging framework"); +// } +// } + return f; + } + + /** + * Returns the default factory. The initial default factory is + * {@link JdkLoggerFactory}. + */ + public static InternalLoggerFactory getDefaultFactory() { + return defaultFactory; + } + + /** + * Changes the default factory. + */ + public static void setDefaultFactory(InternalLoggerFactory defaultFactory) { + if (defaultFactory == null) { + throw new NullPointerException("defaultFactory"); + } + InternalLoggerFactory.defaultFactory = defaultFactory; + } + + /** + * Creates a new logger instance with the name of the specified class. + */ + public static InternalLogger getInstance(Class clazz) { + return getInstance(clazz.getName()); + } + + /** + * Creates a new logger instance with the specified name. + */ + public static InternalLogger getInstance(String name) { + return getDefaultFactory().newInstance(name); + } + + /** + * Creates a new logger instance with the specified name. + */ + protected abstract InternalLogger newInstance(String name); +} diff --git a/common/src/common/net/util/internal/logging/JdkLogger.java b/common/src/common/net/util/internal/logging/JdkLogger.java new file mode 100644 index 0000000..a0e69f6 --- /dev/null +++ b/common/src/common/net/util/internal/logging/JdkLogger.java @@ -0,0 +1,647 @@ +/* + * Copyright 2012 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ +/** + * Copyright (c) 2004-2011 QOS.ch + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ +package common.net.util.internal.logging; + +import java.util.logging.Level; +import java.util.logging.LogRecord; +import java.util.logging.Logger; + +/** + * java.util.logging + * logger. + */ +class JdkLogger extends AbstractInternalLogger { + + private static final long serialVersionUID = -1767272577989225979L; + + final transient Logger logger; + + JdkLogger(Logger logger) { + super(logger.getName()); + this.logger = logger; + } + + /** + * Is this logger instance enabled for the FINEST level? + * + * @return True if this Logger is enabled for level FINEST, false otherwise. + */ + @Override + public boolean isTraceEnabled() { + return logger.isLoggable(Level.FINEST); + } + + /** + * Log a message object at level FINEST. + * + * @param msg + * - the message object to be logged + */ + @Override + public void trace(String msg) { + if (logger.isLoggable(Level.FINEST)) { + log(SELF, Level.FINEST, msg, null); + } + } + + /** + * Log a message at level FINEST according to the specified format and + * argument. + * + *

+ * This form avoids superfluous object creation when the logger is disabled + * for level FINEST. + *

+ * + * @param format + * the format string + * @param arg + * the argument + */ + @Override + public void trace(String format, Object arg) { + if (logger.isLoggable(Level.FINEST)) { + FormattingTuple ft = MessageFormatter.format(format, arg); + log(SELF, Level.FINEST, ft.getMessage(), ft.getThrowable()); + } + } + + /** + * Log a message at level FINEST according to the specified format and + * arguments. + * + *

+ * This form avoids superfluous object creation when the logger is disabled + * for the FINEST level. + *

+ * + * @param format + * the format string + * @param argA + * the first argument + * @param argB + * the second argument + */ + @Override + public void trace(String format, Object argA, Object argB) { + if (logger.isLoggable(Level.FINEST)) { + FormattingTuple ft = MessageFormatter.format(format, argA, argB); + log(SELF, Level.FINEST, ft.getMessage(), ft.getThrowable()); + } + } + + /** + * Log a message at level FINEST according to the specified format and + * arguments. + * + *

+ * This form avoids superfluous object creation when the logger is disabled + * for the FINEST level. + *

+ * + * @param format + * the format string + * @param argArray + * an array of arguments + */ + @Override + public void trace(String format, Object... argArray) { + if (logger.isLoggable(Level.FINEST)) { + FormattingTuple ft = MessageFormatter.arrayFormat(format, argArray); + log(SELF, Level.FINEST, ft.getMessage(), ft.getThrowable()); + } + } + + /** + * Log an exception (throwable) at level FINEST with an accompanying message. + * + * @param msg + * the message accompanying the exception + * @param t + * the exception (throwable) to log + */ + @Override + public void trace(String msg, Throwable t) { + if (logger.isLoggable(Level.FINEST)) { + log(SELF, Level.FINEST, msg, t); + } + } + + /** + * Is this logger instance enabled for the FINE level? + * + * @return True if this Logger is enabled for level FINE, false otherwise. + */ + @Override + public boolean isDebugEnabled() { + return logger.isLoggable(Level.FINE); + } + + /** + * Log a message object at level FINE. + * + * @param msg + * - the message object to be logged + */ + @Override + public void debug(String msg) { + if (logger.isLoggable(Level.FINE)) { + log(SELF, Level.FINE, msg, null); + } + } + + /** + * Log a message at level FINE according to the specified format and argument. + * + *

+ * This form avoids superfluous object creation when the logger is disabled + * for level FINE. + *

+ * + * @param format + * the format string + * @param arg + * the argument + */ + @Override + public void debug(String format, Object arg) { + if (logger.isLoggable(Level.FINE)) { + FormattingTuple ft = MessageFormatter.format(format, arg); + log(SELF, Level.FINE, ft.getMessage(), ft.getThrowable()); + } + } + + /** + * Log a message at level FINE according to the specified format and + * arguments. + * + *

+ * This form avoids superfluous object creation when the logger is disabled + * for the FINE level. + *

+ * + * @param format + * the format string + * @param argA + * the first argument + * @param argB + * the second argument + */ + @Override + public void debug(String format, Object argA, Object argB) { + if (logger.isLoggable(Level.FINE)) { + FormattingTuple ft = MessageFormatter.format(format, argA, argB); + log(SELF, Level.FINE, ft.getMessage(), ft.getThrowable()); + } + } + + /** + * Log a message at level FINE according to the specified format and + * arguments. + * + *

+ * This form avoids superfluous object creation when the logger is disabled + * for the FINE level. + *

+ * + * @param format + * the format string + * @param argArray + * an array of arguments + */ + @Override + public void debug(String format, Object... argArray) { + if (logger.isLoggable(Level.FINE)) { + FormattingTuple ft = MessageFormatter.arrayFormat(format, argArray); + log(SELF, Level.FINE, ft.getMessage(), ft.getThrowable()); + } + } + + /** + * Log an exception (throwable) at level FINE with an accompanying message. + * + * @param msg + * the message accompanying the exception + * @param t + * the exception (throwable) to log + */ + @Override + public void debug(String msg, Throwable t) { + if (logger.isLoggable(Level.FINE)) { + log(SELF, Level.FINE, msg, t); + } + } + + /** + * Is this logger instance enabled for the INFO level? + * + * @return True if this Logger is enabled for the INFO level, false otherwise. + */ + @Override + public boolean isInfoEnabled() { + return logger.isLoggable(Level.INFO); + } + + /** + * Log a message object at the INFO level. + * + * @param msg + * - the message object to be logged + */ + @Override + public void info(String msg) { + if (logger.isLoggable(Level.INFO)) { + log(SELF, Level.INFO, msg, null); + } + } + + /** + * Log a message at level INFO according to the specified format and argument. + * + *

+ * This form avoids superfluous object creation when the logger is disabled + * for the INFO level. + *

+ * + * @param format + * the format string + * @param arg + * the argument + */ + @Override + public void info(String format, Object arg) { + if (logger.isLoggable(Level.INFO)) { + FormattingTuple ft = MessageFormatter.format(format, arg); + log(SELF, Level.INFO, ft.getMessage(), ft.getThrowable()); + } + } + + /** + * Log a message at the INFO level according to the specified format and + * arguments. + * + *

+ * This form avoids superfluous object creation when the logger is disabled + * for the INFO level. + *

+ * + * @param format + * the format string + * @param argA + * the first argument + * @param argB + * the second argument + */ + @Override + public void info(String format, Object argA, Object argB) { + if (logger.isLoggable(Level.INFO)) { + FormattingTuple ft = MessageFormatter.format(format, argA, argB); + log(SELF, Level.INFO, ft.getMessage(), ft.getThrowable()); + } + } + + /** + * Log a message at level INFO according to the specified format and + * arguments. + * + *

+ * This form avoids superfluous object creation when the logger is disabled + * for the INFO level. + *

+ * + * @param format + * the format string + * @param argArray + * an array of arguments + */ + @Override + public void info(String format, Object... argArray) { + if (logger.isLoggable(Level.INFO)) { + FormattingTuple ft = MessageFormatter.arrayFormat(format, argArray); + log(SELF, Level.INFO, ft.getMessage(), ft.getThrowable()); + } + } + + /** + * Log an exception (throwable) at the INFO level with an accompanying + * message. + * + * @param msg + * the message accompanying the exception + * @param t + * the exception (throwable) to log + */ + @Override + public void info(String msg, Throwable t) { + if (logger.isLoggable(Level.INFO)) { + log(SELF, Level.INFO, msg, t); + } + } + + /** + * Is this logger instance enabled for the WARNING level? + * + * @return True if this Logger is enabled for the WARNING level, false + * otherwise. + */ + @Override + public boolean isWarnEnabled() { + return logger.isLoggable(Level.WARNING); + } + + /** + * Log a message object at the WARNING level. + * + * @param msg + * - the message object to be logged + */ + @Override + public void warn(String msg) { + if (logger.isLoggable(Level.WARNING)) { + log(SELF, Level.WARNING, msg, null); + } + } + + /** + * Log a message at the WARNING level according to the specified format and + * argument. + * + *

+ * This form avoids superfluous object creation when the logger is disabled + * for the WARNING level. + *

+ * + * @param format + * the format string + * @param arg + * the argument + */ + @Override + public void warn(String format, Object arg) { + if (logger.isLoggable(Level.WARNING)) { + FormattingTuple ft = MessageFormatter.format(format, arg); + log(SELF, Level.WARNING, ft.getMessage(), ft.getThrowable()); + } + } + + /** + * Log a message at the WARNING level according to the specified format and + * arguments. + * + *

+ * This form avoids superfluous object creation when the logger is disabled + * for the WARNING level. + *

+ * + * @param format + * the format string + * @param argA + * the first argument + * @param argB + * the second argument + */ + @Override + public void warn(String format, Object argA, Object argB) { + if (logger.isLoggable(Level.WARNING)) { + FormattingTuple ft = MessageFormatter.format(format, argA, argB); + log(SELF, Level.WARNING, ft.getMessage(), ft.getThrowable()); + } + } + + /** + * Log a message at level WARNING according to the specified format and + * arguments. + * + *

+ * This form avoids superfluous object creation when the logger is disabled + * for the WARNING level. + *

+ * + * @param format + * the format string + * @param argArray + * an array of arguments + */ + @Override + public void warn(String format, Object... argArray) { + if (logger.isLoggable(Level.WARNING)) { + FormattingTuple ft = MessageFormatter.arrayFormat(format, argArray); + log(SELF, Level.WARNING, ft.getMessage(), ft.getThrowable()); + } + } + + /** + * Log an exception (throwable) at the WARNING level with an accompanying + * message. + * + * @param msg + * the message accompanying the exception + * @param t + * the exception (throwable) to log + */ + @Override + public void warn(String msg, Throwable t) { + if (logger.isLoggable(Level.WARNING)) { + log(SELF, Level.WARNING, msg, t); + } + } + + /** + * Is this logger instance enabled for level SEVERE? + * + * @return True if this Logger is enabled for level SEVERE, false otherwise. + */ + @Override + public boolean isErrorEnabled() { + return logger.isLoggable(Level.SEVERE); + } + + /** + * Log a message object at the SEVERE level. + * + * @param msg + * - the message object to be logged + */ + @Override + public void error(String msg) { + if (logger.isLoggable(Level.SEVERE)) { + log(SELF, Level.SEVERE, msg, null); + } + } + + /** + * Log a message at the SEVERE level according to the specified format and + * argument. + * + *

+ * This form avoids superfluous object creation when the logger is disabled + * for the SEVERE level. + *

+ * + * @param format + * the format string + * @param arg + * the argument + */ + @Override + public void error(String format, Object arg) { + if (logger.isLoggable(Level.SEVERE)) { + FormattingTuple ft = MessageFormatter.format(format, arg); + log(SELF, Level.SEVERE, ft.getMessage(), ft.getThrowable()); + } + } + + /** + * Log a message at the SEVERE level according to the specified format and + * arguments. + * + *

+ * This form avoids superfluous object creation when the logger is disabled + * for the SEVERE level. + *

+ * + * @param format + * the format string + * @param argA + * the first argument + * @param argB + * the second argument + */ + @Override + public void error(String format, Object argA, Object argB) { + if (logger.isLoggable(Level.SEVERE)) { + FormattingTuple ft = MessageFormatter.format(format, argA, argB); + log(SELF, Level.SEVERE, ft.getMessage(), ft.getThrowable()); + } + } + + /** + * Log a message at level SEVERE according to the specified format and + * arguments. + * + *

+ * This form avoids superfluous object creation when the logger is disabled + * for the SEVERE level. + *

+ * + * @param format + * the format string + * @param arguments + * an array of arguments + */ + @Override + public void error(String format, Object... arguments) { + if (logger.isLoggable(Level.SEVERE)) { + FormattingTuple ft = MessageFormatter.arrayFormat(format, arguments); + log(SELF, Level.SEVERE, ft.getMessage(), ft.getThrowable()); + } + } + + /** + * Log an exception (throwable) at the SEVERE level with an accompanying + * message. + * + * @param msg + * the message accompanying the exception + * @param t + * the exception (throwable) to log + */ + @Override + public void error(String msg, Throwable t) { + if (logger.isLoggable(Level.SEVERE)) { + log(SELF, Level.SEVERE, msg, t); + } + } + + /** + * Log the message at the specified level with the specified throwable if any. + * This method creates a LogRecord and fills in caller date before calling + * this instance's JDK14 logger. + * + * See bug report #13 for more details. + */ + private void log(String callerFQCN, Level level, String msg, Throwable t) { + // millis and thread are filled by the constructor + LogRecord record = new LogRecord(level, msg); + record.setLoggerName(name()); + record.setThrown(t); + fillCallerData(callerFQCN, record); + logger.log(record); + } + + static final String SELF = JdkLogger.class.getName(); + static final String SUPER = AbstractInternalLogger.class.getName(); + + /** + * Fill in caller data if possible. + * + * @param record + * The record to update + */ + private static void fillCallerData(String callerFQCN, LogRecord record) { + StackTraceElement[] steArray = new Throwable().getStackTrace(); + + int selfIndex = -1; + for (int i = 0; i < steArray.length; i++) { + final String className = steArray[i].getClassName(); + if (className.equals(callerFQCN) || className.equals(SUPER)) { + selfIndex = i; + break; + } + } + + int found = -1; + for (int i = selfIndex + 1; i < steArray.length; i++) { + final String className = steArray[i].getClassName(); + if (!(className.equals(callerFQCN) || className.equals(SUPER))) { + found = i; + break; + } + } + + if (found != -1) { + StackTraceElement ste = steArray[found]; + // setting the class name has the side effect of setting + // the needToInferCaller variable to false. + record.setSourceClassName(ste.getClassName()); + record.setSourceMethodName(ste.getMethodName()); + } + } +} diff --git a/common/src/common/net/util/internal/logging/JdkLoggerFactory.java b/common/src/common/net/util/internal/logging/JdkLoggerFactory.java new file mode 100644 index 0000000..a1e88dd --- /dev/null +++ b/common/src/common/net/util/internal/logging/JdkLoggerFactory.java @@ -0,0 +1,32 @@ +/* + * Copyright 2012 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ +package common.net.util.internal.logging; + + +import java.util.logging.Logger; + +/** + * Logger factory which creates a + * java.util.logging + * logger. + */ +public class JdkLoggerFactory extends InternalLoggerFactory { + + @Override + public InternalLogger newInstance(String name) { + return new JdkLogger(Logger.getLogger(name)); + } +} diff --git a/common/src/common/net/util/internal/logging/MessageFormatter.java b/common/src/common/net/util/internal/logging/MessageFormatter.java new file mode 100644 index 0000000..a1e956a --- /dev/null +++ b/common/src/common/net/util/internal/logging/MessageFormatter.java @@ -0,0 +1,427 @@ +/* + * Copyright 2013 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ +/** + * Copyright (c) 2004-2011 QOS.ch + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ +package common.net.util.internal.logging; + +import java.util.HashMap; +import java.util.Map; + +// contributors: lizongbo: proposed special treatment of array parameter values +// Joern Huxhorn: pointed out double[] omission, suggested deep array copy + +/** + * Formats messages according to very simple substitution rules. Substitutions + * can be made 1, 2 or more arguments. + *

+ *

+ * For example, + *

+ *

+ * MessageFormatter.format("Hi {}.", "there")
+ * 
+ *

+ * will return the string "Hi there.". + *

+ * The {} pair is called the formatting anchor. It serves to designate + * the location where arguments need to be substituted within the message + * pattern. + *

+ * In case your message contains the '{' or the '}' character, you do not have + * to do anything special unless the '}' character immediately follows '{'. For + * example, + *

+ *

+ * MessageFormatter.format("Set {1,2,3} is not equal to {}.", "1,2");
+ * 
+ *

+ * will return the string "Set {1,2,3} is not equal to 1,2.". + *

+ *

+ * If for whatever reason you need to place the string "{}" in the message + * without its formatting anchor meaning, then you need to escape the + * '{' character with '\', that is the backslash character. Only the '{' + * character should be escaped. There is no need to escape the '}' character. + * For example, + *

+ *

+ * MessageFormatter.format("Set \\{} is not equal to {}.", "1,2");
+ * 
+ *

+ * will return the string "Set {} is not equal to 1,2.". + *

+ *

+ * The escaping behavior just described can be overridden by escaping the escape + * character '\'. Calling + *

+ *

+ * MessageFormatter.format("File name is C:\\\\{}.", "file.zip");
+ * 
+ *

+ * will return the string "File name is C:\file.zip". + *

+ *

+ * The formatting conventions are different than those of {@link MessageFormat} + * which ships with the Java platform. This is justified by the fact that + * SLF4J's implementation is 10 times faster than that of {@link MessageFormat}. + * This local performance difference is both measurable and significant in the + * larger context of the complete logging processing chain. + *

+ *

+ * See also {@link #format(String, Object)}, + * {@link #format(String, Object, Object)} and + * {@link #arrayFormat(String, Object[])} methods for more details. + */ +final class MessageFormatter { + static final char DELIM_START = '{'; + static final char DELIM_STOP = '}'; + static final String DELIM_STR = "{}"; + private static final char ESCAPE_CHAR = '\\'; + + /** + * Performs single argument substitution for the 'messagePattern' passed as + * parameter. + *

+ * For example, + *

+ *

+     * MessageFormatter.format("Hi {}.", "there");
+     * 
+ *

+ * will return the string "Hi there.". + *

+ * + * @param messagePattern The message pattern which will be parsed and formatted + * @param arg The argument to be substituted in place of the formatting anchor + * @return The formatted message + */ + static FormattingTuple format(String messagePattern, Object arg) { + return arrayFormat(messagePattern, new Object[]{arg}); + } + + /** + * Performs a two argument substitution for the 'messagePattern' passed as + * parameter. + *

+ * For example, + *

+ *

+     * MessageFormatter.format("Hi {}. My name is {}.", "Alice", "Bob");
+     * 
+ *

+ * will return the string "Hi Alice. My name is Bob.". + * + * @param messagePattern The message pattern which will be parsed and formatted + * @param argA The argument to be substituted in place of the first formatting + * anchor + * @param argB The argument to be substituted in place of the second formatting + * anchor + * @return The formatted message + */ + static FormattingTuple format(final String messagePattern, + Object argA, Object argB) { + return arrayFormat(messagePattern, new Object[]{argA, argB}); + } + + static Throwable getThrowableCandidate(Object[] argArray) { + if (argArray == null || argArray.length == 0) { + return null; + } + + final Object lastEntry = argArray[argArray.length - 1]; + if (lastEntry instanceof Throwable) { + return (Throwable) lastEntry; + } + return null; + } + + /** + * Same principle as the {@link #format(String, Object)} and + * {@link #format(String, Object, Object)} methods except that any number of + * arguments can be passed in an array. + * + * @param messagePattern The message pattern which will be parsed and formatted + * @param argArray An array of arguments to be substituted in place of formatting + * anchors + * @return The formatted message + */ + static FormattingTuple arrayFormat(final String messagePattern, + final Object[] argArray) { + + Throwable throwableCandidate = getThrowableCandidate(argArray); + + if (messagePattern == null) { + return new FormattingTuple(null, argArray, throwableCandidate); + } + + if (argArray == null) { + return new FormattingTuple(messagePattern); + } + + int i = 0; + int j; + StringBuffer sbuf = new StringBuffer(messagePattern.length() + 50); + + int L; + for (L = 0; L < argArray.length; L++) { + + j = messagePattern.indexOf(DELIM_STR, i); + + if (j == -1) { + // no more variables + if (i == 0) { // this is a simple string + return new FormattingTuple(messagePattern, argArray, + throwableCandidate); + } else { // add the tail string which contains no variables and return + // the result. + sbuf.append(messagePattern.substring(i, messagePattern.length())); + return new FormattingTuple(sbuf.toString(), argArray, + throwableCandidate); + } + } else { + if (isEscapedDelimeter(messagePattern, j)) { + if (!isDoubleEscaped(messagePattern, j)) { + L--; // DELIM_START was escaped, thus should not be incremented + sbuf.append(messagePattern.substring(i, j - 1)); + sbuf.append(DELIM_START); + i = j + 1; + } else { + // The escape character preceding the delimiter start is + // itself escaped: "abc x:\\{}" + // we have to consume one backward slash + sbuf.append(messagePattern.substring(i, j - 1)); + deeplyAppendParameter(sbuf, argArray[L], new HashMap()); + i = j + 2; + } + } else { + // normal case + sbuf.append(messagePattern.substring(i, j)); + deeplyAppendParameter(sbuf, argArray[L], new HashMap()); + i = j + 2; + } + } + } + // append the characters following the last {} pair. + sbuf.append(messagePattern.substring(i, messagePattern.length())); + if (L < argArray.length - 1) { + return new FormattingTuple(sbuf.toString(), argArray, throwableCandidate); + } else { + return new FormattingTuple(sbuf.toString(), argArray, null); + } + } + + static boolean isEscapedDelimeter(String messagePattern, + int delimeterStartIndex) { + + if (delimeterStartIndex == 0) { + return false; + } + return messagePattern.charAt(delimeterStartIndex - 1) == ESCAPE_CHAR; + } + + static boolean isDoubleEscaped(String messagePattern, + int delimeterStartIndex) { + return delimeterStartIndex >= 2 && messagePattern.charAt(delimeterStartIndex - 2) == ESCAPE_CHAR; + } + + // special treatment of array values was suggested by 'lizongbo' + private static void deeplyAppendParameter(StringBuffer sbuf, Object o, + Map seenMap) { + if (o == null) { + sbuf.append("null"); + return; + } + if (!o.getClass().isArray()) { + safeObjectAppend(sbuf, o); + } else { + // check for primitive array types because they + // unfortunately cannot be cast to Object[] + if (o instanceof boolean[]) { + booleanArrayAppend(sbuf, (boolean[]) o); + } else if (o instanceof byte[]) { + byteArrayAppend(sbuf, (byte[]) o); + } else if (o instanceof char[]) { + charArrayAppend(sbuf, (char[]) o); + } else if (o instanceof short[]) { + shortArrayAppend(sbuf, (short[]) o); + } else if (o instanceof int[]) { + intArrayAppend(sbuf, (int[]) o); + } else if (o instanceof long[]) { + longArrayAppend(sbuf, (long[]) o); + } else if (o instanceof float[]) { + floatArrayAppend(sbuf, (float[]) o); + } else if (o instanceof double[]) { + doubleArrayAppend(sbuf, (double[]) o); + } else { + objectArrayAppend(sbuf, (Object[]) o, seenMap); + } + } + } + + private static void safeObjectAppend(StringBuffer sbuf, Object o) { + try { + String oAsString = o.toString(); + sbuf.append(oAsString); + } catch (Throwable t) { + System.err + .println("SLF4J: Failed toString() invocation on an object of type [" + + o.getClass().getName() + ']'); + t.printStackTrace(); + sbuf.append("[FAILED toString()]"); + } + } + + private static void objectArrayAppend(StringBuffer sbuf, Object[] a, + Map seenMap) { + sbuf.append('['); + if (!seenMap.containsKey(a)) { + seenMap.put(a, null); + final int len = a.length; + for (int i = 0; i < len; i++) { + deeplyAppendParameter(sbuf, a[i], seenMap); + if (i != len - 1) { + sbuf.append(", "); + } + } + // allow repeats in siblings + seenMap.remove(a); + } else { + sbuf.append("..."); + } + sbuf.append(']'); + } + + private static void booleanArrayAppend(StringBuffer sbuf, boolean[] a) { + sbuf.append('['); + final int len = a.length; + for (int i = 0; i < len; i++) { + sbuf.append(a[i]); + if (i != len - 1) { + sbuf.append(", "); + } + } + sbuf.append(']'); + } + + private static void byteArrayAppend(StringBuffer sbuf, byte[] a) { + sbuf.append('['); + final int len = a.length; + for (int i = 0; i < len; i++) { + sbuf.append(a[i]); + if (i != len - 1) { + sbuf.append(", "); + } + } + sbuf.append(']'); + } + + private static void charArrayAppend(StringBuffer sbuf, char[] a) { + sbuf.append('['); + final int len = a.length; + for (int i = 0; i < len; i++) { + sbuf.append(a[i]); + if (i != len - 1) { + sbuf.append(", "); + } + } + sbuf.append(']'); + } + + private static void shortArrayAppend(StringBuffer sbuf, short[] a) { + sbuf.append('['); + final int len = a.length; + for (int i = 0; i < len; i++) { + sbuf.append(a[i]); + if (i != len - 1) { + sbuf.append(", "); + } + } + sbuf.append(']'); + } + + private static void intArrayAppend(StringBuffer sbuf, int[] a) { + sbuf.append('['); + final int len = a.length; + for (int i = 0; i < len; i++) { + sbuf.append(a[i]); + if (i != len - 1) { + sbuf.append(", "); + } + } + sbuf.append(']'); + } + + private static void longArrayAppend(StringBuffer sbuf, long[] a) { + sbuf.append('['); + final int len = a.length; + for (int i = 0; i < len; i++) { + sbuf.append(a[i]); + if (i != len - 1) { + sbuf.append(", "); + } + } + sbuf.append(']'); + } + + private static void floatArrayAppend(StringBuffer sbuf, float[] a) { + sbuf.append('['); + final int len = a.length; + for (int i = 0; i < len; i++) { + sbuf.append(a[i]); + if (i != len - 1) { + sbuf.append(", "); + } + } + sbuf.append(']'); + } + + private static void doubleArrayAppend(StringBuffer sbuf, double[] a) { + sbuf.append('['); + final int len = a.length; + for (int i = 0; i < len; i++) { + sbuf.append(a[i]); + if (i != len - 1) { + sbuf.append(", "); + } + } + sbuf.append(']'); + } + + private MessageFormatter() { + } +} diff --git a/common/src/common/network/CompressionDecoder.java b/common/src/common/network/CompressionDecoder.java index e681218..c4b28db 100755 --- a/common/src/common/network/CompressionDecoder.java +++ b/common/src/common/network/CompressionDecoder.java @@ -4,11 +4,11 @@ import java.util.List; import java.util.zip.DataFormatException; import java.util.zip.Inflater; -import io.netty.buffer.ByteBuf; -import io.netty.buffer.Unpooled; -import io.netty.channel.ChannelHandlerContext; -import io.netty.handler.codec.ByteToMessageDecoder; -import io.netty.handler.codec.DecoderException; +import common.net.buffer.ByteBuf; +import common.net.buffer.Unpooled; +import common.net.channel.ChannelHandlerContext; +import common.net.handler.codec.ByteToMessageDecoder; +import common.net.handler.codec.DecoderException; public class CompressionDecoder extends ByteToMessageDecoder { private final Inflater inflater; diff --git a/common/src/common/network/CompressionEncoder.java b/common/src/common/network/CompressionEncoder.java index 8d975f2..c2cf62f 100755 --- a/common/src/common/network/CompressionEncoder.java +++ b/common/src/common/network/CompressionEncoder.java @@ -2,9 +2,9 @@ package common.network; import java.util.zip.Deflater; -import io.netty.buffer.ByteBuf; -import io.netty.channel.ChannelHandlerContext; -import io.netty.handler.codec.MessageToByteEncoder; +import common.net.buffer.ByteBuf; +import common.net.channel.ChannelHandlerContext; +import common.net.handler.codec.MessageToByteEncoder; public class CompressionEncoder extends MessageToByteEncoder { private final byte[] buffer = new byte[8192]; diff --git a/common/src/common/network/EncryptionCodec.java b/common/src/common/network/EncryptionCodec.java index 2598ecc..4a6d981 100644 --- a/common/src/common/network/EncryptionCodec.java +++ b/common/src/common/network/EncryptionCodec.java @@ -1,10 +1,11 @@ package common.network; -import io.netty.buffer.ByteBuf; -import io.netty.channel.ChannelHandlerContext; import javax.crypto.Cipher; import javax.crypto.ShortBufferException; +import common.net.buffer.ByteBuf; +import common.net.channel.ChannelHandlerContext; + public class EncryptionCodec { private final Cipher cipher; private byte[] receiveBuf = new byte[0]; diff --git a/common/src/common/network/EncryptionDecoder.java b/common/src/common/network/EncryptionDecoder.java index 244773b..7c4bdb8 100644 --- a/common/src/common/network/EncryptionDecoder.java +++ b/common/src/common/network/EncryptionDecoder.java @@ -1,12 +1,13 @@ package common.network; -import io.netty.buffer.ByteBuf; -import io.netty.channel.ChannelHandlerContext; -import io.netty.handler.codec.MessageToMessageDecoder; import java.util.List; import javax.crypto.Cipher; import javax.crypto.ShortBufferException; +import common.net.buffer.ByteBuf; +import common.net.channel.ChannelHandlerContext; +import common.net.handler.codec.MessageToMessageDecoder; + public class EncryptionDecoder extends MessageToMessageDecoder { private final EncryptionCodec codec; diff --git a/common/src/common/network/EncryptionEncoder.java b/common/src/common/network/EncryptionEncoder.java index abfa860..522c815 100644 --- a/common/src/common/network/EncryptionEncoder.java +++ b/common/src/common/network/EncryptionEncoder.java @@ -1,11 +1,12 @@ package common.network; -import io.netty.buffer.ByteBuf; -import io.netty.channel.ChannelHandlerContext; -import io.netty.handler.codec.MessageToByteEncoder; import javax.crypto.Cipher; import javax.crypto.ShortBufferException; +import common.net.buffer.ByteBuf; +import common.net.channel.ChannelHandlerContext; +import common.net.handler.codec.MessageToByteEncoder; + public class EncryptionEncoder extends MessageToByteEncoder { private final EncryptionCodec codec; diff --git a/common/src/common/network/NetConnection.java b/common/src/common/network/NetConnection.java index fd9169c..38d2eb2 100755 --- a/common/src/common/network/NetConnection.java +++ b/common/src/common/network/NetConnection.java @@ -11,17 +11,17 @@ import javax.crypto.Cipher; import javax.crypto.SecretKey; import common.log.Log; +import common.net.channel.Channel; +import common.net.channel.ChannelFuture; +import common.net.channel.ChannelFutureListener; +import common.net.channel.ChannelHandlerContext; +import common.net.channel.SimpleChannelInboundHandler; +import common.net.handler.timeout.TimeoutException; +import common.net.util.AttributeKey; +import common.net.util.concurrent.Future; +import common.net.util.concurrent.GenericFutureListener; import common.network.NetHandler.ThreadQuickExitException; import common.util.EncryptUtil; -import io.netty.channel.Channel; -import io.netty.channel.ChannelFuture; -import io.netty.channel.ChannelFutureListener; -import io.netty.channel.ChannelHandlerContext; -import io.netty.channel.SimpleChannelInboundHandler; -import io.netty.handler.timeout.TimeoutException; -import io.netty.util.AttributeKey; -import io.netty.util.concurrent.Future; -import io.netty.util.concurrent.GenericFutureListener; public class NetConnection extends SimpleChannelInboundHandler { private static final boolean DEBUG = System.getProperty("network.debug") != null; diff --git a/common/src/common/network/PacketBuffer.java b/common/src/common/network/PacketBuffer.java index cbc0a3b..e7630ac 100755 --- a/common/src/common/network/PacketBuffer.java +++ b/common/src/common/network/PacketBuffer.java @@ -8,12 +8,12 @@ import common.item.ItemStack; import common.nbt.NBTLoader; import common.nbt.NBTSizeTracker; import common.nbt.NBTTagCompound; +import common.net.buffer.ByteBuf; +import common.net.buffer.ByteBufInputStream; +import common.net.buffer.ByteBufOutputStream; +import common.net.handler.codec.DecoderException; +import common.net.handler.codec.EncoderException; import common.util.BlockPos; -import io.netty.buffer.ByteBuf; -import io.netty.buffer.ByteBufInputStream; -import io.netty.buffer.ByteBufOutputStream; -import io.netty.handler.codec.DecoderException; -import io.netty.handler.codec.EncoderException; public class PacketBuffer { private static final Charset UTF_8 = Charset.forName("UTF-8"); diff --git a/common/src/common/network/PacketDecoder.java b/common/src/common/network/PacketDecoder.java index e7e25bd..121e34d 100755 --- a/common/src/common/network/PacketDecoder.java +++ b/common/src/common/network/PacketDecoder.java @@ -3,9 +3,9 @@ package common.network; import java.io.IOException; import java.util.List; -import io.netty.buffer.ByteBuf; -import io.netty.channel.ChannelHandlerContext; -import io.netty.handler.codec.ByteToMessageDecoder; +import common.net.buffer.ByteBuf; +import common.net.channel.ChannelHandlerContext; +import common.net.handler.codec.ByteToMessageDecoder; public class PacketDecoder extends ByteToMessageDecoder { private final boolean client; diff --git a/common/src/common/network/PacketEncoder.java b/common/src/common/network/PacketEncoder.java index 5a0a628..0f123ef 100755 --- a/common/src/common/network/PacketEncoder.java +++ b/common/src/common/network/PacketEncoder.java @@ -2,9 +2,9 @@ package common.network; import java.io.IOException; -import io.netty.buffer.ByteBuf; -import io.netty.channel.ChannelHandlerContext; -import io.netty.handler.codec.MessageToByteEncoder; +import common.net.buffer.ByteBuf; +import common.net.channel.ChannelHandlerContext; +import common.net.handler.codec.MessageToByteEncoder; public class PacketEncoder extends MessageToByteEncoder { private final boolean client; diff --git a/common/src/common/network/PacketPrepender.java b/common/src/common/network/PacketPrepender.java index 7a89749..943257c 100755 --- a/common/src/common/network/PacketPrepender.java +++ b/common/src/common/network/PacketPrepender.java @@ -1,8 +1,8 @@ package common.network; -import io.netty.buffer.ByteBuf; -import io.netty.channel.ChannelHandlerContext; -import io.netty.handler.codec.MessageToByteEncoder; +import common.net.buffer.ByteBuf; +import common.net.channel.ChannelHandlerContext; +import common.net.handler.codec.MessageToByteEncoder; public class PacketPrepender extends MessageToByteEncoder { protected void encode(ChannelHandlerContext context, ByteBuf buffer, ByteBuf output) throws Exception { diff --git a/common/src/common/network/PacketSplitter.java b/common/src/common/network/PacketSplitter.java index acb73d5..3874408 100755 --- a/common/src/common/network/PacketSplitter.java +++ b/common/src/common/network/PacketSplitter.java @@ -2,11 +2,11 @@ package common.network; import java.util.List; -import io.netty.buffer.ByteBuf; -import io.netty.buffer.Unpooled; -import io.netty.channel.ChannelHandlerContext; -import io.netty.handler.codec.ByteToMessageDecoder; -import io.netty.handler.codec.CorruptedFrameException; +import common.net.buffer.ByteBuf; +import common.net.buffer.Unpooled; +import common.net.channel.ChannelHandlerContext; +import common.net.handler.codec.ByteToMessageDecoder; +import common.net.handler.codec.CorruptedFrameException; public class PacketSplitter extends ByteToMessageDecoder { protected void decode(ChannelHandlerContext context, ByteBuf buffer, List output) throws Exception { diff --git a/server/src/server/Server.java b/server/src/server/Server.java index 3b70321..5d0b5cb 100755 --- a/server/src/server/Server.java +++ b/server/src/server/Server.java @@ -45,6 +45,19 @@ import common.log.Log; import common.nbt.NBTLoader; import common.nbt.NBTTagCompound; import common.nbt.NBTTagList; +import common.net.bootstrap.ServerBootstrap; +import common.net.channel.Channel; +import common.net.channel.ChannelException; +import common.net.channel.ChannelFuture; +import common.net.channel.ChannelFutureListener; +import common.net.channel.ChannelHandler; +import common.net.channel.ChannelInitializer; +import common.net.channel.ChannelOption; +import common.net.channel.nio.NioEventLoopGroup; +import common.net.channel.socket.nio.NioServerSocketChannel; +import common.net.handler.timeout.ReadTimeoutHandler; +import common.net.util.concurrent.Future; +import common.net.util.concurrent.GenericFutureListener; import common.network.IPlayer; import common.network.IThreadListener; import common.network.NetConnection; @@ -78,19 +91,6 @@ import common.util.Position; import common.util.Util; import common.util.WorldPos; import common.world.World; -import io.netty.bootstrap.ServerBootstrap; -import io.netty.channel.Channel; -import io.netty.channel.ChannelException; -import io.netty.channel.ChannelFuture; -import io.netty.channel.ChannelFutureListener; -import io.netty.channel.ChannelHandler; -import io.netty.channel.ChannelInitializer; -import io.netty.channel.ChannelOption; -import io.netty.channel.nio.NioEventLoopGroup; -import io.netty.channel.socket.nio.NioServerSocketChannel; -import io.netty.handler.timeout.ReadTimeoutHandler; -import io.netty.util.concurrent.Future; -import io.netty.util.concurrent.GenericFutureListener; import server.biome.GenBiome; import server.clipboard.ReorderRegistry; import server.clipboard.RotationRegistry; diff --git a/server/src/server/network/Player.java b/server/src/server/network/Player.java index e8ce73a..f45fafb 100755 --- a/server/src/server/network/Player.java +++ b/server/src/server/network/Player.java @@ -48,6 +48,8 @@ import common.item.ItemStack; import common.log.Log; import common.nbt.NBTTagCompound; import common.nbt.NBTTagList; +import common.net.util.concurrent.Future; +import common.net.util.concurrent.GenericFutureListener; import common.network.IPlayer; import common.network.NetConnection; import common.network.NetHandler; @@ -120,8 +122,6 @@ import common.village.MerchantRecipeList; import common.world.BlockArray; import common.world.State; import common.world.World; -import io.netty.util.concurrent.Future; -import io.netty.util.concurrent.GenericFutureListener; import server.Server; import server.clipboard.BlockTransform; import server.clipboard.ClipboardBlock; From 72df57fb3dc65a3e242334c4bdbe3515ae1a7679 Mon Sep 17 00:00:00 2001 From: Sen Date: Mon, 26 May 2025 11:13:34 +0200 Subject: [PATCH 093/200] change gitignore --- .gitignore | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index 0da720f..a390faa 100644 --- a/.gitignore +++ b/.gitignore @@ -1,8 +1,7 @@ -/common/dev +/dev /common/bin /client/bin /client/run /server/bin /server/run -/export /.metadata From ed02e531225d952dd85c22cf875254686bc4c96e Mon Sep 17 00:00:00 2001 From: Sen Date: Mon, 26 May 2025 11:15:17 +0200 Subject: [PATCH 094/200] change gitignore --- .gitignore | 2 -- 1 file changed, 2 deletions(-) diff --git a/.gitignore b/.gitignore index a390faa..82376d9 100644 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,5 @@ /dev /common/bin /client/bin -/client/run /server/bin -/server/run /.metadata From f879b060e886b69ee47c26f1d7c2f3449e7b5910 Mon Sep 17 00:00:00 2001 From: Sen Date: Mon, 26 May 2025 11:27:34 +0200 Subject: [PATCH 095/200] clean data folder history --- client/data/sounds/anvil_break.ogg | Bin 0 -> 15009 bytes client/data/sounds/anvil_land.ogg | Bin 0 -> 10244 bytes client/data/sounds/anvil_use.ogg | Bin 0 -> 14715 bytes client/data/sounds/bat_death.ogg | Bin 0 -> 9034 bytes client/data/sounds/bat_hurt1.ogg | Bin 0 -> 5207 bytes client/data/sounds/bat_hurt2.ogg | Bin 0 -> 5972 bytes client/data/sounds/bat_hurt3.ogg | Bin 0 -> 5575 bytes client/data/sounds/bat_hurt4.ogg | Bin 0 -> 5532 bytes client/data/sounds/bat_idle1.ogg | Bin 0 -> 6298 bytes client/data/sounds/bat_idle2.ogg | Bin 0 -> 5127 bytes client/data/sounds/bat_idle3.ogg | Bin 0 -> 4945 bytes client/data/sounds/bat_idle4.ogg | Bin 0 -> 5867 bytes client/data/sounds/bat_takeoff.ogg | Bin 0 -> 8877 bytes client/data/sounds/blast.ogg | Bin 0 -> 11694 bytes client/data/sounds/blast_far.ogg | Bin 0 -> 15534 bytes client/data/sounds/bow.ogg | Bin 0 -> 6976 bytes client/data/sounds/bowhit1.ogg | Bin 0 -> 11658 bytes client/data/sounds/bowhit2.ogg | Bin 0 -> 10678 bytes client/data/sounds/bowhit3.ogg | Bin 0 -> 13949 bytes client/data/sounds/bowhit4.ogg | Bin 0 -> 16166 bytes client/data/sounds/break.ogg | Bin 0 -> 6816 bytes client/data/sounds/cat_hitt1.ogg | Bin 0 -> 7387 bytes client/data/sounds/cat_hitt2.ogg | Bin 0 -> 8798 bytes client/data/sounds/cat_hitt3.ogg | Bin 0 -> 7212 bytes client/data/sounds/cat_meow1.ogg | Bin 0 -> 9585 bytes client/data/sounds/cat_meow2.ogg | Bin 0 -> 9198 bytes client/data/sounds/cat_meow3.ogg | Bin 0 -> 9438 bytes client/data/sounds/cat_meow4.ogg | Bin 0 -> 9301 bytes client/data/sounds/cat_purreow1.ogg | Bin 0 -> 11379 bytes client/data/sounds/cat_purreow2.ogg | Bin 0 -> 11463 bytes client/data/sounds/chestclosed.ogg | Bin 0 -> 8086 bytes client/data/sounds/chestopen.ogg | Bin 0 -> 8897 bytes client/data/sounds/chicken_hurt1.ogg | Bin 0 -> 8133 bytes client/data/sounds/chicken_hurt2.ogg | Bin 0 -> 6490 bytes client/data/sounds/chicken_say1.ogg | Bin 0 -> 8360 bytes client/data/sounds/chicken_say2.ogg | Bin 0 -> 10023 bytes client/data/sounds/chicken_say3.ogg | Bin 0 -> 7524 bytes client/data/sounds/click.ogg | Bin 0 -> 5019 bytes client/data/sounds/cloth1.ogg | Bin 0 -> 5081 bytes client/data/sounds/cloth2.ogg | Bin 0 -> 5154 bytes client/data/sounds/cloth3.ogg | Bin 0 -> 5083 bytes client/data/sounds/cloth4.ogg | Bin 0 -> 5160 bytes client/data/sounds/cow_hurt1.ogg | Bin 0 -> 6850 bytes client/data/sounds/cow_hurt2.ogg | Bin 0 -> 6752 bytes client/data/sounds/cow_hurt3.ogg | Bin 0 -> 6994 bytes client/data/sounds/cow_say1.ogg | Bin 0 -> 13865 bytes client/data/sounds/cow_say2.ogg | Bin 0 -> 13945 bytes client/data/sounds/cow_say3.ogg | Bin 0 -> 17586 bytes client/data/sounds/cow_say4.ogg | Bin 0 -> 12626 bytes client/data/sounds/cut.ogg | Bin 0 -> 7153 bytes client/data/sounds/door_close.ogg | Bin 0 -> 6766 bytes client/data/sounds/door_open.ogg | Bin 0 -> 7994 bytes client/data/sounds/dragon_growl1.ogg | Bin 0 -> 27205 bytes client/data/sounds/dragon_growl2.ogg | Bin 0 -> 27766 bytes client/data/sounds/dragon_growl3.ogg | Bin 0 -> 28022 bytes client/data/sounds/dragon_growl4.ogg | Bin 0 -> 26210 bytes client/data/sounds/dragon_wings1.ogg | Bin 0 -> 10950 bytes client/data/sounds/dragon_wings2.ogg | Bin 0 -> 10591 bytes client/data/sounds/dragon_wings3.ogg | Bin 0 -> 10710 bytes client/data/sounds/dragon_wings4.ogg | Bin 0 -> 11768 bytes client/data/sounds/dragon_wings5.ogg | Bin 0 -> 11879 bytes client/data/sounds/dragon_wings6.ogg | Bin 0 -> 11352 bytes client/data/sounds/drink.ogg | Bin 0 -> 8085 bytes client/data/sounds/eat1.ogg | Bin 0 -> 6087 bytes client/data/sounds/eat2.ogg | Bin 0 -> 5992 bytes client/data/sounds/eat3.ogg | Bin 0 -> 6104 bytes client/data/sounds/explode1.ogg | Bin 0 -> 22919 bytes client/data/sounds/explode2.ogg | Bin 0 -> 27903 bytes client/data/sounds/explode3.ogg | Bin 0 -> 28078 bytes client/data/sounds/explode4.ogg | Bin 0 -> 27496 bytes client/data/sounds/fallbig1.ogg | Bin 0 -> 11808 bytes client/data/sounds/fallbig2.ogg | Bin 0 -> 9147 bytes client/data/sounds/fallsmall.ogg | Bin 0 -> 8060 bytes client/data/sounds/fire.ogg | Bin 0 -> 22862 bytes client/data/sounds/fireball.ogg | Bin 0 -> 9151 bytes client/data/sounds/fizz.ogg | Bin 0 -> 13942 bytes client/data/sounds/fuse.ogg | Bin 0 -> 27058 bytes client/data/sounds/glass1.ogg | Bin 0 -> 9452 bytes client/data/sounds/glass2.ogg | Bin 0 -> 9358 bytes client/data/sounds/glass3.ogg | Bin 0 -> 9057 bytes client/data/sounds/grass1.ogg | Bin 0 -> 7773 bytes client/data/sounds/grass2.ogg | Bin 0 -> 7828 bytes client/data/sounds/grass3.ogg | Bin 0 -> 7718 bytes client/data/sounds/grass4.ogg | Bin 0 -> 7584 bytes client/data/sounds/gravel1.ogg | Bin 0 -> 7061 bytes client/data/sounds/gravel2.ogg | Bin 0 -> 7658 bytes client/data/sounds/gravel3.ogg | Bin 0 -> 7463 bytes client/data/sounds/gravel4.ogg | Bin 0 -> 7260 bytes client/data/sounds/hit1.ogg | Bin 0 -> 9171 bytes client/data/sounds/hit2.ogg | Bin 0 -> 10240 bytes client/data/sounds/hit3.ogg | Bin 0 -> 10532 bytes client/data/sounds/horse_angry.ogg | Bin 0 -> 10937 bytes client/data/sounds/horse_breathe1.ogg | Bin 0 -> 9136 bytes client/data/sounds/horse_breathe2.ogg | Bin 0 -> 8593 bytes client/data/sounds/horse_breathe3.ogg | Bin 0 -> 6447 bytes client/data/sounds/horse_death.ogg | Bin 0 -> 16233 bytes client/data/sounds/horse_gallop1.ogg | Bin 0 -> 8333 bytes client/data/sounds/horse_gallop2.ogg | Bin 0 -> 8854 bytes client/data/sounds/horse_gallop3.ogg | Bin 0 -> 8050 bytes client/data/sounds/horse_gallop4.ogg | Bin 0 -> 8642 bytes client/data/sounds/horse_hit1.ogg | Bin 0 -> 6364 bytes client/data/sounds/horse_hit2.ogg | Bin 0 -> 6258 bytes client/data/sounds/horse_hit3.ogg | Bin 0 -> 6661 bytes client/data/sounds/horse_hit4.ogg | Bin 0 -> 7356 bytes client/data/sounds/horse_idle1.ogg | Bin 0 -> 10371 bytes client/data/sounds/horse_idle2.ogg | Bin 0 -> 8938 bytes client/data/sounds/horse_idle3.ogg | Bin 0 -> 11526 bytes client/data/sounds/horse_jump.ogg | Bin 0 -> 7782 bytes client/data/sounds/horse_land.ogg | Bin 0 -> 9872 bytes client/data/sounds/horse_soft1.ogg | Bin 0 -> 6811 bytes client/data/sounds/horse_soft2.ogg | Bin 0 -> 6782 bytes client/data/sounds/horse_soft3.ogg | Bin 0 -> 6609 bytes client/data/sounds/horse_soft4.ogg | Bin 0 -> 7351 bytes client/data/sounds/horse_soft5.ogg | Bin 0 -> 7540 bytes client/data/sounds/horse_soft6.ogg | Bin 0 -> 7297 bytes client/data/sounds/horse_wood1.ogg | Bin 0 -> 8756 bytes client/data/sounds/horse_wood2.ogg | Bin 0 -> 8455 bytes client/data/sounds/horse_wood3.ogg | Bin 0 -> 7321 bytes client/data/sounds/horse_wood4.ogg | Bin 0 -> 6877 bytes client/data/sounds/horse_wood5.ogg | Bin 0 -> 8467 bytes client/data/sounds/horse_wood6.ogg | Bin 0 -> 8464 bytes client/data/sounds/ignite.ogg | Bin 0 -> 6870 bytes client/data/sounds/large_blast.ogg | Bin 0 -> 18137 bytes client/data/sounds/large_blast_far.ogg | Bin 0 -> 22782 bytes client/data/sounds/launch.ogg | Bin 0 -> 16449 bytes client/data/sounds/lava.ogg | Bin 0 -> 65643 bytes client/data/sounds/lavapop.ogg | Bin 0 -> 4755 bytes client/data/sounds/levelup.ogg | Bin 0 -> 32198 bytes client/data/sounds/magma.ogg | Bin 0 -> 38826 bytes client/data/sounds/magmapop.ogg | Bin 0 -> 4841 bytes client/data/sounds/metal1.ogg | Bin 0 -> 9294 bytes client/data/sounds/metal2.ogg | Bin 0 -> 9569 bytes client/data/sounds/metal3.ogg | Bin 0 -> 9467 bytes client/data/sounds/metalhit1.ogg | Bin 0 -> 7454 bytes client/data/sounds/metalhit2.ogg | Bin 0 -> 7529 bytes client/data/sounds/minecart_base.ogg | Bin 0 -> 18810 bytes client/data/sounds/minecart_inside.ogg | Bin 0 -> 51889 bytes client/data/sounds/molten.ogg | Bin 0 -> 63659 bytes client/data/sounds/note.ogg | Bin 0 -> 7382 bytes client/data/sounds/old_explode.ogg | Bin 0 -> 10844 bytes client/data/sounds/orb.ogg | Bin 0 -> 7535 bytes client/data/sounds/pig_death.ogg | Bin 0 -> 8336 bytes client/data/sounds/pig_say1.ogg | Bin 0 -> 6084 bytes client/data/sounds/pig_say2.ogg | Bin 0 -> 7973 bytes client/data/sounds/pig_say3.ogg | Bin 0 -> 6239 bytes client/data/sounds/piston_in.ogg | Bin 0 -> 7398 bytes client/data/sounds/piston_out.ogg | Bin 0 -> 7384 bytes client/data/sounds/plop.ogg | Bin 0 -> 4886 bytes client/data/sounds/pop.ogg | Bin 0 -> 4026 bytes client/data/sounds/rabbit_bunnymurder.ogg | Bin 0 -> 7378 bytes client/data/sounds/rabbit_hop1.ogg | Bin 0 -> 5748 bytes client/data/sounds/rabbit_hop2.ogg | Bin 0 -> 6170 bytes client/data/sounds/rabbit_hop3.ogg | Bin 0 -> 5821 bytes client/data/sounds/rabbit_hop4.ogg | Bin 0 -> 5490 bytes client/data/sounds/rabbit_hurt1.ogg | Bin 0 -> 6779 bytes client/data/sounds/rabbit_hurt2.ogg | Bin 0 -> 6368 bytes client/data/sounds/rabbit_hurt3.ogg | Bin 0 -> 6820 bytes client/data/sounds/rabbit_hurt4.ogg | Bin 0 -> 6923 bytes client/data/sounds/rabbit_idle1.ogg | Bin 0 -> 5943 bytes client/data/sounds/rabbit_idle2.ogg | Bin 0 -> 7111 bytes client/data/sounds/rabbit_idle3.ogg | Bin 0 -> 5893 bytes client/data/sounds/rabbit_idle4.ogg | Bin 0 -> 8690 bytes client/data/sounds/rain1.ogg | Bin 0 -> 18951 bytes client/data/sounds/rain2.ogg | Bin 0 -> 18733 bytes client/data/sounds/rain3.ogg | Bin 0 -> 18789 bytes client/data/sounds/rain4.ogg | Bin 0 -> 18740 bytes client/data/sounds/sand1.ogg | Bin 0 -> 5997 bytes client/data/sounds/sand2.ogg | Bin 0 -> 5992 bytes client/data/sounds/sand3.ogg | Bin 0 -> 5978 bytes client/data/sounds/sand4.ogg | Bin 0 -> 5969 bytes client/data/sounds/sheep_say1.ogg | Bin 0 -> 11515 bytes client/data/sounds/sheep_say2.ogg | Bin 0 -> 10308 bytes client/data/sounds/sheep_say3.ogg | Bin 0 -> 11908 bytes client/data/sounds/slime_attack1.ogg | Bin 0 -> 8443 bytes client/data/sounds/slime_attack2.ogg | Bin 0 -> 7559 bytes client/data/sounds/slime_big1.ogg | Bin 0 -> 10680 bytes client/data/sounds/slime_big2.ogg | Bin 0 -> 8308 bytes client/data/sounds/slime_big3.ogg | Bin 0 -> 9820 bytes client/data/sounds/slime_big4.ogg | Bin 0 -> 10433 bytes client/data/sounds/slime_small1.ogg | Bin 0 -> 6507 bytes client/data/sounds/slime_small2.ogg | Bin 0 -> 5774 bytes client/data/sounds/slime_small3.ogg | Bin 0 -> 5640 bytes client/data/sounds/slime_small4.ogg | Bin 0 -> 5660 bytes client/data/sounds/slime_small5.ogg | Bin 0 -> 5174 bytes client/data/sounds/snow1.ogg | Bin 0 -> 6868 bytes client/data/sounds/snow2.ogg | Bin 0 -> 6883 bytes client/data/sounds/snow3.ogg | Bin 0 -> 6878 bytes client/data/sounds/snow4.ogg | Bin 0 -> 6986 bytes client/data/sounds/spell.ogg | Bin 0 -> 5980 bytes client/data/sounds/splash.ogg | Bin 0 -> 14398 bytes client/data/sounds/stone1.ogg | Bin 0 -> 7126 bytes client/data/sounds/stone2.ogg | Bin 0 -> 7086 bytes client/data/sounds/stone3.ogg | Bin 0 -> 7127 bytes client/data/sounds/stone4.ogg | Bin 0 -> 7045 bytes client/data/sounds/teleport.ogg | Bin 0 -> 10384 bytes client/data/sounds/teleport_back.ogg | Bin 0 -> 7814 bytes client/data/sounds/thunder1.ogg | Bin 0 -> 37922 bytes client/data/sounds/thunder2.ogg | Bin 0 -> 38563 bytes client/data/sounds/thunder3.ogg | Bin 0 -> 41389 bytes client/data/sounds/twinkle.ogg | Bin 0 -> 15098 bytes client/data/sounds/twinkle_far.ogg | Bin 0 -> 24969 bytes client/data/sounds/water.ogg | Bin 0 -> 27634 bytes client/data/sounds/wolf_bark1.ogg | Bin 0 -> 5919 bytes client/data/sounds/wolf_bark2.ogg | Bin 0 -> 5918 bytes client/data/sounds/wolf_bark3.ogg | Bin 0 -> 6216 bytes client/data/sounds/wolf_death.ogg | Bin 0 -> 9207 bytes client/data/sounds/wolf_growl1.ogg | Bin 0 -> 15490 bytes client/data/sounds/wolf_growl2.ogg | Bin 0 -> 12094 bytes client/data/sounds/wolf_growl3.ogg | Bin 0 -> 16806 bytes client/data/sounds/wolf_hurt1.ogg | Bin 0 -> 6748 bytes client/data/sounds/wolf_hurt2.ogg | Bin 0 -> 6549 bytes client/data/sounds/wolf_hurt3.ogg | Bin 0 -> 7334 bytes client/data/sounds/wolf_panting.ogg | Bin 0 -> 8312 bytes client/data/sounds/wolf_shake.ogg | Bin 0 -> 16145 bytes client/data/sounds/wolf_whine.ogg | Bin 0 -> 9554 bytes client/data/sounds/wood1.ogg | Bin 0 -> 7007 bytes client/data/sounds/wood2.ogg | Bin 0 -> 6865 bytes client/data/sounds/wood3.ogg | Bin 0 -> 7065 bytes client/data/sounds/wood4.ogg | Bin 0 -> 7292 bytes client/data/textures/armor/ardite_layer_1.png | Bin 0 -> 5710 bytes client/data/textures/armor/ardite_layer_2.png | Bin 0 -> 2720 bytes client/data/textures/armor/chain_layer_1.png | Bin 0 -> 927 bytes client/data/textures/armor/chain_layer_2.png | Bin 0 -> 486 bytes client/data/textures/armor/cloth_layer_1.png | Bin 0 -> 1712 bytes .../textures/armor/cloth_layer_1_overlay.png | Bin 0 -> 8593 bytes client/data/textures/armor/cloth_layer_2.png | Bin 0 -> 868 bytes .../textures/armor/cloth_layer_2_overlay.png | Bin 0 -> 6505 bytes client/data/textures/armor/diamond_layer_1.png | Bin 0 -> 1906 bytes client/data/textures/armor/diamond_layer_2.png | Bin 0 -> 687 bytes client/data/textures/armor/gold_layer_1.png | Bin 0 -> 1161 bytes client/data/textures/armor/gold_layer_2.png | Bin 0 -> 671 bytes .../data/textures/armor/horse_armor_diamond.png | Bin 0 -> 5177 bytes client/data/textures/armor/horse_armor_gold.png | Bin 0 -> 5140 bytes client/data/textures/armor/horse_armor_iron.png | Bin 0 -> 5064 bytes client/data/textures/armor/iron_layer_1.png | Bin 0 -> 1096 bytes client/data/textures/armor/iron_layer_2.png | Bin 0 -> 649 bytes client/data/textures/armor/leather_layer_1.png | Bin 0 -> 9191 bytes .../textures/armor/leather_layer_1_overlay.png | Bin 0 -> 8593 bytes client/data/textures/armor/leather_layer_2.png | Bin 0 -> 7194 bytes .../textures/armor/leather_layer_2_overlay.png | Bin 0 -> 6505 bytes client/data/textures/armor/nichun_layer_1.png | Bin 0 -> 4376 bytes client/data/textures/armor/nichun_layer_2.png | Bin 0 -> 2218 bytes client/data/textures/armor/thetium_layer_1.png | Bin 0 -> 6314 bytes client/data/textures/armor/thetium_layer_2.png | Bin 0 -> 2991 bytes client/data/textures/background.png | Bin 0 -> 975 bytes .../data/textures/blocks/acacia_door_bottom.png | Bin 0 -> 660 bytes client/data/textures/blocks/acacia_door_top.png | Bin 0 -> 629 bytes .../textures/blocks/acacia_leaves_autumn.png | Bin 0 -> 6564 bytes .../textures/blocks/acacia_leaves_snowy.png | Bin 0 -> 6110 bytes .../textures/blocks/acacia_leaves_spring.png | Bin 0 -> 598 bytes .../textures/blocks/acacia_leaves_summer.png | Bin 0 -> 6231 bytes .../textures/blocks/acacia_leaves_winter.png | Bin 0 -> 6614 bytes client/data/textures/blocks/acacia_log_bark.png | Bin 0 -> 797 bytes client/data/textures/blocks/acacia_log_top.png | Bin 0 -> 621 bytes client/data/textures/blocks/acacia_planks.png | Bin 0 -> 452 bytes client/data/textures/blocks/acacia_sapling.png | Bin 0 -> 554 bytes client/data/textures/blocks/acid_flow.png | Bin 0 -> 14956 bytes client/data/textures/blocks/acid_still.png | Bin 0 -> 18778 bytes client/data/textures/blocks/activator_rail.png | Bin 0 -> 496 bytes .../textures/blocks/activator_rail_powered.png | Bin 0 -> 542 bytes client/data/textures/blocks/allium.png | Bin 0 -> 482 bytes client/data/textures/blocks/aluminium_block.png | Bin 0 -> 1389 bytes client/data/textures/blocks/aluminium_ore.png | Bin 0 -> 1655 bytes client/data/textures/blocks/antimony_block.png | Bin 0 -> 1713 bytes client/data/textures/blocks/antimony_ore.png | Bin 0 -> 1787 bytes client/data/textures/blocks/anvil_base.png | Bin 0 -> 379 bytes client/data/textures/blocks/anvil_top_0.png | Bin 0 -> 310 bytes client/data/textures/blocks/anvil_top_1.png | Bin 0 -> 367 bytes client/data/textures/blocks/anvil_top_2.png | Bin 0 -> 406 bytes client/data/textures/blocks/ardite_block.png | Bin 0 -> 2094 bytes client/data/textures/blocks/ardite_ore.png | Bin 0 -> 1775 bytes client/data/textures/blocks/arsenic_block.png | Bin 0 -> 1744 bytes client/data/textures/blocks/arsenic_ore.png | Bin 0 -> 1812 bytes client/data/textures/blocks/ash.png | Bin 0 -> 984 bytes client/data/textures/blocks/banner.png | Bin 0 -> 2029 bytes client/data/textures/blocks/banner_base.png | Bin 0 -> 852 bytes client/data/textures/blocks/banner_border.png | Bin 0 -> 903 bytes client/data/textures/blocks/banner_bricks.png | Bin 0 -> 1078 bytes client/data/textures/blocks/banner_circle.png | Bin 0 -> 956 bytes client/data/textures/blocks/banner_cross.png | Bin 0 -> 1115 bytes .../textures/blocks/banner_curly_border.png | Bin 0 -> 1045 bytes .../textures/blocks/banner_diagonal_left.png | Bin 0 -> 996 bytes .../textures/blocks/banner_diagonal_right.png | Bin 0 -> 1020 bytes .../textures/blocks/banner_diagonal_up_left.png | Bin 0 -> 1026 bytes .../blocks/banner_diagonal_up_right.png | Bin 0 -> 1014 bytes client/data/textures/blocks/banner_flower.png | Bin 0 -> 1219 bytes client/data/textures/blocks/banner_gradient.png | Bin 0 -> 1960 bytes .../data/textures/blocks/banner_gradient_up.png | Bin 0 -> 2016 bytes .../textures/blocks/banner_half_horizontal.png | Bin 0 -> 873 bytes .../blocks/banner_half_horizontal_bottom.png | Bin 0 -> 931 bytes .../textures/blocks/banner_half_vertical.png | Bin 0 -> 880 bytes .../blocks/banner_half_vertical_right.png | Bin 0 -> 904 bytes client/data/textures/blocks/banner_rhombus.png | Bin 0 -> 983 bytes client/data/textures/blocks/banner_rune.png | Bin 0 -> 8856 bytes client/data/textures/blocks/banner_skull.png | Bin 0 -> 1193 bytes .../textures/blocks/banner_small_stripes.png | Bin 0 -> 888 bytes .../blocks/banner_square_bottom_left.png | Bin 0 -> 907 bytes .../blocks/banner_square_bottom_right.png | Bin 0 -> 898 bytes .../textures/blocks/banner_square_top_left.png | Bin 0 -> 892 bytes .../textures/blocks/banner_square_top_right.png | Bin 0 -> 895 bytes .../textures/blocks/banner_straight_cross.png | Bin 0 -> 961 bytes .../textures/blocks/banner_stripe_bottom.png | Bin 0 -> 882 bytes .../textures/blocks/banner_stripe_center.png | Bin 0 -> 890 bytes .../textures/blocks/banner_stripe_downleft.png | Bin 0 -> 1017 bytes .../textures/blocks/banner_stripe_downright.png | Bin 0 -> 1020 bytes .../data/textures/blocks/banner_stripe_left.png | Bin 0 -> 883 bytes .../textures/blocks/banner_stripe_middle.png | Bin 0 -> 878 bytes .../textures/blocks/banner_stripe_right.png | Bin 0 -> 883 bytes .../data/textures/blocks/banner_stripe_top.png | Bin 0 -> 873 bytes client/data/textures/blocks/banner_thing.png | Bin 0 -> 3945 bytes .../textures/blocks/banner_triangle_bottom.png | Bin 0 -> 1454 bytes .../textures/blocks/banner_triangle_top.png | Bin 0 -> 980 bytes .../textures/blocks/banner_triangles_bottom.png | Bin 0 -> 996 bytes .../textures/blocks/banner_triangles_top.png | Bin 0 -> 978 bytes client/data/textures/blocks/beacon.png | Bin 0 -> 208 bytes client/data/textures/blocks/beacon_beam.png | Bin 0 -> 260 bytes client/data/textures/blocks/bedrock.png | Bin 0 -> 225 bytes .../data/textures/blocks/birch_door_bottom.png | Bin 0 -> 666 bytes client/data/textures/blocks/birch_door_top.png | Bin 0 -> 707 bytes .../textures/blocks/birch_leaves_autumn.png | Bin 0 -> 6726 bytes .../data/textures/blocks/birch_leaves_snowy.png | Bin 0 -> 6111 bytes .../textures/blocks/birch_leaves_spring.png | Bin 0 -> 499 bytes .../textures/blocks/birch_leaves_summer.png | Bin 0 -> 6228 bytes .../textures/blocks/birch_leaves_winter.png | Bin 0 -> 6614 bytes client/data/textures/blocks/birch_log_bark.png | Bin 0 -> 742 bytes client/data/textures/blocks/birch_log_top.png | Bin 0 -> 779 bytes client/data/textures/blocks/birch_planks.png | Bin 0 -> 265 bytes client/data/textures/blocks/birch_sapling.png | Bin 0 -> 225 bytes client/data/textures/blocks/bismuth_block.png | Bin 0 -> 1650 bytes client/data/textures/blocks/bismuth_ore.png | Bin 0 -> 1796 bytes .../data/textures/blocks/black_bed_foot_end.png | Bin 0 -> 5507 bytes .../textures/blocks/black_bed_foot_side.png | Bin 0 -> 5431 bytes .../data/textures/blocks/black_bed_foot_top.png | Bin 0 -> 5432 bytes .../data/textures/blocks/black_bed_head_end.png | Bin 0 -> 5565 bytes .../textures/blocks/black_bed_head_side.png | Bin 0 -> 5542 bytes .../data/textures/blocks/black_bed_head_top.png | Bin 0 -> 5832 bytes client/data/textures/blocks/black_brick.png | Bin 0 -> 5577 bytes client/data/textures/blocks/black_glass.png | Bin 0 -> 203 bytes .../data/textures/blocks/black_glass_pane.png | Bin 0 -> 114 bytes client/data/textures/blocks/black_lotus.png | Bin 0 -> 5537 bytes .../data/textures/blocks/black_metal_block.png | Bin 0 -> 4785 bytes client/data/textures/blocks/black_metal_ore.png | Bin 0 -> 5119 bytes .../blocks/black_quartz_block_bottom.png | Bin 0 -> 5417 bytes .../blocks/black_quartz_block_chiseled.png | Bin 0 -> 5585 bytes .../blocks/black_quartz_block_chiseled_top.png | Bin 0 -> 5571 bytes .../blocks/black_quartz_block_lines.png | Bin 0 -> 5334 bytes .../blocks/black_quartz_block_lines_top.png | Bin 0 -> 5523 bytes .../textures/blocks/black_quartz_block_side.png | Bin 0 -> 5365 bytes .../data/textures/blocks/black_quartz_ore.png | Bin 0 -> 6932 bytes .../data/textures/blocks/black_quartz_top.png | Bin 0 -> 5365 bytes .../blocks/black_stained_hardened_clay.png | Bin 0 -> 3060 bytes client/data/textures/blocks/black_wool.png | Bin 0 -> 382 bytes .../data/textures/blocks/blackened_cobble.png | Bin 0 -> 5594 bytes client/data/textures/blocks/blackened_dirt.png | Bin 0 -> 5160 bytes .../textures/blocks/blackened_soil_side.png | Bin 0 -> 5266 bytes .../data/textures/blocks/blackened_soil_top.png | Bin 0 -> 5915 bytes client/data/textures/blocks/blackened_stone.png | Bin 0 -> 4937 bytes .../textures/blocks/blackwood_door_bottom.png | Bin 0 -> 5275 bytes .../data/textures/blocks/blackwood_door_top.png | Bin 0 -> 5261 bytes .../textures/blocks/blackwood_leaves_autumn.png | Bin 0 -> 6226 bytes .../textures/blocks/blackwood_leaves_snowy.png | Bin 0 -> 6368 bytes .../textures/blocks/blackwood_leaves_spring.png | Bin 0 -> 5973 bytes .../textures/blocks/blackwood_leaves_summer.png | Bin 0 -> 6170 bytes .../textures/blocks/blackwood_leaves_winter.png | Bin 0 -> 6274 bytes .../data/textures/blocks/blackwood_log_bark.png | Bin 0 -> 5820 bytes .../data/textures/blocks/blackwood_log_top.png | Bin 0 -> 5635 bytes .../data/textures/blocks/blackwood_planks.png | Bin 0 -> 5603 bytes .../data/textures/blocks/blackwood_sapling.png | Bin 0 -> 5507 bytes client/data/textures/blocks/blood_brick.png | Bin 0 -> 328 bytes client/data/textures/blocks/blood_flow.png | Bin 0 -> 14630 bytes client/data/textures/blocks/blood_still.png | Bin 0 -> 18430 bytes client/data/textures/blocks/blue_glass.png | Bin 0 -> 206 bytes client/data/textures/blocks/blue_glass_pane.png | Bin 0 -> 120 bytes client/data/textures/blocks/blue_mushroom.png | Bin 0 -> 1131 bytes client/data/textures/blocks/blue_orchid.png | Bin 0 -> 545 bytes .../blocks/blue_stained_hardened_clay.png | Bin 0 -> 3099 bytes client/data/textures/blocks/blue_wool.png | Bin 0 -> 482 bytes client/data/textures/blocks/bookshelf.png | Bin 0 -> 375 bytes client/data/textures/blocks/brewing_stand.png | Bin 0 -> 321 bytes .../data/textures/blocks/brewing_stand_base.png | Bin 0 -> 513 bytes client/data/textures/blocks/brick_block.png | Bin 0 -> 530 bytes client/data/textures/blocks/brown_glass.png | Bin 0 -> 205 bytes .../data/textures/blocks/brown_glass_pane.png | Bin 0 -> 119 bytes client/data/textures/blocks/brown_mushroom.png | Bin 0 -> 120 bytes .../blocks/brown_mushroom_block_cap.png | Bin 0 -> 546 bytes .../blocks/brown_mushroom_block_inside.png | Bin 0 -> 315 bytes .../blocks/brown_mushroom_block_stem.png | Bin 0 -> 400 bytes .../blocks/brown_stained_hardened_clay.png | Bin 0 -> 3098 bytes client/data/textures/blocks/brown_wool.png | Bin 0 -> 410 bytes client/data/textures/blocks/cactus_bottom.png | Bin 0 -> 273 bytes client/data/textures/blocks/cactus_side.png | Bin 0 -> 430 bytes client/data/textures/blocks/cactus_top.png | Bin 0 -> 321 bytes client/data/textures/blocks/cake_bottom.png | Bin 0 -> 144 bytes client/data/textures/blocks/cake_inner.png | Bin 0 -> 165 bytes client/data/textures/blocks/cake_side.png | Bin 0 -> 154 bytes client/data/textures/blocks/cake_top.png | Bin 0 -> 199 bytes client/data/textures/blocks/calcium_block.png | Bin 0 -> 1452 bytes client/data/textures/blocks/calcium_ore.png | Bin 0 -> 1626 bytes client/data/textures/blocks/carrot_0.png | Bin 0 -> 108 bytes client/data/textures/blocks/carrot_1.png | Bin 0 -> 128 bytes client/data/textures/blocks/carrot_2.png | Bin 0 -> 187 bytes client/data/textures/blocks/carrot_3.png | Bin 0 -> 306 bytes client/data/textures/blocks/cauldron_bottom.png | Bin 0 -> 242 bytes client/data/textures/blocks/cauldron_inner.png | Bin 0 -> 364 bytes client/data/textures/blocks/cauldron_side.png | Bin 0 -> 534 bytes client/data/textures/blocks/cauldron_top.png | Bin 0 -> 414 bytes client/data/textures/blocks/cell_rock.png | Bin 0 -> 404 bytes .../data/textures/blocks/cherry_door_bottom.png | Bin 0 -> 2592 bytes client/data/textures/blocks/cherry_door_top.png | Bin 0 -> 2588 bytes .../textures/blocks/cherry_leaves_autumn.png | Bin 0 -> 5164 bytes .../textures/blocks/cherry_leaves_snowy.png | Bin 0 -> 6387 bytes .../textures/blocks/cherry_leaves_spring.png | Bin 0 -> 5181 bytes .../textures/blocks/cherry_leaves_summer.png | Bin 0 -> 5399 bytes .../textures/blocks/cherry_leaves_winter.png | Bin 0 -> 5370 bytes client/data/textures/blocks/cherry_log_bark.png | Bin 0 -> 4767 bytes client/data/textures/blocks/cherry_log_top.png | Bin 0 -> 4660 bytes client/data/textures/blocks/cherry_planks.png | Bin 0 -> 4505 bytes client/data/textures/blocks/cherry_sapling.png | Bin 0 -> 4647 bytes client/data/textures/blocks/chest_normal.png | Bin 0 -> 1302 bytes .../textures/blocks/chest_normal_double.png | Bin 0 -> 1828 bytes client/data/textures/blocks/chest_trapped.png | Bin 0 -> 1720 bytes .../textures/blocks/chest_trapped_double.png | Bin 0 -> 2219 bytes client/data/textures/blocks/chrome_block.png | Bin 0 -> 1581 bytes client/data/textures/blocks/chrome_ore.png | Bin 0 -> 1646 bytes client/data/textures/blocks/cinnabar_block.png | Bin 0 -> 5669 bytes client/data/textures/blocks/cinnabar_ore.png | Bin 0 -> 6062 bytes client/data/textures/blocks/clay.png | Bin 0 -> 584 bytes client/data/textures/blocks/coal_block.png | Bin 0 -> 368 bytes client/data/textures/blocks/coal_ore.png | Bin 0 -> 257 bytes client/data/textures/blocks/coarse_dirt.png | Bin 0 -> 674 bytes client/data/textures/blocks/cobalt_block.png | Bin 0 -> 1658 bytes client/data/textures/blocks/cobalt_ore.png | Bin 0 -> 1747 bytes client/data/textures/blocks/cobblestone.png | Bin 0 -> 631 bytes client/data/textures/blocks/cocoa_0.png | Bin 0 -> 248 bytes client/data/textures/blocks/cocoa_1.png | Bin 0 -> 405 bytes client/data/textures/blocks/cocoa_2.png | Bin 0 -> 570 bytes client/data/textures/blocks/comparator_off.png | Bin 0 -> 675 bytes client/data/textures/blocks/comparator_on.png | Bin 0 -> 696 bytes client/data/textures/blocks/control_block.png | Bin 0 -> 5904 bytes client/data/textures/blocks/copper_block.png | Bin 0 -> 1758 bytes client/data/textures/blocks/copper_ore.png | Bin 0 -> 1855 bytes client/data/textures/blocks/core.png | Bin 0 -> 6215 bytes .../textures/blocks/crafting_table_front.png | Bin 0 -> 407 bytes .../textures/blocks/crafting_table_side.png | Bin 0 -> 386 bytes .../data/textures/blocks/crafting_table_top.png | Bin 0 -> 550 bytes client/data/textures/blocks/cyan_glass.png | Bin 0 -> 205 bytes client/data/textures/blocks/cyan_glass_pane.png | Bin 0 -> 119 bytes .../blocks/cyan_stained_hardened_clay.png | Bin 0 -> 3147 bytes client/data/textures/blocks/cyan_wool.png | Bin 0 -> 480 bytes client/data/textures/blocks/dandelion.png | Bin 0 -> 145 bytes .../textures/blocks/dark_oak_door_bottom.png | Bin 0 -> 639 bytes .../data/textures/blocks/dark_oak_door_top.png | Bin 0 -> 626 bytes .../textures/blocks/dark_oak_leaves_autumn.png | Bin 0 -> 6865 bytes .../textures/blocks/dark_oak_leaves_snowy.png | Bin 0 -> 6110 bytes .../textures/blocks/dark_oak_leaves_spring.png | Bin 0 -> 499 bytes .../textures/blocks/dark_oak_leaves_summer.png | Bin 0 -> 6229 bytes .../textures/blocks/dark_oak_leaves_winter.png | Bin 0 -> 6614 bytes .../data/textures/blocks/dark_oak_log_bark.png | Bin 0 -> 683 bytes .../data/textures/blocks/dark_oak_log_top.png | Bin 0 -> 580 bytes client/data/textures/blocks/dark_oak_planks.png | Bin 0 -> 438 bytes .../data/textures/blocks/dark_oak_sapling.png | Bin 0 -> 579 bytes client/data/textures/blocks/darkstone.png | Bin 0 -> 5949 bytes .../blocks/daylight_detector_inverted_top.png | Bin 0 -> 287 bytes .../textures/blocks/daylight_detector_side.png | Bin 0 -> 206 bytes .../textures/blocks/daylight_detector_top.png | Bin 0 -> 335 bytes client/data/textures/blocks/deadbush.png | Bin 0 -> 168 bytes client/data/textures/blocks/destroy_stage_0.png | Bin 0 -> 102 bytes client/data/textures/blocks/destroy_stage_1.png | Bin 0 -> 115 bytes client/data/textures/blocks/destroy_stage_2.png | Bin 0 -> 123 bytes client/data/textures/blocks/destroy_stage_3.png | Bin 0 -> 145 bytes client/data/textures/blocks/destroy_stage_4.png | Bin 0 -> 155 bytes client/data/textures/blocks/destroy_stage_5.png | Bin 0 -> 169 bytes client/data/textures/blocks/destroy_stage_6.png | Bin 0 -> 179 bytes client/data/textures/blocks/destroy_stage_7.png | Bin 0 -> 190 bytes client/data/textures/blocks/destroy_stage_8.png | Bin 0 -> 211 bytes client/data/textures/blocks/destroy_stage_9.png | Bin 0 -> 218 bytes client/data/textures/blocks/detector_rail.png | Bin 0 -> 309 bytes .../textures/blocks/detector_rail_powered.png | Bin 0 -> 581 bytes client/data/textures/blocks/diamond_block.png | Bin 0 -> 495 bytes client/data/textures/blocks/diamond_ore.png | Bin 0 -> 262 bytes client/data/textures/blocks/dirt.png | Bin 0 -> 270 bytes .../data/textures/blocks/dirt_podzol_side.png | Bin 0 -> 740 bytes client/data/textures/blocks/dirt_podzol_top.png | Bin 0 -> 823 bytes .../blocks/dispenser_front_horizontal.png | Bin 0 -> 495 bytes .../blocks/dispenser_front_vertical.png | Bin 0 -> 749 bytes .../data/textures/blocks/double_fern_bottom.png | Bin 0 -> 706 bytes client/data/textures/blocks/double_fern_top.png | Bin 0 -> 670 bytes .../textures/blocks/double_grass_bottom.png | Bin 0 -> 715 bytes .../data/textures/blocks/double_grass_top.png | Bin 0 -> 717 bytes .../data/textures/blocks/double_rose_bottom.png | Bin 0 -> 698 bytes client/data/textures/blocks/double_rose_top.png | Bin 0 -> 637 bytes .../data/textures/blocks/double_stone_top.png | Bin 0 -> 252 bytes client/data/textures/blocks/dragon_egg.png | Bin 0 -> 193 bytes .../blocks/dropper_front_horizontal.png | Bin 0 -> 713 bytes .../textures/blocks/dropper_front_vertical.png | Bin 0 -> 712 bytes client/data/textures/blocks/dry_leaves.png | Bin 0 -> 6621 bytes client/data/textures/blocks/emerald_block.png | Bin 0 -> 658 bytes client/data/textures/blocks/emerald_ore.png | Bin 0 -> 364 bytes .../textures/blocks/enchanting_table_bottom.png | Bin 0 -> 438 bytes .../textures/blocks/enchanting_table_side.png | Bin 0 -> 359 bytes .../textures/blocks/enchanting_table_top.png | Bin 0 -> 221 bytes client/data/textures/blocks/farmland_0.png | Bin 0 -> 258 bytes client/data/textures/blocks/farmland_1.png | Bin 0 -> 6162 bytes client/data/textures/blocks/farmland_2.png | Bin 0 -> 6173 bytes client/data/textures/blocks/farmland_3.png | Bin 0 -> 6358 bytes client/data/textures/blocks/farmland_4.png | Bin 0 -> 6408 bytes client/data/textures/blocks/farmland_5.png | Bin 0 -> 6454 bytes client/data/textures/blocks/farmland_6.png | Bin 0 -> 6474 bytes client/data/textures/blocks/farmland_7.png | Bin 0 -> 610 bytes client/data/textures/blocks/fern.png | Bin 0 -> 157 bytes client/data/textures/blocks/floor_portal.png | Bin 0 -> 10223 bytes client/data/textures/blocks/floor_tiles.png | Bin 0 -> 5578 bytes .../data/textures/blocks/floor_tiles_black.png | Bin 0 -> 5224 bytes client/data/textures/blocks/floor_tiles_red.png | Bin 0 -> 5498 bytes .../data/textures/blocks/floor_tiles_white.png | Bin 0 -> 5673 bytes client/data/textures/blocks/flower_paeonia.png | Bin 0 -> 503 bytes client/data/textures/blocks/flower_pot.png | Bin 0 -> 229 bytes .../data/textures/blocks/furnace_front_off.png | Bin 0 -> 615 bytes .../data/textures/blocks/furnace_front_on.png | Bin 0 -> 661 bytes client/data/textures/blocks/furnace_side.png | Bin 0 -> 564 bytes client/data/textures/blocks/furnace_top.png | Bin 0 -> 550 bytes client/data/textures/blocks/glass.png | Bin 0 -> 184 bytes client/data/textures/blocks/glass_pane.png | Bin 0 -> 117 bytes client/data/textures/blocks/glowstone.png | Bin 0 -> 283 bytes client/data/textures/blocks/gold_block.png | Bin 0 -> 5876 bytes client/data/textures/blocks/gold_ore.png | Bin 0 -> 263 bytes client/data/textures/blocks/golden_rail.png | Bin 0 -> 290 bytes .../textures/blocks/golden_rail_powered.png | Bin 0 -> 341 bytes client/data/textures/blocks/goo_flow.png | Bin 0 -> 10051 bytes client/data/textures/blocks/goo_still.png | Bin 0 -> 11601 bytes client/data/textures/blocks/grass_side.png | Bin 0 -> 405 bytes .../data/textures/blocks/grass_side_overlay.png | Bin 0 -> 219 bytes .../data/textures/blocks/grass_side_snowed.png | Bin 0 -> 268 bytes client/data/textures/blocks/grass_top.png | Bin 0 -> 6204 bytes client/data/textures/blocks/gravel.png | Bin 0 -> 796 bytes client/data/textures/blocks/gravel_new.png | Bin 0 -> 470 bytes client/data/textures/blocks/gray_glass.png | Bin 0 -> 203 bytes client/data/textures/blocks/gray_glass_pane.png | Bin 0 -> 119 bytes .../blocks/gray_stained_hardened_clay.png | Bin 0 -> 3063 bytes client/data/textures/blocks/gray_wool.png | Bin 0 -> 360 bytes client/data/textures/blocks/green_glass.png | Bin 0 -> 204 bytes .../data/textures/blocks/green_glass_pane.png | Bin 0 -> 119 bytes .../blocks/green_stained_hardened_clay.png | Bin 0 -> 3107 bytes client/data/textures/blocks/green_wool.png | Bin 0 -> 403 bytes client/data/textures/blocks/gyriyn_block.png | Bin 0 -> 2073 bytes client/data/textures/blocks/gyriyn_ore.png | Bin 0 -> 1814 bytes client/data/textures/blocks/hardened_clay.png | Bin 0 -> 3273 bytes client/data/textures/blocks/hay_block_side.png | Bin 0 -> 795 bytes client/data/textures/blocks/hay_block_top.png | Bin 0 -> 892 bytes client/data/textures/blocks/hellrock.png | Bin 0 -> 736 bytes client/data/textures/blocks/hopper_inside.png | Bin 0 -> 422 bytes client/data/textures/blocks/hopper_outside.png | Bin 0 -> 531 bytes client/data/textures/blocks/hopper_top.png | Bin 0 -> 406 bytes client/data/textures/blocks/houstonia.png | Bin 0 -> 530 bytes client/data/textures/blocks/hydrogen_flow.png | Bin 0 -> 11754 bytes client/data/textures/blocks/hydrogen_still.png | Bin 0 -> 12275 bytes client/data/textures/blocks/ice.png | Bin 0 -> 150 bytes client/data/textures/blocks/iodine_block.png | Bin 0 -> 1636 bytes client/data/textures/blocks/iodine_ore.png | Bin 0 -> 1752 bytes client/data/textures/blocks/iron_bars.png | Bin 0 -> 491 bytes client/data/textures/blocks/iron_block.png | Bin 0 -> 333 bytes .../data/textures/blocks/iron_door_bottom.png | Bin 0 -> 551 bytes client/data/textures/blocks/iron_door_top.png | Bin 0 -> 449 bytes client/data/textures/blocks/iron_ore.png | Bin 0 -> 265 bytes client/data/textures/blocks/iron_trapdoor.png | Bin 0 -> 382 bytes .../textures/blocks/itemframe_background.png | Bin 0 -> 410 bytes client/data/textures/blocks/jukebox_side.png | Bin 0 -> 395 bytes client/data/textures/blocks/jukebox_top.png | Bin 0 -> 356 bytes .../data/textures/blocks/jungle_door_bottom.png | Bin 0 -> 472 bytes client/data/textures/blocks/jungle_door_top.png | Bin 0 -> 465 bytes .../textures/blocks/jungle_leaves_autumn.png | Bin 0 -> 6249 bytes .../textures/blocks/jungle_leaves_snowy.png | Bin 0 -> 5970 bytes .../textures/blocks/jungle_leaves_spring.png | Bin 0 -> 341 bytes .../textures/blocks/jungle_leaves_summer.png | Bin 0 -> 5969 bytes .../textures/blocks/jungle_leaves_winter.png | Bin 0 -> 6244 bytes client/data/textures/blocks/jungle_log_bark.png | Bin 0 -> 609 bytes client/data/textures/blocks/jungle_log_top.png | Bin 0 -> 683 bytes client/data/textures/blocks/jungle_planks.png | Bin 0 -> 263 bytes client/data/textures/blocks/jungle_sapling.png | Bin 0 -> 239 bytes client/data/textures/blocks/ladder.png | Bin 0 -> 280 bytes client/data/textures/blocks/lamp.png | Bin 0 -> 682 bytes client/data/textures/blocks/lapis_block.png | Bin 0 -> 754 bytes client/data/textures/blocks/lapis_ore.png | Bin 0 -> 447 bytes client/data/textures/blocks/lava_flow.png | Bin 0 -> 9931 bytes client/data/textures/blocks/lava_still.png | Bin 0 -> 16230 bytes client/data/textures/blocks/lead_block.png | Bin 0 -> 1539 bytes client/data/textures/blocks/lead_ore.png | Bin 0 -> 1811 bytes client/data/textures/blocks/lever.png | Bin 0 -> 136 bytes .../data/textures/blocks/light_blue_glass.png | Bin 0 -> 204 bytes .../textures/blocks/light_blue_glass_pane.png | Bin 0 -> 120 bytes .../blocks/light_blue_stained_hardened_clay.png | Bin 0 -> 3114 bytes client/data/textures/blocks/light_blue_wool.png | Bin 0 -> 509 bytes client/data/textures/blocks/lime_glass.png | Bin 0 -> 206 bytes client/data/textures/blocks/lime_glass_pane.png | Bin 0 -> 119 bytes .../blocks/lime_stained_hardened_clay.png | Bin 0 -> 3166 bytes client/data/textures/blocks/lime_wool.png | Bin 0 -> 491 bytes .../data/textures/blocks/lit_redstone_lamp.png | Bin 0 -> 682 bytes client/data/textures/blocks/lithium_block.png | Bin 0 -> 1724 bytes client/data/textures/blocks/lithium_ore.png | Bin 0 -> 1794 bytes client/data/textures/blocks/magenta_glass.png | Bin 0 -> 206 bytes .../data/textures/blocks/magenta_glass_pane.png | Bin 0 -> 120 bytes .../blocks/magenta_stained_hardened_clay.png | Bin 0 -> 3169 bytes client/data/textures/blocks/magenta_wool.png | Bin 0 -> 495 bytes client/data/textures/blocks/magnesium_block.png | Bin 0 -> 1453 bytes client/data/textures/blocks/magnesium_ore.png | Bin 0 -> 1763 bytes client/data/textures/blocks/manganese_block.png | Bin 0 -> 1793 bytes client/data/textures/blocks/manganese_ore.png | Bin 0 -> 1868 bytes .../data/textures/blocks/maple_door_bottom.png | Bin 0 -> 2036 bytes client/data/textures/blocks/maple_door_top.png | Bin 0 -> 2039 bytes .../textures/blocks/maple_leaves_autumn.png | Bin 0 -> 5402 bytes .../data/textures/blocks/maple_leaves_snowy.png | Bin 0 -> 6906 bytes .../textures/blocks/maple_leaves_spring.png | Bin 0 -> 5124 bytes .../textures/blocks/maple_leaves_summer.png | Bin 0 -> 5361 bytes .../textures/blocks/maple_leaves_winter.png | Bin 0 -> 5597 bytes client/data/textures/blocks/maple_log_bark.png | Bin 0 -> 4996 bytes client/data/textures/blocks/maple_log_top.png | Bin 0 -> 4886 bytes client/data/textures/blocks/maple_planks.png | Bin 0 -> 4951 bytes client/data/textures/blocks/maple_sapling.png | Bin 0 -> 4840 bytes client/data/textures/blocks/melon_side.png | Bin 0 -> 449 bytes client/data/textures/blocks/melon_stem.png | Bin 0 -> 189 bytes .../textures/blocks/melon_stem_connected.png | Bin 0 -> 165 bytes client/data/textures/blocks/melon_top.png | Bin 0 -> 326 bytes client/data/textures/blocks/mercury_flow.png | Bin 0 -> 11112 bytes client/data/textures/blocks/mercury_still.png | Bin 0 -> 12523 bytes client/data/textures/blocks/mob_spawner.png | Bin 0 -> 338 bytes client/data/textures/blocks/moon_cheese.png | Bin 0 -> 6852 bytes client/data/textures/blocks/moon_rock.png | Bin 0 -> 5978 bytes .../data/textures/blocks/mossy_cobblestone.png | Bin 0 -> 679 bytes client/data/textures/blocks/mycelium_side.png | Bin 0 -> 441 bytes client/data/textures/blocks/mycelium_top.png | Bin 0 -> 496 bytes client/data/textures/blocks/neodymium_block.png | Bin 0 -> 1710 bytes client/data/textures/blocks/neodymium_ore.png | Bin 0 -> 1810 bytes client/data/textures/blocks/neptunium_block.png | Bin 0 -> 1797 bytes client/data/textures/blocks/neptunium_ore.png | Bin 0 -> 1805 bytes client/data/textures/blocks/nichun_block.png | Bin 0 -> 1623 bytes client/data/textures/blocks/nichun_ore.png | Bin 0 -> 1998 bytes client/data/textures/blocks/nickel_block.png | Bin 0 -> 1792 bytes client/data/textures/blocks/nickel_ore.png | Bin 0 -> 1830 bytes client/data/textures/blocks/noteblock.png | Bin 0 -> 395 bytes client/data/textures/blocks/nukage_flow.png | Bin 0 -> 10189 bytes client/data/textures/blocks/nukage_still.png | Bin 0 -> 15434 bytes client/data/textures/blocks/nuke_bottom.png | Bin 0 -> 1201 bytes client/data/textures/blocks/nuke_side.png | Bin 0 -> 1513 bytes client/data/textures/blocks/nuke_top.png | Bin 0 -> 1739 bytes client/data/textures/blocks/oak_door_bottom.png | Bin 0 -> 399 bytes client/data/textures/blocks/oak_door_top.png | Bin 0 -> 401 bytes .../data/textures/blocks/oak_leaves_autumn.png | Bin 0 -> 6840 bytes .../data/textures/blocks/oak_leaves_snowy.png | Bin 0 -> 6111 bytes .../data/textures/blocks/oak_leaves_spring.png | Bin 0 -> 499 bytes .../data/textures/blocks/oak_leaves_summer.png | Bin 0 -> 6229 bytes .../data/textures/blocks/oak_leaves_winter.png | Bin 0 -> 6614 bytes client/data/textures/blocks/oak_log_bark.png | Bin 0 -> 528 bytes client/data/textures/blocks/oak_log_top.png | Bin 0 -> 478 bytes client/data/textures/blocks/oak_planks.png | Bin 0 -> 247 bytes client/data/textures/blocks/oak_sapling.png | Bin 0 -> 278 bytes client/data/textures/blocks/obsidian.png | Bin 0 -> 489 bytes client/data/textures/blocks/orange_glass.png | Bin 0 -> 206 bytes .../data/textures/blocks/orange_glass_pane.png | Bin 0 -> 120 bytes .../blocks/orange_stained_hardened_clay.png | Bin 0 -> 3164 bytes client/data/textures/blocks/orange_tulip.png | Bin 0 -> 548 bytes client/data/textures/blocks/orange_wool.png | Bin 0 -> 461 bytes client/data/textures/blocks/oxeye_daisy.png | Bin 0 -> 556 bytes client/data/textures/blocks/packed_ice.png | Bin 0 -> 527 bytes client/data/textures/blocks/paeonia_bottom.png | Bin 0 -> 665 bytes client/data/textures/blocks/paeonia_top.png | Bin 0 -> 727 bytes client/data/textures/blocks/palladium_block.png | Bin 0 -> 1805 bytes client/data/textures/blocks/palladium_ore.png | Bin 0 -> 1843 bytes client/data/textures/blocks/pentagram.png | Bin 0 -> 6355 bytes client/data/textures/blocks/phosphor_block.png | Bin 0 -> 1752 bytes client/data/textures/blocks/phosphor_ore.png | Bin 0 -> 1798 bytes client/data/textures/blocks/pink_glass.png | Bin 0 -> 206 bytes client/data/textures/blocks/pink_glass_pane.png | Bin 0 -> 120 bytes .../blocks/pink_stained_hardened_clay.png | Bin 0 -> 3173 bytes client/data/textures/blocks/pink_tulip.png | Bin 0 -> 555 bytes client/data/textures/blocks/pink_wool.png | Bin 0 -> 513 bytes client/data/textures/blocks/piston_bottom.png | Bin 0 -> 550 bytes client/data/textures/blocks/piston_inner.png | Bin 0 -> 509 bytes client/data/textures/blocks/piston_side.png | Bin 0 -> 604 bytes client/data/textures/blocks/piston_top.png | Bin 0 -> 388 bytes .../data/textures/blocks/piston_top_sticky.png | Bin 0 -> 622 bytes client/data/textures/blocks/platinum_block.png | Bin 0 -> 1686 bytes client/data/textures/blocks/platinum_ore.png | Bin 0 -> 1789 bytes client/data/textures/blocks/plutonium_block.png | Bin 0 -> 1788 bytes client/data/textures/blocks/plutonium_ore.png | Bin 0 -> 1881 bytes client/data/textures/blocks/poppy.png | Bin 0 -> 355 bytes client/data/textures/blocks/portal.png | Bin 0 -> 30513 bytes .../textures/blocks/portal_frame_bottom.png | Bin 0 -> 5663 bytes .../data/textures/blocks/portal_frame_orb.png | Bin 0 -> 5674 bytes .../data/textures/blocks/portal_frame_side.png | Bin 0 -> 5779 bytes .../data/textures/blocks/portal_frame_top.png | Bin 0 -> 5946 bytes client/data/textures/blocks/potassium_block.png | Bin 0 -> 1602 bytes client/data/textures/blocks/potassium_ore.png | Bin 0 -> 1763 bytes client/data/textures/blocks/potato_0.png | Bin 0 -> 108 bytes client/data/textures/blocks/potato_1.png | Bin 0 -> 128 bytes client/data/textures/blocks/potato_2.png | Bin 0 -> 187 bytes client/data/textures/blocks/potato_3.png | Bin 0 -> 236 bytes .../data/textures/blocks/praseodymium_block.png | Bin 0 -> 1680 bytes .../data/textures/blocks/praseodymium_ore.png | Bin 0 -> 1831 bytes .../data/textures/blocks/pumpkin_face_off.png | Bin 0 -> 240 bytes client/data/textures/blocks/pumpkin_face_on.png | Bin 0 -> 422 bytes client/data/textures/blocks/pumpkin_side.png | Bin 0 -> 219 bytes client/data/textures/blocks/pumpkin_stem.png | Bin 0 -> 189 bytes .../textures/blocks/pumpkin_stem_connected.png | Bin 0 -> 165 bytes client/data/textures/blocks/pumpkin_top.png | Bin 0 -> 272 bytes .../textures/blocks/purple_bed_foot_end.png | Bin 0 -> 5726 bytes .../textures/blocks/purple_bed_foot_side.png | Bin 0 -> 5633 bytes .../textures/blocks/purple_bed_foot_top.png | Bin 0 -> 6258 bytes .../textures/blocks/purple_bed_head_end.png | Bin 0 -> 5756 bytes .../textures/blocks/purple_bed_head_side.png | Bin 0 -> 5728 bytes .../textures/blocks/purple_bed_head_top.png | Bin 0 -> 6591 bytes client/data/textures/blocks/purple_glass.png | Bin 0 -> 206 bytes .../data/textures/blocks/purple_glass_pane.png | Bin 0 -> 120 bytes .../blocks/purple_stained_hardened_clay.png | Bin 0 -> 3177 bytes client/data/textures/blocks/purple_wool.png | Bin 0 -> 501 bytes .../textures/blocks/quartz_block_bottom.png | Bin 0 -> 484 bytes .../textures/blocks/quartz_block_chiseled.png | Bin 0 -> 560 bytes .../blocks/quartz_block_chiseled_top.png | Bin 0 -> 535 bytes .../data/textures/blocks/quartz_block_lines.png | Bin 0 -> 341 bytes .../textures/blocks/quartz_block_lines_top.png | Bin 0 -> 503 bytes .../data/textures/blocks/quartz_block_side.png | Bin 0 -> 419 bytes client/data/textures/blocks/quartz_ore.png | Bin 0 -> 1018 bytes client/data/textures/blocks/quartz_top.png | Bin 0 -> 419 bytes client/data/textures/blocks/radium_block.png | Bin 0 -> 1803 bytes client/data/textures/blocks/radium_ore.png | Bin 0 -> 1860 bytes client/data/textures/blocks/rail.png | Bin 0 -> 232 bytes client/data/textures/blocks/rail_turned.png | Bin 0 -> 247 bytes .../data/textures/blocks/red_bed_foot_end.png | Bin 0 -> 470 bytes .../data/textures/blocks/red_bed_foot_side.png | Bin 0 -> 438 bytes .../data/textures/blocks/red_bed_foot_top.png | Bin 0 -> 813 bytes .../data/textures/blocks/red_bed_head_end.png | Bin 0 -> 476 bytes .../data/textures/blocks/red_bed_head_side.png | Bin 0 -> 462 bytes .../data/textures/blocks/red_bed_head_top.png | Bin 0 -> 958 bytes client/data/textures/blocks/red_button.png | Bin 0 -> 6235 bytes client/data/textures/blocks/red_glass.png | Bin 0 -> 204 bytes client/data/textures/blocks/red_glass_pane.png | Bin 0 -> 119 bytes client/data/textures/blocks/red_mushroom.png | Bin 0 -> 143 bytes .../textures/blocks/red_mushroom_block_cap.png | Bin 0 -> 428 bytes .../blocks/red_mushroom_block_inside.png | Bin 0 -> 315 bytes .../textures/blocks/red_mushroom_block_stem.png | Bin 0 -> 400 bytes client/data/textures/blocks/red_sand.png | Bin 0 -> 3455 bytes .../blocks/red_stained_hardened_clay.png | Bin 0 -> 3164 bytes client/data/textures/blocks/red_tulip.png | Bin 0 -> 556 bytes client/data/textures/blocks/red_wool.png | Bin 0 -> 464 bytes client/data/textures/blocks/redstone_block.png | Bin 0 -> 609 bytes .../textures/blocks/redstone_dust_cross.png | Bin 0 -> 5871 bytes .../blocks/redstone_dust_cross_overlay.png | Bin 0 -> 75 bytes .../data/textures/blocks/redstone_dust_line.png | Bin 0 -> 5688 bytes .../blocks/redstone_dust_line_overlay.png | Bin 0 -> 164 bytes client/data/textures/blocks/redstone_lamp.png | Bin 0 -> 616 bytes client/data/textures/blocks/redstone_ore.png | Bin 0 -> 264 bytes client/data/textures/blocks/redstone_torch.png | Bin 0 -> 160 bytes client/data/textures/blocks/reeds.png | Bin 0 -> 186 bytes client/data/textures/blocks/repeater_off.png | Bin 0 -> 375 bytes client/data/textures/blocks/repeater_on.png | Bin 0 -> 371 bytes client/data/textures/blocks/rock.png | Bin 0 -> 1024 bytes client/data/textures/blocks/rose.png | Bin 0 -> 153 bytes client/data/textures/blocks/ruby_block.png | Bin 0 -> 6457 bytes client/data/textures/blocks/ruby_ore.png | Bin 0 -> 6163 bytes client/data/textures/blocks/sand.png | Bin 0 -> 696 bytes client/data/textures/blocks/sandstone_all.png | Bin 0 -> 735 bytes .../data/textures/blocks/sandstone_bottom.png | Bin 0 -> 638 bytes .../data/textures/blocks/sandstone_carved.png | Bin 0 -> 596 bytes .../data/textures/blocks/sandstone_normal.png | Bin 0 -> 777 bytes .../data/textures/blocks/sandstone_smooth.png | Bin 0 -> 544 bytes client/data/textures/blocks/selenium_block.png | Bin 0 -> 1777 bytes client/data/textures/blocks/selenium_ore.png | Bin 0 -> 1822 bytes client/data/textures/blocks/sign.png | Bin 0 -> 1211 bytes client/data/textures/blocks/silicon_block.png | Bin 0 -> 1776 bytes client/data/textures/blocks/silicon_ore.png | Bin 0 -> 1797 bytes client/data/textures/blocks/silver_block.png | Bin 0 -> 1544 bytes client/data/textures/blocks/silver_glass.png | Bin 0 -> 202 bytes .../data/textures/blocks/silver_glass_pane.png | Bin 0 -> 120 bytes client/data/textures/blocks/silver_ore.png | Bin 0 -> 1689 bytes .../blocks/silver_stained_hardened_clay.png | Bin 0 -> 3125 bytes client/data/textures/blocks/silver_wool.png | Bin 0 -> 489 bytes client/data/textures/blocks/slime.png | Bin 0 -> 787 bytes client/data/textures/blocks/slime_flow.png | Bin 0 -> 11544 bytes client/data/textures/blocks/slime_still.png | Bin 0 -> 12733 bytes client/data/textures/blocks/smooth_rock.png | Bin 0 -> 850 bytes client/data/textures/blocks/snow.png | Bin 0 -> 207 bytes client/data/textures/blocks/sodium_block.png | Bin 0 -> 1657 bytes client/data/textures/blocks/sodium_ore.png | Bin 0 -> 1734 bytes client/data/textures/blocks/soul_sand.png | Bin 0 -> 633 bytes client/data/textures/blocks/soul_wart_0.png | Bin 0 -> 152 bytes client/data/textures/blocks/soul_wart_1.png | Bin 0 -> 271 bytes client/data/textures/blocks/soul_wart_2.png | Bin 0 -> 480 bytes client/data/textures/blocks/sponge.png | Bin 0 -> 563 bytes .../data/textures/blocks/spruce_door_bottom.png | Bin 0 -> 417 bytes client/data/textures/blocks/spruce_door_top.png | Bin 0 -> 398 bytes .../textures/blocks/spruce_leaves_autumn.png | Bin 0 -> 5995 bytes .../textures/blocks/spruce_leaves_snowy.png | Bin 0 -> 5960 bytes .../textures/blocks/spruce_leaves_spring.png | Bin 0 -> 263 bytes .../textures/blocks/spruce_leaves_summer.png | Bin 0 -> 5680 bytes .../textures/blocks/spruce_leaves_winter.png | Bin 0 -> 5945 bytes client/data/textures/blocks/spruce_log_bark.png | Bin 0 -> 451 bytes client/data/textures/blocks/spruce_log_top.png | Bin 0 -> 609 bytes client/data/textures/blocks/spruce_planks.png | Bin 0 -> 254 bytes client/data/textures/blocks/spruce_sapling.png | Bin 0 -> 211 bytes client/data/textures/blocks/stone.png | Bin 0 -> 224 bytes client/data/textures/blocks/stone_slab_side.png | Bin 0 -> 271 bytes .../textures/blocks/stonebrick_chiseled.png | Bin 0 -> 413 bytes .../data/textures/blocks/stonebrick_cracked.png | Bin 0 -> 469 bytes .../data/textures/blocks/stonebrick_default.png | Bin 0 -> 402 bytes .../data/textures/blocks/stonebrick_mossy.png | Bin 0 -> 545 bytes client/data/textures/blocks/sulfur_block.png | Bin 0 -> 1688 bytes client/data/textures/blocks/sulfur_ore.png | Bin 0 -> 1831 bytes client/data/textures/blocks/sunflower_back.png | Bin 0 -> 427 bytes .../data/textures/blocks/sunflower_bottom.png | Bin 0 -> 592 bytes client/data/textures/blocks/sunflower_front.png | Bin 0 -> 466 bytes client/data/textures/blocks/sunflower_top.png | Bin 0 -> 576 bytes client/data/textures/blocks/syringa_bottom.png | Bin 0 -> 695 bytes client/data/textures/blocks/syringa_top.png | Bin 0 -> 671 bytes client/data/textures/blocks/tall_grass.png | Bin 0 -> 584 bytes client/data/textures/blocks/thetium_block.png | Bin 0 -> 2135 bytes client/data/textures/blocks/thetium_ore.png | Bin 0 -> 1798 bytes client/data/textures/blocks/tian.png | Bin 0 -> 2680 bytes .../data/textures/blocks/tian_door_bottom.png | Bin 0 -> 5993 bytes client/data/textures/blocks/tian_door_top.png | Bin 0 -> 5936 bytes .../data/textures/blocks/tian_leaves_autumn.png | Bin 0 -> 6412 bytes .../data/textures/blocks/tian_leaves_snowy.png | Bin 0 -> 6311 bytes .../data/textures/blocks/tian_leaves_spring.png | Bin 0 -> 6217 bytes .../data/textures/blocks/tian_leaves_summer.png | Bin 0 -> 6431 bytes .../data/textures/blocks/tian_leaves_winter.png | Bin 0 -> 6426 bytes client/data/textures/blocks/tian_log_bark.png | Bin 0 -> 6280 bytes client/data/textures/blocks/tian_log_top.png | Bin 0 -> 6026 bytes client/data/textures/blocks/tian_planks.png | Bin 0 -> 5704 bytes .../textures/blocks/tian_reactor_bottom.png | Bin 0 -> 1499 bytes .../data/textures/blocks/tian_reactor_front.png | Bin 0 -> 4543 bytes .../data/textures/blocks/tian_reactor_side.png | Bin 0 -> 2066 bytes .../data/textures/blocks/tian_reactor_top.png | Bin 0 -> 1793 bytes client/data/textures/blocks/tian_sapling.png | Bin 0 -> 6050 bytes client/data/textures/blocks/tian_soil_side.png | Bin 0 -> 2733 bytes .../textures/blocks/tian_soil_side_snowed.png | Bin 0 -> 2597 bytes client/data/textures/blocks/tian_soil_top.png | Bin 0 -> 2782 bytes client/data/textures/blocks/tin_block.png | Bin 0 -> 1460 bytes client/data/textures/blocks/tin_ore.png | Bin 0 -> 1702 bytes client/data/textures/blocks/titanium_block.png | Bin 0 -> 1705 bytes client/data/textures/blocks/titanium_ore.png | Bin 0 -> 1836 bytes client/data/textures/blocks/tnt_bottom.png | Bin 0 -> 112 bytes client/data/textures/blocks/tnt_bottom_1.png | Bin 0 -> 1187 bytes client/data/textures/blocks/tnt_bottom_2.png | Bin 0 -> 1218 bytes client/data/textures/blocks/tnt_bottom_3.png | Bin 0 -> 1196 bytes client/data/textures/blocks/tnt_bottom_4.png | Bin 0 -> 1176 bytes client/data/textures/blocks/tnt_bottom_5.png | Bin 0 -> 1185 bytes client/data/textures/blocks/tnt_bottom_6.png | Bin 0 -> 1222 bytes client/data/textures/blocks/tnt_bottom_7.png | Bin 0 -> 1216 bytes client/data/textures/blocks/tnt_side.png | Bin 0 -> 212 bytes client/data/textures/blocks/tnt_side_1.png | Bin 0 -> 1633 bytes client/data/textures/blocks/tnt_side_2.png | Bin 0 -> 1618 bytes client/data/textures/blocks/tnt_side_3.png | Bin 0 -> 1587 bytes client/data/textures/blocks/tnt_side_4.png | Bin 0 -> 1602 bytes client/data/textures/blocks/tnt_side_5.png | Bin 0 -> 1600 bytes client/data/textures/blocks/tnt_side_6.png | Bin 0 -> 1508 bytes client/data/textures/blocks/tnt_side_7.png | Bin 0 -> 1571 bytes client/data/textures/blocks/tnt_top.png | Bin 0 -> 237 bytes client/data/textures/blocks/tnt_top_1.png | Bin 0 -> 1909 bytes client/data/textures/blocks/tnt_top_2.png | Bin 0 -> 1922 bytes client/data/textures/blocks/tnt_top_3.png | Bin 0 -> 1759 bytes client/data/textures/blocks/tnt_top_4.png | Bin 0 -> 1864 bytes client/data/textures/blocks/tnt_top_5.png | Bin 0 -> 1885 bytes client/data/textures/blocks/tnt_top_6.png | Bin 0 -> 1840 bytes client/data/textures/blocks/tnt_top_7.png | Bin 0 -> 1878 bytes client/data/textures/blocks/torch.png | Bin 0 -> 159 bytes client/data/textures/blocks/trapdoor.png | Bin 0 -> 442 bytes client/data/textures/blocks/trip_wire.png | Bin 0 -> 281 bytes client/data/textures/blocks/tripwire_hook.png | Bin 0 -> 233 bytes client/data/textures/blocks/tungsten_block.png | Bin 0 -> 1792 bytes client/data/textures/blocks/tungsten_ore.png | Bin 0 -> 1807 bytes .../textures/blocks/unlit_redstone_torch.png | Bin 0 -> 155 bytes client/data/textures/blocks/uranium_block.png | Bin 0 -> 1868 bytes client/data/textures/blocks/uranium_ore.png | Bin 0 -> 1823 bytes client/data/textures/blocks/vanadium_block.png | Bin 0 -> 1758 bytes client/data/textures/blocks/vanadium_ore.png | Bin 0 -> 1764 bytes client/data/textures/blocks/vine.png | Bin 0 -> 235 bytes .../data/textures/blocks/warp_chest_front.png | Bin 0 -> 6066 bytes client/data/textures/blocks/warp_chest_side.png | Bin 0 -> 5949 bytes client/data/textures/blocks/warp_chest_top.png | Bin 0 -> 5986 bytes client/data/textures/blocks/waterlily.png | Bin 0 -> 185 bytes client/data/textures/blocks/web.png | Bin 0 -> 213 bytes client/data/textures/blocks/wheat_0.png | Bin 0 -> 100 bytes client/data/textures/blocks/wheat_1.png | Bin 0 -> 155 bytes client/data/textures/blocks/wheat_2.png | Bin 0 -> 257 bytes client/data/textures/blocks/wheat_3.png | Bin 0 -> 379 bytes client/data/textures/blocks/wheat_4.png | Bin 0 -> 454 bytes client/data/textures/blocks/wheat_5.png | Bin 0 -> 534 bytes client/data/textures/blocks/wheat_6.png | Bin 0 -> 562 bytes client/data/textures/blocks/wheat_7.png | Bin 0 -> 621 bytes .../data/textures/blocks/white_bed_foot_end.png | Bin 0 -> 5581 bytes .../textures/blocks/white_bed_foot_side.png | Bin 0 -> 5502 bytes .../data/textures/blocks/white_bed_foot_top.png | Bin 0 -> 5618 bytes .../data/textures/blocks/white_bed_head_end.png | Bin 0 -> 5965 bytes .../textures/blocks/white_bed_head_side.png | Bin 0 -> 5847 bytes .../data/textures/blocks/white_bed_head_top.png | Bin 0 -> 6459 bytes client/data/textures/blocks/white_glass.png | Bin 0 -> 322 bytes .../data/textures/blocks/white_glass_pane.png | Bin 0 -> 2842 bytes .../blocks/white_stained_hardened_clay.png | Bin 0 -> 3148 bytes client/data/textures/blocks/white_tulip.png | Bin 0 -> 545 bytes client/data/textures/blocks/white_wool.png | Bin 0 -> 508 bytes client/data/textures/blocks/yellow_glass.png | Bin 0 -> 205 bytes .../data/textures/blocks/yellow_glass_pane.png | Bin 0 -> 120 bytes .../blocks/yellow_stained_hardened_clay.png | Bin 0 -> 3168 bytes client/data/textures/blocks/yellow_wool.png | Bin 0 -> 480 bytes client/data/textures/blocks/zinc_block.png | Bin 0 -> 1658 bytes client/data/textures/blocks/zinc_ore.png | Bin 0 -> 1771 bytes client/data/textures/entity/alucard_1.png | Bin 0 -> 1815 bytes client/data/textures/entity/alucard_2.png | Bin 0 -> 3009 bytes client/data/textures/entity/arachnoid.png | Bin 0 -> 21609 bytes client/data/textures/entity/arrow.png | Bin 0 -> 286 bytes client/data/textures/entity/bat.png | Bin 0 -> 2935 bytes client/data/textures/entity/bloodelf.png | Bin 0 -> 2413 bytes client/data/textures/entity/boat.png | Bin 0 -> 2352 bytes client/data/textures/entity/box.png | Bin 0 -> 11190 bytes client/data/textures/entity/box_brittle.png | Bin 0 -> 13381 bytes client/data/textures/entity/bullet.png | Bin 0 -> 5686 bytes client/data/textures/entity/cape_bloodelf.png | Bin 0 -> 2690 bytes client/data/textures/entity/cat_black.png | Bin 0 -> 1367 bytes client/data/textures/entity/cat_ocelot.png | Bin 0 -> 3089 bytes client/data/textures/entity/cat_red.png | Bin 0 -> 2011 bytes client/data/textures/entity/cat_siamese.png | Bin 0 -> 2685 bytes client/data/textures/entity/char.png | Bin 0 -> 1495 bytes client/data/textures/entity/charge.png | Bin 0 -> 2118 bytes client/data/textures/entity/chicken.png | Bin 0 -> 455 bytes client/data/textures/entity/cow.png | Bin 0 -> 1922 bytes client/data/textures/entity/crystal.png | Bin 0 -> 14519 bytes client/data/textures/entity/crystal_beam.png | Bin 0 -> 2065 bytes client/data/textures/entity/darkmage.png | Bin 0 -> 3826 bytes client/data/textures/entity/donkey.png | Bin 0 -> 11755 bytes client/data/textures/entity/dracula_1.png | Bin 0 -> 3468 bytes client/data/textures/entity/dracula_2.png | Bin 0 -> 2246 bytes client/data/textures/entity/dracula_3.png | Bin 0 -> 1361 bytes client/data/textures/entity/dracula_4.png | Bin 0 -> 3470 bytes client/data/textures/entity/dracula_5.png | Bin 0 -> 4107 bytes client/data/textures/entity/dracula_6.png | Bin 0 -> 1555 bytes client/data/textures/entity/dragon.png | Bin 0 -> 7919 bytes client/data/textures/entity/dragon_eyes.png | Bin 0 -> 1926 bytes client/data/textures/entity/dwarf.png | Bin 0 -> 5790 bytes client/data/textures/entity/experience_orb.png | Bin 0 -> 1064 bytes client/data/textures/entity/explosion.png | Bin 0 -> 2055 bytes client/data/textures/entity/firedemon.png | Bin 0 -> 2739 bytes client/data/textures/entity/gargoyle.png | Bin 0 -> 3777 bytes client/data/textures/entity/goblin.png | Bin 0 -> 18746 bytes client/data/textures/entity/hacker.png | Bin 0 -> 1520 bytes client/data/textures/entity/haunter.png | Bin 0 -> 1158 bytes client/data/textures/entity/herobrine.png | Bin 0 -> 1681 bytes client/data/textures/entity/highelf.png | Bin 0 -> 2625 bytes client/data/textures/entity/horse_black.png | Bin 0 -> 9191 bytes client/data/textures/entity/horse_brown.png | Bin 0 -> 9931 bytes client/data/textures/entity/horse_chestnut.png | Bin 0 -> 10512 bytes client/data/textures/entity/horse_creamy.png | Bin 0 -> 9674 bytes client/data/textures/entity/horse_darkbrown.png | Bin 0 -> 9271 bytes client/data/textures/entity/horse_gray.png | Bin 0 -> 11698 bytes .../entity/horse_markings_blackdots.png | Bin 0 -> 5401 bytes .../textures/entity/horse_markings_white.png | Bin 0 -> 3668 bytes .../entity/horse_markings_whitedots.png | Bin 0 -> 4000 bytes .../entity/horse_markings_whitefield.png | Bin 0 -> 4727 bytes client/data/textures/entity/horse_skeleton.png | Bin 0 -> 11643 bytes client/data/textures/entity/horse_white.png | Bin 0 -> 9414 bytes client/data/textures/entity/horse_zombie.png | Bin 0 -> 13998 bytes client/data/textures/entity/jiang_cheng.png | Bin 0 -> 1426 bytes client/data/textures/entity/knight_1.png | Bin 0 -> 1805 bytes client/data/textures/entity/knight_2.png | Bin 0 -> 1910 bytes client/data/textures/entity/knight_3.png | Bin 0 -> 1950 bytes client/data/textures/entity/knight_4.png | Bin 0 -> 1975 bytes client/data/textures/entity/knight_5.png | Bin 0 -> 1992 bytes client/data/textures/entity/knight_6.png | Bin 0 -> 1320 bytes client/data/textures/entity/knight_7.png | Bin 0 -> 1861 bytes client/data/textures/entity/knight_8.png | Bin 0 -> 2175 bytes client/data/textures/entity/lan_wangji.png | Bin 0 -> 987 bytes client/data/textures/entity/lead_knot.png | Bin 0 -> 746 bytes client/data/textures/entity/luo_binghe.png | Bin 0 -> 1325 bytes client/data/textures/entity/mage_1.png | Bin 0 -> 3595 bytes client/data/textures/entity/mage_2.png | Bin 0 -> 1417 bytes client/data/textures/entity/mage_3.png | Bin 0 -> 2314 bytes client/data/textures/entity/mage_4.png | Bin 0 -> 3002 bytes client/data/textures/entity/mage_5.png | Bin 0 -> 3669 bytes client/data/textures/entity/mage_6.png | Bin 0 -> 2312 bytes client/data/textures/entity/magma.png | Bin 0 -> 10097 bytes client/data/textures/entity/marine.png | Bin 0 -> 14958 bytes .../textures/entity/marine_black_templar.png | Bin 0 -> 16694 bytes client/data/textures/entity/metalhead.png | Bin 0 -> 2660 bytes client/data/textures/entity/metalhead_1.png | Bin 0 -> 1529 bytes client/data/textures/entity/metalhead_10.png | Bin 0 -> 1682 bytes client/data/textures/entity/metalhead_11.png | Bin 0 -> 1300 bytes client/data/textures/entity/metalhead_12.png | Bin 0 -> 1853 bytes client/data/textures/entity/metalhead_13.png | Bin 0 -> 2307 bytes client/data/textures/entity/metalhead_14.png | Bin 0 -> 2380 bytes client/data/textures/entity/metalhead_2.png | Bin 0 -> 823 bytes client/data/textures/entity/metalhead_3.png | Bin 0 -> 15927 bytes client/data/textures/entity/metalhead_4.png | Bin 0 -> 2883 bytes client/data/textures/entity/metalhead_5.png | Bin 0 -> 1927 bytes client/data/textures/entity/metalhead_6.png | Bin 0 -> 4289 bytes client/data/textures/entity/metalhead_7.png | Bin 0 -> 3910 bytes client/data/textures/entity/metalhead_8.png | Bin 0 -> 4356 bytes client/data/textures/entity/metalhead_9.png | Bin 0 -> 1908 bytes client/data/textures/entity/minecart.png | Bin 0 -> 2913 bytes client/data/textures/entity/mooshroom.png | Bin 0 -> 1391 bytes client/data/textures/entity/mouse.png | Bin 0 -> 4716 bytes client/data/textures/entity/mule.png | Bin 0 -> 11294 bytes client/data/textures/entity/orc_1.png | Bin 0 -> 3280 bytes client/data/textures/entity/orc_10.png | Bin 0 -> 4031 bytes client/data/textures/entity/orc_11.png | Bin 0 -> 3029 bytes client/data/textures/entity/orc_12.png | Bin 0 -> 2456 bytes client/data/textures/entity/orc_2.png | Bin 0 -> 6256 bytes client/data/textures/entity/orc_3.png | Bin 0 -> 3578 bytes client/data/textures/entity/orc_4.png | Bin 0 -> 1654 bytes client/data/textures/entity/orc_5.png | Bin 0 -> 2199 bytes client/data/textures/entity/orc_6.png | Bin 0 -> 4432 bytes client/data/textures/entity/orc_7.png | Bin 0 -> 1666 bytes client/data/textures/entity/orc_8.png | Bin 0 -> 3952 bytes client/data/textures/entity/orc_9.png | Bin 0 -> 4640 bytes client/data/textures/entity/peasant_1.png | Bin 0 -> 2527 bytes client/data/textures/entity/peasant_2.png | Bin 0 -> 2284 bytes client/data/textures/entity/peasant_3.png | Bin 0 -> 2364 bytes client/data/textures/entity/peasant_4.png | Bin 0 -> 4037 bytes client/data/textures/entity/peasant_5.png | Bin 0 -> 2809 bytes client/data/textures/entity/peasant_6.png | Bin 0 -> 2732 bytes client/data/textures/entity/pig.png | Bin 0 -> 3273 bytes client/data/textures/entity/pig_saddle.png | Bin 0 -> 342 bytes client/data/textures/entity/power_rod.png | Bin 0 -> 281 bytes client/data/textures/entity/rabbit_black.png | Bin 0 -> 2131 bytes .../textures/entity/rabbit_black_splotched.png | Bin 0 -> 9287 bytes client/data/textures/entity/rabbit_brown.png | Bin 0 -> 2422 bytes .../data/textures/entity/rabbit_caerbannog.png | Bin 0 -> 1223 bytes client/data/textures/entity/rabbit_dark.png | Bin 0 -> 8134 bytes .../data/textures/entity/rabbit_dark_gray.png | Bin 0 -> 8955 bytes client/data/textures/entity/rabbit_gold.png | Bin 0 -> 1948 bytes client/data/textures/entity/rabbit_gray.png | Bin 0 -> 9436 bytes client/data/textures/entity/rabbit_salt.png | Bin 0 -> 3192 bytes client/data/textures/entity/rabbit_toast.png | Bin 0 -> 1717 bytes client/data/textures/entity/rabbit_white.png | Bin 0 -> 1271 bytes .../textures/entity/rabbit_white_splotched.png | Bin 0 -> 1601 bytes client/data/textures/entity/sen.png | Bin 0 -> 2825 bytes client/data/textures/entity/sheep.png | Bin 0 -> 3087 bytes client/data/textures/entity/sheep_fur.png | Bin 0 -> 1625 bytes client/data/textures/entity/shen_qingqiu.png | Bin 0 -> 1746 bytes client/data/textures/entity/skull.png | Bin 0 -> 13644 bytes client/data/textures/entity/slime.png | Bin 0 -> 596 bytes client/data/textures/entity/spirit.png | Bin 0 -> 764 bytes client/data/textures/entity/squid.png | Bin 0 -> 905 bytes client/data/textures/entity/thranduil.png | Bin 0 -> 1613 bytes client/data/textures/entity/tiefling.png | Bin 0 -> 2363 bytes client/data/textures/entity/trollface.png | Bin 0 -> 2013 bytes client/data/textures/entity/undead_1.png | Bin 0 -> 1311 bytes client/data/textures/entity/undead_2.png | Bin 0 -> 1306 bytes client/data/textures/entity/undead_3.png | Bin 0 -> 1469 bytes client/data/textures/entity/undead_4.png | Bin 0 -> 1551 bytes client/data/textures/entity/unknown.png | Bin 0 -> 6065 bytes client/data/textures/entity/vampire_1.png | Bin 0 -> 3584 bytes client/data/textures/entity/vampire_2.png | Bin 0 -> 3655 bytes client/data/textures/entity/vampire_3.png | Bin 0 -> 1910 bytes client/data/textures/entity/vampire_4.png | Bin 0 -> 1266 bytes client/data/textures/entity/vampire_5.png | Bin 0 -> 890 bytes client/data/textures/entity/vampire_6.png | Bin 0 -> 2713 bytes client/data/textures/entity/vampire_7.png | Bin 0 -> 2407 bytes client/data/textures/entity/vampire_8.png | Bin 0 -> 1209 bytes client/data/textures/entity/wei_wuxian.png | Bin 0 -> 1530 bytes client/data/textures/entity/wolf.png | Bin 0 -> 4333 bytes client/data/textures/entity/wolf_angry.png | Bin 0 -> 3191 bytes client/data/textures/entity/wolf_collar.png | Bin 0 -> 4308 bytes client/data/textures/entity/wolf_tame.png | Bin 0 -> 4360 bytes client/data/textures/entity/woodelf.png | Bin 0 -> 1821 bytes client/data/textures/entity/zombie_1.png | Bin 0 -> 1261 bytes client/data/textures/entity/zombie_2.png | Bin 0 -> 1725 bytes client/data/textures/entity/zombie_3.png | Bin 0 -> 1731 bytes client/data/textures/entity/zombie_4.png | Bin 0 -> 1298 bytes client/data/textures/entity/zombie_5.png | Bin 0 -> 1223 bytes client/data/textures/entity/zombie_6.png | Bin 0 -> 2874 bytes client/data/textures/font.png | Bin 0 -> 8430 bytes client/data/textures/glint.png | Bin 0 -> 992 bytes client/data/textures/items/acacia_door.png | Bin 0 -> 200 bytes client/data/textures/items/acid_bucket.png | Bin 0 -> 6005 bytes client/data/textures/items/ahrd_fragment.png | Bin 0 -> 1699 bytes client/data/textures/items/aluminium_ingot.png | Bin 0 -> 1337 bytes client/data/textures/items/antimony_powder.png | Bin 0 -> 1384 bytes client/data/textures/items/apple.png | Bin 0 -> 181 bytes client/data/textures/items/ardite_boots.png | Bin 0 -> 1267 bytes .../data/textures/items/ardite_chestplate.png | Bin 0 -> 1390 bytes client/data/textures/items/ardite_helmet.png | Bin 0 -> 1300 bytes client/data/textures/items/ardite_leggings.png | Bin 0 -> 1263 bytes client/data/textures/items/ardite_sword.png | Bin 0 -> 1526 bytes client/data/textures/items/arrow.png | Bin 0 -> 148 bytes client/data/textures/items/arsenic_powder.png | Bin 0 -> 1376 bytes client/data/textures/items/baked_potato.png | Bin 0 -> 317 bytes client/data/textures/items/banhammer.png | Bin 0 -> 5730 bytes client/data/textures/items/beef.png | Bin 0 -> 212 bytes client/data/textures/items/birch_door.png | Bin 0 -> 255 bytes client/data/textures/items/bismuth_ingot.png | Bin 0 -> 1526 bytes client/data/textures/items/black_bed.png | Bin 0 -> 390 bytes .../data/textures/items/black_metal_ingot.png | Bin 0 -> 316 bytes client/data/textures/items/black_quartz.png | Bin 0 -> 6586 bytes client/data/textures/items/blackbrick.png | Bin 0 -> 6425 bytes client/data/textures/items/blackwood_door.png | Bin 0 -> 4615 bytes client/data/textures/items/blaze_powder.png | Bin 0 -> 278 bytes client/data/textures/items/blaze_rod.png | Bin 0 -> 168 bytes client/data/textures/items/blood_bucket.png | Bin 0 -> 5782 bytes client/data/textures/items/bloodbrick.png | Bin 0 -> 769 bytes client/data/textures/items/boat.png | Bin 0 -> 204 bytes client/data/textures/items/bolt.png | Bin 0 -> 5475 bytes client/data/textures/items/boltgun.png | Bin 0 -> 5794 bytes client/data/textures/items/bone.png | Bin 0 -> 187 bytes client/data/textures/items/book.png | Bin 0 -> 211 bytes client/data/textures/items/bow.png | Bin 0 -> 163 bytes client/data/textures/items/bow_pulling_0.png | Bin 0 -> 212 bytes client/data/textures/items/bow_pulling_1.png | Bin 0 -> 217 bytes client/data/textures/items/bow_pulling_2.png | Bin 0 -> 203 bytes client/data/textures/items/bowl.png | Bin 0 -> 149 bytes client/data/textures/items/bread.png | Bin 0 -> 195 bytes client/data/textures/items/brewing_stand.png | Bin 0 -> 291 bytes client/data/textures/items/brick.png | Bin 0 -> 188 bytes client/data/textures/items/bucket.png | Bin 0 -> 195 bytes client/data/textures/items/burning_soul.png | Bin 0 -> 5812 bytes client/data/textures/items/cake.png | Bin 0 -> 239 bytes client/data/textures/items/calcium_powder.png | Bin 0 -> 1274 bytes client/data/textures/items/camera.png | Bin 0 -> 5527 bytes client/data/textures/items/carrot.png | Bin 0 -> 336 bytes .../data/textures/items/carrot_on_a_stick.png | Bin 0 -> 220 bytes client/data/textures/items/cauldron.png | Bin 0 -> 331 bytes client/data/textures/items/chain.png | Bin 0 -> 5626 bytes client/data/textures/items/chain_boots.png | Bin 0 -> 163 bytes client/data/textures/items/chain_chestplate.png | Bin 0 -> 193 bytes client/data/textures/items/chain_helmet.png | Bin 0 -> 169 bytes client/data/textures/items/chain_leggings.png | Bin 0 -> 166 bytes client/data/textures/items/charcoal.png | Bin 0 -> 514 bytes client/data/textures/items/charge_crystal.png | Bin 0 -> 5839 bytes client/data/textures/items/charged_orb.png | Bin 0 -> 5822 bytes client/data/textures/items/cherry_door.png | Bin 0 -> 1570 bytes client/data/textures/items/chest_minecart.png | Bin 0 -> 246 bytes client/data/textures/items/chick_magnet.png | Bin 0 -> 5680 bytes client/data/textures/items/chicken.png | Bin 0 -> 313 bytes client/data/textures/items/chrome_ingot.png | Bin 0 -> 1355 bytes client/data/textures/items/cinnabar.png | Bin 0 -> 6064 bytes client/data/textures/items/clay_ball.png | Bin 0 -> 177 bytes client/data/textures/items/clock.png | Bin 0 -> 5737 bytes client/data/textures/items/cloth_boots.png | Bin 0 -> 5258 bytes .../data/textures/items/cloth_boots_overlay.png | Bin 0 -> 5405 bytes client/data/textures/items/cloth_chestplate.png | Bin 0 -> 182 bytes .../textures/items/cloth_chestplate_overlay.png | Bin 0 -> 5599 bytes client/data/textures/items/cloth_helmet.png | Bin 0 -> 5225 bytes .../textures/items/cloth_helmet_overlay.png | Bin 0 -> 5326 bytes client/data/textures/items/cloth_leggings.png | Bin 0 -> 5304 bytes .../textures/items/cloth_leggings_overlay.png | Bin 0 -> 5445 bytes client/data/textures/items/clownfish.png | Bin 0 -> 3254 bytes client/data/textures/items/coal.png | Bin 0 -> 267 bytes client/data/textures/items/cobalt_ingot.png | Bin 0 -> 1446 bytes client/data/textures/items/cod.png | Bin 0 -> 3078 bytes client/data/textures/items/comparator.png | Bin 0 -> 968 bytes client/data/textures/items/cooked_beef.png | Bin 0 -> 349 bytes client/data/textures/items/cooked_chicken.png | Bin 0 -> 289 bytes client/data/textures/items/cooked_cod.png | Bin 0 -> 210 bytes client/data/textures/items/cooked_porkchop.png | Bin 0 -> 448 bytes client/data/textures/items/cooked_salmon.png | Bin 0 -> 412 bytes client/data/textures/items/cookie.png | Bin 0 -> 225 bytes client/data/textures/items/copper_ingot.png | Bin 0 -> 1507 bytes client/data/textures/items/dark_lighter.png | Bin 0 -> 4735 bytes client/data/textures/items/dark_oak_door.png | Bin 0 -> 208 bytes .../data/textures/items/darkstone_fragment.png | Bin 0 -> 5664 bytes client/data/textures/items/diamond.png | Bin 0 -> 210 bytes client/data/textures/items/diamond_axe.png | Bin 0 -> 171 bytes client/data/textures/items/diamond_boots.png | Bin 0 -> 154 bytes .../data/textures/items/diamond_chestplate.png | Bin 0 -> 175 bytes client/data/textures/items/diamond_helmet.png | Bin 0 -> 140 bytes client/data/textures/items/diamond_hoe.png | Bin 0 -> 151 bytes .../data/textures/items/diamond_horse_armor.png | Bin 0 -> 461 bytes client/data/textures/items/diamond_leggings.png | Bin 0 -> 136 bytes client/data/textures/items/diamond_pickaxe.png | Bin 0 -> 181 bytes client/data/textures/items/diamond_shears.png | Bin 0 -> 1618 bytes client/data/textures/items/diamond_shovel.png | Bin 0 -> 154 bytes client/data/textures/items/diamond_sword.png | Bin 0 -> 182 bytes client/data/textures/items/die_d10_side.png | Bin 0 -> 1395 bytes client/data/textures/items/die_d10_top.png | Bin 0 -> 1472 bytes client/data/textures/items/die_d12_side.png | Bin 0 -> 1397 bytes client/data/textures/items/die_d12_top.png | Bin 0 -> 1468 bytes client/data/textures/items/die_d20_side.png | Bin 0 -> 1492 bytes client/data/textures/items/die_d20_top.png | Bin 0 -> 1558 bytes client/data/textures/items/die_d4_side.png | Bin 0 -> 1432 bytes client/data/textures/items/die_d4_top.png | Bin 0 -> 1449 bytes client/data/textures/items/die_d6_side.png | Bin 0 -> 1370 bytes client/data/textures/items/die_d6_top.png | Bin 0 -> 1458 bytes client/data/textures/items/die_d8_side.png | Bin 0 -> 1372 bytes client/data/textures/items/die_d8_top.png | Bin 0 -> 1394 bytes client/data/textures/items/dye_black.png | Bin 0 -> 5348 bytes client/data/textures/items/dye_blue.png | Bin 0 -> 226 bytes client/data/textures/items/dye_brown.png | Bin 0 -> 238 bytes client/data/textures/items/dye_cyan.png | Bin 0 -> 5663 bytes client/data/textures/items/dye_gray.png | Bin 0 -> 5311 bytes client/data/textures/items/dye_green.png | Bin 0 -> 213 bytes client/data/textures/items/dye_light_blue.png | Bin 0 -> 5468 bytes client/data/textures/items/dye_lime.png | Bin 0 -> 5410 bytes client/data/textures/items/dye_magenta.png | Bin 0 -> 5430 bytes client/data/textures/items/dye_orange.png | Bin 0 -> 5638 bytes client/data/textures/items/dye_pink.png | Bin 0 -> 5409 bytes client/data/textures/items/dye_purple.png | Bin 0 -> 5442 bytes client/data/textures/items/dye_red.png | Bin 0 -> 192 bytes client/data/textures/items/dye_silver.png | Bin 0 -> 5513 bytes client/data/textures/items/dye_white.png | Bin 0 -> 237 bytes client/data/textures/items/dye_yellow.png | Bin 0 -> 209 bytes client/data/textures/items/dynamite.png | Bin 0 -> 484 bytes client/data/textures/items/dynamite_1.png | Bin 0 -> 1932 bytes client/data/textures/items/dynamite_2.png | Bin 0 -> 1924 bytes client/data/textures/items/dynamite_3.png | Bin 0 -> 1932 bytes client/data/textures/items/dynamite_4.png | Bin 0 -> 1969 bytes client/data/textures/items/dynamite_5.png | Bin 0 -> 1949 bytes client/data/textures/items/dynamite_6.png | Bin 0 -> 1908 bytes client/data/textures/items/dynamite_7.png | Bin 0 -> 1952 bytes client/data/textures/items/egg.png | Bin 0 -> 161 bytes client/data/textures/items/emerald.png | Bin 0 -> 332 bytes .../textures/items/empty_armor_slot_boots.png | Bin 0 -> 111 bytes .../items/empty_armor_slot_chestplate.png | Bin 0 -> 112 bytes .../textures/items/empty_armor_slot_helmet.png | Bin 0 -> 110 bytes .../items/empty_armor_slot_leggings.png | Bin 0 -> 102 bytes client/data/textures/items/enchanted_book.png | Bin 0 -> 532 bytes .../data/textures/items/experience_bottle.png | Bin 0 -> 315 bytes client/data/textures/items/exterminator.png | Bin 0 -> 5910 bytes client/data/textures/items/feather.png | Bin 0 -> 150 bytes .../textures/items/fermented_spider_eye.png | Bin 0 -> 247 bytes client/data/textures/items/filled_map.png | Bin 0 -> 190 bytes client/data/textures/items/fire_charge.png | Bin 0 -> 239 bytes client/data/textures/items/firework_charge.png | Bin 0 -> 298 bytes .../textures/items/firework_charge_overlay.png | Bin 0 -> 225 bytes client/data/textures/items/fireworks.png | Bin 0 -> 192 bytes client/data/textures/items/fishing_rod.png | Bin 0 -> 174 bytes client/data/textures/items/fishing_rod_cast.png | Bin 0 -> 137 bytes client/data/textures/items/flint.png | Bin 0 -> 166 bytes client/data/textures/items/flint_and_steel.png | Bin 0 -> 190 bytes client/data/textures/items/flower_pot.png | Bin 0 -> 541 bytes client/data/textures/items/furnace_minecart.png | Bin 0 -> 229 bytes client/data/textures/items/ghast_tear.png | Bin 0 -> 126 bytes client/data/textures/items/ghi_fragment.png | Bin 0 -> 1699 bytes client/data/textures/items/glowstone_dust.png | Bin 0 -> 175 bytes client/data/textures/items/gold_axe.png | Bin 0 -> 171 bytes client/data/textures/items/gold_boots.png | Bin 0 -> 154 bytes client/data/textures/items/gold_chestplate.png | Bin 0 -> 175 bytes client/data/textures/items/gold_helmet.png | Bin 0 -> 141 bytes client/data/textures/items/gold_hoe.png | Bin 0 -> 151 bytes client/data/textures/items/gold_horse_armor.png | Bin 0 -> 430 bytes client/data/textures/items/gold_ingot.png | Bin 0 -> 198 bytes client/data/textures/items/gold_leggings.png | Bin 0 -> 136 bytes client/data/textures/items/gold_nugget.png | Bin 0 -> 143 bytes client/data/textures/items/gold_pickaxe.png | Bin 0 -> 181 bytes client/data/textures/items/gold_shears.png | Bin 0 -> 5562 bytes client/data/textures/items/gold_shovel.png | Bin 0 -> 154 bytes client/data/textures/items/gold_sword.png | Bin 0 -> 182 bytes client/data/textures/items/golden_apple.png | Bin 0 -> 164 bytes client/data/textures/items/golden_carrot.png | Bin 0 -> 274 bytes client/data/textures/items/goo_bucket.png | Bin 0 -> 5790 bytes client/data/textures/items/gunpowder.png | Bin 0 -> 180 bytes client/data/textures/items/gyriyn_axe.png | Bin 0 -> 1388 bytes client/data/textures/items/gyriyn_hoe.png | Bin 0 -> 1335 bytes client/data/textures/items/gyriyn_pickaxe.png | Bin 0 -> 1435 bytes client/data/textures/items/gyriyn_shears.png | Bin 0 -> 1608 bytes client/data/textures/items/gyriyn_shovel.png | Bin 0 -> 1420 bytes client/data/textures/items/hopper.png | Bin 0 -> 795 bytes client/data/textures/items/hopper_minecart.png | Bin 0 -> 396 bytes client/data/textures/items/hydrogen_bucket.png | Bin 0 -> 5861 bytes client/data/textures/items/info_wand.png | Bin 0 -> 1377 bytes client/data/textures/items/iodine_powder.png | Bin 0 -> 1393 bytes client/data/textures/items/iron_axe.png | Bin 0 -> 168 bytes client/data/textures/items/iron_boots.png | Bin 0 -> 154 bytes client/data/textures/items/iron_chestplate.png | Bin 0 -> 172 bytes client/data/textures/items/iron_door.png | Bin 0 -> 5176 bytes client/data/textures/items/iron_helmet.png | Bin 0 -> 141 bytes client/data/textures/items/iron_hoe.png | Bin 0 -> 148 bytes client/data/textures/items/iron_horse_armor.png | Bin 0 -> 404 bytes client/data/textures/items/iron_ingot.png | Bin 0 -> 191 bytes client/data/textures/items/iron_leggings.png | Bin 0 -> 136 bytes client/data/textures/items/iron_pickaxe.png | Bin 0 -> 178 bytes client/data/textures/items/iron_shears.png | Bin 0 -> 191 bytes client/data/textures/items/iron_shovel.png | Bin 0 -> 150 bytes client/data/textures/items/iron_sword.png | Bin 0 -> 179 bytes client/data/textures/items/item_frame.png | Bin 0 -> 401 bytes client/data/textures/items/jungle_door.png | Bin 0 -> 223 bytes client/data/textures/items/key.png | Bin 0 -> 5268 bytes client/data/textures/items/lava_bucket.png | Bin 0 -> 284 bytes client/data/textures/items/lead.png | Bin 0 -> 589 bytes client/data/textures/items/lead_ingot.png | Bin 0 -> 1310 bytes client/data/textures/items/leather.png | Bin 0 -> 184 bytes client/data/textures/items/leather_boots.png | Bin 0 -> 5171 bytes .../textures/items/leather_boots_overlay.png | Bin 0 -> 5405 bytes .../data/textures/items/leather_chestplate.png | Bin 0 -> 5259 bytes .../items/leather_chestplate_overlay.png | Bin 0 -> 5599 bytes client/data/textures/items/leather_helmet.png | Bin 0 -> 5154 bytes .../textures/items/leather_helmet_overlay.png | Bin 0 -> 5326 bytes client/data/textures/items/leather_leggings.png | Bin 0 -> 5180 bytes .../textures/items/leather_leggings_overlay.png | Bin 0 -> 5445 bytes client/data/textures/items/lightning_wand.png | Bin 0 -> 1558 bytes client/data/textures/items/lithium_ingot.png | Bin 0 -> 1559 bytes client/data/textures/items/magma_bucket.png | Bin 0 -> 5776 bytes client/data/textures/items/magma_cream.png | Bin 0 -> 472 bytes client/data/textures/items/magnesium_powder.png | Bin 0 -> 1328 bytes client/data/textures/items/magnet.png | Bin 0 -> 5678 bytes client/data/textures/items/manganese_ingot.png | Bin 0 -> 1578 bytes client/data/textures/items/map.png | Bin 0 -> 226 bytes client/data/textures/items/maple_door.png | Bin 0 -> 1164 bytes client/data/textures/items/melon.png | Bin 0 -> 237 bytes client/data/textures/items/melon_stem.png | Bin 0 -> 147 bytes client/data/textures/items/mercury_bucket.png | Bin 0 -> 5775 bytes client/data/textures/items/milk_bucket.png | Bin 0 -> 189 bytes client/data/textures/items/minecart.png | Bin 0 -> 255 bytes .../textures/items/minecart_command_block.png | Bin 0 -> 620 bytes client/data/textures/items/mushroom_stew.png | Bin 0 -> 167 bytes client/data/textures/items/mutton_cooked.png | Bin 0 -> 452 bytes client/data/textures/items/mutton_raw.png | Bin 0 -> 445 bytes client/data/textures/items/name_tag.png | Bin 0 -> 2993 bytes client/data/textures/items/navigator.png | Bin 0 -> 5660 bytes client/data/textures/items/neodymium_ingot.png | Bin 0 -> 1447 bytes client/data/textures/items/neptunium_ingot.png | Bin 0 -> 1558 bytes client/data/textures/items/nichun_axe.png | Bin 0 -> 1327 bytes client/data/textures/items/nichun_boots.png | Bin 0 -> 1152 bytes .../data/textures/items/nichun_chestplate.png | Bin 0 -> 1193 bytes client/data/textures/items/nichun_helmet.png | Bin 0 -> 1157 bytes client/data/textures/items/nichun_hoe.png | Bin 0 -> 1288 bytes client/data/textures/items/nichun_leggings.png | Bin 0 -> 1122 bytes client/data/textures/items/nichun_pickaxe.png | Bin 0 -> 1346 bytes client/data/textures/items/nichun_shears.png | Bin 0 -> 1413 bytes client/data/textures/items/nichun_shovel.png | Bin 0 -> 1322 bytes client/data/textures/items/nichun_sword.png | Bin 0 -> 1294 bytes client/data/textures/items/nickel_ingot.png | Bin 0 -> 1498 bytes client/data/textures/items/nieh_fragment.png | Bin 0 -> 1518 bytes client/data/textures/items/npc_spawner.png | Bin 0 -> 1419 bytes .../data/textures/items/npc_spawner_overlay.png | Bin 0 -> 1751 bytes client/data/textures/items/nukage_bucket.png | Bin 0 -> 5858 bytes client/data/textures/items/oak_door.png | Bin 0 -> 5269 bytes client/data/textures/items/orb.png | Bin 0 -> 5921 bytes client/data/textures/items/painting.png | Bin 0 -> 142 bytes client/data/textures/items/palladium_ingot.png | Bin 0 -> 1588 bytes client/data/textures/items/paper.png | Bin 0 -> 156 bytes client/data/textures/items/phosphor_powder.png | Bin 0 -> 1379 bytes client/data/textures/items/platinum_ingot.png | Bin 0 -> 1482 bytes client/data/textures/items/plutonium_ingot.png | Bin 0 -> 1602 bytes client/data/textures/items/poisonous_potato.png | Bin 0 -> 406 bytes client/data/textures/items/porkchop.png | Bin 0 -> 239 bytes client/data/textures/items/potassium_powder.png | Bin 0 -> 1379 bytes client/data/textures/items/potato.png | Bin 0 -> 345 bytes .../textures/items/potion_bottle_drinkable.png | Bin 0 -> 166 bytes .../data/textures/items/potion_bottle_empty.png | Bin 0 -> 166 bytes .../textures/items/potion_bottle_splash.png | Bin 0 -> 317 bytes client/data/textures/items/potion_overlay.png | Bin 0 -> 227 bytes .../data/textures/items/praseodymium_ingot.png | Bin 0 -> 1527 bytes client/data/textures/items/pufferfish.png | Bin 0 -> 816 bytes client/data/textures/items/pumpkin_pie.png | Bin 0 -> 308 bytes client/data/textures/items/pumpkin_stem.png | Bin 0 -> 130 bytes client/data/textures/items/purple_bed.png | Bin 0 -> 405 bytes client/data/textures/items/quartz.png | Bin 0 -> 951 bytes client/data/textures/items/quiver.png | Bin 0 -> 179 bytes client/data/textures/items/radium_ingot.png | Bin 0 -> 1535 bytes client/data/textures/items/record_old.png | Bin 0 -> 5467 bytes client/data/textures/items/red_bed.png | Bin 0 -> 201 bytes client/data/textures/items/redstone.png | Bin 0 -> 166 bytes client/data/textures/items/reeds.png | Bin 0 -> 204 bytes client/data/textures/items/repeater.png | Bin 0 -> 182 bytes client/data/textures/items/rotten_flesh.png | Bin 0 -> 456 bytes client/data/textures/items/ruby.png | Bin 0 -> 434 bytes client/data/textures/items/saddle.png | Bin 0 -> 186 bytes client/data/textures/items/salmon.png | Bin 0 -> 1270 bytes client/data/textures/items/selenium_powder.png | Bin 0 -> 1392 bytes client/data/textures/items/sign.png | Bin 0 -> 161 bytes client/data/textures/items/silicon_ingot.png | Bin 0 -> 1593 bytes client/data/textures/items/silver_ingot.png | Bin 0 -> 1292 bytes client/data/textures/items/slime_ball.png | Bin 0 -> 221 bytes client/data/textures/items/slime_bucket.png | Bin 0 -> 6005 bytes client/data/textures/items/snowball.png | Bin 0 -> 208 bytes client/data/textures/items/sodium_powder.png | Bin 0 -> 1403 bytes client/data/textures/items/soul_wart.png | Bin 0 -> 151 bytes client/data/textures/items/spawn_egg.png | Bin 0 -> 358 bytes .../data/textures/items/spawn_egg_overlay.png | Bin 0 -> 402 bytes client/data/textures/items/speckled_melon.png | Bin 0 -> 369 bytes client/data/textures/items/spider_eye.png | Bin 0 -> 147 bytes client/data/textures/items/spruce_door.png | Bin 0 -> 210 bytes client/data/textures/items/stick.png | Bin 0 -> 277 bytes client/data/textures/items/stone_axe.png | Bin 0 -> 170 bytes client/data/textures/items/stone_hoe.png | Bin 0 -> 150 bytes client/data/textures/items/stone_pickaxe.png | Bin 0 -> 179 bytes client/data/textures/items/stone_shovel.png | Bin 0 -> 154 bytes client/data/textures/items/stone_sword.png | Bin 0 -> 182 bytes client/data/textures/items/string.png | Bin 0 -> 177 bytes client/data/textures/items/sugar.png | Bin 0 -> 172 bytes client/data/textures/items/sulfur_powder.png | Bin 0 -> 1428 bytes client/data/textures/items/thetium_axe.png | Bin 0 -> 1400 bytes client/data/textures/items/thetium_boots.png | Bin 0 -> 1311 bytes .../data/textures/items/thetium_chestplate.png | Bin 0 -> 1439 bytes client/data/textures/items/thetium_helmet.png | Bin 0 -> 1286 bytes client/data/textures/items/thetium_hoe.png | Bin 0 -> 1338 bytes client/data/textures/items/thetium_leggings.png | Bin 0 -> 1304 bytes client/data/textures/items/thetium_pickaxe.png | Bin 0 -> 1473 bytes client/data/textures/items/thetium_shears.png | Bin 0 -> 1595 bytes client/data/textures/items/thetium_shovel.png | Bin 0 -> 1409 bytes client/data/textures/items/thetium_sword.png | Bin 0 -> 1516 bytes client/data/textures/items/thi_fragment.png | Bin 0 -> 1715 bytes client/data/textures/items/tian_door.png | Bin 0 -> 5235 bytes client/data/textures/items/tin_ingot.png | Bin 0 -> 1339 bytes client/data/textures/items/titanium_ingot.png | Bin 0 -> 1539 bytes client/data/textures/items/tnt_minecart.png | Bin 0 -> 489 bytes client/data/textures/items/tungsten_ingot.png | Bin 0 -> 1466 bytes client/data/textures/items/uranium_ingot.png | Bin 0 -> 1574 bytes client/data/textures/items/vanadium_ingot.png | Bin 0 -> 1458 bytes client/data/textures/items/wand.png | Bin 0 -> 1421 bytes client/data/textures/items/water_bucket.png | Bin 0 -> 237 bytes .../textures/items/weather_token_chilled.png | Bin 0 -> 5469 bytes .../data/textures/items/weather_token_clear.png | Bin 0 -> 5392 bytes .../data/textures/items/weather_token_cold.png | Bin 0 -> 5769 bytes .../data/textures/items/weather_token_fire.png | Bin 0 -> 5718 bytes .../data/textures/items/weather_token_fog.png | Bin 0 -> 5412 bytes .../data/textures/items/weather_token_frost.png | Bin 0 -> 5630 bytes .../data/textures/items/weather_token_hail.png | Bin 0 -> 5326 bytes .../textures/items/weather_token_hailstorm.png | Bin 0 -> 5752 bytes .../data/textures/items/weather_token_hot.png | Bin 0 -> 6018 bytes .../data/textures/items/weather_token_ice.png | Bin 0 -> 5342 bytes .../textures/items/weather_token_iceage.png | Bin 0 -> 5961 bytes .../textures/items/weather_token_inferno.png | Bin 0 -> 5801 bytes .../data/textures/items/weather_token_rain.png | Bin 0 -> 5556 bytes .../data/textures/items/weather_token_snow.png | Bin 0 -> 5536 bytes .../textures/items/weather_token_snowstorm.png | Bin 0 -> 5898 bytes .../data/textures/items/weather_token_storm.png | Bin 0 -> 6246 bytes .../textures/items/weather_token_thunder.png | Bin 0 -> 6024 bytes client/data/textures/items/wheat.png | Bin 0 -> 142 bytes client/data/textures/items/wheats.png | Bin 0 -> 283 bytes client/data/textures/items/white_bed.png | Bin 0 -> 5585 bytes client/data/textures/items/wood_axe.png | Bin 0 -> 170 bytes client/data/textures/items/wood_hoe.png | Bin 0 -> 150 bytes client/data/textures/items/wood_pickaxe.png | Bin 0 -> 180 bytes client/data/textures/items/wood_shovel.png | Bin 0 -> 153 bytes client/data/textures/items/wood_sword.png | Bin 0 -> 181 bytes client/data/textures/items/writable_book.png | Bin 0 -> 333 bytes client/data/textures/items/written_book.png | Bin 0 -> 274 bytes client/data/textures/items/zinc_ingot.png | Bin 0 -> 1488 bytes client/data/textures/world/clouds.png | Bin 0 -> 13674 bytes client/data/textures/world/clouds_dense.png | Bin 0 -> 19501 bytes client/data/textures/world/foliage.png | Bin 0 -> 32155 bytes client/data/textures/world/forcefield.png | Bin 0 -> 204 bytes client/data/textures/world/grass.png | Bin 0 -> 18569 bytes client/data/textures/world/hail.png | Bin 0 -> 9873 bytes client/data/textures/world/molten.png | Bin 0 -> 26782 bytes client/data/textures/world/moon_phases.png | Bin 0 -> 1531 bytes client/data/textures/world/particles.png | Bin 0 -> 18812 bytes client/data/textures/world/rain.png | Bin 0 -> 2553 bytes client/data/textures/world/rain_new.png | Bin 0 -> 2503 bytes client/data/textures/world/snow.png | Bin 0 -> 781 bytes client/data/textures/world/sun.png | Bin 0 -> 675 bytes 1438 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 client/data/sounds/anvil_break.ogg create mode 100644 client/data/sounds/anvil_land.ogg create mode 100644 client/data/sounds/anvil_use.ogg create mode 100644 client/data/sounds/bat_death.ogg create mode 100644 client/data/sounds/bat_hurt1.ogg create mode 100644 client/data/sounds/bat_hurt2.ogg create mode 100644 client/data/sounds/bat_hurt3.ogg create mode 100644 client/data/sounds/bat_hurt4.ogg create mode 100644 client/data/sounds/bat_idle1.ogg create mode 100644 client/data/sounds/bat_idle2.ogg create mode 100644 client/data/sounds/bat_idle3.ogg create mode 100644 client/data/sounds/bat_idle4.ogg create mode 100644 client/data/sounds/bat_takeoff.ogg create mode 100644 client/data/sounds/blast.ogg create mode 100644 client/data/sounds/blast_far.ogg create mode 100644 client/data/sounds/bow.ogg create mode 100644 client/data/sounds/bowhit1.ogg create mode 100644 client/data/sounds/bowhit2.ogg create mode 100644 client/data/sounds/bowhit3.ogg create mode 100644 client/data/sounds/bowhit4.ogg create mode 100644 client/data/sounds/break.ogg create mode 100644 client/data/sounds/cat_hitt1.ogg create mode 100644 client/data/sounds/cat_hitt2.ogg create mode 100644 client/data/sounds/cat_hitt3.ogg create mode 100644 client/data/sounds/cat_meow1.ogg create mode 100644 client/data/sounds/cat_meow2.ogg create mode 100644 client/data/sounds/cat_meow3.ogg create mode 100644 client/data/sounds/cat_meow4.ogg create mode 100644 client/data/sounds/cat_purreow1.ogg create mode 100644 client/data/sounds/cat_purreow2.ogg create mode 100644 client/data/sounds/chestclosed.ogg create mode 100644 client/data/sounds/chestopen.ogg create mode 100644 client/data/sounds/chicken_hurt1.ogg create mode 100644 client/data/sounds/chicken_hurt2.ogg create mode 100644 client/data/sounds/chicken_say1.ogg create mode 100644 client/data/sounds/chicken_say2.ogg create mode 100644 client/data/sounds/chicken_say3.ogg create mode 100644 client/data/sounds/click.ogg create mode 100644 client/data/sounds/cloth1.ogg create mode 100644 client/data/sounds/cloth2.ogg create mode 100644 client/data/sounds/cloth3.ogg create mode 100644 client/data/sounds/cloth4.ogg create mode 100644 client/data/sounds/cow_hurt1.ogg create mode 100644 client/data/sounds/cow_hurt2.ogg create mode 100644 client/data/sounds/cow_hurt3.ogg create mode 100644 client/data/sounds/cow_say1.ogg create mode 100644 client/data/sounds/cow_say2.ogg create mode 100644 client/data/sounds/cow_say3.ogg create mode 100644 client/data/sounds/cow_say4.ogg create mode 100644 client/data/sounds/cut.ogg create mode 100644 client/data/sounds/door_close.ogg create mode 100644 client/data/sounds/door_open.ogg create mode 100644 client/data/sounds/dragon_growl1.ogg create mode 100644 client/data/sounds/dragon_growl2.ogg create mode 100644 client/data/sounds/dragon_growl3.ogg create mode 100644 client/data/sounds/dragon_growl4.ogg create mode 100644 client/data/sounds/dragon_wings1.ogg create mode 100644 client/data/sounds/dragon_wings2.ogg create mode 100644 client/data/sounds/dragon_wings3.ogg create mode 100644 client/data/sounds/dragon_wings4.ogg create mode 100644 client/data/sounds/dragon_wings5.ogg create mode 100644 client/data/sounds/dragon_wings6.ogg create mode 100644 client/data/sounds/drink.ogg create mode 100644 client/data/sounds/eat1.ogg create mode 100644 client/data/sounds/eat2.ogg create mode 100644 client/data/sounds/eat3.ogg create mode 100644 client/data/sounds/explode1.ogg create mode 100644 client/data/sounds/explode2.ogg create mode 100644 client/data/sounds/explode3.ogg create mode 100644 client/data/sounds/explode4.ogg create mode 100644 client/data/sounds/fallbig1.ogg create mode 100644 client/data/sounds/fallbig2.ogg create mode 100644 client/data/sounds/fallsmall.ogg create mode 100644 client/data/sounds/fire.ogg create mode 100644 client/data/sounds/fireball.ogg create mode 100644 client/data/sounds/fizz.ogg create mode 100644 client/data/sounds/fuse.ogg create mode 100644 client/data/sounds/glass1.ogg create mode 100644 client/data/sounds/glass2.ogg create mode 100644 client/data/sounds/glass3.ogg create mode 100644 client/data/sounds/grass1.ogg create mode 100644 client/data/sounds/grass2.ogg create mode 100644 client/data/sounds/grass3.ogg create mode 100644 client/data/sounds/grass4.ogg create mode 100644 client/data/sounds/gravel1.ogg create mode 100644 client/data/sounds/gravel2.ogg create mode 100644 client/data/sounds/gravel3.ogg create mode 100644 client/data/sounds/gravel4.ogg create mode 100644 client/data/sounds/hit1.ogg create mode 100644 client/data/sounds/hit2.ogg create mode 100644 client/data/sounds/hit3.ogg create mode 100644 client/data/sounds/horse_angry.ogg create mode 100644 client/data/sounds/horse_breathe1.ogg create mode 100644 client/data/sounds/horse_breathe2.ogg create mode 100644 client/data/sounds/horse_breathe3.ogg create mode 100644 client/data/sounds/horse_death.ogg create mode 100644 client/data/sounds/horse_gallop1.ogg create mode 100644 client/data/sounds/horse_gallop2.ogg create mode 100644 client/data/sounds/horse_gallop3.ogg create mode 100644 client/data/sounds/horse_gallop4.ogg create mode 100644 client/data/sounds/horse_hit1.ogg create mode 100644 client/data/sounds/horse_hit2.ogg create mode 100644 client/data/sounds/horse_hit3.ogg create mode 100644 client/data/sounds/horse_hit4.ogg create mode 100644 client/data/sounds/horse_idle1.ogg create mode 100644 client/data/sounds/horse_idle2.ogg create mode 100644 client/data/sounds/horse_idle3.ogg create mode 100644 client/data/sounds/horse_jump.ogg create mode 100644 client/data/sounds/horse_land.ogg create mode 100644 client/data/sounds/horse_soft1.ogg create mode 100644 client/data/sounds/horse_soft2.ogg create mode 100644 client/data/sounds/horse_soft3.ogg create mode 100644 client/data/sounds/horse_soft4.ogg create mode 100644 client/data/sounds/horse_soft5.ogg create mode 100644 client/data/sounds/horse_soft6.ogg create mode 100644 client/data/sounds/horse_wood1.ogg create mode 100644 client/data/sounds/horse_wood2.ogg create mode 100644 client/data/sounds/horse_wood3.ogg create mode 100644 client/data/sounds/horse_wood4.ogg create mode 100644 client/data/sounds/horse_wood5.ogg create mode 100644 client/data/sounds/horse_wood6.ogg create mode 100644 client/data/sounds/ignite.ogg create mode 100644 client/data/sounds/large_blast.ogg create mode 100644 client/data/sounds/large_blast_far.ogg create mode 100644 client/data/sounds/launch.ogg create mode 100644 client/data/sounds/lava.ogg create mode 100644 client/data/sounds/lavapop.ogg create mode 100644 client/data/sounds/levelup.ogg create mode 100644 client/data/sounds/magma.ogg create mode 100644 client/data/sounds/magmapop.ogg create mode 100644 client/data/sounds/metal1.ogg create mode 100644 client/data/sounds/metal2.ogg create mode 100644 client/data/sounds/metal3.ogg create mode 100644 client/data/sounds/metalhit1.ogg create mode 100644 client/data/sounds/metalhit2.ogg create mode 100644 client/data/sounds/minecart_base.ogg create mode 100644 client/data/sounds/minecart_inside.ogg create mode 100644 client/data/sounds/molten.ogg create mode 100644 client/data/sounds/note.ogg create mode 100644 client/data/sounds/old_explode.ogg create mode 100644 client/data/sounds/orb.ogg create mode 100644 client/data/sounds/pig_death.ogg create mode 100644 client/data/sounds/pig_say1.ogg create mode 100644 client/data/sounds/pig_say2.ogg create mode 100644 client/data/sounds/pig_say3.ogg create mode 100644 client/data/sounds/piston_in.ogg create mode 100644 client/data/sounds/piston_out.ogg create mode 100644 client/data/sounds/plop.ogg create mode 100644 client/data/sounds/pop.ogg create mode 100644 client/data/sounds/rabbit_bunnymurder.ogg create mode 100644 client/data/sounds/rabbit_hop1.ogg create mode 100644 client/data/sounds/rabbit_hop2.ogg create mode 100644 client/data/sounds/rabbit_hop3.ogg create mode 100644 client/data/sounds/rabbit_hop4.ogg create mode 100644 client/data/sounds/rabbit_hurt1.ogg create mode 100644 client/data/sounds/rabbit_hurt2.ogg create mode 100644 client/data/sounds/rabbit_hurt3.ogg create mode 100644 client/data/sounds/rabbit_hurt4.ogg create mode 100644 client/data/sounds/rabbit_idle1.ogg create mode 100644 client/data/sounds/rabbit_idle2.ogg create mode 100644 client/data/sounds/rabbit_idle3.ogg create mode 100644 client/data/sounds/rabbit_idle4.ogg create mode 100644 client/data/sounds/rain1.ogg create mode 100644 client/data/sounds/rain2.ogg create mode 100644 client/data/sounds/rain3.ogg create mode 100644 client/data/sounds/rain4.ogg create mode 100644 client/data/sounds/sand1.ogg create mode 100644 client/data/sounds/sand2.ogg create mode 100644 client/data/sounds/sand3.ogg create mode 100644 client/data/sounds/sand4.ogg create mode 100644 client/data/sounds/sheep_say1.ogg create mode 100644 client/data/sounds/sheep_say2.ogg create mode 100644 client/data/sounds/sheep_say3.ogg create mode 100644 client/data/sounds/slime_attack1.ogg create mode 100644 client/data/sounds/slime_attack2.ogg create mode 100644 client/data/sounds/slime_big1.ogg create mode 100644 client/data/sounds/slime_big2.ogg create mode 100644 client/data/sounds/slime_big3.ogg create mode 100644 client/data/sounds/slime_big4.ogg create mode 100644 client/data/sounds/slime_small1.ogg create mode 100644 client/data/sounds/slime_small2.ogg create mode 100644 client/data/sounds/slime_small3.ogg create mode 100644 client/data/sounds/slime_small4.ogg create mode 100644 client/data/sounds/slime_small5.ogg create mode 100644 client/data/sounds/snow1.ogg create mode 100644 client/data/sounds/snow2.ogg create mode 100644 client/data/sounds/snow3.ogg create mode 100644 client/data/sounds/snow4.ogg create mode 100644 client/data/sounds/spell.ogg create mode 100644 client/data/sounds/splash.ogg create mode 100644 client/data/sounds/stone1.ogg create mode 100644 client/data/sounds/stone2.ogg create mode 100644 client/data/sounds/stone3.ogg create mode 100644 client/data/sounds/stone4.ogg create mode 100644 client/data/sounds/teleport.ogg create mode 100644 client/data/sounds/teleport_back.ogg create mode 100644 client/data/sounds/thunder1.ogg create mode 100644 client/data/sounds/thunder2.ogg create mode 100644 client/data/sounds/thunder3.ogg create mode 100644 client/data/sounds/twinkle.ogg create mode 100644 client/data/sounds/twinkle_far.ogg create mode 100644 client/data/sounds/water.ogg create mode 100644 client/data/sounds/wolf_bark1.ogg create mode 100644 client/data/sounds/wolf_bark2.ogg create mode 100644 client/data/sounds/wolf_bark3.ogg create mode 100644 client/data/sounds/wolf_death.ogg create mode 100644 client/data/sounds/wolf_growl1.ogg create mode 100644 client/data/sounds/wolf_growl2.ogg create mode 100644 client/data/sounds/wolf_growl3.ogg create mode 100644 client/data/sounds/wolf_hurt1.ogg create mode 100644 client/data/sounds/wolf_hurt2.ogg create mode 100644 client/data/sounds/wolf_hurt3.ogg create mode 100644 client/data/sounds/wolf_panting.ogg create mode 100644 client/data/sounds/wolf_shake.ogg create mode 100644 client/data/sounds/wolf_whine.ogg create mode 100644 client/data/sounds/wood1.ogg create mode 100644 client/data/sounds/wood2.ogg create mode 100644 client/data/sounds/wood3.ogg create mode 100644 client/data/sounds/wood4.ogg create mode 100755 client/data/textures/armor/ardite_layer_1.png create mode 100755 client/data/textures/armor/ardite_layer_2.png create mode 100755 client/data/textures/armor/chain_layer_1.png create mode 100755 client/data/textures/armor/chain_layer_2.png create mode 100755 client/data/textures/armor/cloth_layer_1.png create mode 100755 client/data/textures/armor/cloth_layer_1_overlay.png create mode 100755 client/data/textures/armor/cloth_layer_2.png create mode 100755 client/data/textures/armor/cloth_layer_2_overlay.png create mode 100755 client/data/textures/armor/diamond_layer_1.png create mode 100755 client/data/textures/armor/diamond_layer_2.png create mode 100755 client/data/textures/armor/gold_layer_1.png create mode 100755 client/data/textures/armor/gold_layer_2.png create mode 100755 client/data/textures/armor/horse_armor_diamond.png create mode 100755 client/data/textures/armor/horse_armor_gold.png create mode 100755 client/data/textures/armor/horse_armor_iron.png create mode 100755 client/data/textures/armor/iron_layer_1.png create mode 100755 client/data/textures/armor/iron_layer_2.png create mode 100755 client/data/textures/armor/leather_layer_1.png create mode 100755 client/data/textures/armor/leather_layer_1_overlay.png create mode 100755 client/data/textures/armor/leather_layer_2.png create mode 100755 client/data/textures/armor/leather_layer_2_overlay.png create mode 100755 client/data/textures/armor/nichun_layer_1.png create mode 100755 client/data/textures/armor/nichun_layer_2.png create mode 100755 client/data/textures/armor/thetium_layer_1.png create mode 100755 client/data/textures/armor/thetium_layer_2.png create mode 100755 client/data/textures/background.png create mode 100755 client/data/textures/blocks/acacia_door_bottom.png create mode 100755 client/data/textures/blocks/acacia_door_top.png create mode 100755 client/data/textures/blocks/acacia_leaves_autumn.png create mode 100755 client/data/textures/blocks/acacia_leaves_snowy.png create mode 100755 client/data/textures/blocks/acacia_leaves_spring.png create mode 100755 client/data/textures/blocks/acacia_leaves_summer.png create mode 100755 client/data/textures/blocks/acacia_leaves_winter.png create mode 100755 client/data/textures/blocks/acacia_log_bark.png create mode 100755 client/data/textures/blocks/acacia_log_top.png create mode 100755 client/data/textures/blocks/acacia_planks.png create mode 100755 client/data/textures/blocks/acacia_sapling.png create mode 100755 client/data/textures/blocks/acid_flow.png create mode 100755 client/data/textures/blocks/acid_still.png create mode 100755 client/data/textures/blocks/activator_rail.png create mode 100755 client/data/textures/blocks/activator_rail_powered.png create mode 100755 client/data/textures/blocks/allium.png create mode 100755 client/data/textures/blocks/aluminium_block.png create mode 100755 client/data/textures/blocks/aluminium_ore.png create mode 100755 client/data/textures/blocks/antimony_block.png create mode 100755 client/data/textures/blocks/antimony_ore.png create mode 100755 client/data/textures/blocks/anvil_base.png create mode 100755 client/data/textures/blocks/anvil_top_0.png create mode 100755 client/data/textures/blocks/anvil_top_1.png create mode 100755 client/data/textures/blocks/anvil_top_2.png create mode 100755 client/data/textures/blocks/ardite_block.png create mode 100755 client/data/textures/blocks/ardite_ore.png create mode 100755 client/data/textures/blocks/arsenic_block.png create mode 100755 client/data/textures/blocks/arsenic_ore.png create mode 100755 client/data/textures/blocks/ash.png create mode 100755 client/data/textures/blocks/banner.png create mode 100755 client/data/textures/blocks/banner_base.png create mode 100755 client/data/textures/blocks/banner_border.png create mode 100755 client/data/textures/blocks/banner_bricks.png create mode 100755 client/data/textures/blocks/banner_circle.png create mode 100755 client/data/textures/blocks/banner_cross.png create mode 100755 client/data/textures/blocks/banner_curly_border.png create mode 100755 client/data/textures/blocks/banner_diagonal_left.png create mode 100755 client/data/textures/blocks/banner_diagonal_right.png create mode 100755 client/data/textures/blocks/banner_diagonal_up_left.png create mode 100755 client/data/textures/blocks/banner_diagonal_up_right.png create mode 100755 client/data/textures/blocks/banner_flower.png create mode 100755 client/data/textures/blocks/banner_gradient.png create mode 100755 client/data/textures/blocks/banner_gradient_up.png create mode 100755 client/data/textures/blocks/banner_half_horizontal.png create mode 100755 client/data/textures/blocks/banner_half_horizontal_bottom.png create mode 100755 client/data/textures/blocks/banner_half_vertical.png create mode 100755 client/data/textures/blocks/banner_half_vertical_right.png create mode 100755 client/data/textures/blocks/banner_rhombus.png create mode 100755 client/data/textures/blocks/banner_rune.png create mode 100755 client/data/textures/blocks/banner_skull.png create mode 100755 client/data/textures/blocks/banner_small_stripes.png create mode 100755 client/data/textures/blocks/banner_square_bottom_left.png create mode 100755 client/data/textures/blocks/banner_square_bottom_right.png create mode 100755 client/data/textures/blocks/banner_square_top_left.png create mode 100755 client/data/textures/blocks/banner_square_top_right.png create mode 100755 client/data/textures/blocks/banner_straight_cross.png create mode 100755 client/data/textures/blocks/banner_stripe_bottom.png create mode 100755 client/data/textures/blocks/banner_stripe_center.png create mode 100755 client/data/textures/blocks/banner_stripe_downleft.png create mode 100755 client/data/textures/blocks/banner_stripe_downright.png create mode 100755 client/data/textures/blocks/banner_stripe_left.png create mode 100755 client/data/textures/blocks/banner_stripe_middle.png create mode 100755 client/data/textures/blocks/banner_stripe_right.png create mode 100755 client/data/textures/blocks/banner_stripe_top.png create mode 100755 client/data/textures/blocks/banner_thing.png create mode 100755 client/data/textures/blocks/banner_triangle_bottom.png create mode 100755 client/data/textures/blocks/banner_triangle_top.png create mode 100755 client/data/textures/blocks/banner_triangles_bottom.png create mode 100755 client/data/textures/blocks/banner_triangles_top.png create mode 100755 client/data/textures/blocks/beacon.png create mode 100755 client/data/textures/blocks/beacon_beam.png create mode 100755 client/data/textures/blocks/bedrock.png create mode 100755 client/data/textures/blocks/birch_door_bottom.png create mode 100755 client/data/textures/blocks/birch_door_top.png create mode 100755 client/data/textures/blocks/birch_leaves_autumn.png create mode 100755 client/data/textures/blocks/birch_leaves_snowy.png create mode 100755 client/data/textures/blocks/birch_leaves_spring.png create mode 100755 client/data/textures/blocks/birch_leaves_summer.png create mode 100755 client/data/textures/blocks/birch_leaves_winter.png create mode 100755 client/data/textures/blocks/birch_log_bark.png create mode 100755 client/data/textures/blocks/birch_log_top.png create mode 100755 client/data/textures/blocks/birch_planks.png create mode 100755 client/data/textures/blocks/birch_sapling.png create mode 100755 client/data/textures/blocks/bismuth_block.png create mode 100755 client/data/textures/blocks/bismuth_ore.png create mode 100755 client/data/textures/blocks/black_bed_foot_end.png create mode 100755 client/data/textures/blocks/black_bed_foot_side.png create mode 100755 client/data/textures/blocks/black_bed_foot_top.png create mode 100755 client/data/textures/blocks/black_bed_head_end.png create mode 100755 client/data/textures/blocks/black_bed_head_side.png create mode 100755 client/data/textures/blocks/black_bed_head_top.png create mode 100755 client/data/textures/blocks/black_brick.png create mode 100755 client/data/textures/blocks/black_glass.png create mode 100755 client/data/textures/blocks/black_glass_pane.png create mode 100755 client/data/textures/blocks/black_lotus.png create mode 100755 client/data/textures/blocks/black_metal_block.png create mode 100755 client/data/textures/blocks/black_metal_ore.png create mode 100755 client/data/textures/blocks/black_quartz_block_bottom.png create mode 100755 client/data/textures/blocks/black_quartz_block_chiseled.png create mode 100755 client/data/textures/blocks/black_quartz_block_chiseled_top.png create mode 100755 client/data/textures/blocks/black_quartz_block_lines.png create mode 100755 client/data/textures/blocks/black_quartz_block_lines_top.png create mode 100755 client/data/textures/blocks/black_quartz_block_side.png create mode 100755 client/data/textures/blocks/black_quartz_ore.png create mode 100755 client/data/textures/blocks/black_quartz_top.png create mode 100755 client/data/textures/blocks/black_stained_hardened_clay.png create mode 100755 client/data/textures/blocks/black_wool.png create mode 100755 client/data/textures/blocks/blackened_cobble.png create mode 100755 client/data/textures/blocks/blackened_dirt.png create mode 100755 client/data/textures/blocks/blackened_soil_side.png create mode 100755 client/data/textures/blocks/blackened_soil_top.png create mode 100755 client/data/textures/blocks/blackened_stone.png create mode 100755 client/data/textures/blocks/blackwood_door_bottom.png create mode 100755 client/data/textures/blocks/blackwood_door_top.png create mode 100755 client/data/textures/blocks/blackwood_leaves_autumn.png create mode 100755 client/data/textures/blocks/blackwood_leaves_snowy.png create mode 100755 client/data/textures/blocks/blackwood_leaves_spring.png create mode 100755 client/data/textures/blocks/blackwood_leaves_summer.png create mode 100755 client/data/textures/blocks/blackwood_leaves_winter.png create mode 100755 client/data/textures/blocks/blackwood_log_bark.png create mode 100755 client/data/textures/blocks/blackwood_log_top.png create mode 100755 client/data/textures/blocks/blackwood_planks.png create mode 100755 client/data/textures/blocks/blackwood_sapling.png create mode 100755 client/data/textures/blocks/blood_brick.png create mode 100755 client/data/textures/blocks/blood_flow.png create mode 100755 client/data/textures/blocks/blood_still.png create mode 100755 client/data/textures/blocks/blue_glass.png create mode 100755 client/data/textures/blocks/blue_glass_pane.png create mode 100755 client/data/textures/blocks/blue_mushroom.png create mode 100755 client/data/textures/blocks/blue_orchid.png create mode 100755 client/data/textures/blocks/blue_stained_hardened_clay.png create mode 100755 client/data/textures/blocks/blue_wool.png create mode 100755 client/data/textures/blocks/bookshelf.png create mode 100755 client/data/textures/blocks/brewing_stand.png create mode 100755 client/data/textures/blocks/brewing_stand_base.png create mode 100755 client/data/textures/blocks/brick_block.png create mode 100755 client/data/textures/blocks/brown_glass.png create mode 100755 client/data/textures/blocks/brown_glass_pane.png create mode 100755 client/data/textures/blocks/brown_mushroom.png create mode 100755 client/data/textures/blocks/brown_mushroom_block_cap.png create mode 100755 client/data/textures/blocks/brown_mushroom_block_inside.png create mode 100755 client/data/textures/blocks/brown_mushroom_block_stem.png create mode 100755 client/data/textures/blocks/brown_stained_hardened_clay.png create mode 100755 client/data/textures/blocks/brown_wool.png create mode 100755 client/data/textures/blocks/cactus_bottom.png create mode 100755 client/data/textures/blocks/cactus_side.png create mode 100755 client/data/textures/blocks/cactus_top.png create mode 100755 client/data/textures/blocks/cake_bottom.png create mode 100755 client/data/textures/blocks/cake_inner.png create mode 100755 client/data/textures/blocks/cake_side.png create mode 100755 client/data/textures/blocks/cake_top.png create mode 100755 client/data/textures/blocks/calcium_block.png create mode 100755 client/data/textures/blocks/calcium_ore.png create mode 100755 client/data/textures/blocks/carrot_0.png create mode 100755 client/data/textures/blocks/carrot_1.png create mode 100755 client/data/textures/blocks/carrot_2.png create mode 100755 client/data/textures/blocks/carrot_3.png create mode 100755 client/data/textures/blocks/cauldron_bottom.png create mode 100755 client/data/textures/blocks/cauldron_inner.png create mode 100755 client/data/textures/blocks/cauldron_side.png create mode 100755 client/data/textures/blocks/cauldron_top.png create mode 100755 client/data/textures/blocks/cell_rock.png create mode 100755 client/data/textures/blocks/cherry_door_bottom.png create mode 100755 client/data/textures/blocks/cherry_door_top.png create mode 100755 client/data/textures/blocks/cherry_leaves_autumn.png create mode 100755 client/data/textures/blocks/cherry_leaves_snowy.png create mode 100755 client/data/textures/blocks/cherry_leaves_spring.png create mode 100755 client/data/textures/blocks/cherry_leaves_summer.png create mode 100755 client/data/textures/blocks/cherry_leaves_winter.png create mode 100755 client/data/textures/blocks/cherry_log_bark.png create mode 100755 client/data/textures/blocks/cherry_log_top.png create mode 100755 client/data/textures/blocks/cherry_planks.png create mode 100755 client/data/textures/blocks/cherry_sapling.png create mode 100755 client/data/textures/blocks/chest_normal.png create mode 100755 client/data/textures/blocks/chest_normal_double.png create mode 100755 client/data/textures/blocks/chest_trapped.png create mode 100755 client/data/textures/blocks/chest_trapped_double.png create mode 100755 client/data/textures/blocks/chrome_block.png create mode 100755 client/data/textures/blocks/chrome_ore.png create mode 100755 client/data/textures/blocks/cinnabar_block.png create mode 100755 client/data/textures/blocks/cinnabar_ore.png create mode 100755 client/data/textures/blocks/clay.png create mode 100755 client/data/textures/blocks/coal_block.png create mode 100755 client/data/textures/blocks/coal_ore.png create mode 100755 client/data/textures/blocks/coarse_dirt.png create mode 100755 client/data/textures/blocks/cobalt_block.png create mode 100755 client/data/textures/blocks/cobalt_ore.png create mode 100755 client/data/textures/blocks/cobblestone.png create mode 100755 client/data/textures/blocks/cocoa_0.png create mode 100755 client/data/textures/blocks/cocoa_1.png create mode 100755 client/data/textures/blocks/cocoa_2.png create mode 100755 client/data/textures/blocks/comparator_off.png create mode 100755 client/data/textures/blocks/comparator_on.png create mode 100755 client/data/textures/blocks/control_block.png create mode 100755 client/data/textures/blocks/copper_block.png create mode 100755 client/data/textures/blocks/copper_ore.png create mode 100755 client/data/textures/blocks/core.png create mode 100755 client/data/textures/blocks/crafting_table_front.png create mode 100755 client/data/textures/blocks/crafting_table_side.png create mode 100755 client/data/textures/blocks/crafting_table_top.png create mode 100755 client/data/textures/blocks/cyan_glass.png create mode 100755 client/data/textures/blocks/cyan_glass_pane.png create mode 100755 client/data/textures/blocks/cyan_stained_hardened_clay.png create mode 100755 client/data/textures/blocks/cyan_wool.png create mode 100755 client/data/textures/blocks/dandelion.png create mode 100755 client/data/textures/blocks/dark_oak_door_bottom.png create mode 100755 client/data/textures/blocks/dark_oak_door_top.png create mode 100755 client/data/textures/blocks/dark_oak_leaves_autumn.png create mode 100755 client/data/textures/blocks/dark_oak_leaves_snowy.png create mode 100755 client/data/textures/blocks/dark_oak_leaves_spring.png create mode 100755 client/data/textures/blocks/dark_oak_leaves_summer.png create mode 100755 client/data/textures/blocks/dark_oak_leaves_winter.png create mode 100755 client/data/textures/blocks/dark_oak_log_bark.png create mode 100755 client/data/textures/blocks/dark_oak_log_top.png create mode 100755 client/data/textures/blocks/dark_oak_planks.png create mode 100755 client/data/textures/blocks/dark_oak_sapling.png create mode 100755 client/data/textures/blocks/darkstone.png create mode 100755 client/data/textures/blocks/daylight_detector_inverted_top.png create mode 100755 client/data/textures/blocks/daylight_detector_side.png create mode 100755 client/data/textures/blocks/daylight_detector_top.png create mode 100755 client/data/textures/blocks/deadbush.png create mode 100755 client/data/textures/blocks/destroy_stage_0.png create mode 100755 client/data/textures/blocks/destroy_stage_1.png create mode 100755 client/data/textures/blocks/destroy_stage_2.png create mode 100755 client/data/textures/blocks/destroy_stage_3.png create mode 100755 client/data/textures/blocks/destroy_stage_4.png create mode 100755 client/data/textures/blocks/destroy_stage_5.png create mode 100755 client/data/textures/blocks/destroy_stage_6.png create mode 100755 client/data/textures/blocks/destroy_stage_7.png create mode 100755 client/data/textures/blocks/destroy_stage_8.png create mode 100755 client/data/textures/blocks/destroy_stage_9.png create mode 100755 client/data/textures/blocks/detector_rail.png create mode 100755 client/data/textures/blocks/detector_rail_powered.png create mode 100755 client/data/textures/blocks/diamond_block.png create mode 100755 client/data/textures/blocks/diamond_ore.png create mode 100755 client/data/textures/blocks/dirt.png create mode 100755 client/data/textures/blocks/dirt_podzol_side.png create mode 100755 client/data/textures/blocks/dirt_podzol_top.png create mode 100755 client/data/textures/blocks/dispenser_front_horizontal.png create mode 100755 client/data/textures/blocks/dispenser_front_vertical.png create mode 100755 client/data/textures/blocks/double_fern_bottom.png create mode 100755 client/data/textures/blocks/double_fern_top.png create mode 100755 client/data/textures/blocks/double_grass_bottom.png create mode 100755 client/data/textures/blocks/double_grass_top.png create mode 100755 client/data/textures/blocks/double_rose_bottom.png create mode 100755 client/data/textures/blocks/double_rose_top.png create mode 100755 client/data/textures/blocks/double_stone_top.png create mode 100755 client/data/textures/blocks/dragon_egg.png create mode 100755 client/data/textures/blocks/dropper_front_horizontal.png create mode 100755 client/data/textures/blocks/dropper_front_vertical.png create mode 100755 client/data/textures/blocks/dry_leaves.png create mode 100755 client/data/textures/blocks/emerald_block.png create mode 100755 client/data/textures/blocks/emerald_ore.png create mode 100755 client/data/textures/blocks/enchanting_table_bottom.png create mode 100755 client/data/textures/blocks/enchanting_table_side.png create mode 100755 client/data/textures/blocks/enchanting_table_top.png create mode 100755 client/data/textures/blocks/farmland_0.png create mode 100755 client/data/textures/blocks/farmland_1.png create mode 100755 client/data/textures/blocks/farmland_2.png create mode 100755 client/data/textures/blocks/farmland_3.png create mode 100755 client/data/textures/blocks/farmland_4.png create mode 100755 client/data/textures/blocks/farmland_5.png create mode 100755 client/data/textures/blocks/farmland_6.png create mode 100755 client/data/textures/blocks/farmland_7.png create mode 100755 client/data/textures/blocks/fern.png create mode 100755 client/data/textures/blocks/floor_portal.png create mode 100755 client/data/textures/blocks/floor_tiles.png create mode 100755 client/data/textures/blocks/floor_tiles_black.png create mode 100755 client/data/textures/blocks/floor_tiles_red.png create mode 100755 client/data/textures/blocks/floor_tiles_white.png create mode 100755 client/data/textures/blocks/flower_paeonia.png create mode 100755 client/data/textures/blocks/flower_pot.png create mode 100755 client/data/textures/blocks/furnace_front_off.png create mode 100755 client/data/textures/blocks/furnace_front_on.png create mode 100755 client/data/textures/blocks/furnace_side.png create mode 100755 client/data/textures/blocks/furnace_top.png create mode 100755 client/data/textures/blocks/glass.png create mode 100755 client/data/textures/blocks/glass_pane.png create mode 100755 client/data/textures/blocks/glowstone.png create mode 100755 client/data/textures/blocks/gold_block.png create mode 100755 client/data/textures/blocks/gold_ore.png create mode 100755 client/data/textures/blocks/golden_rail.png create mode 100755 client/data/textures/blocks/golden_rail_powered.png create mode 100755 client/data/textures/blocks/goo_flow.png create mode 100755 client/data/textures/blocks/goo_still.png create mode 100755 client/data/textures/blocks/grass_side.png create mode 100755 client/data/textures/blocks/grass_side_overlay.png create mode 100755 client/data/textures/blocks/grass_side_snowed.png create mode 100755 client/data/textures/blocks/grass_top.png create mode 100755 client/data/textures/blocks/gravel.png create mode 100755 client/data/textures/blocks/gravel_new.png create mode 100755 client/data/textures/blocks/gray_glass.png create mode 100755 client/data/textures/blocks/gray_glass_pane.png create mode 100755 client/data/textures/blocks/gray_stained_hardened_clay.png create mode 100755 client/data/textures/blocks/gray_wool.png create mode 100755 client/data/textures/blocks/green_glass.png create mode 100755 client/data/textures/blocks/green_glass_pane.png create mode 100755 client/data/textures/blocks/green_stained_hardened_clay.png create mode 100755 client/data/textures/blocks/green_wool.png create mode 100755 client/data/textures/blocks/gyriyn_block.png create mode 100755 client/data/textures/blocks/gyriyn_ore.png create mode 100755 client/data/textures/blocks/hardened_clay.png create mode 100755 client/data/textures/blocks/hay_block_side.png create mode 100755 client/data/textures/blocks/hay_block_top.png create mode 100755 client/data/textures/blocks/hellrock.png create mode 100755 client/data/textures/blocks/hopper_inside.png create mode 100755 client/data/textures/blocks/hopper_outside.png create mode 100755 client/data/textures/blocks/hopper_top.png create mode 100755 client/data/textures/blocks/houstonia.png create mode 100755 client/data/textures/blocks/hydrogen_flow.png create mode 100755 client/data/textures/blocks/hydrogen_still.png create mode 100755 client/data/textures/blocks/ice.png create mode 100755 client/data/textures/blocks/iodine_block.png create mode 100755 client/data/textures/blocks/iodine_ore.png create mode 100755 client/data/textures/blocks/iron_bars.png create mode 100755 client/data/textures/blocks/iron_block.png create mode 100755 client/data/textures/blocks/iron_door_bottom.png create mode 100755 client/data/textures/blocks/iron_door_top.png create mode 100755 client/data/textures/blocks/iron_ore.png create mode 100755 client/data/textures/blocks/iron_trapdoor.png create mode 100755 client/data/textures/blocks/itemframe_background.png create mode 100755 client/data/textures/blocks/jukebox_side.png create mode 100755 client/data/textures/blocks/jukebox_top.png create mode 100755 client/data/textures/blocks/jungle_door_bottom.png create mode 100755 client/data/textures/blocks/jungle_door_top.png create mode 100755 client/data/textures/blocks/jungle_leaves_autumn.png create mode 100755 client/data/textures/blocks/jungle_leaves_snowy.png create mode 100755 client/data/textures/blocks/jungle_leaves_spring.png create mode 100755 client/data/textures/blocks/jungle_leaves_summer.png create mode 100755 client/data/textures/blocks/jungle_leaves_winter.png create mode 100755 client/data/textures/blocks/jungle_log_bark.png create mode 100755 client/data/textures/blocks/jungle_log_top.png create mode 100755 client/data/textures/blocks/jungle_planks.png create mode 100755 client/data/textures/blocks/jungle_sapling.png create mode 100755 client/data/textures/blocks/ladder.png create mode 100755 client/data/textures/blocks/lamp.png create mode 100755 client/data/textures/blocks/lapis_block.png create mode 100755 client/data/textures/blocks/lapis_ore.png create mode 100755 client/data/textures/blocks/lava_flow.png create mode 100755 client/data/textures/blocks/lava_still.png create mode 100755 client/data/textures/blocks/lead_block.png create mode 100755 client/data/textures/blocks/lead_ore.png create mode 100755 client/data/textures/blocks/lever.png create mode 100755 client/data/textures/blocks/light_blue_glass.png create mode 100755 client/data/textures/blocks/light_blue_glass_pane.png create mode 100755 client/data/textures/blocks/light_blue_stained_hardened_clay.png create mode 100755 client/data/textures/blocks/light_blue_wool.png create mode 100755 client/data/textures/blocks/lime_glass.png create mode 100755 client/data/textures/blocks/lime_glass_pane.png create mode 100755 client/data/textures/blocks/lime_stained_hardened_clay.png create mode 100755 client/data/textures/blocks/lime_wool.png create mode 100755 client/data/textures/blocks/lit_redstone_lamp.png create mode 100755 client/data/textures/blocks/lithium_block.png create mode 100755 client/data/textures/blocks/lithium_ore.png create mode 100755 client/data/textures/blocks/magenta_glass.png create mode 100755 client/data/textures/blocks/magenta_glass_pane.png create mode 100755 client/data/textures/blocks/magenta_stained_hardened_clay.png create mode 100755 client/data/textures/blocks/magenta_wool.png create mode 100755 client/data/textures/blocks/magnesium_block.png create mode 100755 client/data/textures/blocks/magnesium_ore.png create mode 100755 client/data/textures/blocks/manganese_block.png create mode 100755 client/data/textures/blocks/manganese_ore.png create mode 100755 client/data/textures/blocks/maple_door_bottom.png create mode 100755 client/data/textures/blocks/maple_door_top.png create mode 100755 client/data/textures/blocks/maple_leaves_autumn.png create mode 100755 client/data/textures/blocks/maple_leaves_snowy.png create mode 100755 client/data/textures/blocks/maple_leaves_spring.png create mode 100755 client/data/textures/blocks/maple_leaves_summer.png create mode 100755 client/data/textures/blocks/maple_leaves_winter.png create mode 100755 client/data/textures/blocks/maple_log_bark.png create mode 100755 client/data/textures/blocks/maple_log_top.png create mode 100755 client/data/textures/blocks/maple_planks.png create mode 100755 client/data/textures/blocks/maple_sapling.png create mode 100755 client/data/textures/blocks/melon_side.png create mode 100755 client/data/textures/blocks/melon_stem.png create mode 100755 client/data/textures/blocks/melon_stem_connected.png create mode 100755 client/data/textures/blocks/melon_top.png create mode 100755 client/data/textures/blocks/mercury_flow.png create mode 100755 client/data/textures/blocks/mercury_still.png create mode 100755 client/data/textures/blocks/mob_spawner.png create mode 100755 client/data/textures/blocks/moon_cheese.png create mode 100755 client/data/textures/blocks/moon_rock.png create mode 100755 client/data/textures/blocks/mossy_cobblestone.png create mode 100755 client/data/textures/blocks/mycelium_side.png create mode 100755 client/data/textures/blocks/mycelium_top.png create mode 100755 client/data/textures/blocks/neodymium_block.png create mode 100755 client/data/textures/blocks/neodymium_ore.png create mode 100755 client/data/textures/blocks/neptunium_block.png create mode 100755 client/data/textures/blocks/neptunium_ore.png create mode 100755 client/data/textures/blocks/nichun_block.png create mode 100755 client/data/textures/blocks/nichun_ore.png create mode 100755 client/data/textures/blocks/nickel_block.png create mode 100755 client/data/textures/blocks/nickel_ore.png create mode 100755 client/data/textures/blocks/noteblock.png create mode 100755 client/data/textures/blocks/nukage_flow.png create mode 100755 client/data/textures/blocks/nukage_still.png create mode 100755 client/data/textures/blocks/nuke_bottom.png create mode 100755 client/data/textures/blocks/nuke_side.png create mode 100755 client/data/textures/blocks/nuke_top.png create mode 100755 client/data/textures/blocks/oak_door_bottom.png create mode 100755 client/data/textures/blocks/oak_door_top.png create mode 100755 client/data/textures/blocks/oak_leaves_autumn.png create mode 100755 client/data/textures/blocks/oak_leaves_snowy.png create mode 100755 client/data/textures/blocks/oak_leaves_spring.png create mode 100755 client/data/textures/blocks/oak_leaves_summer.png create mode 100755 client/data/textures/blocks/oak_leaves_winter.png create mode 100755 client/data/textures/blocks/oak_log_bark.png create mode 100755 client/data/textures/blocks/oak_log_top.png create mode 100755 client/data/textures/blocks/oak_planks.png create mode 100755 client/data/textures/blocks/oak_sapling.png create mode 100755 client/data/textures/blocks/obsidian.png create mode 100755 client/data/textures/blocks/orange_glass.png create mode 100755 client/data/textures/blocks/orange_glass_pane.png create mode 100755 client/data/textures/blocks/orange_stained_hardened_clay.png create mode 100755 client/data/textures/blocks/orange_tulip.png create mode 100755 client/data/textures/blocks/orange_wool.png create mode 100755 client/data/textures/blocks/oxeye_daisy.png create mode 100755 client/data/textures/blocks/packed_ice.png create mode 100755 client/data/textures/blocks/paeonia_bottom.png create mode 100755 client/data/textures/blocks/paeonia_top.png create mode 100755 client/data/textures/blocks/palladium_block.png create mode 100755 client/data/textures/blocks/palladium_ore.png create mode 100755 client/data/textures/blocks/pentagram.png create mode 100755 client/data/textures/blocks/phosphor_block.png create mode 100755 client/data/textures/blocks/phosphor_ore.png create mode 100755 client/data/textures/blocks/pink_glass.png create mode 100755 client/data/textures/blocks/pink_glass_pane.png create mode 100755 client/data/textures/blocks/pink_stained_hardened_clay.png create mode 100755 client/data/textures/blocks/pink_tulip.png create mode 100755 client/data/textures/blocks/pink_wool.png create mode 100755 client/data/textures/blocks/piston_bottom.png create mode 100755 client/data/textures/blocks/piston_inner.png create mode 100755 client/data/textures/blocks/piston_side.png create mode 100755 client/data/textures/blocks/piston_top.png create mode 100755 client/data/textures/blocks/piston_top_sticky.png create mode 100755 client/data/textures/blocks/platinum_block.png create mode 100755 client/data/textures/blocks/platinum_ore.png create mode 100755 client/data/textures/blocks/plutonium_block.png create mode 100755 client/data/textures/blocks/plutonium_ore.png create mode 100755 client/data/textures/blocks/poppy.png create mode 100755 client/data/textures/blocks/portal.png create mode 100755 client/data/textures/blocks/portal_frame_bottom.png create mode 100755 client/data/textures/blocks/portal_frame_orb.png create mode 100755 client/data/textures/blocks/portal_frame_side.png create mode 100755 client/data/textures/blocks/portal_frame_top.png create mode 100755 client/data/textures/blocks/potassium_block.png create mode 100755 client/data/textures/blocks/potassium_ore.png create mode 100755 client/data/textures/blocks/potato_0.png create mode 100755 client/data/textures/blocks/potato_1.png create mode 100755 client/data/textures/blocks/potato_2.png create mode 100755 client/data/textures/blocks/potato_3.png create mode 100755 client/data/textures/blocks/praseodymium_block.png create mode 100755 client/data/textures/blocks/praseodymium_ore.png create mode 100755 client/data/textures/blocks/pumpkin_face_off.png create mode 100755 client/data/textures/blocks/pumpkin_face_on.png create mode 100755 client/data/textures/blocks/pumpkin_side.png create mode 100755 client/data/textures/blocks/pumpkin_stem.png create mode 100755 client/data/textures/blocks/pumpkin_stem_connected.png create mode 100755 client/data/textures/blocks/pumpkin_top.png create mode 100755 client/data/textures/blocks/purple_bed_foot_end.png create mode 100755 client/data/textures/blocks/purple_bed_foot_side.png create mode 100755 client/data/textures/blocks/purple_bed_foot_top.png create mode 100755 client/data/textures/blocks/purple_bed_head_end.png create mode 100755 client/data/textures/blocks/purple_bed_head_side.png create mode 100755 client/data/textures/blocks/purple_bed_head_top.png create mode 100755 client/data/textures/blocks/purple_glass.png create mode 100755 client/data/textures/blocks/purple_glass_pane.png create mode 100755 client/data/textures/blocks/purple_stained_hardened_clay.png create mode 100755 client/data/textures/blocks/purple_wool.png create mode 100755 client/data/textures/blocks/quartz_block_bottom.png create mode 100755 client/data/textures/blocks/quartz_block_chiseled.png create mode 100755 client/data/textures/blocks/quartz_block_chiseled_top.png create mode 100755 client/data/textures/blocks/quartz_block_lines.png create mode 100755 client/data/textures/blocks/quartz_block_lines_top.png create mode 100755 client/data/textures/blocks/quartz_block_side.png create mode 100755 client/data/textures/blocks/quartz_ore.png create mode 100755 client/data/textures/blocks/quartz_top.png create mode 100755 client/data/textures/blocks/radium_block.png create mode 100755 client/data/textures/blocks/radium_ore.png create mode 100755 client/data/textures/blocks/rail.png create mode 100755 client/data/textures/blocks/rail_turned.png create mode 100755 client/data/textures/blocks/red_bed_foot_end.png create mode 100755 client/data/textures/blocks/red_bed_foot_side.png create mode 100755 client/data/textures/blocks/red_bed_foot_top.png create mode 100755 client/data/textures/blocks/red_bed_head_end.png create mode 100755 client/data/textures/blocks/red_bed_head_side.png create mode 100755 client/data/textures/blocks/red_bed_head_top.png create mode 100755 client/data/textures/blocks/red_button.png create mode 100755 client/data/textures/blocks/red_glass.png create mode 100755 client/data/textures/blocks/red_glass_pane.png create mode 100755 client/data/textures/blocks/red_mushroom.png create mode 100755 client/data/textures/blocks/red_mushroom_block_cap.png create mode 100755 client/data/textures/blocks/red_mushroom_block_inside.png create mode 100755 client/data/textures/blocks/red_mushroom_block_stem.png create mode 100755 client/data/textures/blocks/red_sand.png create mode 100755 client/data/textures/blocks/red_stained_hardened_clay.png create mode 100755 client/data/textures/blocks/red_tulip.png create mode 100755 client/data/textures/blocks/red_wool.png create mode 100755 client/data/textures/blocks/redstone_block.png create mode 100755 client/data/textures/blocks/redstone_dust_cross.png create mode 100755 client/data/textures/blocks/redstone_dust_cross_overlay.png create mode 100755 client/data/textures/blocks/redstone_dust_line.png create mode 100755 client/data/textures/blocks/redstone_dust_line_overlay.png create mode 100755 client/data/textures/blocks/redstone_lamp.png create mode 100755 client/data/textures/blocks/redstone_ore.png create mode 100755 client/data/textures/blocks/redstone_torch.png create mode 100755 client/data/textures/blocks/reeds.png create mode 100755 client/data/textures/blocks/repeater_off.png create mode 100755 client/data/textures/blocks/repeater_on.png create mode 100755 client/data/textures/blocks/rock.png create mode 100755 client/data/textures/blocks/rose.png create mode 100755 client/data/textures/blocks/ruby_block.png create mode 100755 client/data/textures/blocks/ruby_ore.png create mode 100755 client/data/textures/blocks/sand.png create mode 100755 client/data/textures/blocks/sandstone_all.png create mode 100755 client/data/textures/blocks/sandstone_bottom.png create mode 100755 client/data/textures/blocks/sandstone_carved.png create mode 100755 client/data/textures/blocks/sandstone_normal.png create mode 100755 client/data/textures/blocks/sandstone_smooth.png create mode 100755 client/data/textures/blocks/selenium_block.png create mode 100755 client/data/textures/blocks/selenium_ore.png create mode 100755 client/data/textures/blocks/sign.png create mode 100755 client/data/textures/blocks/silicon_block.png create mode 100755 client/data/textures/blocks/silicon_ore.png create mode 100755 client/data/textures/blocks/silver_block.png create mode 100755 client/data/textures/blocks/silver_glass.png create mode 100755 client/data/textures/blocks/silver_glass_pane.png create mode 100755 client/data/textures/blocks/silver_ore.png create mode 100755 client/data/textures/blocks/silver_stained_hardened_clay.png create mode 100755 client/data/textures/blocks/silver_wool.png create mode 100755 client/data/textures/blocks/slime.png create mode 100755 client/data/textures/blocks/slime_flow.png create mode 100755 client/data/textures/blocks/slime_still.png create mode 100755 client/data/textures/blocks/smooth_rock.png create mode 100755 client/data/textures/blocks/snow.png create mode 100755 client/data/textures/blocks/sodium_block.png create mode 100755 client/data/textures/blocks/sodium_ore.png create mode 100755 client/data/textures/blocks/soul_sand.png create mode 100755 client/data/textures/blocks/soul_wart_0.png create mode 100755 client/data/textures/blocks/soul_wart_1.png create mode 100755 client/data/textures/blocks/soul_wart_2.png create mode 100755 client/data/textures/blocks/sponge.png create mode 100755 client/data/textures/blocks/spruce_door_bottom.png create mode 100755 client/data/textures/blocks/spruce_door_top.png create mode 100755 client/data/textures/blocks/spruce_leaves_autumn.png create mode 100755 client/data/textures/blocks/spruce_leaves_snowy.png create mode 100755 client/data/textures/blocks/spruce_leaves_spring.png create mode 100755 client/data/textures/blocks/spruce_leaves_summer.png create mode 100755 client/data/textures/blocks/spruce_leaves_winter.png create mode 100755 client/data/textures/blocks/spruce_log_bark.png create mode 100755 client/data/textures/blocks/spruce_log_top.png create mode 100755 client/data/textures/blocks/spruce_planks.png create mode 100755 client/data/textures/blocks/spruce_sapling.png create mode 100755 client/data/textures/blocks/stone.png create mode 100755 client/data/textures/blocks/stone_slab_side.png create mode 100755 client/data/textures/blocks/stonebrick_chiseled.png create mode 100755 client/data/textures/blocks/stonebrick_cracked.png create mode 100755 client/data/textures/blocks/stonebrick_default.png create mode 100755 client/data/textures/blocks/stonebrick_mossy.png create mode 100755 client/data/textures/blocks/sulfur_block.png create mode 100755 client/data/textures/blocks/sulfur_ore.png create mode 100755 client/data/textures/blocks/sunflower_back.png create mode 100755 client/data/textures/blocks/sunflower_bottom.png create mode 100755 client/data/textures/blocks/sunflower_front.png create mode 100755 client/data/textures/blocks/sunflower_top.png create mode 100755 client/data/textures/blocks/syringa_bottom.png create mode 100755 client/data/textures/blocks/syringa_top.png create mode 100755 client/data/textures/blocks/tall_grass.png create mode 100755 client/data/textures/blocks/thetium_block.png create mode 100755 client/data/textures/blocks/thetium_ore.png create mode 100755 client/data/textures/blocks/tian.png create mode 100755 client/data/textures/blocks/tian_door_bottom.png create mode 100755 client/data/textures/blocks/tian_door_top.png create mode 100755 client/data/textures/blocks/tian_leaves_autumn.png create mode 100755 client/data/textures/blocks/tian_leaves_snowy.png create mode 100755 client/data/textures/blocks/tian_leaves_spring.png create mode 100755 client/data/textures/blocks/tian_leaves_summer.png create mode 100755 client/data/textures/blocks/tian_leaves_winter.png create mode 100755 client/data/textures/blocks/tian_log_bark.png create mode 100755 client/data/textures/blocks/tian_log_top.png create mode 100755 client/data/textures/blocks/tian_planks.png create mode 100755 client/data/textures/blocks/tian_reactor_bottom.png create mode 100755 client/data/textures/blocks/tian_reactor_front.png create mode 100755 client/data/textures/blocks/tian_reactor_side.png create mode 100755 client/data/textures/blocks/tian_reactor_top.png create mode 100755 client/data/textures/blocks/tian_sapling.png create mode 100755 client/data/textures/blocks/tian_soil_side.png create mode 100755 client/data/textures/blocks/tian_soil_side_snowed.png create mode 100755 client/data/textures/blocks/tian_soil_top.png create mode 100755 client/data/textures/blocks/tin_block.png create mode 100755 client/data/textures/blocks/tin_ore.png create mode 100755 client/data/textures/blocks/titanium_block.png create mode 100755 client/data/textures/blocks/titanium_ore.png create mode 100755 client/data/textures/blocks/tnt_bottom.png create mode 100755 client/data/textures/blocks/tnt_bottom_1.png create mode 100755 client/data/textures/blocks/tnt_bottom_2.png create mode 100755 client/data/textures/blocks/tnt_bottom_3.png create mode 100755 client/data/textures/blocks/tnt_bottom_4.png create mode 100755 client/data/textures/blocks/tnt_bottom_5.png create mode 100755 client/data/textures/blocks/tnt_bottom_6.png create mode 100755 client/data/textures/blocks/tnt_bottom_7.png create mode 100755 client/data/textures/blocks/tnt_side.png create mode 100755 client/data/textures/blocks/tnt_side_1.png create mode 100755 client/data/textures/blocks/tnt_side_2.png create mode 100755 client/data/textures/blocks/tnt_side_3.png create mode 100755 client/data/textures/blocks/tnt_side_4.png create mode 100755 client/data/textures/blocks/tnt_side_5.png create mode 100755 client/data/textures/blocks/tnt_side_6.png create mode 100755 client/data/textures/blocks/tnt_side_7.png create mode 100755 client/data/textures/blocks/tnt_top.png create mode 100755 client/data/textures/blocks/tnt_top_1.png create mode 100755 client/data/textures/blocks/tnt_top_2.png create mode 100755 client/data/textures/blocks/tnt_top_3.png create mode 100755 client/data/textures/blocks/tnt_top_4.png create mode 100755 client/data/textures/blocks/tnt_top_5.png create mode 100755 client/data/textures/blocks/tnt_top_6.png create mode 100755 client/data/textures/blocks/tnt_top_7.png create mode 100755 client/data/textures/blocks/torch.png create mode 100755 client/data/textures/blocks/trapdoor.png create mode 100755 client/data/textures/blocks/trip_wire.png create mode 100755 client/data/textures/blocks/tripwire_hook.png create mode 100755 client/data/textures/blocks/tungsten_block.png create mode 100755 client/data/textures/blocks/tungsten_ore.png create mode 100755 client/data/textures/blocks/unlit_redstone_torch.png create mode 100755 client/data/textures/blocks/uranium_block.png create mode 100755 client/data/textures/blocks/uranium_ore.png create mode 100755 client/data/textures/blocks/vanadium_block.png create mode 100755 client/data/textures/blocks/vanadium_ore.png create mode 100755 client/data/textures/blocks/vine.png create mode 100755 client/data/textures/blocks/warp_chest_front.png create mode 100755 client/data/textures/blocks/warp_chest_side.png create mode 100755 client/data/textures/blocks/warp_chest_top.png create mode 100755 client/data/textures/blocks/waterlily.png create mode 100755 client/data/textures/blocks/web.png create mode 100755 client/data/textures/blocks/wheat_0.png create mode 100755 client/data/textures/blocks/wheat_1.png create mode 100755 client/data/textures/blocks/wheat_2.png create mode 100755 client/data/textures/blocks/wheat_3.png create mode 100755 client/data/textures/blocks/wheat_4.png create mode 100755 client/data/textures/blocks/wheat_5.png create mode 100755 client/data/textures/blocks/wheat_6.png create mode 100755 client/data/textures/blocks/wheat_7.png create mode 100755 client/data/textures/blocks/white_bed_foot_end.png create mode 100755 client/data/textures/blocks/white_bed_foot_side.png create mode 100755 client/data/textures/blocks/white_bed_foot_top.png create mode 100755 client/data/textures/blocks/white_bed_head_end.png create mode 100755 client/data/textures/blocks/white_bed_head_side.png create mode 100755 client/data/textures/blocks/white_bed_head_top.png create mode 100755 client/data/textures/blocks/white_glass.png create mode 100755 client/data/textures/blocks/white_glass_pane.png create mode 100755 client/data/textures/blocks/white_stained_hardened_clay.png create mode 100755 client/data/textures/blocks/white_tulip.png create mode 100755 client/data/textures/blocks/white_wool.png create mode 100755 client/data/textures/blocks/yellow_glass.png create mode 100755 client/data/textures/blocks/yellow_glass_pane.png create mode 100755 client/data/textures/blocks/yellow_stained_hardened_clay.png create mode 100755 client/data/textures/blocks/yellow_wool.png create mode 100755 client/data/textures/blocks/zinc_block.png create mode 100755 client/data/textures/blocks/zinc_ore.png create mode 100755 client/data/textures/entity/alucard_1.png create mode 100755 client/data/textures/entity/alucard_2.png create mode 100755 client/data/textures/entity/arachnoid.png create mode 100755 client/data/textures/entity/arrow.png create mode 100755 client/data/textures/entity/bat.png create mode 100755 client/data/textures/entity/bloodelf.png create mode 100755 client/data/textures/entity/boat.png create mode 100755 client/data/textures/entity/box.png create mode 100755 client/data/textures/entity/box_brittle.png create mode 100755 client/data/textures/entity/bullet.png create mode 100755 client/data/textures/entity/cape_bloodelf.png create mode 100755 client/data/textures/entity/cat_black.png create mode 100755 client/data/textures/entity/cat_ocelot.png create mode 100755 client/data/textures/entity/cat_red.png create mode 100755 client/data/textures/entity/cat_siamese.png create mode 100755 client/data/textures/entity/char.png create mode 100755 client/data/textures/entity/charge.png create mode 100755 client/data/textures/entity/chicken.png create mode 100755 client/data/textures/entity/cow.png create mode 100755 client/data/textures/entity/crystal.png create mode 100755 client/data/textures/entity/crystal_beam.png create mode 100755 client/data/textures/entity/darkmage.png create mode 100755 client/data/textures/entity/donkey.png create mode 100755 client/data/textures/entity/dracula_1.png create mode 100755 client/data/textures/entity/dracula_2.png create mode 100755 client/data/textures/entity/dracula_3.png create mode 100755 client/data/textures/entity/dracula_4.png create mode 100755 client/data/textures/entity/dracula_5.png create mode 100755 client/data/textures/entity/dracula_6.png create mode 100755 client/data/textures/entity/dragon.png create mode 100755 client/data/textures/entity/dragon_eyes.png create mode 100755 client/data/textures/entity/dwarf.png create mode 100755 client/data/textures/entity/experience_orb.png create mode 100755 client/data/textures/entity/explosion.png create mode 100755 client/data/textures/entity/firedemon.png create mode 100755 client/data/textures/entity/gargoyle.png create mode 100755 client/data/textures/entity/goblin.png create mode 100755 client/data/textures/entity/hacker.png create mode 100755 client/data/textures/entity/haunter.png create mode 100755 client/data/textures/entity/herobrine.png create mode 100755 client/data/textures/entity/highelf.png create mode 100755 client/data/textures/entity/horse_black.png create mode 100755 client/data/textures/entity/horse_brown.png create mode 100755 client/data/textures/entity/horse_chestnut.png create mode 100755 client/data/textures/entity/horse_creamy.png create mode 100755 client/data/textures/entity/horse_darkbrown.png create mode 100755 client/data/textures/entity/horse_gray.png create mode 100755 client/data/textures/entity/horse_markings_blackdots.png create mode 100755 client/data/textures/entity/horse_markings_white.png create mode 100755 client/data/textures/entity/horse_markings_whitedots.png create mode 100755 client/data/textures/entity/horse_markings_whitefield.png create mode 100755 client/data/textures/entity/horse_skeleton.png create mode 100755 client/data/textures/entity/horse_white.png create mode 100755 client/data/textures/entity/horse_zombie.png create mode 100755 client/data/textures/entity/jiang_cheng.png create mode 100755 client/data/textures/entity/knight_1.png create mode 100755 client/data/textures/entity/knight_2.png create mode 100755 client/data/textures/entity/knight_3.png create mode 100755 client/data/textures/entity/knight_4.png create mode 100755 client/data/textures/entity/knight_5.png create mode 100755 client/data/textures/entity/knight_6.png create mode 100755 client/data/textures/entity/knight_7.png create mode 100755 client/data/textures/entity/knight_8.png create mode 100755 client/data/textures/entity/lan_wangji.png create mode 100755 client/data/textures/entity/lead_knot.png create mode 100755 client/data/textures/entity/luo_binghe.png create mode 100755 client/data/textures/entity/mage_1.png create mode 100755 client/data/textures/entity/mage_2.png create mode 100755 client/data/textures/entity/mage_3.png create mode 100755 client/data/textures/entity/mage_4.png create mode 100755 client/data/textures/entity/mage_5.png create mode 100755 client/data/textures/entity/mage_6.png create mode 100755 client/data/textures/entity/magma.png create mode 100755 client/data/textures/entity/marine.png create mode 100755 client/data/textures/entity/marine_black_templar.png create mode 100755 client/data/textures/entity/metalhead.png create mode 100755 client/data/textures/entity/metalhead_1.png create mode 100755 client/data/textures/entity/metalhead_10.png create mode 100755 client/data/textures/entity/metalhead_11.png create mode 100755 client/data/textures/entity/metalhead_12.png create mode 100755 client/data/textures/entity/metalhead_13.png create mode 100755 client/data/textures/entity/metalhead_14.png create mode 100755 client/data/textures/entity/metalhead_2.png create mode 100755 client/data/textures/entity/metalhead_3.png create mode 100755 client/data/textures/entity/metalhead_4.png create mode 100755 client/data/textures/entity/metalhead_5.png create mode 100755 client/data/textures/entity/metalhead_6.png create mode 100755 client/data/textures/entity/metalhead_7.png create mode 100755 client/data/textures/entity/metalhead_8.png create mode 100755 client/data/textures/entity/metalhead_9.png create mode 100755 client/data/textures/entity/minecart.png create mode 100755 client/data/textures/entity/mooshroom.png create mode 100755 client/data/textures/entity/mouse.png create mode 100755 client/data/textures/entity/mule.png create mode 100755 client/data/textures/entity/orc_1.png create mode 100755 client/data/textures/entity/orc_10.png create mode 100755 client/data/textures/entity/orc_11.png create mode 100755 client/data/textures/entity/orc_12.png create mode 100755 client/data/textures/entity/orc_2.png create mode 100755 client/data/textures/entity/orc_3.png create mode 100755 client/data/textures/entity/orc_4.png create mode 100755 client/data/textures/entity/orc_5.png create mode 100755 client/data/textures/entity/orc_6.png create mode 100755 client/data/textures/entity/orc_7.png create mode 100755 client/data/textures/entity/orc_8.png create mode 100755 client/data/textures/entity/orc_9.png create mode 100755 client/data/textures/entity/peasant_1.png create mode 100755 client/data/textures/entity/peasant_2.png create mode 100755 client/data/textures/entity/peasant_3.png create mode 100755 client/data/textures/entity/peasant_4.png create mode 100755 client/data/textures/entity/peasant_5.png create mode 100755 client/data/textures/entity/peasant_6.png create mode 100755 client/data/textures/entity/pig.png create mode 100755 client/data/textures/entity/pig_saddle.png create mode 100755 client/data/textures/entity/power_rod.png create mode 100755 client/data/textures/entity/rabbit_black.png create mode 100755 client/data/textures/entity/rabbit_black_splotched.png create mode 100755 client/data/textures/entity/rabbit_brown.png create mode 100755 client/data/textures/entity/rabbit_caerbannog.png create mode 100755 client/data/textures/entity/rabbit_dark.png create mode 100755 client/data/textures/entity/rabbit_dark_gray.png create mode 100755 client/data/textures/entity/rabbit_gold.png create mode 100755 client/data/textures/entity/rabbit_gray.png create mode 100755 client/data/textures/entity/rabbit_salt.png create mode 100755 client/data/textures/entity/rabbit_toast.png create mode 100755 client/data/textures/entity/rabbit_white.png create mode 100755 client/data/textures/entity/rabbit_white_splotched.png create mode 100755 client/data/textures/entity/sen.png create mode 100755 client/data/textures/entity/sheep.png create mode 100755 client/data/textures/entity/sheep_fur.png create mode 100755 client/data/textures/entity/shen_qingqiu.png create mode 100755 client/data/textures/entity/skull.png create mode 100755 client/data/textures/entity/slime.png create mode 100755 client/data/textures/entity/spirit.png create mode 100755 client/data/textures/entity/squid.png create mode 100755 client/data/textures/entity/thranduil.png create mode 100755 client/data/textures/entity/tiefling.png create mode 100755 client/data/textures/entity/trollface.png create mode 100755 client/data/textures/entity/undead_1.png create mode 100755 client/data/textures/entity/undead_2.png create mode 100755 client/data/textures/entity/undead_3.png create mode 100755 client/data/textures/entity/undead_4.png create mode 100755 client/data/textures/entity/unknown.png create mode 100755 client/data/textures/entity/vampire_1.png create mode 100755 client/data/textures/entity/vampire_2.png create mode 100755 client/data/textures/entity/vampire_3.png create mode 100755 client/data/textures/entity/vampire_4.png create mode 100755 client/data/textures/entity/vampire_5.png create mode 100755 client/data/textures/entity/vampire_6.png create mode 100755 client/data/textures/entity/vampire_7.png create mode 100755 client/data/textures/entity/vampire_8.png create mode 100755 client/data/textures/entity/wei_wuxian.png create mode 100755 client/data/textures/entity/wolf.png create mode 100755 client/data/textures/entity/wolf_angry.png create mode 100755 client/data/textures/entity/wolf_collar.png create mode 100755 client/data/textures/entity/wolf_tame.png create mode 100755 client/data/textures/entity/woodelf.png create mode 100755 client/data/textures/entity/zombie_1.png create mode 100755 client/data/textures/entity/zombie_2.png create mode 100755 client/data/textures/entity/zombie_3.png create mode 100755 client/data/textures/entity/zombie_4.png create mode 100755 client/data/textures/entity/zombie_5.png create mode 100755 client/data/textures/entity/zombie_6.png create mode 100644 client/data/textures/font.png create mode 100755 client/data/textures/glint.png create mode 100755 client/data/textures/items/acacia_door.png create mode 100755 client/data/textures/items/acid_bucket.png create mode 100755 client/data/textures/items/ahrd_fragment.png create mode 100755 client/data/textures/items/aluminium_ingot.png create mode 100755 client/data/textures/items/antimony_powder.png create mode 100755 client/data/textures/items/apple.png create mode 100755 client/data/textures/items/ardite_boots.png create mode 100755 client/data/textures/items/ardite_chestplate.png create mode 100755 client/data/textures/items/ardite_helmet.png create mode 100755 client/data/textures/items/ardite_leggings.png create mode 100755 client/data/textures/items/ardite_sword.png create mode 100755 client/data/textures/items/arrow.png create mode 100755 client/data/textures/items/arsenic_powder.png create mode 100755 client/data/textures/items/baked_potato.png create mode 100755 client/data/textures/items/banhammer.png create mode 100755 client/data/textures/items/beef.png create mode 100755 client/data/textures/items/birch_door.png create mode 100755 client/data/textures/items/bismuth_ingot.png create mode 100755 client/data/textures/items/black_bed.png create mode 100755 client/data/textures/items/black_metal_ingot.png create mode 100755 client/data/textures/items/black_quartz.png create mode 100755 client/data/textures/items/blackbrick.png create mode 100755 client/data/textures/items/blackwood_door.png create mode 100755 client/data/textures/items/blaze_powder.png create mode 100755 client/data/textures/items/blaze_rod.png create mode 100755 client/data/textures/items/blood_bucket.png create mode 100755 client/data/textures/items/bloodbrick.png create mode 100755 client/data/textures/items/boat.png create mode 100755 client/data/textures/items/bolt.png create mode 100755 client/data/textures/items/boltgun.png create mode 100755 client/data/textures/items/bone.png create mode 100755 client/data/textures/items/book.png create mode 100755 client/data/textures/items/bow.png create mode 100755 client/data/textures/items/bow_pulling_0.png create mode 100755 client/data/textures/items/bow_pulling_1.png create mode 100755 client/data/textures/items/bow_pulling_2.png create mode 100755 client/data/textures/items/bowl.png create mode 100755 client/data/textures/items/bread.png create mode 100755 client/data/textures/items/brewing_stand.png create mode 100755 client/data/textures/items/brick.png create mode 100755 client/data/textures/items/bucket.png create mode 100755 client/data/textures/items/burning_soul.png create mode 100755 client/data/textures/items/cake.png create mode 100755 client/data/textures/items/calcium_powder.png create mode 100755 client/data/textures/items/camera.png create mode 100755 client/data/textures/items/carrot.png create mode 100755 client/data/textures/items/carrot_on_a_stick.png create mode 100755 client/data/textures/items/cauldron.png create mode 100755 client/data/textures/items/chain.png create mode 100755 client/data/textures/items/chain_boots.png create mode 100755 client/data/textures/items/chain_chestplate.png create mode 100755 client/data/textures/items/chain_helmet.png create mode 100755 client/data/textures/items/chain_leggings.png create mode 100755 client/data/textures/items/charcoal.png create mode 100755 client/data/textures/items/charge_crystal.png create mode 100755 client/data/textures/items/charged_orb.png create mode 100755 client/data/textures/items/cherry_door.png create mode 100755 client/data/textures/items/chest_minecart.png create mode 100755 client/data/textures/items/chick_magnet.png create mode 100755 client/data/textures/items/chicken.png create mode 100755 client/data/textures/items/chrome_ingot.png create mode 100755 client/data/textures/items/cinnabar.png create mode 100755 client/data/textures/items/clay_ball.png create mode 100755 client/data/textures/items/clock.png create mode 100755 client/data/textures/items/cloth_boots.png create mode 100755 client/data/textures/items/cloth_boots_overlay.png create mode 100755 client/data/textures/items/cloth_chestplate.png create mode 100755 client/data/textures/items/cloth_chestplate_overlay.png create mode 100755 client/data/textures/items/cloth_helmet.png create mode 100755 client/data/textures/items/cloth_helmet_overlay.png create mode 100755 client/data/textures/items/cloth_leggings.png create mode 100755 client/data/textures/items/cloth_leggings_overlay.png create mode 100755 client/data/textures/items/clownfish.png create mode 100755 client/data/textures/items/coal.png create mode 100755 client/data/textures/items/cobalt_ingot.png create mode 100755 client/data/textures/items/cod.png create mode 100755 client/data/textures/items/comparator.png create mode 100755 client/data/textures/items/cooked_beef.png create mode 100755 client/data/textures/items/cooked_chicken.png create mode 100755 client/data/textures/items/cooked_cod.png create mode 100755 client/data/textures/items/cooked_porkchop.png create mode 100755 client/data/textures/items/cooked_salmon.png create mode 100755 client/data/textures/items/cookie.png create mode 100755 client/data/textures/items/copper_ingot.png create mode 100755 client/data/textures/items/dark_lighter.png create mode 100755 client/data/textures/items/dark_oak_door.png create mode 100755 client/data/textures/items/darkstone_fragment.png create mode 100755 client/data/textures/items/diamond.png create mode 100755 client/data/textures/items/diamond_axe.png create mode 100755 client/data/textures/items/diamond_boots.png create mode 100755 client/data/textures/items/diamond_chestplate.png create mode 100755 client/data/textures/items/diamond_helmet.png create mode 100755 client/data/textures/items/diamond_hoe.png create mode 100755 client/data/textures/items/diamond_horse_armor.png create mode 100755 client/data/textures/items/diamond_leggings.png create mode 100755 client/data/textures/items/diamond_pickaxe.png create mode 100755 client/data/textures/items/diamond_shears.png create mode 100755 client/data/textures/items/diamond_shovel.png create mode 100755 client/data/textures/items/diamond_sword.png create mode 100755 client/data/textures/items/die_d10_side.png create mode 100755 client/data/textures/items/die_d10_top.png create mode 100755 client/data/textures/items/die_d12_side.png create mode 100755 client/data/textures/items/die_d12_top.png create mode 100755 client/data/textures/items/die_d20_side.png create mode 100755 client/data/textures/items/die_d20_top.png create mode 100755 client/data/textures/items/die_d4_side.png create mode 100755 client/data/textures/items/die_d4_top.png create mode 100755 client/data/textures/items/die_d6_side.png create mode 100755 client/data/textures/items/die_d6_top.png create mode 100755 client/data/textures/items/die_d8_side.png create mode 100755 client/data/textures/items/die_d8_top.png create mode 100755 client/data/textures/items/dye_black.png create mode 100755 client/data/textures/items/dye_blue.png create mode 100755 client/data/textures/items/dye_brown.png create mode 100755 client/data/textures/items/dye_cyan.png create mode 100755 client/data/textures/items/dye_gray.png create mode 100755 client/data/textures/items/dye_green.png create mode 100755 client/data/textures/items/dye_light_blue.png create mode 100755 client/data/textures/items/dye_lime.png create mode 100755 client/data/textures/items/dye_magenta.png create mode 100755 client/data/textures/items/dye_orange.png create mode 100755 client/data/textures/items/dye_pink.png create mode 100755 client/data/textures/items/dye_purple.png create mode 100755 client/data/textures/items/dye_red.png create mode 100755 client/data/textures/items/dye_silver.png create mode 100755 client/data/textures/items/dye_white.png create mode 100755 client/data/textures/items/dye_yellow.png create mode 100755 client/data/textures/items/dynamite.png create mode 100755 client/data/textures/items/dynamite_1.png create mode 100755 client/data/textures/items/dynamite_2.png create mode 100755 client/data/textures/items/dynamite_3.png create mode 100755 client/data/textures/items/dynamite_4.png create mode 100755 client/data/textures/items/dynamite_5.png create mode 100755 client/data/textures/items/dynamite_6.png create mode 100755 client/data/textures/items/dynamite_7.png create mode 100755 client/data/textures/items/egg.png create mode 100755 client/data/textures/items/emerald.png create mode 100755 client/data/textures/items/empty_armor_slot_boots.png create mode 100755 client/data/textures/items/empty_armor_slot_chestplate.png create mode 100755 client/data/textures/items/empty_armor_slot_helmet.png create mode 100755 client/data/textures/items/empty_armor_slot_leggings.png create mode 100755 client/data/textures/items/enchanted_book.png create mode 100755 client/data/textures/items/experience_bottle.png create mode 100755 client/data/textures/items/exterminator.png create mode 100755 client/data/textures/items/feather.png create mode 100755 client/data/textures/items/fermented_spider_eye.png create mode 100755 client/data/textures/items/filled_map.png create mode 100755 client/data/textures/items/fire_charge.png create mode 100755 client/data/textures/items/firework_charge.png create mode 100755 client/data/textures/items/firework_charge_overlay.png create mode 100755 client/data/textures/items/fireworks.png create mode 100755 client/data/textures/items/fishing_rod.png create mode 100755 client/data/textures/items/fishing_rod_cast.png create mode 100755 client/data/textures/items/flint.png create mode 100755 client/data/textures/items/flint_and_steel.png create mode 100755 client/data/textures/items/flower_pot.png create mode 100755 client/data/textures/items/furnace_minecart.png create mode 100755 client/data/textures/items/ghast_tear.png create mode 100755 client/data/textures/items/ghi_fragment.png create mode 100755 client/data/textures/items/glowstone_dust.png create mode 100755 client/data/textures/items/gold_axe.png create mode 100755 client/data/textures/items/gold_boots.png create mode 100755 client/data/textures/items/gold_chestplate.png create mode 100755 client/data/textures/items/gold_helmet.png create mode 100755 client/data/textures/items/gold_hoe.png create mode 100755 client/data/textures/items/gold_horse_armor.png create mode 100755 client/data/textures/items/gold_ingot.png create mode 100755 client/data/textures/items/gold_leggings.png create mode 100755 client/data/textures/items/gold_nugget.png create mode 100755 client/data/textures/items/gold_pickaxe.png create mode 100755 client/data/textures/items/gold_shears.png create mode 100755 client/data/textures/items/gold_shovel.png create mode 100755 client/data/textures/items/gold_sword.png create mode 100755 client/data/textures/items/golden_apple.png create mode 100755 client/data/textures/items/golden_carrot.png create mode 100755 client/data/textures/items/goo_bucket.png create mode 100755 client/data/textures/items/gunpowder.png create mode 100755 client/data/textures/items/gyriyn_axe.png create mode 100755 client/data/textures/items/gyriyn_hoe.png create mode 100755 client/data/textures/items/gyriyn_pickaxe.png create mode 100755 client/data/textures/items/gyriyn_shears.png create mode 100755 client/data/textures/items/gyriyn_shovel.png create mode 100755 client/data/textures/items/hopper.png create mode 100755 client/data/textures/items/hopper_minecart.png create mode 100755 client/data/textures/items/hydrogen_bucket.png create mode 100755 client/data/textures/items/info_wand.png create mode 100755 client/data/textures/items/iodine_powder.png create mode 100755 client/data/textures/items/iron_axe.png create mode 100755 client/data/textures/items/iron_boots.png create mode 100755 client/data/textures/items/iron_chestplate.png create mode 100755 client/data/textures/items/iron_door.png create mode 100755 client/data/textures/items/iron_helmet.png create mode 100755 client/data/textures/items/iron_hoe.png create mode 100755 client/data/textures/items/iron_horse_armor.png create mode 100755 client/data/textures/items/iron_ingot.png create mode 100755 client/data/textures/items/iron_leggings.png create mode 100755 client/data/textures/items/iron_pickaxe.png create mode 100755 client/data/textures/items/iron_shears.png create mode 100755 client/data/textures/items/iron_shovel.png create mode 100755 client/data/textures/items/iron_sword.png create mode 100755 client/data/textures/items/item_frame.png create mode 100755 client/data/textures/items/jungle_door.png create mode 100755 client/data/textures/items/key.png create mode 100755 client/data/textures/items/lava_bucket.png create mode 100755 client/data/textures/items/lead.png create mode 100755 client/data/textures/items/lead_ingot.png create mode 100755 client/data/textures/items/leather.png create mode 100755 client/data/textures/items/leather_boots.png create mode 100755 client/data/textures/items/leather_boots_overlay.png create mode 100755 client/data/textures/items/leather_chestplate.png create mode 100755 client/data/textures/items/leather_chestplate_overlay.png create mode 100755 client/data/textures/items/leather_helmet.png create mode 100755 client/data/textures/items/leather_helmet_overlay.png create mode 100755 client/data/textures/items/leather_leggings.png create mode 100755 client/data/textures/items/leather_leggings_overlay.png create mode 100755 client/data/textures/items/lightning_wand.png create mode 100755 client/data/textures/items/lithium_ingot.png create mode 100755 client/data/textures/items/magma_bucket.png create mode 100755 client/data/textures/items/magma_cream.png create mode 100755 client/data/textures/items/magnesium_powder.png create mode 100755 client/data/textures/items/magnet.png create mode 100755 client/data/textures/items/manganese_ingot.png create mode 100755 client/data/textures/items/map.png create mode 100755 client/data/textures/items/maple_door.png create mode 100755 client/data/textures/items/melon.png create mode 100755 client/data/textures/items/melon_stem.png create mode 100755 client/data/textures/items/mercury_bucket.png create mode 100755 client/data/textures/items/milk_bucket.png create mode 100755 client/data/textures/items/minecart.png create mode 100755 client/data/textures/items/minecart_command_block.png create mode 100755 client/data/textures/items/mushroom_stew.png create mode 100755 client/data/textures/items/mutton_cooked.png create mode 100755 client/data/textures/items/mutton_raw.png create mode 100755 client/data/textures/items/name_tag.png create mode 100755 client/data/textures/items/navigator.png create mode 100755 client/data/textures/items/neodymium_ingot.png create mode 100755 client/data/textures/items/neptunium_ingot.png create mode 100755 client/data/textures/items/nichun_axe.png create mode 100755 client/data/textures/items/nichun_boots.png create mode 100755 client/data/textures/items/nichun_chestplate.png create mode 100755 client/data/textures/items/nichun_helmet.png create mode 100755 client/data/textures/items/nichun_hoe.png create mode 100755 client/data/textures/items/nichun_leggings.png create mode 100755 client/data/textures/items/nichun_pickaxe.png create mode 100755 client/data/textures/items/nichun_shears.png create mode 100755 client/data/textures/items/nichun_shovel.png create mode 100755 client/data/textures/items/nichun_sword.png create mode 100755 client/data/textures/items/nickel_ingot.png create mode 100755 client/data/textures/items/nieh_fragment.png create mode 100755 client/data/textures/items/npc_spawner.png create mode 100755 client/data/textures/items/npc_spawner_overlay.png create mode 100755 client/data/textures/items/nukage_bucket.png create mode 100755 client/data/textures/items/oak_door.png create mode 100755 client/data/textures/items/orb.png create mode 100755 client/data/textures/items/painting.png create mode 100755 client/data/textures/items/palladium_ingot.png create mode 100755 client/data/textures/items/paper.png create mode 100755 client/data/textures/items/phosphor_powder.png create mode 100755 client/data/textures/items/platinum_ingot.png create mode 100755 client/data/textures/items/plutonium_ingot.png create mode 100755 client/data/textures/items/poisonous_potato.png create mode 100755 client/data/textures/items/porkchop.png create mode 100755 client/data/textures/items/potassium_powder.png create mode 100755 client/data/textures/items/potato.png create mode 100755 client/data/textures/items/potion_bottle_drinkable.png create mode 100755 client/data/textures/items/potion_bottle_empty.png create mode 100755 client/data/textures/items/potion_bottle_splash.png create mode 100755 client/data/textures/items/potion_overlay.png create mode 100755 client/data/textures/items/praseodymium_ingot.png create mode 100755 client/data/textures/items/pufferfish.png create mode 100755 client/data/textures/items/pumpkin_pie.png create mode 100755 client/data/textures/items/pumpkin_stem.png create mode 100755 client/data/textures/items/purple_bed.png create mode 100755 client/data/textures/items/quartz.png create mode 100755 client/data/textures/items/quiver.png create mode 100755 client/data/textures/items/radium_ingot.png create mode 100755 client/data/textures/items/record_old.png create mode 100755 client/data/textures/items/red_bed.png create mode 100755 client/data/textures/items/redstone.png create mode 100755 client/data/textures/items/reeds.png create mode 100755 client/data/textures/items/repeater.png create mode 100755 client/data/textures/items/rotten_flesh.png create mode 100755 client/data/textures/items/ruby.png create mode 100755 client/data/textures/items/saddle.png create mode 100755 client/data/textures/items/salmon.png create mode 100755 client/data/textures/items/selenium_powder.png create mode 100755 client/data/textures/items/sign.png create mode 100755 client/data/textures/items/silicon_ingot.png create mode 100755 client/data/textures/items/silver_ingot.png create mode 100755 client/data/textures/items/slime_ball.png create mode 100755 client/data/textures/items/slime_bucket.png create mode 100755 client/data/textures/items/snowball.png create mode 100755 client/data/textures/items/sodium_powder.png create mode 100755 client/data/textures/items/soul_wart.png create mode 100755 client/data/textures/items/spawn_egg.png create mode 100755 client/data/textures/items/spawn_egg_overlay.png create mode 100755 client/data/textures/items/speckled_melon.png create mode 100755 client/data/textures/items/spider_eye.png create mode 100755 client/data/textures/items/spruce_door.png create mode 100755 client/data/textures/items/stick.png create mode 100755 client/data/textures/items/stone_axe.png create mode 100755 client/data/textures/items/stone_hoe.png create mode 100755 client/data/textures/items/stone_pickaxe.png create mode 100755 client/data/textures/items/stone_shovel.png create mode 100755 client/data/textures/items/stone_sword.png create mode 100755 client/data/textures/items/string.png create mode 100755 client/data/textures/items/sugar.png create mode 100755 client/data/textures/items/sulfur_powder.png create mode 100755 client/data/textures/items/thetium_axe.png create mode 100755 client/data/textures/items/thetium_boots.png create mode 100755 client/data/textures/items/thetium_chestplate.png create mode 100755 client/data/textures/items/thetium_helmet.png create mode 100755 client/data/textures/items/thetium_hoe.png create mode 100755 client/data/textures/items/thetium_leggings.png create mode 100755 client/data/textures/items/thetium_pickaxe.png create mode 100755 client/data/textures/items/thetium_shears.png create mode 100755 client/data/textures/items/thetium_shovel.png create mode 100755 client/data/textures/items/thetium_sword.png create mode 100755 client/data/textures/items/thi_fragment.png create mode 100755 client/data/textures/items/tian_door.png create mode 100755 client/data/textures/items/tin_ingot.png create mode 100755 client/data/textures/items/titanium_ingot.png create mode 100755 client/data/textures/items/tnt_minecart.png create mode 100755 client/data/textures/items/tungsten_ingot.png create mode 100755 client/data/textures/items/uranium_ingot.png create mode 100755 client/data/textures/items/vanadium_ingot.png create mode 100755 client/data/textures/items/wand.png create mode 100755 client/data/textures/items/water_bucket.png create mode 100755 client/data/textures/items/weather_token_chilled.png create mode 100755 client/data/textures/items/weather_token_clear.png create mode 100755 client/data/textures/items/weather_token_cold.png create mode 100755 client/data/textures/items/weather_token_fire.png create mode 100755 client/data/textures/items/weather_token_fog.png create mode 100755 client/data/textures/items/weather_token_frost.png create mode 100755 client/data/textures/items/weather_token_hail.png create mode 100755 client/data/textures/items/weather_token_hailstorm.png create mode 100755 client/data/textures/items/weather_token_hot.png create mode 100755 client/data/textures/items/weather_token_ice.png create mode 100755 client/data/textures/items/weather_token_iceage.png create mode 100755 client/data/textures/items/weather_token_inferno.png create mode 100755 client/data/textures/items/weather_token_rain.png create mode 100755 client/data/textures/items/weather_token_snow.png create mode 100755 client/data/textures/items/weather_token_snowstorm.png create mode 100755 client/data/textures/items/weather_token_storm.png create mode 100755 client/data/textures/items/weather_token_thunder.png create mode 100755 client/data/textures/items/wheat.png create mode 100755 client/data/textures/items/wheats.png create mode 100755 client/data/textures/items/white_bed.png create mode 100755 client/data/textures/items/wood_axe.png create mode 100755 client/data/textures/items/wood_hoe.png create mode 100755 client/data/textures/items/wood_pickaxe.png create mode 100755 client/data/textures/items/wood_shovel.png create mode 100755 client/data/textures/items/wood_sword.png create mode 100755 client/data/textures/items/writable_book.png create mode 100755 client/data/textures/items/written_book.png create mode 100755 client/data/textures/items/zinc_ingot.png create mode 100755 client/data/textures/world/clouds.png create mode 100755 client/data/textures/world/clouds_dense.png create mode 100755 client/data/textures/world/foliage.png create mode 100755 client/data/textures/world/forcefield.png create mode 100755 client/data/textures/world/grass.png create mode 100755 client/data/textures/world/hail.png create mode 100755 client/data/textures/world/molten.png create mode 100755 client/data/textures/world/moon_phases.png create mode 100755 client/data/textures/world/particles.png create mode 100755 client/data/textures/world/rain.png create mode 100755 client/data/textures/world/rain_new.png create mode 100755 client/data/textures/world/snow.png create mode 100755 client/data/textures/world/sun.png diff --git a/client/data/sounds/anvil_break.ogg b/client/data/sounds/anvil_break.ogg new file mode 100644 index 0000000000000000000000000000000000000000..e18b0c0f82170c3080a51d3f185bc104d2d790bf GIT binary patch literal 15009 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 Z`EjbFtqpbpp~9II>!ZMokrfy4{{TIB$0Ps% literal 0 HcmV?d00001 diff --git a/client/data/sounds/anvil_land.ogg b/client/data/sounds/anvil_land.ogg new file mode 100644 index 0000000000000000000000000000000000000000..45f9cb37c16c2c3631dcfb9dd69db422fa0bfff5 GIT binary patch literal 10244 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 literal 0 HcmV?d00001 diff --git a/client/data/sounds/anvil_use.ogg b/client/data/sounds/anvil_use.ogg new file mode 100644 index 0000000000000000000000000000000000000000..f161d32c0f0be148d190ebc48c24deadf8df187e GIT binary patch literal 14715 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 literal 0 HcmV?d00001 diff --git a/client/data/sounds/bat_hurt1.ogg b/client/data/sounds/bat_hurt1.ogg new file mode 100644 index 0000000000000000000000000000000000000000..b9a0f834f115dcd3a8c25e2c8b911275caa94e0e GIT binary patch literal 5207 zcmahNc|4R``=!BHVyq2@D3ck{H5xHR*S?H>cr7z`zOqcVD2-9Nm&6c?q_H+a84>Cd zisDum*|Ox0C274GZr#+ajH3F^jOzQozrOQ3bKd8D)^ncoJm);`c!h`iLXyzew&thn zN+K}WjP*i7S0Z8Gfsjb12qBSjUG#vU6iW&5^O}U0Nb-9VNs1^c^4yb(Hedd$9bL1k zW-Xw)2PfcQ-h7tvh&t_hOrxpeyM5auAGW7bEgepnR)tE6?U04+|iLd7!nB_vpuB7 z&bCGBv$58J`DupM0Lml*T%-txvimkTk|F@r7OBI2W@@RB_S|v_!*(PEq5y7AkF8{P ztu(Ek1eguXUA)tzNpl$XZDU+^YM1FX4K~6YcOvyq)80SQn(;v6pf98M0U)g%Y?LJ-Qv zN9|4=rtcJ{uMs1UTpJ_>_5nfyK9}q&m)t*H@(qIWvEn|PbVEy&D8vNP%>p%e&005e2;Un^&h!>}Jb(Hb-TU!7LS&=iXU zAENF>?x~f|G+m=9E#3z(jTGf<)2@_nPEJ9S70<~wkREZLRRk%Pk{d}nT$h%_{4?2Y zBmtK>)Hll|3<2mIH%Orr@CmqG6+v>VkYQuuNU4zs7dJG&o2%RdpiK>ld8Iim0Fr8m z%q?|m1dvNxBIS&m2*(tu5)XfM&ttf%qSu;^w!$+b-2n3HnSaPdePake9|1#uLz;i|(WAseKAx*Emh+Ypke zpMgHmkH1inN;aykId{Tr!1&6bc-a23{)*xb1wt3feseB>`#qu zXrYktJPt)p>_0u=dpl{(usk1;=8#PM1?~YkqncHB>WQ`ng1r90j4JE=r@z4rD`S0B zKsOmPGavJHgjtM(?yJFVbY`j>U0_L5>+5*d;Ugz{sw&hGs|29SDT1lBgjTtl#$s_ak{dV5_W{j9Be4cwVkUk>cv%6On8!Jt0o3< zsayey5L$ePLaNXL znb+zU{frA<`*A#~Tb&NiFZyC55Q1dDPrh;_PhG-B4T6p;P~`CGoRA^BAdk{dn#F`< zlP+*Whe)_GPCv=8?6eA=2VU_4E@#MfmV5f1D-OiRO$qR`!x6(AA(SEXct6JDG|@v1 z>!IrCrAD7nb>tTi?-I>@{9q3?556B9q~QS|5vow=jl@F;jl< zj0VhaWzZIr0t#6(TRo;kuYk$|uk_ZKnWFEi;0Zr?dK;jc`^3|IU`7zooInqnfCI*p zfM&k0$CNq@7s69~23*M66%Wt&)2Aljpz);X@$_BeNw;e*w#W8gx>VOxzudHCx&7}K z9M>^-(S-O8KCnkXON=iohNkK`p$_v49er6qOVTbDV`{=-l;sE)FhnK`81#dTfU7_x z22MzN6i=rYvFL$&Xu|X{7K>iMcoe`05;Ev_##xVq?qjVU6MWVf%z8A=dR`JUy#&Nq zaAEo`z&DZpBr$eo-B}-)HN&Cr0%Gf8cUj!;jJ3KP6FR-K>GDPe=gwb^>C@ZVJ3We7 zGjrPZPb@NsW6d!@-%LDxR}pI_;zhf+A50HmObOwD#UwC^CyPms(C~y1xIBYjSQacy z;=PhDfLqhS3+h(ezfujJ=&ZBgp*@Gm!CX-@^uT7^=j-%7^NSm-sPcp8O=S_C2WRKh78`CM& zy$$?Q>Tz@SJt~gZ;!QqY%hRGon>(Gb?d6`%CmHfMV!|NFs4NW}q2QpS8sobINru?8 zT(XQlFQ4p=<)Q738VfiffG|nj+tyvo#PPcG$$PQ9K$<(L70t{Q88;Lg=e1BM(FIHj zP{mLr8v#{hG6BpAs8X~e1696cFsqQwczz%`su8GiBaC}fjst=lnE+J9Ha;J>jWDTF z3B_T1G(s;mv}oDmSB>*ELK`|n#<4y5i{7- zs&TfIxj>km^o=&ZijD?0s6f^1cqk}-)+mDGVH4*l$a_gq-XrwM1nElKOoE__h$PH% zIoSk(UKNEfi(ymD1bUo&iU^{}@v8DE(UlwuC8`1By`(7bwTV~_8IZPEC{GUBy&p61 zkChJ*o=Pz8d+RVt1ev8H#(?aL8Cb=zSTkZCm_?@x9em6|0D}Ox22ubMw3syJC&sj< z?;^qh08_|#6i65Gw6bVuf4&G4L$k=BO|WK!>A|G!S7TqaFD&1Fv*Qi~y++7D6_VQi z&X#yBd1LXcK;Z`V*49No4F#@J9*RN+XCrz)C`(K$71XqvRG>@{tH@K}ip=4N?nx2E zbMOor5R)4VCaZPat!sLzqX2 zCX7>=3mrw{A@$~h2WhC=&1#{S+7=)Gynt_|M&Gqw(qnr!@~O<%qGIwmLHHo;H7GED zIzbZXvR~hl35KA9X=@;d)SRvL24(8G((6R4Man{Ys1UHhT#$!g*?=1ZE@vE;BE~7& zA+cfKa6Hb5RX$lBC;uxSs3Xh-6+jl?C}goLQUuL^$Kgelt(c0(eusE$6d5Pt1HMJs zf#Iu{zv1$~<0zDGIIvY;`8X6;P=aDCL8zi_4K-nn;PbNUbW_CfYXd=QUH-mVWwwKa z@LGK&p{CZ3jL#t0_v=;TedYAi^_kiFl9k>5Zr$KwM13V?ZPr#h{lLxG6j$_K^-#Kg!@y{CcWG7ez#P-=Ht{YuePJ?P^qY{r;wb>&0De- zR&O#4A3R2soukNzz9*pF5Cpzp?nt4OM=?$rJ<`s{?#Q@+Y8bR@&`lZWroN|!BCOH(i-cRn6g{YZ}T9i}E7i@tavAS?`eCpEo3`@^9d3ik&#-HEtz+sxf6AgICz+mqTl{d( z@0aAJThNPZf;q7z5yyX6>fh@Ub?5l@E0pGC71h&)Eyt6mKh@gIqDq!!t_1daYW|SB zQtCM+I%GvV|(Mx-VWPYo+nrX$H(ikc}{_)h+4-zhs^+Wxc4NAJC z9m8`IHy>uEx1p+uMRF5bass0D)^`s+l9Da{p0V;5c~94>$ES*PYRgoV`bnB_EE64k z{AJv`k@IE_koG@{S;CdF4W(TpFJ5ClYkN=2%>Q!qpL?0|Iu_}^WX-?m(a#HeYm?Is z)YxXS+5Z$P`n3yhlqbAV9~wJwVcEC3YFEXOvD)wO(c6n{A4968xOX2%Xge?6icSl} zl*+l&(O#@LM<$QwdcN^nAtWVxHXbgKR3#Cr8WOwN^X zDmOr5ZBV=(6y7kRbM5Ve$TOX{bM)?JOTK#N^2>NNeAFGaa*kyLPab92={9vk_VD40H7651 z-u?WA5B%RL`_TJod+hjvN|@iE#8Ba-QB3pzOJ6Kt0wge(xk_sJCm`%SW@kI$xJ^to-bUQ*&4FrHYQ} z!@nK8UiJ!AdF1_%vOVv6c8nz7*kX~ZSYorQXQ8k8s{FmUTzli*gq2_4px1#*Z!&SR zed^h7DK|o_CBr9=sDE1Yn99mt+R_>_UWN7c-P?Nh&-`4WHa60K=0%jZO?Wf%gW@rQc z$ilj|PR}~${zP1~RqIPqX$x_O%S!yX-QB{CLBGW(#$KvfU-k-Dyr-^d4c#zIur%wd z(;`vz=&TbK*K@cdc>tm1WTBLx3|+1X@4P&GV@HdAk~ZSXhc|+yxQQE+1;jhX&tJ|% zas7tcI}o(loOL@oBb#!aizRGX78!r6dAyu*d_I1H*PjcO0+TRPQbR7vuAv#dk z-|4gP=iM7Bw>xb4)luN{e%MdSv$}WQ=79uqW%uN*!I4kZr^Big z_Rw5r$Fm|omjvFFA3h|sT7G}+SNEpyEp7exlkpG&CY-5W)>y0f4vnpNm7h)T;Xjq1 zzv`eG;+N@sJ=Lj5VPAk{`RBh)E=aC8Wu?BRtB0E0T3eCP5bBw=uvx;Yc&`8Ai#Y3t z)eUc>IL~^xOM82sy}1Uh*aZKb7%E1M%}^ftH9tT=3XVVR zR_-h}xS6uxxV%VJkIny3cblnwxy__t^WvE*=$%VTZ)$M+P7`yQp3usMma`&D3#CK9 z6^A-JZ>@74h#4^2>Xp9r$qz5xF_G7j%Zc{Kbt{rz5uR3l`th>PBbTz^F>K4(CuHa6 zr3oM2$N59|Tik{3t);qje(`r6K2dr01WoB}UBFu_XPcg4bfp7y{s`Pz*Yf2gp~rur zLpZ%myZp9{+5rx|k4dzj=yYo)i}ijQ-nQlipP%C&@Z(NVtDw+l_Oe*48$$yF10R2> zk8N(xmV8=QS6BYIJhpk%Aty`b^UxHZfA`D$)We9kO7ehhKmh6Nj!P6ZlIGcyN;1Vo z;bVy1ks`zt=U4goR?}x^poc9hR&qaQ$sn|~GE4pyf!VlWvK$LRnMt>ik9QXMU94YF zzo~HVT!KJJ(tx_-8S_ui^7Eed^O}=Bvy?&EO^-Yt!^osu+xrA1tE9al16~Jw-fO*N ztzFjn6xejour;>&F?{g{${C!=g}YuRiN{adDM_PcMvlsuZXWpp{`=BxUAb;@V{Xlo z-A0$gk>}zvGj~JLeUXvbF@guVL?unh$tP#nUG|9Z8^f9W9yf+P&qP_%$ zC+tW)Ybnz=ev(#|9KKIx_SH{OeS0PDD&Ehs?Z0CHm6km((lp$*&gqu_K3z*|SYrJ( PRZAVyDCAsdgCz8ClNO{Q literal 0 HcmV?d00001 diff --git a/client/data/sounds/bat_hurt2.ogg b/client/data/sounds/bat_hurt2.ogg new file mode 100644 index 0000000000000000000000000000000000000000..5b822d7a5d5341b84dfdd9adab10ecc5ca956df8 GIT binary patch literal 5972 zcmahtc|6ox`)BMS#+qdkMT{+@5mVf(VNeWX8BJMBjUmg>a+Mg8kYr1vD5DfEYD7{h zR76T+xX4zvuk9&iDB~>p9PPo^zh>>^XSQ9SDG5jiDMi!UMNN zGFlO8h?wxmfJ0F{1R}nH_W&T?48ecaA@=Yj|7|=;9_59?Wulbj&;M$t1y|Lqg;Zz% zm;)v_Lt|4zjFAzKeFOXjhXsZQ1xH#yVjv`LKaqw@4rD=`ha zmW6j#qP7KuQg9G=h=)U3|1;R(LLk*jY(0I<$V@WvgV_>_Zin+mLfnKpUD~>?Ah8?= znKexuToXlb6DaxVW}`Yqx{!%ZTEcsy=Wi1wtWydS9Zi;0=m)KiDz4hlv~tKy z6tQ})MBilvXCQ*Blc%>^-Bh9L;>0%4)v-YeAQOP1YdWddbi|P=HR9ko07y$W`DYQR z7Z*@3s!_J^(Su=a5?Bkn!FjOVcMyi{Ho3-qLTc;df)cxB~#LZjyEp@}hjX zAOOUQ%u<=&smzd6Zc2t2J-J)}!~-A%&0uZZ&F!;oUwIHYwbcIq>b|+b%6xI?L*$!7 z2g*cJj0BZM`1=5-5igT!)ExhhljD`}QrFg0;D#7uMLtpm_-fpGh6C$Z*5%ZC9G4N* z`C^=b>4eZVhL2*5_XCYJt$6*2#AaHY&~ zu{Ych^<6RnD#nvmixWm`R1z81Q?DmNO0u_$Y2`!^@Y<^m7XX%G8cFg5hku5E6pdu1 z$Tswiq6EBd+0AQd#_jrdUh;?SGv#-rc1U8Hkv4i2%>;L^u4u+a!{rlPjf&D`UWFXT=(XxJJoqx1HhiosMj*<|I=$--{X zZEVu*ZbzgAb8=}u_u_nelgNv4gRn2r{JnF7eg3DfE*&PhIt=#Jg`iuNqF&-AG_#Ta zEE8@hI3jP)k2l8}O{X`S9dGpae8KLKvv8BQ>&6maE0EnxsczeXyG_XM+sH&us#h-6 zx0cqQ7u>%XH}qefEXrS^ECAcHHledNqO-=#GBh16L!RpbOA%g1rjF`ljG1L=I%a7d z$~t%~_vWR7$xBysZ}C|GlE=bpsij9#%Z{erJeo0)k`;0(_hwmvUR&wR{mSY8uS@U) zToZt3P5VeqdxEAN0RnvQ#!K?Ni+YODw2Rble}i3J<7+t!=uofd)kEXg1^^)WqDsE~ zHOfU+i%l>fx*Mhwi2ODGuklJAQ2+HLm)seK;A zK}90FHrRI|&MTKTxYebP_X?>r_)4y&4(9!^KTUcCMW}4Qh$oPYdqj*uJLO5p#lhCUb(xvB6&V zpa_*16E_r1Cg;(}-Uoaale%d%a!&A&SFq1wF!@;zZD`TCyVixnrgal(Lp`()m#Fe>*P1+CnI7uVN!Uoq}aU;?Ov&s9R*t)R&rhh&RGyj7c*#BG2ADblYA6Ds;`?uYH z=#ozxoKUqHF-^vH-=#u*gVE&ud9=Zh>HDr8M6y?K-y+d#Ar4MrWFc-yiO5-mE>C9X z7Wyy7F=r)mh_y*@2Hboq+560qL9x{S8Tn$#TV?D`TqoQcQNGSv_Z5%))6iv-yOVINicTc!a`(j--!n z@y2OuC1&77HJDj=XDz0Zjc#>Lb^s*wl0xfS@}qQ^Em`30qrs2-~GM>tUswmY9kN{OV;Z16lC>bUT z1*F@MKsj7JUJ&&WGv4b?F}bHifi_4`)p$=JEPe!~;PJ3I`!vjZ0bbq_ z5ZCR&$J8e6#}d6DCO3GrTHp(vUwP)uW7O`hc>vFygSz=TyDX&r^3sPXLid}$L zWO_F5p5#HyY}tQnv;S0S{{snwr9Ea~X=iT{y4uXLSVIpH50y44G4mrOx358)q~S!0 zv$LV6{L?UE%#ybxr<^Dx-m#3;8&J+jbS2;`T2umIO!bh;t9uG|z_?YUl;e6)_(KM* z-cg;6iuu`#bFpxlHzkcfP8S3a<^eqs2;M|3TT(qXZrPIs+llcMH$#pF56 z;y~gYEHL+`;kat_xyPdZ0K_H=0^5Z2t>v193K=5nc&im#1JscLaDy2z58<*QHws?P zI$8uiPRd$LE9f5_GdpdSZw)g$>lYuaBaFF4P!{3{c)qL{51RZJhvrqbd@5S&Ux-OZ z;&pg@(6>lyIQ;VRKe()aaRkCYIJi~6__7I(umnY!!BADQ(pDxa`d?qOPA#4vzm@>V zH+#CDEwp-xIasD4hPhd0jYlVAY}(XI(eC0JNg7e98Un>Fo=z?BVn+%AG3Wv#OIIU7 zASs3XP1H);^2l9S-C74FJ7D#N&WPp!8H@tZ+^q9nz%r@D?#~wCXyxGq!`bafYh(hl zc@&5{G(BEpYW^u%dtg|o@ESps_dNmp0FVaYnJ`l3HELIKtBC!XXQB?U8iuV7G>L*H z4FOwQ?3oM2)sJ6~d_u^=BIQ>T5)$G=Fb;u`5dZ5&XxMO-$osnC;T;m1E7f)NS{pfN zy)8ytwrthY*TWcN47V8Q>Z3Q`uPP}_h|ml5r`Jt|ZxXt7|65dy+^G@f&*_0BS*DrUU{YZL9s>6Jb7}y(FYOoBV72?;OFsyJ1kRs1LP~EYDn=%>va_{?H&KKr} zM>0{%(y^z;ziY`wiQM z*p=vaUmJe>J>F&OVxRT7weGmEQzK%(lS1p6&U$6H-6ii*Ga6i#pR1OsBjnD6L`wg; z_*(ivxTh>)Kk3IqhEFE;=}O}G`f-xxb>z7_F|Um|D^K=s4Ki%_p6nx%c}6{M?A{mq z!2M2X;yxGm=iOJgk=fmQ_HV~L^5%l2jK!*Ok|wp+lVaxtE`=9w14$6dKVNjw6+Y8wu&%xLp$44kZsLp5Ss_o64WbziYEMo_wMC z=W~pL0J> z(c?aO7B_JMKZ+e6OTNBz&b4%HhSLW3S6m5|CGQit*NQ^eYZuBsv>26K64e{@yfT%u zc&?v#>TCP6j~(5dm7OEuA)57oUi|IlI=E?dv#+w zS-QgdtIdT_Qr+Pi+lFfh@22SAzpiwYe(ATOtpjQB2KcnXS%GbB`HD`=!<|RIf0}0Q z2omz^JsHZ1RhG3J5Zrw*sa!<8*zn-#2U&$%<0~${I}ts~K6{-|=h>@%&Rk_` zlZOBht?`wyROmtzs>Zf7#vJLdQL=+N@g&X0pNuS{@7>eBi#x?mKFW{^ee?M?>5E=R z;}1@|Kwmz4Y3C*l10d9Fiok}CI!rz!hGhl#^{IGFbh~|N`u<13Ou%hK$B~xj7mwI( zL{A+T0S|E8yoFQY!a$#*mn$0_esx>@)=|r$D+6^qfQ?Z8tH4oIU0$?YWR^qG;v@&i zhu6=ZI$GpxrXP`R);`w^s(TNLuj^gohn*8YQh7aYT2+me?q|_jD_7)Y_n=s8!o$v* zH9Nmfp1Rz#WFP`&cMjNsCe>qHIYgK6b};4WXl8$x35p1(Ov76R+RoqEJa>5V@j$4@ zJ|G`Ks!59+RFzrd7Ow=Nnv^LsdfH9J0Qg$&ZX2cf(}mQBC$C$Lh*S%qsQwmJ%iuyC zd3}7#tMK_pSJn#`4c!zd_YHqz{L^{C)dfA8gV^-5UFsAkW(mg++JEqBOSHuRc!xe2*{ zrmyc2z4Gq+V2k0BSVrNu=B;X~k80C|bA%kM|Wsd4G=W_pEcsh18L)!Lk_eRY)M zr#pI~fup!tLjPdxmNxF}0dBltYsdSz3PJEh#_#3M{D|zlxB4!zhdJ)28-y(HE&cgJ z&H|zN7m#0iaF6u%E-T@ufJo&X;AdX6IKR+-@&vbYc|Gg=Y}W??Q)S8Owe#=8SUFGQ ze)h&&RBSz7w0FYR`{LD7%*k)lKl5BV9)Nd-lA5<9Mi}vLw}9^+O@mXjF|zaVMQMr{>Vve>dzj+4LiBdT>%|-r+$|(1tHZLOSye^_S0G>T5rKeMG&X zQ~$}iaXdL#dg?{lmKy>E_wJgfC4FiV?7cE%dg|+Z%O3j%v_|Zfzb1l2TtOq<?T_MC3RrwbQ8P{}p9 zPF(+w8wR~DMcp6neR%2MrZ2gUvO4@ICLQ;|BIk z$dj8x2;14WHoo`oH~XB9c|(+@18nz(ugvm_5n%S^5jJgZtFbq>dc)&#)41n-;!^x%sk{C^&Pxr?6oa8 zI&N(0L|Eh2sH}`?z_?ICDn!^4dh#fq9gwdbxjsaP8!p^cMu2@92kp&PoPjspL&Q zy$^N|RfT67#U(?NqWuo1DbCyGd;64L z7&)7M)|Zfx%=zTCkrGn+2|g?eY!J0|-aV<^_#E%%+@bLdQ% z^cF{froVmioCwB}h>T}k; z6Qyz{D+`p3_-OCffdcoCq_dZml+w9>x?@(P8cvz-9$Ep*S z$T)q+p~(w1%q|fDYPH`R(;v(sq_9t-_4{|(ip5KJ-7>6Hni;!v`svCG?R9gE6tB(= z!&h0(9~{jZrOtCLWPN{EJia-xo8?}d>V(bfi%{1sX%kPnGdeF5S6T0EH!)!RyBcDm zk2r0U<4;0d*Yy~AyT+zTw5io^ZdwT%{HXunt<;jWi;Sh~MkO&`wOIAmZ$clj=$x2C4%4OfiU<#77i7I literal 0 HcmV?d00001 diff --git a/client/data/sounds/bat_hurt3.ogg b/client/data/sounds/bat_hurt3.ogg new file mode 100644 index 0000000000000000000000000000000000000000..bcdf9b00c0c34d9fe2a60e0ee00923b1bf6495a4 GIT binary patch literal 5575 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 literal 0 HcmV?d00001 diff --git a/client/data/sounds/bat_hurt4.ogg b/client/data/sounds/bat_hurt4.ogg new file mode 100644 index 0000000000000000000000000000000000000000..8c2d7f4c1888f3789bcf194dd570de96e4e3ccc9 GIT binary patch literal 5532 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 U5}Hb6fYwg7<*uUq5_zTn0HtwfY5)KL literal 0 HcmV?d00001 diff --git a/client/data/sounds/bat_idle3.ogg b/client/data/sounds/bat_idle3.ogg new file mode 100644 index 0000000000000000000000000000000000000000..69ca797379661bf7f3cd8422ac97476dd8471020 GIT binary patch literal 4945 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 literal 0 HcmV?d00001 diff --git a/client/data/sounds/bat_idle4.ogg b/client/data/sounds/bat_idle4.ogg new file mode 100644 index 0000000000000000000000000000000000000000..9b3aafa087950015429d8f092f000624dd755967 GIT binary patch literal 5867 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 G@c#f8zwx;M literal 0 HcmV?d00001 diff --git a/client/data/sounds/blast.ogg b/client/data/sounds/blast.ogg new file mode 100644 index 0000000000000000000000000000000000000000..574a89a731f5788bc6298659b6b6e9e5fa74312e GIT binary patch literal 11694 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 SrQdEU%J~UHb&6>b@c#gAmRVf@ literal 0 HcmV?d00001 diff --git a/client/data/sounds/blast_far.ogg b/client/data/sounds/blast_far.ogg new file mode 100644 index 0000000000000000000000000000000000000000..9bd770903aef99fc03da1e5c650880f76c4b0b24 GIT binary patch literal 15534 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 literal 0 HcmV?d00001 diff --git a/client/data/sounds/bow.ogg b/client/data/sounds/bow.ogg new file mode 100644 index 0000000000000000000000000000000000000000..b7779c735bddad600059ad480d012f0e2ac89173 GIT binary patch literal 6976 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 z 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 Wv1IHt6NV_dKw60di!0Co_x}S-Pezyk literal 0 HcmV?d00001 diff --git a/client/data/sounds/bowhit3.ogg b/client/data/sounds/bowhit3.ogg new file mode 100644 index 0000000000000000000000000000000000000000..a97c72d68e5e1a1fd356d4301f6ba3c02297b1ba GIT binary patch literal 13949 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 F{{c%NtResa literal 0 HcmV?d00001 diff --git a/client/data/sounds/bowhit4.ogg b/client/data/sounds/bowhit4.ogg new file mode 100644 index 0000000000000000000000000000000000000000..d19c74e9e8db3a8ddb7facf402957603cd2b9e02 GIT binary patch literal 16166 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 C6TB+` literal 0 HcmV?d00001 diff --git a/client/data/sounds/cat_hitt1.ogg b/client/data/sounds/cat_hitt1.ogg new file mode 100644 index 0000000000000000000000000000000000000000..2f361e495a410d8012dbe12b606267a77a0457bd GIT binary patch literal 7387 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 Nkewz7Y_%C#l_f&xwIpkV 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 literal 0 HcmV?d00001 diff --git a/client/data/sounds/cat_meow1.ogg b/client/data/sounds/cat_meow1.ogg new file mode 100644 index 0000000000000000000000000000000000000000..4fdd430277de500b6345c94122a277d3121b79ca GIT binary patch literal 9585 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 W8$pycBwa~i{SaJJTgZJB`Tqc!_8HFr literal 0 HcmV?d00001 diff --git a/client/data/sounds/cat_meow2.ogg b/client/data/sounds/cat_meow2.ogg new file mode 100644 index 0000000000000000000000000000000000000000..686e00647fdc9b132cba21bcb67c20a655d29eba GIT binary patch literal 9198 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 literal 0 HcmV?d00001 diff --git a/client/data/sounds/cat_purreow1.ogg b/client/data/sounds/cat_purreow1.ogg new file mode 100644 index 0000000000000000000000000000000000000000..dfb58973de15c2890b4685de56da081848f4712b GIT binary patch literal 11379 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 literal 0 HcmV?d00001 diff --git a/client/data/sounds/chestclosed.ogg b/client/data/sounds/chestclosed.ogg new file mode 100644 index 0000000000000000000000000000000000000000..a388edd9ed3356ca2b9e198e89b0988d2bf83c73 GIT binary patch literal 8086 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 literal 0 HcmV?d00001 diff --git a/client/data/sounds/chicken_say1.ogg b/client/data/sounds/chicken_say1.ogg new file mode 100644 index 0000000000000000000000000000000000000000..649fcf9f56c8d8fa6675aa24e45cb63814c3a7ec GIT binary patch literal 8360 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 literal 0 HcmV?d00001 diff --git a/client/data/sounds/chicken_say2.ogg b/client/data/sounds/chicken_say2.ogg new file mode 100644 index 0000000000000000000000000000000000000000..fef786bb44c8a7b1af681be95d7afee6f331ae94 GIT binary patch literal 10023 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 Iy;B4JALA)3&;S4c literal 0 HcmV?d00001 diff --git a/client/data/sounds/chicken_say3.ogg b/client/data/sounds/chicken_say3.ogg new file mode 100644 index 0000000000000000000000000000000000000000..d058652a07db7ad61c285784e13b82a9af079b04 GIT binary patch literal 7524 zcmahtc|4Te_jeeKC5?RvQ3fMoWE)Y)I$4LYPj-@~Y(t6~S&}U=)~sbLh3s3A%1$c# zn&mChCM6Wr?-{-C`~80Z`rXfc?sM+h?!D)pbMJW`b8l}ezySU(eSw}ebdbT&WeO$+ z3qBv<<`YOqz$g#sF90a&u-$hP%$zRyZ=p-lDN==aEl%y<|5YLw|ESpmQB7Qfy;QJ= zmDCPn6cy?0`=Q74ocnnX&j2lm=nfH&>=MP#`ndg(gE9SiAJ9Ev0|VLsNCpbZ8qfmy zqmaV77D9iC=nndR5Yjc_x+DVFNt?Ahj)dyZuFa zZ;JF*i?Ad1*fT-<01yzLQCyKx(rcp>N&6JkZe6;5SFXQiw<_(58v$Tp$)WGh%d#uy z0RW;vJ&tA`$29GirQiYaFR6ae7RFv=&aG!3bG&#ejL4W#M+s*dTNLc8LS4Ut1W zUS-U&ii|?cyZZo5gTfW3*g^Tn$P_^w=WW&s>|D-Y1@@fTxN59uj!}JR%B{F&>~c=v zVDC~6W)OmI=h$;(Lww6Q9R>Dme<11V&==XVbe#X-ic1bx7X(RFgeGSv)bjRa(L+7($?nmTQ52x$h>RiRSxoBmR-JGBSY)eM#dz% z&Y%%P%csQ+xZH%5R&+MsDzXYk=IFkA`Sx@XRRe)a^T*?){}`MBXd@(|dGSX7G;XmH zF@gbo=#qk~IN7q&+X+hja!m=5HLLlqr(E0W5Xo$n{?a&}~$je~DR zJsyXqQSofM_7jI}ugfgtk!(rV>=uhI$q8VSE&XFoar)K(VE#qqC70-b>YB)NE|euV zRON@2REDke31rXlbh3S8xZ^}LaWi}ts#|1NyL3xN3>KUS*m&ts}QYJi3A&x zZ92)ZfjphzIlUP^_g|IBvb#iX05nn#qEil_Q~pv00208 zt9bigikNbvM)C3lEBR5p{-_n<|0|}$%BDP!VOi+``@$h`pduql=WTgLk4#a)xEXe- zXna8CYR)nek<16v<^>>v1J8zzrn(KHmy_{* z*d-CSIBZFd`yf^(m)eJw&Q0Y;)1WSTIfpuEyp)qVWGn;uM>`C9bY+x1^Z`;D%=?L$ zrYf8AqD*=8&3TFAJo=+)%FmQlEUgKqyr!ep1bco{LOROyh^Z+r!HP$pz(=r3Hzm}2 zK3679S`%jZ38M|3jvL{&>EziXrjzt8L?uIAVgqS5<6l*Tacjb~DnwPW3?f<*JnbRP z!9@FUg6&v1qU$N31O>H1b=NK3dg*>iGS?11;%VCmiI51v;d4PmVg{LL=jFH=JxnGO(>&*FJ?%F=iQQx5xlNPd2Gj9T@-Trs zH%5MwMVj7%#K?s7XlICTJbEGY+^j&JC4oFkB|1Z50_U97rrOSF-Y2>IC z&P`+(qhrbuU=a=kqjFA|=*03yLPr5QDjDA)7&U-J3kBkJ(Phzie7s;}GFA!|Xoiz1 zq*>rj7DkQfqN}6v4rePyvmN49qJ|t~X!RDj_%fQXqpylVf=*9PY6@1GM%^V0U}bY7 zp(7MJ=p5wGopxAhRAds4MS_-sGeOY=PsmoMQQaWIgu~h9&dfj=T4xIGEQ)65Xo77J z3{0XAF1N>Oy{(G5x2Vxs*B&fvZ7x21p3e5qx|j_t@OcBT`9Ok`rwJp&~a#1 z{U+O?yt#A2m(=_%JMcwWy@QoWGksRgO!k4FS|eXTEAO~g!af)Y1qZ*`0$B9YKlN<-pt(Ag;H z2c;#7g&e%XHQXQ;@>Rr5=!#6F((g$+M5A*5o16V7OZy*)32d3GgRSEe1?XyZ?Lvt| zFbbr!U67U;z@fp4R!P7z7gDK^rCbv*2wKsI!^yNjB+j_3e!{IhC(;6stLPMVhkRkaywqG5T-RgS87%9uaud$>7E({-#l#+SP zpdH<*Kh?<;Bs72Z@FxwVF7hg}V-c_!wLfN6(_D*@o|%W|-o~@gzbAkT0DA%GWc=k^)?nOFlJa+f!{NISJBmaVV9Kiz+5 z|F$LRgIHRo5RCPG^YB;2YlrS$e)RnZ@AQRUr$&|IJEh^g0bE}{a}PLm=5Hk73kGbr zm&)Eam_6%+C)?b(JmPgAx;68)M*HtQZRwA+j@8XyV#)gOWU}N-rqt_Ag`eM@twh(z zqs|D;wAt&^h~F7;2{MN9{=VyMFUIZw6Wy>7{U;RH9b=d#m>KjQak><6fYPqg^++w_ zicQ3-=uZ3*uV+cZUcO*w=vKnmrx07p>!(sJ3JY)d9)HPNZ}e(vLc?l0=+)?BZr^Yg zIDFWaBvuu&YOcC2WhAp5Zv1v7^Vdi1rs7{i4@cb@QZrKSnB8%LiA;Jsp_WO9-)XA} zBeo|;2G?m-sHDxX3;Vx}-XI)DUuO^1cN#r(af0yCIj3m9ZS_v8R=u8n{Q?^RwxC>z z5$OV@^v}bTcn=5`m#Hu{J&|6v$6&~5d9Bt3DENa}7AhmylC!l+dFo))d`9*D%usdn z6~ZeS1^C7A?Zm`2C$v|^CZmfN&op*UZc1yfohPgcNjsM&Dx;bH!%?PPjnR)q#-&Z6 zl)|^|#YV9|;Ip_Luas&Lm|LWGM9Jp>>wS+>NyNPxHFM|bv}q5)Oc)#-D}57lEW@(r zNx=U7rM{#K*2hBk3I+BQM#Emz1T(u(Nz7oU_?;jutoY@`z7v~s&aovcwm-iex{&sy zT+ubsV}6hm=)+8Mqz;V)7_uKeJ#NPQNr7-D-!+=O$MV|G;I;VYUxYy{W42~kCG*&G+QflN9f|;0 zD>7v&KkuCN7v!yq9)2_eS4Gd-=WeOPOsm2;WjVIpj7BB$o;`n9 zWYXU1C4H`OrnJ#CwG!()4^~T#M)@yhc-O6c+ViL|!Sk;*jeF)tC4E0S6&}$ntE#y< zaWD~c$&bef!^zx}>&#ApDaId<=Xk=w4U%nnT=v%Mq_t(sR`HBkKwfo!%U#|nc}1a+ z8N3?P`+g*dk-1bNV0}-r`$VHR7lJZ0G0Sx?nQP$oz^X{4;qNx|xQBUI(e0-6?s7sq zVEIJ!>p1pl?XLO4#w(*hAD;@Y<$_~%TKZ>Jz0W?2%)G9`Wf&AOJ=_kmSUq@|TazM= zDSAjf2b27!sLhd=KcQ(o%v{R85D!UOrL0+LU22Y~5X7KRn_( z{dLqhvS%qj#rX5&CC71Wdfc0{I{pjA6iS_}gE)1;82RXXUOLl)C@jBugFX6|JcGbW z?)n`*akql&rgqvqq%@(JxEvnS4}lq{vD1!|uNBxMspT`gT-W8^B$7Uxp*6Q3ya_f) zX}{6FCB_Q!8YH(!r#U1Ogw3{bTpHJ3wG_f0ewyTOVnQiebv^%FVm+sHr*i4=^v~#m z3&!VS(LCoKUk|)D{uiyU6vt((%H@Weo=&BK8+;mmtw}g0478!{Lb8yDX-`vm> zcS;y@b!wI`@8i{8-&w;=@v+Ufwd--V=ziyDUBmOsZ3%VD-nyq66CYc2Oha8)g!y(@ zeSBIaZ{XLIVkVHc)iI_z8Duivs&$0P>FI?Znx(!$#PMaG!bso&a$M&x?Q2s#0VsZaRwmb7j2D*nY$SR3 zhwe#Ep_w5_PXgFHDi-(`GpS18RI~o%ve(t*^5eh5(#xyG;!EzYtOQBCZ@DZ1OJ=9= zOVXIyuZn_psiQss=rI=roEh?nI~*?+{`~Ojajjnlal%Zd??+Ajf5Vwr8ea6;g7%2F zC#NP2pzDp|x8CqIrbjV2ESi+@wIf@+OOeCgd`)A#O0Gxn-Zf)CI52&>F{KRsT;c;Y zg+}f$nbAH~Muz#Bcp29-4o?qv2NpOeiTQ8xOj!?ee+PMprEACdVLF??R?C?7ji;`y zoBMEnZt2Tpxp|b4Dx_V~^@JISb4#r7Kr@BUkEqO$C7!hpm) zFgKA~=E;zeQQ*eJTn$q#XM2Cc@9Qc8`l+xPDY15Vn=R^^7Wc^)_WgB+i9KCuCE=2) z`KkCzvm4T>0ALuAKkf2_6i6CGjV| zlB=q1o;f(MM_cvO32{4a1_lx-&B5(Ul3dMH2$gttQTY6!k0Cs|;y3M0E;w&{U(L*b zDSa^6bI`-)h|T$ij$1nlJ*-N|oTF2TTXq)=pls)YGB0EM5BEVkh4E(x#IIl!7mfwCZZau+Fw}C22jZkC1FUx!amI$K!DMmGQYAweNkn$-ET_43`^Tvox-u5E{n4 z(|#@Ayp%P}Wp7mjYS$(!oTXFSzqa^sRPA)&or4Wp#ae@GdWOe$>}?orr-e?vTfgV} zrq99BXteyg`lXQjA`=EQ-_zQNjaFv(BmV$D*G1$t!5CEyQ{?~2iucwa|8Yc z$?xBEnFJ#SnilHwUtQ6A6Q=Z}sJZXE9E`#mUK4i4*yYOTa{rn_sPMf8>Bq12*BgeF zAL-j(;T}KoB>eg#g<7A}g^LR;U4jCsdBqmlLyCOLa+Wc=3{L&OWZus1a2|+~ZD%zT zn?4YF67iX_`MJS4xtZR6Ds=Tu-*0xnF>d%?H007Yo4P9ZO%UdN?Ckd` zj^7p`=1#hMHE!snJW7*SDCCAu3s^q*)Z*aGq?%0vVc%xfv$_OOTApFSPiv}ma|FIs zP0gLW*t6%!wAX_#mO-2OH%6L+n;3w4DJw-ph1F$|a{UAVRk?6Gn6@71-ggcD^o_}o zMv`_>H#_)ze&mLv^@sUfp3 zdn~&4nE~Kc4rdkDDe*#zN5ZOZAU}PHzDz1F7#+6zh<|WbsGRVHP4O15m_IGuqqfxY z4qLnOz1+krcRk;Ic`nCnAgf#f9+EERX9`kY5l`j6JMNgu3rE<&o|`tgzhr0!K;g)- zW}#al3J;mpjTy8H7o&|T1+#SQ^49yoftE}r;filc;z2~5SGVcoMOa%C)0lhXwV?gE zb5jC^4r>$NZM+S#r%$DNo`X}^gykcaFv8FU>dNS6C|@TCeq?M&jz-KK%eP$1X;Hq> zmMihqeo?<7MbC8GR0~WATj`(|iqD^Ndv}2(ujD4&Q}G!7_`>e{c7DZ2M}0 z%^;_|OvpA_=2q_4_k8NpiVJJ)531EZ)C{?v^0X{J=d_2alOKAWcI*4;r*lKZ!ZBJI z`vB)LTS81eSHE54cvJY*x~|um%ik|2Wu>^zM4bW$P5iu1c)%>a_iRj7)Ygyvk}SCx z!rC?TGE_A{QHy9o`3SGUXt^h9Q|e`Iy*tmHy(Af!;e9@;N7T+meo)Sa^l4pZY9R@5 zi@k3-A_TYuiP7=~!OFfe>Jg|Kdug!KS@kg(sGoK}80e@`U3YN~SFf+3Uyu-5-c#As z_?Y9!vBr*_<|D*b4HZdecYF7Mk;aok8qdCpv_1yOuCQyWR6&lOds+Rfzt6b0RZrHf zM3&7@{bGF(7O~~9eM+Zr(6WV_$>(96S^r9>79k~DjPNd7G6HTo)RXa0xk&$d1ctTb@gjfi29L;c|ssUR6pn&vQ8qcAb^tV7s({;(59_h~n(2ZH?#t z7`eZk4g9K4aM`xI_QTL}*{@8RFvfcW!+cRP_>(fQsG+cAP3nS~ruxcO`8?LP+V5w2 z#<-gb@6t-8;qPzVdth+qU1h4hRh9PBn4594hVtC=5;pgR$h-~+?Ne8OzIGkCWOh@; zT8pw4==_oJ!NoP>8aq2Fxci>fwA+#WvA5=)Z%YY29Z3>7SBuu|lR%vk>v^-NIla?f zw(hMB#2Ui(^EhYk73Lff+$&zCHPXxhgf1TL8E`3Jprl;gywf&vGcS~wq`;^b9%&+J z?{VcVO$&xC`>P)bkqJa^5g?!ABA^;>)GZ-39VzV&@;ecNr%9uG(o`rhnL^Ib)t zuJJP)2_1>p{n0^TOc6pN>AL6zK}l8;;`cQPH<9GeCXy6UHt#pnRI>Z$zuFP0Wi`J5 zs%v2EZY*w-`PNMsGcyspE_fJ`!TUoP(YAmX42WCAM7@1sLCbOyGRyC^1bZ(D$PR)G zm>MSAc}#USQj6fOIf){4h0kdcT$Phi=B|DnhRhuOvJygupYf6I92gP_q~qh&*qL~Q zKHJdNCpX2&7C;#|fD04hkc1xt5f=)mc!V~4(#%RR<(btIicQ4%AOUVhkG+y`tth1m z2bc}8PVOnPxEU0?+0-~Qxy9_7I$IiRoRvIfcCRmG1tFs-#TmP##omLDS6{YafOpDC zk;UKBU~k8R8OY+Usj)lo^6uSKmu{NgJE_5nfwKBvqwr|c=GTm#=+Lvf!zT4~x*C+_BAaVH3JrzjGm)a1l+ zArOQpvC8E6Wb#5Yg&Elhc3PDrlmtQ2z>I~xhm9l0;h`ryD2N#TukM%6&=iXUA0m6g zc2~$|m`Q2MiuVCbBS|^atR?A(lan+^O6TOOabw)c5?`evQY}uK>%>pU{UfshC*(4_ z?oV?uT>v`A^;Ikad_rzZiLb&kWK^5bU1TD{MRm;vaFyEtw7xnar|38zKr+=~*+nk3 z0CH+bp#I?^!ZAgv#KZH}Srk`Q^jUtRA^(r=RsgxR&Hl|r{$vsJiJc7AYllob9yo$V z^aw-swkro|na|=EXUycaQn-ZYk7h#4INK10c~Ml7(XzuOAv=VAsv6bl#}JgEpQaJr zj=oTmOfsn`KbK|RVOrlQ9=6R@)hk&mVp@>)8>(BV9ue39pYT^WVNuEzFIsptpGrdW zI8+6(|MYkM3a3?B5Dy1lb-Q?;e25qmA*N2}`~F7%!WWG5@i$jqn4*^^ee2F|&LVYzz} z^2<*b&7MAEQYmJEkRldQ%ltDwvm!pTJU)9SBRBMPetAXFhW0<_8f#wszrI2o;06#B zW8fHV;7BzfQUM_LZjz$NyQn)D17fskM~}tw8Xu|J0*89XEFT)*HvobZ?_XByc!VOW z81_>)!X6v@sluLW5ZI96Viu-!CfXLUg~ex|D6o^e^p;11k$*L;-n)xrb>%MRz$rHz0Q5Otg7zILC_feH2pdpEPR{Pv99o z$pxS7#ypzKMQxsEcx5dRg55Dhqtl1rehKKUKklp75|GpkgU8bPCMy1)5{&zJsv$KqAoG??E0~ z1;hF9P(K6CXZgp#qh9o(LD+X7ad;rre;~2Bys|N}y{6`3UDfBhO`jWIzTi0bx{4;$ z??8dc-uws;R)n7_ac~vfpHK8)0WFFCEXL5F!y^_E&SQv7<}v7T4DYKzBm$029E+jT z3s`iY-F}Oyy(|_zk1^)W@Lgok?+&oW7F~M<F}wuCSa5!-Kj0fo zok)lrU44cEvqm{|e;~Fx(tqodrbwGh5y8X1)?Hes=-71Gls;_P*hDU5jn1sGpV*pa z(R(EV=o^ip`xmfALtiwyd%|>Y#?T_{y^shdF|m+1rU4Hw0+*-t=NAVqCh}gb$b$u` zUOL zEd?9}Xm$>@MT6amLu)dr1aw6zm3mAgB?q_Okhz0oT*`ANxs`iL(I6;8$n6|H>wUBAdYt1F?GvxXBx#9#G%xsZyBe8KFpGpnSV^V=Ch7!pH zs3MUtU{*kt5`hF%d62-Yf;OQ0eMoz2fhrfwfIIaVAh?h)KviVzvjKeQ#xj*)W5YJ} z;F@Z_mOXmec)xmZ^$n46!?s+~agp)k4d6K3QTwcjR@Kn@I6R`^LlLvPf=}~sZ4k|> zLB^N)>PAX8Sb3{EDXW@K^UK1ee>a}V2dctr7XSgMav@;_8sXX4g(BKTKnUMkJ6*(_ z$4o!=2*+O42nRN3K-Kg>FerYcl)&+@o^u4`y`(7brS(Y|*;0H4Mp$Nnz)W*FnHZs7 z85J{)VpGk9dYoLU2%;+R%5tgUr5q}CZ#Bq!Nm1Ufu`pDZ18HjrK9=m{I;g~4YEcTQv-3^u13CSod4YX#`-PKv`l|s;H(_rvhbwSVf!!SLAVy=$;foJdVoG z+U!47+W$Z@(2|=KwDjBK5_GMVU8(*Ci6o%(mIkjdT5+2^8k>caE#+{4rvkGu2wqtq z%_WbCBso{`9|u)&Q{1Vf>Q=2_5K{xRs@j1fYY?~U;Z?ZDC{ozQHXml!jl~>lIA(yx zoWD^p5LAT~j-())uc!srG%SoCnnw$0;SX$=^w{pT{WRulQ89T8vpACS8Wfm2vv5Kk z_Uqenfe;jzA_X}lAKy}CP`oNzcC~1=2zf{k83Z<%3-S;w8*rn*IidT36KRiDoHGh5J9s)acEIxE2g3ie?mMql4LC61HMHP!0_G6 zKXAD}aa8IL9N4Pwd>pDXC_zzHAXGK*Mw+mC;CcDgI!WUAwSyqF7B7#Z#rRIlo(g>g zro4hcLZ@Nu+x7lLdno9q>N7L-B}-eqTw1}!j+BNFzy)S@?q*Vuq7w2~IlPhGfh(Z8 zC4{6oS(r+v%jH4Jm{pL$dgCccyVO?VlUA7+&GF<-ueKox$Yf;8Q%J$-)@}K%HgD35 zM#iO!&r#(>{}WIE1g(UiyD~`SN2u*-ZL*H(cjcTwH4NG{=$0IGOJCB#!6N-+Y3=Pt z6K^C`K#}sjNlQzMArOa|NR!M8FH)_11qpPp4ucx~KZE{^u zd7ddDZgZWOUfj{B%?z^k0aQuL*)Qh3=VLV6f&)0)P1YP9k63&CGxbcIV*iNu>4wk6 z6;c*!Yq@a`)&GclVK9qJb3FBd(!8`fO;q^{)Zyq~X8UT-d>uX> z)Y^LG@x`;{Y4N?@$_#&><3?T#UL}b|p8LAA#G)s^^))BXO?G$)P9PW89ppDXK79A=5xZ^+yCJqzJYhd6nEDT@#~O!(le&s$y`SlTb}3n*VC<>r8j-Q&`Dy)7p=9@2sGf_V>|`4ypWNvy z=2~~rCFXVzY@aMi^kB!|9(=j8hF6*pqhm2PtBchHv@QQ z!WzLA@Z*W{{gBT1u>Z!^gfjm9*vO?rhYH^K$$Cb(oEb0J4M8^HeB$40Lxe0;^b6GZ zN5l59SQ-J2x3!)4S6+OL`sb@E+xHXj3{MDZMCfd~Vco6OpzeI4JZ)A1GTSaGh~(sk zNpHGW!agykp2YcBR>>E9`A2#3uj8$Ibn3HL-oO3eL(;ypad>P^-?KLbRh3#>9(H>Q z-@h9j-Cl3{zW?pfQ+%yI$L90o`P1{d zy1Ed;s!4742-51zy{Y0ZSe5Y59NXfN5Z}^X&faC6rWPP;xG-}%^0uDwp}+4ZbWPnU z^lZK`J^N4Vz~zn28#u_ymzRGz>Vt+CLgqu&4;~81S3L26l6GOexz0@4lRb)ZL&{FO zhsW0kx;A&5xuR?@`>x>kK#H>N?x+XkxSQX;@waO6-_Oj}`;m7ISZ4Qp@w4Qllm(QU zWZm3kQ-MzHQSj!elgX#9P2axc)&~8kQiL~40F7q)R1wN`X@8ZYaCtiyc zAk)Vce;06?=7ys`=GfdZs!@)#PS**}Iw?D9ID}iXHYHm3jG*_$3ayZ-&xcng9=rMb zyRwI^La+Hax^Kn)O~o*odb_Bu@x#5_Wz2(xD?UAu>wI_0ta1B`f_=7<7mqRzuh2fp z*|PDYc4d9V9bY{a^EF@D=Iu`$o8_aVbUAX;^XFosN0krB2TP3GD_BM9yL^IvH~w(c z?D>r|b9;sfX;v5K>$^Ijzxn^#6&pFNl)JSVOMIX^s0i4GlOINR6-n!~j4v6cW`=2KleciHNViHLR>XL?BBD z(xfTt9N^HD7zkA>7nPSttKQ&uDprnimyiaIKHVrR@(wVi8z1@65tS4KL%UeaX`gOZezUEHw4*GR?_U3Ai=7X5l92Fw_pd}&s{V<>imRbqCmz45Xt;}||lY2Ah< z-YzW`j_*)r9KeGaz;X48jBfmGRfY~uatA}rC~z~B20{6S=%hllG(xpn8tQ-`gr%!u zdpNT58nUwrxj}NHw>a1bND}bbB^BAF&f2AGdZ(j=eeQCpZg;h?8wkbiAjrj4#x`70 zLMRsqL6Z5VNgS^v&haFEVyYw~zFZWFfgl(#V`S~N?;z9WPj}LAZOGW)x(|!0A`}Nc zL<|HSErBQMi>bhc`v9g9BbTJ#67$2!G0FtlLa7Se6#Heqw`?|{3b&1IS93N!C#eC) zXVZE+=h)a@02Q*mWwHSupWTx0ExitDSDo$4))C;sd*_d^<=OzGRdF^gJEaCd;uS%u z*$!0zvTHa?%yAIlXaZHj;Z5s2lC2>4y#26&mDAS>Am_IENjBmqi;z#~WUyXKM0|?h zI7V`Se_ZW=oWH8UJbvl5zLaV#+v-jK>*GaCGf7lNIFX>e?r>4aQc^umk!bg0@K02a zSB~hy6z5+e=#<bWgKoAYI(3*u_pXcf8HuATMNfdfO!xC*QN91CuP+@Wxf%%e^@U*ClxaP<*P2Yk zk7a@lg~AjM3ggYbTGL@b^Vxu|^JgPx1q)Y2+d(5z|7MD-Nr>xS>Yy>jZ7+r75#q@T z@u{VcWm3nMqNo1WDH6gZ%0rM@`c6!`1}6QbX{x5ZPypfP5X3I zQ2Md6tlL@H^I3U1r9u`6Az%@-q+3x*B~eMYqf%cdrXSB@-7d-A)phG#W98fb*Ea|Q zToZyKH4jE;9wcho5&y{$Fz%G;&e^j+GK5Y#*7{Q<0g9e_fv0fiB7)K7^Yq8ty?~ zV)GH$fE(>ZthG!V3(sJR1E;|tSCCiO4r~iDqSyY7rfn}yXB(#tcd+D-Ay-1xEwVX* zQ|li5k_|q)&>XTu**1=QaA_3~f+WDRp`b5qvxuc41YMLNN@L=f{=FD}8nFvEhxAXv z6|)0+ap+uT7fw6(x;%yhJ~4bYv)6u(eSN?l4dSCo1Uyz~qd;2-p$)wVLpohIa#BP& zDcCwIQic_5xfw>!jEr5~NluDRTz8VUk`sxAax!#sQY5)4*pfDr+*nSe8tR`$A*1f3 z2_+J@mg=(@?a87~7&?s#J^_^uJ}I>!6PZ6%k%rw#V|xMB*fo;kN}_rL&8I2e!z52$ zG|cvQ%8qw`suc$4649n29RAUw zLP)2hry?noOghEusLxW|Ae~OhpiX&Gy_cwzb{>6d$#JmOX_!kNB+;jM^jBFSW6MB{ zPGZIR0>0t6>9e5|Tk>2<^a&=#7l>^M^)-3^D0JVQkbtpYs_*QSIr!+VE@f8~H$o_07hb+zePj?x_W`n1J&!8)JqVAC{{`ec90@_9j%cyC_;N{T z1_miJ*w&8tM8#Ne6kr%>#1>^n4-TV3BU)if;)uj6%CTuUEfnn#0bRgxAvhE;cvhII zI3oFE1vi^~#h5WbMssRh2v` zq=xL~*dUlygSa>C!^7A@=JRyjD;crlw? z1_;3?s^+q33)s04w_xKsk_PH97Mo;T@ezxg10-3cL(9&l(DMF~d`y+8Wr6xGkr<$~NttsaLdHxAW1NhG7ciN? zQ+~-EHQ49bv%F2eJT1BnV|C1>Pl&@n5YPfX z;9GgmwS*wW77w?} zx%eLJu@ZGj?ClaO0wx}7-KBO5<0h>hr%p>!7cFS@aA*Y=I|2qt0vG68y6B5RGO~zY zB=FjnVfR6GYZVx8XQT^DkjQ}Ku$v)GE%dCYWn8Q6^H%Xll^2(Ge=tK>Aub_WW*}+1 zre-OVeV^jB$6vs53yBhf{|V>_1Z{$#c5#GUKk`6)8~k8GyM!I6hC!=`nk1kmbx|7| zql9Y(Rn7g=pG4$Ak@CI4U@##B;t+ztgnu_MZLM{p;O|C&_Z!T+zfng=>wZa5Zcb(% zJ0dE%MBxq5uW>11vGL5e-Cjmxedq4v zeC0ID-p5)kzdGdoG?2yO}><;4!|ExqoKt=C`%+z?;s2UrsA2 zXo-{#HMu&S4@p?9TBAO{Iw4z`@M#e(I;=5M7dF`@BByZR>8hOEv999BAu4)zHOlpC zYMX|SUQFJamCzgT=DlC6xPRA`_J95B0e;vy$WGJCyg;RW&%J_sX)e09{W~qgN0k?k zBpl4>{7oX^<|OZR($b3evh?%PI`@yxd2Lx${4-l*!o*_Es?70mJ?M{MXJU@7Zc~9C zb#ucVxf;8aDze*hj&=9;KUMRWwSWR|QSK??rJ23XGg*w8ixt6FlOD&^Z=763NfYn5 z4(?vjx&~jF^4wL~(X4WryVzU!=Fv%6z58^YgM-7#MaL2Kp@Qds4z&OBz_veHyR&G# z+IKcSH+XME)8~k>?T-;@#U}hGL|0tsC#K7Tf5#)GlvbvC;RWY*^b6!O z^iMLdp}{te8#5$LqJ?I+11OhK8?Zn;_peCcl-eyrLD?C4AmhXI!#|~lrk&)KT2`uRTg%y7AJQ% zIoh=!pPsRY5aACBw`R*(nIiK#XJ;Dds&`-Ze6^!?M&`IR_2#d=D*f7^JrdFN;1#T_ zd~7HBedUI0jt)U%DidQP!*9E?U(hEXh;1KLw1mswy_DeKGhTGa;xtE@@vE94DPLln zGQ!C*WarTH54msU68`N!8vQbizIrPDs#X>whbp!4#4d3sjo}57a$#%);!SISYlS2bNonB+~3!;z% zOa8&0;@QLjUfIYTZ0mHN#=XKd7r4ktR_r!0=o{b05~dU;GR%LYo_a085xYT8q;bo0 zdqm`sn6*>qL)$f)uZLG4tNGl($io52NG*Q8R%k=+RySK2Tg|9BSA)M8)n^9Vdr_HwGqoZgm)4^z(BM^653h(4sTl|#UalJ_v@mbb4?k*=&x z&6;`#-s!lgw&!>;x0)3ERev%anK_A+zPL6s4n3+5Y=ddNP&fe_QwYA3) zaQzP*FZZ9Tbyz9A(*{o+{lI7a(iML5)9AvrMjE?%(<`}|JARpS`06MP#|Wy)>MbQT z3wpR(!ckH;-#Ujfq+t?0ieEhVg;)RZm3-&qJ9quZ$i*34D)&Q#mW|oGQ~LLiE{)%z>u06{6Z>+- zWNsmmI`ggF>-R?$50?wthSVg6{RwM^+7c^n`PDoYtnY^E&5OU_$T(4 z{iSUA>>osZYDiPd@A6ILxW3ipiM?4H`md)qZ`##9VIWPry(6f?VU2nv!J!9r(4f;L(s3aMiuYl4AtUoD`tOO)UFWMXgNrg-jrd zOIZnQv51mqkIKA+5zhb03V(9m$D>{Dp25`DWRoYUXL71q((aZ=sBFjaH^F*E(3zhS z@NRZ9pBkdZm&w}Hv!^qq4J_4#BXCsl@0qG4%U(HYJWRm++E&#q~^T+c>e&49(1-r&l)w)#Y9tWr3%KPDt1R)$bWyefM^P@;{3{N1eJDU-_VK-?@RnnXo}EXgUTEWOt_IQl9; zBnU#qA}n@@V-0z5V+SvzX{1Ac8-0WLy@gFAd1$i#hsY7bkolM)2!fNm z^*awDyMIA;*CI7x%K}uuK0q+Q=aOFPlJ&%ej|$+U<$dNUQEcCnq8(+9m4M#0R43q5y3nrIxr-kelSU}Z~`_BaU-a*wUEZbYAIV25xK@_85QNH9(6WP{4kmsMsL7kQV>2HvCbQux=^WNb9w(rQ8#tQ6T;xuI{+<);pT`RLpT4wokmM#H*q0W9?Lfr#5$8|> z__t+(4TTQqJImwEwGQQW4|V6BrRQ6`r=Fd+K6waFA2eWkTeH2lu!aas+7>3=m+hCw z4s7I10n- zet3Ldd4X`g;G9LJoCSi*SY$1|>_~dWk@WH-S#xRpeFb^t6~c8rWzVl%eD?pkraZt= z5EO@UjzKw7QDiCrTFC2;-W7&HTzqH0dJv-n~zqqACEMW&2v3=F~S@v^P`CXXOqLH1%nbMIyOp<68 zjtf28NyRy8b>!Le1S-I3%8)n6D_j@uHZrE)^$!%epJ=gC+(C4%I6v%7sV!q{rHC7S zBBw>*vj-z)xc$CT>=Rj83xpsw@MsnfWE&`u^dabk7F7eAA_(cn&Sq14h%?BLbm9e3 zXg?8CDCi-Y7v|_<#o!Y=D-!g(&WLjExne+k+)x0I0|p;PhT!JV!vjc<9K44<+Cz`* zsm~nIBTI7eckl#nAG(LWhs1{-VCX^5LwjuY@X)8z^vHArIxWwG-oUzxXOH>NCk^S6 zMpobg*DsGVx!Ge(_6evQ@X2gsPv(DDMIZ5@Piz5Hf_EI#o6ZUVnh!ApM(BQ0F3>EY zd5js*>3Q@q35%Y`35ugn`ZC8x=mAphgft~c%Dq)yc_q5%;>F+Vsy@|i_;lsPGlA=n zyKF)dCvUokUjv)QVF&7wM-1qaJTi>~v~Ytstg#WNK@ORo%aWPQWib!4{F;CWn|_G< zAdbn*=P>>E1}>%yaX8Fe)&oCQz#@y;Ddjv^bRTN;7?E&>=$r>q&eH<+#Cssdq35Lp z0ltxxNAb~<%g=e!IgqFoW5%Y^MM5>AAn#HpOuQfoyGG+r@2H55}c#2RW~bgdjzCj8aN!6%2Z;3?Xaf25nqe5&P7)jWXY2PKv;S>ub(Y(&In$&8!Jjf)$o)X3aeDp1AJ zrdR+~6bcT^3aHX{pa4}g3Yb;MI;_N>@>4BP<%W}bQ8NI+je-NJqHCW@?f0!O)eXg< zI}AfFRyPDYS%d{4<99%a{HbSNFPs7cY;$gTMksuv6 zYf?(Z%^-QyO|vEfK2-)$HN>TSYGkp1O8u!C35O%kH;MgLsfxE9DrFeeB*P42Lr*=b>|$%ta?}0tjFb;C4U?U;-AnLq2j$V@eR7 z?gub=tOx!~8BZf85aBD4Vc3DzsevP$$;FglqHR<3vn#JY-FmaN6M|kVt3gGID}0@8 zu*RB}@>zkx4eYJGi)k_(T%}?-l>*L2!~sy2SQTsO8`tSVX&_c%zkn<9v_N)G${?{o z_j_&jpDOKtAQkAnrw#P}$I&8etqrNzbe%#XP<-@0^q6OOdL#H zI?Qm(jfGQOD;h>aszk|NR7!QbaVUr>DWj@ZD%=X<)-bY)IEti1tncuT?QdPorbgnV zjM!JL`O=Uo!tDKI_^r$Op%+^g9{&6a+sKH#WB1;K=T$3V#J-jllNq?h`^m3Cfw?P_ zIJ=7X`lebi1RYLRf}E00Z>~ZW8f2+1m#r424w=A1zy^yz9)e{9ZX~#zF=(nBr|kek zhke6|1({2H>S6)^D<7yMHq90RS%9Nb9SdqM}lprl__;xjWbJBs! zpt^MkOLf6pDxXx#g>-NR5XubmM3I!zP9ASpi8FebwBe;K+yR~hzx^1}aJg|)-Fn-b zRP*}}l?zL#YO?oFW zesJYaA8F3Uz02GW!)%2FlA2vnKvC+Ok%?R7L1sGxku{qP*Y7iN-m6vUV0GhI#bkZW z_DZRvgu<;}`SGIlMb10av5LC&)W2HUyBoG57wixrD=L*Z>w^qDx%YQ=6!HpQDFr?^ z9$z=;uy$>UrUoLvC*tOd#8akudw;XpsA`VZ+PE#g{OK2B4B9K}%bll+Cr+*T>*$)r zWoJ`s;_;8{q$&kp&d|2$IUI)hn%K_9--TL{t=G;+xkKC24M?hnuM-(bcH6Nj@l!<7 znVzZ9#$~Eiz0Xc>``nx`fny(^_4=#9IKM`CB+U_#HfGTqs?%!y^FiGz&X-$jXs7RI zygqJnt+R?gj^VB?yYh~EL0ONlz2fF4OO=W{8w_LE9&)>0zai zX7jbS>y5#@ZAmH0U42^EoBn$ee@i%i;rdIqx9ekmmvIGwO|r2)U!XN9S+9No|Ht(s zyAPNBl9_k?j@Gp;H+DZ)?(SZUHt1)c+xnqFOm3Rdi|<7J;Tl+@>O4@+OB#$@)xv$( zdz=(jIF)+9IBcf$tie9Xfl*qWQnWL^teMiWeb`bTF&@4vPW+?ug|Z!=#uY7sLoY*Z zSXQD6@>1gLx@W_+c3E&cL(@c5=sv#jPbU;U&D#X+e$ce;pU)JhiN71973+0gWp41h z7oKi$w3q#M-FaGsL6k<^PJ-s2Qvb`(>qR=x^iwas*Nyd2a_rzi?a^b zC+x&#nv&*M>u0^)vj3XVI_T8LL%W03(QZ55p4^@`d_#n3<0A@4cLeKxPoRC?ZBJgN zJwvvGrqm7kQ~cqrmY3L*1x~BO!WYa^pF7=5WF$0o5;ihpcTHHb3;$j?q$#HVDF|2399sCjK`ag2#$%yHkZBm7?rgAXJWZ(j}R}>Q`|cK>e%?`me*#!URM+H zJ%4(M9mz325*Exi)`I?Nav~|4xokI?zP5T+gnxZQg3}PfmU;xSpRJL z_q)4-BQ|!P>0!~Et0+-3?N6>9>abit)LRi*Gk$fY=9$Z@TBq0kuH6=D(&Z9)>0Gkc z@DzH#Zw`;$FjN_k+i9ocbY{qcZCz4Hz}f6EyYA$Drm6c@o^M@M@rogae&r)p2=iFi zin{|ZwiMiH75-TD)(Rhm6u*#8{ENyb4Sbqcf~J~KC$x|^l#JU7HIDYN$57-o_Gbop z+7-~ldilhi4rt0=Lv+omk!I6Tm(`kl{<>Q&2! zo|L!yWbSx-*&Xs4J(qDvxMn!~o-u|A9sQ!{b!+454JuO`^$$GMF`w_#$*X%572$Eh z7Vl(`p!M6eWolCLV?T|}>plb>57K?^n%g~-2WxBeNz^(@iqsrNc{t@{f(fhJU40GWM&_r!&0B~ebsyL(3sWYp}q zjkLRYX_w>Bt6lK=Gs-5m$Fb_Cg7@w%YY5w3o+aGo){Abg*E&(G7)^kt8jcmNz53^# zcHa2fmarX0>I%@27}0aDJNIAgzc`h9dR}OFu2u2*ea(>x+q3hPdzFuGKy4;)7YzL! z&t{N3tNtm2C3ocZTS26gJr9CjBfEO?$>(8jxu-*~>GFFw)$jcN`n{j``+lGAbA8|EeV+Gyz5zRSP$6aLOZzOH z+Ajz7PWf+CTB)>WS90`DjvS$s@vHm=K^aa;iuYxu0J-G1CYO{`G%^$SYrB2^S39J# zsAegk`bX{Aj>Fs9JKAFH?BwjLz{5<8*%ix7b_K*3KwPgNnkDRvUX)W>viM$2bPrL2 z+#tw;V`S|m<{0u3Cd5GFhe%>S>rZ2%ziuYd-an!j#VItet|aD0pbrfc(jd7&4q=}@ zKaZeh&PTb133yhn0LsM!+)gHGd+hWc$@j#EApq`)8DEEZ zxr|qb2h0{YpFkcQ{{+duW`oYlY`42?$cN$3`I(RGx^D3_iMeGwU)*~W{tm)E!$lhw z1fN14oX};&_acB9!10&$`Mrc16TUTGZ57|lA=UsYgrLe(=)6;C4TQ->4X6u(5N<*G z*OQRl$B^9;q^8=^@Fid$AT_|}lUMCi@W@AC5iUR}`t*;srahHjo+d&XBMXBd&RPpQ}Ar$i4c!?nvu61=I%N17@)nb(Y; z5pnvvr$yL)0G$$rYn1`M8Bu#>xW*!6B}pA9vzFtM`e(O^bUOiLS)W>1c0>xGCG|TC z%KRh%@@Y<`ob;39IC52r;c3S#QluyUtZ8j7J~_|i9)hkbht9)re>a{Px1LWMCY1k z8zuK(&Q@lUtZQpd<=gk#{L-fwod2x*McYLS+m3KwTi;HhvT?F7)(iYh8ShdEomDTT zkT7B)MML2~GvIq7+&H!{NUk|L7jssWtYKZV=uR{F)<96e8|0v_>3{oc{|p9K9qH!7@{8U85pTX1E&PToZVcH3ymbiBa}Cn>9Cn}$8Zd$!*+Cna!#DQ~&A=RmBpQL6Eax4MwmUBY5akVBzZ)*JTa4!Q~m5_W)h+&`Dt7D?sfO z>_{!HDJ`2Vt*}0)V1W>F7J17%voEi9UtZ0=f+x9xxYFX9+OoAhXZ~zyc=rFgrXs*C zASlJcJK4gUV&O>vfWo^OT5|6q|G-*!CfoE5IV`SmP|p=OG&E)L(DdMhA`047=K6IvN z27!$^ah-y7*Xk@L@P$i&(_l~#$SZ6YwjG(=@B7rkvmbA5D(=L4*Pgx=M3S7LyO6|< z!K{ZO@Y#bF)BS!n6$i7fkFc%H+={?q(#xdWC^4DF*Ajf9{e;iIuCzV z6w{AKmkWFFR^`W+VZ`7QGb0lA`%a6F5BZ`&e6%TnhlqBF^@I>s(7oMA@^J^UK8md8 z8KBP?)$<%Fa=77u3ks%@^~oc_v~WW*tr$gKPbTZrsCu3>0~)oMOp`KiIT>c5DT=2b-)G23DI5*z57OkqTpa3|xQwFCy!7@^GZ1zPBQI+(=$`Sd9x+UNpsdG<(gdDKF> z_=RQ>tuYJCVCDpy5q99=lMh$yQ@9a8R?>H+VdJk!DcPGq&cl%qr0kDY$;z%%gC4*j zBfiMppOCB114jXdUr1>;;`iY(#vBR}Q=3Jh95&(=;w@2}EhKc6IFRI5#g`E=k}L{6 zp?;){ei+9eqNByqK+@q_u}K6A=aoK6^d6t zQZ*L~Nd73Xk-N2|NEi(WWAudPjuRZTxI;inK#9X5{PB%OoC3LVD}`~fltN(@aVS6) zQ=4QBRFOznFe{)+n@9qxs3b6}=(U)UFjBk(sPeakYTLsuEHt@%13@mF0QA!U1Kd3epw@6>31+b|ZV=Yz%Us zjqkDPe(N#l05Z!|fdSda?p?%ixswVW8kfOX@Cd?z00sf>3Zwugd_H|RSb=HGigcib z0!%S;DvTlLY2-#2g^b8C>__{L9bw{P^I#U5N{`p ziKdNWR-kYLdrR;!=OMsVDn?L9;A}M74ayR`DlL7Ji_4%~5UXm(z!iB!D8DD=kXX3v zTW$8=D(!!uCD8i-C+Pj=u}X}@$*szKtx^V1+GZp^k*wvcj=|;Q;Z;H*@KjVjR!v-e zi|$v%L6CfFrDM@`B3>YcRNr9|17b=>uan5iTtM6!vg+_-NYc)Aonf5*)`da}3oD~@ zUbdFVqU&%ocX)_vm-J&An&~A{uP42;?DHHsD5r%NdQLC~(?DHB{_Z zoLHE@$fqtA3cm1xI>LUY637A^g`|*GlS8xLa2R=ItDs^~-yks`K|;&z z#Mo>f2OC(9Y7wN1HGnKE(T|kfvN}9(cPvRUzL#nH!WltCWFp!hKpH-6SJfRizRtF~ za}QR2ilQq2pMbVOkPZZ0UxLsbM0#a+!o72@tNMUy7_`e!n<~_1uI%CAkaMg`a&_?j zYo%qNNcqxWFqi@YaR|X+ioY9}mE|H){&yqC+uj~CSc+O>SzB4%P*G7XI+4}4Wku=7 zxkx-Y&4M#A^UV8=CtLd<^6kLmq-M7}3}^q7&sSI}BdM3RPAz!DC~ennE~zf zA0OI#|KsZSn|h4;Qts_mm>=trpfud?)V7QqoN>sb%{r!* zr1#&gKiIG@bmOpwgLz4@|!{4Y>xWJ zG?y{_ZZD^sQ?H9U3=m2#2Pl2n^x|C>C6hF4s}<03i3&{(3bZg7SqfQds)o#OG z*9W9hcFgIcsRs`&7qRRgyI5`YO|<=K@@&cXx0eq;ys7#5jfaH`A@R1@Ilt@5vIepC z?&lwa3n1wG@mMdoHRIX`UC8CM~RqluD4*X{=Dm9f~?V{X}aR# zx`V_^_4Yrme7a8NMU4G!Xw`RhsTZ{K)rp}mGk-e;7ewUq!pi2K@r_Py94#26MxR}< zset35XK_nb*nxZYZWAm6uHE&0;F_@lAIIsj)W(Zx#@W%@SE02PeTGN(ROg&ME{oXk z*YErOXx-IM(5NMc(SO>SWVyCfne1`!N>7E>^r^T7yQ_@p!4tLHoL<{4>2hVgV~5|U zb?wR=Qs-x%ejl~sz=>P6aM|2`Ipd*f+`pEk@y z3(G@e@hVdLTjs`FCw?4VZ2*1WWRan@wM`{n_xFjAvv+T$4#6zU&XiOgH#53`Wa&_H zX8qF29_`IpI?Y-zxzx=3rC*P~-f*Ji!Jv;(Qfkd|yNup_s%xqI*8={v%jk(&Ezvqv z$vrE=n#_^zls(=3iQ_MVChoV9j&655YJ}>v(lh>h{77qPzs_p}J8ivgDsR^RSVt3F zC6OX~QJcN_?JrSN4_o4PFTcR9ghQViA6*D&SL#-Y&rCRWa)arwt|9X)Ww7n4@NEy- zF+0=JBLY5W?z;X_5;Y^u35C8J5sSjqG;e{b#D3x7yz*H(WJ8 zz2;2p4OukUtq;+g7x!;?^j^ih}4it-f0c< zip`85;)?@Xzk7ce6?%T&J8;jb4fiaiMikKGyxT1FYRlix!-Ef9+~;&G>^bS}{t|AY z;fii^Q!OnrSa4?r$UYq#xgR z*&MS&-L(5vf2MkGFKPXGWznY`zRrDJ=&tlP#+@`5#JLn5_L_J%uQChR5>j9$q*B@6 zG#ve+=h^X1Q{{;_nm)VKZ$#z0EDlD^`1@j{@%ad^Eu!1eZJ52oaa2xInUQUB7zFZLOtDX z25gj#Z!XKo20)p3fQypg;KW~pJw6gp2{1kOsHv4IYuxHHl5LOog#+BAK6^3oI-ga6 z2h4^zCl8haeiF&PYl7yaHJD!4X3OEwS!rXY4<55rh?#trGw!o4JA#m;y_>z$UA8eEwt}s15vB#@Ku}Q$np1*ShU;EYh8{o=+}2aGX&3V0 zG33K4qzdd0KY6eZ5Df4+aY~)C$DDEv{c=&#K5^*0$)hXMZYC9Xf*=o1Rr_6sW|W_RW_NA@rxq_3FxnnY z2(WDcDiQdp@&TV%&`{*3yZ{+h?e5?kOK`i|UTzhr-v`j@%H28qBQ*e$uZ+s(yHo+l zsdhJ|z(s;%NK{FOSB)=`0u9M$+09yBK}REi-0#19DuDlHk@88M4AyH4&o~l1gn@O5 zBlR8BLv+nv66PjNm2_DG;;YWd$WpE~43)QwLNZ!#xGZD~Gf3B@IQ<$zG7T~i@y(cX zMQJ4C^0JaFvqvUZTcm^aRK-=bjjGrNxZRq{1`0J6*XtWSjTiG-)!zQml{FL+M#!Zo zOZ}%0d{0!+3Cr=6Xb#E5oD;+=8<#D(Q(v+*5aj+I*{QDg-~JBSu8#6t0{Yr+Gh8>- zp2iIC<1ziNr3Cb+)8|r#LI2DQ_T`29{ZC(5I!JPT5bO&J!Q4kMTJV#GT==hLf(?as zYC1~e&H0L&~fQ^x0|ED&76B59nnNu2T|PFYg+WM*#UNnTkwe@*k*sk)1=|6f;;2Dl*vB^Wx! z8#+=9?I{3|dN);7;$7rDtf76p$)hfdg*A3+*Z_z6BrF^nKQ{n^R3Bc}eAI~~FG2NC z*3zhJdnoojRNDV*v*YC_NfRf;kuog31I5$8~v@e{}p4*r}Vv<;6g ztEa0{|PY8~8Iio>*)XRW}h_(o`hu}ugvzhKn(%gu*a0uvur{qn6do{} z;=^MOo0A75pMc5)pL9{|aQ<&qv_3D|;08d&c_z?3Y2kiAb0XcZkLJ^x0yOtf$pcz6 z8jm*66HenXgA!=N-t>V!nqP0qU~hU*Z_3@W^L25}7cXA8Qt|D|x^H!FUUQwhT_qFh z+2Tnf`_#lznXv&H_I+Bk9-cjw3ACgHF~bM?wsbP>X?fuilX>Cvzrua40g+f*V#-JY zou1F6`)&)EOYdef>3QKJKH+|I;q<0n=E$6Dw}{-=!|bLpM|zp#Cu0Xc12HCzmmUQ8 z`qH28jvHQj%9F+%=F)?J*wVNl%O|(uHeHGh9o&57(kfNQTbE7fgB$8@kxwv(Czshh zx6H8Uu8sxzh7;&P`OM+S*L5CVG`dgtz#PqIHU&)L`E1Gvg4Q<&T%OUxD-51X5l*Y* z(M0KB2I3R3bl-iWlk>OC5|{x%wyNdU#Z5PMC1h*{Ij?|(AX!)RqV$Xk81zC8La+sP zu7pfY7B~tp>>Nr1g5840=rAZmOnEwmau~tN!LLR!+(_tRp$EyOnB7anRHak=V=8<2 z{)chwE`PMJ#)EXYT&NomjdRE%JP;hu#TyB^QbG&fxR3>oP;k)sn_wD!@kS_CHc8Py zm`id+2@!V2Re9VHKbVKw&v$a`5y-pd(~unNV5Osu%n0*0Lsa5-49 zeklbzfn-z6#QNM^iUgu43rlk;(ZyT}WqT#ads#`|FS9^tD}uB|K{?9M)}6>l?>Bi` z&;}As9)8%;X#p}zPl^HA7yD=d!(JeQt{<4g@d=a2p^6Fn+Ts-Ck0RC_Tu6 z<^wRi@DX3Sgh#{-KzR2^FtGua83BFF;koo+y!ExX*L82d-F>&Q34&(i6rm#7W!{cf z7+n<;>8wEE2KJWVWWa)ht5gW5kigl9*a^xK(_&Rk-78C=Oc1NEW8jKB!j;^U5=h8h z^1C+sZI)2@CwCTF7Q-v78WKf zeeCa&$AFWZ%WL{WDg-PK3aPSDHx$HFuYW~VFMlJ5TkYryd_R&Dwf4R*qwVHg4ka4f z>(6+5Gru>a0w*3~!S7aUhF+|leU|(dBl3@KwfU^i_NeOdXUs^7$-~&WA=V5iF#nZ> z7cXbe+))gMpubp)pe<=f%qt8FwXzkKN>&R~g7o1bV1or955cklHxgXVXcR??QzODq zVZU%fZq@>yl8~GGlMmDpX5u0s3vd*YR2C+IUjD{mB$cg{ib4H`glsqoE#U*cg%iQ> z)62hbxxaA~$}b$)s-JvZiZdudkyap75dj~s3|FJaWNp(M?VmKtC+Iv&TQ_YDC&JU<4KE;Nr}{femYd#X z7!5s>D=eWXO8zIHtq`;rf|}&v>YYf3jQa|X2b&a~Ks5~7b*NqusyC3`vc=-yvEr&b zozLINECEHz&n71)Cxt*9LUMA_zZ*HD)eA()-;D&Xms3BySZ~E@W6agE)2E6H&Iw%p z$Brke#6^Brwuq)=jiECmHpG5sShV}SmDTg@F*~kO_9z*MXDHbdOBk)HN$XMywj>$e z8Ix%=u{&A%_$@m522aIL%KEjXEz0sh&<9+*_7xd!lu~++pyNy6W{N)v3j;C#RyK3*#PV@Mn`x*BIOw zczt^S-6^)7imZ%?OtDOiryzBTwmnm6I@5Ssr*{9)L1DYY3Og>w-TL2kB0{X)lED{j zS;mgB_kTT6`g?tOSWS$ZNyDDc9IN;5wUbVJ2n!U^J)Ek|GfEq~(sER{ddXy{OfEhC z;$_J2=l&Y+8FBkvorqy;rVO+%;0;-^u&B03d#ic-hwVBScqgMchO!8ck?ac}JNE<* zpN)Q}wPRMkyeIo`$mtKS+A6f{qSeU>Xj!KVqrL52>Yp0Z9`h@<4K1Gel=w+O!+H6# zf;D_m9u9phFA%o&lpZGHyiAi@`+4YS?HRjiJ2loTtAhC(_HW*7S1NB$2|V>lb?uP< zUp>3`M>SC&eG9xScRsCqm-U}+FlWBXcG-RXW2vf|&*TNQS;w};WD;U5EyDH$mWosn zJL5ug83*s}jiKLO_Wt(ctCx7xHJy)L39z!UKPYSL94_wwKVTQC&K}x0#>-E9y|>D2 z)XgC9tCzv0H+QMy=FMZ4hUb#6bn>lFxegsuyS9x-4R~4SSBY~ibEzoILR@B-EvZ}Q z`_{qEO2)u_&A`X}z{jaiY9dD>)*BE@9+af(Df|I_?;AUyX7Nn^U)gKMT+h-sDnOHg zCu&+bMY2xQ^G8uzKd8Mnjy6BKR8&^ywrQ}Ns#D0Ad0JwAz|v?D%xoXM>{$OsyhGHA zl9!XM>wFS;n@yZ&m#I$)`h&+0g%x}HM)CTay8>Ugp8IHySPM$zr((lYn8`EQ4HpY? zVqUjo`K>flQJoAv_33KG&JT0zzr9p+)M?223p@pVC(87eXL#U=3e9n_9uMG z4L!~{M;|p~^sVoFyT<9_^25`*iJdsLiSDGXr`zo`AHKS5({gr)>b>Me(09?;fyKyr zW%4bCRlNNc#DGnG$pNJKDkf)Z{hi#7i8Td3rdPiEw3$_5`A5WM-7`OIx!>DQw&?Qo zCs%w!2i~S+vO=^(N-0k+EgP>c!=x|uxhB}Ee4?X4z0PPk?fsomO~o4>Uuf+`C%NC$ zmTC9D$Sc^`axal@eI_96(ji35GIKTJ$B%o~y&iH~{HNm4?EbsuIG2EFt}tZ(^~@)! zyC1z+MbUPZ7mOwh&W#)!fU3(J~woWJ6o$z2QB(D0jEhzukiJ6ph1@UdkteB5C z*3ot)9ekEmBHuH66bK3;(9`tH7R+~OgpFj0+6WjDtzxc=|L5VzG$vgV% zhyL!X&(%_MOX4r`gEPl%wg)?eAAhJ-I@=CQB&)QSwG=mhmEQrSj;H^4cC1%tpgnGVkN136cguCT)b9`eEZggs sG^Fu{Z~CfbeOs4H(EH?vS2eGSBlf*CFPu8DOD8|uIqzom3gM#v09j+J5&!@I literal 0 HcmV?d00001 diff --git a/client/data/sounds/cow_hurt1.ogg b/client/data/sounds/cow_hurt1.ogg new file mode 100644 index 0000000000000000000000000000000000000000..41c0e7c83b2c327d2d130644a366f309f05b3f33 GIT binary patch literal 6850 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 GWBorEPMQb+ literal 0 HcmV?d00001 diff --git a/client/data/sounds/cow_hurt2.ogg b/client/data/sounds/cow_hurt2.ogg new file mode 100644 index 0000000000000000000000000000000000000000..50fea21bf1b406913d2a875e46c0448a535a73dd GIT binary patch literal 6752 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 literal 0 HcmV?d00001 diff --git a/client/data/sounds/cow_say1.ogg b/client/data/sounds/cow_say1.ogg new file mode 100644 index 0000000000000000000000000000000000000000..017067dbeed1e947effb7d58d9fcae3e29629a9e GIT binary patch literal 13865 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 literal 0 HcmV?d00001 diff --git a/client/data/sounds/cow_say2.ogg b/client/data/sounds/cow_say2.ogg new file mode 100644 index 0000000000000000000000000000000000000000..4d7dda346ae0b55417a3e547f97db33ea43f8a8a GIT binary patch literal 13945 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 LM5ABS{>c9i+o30a literal 0 HcmV?d00001 diff --git a/client/data/sounds/cow_say3.ogg b/client/data/sounds/cow_say3.ogg new file mode 100644 index 0000000000000000000000000000000000000000..a1dd244956a88d29521f336d10279798da5a93ea GIT binary patch literal 17586 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 literal 0 HcmV?d00001 diff --git a/client/data/sounds/cow_say4.ogg b/client/data/sounds/cow_say4.ogg new file mode 100644 index 0000000000000000000000000000000000000000..6cd878d9e978f9381485600c05146adb30d7a59a GIT binary patch literal 12626 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 literal 0 HcmV?d00001 diff --git a/client/data/sounds/cut.ogg b/client/data/sounds/cut.ogg new file mode 100644 index 0000000000000000000000000000000000000000..5643843a92fe9f0eb0d6d54245bc2550b4e69794 GIT binary patch literal 7153 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 Uu+;D2HkT%jbd#rGK#&^nf1DGFa{vGU literal 0 HcmV?d00001 diff --git a/client/data/sounds/door_close.ogg b/client/data/sounds/door_close.ogg new file mode 100644 index 0000000000000000000000000000000000000000..5888d1a30e45eb793c2962d5a2c4c0ccb65d7f12 GIT binary patch literal 6766 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 E0Q5W<^8f$< literal 0 HcmV?d00001 diff --git a/client/data/sounds/dragon_growl2.ogg b/client/data/sounds/dragon_growl2.ogg new file mode 100644 index 0000000000000000000000000000000000000000..4a8efcffb4da4f7f2714ae719493d9012ee6d8a1 GIT binary patch literal 27766 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 literal 0 HcmV?d00001 diff --git a/client/data/sounds/dragon_growl3.ogg b/client/data/sounds/dragon_growl3.ogg new file mode 100644 index 0000000000000000000000000000000000000000..d3ad63d620b4658f353aa77fef2e60269c1fbc09 GIT binary patch literal 28022 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 literal 0 HcmV?d00001 diff --git a/client/data/sounds/dragon_growl4.ogg b/client/data/sounds/dragon_growl4.ogg new file mode 100644 index 0000000000000000000000000000000000000000..f50567c52f5e808be83a5dbcd48986d448f7dbb2 GIT binary patch literal 26210 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 AH~;_u literal 0 HcmV?d00001 diff --git a/client/data/sounds/dragon_wings2.ogg b/client/data/sounds/dragon_wings2.ogg new file mode 100644 index 0000000000000000000000000000000000000000..3ab732af5dd2dbe6efd9fd063a6869a1a48045c1 GIT binary patch literal 10591 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

T^glKIrp+&%5#V?DpxkLH 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 KZ*YS*+W!LreasX9 literal 0 HcmV?d00001 diff --git a/client/data/sounds/dragon_wings6.ogg b/client/data/sounds/dragon_wings6.ogg new file mode 100644 index 0000000000000000000000000000000000000000..1af680b3d4dc300dc7035881297c80d9aaa69cd5 GIT binary patch literal 11352 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 Dp+*dh literal 0 HcmV?d00001 diff --git a/client/data/sounds/drink.ogg b/client/data/sounds/drink.ogg new file mode 100644 index 0000000000000000000000000000000000000000..b5c73529c5c2ce43df10088def2dd867bd525b16 GIT binary patch literal 8085 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 literal 0 HcmV?d00001 diff --git a/client/data/sounds/eat2.ogg b/client/data/sounds/eat2.ogg new file mode 100644 index 0000000000000000000000000000000000000000..7215480bc05465e25c77476b3b70736150da4414 GIT binary patch literal 5992 zcmahsc|4Tc`|rq_rAf##6)`cEGL|x}_GM7a7|ghGEh7?@X_Sh@SVCeN+cXN-h_a3B zQ7SuG8%s!~Ea_4yL|4Bv)4lim{r>ekpYxvgd7t&1=RD6j&wK2|2|OeK{oQm{W-su- zqork&u%v|6Kz+#*_TF@g#W^8@hjokfQKC9ecFc{dk$pnZe5NmQlh8Axk zszO5^a-~P99|BMu2H^a8IJoIQg9XM9P)$U)(I$0`B%vX2t&yV%8fqj)zSC`c5hZRK$BeQuTv4Q*Fu5T2%Z8eX zb#j!jNt-;)(ge&v7*iud>oh4)q-kPAchHm#d}N_y2+GdYh|ks72v;oM2(>{F+}Kg3 z^(>-21<}qyh>J=Rg}^>QqJYmjKF>Pooi$yJNJsMf)U|uso#p(l#}~JTAO}YYi?cE! zd^sNo63sS>XS>F;{o<$Nl0<1SMFLO+1PKB&24?t!Rt)nVC&Exw;OKvKw=}W>UmW-l z-tX^QC>*D|K|z?m4`3P*o8xtxBK~o5ggjO%SF9K_!J5n_N-?n<%r=&FWhnhtd@W|0 zMd@yzVxhYMl*=MYFah5*t0|kf@fW1d3GHQS@^ELnXMbmHZUNA);?QK~^-2H<75gVK zZ8-q4t_{WAvgP3@JXQSRL-Q+(y3tl!5O}g%x~~9eJ9);!t;4!5cLTez{Ybw>1!S>;wCS)wk%gFe*8cCBzbTu0~ z(w}}JG_4?$Ih%P~^B$iCg7a8-Ek6H3eBp)of(uDAadf}Tw1PsWR!9EFx{|s7uZ!~o zTn&QGsaXZ9S>ee1RUye?$@F5_Xa?aM0=S` zXCJ~|8p*}!5b!!&oCOz8`2U*yfPwuM;8-zU!uFCVUB&51CNo9pZ5nymLq{=Fc|%5ahc=UFNi(4_gn-ioAxDr`=r(i{BDmY;gPKJ*Mspjx1!GnC#|uX+C!cfx z%dTEQ zWA3uNyD=JBj1G)?)=g;?8+@XsS&VL*Db~$?8x0U2jWF<-Y8d!fKyY>F^%;cyO#^!w zr2Q6)V>0eTTP(P#2G0!)9i0gFGWJ|20#VMMkcPC^x3`xe;I~*1WC{2*dqO3-#~^UT zi7+ll;8u~{mcm@psN?$fBfL*QrGiiQs=)E|e^n8NoCu?P0oBm)oVz1|Oaz)k+=)X3 zm%%WgnTxj{ktGn)2qRoFA&u&Bjxg@*J~Big4u*{mMtcl~JuSFb7t~Qwa=*N2t$g=d z-Jf#|n*lrCgt+F81bdgtKs+_jZHvW_EPp=9x?-yPqe! zR0EMfLP*%eId}JTs=KSN+j8^(mFk{Ko^T-(m&xv}gVc#-yMZeEAue@*K%E$*zRwIC zT>)ZLLRz#3;2Vm56B;zW^|m8{I?izS0AgE%JodeO6m+mO(0lZ7d8w*|)uS?P_tCv| zkL)w3<1}Xnggjwr8Mr)# zo0jFd9LAm(PbE}EgBeU`1iHJ1PtN>!q<4<$24p#1k4g?cJbNzYFvxjf1Oy4#X>5p& zDH4U=3PSQUmYJPNoJn0te&SvllT^P-*C~$;=gN~$) zYIen_BcqbAA}VY;)(***H`C;#GQ0p`m~^VPIfJ6XZl+^TA=$2Oc9<%8N)pewI^Q_E z5{C;&rQm=nvJ_SmsKR2=U{*ktlqnXd!eha#ytGhUSL{g+P-TlAbigG5f-M#eR0VO~ z51RPtt8Oybbf zc?P2BDHbChJ*}LFLr)=SIK63Q1|7$Pa2wfqbX-6V1BW|V4Dw!pm-k8rNI4OZwn!*> zBlPXUis~ls%;jMM-S)+}4N=FJqdhVEtApn17S^7AKF|t5 zp9DpqYyl-_DLwN zu9WVE{e#bg3{ zc`WJ^C@_CZ#7u9eeR?9|2|?$hHbCZ)*Y%6kvSgElxAImiDh4UTy}$;uKpui+18xMk zoHdX*K2FM16zTI1j?GB?#V5vQ(EsKGb%fq@Hjo849F{LD%7bSA#i4kWEuV@){tK~b zaI6N85BL^t3WmSE{11-)FAj(M2M4z5Z$1Xj29%%(BM_?cCh7_VInO`Dwr-E$$FDI2 z$uv3RuVtBZp-&X5h@uM$O|hsLv{{F8J_^54C0d0NuOg7s>}=Z%E_S#eBnn)hYwV!A z0g{k{9~LoDH$GDVs#{Z^7;6JK>U z1Zq?fFgG`dP08Ur>3j1TCJl;|znh?-ARhv82nh=E|84{)z*>2Y_jkj?cO)8am)WIO zxlL8IqO`Q6^8Wq%5APRc+=fYTQ7JciZr>=HExYk5yl+qJ&nJk`{K4C^C8vZcJ{Q@o zw1-SwgnkU7*b{!=toLfX^41qI?5fW=((=If+r-y=zuhW$t25;Zj*#9o0@pH}R%3iC z=JEQI@ncs${pt2|rr4~Zea>8*P7E zm-i=+#Dj_AMWa>iT$u?iTCM?cG@Rn{SWK?zP_g~i(!8~$+TZ#gO=;xQ|9UHA?z!;k z*6^OYR^|RhCk`K4Y?IWdJaF9BVS9i1dwI3hT>N!mZSNlDrnN^~CmV6Za_xpM^^LJN z-xS5(zm{J8Qf#Pg-_&lwi-pfK(qy8Wn-ra)2+!zDVJ~01j$C-+Guv`g>%^L$i=XOT z)MA3p9}X%csP}YT&R^268!tf)yz*%9Q-6^8WtlowVl~%TI&b&0=I3}k>`&FZN~;2| z6-o-MKG$czu``)1DqPUCZ*RV&`p4UxGeT9GvR$X*tDjQ3MLj5yWTWa^NqX0^#99@_ zy=50YU+;?73?7%oJFy9-e!Eb?Crk>Y-tKQnL?1mIy=OEW{fW$QgP?UL^5Tsc@4hlk zazLwpgV%x9H*G2QyB=sjYZ7(Ci@z(>FAY+@#$M3&2%Yh92wU4>bNuL6^)skv*!@Pkeb>5UQh$NwzicK6==QTJP_ zhx96Z^`u^_esIE}vx&az3z~fkzDu_il%~tPr?qQVE+5wIo2y}E*cVwz!LhAEUygl= zbG`MxWQo>NcC7fkO+_B1$_iPB@xDb)^s6tb?ATWt*WF@T5P_n(T5jh))qnEp;^Ys3 zBYu<(eK{v8IJ5DW#!i#BN)yLICl1P0rTA1pEAr4i*sF`p1k0B@f7@?Yh6&c&N0f?3^xn+)EqF@-!c`q z@6HEv?D0+Lh2L-FS|3cDyKRM38z^P%9oo7(CbigY)PLfAy7=XHFH7U}TE_zggeB@9 znIoZBOeC`hZttnvQ-<#T?La(Be=oV`oF05*;=_v1)f2&q;f$aC@!zXQw&YabYMxiP zjUmm5H$<90Fmm+VB}aOow&&#gVuRI!^HbKV^p4M0&xDy97F>^7SttHbovfjG7_qYl zcVLuee!dhTroVMc|!BsmCeF$Ui$pCHcQ#Lreyr4vcXW+zwS62 zK_`bu3a@|9wtTyE_Dhu28U= z^MxJKCkrZE?RP5<=$cF^(!chl{@bFkMZ<5;9*)}$IMiwc&gc2oHV9XoG3BKgpOuK>N?mnoqyqpMol{`P`dM!5R?tL+{w z5~CRxgRRGwF76&ArX0C@&Df+M^ybJBU(Ll+G_x-2_iMWgR7#{Vi z)?@zBy{9A-T5_zcts{Fg6Bb^sKk7YjCZjZ8Lbs4Xz6k|>C!3Jqhp$V)=bSW>Kr5;=7b$vOTZ zpO(F>W&Cw(`LsI6H8cE65_;3z{Y^XDakcl45M4VP1Z+Om-V!G741Qd(`AQoLDIThu zblU5}?!XU6#-%slh8IJ*r~oU`#kEl@N59At$*UAQD14@CQa;eu+v{p^^$lFtwvk(U zh^hq39OLHE>EIR5@JE!4&(n_|U&0*eAU}|QF4=XiE^{$mwsNESV07S@(rUUaprdbBxc5;3WOJ2Y0zgs?6lflUzK`P_>(sJL)NDz#6MV?D&E z&DDO~2PZb@Vd+`@L8`sq-cId*9MU~mVD{Lwuu}5CY4zwTGym&-vm=|;tG->_eIY=w z@Q*+Ia_iij--WFS>kI@wtG^n&qse?sG(0=!#>c%-_)ymyMa{-00k^rcM!iamF27s} zpNLy6U(;z9RvX?&}JCJ(hNY<|lS2 ztZX>FFd``QOvkzZ9m0IV{3UnYQpBQfKAzz1M-uB8{VVpy*n#|lYgghh3WLt&?p23h zc;9=4*J8Q-s4(B`ZZHCZ=d(7or5!WudUUnC|>O0}};SR_CG-a@UeADT@q5C@y8jM{^ zpSJ2v8#%@JF?GrXX78bQ$)AYc@B4UDwBb&w>sCv}uerKUm|`Dq^hcLGC|`D7RY%|} z?gUXkew*f9$E>oqN3}L?mi0QpG~U5#0-a$iAE(Jt|hOtNv^Yv|h@>YQU5xLl}b!mJm`HJ2C-wEed3Z~XPWH|25)fI6olWSKdkxez!r6WsaB*S zC047e7cSN<7v($WYi%mMap?TEi1O71C0WmVg~Ojmw8-wq4W<<{QYG&sFYSSL1ai+=nr(2`| literal 0 HcmV?d00001 diff --git a/client/data/sounds/eat3.ogg b/client/data/sounds/eat3.ogg new file mode 100644 index 0000000000000000000000000000000000000000..35a31799cb1a004c5a3678a884b294edb3e85c74 GIT binary patch literal 6104 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 literal 0 HcmV?d00001 diff --git a/client/data/sounds/explode2.ogg b/client/data/sounds/explode2.ogg new file mode 100644 index 0000000000000000000000000000000000000000..1a776b54479881321881f64303891ab4e1ecddcb GIT binary patch literal 27903 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

O76-sM6-vx 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 literal 0 HcmV?d00001 diff --git a/client/data/sounds/wood4.ogg b/client/data/sounds/wood4.ogg new file mode 100644 index 0000000000000000000000000000000000000000..c493c9ebe585723357790777e18bfbfa4812247d GIT binary patch literal 7292 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 AO8@`> literal 0 HcmV?d00001 diff --git a/client/data/textures/armor/ardite_layer_2.png b/client/data/textures/armor/ardite_layer_2.png new file mode 100755 index 0000000000000000000000000000000000000000..d42e019a3c7ec0ededc018a6f619f5c83578aeab GIT binary patch literal 2720 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 BuQUJv literal 0 HcmV?d00001 diff --git a/client/data/textures/armor/chain_layer_2.png b/client/data/textures/armor/chain_layer_2.png new file mode 100755 index 0000000000000000000000000000000000000000..117811cd657f692676ac0ab489a74b539ac10bb1 GIT binary patch literal 486 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 literal 0 HcmV?d00001 diff --git a/client/data/textures/armor/cloth_layer_2.png b/client/data/textures/armor/cloth_layer_2.png new file mode 100755 index 0000000000000000000000000000000000000000..8d8bba6ccee7b494f672e1ac626c9098fcf52bf0 GIT binary patch literal 868 zcmV-q1DpJbP)+kP?@p$|$gdj;0y4@~i zS>kyfN-2yn05na5QVJn{HB21GBuRqSn$y$Mjdp~SrYZe?AJ6m1vJA&@*xlWw+wGEN z8O9if!y)teoag6fgb?)meVV3WHk)m}1FEXB@@tyLo=Yil90%X`ky6s@^?uzT#BayO zJD{#>JkPV@12D!=*EK~^0MP68Y#2%@T-UW>YH03IJ70hrBZ+}_@9egLlP+5m(QXsuC7StsOqj#3Jx z6qCt>D2k}-8Yv|^J3CxnUcPIs>2|x^-``V~B}tOd>2$0klu~$}$IHtLaU2tdA$46- zRTWVb+41@i>uR+^YmG66v$L}=U9-+)GC?UtRaH2S!_(6fT5Fo7A&Me|5L{hdk)|n0 zk|3qz_4SpyuJL`Js;W3XK1ORzQ51w>$Y?aO571iMV7Irosj7<6XvBOz=kD$fV+=<} zN58$)$0%l5_Vpcbet!Os5+0Ao?|GghrNkIx#kgE9S+Cb@ZEgLrF_z0E#u$pCV7*=g zP?jY^2)kjLrm;N|EO|aU5Hxd~BBwzc`LVnx^dS?a?$1 zT5G~E#291!MjxPNzsIIXpZBAPmDV58y9*rDF+&a3XL30000 literal 0 HcmV?d00001 diff --git a/client/data/textures/armor/cloth_layer_2_overlay.png b/client/data/textures/armor/cloth_layer_2_overlay.png new file mode 100755 index 0000000000000000000000000000000000000000..006f553a9e57f049f907cae0348d1d25548415e2 GIT binary patch literal 6505 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 literal 0 HcmV?d00001 diff --git a/client/data/textures/armor/diamond_layer_1.png b/client/data/textures/armor/diamond_layer_1.png new file mode 100755 index 0000000000000000000000000000000000000000..14fecf2113d32da96d4c6952447d59f7bdce2c32 GIT binary patch literal 1906 zcmV-&2aWiNP)b=x3$8$E z`jQ78`@dCDq&`-aA~lsNM2Qp?(niJ?N`Ts+1P9#MU}Jkcb7szM?>_8dNJFVB5o1C3 z+ZpY1`PN?FWvvnHuxitnY`(RHf8YT5))p!(p(+*f?K&94ji3EW@ER|@-#~));J_Ve=drMfm%E^yUK)ynP52Mc6dOS_?sduJj;$pEqIc2!Lrev3ZV3 zQ><}0FSJHVi9bC2<^xbP8Z_qT+=Y~+t1IZAwZ}-$bHUe_5L$zg z-I|iEt?fMkCQUd~U!tgQq5JxY7Z)g+O>}QBs$3@9*yz&KT5C@({H;6w)@CkSTNKp3 z_!BnIQBfKH;6Ya|I$c62&BT*?*t|gcz5_u@yeL9ft9uWCDwk<3E;!2Hxx?-EfBnLo z9KU@P={;+IH%|WYxxL3{uUHZI2q}?4fGu)NJ8@uCDqu_(92o?AUj%pi1-0o*79c!) z7>vQB88**Izx@`W)Sio}SN8JbvsbK)B7~Hfq|MyeFJ5aE`NpgrPvO+koHcPw(P+55 z-($*--??T@lAxk8vRr2R;OI+zkKAz*tk<3T3qzi^%)MOg2M?I5oks*djT>{jKMMPA zy+!tT4R7BNCXV+U02zi%tSzD{6;!2X_W@|%zfaLT@cR2nmX{Hphboo! zz6*^1F2t_@%c}! z4BW_^t*zk=3}D)AWEdiY(9IV~f@!xAp69elPY=4cmvm*tIakK)*lpy?0+2mf=lbDO z_y-QSvDg^qYUdgK>|^`gU@D_ysHlwY>t}X!3f0p~zFntix0oHBqBe8cj(+yB9lQDm zTbsUQ=W6FMtu{hwZcbh7-eb~~>qkyA^X?=z%do~UKmHzbweuto9}+JtFgrTM?9sEB zH2vW$u@@rfd7P;)J)=~oP~M!n$mpMcXLWx+bG7sQJXxWLo0z1{WZyDEDOXs9JA?W0 z_c&8uLPZf*^*-l8T0_3M;j~8M0W$EhnVTYyUHilZP_6P|yv~OvMpvr{rT9&<#Yb5k zq14NFfgN+G6R^-4;dx!7bYg9h^4KvK*yh(1+jVS~IV}JPArMLAM&<6wAtf>_fpkhxJ_SKatdvZ~%kF-_rb%~yys&^Qm0V5(GAv=* z?)k|#OGwYBh?_KT-NK}at3Oh*eSNy?Uhh5tQAE*bbUq+KmP*bttyr0is=ts;PuJHFRV2NTjX6j+ahh;wGO*2bqkQT@mWI$wF&n5ID*kgYK=OdwMD2 z*!hj$XMi7cr_WuTD^QY|pH5IdI^s?sOPM`-mh#9b!uQD@J!0;}1%w}vEH9(N5_2am z&~x%6-r!)D0eOAvKQcggUgu;T18nC0T*>QOd6-DSu#Q{_4alch6yYB}i z%gam-AHb$5McgD^S>eo~B~+#2>~F0({m)ydO2q~2`J6NB&KM0tOdQj$*RffSH!z3@ ze3#==BEFM{))@SueV8nz@%I}DA-mR_&>EZP{%NQ_*yk36=hDfP|O`VZxvkZTD zm~3?wZ~uORw|`8&v57x4)MDEEOyyG_2m&CSUVp3Akd&;MvEW5=FZ>uEy!tFK-t zq)y!Wi+yUi3MnzIHYRDm62nx>Fhq7n%IN3_$u~<}KXRJ0=_-wTcPSnI3D#PQW`p$6 zYDXBA(0zS8b(6opZcct6j?Z4PCQVS~GQ#u!tBRZ(Ik#sDQ`Dv}*`n1#Na^}!r(gkH s`y1nix}x1eR~_|>?QMiouf4JHFZuj~E`Od`lK=n!07*qoM6N<$g17&sb^rhX literal 0 HcmV?d00001 diff --git a/client/data/textures/armor/diamond_layer_2.png b/client/data/textures/armor/diamond_layer_2.png new file mode 100755 index 0000000000000000000000000000000000000000..2cca05667ced578ee5fa9407d345adfae9068ef8 GIT binary patch literal 687 zcmV;g0#N;lP)pHQAtEWRA@u(mwPKkK@`P(9PjJR#b;Gg zk`zhuE^m@o$SZI1CP|UB&2M!!@~_++cc!L0bI#0d*4k^YJ*S``w#YzaATkgchzvvq zA_I|u$UtNuG7uSv3`7R@nA!h5`d+?PUvD)5Wc6Cg>490w$lX08Z-nG<~s4>C%|y7Ugx{sjS)JEBQc z0Yqm^q)SFR<@yd71^Arz#RKi>R{)^=;-lK1R0RMM@xq=Kl}9@Bj}%F&0G@$zs1lG< z)YqzCR}<^Yrg~+dMg46WQ*D%9!C%~XIS2O-{>RUe6OZvbfE+#?jHq%bcYMGU4|RMV zG?2t$t2U=a7VAE)&dI$&50d5;1r?z#K+#Am#=igi9yjGb?=eIXbpQx3{w)Dup5ZU@ znBXf;fT~PT5Ge-XG)$NE?mz6wi2{Dguu>*~anEo<@D)!juQF0ia<6E9yOGo(#XZQ& zG5_UN=%?rV_5GxfM-DK4ks^|$5}+xefJ7l$AEL`MavlQNkBa06VXli;=(+e7c?bJZ VF64Q<>O}wm002ovPDHLkV1l##F=7A! literal 0 HcmV?d00001 diff --git a/client/data/textures/armor/gold_layer_1.png b/client/data/textures/armor/gold_layer_1.png new file mode 100755 index 0000000000000000000000000000000000000000..6802e06f2714214603c84b65ec5ae8848f19c2fa GIT binary patch literal 1161 zcmV;41a|w0P)#)v9<7-mazHXYKUs zQzz}eUQLJZ*V6IVZaR3kmKdvAzwqM_TYj!Cw$jDvX1W?}35lNP$}Xrf+GCp!FUJprH!%o$jpPe-*&e!)diJdg%TBs}+3@Ual-Y0DI5d2|cIb z=Z9aqa&Hg|p|s)WjtD;b*eQO;*wKd~9-z;SwfrV#7`#|XKc2MpW)J$=m$%QG3jiVP z`svHc+ucE=$LYuLVg1hs;RV7NnlP{TI@<^UD#sC8AM4l)RRXA)yGgjhGaiSZkA{)6 zwTDyYC~x;${2dLl9=l+|`3X>9 z2U2pW(U>!H0P4Pg!9@zN9{_Q>y)MaFia5dmBN?cVJxATZ|KI%S zsMB51`Okf1Bnf&Q|Ifck2zuN?pg;xIVJ z0HR#MLFC}7^-($wOuF literal 0 HcmV?d00001 diff --git a/client/data/textures/armor/gold_layer_2.png b/client/data/textures/armor/gold_layer_2.png new file mode 100755 index 0000000000000000000000000000000000000000..a7cf8351544f9952e0348c0fa576b15535ff848e GIT binary patch literal 671 zcmV;Q0$}}#P)pHK}keGRA@u(m-|XWK@i4$jZ%+y-~SPU zh@yz1h$4z23e8Junr2?6{f&-9|4P#F%);W%IkU3gH#6VtNu_)^1I~am;0!ne&VV!E z3^)VMfHU9>I0Mc=;u+}OM$&)G%g0MWM$Mumj*$2JoG@mSia%j`L`W~6nNk=|WSKHJ4b{XZ|jcW)vsgU)rNKJAOFPJGb^bRzZy0cPAS z$z)hou-L54?p#GO8I)yMF9>VMz<=B+sU3R)00E%cxT4^QJnQ+iqHDE-AY$W7R($mX z0bvjRu_u6(Cfa}|`T)iTpq59NL>th&f4j`ebX3*}8L=k-ASk{?98j9#VFH%ghY;SQ z4b(nlkrn7g>gib8!FQf9xC^(HOe}a6k@5R5_F>K42P0i)Vo4a2&S(kW;eov#Yb+ z8}z|)SVtj?$S!;sloe~+|9g*#^1s&@qDXcC2r%|70brh~zJ!Uc7y;U4LIzP{5Y9k! z@i+Zp&qgv}U52$}0vOW_BLrQs(y}f?)~xOo^QvZ(YR*!FtR3@T)`iwR-=FWNge-D^ zv5ORuq-+393k4(@qHQ%qmuJ*G1hStj!XH}+33C(QBHxMOOpWs%NJIbt002ovPDHLk FV1oSeC7}QS literal 0 HcmV?d00001 diff --git a/client/data/textures/armor/horse_armor_diamond.png b/client/data/textures/armor/horse_armor_diamond.png new file mode 100755 index 0000000000000000000000000000000000000000..39068f255aea67514773ceb5e588a8184c46e30b GIT binary patch literal 5177 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 literal 0 HcmV?d00001 diff --git a/client/data/textures/armor/horse_armor_gold.png b/client/data/textures/armor/horse_armor_gold.png new file mode 100755 index 0000000000000000000000000000000000000000..4a0786de0931d27895331cb49bbd0274d8e3b529 GIT binary patch literal 5140 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 K6)WT|!~O@cjn_*6 literal 0 HcmV?d00001 diff --git a/client/data/textures/armor/horse_armor_iron.png b/client/data/textures/armor/horse_armor_iron.png new file mode 100755 index 0000000000000000000000000000000000000000..533b2dd9966fb6b4285844061552ee16804e6f4b GIT binary patch literal 5064 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 bzoUv&XXBb~OU}ZUM!*XdP30;@i?{y+p%jf~ literal 0 HcmV?d00001 diff --git a/client/data/textures/armor/iron_layer_1.png b/client/data/textures/armor/iron_layer_1.png new file mode 100755 index 0000000000000000000000000000000000000000..6da6e8408d3f28dfe3a261e2011b902ae8854ac3 GIT binary patch literal 1096 zcmV-O1h@N%P)PbXFRA@u(*@sRmF%Sh%{{M%N=r#0C zLT>`T!%xT3MJvQhgv4$Vf+Z`v>o#-e&Uoz1&5bBqTU%v$dAaQE?Ujv}lmY?Z{r$b%-{02?fU~o+%7Rhjr@lP^ zu=vf*O;!Hl;-Xw$UY3Q0h2Iar=H}*y;#XH!rQh#Y>kkHl*@yv@eSCZ@d>;!`&%Vt} z5RBhrfXWqoJ3T%9{VpKVv$QJc@%#1l_4>ZHwl@6$tgNgQey-Z*4-O9M_C{HXs{8x< zRpH&;-TJI;XJ@D81HPpi>sijQy1H5x7Z>ZVIea&-->f$g08%W4UyJhD?kJgd-vvI= z|NQ*C2E!_ zLV}}b%3@RiG&YKBvz21U*a4s<;RG}SQVKO$pVCd5QWVW2w7#J;HUN`iY5?$!)$`37 zDzL0Eb^s`uAh)!%G*lpzMd@KeQ&_*m3Uk{^)g)4sSM?b?0Bs8paIrxA0L013NoCGV z(29Whjv0lb!P2*EKxw0cf?g>2SY(WUO$q|^sNv~yu-dVTV-#iXf%JcJc z9m~Rs^!fPsxLP*=hCOM|{LS~)89<0!k`N#YqoVv@$te;*sGEaR+(sVJC za)X0%tQvo$EQ##IBg%pHD@jB_RA@u(*XeFzF$@LZzW)m$ma^|_ z5tNo)JV{1hG_FSTw;D8*M6yWkbx_W+eVqI9Qbu8*Fi;pM3={?m1BHRYKw+RTP#7o- z6b1?dPtU+;G)lACEG?JIv|g{%(-AV6Op7ndpU;zQ z`0)g^TCLP>x6^n$PMggp*Z*R%$l!;=VJ?HgV32*f-EKC%^np%1JVC&`zrUx?&(93j z+C0|%em{MDe5ALxw`7hC{@d*~uOFTOAOJcX4jG)to1adnJZA*any;+b?RI$&|A!|) zN{cqoq7Se&fXai3HqhSpdcCyY@3SG};Ryiba=Cm(94O!!uxcM6GJrOyePqcBdhzfC z0IbG=l+xBn`ExD$1P>X_W;4G-+K(VWyAw@O1&Eo8^y}+uR(*io3uHj7y|35nkDmcR ziRSHg%e_Ck0)Qf3sZ?@%WY$q4(FJIR%+V!~Q>|9>Z)6kyPN$Ovv{tL-xo)Gp=t~H% zbGU!_pE$=|G$!r<4(MQ_>QJHhz%&|-uY)?A!%nBuOcuYmI>)^sKlnYOqsSuJ#m7)q z=CS|pJt4~fy~c>5>;MRu_?7_JGy1~lN)X_k3{qkUH;69(&>ws5k^$dkSQY>inh}K1 zmH4KJE+cE=UU5F3bE+dHG$`7!|B5d3-ShqP{Yoez2TWX~L{cdMt%U+9L->oXXKEgS j_RAvv)_mDLzD0fksv*FCYGN$y00000NkvXXu0mjf%aJI` literal 0 HcmV?d00001 diff --git a/client/data/textures/armor/leather_layer_1.png b/client/data/textures/armor/leather_layer_1.png new file mode 100755 index 0000000000000000000000000000000000000000..39d58bc9688654e56c961573315d8622afef20d1 GIT binary patch literal 9191 zcmeHLc|4SB`yY{AB9%%SYs8o_GlsDxjS<eFJC)JWy^~dM$chE!EeAQ+jOlrTf7!{uNJ$_-vH*sN>W#;I} zO&?y1NA%lk7jA2s2Y)2qvQKdkuoh~Y&(l1EzX$zl@ApL>+LMxee4=fIpurlu+}5k> zJ2v;ZVzGHm@9B`xSg2Ue#K=SY!l$V#=`Y{B#gA>rm)&HR)1S89PXX^4emk*JDX}nv zm|7@@?v(YF<-E3dkjDE7efq+I70>Z%pJZn93{BwS7ayMchg*$l2-2w>#J?L6$h;*?g!^&jS$>~po{yF-719Jrvf^(lZ1x~zanTFoqT6*FuiAZlj^@^ zD$y2}KGxRM?suRC8>fkqUYXs(0gpX zrzxQ1tCudTGonp(>4+AU_K>)YR`{fIGxSzTN7VJ$yrTDx`|eKP>x@Y(pDCK8&SoWM zRSr9Tv46Wt@A_u0#64#8Oi;Nx>k+xDXZz47CWmApFKPU+>k#NxK-bhE&GfU^=_iV_ z*{#Gb$~+8X?avh6Y0%8kyJ}N)=K69fb=%NdxjRoXfT>*5eVcH7=4R81bvZ2y)lb&F z!_RrM{dttP&ctKB>=KiBrIO_*JNSZno%9Fkx#(qE!fmy4qbM^9dHObWdb+(yMA{|U^+$Z0=vZt%SD49O`oi>;v0QeMq_{LbRG32~E! zz|r@6KEnb+Pj;84LXRSfGh#UA60#)a^k<|f!zCZSeLUE^;&WxRQi1yjTBbM3sL@6i zWMv%Kxoni%pW72A(KDaxA$s=?6}#&thfh^;MrjnAc42?ym1B47g6(gwSio?vj0C5> zd0Mt8k13=ad4<|_u|*}C+J@--f}2rri62cUX;?MiK?NDUa$$cUXFFWz`mV9cf5+*@ znTtx(6iJbB>$gG`Z^}@5xAn1voY5VZ+&FIJYYBYxptWTd&waapTSY46mtV8(n4(W* zlEpN{Cl|l31Nw@ntUThseP0nkSRS5vSSVZ$jHogw}V2 z_a!*L9pbLEkX|xo%H7bW=PXp)+0zpX{r?^9Qks>wThi7L>mdN{F%EmA+l{Q$%9WHc^V->N;a35S!gF134GYnGwa)wq> z>hw0&`I@=0?jc7v-t)=t2k)}5UJkhyy~p^`1V@3Ahf|K-MI%~EsoRPNNBVV}utA*JMO5R&cbq36QZb}KkKnJ-OG{%Ds~)fCC-|zdA|Y7qt8)|Y zC=Cpm4{d=qc}d3%R8(0yCUf6jz2R??(vx29T$wWzXg*%FRceu*I}@z8XX?>asN&3i zn?C6~GV$|O@!f)Bn7fyYUmgez&zq`8E@F1~7L90AiTwwf%H$m5Cm$qN+L+-}8o>S8 zD;=kbVRNy4WwCupkIhgtHItO+^^oew z_l|qa^{dKcMMc5&(BKD#dV=pz?#{ZFWZiO`Da-A`Nv$WwUQ6X=zk%~tN+p)IShe|o zba;_}`Z4hoT_}FAh>a)Xn)}TZU9M9PuklYJS*hq?n`Eo5}(TZJdtT#$X?4j$UMb)L-$+7CL5z{!r!?D*>MNW1c4 z1s;e9L(1eQ*<&=B!Er^$`e)ie6di2JXhkiX+M8d$43RVtN*#{#{^WQqv1RZOo z12H>if?y1IYCd%M@Ku5Nm5k%s9|r5AbreS?_p}`~>-|*s+!L3haEEco*5QhC*8LG` zsknP;{Mfm2{7^<$(0hqr#{|x?ncF{bobE!YvLY|LtMw}u{VH1C`zX-s@x|vWsc*Nw z#2pjkbO{E>j0ZxEVKOg=w7MxHa^3E!VcXVRmqU5Vp&5@xXM3L(bUEG8@A_t`csy-n zuepL`m|>cG|G90wGhttf2cA5L>jUjQomy`=CD-au(O72@n3H`GYM!9-Ii|{Qzc|Kc z>Mbu-Skuqos&ON^I{yNF4qx>PMZNPy@!889)jhq^(u)bN$`#eDzX>D`k`5UBk~L_* z+Tfu!W%aCGp)hgB!v?HOM-aa|DXkZD@>*{DWx=mmUP9n~c?J#d%IAxRyBnMG=Nucy zk=V(Z#%YwnSZIsa@ZQ#L14G>BIZVk_t6EpqqA6w6QHEOeOxe`*ud~Ov5(Qs0pCyj& zQ4VbdwZ(Ap_j3BS^mDaWFC1sdki9jun)?K@{PAJubmWjt+se>t-X0dtsS6ijZ!~wG z!WeL-qjwjOWP&D^gk5xa9dt*NOH88!ns`>VrS6#KEc5iXqw^d}U4@Lg?1#II+q6zexVK0LZ0#%bkUV_*qt!>peQYBy7~=KY9|uM{ z=y@xN7=o}Co*T}dB>HtK`a5`TEe1-QX)ScmK^f9KZfE(mU*;H zOxGh-gx2%r1V!QVwj)o^HFexs85g?HIVWta?;6!AA@kDzvRYQEX zs#Y9Kw$l(lsbmN;V_oa5w}&K8Ny9GON1 zuXEz?G}Z(_5G;?-2!+lgPIZPGrr64O=$is*0fz+}D-rVKl_o z?Nzm-5y*C`8>b``iik$T(GWD=4h2CfDXBovID#?+k0T%uibwos;HU)R zIu$^!Kn8f=$_NCCfWSlWb_gX1k^sX)(8_o_2mxV-Lg7dR9NtdpCkkUXGEfOP=bx=w zr?La6l#yr@UWG^kSQOz9Bo0o1pb1I{2wX`SkB6ZU1eDUIHS6o3dc;IeLmaLE+aTW< zF>%H*NHjN!hPVNl>dyRq!h%d8nlo_gK~q##L?aP!MI=%Qrh5LeuKX#m6< zUpEZA&iG^65U5}~90P~JF^GUN7#yJrQ&v@kTfkweFr+FBCI^E9$KUZZJ2J`Z-=Wv* z6|DZf5>*XogblMcOd;BBOm3F5HqIWpiG}_v@INq_JJ39-|2LlBp+8uTxG_9wZcfH- z#&|~}f$^_-{tWzs$qZ`DEX>i-0|$zVVx5UF(9zcT%2$Yxl6+JgW#Z;k%$g1YZL3@Vu{d^zash)J3_U{~jtTa? zLR*CIoB26|KwIneFh?vLhTg_CQ+G7)x>WoATx|a%6f7j=?1SfCtfHVsqyZDlW-uMe zA~@^EmJ05d2@8QTmOB>u0&=qw>s|-u%6ttpkCH04IiFeEz0|Xozv~x8_JE7}QGp&+ z&)h07`k}MSX=LuYV*56>a;C~jLr#Ccm6h}KUt*+)*7$zZnHrzhW&D%F26D5I6 zm$lXN>TL)wesEx&t4M2G+nNukNIo^|P*YKw3^&MUI3w#&{Ijt&4p3_Q6OlF&!XK=q z|J1v><})bdWWKFzk2_zp@=e36ENxlhu9uFbGR=a`MFsNBJ`3s*>TPRcLe21Rk&;|G zrnmC<>j>z}25!e5jV3;wA8#wql1RX&x@NX!kR3(6;c+HCO6SgP0yp@RM&o z78NMp9Fh{!*=gQAsbnf7z{b-2wj=P}<^Al( zY!u(9ptRmia5qHCgq87YZD+faU?{!A_C9m2GeIOAOJX@Z&(iSP#5yKuyFZNARNpj4 z$}d#-u`92=b0QmUi9MiRi)Ent+(K0Bjka-S67XX6b3av6WZQL0|0Rhe&GX*bHlqg+ zc>_TUv%}f)%?6@0HM@w22uqtDW>WC%vigN@Ur)8srFbZ)eG)#5rvqa*j50oXYdH6h zjgF3v4W7;DtalYrO>AAm^t#!^s$Ajn_XBfMhjrsUQNH6O7?1ElYBWIRv{^QA>{Oczob#-+eJw0Rd&(ywI z)*Ph9rpN%sI-~Y2t!M&aAkRysr}a$EEza8m*1viM@|$BCSjRj%osf`VVtIWIen8U) z1e^B_lE~u&G{qvTrJDi*SZ!;3GUJ~~SKCIU$UK=(P;U!O;S^&lquhiI4G$mG6HJT7 zV$U$ryfaGE6vDQMv4vwBzWH8F?Le+brF&68pZw1cD|=X#cZjMpwW+TO;rvL6m%1 zO&X62dY|Yj@)(1SA(DDNf16`oj_!C#;``uTO)9i{RjJ^Wgorb^ch_>&(Ca=5v?LX3 z8yMYz)N}4fsr@3f_2x5nSt)JK6WKe-@$r#8wUeA3mwh{T^1FCC;XMAJ9{0KP$z6^_RUJ!9)1K0Iyg@jJm)82^EWa5Q-vdA< ze;k`GAX-mNPqVmqd+R5S16k6!FJ$D#h1xcJ;j5{s%YdH^!Tg~kH{LP4M+96(Kncmo zo$nY1ZN8exozot!HnG^$i`)Hsoi9yRB5xZ0(vzO&bnT{fjH`#oC9|*-*+G!a-YBENtwJ(PymC;XX13F@w1t&C zHt3AXIU%==pWpXMyE1L)u5N^A+=zNxoKePMB{SM^jb+WOL?E~se)Mu}D(=0*)~y9q zRn5JD*!WJq%DibWyR0KOo<{l&|pd>9vEW>DF&j xwm6|~%A^~-e7}?xs<*%mtr4xA4iB#d>EDauxleTP1^PQkPsa$8r+wD{e*mib61)Ha literal 0 HcmV?d00001 diff --git a/client/data/textures/armor/leather_layer_1_overlay.png b/client/data/textures/armor/leather_layer_1_overlay.png new file mode 100755 index 0000000000000000000000000000000000000000..5811b7c6b6347eec30c7fc397552533610c2129c GIT binary patch literal 8593 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 literal 0 HcmV?d00001 diff --git a/client/data/textures/armor/leather_layer_2.png b/client/data/textures/armor/leather_layer_2.png new file mode 100755 index 0000000000000000000000000000000000000000..5fdccf5291226ec123bf74a2a7022fa5eebf62a5 GIT binary patch literal 7194 zcmeHMdpy(o|DRk!D&CmZWkzT_km!LT*W= z3!{r8B~+rDrlOPzk&q6h()Y7*O22R4b54)P?|lDidu;oB-tXt@`MSJcuh;wi_-xy9 zcbCbUhMF)KY_jVTCokyN9{Rx5)u8X}gXQxYOnI2y0^|O9Ee5R*@fP?9kgg>oPJ85MY*{B@L-F2>(oxn&CI@~M+fZ^`?qJl z#{~6qlQSLn+19+enmH0e9ZaJe1CJc}Ps(Zp+qh{~ekln_d6(fqA1TSR*O%L4E9!1F zcMKl5y|%3Nm7R&#Cl&3hH`Fz#y?*n#$oM9Y;rKSw^K&REBQ2Psn2%r!>AiNtfN1sI zc+>mSoNuVUSm3ezg!T<%wJEuQ4J8S6eZDQtXAO%q+Zt5P7@R@#XknKnmo4vPySu+H z*<&7bz5M=7tVh}%zv?snDikx4Qn_1$IW5g6%UbDp*1pzthl)81>u7~5#nTpJFU~MN z7M0gj-@B^SkUw>Jx-+)>;QY7M7Z;qFcBLA%SV{Y}!Ok~kZ$1%9ws$i>S=#{aUx~K<2z4C%dSyiN=IHN>^q=( zmmWlt)fnaA()RXpI`t&Wb<>p6&5c(+KX%qkm#MntTr$fS85SUAqrCXHyps27S8(X} z8SH@g)(dP z?)Tx1oeq;Fd7J!evJApH32T4J+NCr3x@1Pkgf@M3$xWmE!F&1b_ExGaKZeg{YA*Ar6$A0?G&oR7Rw4$?9G z6%4mozs z^Xgz!ZU{I(a1D=edZ7G7;;3;T>SpbEllIfuJ<8?OoTviJ*fnIw9KCnW7WQiXw{*1I zPTjSa?Ohk(S3iGswdBn@t;#h_LyKj*8mZ1E`_)*L#jj4?ZI@NHl}geBv1e8cdr>A9 zDZdE3r8jXT0k^N-82wzwi)`S|AH0hN) z9ME;xw(DKPj7~5*DM4q%+^rApsrtOFXqM5#Nhc6l*-sv7=&^{w38}C2QfA9um(KVp z(lILc_&o=u3vF+JTHsF;<%>3TB%*Ia<%F1~l~HU^i?4AGu=KkG`;x_Y&Aim1}!XxZBsV9U_MWe2=xW%_(rVtQ=T{WmQij{Qbe zJs72LUvMQTQ40Z(g0Xw*+vdrX-Wn3MUk%!_9v*fqk)3k(JipOUJm>yP0{4WQ(xT4x zT@UJ}*|tCR(VgnDb-^Q}OTCZwd7m`s4w`2wruJ#~6E+ahJCt7(PZU@2Q}5Djrwj?s ztX_=J!fCTB||Mw@hZ_x1?SpKetR%6ng1?9IKicpq}5|_vwk=|Z${v= zJeB?QoTm}G=kK0O=n11PoMdKs`N7km^A{6^)(2i>Q4u%$*J(wDl4_iMOy12a8gxFf zW#yKxzGxAA)BMiUrp+CDb4JFcX; zkr~`bD}c$RgI3~59%KXzMp-200gP}^2&aP~Y>q9W_xuF}oXxaF_*v7?G#(WUWiN^2 zgWhrOK8(0<28oGSWT#0HlOcjgPzb=qkr5mLS!|0?@RFfx`7jCrS3rc}wuqIqMVu^#}vr# z74!lj6Xgos;30n?01Asn6Om{v5=%mjmxpF)w9nEU!B`Zbc%sAr4~4Npqaq`}k`M@; zqrd3;ri8!;I;5byKmk|8XMoPpAV+9AUMVj^Bp9z#Bmm_@3cDkiEEHsvLi2bT7gyTy z&oc5bhOi@f3JE!SJd(-yjN^&;5ef{GfdV7INXQTY#Ekh0FJ!a6EYMf}$Y=h;5J=r; z{;$w~#7kj|BCcd7E<+?&>gr^RklRaUav5wUS#e1KnFJ63ZIE~tiHXFMperJgghdjW zBnA6*A-t6jwlA8W6E!9CC$B z<%58b%lF}OBWw|JQ{i&P&(k!hf|-C2Z~}xNqzsM4kOGb~w zbD3;b>|def^$MqqRU+Aq%TSo5Fa=~PCP&NJ5ePwzVo`qv{tqVaP;Lz8@9}(rer9pt z3uCzaa1Xu*Jq%|lTxT3?50mkU!3V>*EH1(h;k4`Z{0Zs@Aweqn#{$rf|jT!;0v7j}G#v_>khJeIF zMS&!ti3B8?fgun;YdjNgO;_Z{XLbRXC5!?1phF0hVNe!9b*soCxP>2^!{o*YEWgIb zgo5(Sg^~%0wn2_dCdBA!k2Uju#yvWTNkH2$2uKjk0FZd7wvYhJhK^)n@eCU*z$96d z{mS)jk#9dV8hL!aQsmnc*;U?#yhS`-1RLakoyULF^?$*QlOO9)eEj`zVHtM@fovWfgU&Y4Q3>_=tTa}|PzC*y zud(j%PpW{!e<=B``2Gmjk8pig1ilOWBfEZt>$@WGUEm+t_5T(w%`Z<|Kn`>+kAa@0 zaGL``=sAoUeVL0B%v%0_wwrqk8qwe_@fW~gQ!dFrN_rMcCD7nRp)1XKVyBv+?gah7 zuH)e_*o1ahCkLOAHq0~*KA5wNTjBXkYdWg;HyJ_e>(__YzV)lbv9YHrdUH|{>Jw(qo?Y&( zZ$FZ~wIfO(*d$BexpU{96R=Mmn~RH!QDClFa`qmB$NMxx)03X_w_%csy4_oqS;fDo zE=fsTP-l@mAy1cf=jM=YM#rroThPBPc6GFNEry+bTVxC|wLUOqrkHK7Wu$s7(4Pc5 zy+C=*sg)3V&(*|yHY6ngr7&vOHY+Sn|`%2`40g9i-yeCS& zzK2qWy{bOFc4BDx`kvKUly;%_eWQprBguU`7ghQ3qwP}5?U2T?~89en4g+b8hNDf+RUe%vYevu zu5;!$1Z~9p$iUoGrhiR$_fhMbUHO)E&r_OP8%obVt$MqgYwQh&Khc*^NsTrdT;bX$_-O3 z>Tt#3Zt^kdh7GzS!6{}@^MZ6$9o0*lk*+Cc)>dNzc6!dwbF!?iu2u~QFOfm+r4%e! zmYa&F4YV4pxzH+DzrG?G1_dW0PzU%qk_xsk`<>~G` zOT$nD0)fnOb#e3p|CfO$Ono|dJ)ZgFPY}p-zbKzIQZHr%Oe7Wt^Y{Qv8Yu!`fQ%Om zfyi23u68T!UI@)7`q`?=UVT^hKqI-?F8%17;ql>K_nb7l>1DP}K~Q@iS5^1%5`zR@xtn zgbOP~=bv95L_S>Q`w+WY3irLceO`b4+l_s9Hon!74IB5J`S|8hvS-$5TjLiNiATcs z6r8nDFMqc)AaAsDW*yO_pfch?8B)^m?nPAYvb=2WswVc6yA7KlD{QYWw!RkV*(AZQ zk6+-9D!u&lGF}H?x2!d{;kdi|_};XI>#ZWWP6vnTV_FjN=c!~%%T1|V)mclC9fj{QIp(Gt)RLt4zD_$zWPTvQCTgqJ zYc+53$dM)GcgBWivJ9YgTbm0n|CrQTtreAku%%+hZZPho{gKs+hU`S0zihxl#a;?J z=CV6upE}8Kq-VfrQHt6Ru+&SIOk>T>GkKkP0Ew0vb|;}G>r)@&vhPSZ|?QWaX%b7yiXsQ^=F=2FXDq5wu^bJU3i8mWm&%ewgfcVn<0(e#VbuHHL>6fh#?0cd2lLtn`&T z4WY1KB%*MGeS5Z*J?aZFa5Xc?PgNl&#Gz4Z2*9SO?*61Q)7R-)?-A{<-yLwXYpbkU zukpgk37^p8{A0jT*kN`>zUzDJ-qYEG411#aJ{*DX3a?ijKz!EzDmo+w`s8tam zorPOBo$~EcZb8+wt3KFG$(fU#ec@^R>gM>=lb!fq<2L_(Fs_(7chIOQm)-cG4D*41 zJz;+r^wBTq6!UH_%M zm~)y7JG7*v^9MSAH<{_{jBXN@X}t2=q^vWthhjVTxX$vR*|?;!xOJ|D))X*V-?`9)*O(Xp_8#{=cPm*}-z zo!uFtk=w|2b<#gl1`IMpI1(4*d(c1X8Y>88b;94%5Ym=@KXXt)@ zn;|QgIaJg1jP5hs#nrGnHk`zEPF6+PYG~!8z%x8ENzmF$Y(z)j+W-;au-ftXCX&PS z+BrFzN+&bZ2ifKoOWsuXQUjh9;ez~GCu^Gy9O>+x{pJ&Yr!leagJPoVekwx&- zxy8CqB2?5mHaqt$&bnD2xgiTGHa9Ctd8W!L#X9D>g>UO$5qS7&;+4e8T)#6eOO2vo z#q+qPiC4TA<>lJL26yeAX0+#EtVQujSmk5WeBsWa*w`Of1|F!2JUf01qOyJQtA?JW z&7t$|U0Cj-eQsZQNvCHv!>q=3@4~shhW9PE{dTWRL&I`y&u_PS@NbqfYTH`w6?WBX zs1L1b)t*;uEuf~R$6Iq z%8z56RUhGbDy1S84v#^cc7tMPOcUE~04;JHMJ0q-bxA9mD6HkkuoYO6t&Q9y!FK+1&4Liqv-MMi@w zcq!n$yc-FJDIn5~H2502C(J=824FaAoHYvJB;$o+;IE)q>9laVM45`#g22!te3AZ5xB0*SetVuHgFkg&y|c08c~Cg)_b zgke$|91f1dCduW>I?2G!NeA+_f?gu!AYH)*4tyREfW)9sBm@eBz>tws?ZHtx{gbso zGN~e{CsM`~A<@<-WN7FY780pb_-B7#wUGFLZx%=|Kq3qivjL}YKp-`r>QuxJlT7s) zCIRGKin#flU?don!t+!cXIHxCCmXqpTwbV1VIfCPMRM4maH23VUxDGUkpLeE1p|?Q z%;+!hp#3Lp(t)qSQ3`S!I2SI7C=VeICva_ z%tVn97z`SVAuT`CJsP=e$gNm20)MrBmlv|umKd4L?)og zcm3fW9~F(|+QM_wnBm1582A{9+4^6$X^!sNX{7$NxYcs@fvvDk^F z5km1s53vU;1Yk@5p66@ePfT9m8YPj6BVGT)L;VwuI+2wwpsi3GImN#>uxX+-v5@e2 z3aMZ)Me$OYY`KawxP%!Fa1>Jj>NqjP-oO-a0dSR^ERnzZd0)v^G>HUY@mMl~!(y`# zICL-p0p>pkK_Ud>$pD*8B%%plvP*=)(g>y)u;YR?1kN*9L5g{XSt^oj(U<6m4FDMA z5)_7lLcu4d7e+dnVH4I4LQy1Gn;WDa5rV&U{}tc_!%7|-5J-f77y4Alge+6`3oz!1K5!obw>9La zeQh!= zd>ySmGNY?&=Yd41b}DSX%Jahh@K@pCwiiwt*Y}UaIM!0!&ex~W&*K{3`rd2Bqp)8b zLt7mBtz+JfUYF&_EM$y|j~}0<&Ar^=@2U4klim%?7U8f(pi)%CF{maa$KHP|P5)7# zw&v~M_)#p(p67M~7Mt30f*!w0|A^D$UBNL!SCO+X zDyIWM{`x8w>-p<^wlf$I(b-T}vZUe+Z@jkDSZiyTe~KiyD0z0JYCPwJ!OkF#?&Ej* zM2OYRSh!5jH>|4E*i%IhrIM;M5PKl;QH{%`#TNySn$xiHdq;;t)Gp^~ko4lbFB}jp zCM}B`(HMDWf}G)A_AMabe8?Y%)H^5KVgqGEAvw1`r4B<%rVjtL{RccFt3aF-& zOM02W=FB0JqWW=V)1!>(@=$W~6Jm12RA5LS7W4bbPD+ z#o@;@ANh#XlpJAx*$ISwBXnYe(}{!{Mx%G+^%RWz_9DzccaG^Et0GHU>t>Hui@Yn3 z85U_qdmj7nE^Nh+;=K0&thyb;h98_bxci+@7I~=6qq404vYPH;8cNMlKU`{YC>86| zZg$ypzfF3#?46BXi`g9Sg`@>*pSC&UZ(zo4=Y({}_wCPMl8| zH@P_=Wt4}X>V$-s_4ZdPS9}<3B1To|AEln?fxD~TT=`O3|Kv7G7WblS;#M@bQujK^zqO}5g4Wt#y%+SA1ST?AOHXW literal 0 HcmV?d00001 diff --git a/client/data/textures/armor/nichun_layer_1.png b/client/data/textures/armor/nichun_layer_1.png new file mode 100755 index 0000000000000000000000000000000000000000..fe902900becdf767e636e7d85f332702449af10d GIT binary patch literal 4376 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 Sr$1=`0000 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 literal 0 HcmV?d00001 diff --git a/client/data/textures/armor/thetium_layer_2.png b/client/data/textures/armor/thetium_layer_2.png new file mode 100755 index 0000000000000000000000000000000000000000..d5f92d16ba257d697f16deaeccfe63a66c52a2cf GIT binary patch literal 2991 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 literal 0 HcmV?d00001 diff --git a/client/data/textures/blocks/acacia_door_bottom.png b/client/data/textures/blocks/acacia_door_bottom.png new file mode 100755 index 0000000000000000000000000000000000000000..2f575085b20b456520dde55dd6376f2f263846c7 GIT binary patch literal 660 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 DmXk^o literal 0 HcmV?d00001 diff --git a/client/data/textures/blocks/acacia_leaves_snowy.png b/client/data/textures/blocks/acacia_leaves_snowy.png new file mode 100755 index 0000000000000000000000000000000000000000..a97a67b9e1b6426e45b86fe2fb4e8f71e10227c7 GIT binary patch literal 6110 zcmeHLd0bOh77i|~f+!;3MjCV~(wDsKivh|KH7G(MvQ!aYk{5_%BMBrxu^@^YiXs$I zae;zjS*!~#fQTsIhW>ED0umJjkt!BM6jA3TP{bL>j`N%TC;Sp}&;8DK&;9N>=jO4& zd+~fz<0-}{6v~vnz}*M=Yp#76>Lc&AJ?|hCYD`ZwCqU@~sn9aHR3H?=Xl0ZPM#E~M z0EJRF6!?YJ{XX09P1hWO(Q3@;X)W0+Bf-nIB&Y7vnu59H%%^MSxibyGLjygkB|ly? zh|fH7zIkl>u^&W-^|B3@@7>#D)bQf<%j^TP8^4g_vIyOz_F(_S*h!90j700+p6s+d zaKC!|{2M*8(1uI1&mHcm+*aW`zNOrlxBOW8lceA|ch@G~fBs5yByJl!Ro`;5UG%Bf z#T$jrVOft3Ycj3l_hSuCO|8`2$(!YLc4^({xzpD*H|_UsFdf}@HuO>anO{2%9Rqeb zX!Mue%rDw&5_wz@97b1J6JDiddR05Pk|(&TxB zTQDv@J&m}2)@oW<(iv=T&H%1n&Iwx>gnDA-H_@tiOe#1<@dWGVYIrl=KH`VhIoPOd z-1#ZcR>qa(6zksb(=@|KNk;9_33KcGI*yX!dSqzxiw!d?;wI=H+kRf(VCMvzZ)MNV zd8O9mjCp3RA7@BBIH$=vZ_K=8u{fjhx_H|&&cd(>m>OE8>*h%tx55DX?cv@Ow{7DB zS?*hQFvo7JrFGWOs|$M%)+7QJa|JJ^(V|-lzV2eibR{I~C2X5KuVSoU#X56tDl7Zs z7Q)<(tR#aOZHEn}KfPCJdw)H-|{tZgSJye$7Bb~F54`O&>+EW}u1h!F zT*&X8bW5DFnP*dfFU`&M(8^8Iy6v$Z*RNF^yt427;&_Wz`!)irX^(Jy{|k;6E10n* z$EBUDDPI@Sur1GK%C(vmti;21yH4>b-Bm!VZ%4lPQ6t#D?s1LpqTWsE8;Qy2(u6w| zt^GC+)+noTW*Wu>{!lj=cf-n*?uiQBuNe0z_3VzxS*11iU#?{ZWU0c#b{$NNo@(ox zv_1M#FsqDM?&a;(C(Lzv$56~vmdsBcsL8%u`AuT5f^x0O12Q|< z)gqBK#rWZbW^lw} zv;gIBVslJ-@6)k!$}kOOUd`4C{Z_@_nam{t;4erQ&83J_#Kz;vEuSi1xGtqT`HcHyPrs>Wp)?s_-;?=&gn+}>%9%Ousm9C zHm2$A3#{!r-DpCvn)LYLrSrW=RZ@;Y3;B*1f3hd&DRYBEg$ttPuy6EY4lg>4N9SXlos5}k20|c)l@MAj z7D*HgwIfEy%RoMB%{UBN2T_JOVgfw9(QZ;Xj3!}8SP)>Tg^>h|lQEhp=L;AEy zkdY%MRH>9Pa5$Apg;f!;Qh5jtPp8vyAOS}p00;t5L`js88jvXLv=oCJ?y!O5t5M zdJcO_6hkT^dg9cO42Q>pII;Kx4~3Ey`F_2RdMG%^orm**719Vf4`xNe5~bb9MP;H0 z#mF@y6tLE$i(AAO;Eop2P=8LS89!MpF+z}LBav_r1kZ5F7S}Hz5B_QLuFrFX)xOfr>kYFwZAPI*Dr~-(@ zCGz+b5=hojX@zCDc(WZb1T6U8;w^%d0;yc=h*>0*M5y0SaD-ymR|#oF!&8YQBAG^| zQprRTg-(AD@`L3HBx|*tco0j|P4Ib)c?cndB#%%Gg}^wOBt$oXgv@Z0!;n%c=SZa@ zM~pTkwANEs3TWm~k~0=bd62dkbYPgTt&^cjafL!~x*-$yDe%8B`G!hWlK+n9J#?7G zMXppyK9$7k(sLAu107K{^ef5os_$ z;!&soMCVcg7{XIQI-gDgd4mZx%&w3MlqyILyM!P$gq$-{LArBB&(OT$YdfREdTJJ|4jV7|l0&5@+} zJAa1C=kHtsjsCL8XX*Pzt}k+ZmI9vz{*ql^)OdUZ@bjoi4(K#zk7$<=^h*Z)Az-~sqIfkcWw=G zrk^6#_k_Rf@1OXsp-Xd&X(f7cdrM2pUTIumXWO)Nh5o&#PtDk+XU=?Ygj!(#tEQ{B zuQ0VPe|mCtaQ%&rpC8QNrS>gHHOH(qCyh(+@t9*-ZEfkg)j@yP)hbj&F`1pzVi>2` zvYSW`nThwbK&8~sTP`^~ynsnGN42${I6+-nRPV>F3LhW`6!r1Ta+slS?k}55Z@p{LG>LS9UD#;7IZQ)Y)bCdmiEbOzgv=~H_gnTth6*B zV|xZ9IC;7-O07oi6HX~^1Y$K|flCZsJZ~Iss+F7|5-aa&G>TKp+Ex|SJEXL=)=51! z6pKyoy?SNSRVJ@JnL4pK=B?Rw;m**;+gFmV3V1>Fd4*xbqc&NDv&G`g?=Fs3|M;W7 zrjIE8Y7ITND<<<=yJk1Cm$&;xdFgA+S35a7hum{Dl-GAg=nLq_xPD90ESsvsch@@@ zv76Ftt6R49MmuiOXf&7Sw3YPjvCf`}ME{$-9G;P!oGd!gm~p!D{=V>O_N70kDo-t2 vm6UFn?i-Dbt+GDOzo%s6b;Vq;?lmxT$ulQSs(FQ+K8np+>|W@)V)Z`(!e=zX literal 0 HcmV?d00001 diff --git a/client/data/textures/blocks/acacia_leaves_spring.png b/client/data/textures/blocks/acacia_leaves_spring.png new file mode 100755 index 0000000000000000000000000000000000000000..d54eb17d4d1e7755e291ae2fc54a24dd030a3b88 GIT binary patch literal 598 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 KT43R`<9`5ym1#u) literal 0 HcmV?d00001 diff --git a/client/data/textures/blocks/acacia_log_bark.png b/client/data/textures/blocks/acacia_log_bark.png new file mode 100755 index 0000000000000000000000000000000000000000..d22121072f739cf4ebd14909c3b1f603d36245b0 GIT binary patch literal 797 zcmV+&1LFLNP)_y=Sp{2+c8)bc9WfQT4&Ew7C2 zl`Q$8k)@gLnQj7AO~I|Y(K#o$_k7~pZ@zZzR)X{tgR@h9{N*j<(K)^LF>n9)lg`Nt zg!FLE(WoD?-DMoqBGNQvJQ^ak)|6$5l#=h?{EC#4vtGLjPsT%LS2qYDXf+e&^E&{R zt4EB^QN|dG!s2#Yq9~%$%y;Mb!Dm_#@wwQ01!e{ zW+4R4q`~HSOY68vmTT@-56H4CDa(>Ds?qJVs=#p2$2rIB`Xj#YBc()2xfh+q7z2Qm zQgZy_s1jPugr{|i(K(*yVXdVo3UHR~c8d^##qu7d6pv49WKk3}n+c1>55ycR1&ep5o@?lF8^C-}ec_5Nj;} z*)C%^=>P9O(%BN{96|_`Qu}I@;{Egk&N(hFXM|x$J^qAr^Nb&aY@W9O9MmEtfRG+R z5RhdVH}fT5efb6d+$`vyc0fpUo*|{g_kEmm^t&h3L)GnkMI6T%WAHo=tu<0g@;s+7 zn(Ny;dfg6D?Vze!`2j)*j_UEAL;&a9zRoa2DMc8Dyqt`yx~#Pov9>JGTBH16&q1r1 zP#6tvZvx1&jQ5vU1VMmOlEP@5b69Kn>)i!PDV#0wUcZ`rhY-}Fh%k!SgJsFGoH+iJ zqedNLG>_{I>vTh-ame7T$9Od0ho62!=6R0RnwOIyA7$R$F`dyqPVkh^XT!7o z8HM3-z2VKzzcV;LMV)rr2q9QKJYlWH=$zD+BuRr^mUDeOM=8a-=?q&IAS7v;((j$n bs2}n#D|l&eM}YP*6^5yd<$BkLLU^;04DCW$se)1I4Ndpp?{kY=Y*(oLWgs6xJiW?tS zE%^|1)vk*;s#oU_mMtpvE!|!s0-eFvQG?Ff1>s2eC59k1+4qc6!b)LpJf`nDwj+ed zu@zJmolY8T)iP4$xD=8Aqg0U^q3_5DDo$}wf$yc@z^q-MzyJKj$I#_W3c`ay66k%y z7{z%oP!Sy8nT_7wEs-&ZJ0Jke0o8~g^d(ocz#Df2uu>qzD)OnDgn$77!Q5!9AV3O` z9cBZuBZL^itA)Ut7Y;@V!wDh;;L+f&fDZ(Z4k{Z9=O5k^rjrH-4#xYex_+Ist*KYp z#@@i>W~d1Ft7TOX1#XwCK_Zl#3BZ1+CjugyW-dbZszggEJX)35dj&+*wdd_fLz5r^ z4(6cq>l@7+pqU%lj8ddnp>5so(CoDNZ%M00000NkvXX Hu0mjf@tPC< literal 0 HcmV?d00001 diff --git a/client/data/textures/blocks/acacia_planks.png b/client/data/textures/blocks/acacia_planks.png new file mode 100755 index 0000000000000000000000000000000000000000..6858c511972b5a6702f06c45e3eb1fc00ed98e40 GIT binary patch literal 452 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 literal 0 HcmV?d00001 diff --git a/client/data/textures/blocks/acid_still.png b/client/data/textures/blocks/acid_still.png new file mode 100755 index 0000000000000000000000000000000000000000..819369946c5b57f6d2367ce9409348a412625264 GIT binary patch literal 18778 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 E4|VGr2><{9 literal 0 HcmV?d00001 diff --git a/client/data/sounds/explode4.ogg b/client/data/sounds/explode4.ogg new file mode 100644 index 0000000000000000000000000000000000000000..f5e16496cbed915ee572815bb5069a7fb854af73 GIT binary patch literal 27496 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

JP8$*e|5G? zjcv;`2(r#mo1B<@pSSMZz@L=5n|+;WdX(mi7J+3MJ`)waJhQGED5 zFeCWrK?^-LY#zG(bse#PWP2-=RvWq2BP~W$&WK2QxMsxNt~bOPEieO>zH#7Qcc6yLIyr3WWw zpSf0Tnb19@j~Fy_~5Iy!w#c zk9VT$X_A>+68uM8?FdYFKIj|aM|@POTsSFS_d~_w+27VSS^A>7Xw_(wlXBenL-?5Lx3#~|10aqD zC@U|EqX-892sEoB)p*2;M>bB`N;!T-=72@L-#G4VN@7WXl%7D({`_-9fa#V*%?pE7 zRGhm#i2LPj(WbhcwlJ6ioKN-C-&#CPK?( zJsA|>vyBR$0gLyN%^1G-6_IIoB1}AaD)-6xuYXSBgIZ0i!9bJ>DkF~?cG3o>rwImI zGzKr&=6rka zMp!-hio8mxmOYE(RY^1YD4QG%Ag*ph2z&u*93N$!FU`eFF z%f?`HT*1rRzbLf?qTjFlRl&$OH4NYb-(!Fr)CIr;$p9d4Qg2JPoWNZpRC!5+X#--N z^q26_s>gZkpmbbVi;J$H%L>epgE`28Fxvf-xmL|wLuJMdHZwA7Na#W{d*9@7bc4G9 zG3I%vPUL_0^{A~;9q=21`W$1I+NQlOF-_ZlBBjx>M8f;IE*QFEqWOXg*T9z9kQT7$ zs?P>60t@=c<1mRJ0V3jA2466-h9KyfF523Lz2u+l8gyH0R0fdDl=F31c~A&a>_r8- z@8mPJJS%%Iv8tNQ2YunUx4L5?#?{SR=b!d1KLXDUwG|kw7vo7X#Gfsw z7&q-$*2Y*}wKCbX=t~Vj3BMElZ0lK&3(e4#w`U<-yzn7e#mr*3WW#_E-e`~l50o}Y z+&M}|U5B8uXn>`uUbe!)tpaYz5CoD+<@baF6ge*2m_!3Gjctdrwh6nf;Sgx;8TQ)e zlcFWcK5T1N5aXxCcwbe|UKCu|N_cLH+_L zOxjse)Dxga0LR@E@~j->0-)!-EdBPzH38+uG3p6IrZs9YJ;ee8dyoGeZZGpzpp!-vb^pOplGX1C|a7EjLp?Cwu;jR`BTvhde4SWWw8a-^vq-t}UH1OH5y&6ss8D0a zAg3#UM5PQ!)jCL@WgZzffrH9GXi*C!rRV)ActXF6XU{*+u``ts0ga_Mv}h^(8Z6^5 zvh-8eFDFqgg9*PzQSfICo zaUE~{(Utt(F0UQMCsJyufj-4PBJBn;n#kIz{*Lq*!}Fi)o|$p&s#7QejL3!NSG0hv z+TSEmdI)ff3G@Yr!O~GwUNrE6RR{*q(a^?-@P6ZF=#Az{dI1I&=b&JdD1d*R;-5I= zGmN`RY~VzTf0iit7r|+Iyl*_&Ff;9yW1xw%V(!iND(HTZ6i&b$xEgn1i8u_WZFHxQUKPYEyh3#%2C{l(D;bLREr7VlI8jt01ZfU+ z>4D7#{Znys=@&7K)BI?MOjIQL5IU~_g#dX*K*uz!$n`$?hlTj3Mn&HI-FUhmu-3-* zrn)$eU;IxoY41rIY2_*DgjuA5y9xMuw9{&n8u0*>6u?J<<${mFzo*LovkNd#0F_|; z6GHOh#5S+I%S|!CCCk+`HPQ+Ig6Y{|B|_A=0ElkxnoEi6>@ydISpZ@x2Qhc}c&Ndx zck=M<{U;#kl}}Hs9qk7$HEUvnntiu2WOCnxrg!>}FfI~6*YD}|UT>0#DM<|%X))hVde)|d2Nt^3UscGV_#$Ra zdejy_+Enaf6ODX_1Mp&*1Dt89Zh-0d4b?juQLDAr-45jc1XvC?(S?_VEh;1&?7Dzi z(18Jv+jqn1k^9aMwRGq_ozSxS)8C9U!$mEWVBFM;Bs+rI$5MZ6Py_6!Y8|5j9# zbeb_&o5Gqt-DU#Tg^MGInb;({AK+BQI?i0IZB~^EV~Bf$zYI z_BcTeuT&gF2t>r{d)`_tH(z`S{R952bNWgajQojyQ6%Xd=?YjkCfY(~l^zW2Xpi{H zfL6p%7GaskD|n_5{C}X(p*ivrbyI55refh>ni}`7RUOp^7<+se>S+zD7h}p(GyPN= zzA~eAttK^(Ac8xOOlNnsbTxgDydywGWU3j)#O&h8f#ElqqnuShxiNquMp6DjDd}Lv z7Q7Wgq0d!~H_cQ_6mkP4577%(w0%$!NdX2F23L5}V!k#<`Q zZj!Z6T8fW0vefzhe%BAbrNt8${5HUbYCzNGqVxd=cB03sx;;sBt#2H4;a;MExSa6+ zge*8&P|EF)qZRmZCjV#GAr>TB!z{raN}TC3p!8}BU$1SkcP7lKF#$$M&-(Ek&lBu* zS@@0gR}k=mqit%mOfVEg3-`mrX`3tup#X0yEPe{c*f)D>B~xEt#?WD&aA9%T_PLwhANwo+ctWD_5R|mz zoF-@l9Em(v!#PZ4n0Et!z1A?S58xFBJfym=9?*sZ@XKSO#Yk>8;YL~5zgkpU8yIgS zCI$hIQ9?jU(MM1f=d)cbjXXl2X2wu*d^YhcpU4ALldT@~bu|vqjd5r=rRR`$A4!Rk z#*9p-L)yF!L@Fx{B=D<$jc`S_f}E= zzf+!{*O4nxZiCUY#hX8TnLP`CtxDh6VBMv(RvO{V$^X)+vi>c&m}VtPdFT5PVhaz- zOK%}VWq0|lZ^i}ANQrdPCZUpj6(sKU0t^HHpKp_ZrbXDc;>!zq=es_`!r(@S=wqAp ziaO7Ae_Yr6jE$G`H8-#|EIYC0cp-wY)|MWvBsi2w4fvyawuiK*>$xGE_4NRsP+rmG z#e!?%lw!jgL9wz~TKqhxXp(%icKqkqu+SSqq>_~DJTnLn{fNgY8lLnYxbC&ro$iEh z#6*orYY8^nw(+OY`Hgu67L2pj-%s^mLTQ~o_XZEIeh#*uiAW;_)>FETSHp^N$fxbH}q#TOa#2$347HVI`NLftTc>gyso{L$;GAj*bog#T}$X{AgcIwBc4}$IM9#EO4}4J2raqZ`eRJ`C~{u!|pf&dZLLdZD4?~U|$O@r(=z$a`j)~d4l z4;(Yn7g4#wMblYWt&zP&q976?11t>S$Qm6FGCiO|u6Z|&^8(^k3pY8fFV;5CS=K4zlEfdG~ueqaHB1b)B_3ByN{qW}MoOWOeb#$9w-2^O*x zmza&~6$mNgw^I2fBY5?v34xI@W8)|o&ShyJQvr*N@q)~xO>B-vJWa*ZxKY3}UkR-R e+HruUjCUgd!0R`tfwPdn2GmsY8g}91f&L$VYi>;d literal 0 HcmV?d00001 diff --git a/client/data/sounds/fallbig1.ogg b/client/data/sounds/fallbig1.ogg new file mode 100644 index 0000000000000000000000000000000000000000..cb63c8c8b9560f04054cec7fcd9676f691136e90 GIT binary patch literal 11808 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 Qmv|xdZ}-UqJyC)G2llh0(EtDd literal 0 HcmV?d00001 diff --git a/client/data/sounds/fallbig2.ogg b/client/data/sounds/fallbig2.ogg new file mode 100644 index 0000000000000000000000000000000000000000..25d687b8c0c72da644f10fcda9c5b4dbebee7979 GIT binary patch literal 9147 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 Otck*?TAFs==>GsJ?@Oov literal 0 HcmV?d00001 diff --git a/client/data/sounds/fire.ogg b/client/data/sounds/fire.ogg new file mode 100644 index 0000000000000000000000000000000000000000..747fe59bc8463aa4e4c661ba0166710575950e75 GIT binary patch literal 22862 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 L0000000000M`vd9 literal 0 HcmV?d00001 diff --git a/client/data/sounds/fireball.ogg b/client/data/sounds/fireball.ogg new file mode 100644 index 0000000000000000000000000000000000000000..9754da5cc65207917eefe73628f06f918c25cf84 GIT binary patch literal 9151 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 S0RR9100000000gS4h{~-c2(T~ literal 0 HcmV?d00001 diff --git a/client/data/sounds/glass1.ogg b/client/data/sounds/glass1.ogg new file mode 100644 index 0000000000000000000000000000000000000000..3224a90a35bdce7e8725e68b0af9295d534d29cf GIT binary patch literal 9452 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 literal 0 HcmV?d00001 diff --git a/client/data/sounds/glass3.ogg b/client/data/sounds/glass3.ogg new file mode 100644 index 0000000000000000000000000000000000000000..a4eac8c8fa486dc6105c96f24b1b988281b4d750 GIT binary patch literal 9057 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 literal 0 HcmV?d00001 diff --git a/client/data/sounds/grass1.ogg b/client/data/sounds/grass1.ogg new file mode 100644 index 0000000000000000000000000000000000000000..f455ecb8e6cfd6d6554c8d9361ed3dd403d8448b GIT binary patch literal 7773 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 literal 0 HcmV?d00001 diff --git a/client/data/sounds/grass2.ogg b/client/data/sounds/grass2.ogg new file mode 100644 index 0000000000000000000000000000000000000000..6aa1e1544b00f18c5ffe88faca1c168611b748e7 GIT binary patch literal 7828 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 literal 0 HcmV?d00001 diff --git a/client/data/sounds/grass4.ogg b/client/data/sounds/grass4.ogg new file mode 100644 index 0000000000000000000000000000000000000000..80f360b44e18e634d87f2782362d0785dc9a6ff7 GIT binary patch literal 7584 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 I5R78{KiLAv00000 literal 0 HcmV?d00001 diff --git a/client/data/sounds/hit1.ogg b/client/data/sounds/hit1.ogg new file mode 100644 index 0000000000000000000000000000000000000000..46d3fe60c5a8d24466ab51ab8cd9e0ed379930f9 GIT binary patch literal 9171 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 literal 0 HcmV?d00001 diff --git a/client/data/sounds/hit2.ogg b/client/data/sounds/hit2.ogg new file mode 100644 index 0000000000000000000000000000000000000000..e01af940748e16a3732e694f40f591d11eb04de6 GIT binary patch literal 10240 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 literal 0 HcmV?d00001 diff --git a/client/data/sounds/hit3.ogg b/client/data/sounds/hit3.ogg new file mode 100644 index 0000000000000000000000000000000000000000..6b1e1c1eb9d6cdb6be4fcd58f2b2443db47209ad GIT binary patch literal 10532 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 literal 0 HcmV?d00001 diff --git a/client/data/sounds/horse_breathe1.ogg b/client/data/sounds/horse_breathe1.ogg new file mode 100644 index 0000000000000000000000000000000000000000..8454df57758cf2263ce8fcf4ad301908d0bec587 GIT binary patch literal 9136 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 D$8lG9 literal 0 HcmV?d00001 diff --git a/client/data/sounds/horse_breathe2.ogg b/client/data/sounds/horse_breathe2.ogg new file mode 100644 index 0000000000000000000000000000000000000000..8968abe2a4a72dbbc924209b705110d7b0e0544c GIT binary patch literal 8593 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 literal 0 HcmV?d00001 diff --git a/client/data/sounds/horse_breathe3.ogg b/client/data/sounds/horse_breathe3.ogg new file mode 100644 index 0000000000000000000000000000000000000000..bd2f435781f8774931a43dc7462247cfcea29b51 GIT binary patch literal 6447 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 VCqxztP>`RpLSb5PR60%Y{{SB>`>_B3 literal 0 HcmV?d00001 diff --git a/client/data/sounds/horse_gallop1.ogg b/client/data/sounds/horse_gallop1.ogg new file mode 100644 index 0000000000000000000000000000000000000000..3565549f5ffcbb11b24d06adba7e6b314e3d8d07 GIT binary patch literal 8333 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 QFa!vu3pZ5SQ8fYnA6T8(nE(I) literal 0 HcmV?d00001 diff --git a/client/data/sounds/horse_gallop2.ogg b/client/data/sounds/horse_gallop2.ogg new file mode 100644 index 0000000000000000000000000000000000000000..f2574084cad33079705d2eee0e03914dd4758a95 GIT binary patch literal 8854 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 egZyQCs4fY|qZE literal 0 HcmV?d00001 diff --git a/client/data/sounds/horse_gallop3.ogg b/client/data/sounds/horse_gallop3.ogg new file mode 100644 index 0000000000000000000000000000000000000000..4c19bdb2c897a06f8551be70be2060a3b7b33037 GIT binary patch literal 8050 zcmahtc|26z`jm;Xr z8N?ZaF9o{!;OGd3s3-In07Pjp?7tfsEa;N|7P=&z;-~o7g-dtuze@ChKWhF0sb;Rh zp6c*pYNw8=s;JP}CBO$0;C{&i6Q~Um-9h4seWIkFkJ}$P2IfESBl-rm41g{GNaKVQ z&XI9~1a1+1OW|3F{s8uqu)Y~j3`EV$sZR!%CRI|XpXekXJ(Pw5=mH6PSNRD^dTdez z8EyOYSUGJFN`!+rA3Ba(|DVPX?hR7)*u)64DjJ-za~j(af+5_V8^kS25)SD%l42|2 zAhWc(v1Kd^d=Wx;t|Xrn)1lHRNMKTzPmcMh((@+vpnf7L)SOKtAK7664g5#_7@y=`#Cu{zipTU+sQX+ZQ(m081-Q!z=u( z`*I!tz*eY{M7B>NdnYXeUMDZl4bVU7Q+8B;>j?<6(B z7xHiez4Ljh10YnK=fFt<`4;jz3LQB9Kyo#qLnH+{?#jTDOCC=b2+3B3rjb%8AjDkd zlS(qJ0U_h2P~;s`Iu1uywcjjvEOflitJCbUtMCOZT$G-g}LEG!I2z#Vi(KWjzLht7VawwGjF{dPbYXHFFD`c2Q>_2rKGRPxi z#S2#D5jFJ@YeN(sGn$2WXoz$gi$iZkPJwkB?`ofgarmG5XX#*&OM=e+XCcroAzVLv zQJTp8&oaRc1upX&?faWat+eTD=~u6nEWW`k__VF~4M$+8VF9$&DSxYzm=Sff^+`0! z*55A6->Duyk&T(yik$hcie}wkA};`FrXPi-AAzRNYNSe==z8}k0J<#nh)nt*pE|3N zE^U%7>F;>*%c%@0@p zzj|=r!KDEpNZKe++6XCahy;Os>qc?XtqXafDs333)b|?pXN|*r+Mq%0g8m#De{TQ) zaQ0U7_YFhLd1a_bWt6ot6=_JdM*V-qd<16B2O5^09xc;i_RK3N@>>l}&!qM~a z`I6Co`Ix)~ZdLc3ZltOKXIGXUfyfLRjR~*<<4UzhwF443V6rT2H~?1=BX_}#%J03g zLe!KxY9Yw=HrUxbu=`S;>}dKxjBJCgr~!olR`5AkG?XU5pvw;c(VR#QXdKaP0J@Nd zdOsX3j5T&Sz-Bj~?YSq-Mfi!PKp6Q0DyRR2!6opgAf_#{7i2IX}vp&k!Ymvd%I` zQ80rr|8X1Clpu;)k8#?Jw9CRzoiHD#cR?y1?4s-ar?UT5g&MU%O`HU&>Q+H$D-^~7 z)Eta<7)9C9B0dTD9V8rIYEnarbRw4t7r~*`S9U` z+REM9W4q0tSBNGfX7mYB&sw3(?I`}%cz-88!%+bgHOtT%4{C{Y#$(1u&ko}aQJEO} zkeL{C2*$1f6!Av|N6rMH(b;&ky{FSw+z1|z&cw{vVH~zF=x!Q*X3K1(-h7mbA3@<~ zX!yBY|A}o-43El+a|ZcFsBOr^+^ph(=@j774vp@iV z(MsBIFsE=_T^Vf=22NtRai7o+SICbA zk5KTSb5w$M+Qa2!Vp9>UQsi`mnG9LTK%pj+=mrwT9Q~R)b8zzH&UA#I4B6hv3|=pU zOQjDkw?8p?b)gIwn1FAArrCB0x zf&^29DyS-;W{#%ktz5$EE-%w1=>D*ZB4PmjGdNYyy{eTyxJ*|%B85J9N)vb-p0AlB zIaW4xj$!?qHb}Uka*Ct1SrdI$P0S9s)z;V{aOItrh~z4Yqf;_G;qSqdD4;5A%_c|y zRhc5x>xHnX>YF6T2Ot6KTQg6>t*OqBS!2~3gs|Wkj-aY}nmd^M9N+?v2U%h?8260y zxMz|=sInC4C8{ozz}Qsh^N2~R3z8*B)p-a3skR_VOh?ioBnP=99f>U>B9XpTVB9m( z<6aadBghJdtqhRH0k~X-^nE>T1w)MoEA@UmI}8IOOKcwlMxTG*9}FHpwaV_vigSf) zHUz9RukAix*XjmvisFcnZNM$)pUo9Iu zAj$0pZg3tLhv2e7ZU}fe%gZ45aa{UrG9Lfn$i(D7eC%Xm`rmwD9-+2S2+D#uBw}Bd zjSemSi-XcL+kGlj=3j_R;6}*P`9Rxp>x0eTR{jT<{x1%R{09ea)!%$XqzRaULNq{E z71EOvMhUv!V?Qh&weP>W0Kng2YkebMuV2-xT#8M#tXv-fjaM~zDOn1&=8%e$!X-&D z7IoU1c7hi>Hxs}Hnm|R@Qsn@^$;GY1swby=xem;3^*!Q^VM*Hr_b0=onDWZn|#NVUyNj>e@_4|0B{HZx|z9o zh9T$TyI718x>=3EY#1z!z*AP>sTAYcv#^BQMK#Zc->)<9f=SBXg^7u29|HXlU}D<; zx?y^b{zIgH-O%wSwej#Fz656~(nhbcckDKF(FAN{>ahrsF4ujN7x* z91`4*SH9Y1do`WgQkwZW`tIQ(Tel|r!IMh8iLYUq9}15RuUzpR^7Q2-rABXvzgtF6 z-!t!0Cmy@IL8xsd4t$N}?Bmz{dem2kh1F6(GP8C%efMi+LZ;w`%8|9LvN}?n*ldu3 z+!2~s$dl?Hlx;lb&F3k-Vkzd_$m4|qTy4H7sc}fl3xa|YD}`e2e!i?slB(|uQ>0g2 zdQDzuAG_lH^SOFyf72L_l(Y1TeB*|bO-x2!eCS(y&y98jkuhM&Lobx?f$R3Gx}xut zwCAek(R|dY4dxWN>TT%5?U6m7of_rsh#f%H zrA1kZ+cQ~Gg!kqiQhD$rY}p{}ue(;Q#=$f?)h)5E~o;j_n18t5e z=SoOXZp@qBMx)<+L~kc^hMOEUyu*LaJ+NT+C~8Lbmh9ZF=wb(YBscZ4or0xlnX^o# zlOz=Dy*qTVH+rg*)(Ec-a$>LfG9*>&{gV}8~N6GlCh?@oM6kTs;7^Vuh^ zC-%qv*Xlb@N7r6CdP~2bG`z*_|JVHk^+)oSU`@Zc++YypwV~zTw9bYNE&s3iQ)xSQ zoe;u9 zC85>WPv2eVQt9;g0PWsRL1;yJWaFb@<%_?sZDBdpWew)o7hCZ0ye_lnZe=@BHcqCB zxK@}&UWEdq^)? z%Jn#H_uhPbOFX+PIrKz_jBJTF-*(X|bL7Gc!(}gy=Hk%n^DCLVa=!vKQL2ms;-@x) z6H1u?nB7AG|Mn_B$%^dIIXpHgUm_AAdZ5>fTQvOJl?h94@JGs#aLbS8_YV?CVi8|E ze>dMUYn(eD(*9)4w~>ANIdIy!H2t?kl=0y-ZE8<{eC36MW~FO)-tCcAYGDt4%VGhD z^|gHRnW(atjHjl|DY*yi{3+}!5nHRW+70bxd+ha*3O z&SwJbrmt~%-A$zxjQpMBXC@|=8cv?~v6}d+XY*uB&Wnj4pMf75YcB{4<+L2<Dgw8DYczhO9nZtXZ%S<5T2@PYndj}Ob#ngmNcNA7?W{{XgNjZ=)4Cf8TB)9p zJ)Pf&01~!~*fo13L&DRScdu{R+3ttIw}>-$`*DlOCR0F3wvQVpFGm@|?hfSHHsyWz z`lfrqf`ofyjnC{~hhX>k+Q0K*tUK1-zyFZcw0Y7;8Qc!7+6-J$GxnbUhE*M}e~seS zCK#_cRaP!#+m+P#s_rzrS{!s9lN56_7P7OkKFrF7yKVcxJPdjfSvyjh?maBtVPK#4 zD=nm8l(uoSLW%uGa^L0O94{_kjJn_Ny!2rXde>^`;(LjMD&{KK0ljem_>C36x9Y+I z{A_z<&CPS$D1Txooqyb2Rv=T!#fN72L>b$R8Xq2vbH;L-=(w|fRjR!;KEHh18ndm* z6M8u0PVbWm4*hi5+K`>i2IOkx*z0?Ohqa16>9$w>G?OZJp^2cx9@)MV`TW4NGmSeR z+rL!3@;#Y$P)ers;*nEdkCF3d7bf4grF#UOXFU}Cq%r73n8O=_lVXJ}Ulxz7=}pc; zZRqkB%_)`j$1H8T{+)(*4giDxrq;&6My*p(WUn%BH5r%HmW-Th?A=Y1Dr+GjQ^#{H z@;jf@W;@RGg*_?_>JR);IP6l;d7S@Hc=yzyvwfMYe9lLD;p3qbSBIVl7vtN6uq&)0k%sW( z0#RjA`<_~gXMbCwxBQJUi}lQ-ug=@X)bt$jTfTf!uIz!M$lcxMn;k|!M3fKm7FWM} zW~k0)nZu^e3P|nzpwV;$Qa&)RrdK>kEVg}gJ6N3X#OlqBMrI&Pfkl@o zGOCXxBD?o7WA8`1!n8*2$Yi&P({oOdTK*Y%gjAWM$VIX8JL60554o+jCiu&2imzdB z3v$uYfBkGguq!6eMDMevr!0BDe?fDS&M^1sdBN1`llg4EYoO@h>6gC57D8mmbuueg zQEmH0P1Xa#slem>9OONbq$;oPlH(EO>LW_WIUd-D7e`F$df1i~Hr89LtgYwHn(`>V;)Ci0TC9h&Hd}alJtc13qv=G$Uzfy7zaOmMxmJfXLLXpm zQ%K>J(*r7m&o4Iz7Y_6rodn*fa>`_Mu?ANJ!ygieLo_L?5gwh1-A5nh=F8YD0cQ?s zDAskkZq?Z<#ODnIZ}#Qn?T#>W%R$uFrpc2DCY%XBrZq$pUQlE>UF-V@^&2w?kA!pF zwj-M@gH1QTcf?b)PqnEvhu_n*Yq`t)Wx@>#TYgLRtJp?Vjso9kbu9W+E$SO>$6jy{;EjBGh@jUA&KkI+5T z{py$MrvXZrXX!ejl1Vxlv)zoG=*kmUT`;o!3#+V%+L2$K{3&ZOr&Ov%I+K@4IQeWf z4h1ujQmf9rrEhdw^HY8yBtTsJQP&05DG48+kCe8{&%{?y;vHm3*wfGP5fcYHdKW#H z`)cm|s3u>1%gvTM8#p~#>UNpZy_|o^^l{Tc>gw;q^My*|r>Ws*jvwbWIFpgGvO1V( zOT3idMv!i6gy}LZNuE6SFkvM-?-L}bYg5P=`2OAPT!t${aeh~GQo3v2o!8UnoGEB3cupewh+nUF3bZP3y}uch8^Mb#eLf!#qZj@A^vp zEMK?;A7)x7E{7&?)~G(b$**)I>^<7|flS@i!J8Hc?1yZg4QO5d7*e{WEBmTSN?71$ z-z}r&#=cGm;qN!IS~UD`7x5@^ANMIW3PE|A3nvZt_07}PwwqhTx`N-*l&)Ub(v~Us z5>$O`m_fYJOrJ%hT37jlC(f_K{H<_qkq4&-qtMFUs^i`^TidZEo>v7*AyXRF`Tib8|ZF9OM16$V}%VD~}6;ysTn0l9_$BkYNyPNcC_j?7(l{mXB?G zqpy9q1`h?i8em-<;RSv-1Od$AF43e898M>z30E^O*vt?XPZrd(1b&25gx~|2Aq^8t zU7KsXR)Y2!p-bCu+2ocghMV|1hR`~_>#tHwb6pCox%wsR^bL!fnmZx#5sr|l!dHlke+n%S`)m z{zJA$Eh{9b8TU9n`Llw8JySl!I{7$bFX*Y1JQWk*^AzX_Jl+D!VVJH@R*5UoWp5OH z*qJ;vg$^3UqerLGobKN^&#Q0wKF|3pMdg;5*YWA0>2S@qsLd;rGZwt#GM`Ib?JjP9 z-aNL9hrlw7#8B@WF&kgLWSprM+`eY)a%$5-?D}YH`Bhr3J3qVjv@JOyWYYyjq~ zls7JKS-DFhDw_))ElrfO1{ZjJJIxA=kI0uKGpSS}JxA`=ABX0?IJuX=9g_Ue|L13g zu;Pm4~sGQIX=r@9n(86LxdY06IxuizB12Os^-&958)zU38tJMvgp1&|kCw}1XwHtea{dR!D<4aDHdPnFN(9XEg5ObDni~2c^H^oCw`HAN&eu;``g> z97&8wrFt+Ier>F>6sA_!`MK45sNAXL^vUpiot2%v5#%0)$r1&sPaCMciFy8- zMLGou#rQ7xJkR^Se|__tJNMj^GiT13IoHtH*%%-M{%IG3Yh=$ri2jl>0Vjcv=RJE@ z?=u8JK*QM!00QI)&fjkd49_J0YiE*Ylv5r;0UG5$|EmQO{Z(@Tr0UuE+>(ZiNy>^z zT)A?_&ILYBcN{z&o$e`uLJ8Qr67o;o>d>zJC-LmOEug|FmN~)1)K>yQ+db`5}`uQ69QEfmL$6G(^#+?*D~t#OB3RDGKoTmlD~`K7gQ z1e3zoAR%ocf)PROSKcy(5K9Y21%0{FJswP@8lD=gBYnaa;;izJ>8}lb746tyQk8C& z5KR?u2Bh$}3?Y3g1#BTgaB{8?ZYf7bAQk|!as(rC1Sx6RDk*_(0H9SiV(9XM^t^=h zR6wZ6FIbR(`v8!GeA*GY+RJ)#mE^>FE)M#TcGUG& zA!+y(B39D#eE_Esa4F(Sd%(X=4q!phYxL#%2uore8 zVdSH$F5H@z?AavORgTxLP_PAKRX0Y~TyhiS$)Sl}NQA&&hZ6$It%lw_YsRsZ=Qzg1F2qd+auPOBzd+Kx2#ke)Pm+kvm923MO}x|P-- z5inc=lJeYt+@SAONm(6Zjm|XNhr{x*_b7!5{<@Rl7^kTuj76=V)pRKO*l!N(Cm1{PBqxji)Bi3VOmc28*#9mB*2&`C4`1U? zp#685;D!Qs8MMyhO{bDyca(o%RK)N=%8*{sh(Tja3N^xrHj?!)l5rZ7MjOkZQKlYd zNgh^s%xtpL?6Kd%|LSP6^Ci*&fP5SuERGizw#>z=Krr# zod-BS0Nm%-y2r1D)OZo%BFDFgUQ z?o_{E5O$ST!r@gHQbLWoGf5>Rfdq6KF<=Ddl|;8hJLKM=&IZ56AY6z8*9q4ud_8W2 zsK~QaK;ZBuZcAA3vsVyjsawo}GjS`b0EGZD@S(~cj%6fJW&nUdY9u8rG{Jrlwi=7< zg|9&DBjEX1he5btdO|N;AU&QAh66ugtJs7=ofT~SsE!~QAFTx7qbexnr~%Ll0E>4a z`tefw3{ZV~4MPU>6urhoqSSztw2=u)pFw}Z1ZBabk4l2-U)9%VKpE3(pcqlcN&2W7 zry(hi857hT6KVqQWOd|cmV}wRsy}n~2~siOCmQcDm;9e9)RYNoRtBU>8{J16p`0v0 z%|2+0DU{iyAEBlIH>>e5#&}rKYfLesCXzIaF`yPdTa44pl==up1C{7> zW-`$U{lLkr78LP7`S>l|N28N5X!BcE$Dv~w3_8(i!OY3x*a_V=iCH+-8^h~QO<=}Q zn1xBqa*D_72`Gj^C5768d{d#H9^IK^&M-n@<`U4hpcwNVTiFlIcdnIrILs^9P`0AK`OUQkulr$2V9t|5 z0Dw?WkSH{)gdF%x46uY?)$~-t8G^y102UI9Y-b7Shr?LCk*cu5P$V*vB{&v-8R~6- z5X{EiK0IJeONaI=DqNR^gEsH^d+wF>#RPSAhm1$!)=~@;y(1shXJ-ZZ?i406zC=g2t+`J3v+rMTcg_`jZ={ZmzkpeS|;~WEKpGV(c3y2ff$P;zcG_@3_jFW3S|ajlAIRI(Pun(j1`ON#2LoJN;b@D z3Nv>cY6q9Ey|Y=rd)oF@p$h=^h{=E~LUvOvIT#z2$oZ_m!VTP86>XkiTJS2x(IOGx z*~oGiEK9CrQ!}tt(gERMtdhS3ugDh(XZPe8giE0NuQvOiD((M3B*2NG9B^`dItx}I zr<~0rOb`GnZDql|x<@Tf0h5k`lV&F*fS$68k|4+Bj$7&`deb6w3TvkAOR&K=kciR_ zHU}`KCM`=UCQ}u_xMgxHflosauA-gh-h)lYu}C+GNlWkDrsPTc66w{C!L)7F3=VJV zjus#9!tj=E1BxfyAvY=}EWP*6ipfZc;K_kXO-**4vG912X56r zd&~9q{JYA(*6#)yAQ0wK+ zgBerugz|Vt@DOHqnCf#sL;y7ntrD4vfb!jHu)0-s4AYhpA$~@d z2wak21o$rtej!v2?a=tpL2{pUF-UAjo>rAMh_?MRK&jpOjzad@*D!&Pi^SMG5;`8?81LUId#z2*7ay{a4!(^uD4kbZ|8^PvW z(;?PHL{Ln@xwYNuPor9LLT($~4Wpa-3X4lU;+OJzLmiz~Qmt+Q#59W}@GlF^hbw7{ z^SmiBk9~(zNgQ(()8n5YvAQ#ue7EhUx0%}}yE2OLuE=W_Kmg+GWiX^6TPF2f=-f zH|bZh0zIu(o+N7iN$5{D+&v2+f2*^QCB_Zy309p-6gEVgWNbe-^81Q#I@B&Th!F&x|OA= za1HuJOPkay_0yytI;3{Iby6U_4*NPR)OqBxWHAI%2ht>;9j(`{V6Z!h6L+%+8K?;_p87}iJFdQmR3IE^{r z;X8QdLn%utV6v_Q#awBrQjz*~uP5I2cUF$voUs7B&^wx9I3Od%73ns!FE83}d~6NkDFQ>X z>xG?#{!N4p?@pY5j^_#xqC4`Y*PjqRSJQHf-xQzFRyMOl+2`-+?lv?p&Gaqrf`a%uO$QIsW9EhS`q!228dXPrsue7zI?4n9q|gD>E1UrZ zvjNwaF4xGZ=moez$gs;)u7>K3jSIR7mjEe?Fpe)jN_{G`e(0;4si`saPVHFmChOY7 z&9`;cPMpvH>JFqg=ZS`^fvq{kvb{89|A$*US7U0oo@LMf`TX1xZK}vmEaITtY45J4=mQ7;co=r6<-M_XUX{7`KgU++c2*5vo{ z_km2$_V3f%a(gF5O(nJ^($;AFlj@@*)nKx&ign`!wj>OJ1t#XCozaM&Yao5(PpC2Z zP4-hm65yH>YE$&j+`z}1Y{kL&z!UOav&1wR_K|Nj+^x@pfApS=XnxEf?31SB1|rD~OuLROM@c zDo@K#)WIBEEn-MN-Q~-F7vj>*r#AVYx-BLSl6# z0m&P5Eqiv=o_K1r1;94G{7cuxl-GNNJ7v1I`KNFKn-^l~VM_1Tn7d(5Cu2H99yCkl z&{M=hw;Xjwi292AcW2k#(j5m^RiKc4vhd?1w+Q|sH@*VqW1Vfr9s^deqq zA8Qjpt}E}X9BME%U(^Gw^Q>^KEiY9|Dst^}txJ|!aTs_MrE?jn^}*nFGb5fu|AO}; z*ShCj*qhf654M&g0l>zclm0?3sqe(zR+L$^wV?HwpbdW zurmIoBBs4S=+~A2HX(*X-J!6v`Bp{~d0d(}ob%W+N z?!!U{>zd}rH=O5dJFc6zsfpg3_EmO$$I+Z^)_M`bcXA^@fM#$C@YnTW;BU`a3>1E< zI6CThu~dsv7)Wuv9??M|kNji6qnK z%zr$YCm*`O)G6d=|GFyMX|9y%$V1V!(6KlN?i{$NVnZYN)vvC&wgqASI6K%$b*(%IK+LuqU-yw&6}49-MP@^6@7Tty!nrJHchDr zFxNYE4yUdF*Bq2`+x`&UXofGAn@B_H-OxHe+b{;bwR9b$8=scCt#bhpTc5%Q7nM!O z78&Q>7{Jt=NY@OWE*uXR{?JORVN}T-;bI1?7Yd&2`@Q0hUG7SC`kuB#Y5lC_`t*}M zzt9UfUa}?UAbA3LtPCe~3Ggi-`FZ+)t7!6T&mcz8E1c7iFhD+v6{gS-&}5t}GxTJ> zWWU?vhkd+xvkBGe6YWcE3jgTiE@{X4}ZSx z8BJ&rMfPO455621kKPb0TYg|C`uPjXba0ID9E`uTcKQ^yX`ojh5ja>X$vN{_`}fu* zZMn4!lgL#3(3hs=DGSYk^6#Q(59V%rl>~AO?v-%LUf0-Z03qP-o}tO29zYFg5%4D8 zTG?UqaE=}3yZSo&GX2R#L+_0RtNs+T>v1eXwO0q#Oy(92Zca_@Otos#?s5vxbxnBJ z_gO4fX;cK`fMoqD-Yw_cJ#J3>Cnfg99>2P z!vsqDZ)THtODqNw;$Q-S!G5~Dx8al0XwRI7 z*ZoVSD%uW7JQCYPZaf~&5pGYAbcZS09{S+=uhKk5S)5lCo zk#To#e5Z`$O>OWF`ShLdmjAaHPX$erTRbOoKC&LI+jcB_JjP`*&N-Gy0j;O(#EI^Q zJC-}N^Sq8R9!h<=n{7*Mw=06G_dV7={dr&rRSkVi)Ji4&{a42=A>g+!j)j=KT$$#6 zu>;YF)oQP{EY9qB(QTk@HKZ-`k_vUI#=a5~(678m`cLi0;607wT3ym2HmxWhN?R%GN&G)&T#`s)zkDuEp zN}J8q)pXpvjjsAoo1Sm;P-n%Mi4DO8=?=GC{U-J_TB=f**G&At+J3+4(6#in zo%oQy7)IMtEh5FWa+sfHPluz%_DPWA-KK)U9AT@Lu{X%l5a4QHZ5^GXh?|(nb0UYG zv1d=j7&UsjznFIDmNQi~NB&+4-L@0%bG`GdnV`$>7ldFPOR4OC(n3S=(LCp>J2joOp7x_xn$5G_LA`L@c;Fi{++v3y z{5Gi|ymt8YN;@P^sQu{M$TenPbJUS=xS$Ajw&97~{w@xUKZpLyns_Ek$=8m8Ko(U2mEy|(gW$WgpYdc`)( z_0Qx{I9!8IG3b5Z!@|QS#wgW5vLvtL7sX=py1PipOz#*qQJj(8i^<}TQ}-EMkt@ow zD+bc>Z(X6rM`VZ?u7H;_i|eBcYyLD5Z-ss%JcQA6-ilMRc;-|;4k@GQr8mh!HMEjT z7o;lZ8wJfP&GN~ycbe>?Xhd_JMh+FtzV&@^Vj^4|LfTJ0^ik%GadLAT``F>m?)@G;V;w7>3F%TM ziHR8`dPQQ#$0VYXm)sd*Pn4IvpRAYZFTA3jy6$}ABJY7AGOc(zB!hX~rYMC)l;p*W zzK24eCnPGvbKcsA%FBj3=4%LqO@}Xk9Z_a_&ni=0Jn$jY??T?M(!rz!daV4TD*Dto zPZ|kWzd&|6;fPa>b#;NZ_R+3xf$IsE&ZlaguIgiRh8wV4yu6PQ?}jca2Sv4@7cqRv ziR>%0-pCU|z*NrTC6nod$}oX2pzK)-1?di9jh@3W*}JM6x3Y|5I-EQj-zs3(*bwV%&T&QkI1_h2?TjuM(+)jF+wBxSl<19ND#IEBuBX)VmSMVbN@CA{y-9x0@Otj}V z1id9jGf2X$?yWF2M<#Qc^||pP4FNUk%E&YkZ4P|#n5mxEPIE2(La}FGkj!T*QC<}u&pCLs<{Uk6OJH{~bYYlH*#a*D#P_^!;%XZel2iEZE7xbERb zd;g$IHiv@94NZE>lS_;T3__@i~6&@P6{~A6vgtyUa^3 zVN8CB{(iPyYXynU$63@?{j|}w5&gPP{=TZE+~9icK4uIv1@~e0#`Z@UUy7Yr9edobN%ta2qY_1SI+8uPDmN*w(m%szrjW4^yE1MZa}LqTxxb Wk35A5ebTiVqMQ$jJOz^g!T$rI8e&ZV literal 0 HcmV?d00001 diff --git a/client/data/sounds/horse_hit1.ogg b/client/data/sounds/horse_hit1.ogg new file mode 100644 index 0000000000000000000000000000000000000000..4f54dfae018bdc9caf0eb8ce4da48397654e1454 GIT binary patch literal 6364 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 M3^`|{g!%COAC9;A0{{R3 literal 0 HcmV?d00001 diff --git a/client/data/sounds/horse_hit2.ogg b/client/data/sounds/horse_hit2.ogg new file mode 100644 index 0000000000000000000000000000000000000000..9d628df6047bdd4e4726882dfb7e16224d0bacbe GIT binary patch literal 6258 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 LDMZ>QRS5b&Is48I literal 0 HcmV?d00001 diff --git a/client/data/sounds/horse_hit3.ogg b/client/data/sounds/horse_hit3.ogg new file mode 100644 index 0000000000000000000000000000000000000000..c13a2414b21e8c60c8e92c60f2aee9092c7f606d GIT binary patch literal 6661 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 literal 0 HcmV?d00001 diff --git a/client/data/sounds/horse_idle1.ogg b/client/data/sounds/horse_idle1.ogg new file mode 100644 index 0000000000000000000000000000000000000000..1a94e43fb7aaaa11c3c8bc1e2557fab3def0d1e4 GIT binary patch literal 10371 zcmaiZbzD@<*Z2jA1?iFw$)%)aDd|{1U}1r!Yl(-HP*Fmq5fPRpqyz+{5hXo=ddbI+WbnKS3ioV%;%QAAfIM*u4e4ACWZ@z;l8RXQAL8?@2{%ZmAEDV=o^rz-J>DAl5+q6 zNS1VTo@sQRbM$ItEF?6%1Q&P$0C?aq5-Nsr8d%kSBjk9s`}F^+=1FLVD{;_<6hkhK zg#?iz*BA({_5qy66Uu0jmM8x)@)LSESq@PtY(9M{3q_U+uYj?nYgYMV(xU5NtLZ*{ zoh#|0eIS&Rjv`3~`Bu|gvQWf-A>IoAfmHrW+`Yban{>)H5aKEIk4t?~1w#0xF0rZF z6(FQp=Z{F!zQp-ls=8`6TGyG=sV}<)4RuLr1FayW*S0>FPVrxsE50iugX>kK2!CNa z1BDE&IyAsk^e2+jXAc99(6 z^xj?2w^`5N{DlQMF=E|A)Q(~xq}~2B)E*o=x=qda;8p7St4#i)D;9v_lI5~Q=Rb@td>CEuFm^2xljP@I6akr4Y4GX-9~vkhCQ!g<|nRqu~JtU|flIh_*0$_i1f#srAA5S@POo8ij90 z4B!>{X0q_SY9rUBbgCZYj_uQ0NlzHk;sgDo2?uAj#i`1j{{AT{AR^1yUsqd@T)- zXcVaVz9niLX)+cFY92Mzouow~laQ06Xk?O~wJ&nk*m80li5d%>9t*P`3;a@0^wFcM ztgQHb$?x~VzdvqmVzq{KE+;gqYJk)=sd6{;b2q0}8>dB%CaD?vfm#Bs{m_%+s)K%N z$VBwzkcnu^2WXQTP{bX1KXBgH(lXi4($vxXBy8Bv&oU7`Z-Pdhpe@_S{N_(|hO2eQ zNBxG8e)D5~-(R^;pMqk3$fPi9kZ(L}(cfeCMy3JMZx(B54T|0Hu)aOj=pk3`Za=N? zzMPXpqw$@f<+RktM%@&@*)=AW#oOT$!tw%K=gp7$Mo3E&^yCTB?SVlVd=Sde!Y~BlIekbR zjECFjE}SnrPam$G9Xh5Atq4Pyxs{Hlnmv~c9Wvv~tI~%*FU(^!ca>C+QR+xfz`%I( zuvdg07=K0xc!YunotYrC)fC3d9TE#C62OfuaE54_imDIIPxVqOJrTPpMR+$;<)LqW14j<*S-4HSWuDn$r9#dLnW*!5J z_;>K=Do~Yc#W6?#RcXT|tLa^1C680hia~HCF;6x{{8K7F}h}MTo92ha$vQ*|8YJC4?Z( z%f%pEv#|)oKc!&Y<6g!+lLR*%AsDvYKpZh(49;Bb8<%z0+B|DIBax`48#!_WLzom06flV;OU4+_9efk_tV1j8816ySc-EAhc1%L-3 z*8tULFT_i@GH7E7Zd|SwLIki=*nu0I4#pw4Y>=B7yqx*C5mz`eWeB&!e{gx&n7@2P zd05Q9d|)0SwweXXf;a^HN)~bnt^XGXz07Q{s8H_zLV2MSaK1}E(6$uHVDqn)|AWK) z7l%On2M2D|zkFDP7MOxEOM|XTuf)rMq_cfPbc6NDmH#RN08NXrVN`}vkEl~22Sl`> zP#F#l7ggzE&xaZkbA)mDM04O~w;F4=f)_gl9smJNAfl)*at$CMqfj7J;#Ksj1hZRZ zhj2{^LA(gUM1WG17U1IHTgFukYgLRnxgV| zWd${b?+fcHO6uMh7nBy}V_(H#ld<7Gp?!7Cl^Y+&vT!u)tf-Xv@WVHo8=S}+$Ft_? zpE?4+ssb{@oVu?&4|qv!Zb`@5TdP}+$1VYi`34YSM+iatT6gW{gQ=yUi{P%pLd8}J z{!%46E;c;!xP9DudjZPc2F{)TjP!QzNCm6WxE{x$Z5bP|teG`QWPrafu%Ig94Cu$oYH?AMt+r*#K3e~p5d(D$eSB0yX+Si!TuDs;IWm^$ zi|Ba{g9#TkcW>PKO}RfVDOlj87uoR4cL%5OJ6=|(B8AA;a!q4H4c7KT1u?uQG1-K= z#4-y#^HXnv7?FC0jR6hka*FDCiY;&+s?d^`d2%13u zH@Y|e@sUHkucP?(2%czfrgG=6^~&xdSv_UFGu4aRf(m=de&`9lepJgwP&7@@m_rj` z1Uo+8ZtQ?+%||kg2H0`IcU*4!A$mCOHplN@eLQTpFRagHU{Co>8xy$;6j6^wLv z3?{vDy0uvH&TE3rA4&YqNa-;Ht7Bu9(%OypfzTQnzq+}0;fRN^*S&wV+WCHbx>44E zBz1q^!=*E?i|>?W{Ox$c+KJpG`Z;s?&T;MJqw6oeo6VkZ%Ba#jj{jj!xj4uq*5v$Dv*^ftHn^(57?3(Bhs%&Wk=< ztHZzOmm%Y~(raYG%WKxAmi_Ef(5!wpx-zroGjTn1wj`0VCMD%Nhj@375Bvv3Ow*Pi z94qxCjJbCZY2H$@z&yD0@e9rqoM`D?;$FPpGYa!B4$8~3U&sh)ro-Df*M!TH`8ru5 zh$HtS;%IUqC#pm4w=t+g;urA(GoELlG_1nS_*A9BiCnrEM?6zolLIK&#kw3O5zp*Jx!p-y=}UCL%8ETV$ zI&@;uKtX;Js~F*i8Ww&EGbG~K{HHkP9|AXuyV15MSdODUBXyk_1E-t8y*FE>Da|D9 zEWFcc{7ux&>xK9a2U125_gzd#HxdLBW~91a$`%SW>P^-)S>XVgb*lNhc3TVybq_h)v34?RyKXPpR^`1Jm-$G8@DFNyZ{D5}oF?Y-iXUcs z0<(RaZsBCt#x>TPF9v;ID;eS|!7Q07t z=2b5`Yw+7JG{>oAg-;4N|B1&lx^+{3pP03*rhsY0Z-ilh4lfX=5}-ke!fAHBS`Owt zTwnLI={T&r4+=jVGiowq-PSGWj#_AZwv>Uu*;wVe@08TL`MDF>{&hs@elhXW^Cv!J z9fvd~4N@n1Df3e7yc>HRysVM}fu<79o>is209Ww0xuL$M$-^anVd%p?O|Q!Dn{Vr$ ztEfXHsv?o3)5eoXm#`lAO)8JZUP)Uo)8JA8jd-D3`)LZqiDF|f5(w_Kjt-AeYJ6xO zjJ1l!_Eq2vEM4!dJc`-bOk|ty_zG3uleP{-&;81e8dgF(V(0O)SKqkw8gm*4K+_iQ z`u(J%Vqq88wM(FEOLj^S2@7?Qj4mUbGxJ_Pw$8q32~iK&3K`zu^*f|;bE5UK0}pe{yqVdr!+g5iwx3}=aE#FKXdeZe81(()QoCJeTou4 zhpLs(O-CsPI(IyrkRf|lF`H~5H~?_hMPP6^1!ud~28TZcbHb>i`2&@pp>iWfHkMPn zwtcUYsy&2^k&1c#tc;Oq(VCF*$@vrNC&14~i7)$v;j;I`;tPFbc5^V}Umj>lsmYBC zj3vCg^WppT4`oEt-PeVVHfZV7K2k`$saZS-NxQ=@X?DY|w}f^pwu-g?qCOE-02wz5 z8!xZ;3i6cZsN`jH4FbdSV~NIP}|Qb51OC zp8d>gS##*ZNgo(4pZcV}W9t`b^l?ls*m9aLXG8w=kx<;@+q_}7mS*7`)SaT08R)E> zhQ^Y&13tf`cksJ}(;le|yKnktj%|BHmy--HP39__raR3~0v;444~%dW%vvSNK2gey z-DOBlbINQI!~Ve@Qptt20bG8s3nIoGw5DbP-gpKnoUAg2dThw2hHjHn9W}fnyYp$KC(HD`?PF^EtzTM|-8h_Vf6h_*0qnmiDQpaK zWaMYUiTu9t^lj-pWg)ovVMAb||2nZ!XRvg`>GpomxjO925v)%s`%A4tW=Vy@$Ct>K z;xbwLhprM02!BE>U^Qfq%PPZdqrK+@ry&h zn#ps_(!{4_{1?qm7cC--cEyvHtD^6;-9);KG_)ui9HO*jhz^uz&3J+(#N@ea@=`ea zy3AJZe!5|eJ(Oh+w;mA+UU&Q_@?<2Y2s>fBV59Dg%@^Mz2Q02x5cfF7sffgu%$YQg z?|VjU8!FpJFRy*+cymWdZ)&i*o1DOR=kWv#zG+91k;P!NWk%D>VlIvgoJVn+mY6^Y zWOg5-JYP6hd1YWWt~GgC5$FmT=ySN%Bw61%_>hMBI&_x)T{t5(N=tZSWb_9~Q(26| zD=SSC>c)%dRm&JH%W6o-kIJ#}x|CtgnQQdHt(xP8?Bf3*`xs(R7tbYgjec*-<*3|A z9QY7?3tFSy5x}{@fkQ~FOF%*d7hojJKH&a!L**NQ2}RL##_ z@h3~a@+kqp3Le&kPcfiE=2egCx6wFMdz&c^;Tz;igzkJHsJ_;<9n9U?R2 zsPT6XV>#HDBGrhONKH^@-Y-p?@I|d`xKU%TB-O2&+4@GyXm0&Lrf1;w`X;{&m*Z~_ zFby&zWVDZ5yFss;BQ_dEch_UlbdgAEoMkH3d9kXny>s~|b?5B!!7P{0(SC!pOuA`( z`^2d=UW7J?y=piq&=~bSzP#=_-=p1!$=!l$X{00=D@Ew?m-k#apLQ-@!ng}J*yUmDWnA5`9<2M^UE+d72@c-bM_6vKJ{b26!w)yG|a{;>%kNkRZNp*-s<66 zJ~gWG0751IkVU>exT9idsNB`YEl_`cd6L1qpl9tuvi@isMcaH zbLn!-2X*Cw&8JI?R@QbyUP+jcb~)D$o-!P*mkBha0v+Bpo;$<-=klRiyD!rfnva;X zet)`wtMo?E;iRep{kXR0-s~%7kBE_s%$qE3=pf>T1lnqI40T}%Zyf8`aWt#YlB#D^ z&fFs>k(lyIBcAr=TPLzddD=a76forA;nR`tDckd(b&cpK2VmdLrV zxOwr5Ps^lScehYq!WW#2-upRmd|NSeV5uRYbz9wic25U}T~ZyfR*r(Zv&O6~7T;OD zV1A+bI&k`2*hs7ILX*abIwY!=O|dkm1A{d)ktvreqFfl!<+!y=Y zyXVfY48{Tib(rFPB0UcctLTjDPQI=-ly)?R-SugeZW$E=`Ht1n=fKGKdAO!PxE>rx;iyXr*XD5VlQ{XE_rdrz&VF$qo|6&6`7t= zn=JQWHR8GdMAEh8`aBPT>K#e6=4b9|8(GEdyRDG5H6>W_?fjY-AG6qU;YUjr$KQqj zzz{lLJy0Z@v`U)wJNrNOSLS{k6BBPGu|4g;`fB97y36Q#P9fVG;4PvbQ+ns-6Uxpz zRRgecj^Vmd~;?H@~x-;Tn_q zM;{qQtN1oa97csyRi}lD{jvLLgTJ=n{4$4kiQ{)N^T?XESo=nDrP?JQO}re(Tf*+&`7fW=flNUEatXH#t_n()g4Z}{3=TtbB&wm`($<*T3 zd|e?5#CX0eo78Ps!{BM@i;-lY-4bkmoV{MR!Ys>j^)U798jwdtnQdOIM|p5jVHQeo zz06yAlS0&kPxGCf1?b|>qOt8+BD4DeH#(?AqS`*8cDoOiZ&(=H2F6>w&0qdlnz&d^ zT2tk_*|srSTslp=$lqbhFeRqSs{MIlAiGRQO!R9AO}TTq`b{rCmRMolGJW%!;h+4) z%_hvk)?SPv<8e_NKaqPsRK);=buNRRhx7&`DrC++^&BBHzdAlX9E?&Uun%y#$x&SQ zc=7e3bx>VH3G9=;bg7!NPD4-L51hG>{(fgS_%#aEZ>&DK(#4;dEn8nJa2->Y=8lwp z)X|Mv_9Nwygjx!^Yx?@+-f8FY>|?>reLiMA%2ECK1owBstVaD(HeZl<^PT8ha{WSl z?lw28InTzo-OZi5A3AT+Bs}ZTCDr@7QZ2(2Czt?~9FgDxnWrR)GW)TiG5l!@i?I_} zrh5BK_Ie!Bt~lKg49S4-uS|C4@ysPGlL}J2@?h83XTw{IYKDabu*L~Ab#$V;EF94hQ~isZI!SQ-%AE-fVS{WNdFuy0$;JVmA4 z_Neh;Ki|4&EAMae!iuBLnx7cM%y+8JE$?q8IMe1ud`ckXRxPr)(-0Q6Q$=X=2S;HY zn-f!l4>@{oc=&0yy>DRq>sn?$o*|}5^XmgV)>VejG8en^0j!T2Jr0e75ANSs-g~<$ zg8GuWoiVCf^m*pn{G2e}P~^E*cAWIoOUwDg!IOk{D?wc^O>0L5Xi_uB@03vc(5)FA zG~S~lIEdrGbGfmj0Z}oNB-+e&3QYPPC8?EQK{#>ufFNJ{{_+avm;;`o_%wC@4%g%8 zx-DDMiA_6MA4t;bTpKYF5VRU<1Lw!XS9vG?rNTCrb)bIL86IuZ$u=ccDsNb->lrLH z?whV_*CjqBxglA!rB4{6G4X*9mGo*(V7DasyOK~?Xmb?XvlRxrPUa!1=qI6@0Wq1Q z?p6_BMYdnGHt244YV(hJbn-ObSZqqjlDvOJ`iu4{e|6E4rK`U+2{v!63*NgfVQ>v#UCnjWGL8w;ob1(gxcMU8g^5d? z{n0P)_YO)68M>7WE_QvCb7Bqo@fRYamHroMh|Z@`4rN9IMfHKaXS1toFSJ6`LT) z+6x?ppqwB4mZSRd>*+a36!#`a6 zT##2qmfm}^8M=dAk0(kGYN%!-xTXCh5-MwS-h~bCB5dY~59O=7OFqA3Zzj_F{Uin{ zyv<4WdaS2Z+|6R|LB8F63b$s=T#9H5WNqdt@AVErd|<9BJt;(f^Y+cme_)=Q0lf(F zc%MfjVaj+oO0D}DjvlCQua2obS0qKN^&;Zcskx2rF(`>fD+VWgTxU{x_qw-EK<16h z-CH^tuWi&L=(gJ5XYw>h{vna6b^D&&2XICDCQeSDmoSc~y;Xe5XB zoQ`iiq?-#+|%H z^p5RaJj^w#X*wT26VG^h7brb-^XH>eZF|d>q=ur(#K>Jox>3$8?{8ec;+$^f*M#d& z^bw^1L^L8nq<7eah?a=JKM(}hl|$MIZl~917T#r&>gwwoQ01VIC<=Rv0}gt$JMIwhl;ZH$vLd}YfX zBWY80#MQdlcJ2ck$-a*#KO(>RGvR2_(gTBzS(}aw{Z&)6&0@9YZj&n2l%5}3Y{KVB z za_IFwTxm6?Cd=sSn-B)Gi~`eoI=ewZn%mk6Pu0x4*#4oJWKJC2cmn3wQJrolpYV$H_sI=V*(JKgh4SM~)qc zf}Ke;U5-q)bXrVz>FdxImOlD>%mcua+s#DHv}6UR5q1J|RcAh`9>1=ihO|+=VMeP0 zxcaDbmz=*GL1g&+&ImRN@sv}IBCwO8f%II!P87cDE%RMppHapqdZ z?K6dFR%nxSGRZ3(zKHd7iU=?{I{G^%B$3Q)Lx4I|h%64v48v*j0_DpmD4hQX^~K2$ literal 0 HcmV?d00001 diff --git a/client/data/sounds/horse_idle2.ogg b/client/data/sounds/horse_idle2.ogg new file mode 100644 index 0000000000000000000000000000000000000000..d7af74f97052416447d098420e22fc4dbd09a042 GIT binary patch literal 8938 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 literal 0 HcmV?d00001 diff --git a/client/data/sounds/horse_soft3.ogg b/client/data/sounds/horse_soft3.ogg new file mode 100644 index 0000000000000000000000000000000000000000..cfe4011af97ce263dc883dfc4311f996a3301737 GIT binary patch literal 6609 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 YsDaENL7bQ1d_{QP^Y#&F4^+bQKj6qcrT_o{ literal 0 HcmV?d00001 diff --git a/client/data/sounds/horse_soft4.ogg b/client/data/sounds/horse_soft4.ogg new file mode 100644 index 0000000000000000000000000000000000000000..888f4a8002275669d3deac3a72228cee760f356c GIT binary patch literal 7351 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 literal 0 HcmV?d00001 diff --git a/client/data/sounds/horse_soft5.ogg b/client/data/sounds/horse_soft5.ogg new file mode 100644 index 0000000000000000000000000000000000000000..d548b5a75e6f4b6b9ea93df2663095a6bd2b5227 GIT binary patch literal 7540 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 literal 0 HcmV?d00001 diff --git a/client/data/sounds/horse_soft6.ogg b/client/data/sounds/horse_soft6.ogg new file mode 100644 index 0000000000000000000000000000000000000000..8a5c4aa68f70d6bcb4668ef8aac40d23e81387a3 GIT binary patch literal 7297 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 S1k%6^>`(Juj?fNgW&1xa*SjhJ literal 0 HcmV?d00001 diff --git a/client/data/sounds/horse_wood1.ogg b/client/data/sounds/horse_wood1.ogg new file mode 100644 index 0000000000000000000000000000000000000000..7888040913d0a8e6403e0d2893442c23cad6bcda GIT binary patch literal 8756 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 OQ3C7%>S#DO0Qo=aiH9oy literal 0 HcmV?d00001 diff --git a/client/data/sounds/horse_wood2.ogg b/client/data/sounds/horse_wood2.ogg new file mode 100644 index 0000000000000000000000000000000000000000..5ffa309e18741582221a231f2c71e38986887ae0 GIT binary patch literal 8455 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

|t^SY8j}c!li7l zzAVr_+H-K&>-5a^GzywNEa$U*q|{;C=Te#_S_`9M64ogH=$^%MgLu)48A8RP^2vRB z#+o`n?EZR>v+K_mD+6Tq}3B>34y&oBSGDi95 z7z)}xFR$NF_q^EID%emUB3O;t-ptm@Wmy}U^U0CSrh57N^c^YlicyMT`e+62p2;j- z>{&x4k4BG&7OasY1?juH1>f3EFxz~%DGqP>eB`#65q5T0nU@LtJ5}Rk*edN`jr<*E z8HTY^cv8w&k6@c8I7bd`XMO7XVwnEhNB$E_LgousNZb?m{>*Cks5~a-x-b|5}&tKQHHHbJ7 z;gDqKT@bjOf8J^{XIPf0(A=wk@Z45h>49j!;{oH*nQJwLSYAE$EMLt$1N;KbNiEZk zh^;{zO5jFgplGiMV}D_yU-a#<-_|J>#R>rN;Vni9aR9v;v~$tq=~OQNvcq8>Y^*j% z$LHDQ*C#$|nR$P#Xu0@BcwFuzle)r z=ja07cB^+jw2`n~EqpX^{vH{ynS<8d-=7h3YepiKG674DzDS{ZB4*4?n~ z@3w#BJ^htCj5JqU@SnbX?^D^hZ}3aHH$}f-5)|1D>8JtDXc8Rj7$A;V|tDVmk?*bdo|UQ0c^c###%{)A;S;l3N~%lrxQ_5G#kz zDO&g5i?gu*Tv6DUaeDhy zI8zFFjYJvuo`hjfl zMp@m7>1U|3EMwh!Z{K>|&ReTH(oX@n65CS~e17=Swj1R5HwTMq6)^F1n8pl-g|Z=P zo1F75MvT;kZB+`L=|!iVe7<3OP_xD>7uj+76g+6nu$ImITiH*GYG!ve(Vn{%kr@RR z5_2^#u}~S0#VW0JkujyOQFSuYvbb9-khfM7so!Lv#mu+lRcD!#(vS%zN^++H2D1;Y5vqtrD zpKNTH^>p1N^^T&W&vZC0&XsR_FPvA4QtD?bd4nFU9nn3r$N7W`*%}@y>-=4$r!fm- z`J4Mw!RO>#uy7OVol;3+=^NQsU0GsFPntpm+9OG^`b$nX`tKfjc-#0ZY!UTr1@}!{ z2r-6oI|36mO;*Mh2FoWJ@G&~j+N8@7qU_o-|iYyHlh$;NY zOp`#ZI36PZI=cA)v;Jf{+<8NA646rOia&u9FTW%T`?lA?>T8qifRu=4GZx#=8Veh- zXC@Amc7|1L1^NuNjJ|H;GVSjA$lF5K7<`e#MS=q|T~KZ9${#$jxR>_3Qu42`@NW(& z5|>_eIu0&&%djHmk})<148MaWE;Dy@QGPd3O(+eXx$#uaALwjs|1nVgbF>wz=m+wOx0dh7NrhW}*_J!%VoPjE zkfAbJ_cx9%7s=+KqugwLK-G%T*f*t5>;sFn5~otKbP1`w@ttHAa)M(iHY(4P|uQ-0O~?bg#}EXi0*y z{v|ff$6vW-v8e(<<#nbKBDLSev>M8;p4q03-7aEmBWSR!;ckfQ_!o|h)jm!vX5vKI zm{opVJbW(2Yi-ozEZV6QM5F{gIhbKrKcpQxSzDaV!)iaE-ytkUP4OZ|ML=N#vv}s_ zc`3o52!S_>;am5!^fTC6GaEZbMTLyGo837NKF4x<;N>>Vj0;{MPgy8Fn>ihmr%G$B z{Lzu(x2I~b*`@+^^Kdk3cfinZt@8XiKHk%Ow2}ASECSyzy``)L3_dODj;~t)f2|y7 zim896J)q!=9ZsLsHi;_ire6h~ZweAk_N$N1b{4AB&4vka(6Qeg<`eBzrmXB_Nsu+% zxsk1ZV6LL?G#%b3hgLpS+q<2vxI}dK(yKy8TvSmuvN-$ulw*aEh`ZW=Z<}kRQ;jp~ zRO#~V19aIZF)QGq53^eguWal!iW&;hpzAE)8Gq1$)@qcwo0~+hpSeq| zjQMSEGw5DsF~ppp1^DyUODW#+q;h}Z)THtPuC(6&&H#*F0JyXApF%xme6Deh zAEqd;^-By>?)mP-hgkFvjcMcx8UQ9D6hNsT+So*AAc9iE9LOzIRq^!<90dTD{{xrl?2-Tg literal 0 HcmV?d00001 diff --git a/client/data/sounds/horse_wood3.ogg b/client/data/sounds/horse_wood3.ogg new file mode 100644 index 0000000000000000000000000000000000000000..504bd8e7f78ae4014767f4ef4230ee63579203d4 GIT binary patch literal 7321 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 literal 0 HcmV?d00001 diff --git a/client/data/sounds/horse_wood4.ogg b/client/data/sounds/horse_wood4.ogg new file mode 100644 index 0000000000000000000000000000000000000000..26689281a21d5ff408ba276be4288e05c21bd3ca GIT binary patch literal 6877 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 K0}<*2c>WKzZrjBG literal 0 HcmV?d00001 diff --git a/client/data/sounds/horse_wood5.ogg b/client/data/sounds/horse_wood5.ogg new file mode 100644 index 0000000000000000000000000000000000000000..596e1bd83d5421872635c373b64d45d605ff34ef GIT binary patch literal 8467 zcmahtcRXCn_ZO>+9#K}b6;_MIVx#xomQ}M6y_Z-k5#lHXl^NHui{^F*R# z-*)pM>Kg zu<~kK^1O#?5BqKKXq&RdLgh@I21RihLM4UTNlxN7Ml&z~Ss+pC8Ydw|i%y6js%D=R zC#D8MNhlEKL&mXc|I_H9yg{lK9Y5i{tTI#FvhpF6pog+&1#xSF1QzY)g1BlF$P7ao zTE@|!)}VyvQsODG-LlPG1PD?*HTHw-i^(`f?WBS@Bjh13!At8J*Y7c4T80^MG+HmX z3Hn;#3}{fzoPaRyf2Ck(&~0ASU$;_SNu?azev z*FqWTPB~D6`vA~^e1<6{hUp&+vtSNcq9=7Fxl(HI$w`$v5jO+?ODiV5E1a|^a_#^? zSE!sqvQHs-r>rKW(-9J?DS;ROfPlj&=vb>7Wb2ODU}hQv=KrfY<$Ca(h=Vp{9ry99 zph=RY;-NX&2XGoOY$>wcG5;7jhTE9An7#(JM0{W9z+7Nli{d95HiT#0O=&@`5^=-* zD@4RF2o)0@mP6=qz3B_}w4gYCelY|nu zLk8ewg|WsG73IaLa)VNJLnqCJjp{mP6(&SCtBzz%H`+P?Ic@K^iCQg)tG9LZt7$+R z!%5j_h7%Zrl)R4VKON z&oaRc1%f#ZPW;X23Cv_1_HtaxVpqX}L(Pg)Z$bexb{cD?6kw(3F@eNdD`GLW0d~0o zPL25aJ09}~QA__-v9u>kWCwr?St9T(VR+Vi<#d>lruPd8K$C_Xkty%Q)88v+!Hlv* zeX_j5bIbD!KIY$-s61f-SjjBpl2UptrQ%vj`L*=5q%80J-13S7$$`?1)`#o=Uu8UT za2NoD!VE%S256Wb8U#+P8^c7lF7z)1OfN)ga9rW{8pk-)K!e(a{ysGR-T(k#>VM2R zI0iLi7o9>&W2~j8(0WtWnE$VsO(>XgfQF?f2kfXLZm8x?y4G6tofqOIg)`=;m6Dku z@mS(2E5a?W4~@`a>dn<6WK)Aig8)`wTp?Z{x}hP%MxS7M!zc-UQZLG&;=!bqac!xi ziZQ9t#_v55><);N98IeDNj83!wV)6{3qFiRqZy|uG&up_1{0bA9-r+x3}4Ma51>|{ zt|_Q8qT4V^{9g6|O6=Zkb~p*_!dHpe!$vE_+v7&!pnr5yfRDDgg1a8TDh9j>hML`0 zFyj<8(haToM#yZyw)8H|p z5HM$hS>(b@HF`MhN7?1#7v;_7$X$?%2fNtDfW00JVCEG;D$*(xYlZP}05ykU z9cD0g(@~)2DQmO2(-=%HW^T#@lZ$r_#Vp!l=VmYt(^2!&@y^px&&w-Y0|y>Hta?)Y zQ5etFd1|_ zmcq^}wsx51;TPBVblxf@C`{A`fch3gvCen!i{9(4mNpoyoyXh(#%@0foW$Gxs3mU9 z%mHZfgsI$nE(cMhO~xEdV>~#6)w}?#ef0aaqYk-Hyb~x}JJj(|_34$+1a&axX`lc= zX(~E8@}Uo7{03sB@w?b7S!$ zlBKap5n);zUK@{g^skvJaJ-2mj5~^x8Z3=(R*-m|{E+&oS}%yVvruBB>=VKeO5$D| zc!Yunoud@I#~vjn8kcTND@4jNHWejt>qyk*WV?cdSx5hto;;j5sVB?WUzB9;WQuC! z#-)=77dsi8)PP3&<>1huDi3C32~d@>F#?b>{|<}GC@pR zqHlr(6JrFZDzJ8WTFYCygxyVCw3o~6VNCTYw;wo$BdBU++6_#8sF=ay;av6& zFzzYIaSstPM$i;#B_UQz6zC8u#OxHrs$dBku>vKa z45lTrMNFK$PuPJZ&{yd)!7DN?n|x1_AyPK`zq#3evb6t!sDVQZW#CX_wh&&ctXU)^ zNf84o?c^rqg)m*9ha*!_G)39jpru?=5p<-INk@|$9ILTWMZ>IXH8IW-ZCumC>jwJN zv}1Mcbb$)!w_JYJs9C77k94m+Zn*s*1MP>HcEoM9-Z?Gusm?T=ZXvL|`=*C-Z@}Wz`0ozpeZaF6&<$8vPFr+^WC%ve8Ch z3JO&QU6or)j0eNz@__!#*_adm)dT>}Zd>c*ds;&XuL>bLM0tg_F+2gGGay(Bw`LHE z7s90oQ5N;sn)HAdJ1YdB15F^SX(>wuFfp^L(`t!n2G@hxt+soDp@I}7kv0clL!1U+ z=fpoyYR32Iz3QP3<#`h;vw4A4n>CiT`yIew*x5y|q`H$Jw(tgWuNX~B{+<9X0{{yE z^ii|2jY0JjdT9(2`)CcpY#1!fKqoEGDMYEOtB{ykRNFQ7c87u;Oj7IUUA8v#5;G=Z>OasUiWwL zvbVIsnsRbt_&>J)Y!JQqWrwtqBpqP0dQ+qJ{sS@32&Ajs*nq=OiSwr~@fs9VP&aYv z{O4U;1=Un8Of#P}jGP_&!>=yYJB~a{k?tt28=re9W+4KYdOW+pu=m5P%p~i}dEa!z zp4Y9gogHzKX{5`Uv1d&&RzRzDT5F5-*#?HOM14qy@`Zx_8BxeX-yg2+hf#6$@g*#E zTdG5RS}@?%AiAgN-496*KL&SYCp|w$Tdtcz;X!VmZe>+BxJmC1lbaPEK66LX#j83S zA-Xj_DdbVN=fk?Pl0>l2ijTUVKJKI0)a3u~0 z$amgjM$!~7_ENzwh5IHUhRb1_%Zfqk2_inFUpC*3Elx|cjO;+NVSedzgH7x~PS0+9 zc%bWz=i;kOW;F9nQ*_*5qh6;E1meoInw5%3AW}&3`*;L)y zCn4&n@uuX;RmUKFROIaL{iUJF(c8L0$Z1#X-^{$raxj6n4;^`?86CB(D^_` ziq}mW{;70S!rlw>d=c_q*_jtENS%`q)qULWdteAdE?pSdAGu$nvqV3*7<~b5hmCYd z$_Ng5EK$2|anUP1Rj-?tQ#c|)OF2?5jwIy5hpHrLby*gk$-g+6RX_jXGICc#CAnrk zSx>{{Er;EGwJxrwFWK*A(%5KK8#uJJS6uEU;zQcqQ#egR6wjacwTbl|7ecJBTlR0ujnS*yUPR1 zPlf3O^*aupysHsi=Y7`lSDlEpI=IoaoEe2z?&4-;#~*HH7bDnpA4ewrJk}T&O)DRJ zKdDY~dHj6$y*1tbwN-IbTG%N(*K87SgIb~Ws~ zcMGHphF{i=esF!&62C_;;aZMiGP{}ToTdNvDgwpEAkQXeJH#tCR3XVW9q{eg49;(= zRqV`|LEm0XsbRSl+lhl)e_u?}_U!*efpQ5E;Ex(0os- z$l2nLrSDTN1(jcg)hu%F2naVMO<$M()9d+l(}4V!9Q<4{cdC;;kMEYHtR?JxwG@1^ z!{ABdWZq={UH44l>=6E0wAx^E&Rto9{x_@=DGzJ~ESUU-Di%ezZJ+%K>oCWO*nk)9 zpAF{t3^sY5Xq?nEbOZee#^sNsr@l8HBOl#ZU98v1L^s;(aqC6>+)JUfVm6(GPWU6~ zoA(AU)u=%2p6lCH0-!QN*O5-|;P z5N>+ge7jdX5t65eh=TKbyylUJ&u0u%)K{8~tNfPG<#&syFwslp((~)WtCS4lqF*Fa z{7*MW4#DekG7(x+kl?9ciJ^i}O7+I-RuZcwp;vlsD7{7+9TJi*O~Z(*XZ1X@g&#Tl zD)F=aABI29Ui|rU1^X9va;LG?&N+bf8!;jI-NIbym;7`t+$~#|7fEU5ohX6WzUW;> z#?7GGyqx^}W&d#^mic|@ZO2Nck4rP`dGv&=pP5UJu0Dl5h?{qN6z>(vR~mOwsV_q7%(N_kOO4R4+!XFQaS2g-3#xf~n+1j*FOux3orXtWy|Fkl zEcSZ1P(7z)clI1pSyTV|*QU=F?zl|OIpzr=q*XJcd54Ao3(n{5Q<+GW9R7m0$FF`R zJx?qYP%QmAO(gig;F@8L&S!hkks=)WmFtNYtW-YpBmHXrVY6_M&MooJ13&8cCZj$j z+|UOAbKV$*LTcb_BXNjn`-The=r$`Q)pfT`Jz=epR2z03&EbGH9>4UxM!(G~{3=ax zRy!u79|%)kgZk1;nyS2eD+!nn$~*yHZYj5&*=HHV80bR>6hq4xnrUAd+N=_PhmKv_cX5xnyDMwQ1y&o}+iKl+kCHwoSdZnHce73V*b z*JG}*-K-F5=DK#yi~7cb3gl-4bP+NzLZCRcWlir&5d6dol(?ge=(>E(G?;t59q)2~ zQ5(tlYdj=qMx=PY{!fL^X?F$!uN61=j(2>GTv~g+RpeYC?Y`e#N6GR;vWh6y7gzoK`+-N3Gffb&q^qG$Kf4b#~U#o~I^(BJ$bj z>Z}Gu>m*^fE4w5_o&$(px%g_RTfGqF^0sxVukco^vTJUIxSkM&cbFZ&+glvA@$S96 zM~ZeiBjtjb;ehe4HZ(;`R?h2Tesv$ zkgqP^-3mYHlz+-=*r8gI@7)OtZ@Egp;9AyAcz0|5OKh{mTfc6j4la?1Yn6L*(TacE z7)YI@^KqW|o?gq#iogorG`ZZ_QCc$zTspd(a93CfjE9T8K03nUj`owlc_;VuqJ~Y= zBuLUnJyBR;4A(m~9mD!R?EDtKiK>)iGXlB7+l_RTTcXap6lKN~zs^lq#_tY|vOLgg zyj&D`)pZV8p~lx+mAEjvyS$~fIpLx5SBz0lnb~N*^g^!rKsr~GEX&p6=c)bNtjg2& zYtg8O2a-1gZVsp|z0-w35^9-dqlT~DP#iT~gCDDHpALA!6Wyrlx2p38zj9Hr%lyk0 zy(oA6GKEZZ?I=Zu)MrDlRxFbGD-C$NllEk$*YlL3rrD{7O}_2B z#!tV;xIxwM(bf!aDiSlqk0$T2h~a;(XRCix4c}d*{NQX~xLE3xN`30xL zoEK~G5HUSdF)Kv1Fu7HHeYPzjcImlJ!0Jl>t3=!IGaF?s3He^kNw<>cqAx2J1(nM} z`TKz3(3}sqPZ!A~U8on*Fv68T8Omzi(-WL}>PEjCa^&9TZ@+K++KKx~!GyEqdic=3 z^t3ZErR~n!7*C4bpnY{VlFftIJJ}K=mLgJyc|6XrWR|P6(T$PA_ZGKh-!coVnvE1I z^)%|N!9+YcXUCt3_*VoQ8b(3+Ms{0}V!Z1-d%?!U(Q_INze1AF&e&ah;08_%Vbp0Kwwx${=*FXsdrsT3mlIMF0wRzoFWS2y zDXzKX+is=tEo$x3C^AL7F8f+MQCA_YPq=J2=W@sIj(Xqz z)}*I-RS?d2af;4b=hSV74<72_HLEVrelS>vgqV``Lo_4l<5l0N#2xwBF#&%7VhxL(rtZ9M<*LrwT< zWuL>kJAFYz;vc}9_P^>_n673_EX zRL*!=`+auGO?Ew*ZzzEFuMW@h^bL7YUoI@8ba&X1jIruZJM)V-BradhJOJOd&Z--I`D(5}?nV zESxdNhI>RzdG^+ou}*G1?+zhn(unJ^k$F|0zvSxbx_{BLx=J<6q-QEdMq}}%9X5~b zo<5h@myG8LE!B0e5X#X%x1p!`o=FGR^;p1EIH1>kpAxk$xFOo;VY;lpjRXzz&n`((_{(u0CH<^+?oXHKT=ZX^c0IEKImY~nQ|y@Tu?EOlo~TlmG_Nf%A9NC-iZ%Lmnuhm{9t2WxN=*f zk%1f7w4m;!JaQ)M&2A%-^}0|9`qOuHig!xC0FV)ju?tfrhx$wkJe*RB% mr5R=2HkSnelZDKKKZupy)GH~;N}McSs%`SrAvqiVyZj&PhTG}@ literal 0 HcmV?d00001 diff --git a/client/data/sounds/horse_wood6.ogg b/client/data/sounds/horse_wood6.ogg new file mode 100644 index 0000000000000000000000000000000000000000..3df5c94f7660bcb8b3736603acde485624f1afbc GIT binary patch literal 8464 zcmaiYc|25Y^!T+?(pVBg$kHy)zPz&%8(-YU!zD;D3E-Gcowz8|J82O{8e)Tr0O~NUz3Ah zlvcP1laivap9L=$FQ=Q%F1{)t(Fr8V91#UP+#LVPQPKT<3L(|ar~owp5XNyyXp(T8 z(GVV_5%(f5a@c*78>z<{$t$gAJqX363Kr%e)}AcsPi2qu?OOe{U%Gb&!f+BajHZU$k^92uV-r6YI16YYu!LxM#uJuw;5q<|AfI+Zp?1oWcABtd8uX|y-zk$EtU2n^N8;K5U}VgU^5I}Ol5++C z#yrIYl0^dPdcsP43S)F^IW-Ug0JPvRvg#(vS_F*|Q|wf|=iLA5))_9`N8+FlA>(e> zO6lXJXt?Q*)&ZPG1Z#p+SH!vfF`RWkMtU1e^rW!CyIz%A6va%NVv=hP4~f|MgKaS8c<^tjN!m&|9f+c7mVfd z9S|?hi$qJ5mJ}pO4@y28I=WrnEPuwL#0=|#sGqOs!kBoASYV-h8Q-6=p>8UQf-$~(r&_dop$?+7c@m<{X~ zCZy#iOi)<7%Txy5vLV!ZI>u%{bRO&ncn6CN7t8?+0_s0mr@*eM%h1y5snmkBu=6L}k~nWuS% zr*%DkF4JXhKXl=LbsL5w6WIXZa@slZG$HY{Ma2|h9kuIy5`Y>#B_k6)h@~tlrU~n$ zLEX|^gEC4UWUoEQl_)!60U#6>N=qmTOehUZC<#nijZeG&Afu!-`}{!BW^?7n|F0iE z3UFZn@DtYZ71qKCqc9+F)KAY)Ku6YT%5=}*Y&vxAOhq9p976>g{^GX=3)p4lf>m^WnrUoM;) z5{o3RKwwT;y%?A}b58~$nm`9SjTSHl^9t4n>*Dnt)>#)u4Z|h)NIh_^(#Nlj(bYv( zN@!BOsrw=kd>s%YS?NCEBbmCFfqQlYzyMyy^G8!pQK@kNz-?yCG4U9J>{y z+gMIv%_l=a&14h(nNwJ726l$*g3Z9&`C;eHY-XmgmXo1#lQDLap)X3xn!N@pE1%Sq z|E#(Av-#5oL1#jbG9j{tF;?Ha&eH_%Y0ZwBI)x=?piJRV=R82U}Fc0o%XU*m~Hn`e(LEor&{y$9J5w? zm88v_d~>^g7Jh#9jQV?pSlNkMPf*{ypN(B6e*XGKvymy*#@uCQA8WoB3QpqvUg!cB zc4{AVc`P|2$6-H|v~@fkTOR|?U?t1b#v*KS^;f&JAKn_2tsZKxRBrL{i&X`4o}L!~ zsP)8XVq(h~fe*9*S2R&w4-wB11#Si6(W#g&uIM4SI5!T16fcdzU=q2aQsE*{oB>)a zpJasA&5xc$idV;AtUM~n*;a{i(c@NPq&g#XVkwEo+FedF3DHNqp9U8t5snB$aEY8K za0>-DIx9)>ZVR|5G%5wnAV^9>>p@9e>JruI1V@lCZROF_orM!4b*G^{pd<@xJ$OAA zE`>6<=+WS$It<1=9ftu`xv-!mKvifo44f6HiUo-VRhgi{Svj5;CtILzRD-H?VUtFf zM3A71hJmWQsy|L5u3so*a}tC0a5`01)bXf`{~esn=~U51864V^hEApop4a47j;Bo&9o=^v>aa?2Nx;|Bl9(ESOn*M;I{sJO}?`@c8*79xUF* zW?#ct4h�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 I000000CM-6OaK4? literal 0 HcmV?d00001 diff --git a/client/data/sounds/large_blast_far.ogg b/client/data/sounds/large_blast_far.ogg new file mode 100644 index 0000000000000000000000000000000000000000..4be6eaf3647181a68075d4ad484afb1479adb932 GIT binary patch literal 22782 zcmafaWmH_tvharB7CgAS1$TFMCqQr=2yTIp;O_43?iw5t+#P}hclUfl&bjx!_v`D` zv!`}hcb9b6tkt7rVW9><0{^z%L<6^1@VKaT9)bwM)!xzA%IOsW;oJ851pvO>5P!d$ zA(UPv|Jzc~@v{AvhJre)7qRpv(<0i2 z%qJb1FCDop9ZR7TOZm6&gp@K2*Z%FSf5oK%Kv@Mz!T}TZube3Wz-4oX7HEeSScdKf zN5c6BmO}!*000FZhFwgJUn*XFTwPirF+FWjO~9+M;ib`R23f4sSyoe2)e>5GF7ey3`w_msHVxi z;+$Sp{e2wt?-QhByuKE9v?QiY^n)R#f&H~~)c>;l<@;-7@Op(&10#%9XyK-IElDKN zjPY3aMQ-<);qm;^MGq$TEc4@e;V2UvRAs6EF*qb33`ZJ(sVe=ShjB1zAdcft+M?`l zvUDZIx#6tC40R)aAG}B9btrsDEPbeA^c8)oY9Nj|ZJQIG-BiDNOm+g=m~*ECw?RkLw0ZBe=-0$uSx<|KJ_4FD)z5KN*G{!c$A7)PU2K?irnX;zMD zH3~LRrAi^83I_gK*B9y4x&*x}6cUaM!&B`4tZ@=U0Ble#=YKYhe;oh-NI$AE zhbIXX&?#qC88y@xXH_L;)inNpO<|f{0RwDU_}7G;&~+NANQxBMD^D7t$Rv4K^ASpaRY-mLZlt0>?3#0}6>T9y-E;0UoK6ycreQ znnGPZ*@8xOo2_*4>ra{jUAZ#C0(G0x8n6%m3;rPHOhjWr2x9`kS0q&g+JJcDG1}c| z)t@{&1jeB}Md>DEJTw{cKY6G#;?QXez^}Bs>G5MSJLz##GBn`$=z;)$L}}PfB>+@v z;MXStg*bKvOiBd|2_;PZc?^l!1olyO4i$9`1x$rmbqyVC1&u^X1vUi*Obs;*2@Na_ zwL}Gt2D5Q?(4xA=Dz?UKqnX}~w^pLdDx1RM>noV*0)EwR1g$3hSCz)Ry2dgmn98Bz ztgoVBrUTaOs;@Jzp*80X);z1Gu!yChk*KjaYo?LtV(6@~s;R#?uc0&Ny*w9SIOp9{ zT-s{)v$C?Rw*0Y{>9O_rFkWU_{&hmL;wl;nS`8pI7myx?#5|V9Y@&pk3s{S{p^Mq# zy!fPxghqnd>yQa%`fg@gO<)m_hO76wv%Y?ki@vtG-fh6Ni;I4O*}9gQ&aIjL;GE0) zt^9PO!u+huw1&(2oXhVN(DEHv%ta$Hz!1zgAF$zJxB4zqMZ;w^Uf&Qb_Rh|bYpK(Y zzY1isELdAbjwIDt&7i-`+1ja)?6SItFSfxI$Ua>U0_$6K);COYS+zWDRaV!~*D_nY z)zG@}22Wz+#(Nz{WBwLw^1#`|45M4`f)m69jm7}*40e-2`r1BQdrzIL&Mtaj*_x5g zO8zzn=RiSl&chG@0Hi$4n}EP_IA9YB!0}HPlNSlb^aF1NwEoemeK`IjJhZq@s-mtV&jv1w1RTDil#! zuqriK@T`pKX=k-%t!u!l@1pPaBXaiW4P0bCM09GX@%h8Bq6UlLts#^vo*jU%>q&l6l>@29+ za5UlAfXC1UtJ;|}0T(}SP{7**Rs2_Q-b23TJrt=d3rvnkFw1T}I~>bSdVDC$E=j&B z%MO9RD(fyue5~p#q>50GAFFDU6R)ajT>;K}$k)8bXQ#x51*a_~5RCwQ{6sK(!LP!u zvFOV1<5GN*9h_N&e=*?f0}cO!adBDw%cJ3nyg#9z5)R@dq5wU`WJ zxn1!)0~eSd!g+Ry{Li{!jR3&S?+qaSErP9_A_FTD=H2UR;ot!hRAaD%)4_QNUN)GU z0DL&pP^$jLp@_m!n*Ik@5Fh>zAACW4?7w{AI)ZgK8!QXPsmlJ9g?oke|BIu2t!)2N zX(|5;75Jmd(!BD4ZHp=je*A0Y|KMW(i&Ito4-V|AfBE87WxypU0XH~QaYU$bHL#8H z;NKDX{*7N@0Kn|iR13)v8DX&~A%$ZpE)kWb4P+7fNm59whCmuX>J&-}nbWT+*AG6} zQK0}hunCxjm6_iFNGPa+up-pLpX$NYt*B|BG&=)S5NrZ~#)1V z*D zAb{7Mb*L1w?OxB~rQLZ6dYrvk|6a3e9PM)@$%zDf27T-_KDMWY7;nEUAH)$}^GZm$ zbt`8HB>qn5TfN@#e3Nl-p$i#h`QFy*{`llM3#04X!(Go<7O3Rs?riRbW?7D4Rnv+1 zJ4`^_aMC&N&mvqlZrs(pmrFn*vFCWa036xHwgB%pJ$QLD71tR-0BRrZEIHdaxZZO9 zXRbcMpN%-L#R;$D)~~7`(k0)vRc;j? zXg_t%rHht1pX^p_Ljt^>gyiyZu%_98pP&It4k-BA{Hz#s2AID3x-{uec~rww({l>J zx#DZ~OEVvyLpD1sIug=(&+G8b!|O}!x8xhKyI7>(v)9_lG##25@BWZM4KRHS6w7}W zM%-M!M~6R>WTVqT$C-9qJ+dM&w-b^dZItYiHNqW|AxHIeU9K01#~v~)C;~)&KEYUT zxS7-|FuGZoC~%{^Sq1seP-%ZUv}ufKQK(k-qzih(Jp^ z24`yq0m>GX15`cUBo>hUt_5HXr~I9a_A8|wQg{*1q_RT|R|Bg^U~3Y0(C0m;^YS@c zo>a!*HFxDq<0e_6ybs3@_}|LXl?`FedSAYV^l^1R=Oj`WA#Ro>-+*>0^itoFk@eP(;;IIIdBkGE6Qt#O0OnjOI@+F$0tx#j^ZPTpI z9=c)HwRsvxTh4^x4ljt4kbhaaxm{@ufNHM_Gp~wveVY}ElPsjt^*B^RkoJK}{5RyC zoDlG}1LE`xm$_f?v8K`*Mk&d}Kz)y97?}ZJy6<|{dLlIi2S7kh_#F?&90 z_T#Y80OG^G=M}+Yk_iOlPK_1I&ygd12%Hy*xCdhoX&r$7H>5k^#&=5quGnOmUax0= zU9eYwpGoL#6%GdQ;kWtr^YbBX$$mB-To%YsXjl^ABjN8GfBvSls#EIN{m$N^gWU;1 zl`&^46`tzvv`y8cvzJA~?YEjj@1M_0Z5Z38Jj7Q@Z;sy`bDa#IXCVXO_SX|^H$st? zu^BKGVT+_$o!vPqPaV2vLRq*C2_FqHLb(`$Ry@J_$VJS?8OWLVN&wKV0a#4}YY7pV zTX!pL-)Mh}a5bEMz#@+II$>$xA3FOZpvuXAShA_#kJ#w@Zk}DQt~@lAK4rK)7Ifbh z_*U9FTJ#~D6*2G@mGgz+n`>6Iz@C;Q-x4z7WVm~{5%cOcw;#;3xd@A+xiantbV?-0 z(X4qNrw_*iOzJ;+Z$^GQD@qTTyKu;lD}GZz(JT#PgX3|zr?a*EcPA|r zCVAMaT|8?DTVXV{7}pUp1=$R<%iM-ti3dltCVYIWm04RzhYy-2}D%Hkf8ZE*(6Z(9|zqDUH z&9hZYM6KT#KK^b2ttNwdtX6ql9=4TLKWxucjchCP%TpDvQLz5BOh9b13fi{c4W;$R zjt?L=cC3Ik@i>s{^2W_0K;EjwxjW_ozI`Rxs@*sY0of=AxOwB~R-oCCh8u@zxkhc6Pt z>cb<+u@o@Pdh+bqAQdlv^EK@bp*x<+jh6IfZ9+$wAfnEY^NdpHD~Hoc-D*t7;-8vW zcUe68JSySv%99p&I(Coy&ZVW+%pX@@jN(F`@_rs1-6^s>zeDpFCU41`Y<&wupQl^4 z&iZS?8dj8oEc4|mCu4k}{kL3j6{^3Ht?beJ*&ECG4GL<#e7YZAg&Dt+;X4nX_h`v* z@i}Kus`NV+NpmWZtA$N(kaDt7KcyU&ZiG7?)9!;Vj=!X~M5vOL%)SZWZOEJqHJwN2 z@{JK=rwXB7&EfntwA>XbKv6HTV3Sfxk!t?su@22`MJFJ%x)@pOyQP-aW&=T3Q1&zq z0s?fKv4*o)MY(it4WrbN&QQD8Kx{;_xkQKICpM&#C}N@wC7cWuBFENxXis(4wMmFI zzLyUJxIB<{#e@cf^t-ri%k>G%+QKYWxyK|DT`paVV`j@)zsozeQz&CvboseWL~=!D z;<%>ydJ2@v(w^uVUW@~_W8vG-Ff7g<7P5<;k`m)0Xe(}~9;=lnU5SGO?ZwjCJEenKhi-e%oi^sA>RCP-DfM|hQhUivP%>(!8~eGl#h&!L zzvV~6W%_Q2uPuNN(hI-m5d0@Gkh{JT&x{^9TU%Wr#2H(}t|<*<->{}Rymj0GhaLCJ z+~7*?C+vQ!_fjQnVn%4cvt?Lq5Ha!e(s7(=QZf+IblE8(qvP^2SESld$sC?0>u1I` zoOigCRS-&iI5^Dz1czBITf#_O_@h&qU1^6%hdGIi6HzyH*_#v}lc}mWnoDU}8sn=* zrgtA0>C0d$+!^I!dgO~Jqn83}kI!pc;giC%6SMM_yL(zkmOY7Wc)()b2VQsxUA{&R zf%_L05I6coY^4jQ{?gzq#`s$UInr827c8>$H(||=spYapR5%+A50}-&!eyYgx5@?T zf7FjHOw9~b2WQx&>B$`PJa_$D?`Qp^m)`ejxN(FyeKDV6Mh}+x;k1wlVI0)`OSN>P zwMS_Q4QD)h!;Ge;JRo@Zys~N<2SGI>s|f%RU63i0Ke*u` z`p6+>M3*i{Pb4mTsP2EUX40rtI9JS3in`=+;o~$dE;h;`|4hsR?XCqOMJr&nX2B65 zvT~;E>V^2VwueI-W0!rnT3Q8_-Dr#8`etx;RsKa=~VQCQX=8U50~z~bd#!QTR$vZ7D{a8BJVKIM_{W3_ER&>fa&KvtJ=^8l@Q27YFHh?PoAO~>+(lF$lKu3+-bUVx z&G)Dq^|bp`#xi`;Vt*dF;5I8vhtsYumho(oCDCjZU99rob?x3ec&{xgK5kR$!y$#0 zB{bW}8!71}rLMOQyluQujy#?mtJo)@mvRr>TBOZ8KA-*@a3p z{H(J)vi;3BUw(8u(Nv?N}6oP2JHo`D<^eP+1v| z&4sUDsPcpyDH@Fn<1UM`UmERs7hm>f-Y4SM?4#2vV<@$q*HkkdTcGP!MHO^FVAXid z6Xv95GTh11hN3_MFKw#~%jhvU(b^aYdA0Z-m^+aVouTPr^m-#xcS zn|#&ba@qSB)yk~| ze$xG?eGc+6o5o`)lJfqC1~|qcU{2>5$7FjzI1z3B^>Al|1X#%vVoYGRoTp*1Uy?LU zW|~l!3ObyJt>y*RF;5f_pV?e-r_$GLT)JUy3dfcaR~AV};e)eKP>GMN1bF+=7(0|h zlFqd9#3`wJZn4?C8XCx1MSb6B)Ky@PQaoSmo;`?o3!?!JhyG@+m z(T->lYEpL`b1AoRjK3v6l_ultxc55B_fcH*`yDw-_-zgZ0T65uO?I!q3U~2-MStF* z`G!U5e(7-(KfXBccvDB)@rHfX^+U)X07?2?mzsS86Rv5q{-t{%^nU*Bl<<3E8h(r2 zZAC8tZovsCU~7y}6|Z0A|MTg`XMUNA*eiI3-;J#Ze*h@pJN}vXTJL)TTA>ko{zCUB znnAoSgc;q5#kK%liX)%@1C51QsQuO{3~=XLjW%qU|&S>G;{sJ_cnTm2>xQ@F{^m6>b-xT znavevzxp}Pu+N7QPGBj;yFuN29ttO0(is|X=N*EH<}sBshA<$QgVY|w9eXU6W;i@B zzKYx;zU=SJGQd)pyTQ(IF;xfV)qmg-JXxS2F+h9hbg2v;G-x$NgO7ZS6d|5#4a8wQ z;?T*`CZBM_pr6C zeM#a|GpW)NFzXVdJ1k-2bfw_0WrKZvFg8CM)4LQqBT};er$Yrd&dk7kok&~@VqVKF zd4Bfc;K)tdxU#o4Iocr{pwMiaM_9I$EIMBqE zTr{wH;gf(Yy_fT8>6Uq*U~~xRO3iX+Ll9zfk#TQXba|0hCJ}LSb00FT2+|w`-7y5c z$xc>N<<(TIeja3P9c@$Hx?8{5QjEDfzFbxJlB z)5Q$+6B)!y=yQ-57g8nZIKYwX<|9Awjl6HPy~7+TT7WH{lBKKTOKO3{I@|DPmK&a; z$zGJk(%~hOquz8HxZenLi{1eUvE4H$grUv3ZK`G+VrQNo*G)FlPv@VF-trKW^X4Ae zje~;i(yB3=2j|tl#?kf>nQ?zw8qOK0Q@sePt}()b>XaJU=c_KMrP&y5EQ;mB`^@W|=4gaF^()%S-7RaKYN#@X#Ts5XF!Puu z0jJn!JXCQB-AjtX$|99Yqln49ynqt=?$!?yA&gl((L!Xf_bWKgJA@9 zgsL`^?&TKEgieB5!2pHNLVSk*6t`+84T?))C!bYreF0RNR4E+p#&R%F%1I0r8ddvE4W6Qhi zHm8-oTAnEbUKp;+t<>4IGT(X|9n9Ew#lM?GFFiQhFVv}49zRUDbi?UX;V~cN13sS5 zm!GE1^UA+MSj(TjyA9&3uFEFk;Q}ao>p@|pehur5nmYjwMTukPZRg{ni-8~3xqoRn z=PL9s#)UZ`du@NCbP+Z!tb~ncQCc-$Dkg?q<&7-X9^9!cB6Rx|+A+{U8JMw07u!nt zjqJ@z==_l?qhi2!g&AXOHalOOTiBv&=Y6Q=?Y!Z@I6Z7x|DlqC5LXNWTSFdv3M%9e zE{H9Q7lESofRFC;sp)hzGK3^UUg1?E5oJ9lAF(PdK*dJo5{@)d$A0%D&v<#`I)d}u zW{eiWeYtb4UqDAE3#aq2H)wIc-~cmLKjBTUU3~Gu_Wd6AOBZ(P%IbHFU!&6ME4?Rc z>ulO96^#w%ZH(sFdk9|_Sa!@m$FrpQ-QZ(GP51Zp>9=Jn5^Pq`q?W<<(!(jS6b?;% zUOEP?wQ*WVa|RzJ(uc;T0|uVYP8@X%Y9_Rv@-xXR#lhTEA14XXGJyPdC3#RHP&2JE zJ73bS`-%3>h`f6gx+TwV&1KGJWe9^K~#y{t*y zhY91z+tuRXr8jc$;8kSF%mlHo_uVlYN zwJ!e&3gP(&dkj6uZcA56U@g?Ys+m0g?{0e zRdnxS@H0a$eZ+o*H#=M9AZthcQXQkUW0d2uC}q&lD{zhQkwdw>fmdU~1zxP41qK5n zQqif^f6gSYJ?hDsTGpnAw7`(`BIQvG3D1V{A@3Z%L~K)5$n%f!ba>`?qoYc?Yi@_K zAYID2T#a$#OKl9JCfoL~7h8NRMhk&{f5dzc#r;U?fXZzd0OO*CgGSK`*T|UE@lu+h z-ci0Gi3-o+m=t?lA+!%~J?^8MckZ=pA;&5}Aet}z86P+5tL+5}|3OAkDO1F%BF~Z+ zYi|>5GIFQPvr9zXMryTjZ;9lUt0y5Z0c+w)D3mWdi?gl7P}k?f$w3e(<2YPpKF^q2 z-;{SE*FC4k*oEG7c<)^a)9%L(cCB5HI1VM8$e%BwFZ-$xZl9XQk0m~u5C52hB892i z>@$L`t&qZQ?hWfeu_j&J_feWGZvoVN| z-E|WyOaxz##vK6r`&K$)^am!Y>FkWWow|6w@NjVEbvh7!#6-$w+O-rRwcPF%jk`v#{WYb=)@% zG?`nnzxK!=jo)(z`^SwnT^vWLOdf1CqLZ)Yh{LPv_U{&kDan=7mkq&;Y-lXq_aryS z9#>(ut!g%wYBy~pVo5+iWXe7_%@?Bc(XkEj&d8snyhW4xcvzkT5k26= z2j86$HC%h)htJ|j4-G`|Wk)IUsU#RZ{n+%UJDGFzqqr5pNd4%Rsup>B^c0lq+M6GW z;g;p@D%C$6m(97gdM&AI-w;_p+eabeE|V1vp<7dFb+kKEH(t*sG$;bBY?_RirXLeL z<`^{CzgXK5|4H|=F4UUf+Lsj(5uMdlLTqlPHq6Mf#w;YL07YNg6*qc3&4n^38`)dA z(CwjyCaK8ABR5@A;XMV{2fA?^b{%pCTfS{R_KpghYRg|f`SL61e%w3EfY-_(mp0mM zdC>5w$(r8619^%IyF8Ewv7#B09|GB+^m(uf+2mp!1F0Bm{g1b0TlQ8cBOp9JL{uOO zHAY~^ZBrB0vYuj?)gZ?#FH#?Ls=*{|jbq0Z;a)pF$S#x%CBHz;&r@_>5fr^S+ghhP z!<{?kX@e|m=t;^daarQXkHa)>pL=UoE5#)+?N+2-xZo^#|PcyVTLd`FUH zgn3}>Jmc^c^=nyrEcx#JFm4nbD*X*VVr63NyKp;(O?C9%9BaeU6^EA`tTsqpEGhH1 zyUIh{-NPXl^*Lcn7DaGgc+xYhs$ntIDrv9cGSQA6|4^sx|M|ObUFnZX z)DR}U9m1_E9aZGBny#rH&NJ=aXI{v=;=Q&j%X_7xrT`S6ljr$VzGCD@$CRA3jqFK2 zgM?o2ajT@Rv?*t(;x{;kjcAh&!Sh>U9`9X&Z$@(2xbr0N0ZVtl=lJs^7llMhYsT*= zK*eZwOS)Nyk4N&6Uudedj%=qH}nCRF_OlYghM-H)Dmj5VHYv@nH1hTr@DaCUcC-Wg{T%JSa=sc zXThFzDXPH~Hvr>3&+su!gtlCgISG}k*?_YLP&6dY%e=GVIc+>LqU~37JH}YQII4(@ zI}{CxD>zT<3+h&1hss|# zV_3foh>UufL5HhbK=rXX?k?~@hAbHaRQjRyeJN^z%uEOyG02lP;-fA}bsJWxMd7@N0noya8eagMu2~kO5nJ}I0c;d%_?<$LA6g ze3{eAaVeRzAMW5%(>2Lx4cE<&YvUgP<(@;77@Np+YT|&(tfp9=ryt{If_W|Pn2#BR znb{q9xthnG#z+XZCLef7p7cN|ELu~$aD-s)BoVzmD`JM{9t>7HbUq9(`^j+ zGFWQrSs{pL-q%3l8V96hL4>x$O97CZERclaS}u+I1e*P}ZAhlCIpjt35CsY~y6sK9ZLNph6NRGZF_meMtzUMT8l>jHIIUsP8G52|5J+v->n*R6B0!A|L)53zs0zJgGB|bmTjhJjtMUAse#-q(J zdXO5l?^_^q|LObNMRWXXgSeN80nuypjx^7x6U%b`$kBdC)AHVE9n`O0KAb%;O2k6RYHN$oa@p;ot>ZvFyEKvvE*L%K0Y?Kl+6Ez@k&dAD0&&tg$NX$s|xqsTlm1C)H>dB}#b;wBh zY=1!RIeBN)TyGqcVnVoyD7`664Htur?^m~1f2=U?aCi(9x9#pZug2W$jcnX&%O0IH+_0c z_p#W~GVU?+ym51V5Atnu7kdRqi5CYyymtyU-d2e-7DfgpyE1_E&jaFZ_xT`do8ENT?+LRb|}EW~p#E9o`P zX|Rn-52|4V3BtBiYrC6|B}*-TO6=86=98orU>@Rp?fGqWNa2dNX`Gi;$S8&-`-cfp zn?7Q!)K(CeFQqU&o`dve)@wD!_J($`%9(It*c&lMED<7hE|d^LZJ8A>Sn$tRI0V3_ z`N=JT(a)OM1lI-HbHg;&PIJ411q$#CWM@?y>Uy%TeUW=KS&(bp&b=D(2|ae7h_#P! z%I4UPSJGswjiSc*PC%S|a1um#|E^*GO%&E;w`#87SRl8{lVPJ`UJ*7~=TG;g(@j@y z1P!2ddO;4kHz{#-PD~4`yQ#L z`7*=;W0=U$7^FEEv-atY6Lk?%qkIz?J3WSMJo1Zr)q4-)s~o*Axf8is&W1PPL<|qU zmd8*v1qiG+7j}+^@9|jyZO=G=5hN zHwMcdOLgX-7=g>N>VQ@dXhmOTRKd>sC{Jy^Naf?=X&qLEki?zDXj!aIH@j7`@P}gy4b{=2q8;f0G zYD+WUX7wslKuWl_bF4lL&rkYse{x?xHBtI<iH&U$|h2lKkTi!m&Ix^r1ct8T&92&OBdyampP3#eE3 zXO-EQsk$-7D{stP@#)xi$oUSLX4(K$CWNerXvw5Yhb+W{YlFe|$SqIO9BKy5I>CFJ zw!y(TE6CoR&(Kx%2DNrFV%of%BM~V>H}~DNy+w+<3KxNXk}hH(U-a@p+|n7MZFYP3 zNw|-bt8m}O*2V^v+t}tr(-f@6x&~1Nq^;9gKN6dyB?d3ZSBR67{6bn?`=sdmnm2BT z)bPtNkTbq3AtomGTi&vCQB(iywEf1z<=!}kjIa&qwqi(_E-YJPIM z)A`x&kCqK{B|E>*;ur6+M3@1%jI@vBb z530qjT_H*GW)F|@;LSOg@E6H^6<_E|>9%+3PPQC*gw{Hx`h z>Q&(`8nJT1sl22JbGS$pOm7yd`#yeTTgy2=VR|kc_WVLr`NT#h;6xd%@ckNgVw;cD zGr-I&lf=G*d~oz4&GKEjBdUcTEbX$2+^T^q5&xets>5WhH_Q&^y2_m2v+DGSCY5Va zI@BWPDjeKcZ5UWS1h8d`lOouJ3xW+~v2mA<(!Wq76ZkLmcGJDA(012Cd1+_Tyd9(V_xH|s4g3Qaf32T4< zIj_bc=2jU8*0q+EkM)Hiy9qNzy`JKX^0}_rBi;NjuVXfews z=v!~KgrV7im!>DL<~ixcq!56EL~Cxongo>O3PCc0gUAX&hWaOduJ4yii=0{3cg>97 zP+_5KZ3#Trec0aJt($B`!3y{Bk#08JMNRf|%_S&2Okp;w-@RzUW~-!CqAG!%$c=ja zHjk0nIR}y_ZV-PY_qaH}EMS!G-V4Y5u9VLr!hQ=bsZHUHNWyy8I`6^+NiOIED z?R87Z3bGF%X)8jYvi9|gx&%h%T;mqepmEPGZzws&V;H`B41NjR2r;)=qpynDhjHAX z`@#zEmEb457m0Rn^lrMgBoL!QKW5nNhc(D%X>~mk;_CenPi0ARmE9D zbhIyov+_qX!5t{veEXBOCw0Pyl8+d-7c42+Qe)@R71w;M+6@I9gfrEGLNy5Drb(F? zKRp2@E@@_(HT@N5zXyQB^wHDSKl#|XQl>h zb0Zcy=#T^n>O)zF&+KLkG``m03lyU1d=3Egq~AHYAb5QSAwJ$4ju4N0a*)M~342-dZ zmcOQq+;U-gMa>A}@G~^TR|!B6S`KeX9f_w~dCcVT zZROJ4I4r}xSuC-&(L7GdSF$`7yY@IE$s#q+Zgs~Qir=wq$t^G^*h)TGzx$k0ICY5W z%RH=!Ku`N!@ADo|`dVw`Mhl4m=xYjFMm9Q%g#93_*Jh^*18*=PfjPxv9W8y7?6eJUafVS_xN3K{e8~$ zw7it52Q7tK;aTSCP7dtQkxw_symchWnZA_H-ulE~26Jb``Y^Y4VdZ;l{emlE@=ha% zXNdl)C}&57#~pKI0POpwLbF>;&h7-?T~ElU=0n6a66I&VMp zmEmW2@WkaKkQvVB}$xnuyMsZ5Y@$sljr!whOFd?M@_ z_8kJnT9Jma97QzyFmbue#N*x(O-UBI&USvYs%ReL94+!f;cMu4G$0oH>ZwILGZc&D zSUnMR7=7gPYZcwYF`2gV*-O=N8Qp_2NIG1(eg!?$!XoW?K-Ud)#7b8mB`mz2TX5cA zSlE-9I0h39WHvpyIU~a(lfWx9e*ev851U(QqjP{05RIn%*5EKj^Y@eD$f@Fr&sDG1 z?ZJHhgtXw*^=Y_4n*?bZpxQO?{(MTtsTdGgQ4ypWe-EbVT)o zya=K`vwI&i`bhC2i(D$Gjr))ry+?(!aAj{nS=V@`H@p=>Xd3D60-gah{YjHY2aYEErm)#Ad=bw{NLsC6&yF(rp|s zlCVr?>Ejg^fO8PJW&;ovwN63Y^WH;hV6yVr2{qxMdTD~9EJM*Py?@G^$b=9QZL zKH-&46RXZhQ=whj+>c+c&?(P)j%eAlZev0}*r&{a@9oB-w)h}!5P7D-aw<%Emwu*` zVARQhS}#vFv3`I9I-8!HZsRabuPBgHSCWfm5Xr>Zfd$;a44q(M?>VHp)RqO-REP(4JbuxT5^%5H|UpM4e@ZfwT`3BhE1R`p^b{;f1s1`INO z9H<|HHXvk->&GPx;d;4$O}3xo^qsV19Eet?H~)+rkg&g#4M~e^hLU-hb&Xxdo!|4i zoyZ0-1e>08)WXEsWxi2yX+^_x9(3*pL-=aG(Rz%?ejj=@rliV!NGO)mZdhK44o}A`{*(+ zO+|Js_!P;oyp`BX1BJriJyC92BR{%6gPxs(^SIVcdEE$VNxAqm6A5M7@ zRazQSWA++RODe;fcb4^(-Tv+)ZWzm38@iTdJpQnhHa`;6&;o8rcdnOnj@gWhLYnW> z3gAH%`eT$3Zb6hI)@hTEGPqJxW0b4Xbm*mxrBpP zm=q%wh$+*^)PMnadQKSM*e9|jw=>-*>8+$r@68c`_UarBa}lUS@|5SD_CU(jAAG3^ z4!h2hfX1nd!r%Z;t@!vTmEA8$9+Fdt63zQ$ZarV2C+91`QqcOxI0DZ`hkE&}EX9rIqNnD*LI) z;nN4dkA-%`vOVq*xvgc9>K7}j>qr@%?JvLIY|5zVUOsJ3vDoG)y4RN*by}@P+%ZCY z++NVv@>m%kTX@24JjM<;a8;#GW$gX!gSCinls~=}QQwK38R-Vu-QpA;zp{<2adRdN;>I5ajr=firWXKU&A)kdh_4w}F2_M<0hFB?`pJBQ~ z%<|5kr#wkFM@r{SCO_Y|&H~1cvge9lAX#V4_YQcvKYWn?(Y|R*@m-HQcf+A70s37}YF9;)7&c8G+AYHs~3b(WxN0J-Gfj0+2x{8Vz+8TBFLc2mM zmNw}`y-&tNxswyOOH{bY)ta+d9bSw&WouOf$ZnZbjL0!Q&URiw=`$La-ou}$Ka1r{ zY{d`u1@GE9&iF_@5UN9V*WlryeBs1JRB-Y8zFc{;@o`VDC)9F;f&cSXqtj$E2e2qn0 z6GX|9dif|o=(EH+J*?*|x>drbrv$x0=OI(%_t^$5Xj?U7tuTldgxCL28oc`4)eG7s zvTINqZj%4GlB+-{>d4vAR2OXb<9Xkl)!q8AY_7d7k^t)V_uDqA>0ocv0*bG^mPp4< zE)-qG??$xi^x>lOW{X6eS61e^1ul?RbB~v2a7BPPXCkj3x7>@Qd z_-fddWI`e9`nKX&mjt8P^Habk1{E&=A^4gaFcOB~`(bpXv`i^mTy%pFlYEC>B*C+k)~#`O#{6NxYV)Wm8)h|Jf6< zL@L`_&bloxK8&mXYa!Cqm7c#_S8BaOJE*%Oa&y2L9k|yNN)NUF4QI9a~~O$H~1}u04z_@>o1) zWi?eH%yTG-X!*%wpHTuFX)&>5`?Z0q63TYHlU$|v(MRp7aC1MhA3ZKq>>+b7TeIU7 zJNs+YlNy=R7IrJ|pz`+L6Gld?S!9U(4O$u-+@0nVj04`b{Jy1`0X;#18k0LBGB+T# zn-u_%8KWf@1trklhzq7Clt0rX#C%j`qYK@qd-5bkS%FLm?|Ie4$^bN+MT4gIi)%DgC}TpLw|YJ+Hqqh> zPZ964aO^pJX~(7K&H_utd+rY!JG{9rh%KG_Y!t4uD)*}Z0DiXoyu=a#4KScacu!=F zq|Le;0LYB#1ceBMQ*c^RHmawA$l`k*f=;}R~5-gM50uhxmQ;ujv;S?g`DI!dmeRuIC zBPksEY^-gPEAP#QUgWZlm}0lYlt8ZH>;3Ohw=Q?G{#1N{0vmbA(r4T!thW>!S8PW_ zd3Ic)IvRTa9S$&)f$A*c+}vlBs=SE-o6RLE>on9*p??6L0RXA()somzxfWmD}I$8U595Yah$a%95*Dp_j81`$AtJ0 zK%mncn5?4s;3E@j{h0gGQ+y)qD3v-Ydff= zlahQWG+5rHT)KY)3Yn=sb@ffF_e1P3dnJ{YA0p)j(hS_6NJEJl0KT^TyqC!WJp~lW z)PP)3=#Bu4b3rtKl0AB25fE6;!}H5Mm5098j-IOKlfE=_63MZq{@@-&lPc`_u^7?Y zW@QnI>k#`349V-e9$J8?!(yH;_5~D#n#p#z^OV#@JI5%0XcGtZsb}j>!E|@W$Jsj6 z|Kup!xNS4NXU>j(F_n(b8xA_#AAJ{CJ1P#BIHZ`j=)^O`p?t>Zf$<@mz&!vyxBPy0 zEaLYD#fTc?oz6=ju+HTG7L?2wZ6}C8e0w#$8?U@dpG)s@&FJEoW7UWc;qp8Vm86Bix7o)UvRAPcu&O5P?;_C{ z0=~BVx)qG&_mq&JruZ#t!h+RTKmy3j^r#bp0n1^HH7w>*GOO(cbV+DPQlhE~4{toJ zb;`<8q5lkeOc@c?PByO3&DVEj<^Q1EY`yemU-HY zNfVojDq%)f`UaI?Zt7%-j?6{je*KEVEsw0SL7?qgHD!%!p69sLV?#&CJi~>z%k1f| zGTOrH`(YuwkDIo_YGacUtFja`hMMiyyLP_20u2*5O*)bM*;iWO&7UvkMmWZXFKhlL z%)lrfp0@nFS1jiD1O;k@cd{*kh_34y0LaV~Wic248rS5@P(9W@QjJX zw1{(W5t;5P|IAs(aQP5DZ5N?)u)3=cdANr86@~4?7_+_*Z$bpv0i<+KRf%_Jn^Oxd zG@n_ieqRUzm6sHgM%^y!$u-~c5R$IN3g>WT#3A?ut^b4&=iXFR* zJt+a46MnY*xTguA0SeRz@5a0V<~n;G5oiE)x)>b`RA4|Q0h7_{J-y~`u{))o{`3#h zSEp}ky3K5!MM(Jcu7NoRVGWWPRqpA@&4j3*0Q`Vp_QDPn4OiGl9!U0m6MN}n3t80ihj2I zx|YUD=nE3mh}?6Mjuz1K)@v;QndwnU3vk@VB81L0q z_RBC*7vHdYuFLjgDUF6slV{7|n`S-K)`SPOqDOi;`;fv5cDh@UGkBZ-U<52|-~pbt z{Jd8r{JtPTjd1T|Y+73Dy^4t$SwawCb3Kk{kFdYG%UkYo{Jy!E+?63~nYQ(AsLA^k zj0Z2n6qq4}x%SBJioP8|eZaTLEFEXSi5Wa{)U}&diZr>CyU$i&RdQI>zC=ULL-)St zQXFg`VWmxH1GkN;xA`EGeYx**THX)|P>ZqaAjJ2v!i&#b+lfy{hD#V?Brv%F8US9l zeBT&WtYt!?2{PX#GH(dtftk_G=s=n!Xo*S+t zgn>z;JaAwl`;z`>{JmnEks4I>?)|c&x3S)nw0(O<-1$0g@3zW|Z0S&X^?>m#??dz+ z$6#;m**Hqe(Cv=B6Kb(wCvLq0GY0ipKPJUdYB5*XtB|8cQTB;QpDPg;X6*23;fwtW zOwIrvwtQSG27Wh+0yW0%Ddt^(h|JJ7ks>0%Qs-X2-ngTkzjfJ$hiF4hStrHvr*v^X zzRjrvKT(6Jb#hOypFZm}sXSfpeH9g6l{s+5c+jE2I!$X`*^hTPun-e*$iZZp?NK>y zT+cxc$D~@DL7+2X(5q}O*ceeQbtfO*YZ%D37+641f9qr^x~HMk#~cL}pz{d;9=3d5 zYXQ&z0cuP(al0E}?(|$5Ic5YT?aBFT45e`FxAaVEz5jEx7tS>bOy~I9+YGk`C(yV)ri+MuBVjZMC_yq?;7h9^>X9GkB7su`Rdl|!d~6dF`Ga0F zQ3KrDVgV5;Gh?J;L|`T}9Eo7G`=1RE=i1JnHHX8*K7RhLMVjmV(nN}Z%(9%S)e~ps zMl!PrH7p%0OPV<<6)sAa2=JsLBW`gNzwY+WX1rSi6 zMr4~~06>ODk|G!ar2qAg>a?Tbl=7T%kGA&>?6CEKSVVca+j>#-#5rjbEArI@La`-3 zC8keZ2veV1_gkx9&DeG!`NWmln9Uli>#9jPb9VNA<>gKP8{HVMJB0G~r#U6Er1uf| zsZEuqDI=Bk-BZY^lkZH0qU=dYa2Pw~27_N1Tt8_iId%Ye{vc?G^i17at1)8 z7o$YQ2*w=Oz}<9(81tdpn(LX9hkfgHh38ezbnq-OP!I43veAv%wc%bk)i84wkQ3iw zZe`(BjSxwe18&I?oQXN6#W0H;4A9z!e zWIvHHHeY*mDWhF+L_JJyIps@-`YnDV5d5&%vT0N%B{U(y>8L*rp^}ZhF__=x5KpGFYiBUdbOUe z2R8I^+l`#?^1uSoqT=P^+k}{y^F9L3it)}jpRx@oZ>4o(*#kj3MfZ}s$8P`UTG1T-c99=3d3%NK`$hNuQOV$6(G%m@Gg*Ku(7Y}DI!<162?jR&KsNt*1~nkV7#gW#78n3PTj!RVdwy@L^+S07HRn0Y86*!hS0lu!x4yThc0&-i;^bCet%|dt+V7CG@0Uow| zTq`g9fB-eZkztG;TZ{+*a28B(`}J_tUbogQ>c*+-YQM)fW+i5HkS2&PcoK7oOL5*?L za&i<(3;+Q8dH4PM*H_s5M!&0Jt9<&F3C=fabU;_zi8bzCM5XGm@QzaX46U(mxoW=$ zmPvT}N~>hM#AqDp$FBRnFK~8N%Ax8;RwQiDeg0|28JLC6@6((GCP2p*Z4YwO3fyV| zB(Uw1=SuREB%d~nD%@(6@fJ-G?H7THgAV{6wtUGe!v_007kUeqZ~E zW$9dacRNC@=>P+s^U3=EVaQhu!@tl|ywao=n6lb)zsMy(zn> ztcae|kKu_W0n4P}CAv97q)Sm~J5n|z3bIc3GanS18Auqh*uxBw_6$RwWeC7t3_`@yj5m-0nu!871os=y5~4TRf0k@iUXEf`h*J~ zlnG_JJaG4ZD27rT?yY_1_5N}52$DQ;|_-=bVLD>d6Md4PD5>3fHwT z9x@~T%gp9W8b3y(>8S6yfGQ9w0Uow|Tq_^)2Nc9L!VLh?Ei;YBf&v2rfUa=G${BS# z%|;J#`$WB6UCKnq)i~$)9dG-jxltN%{lJw+#$w>ax1y{`jWUR^^~XS#M?bZ)`s0{tB&O))%PwlLgrM`#-=);gJEA zek*IT=^9Pb3Ok~p!H_Bd9=5z+`&R$~0cu1>6NWKT76bzT;3`?>zBd2nCtG&wy5G3Y z$8U7n!_z3JW(6|~H)g&A&yQkfsX!Z3%ks0}U4z?WCRCdvr#RV6Gs;$n9M3N%h;a^r zsK}hS+OEhZZ5}3w;>qfksCphHt|Nw2dbbvtD9Y3F3!)Rw!=CJI+WRSec;+52@XKD2 z?UdN4Cg%_g0UoxzU+Y%@0S#(^BW0ur1rY!M$aW82;^*j12iB)I=?cE*Yf4V_&l7%f z+K5$!W(s22m%;*5lI8cIE=6XF#teL9$i=-9TFNr9TH#|06-H~#u~CG8i^$usU<>2e5(lu znFjzOgikuGKsstyI*v*+j{0xg4=rOFtNYv7{)$Tj07}Xz682aKf8~q-0K^=gutJTn zLbI@gkSN4}pbBV!F8}}w>4rm0ML;S+d`cC()MUN(znXTEG5%k1h!4?b%}q+-Ls($& z;s4G9#0+2bFqVGb|2Wwf4~UxgrjmCnV<$%wH4RwHOPnFy=pL6I*2;U3;W#<6pTRl_ zf$}mmQPLoM2O0f2nn?dZw6*TjX$-G8`^h8y4D>+=L{sS=lNQ+sf#535qtaw+A&_*d zJ1AZD73cV>>hI}z;D{&#^Yyl*vo$GwdH@0`4jyf0p#7KSFW+A$L&htN78Ln;ogQ)a zz>G{1-GG4YNaXI2!ieO7SRm>DoD4$9gYX5FsxfDEN2c@b=5O!eb`Pkg5p^{D(Pto>+WjFtT$6>H8#4a;-hgEapJH7(1^Mi7v` zFad=0*MDRX-;2WI8^tKUYBmU=FV1j4Vkr5?on)_50{|#q63w6!|4;ixG=)yBi~(uP zb8MV*DiUC4IPW1< z0@{Cu37JrU9hTJJc$2B4lAWcRm}OGD;!wmCRK}8+;{eZK>nL+uD{~poaq6gW>44R& z)sw8Xo1E8@jo0qHw*FVsLHIjF3;=*Hj*>o(f|D!#?hkFwyKl= zUqk*I;8XyB6P1($l@y3d0t5m6de;}_)w@J}tW**XOk=Yg|BP`4QxM`%b*Fz8jejQq z06-b3!5W((lEqwoz`+3uS|{-Ijl$?rYp!< zQsCV$SQ@AE%Q!$|HB1=-v5KJ#CW!yKFtAz*w5Fj7q-02u>C}AuB;42CUi9RsF zV3PhI1~kgMPh=3rTbyAy$xD}+Fv?4t8IM6<2)U&{$Vix!+0Tfdm7#;gM-LR_BTC0% zBmqF91$?(7l8@(*$D)?Ulu*RdS;CZ9NaUE{;8a!x%VWtesDd?dy709ssb;mg4ehp zR8D0l9c8ewCPcG~j^+|rebEb|c|k>f1se=b0gOi-~oWL7uIx9k6ODCTjn$hWBGzCRuPrAXon&Vn4HNCVz&U4UokZg;bz{vtW1XQz z=dC-rxhDCg1?M@i^VXvCUaIxlJw(hIoD`@B;advacDLEU%~A$CZzSmGLBw!v^te~M zYy_&U4cCO~swq*Vx@wqo*0|cb3 zD|cY^TQ7(a+qYg@c;KZwh|7Z(k}^Nvc@>@`CxV*-Ar>5@SnFtb?;QT_VsmoVhRD{A zcU1|r+dBmbL2@3R2mpYVqk{1zW)T2_?{XlhLOd~s+Qb9{2w_>v zs&yd6k*;tc4roPPsG%*#+l1#B_1Zb@-_8pgK_JUSM-W7nF)EM&q6!FPg;)hqg(?b! zs8Rt!tTJGvU(f(r)IwCrvMwrt!XX4%AS*GWg~$Y{Xd;A z;22hRzIIMM7zd1e?L4v-vK%VZ?xkr}v<@s=TDRV$IZl^0YN^PzzFO4^r|Ed!=|2q_ z`G68IqOws-JAya(-_FAtA*w8EZy^MTDp??B6P{%h=WUu+IfP(oQM;e!_>*;iS;dmG z8P5{ZhZaQD{-PnI_<=!%EDtmZUmbTfGi;n^a_EH3Jc;umbnQakVPdV@1bAwo{)nY2LY0{)PNWyfW95k*rk9n2YAJW zY2-?Lh69pW#D6i6?6V&G2jlF#@s|hetfO-$uFMGuU`T)qLZl!V&0DWI)xVggKs^qy zIs}tsyrrS@%G2bmjiTR$W;BymjIH1l%PaBkWj@Fp~VN|e9nJ^ zOXB-CeuV)5tbR3>&`gnWR?|{)MAnj0Q6PN~tJo-65xoi$c_6uC7&&zAfST+8gYZ(p zLkQB4Y8Y~~0D2GrJ><~h;vB)TxwYSBwtqokK#G)q4_H{(zYru20kE+Dyxj`f(b3U0RTS4%)z{S4R2Ajr z6;#v}mR5W#bea@t4jS+IUcNJ#B=u`RkQno`kL&{%EAnb1k?p=bB2MO{=nnicW%SP8 zFvm*1QVbN`P2ExKx*dD|pYDCx8aLhoKRQ>xl8(!~Aiabk zJU7Xp4ZINdY}vOUMC7ef`G(ScFL(M_l-Fk*2jzC}Dizep*rM3gxJ&*N?#BVxiG1Yc zy5l))Q;5gs(2amYNpkw&(`2dw(ZcFo7q!pZJ`{5s&WtIXp2of(tY8 zIBeI_nuwOF07zFu$L{nX{J%e>CoK@A{fexK0^|}b(mlb{hlvLKXN3bQ9O5gUHM<0g{9pm^b!D8=S`+_>`Qv2n_vM)h{HE zA86m-?R5vcD%f*oE@_>e6_dbi$vMx#;FGFR(UHUD12_ z)9(7G51sPB|_z0y_#B$#+U#~3We!y>L?%j4@WgghI_8W&f`Bd$X znq^nrh&MCxf4+_+YHqXNjH*4tCSJAaf@$T*BLDz&)z_sZp+o_~JNCm%&JpkV3TU9v z45wm(YVmXO=GtUzJl5dInJj2La#`PN0q`yyU-|k#orbn3}iU{zVDuL zXL7M=Zj7jGBA@4$b{gv*ZQ_!cTYew<xz#<578**!z^;_rc}^rS1pg9?mbv zLvOy*aoyUSHy2hjoyewQHD+eY;nWKm>6p|62ZU%gGmyYkzYQZaFpGy3LjHq3V6bqx z5(4Ww2siqsmOB57u-&MG=SMNNFRr|U(f0f3>2x1r@#{dayEw#a@I&{x=WnMndJ&Wo{L`%9TmD&lh^yt}{! zWF4-X2}3LEYvd%^%~jibkXmx*nVLkfQNXyZ&B_V&>I%yA>3sQk|K*vX_$6|wWKo>q zF4UBE)09mng`;J?{A9JVj2aGIN+K!C*twiQeJ4I|T#vKp_()35wcbuN3**Z5_vhaH zr*(FFvY6dA$#|U+VQIPbpT=?b`I?r;;gKp*58+=Qe+1Zhq|{YTEl&2!ZZ73DSENY( z+`+v_qwos-0&SG!(;rSEC2jjW6x&#{mo8JzaMgC`04vn8&e8`X3dJ~2AxII;x8J(C zY32|(gJG05P8W(2G})A5TXhx?|}qQL(?{*c-Gknwg`srfuZ%R4f0M1D>#XasY+M+$Q;6oo0b*tL@o z7KhRfg*~lF{JE}1WP|MkHJW}ZE>A$~!Fzc)RxToPDrzC?Os1{%*{1D=`5*!WqpJ4{ z;GSkvXn;@(Bu}9}^uRTKv6|n{=Z~=R7?Go;g_+JHanC3|YU3L@IUJjej`qo{XZLEC z$Fm`DN20DNv?mWMy!(^p=-}rfG>$9afH|JHiRvq`h3oRvR8JUUe(L=54TX=EP$FZ; z`b9p|EN;v-OBD8EJLSi|5yduE1$^*aZ=-Q<`ir;}Hel`o)N>0rriMy zlrcyzQft_Ag}tRVSYUk*bNXt|J4Db~iO5}40X^tIyrSe(IMwkf8p(t3r%9e}2miK` z2Fa1q?u;*oPA|Vqj=U?>+ns`{cVa)*jtd7^LYsSpk0z*}?E@`M=n2EWfit|ny0BQ#0^vvM#(XQx^dmR$ov9(W}2-;p>*+NlA zW~~Q@!6JQYjlb^&kKE>TR@o?PFk4F6c0A$srD}ZUdD%>lD{Z^GlOws!#BmPaAs7US zcii15A{?9z4EzkL!c-gVU%ietlW^VY+a1Ws#II&zP9kIvS7>mKFLJP4Z-v_GL+;ia z^8VxHiMdO$H>OP8lXO%G9&;no`%vXo4g(-j-zY(Xs`U?x{UUG@R%PlLkkl?yPsITF z>c}lMD5HyBUlp(0GQvHrPuY~yRkzZZJd~hQfbaW&rjJUpXTzC-Y)VRfL<^pa)r(r4 zZjeS%|1(VsU|~~N^@m;S!)U@j+S90?MC{G`;rne-Y{)O)s`S{(aYkX&3ThuCh+^W@dd1(j_K{;eMpuFwKPFO|cl%tnO(mI|0 z;hmP1*RTWnq6#kOxQ)B|Kn@~baAWyYcCck$eD+w=Ch$o5AaOUtCKr2KE2f_sYSLkD zorI&{PnIK(KgH4H!X0;d^H-<3#X}Xrm6f-@?kvkNvV1GQ&>s#B$U?s>3mSFAXc~W% z&^0B7r^_KN;p@v|y16)w6(Q9*NBrzBJO`ZvqiYg2@LeCxe;+@~W6k;CviW-Km*r9B zRR%e1;{L+Sv(FD}!EDb*26RVoLDAp|$|l|P&c5;@H!nZW_-LvPbGfcS?&Sd3!~d`; z`QUKNzP)AB*oZTd6Y-rlu#upk(jq}phaZ7v_QYZ8ar`vR>Q0VmF(ciNqdhLLW#A#jz8vDYggVNN~rQA@?i#utb-1<$fL|Mm7d6%=upXUkYPMG)PzP9O`C0e@% zD;stBGg5>Z^&tZxDpD)DtovC_hJ6BOLc*!L7UIpJXwhLu?>K|jz zHRRO6(Cb;k#XHc&kL6|f9VO+bkF3WHMani8QhzszQ*33ge0e~e_yL)PeL3%7gRbQuTjC`>3^)l8oo z3M5la$TjT||nf~;WXfN!faTCqUg+I4d`Pl~lnuEF`4JmPPF=G`o* zgg-NWNM_Nfb(I(3pPZr!#|8g7fXTwyaPxZ)3#E3^Vn5#|#CHc&hSK+CV$G*Q`d-a3 zbjQ0*P>0+yn_E7J(;Hf`-=t@{RcTKA$bG?dnJ7rUgd7j*iNN^|3k=5~#r}}n#htopdt%xaB@T3a z$a`o48z40N@vz-&5;~Kr(9rIk28dA|F1VA_h8(gHazdPNb zYR%6Gg6mbFSDAl`KUipECPgwxJf;p(p2Og?(-vIqp1HC<==N1CKZP5nS3mr*;(cka zzpJFTY^R`1w2^u}R@Ud%34Xu++!%rr4b?&!9b`5*v1Y^c*1rNJx=sFPBLtY`vr z$*C!W_%H5(MIwxd6mXl5J8IiwP6GmZA6S>t>VgGuRU(Q}WWzx>*N6xkjKsJ0paND! zq=#6gSR@Ct3=ov8#DFFbI#dRKGsE4m+fkYnj z?H*As5vjC!=vErcIZ(quL#j8bH7`w(L;i;DzX%zJ=xN&*1T5TzVMSnSj?yFZ%@Mxn zPry-Y=^k%Zl#?kqnFwf=n^;@~bu~(P?3j+rM@$so0HDOB5^QCq8jK(LbmMjksZs+M z3&o5EY=~$tn?dN!B4lJ3p9aE~@aImI^}ZE>#@nN5vRT`&Cc4~Mn75NOeXH+7lU^Rz z{0&}QzG_**qCx>S7uLlC3_m+*fOn4Yt`=uMtx~gFn&m*7`NqlUU~vHE`*=L8pLBRE zzPvOPZ7rMA=;sD^vBR!eAXcd1qnNB&WeD}T&V2NNavn~zBplGjEZ$vg)Ede_bseeu z4Ry0Wc66 za%DA?wbYy~AskvKZ_23*1;Vz;{f4unbF!O;LX{5Ob6x)xW{DSAUEk<);U^qd#@|P*|$(rUq1o6M$c=huENI6LQx>k zclkbxD;_js)(u%&mc9ywXu=; z7BDXjz*G%7%Z3XLPrh~PFR*w+C17k}vd1GLNTqjtP2lP3dg%~B2k4NS{YEjTVp?FG zx)H|Fde_d4pEb(&VUNd7J+As`92sdR`*&ah8lXXX7N=%~5rI>4D^l@!$&dH$4`ZAl z&{MyYg}DEZ`=^c}MYOAfaHzJ%by(pS7-%=&A(fZ=GuMQVFF#G3e+H3>LMNQkWHQHo zD>1LosgLE3^o&-~8%5!)SQ6b+!ksfcGr}%kkn#bOXVN_?b;=*B7f;TIM;5m}+zlsl zjW*PKEpgvfbfV-#i4hqPn5(E{%bp${Gyc^f4vf!}M zD!xCkghjoT`AoS+D6n$yz4w#iBp(24D~}AsYWI2A`8C%g!|EH%6o3# z{_q{bS-Xa~!QHua4wq|IU65*iC<(OZ$BZNsX6vGdKly3Jh*9z|#wi1yI@SAK%@&9u zhr6*!*W;ZH4$nL8w`*%PJsh~Cu8&T({n@262ZC}!FhA_YJ$E9WhJw;NsY=y}2r%Lg z7nhOy_MLzo^v0wZrjMO&7CuEuqqC~HJmv3I<`BzFfRDHfpJ@i6&h;8id7u6RiJ z@k?*>Q=2Va20prXTTFFPcZV(J?Kvff0;zR2!qsn65r8(l^Ym#gEgDxjnPGE!GrxA1 zUkK_w1E@nnoajZ3LY}IovYsuSi1G(q3XyT!4T>YJduTIDDn&O|0!C&T9iH1-H{SR_ z%CL5vkS8n8f_ZYN4m#7{#S_XR>v_2)Y+|I7h#uQZQa^4-%;nJ8pkIT4ha}sV?1)@S z$RRsI>mXv2>KmJ?FaS*!L>UTzpG-mTu8ThWXmjbNt2}A_$1sU*yyTqnJ)1>s;K9J-i1(-W24k!!TZUb^%L!)eBWWT{%bEV9s+oL~+5 znvHb7U^h&kwT6FaEq#!It!#jWO}vg@yzJ zJGmOw74Fr)G5W=@%=&>u?mHnwE{2n5ZP0Ih#}i7#zm*tQ?#T5$kd_zFZX_@g6y>9v zaC)4GOA2;(?5ParrAxKTaw73watsItSX40-J=NUH8{m0UKK~y!Z$4j(fkDO7&SX1x4?E=2+VwA;z zqT%vg*Bi69yc4(cT;7KB>BB6axZB*PW-fq`?@Jrk5sjh)h3Cbh8ql3@Nv(**k>C2t zwc=6R0c=VpWX62nNop75hA9-7r*C=x-a4Ag_PTW}=gPG7`Mfp^TD6#8u*R;a(Df(Z zk0p$8W@)@Q1KNpm_egmI;}OeaD=V^`xnGRKc{F5DZQI{@KJ;(c`oEaeIg=D3!7qC# z?T?${tRdErRSL*59oXn<95dgYhA2;%DCHVRO}k$U&O2}Eead0=VWIL&^sRDUgW7B) zdcQ0fEK-B_eY-_6B8JPru-%-jFA4G;bplFB&K6C0qq)S1F|N7Dc}=rt>Uh;sQEqHF zbt#jYJ82MKncI{GWtiTRxooJR)oPZ{VR%R|aAw!CW4WPhiaM-SE#H%vkfs(RnZ+UW zj~<#hL#z4V(Ed)>rXa|+2nJRJ4g-*CUP1-g z!16*Ve?4EL)^Wu?p=wwhT$wE^E~u`fjyeqR2j$Ee?TXI!X+lf82hZhWz21Y9j0Ma|4>LkwV)i6jI=^)>@fD_rg|f?c z4vuk$_p>^@i!ftqo(A*S6a+inB8%i$9TXAB6UBUD8Pm858;}>c1)^yuQWofn@Ai~Y zldMy$9!1w2xkSb=@b%qXvoF%)-N}Dk*L5!<0tv3S;ccTF&g<^PqNt z;T?8K0_a*;M;ql%%PD{pu-!f1Wu5t|iR$1nh=J_;$ujQr<)u&Qwz-da@B#6XueMBj zLo+{tqgf(}76C>gL#U*nPB}D%-TyI&&-nwU0}1a{Z}wJuo0fiM5z#1B(5jO*8)rm- z*Vhz5(rpx$>#s9q*DReKZ=?OJEK^5kSg`3PRs1_Gg4AqL&866#KqGshhr=VOIBq&X z@@>|fkZb%~EgoBfufMc7br*=DcH!VPdghAK=g=$h>k^cLkU%VM#k@De=2V3FKlh>{ z^NBmn0x6kX-bwqTDQ}S--%#YYTZ6jK zZ=r-vZ*q^4oVkl5O`Vz-8%s|FF~4R1daTSMP|Nnm!|*imQGK%v>rW7sG!SOmT<(#7 zyB*UI%*8PmiZmo57v=j zVGtEF?v-84lrTzsCSGKw#nMuYZ1wz5RiPVmKimD+$JsLVAabFAR3u|}R{%-3H z8&Z-VxVYUz39x9|>cxUD+9iF>&zhsYbn%KpEZj%Qd=>+=U2L28*~gtN*TkAjiP5XZ zK<9kDPhG;0?Cn$^`TY6_-ke30_*4b(V9j3pLtIy>ho0(L_j{0OZ93HR%pm)4ONe~O5yx2C zA~O*?{c09>>x|D8mRk^IzO{baTmP%|oqEc3Gg_V(f9=NB+pNZMwp$Uj!#319al%?> zV&-Vga`s57Bq;rlo@x1UM*W9PTj{H(*ya;Sk@>%GcMHJ|Ctk5aJBK@#d$O~}=s_53 zu02xZrNh;P9rCoQu@k$p%w@pJ>m_lrXO7#&7U%jyV|*;b;oh>H%&immv91BN^hSMf z`@5B!^AnZZ;7hC8OpK{3*|QVoOS@xsvELNDtSs0cpoh5!i|T;^fG;5v^^yL=BXs40 zkY^Q2{kN)Y85&%pM9E|e9HJ&n7~0rmnqgr z1+=(*rycP7%X3Vg2=#aMCjIN1ycg7THOpH)-J$kQQ+&%2>V>5Ix)SlZaTOHJ>@!3PE=elt(F!o8}@vex5htqPv zHXJeW@O}x+I*(5N5{=PBw0gz@HEKq(9ciqtnPK*GBp;Ev=%q_o^dj97V=FOZS1jK? zxc5`gtapl|Zp_XE^HMj7r32hzfFGE1wX2qQfw`Uqu({XJa4+UpLD0LSJQXY#+%!Cc zBdj>pPbUMopJe9EI#Q3OY~0z1-$?0iJm30WFKEdrvgX4Vq00l6U zu=xyVmE&L48W}To;;gvdK3dnY=WSU@l%_@JK8Q!wHCHuYL{dC1PJ&RT?|WOZ%6{wA zWIy)ssi*Z=Q>BZ~nQrNM8Hi zg)%+#M#fO^lk9e4;jeFvTvK&#em>zDb?b*zA%ybjMuhP$=^-nRx{F1d06qGeB}wsN zp+7#-{BpN&hK9U>i|a~{ivZsNYij>w?0ybtO%jyF6XQjKPrSBPH!A3~82tTwX6Mu8 zQ`1`Yvw7h1#grJ_n^or1PS#oq`pZQnX&b1W|;#lnE8Tuv@5NX5OVNA1Gi0NSb!@ zV-eqKz=%@<}^x-6Yc2s6VZwPRZ-RHXE9turDC}lA z^Ld#}jx$4?Sg;@q3kBdx8aiDT3oE4?#eh+&Z^nyuiqw@w^a<(WdD<@D3Y-!guT5zD zRLyz4;92%@s%y_S+-0@G4B1!U?&An{$Su+_WeV97HQ_bMd3NafAo-HT&R5Jr_C87segF#aK#3VCa~SVyQqen zJ9S+3zY|+2(pyxqVjD=yJOws1$S5Su{+hbQpsM5j`KQPVnecZ}xn5=RPX=I;zGe1C z!2bScoan}M_*WAh<4~XhMAxX|)-)&_(wQ4vldN?;zHvh72W{|AT@B~XT`lfkZh6=H zX-VGXEieCBzA$6@$z-&5T{7(kXO1ahr>6dKP6#cHTIMpY5{LcGy_S1nT&iIh`P7LT zbfz5}#lU-U&vHj0#dT!10e*VY<>pBSTh2>jyb*Z#GTTplj)%Qi-iAoTZzzvr{cx(q zl1CcYF(8X7M|pCJteA*Pfcd)q0={uwYAU^U8~~tsl6A6Vf)XQQb#8Cn_)XzGLHT?Hdpzk6C*k}(`9P$rAD3k z0GEkEll}*R^%DZV_rNK2DnBE{Qm6K0v{EwtkRX4mdCHhn078?goc6p7z!%}yHBV%N zGqdg#J-4*B=W%_-@h3)I(xG`L{_h8Pq8GZ<=fJe%Kfi+V5j=Io{Xw{&-m2y+H}JWc zZin#8!#9ux*CoAe3i$MDEOc!S-dk-$)75Z)0X_udKEG1?F8GFj~fV3(zumKt>Bar$$a=BZ?Ez6 zW1u>w+3u%9rzMTew#H9g4WBLyeR#s$Gv02l4SQ;@?|A-}g9omS^rvRejn|fseye1n zJ6|{ZkqE>A1`*~`GAQukeRn2bzCCpkQtAZ03=sDZ@4KTsm2&l3m#V~?H*4g~0!2+2 zC}&PxYrg+>2%mf@QnyzNsz>2in(C}klmJ#Eo7>VY29uR8r(p~bq#e(+Jv~sfQoqUP z#bF7!1IDF+^qyw0rkM(-j8QO*z&snK@~)gEt?c+bA;Mhg;Hc2b9J_wR06e zILJg0Bt7g9GHI4c)(aEOxQC~mCWWN?f0Z53%pDcx^CCuXO5jiw^eVuDm{yT|jR50I zLnxfd-A;i$=Mo1C=-}3pji(BB3a*?xn=-kXX?F9{Su(v7w61T5C0%sz8}w*uyj^ox zd9sN0T>NP7FoW|po=S|3>9&b;sLMDyS}?T4j7zv}^@#0;K?XBh=#aT$k^aO1wtVRa zCF5M9Q3Ag02y--re3`d~D)C3xKLblz+VWgFfQLl%4?T)A@ck_|Z`!hb`E;d8nwXX@ z5ny0Tpm=@x*5J`Ur_;_G0yP3iD=?(b^Ho8lkOSjL~u$~qX*1x=I4pVIO zhz*SwEbz*p2G0B{3%-TA2PsChw_&0_1bT_X?-3uI-rG)p8}F|7M;P~KGuUvT=K@;f zeqwm9^1J39^0xv5ZgX3Y51Vf6F+fJYi){=P(R6MBekI=EE)A6nLx|HdY>tAlgnelc zgrg=Xec?ok?3?-{ApgrN)WQ%-eR)}U&uG6PxPfhG1hVHzZAJbRVN5JGbZ8MV_=eC3 zKc37#-!YAmfeq@!+h-<96~0KU=QNz6bnkGp%Us;{6q>DrFMyC$d!XN zCNgP>261E|8<^->(#jQ1K4($*BF|(n>Bl@3 z{P;b|-O;A0gtf%TRi{gQLr3IC&Q1etSNh90Xp$xYo11d95TyB#`wgQsIuXd9l0G)K zNw@PBKQ(n!I;c#Uz3Z;>KB}79%xNnq%b%V)vwSC1XY^Poabq|E9KjHVdz3e4T7CpG zZ(tcId4;isOtcpiB4kKMl##yulb?GQ_eKm3xG}SLsnnS}%y8pOPXl|Y3#3)Cao!&s zaEhL$CtnT2f6}I;v|;4GJ7qZHyn@W%y6qVwwmD1g;Gt>CXAr9&6yS?|^xbk)(8oXL z4(uYXSO?ruYN?rMOk$D4`|3zXOfwdDt9l@hrhVE}d)d_ST#oY~V^3Qfqw?rMKzmyk z>^!4R+jD#(kK?LiK750)S2ltoMI)2EJwlV)3|JJz$L8VU@a`Ml+V3Bw(}Qv>3=i@6 zFwe_xTZh^hN+3>J-yFsLnv*6uk0oU?C`}FjT4kq9<=YZX;Z}kT9pfL0F675u!#t{a zB6+fCg5_n=WJwS4-HdBUtePYG)3nl>wotDm=Z}Hac@fF+DK*iRTV=Qe<jaxA9Y`WWdVJ+r>? zyEtT8`qD34#+<8-_l#Mpf?UUvGu3t~p$};XKwAP`^4AQ)>U7fS9Ik86G?p-5NND?> z4OY%-R8JBLd}<5^ReLDud>mDZ@Fn`Tq_*~@AIwDAK`c{lXMHXkYhC7XV99m7l3hq} zL#OM-ea>Q4j@)!ve2ujT-6FQcD4g9n3~kwbhk3on+}~<>>{|bs3NN#E$>`BN!o_Q} z7oafTs%;5CLxV(3hn|#fGHH%Tq`gsELOkB@J4iuXarZD zI^87(P8QqdS_}-YkPSWyLPL6xg_I7#)+JU!;`qytT1vhcdDNq1=>$}>11W3vRPsgd zL~fa5U9AsyY(3vox{jUd24+{bY;xI7tt~;n54}N07~3jVyZ#C^H59A9bQw?(bH02c ztWG0k$$SW|Skl>4(J9t{eB zbFB9n$yKn6`CwU!qE5fF`c!eUDYJFhyqqk~e zBX}hj0fhiyns^Oa2fyete)#PR#o0>|sT{#14w<8U=|5YN&=K$Vpa@UcS;?r~o#j6^ zNVj+YY1b?({A^Y0MJx>WZMxnbACBP?R69kx^V0SCQ`rQVkzxz2Fld8HYD3#ekS9!o z%UzO5un9~RFo6B6qCPq|bP;rgz2AY>p1;5we3@=K)O(ih+TxWnclgE%}NU4`M--18!0?Cc%#ySI z!gV~ebmy>G_TkC8(?Yp?>O-VBP?}hsk?*t+bevW&5|}9kU}qU^YEw$WO$JrAmXy!b zPQPa(985-FJ8NR6tcxvc_Fk-N}nH8!gwq?W9#A>=)Hy$D@hy3 z?a_{((CAzAM74FnN)Sz<0NtQ`%kpZJ9_HWalK5yi8l;2*4>(=L&Hg%Qx!tzK(^flb zN1rQ>rY)6C04oqtA;Ow>(1X<*vcDedT6oY_`NfEQMM?6s!;Xqz=Rucd?7pIQZ9QX^ zR*1;6zBj${*C^`ZS7oUQ9%P1#1)yU4$~i;qkV_V&3g|qYQ>97DY%*GQT9fGGG-fvE zJ;apXEnpHi5%wGxM3Olr2^?sE{ydlD=~#C^?fuc}Vxl7X{E0PWuR;W7+Hs{?ThCR} zUbFOP#anSA#@(*wm>D;)L%2tX_Pv7VmceGZaT)Bg=Qo<UE_K5RLn9DZ#@{9qpR_y17gs4bdBrhoxkJ6+4FqNnQ{1J#0^TrB`7K0}bqY~0i4y6$SLs5KSoXsB`n)rV% zQhe56su(H|n3b3}&OdEXipeI1!io*!g-MHndjQMVh7~p@ zRzVO(&j(K$M#gE54I~0U;V0VYPqc_=1dWKmFaV&5s$dPd5RD`ejWiG;!K3KFfad{# z2lL5Bm&nHN$R<~&0YF&=S;_?q?ysCV0KgaWMwel;%*jQG=MzKQS!~UHI za5sX{qgnfd|6}A}JbBbl2sM10x!Z+0sM+!je8jo3Ek4OP(d~SDxo(pqySZ$WVCYk> z4ste_Z!fpMPzUiJh^E13Dx3Zf&SmnzI2U~o3{ltkBxc98fFYO~oA~T^4PZ#N-A6U& z-5;FWA60)ZhXV&hxtM<*E4tg$bEXEs(EGuIja;<_vMbRSSOxEb&XZEbg zq|r?Y*bl^R_gN7LLUY9rr}wQ(Qu*Pj(p*&KY5p-dBp?b;9*(6d`=5(x6nO-m>nL4$ zVTe3^WyPmh_A$n$@xK@T=cn%D7U>s8UL)f`Px*4MzTBU7|iVN-0;yu^G;P#yE{B1U9Ia`#+1uzY_oe z$RqVwW79;67*zABOd4uT^QuzwY8wB)qBzT`hzT|Vh(sdiJ$%q%*ug(~zEh$`7 z;@d4*9H$M*-9uwD%N$Z=lRzF!7Yj>;0UHe(Pyxpk+b~-{k?W+~A*IwLA3bsDAfHTS z@tlf$Lz%9Cd?`rXZaWwJI7(Zp`>u+(RNd}#16T-v1OJeUrV_CsM6m$i1F|Y2U3jYL zB;8)3>L}kXk!dtvd9K+cA8lUhC?8E;3I<&%_>pceH+52OH#cQQjuz}6y%6A^I4!5S z6o5tp{BR~xOyN|-qEf_^dXHtWh$%In#yP>srJ}B(h^08MuAzgYsF6;k$f2l+rJ;r? zrGc%XmaeGLV)32RVOd>c9Y0U1OCS zOyyE>H&D^A&;e`qG|*Yp&{_xpYo1qAT*lVWNY_}Nx6nxUFml&e*ECpO)X-T7SX~G= zS_t@7@wvlsw6?aYvHG!*`LW~VC{=D&;ZKL=B~>&OwOSn1JRI~er53R@=F_FrJiuB4 zj65us7bT}Xq%_hj{xq3pVc=z<)e07I(C`e{bT=@_@G#J})VmFz_3$uAv)I(K(7ClR z7+Ubyyj7S5DK5@?%xZXSE_nRPa#+0si+O0IhZ}+U7Q=t~IIiR7t7v$vry3Z6#c&;s zcvgBG1?wElR)rhuD3E1(>KP4IxjT9kGdfYMW>G!0NVxCeWg4hGtR+xt&F?Cu_V zVA+Q8o?5|97xxHZaLmIJ0RW@|EmU|!H9W8d4d8|4N+^g$VTFR10=lq7)qcFNaXvbH zH&t=E%5YWH7`)I#K58mAC3)JSQf2vfMPUo#bPeIEy7o2m*}5@YVKch4r7g9PS zf(c8y_U!|iZnUKX$@2D8rP_K5d>}lx_&<%){B69nMOD=<%}o`o$^uoM9;`}Uo(d9W%qd2p{x8R+J<US|9@h?D4wV{yW$RYA4=mX^v|netO;xt&swuSp=~X+7 zj@xN>=oEP51IqHTH7&Y&v3!yLHXhvqR%O?4115k~y_4qx;n~G=-DK-lfeCiD4ZGQH zXKcGmYIa<$cy{16bit~27tFxP4-_hRd7w`H0FHaeKXDIDF3$#ABo@WCSHcO;wws$8 z&9+BYqRO^Q6sF3)N0yqb`Ug@)EG+;aB3`jGLBqIPIH1Ii})`F9DNRB|6n{k*8lQoco-PmN~&;y9T@E3LSQK{M&~AA zR{bvq6mG<+p#{dITWo3@{NVw4=;3M3|G_xu@kHn?daU1uoAB|sIv#bLJ$^eE7y^Lb z&~QK@B%!7ZFC76AOvbR?u7&;vCz$%Ne0wBezrVtn0DxC06d)NA$5Bn0haC@#`)9Q92ml$HDR_c& z!Ep#4Hkg|TygAcSss6>Gio;Wx{|8r^8v73)LTPI9zkJ|4f_<+LEDOe|%Kw#x{{tQT z7f1Iev;9k@qxvsY8ipoM`-cx~TQqU-moHUS4xEA#@q%3y zPmBg%1IMHo0hc8Bum6ey09L=I+Q&SxaW<<;a(K3iN^yC*2sVjPvNAd~MDlQQw`g+6 zq5;i!1K^Dv4H|$4n}AhRnH35^Mnw~b6QdDzZU$$!;^q;uoQ%+saA^QK8#X{mO}hgr z8a^PkG63U_|09I?lpjqTEd;H93qX|Z{ffXNcpgEs_5(WalPcVw_X)rl0Nwz=5DXgn zG?8?~AgoN}5S%PH8wQs)pcfA4C5M!hK8w2X}8q|}_u zl+-_$wDhdFl(ZuMNtJRoF+iwU{+^CV@$<)Z7W$N)&j11FsSC@{8v@0)FNrOMo#Rgf z0576w;JQ{DJ}Bk;@PUpn6T-ve=ObAf)AG{1)tdP49J^STwQ%H#_Cv1FE3*3i;{G30 zqlrjt8>9S<8IHS%={D=h9>NxJa-N#SNX;{aoovcO4!LpUs6g&*KLhHHBz)7*y}SPoG#cxX_NIc>ZN$l)l=N(%At*t(`++dd?-0GisgT|Uf}ZpVwGDOql@%x2I(;FDWh4tfqG%V zY+8dac|mTlanE0NUkfwz{D5`F&af&Id|M9YXp_B|JxnJK3L(q*J`OxoJa@|rb3Mc9 z3+dc3^G&_S-KmZ*HF;KVzwrterhgPD(f-AD_azAm>*gj=)s*!khjD$q+@y*oJkg9W zW#0MaigD;P1R&h{BrM%)q-c4afS@XkP zZ%`{?5DjBQ!0#43eVER8&k~LDLr&Da)uhxk$MVtKUM9;E9tCm~$KlPG9fgD}`RQ^9 z&5g0C!0Z{w!SVCEWJ-qp*hQuz0abn#6NrcpYKC3dp<1zkL z7z=HPgcs4qUhsy;&+BPz?{ll6ZKXfOa3m=Ld3I=#wE(t`1UaF3{UQ;GwBSOP$%3Lu z3A~-znIBtPPRz-4j0q1gFn!&I5 z^bjPiPx>;k=ij0GqO!Mc>a6XgoW2Xqdf-st{a()66uLkrIJHf{p}7{K96qxB!qfJ} zLOv0{ix*5`mca0gZr#!a@hACmJwa{F>3T!?ik|#?L=s|s)he6#;!p~ z%13-sox!sbMe57O`CdbTsT`b_Rd!O3Kxt6ya8;Dpo1KXPEkyL+`#<;Cvw6uzQq$r3 zrIoc-mqsM^f`SA#Y(sl}qR>SYjd+A6-;{locspF9cz^au2r)M)YtXU^#&fFI2M}(1 zl7$<;DIQ91SB2`zi=sr`zt7f#M?&K;D=~$J(w_??Z{Y~jn*d#znh|(nq?B^~a`>z< z(E!ZCvwpY3*)O-23i> zO%x_Xcl)Snziut{8_K~a>fEruarmek!`gkq*Gib!Iy$MRi%2# zp^jB$PO`50(z$%lMkRXUe#Yb*%mN-$bNG3(A5UX_L5n(8yxTUEu~zx9cfm*OpG#wF zC9MbdQv%PuK0R@oboy7WYP@RG4b0U3bOg-aVkW{{#-^^A@FVyL+@vIJU1v1xIU;dp zqKfApo5cJ4N1@e(@V#TmmC)$OZ5>Z zt@_bf)_5`Wr+1+yx0UCY2rgibpJWF@S$aWjE_*mU-Eqmz)iv}gci1b^>J6YDM=<1g z=_h#QAB}}S4^1(@enz#~Co8h3|2mPQqSEA_@7xNp4IA#9e1|Cd9^5mc)tO^7g-!yl zL7^LmUfx}$!|~X7I=qVDvneSbc3)yMlI!fHOU>1?Bb|hA(l>QJSB|%7m{^brG3Q|@ zb>D8q(g@Ue=;LweLhpb0ZLt-9j>auLgwJQ6x*m5}=hVDPN*q4*I3v(uUX$N;tG-^H z3MC?qij95$c+~z(ti$h6((%qU_S23WwKy&IeG?KW2`083Y2OwA@>{zm?6SOQgAGWz zda(gAel;j%s}vH84<8@|fnfOvKD{b6SFtC>aXhv-P=|bj)T+?kBj^(xDSITkoycaF z1E{)Yo{|c4NA>nW279S;knv;V!a04NYFcI1OnT>%X}qBZPr>!i<^!lq9kG$%i3#y` zZr;`yqF4gt+fV_h>mE<3(Rs=H(e&m!znT)q=*3|C{u&?jzIi^AVF?uBHh*TC8ITb~ zF%H)NHejqx_Q8=I8&M2_KG+RVc4EsBFg32(6^dW*m9&HkU!+_qGCqmanl6F`&}?{z zuH+SK4+@7k78wiNW2Lp64WlZbcnlKn?9wLgSR(qIxyqN+KgsN^Pcwl=KTwFx6}L9F zDm`|_btS6b*;0IWWe-8^?Yc*^ZYckGKf@l!5z;!b)z+f&(DY_#_SCaua{PfJYu&R9uvt8VV#M*J%YO8$kDJ^7@cX~ zul$T9^AWv5O79DcU#FDFT@|!MNO99<{;u=RaBA_II&KH4O~6d?jJ##pHwZIc zf2|Kp*N}S4AGAQNCs!Y_G#FOl86e>pdSP{%>^&+o^|cf}_kM*4CIy%WK#}gW}d^HKw#q~u}=iWm6q6rVG7MZmVE`~D?Uu`4+!vVUbV=f*wQ*ypbKAQ zic1z2LoJ~Mzvn1Hjs6;JKPWGFq2xHeY_$|tsK;?8C1#0idOIJ>;JmD56DY4sfmFlN zcC^NJqrJJKJXjw;G3?`p=4-z|r~`Ubk9+)9Q+@3ydFrwiA4G%jwQ2F$TEs6QyApu{ z-f8d0;fFFKYC5o0Z;}cZzL)hk(P1`>WAa0)^8gx#ZT`eGl)|E+D~akraAM;}acRI9 z2^fxi)1!v$Pp?p}(Nwg!SM_}3v^bPo@MPzEVR|_Rn}8%)MO`DIQ=Dzzmg#GO1Rs{W zXRU#Nn3NTo?8~;=_uGcf^01Ngg#=}QM9)}??(RKvPKZc z1MXw-l4j@pk+gZ4-Di&6d@m0y6lwFPLgIdg?~<MZYFBMyxMb ze~x;Qx0pZI9+zoBCP~crJc5oFIKHy&W&fyp(r8~?mqfWnxK~YvXb3fuA&YA z8=%}#ZcA}i;tIA?5)N&>Du=;XX52P!lxI5ef}2d;h$lR=lm=3Jo3khQAquLAjL^?bHK>LZL9l`;v3}+<#c<>j z^uCX=d|`W#?aP;yT<$X&M*h%`wDanikZ!Y@K6?qV#C(m()|e95m`T!3Vi|HP^+k$Umd8jLX2Sj`z{J{vkfb5?U zk40p;=OSKL7>(7)-S(`FKOl1yqtO9j4#!m*I8C(Ylf?z+?waT!wk?Q#0p-p#dJ-fD zlWn~fG(TVS`i=qd_?YuXp@sY}{v{G;T+9?COP!A9PBZEwosP8mi;pfXZ+4Upbw~Xl zsc?{$iQjt8)3%;8rzKF3c<}Dk`NVg~pYe^kI8i)P(JCP8}4-jy+eF3!z zVN_;0)d~nw02Iyxje*Sj1PST3B)9p9Ns}h`R=>S#oOVZ{3$4odc7Xr`_K&GV@v@Pl zXGkqC8!$Cqwr@n@?J=BqFF%Rb2@Nwh!7Qqp^z62A3V85iW_Y!#aqqEJk>TAJ7CO*4 zD#j01)wHK^3`Kc_eLLpyILw*zZ45l1vJ`-_)dqT@fk0618tN4(7N+fh!2%x!ENTw^ zEDi+(a-pW#aYu=zjh+5g!$EF?qC-U0Yg@h>f%zRp)SXzM+93D?K8ehs5xhc~VJ8Y2@QQ*}%7)x#1bC1aGw z^29KmtGt>AIqc}!50bc7szuGVn^eirgVmtG);fNM_6uaSuRsyWFfF1usz<=UVE0Q^ zhKH@NUvQ}ixP3}EX7LymHDxQMxo!_kF`-uwG45ejA%YNj5`YB6crLp^ZY+V~>@`_)YLX8nuqt zJDGY%%J4oC+>@v#dvvOnsxO&kHEmy+A3nr_@bp4>fn_I7i%a|(tey4Czj3g1*@9VsuP%VE z#A>CDWF+IW=i6(?zFzvYD?1zX%x^O(DF>JeJ9ar)4sXj8VF}#gtlqTOy@}mawS9@x zjSSMO`nCPzGR(mdyLbaf>T{AB|KnF-O8#W+7gXl!V)32;8v-79_1_&eGQ~xzPAF-B zCy^nD=y|0nq_C|>x~*=Bz}0Mg+IL(wys;NJ7)uBPYJ&pV3>)Ke)D; zXEizTjx*!CpS^Z+ViFP3kH0F!aQ$8pxQXMW*agj2!142$ciW9UrEDLKW>0{<$%&?N zJJcpS<+ZV8ZBXGg@#9yJ1AlNzHc8)aO>?v|7X67560_p#3Dr8nF*Ov?Gu;6;Kt>o; zeJ+a#AK_3Y-PRP}kwEQQoG_kg!)FeOM>a2?uI0gO1OIL&;r`6}&8O$A-96O)la?mcWq~8}=t9sdu?416V&x zBdt_^=x6ET2NdD$?GFxGUrS@6Cm~N`ST~0KM3AI-B;yN)AwvTgdq701hVdvNHWChP z1=H0&0;`k0ndI1?U|{>-ODlX!GSc2Yo*LhsZuRhXXJ{#(cvq@bhd;$nBuU*;l;-_S zHbLEvh@@1zzDXKD{5I<*bi$G%kSCv2nw&c!<5;Cg&^L||7g5O4T+<`GRWYP@qjBcR z5c->;A3FX0WcZJBEQ%*mw$Dqc+62T_z|dMBHrT_fE#EJoVG(Bgn_}Xd$ojs)01hnp z$t78TEK16l&IH!_z!HCr^*AUOUlA|weikCwYJOnGbchmf`|Us8gC{qN>^#_BY$vm2 zx;CS<_2y$rk~b+ck*MPq&K%#DKF9RQX4PyV^j#j3U!z>(D++^dHrpb0)@xz8QW?Zw z^)qpmSY?R8he2u#Bd*;^rypia)Zq+4)i1|3;^1`v-)qums!y;ZA!@u{AkvgobkQRv z*JyS3l!A!4W>Ktqlk9P8w=dy2M^?M7i24iqdfltff`a{KvU9$yg-krt+E585o5h|o zF_Ip6I@+Wk$iv3Q?v}5LV>+Mgl)r<5h&Eq%?9l|@T2>k%SX#-nY;*ZM6q^$Erjrb+5m^20tk&0&NeoI$n_0fJm(xd1R7g9D{UA&eJ^wV zVz*k~7wf=Hw`ISQ7M8ci`h15Os>9CmRyKD`Bt|{&;3WkH+cHw-J#pUtY!qcdW^a(c z#+j|1K12$sntTx&de?^Cp&)Y2?U|$ueFZOpBEtTrx;0HQ;Zbbt32noir1K8h#Lac-FcJC{C?cbbMSqtb3B=Nn zyjqDr)G?M#egAA*AQN6=u%fG4iLvj86b&8!eJx|={vlfuNw;Y>oB1dWen5qOBfgX^u&3O2;F4-f_G_UsR*wK_;J%XAD3zDRTJwyChV_%y$g0|i?g60m1^93ts^XJl*9V@n#;Q}FGq1)0aDtSF=M zFe;drU9qluNjkC5@T1SLS95GuP@E=9lWUHmYM{Ll^V6yPbShiR5GVaxR_s{f0DN_g zvCzW@+vYtZlO=T_`;I$KFO(WlMt3Q@&$Aga!a~uS-7RTN3xf@j<~d~GU61G)od9}b zR&t`Pj-X??wq;x$OM(zUea;E~7=oz+>GEaNH7@mzkY5_i-BWlp)5 z$~4-Fql=4(R@UGppAMDsh2^3H2qd>JAd$0g#SPiTNO?2E<~~Rb1q<~2@hZ%apQ1H) zc^(d4ojlpW0HshjUN{;=a8?qF`i#-Dk&<`o>jE>bfo`&$ld4VgBcN6#A9M69(OC29 ztZQKj)lCh6)Rhgzyf8hsqSB=5NQZmQtlQrh`jXvCpS~S&Oy77^Xb~*d7usy3a5eRw;C|k?N;trQFK|(bKv%i;fDtrp$4gU$?eY z$Ran&FwG_jSj)V-2|CXDJ|}pHSy(d}HJ-NN`|P)m!vm7A~RWsCR4T`VGl zZk|tpaS4f>{@huKyA)|uw5#qtoN{=+Uq}b=)cWN;>ARdJZAx z7k^gbi=WN??I?VF<=E@h`YzIG7Za>w0guYLZGCA%Zw0OiteW0`+(=z+rdtg!c#p%k zs3t-3Tfa{fx-ZB^h2zuaj(RYs2~qw*SGmCPW2Dr1ShmaR8yfpBK+Yhqj0z4U#x}Zx z!a}jHs+_OB*;upV3-zM+kd1UYCagPxGC{7GOcn|Le0L8D6JotR?H;349rsFBf$mO% zSgo+SeVVchM$oX^3L$s0eMcKOD2r@jZit(+Kob-GwH0LX#m&=vEh!!S{YB>(2??4O zgskF3XZ5p4>T;0o^$>s|K{tq{;y!psx)z(qU~xLG!;^@OgZ@)*FYwSIALyi*e$|8X za$8Iq=smTd3>y9NN}8-XcoHBV@6>90ZB|pWu*C1$y1FiGJ9jV}(KjTfa-70z*_sK=JWzhCLHY*Ks>~@gta!@3y>5nLzaC?en zR(m_Hoh0swojJ~W;ppxoCwQS|!;5sK8hoDDEBlb?Ix@dWI&o;IU<`q?VQ;}6jw~6d z-CsNHZ@LS;CnfZt!AeBOf;A~QPw`jcuJ9Us8-yYK zvw%_W_Aliw@LHAoMKwD$y*kDBATt~gou!Hbaf=5ux(o3q7p%<1k3SdPoHr_3Vrt6j zl8J`JaI@@LKD6e6+zJU3J*rw!vD0%JoU6H%V}Oe+JchYZXm$iX*9}S4GKF3TVFgwy zpYivXY10&=kd3Y<%DRo%Yk1SRBj045b+^vsQY8QcNu%fBEUqjuv`txaB7w zlUcnFQJyF-V4mqw5`_lc%kH+xL@I}5^$j=Bz+h3DEu!trO6Rfj&J}u$4MG@8kPRvH z`*?+OlSJ#NL`@$u${TT2B(L%>gD@7prncd7WeVb)7I;4!Qt*lgmzH(vL-nrE zhbPUr+U0FB%HZQ7p~Mixw`hy)v32H(IQJ7m-xLQo`u_MhbrJ zPs=r?-c2)1m@dPT(e7TEk$6lB^0;J3bUsQPKXlk~`K3%gf7b{~fT#_I1hTSNTkFo= ztT5A4!N6zkzRd;JDSK)mMaA!K&78SbAz6zSkyW16x`loqSwjAE+Su#!_XrdCbJ_?6 zJ_{_LpVX7c$jYfEqpJP%DJLr@HIbNzkdTOkocb*>6)2@w%F z4Mk~Q2KeN$FefD^>(i&)g4E2c)T-ha+h;1&V>XeBGm}lj;+8E-3<~ z85qU$%W`f~!F+`K_B#bZJBjZ8Qp-68`xL}5bREa}2ua4rU~RGTskP;4^NCS8H2B_Z z&M6-rE%{(c%yMuCQ8k$$0Yls8lh#bkIy=nni7nmpIX{N+*>nQWcqQQKElV_e2!x@{ zcvi0e`FJdkP{6mvy7WO!?CD4c0Ug##H)cazKD#W^lEm;Nek?LsL8ZQT-=KB0Nq(J5 zJC3i(_itdT<+*Kk^GlQD1VD*19Q4=!3Ov8|KlbYVcscxT#W40~d|X=qk-%Gzp-hnx zCHOK5r(RFp&|g_uq@s}da?hr?JL`svgd0(|QmPQZ%w()-6ad8VL6CDUaJ(;=FlepG zqMzuBWimN8lVd0p+vXMwQWToTdCT8R%|pg}XhT*+lY;><Zg`dq_sg$F>ciecpysBSJ znqjp30NrgS^ehCJ>w&&@tZ%N|%C+6m3Pv?cy#{5OKWQbnJ{ItAj8tsz|NL2Efx&}k zRnV0Zy28S8)Q~!()5@KXK0+kgt)sJ{VRjNy^@ckM?<;FE`p2f{FKQ~ezwldb@wq12 zUp!hh-x&a#?oBY&&>pqqIh87NoBlL>KTy-`w2f_Ar%#UC zNwaUkM(Gu~e|LPPL}gDJhI32R&JTB(;g&k9*Tnq*yq@-teoU8{iE8u`^4*vjQzTZt(6OJzpj{76uW{q8MAT3SPct zFh@SoTGVSdxWsnAku0y>>vhv4hh!C)27%Y)`D(iIGjq+9 z;$;1Je6$?qjfw5i?5=}H@~XDx`|>`GR};Af1q28LBz@~@@ettHPW4dtPD*28|3>ty zlMEw}Kflg_+rOsyK;i2G5DL|E?~kt5f%aRORom=Ix^d{kK8YXY2Zh3tt}tYIcnF;Z zbE1)l+q&_|_cHnk%3iTpMOAQHKa->;j7=>KYabl;ID zHV}U5_V%#(TF%HjJ362|rT+^gXOe!AOL@NTGmMt?1=PG)mC!~$s(zEGComH-zJ$_@ z_x8t_)$cDeU*vav$A2w&#Eq=IyTomcHQ&-x!nSCLG~{0z|6py}l7tCsX!{L$c>m)Ob?E#cNd;4@6TV6&N-A@SNxAmEi_>lLOYC?? z60(w)OwD9x(_AM4%z)B~(z~3TG)lnn15Cc}bM_nL7bw&@dB>ihmXNs_O9LJm(+@<7 zaFK-(+(5IE3LAbzh@-+Jq5A3Hov}r%GG8jd%9b?O-(gsUR|%rz485) zUA2kvSB*HT`i%6NQfhjENj0Uoy$%h+$o)kl=Xiu(xy|dRYiXHt&u#&8U@52KRV0&~ zL?DCKZy#X}SPK;pMq{4ese|N&=w>uL3OM4ELl{_zAmS`g7HGU)T*YXf@Qu+T{*fq# zAO<{fG;eaAK0lnFEILQ`s9%f7WFS=N;7PRDI_>EpPHJo#Y!kE+sz-bi%KseDz@?iAtG0x!Pq>_!dDBInu$Y*`+lw#^jb?0W zrTtnrbM<8ZyS*Co3!iR*V#xA7t;D?Z8A##;G!b9O>R68~neJ3XCuG4NC8LV#Mj68c&0}W3vzRA?-_xv=9vz0l&&ya1gx4WzG(bXKpi})kNdJ>M3C0sq5)L4^d8wrJrWe=%Ztzj$BhfOq z`e$`@{Ei-L-ispulAGJru8-fTS!M0CKM%F^v^MSIIO@6i6pMea%flpi1sIL&wvge4 zgTIEX2J49VX)iDl5OK|TC2jvctE?1z-rpq6LdfD~T;&R~dkC@*hD2K6IlHvv7El`= z^^G#`rZ;_iRfsBy{*!W%>ir_dJvNN7=*liEPMq|Y**ttbVWymlQX>F)T4oUE%h@47 zw@Z9vO20l{%v(j2wt73EPCn;Hh{=*9^;8Ay%(Yf~jRpjB!~W1D{(;x}F0`JFD(SWc zdBWc4byrf;efC+|N;m}@Sixhujw9L|T48hyz^mbYqJQ;z{bUm}+r1!2xJ(7mW>F8v z;@}m!l@0lNrA%PV4|AU@YkZ7EoF~&J&p8T+oV@2I8Rlg=6|* zKI*B8XTAuV^e*yK5#hxF^uR)JbWVU7dlmFjR5G`Ysg5yF{>r?& zkDY)Y(sRA(+4CUm(>(9ed7tHGYy0f|$ud5xzl0y(#;K%b%`&bfNKCZmG8WVvQmeWb z3J&zS zPue*Q#5scQ{$u@E!Gxkzf$d%M@AN<3DBD}KlzDp|-SNIVE{ns5NE9lgeP;|j`+vO2 zOsP(?=WMt{%Gbkada!n?$1DZ~{KCZ-&X33(xQZ+#_zIbcHi+LGFb>-U<9I=|1RB+j zTHimum_B(2FVl%iPd}J5Y{(aOMQle7GtK1(@qB?P($RsAcsx_xrO3KqQhR-XOk8m*AuH1V3~t zUJ=^kb)4~s8cj5@%3F%53fiGQ1Q;+`8B{51@`P=y zNT4h8nquj0S>>sK{I;$(A?Svtbf=m~f^D8yzMqZep+F)PCyB+dv1qGF9Fw$w?{IRU zuEy>AiB1xmdL2USs#VDIyea0M^yuUTf@0l_`<`RhmQQoe!>AwnBCuO~?>l~c>G|G3 z<4`nSoU>59f)V2vD4=8o(eoa$f)h@?EPj5B^H-UR;8nke5E!&h#L^&X+>ocfI1h=0En8;Op$TKgo#6k#LHp)9^tK8wO&cV5BK2Q zB)!)l)um#0?kMH?-EDe(Kh@kjz4c@}vZesh>dX20;~|XxnT^qWZ0un;s^t*WRH>t_ zcsT88=t85Z*bm;$3Dm_Cin9SXSRaj9ybSi}1xbnA$Byrc^C7W*Qr(H|5!DoK^!r%2 zcC7*Lk=OFcd*pa!?3AEtzp)0xTurVbQu#fLAl=AD3^MmDCRq7-=Ia%$lg1;6omY%i zJ%>#}tW8?Qs@Auy=Q7GpPA{A*P#}C=Jo_?&45NIm<*a&BI#|*^d6Br^NPR@G^Yb8i z^qX~VBs|!jxGxc`2@Lc03QL|{&pDeGl{s?+;v5X_Lsc5m{9V6o?ymDNjbcOVdKZ9= zR>lWiUVA+*H59JxQ&zsnxB{P;8jy^p%glE95;%D#?BeSCh23v$KUx|!+&DPifA6-1vV;Nj{`pQ4&l+>`OoP@~ zX-uM~hhJQ)kqACv`b(V1=#x=5=EbF!^zaCYU{&S;HA&dB?rYAI#Kq2f>-bqKEw+fl zM5t`wN@GB|8h0phkK3d(JvPhIVBK%aZu+>P5k}z~avsM$x zA7=K&QJV41_+-D+Ex;QLQ#kg6QR72pwBoIgX5zHnkYhbW*Q8>f^_`X*1SGX$ zt;Ra3nAMwx0^Y*3kL7g_uH@;$cZLKE{;p|Vsj+rUBQIZJDYxw4etLK=pw{H6{-poZ z4iA6CUw%EIZYe!REAEpLJ(>T|OJKYd&oYFSHVGR&@mayvGn5M2#F%&sfuX_pBLd4}XknP6N7g=|Pr;hx%iop-czQam% zB)A>K>0WJ6h8L&9g2!w%K}htX*nnXx(KZPg8c_+?U>;1dfF9G8N^+T57!F?I&g=c+ z7duk{B{S0i$J0ojAd(hdHIfngWRcJKfv)(ep);9`1!3)GR8?^D`LvQOQlDfPkDFUx zHe8v=2`uFXypf{H7GQ?Cc}!0VoN6jnjPe!O^Furx?Bfxedwfb|610l#&^Ca>I}=+6 zYR93DQ33BypYbtmg~3M;xik0#e~v`j>ILff69>D5;$-mYprJyRRv*#Z0x0DK1JR3k z=8YxDl~EUWwMUb1)82;9;b4R=JKgb~lc2eEMtFqa-|yYb`6RQQC|Nu3L!_+}g@Qkz zZzQ-5ona(ma!NXCtUztPM=+(wWf4INIlvrl|N}&8p;P=jg-$uR58d&rIk|3;JB1;e57m7M_U>u&@=9&T9*nm>kVfoHWs>{~ zHZg|N?}r2AD%i#BeNo~dR>ddoXlLL%<9DK@;sA5Y6>&@GV;zf`HZxnzyhmhDp*jT9 z_k=tLK7Ksy$^LPj-d-LMxTM5ME(UlaOcWY;7d4e6liTeS$;8vX=G!oAD}@LJj3!1W z6z>=$tBL3k$?V{j_Wj%?1NmXtWj|vhRNuxzm-@xU{kniRvn18M z^q87|EU4u}o}a#;)vpU_$`2~9?*30?Gbz~{`-}u`nQl0gg)Gm^+s%e>MiTfg4--IZwtgF>y95JV!-~>= ztpf#yEfPwB4cabOgYz#Y1f{pTS3bo?$ubyHTFa9e$W8}@lQt!Z)kVUVE@EuX=+!xKeB>X10W6C z>@SdqfQf8^GTbzT#jyS033LoHiSI77lF$pUeTomQgbBWtpU2s5s;om`(xs|@M9x47 zA0DTEfD~ITV#9XW`1Pi5_EV_OCPn^JJ1EYK%fk;Vo!65CPvqld$S6_Ec7OE119M|d zrMZ?|r~MQN6L#x+p(Gh5-H&^J~9Etn0glQT*i-D!Vn=q8! z>VqAQ(o5L~0E2KgxFZ~{fcEQ8y`ppl==Q+sXTr2+38q!O{9NwuuF>k|A6i#!*#;{g zg&uGfKmU@nFwpc~kjK+g$wpsca7ntmpvJ`uL6P~esV0N-jTACa>=z$@(!Q{l+#=PL z`lx3hefNUH3={G(!1Y!uU*1>i13oN4VwUT&3j7uI{G>OLMCb1)iH!^p3k8>p>Rnggw=l2*2$^>)jqf4<7kuD&bCr5ExFn zlzq9Q0Lk~F2joY0*JFzT@5%q_C z1qllckbJmK0jyj-5^{)rqQSct0wZSk0=yARw-wa9E)5}va=Ok=Hajz~ldD@dF-wslfw&%iTu=in8bKY9PTMdi+0e)|!0TF*H*Tm$9I-pox4M7Q1)XWjalZ&9EVGJg%r04*={ z4WAi}*>qdcKu7={+ubb76>-sb6ims~hC9bp3vMz~$c!bFhX@9YU&l}g(n3>hJ)`fx zJRC$Ty-|Dhs|K{Nl>7C^q8JcTSDC(hAliHNN{4nmj&kbMbsE@sE7!M*L)HU_z>$#U z!cql4KurB8tuE8a<;W;F;4*m@eXl2&;ul5+k*)p{#P|8)E@P_U^?XMFa!huwU>a+FJHG-c1h~ zPb4Z@&B+WSQrwoTwINta-6qe%tVXVNj_l9u>f_YwAf?`q9jnlleh+Aj;AnT!8Y3pM z4T=36Sk11YfwilBwqn+OLP{$jX|zA=*u=E;%wp%9CWTp2qm_a~n>^fLrX>8>IUm3! zbbtZ?9{c_1Hzd!ifj88OTUYC)Y2;qP6p?9UL+kt~A#LHtKjQ71uUR`azB0Hy zW}@zc>C3zYZSJ&>&evuYpIIS~`i13PEMmijS!U$ z#$?`Y$tU%{a2l1&E;ALKuyqUDYbvWfU>sn7KDHphIy!pee7lck{G$II*>x`Czd@0JlZOMX-G7Wn&soWtMUXsPXrto>P!H={iyF>{p7-8H zbebAPtQM{<_ zWlZ~nrV`LLO7)CWEg{Eh4gpVRXHx(Gz%~K^00000GyZpI1ONa4?n_8*O{1BfpPHWouHwenVXrHoSl}V z9U&$motv8;92^@UB_f!cqn$ns-js5I?ECRG-_2w|yM>$cTXERzx`ynEH0WUv1c3BY z=Q8ERyDW+R6OG^hZ}U}evv{x@$ZcE5jroY zUrFDNQy;UC>t{?)kt>57{LbdoU>mp3aeg z?t#zuL%`tdOA{IU46s+3>&;WkBeU@8zAn0d9RF8yP-&|#wkgiH(35_}un1Q-> zC#j!_AttY?)A)M4@7}1jW=#kp9*7Z9iFe;mVlzz&P9LgY8IfSI!+gu|V5!3ZSfzfk zUY)E?Cb*5z-ri^AdtkdE1G&V>h`3C+9IMt;j|$%7h5-Sl^HS$bs&CT&Y2*cMOwy#y zJ;sgl=$=46058egfG>dEVorV+Z1qk6UaNidGqsSy{@ZA^;o1AQN6$981R+8V5POp$ z29bb(N7u8rAIW%?9lo#rVg*q+o5Bi5Ef-;vgEYUsNYfSrY)rDiz+^a@Ch`Si?%2** z+o`eldvGiAb}?Sq%03XCCm2ko1Z1Em4R_sImZ{lZ@$CBgO9cx}Hr+qS17PpJ=sSBe zWngO2=E-eH*o=0J%^@>z&U@hGB&ktJ4R`=PT7BX<%^BqHL|i*OcH+cMhOEH?fL^Fc zh>Qqy7bnE_I@$Js=Ml41H)szbX?;ff{`=k_D5*8;b>d1R8Oj%~1E#?qmG(C;5mW=| zKASe#uZj9l)(WTBXL94dr+TgN`iE~*AUYm!K#S&NVs#*KQSuBwUt89l$zndKVI$Z% zF}-#Nr9txJu;VvR9~4xqs+vIQ}fH9$OrOSUYx}oR6g>PO7)pnS*ifmc5C$p zjq?VoJ$u1sU$0MmI*G~Tb1J0y@%$#ke_hpgB^Qidk3vdbT2t21ia$77s=ZE~YnSr^ zggy)&I+;gcqE74S5nB=!HE281Z8iZYN8oe-Ao#=o9`FDCasQDZ0bUxtE%zyZNIxHj z?DpHH9+}+M#$*a(XT36WfCeSggd&33U;y!M6W0EFIsbQzwwfDVb^p3^j0_)5>A`M6 z^`uoG zsPehUHUPBMIy)DM8YH-K+>JL@c&uk$aP>K#zPr2Yg8-ld_UckvvN8@oL4j-&06q$x zrn@58(U~RLQp5E6^a(Jxkuud5fJ~3FX#g=;y>(f?B_8w0?+g2x)^M5O+CW<*=b}H~ zy&Zf#@N2YW=WC_GFGS)9yIpKuPU`1y$oyL>a=TmK#*(w(tVSiOX}LD4f9G}U6bybM zA8m-xyk5v1IBlQ}L!#3Tkp+K{UwQ38D91+>%{}kEb0AWocC}Bt!_EL9k2hak0N@b- z*65V(scfKOHChMuFwn=>`8zKs0l$INdY zudk9+i(*U#1yjG?;$Q8ze<~N|cDvJk?14-QTi?9`g&REa=%HfUZ9HZBNu`3EQ>I+9 zfTFkrUK$9Nw40({uSKe=Yz*FsLog90;xx?yy<52f_t}g&jn%m?^{7_zc9TwVIMqFZ zswAk*d?;=6hVtJ^JtS2RGYbF!bq4@MWoLZ&Mgb^*T|h9X)nBWa3SIMNy~(&tqT{mw zB;S+9phW=?zzgtcai&=W~dLJb(lMsskK0YlcZ2hm?Kdb=?BH zsh=ROb0pydxTXC=_do%F9=~et?o|xfB0zok98QNFRg4WR?2`-tMB{rvrQZF;;Q@UF97MR8 z0SsGbwdP%{a>i=nl`VP6;+6?ekG z)m8%nLcsnZ^e#zA`f~dckDFd}4z7o0G^eRG7XOsnQ4bKTU|ur;)i5Ge+`7yv>u~ir zd`in)guS_tda5nFuJ(`>AXh?}byA*!rR-@HRpX=GDDeFg}`B@ zDj*=&^8$x{e%9GeVCovUaYw4ZSLPBDme@>gj@bi@{YJ5d$$qZ8seWJ0 zhlzTkcRo_~I-SQ*4A${*r1$v4NaoDFeSa6emfBap-TL)yPem4mmV$m0QpIj-6 zxjw;-3vk|)b_kW~3q4|KuX_^CM}B)c%>cN`ItfJZI=k%kA};~&%^aGJz~~{IbpR}1 z^Ot$|>FZwL0c`m$O}LHTR8@yA7QI_8j1dJK*Cua7AAkUWC%}vwB84@j9FMrhDB|`v z#+7E*0TkckM$;Yu0@xVfn_nYG2q}DsUjQawSgQOwPV@vE+2gR^eya~a0Qzp$Ozko9 zYL53ehEbXk)VB@{*EZYz{(i**1Tg$d)Dj-^Tpi4%*Hi|xpZ_Nu(WWoG`%j|*0`}J4 z@QOxgqVloY)GnM9CJfarYV7Tka?uh{$!Fg~Ry*z3S~NKy=4<2gb0uZB0R+z#i}mlS z|AFfWAesMOSms+YVExkMq#vE&Cp)5O@N#Oe0vy*(X4h>$G$&({f?=NGW)$N3R>JML zNI)^?IVm%qO1=UN&n=@P*Hb=OBno(C8VSLIP(hieiA5HfraArz6xWK^bm2daMG}za zy3^Z5M=~mzockth-i6U-q5@pLYPjBUIr< zS`NP5yh=$bZtW2JX^o4mGU~kroD&gaSmEm*iC;G*8URe;dgp-sd#aRl=zs{tFP$7) znqDnD`lgqL%`cJlj3q}|GR z932X`b&}oi`NXoCVKJT-_e@?fS+NYhMVCP)9}Rk?61SPuu@?O|sQsBC0Kg@#^WAm2 z9D>FPJ2QB()xZN_oytqeKm?!$JMFcefQ3;Pz6QP-J=q>^1*P$9O7#SE>)Twh3e9Pl zp455B$N;rXxS{pZYxcaodABXluNYlVur@O5GUQ`E-Gr@%`G0t2a$Ozybi=n;V{W zj|KpAEPK_YRDc-tJgc0Od!7#G9e=&IOk;8<0KVy*=$W&O*_^X|%4I!evUw4m%r;JX z?y=aBjEoi#D`x$_e;nVM+V40&*YY!0WW5LRMd`OBL#ICy(6u-J#M-q7fM}I}psC}p zHI6BK^$tEWzZH9vh9DbVl=9iEC1Jq?cE58$D`4p*$H}vun1sw>&Y`T-*>Wj{cV~_k z06;=N|E%7aBM?vo_123#u=v&t9p;e^(7Ev28NNZ#ry3nT*<4wVdtkcXTUoJ2WUJ>4 zZAR~_Eyedd3oS&jOE5N|QRKG0bDUGW*{(f&ejl2XWkYLUE(j|7*#jRA?cOz*3HU;I z5~!H%%6~!_vumy5ieo*?gy48kbBz^6P-cBO6A{rz$Mw!nwRCnTd0366RA%47uzQg> zi3%V9Q3^25b7hSDlK^D2c9?xEiS4;3;{gU`0Y>Qo0G_MeOz8j{KjU;isfe25=JeW* zBcT>q>@X3T!2o~b3!-Hzp6j#6{jK`wcPEavM}6vhy;Ek#SKB#q=tc%?F?d$?T4{0K z?ri(UJZmnv6De%^)(!|Tc(o~XxQ^8;$z*DU%a%@q_sI%n`Y911#(?F_4z9+Y(BCK= zW-@`^XI^C+TobR2Xzfh(PJk3v@u1THeyZJ~7peb`We(F1)Qra*bI}JQ!HhWo$Qh|z zkP!^f`yW64mh^Ids(N?#sHsGNMB1dN(ZBzh=%Cqm3#YG*B6YIY};wnwrih-Z`h5vxiy$C;H_;KiJG>O8GL>DNWi~8@JJQ{ zM;uq|+MF=z`#YbIbtu`IzK46x3~CIDW+L{g=K6H4xibcU@{>qTpf9unz^z!}*>7B% zk)~Gw;2IY&PQ*f_A{2ame`~p0768t53IN_2t;93yXH0h)mPJ+IJzJn(MsYyBfDJ&- zVybo!a17|yLyRW}>eAg$>&?qePr6dxlH}Ta{2}Cuv|HH#gR$ha2vu!{m3buLdk$*e z;TX5+ddwbt9=3j3$L<__*QzkNzwofSB^V%auV^%(#`J9JD%C@oDHC-^&e{QI0RXAl z=Oei`s^noMf+7@8FvDlOHbakSILYsswnYe>5|wkN{V8^!WU!rIk=X|g>6}k3Y_B$tvA1@X zxPbYmCS^SUCiO@C^rjrn?dLepf|LL9$z|@8pV0f}yy1>T7fg4+!$;~L3ixsEA%xocmK0vyipYSc}E?w)H z!q%2NusKE|ooOE)EHMN>ZMG*CkB*;0qD4sl&Z(v;ID^2)>NAAFP+Mtw{w2`TXu@9M z7qvw{+H_q#E(y#gqf>`7uA-S{Z_EiV z06=k$E7i@QJeUB$1fJSGh$HV!c!|$oMD6fA^IHQwZjRkx(*l&tm@#NE0_d6>QDcnf z|I)gDyvLXBGQq|Wg!r%j%WOM~Ch1psbwbP-R+g>Zy^U84j@NNs_ALDd1U}*w5<%4X zkrTN#Y_+FHuj=M{ydn@YoDb|Nn<0Rs+XJ43xN){K+a8iI{=gij5J!`MJu;#@3{m2t z%b`&D=rI5QU?+_U0HwQo)X+d>fCt{%o&4U#ZSqQf7f(_nvH}1knF&Dlgs#e9jsS+e z2VizA`97uflU6I(=z@;*;*fQjj)yY&KfYU(g7?mUQg!ZEeNu%*oP}JOvG)l~#y&XE z8p^`fJXQDbfL+%ANF#>`zWn23f*Q4bb>w4C-Eo>%`-1V$7WLA4-&V*86PW!jO6mB5 zKkKuhnHTCZ4iv;~a6pv^K(v0TH&iOU{u@BlS`?cAo|?UwIi>{oH=)L4BVIlgthF)M zb-HLpgb2Volf8xYCEuRu>)JS}Un^7FCFk7NTDR}__cx~(r6j`(I~7u??ZjW`JrP-7 zKUqJ2+>t)s=32uu|88qh)*$oLUc+1vYNtzEKn}NT{uzDpDftHqj*NGIy{ADfYo3t< z&rksH4q3Trzixf!PQo)h0|536X2pR)J-T_Q5kN6k0N#0BS)Da^(nI?HwiKLYmFUTh z&(&+#x_cYI3>nt0VTVG1uzKw4iNw1|`w~fNXMMG_DQ&;e$Pe(DXJ+ zuez{!$q)|Ch0{|>Q0eJX(|F6;igazEDY5@LO?c$cTn6WZ$ zs1dn{vrs{pbB<^L3u$6e=%Em(Yuk~iHBahZtoHPZo@N==^hJy32VW}(hKtHfWXOn< zS5D)6cvEJu44(3n#nz9AGEi5e@0;=N&A6c}3#_Lw_Lq_x1tWq1oA*uAL=BytO^8FD zf*J%}dn(O6BaM1?e@e9`a(r>N_5eBn6I6nTg1o#0ELs-X#&GpDih0QXTol9m=$~4+DL* znCJs_%T?GtZ&yw(@n^6`;IyFRSekfi0YfgSRaQw zEf8$YH`4QhESUlH&Wz4(^FHsLp4=yNs5i)i)#^=M^2Zs~DRd10emcFlTeJ|DQf`}! zb4|&a%MBPAbB{d%07`;W!xR~T+Q&$)W(i;QY16uMW*sd#qOB1QJFn0)OFYq44CLzu zy{mUwO~Q1Kw?5mpi%Iw1OTUnl?YWULpMy|WLJJ0iBQeQK#dHQUXZ zNaW0fM0I69&v09imjh2;n%JcbB7yqb^@5-2J&P6nXZv6_Fo6#KxxChG>~snf4mF^g zF>lCvB%n<-0K?Woc5U8bmm7zjj%QlDOY@eRLI9j{k1&#d8)c1IUY)o^S3XJNg zFrH|OX7G;q8;{-YkM4Q*B!?r$ve!NFE0G@*(5ZX6VH^Mh*ZV_VSxFZ1>Z`8xn`2M* z!nf`ckiDHPV3Rx5JkJb6>P#yvCj%Q$oZnd8#~x?v4F!M>-WfgnJ#+{-P#bQ?mOBgd zATz0;asW<{SE1_79UUx+OoKlmS8O2#`9*_Fhlz61o0bCIe9{!&x+FT+^EY1Op zCjeTMJ2I*#zSRI=j*QAA!%Bd5@^vTus{s=N|FyCLo_d|qJMlouqB-`}TFJgnA~be) zUY+Tjfk6v`08Sfoe#2(kxa>4Kci$r0jP%WLWf4cOY3DFZ72JSVFUZMNOgxrnA7gLO z(QOl48mh=$&0})z#^g6bgUHu!({yOn@&7XdZN=(8sP`W+#{OEdF-_i`IbYwtVN_@5A0Lk@XY2eXVqaJvp|8zIlTCDH zgIP87($8F|U?;cKAMZR_*F`TkRqoWEnRHcC`6hvOYof5;6hG#6^fqqqNO+5D_wdt< zU7Tao-PF-{EHv5ntC$OH>dDyVqa@>eT(Ii_4WOCO0W{-tsulVHAb|A%yWEl_YX~7e zm{c2G=T=Y^V)Q~-d?m|`&)0BCjW0gwqtmwZspE_Aunl$&1l zcFKResm7t%wh7MHl63}MEl+PX-(1OIVk*oiUH)Y4XFOX&={Q%>fdP&l?=b=T#Zfpq zjt2iD0}2_%|1+Aq<3=j(2y^4UUF2>QwSC^M(RE)_78>;*IV!Uor+oFK!v$nTvyw-G zHc2$vq;iqAAr$}~9Ntv(f`NxX**_Y^siwHO{o!ja;J86%EY65Q001Qaw5b)ja{GF@ z{qv(&!+zpOZI@E$B@$M&R=l?N6tYI(M-vhIdUcDuLXJfhi!5#3koF2bQ?GmOEU@_` z_(COU}$0ATVwCjko9`TZE58}}E>G|XIW z>^I#tt;2QK`nLbNSsHceta9bwPFPv5Aa;$3CnGn`C`Z|c8Z@+lF2nM6a_#4p9KCjVO-5SO8Ll@`_+zuZr&Db=`*=&5dQsu zBmjn*5^^Sc`&63Moorp@sR3;3%bNl40Sw>^VAJ@byj92s>4*D+SaiU$ntqj>iX{ zz(wxv_EywZ6~)@7Z=YUFEYUXP9RKw1v$DrjZwR$lzei(=+`*q@PYFF6ht2=p5lgGz zK~}gZOG(3EaSaoR8~(c8iErR}L3D`5+Tqc4-4DG;bzRp1K*`{U)V3f1=y^zNpNrcZ z!})Dnf4T*i-n+t`mKmf76TdI62QF7zEJT)zpE*Z65pU;6ZIt+MhwWOSNB_q&|EZea zy^>J005LxtXy1H2NEKXMG$~~)Kvy`+c{&jl#f01HOC^|Cwu0Lb$Bby2hyWg6NbcNh z7ceED09Nx=lzG7bKC3;@FVy;Ly8X4cigT@a_N1d>=Q(cfObBd1_E@3>5d?6Dgfbd) z^BMKd2gUmbZAo2eT_e2h97DAFrL;Ob@lTF5g_(qD&wg|w=xsL}BwC7<@C5BRS2WoO z3hW{Bsj-ox6n3#xnaNU^FBD{-NmBhxmN*Vq?7`-FJDs#QBU@?wdvVj4gzoztM5YF> zUq_rrr{8SzZfH=yo~PfG8y!40DILunIqDC1LhbSP>u!GKyPHo9h`n^%1t7*y&bEXI zi2ZJ}{x_X+|6@%oYgpbiJ!p5|X}N)}B{d@t7{;;`Q6p!#i(Wb`_94svtwdP8XV(vf4>64bh(VFzYZ`a) z9kmsEP(F*&I*qS=C2Irafdx1NPiJRS002Pp0ssI2001-ocW4Cw0014D^pZRqBPS=B zmX@KSqNXM!B^(|d9~~YfBCDmMqotFarXAo1B%OoST!4n2?>A zot>cs(+x(&FMNxrfdFVdeLhRxzfHQ2%C@|$UjP)-(}r{XS2myxlO&s&_IuoVyZO`t z8!hW~^YNS#ZUxLk01Q(r>*F=C-#G0W5+?UPm2`b@+OEaq)nEcz8Ex@inpY)747)s2 z&zNrg;VySM>+WTlQf`!DyeeBDpaonR&P+_stj)GNCTF+Q*Hz`%nCfOJpJPdL7HQG>+ELQopEhNMOwoR@ z769jUM1g-RtgrB3*H0CNGcL62YdoF+_$E#C`l(ugQ+WUZzIuJdOCuVTAIy13G1nNc zGv?{Kp|;1NYXI~iyJ`&(XaRK7Pf5>j6^;M8!H%=_6e zjVz?51^_etv@0M(<+PZ=7CkGGpaLwxj&Qqg%OG<8E!qK~{vMYh&FDSylU?;LHe=@y}L6s1j83<#Z$FxbTS+1W{?RW z(?Q8bF~FaECZ^`be^`G>d#~>`K^#h}9biWhls6RooGvWlt_G<@Hk^x0X=(Mb_2xkf zbR!zhYMguT*HlqqVdIkrkfkD>Ozq6?OMOOfENExF?-V=7*KBF=)#LZX&M{=^4#D;^ zA0o;PV8Y@+An$BrZQA0Dms|@CXwfJD9*XVl9v;NP{a<}*gttFRz#eSYv1|fJFO3mJ z0s@chD}BmUL-~>}i}vI5qzHA|@ROU8gv{|a>h@%`?WWS8cw}}twg~$VzLo?KcfBZ} zhE>UBrd}pVYodZ*rz-T*4_6#lV3W9XGdpc?v33*^J48+y{cXr5qJPEf+C1HDyl*XO z!S2#|+@^_F;J(pLR%yS%0GdkjsD14qqO9>YyPcKX|`T1`S9lJ3YF!bAgBg(IBwM5VOn|I)Tjn*yB5Wg zaRGa6tSH5G@aw=aauZ`i;&Z4#!1obS&Tf5`=l9}BfC$lJMntMFG9kIOS$WzoL`Rs4 zjz5V(w1qWc{OtfN5~|#HHGt7hqWKMMY{1o4Bxw{lQ3?S5dA*NwnRhmk{KJ4X!p+^r zA~Uwfc$&H-R|!Z!urv2x?mo?zk5k?{|Ad)6!%sQcey5$cKpWden_;inN2}~7Xuw{a zBA*G#>$Gy6bq4Z#D@A;4Plbj3k;}awF1_}UDjepFi11|Mnb7Cz(A+`$te|?FPik?= zfthu<;%~O6ylw~pATe?X_OajrGC9MGRz+Xjt)mP zH6<$mz+7(!08;4`nPmZ@S4skX_>1OuTf1+-^??3c)?RwUmlu^~6I>E6_F7F$kjYf> z3$f@pJZat5vPIXi=+M`O%r;K7vj$jN6OFl@I|J`EnnlJ0`$&PmYM#3r3{@j5d5bl zSB`{Q>*4juTJ2av3$M8hmVe*~0Nl=9)aHGFgiQeRRc)adtr`zeQ;z5HXZvDvT6vv9 zbNE`Tiv{G)UB#mIuMvO^U|!E#s$y}xGTlr=A`fhE=mq4?L!|EqfB+VN<65XC1yfaw zHg7$8go(t7dFY}6?9L6U;dJ<;Z}j}n{rJ3X*nygtx`$~zGn(A`ahC3$ z;kvfUf9bt5fHo63CY-`qk>_fBB!h1~6}hgOHnl&i_5Ryx$|SjY{Ve%+v7y(&y#$OZ0Dd`L(KU4-dC~l>Q7fL8X8dsqdt}sN0f|gGk1`YjSJ&r@ z=he36o{S?VXFkKUS{PF=k6NBJG9U~M>4`liRJgMuqQ?5oH3x4pxAMxc?XjA%xG+t^ zHnl!XMub-ZRsp&T>3EjnOd6=TDxtv*?W1DQ-gUc zY#48$4&h^Vn6DsfkCP<9W=D*;qY+REg{*EL*EQZom4u=-VB;*LzDp=&-PLA`_-NNlx2rNbTsD z0=y6Ee^V$0PLZ!iAo+BRV%c@RYeo}*3BN#q0-rU}@LOy;!#F-FeWV+B|8R-k7HY+~rKmxg*x`my1HL?x4m7H)u?c5!BMYB zJ8*!HX7r23L?xmI)*x?NN-Ol==NSr#(T6~+4gj9nyrfH$8XK5yBWjFWp7!R3z{tpq z@*-0qz<19hRCv9g6_TjcK5>fT*_QrwAEuCc$ctP-v7irgag#Btc&9`7F7lH+teWxy zZ&J%U;;en8OMJLHYD%b>bSqkj1?N^DWk0b#O$L4QkPxRI=P?$G4JoP*m_07bJznVf zSGNtV&GC7OzWVoK&U;pfJfdx!lvYOK)c$&eM9#SH{+lkrwlf9p0shE5+*xWP$7R@N zY9?D(WN&>4Ry>);NERakE&r14G-!Hfo!_jjyNz|2y1%Ot_SQiEClxSHkVd?%P905# z?rw{d=WI|6YEmIfOcSnJNRKi155v^P6M2!ht77*q<9W;R{WXRhv0BY57aQ}{4)?1W zw={9XYz6o~)Ox?Zske;v1f^q4Sp1gE^n=1wF`-SBqMIRU05|@)yqhtof@m0)Yd~(F z+UhzEg5${MP}e~5q6f~PWQag5DY|uS>FVp|Uy{()zSw*wFO++p6-@!dODfbO!Qu)Z z1I@~@yFDc3Tad z^y(bLs}3VjG9u7E6Qg~Fkp0<@$b(xJ3$Fx4+(@Wh#9w z12eoSN2$1NPfXL+FV;f90-U=YT$wCjf=Lx#xIE+<;X?XNl~l`h31sUC=`hPkTWEI_ z37{k*aLD=XN`l?LEs>D*cW-IA`Qy-qS>pVXZ7CIP2^TGktvqm^F+j=P4SsYkk(yz&4W zo5_VK>A;P6EMNdgumC&&9=J^97C%aP*qYN#HPXG2bJHVJ=XTPRVTuGWAf^Y`-xtgd zJ>;uD8;}15pE<6TW9GH~YV}JV4uuvQMX@?Y3xdCO`W{ZmZ!Z|5IB zQT$A{8F<$M9s@SztIAt%7u7xx5%qC?QHf_!#shEC#Oc)P6=$K90@LI``OsSa3tFi}6BH2@IICW|nDkDm&@tu`3-?Iz^-e zO=bkjfNxu}41(H__1{6U1WQIea{LEmlE~sB*T8n8-Y@VV70+QpD`ZQ~b+B=L!%7JU z>&W@(n4J*?2;KMNn6T!yGLaXkx2vXwR9aL?;cj>p0I(6IJ_zmE(IiT|W49WaTFsty z0TLYmo~zyL^91)79ez}(8F$}=rv!SmSY)Cof`I|=yVka0w>`waKL+Pda~F-P5w^&5 zrv*+3xc$m6X4*ZNBt23$p`E7rk->GdZV?!!7oE@>WggWG{LHpey?W!M<=A5HG5k}0 zv|T_4!0ux~xAj6fWp;UzJd!f@GD&WaAB5c8#R0(b@fn^#1q=?S0091){fBjDZ2mGH z_(ILNb!|`1B=n#Usw&!uV1WHcx>)nze9x4Y<3O9|s=hh3y-Wo^lpaQumG5nbRK>eA zU2CK@cugNR+Tg>6Qy56*Lr*EsdMkLVbaORA-ihD{_tUmzntJ#^qSPK$HPM7H4WEAQ%9^1YCf4GQ4Y8+<1pDz1V1-RI@<+ zYqiTFC&Q_hW8fjre;WRJ{Ssdjyj77raR%sMFzfU+9XW*v$8k5CVMk1T#StmW#iBrz z$G1N92eYJE91MKACP%}9J9bXkb9&oJQDfXM=j4?cSR;xCBS zU(QqUCqin9d!5>E(4XAB4zW8^bp%E*z{3$1lY+$Zo`I`Abf>w!eYzv}nLE*;0;2BR z$69Cm2rg3_z@k#=&Gwt+a6m~HRc(n_8KjESj`(fnC||)!@|mId%u$(=5?a9NJXFlE zro(ZLElGTyG;`M{RvHCc>IzyZlmk1FN3!v(q+3ji?U{gp8US8u{eU;jd%svUe-cqo zguA0=`YkYjzsR25gxnwj40xkA$=d|z-L7xE@{`HQsk3qj27PbRr06a~52`-`e5v2h zK+0i00e;C?kj+6J%Zg~FuXCaYbsGRj+Q+W!^Tp?kK-uaC6*egl|E@@GJ-!j41gicV z$^N`X+vc54mh3kHMgmxfS6caRupXenC|ut~lj(yUo?8Hb&sYHdDgBTasQS@sjy4w8 zj2|(h&j!o5smKL@PBu=e5hQ>CWA;M+XuZZF)+Fl^W*25OZmOsr!Wd9pt_&$C=1 z#J{%kc_5CwDIpp<(%+_&xA@L$<|4H=IV4~^lRW9!+K?GJv^ z=-8xOlkH7ZNM^D>w~B-MY!#4PtDsg`QSL$iGsPjL*$r1!0A3k=aeIbb)nvT~1({(TJUh0`4Qv6s zn+eK9d>f}$PA6N1081>U^0-6Nn&Gg(9!=Mxi%?qDX8}W(pmks3Qi0+mc4sWeNaIPr zyo`47-MMv4v|G6Zv~44ZHn((5LAJ*6F}8!+<^>KbbPCW_0^S*Y6Z;^b<|#UeYbBQ- zV*||h=K+iXApIDPkQssAn5(tw{_I!B(q1b}^(qku&u7~yh^tagM1$)p6x@-nvD+|$ z+d_mej1YW5u<96`P)t^-EyUIlK(~b1rz+N}-)w(oPD6NCHAj@fBG*Mq7_?~EjMV1b zmMT>4no$YQped+dw@x6m&Z`6iYEklnK|rArJ^_9iefbp-zlrLNTpRAqKSd|lJ-I&j z^wO5ZpaN*uo-FBzd0mh5cs3V|dT(7D9pvfd@(NWMR+O5W2z$k&HoE!o_YP-pF=Xdb z<=GTcBNl06_kK?Z8LDKIfe$Hhg#2iB%s(@~9bjFU8wMHZ=0Phs{bi-i-~9@VjMj3l z=~$K}(zY=pTZMct>jN}fCvV>?MKcgHa~`{jCwkMou28FeR|ir<6}=5~^NT0vLI+1t9i*abF8jBdXQ{6QlgNhv;G-0a1U837J2i7#5RE_GC7_P4 zqqHlY5T2s24lER&&AB>Z>eqlDJQWH)YW=ky5bXuc4~jM8?)Yh1FrW9(V)4mUCL)3X zH;3n+NTn?dE*X7(zMW>?rq)^*g>PpI6(nxydpwsok?1f6+jBkoDo~gv;UYk=&IS8w z?BJ3_=)#cH)iqXxJspOQGAm4V{cjwI)+Pz0m>0$Be$$b|T%v$RQ)M3@i3Oln5|~4Z zO50h21t>H+{z?75?ASCvFzVO90JY-n#~+{_897V28UpBzS85RVdI9ffQ;>s@x{?R7#9jW4UlaB438)&#?gx{T8Ey4 zUqFopei{APmu4skxS@77xjyK~#nxd9**-=rl1G8iB?l{MErPesx?o0=uHZSUQr zSbJkpi0G3s+^aVPZ6=j;zy@jh z`;duppIck!qB4eC^0TNsOKec62k3KXfQ458{bt{#Ao{wLOrPY@V2q+IKFNIaBia!( z2WlqU>0Cu%`$XHGnNchT1H!>8+nh*#wl7DIUa$5Qma>Va_V$C@Vbn_|sk%ltQSEI= z1=U{l$A=Gb04F0>O4AIlXoAoxUj^q8hbSIPi#t5!*MWM)_v(|xuVMmBTqBH*8Q-8> z#9r%Eq`v)BV^!-)q^X>hWuY}ZUx6zIZ%dM5UwOp_JM&d9gmQ3fhk6&;0A9G<>k%^v zOdD#4-@+LQ=H4WQ1R!IkY=jI3q{b%01mw>rE!U`|Xte2A+i=z2$m`oeisJ^Bu`VGz z{jJuTJ%p+O(X|t zjd6dQfZT2}W%d#!7AO%&tmLCU^Tv@bXPVICKijKb#0K5*zS7gKqM4@n>ufr6giZT= zPz&t2MWN0T3({A}Jfy7yr3KB}DqT${MVN?qSXzU&UNy13_;+7l_lS;TMhO;Ra3%mgxGe67_=Itp zYmuYUR=485Y7lC=kl8a-A_OIZW&NC!Habm0My5Am+OO|cr?L)9rUc2ZX z9KS#?&Y|Xt>RPEvF%qCzKf>n2%yLPiyzU7+FfZPC6a!dsO{$8_HvqtW5|)AS*)^e7 zHW6`os-p(tij+eNaOa}m)#ZZUJpgqIxDJH9JGevpJg2D`K)%9A9#xotS^xn6PiJRS z006+S0{{R3001-ocW4Fx000NlL3%=*n4OxKmyw*Fm7SWHq@kdh0RBJ$znqw*ARHSV z93UJkEUK5ArJS9bnw+N|9UUDgDyx~Mm6@BRo}`zY9UdGYCL*b$qMbgt9Mc(lh>;Cb zHMPUNDbhTzXrm)lq7ua*z;r!mobx`q(m%~+vBu;wgpp-GU5{-`Hmmf+}6}1RAX*#t?ivUn@+v^K{x9ssq))@>NYQ}9i z?R_wtL!`+lhm;Xe)$!G$H(Af)+{gIwD>~8OyEkVV@F(4Ufr=BqlrMqweUteA2`lsd zHCO&?(c6;4Xu8QEmPOlz+MbR$*)kDQL~@X5&Wp?s#OLE$QbtLC!t^QXfqq-tg}g}h zavyx_a`MF?&BdGz1p4&B#z%Lu=}L3eP4-W}IMl04p8)s-0KT_e;t?%EZ`;b$7qajv%%AXL{E9lbi*cRrrs^7sg2phTD*ScoXNcg7tt*To*K(n% zofKnpZLhXPo!mn}Fea`JpDeD)o}zVoU2o3uVnI7MXq0x1` zvMCwPzN=5lFvCzxkZW9pqNA^O4%wRxmLmRb6ws{@=p0@ATZQW3%(Bw4*Trudvo8(N*B&kcPP&mt!Dj~}^ zwdZ_GW7oXHIT!iHHFXmA*+=Pp&G=CAUWi618SvJ7<=BDqN@oMxB&%6B63)9pkwrI{ zimW~!Zt72fu@+!E1NfE89$-b@Q^WC~hA^-VzPFs~o~*Hf?LZCi_jNQn9U;2T)&zhw zUZfN$g8}(*PLtYC+{e>&+$KSKtni77=*F`dQhmv0<1jciI?V{<(I=jfHuju}82CbI zBC%Khq%4*;o?&wPvYsp-0RFbD?uhLOrUSLZJz|eBcUtoiYlN9DqGK>1>BEq(@wJvi zU);tc(f0i|e4gAoovrrm>u{Kb5H;g4iN!Mu%ACTG**+pd?f8&e{Ojs9vb{s0CF^jg zSlvYN?4ODC>dd7vZT0fvR8tp8(Ii6dlF@7uqm@-3SDFCO*cbU=d+;Bk#1_&j=um*o zeNG4Xx2#p#_T~gLjUg2P1fI8?>K?lo3=`^B+{T={H^fMt*)yYaf(!=u3G3{;^js@7 z=G*P>%U5=EH)rxXuV|mRg9UXeIkqx8inAxUrxDM)E;0i(9Mn?T6WfYLKW*!$-xjiN zUa_BU!&gsH-X<^4&Wa*>lHQHc@am-euG|C=Mdvp$kV8Gp+E!?Hq7o@f2T=U1r zdEeN~^Gi!P1CIx~(YgIi-+P|sk;Ybbj(T$IR#q9YrfHpAL#4+H%*VxX(mK89*zrN% z53)xLuU}P2Pj`!3?LD39TeZ}GD5b>qFq@Yd-4rq8n&NEwT&$l`YO;&~wAT1q&pFYi z=2{@VN~UuZ=#?0U34XVn-5S#vBpYc>@y8Ke%hv364`aasnO>-9iNSzmZBI+A^EB_T z&iS@R=m++|&g-kwh6K?m)4NShg!Hy!)yozmr&DB!ZgXNi!1gthy{Y9zag{dKDpvwR zhY3hXfUnUN%S|htByPJ$*?pzkddef$YY-_-XK2DG@}%7~a#H{yqm@3ssDG@#F&gKn zfV8r{z!wG&U>pGcw_Mwvv=}5CYK%K>cUa4;b2ED;g)9aG?6^9-!g`ZvhZ*%@6p!Rf z>l6=CNmN7q7y#+n_@?q4Ju*ff*&k4ju>oe$yU~g?`x$+~qg|2URcG0I!BdgiM@S^Z z=LlO-Wp;nr%C%xBpH{`W&5NQb212;tgDb#BrE!X z+(G~b56}U=xV$cN#>F7H5!VQJpKNfXBYQ^1%xI$o23*}XMlol8-`1Od7j8_`e-A#5 zc$v<$%A>+|JDaV9*_~**>k~xqu9$+-<o5nc)p)5mx;%m{S38+>5+*6h$+Y4m+;Uq!ykB3tP7_Sp#hdo5hYqh*sDUi!TCDVtk4$*99uQ7E*=xYaR{5l3#_qI1OR3?OoW z2#%J809JEI4{PS{{NJRxQmz#fIhyj%pN%l68_oXRx~t|WiP)k-@d_#(Eb5ufg6gUf z2gNt7UsjV}%0EkA_N>5q{Hvx;4#T~`LLWE(_8K;Kya51;W5aXxkgWu848!E<{-}cu z-~^&&KkYHeWxfDwknQ$t32Xoz{8hy;UfJB1J@#g1!%(3{w}_YZttz*Z+XNEi$)q%rw5YjJP%MmKG!)j`6C6<^4BDcAQ0`_WNf%dDYRQvvYu z?Wy6}@g7as$wTrU-ZF6_0rp6}lp`@Al9YaY^i1_EkW>JG^gKg}U<_sfd{%-5leb;B z$;SydU$%LGt^=oHT&O)X>CGpsWKAXQjGbqCP6OJl&3Q^`91L$^20O)a_HAN z#_!*}o$hi;z>=XpKiqkks9^~7*-o+y2mmzQ_wE7a4v+xe43ObZA{#663S{=-D-W!6 zIi1e{h5;nkGtsJqe{li`0NC>DQ@kB*-<_h)p=~;iCjk7;x~{3=-<<;j*uJG`h`Awe`3}0rb$iu4z#K0sI0~SLAC((?*q=u|}SpCgkX?JOvchGn3))pEY0rFtuWi zUQ%D%3o5#Ihj)rZv;pMMAXgUH1JD3qwE(txm`TAZ5T{L_WK`}mPxKujg9Z#!qw{}1 zTsJ^Kl`l3#bK|@cr|iaeLS?t0TL28xEugEpX;u%A>IfWyKCkyk05U6hY7GfDPC8Si_ZwVGY~FaG8)Hkxr_z<4t&bLBOw1WN>>F8m*6k+J7W zum;*S6$XQgvDlq3#(gH@u&0iC?MurmbYbGMUcS)$O`*=F3~lH`6%;n?Y%MUr4{lI_ z?1h2&Ea+^wVPeFyBkM2+=N14SN`3hw?Lg**sY0z}>v*rUa~OwSnZ|ZPgb48dDSeG8 zrfc^voQ-eaFADKnyCJ;aBynXtRk%*WMB71rR=@ZLW(voE>b-jCx}O@qDITb8l7Lz-NSpRy^??=?O+ z3$8S9ow7g51u(7v3jm(^e8oN0nek9f)EblR==UiBI+M(_6LB;Y5J3;;Ti06w{V)IG8jjbtO&hFcwZUWVqHLCzk%2%!+*#dbcW`+UB?RuA98 z&3H)k!{NHN2jdp3%Kx9+t=9NN(R3&k+RI^!26mYP@8i7hwPx&wB!#<`{mS}5S6MNU z7^aK4R%K^rdype$e8dnl|qa zH;E%MDM4WCKYU3VF)~>C10Y}&JOCcKyoxn+0VJp?*~XDxa70-Iog8HxO9)V2Jt*vT znW=_m9?;ZElB!QwjEeY%SF? zU-}h&qrQ*4{jRwTb-{I}k+g?8a*Iml49;sZqRmqi27aemL)6Xpp@>!P_wHjwUV zoa{guE13bn;845LDLd&}h-Lo(4HyD`x!f*GXaeSWL&MgukL(V+yOEKDhSX+=2v9rB zyY8CnPVUv)tH%C*y*OS%=8Q=|k(akwU6Ew4v@Xysk)2#XLaFp`G6m{~1hg}i=E?VY z+V;64YEIXOVl#|CceqS*NRVQ75W{!@8=IrKDa%8#?2x^%DLK>kb-G2R30z)SO^UGa$=)HK-S%^(Spc; zd(4DooJNrUE+nekR={w;1JBhdkAh5O# zsDbxR3p*#y1^{~>3ZWK9xrYfJ*=*yP+MUgrZ}VK2lHNEIh*>~)icm{PyvEhh0u^LX z0eo|=H~#5!{Zz}0_5b_t>$r%i5x3^PGTyp}O^@2f&5o?)!K_T~wL|Rwx zg4@ZQc+FBVe7W~$MY2~i?UuGtl_wQ;}&MqEM5BQ~-d{WEeCSLJP2!4IshX{GIpz zjucPy_;Bm3^EdXVI}t2yr`S*JJ$~@A4l>CY5J^sZqackaZz z3D&s1cmUV}{LZam!6N^n04QMZo_@EroX1}$p&y2qp+XD*2L~PG&XnJheY_74 zbQ}pFhC%+U>pRnuARGmA^ZuZ1VuM+A+ZlPLMh5`&&Rjo!SMAnyV-I4*9OnZ-ZSvpk z>R!b^zdP;!Y{A>#t{$8#`24ku0NS=hZX59#P~NQdn8^F5s?|)dCwE`wV~%HzV3CO= zQ!!=`A_MViU(V}qX>@#NAF@0(!^qrgL}BS@=b8%Rtph}wo;$tHs958y_uuxrN)&jp zmm|z+^D^eERqTJhcX%M*(EYyWC^>#}pKni)R+F>YvmAG?N%c6UW)Ut1@*uQ$B9U49j>?RrK%YEiI$@9x-HWx@vKmKHOn6N0pM!FB z0GS=Kw!;ItQad6+7?T8?&~M;iTdMUaI6@sT4ym^T=@OVHwF(PrtuxKeX%+w30mT>t=HxSY*VnW7;X zh-*OhxLtz4*7OX6)UXhN(Ld2*UH|kQ?_hoI>q~(DyKiu$HGWJcA(3-tbebm~#d)t& z=ES^>qYhYDZ-fF2j>Zivn{+IEWLNyu^MV=d=H}Xc9_^A7199SqBt!_0236PES2V-T z30NfYm_|Aq<*R~+S4_ZfjpS28&9oR5*BDc0@XiJHq5_xzUbt*xDeMVDCO0|CoNGY8 z^`dQ{cVZa;(7iA;HW)JqK==NlrZJQ{@i=Xgl>JD@j8I}YNf`(37G_#?Qi!x}*9e%H zQe}ewOYlTyfDE4hBLSaQ$i*%brI|f`^eF%@Y>y-Mx-O6JA5DKZ!wxUcHj#-nKP6(T z+7x#>0Pqallak5u-}T=~r!2B=Wdd*z zjlsW<#2DQ`ySE|BkQ@T>!MrJ=6-Qd_V)9r#3iB-7%1;Jr-J`1bn6%q+k3Ar4Ralw` zD-M1OYJhLo-r@#+QCebw9miKQ9MoHr8?yeY5^xOwKDaEYC!1kfb>mGe*M-EJL!coh z9Iy!>WAuU&6aro&?{?VqY$d_Q`IFRs8ccN$p*ugDLPv8tes7cA>@E7FvYZ&yRjM;joL-lCwSVQM6uK(vxDnq2U#Teh7~IEk!mdX2h^I=>T~W zGac+2>+6h2%235Cw7?$e)8R*C*oh*`rN#PB9el6A&QiV3E(twT=fLme&Pt3h;NIFf z8BexTY>E3>Hu36N8yeHqV)dry+nZ6=k}krBTq{n6aSwJr1p+Q7K22$u096*ZtmzzC z5nw<~@h?;U>%*(2>&X;Z_ku=3k6D};BB%hf%1rk09nHI(>SA9Pk^k3V8n{B(h))q^ zl0M%a(!^~W8kZy#Qvtbp&|mvms1UBLR<{PNpi{ilSf=2^UyRzb^XEnqsOfpl3awN$ zVRa7W0)4NrhC*rfKF8)bu;IPsXFN>2KsJBf3KB}A575W)+e7@)nH#_ez!1F7T`K#8 z(>MYMV9*^*tmK8NyTW3suj@{nSMmU~&iy)hqW}V{0N<#WN`c z154J?*I)Qp)GQhW;0D#ogQO@Ap31Y6j0DTIud?;$Hv^&+SIx z^!Ke&(+q2^Kd$NDMdz<-Ra|g=Nxs0>4YA8g02;{D@l~XqB)x4{a;UUcLMi}2%vzKR zAsC>4bqDQ)QT3Yt?{7~y_5W{klbz}f@%dHz=kE{3b0FAIzN(km)z#IBkB^Up_gL63 zRy{3<9bjo|xZ0U2Brx=%>Am&an}^z)EZ3aeP3=~%v%}std7xRGS{(7VCd3niP89XNCs9XoU7rmn&XMgblg9m_NID)GZf zQ=j8d&w*}ryl#!G_sEXLOV6@F_z1Y#rPfQDeAcAq>tXz#$Jp-;acghSq5OITVl?Lg zTbep9@(v|9c3m-Tg8o)zYm=!mi$YI~L+rB}h&Xb%IWQEbTfJ?72dKwKA+xYs z2Vxgs$9q;<+XKh3k6;6sRstjNS9~Zt`SiabnD9T0*J{SnMTweARq!9epfWdU;e+6?>%<1kehV8u= z)~+f|M2GDJt@;wjM^CRRs6YPs({E&xTxWH(t3JP_&wbgk`kH`^E#Tzm&7UFJ8&{95XKY>(nwe;;~`UYpel8%LPr7d-HB)s5hsx#l#|!5bm)ea&`sK zrZ$e49vg+OlTMkO`%2_`|Lt}kpl09&;l{le!HVhc&N<*51?aFG#WqTII7#8i`JO~) z(RC>RPiJRS004k&1ONa4001-ocW4Iy002Fj9>!yznxK`6kD#X;93vp6pOlu7kej3( zA08qlB_bv!q??~ZQb&~tk-vXkVd z$zA}-NaGo_K-dVN@k{5Q1QB0G`l9|*@ij-+o#+?<>dD4{#_rv`X~jVr;L#}THX~t7 z_!qNQ9TSn|`f;85NW8eToiblERGI3lKa>)f2au<4&!et=&d0m`WyZXkkKyFzW2nsz z?1mu}rY#g`gN?#8!3zNLOt$!&bP~-u1cm^f$-G@I85e_QLk-BL`uPC)tc~t@F_wq| z1DG-TNMo35^zt4OuSdaFq{w&B-%DR_R)NG~&c}@VHT7A?f`2XP;e$3Pqw~qO^Ca_|U z^kRu31|fnHpatRO7n39I83ro-dzf15zDnK6Y@RIM*7N%_9Uu`bJ;%`}n}T9e5Ug19 zQ!uC2x@PHfw8u-5Icz9d)0t-Sy7J+};hQ61DbAx^6YVd6m?LeZGi$R0(S-#-iN)nw z(-3*s!4w4FTsR~$U8S-iuMVDt=sXPo{<{6;4zjj>QtfG6CdDS3F6aJsWSU1nCYxw1 zFa!Yr#NoU(CW#-CPVS!Jw?7=PM(vH-n_SpSmcXs^yOz|4O45332_E(RT91(jwPhxU zoHWRV2&bvmxwG=z4@IacE(~9WaRpe>gX+8<-Tw)Nprv#GUh}fgyqbbQj${kib8kUM z0hq^--~pbB{i#>dK0p2JZU3Ng)2DZ)YN2zGsnBLb1Oq6~<9^BO8vQfNFDIiMKg0KP zcQWVhmNyN`#MQ_t5eAybZqQe^95`3K%uG?H+*bCRugnf&=?5o03NG*F3Znt)%q2#O zFc*ZI+l$j&rNGYfoo_y$+)kslz2NLh>B>#|a)|4RFUl}ph0!6QfMNjx0Dft`fETR( zxSmXJq&4Gl@}BNb56I&<@<_W0NaMvAp%4tf=_ctTUDJM^Uy_8IjQ`k!U;bIT%iK~- z+uSbi4WKxGl_9QnhLN_>r%2Q&JRZfy4E1OAeGC`7Ww=wye;rl&mol17o=uwG8tdI2 zdQep+A{fjxk-Y0ds|YVN#nGJ+*Kq6(ic!Z#~)cwWc;)0RWH?81Osq?-@;9Re$za2n$%K_+RZMX@NmZUX1MCOJoI zW<`s*UD3K!+l2%q)fHvz_VFGl=%)Jln{~T=6^|`mUe|voU07dB;2HJQNdP?8=ZH+N z|85eEL3&&EjX7O;(ZALFVAK@&dl8Ctf(=?2t>g>7_$()y>8Y3d@vaSbzwLU{oG5_2p??0_hLOGJw{l5mbhQ54Z#P;+ zl{*YWmlNM=AAqH#S~Qlz5o0Ffid>JSD?Z9WbQbDj^UG0;iEq#UfBzpgOwRrstLa!D zCm!=)>&(AwOso2^k-o?#7*!)Pk_8zpJB#$w&|UI}z>FIJe(AicrxiBHW_S;yHr!lM z2XUXiP7fKCh9WZ0A~6U( zH`}^mdSf!h_9MxL)zDVnw?bsu>9<8jH&-Q@@QQ2^14d8MEzSVGTK$8!aP$TIL9O^c zZWd@epC1Pnut;*~DT;t#K(fBsn)$0l=V$+^!ZK9R7L%{k#4Gr8Dz`V#BJcirWt0OR z4dbO3vmG?BFvWS*6V5Hcl;u2aT)fi+A!2^B{CzmogTwQ#CkMsxhap81l<>5$mGVw0&PG(w7@^-yW`i--!7wS8wVloFRXaf=pG5D8op*+WAw~wzL+X~(XnktOkP{bt*#O-Z-b(3v4&1B6 z-Im->)ZAnucjEE(*rDq<$SYN5=Pp-?0^XYaba(Lnk%<0_{T4UbJV(~R{m*2Wi8WI& z0Jupw{?e^>nLQ;b`{sjhSC;KM5w8O&{_+nS04K6B2mElrwpoB$o*=pM`Xb!An&w)z zOa*{!Vi9mKe%t|WvsUOFWY!-0)VNLqLVX&!K6#PQTgqmjzgm+(0yC=cnQMOe-eM8H z83JdET#&8$PD9{^g&JO}-T4pvV!hHj6n{`t+(dOVY;Vt}8C`^S5D^4WOFsVmNe_o4 zOO(eG-BW`H+pG4fmHM3X&i{dMo=vhA$~gM52m043B$N5Y>_cMvyD7COyYy4khMRSZ zJqS*4x@cHW$~j|D3)-;!eqL=QeM8QUu~x`u0O`*CQ-hPrp$cZ<0w@~lsg?<-gmEwc zkO00~ed8OR`p<*lU0J9pUi7Fu5IgHJIp!Du&~2Y8R*`}L$opRtRQ@HK8|Jz7)1c++ zVIejeQ|s{TAsTn_F_NDJ9XxX`uH&7MQc7Q^?fvQPeE_Sd{6IE}VN#37H%ET`ZO~_H zPv8U@X6DlAEWH?_U5QUjE&vvY*>k4c^zPK!_1*DFO-aSE{$rA0;Cx_wRRGLj;@J}b z6t)@|=nj#iKE33yTtBQ@SKia>1 zpf>d2;gEj-TY2aGXUkynD6=@D%mwF{x7GRd{m_0yIhL&)`baKFuC2w4e;(?tHOR)I zA~X~Zr=A?Ncb2ia72$WjDYTEXny%$qI)^l!d`%=_j3R|NX=-x@7F^;3Q(?-AkZ>mOODai2(QyaEi_4bJ970SsUxfWEvA zPnfYIoJi#UJ}sH%6FzXz6b#k4d?;|5(GByCO;B&P#Vd|xnD@`kmB zGLLQlnX(IRUd#L1{w9x7+(p~T?@B~3Ti$0iNL4~tZq zhgQlYw#OIiQN-M&^D~wGUA*BzH0St(V^;<)aDZhw{I`HB$RyjYIvP`Pmur*|&WohW z6kLdIgtGmlWNa8T$026A)uZ^w`4Kdn*dX^1jafUh+g9^BLAIF(!ulR;t z`}FGd&-DE+rM*X6GTn`%-jIaF+Uk~yV|O?o#W8PrtyxS}&2HB)m{0v|OY9_qxoZm! zD(0X}PUbr5m-{SmgrZh+kS6-pB^a4=PB)5&NX~asC$nXg_!hwIUrL{?0+m%EV!0nH zOS#3U#zTSpDtrL|9=V*;GqWQQHx9Lui!U=B&^rh70wA+aITir`%y)ZAe=%f3G$M=L z>y<=pn^S#yUVYLI#W-%O8@~yZcU}}tLnly6*+b?ifp})B*~LJiz{oFK>O>yj2k|o$ zd-LG4ynr-8Il@{5>)(HKzinW5FR#(5!Z|ULYIl>7&Z17TQOpOSH@&%MO`1ww8j@+| zmL%xrTql^}p&9@-xSZ3r;;12+NbM&6n!o?wAN0O*q_W;&X3YS_#H5DB0AOAntF~a% zcB8bMjDxuA_gUubi2OhIi9M675>8j{v+}2;Rl4(^{W%s4)e~{`@>9}GaHf^thpQ(V zQ4$s3Zu6re|__iDSOr0LKt*)oOwZ1+(y* zx}Fo(MvCebnEE8r=&87|Z4~UzEu!Hc00MXdv=-DE%D5Kr+IO%2X#A}{`2zs#&VxeZ z`d2j|Amw!qLP@@!de)i3!ExJ*9G&;%&WP`R_^k*44$^m2tLULoQ0Nl=` zud@fhfYbmi@IZA)#a2cv)7yM$Zhi1ucLw~<5nry~ei8`+V3MB6c8vTuUrtHUz5H13 zcL5B~I^TZy<}(ryq=dH8+*G)Y^%TbzamW%f0}R!bRJ4&#yIFt$CT%Hiu^nu#wU&nj zy91}#2@K6MfmOdzg@s|8ZSS~rTf7x|aYMZ=g--Egx7vbT&H&`j+h!&GZceiyL3%Zw z`R8btwf6_*%D!0!rZ*%S-j><{?9QD#YxlMef`mICpXQ&(kmq5F`B^xydw8Q*_GTT6 z01VUPh8om{Z&64P!2jkX=h)dvL54vq^gAV+gaqWy9V_E?)k;7>inp1QrmXTIn{8O+ zA6arU1_|s=@Ukbs^^2#CF(t>3r!aatmV)E>`s$!wtw)N01KclVr``E zTr3vV9b@sQVhfc>0Q5{Rwwr#-D*yvm;_1@W&Ex@9s?CwRR$)~&D*yyf58jCO{b_&z zpt;xXK~$iR^dNYFeMHEuH%3(g{LUqixbR0KLLktiT6+u?_WPZ`gS`nEp>^{t0sPJ- z!d|~Q!v+Fv^f%9NRSNjD-xB?)XnR!5-EoaoN&wu>A={)@QQsr`+WCdyd_Cp1)sFf-TyM@HshnGP8~r@} zyb&10qAwo&OI8<~LfjJ8-#;|puKtr{m4(k6o$b}WQPSAs=@Tv!Az%p5Y;|>6-E3W| zaizMtGSRdgr$tM60W->#Qcpdh*ip(qbv)Je=2P8hr5a@$ms$4xBA5 zV`_3H7bt+U003UNOyw3D12)tcuhYZ=8JTg64p^Xena*Z00=Xr-$3&Wu_{{WkIsbFi z7Xsmv2)9g^Ai7DMs<>20C;HFm@2Bmah5ZSZyS41}|9ER>NjhwBvfMG%KsG0uLgSt9 z6n+)iH}1T`KgLO266bJV{iVE#gx-$R#H=q~-t_>WBsqw>&IW!Y zY;TX`6tVXzTP03t0EPj6xb*c_+7d0ShGC&L{BzQX=vD8*#sVZ{&mQzxj9~k?;rIXk z)??UwwFGVH*p4pI}PP2#4SCqd!H@^tJt zK}IBt@B2Qx4D|H%e0CbhVdj^Gm`2EHzH=s26~Yu}wh!4=DIv5uCkiT%)A7A+i|8D? z$ts1t1U<(b;s0LolI{4cb+GNQS;+zn4NI`2+$R85w-jj1Scax{4Smh<`|0(BKu^=#CyFE>3dwfmbxHi~pk7Zf{XN&S7pA5UE>UhuVn-HE17>=xdZ|-Wxz)@*eIy8Y)9R~Fi&V6)tgDPBx=effx)dV-9bWQuiOGV^ zTA!I2U}tL*Ms0OZbndvqQE0~>(DSC%V9t{|xIL~%EWi^FI$2PWLkZM(tYt=GXq z03HXTd$BFACl~c|YGMt0isA;`&dqC3`b}jw2$bFj(~H@mG4~-FaJ>R7hp+(D&Q(PC zhHnfFJb?SKsnpK+rO6mY<{tWEm*_h5&Z;dhJXp#eX-CYEAIvW&!lh zxS!?i(#f4gkc^7lF#{-!yw(U<@#)e_NKQ zVrXJ#^HUgcvq0u}e0j|R9y+%~;S_`c1Mc(7>#NH9)!)CFoFg-5H?z(eK#A2shM)=( zKmwTm{&oJDJjE=l8#za8J4ly(OP=Nqsa_-7ysHWZm&x!nc}8Cj_ltlp=j-A0#r{qD z;Y;b>`?T^Bz55G|dmYuup0~%w1|>XiH(QO?;VO&T>q<&%P*P`RUy-a`6mpd8sS}x6 z6?!@MxfBLqr>2EpiC}mdzyi0@Gi96rn-(W0XlnqzxLn{IdVnYyQ6u^d^}NSGhafva z1DP?3U@;LRO5|Nal%BfbMG%-xq31tF-@wD8QSkfN3-^E}Hv@N) z;BrlKE)t_AS`>sXID@xw;5zbrL-}}r>#tyi)7q1^TW$Kq)By$tzfJ?sG^5jt`V|`TL^U8Ab2x5#Cic*DnaH*v0&C;T z`mV|gkF}j>_PdU01$AHV3POKTsuyu#I3%u_uU?p$YrE}iP2;R6rq7rpjkZ&8W^XyG z?qS}M#cbq3R>YhBdWBe*s~c}NA_1|?Qj1om1#s|poEmmaRGR%LT#9HyOKB4T7JoE# z3!v#2U#CJ8T2O#V@9u0bP?`k*p0}LIxs75D;)WXIliq!qh&GO8HIM^jr(qNeB9NuR zu{KF>H0v~<>3`#mEy<@%ZXk%vIgmC(>-I2sI)Y$L9KD3YVQtw-XRqGQ2yQPGP0vn> zV)Q0RsaE{tW0QBoL>LCXahBvqE3(bU_>cj$dh2q^rdgO)Wq{n_F~hF2E)-8k`H^l~ z$k+v*_X>^O^e}petu(h)B`{Pe03Nv9<(%lugab9kJ?FwaC*35?bPged0FHld&S%2P zna}$jj@q5ygIS+ge2kL3IPA~^hY>8Ak(kBXc08*cDKQ3vwEuK5pk8h^1 zvgue2zKY&d&fEdwj=eFF#OPe{9&X$@0l!ij1`(pEuk*yC72T>}E7dIJu@m_dNu<7)CA z^H@B`UzZ;f`VVVvTK|7^oFyXK9=#{Rcj6-T&W+PsHSPOT&?XrHW1=Lm)?&@~wo5ju z2*%PHN{AQT)(@L&-M3e`sJzHq$!d@%R%ak)?9Pw?3XB3LA~OiExxDnsX+xc7ak6?N z9!bvgu*$tPnPmHBkPObj@H`x9rVDIKJ8AuiCPqyP0n|bHswWX-C(b$WEOi#)2_xEy z4v$}N7C@q9Ezj_R!!b|;$cEwkE$Fn=FM=Wg8o+Y$Qg61i1W1VGJ3y%cuBIvgcDEGu zmV75r90avPQUL(!%(R7&K>*IPL;@&|{{NHT(r=EoozwHgW7m2Zwq75OV(#sdu0ecz z!ST~I{ZzZG918ud!llW#-K_s;CBNg^3RJX2XD@G(m5SG_RnRU!@dRe2GV;!8jNTk| z%Wc{<_7a<4G5KRS9!!P+ zA_3gatS9#Y5_SO%Gy8qjtf9lTHruyw|EP8rSE?He*i7GCkN~vMy#2WS00~$FPL>ZZ zDlnsw8X1>qXZ-fy@#tnQZqT79`fCZy(5UZxzom$l5~d&8eT*456n>^{cs?CJ>HKtF za#%}qik<+nwgl!;H=U^;k}Z2HtqmXXrjJ!`qUfu~c|E8@$_6?zn-pco2#jNC{d+g% zo3B5!oV)od=TLz@tl)X@jqBbX5%1p3XTwAOf*D0jdtODmKb-fhIjzab zbHdkZdDBA&GVDEi#oNl+5pq*}&Dzz9jcljUqj|C}nHb%YVWVdO30G}N3y@j*y-l<2 zED@iSE1STmNUs-fYeFhYkD~;RnWs`ACIHmVEuu0u3V;9}0VnHgo2A8$MgH7A>SUiQ zSOCn<4I@E!7i9winrF%?VMB|$y01kk?T=8Gg%0e_2Ow!8|9wOQ4_HaA2BT&Az!}ZO zP;wR2;sM-Fz03L!00HbA@LQ+$h+_s?X|v>3hP(EL9&Ppp?9OGPsrz&hD=j%e+o zuNBvNQ09n#NX^aBiFkJ{a?+0j4AnLJg2ezpOTZJL5vvOQps~*aSzln^KGbi;FnDl< zO*P{s1l0r95&ZxK(mUY)x?M@^bkI^bl$&H_j94B@g1l=R_%>4lp!0H9C zo~s>Kok}Ki`0fS{`Ri!~jTdx2IF$w@-Q`w8AHa|R(h)#-M9L>NEK$iR>T%2F zJN3S7H*wE*`zzySlFo@A)Tc5tOygi=FyJ?7^gZ<@=aRnG=0(r@`J(po`)LAFYxB=Z z@&z;0NT#MYyWx2WD@zq=;}}@&_@8W~A@?MG2D%o}cxK$ngj(@MR{ zR&4-2xGd<}CoG{Dsn=@FxV?(B&>u(DG{PQjp%8&Y)9L=I{4YP&>UX?E+d=ExW|4N* zKZ6!zYVEsSacZI7UE=tWVoEwr)U@Z@ADF#dkJq)-SH?~|vt1Ma?KQhbq3tMx|314a z%G+jjt!?m%X!g)Oxj!e7RAxC0`SmL;nLL*6iD*dY>No!%$gTGe?eKggpEUR2v8fYns-DR;*S7K1 zWmd8K;w%?M;?R2BpNU_a#bCt>2)vE@&6qZ=+E*UlY}A^X1g0}~M7_2Uvfh+KFk4B( z>KTKU&XIIV%79UQio)o;C;==BMot(%iaR5g~u(3?e% zM*TT3v{Zpwvy;NrR&Q-4si*IoZwcq@KS%cy`HPxJs3hHgc0?wJdeu`b$qq%HKAp-_ z`dmpuNCUNPuMNUno^{U&wX92`cf_Q@5Pt=f<8JL!rn5aE_F$Qo@_h(k0Uo%V(;9+E z9gbw|Cho|wD`L&yMdObvT6HXw&C#yq}z{)VSMAShW^jy6+wLqz<2#l(5r zSC6krVER|eL)8XFFbMLU@dLP9aI5Uwv_S+${;%i)Qms- zKjlt#9dni+CbA_Nxq#F&dZGv!1n|ic?cGaH#u<)f&z!Nr<4|*s)2!jG9FbO!Ol|=Y zlP*G$H3lra0QpY|s_maOW&E;P+r;2tIc_&OYW3m{&kZtwMQX(O=@jC6|@6LP&0@0#U;*`%ZDW*vC^77FN^{J%+4Lk^!{>|fB?90 zj9UB)cdL4N{U?yDWo9n{)Xpu#F7kIBKmgopYHiVO8)7D~-Wdz;A{w;L!^^)YfB;x7 zaO25@B6gh6)yk&*gKY8?3YnV@)Xohn`8@yusRGz~XHvgugPkJcoSo@$EcuV6CPDzz z&Mm^Y{>u{p0nA4*BC<*4y?j`UuD@bu&JEPg4NETkbf+C40JxENlm;ThliGzj+T|6o}8AK znwFZKpCTlso0qK|9v&SXBqXDlnv|fXl$4R2pqG-5nUI*&&Z3{eK0tv~0Lss)8xl@l zY;t*C)W5Z{L^kDnM3uP-(*X?Co%ZH_fCQ-nurE!Ar$nStY$|8wxo_2fjn}n5^9NOr zY?}oH*&}!B2T&lr0_-j}C)ui~w|UOC%v8NQoY+RRXo@}Ip#XXajpntR4gpW7J(3Cl zkmO9UB>{l99Rer=e7&FjP~<+dazOd+m{W6ywKv=Q52c>;HxBi6V>(FBC13rdww(k= z@zuZ=r^4^Fnz$HSqnxg~`pkPI)t6PnEu8GbLret7(h0BTXfAm3i5y2aWag@P?xJdq zwS}-8?6~2ZeG4(1>$_G|QrGQ#_T3gAV>l}?uz~meRz;2y4nDITi`E^)`&Qr=zR0Zp znYoC@bVH5s>R7P%1+A9=K+^OSvJecoCRvQBP)VHQyz%#I4TQcJMmt?|!bX`H;~ZoG z2A4=!>A0zy9c`SvMfjZ2#LO*D#Fjc50~3rj*sGpZDH_z8hfJ4{z=8s)wNC! z^2O789^5+-H%Ve$_9m|-b@;trgK8Mb3#1{s`|a;@U36sMyqyTD!?zO{Nf{0?Lf75O z<`1qqVzeC;p%{RUe`a_9h!lI@_{>ThtQo*P9e4o#YW*4?80KqZ`a@JR?mUh|UDvF- zt|NV!D1-Y}_dZ+So3_6@QMfIRj+E>!hTWy-_byf}kiHlJ@H!90GKYD| z_j01TN*T4+w#;m%fUDn0JpD19$meIDFCx=aq3erRPRmC_LFO%ERI8OQ8;3ESbKXmV z*wTJBySgi8MAw9Uymp)QD5Vws!giUX*wGG~l^@2p0TXxtK8yWT?$G)Jnt#^RjC(h1 z0i7dkhAtyyhybvdr#Z-1-}$JTN9Xgmeh73Y)jY2Gl34p1aRmSEMivJq`sL#bBf`!J z^wSw5OI?Y0SucMn46@1|iMDXZxZ9;SGQn3+Jx8v_1;`VsYBtg!YRdMNm}o1rx7D)V zMp9(hWMt}xgi~}}F}Z2mZp@B0kl+FSiv4rkp!@;FAL5$g`D0QA*x13WZ2$(1zDOXd^IK+O?BaAW|cmm|w;#8!ZaD1Nz^in;?>96I&i)LI~5vS($LVN)LT(h}xndL9@O93kDJZ z-YNZP7l04&gj(?`XDQgM9S)%b(5N##D?$hc1}ydGua0xkAxT)1I2lI|zL?gZG`3|e zUt$(2w=a*hs0WovW9O;Fh=Yjf1tyy0h$EmeW5w5~R!5lGAUqUC1%~>>)+u3KK}x16 zeaxiv*N50alhUV>ocePU3#$Rs{)oTM%`>c*jfyoOl9`w5nP*OuF^$VY}W8BTwS zU_pIwm?W!hbC`mzw603~H}WB@-smkju5+j3V}I+}XuMB1Z&BB{%cSK*>juQ@mPVq( zv^UR25|v8{D{QI^U+Dr}12>qP@i zLk%X$O|l6-d)+MO73eP*{-9>u_SK03eQeZZnl6GU7yz&w8uuEs4Dq+=_uFA(edYJ8 zEnU4mEwkQ6i8%xgy69)E*=vM;f?~*zXS+VCl2WEIiZG2R*Qby3{b?bQTW1HR4arQO zy!Lb8ccac_5S3$zJ$0M7wvk*(I5bPSX1>oR7vU#)%oW07P&k(b13cu>$lU{1`Fh|% z4W6t0sh{BcVY7XqX1rs}l~;%XxfR7mfggY;4!- zTGv(`WeWjl-bJlKE>Z$6l^W%v_Z}>L>~g3Rdh+){2_dLOSxXt^r+T(qhUBsLiqD@c zMa(}wM?99cM>3+Z8Fppgd|O~jIM=Fiql=^H(>p{M-&BLA@% z!;B!C0oa7&eK_(f$Xv5O?1L_(H{OHT6VZ^ zNj3ni9%kqmA%g*ZB=_|7?{B9w(H;M}w2?z9VtO*4V!I2r!diFJqo*Dfk42-{?lmt0 zR2k;SCpNBirJ}1}^`l#ZQ;$$~HfG5IA2;b5-VW(i_-T+Y8nOMC@ql=;DlNaO&Q@XP zW^J>TW&WFhZ$F>5kXai!y}pr>cVVakr2#qs9xDAdJ5>7tZ>SA#$4P^oW5j9K0RVc2 zF*<|{2HcqUQ{|0C%{`MU%NlBqlhFUx*L-icAiE`sIGnU@C(Kj^Ag?Wl2UuoPiyr6L zAQ|;G){%Hc_1uIYcvl~@xg@EdBn;G}RE~s@iga{R&|+lHs)T0S*TnQJCroYl{attHP7?d-emVe%UZ$uG z84Q@~`8glSSX+ANwqLUi7u{v&OJnFq5|f>QWscszlgU*lCJz`Q(_-!i)Hydc0TFP5;iU@D}o3tyhPip>J$*GlhEm@oJcR}^-iVvBzT6G`- z#vR@Q*05)wFeiQYyLh)5DtO#2yb0)Z03Q1M+|SS;D4tL=ZqFPe+R7%RSG*V*A_BF{ z+d0F*Y3x18^%!q<8{MiEo{u*h?WbM7$L$2n&jZ9%9w>M3qK{kziP4;}pv<8WLRvFe z%w@eAF$4#iW6xK;(Q(Y0%J-;((e?C5Drq&jDdZ?%bUZ66OD zD(pB7jRTq4*iq(c1djG)C*Tx`#HiCBFWV#Fr3JeUWrRh(e zf%hkQ>K~OajXC%2KC^K$tTTijPP#Laj9w}KLP!p2t&xJ`#E^EY;M21cOuGMufGEs; zxINO4)c<%{pLP4v5y&!OoDrjed8_n4^hN!orAx2xnG1VE=+bUoCg?t0mO|+skEO5uVb7 z#3FmCYR0d(>u1My{BcNEhWnErW(ZB%{u~Uc?22x2aSwtkm$tQ)XUUe3TPjI3{i&3MXVo<@SXF``@mWSA*Q2nH}`JeOo5rR`ad z+_wltGs1~}Vms|flVsv(!gGALp^Dzn#E3<7rR7N@sq-)DIr*aqJJHV0^jd=@(KVlL z1kCHcYeiD2GSG`JXXhhS)3&&>e#b#By$yjU&v1qwvI9)XCWpTyL z{^nJ65}?QiUI~4+lbre~Bu}%THr!n4`jJ>@vWFRihM@%p#Q24yf6}~;GX`IWmj1X= z?NIb=gbS&~P>dYuSYy$>{YQ%o(k{S(cV0KXj3 zo1Pq%$K>&NzdV&aL0n@4=nlL*mMcA>7iZ80RaY?%YeOK&-#t#BmdiKF+_B7Ic~m|? zbOH(38UX&de8lw-jo3uDiJFqV_2Pc210r-~N-PEeczQL&;aNpy8sl{oW5xS-?P=?? z!y3o%gaQX-0AMCWF0wqiJ<;w;mD4v(1ljx7U4Y2d?>@O06}}aA6y`UV?U>qrMI;}@ z3H5M#6#>{nQU0^#GwvMW5AVPIqm_in)E;MutYA7VOO+Oio1f+^XcDiBO$zzzD{N^% z-fsgu&H?}yDSh@Gg!pMIo=_{U005im3JrnmjsyS*HT#U90&w3bObLkM??xWr`Qp%2 z05m#6aTsimP;^07402tV;b<7y0}LwLhX*CNbIbuYX52xq z)+ng2dvSmD*^%P`FkE_>uQdzWB z`ku}Pn7i@psu{DZoaP5%evW#l-FjNy zl6L6T_z~gW*0`QHH_xS=SdSesWfXJ7Ij(elKrIVzy#m0S0G_y9*_qjy15c74*SK&Sg&xU#LTl#cmN157A~jl1Li!VuJ|N}D ziE46Rzt4%e2IZMNO7Vw$)}-)#+-)w3;%EY^L;rZ2a0fR4{031m@y;+EjJx+G6uRTR86cdxng9m_s;X3#(9e3ALl@;!hGsv(zC?vd#2q zpiwBi7ezbk^!j_ZK7y#FF&w655l5A4)cWzseWS6+qpCvI5QVfmRye*wvqi^~+#Iy( z9Jad61@}XRHj1a@h0nXH(1}~M;cXHG{xFUBP746Gx19Tt+zE7Us2ShS|G4u`<9J3f zx7p}J04s@^Jw`!9puX+zlv-}Xo;iNsJk#%T(`At$&t(Izo6R0CaIZS3_HJdm(LF(5 zq*Tl`G3LCCv@~=UH&?+av!)N-|GUUetU7|A%wk1cvZN1&GiuU9%nL7QMB$NCqU7z& zBg7M&;G6*f%+77t zZ-2TnfB>%XPqLZNO{{x5_Jm-=QE?0b+|K>Piar2@N5B^)J^ZploB&|q z#N6`R%dUAL0o=}Y!%hFH=pZ4~edc}|e|78_EcMXrUb^%ZGywe0rPrq2-Ao`H2^Rcq zKCyRc3(mQb(W`F|Xip`55FNAUb2$XnEv_;7011zPM-CRx+K0O23(R)E@Cx<0a-Th0 zVNQ3QIslrtl;#;d=xCBBYR$L;0E~?g0K{}A3NirU~%L7Rn}^*FLbF|mL0qI*dC zyxBL~>UYYHTK(Ulh6d{|!iFzAyNSMUbN;7ZI%}KHl1mF#bg;L+yj}r>^zs&n?vNv> zFWn3Ri7U3`Y>ySFcE(3CLPwVfAzJ$LN!S{Cc{@gJbnB(weuZ#R=HWEgYl{SO)0*&J zuyCr4V#0aD6#&3D0KT|9+cpFOZfk0XyLYo*9oy$Mx(Q7bLIeZa3*k>y)K6ZyMt!nx zBjMF3+xT2eR^w6)Q&T)1iS6jBpx-~a6pjpoT4UAywaN&X(Me~Aqmjgm*?zS@JU6K? z@%45anwL}0#lxZ7_k~-=8DcO9+0J;S zV6VEU!VbeX0A3os#|P}|2hktWnsGBvny|F(P%;`z3>gf-CU?YqwEq5?S>oJp#<$t{ zD#u5$>z;z#zspcz?i%-wrBW`}RIZV>Bh21$y79}L1BaQGjH5BkNwtd2$CFKxQ%2RD zaGT%r#O~r_xG%Rxu^reK^wnlRUEqc+nz?_bMN}A}DssJLi(4mtq)h8@XZ1*s%me9F zTL%~ei~|7v3H_*BnEnI4P#bRhb?SZ5X~~~S@?#Y2T5+4_!2`XsO)pIpiot-JG3RoeO+ydnE^oaXBKvXQwpx+6YTT=i zovw`&t4cRYJo_3w6`(fVEKswa{hQB%V3zlEQ6h?rQg6rKj|#YXKqK+e;~o5m5$IGp z4;c-~uAuDH-d>O(nmdY)TX@yUL0-(a2sWCzmr5MFiU4;04xBGhfq;=?$O17UQVD-K zGy@ZUxoq=SE`A~)pGBrvGoIJ;6Q*D_+dDP`K=zoNEJlE3$w&*NK2y1S!Mt_-^Vn~{ z{bFJ=DV8fwr2@RO(HH5`Mv3;l?Qe0iL;h%x8Qu;0ZOx+atE!rv*{hu>h#EWE4U$Frf0!zR8l>X+(24 zvfchLhpTurqpxUIfPD^5<({3o8|jbhIQ@B(APNIv#_h!9qK@bKxMTuUsFfl3LL+*X zB=ySTYyDTON(4ODs!gh=Dm@-ulyv6~Dg_z47HaeZ^~i5#gFGwz9(AyP_7e6DOC8P+ zXOB&|0zSFCPshY$z#D3WH=FD^a)^0hE5WziO}26Oe$BF48H~2KFY=bwqHun_RrIdW)Y60L17LF^0sgqW zO-E?NfE#LrXJSvXS;CS+G=PlJI59*7Tr@rU?Xi1EmnF+BYJclgO+%f%2|;)+WOhJa z!g~TjvZ7U-4bGc^5Gvd<`Z3?m{W+k;$2fkR$!Yvee#89IUD}$Lb1T6Pb{*OmSLHks z-OS!akltL#o4&z{s^wg;Vdeu>oB0NcGm2K1Q|bbsfx;+Y69E3Wob@AFLy+BQwc#o2 z4my(F-Z~=zkZDqaLIgOkxi*+nd^8gEUcG;5deZsnq$KkqRct%T#0s9=){DvcsaN;U zm3#dHodMjp6W#4fhVV^9iDn=dD6&m7@JU5X+!BFfWG=JsrpXj#F1C?(Mf6OwA8rRb zyqNfD6E#bot6@&}pNza`-#BwkzBfC8J#CJe1z*W2f_ea30RUc${S_Y|#lzsY@ij2r zRx4~IR4%p+>dwjUIR`=j0m`U3IHBTeX=V?^6TGk zud}iDa8O4|&UuJ<(n$uu7yxqEeI_APOQFaCI+LcQu$rnh-YqK{)yZ(MESXKIXv!sbeArW~wZH|!YAMi!%T;#Ybhtr9B_YTP4qSLJBB@`^f{rYwnW5nT3>+vxn0 zj&Di+%t18=9);vgL|imdFsM?55Ap$zPmloq`TTJQ^!SkBP4E5$1Xkig0z&y4)lRSY$x9b&0U7qL9@a+Njb>|SEyzgC^ z<**29t3YgKEMdd%Fy0V|I^)eP7gWq%W@C>*zJU$-G{?80N^i?_N!%a8T8M3!yIL^6jooHr{$0we$) zdcBHIjMyLbUKBrT)D$$#bnVM8t(q;cBe|$=P-^^F>xo_uD z{Dl=6DKL%GPtnnR~zS-mi&$E;X6JjtlXV>CQk4TwfcMiHPy}k0A^C*%L+{}vBi*Kz_O39wwRe)Lt1mgftXJ=CY z06^yj0000005kq~XbAuS0MCbGnwFEInxK`Jmz|oHk&=;^j+%#shJIO%@;~IfZ{4%fe^sTP6t^~-=Wl@{ zrHRFOmJk5^&u#yG)hYGX@;@JnaeVCF(s7d+s^68#_gUHEjX&+?tn8eN#JN1YEWFF~ zArn5 zy|S5b(k0pmI|eI*(@?(21Cq@k0m*W=XSegJeA60VaY>G|&xfC8usFAt2}Qih(#vFX2b#^Dbd_fa^$`*ycgZ8T~_U7bbdOQqdM z3?;sv^nAviTYgXFdITRgmENIu`Y7eaBAi+GC|4l!K{-qFujl!-Daoaz=-=PVJ@4%s zD~Qsy2aSFbN#X=JO$ob8Gq#fWUqyFulF0WakX5avk7N(~=PC&&y64&u0A9KLAdW1B z%!COw<95uEaC5tW(152CB7y;CNlr7(8eXoh>Af~i(bU|-ZI3UqyOX?tzAJ|eL`R__ zvKPL3>_2pNZ?4%^u!2yAK5l8h?X=qdhwF|x)2ZT3l%ls>C-}-Wg<#wB?GGSnIQvJy zu5uJR?i2RYsl}5e$sXTKDV9xb+cJ33uGFM8{t$)%erny^U&zZJZuoFs;%P@I$|0Nj5w7E04tp;a#geXZ>t3s@?zXpa1aqW$ zq}|6u8$87qBESk6NZrU0?uF?y2i8oF)p{}Hu`Y?R+1EHl z-@9e8iR)m}oi{2_80i-cm^>2lB3)f^3{V3M+cU|EItsu5SOqw-px-U7IFh*CL# z#)XL0^iKgK+4FH)hi_4kKmc3v8B-G9(>bWEGi`c_jsgtTKHu!7t{#8@@P67iiR4uL zL}5KMsNbzQ0sPhnh8ykx2w)Y!|N5vzh-2#jx5E=PV}s!702JMWPnj6N9*2Mp7VaUS zvdnn2evPX(j@C@$TTK91JC~@h;s5|V-5uUh+BEKALpWildE}_B?st*YwC+Wlj3Je?A1!}s{)hfc~vuQ4jc92tPMWM&2xnZbbTbmKE6k4453mBa?U z-{Y-q`5HBSixb}#zPcLV^K2C|;>_^vm#!tV7BS(XI5S} zYT=yF%7)u*;euc;(f%#MtAPTtnX$Mh=ZTZwtJn$4?_zOb#BkNvWvMn}YikLmS{@PE za$AB7><0NiC$40SghX9b783iFCFvBj95Da$o z-=@*tZ}HsH9ICEckwoDiyCGPpU~@*z;iBhT3cbq)HZL84&!w-up{T`2deqYV1lJKc zr<)A2C)V$7D{B0du9O*Wz6GPoCI-q-lZ=*! zB@Omco+^X!a!Viq6#(8i-P(65@2~VYwjTx5jF+E_NO1GJ#|8`lGCd>5LJ)wiN7O1A zO@`&wk@ZXNH>O3z4+U$VPc!Q$G4ex(AxVy%3a=%%pzHafg?O)2B#wo9VDw47KYwJK zOT;ExSsuC&JEEU`6`+xMmi^=qrP;jwnrS6feR;(fo?Dq6SyPP$#CN_i94!Ooak>(0 z<__ST6aYG&xIECMA0->jMqDHE_RP@)o{7m^%M3uKNoT}}!27%ICqxn@zn+sR=NvNK zrT21CsdN_a;(nE=wvu_rJ9v$Z?Fxa6u3#!noO9+}EA{Aa)xyyz6VIUj^=T=MawjMF z%s}a;;$g;^1`W)_p4$mVev2cW@p(@DR`fb+TTEmQb40B(3xB^NEtTAn6Eorb&q*B2cTROBjC(d<*M%6}iu~NA7YP zU$^^D+{Tgf!TEu%t;(Fi-C1hg$6+F)!#25JY&EODt4>m@I$jZ#fXht}oDNrY;mE5j;=QRa8pw=9MAwrZ0_XfqSoKlQXUyl1S8-ZbB~rQEWf*sX(c zCLf>%4*)(Y{Q)=h?k|Jk4YlF6uTEg+4l^+`LuN)00E^@>=&PG^eDR*OuHGXp4TnUb zjk%VH*pV4`y%zrc_V=7Ca`0OYoVX7)N103zcFqqxB5(EKhco%;!kBuvr$g=Vy#0cE7qjKawW z3jjU|eZU*6`shh+q_yEWt+3#zUI!gV10XZKP$&xk7H#XEM1OHT)`(tf(ve3sDX%JH zGl}51Ulz4eF5+w?8s3<@1I}8by7u*bz4fmGeD;NE5w6bB}w(^@_r& z#p8K!SU1Vqjn;R{5jmi;PsWDoJZAQfsx!S-J2dP1jDC0PW*cm2I#xslU`DS6SYIoJ z+rP}TUF7c2X;oWWlmaAL;)$c{wm;oQ>5(*)aHev1t}YK_03qq6;PjuBU~v5bi~~Nn zJj*3C2slt9JU`uIgs7u4fdCNp%up-_1I)i|EsMCRQ|~y>981sYQ9&4@(5onp{ethCz%<|sc2u)qpokXv!o^ZB`XFwVb zD#L=C8P}tY4^-hKz3YvUf2i)JTYa%0St5F!F;PQL%pFF)_*_;UNF{*FDtQ9yr z2+6X}SUYJ~CanAqZpF3Dl_E{w?`L8s4Orbf8>U;pd;FHEC<$>V&Sljmiau)jP-O-& zXLL~1_K!pg+KyBQz-7fsZocqSbaoJhf@s%>M)slJl^bTp@0MDPS%a-C3P1qF&ZKYT z0U%&6!0B>{#)TvGe?&D`+oZjMh(Z9=&Q;YZw~C3n1`ym5(r$dIug(30zCUmU4S?YP z`dP*mZ34v3RiO;`0Z3Q^jy29YN?6;Y2APdl&G!5%$OYAfaS+ej#$(5n@gC6YLjgm} zya{E>o-Yme+%M^!SJ&}$00S8T2~wIDWY=FeB*thvPiZBz55_TMvVj`_zPCKaqs$#i z6h}iqjqtpp7P=2TmIf^7aoCZe7z}9ne(&cuUWsiL(sUoBPrMHP)Z+7GBPmnm=XB|* z;(3;O3YDZKm5gDG3zKn3&DU|(ihsV>$Z#ALmq6D_QuPU#uX3mj$3s& z$_{+_=4G@>zwv{;tlIw-qt~H2ZIRj9_CYr$VzUbZMSKGc8go6dy1E*0yY! z3zYZ)2Wf4%-%rOx_FGRJ<860Dc9iVt96|&DmYe#@HShk`jN`Vy(bukzAMep5uID4Y z<22Qib-@{Zf3VAoG2BS*#a0}SGjz?o7jw!WJ4tk7zBhE#mntfHEdF50a}1%aG%tf^ z(9J7BLHS$w?_QtVK~kx97#|4MNz_h^@eWuYal>;`x^i(*$c~^a(_`Zz;biD1O&HeZJP98 zm$tiEBMl?S#_gXEMMxVB8VUUr7dZNYc0?CqjRQC;=V`I2e?{lJLyUqF}?uMtPJ$+^=I7SX7msM>D zTsbm2Ye`XHfdGEV{MAlq{xM)f?eNrPSE?~|?i>vgq%dPhnGpeiww^5appI{+mGpcA zabo%kZSYhe+nb17)YklstR}?;6dGj4r4sNahZ)6baLnrbt~~%ey1g&{8cfJ4KOW}( zFgd<5_i$cqWh^s9Nq;G}azk=hw#sfRHBqO>qbDS^)MY!mM0ox7`eZy!Ra=gI5>5?X zxV)ydG?Nk4IMtft8k6gCN;3!0a~Yxm$ZSF*OB4(MvoyLo$-T$>7eYS&7Eb}%tb;zB zM9Sf&b_99@cs&2hO?6yxSYgu3R!u-*G`0<*k<}YLuR_+z>2k5~X565nvXuIS?)#Qk zWUn*BT23?WSHaiw%EV;HTR(+BhQDT7V|??|Aq=o}c#p=e-)ro&*6`S>DGx~I`nC$N z73u+gxO}w(Wc_TKX{M%l>atUBVADthNXQIh6cP}DLeg|{-b@Cz1rI< zFu~U7vK$``MZO)CV*B!gJ-#AH>YZ?)@2e_c8LeDX!$AFOuQa{&MWs*i0JyljqtpAr z%V~>8&nW^L;*s1SZfp%U?yWZk;V|cO*m>gptflVV`QlL=k5&@411hLN0KT_;^c_rn zfCDw-=65NGZJHitDoPdtx+WVlUL1eLHjg8f7;PVXT&}y|&G4(4FvF?WusQ@Y6l=n+ zE|f@Gw%~TI9cQ&{Kh2-bpP_GXh;-;tMVWY)}LuQH5k`N3i*STn0()+qF_bn1k#ys@XYC4eF(>~$wbrk{O z;hrXQMaqF)g`X+hc+1*Ymqv~#qDl|&z3PTudrZk(okmn1r*$M}Xc#-5D*axpf4apg zs|Ou;Yp zV*X5+P%CbG>7Ygo*|QrbF#JfRwGEVS?SDH9%`|j6CVOrVzFc zO>c|cIss%4GYSg9fLi90s!xv5{y{uro}|kVj{@{(dfB^M!(rr_L*gGwynngXd_1p1 zXUYIoJ0jEyw>NHp`6m7V(NV(n$@7gfQFfWPF6M-VZ=#AnPkZJ;ecKHuj`JgCo^2nM zT8`q@=PkEid$f7372{Qu2r(EblBp4% zTWcn>I#I?`);QypRyUSIDf48fyV84B_e2S~`o4d0slKc` zY5bc`_s+9L!I*BMy5@PS2D^s1p%s(x1VE?eLX`4lKz*Mhh0Ina$VpMTjpQ%?)8}-e z`#mmvk3~ePJ!X#~qKu6SWLeajglanpL?brSO+w1`Fl|5gx zzl!%|;spQ)py9#lq^LY8>gz@UII5WVY$pV|MdBAqxo_?ULkr^o-nV=cQ#?ULuQ6O{ zvOO%;0M9j>>kVc*k1?PDWEj(i%!mNJ=ZZgPj>k(p(QYyP$3X)Z>b(B_E9i+U+>Z|BGg1~?+EnCcX(HV8M&Y%n*?_TY^`~^sMw``97fd+i6I{?7G5m~Z2q%JoA zs6O5|aAWy=x0kFZ13wz?v}LlE3|W~31xJ0)0Rk|203Nq|y9J65(4eNcsY{MbMvft) zOBx|0fB_ZGzuRO@SmOF>?YH-QGaI+_>-fHu*X)*Q=$>>d+O|zJ{4gxmotYvt6l0ar zN_j_{SfZF!svj0yw(##i;iMYGLj$# zfVN6hto1(j8D48@H*JIgF)!2|R5j(wu&jbAObx6hmnCbJHDTnz(bx92pX=l*v%U73 zWb)RNNr()ClWkkEt*zL$@`;5Zo=PMuCv&qX0*GG6p(b9fs`l0(sVR*;>d8NNDE5HT zzDZ0E6onn9f>;<9C1tqifD4{_NDlzMx4i8aOw-p67jr<(xIb*qo4JBGhD@c4%me`V z{ly@)c5MPXA{ZdF zU!up^+Y(w_-+cRV&-e<$+z7u>!ro$@Cq4MCm5qTsJ1Sgxi{!mv%96v>VE|$4Q@)yA z7pD*>h=5~-q|2Fgpskj>g2LK)bD~UKKEBb+$)rwdC8v{j<|9}W1vb&l@(lT6auWVmY`*8uJw z-$_nJ^RfonWG;$o(H$)B^0mVcIOjL@c}#3Z-*_wA1AWtKA4c9l_xP`_&kkeqfhi0BGU(M|J+uzSe%P z{!QEFZ)Y9tsUmB+*EKNeyv%IUWKM5db@D*UZB&B3eVqN}?+!;GBnKwGK%qq+ZFfz^KmLNFbXR&3aS&5&Btd&x60QXv9e0|m! zt7DwX06w;S`w{KDCKymN?yVuWv7K|;UJRWef&qEvfDH55K*@;lm(=<0kn@ReyDiK2 zH&^=EvHCENQQ|v6;am#C~1jOC>=W)TPx8RHz3#7IH*Lg`BevjblvVc`6-Xz>v=&7ytmiwY+XS z4j*7bP4T+{ODCIXG(as$wiAK@$a}=?bJi&`6AkXCu`hps)xGAkvX)()ZE-3`y7BjM zEz`zzT`ewO?Tz^xVTpD zh4Me!vNrb>ETWP;h+n^JSts8}`yQRhs@h=_LzVP|iXl`09=5EnD<%IAG!trs`-%o_ z&>_7HomdD4)H`Ds8d`l{Qr&F)u3o{zjdRs?Pr=8Znz{I%jp~40aHdd9FdW~H8&^5n zZk@26uy{|QBYJeWFZL#P$+jD*=;b`AAJk`lRx7$rU27KgF{uU4_*m0YMUX@3=R$$+ATt#Dql{&pu z&)XOG&Z5XSLTT#o%`}iFQz#I2je1wgK81mPU_ubf#qM!emmhPZtr}0ey>MiW*gpAB+rNZ zCO{SE?Q+OU`EdNmthJ+y>Jkq%b@%OjZG_Exui%?>Kn;?>3PvhNPBB_?IWbN@=rVhe zGb3L{C#JKTGfD-XPY1~uad(?lu>K?PjDECApdp?Wj9(=a7s4)NVm zbxyO;-iK|J;??jqblVVgv7jAs**}KHRWENugF zVlb@1#-M$JKB+SC9*R(>98gnyET%SZ=ceChgwK%?Q7N{EBjLpl#hIP2zTI0ZnrSN; z752Ps`yDK{AbX=^56zFT5@!Zq1&#p#-nD#h3p;#(0X4?alR75|5e(pL0N6W3h(xt< zTkA&Olf7ns+;eD@6|l0aL?t16Rypb>)6K?es~fMKTp>!y^BETP@j|>luTXgVPQV1K znK$#jy}4*a)$2Ay_q~DB)ztZNwR6DurmkOtMVE~Ht{4_7bSsp>nl_NEqVA|JfJSoz zi~~<+XHx(K8U6(T00000GyZpI3IG5ACP0un29Ak|ihy_iwfwjiZg>F$YQ@o`$>_uc zFo0SCAP;ZQ)45qWt_ukoVaTeAckYiJj1IoT>YWw%t%OFpB#{mR+ScY}n+i zc?x3c+wQO2^A)MGIm>`?W`F^V03Npdyd++D0TXJ)UNSUPP@n`A0002b9H2a(yELa| zHWsRdqBgA{kkFSo_Q#Z!D-#V(XD`gGrT^H#@swJV7Q4|)r(No$npCvKrgF z-?jtb?ZKdTy6pZ?y`gy-AFW=u(6xG=> zNeC_djp(h`48Ov9h5hraf=aL}+N@zMg;E&w^G5gpQ0@U9w*0(AUi1fSs4UPvpT;kiW3!oGSROIMAnSxXuf~xPsR3DnU-MBhVZmfub!PN4Z_`K z<;hlx?mKsT(N$3b3LA!K03Nn{ZyRsp12m`^d#2<0Dxz}v~IN!1P3p9wl@8C zbyTt3xMs8qZ6gNQru(~}XeEv~b`a!kOT=ExMi^F1i6(B6$GozI*F@^+`e?MPeg&`h zyRjTizM2Sj^=d=g!t>xYjIFy%p6|~qGSUZ!~Z@qCn-pWeKz6w0--Qjz7u;c9kF&q$ok`aw}MTafP$tf5X}5K=IT}L0fwUbzwL;CgmlRv>@z}z8n~m3LGWx z*WqW7ktTeMeSnZ>ZV#X|62L`EaVW~S!I=~VsAS|y{-l+SI`6s72Q=TA6o3M_8Dsu3 zN>dT9iUgQViEiFJCDIIq{l}Pu~{k4tU4d?)F^31Ja^&;Lw+QAzuuA! zQ?gqQPl?>A&vzk%87PsObogE53PZjH3Au`IOxU3dtL88)K~tBNwLQ-wMq2<1T6 zxxE*C=LGsrEm{rvL!ctq2M7uH+%n4DvY)vLO#_7(S)WS3VA)kC>((-HHwf~kt2^)2 zQI^T=fFNXvO@<^OLlTuSotBN{r&h^B$qrC^{W+Xpa>WX%k#w&ZV4PS&Stl&MscCd88^ff_~BTGC3fTSKDoR7Nvt zTFmLaGbP6N0;o(Js9ps4rp0X~fvQW8d2M1}k%bhuw|6!~tl0q|v+Bg0qGJsJQml^7 zF7l`akXv&i$_!x?aQiqjZNzKHk9Mq>NbW?EO96x<`rqWhT%z+=f0)aJA#+CJzd9nfB^UFvgjLQ=^NMsM3&D67VH=6pBEd{ z$Q{dPk1Zxm{G+p!WlPk8AY0)YoNzTxIBAn@>h2KLX#qJXNi#CzDK>l3Mri6T#6$}t z6Z0wxi)IT?TU?N_Kqx7Tv}K&zpHaC#qhf#dOqwvNFt4JrXzkr|FIz6n{lBgz3vg2i zN-%YeH+5y0Ix_$u^KP=b)Vt_k@utr4mRtLUCgAC_EANc<@+5my34IHZ?P1rsrr@J~on>9B^iod}%7pCdZ27Tc`JsO;cq5VXo>A*hP&af`*lShLa*!KvrqrULC9z58{ z4q8a^&*P5&L>rZU0xB1LvKnK@^S`TthkfC(4S-6dC$Q)+I}m8z#|j*V{fCl(=0P9Y zs4fiW!J~t0IFB2g0FV2zMu*|Rp`@`PLGV!0t%?gRyYF7Qbg{1LQ{DPcEx*r++y^|R z6B=})!!-YfSRZa|khb%%E2O!3U^8~?w zZ&>goargN0({z|SE@A}(vE{piH~w~gw_Qza_}J#UnlS{%7+SO6}A>P7(m@w3siaFhrAh?fZ##J168|gpAV6v)|G38V=*0i z;g_l#3>|Sx#s~Gnt6QbUF&#qcF{$xm&EPoPTKl|+S=HP=5)<3}zKGLT*}(MiY?jWd zSuv3Fs+HFVR^IMS&8lu-24#_sel?!a093`)E&u{hc?ag7mAn{0U>5*?NkwG z9zQkW6GObJ9|LSKfvTyYa8UdxXn^CvOmqa~y}UH<5hhf;QYkqNKV42h;-|!-4E(fl zIRih1<}<9PjYUF+6k@1K%7u)WQW1l(vl`^Ryfp7u5HNbmAZ;;Fjw%!qhwgf7M<>9e z`z-IgbLuC6%vveKfb5IyTEcL-<1!wY%VI4$(TN~{L4ex>DS!!FNE+~!VHyR&1lS*7 z^4JprEGbVTH%Q-aP>P8S+L#(N%pG48gpzEp?w)Iz|8(okrrQwo8leo8$gl8owZR#x zS;}Sw3OBH~WH%EY3S6ZU6oU%RM*TQYmROal>loH)L1`dXkte_vc}yg|C#8@?r1iZv z`)`%@Kae8y!OI5vuw|qKS8L-?YO+=?87RG>FDZyuw^hLrvq(y%A`$RZXcitRDSyE9 z$mO7@?v)KAVO3(DH-lQ;ZWs9e8_tZ3e0U;q-i7m z>zm4<5cD%o0dh(?_EVKyvzw&`P!g{&{$O0ULDw9P@q1o>^oV2o)QE`~>kc5w-Vx@e*w`veE8Ms`8*tnYR`}%&1#k4747dd~XgK|C|UE~>_P_RZ-NPVm#X{+i6KsEE(gK`oo!mwxWEKij>q$B?Gn z*mZP;U0_-L%zQ7AkXN3+g_Q5R5STd0eRw_kp|7}pCGPw-xtihLd^O+jyvaWla{eSf zo|?IWor~qSY&rDFAo!Bit6vVs8DRemerM_PuI-F&!k+5%8RZf!jMb(gKg$fE$%>kK zqg8fcq3ZWy9(p~Y)@SB7APf!6-r8^PP?2YZ%wJ8s{ciH`?0}g^couqA;NGqku(|ib z$M?2c9S7e%o7-AASAG8AIk%ojHH+J`%=Ve0lI8I|Rtc-85}fphx91;kxiMj7xS>*1 z$ld6-Pwye?Q=p0A3$n{w^1`{yGLuf*u*3*P82aDW!anXhRj@p!#n!+e{b$dD!q6bw zt_}GKk(sObTz)hzKHc@1U1V2>Va{RBQ=K7=&}!e&oeF8^iJG*Cj5vkOhC~~e70*-< zVI!u!obthIt&tI^GIi{kao1gu!iP!aHMf$Uz1-h)baCPms{fuVo!x?3oz=AUXC*48 z@eA|#z@r~&>6HnG@TLpv5$ocXJM)VgC$ z{D!OZXEhvqUwsT%#OQI94mFEzC8y_;Z>7CY9eFi~dr_wlu+!VRql$t(k|^4;{hHwY z%(_Is&yNZv6l&J3xpLAPq+;1|SMhO|Xt^&3UPy?Knp?lPT*#)M>^M=A^sK8QWckU1 zW-DB3!piy82cFVzUo?s0vGxgyN?wIZf^;LY%I6}`WKq@D&Gu32>}*NDjOIS=p3znu z+4bXHw%Mb1y$0 zx4R>=dv$XBl|PJH>#uDdYbc8TZT}su?dH3)?eiKwdUQ>p5yDI7es_IQfLL|wwklD< z)X1wuLI3SFw-fW`)j#U*43qrv#GJ)_y@OHw>zEd_ZO8uwa?kDJt~zGfonEj zsM9q*ZSr@CAorO|u$#vroy)yxuy{&bPjNY$M{ruC`J%1U|Fxz)d z1u9Pr8=f9^DrvwM)~7UdPg~VA9q+~0UF|{0cXnI3=s0!9Zaf=G2 zIRlpWK~7&%mv2G4HpdoNLJ4O%CgS-CnY8 zZG6qm^>m}KU2m_&mZBeo_ZRcr@4WPY4mGqTyeiB5o6sK@r#{4bxZ!0wz9Z!Hw6I@s zjbmqs<(4(9pm+8EMo&8aNSij6`4=U+m4bJWYy zmIJS^9=GBX$F$E}ZZOvfP#TM*PL2CM<)zx#t?9V# q#wpXoHfG(1o0>=mn_`7_Djt2p`Cn#k1X8!(KfbIn$}BlV9r_PH3)mn4 literal 0 HcmV?d00001 diff --git a/client/data/sounds/levelup.ogg b/client/data/sounds/levelup.ogg new file mode 100644 index 0000000000000000000000000000000000000000..a52cfb453cea4a33f2b1ce38bcdd10d43bdb3501 GIT binary patch literal 32198 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 NA^V+|TR|Kf_&<>0pV|Nb literal 0 HcmV?d00001 diff --git a/client/data/sounds/magma.ogg b/client/data/sounds/magma.ogg new file mode 100644 index 0000000000000000000000000000000000000000..c49efaa30d1136d41926f19dfef95b7a2cf553f6 GIT binary patch literal 38826 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 literal 0 HcmV?d00001 diff --git a/client/data/sounds/magmapop.ogg b/client/data/sounds/magmapop.ogg new file mode 100644 index 0000000000000000000000000000000000000000..8231976ba88e90e651b33e03cf2d151886d494af GIT binary patch literal 4841 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 L#BA#`JrekTezFLK literal 0 HcmV?d00001 diff --git a/client/data/sounds/metal3.ogg b/client/data/sounds/metal3.ogg new file mode 100644 index 0000000000000000000000000000000000000000..af84cdc809c98330d76d7b5eb555aa17977131ab GIT binary patch literal 9467 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 OMYrkCziXGsg8o0LT@v&F literal 0 HcmV?d00001 diff --git a/client/data/sounds/metalhit1.ogg b/client/data/sounds/metalhit1.ogg new file mode 100644 index 0000000000000000000000000000000000000000..433ac5369c90c1ff4e28e0699fcc573fc77dd87e GIT binary patch literal 7454 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 NWR^WU^!#oc@P9Wd-(vs( literal 0 HcmV?d00001 diff --git a/client/data/sounds/metalhit2.ogg b/client/data/sounds/metalhit2.ogg new file mode 100644 index 0000000000000000000000000000000000000000..057126f70fedd185a34de919f0b8579d5b2e8aab GIT binary patch literal 7529 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 literal 0 HcmV?d00001 diff --git a/client/data/sounds/minecart_inside.ogg b/client/data/sounds/minecart_inside.ogg new file mode 100644 index 0000000000000000000000000000000000000000..083627a09043e47ae264541947b58144212b7d79 GIT binary patch literal 51889 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 C^aQs6 literal 0 HcmV?d00001 diff --git a/client/data/sounds/molten.ogg b/client/data/sounds/molten.ogg new file mode 100644 index 0000000000000000000000000000000000000000..157774364ba610014805ebcfefd3292909caf60a GIT binary patch literal 63659 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 literal 0 HcmV?d00001 diff --git a/client/data/sounds/note.ogg b/client/data/sounds/note.ogg new file mode 100644 index 0000000000000000000000000000000000000000..1c02b117abd2e9bfd7d1eea7186dca5cf8f85735 GIT binary patch literal 7382 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 literal 0 HcmV?d00001 diff --git a/client/data/sounds/old_explode.ogg b/client/data/sounds/old_explode.ogg new file mode 100644 index 0000000000000000000000000000000000000000..0eadea50343d7229315bd35f60356622f239d34e GIT binary patch literal 10844 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 G1^R!6vm%)Q literal 0 HcmV?d00001 diff --git a/client/data/sounds/orb.ogg b/client/data/sounds/orb.ogg new file mode 100644 index 0000000000000000000000000000000000000000..a00df55749e0aa8db66ded8f4917d115bc0ae0cc GIT binary patch literal 7535 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 SVzS_CQ=7Lxmi6RbC;vZY2f)+- literal 0 HcmV?d00001 diff --git a/client/data/sounds/pig_say1.ogg b/client/data/sounds/pig_say1.ogg new file mode 100644 index 0000000000000000000000000000000000000000..586e10d21b2f627a62f0c45f123935d6dddf060c GIT binary patch literal 6084 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 BSs4HT literal 0 HcmV?d00001 diff --git a/client/data/sounds/pig_say3.ogg b/client/data/sounds/pig_say3.ogg new file mode 100644 index 0000000000000000000000000000000000000000..0f1701c2e8c467c86fce111dca85bfd9ebcccd4f GIT binary patch literal 6239 zcmahtdpy(Y|IcP-BrUf_OLH>Yq{5k4p}8}Jv0T>Ng%;(qB1bJo5|Wl`Q4~dyD54Ij zkXtTkE=h`VNhMuyPN(`k(>dq+{r>fPUeD+Ad4Jy5=XpQx_w#u_ALoz|H-H3xx1si8 zKM8oG;;ny;Z3||M6e#kkn5# zOCib3XTZe9TXg83W&N|AsM01BF+TDqCo3az@_S^d@FL;uy;Il*d+;?RfK z$6-54(5ZS-YUssvfWzP~Pt$AU|Knsnj-hZtwv0BCJC^UIAYxR|R^{4N#buvOtEElk zMt8Q3=jwMt=t8cSya@75#6>;4n9SJV7bILDwc{7Bx%i^*`8C4LHE(^;P zIaEN%t~QQ&)G~=Q>Xp>q( z>_5|l3kvoq+b+hNeWjMeW35Mzb)7#^os~>om92ZJtR5APt5LY?#^7EzLs^AZu?{E&pGxenL>wp#QfYe{$2n8^ZU2b#tZv9 z$cecVSpC4$51IOw^36Hs0--c?8Vb0=ywY#cZ^TD++P~4V?xg9gDr%NF^Mg;XAV%ZQ9H!Za9b(9Q9Y~{*w@~8@Toeg)3s8*5%1QQxeErEU<06JvoO5OIhJ_qoD7GTP*XU_|gh_dL;E-8m`5JlK`s=!! zp^dleolf(HCs$g&G)kfN-VBHOhGRIsr+CAm)3;sRSsahx!FiU)Tml@#%ejOR9IJmG zx;#akljlF5Q1pJuNmg|-9KpotaE|AJvB|&c4Ptm~C|l7{f6e4hWK4<~%y~2(0Hh;X zDmkST14dB*C&;yQG*4Adf?EMaki~4o2|8#LwP>aVr6ifjJc>)oqG=POw=&2DMJ^17 z0zsbzr6QT>y{k+t@;+)PcGf7kywPY)TuZr41k0I?_IS`r=!V5P1%fH#3E0&Bdr=2ohdO+ zS~Ol%#bk0%Ml+$RU6|j~f_GIj=fT|qy`&^huA;E#6 z4^>4}yzVm(U00|WNG3L`23{+xQn#f1G%i*REUS|kCpKp@G9<<`YTMHJm#QswRDSSuM-t+ZG4`?{oVIP)eKMtWJ5H#?nn_;2HBRZtbTVh$3ZDhGyP zHIAEUI4APH3JKhu72~4l8U67AH?H9=92eT~hN{N<0%7qZr2w}FZQ&u9_ee?Jqcj=% z=mPUp{fR;DpzZ*BIUD(!zDX|UjI3>LNw?i=5qzk$0atW7N`8|p z#W0yd6$PV;S}(RRaN~xk)ZeMp=`3AdIO#@6w7s(PkL8s@ziA z0G<)HuGurXvu-|%$<^=kj-IJI)fZ4|IPokAd;g|#;I-Ph7x6QcYH#i%(*=USr9$i- z{XtSp9@U?Jmh=G@nA_876B>dK_hkG5*q0;)tP(SRE!E0X$waS^%oZaH2-pC)z_~CF z;j|$)9)6t3MCKw+!2&}J`Uh7eO#jIzTO`c>n-A6z1{3*E7UGzUMOlmln)(+W zY#OUIw20c}gw>h^g2pOsQsvc47tfu|$w=JC+ZF8TE9l(ecJJl-x3$aYSsQf^F@i;N zM`P~I9nJMn0fNp}mp>ldsq>M=_&pD?6+PihbK|ar#q)de5v84l2{{iiGna0eOM#d3 zsO{hXWO({L{p~`BCHm&p)t|Pc2dixWs1J94Je{3O8|}IrvUKm!wEf^&r}=^xv1-Pf z+=F~^d(MBh9ix13R-C9do^z23-flhLZC>{WKsCfG?w=oEBdyl2eZnb>;uiYfkSig* z+IlSeSkK*OWj#nfsr_StkE!io)PtqM^?3Cg0P$C6OJ3{Dx)ilDAl78XP+bCh`$7EO z)Kj1OgWgqEJaX*VHx6|B=MrAc$Cs~{mD8Q9EB2%*q!^Wj8xgD60dYWJCcl{;I3QxWU3o&*!g4g?wuo=XRdEd-1ZYo+*<F*U#Pa{mpA}EAIpXL>M4bAMCmxp_CsI9%pOSNH^tFf45Dl^i8u9AA0vm zhu>;Eb#0~u3Gghr_6mnO->!3r<=E>VL~J@TW3-U|!bq*AQGOxMOWsYf_i*?R9YvIG z?xgFLFk0$eXX!u6-{Rie6vj3ql_lcs1HP2oXvC87d(Ic%Y5lp9`l8U`!RL*~auhSA zb^9mx+ZcPy01e#>NB&sM_p}vzZy)L&X%Ov9YiE@3f0NHyx_7m%{dPwy+C%esb z4mE6T(UCa^hpOdF1gI?BLP(6yM-Ghg68U;#zc-hE{>}T&s~y1)Nz=l$)XVi|5!F3= ze!MOut@SEVNQf5|=#724#yF!i!@$fo4I$DWy&o<467=A7z0SHDTc!J^y~YicH?c9z z=_~V~_IfixjLqi3&$qXMOY_fXG;|`2;L&-{t+v#AarnDye3IYkPWUQ17$_JtNz3AD zA`bU%(e&K?Y0rLn7pLU__=w(F-2k}Cy|S8Vy=c^K)JorlHME;@IuFW@elQ%pf8OJS@93BMBO^O-z-Rxv8XQ0TlsogXsorq@#;9Gc zra9gUAbL_U>dBhp1PnTVWW#0r-sYR)m-RPxYM%@9%~zKT6kG0$cpAw*^yZ9uP^)F& z69h=rnEqs>!Ik1Rtc{vHKWG-YM!Z>@{mgrAjAf#k*2vxh|KS*d`tt{4Ki52ZjX*9O zb2zBo0KS3qp>IuUc7L~e&EyYtHQd}Vn<`hUW*u3RMk6cQc!(eWg_8mYcIKVgeQo2> z)uf=49Tn)H-h}Mq?aqf)=8Vxd8S#x;IgO}8n zS>dVs`wu%s~78;;{Iov zEckB!&MpK`dUv{{lcXqSJMUV~7m=RPgt}{^u{_O;+7|aN>D?{M%Mnn%bS7 zUZK!K&-~J#eI7>N!udtblXdZ#I(Ap*6L(7TY=kd=sN3`S2m*2bZgiMlga zUB*_BNv8Zcz29%?-Dul)YFzV-r$?9!P)R;JRq-`x#n9y=vnTGm$nBRmbCdTcd`+p` z1izpd-|C3aTC9_l3&H^Z`*@9On<@y3O9*vP{NluCNLR~MoB4Cnzo&Z(sylWePtWWw z_@*ceG-^J#gxowad$H=e*@27d-4BFcJFoYwd{KYT;?HxYghaL<=o(ND{!SF# z*To-*FQc1_Xwy0h5h~3`#Nypch)ptusPi>tE+?X=elHlEI^}e*{mDk|#=YC?%u1v} zO^?ce)9)&W;x1CP;V}8pw9dH{>BA4yuP0NZ_p0(u?&$)Rb^m)_ ztVvTyl!|Pqy%e>t-ieL`X!@xv-BRBzD_obGmxwLhhamDv^RwfBPu;?#FE8=frqxKc#_z1@)Bp zSoJaIr5V{@m$JLTfvWA19esqUWzi|axUPsuDRyYqC%TkRK|P&d2dkT-XU}Hpeepej znhjF3`*@c^{IFpFMw2uy!_Vh<-&LnuUor{uU-06n&9~J7J;2_-tCe(&WPLEIyvY$I z4Q%w%a&Bwaxa|m?t&vshUAjpZ*B?570N<;g-EK2&9x-$hz8?K!AY*o5iZnpdZE*x5 z`S2kNEX>!)>BC;*wEIbuT>Sg6A01>V(BP;`zw0;2sPrvYZ9wOnwsj0X3qz0nM!zSc zX)K;tza&zo{#raidaoS#a}xO*A4~TJpj_@5D89E8{m=^<{mt;Pymsb`n;J)2}x*+)wP z9D0?>ycN?mHKRe&#U3v%&ixt_WUSd7XyR35039qiq6y{Q&g zK(jPkN0ZLSe~^>c05MVx@>>-_KDro*@@uf^^~XRX6Xw6QYQ_$1yMD}~t2#U}gU|rg zz0gMZG-4A@*dZH!B!Y(Gi5>Y@eZ-$d=+SG^*K(eybssnAYp7Vc&kHrcNI~!?KEXrh z7@8j$^VwbYBuJ9csDAcW@$U-?r(HIqWC^b6nn_7O3J@Y%kHK2{oAZwnRhKvli#1db zFtU2c{($0Bho|0Q{yZ-y3#66_68N~UAp54N@drc7U&X0`tO!l&kB`MJ)i6&!&5JII<$Q~8h_sUlG zon(n@X`?Jf^?OF|`+mRQzkc^~=XuU^)_c!A=iYP2+|$zvz`@@w&!p6t2}(R@+=Pk2 zE}Zpu^$uVnVALAs3jnGrZ2MgaGiOTv+nAC}%EY&dc3#cj|JAOt{87ULQB7Pfc&OkH zC>}n5Q&3>C?}dKkGj3$d%OOTgR%a3@6*;f4g;D1NCpVY>SqTC zg(Feg79ulf?Jl1WBHAXq!qAE)4((C_@e*0-+K~>Jt3B}~z!bQqbx|NZT8l#>TuRM0 zktU-CL6LX}=gq_+wf}kO;k_WL7Kdo~jDjjRZB}&y9j=GBMMAg*@$jA6m8rBsJj5)i zVrW5Q!!Mx2pUYvQ!3|; z!r}T_&*`IT6w5&Sv<$yaB*dKK@bl>dL|}16T^i>m2iPJ0FauN02_O_hRc1&{;NBrkVUq|As-_9ygl;S zA{AIf*tXXJ8U}S&v_cd0A170V3A~w{Mfgd^Ou8L!DxnxJ$}lVoO1v9gg`Z~xbiJHo z;JP3vlVQi53h~V|n$qpK{y;LtK|QImOx(GyMQ6sY76_6q3W`sSErTG|BJa3V<6;Oh ztO_FDHD=-hn5woP@0%CV41VTkUR_nn-JWI$GH+R&U?Bfx+2-4JGBjUJWJIjX8!SiP zyqCECE?1P|qSpF?0w;>b(0<>$;FXnhghML%9FZXN$Ki0G$ss`(AR7MjaE+9R5cYqC z%}oy@$mZu|#wfPSJ?+?j9QjcAl=mn%t_i8Lzo?05<*PDe>+=aepGqq|Ztqi6MkHXf zlZaf~{u76Mugxan9&gFi>>7#9W%zT+=KXP}ICE(LFkeCU?h^e^Uq*NDlCtE3x_rN) zO23sJi9#Muq1aV~IE>Jp)RL}2Yx{^3Hi@7 zp#=qg0tVahW>g|++$Y)DCujau*_>a^Qb4a?nba%jWO>-v@({US#mVZB6Y03GO^UBW zIc4k?d2Bso^1r$h`}P$1063EP7dCMpHgQHZPSQxzt4$VYvN1Ceq7JFJD+q)^6{Oh=iY5S0RbI+gp5-}+Y-Y1o=Hb_k-XSe|#XB$4eP%@>^P zhDkO4(s%O3dJdzJZVF=TPHiU4pAo8P5R4ChX*PBB+BFv zW%iEm*ajpLri=;x?#% zBIh)AsJhI*& z$hIIDXM_)FV~goT`_n~(srJ`Z!u#wo*<}`l>-pIz2Okyv7_BzO%|yIRcG5PX123CK zgSJp;qqCR8HrwK5q-b#jc8Tmnf{9eNu#RkTa*``V7_mQH)qFbulii$1I4zZJ>tKQ} z7Y>MH8kgBNo?S*H`XmPsAys5vf-IzpK)^wxf>iNp6ChPq1ZY&Q`>}(zgj2X^o*S`rDdOyjXt&~|86 zJez7?Sk*k@<6E_w8qkwpW^ZLu#T-=?t6jjSI$94j^JWV|Oi`J=Lk#}f-^QcMAXPra zYY+iaWlT^h7xsx$SxdEl2oZcv70;yxe8$aU=b>>*WiLvB#(~57J3j zp}dDP^By5Vz_Dd$MdIeOlsRy7jHGDXym%H7H-`=Fb6#0oadRl$bFNIJGyRWn0k zKa2_~Z4}PF?azIL6RQ$~XUj-Rf;{CCgX74~8n8D`4nPu&^2(O_9&qj!qi)BqCIA9W$E~8$v^sE}`4SwsynJl}HUg*fN<0T^#U(+P z2#A(|XEYx-ZiWtaBm!_iE>O_4P+$SvyhwF+Eg4O}QmDGsc8@SrmP1@)PX@bifvz7_w;^a2Yl}<2-z9IYQ>m6e2B?$j-b^0A~Pp0?^8e z+|`TLk7!{txYo*U2vx&Ss|1bgpiu&@tE+r1A*1+N@7rY=c$em(77>QA-hq=0W`!YliZtw~5p+S*?J8T!-e z>}HYWN^ETM(`oW9Mh%bJUbHWC)gfgDJAc}8*9z04Q0vhb220v7VP9lxtImzAo1eHf zrv75*eGY&yef@)WdLow~k$v?Hr%<5o$En-KwR`omo!-v|1!{=yTXFBz9Nd&Zmt#OS(8XLE| zXGD@88;ldr)ZIPLZrYzz&URehh@Cecz?+_ph-YXSv-A{a!4`G{s=cy%{o^vJ$zjP( zeCXzr-wn}klC1%k(V!(OaALD40FB33zZ`{$<1}%sH>WrN_5N2c9uVny(G=rYapA}Q zEYWgyX}Vm*b;)a2$LQ(<^1^)~A<;8j=RzMhnH~jRT&&0N*Q$7|)=jr&m{(8DV+iVR z_>||K`hB3W0tp26z%^UI28EwGi3n{ccd=?XX9=ES&wX$Y!v_;R%}%|yNWah@&!!0n z7Oex{QVtxwJUY9z8XfUK3dL7bopKP~=q<0wR_7lQ7|fT%Uc2|xh2>KLa;n)|`;G7T zKael*PpqcHUp|bv)z|?)AZOkkAp6^2<$ky1?u*O3ui3M7d-8m*`FDeFtA?wbv+ZZs z-<*@K9%_@vJUhL}CS5z;kkm}P4ZHIB>W4+v%fQBOByJOkEzKre@74K>&hFkdk13zX zt7|kgHGs!hDzB1?AxmYsRh?}GaI1SlAc=lUrfCe;D3~5s z>zLYMQb5dcN7ED5nt6p!rT@G{xvw-ZXoPl1aL&$J5&cD0?_NIQxu#=T5v0O!;$Z9D zV+PKMZUDtyE?%dEk}V%+>HvGpGrJO_rz(vy;%PgauN>yON{~6bxmxbRoBMUy^CWJH zlb@X`#<~*M0|zH|=r^*ar6;#5Onf~(fq6GlC883}_U#k-^;>aP;MYEJLXFK~ar0;0 zuQr$8JjpB8g;}LJt2remYoj@N-OJ=w>_~d=)S97ALR3@Ml}qx$>ns6%hZUym~&M)1L$$aCvkX?51NDj#oO_5U2dbAHdeM!sWL9o}%MqF4t% zy;SXeB5JPEr9k3Li#pNVPMNvSHDto$?xY(ZW(sb9xFLL7Pl{i&Fg4KXWu%_s_2ggZ zbF#J};x~2nDy#W#2Ak<`q+-owGWJdSSDF^m&Hx^Gz&;a$J=3t;h<+{V04XjbE5tdbl#JS?_>g6ugZ+-srk*513+}E55Q;>^2 zj-9>Yva0Ysute{J0H-W{^N@j)#@A@BS0C`!QHysDzaP_I3dChOWa4GHX3}UM_P_MLpy*ih z)GOuZDcnHTy}RdPPh56QmGby@Oyld;bH%Vt{77%?tGvh0BIn5KC(Sm*BA(P8B|Jqo z)>cYfzJi*~DFG%1=Zm@g_CyGN&s7}S7yKRFbOhz^U>mXWg3}y!;-Qp8+|n27){gnq z>6g{&F%R@}%V4&ryG?51*|DH;_vha$$K8?xf8-dWZqgFV(NEG*CyL-s3-3(!>*w^N z9v;bvEa0f`)OqaniPh$ynFS(7+b#HA5KX{cdX2ku{bNjVLVygA0)8pbzInvac%q@S`rtd~ zhJ%jjjMX-Mv%k7Ns@1FGW`Y`@2@V-usxD9>2hGX7$fZ8#DLnnH$YJxf41(Q28Tl+K zsNkowTXyJ=-Vjv!l{1!0>wMFllGBvj7mmBs=f<5Ui7pu|M7?1y3Cg_6a2 z`q+~JnH>#$w<)cnp=^6S;Bq&_TV9LLs>Z&sd9~FhgQFR6KPGaNhhs0a9ddlKLzNTg zzTHqo^epN4_`qadl!^o|+|Xc^W&@13r(tPY&NbBEV55u`1Q5V4<4^hQ3{%)C>58+u zjmNHiLQ{Ec@4PF$re>%_Wd+n#p}xY(+=@4n`L8cyzIwGpj82IFdjxgi&Tk+7j=}o6 z*9QZ??9k z_^Xfkm-(x9XO-e9^VNuN;*;TzRcOu8*SZ^FR_t*|iVQNv4o@T1S%VKpDeEpkGHqSVy5o67s6 z^1t@UEWrE1idFQnoXtft-iO~FH8Y-FvdCQvh{_1se6f-^#$C^$S;%&II;dOX!H(}j z3U_~&=E(AyN@;jM7TJ*7*D)ZBt+fhV16hGzDX^>E1@tN(*cTZ9P7p**32kgfbX1FJ z$mD*>4-D_V(N5?@nws0Y`D>|j)X>rFR!vP?U8OF!_bU5~Ezj30`;-C~Yk6b`ziZgW zmbEp1v@@Y~H^~+F4KqFzv>O2QEPad(v_exeywHcCpri>Ka_XxYyXoR$?zuw z$x+X@I$jUOM9W+0_TwGtwi;lNX09#We19h5c|!G|38qhOw4oSJZybgN3k{v3NS-4H zk*^*%e6r@ZRBUl1e*QOFPn?aS^ra+nf=&vxnd83v1+jrJTBU z{b|L>n{zi8-+qM$g8P;CZU|!7s7j630XSd)o63ca9EL$9B76b?LaP|3qMuSpbX5FU zwfY>|rKoC;GR)mW7+a>v3d;Iw(w4d}&;3|+x4U#~|GN=#F86FB-`Vr%$cheyOfp}D zqWzm_9$T5xvG4KxYrCFlRbis{hK4Q^+sE5xC6ewYxb3;UYP_eUDsn-ZM*)T+hPayd z_GCmVNuD!kUDE9&dKf8T90MtR`hx0kYplaPsNA;!0x6#i!QR_i>l}C=<}jymCV2 z#N+VVER~*W2M~xiL#o?su?RLC(5n@06ByRt@H2bK-`JW>OW7AC4zYS7dTQajx(09F<-*gPys@cIUpLg+dF#n?dnhqm> z{^y0)4{DoGmfor9KFibg{1IpRJp_c|c8rs6ldB|c9N^c_N_W)o+^d>$)qq*M?XCg& zFZirB;F3yr zc*|cj)Scv|Qm{8T&T3fQ{;m;=Z(1*!(wa`%8(HMOh{X_Pj<#NiICKZVcUc3?JrxEGe_{LNLL+LXZjWMk=7%k3 zU!EPU;(PJqMsZ`x#qWy;Dpzl?_z>*Z(w+?$d_m@?mQ095YJdM>v3@(-P5aUac+`##K z-s%WT$nT$b&w9Uep{(@e4L)GuJ?QOY$Ma=jx6ZnJ9P>!9tHjJ;Ukp}Vqg`hz=$HaSov1)sS|rc7wpqao5Y@_a?{yo!?6Cc6j{TGgxay{+|eRxIX`8m%mu@g_@#nZnu>!Khwbyf?OMidN) zmA~1_t5yHRF|jnvuJ{NG7xx}JWEdt1scOuO^FHqt z`8r>e?X=*J?88j4P+<{BBnQW~uv~4V=ofnGKES7l-4=ANmyx^ExbjiI{r%{Hmp$5i f=_qHOFBhE(9-bTs1DZTfG!T~~?H2D_90LCb8rqGK literal 0 HcmV?d00001 diff --git a/client/data/sounds/piston_out.ogg b/client/data/sounds/piston_out.ogg new file mode 100644 index 0000000000000000000000000000000000000000..f67b0d75df7a69f4d34ba194b41ed0e8e5cf6520 GIT binary patch literal 7384 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 I9n^LI3vv+$AOHXW literal 0 HcmV?d00001 diff --git a/client/data/sounds/pop.ogg b/client/data/sounds/pop.ogg new file mode 100644 index 0000000000000000000000000000000000000000..757cc14c3164e5e1c6cee3a220aaf50de12495d3 GIT binary patch literal 4026 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 Nn);5`@PIYe{smXoXQ}`I literal 0 HcmV?d00001 diff --git a/client/data/sounds/rabbit_bunnymurder.ogg b/client/data/sounds/rabbit_bunnymurder.ogg new file mode 100644 index 0000000000000000000000000000000000000000..f39302be83e8c8d4244160183a3080b454a6d531 GIT binary patch literal 7378 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 u;JUG0oSYq{_vD~t{~c|@%fJu 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 literal 0 HcmV?d00001 diff --git a/client/data/sounds/rabbit_hop3.ogg b/client/data/sounds/rabbit_hop3.ogg new file mode 100644 index 0000000000000000000000000000000000000000..9df7543bd39abdd6e6ade009664ebf6e6a270633 GIT binary patch literal 5821 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 VLS0pGh2hz^TMU&Ww2_e9{{f9NxJm#3 literal 0 HcmV?d00001 diff --git a/client/data/sounds/rabbit_hop4.ogg b/client/data/sounds/rabbit_hop4.ogg new file mode 100644 index 0000000000000000000000000000000000000000..972565937d0a33a804293678fa9324cd93ff57e4 GIT binary patch literal 5490 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 H5Ci@X(k{Am literal 0 HcmV?d00001 diff --git a/client/data/sounds/rabbit_hurt2.ogg b/client/data/sounds/rabbit_hurt2.ogg new file mode 100644 index 0000000000000000000000000000000000000000..5f9dc2dde21c2bc2926ada3212e6af18a7de9ed4 GIT binary patch literal 6368 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 PR(c^RXZL2=4vzl^XaCp? literal 0 HcmV?d00001 diff --git a/client/data/sounds/rabbit_hurt3.ogg b/client/data/sounds/rabbit_hurt3.ogg new file mode 100644 index 0000000000000000000000000000000000000000..9b21d9142bb9c24831c32ca3027dcf6c1d5b97e2 GIT binary patch literal 6820 zcmahscU)7+);IJ{s8T}HP{JY-2uKu^Dj13o2tD*FMJb^uAksx(5kiqBs8LW5f)tUZ zs1y;TN|z=jfKrsIh^9_mYQ)89)R4-O{#bEvVqx2BohM zQAqHW0B5g2DgqMKKz#u~lq%%t{Q`1{D*11tN>VAy8}K9!jl=(HH)(&XVF#&(PQmWV zXnDoc@<;^*D!Ul?xcRwUadit&2Z=5qQR#>%?&IbBTMk11`+ZzX8?>MS0PsKo*$bpV z{#dAxmWkjTOsmKHi=dVvS2Rq~(6&o5FiqlNkyfIu%+0vi0JEx$^7PFwb2aDB3TR}nGl6Wkq){ESjGBn5x zSJpR)VL&gzVqeS2Bt^F>yx@zGLA%;~eF*oL-@}5wvhh`}MZyRt;{j?Yc z&9?%v7c{{cFrZ)X#&&6z2*t{xnZ#nnQLcPI8UPgCmr1%W!vYnmVgcR)093=2x5FRS zc?Z@>hOsiSThoL405E}k`biJ879e0e=J7&x5H@w4JL^=UabB1x#!(S!0pwJgTelLA&7Q?z;5&s zoCy7Anc#*3S9$f0;_YG;++YCyen9ThCh8K8x+$;jAPU#dhc`X#YpUWlsEjvL!Q(7^ zEwg-WYY7wCZWFr^)Bn}+j7Ll427oi^ClKk!5$SWPsql*$o^NFV4F+mPCVi4gol{MR zUrd+uO7{rMD!H4xe78{c$q@?xrLs_4(xcF%($J)m(A1^GbkDn4C8fE4ynFQJ<+IQK zUuQiEa5w-2!Sw>*dRVwF76gvG8^uQTF6<2wt{WiNHGulP#(o}k(4m$=zYmSSHvj&IJ1*OSluBr-2c~%22n;lpktY-3EO8A*j=8Ts<~8_{Z{5-(TFj6 z@!?3fOmsd4igd~8z#_HT+OsrciS(e;=m1kNuaIw%t+0Teiz{&59<;0osU59X`rv~p zhWyCpEQVBT?md?ee!i0-*%&+(A(?wWA%j8yBlxfu_oeYcGoRe!s^SEj zUQ?wUenRDClTi*~a!FWw_H;aIu-X^YHyMO?$RB8JjqTzrcOt+^%Mv&H6GjX+X;0!1^zIdz1xuu^?ia`WhP?p@?^h~Y6KPdhjnDY!U z0H86Hp^b|#V*)5myfNTWfQU`QwhF{{qY;9ESS>_p92R?9ASMkhB^hXp zktrsbU<`_5hqVyoIIN9N`B1LSZROYj8yQlK3FdYwNyye)`9iYh+x(1lv^0r$MCeA# z7Q}!@D0tA>$RXOS(9)7IsTf8HQaZ*^k|dxlOU@)ZgM?8VpZd0(Kp9e7I>twmWMylJ zt`!JOr5cw$GES<&V!bm1v7jn94vZ|Q3WGs{vjSCdXkkEAW*Bf*&VL|=tT30!peh68 zunG1yNHD-4K~;X_g<(z4lMlIFWF*`9U7nTK2x%jJ8z16#DQ~12muyeRq)?5g)Pu*N zF?k`^rmVhg)Z4dyJ2$Yew8qBFu%0@rdV1@?wZ@n}aOG_#nB?*r8{1@b!r#V|YCu)q zp9=~(Y#A{KkO z9L#$fYTgT@B>5S^w3P(XSOCYXu&!@vrYPK4uw3V+PCp9FERiD&n0>xozcB>DFb6L=Ws;QU&(Tj}{@wsv5-- ze?X!@r7Z%aoB*~n%n0RVG($0w2ztsX8OcO?_`${?GZ2coSXwjcT$UeWg2j}#3AunV zHEdHx9?m@r#x1{h8G00k@jBUV71-0bn}+p94%-B-H)anzmnl;|#z0?J^SV5%-x9V>`BK9I! zg2Gh6P!-UW7R2#8Jzzd28g&%E8UVoCYGHP(K(ia^Q7XZNEGgB(AmWkQ@5CP=%vdDi zBm$EpXo}k`4BEhp9ZClb!(e*>v@ilK5;QtGsDwMk`SPF<<>4;w-XpKvNGXWiw82JncoZ{S zT$wRH`(gynQT(%opnJQ2#}1q7#w-T?U<^Rbu?A_Mi(=SdvLbsVysp;TTTDUBJm0)> z^8vdPEo_9N$Nq4GDGHD}46`M0RSkbUDC}%l=VFzcRAM?|3P399)c&%?r+c|PzWs8) zATzq0th%cUu+3)HW-zt@z|bYf=H6gzX4#2gnUQpnE%k#~(7dK5aEnd$d0J_$8++#fvUzF7D1&V2~mM8<`DT?n*Awq?+M z%Y7UgSCLGq9Y)FNfSTAXB`nIc=$=4}5!-W$U zeD?La15wsA9Og!lrZte%jC`?xjnF^Mw@Ygq3}|{C+>T$f zLksTDEt|HT$7iK4mLwY|x-~u(O@D^k>FWOE$f8v395Hg2r#?Vc`a$V4>ykYBQ>!ho z=O#lT3%{&98eARn)B3MpFbX~8PoDBAAH%!6dS2s>ChXcFn^@ULtx>0V06EISmoqF; z8{IUa@tT~C?((TWl1}JXl1&<1^MbV)QFC)xZP6$olA*g|B_1)G_nJ#LVM4`Dq$%ErvYb(=(;mY`?B+O`Ebs<-xnpXvGscby(wuKd=w5R$gtbAz%}=d=bm?(kgw#>6gt{6IJSfH;M$ z;OCvX;rqkxV_1&jkEI8qG{Vp{vb2!^nPgizp|2s?yI>m-e&bu*xqRrpQ+BN~A*bAU z+ni!Iz;vp(0aMnqva)ij@$w*y5M28uS7`CDdbyeDyURU|^?|CM$@aCgb!A@KT4kT^ z>=6Zy%U4vUR6D4j)pS!2JY)XI?Pqzd1OSjEg*|V~hOb#Z!#D+dlEYIC$|Ph;2)(3=}dngJi| ze)f&&lD*~!uiQVWujjmtO1$;hD6fA|KaeZCy7VD?>v>lhX?|dSz%Oa*2VkU^{0I~E z?9}^jJ*V9F9KEsIqp{I0F*lIzYVz{yq@Q+P0NWrl=L4~#=rh8`K+t;@BB3OmXSS&9 z%9-b)&7}UfYUj6l#ZLG5JFfh~3fG*lk;$C93Z>9jDDMZDfR_Xl@CCT0tIiCd=*!gG z*?ffkM*3^mG-#W~$C>q4gxT{$SfU)8{aXOx{1`L!MVlU%VdtB3)5mRN?Q*cD%bJdQh?&=4gUs`9JW*$h{B7?N zSLkMM*%=RS{TZK}kXg^+A-2G+)>_s2lwg{iEP!5m5+#UnEe$xguP4w?Z$~rLb-B<| zdFRd0{=%9QO&U!Oy(aH3)yW=6EMKTqWcjbQ;8|0dHDVyftAubG*!7{S+Q6*HZ#~6RNKq>YUg}j#1*S2oPJ& z;4^^J5}d9h1Gj!U7SZ<6L(i*yYzuf@(0SaKY4K9Ufouys5Bw2IaiBhbo(5o8+~y3e zvRR@3_D8Rn1*C8(`52#huuj*@y)6{`yO0c(tMg@Vl9Pv`ShglqfLwaudTY^_2NWbX zz+Gv>8O1JfGh%Ssl~eMS{3_|?J$?HXH8Zi?uh8^)3r4`QkE6tPa%aM{M_b>{lRsM3 zsa_MmN7k+Qh)6c%bGLPa@gJ|du_^^vX>~mmy0#4gzOE;QBp9kA3wy!pc zq6Aw_2Fz(T)o6)&vgfs<BLAt-u+0}pk@zxGKlzE(qRO}X zk+1BHN%FM8#%T-^Fng1;8h7}9z(a_aqS4Pc^CsQR+r~HFhs#7?)~az2KWw@eKNIu- zS45|mlfH|tmteXpS#EM$ziHh5hL|GDX{U_sKGX?FVJ&Jm+VIU4Ps}I7a7eS zUtnCCz+055AU?-YJKN$gAQdBgYpnKrb9@lF!$3Ukp3(=kAVKcD{)oNB=j^E4(|V_1 z^bL6Y0cAY_?`Uu11J~jH(lw@{;Z(`Rs*tm%qPQDUJ&$iWu!?T;dTb_tsyWog`+Qn% zv-gv{*ltCG1d_mOir{TtJO0mq++p|M`6TC0C+TGU+^Pk~x;mp>^C9Z4Y9SAB;`2t^ z(3Q!=x^vH7kB`v+_KRhIMr-^k)Tga9;z)54Nk}YZTY%qObzj_HQ#k95b-8=*ar43V z@(&jpzSkP7IA?GU-0Rn^d`Pp6c8zGPTHdXGFqCXR@+YTF%jt2ms^g-1O>iHTz=Gz% zm|ETYR<^f&gBgf1)s%bBhbHE&;O+1Er(OnpqvcAgV`u5Fvkngt@tZvUJYS^tAhNn^ zu`P7M{@Rso_RL4ylR}%xMC4d+@D#I+=CydWip!FK=wh-M!G|}Ru5$NQRPpu`C8gwI z_|21D2YGt?ru$*n;x*gj3){`UPN+7W&(QGqEq&6LmLW>t)4?Lu`R#G&s^5%y*`-vN zl811JPF<}(G>*%y^}*olw(q7E-395NBVHb+C{CRn*?LvXUEOiBE=Hp+MxS`n40?{2 z=dZ<*G`R7NU;K7?HuNrKuX#yVo{6cKw?FK!`%!k=z1t@o!h^;9R1wpfu>htPczZ*8 z>E_jVqf{tH&)GD((=pPzl`7dooQA;}{e@%a@viR!?Kc5;-w{Z)KLYORuvMCu8|X++r6v$)q4aqTo7L4rQ3o8K9AGQ6{%bgJzUpCEoN zP2A{3DcnNw@VTu-yuMi&nQx1oT$I86ycE+_ z4|%RvDvj}^kgpQ%N+nVb=0lrx_TFK!cBqKkj`+CC;THxys$1Uhqh!tqzvb^Wol1_se#7b&7>=owS@c9auMiKl^^TjtSTy+&Ra7&XIYtha2cz zH&(L7PSJyGJp*?uiQRK@d4Ik^t?+km^k*jrS$$G>y4dfu{BzGrpFvyal_2E*0OlpT AdH?_b literal 0 HcmV?d00001 diff --git a/client/data/sounds/rabbit_hurt4.ogg b/client/data/sounds/rabbit_hurt4.ogg new file mode 100644 index 0000000000000000000000000000000000000000..7534e91cc7a04e4d786d92df95f4d593a12dc8fe GIT binary patch literal 6923 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 literal 0 HcmV?d00001 diff --git a/client/data/sounds/rabbit_idle1.ogg b/client/data/sounds/rabbit_idle1.ogg new file mode 100644 index 0000000000000000000000000000000000000000..412fe62a80984ba9ec369f5e8325092aace4d8d0 GIT binary patch literal 5943 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 M?bu6T-Hf96f1VyWG5`Po literal 0 HcmV?d00001 diff --git a/client/data/sounds/rain1.ogg b/client/data/sounds/rain1.ogg new file mode 100644 index 0000000000000000000000000000000000000000..91dedae9ee091f84953bccbe6ca79146240049d3 GIT binary patch literal 18951 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 literal 0 HcmV?d00001 diff --git a/client/data/sounds/rain2.ogg b/client/data/sounds/rain2.ogg new file mode 100644 index 0000000000000000000000000000000000000000..c5b504af71ec462380ed152a357a394f8250421b GIT binary patch literal 18733 zcmafaWk4RivhdTafTd#a#NoTFyvSkuyuXOTrTBEvK-dvkII4JiPFM{eSec4TRy7Qk?}#Y8kBKfe zbbz%TCmfoKEIPVg~5uA;Dt+zfg^zBYsU&7 z7po))XW)Y;4JYHYzy^{4py)ka?0Y&yG=fG%U<4$ks2bL=E752&(P#q^5mB9|6zL-VlcR0${hGt@0&|@@HpxRD0&_IAzDYR=Enp6&);2Lmp#jXvcKE92 zD!jnlUr_zMeIGm~%ENqlto+oGk^6NJ%&80=Z|0%>x60poe~ApvR}?KW!E~J-e)iCY zOd8#cfc;qP?uZqEAS_S(`^=F|X&OH~b-Js%JncUOhXh37$s@4TW&d+Cizbi6a~q?t zC<>KlsH%J)&pyu7H1YSwe_GS@N&uN{08N6ic0gUjk!w-M{+#bHC#+dZ&%U-rU7o%y zO&#$s{m4Mti^JkuB&oe%HjAdO$a6zvsQibVWG_nt04hI;X3&ZMC;cFrMyFQ802A{Z zJJ+0sl%}WUQii8)TcG}OgyCJ_2AF<%n(Aa&>i(bf&(uL7Cj*)NpNY^9;ki%n9Z{vB z{b!osf&wmBGJp9^u8~S%mTGdAN#%-D1ye{3OKOf&a|YW`jmJ@q+j5S}P=ni0Q_E31 z!%@H0b1lzf;5j0R9w8`VovvZEK3m889tpcFERC&2#%Y9<2d}1qo5|5%&Y_c;dt8y5}%1=8#p8Wq3 z(q9Ir0ss#x88<2!bt)-!F!PtXA;>S(CF*CRl5%4jpXK~#jx(4-AVIY~{!tqLE&u=^ zkJe+2&k!kLP%o%6Yickrs7ozqX#W2$r8!O|Opve$F9Q2j&wZjcGg0iQCUb*8O~Qr{#R7o0$m)pn5ou;q z^oL36V|)ihX0dz~dFE4mbopsxe6;zg81!Y}BmH4s+LYWuUh1qI9mpTO5a3Uoj?+R4 zK%)h=U5J!YIhC-el`y4LundMm(&F9w2`7c`Vsur)O^G*=cZH8VVoJv2A83|E#kbr%EI79)%o z1N$mJbUKZF{8-&s^U%oh(0O)}CO4<}GN1)XHBBY$7Do+FM}17GC2Y-w3@Hsy5KEx3 zr{&6$>JU=v48ufQ!2L&Ho@LmeyqyNEeYPs4P}Ep1EPJ4?gi zMbE7}#kp3cr3KG9P0y`G&;4x2wO?Q}PtA-7W3b**#5Z534cr1XP0x)qLu0TRu9Gp( zYLAm(oum1haAO@MvP@4sli?b7XOB{r=f)AC#5bNu&beks5Z{J}p>d|?hRsQ*>Kjc% zZOfHAP3_x2a1h^a1Gn%rm+nB4M=oUKo8ASMog<}dwnl&>ILvZ1)Ct->dhB8M@YDy} zHca$<6zp>Kh!h589+n6IAQkDLA|h+xfgNZ7FFa2|Q7jrO3{(a5;YsQPc;OR#^!V=T z;`CJ!>gsWLVM%;6)b7gibj4+=@(RV_i{kVR5$bvlwF^0Vaa`fEdURzis`7DFWd!>6 zT+;DkBYCMQe6(e0e+wq~81lnF6$&akJtq1=9X?v>uta${^0E|pMd~s<35JIBG&8VZ zSz{lF|Ymf(mC}|ihROL=LsF4I#h1h&(W*t7+kh@?6}Es|60|er=i&KGO7+3UH9`( zVPC4F@^y7is8c0F}Ok9Y@e+sH` zYOZ)Ojb2I4aDtLW{1*aBpX2yH5KqsIzjZV{4Gr%k)wnZlz^t>hhp&#B%}764qj5EP_T1AR6RV_+)U4Oh|j# zCtq@9X&C>t&Hl$q`#(7t;Fk(7@JnR5h`xbWw3wU`A_PR*i&vKAhRlyZ&lS%HTbz~# zQpz-*4Zf^&UQZ$29Zg=Ys%6=%CNE4?UA}gZz#QbMMZKDa#T)^UZ*lBv_?C&}ZJCF3 z+^0U>C8^u9E$X>ne9BxjtKm9a4@2u~#xnodal7q*LEoxpKPmK!EL^o=LC^j2#h8p^ zyIT*t1Px4sc)mlD@XIf7rU2j_1_ellCUDeHw(Mohlg1e-p_oV*WNxgQGOmzEWkD@k^--ifRC>&b|K2mKHqj>nmPII1n&VhP{3--o@)wkQV6VUr z-gV_*BAIp^|K!JHzeki5(gip zuO`bk`H|j%>9bO2O43mErAix4k(}2MLE*7RbiKAsPEb*@i5SZQaSv1`T^!;jch{to zT?pod=R=y?Z@#>T91>1oRpq%Hga9;~0FqYZegZl)NvPA?5JF;KH6#Tqy!>IDN+6`M zWJva-;Vg&e{qMTtfx1bqi<04GUB-9ZPWK!8Q8I&A?Lig4-5bq~zg3o~MRk?nQA~}r zm2~lmXHg=}=X46?;ITJcIOH^Fg@hOoI9kU)L3L2%!R7NCLs zm56L$3A_qDLsVsCx;0=qodbYBtrM_pE)c}ajy|`%2KZ5Y+I!M=N}=cMj%=xrz@<%O z_a%nV07>!fvmCp#I%&VxG#S#nH(G-3T8R+@uk5AVo{}rLFgh0VFw)0juubcv4sIxX zV`Wxu{CtqO5CaX;u=`|7>ALv`?tnx}t@|9mNKy;T9+88LHJkJ^!&>B1c*%2ClbY(? zl)j~is4+@_9b}5lw&q%1b`~;;NuS$*vINu3QzZn*Bm5@Uc}Q$PG@qGmnx=wu{P(%H z@S6jn`HRcYy6QwaJXn8q5)HP*FYK>YbrPwJ@SjeoU$No{5aDs3JIi1(x3=x^K9@HR zjtz*_R?Cte)hFXfxzMdBh7gS)b~7El9%{Y*u!6Z+T)7h zsRCJg1tbtOOf>Sl7yhW&%B|IF&(=#)A}$RB?Ur*M=Y>@HG+*{&P3OL!cUsn@l!Gff}!!E6M+Zd3r-x7D3N**`g@fsR23!N|{p zLZcl@q#mLf?lI#j@$=!vg%dO3MZi=km9YBH7#k`%Rz#~Gv~>Xjqgs9gyL}Zb3@(~x zpo|9L5);IJi7$$YwvQnSoNYLiS#9Z{PLNINPy4Ej2zm&H@2oFKZQNJlqMTQ)thOZD zA=)a>caBvHu|mVkufD*EVE7`cJ{3dPb0m_aI~KX(%gScaU}0k9PNIHsrU-Fjce)_FS5{w% zEaWVt4Dc*~1$wlJxziwVIk8W<1sP8jn3E{YY}BDv=6K=AD*@5ms&%(^o<9ei1@6LOEp0X0xMKM@BY_G@KUwLwJSV``(h+pp1hr z`iOmks{VHXo&)JSkGglITLm3^n|o%O`sPA+QgTNwYgf`EUCy?`jEWb6l0eSe7@RN- zK8OOJ$pgi02>yEgz0=kQB83zIJG&a{w25o@L}UO+uhEcTPx-=@uTniLA~(I8mElmH zdp?6wF8`*^Xu8^=eOu92+Q&e7mNCNVX<6RAnUn7PDLgoy-TGEDmxi}VdX1CqfkJ^e)~3;}o8T%iDL6djgy|{Od%$nD_0X!tyth@M$bZC z?N}xZCxHfxs#>6UQo2KcmSjrW@2BXVt28p40K30~^ba`*08I%)e`7zuuypz=;7Np$ z_m4|#l~!T*Qg6uzh40dQdD-`w#EmDzGH_M=*zU#s?wdNc$$_rex-mor%teh%rvx#|J}xF;cYUxO+=(YkNP>5Z43|HxR2i0zn-p4qGz!s;Wg=f`O~F;(@PuvPyB0EUYq`;cNjM z00@9(4E}{mNHn1{iSKMjTOl(K0rWyD`psV^;nQwl$Ouo}YDlTOm^wRX|L*G5YGL}c zduWS2T25&u$i+dRouktkK+1@vOCeo#Wz6h3u!4By7!t;S-PamSO&Blhmx!m=oRDy> zS@k;!0`{z5A~CA#=jZhXX?i&QkYH%wtCr$6k$Az|dxXs_;*o4B5{gE|7RuqJ@!te? zRf*&^FiH3cui?aCfc8_%hH+Btu2BU=&kB7;+Wpc@hL7!JET@GZkIJk|e)vK-q>2+i zJsp#snJZt?5uMsDj4woQakAh1d?Nbk8?l-1(ll|U;Q@DJE&2-zTmO8mv6s>$d_}wV z{yn@rK7`ngr>5yQ>$zWF=<=y8!@rV>d@VswrA0ERh6RMHCauk+UC~6dSHG3_PYMel z`NMOhen6hZ0mGBq&%yr7H7B;7h_3)T;51lR#ZjncbaKN;7lAvfqyY_@U*|5*>f;Z=}ko)WY{A=j{&^a<@odd2yp|Mxbvn=a6v z?*CO`1^SS>K7bO&wyHhl>a`}SJL z%wbBHj;!O7Cunm87Vi#&=i|wZoZjhHPbiVqG5r*&#Ov{0)4K1oe^7J5J_4!Nf#Sx$ zjE+|9<)bAn<3U`1{iT>WjWrUH_$?ODn_F1mSQ<1}x^k26$>PS+jK8}&zZj`CocN7h zyvfTS=Qfg-P~gxb^V6sHtB0-tj$y?!*=Z8!RzhS0UBS-JS@_udOQGb_bM!-=(!%+7 z#>owNEmVvKVMwxUD@dOmBeP_Jkg}r`wD(TrY(l(bta*w1;e3u)VK||H7uK^hNJ332 z<`!&1z}JU{;EVdi=MnV2VGIhVxl-z&q1UMv3e(DJRn6Ld zx3Th{{ORp4en|UGLv+#3-IX8z2=r%$&W!L_n2yUZvhRy6RPMbFgH1Z}57b$sXX7V(3!g#GD?Y5}26^B>IeK{@9Z(ZMCz7Eq!j=*ROqziUIpVH4fpDPh|44 z_SCs&TElF<9Kp2 z1AQ==0(sf(Awy8x>FYv#u+Jx`LZC1eMK5iD#%OedwI~2Gi>!aVx2a`k01{w*hTm54 zSpykxbn-A@8v>`EaF={HXWwdKHIf=&?>{0UR0jY*n)59+wh>pKjQ0NbT(RNus!zx* z+rQqwPh^C-QXHu&{_Y~O5qG0qPK~8zWm;NU8#Jg{Pn#lI8`RgH`VF$0mfsG$^)#D> zbe_@QF@-ls38gpug2Y1$h0?li(>}QKdoA3ny!Y9?iCVuQvQyScge#hNf;_q8L8mdO zWAXqT7ib~)@b={q-Yizj&C(=g;}0S*0AKkp$ertymppPm6DH8itibY@NH#tqREo5{ zOB_r(q@wyT^c#Jku8_FY;TDsf%Rl;ZhAp%wM^bSsCL_TrN|iJ!>I}iTs%7&~!i9b0 z>`&xF_75|WLh94Q(aEA5{dQ*0l_wJG>W=QX?)E}asn87aJ>5LC>+ezYs`OvHkU@pA zr(TaMTV%DqeKSLY!K^UtQmO*V?C7tZESV3p2{U+He}0h!Cayg&EAE#RMyPg%7wcsQ z2u8l6ky^SYqeG`XArZrFlG13-NK12w+2cElLq|8P-S`ZJ_8TF{(nq=+rs$`tsq^Jm zmFelci}VP7X%4(7z&q%b0rh%zTd@$ix1ek>LoF2!eJ6|xndIr7rl=?xosSy=nNkiC zzyd+~1zh4hNYGH2v^The7~#|7@?s{M&XXfd432X zdv`UiHTIJ zm(Ld*#^g!%NFl>0z@IGQiQ!%t=t}%|u8Oz!R+KYuaZuDv5ggZOK@K>?v(BL@;1*aK z+v4kYZz*faH;?_Gt@Cue@!=KI=XbPqgXm3(e3my`5uL&2^k$R&ZC|?bD2_9k@*Z^N za-+}XOAU1?`#j~3)od)-wM@_K;4a4%<;v>@42cvrM8w3Ssm(J)e;q0c<+KDz*P6W7 z0{%EtIG_|(<5K_@ffz8`c7N5gwZ=B2sM2V|ux< z_-sivr15}3{fRtbF?R`Bgxx}__Mk^(cABgpOX_?LKsIow)()2|eD2C`I37=wU#-$1 zZ8Yges?go`dezz#D}XFgmlB&G-&=nx7`=x%Jko(XYrf|C7{q3gcD$m!@RJo!s?gpT zPO+*VsCDLDcwV>KsT{P>eYq-Hrt80nP6PSpzH?warDPa+cMA7!li3C5}O@C z5oUV5uzBUPTYtrJ)h&#}F+fxC6RFo%@+yF8+-^N{VV|#df|!d-OYqx=C8OZGuS(7+ zRSbd6ZOYNmI-e^}S@vA59!w3s8NKqz?24e=>F@mtx2(9DrO3blC8_tw7jo*&9#h|+ zje;fA^ZRXk9UP3UJ{dCFRz=8}3QbpBB&6iAJyZxK#LFgZ0q%1Y^YY3Y#Mi9_nIrWn z(7Nmd-yOg){+aHXxAw4O12u^!Q*4Z+V1zwRtTylX5dvwyma2o;=l$5sB^ z3Mfb0*?}a2t|ZX;-J-(o7U$tO!re{fLVkKzwzH%|e9ulHJLku2j0!m2|45*Spe@Y2Y#Aw+h+yka1 z>yxp(Z;V3*1dcbF%r0jvRwQrw78-4%&_Dj5uQ8pF`iR)8@fCthL=7ldCMG%veFV_$ zB&W+58woun^T(h=mO0`{P(Wc0VHurxF#7a)(lKZ*z93Idqe08Fg`hN4xj%}rq##1> zIoTPn%*`lJkiJrxdro$Lpni|z%;Jx?sFwA*Ep}Fx(UO|R1l0S-@bq=d7%_cipIaKo zt~Bh6Dx3_ogD3BhdG^BDHa0^J44Ix_Gd!*_`x?BuPv&G#Quf;{fH~!6B{4y?SfWX# zDy83^5&>~;%*U1RUax8XRDQxYK!|?RLRL{!$LO8CAoqCICdbB;P>YqbVTdk**JsK1 zaR-8V@SPgNK`0rUt9`2J$q-ugerjkpHaA zw?oT8NnY_HvTx1b%cFNF!A+&f*+Bt0@RT~HdZ;OirJrgh$?KO#_C=D*mdIKa8Lic| zo@QE;`u!vnOitEd02`Mt>EU=X+L_4X31r2HRoR!3_~YK-QZFOxG~NiGH)H6STmu-P zH9Qo25+M3QdI@{sK1%QTc1iZgKmaB=e25Up zm)HP6Qbjyb)(az9Nzb>_ea2*7sU==@Aa__x>NWGHXJSf}0Te!qgQPT~^>l?1<&)JWk+iTZhC>AJIKQ5|=wBX73qEDvW(d6F; zndUE_hg%UDE z8h!@HX?E~4Q+ZV>kx9ge$2apmcYVJ`(82xc8(I_X3%*baaMQG zNVODcxQibax+(iba$68@{Ace3yH&rvCiEh9?m~<&IFK!`x`J^KmD>HgZT^-mw8|)C zMB|W0Fib^Hu06_DD_aswFFnNTB)oj#{$tL*OsU^FAq_vrue>lw5VO{x zOh&fdDs1ltQKs$>UlWZBSP()SbhP2Wu;JvPK@#OlfRb*^f*paC^yq7cMfs1)NpR2G z$u6~D^WU_O>zLxWdHu`QcPoW8=%Vs9inO356CJL3xt^?Q3l4APu6~PoBHQjNCPZ4! z*LjP%sB?2UZ%;{9_x-Gztyj0{rs|fg^Mn0A?DghaULm#QPQNj4&ZCS>!uuoMffm_! zxl3{^YzD>Flz+w>F#c^!3I+kEHXd}!g*#qk1WF<#XJ@6Mzj~5SV&0H+O&p4ygBax% zD9U9CRMY$W{F6`5&9yCUpNcn&vGITR3DoW3v94U?;CUf^WH(uisk^3KjgasiXi3m9 zlj%$sP>*T#mi(NT0&R;e%j0R{txY72v8L)+t9>H7tr)gDcO;hDb7h3*#QbBaR9JoL z4Jmgvo07?ty<4vk6cS6?AsyNl%1R<6;O6mSwJ@hy^)gtkZQ`7TIf1j!=GoUM_ARW4_jN>`E`K;%@7su1w zPZ*An6vg>wzsH(gzL{3--0O?rE)3k`N39<)R_e)qW`o2=hd|T{hvJBBjU$Av*zoy` z6n$_wZ^@T0fs{0uH$&}u6yvNWJb_x zm^`Kxmlrip!1SpbY&;7H;Lp({>Te4J zs*u%h=*oAhuisN6=~!f#ImnQ~0Ay!GGxF4IcVr*NvmfSHuaI;58yEyNGnI@*x_?l9 zOUKzkRLiX&HBe%*%g><_l~>Tpc@IyiO04Q&ZSaxeS4gRT)S`XAHI7@qr!%UiRoeKU zq|UfAyeOYx54_pT%!k;A8lR9pqS9w&Xz?JOI+Lo{qM^9%p)_%A*B@f4#r>d*ytzz_ z_fyOOjjEEEkHvDTA}VqOHwR{5qUP)?NJLiajZaLcO@gImR=P;vu97#`o!rtB1%vX) zsCe`k;xCT}zbgy`QYnwtyh&#&7P{=9HX|tcC;}TgUQ)as6KG_~wX`wyyABcA0y)-pMUWt6{wv zEfXkdC2hsSW0Uaqqk$Zncu__j6^~5Wz9`a`@6bKfhq*@Pc0P$EujU^W@&>cZ>NidH ziAO5uMf|yL<3B#b)P+vnTec{FO=6dqhLGsfecDvoE9$hcjI;hnl9|J3m6votSS(ct zT-!=wy!bB$qM-!4t`b7d#9T+c7--*h5GP$glaOrv&2w2x(An&nNI4775XXgYYOr!u z`U=@~*qojOZ@#m7b$z4JmC1E&h49&>-vc2WgDa%GGeO?!z zfcR?J&5J5Zl6QD<)%c6KgJ*x#V6VO-R8%Eyzo*O$3qxaR;_8O)T zuD+ur>r#@qQ5~22#(`|ni(|E8!_9Sxu#yi{;Cx-3$a|ycn{6FGX;<$5#>#x6#*NK` zN8p0o&eo4e?Zf!T`RBYnP9t54_FO*PrXLpT0Ve9A=nG#ZLkQBgt2HmgW~H(u5buAM zd{=tSl0f+IB$KWU*@1(v01t42@31uq!u?e?227L)6!Temc$o3Doh_6Zu%cEf*-P(gf?+piJ-pe;?AUo_#FX0>r%z~81nmWb9#q=z9kfRZ+%heprRLOQe^ zRybz;I90H4NT{iU_|GhL1zw`A48PwSLCzRVg}#Xrq?O-1nz9#$D(x9dK4=CE%aY68 z*tiFVdd$AmjFZRP6VhvTRuype6qf?9AsFLMz~AF#Xuum>aqxOMUIyhGxX*dge_fta zR9aHnQ(j({Us+n3Tb*B7SXl!8l^2v3loVAJ73G%}<&|fa=jP`nrX<+BnCjPW;bc`g z_|86Lb3$%-*6S3}SFsY2(*r=8;%zXEii~398QY4&h_jse>#NXKZHLIYCac+#+yQp` z&DMsBI`pL>{$zU%UH-ltdR8k}#HQpJDUU8~VMkhPvc+eObd9SX4hO1_w6NIJyjsRV zG=JWmLL%$XuB@gXOI$^KI~1NMi>*faZ8m{kzuWVq$c5%yWJ$gA5i&##>a7Yyh(tK& zOI&I{@Wo-2PGskK_`Xb*oXiY8f}F~q3pzV4ALTI4D|~C0HlN&yXg>K`p?h8%8ID$H z2Yg+ z`b$W8-#iHytH{e@&a?FaFPUASNoEc29TxCa!klkXZ}EI4-nU10lV|mwc{%#ilfy*u z*m;iL**p7G#V_Jf>V|2~!uHX9{iv-)(RzOtI=GQD*BdJ&EM$*%Y1SwQ2(_?D*>cEt zehF#jP}))Oso3FrYj}-0nff!>pOclJhf?O%AnsY2CEOYVA1fm zD|-ykWLqE$2Z8QbAQ~zszMV><5C-DLCj=$LlnKQ{arR08c=C7Ke>~K^uj}6I=?=JA zW0;i1QWg68{TrFq`P+!B;rc9&u8Wnt@)RvLR8qbL_;sx2o<3!xqh?i?^KiFE$|^j~ zq!}-N5owN1C&_D0T`nbC<_H=2U$Ae7}XRqYAb2B{YUoQS*c|#vc1Y!pMY%h_WYXG?7|>Zp(Dn zgHZ%0PU%WC7Dgxc+bPe@2S?+uR78@M$pimJPV{6fRaE(@+XIf)R~`)wgt>sURdw-P z=sHj=24Dc@;C@wPB%J9yt`g_m)~;Axe1c4E@~atHXX#g?*#B#3{l76TUL^Ph?7ZcxAFTLI?>HrFsRoC57d1JHP<#8 z1jwi;O~ToMA;?@bwCki5SKS?E&Au=ps_b)DeUVszsIFzcukM}?J62Z>h3>}MVUD5Q z7JW}uy~D}A6G;s(98LF4Q91X>qy7gRb#F8M(LH6E{O(74Lh-Bpz6`=38XdfuS5lZ3#y2KTHoF$y$gL&6MIhqdXV#uKtG&&= z-g)+&Y>&?GaJ9BHPL(+%_Svy*FB%8TogF;Ct%lpV&qraIUP=d~NZ&2jy?t7g>k z`C9o1C318;-@cC4WE&aT0kb|8s;8p`Dsw`RK(Z2>=juGX5r-mS0@-ov4m@v2vNjWO zU)9)Z`P9MFDD=a4vEgS!1z~octB3LLLf?)D!H?=UERqilOVg)Vb-`Xe_S_sX{9VjQ zs&mCB+&DM;x^bg1bLErqbhme!Zcy%%lLEdB$c>S)92YqQ zwcj*}-ymoL^nMQTCl7p*Z=0;OectN$^PpXmTW>u@Zn3C{B%RTasuZ-qP=jQ*MAf3k zGv)NIdQk-NtEbIZhusNy-hI@LjaFd@v+Ek_(OLXvjn~c}p;HaUs^35kFE_{i^G zpI%lTMmSejRYw}0j2s6n@J(w=QLE_{3P@N#qRO~(!eAJ#!L%*9v!a^DHd zx1J)5T{rqrA{PXRm>;*XhjbZlL)iZGP7$?-xGv#FpyFE+iezRYC?gW!+7UtG#FIhd zQYDj+0R%o;SyU*T*HJ&8&d$WDNjvq#~2KNxW6CqIs&e%1bS1q;@OlKOiyngHQUI3SJ ztHeu)gQOJ=R}sc;sKn5)D+9-kBNQgQAE}=m_810y=kV)i%TgylXlL!ZnBk|34wY{R z;~u~mM96-W4g2`6AYa+`XS3irx7re2a_r!=_qQbM{NjS?z8u#d_X?Y@F?fz(MEu52 ziWoftzd1zu?h#CS{Zjt4#Qptv`KLNYiGAs%-w0uk9Tb036CARN2`9CWC01;j?qSk~ zC^`5AmpPz!1pv26BoIIWr0_8@5gq!@ESdP(W%Rv^kru3>z8*YEcr&Nm%3DOh$K5IB zIgskd#j#+`$g!@o4aKMK=cC0Zcg8mSO7|sRSFd{6DukxW3N2F+zTb3NhLIH+tZC^& z{%X%TDk-{zi#}u4A6N93ciD2~gzVK>is<$);oLs-%7#2EOMbEcMstlwK|gqXGsbZd zlgFig{h*H#kWGATzhj&DHIdN4^%s=@;ioK04bRF~CN+r( z_S@6y5&=!MVKjK1k>K$MMn$8KB>ar;7YXfcd>fb^cF0Q^_M~q$w#>^^JOyS*2Qa^z z?cl^-2}0^|Od=PBgm+a70uaPIfD1wa1`y2nSENzyz6gJ{s3cw~^|hwWZXBJsE`oR2@BP&eEC1z9SBp3dBZElwK06HW8d8#}t)k`B%5ss1^k93>pp-Pk-^g1BaXKsvZQrhr1&ju&hb4_ z5Cb8*I$n16_OxU+TCr-{=?w+Y$`j$3Eei)(h5d3ivS-GMnp9*ZxU&;bAk&s)g$@C| z(l5&a2YL+8@{WEi$KJQsb@i(v3nIbB7z*Q0jEC0mMDmMtv>PcDUp+I$(i)VVf2A!E z_o!S>S8T#0y^Y+SakxjM0ILjGre0maOtH{maCNzyT>S*P~Sl^h7^{z-< zXJoN-lo2k5qVA~Dv3(=@?&1rDTXFash0k&jbrEmAN7L}WKK;HlLjM($_Gq)es8WXd z$2vKk&M`;lb+Ev-fL?#{BUGe^$V_Y9(*<-IV}o!)A@F!b$SQ0i5c2vO=-4861bS9l znpm>nFkt6nD`Y$*9qRBTa#w&aBVUo8ULrCfSsOpO9`5k2;;esRu4I!3T^VuE;@>H7 z&EhpsS&C~s7O9cePfYZmhuOs@beXclIXS$xq)ym<90N8TUE;rG70`NY3TCaJn;81} zY;VvYPVJ+MNkm-gF|j`usPxvx4Hb4`%45+e_a*PuQQ`+UjS#Tq8VTL~@SvS%RRE~a zLl9+}ksa_};^$U@mvEsr<fe(21$M#v+uZL^V zHJC2XMTAVlnbt*&$l`V^L8Q#00j!7;uw}~>RR5=tGCyis(33Msz)dJRz}JCM_DA!S`Nt9VPr#;NeE7}8gLjY zv$7*891zJOcr_Ad)TQ{anbdrx>8s45=K(f%w z{ZP9@AJ+yN8vx(8ziwU`^%^>@E;;uX0L2MJuS0HYn1%;E2kuYDVtqn5!{5=JCy_n%OG(pvd-+t(%bo);l@r;ELqyRe z>UO&8#rSYJH>ODLexjSC9t_?#OQ8GGF<12QtgdgX5vHM`+X!ebV%1PVn^L9P%J#fy;^i7Ab`8oSML zxW^WS0VDCYw636QL+3uQ7kfZCF)-cuBzD2!d8nI9N)2 z>427${s8xY{4wP&&re?t#U>`}-IU4QT?tUOcc zw4*JG>jpkeEm8ZUj`z?iZn>}J@yM;Q%I}5Vx^V=Ie3*zrKq6`)r5A-AxrBew;>e}& z?)XVX+=5Q4c*)!(CzyBt3Me!(KF*a0H8a#Y#W9MxUd~;x(5|1DC3lWb~&f=dS&oNHi1`s zgNCN9YQs{&YCLM9LZMn-%XOSs8zonv0#keb_mjjaStdagBqU5rk^T zicheigN_dj8EI2rU6at6B+PJky(N<`ebywyqPN}>$&B^`c%IlfuP^ce@f~jjE4x_E z@G@T5&6O5*7A;{6&Pse9>8Tq*5lYs~2~ML|v)~7)z}UsH=JVsMwK1$V_+`tV$J*nY zyMxbLNq+4COdG2NwK_LBazY&W$EDXRsYb+yl0@n)`YCXzx3`Q(n^W?#k%C)+?>V#? zvXk(HB5#spjXN{+@a_GFJpDJce+Gn3OAl%ZN3#)z-f+hzzaj$_qf6OE%e2( zPBer^5)X_98t>>r0Jj{RNTAPpC431W*u`6WYSR!8m_R9oO(@E=27m&3<^`_?n?RW4yYiJ(ahM>XY;;&vLF?Q+J|eiNRE`VGjbs^XRn{mulWo5l($vG# z%Iv`AF(CsrJHK>#_$~ulYnl|7fGYC>g^&6Z7M7zaQWn@&iA-F-`N^D7?YIs!^&(Zc zRk)5|3($*z_gP6a+bE&0-)2H=6PxhAg!u5H#RREfXy4!Zv~TgBq&4Yv5&&l9*8U_g z*Z|t^X5V!0K*bL0&*}87X9;2!Q*l^1DZhTC@ZYvXjM~PESW4BMc!a5BVMEF# z=`jm-CAmspk9|LTFu`!GJNXtMCNnpRVuI>W-VKvH9mtu`#5Z$BZyV@OCuQ%0Y6izV zaG1u+SLwCo2|QV1PWRoXke^-Qwf#Lno3O(qH~Nc?qVop+~|lw{@Ojl1lZv;a^L4IXk^7(i0lxUoz54miFiq%46Y z<1nXsKmmg$8&rEXpVJ?ng{BC5@?Ldf8$W41ZgC?t%rG=HVYYn14$<1<_^9_lP)G~K zrCb#*jR@f>C)*vjG?QVjQE_w5`fY^Q+t=KI?MH{O`9T~`F@(2&qUpiAOr6e-w7?1E2Q_suD2g zY5}ADel0RE;EBokeagY_f(AA9uDZbKP27}7Wv4@7!_NxJHfXk`WMKX~!&=CCHvsLKm zdOGV7#V7kd)1&wY5@<23ulpXl8Fe|u7c_2i#9BwnX+Koe6tR8a3rF(?J`EyGI(^ZL zwoa-M>m8FGFc9L9tok&*On~Hbjx()(ReEFJB~VDDt{a)_N=}-+5_4Bs8`vEBAv1Zk ziN}Cm{vyP;7)F5B`re;+9m;jq6i%A_UdI)!Po9A_6%HW9f&|chfFB40Jvu1tEZN;y zBdUyie%DWeqO<~IIp@BYUY!$X!@=hkHLU&G_+Jm7UUMvSe3Pf=(ShY; z*`3`z@zErQv?fn!_Za^c7@(Eu82BX>K`gpug}FsEy^+6)F@tOVnoY4qZwuT?ei~Ln zQeMc=*m`S4^lI&}nQx}GmA@H_q>IIJavt;=xc}762b(2e2?PAU0FMN4`+iu>W=oJ4 z6a{LG$7YtwL#B87B=e045r&=ixNvt1BW06>Mq>dBX)xCxH*wUHXirK|P> zuWmi35n^dnX0oeuo_EF>yKF)kCmeINf1R`^(pj9)!(zkQ8WESDQ|lE5h06hlCk?ke z36Q@hY&}P8NQj0UZErNB008*LjwU^|$7s$HGm<|O{g|X_ zQYG9cIo@d+sjd8m-~Z>e!u61-grUkAdPF0Wl|q)4|1EDj*$yUgxG~UPSx|ydP($42 zhHrxN>{t(Tr4XqVW+Go_Pg~6dMbPK{2*o@@hy?5gU{(cyofiP^fLs}<37{U}O`ur= zPXGWux6BRrpbr!oYQtmJ$Jh=n#3IcEs56c8WRn5_!2Y4UeW$-c+$Aj>$vrAf>CFbm z!lIWR&>HB)x6dXdB?uA2=e119$V(em_Z3;P9$DiY71b{j*HumASq(y;-W9dKtKYJj zv5+Ss-ey0$2O|$6rO`F#7tDtI!bx^I-LGSR13~xIIJ@L(3ZGzGD3~d22B=ry3Cs@g z4h8`JwzPv7IDiOt3lH}pn2qS|z(#{4GhGx!Pyqn7-_)b4DGli#Zu)kJ*@`A1ni}|_ z-ChD$ARg^VRH<=av9Ar*&Ng0eze(IBs zQiTaSlI&nMU2G?hCp5O;h_TX4Fryj^XFx#cpr8_-wFD?$;DBZbyFK7>lLDO>1_KD_ zX}pl41qJ}Xci2Dbr+ZX*Mr%2ntGt)Gt4!-GUvJ;t-Q8(a&BA(^&|KmieE!>wKr`2P zB6iu*Q4ec}SQ9cKBM^t`_!o2l%rDt>=SJEC3!3Ty0>1uR^mw$&?S%QuN&rhmQ(!+m z09y_4gWcjH!2b}a0fX@q9=81ND7=^*@P(S<0YGkyjj@pn5KI%n00000005lk`pv`~ z+Pp$umyn-pbA5{EpUzr%wYUR2G-{JL=i)J){*OP;>d_+gs7+$Hmi7TJ`$c)5&c{uE T`r{U=9*r#4h?IRV*8*SxG^x&D literal 0 HcmV?d00001 diff --git a/client/data/sounds/rain3.ogg b/client/data/sounds/rain3.ogg new file mode 100644 index 0000000000000000000000000000000000000000..85f369a58c8a418010a4f7b4bd77c59b2cb6375f GIT binary patch literal 18789 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 KrvWSw06G9Z0$<7Q@MVR@-e3jSF*nmL(U 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 A!~g&Q literal 0 HcmV?d00001 diff --git a/client/data/sounds/sand3.ogg b/client/data/sounds/sand3.ogg new file mode 100644 index 0000000000000000000000000000000000000000..ca748a0e8b7ec777eebe61a96c62f144be354b1d GIT binary patch literal 5978 zcmahsc|4Tc`>!Qima&FLQDjDvVaN#0*bTxkVKiBX#Ms6tb(I)PlB;QqrBQTESt~NO zvZPS53zcY5mg*)^x~;!6+xU`v%IWMYt+Lo(|J6>4tf`R! zRF}YnP!o)S(Jlj&p&_4rGk7Rb!Ohb21H{4Q8O|;XiZLN-P(JLwaq>u2n#{l zG*vx&E=`32Q@3_kn}J&oM7&e8c9Bnk8@c#B(4pmOm6cd$`XNpZD1R|U*HToj1LUp<~12|)=fpJ z)fm96ZQ|&jDu$VdGdlGVSt)l7n^YL0CW!2mSBCcg0cQKQ={8AP#&8 z8wn4s5X&?aQ4aR>jL+lB~fzY7%pc&hP-Vt|mOE z$hj6kj?IaL^Ui!6jju{Dyy;qia}@cX<*m)^^Fv(#a_e50=D_}C5%39|4AzTic;(Mks@k% z1U!<%rF?l!?5;iIdVRUvsA>e`_Gf?IV0xUgJM~2|g&VE0aBTQ9Vp4qb6ieQ!;TM)tgQA zYoJf&QzloFp8Z!Riwl;h072%=tw`n;By+|rN81T|@SYxo72{`Q)=Narj2TngiK!FL z3`=B}7ZxoPUeK!)us|?A3%_MuK9W^&B&+;L&U_~GU?ID_qG)^X<##Pt-~NAny&%A~ zAt+wkAx_(YplwG0fWW)S(tPj2@1V5p;`ASkpx4$otY`@w>K(s!X#Bka5F~y7y3&JT zxT}KB7-0v|bH^CLZp@ST|25Z9w5uX;tRz2She))(n*1Exe0BakL|MtiUd(LSL?0rB zGY3Nj7xWNNHqzZ}9D}tEI87At0C|PFhq?=o8*qA~Z8w0?)8KYv94h{J=z*`jOxlg- zHh4wMaKL9Tf=hC)(%^bURMr9^NE|%tONVlmg|JExbW)lig-l}w4It-o3B8zEcu*GR z3MY5~gD7V8VswkoDImGv6FJ9W4LHqm&W$)BKzwuvfyWww4zYt^y3q3&xa&EztCEhZ zqMe%(c|y@{EDzm}Hu3Nxx+=Mjc@ce8T#0NQS7TRKC8DRI9Z{L+$#y03D1&I~V=v;A z3URD~;`cepn@yiGc74qM1XMcsBsWl}^8ZyuobVz}ngXhcM?BesNbv=l6Ue?3MDOt= zpn1&G^|3OM$R<7>qY&A2|9IlmKJw!UqVIUp&Fet1hDrt`lSQQ6l}>IQ?}Yb@B@k zqZ8R_{(x^H?L}hL)P@TlMEVqq><`2?MEUP}(iUZLjT$^@Rd;Qxv_so>=+SyA&^HxN_RptJ9ems3?nNYfQy#Apy+0=bBVK$?dZtR8SOqRmA7d8> zt|oEcug@bkqyY=&3aDhC<1_Q$+l=Dren7UiukEVE&Di*KE0FVIa0n81L5QTKS4%)I zMIluN$HoPhsgw$i0wg1sa95Slhe4{*2-e7oGy>tYYHBWKn+|O+9#P75$2*rY#;uXH zX#`Sa%~%oXvV6R>_Sv|5oO4W!E|(=B^kMXhQ^64m4my%Pvdagf ztCO087uVu4@h&=CRU5t9JXR1OJR(IlcNNeO+%6_QQito~=YnZarRDG^*A-08ft7c;buR7hfuIkf z;!uh3#(fTENcHvl0;@pb2KE-`sFex>S1A`pz=N|U9cGCWuvuv*3z6 z!{XnQe2B|Z__sFuPnGsR&^qXgn;G>`T4O$WCJOp-|~wl!@YKlMEk%mCQqYQ zpQe5Q1?K*2%-kl%huh+T5Og?I1hP#zV_dCWtehjZfxlV_Nk|hG1U8rh@(?T=aKpjn zjL;znaI)4CIwAkyxUB3oK1nW%`8OY^BaG%sfGoff@B�KD6*J4#}@<1yrQYzYv!J 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 XkNCncLMAIg%W)rbg!GZiM$rEO&P^o< literal 0 HcmV?d00001 diff --git a/client/data/sounds/sand4.ogg b/client/data/sounds/sand4.ogg new file mode 100644 index 0000000000000000000000000000000000000000..7eb862c373a6be316a6b76e1e3bbfe4e37ecefdf GIT binary patch literal 5969 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 literal 0 HcmV?d00001 diff --git a/client/data/sounds/sheep_say1.ogg b/client/data/sounds/sheep_say1.ogg new file mode 100644 index 0000000000000000000000000000000000000000..209d4d51bf698dfbcdcb0b69cc5ce7e1bdcd2b16 GIT binary patch literal 11515 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 literal 0 HcmV?d00001 diff --git a/client/data/sounds/sheep_say2.ogg b/client/data/sounds/sheep_say2.ogg new file mode 100644 index 0000000000000000000000000000000000000000..ccc6f9d48e9c5e1bcd6cd1b6e9490912e92b6c74 GIT binary patch literal 10308 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 O9N2>&)ZG2BNdF%v-cT6; literal 0 HcmV?d00001 diff --git a/client/data/sounds/sheep_say3.ogg b/client/data/sounds/sheep_say3.ogg new file mode 100644 index 0000000000000000000000000000000000000000..80daaeef1fb090321e66a867e9c08e2ee7a51f9a GIT binary patch literal 11908 zcmaiacU%)qxA3HrP$L1P8>Ayj@2H_e=q2>tk*X9?iV1`&BGN=e3kSiy z#YG`#>R^=$;+3hVcUE(_>e>`D<MfgnWd>_YMX+zAia3Lf9jCXGtEmy z>pkVC8S6nUKx?(}&|c_O3)1AYFneeORexTP2LSzwO!gHSR-9lHD|iY3j%dr%b5!`* zIpJrG!fY507ZfxO00Z%vW>=c#zBA32aLJeaTjsNF$iHa%Ta^Ebn*v~C%Wia(hvl!F zKL8lIW_Fcxc2#ipLS`<8mR<`76abJ=HL3>ox+aB&uN=r@t>IJutGE>h2>ca?Y=|2S z39Lb9Dk22Xf5!o824z>a;uFfhMyBwSIIm#qv}ViR(p@-9NsU?}Wu`4B@-Jq$Yb}&T z_dT00Q|g1DD`hV1r4Zjj*%P`8>pzfm6sP?Le+)j zmYO$0kZJn~yNl*Kxab{Ke{V}&AB4;BJFnFb+KVstcR`SK_lMVIxc{>J<@;-7sJ}#9 z`Wc^TS+}?oTut?r9OW1C&Aoqb+RL@goI31EPjCkN>YmuyhpUY`hpuQXl&0Qx zbPcU*u_MV=722`>wI2bpy*^sNKhJhYvu~#C^|E8Ea@GHsldv;109bz!9@r)FKjpLV zt6h?|+)&v+q^ve%Z$yp_7%Pr-xs&8Jp60QUGy|2*SRd!&0GIz${^>dt>NKGtWpBw^I2 zB_~qVtz}Ykb=a2Fc+FLZRMqMb`nC*ueJ)ewYJO9s$|3YdBP0Y^pdVXBe;zN4$O8bC z-Huf@tJi|vGX$^2&PjV`bol&uz*m;GhvCykWYxvCh|EeO7 zIgqE+A*z~fjE5~bzy;DA=ixF&b{b8BG>_O@PVkb+#pH>R0CI7xR}6W^(PLta>@u1( zHJau%n$%f+<8H+B`udwqwZEDU{JQ(;W1-oQ#ZH4p3~kAlPA%c~vEgobqcL9cNU@Q9 zETkpLD>h(a%y1yqh+Gt~Q)N+r$MFECJCH~?IWB27#>3-$tcP=;+eX?@Y^+C7z^qe% z%SM1l&uHxIhQ&~;<=9B<5IJ^sH1_?4@TpBmES6lH<^}PMrOlm)nAu%!OOBl>^zeej zc1L(=Og@azy%p{^b*SlMu^}7!(OJZjhg$(92(p86UheP^iVm!Rg$Ib+Q zyldk?_HYWA*dRNtCqa#vTThzhCy#AFCQlzJzT~r!RJFoZL~c!kTCh+O?%|yLc5&;W za!jlnB-_~guwM7x(U|l@P|Tx+0f1Y`AkxxnG2jgn@YBi+Ec7yYQlY6pmX>GtgrC-{ zB`XkZr!QNRW@mSrKQ&KFN;2AtBvVmkLo%rp`y2@0w*pN=w zR0+C;su}0#JuNH9*OIO({7dN7lDm`&O`*_4=PEDT<*X$wnVL&t5v$54Sx8p#8^|>l z75YMiao4c+u99e(s;+!em}Hf+n}t>@e{}9n<T*yT(Jq+rO7a_t&(z+FP{mw5lED z620;uwIAwvmklYWuEo_YM=Rq$m1nm=szMvrAp)ezoTS#uADXMSUg~-iB7`1koG*=D zRhl2S4^_Lv9}3ms3aOeO^@EZh1Sd2-NEK3{xQFk=JyMLMgs#xbR9dK1#VE~}6=o|f z5Gw7I=7ni?$_s?Te7haUjX-!8PG(9Z5i9TfNQowyfLmE>cA!d4RGu>$WX;TKi+?b&u`_>p$gv(C8-})OkOM;weh`v^FfQv!Lk@p2 zt!ZAWWG4ty95CzbvBT3E>&EXmvV#eC(@1w4i=Ej>^U>126Y=rx>aWhvIz0faAz1(& zF63yUDJ#e(|F>08;s%Yao~c+W4q8g9aCRhUZsd=G(h|iAb{@edZjcH2D&`!tM4lvmT}+OvQ!&8QeBszALLV`uCEO0C2t-dyzVo!(-wfPnLb2Dl80L#W#jw=lFg z%ShV&#c}FmB>n%zRTbv^!-uUZ%>NG`lt(Bp&>>j}XGi)gi`jub{1+#?liB{I%1Zth zs-odYGCO>bZE^b0?LSuj7nlEEoSogjIB2N;!&hi$2Bo0FnvkpV>q!fc`FyTocZ*W~ z`Y#axo+pm>S(o&Bm4a%-FiO=m`Xt$OC4=XLYqIvNVrgR0*<$dDE=Th&Xko`80R}RG zBGE<>0oXZlhgkHaiBY$q>{j1D-BeW`nZZ&7b}8`!2`QO(aAI1Q(PS4YMu3@eU_~3J zk4wQlc>`EY868*+-OuUL(@f;0D|Re9`w8F;02cr~DBP|AVdL~}v`Iz}iz$>1LsuJM zumFY_+|W=p<6K2!$H3fY7&nxp{O3XU1LK_V{`kRJI%LSAKt#*cDt#y@pg0F?fSZ=#+sVyx@#4s z*={jbmsfI{0sqp&oAuz8i?(&^waU_Ldw7i1*>%#xU5wtZ%(~NpIn_q1vf-3|kke;j z_u|vW6f3|`WnDrXpqkClJ-~&!e9Rg7YRazM;yS`jpI`Zn?!X625yKl5ya9If9Zka0LfIu-Hsn~QsVFM9D?{b8yimLK&otM4* ze8bV5b{GuzPn?+gJ@Wvq?c6qhvRm@QPfP1u+umiqk7u@fV{Q%$`5){E0pNCjXxsJ) zB?ddkd&h8Uu4S~q$CF+j#%`O}$24BsJe-;u`SY&pYd!2FdPa3qU=DBl+wDQ5M|)fP zA}gR9j#3x+Jg2_S3+?mcNC+u>GggF!K8DX_ol60`F-sPfM{O_C3s9reFTqD2o!z}zqTETH4tzG8y7scPqW#2|UX=Bb zr=PK5FWhkEeNN!YPVd93nY#K|%r@JlG%s>4{L8YEPZivySE_5d+s4GAhHpBa$Q)8Ei)(aFDS4ryZxVk zQr@}W-mXYQ`BVEhOy^*e3^o|h1zO&Z;0ghpa|Z-AIdxkpEbP61l$XDsv1;885#Q8U zb~VXhi6TpzJZNBhXL@mscPm@?ysc)jT$ASG`r!}*;hSk-_3s<7#v$TSQ)gDNoiU^N_2>Zix78)HBNmPTY)EpmUG;@Y_~)c^ zo=#z|ae>gJXuOA@(e&kZ-eUICK|#ko2bsJ`MNd`Q&%;gg zT}As3E)BmaduMOyI1^v*0tcEvH)Z%MV_NZ(*z7s+v`y}ByIw=b1rIZ3Bz|z(5~fFf zj+D4RvmR&jviCWeg_TdNKvO;eV!GvInk;|Rb7?d97wJiZyEZk{^Q^sqml{{$$rCT) z_>9Qf!lNto6PY612JQgyr`GPzrbATj)#+I8@{W>m-sU<|`?7BS7%cu4{B6TL2a zt6MBKQku@3I!wBE&do0k{7G*Qb(_6)#B%<*zN)2mELd)tk0@Y#UvRba@jHZ2#33XjJp)Cf-puQ{2wZ$hRenVCSJgd9 z2NY5GAHk*LgJIoD?7HywI`KC|&OP6j22UrlRQ6_uP_8%auGLW6y;gD7yRE{PR1Da_Z$O8#e*AdyIf!GyTEFWq>|Y3ofyX^j;w z-qMTC5GtHRFX6Wm;n{W)HfqdKmWQl`h)JGV&Uct5*avuwo_)pL#o-C$Wwfb5AWD=a z^TG8(ez9TDum^F904*TCT|c30dYi4}=eYw1lm2+mE3H@H4O3>8o6g*~dZJ#qy-&>| zTu@K8+Tu8>fL?O1(9Fv-#FS`=6HnX>TS#R#$N;)d5fy0 zf&FM!_LA{7?I?-hv*~wDY(H`tvVC<4);sD)Pwz~^PIKbqqm?;nh!Y59zTnH~?Jb5@ zdP%en&5QdBA6&O5=)kxb>eNO5H{5TJ9QGBW3juJ*{Oc>*UBH{~@bQO%(Qc{^feY}_ zgB5IeJ?)Gdl||XBBQ(7s|FWd6pvL$YQ`GyY<`w8n=(W>K-ppfnW;>B%i0u$xJodhT z*GOYlchNZfVsJdYA_ghJ&?o9+@9p71AzZKgm`0i0NT%6`df=VyPG9GoLKSly5~=2K z4en0|#_caLX}066$)JVOgWQr{Jk%lGk>6_bh0G{^j zeXXP?fHdEHjzFX(11TTRwKXNM%YV>ZBH4>{Tzp=c)o?V>sQc7+#|ChQ^SgVJlPK6W znITS#uN(I)O4{RN1V2HpN)k;2w9wqD?3|NL0wXs-W9IT~COvop3$ti_w z^O?Y~)xj0@j47f*)Ir86mMp%+m=c!?!6)_o95%c7K~yS*jYl^=br1TdM43%z$WtdJ z4yUv-%-U(Q%N&SzVz{qjXRhzf*v3r0yb{eZ<8c*rb#Dm=3y5N~IcRoCkYz9Sm3Zcr zh?iEL_^lq2H%gls#yJ%|Hih?gBwQ~0cuoP7Ys`Sz&M@y<8-s6amv0~H+~|+AQWtCc zYIx4sR6dN^-HoDJ#p(M}BhEg>vFAxV+TUBnF8qPQ9<>|gMAs^0FFDY!VFPQB4fdr7 zRfID+6`2c2DMkqY(1qu||eM`aMQNXum|S^sc?VZ}t^0A_yF-emYEr83RnB z6k#_R;7(kqfyV`~if;-5+E)RZW#!7`;GF2UXXmm%w|>0uB zch}U2oqS=Ib?d@!%0m4!ee`hz7QtriJ@?`>h=C8|8hm`Hlbi-JiuCnJ-*W2P#pNfm z`=F)q5am2k1aJ{R2AN^Ui*i&b;i!i5p@#JkQBF*rHBFv!_@9`kLTk<(hmV%3*9xGO z>L#&|C*p4A*gvY=@U}n+Jl%7m0oR8(#bst+n6Ba*^=zJVM2MpQT}e>aJQPmf2uM6D z`}VHUO{PV}r3u(J)Zjfn>WWU)*pn|4eBsG{_3J)})4$L#Du=vjnGRY)LQpx1kEAI*hzLp-kfg{IvTagyoaj8x z%Dv)5L{k|27TuP+ngu*%7yrKdJWL%m1lBnPZd14@;#Neo=0(x6w*5h!2}O6)om5Dg z8Hk~toOcUgJfSIp5&4ex?Y+_0oV)f803>UO022#&#}}TGHEMd1^O4kN-iJHBCxubF zUS^p&S2Ga1%e3L#BubhfCmcv1y+;A%vKlLUb!yZB@gq-NPoT~l5>df?Yv8*;$qfoG z0gh^5$Lz7em!QYdTe0!h)IDo3cQy+qCrkmQ4&}j?3j!$bEhmrfyDho6*tDOYk%6tuF z-%;cbdDBp;)z>Ij>S5*>9JF2b?v@hdLk5~)31T+Vocw1ZHPn%al8B)Sv1g+%mUHn) z#w+A=nPu!S%QU+oTPCWMh@#ptEvR7>Y*|!a5^u_JnECBF%;pKf%}@qhRJr*CHvw!Z zf|i$Yz_~8CxdJgwyA#iO4KAtf7RKT5_}abdqDG~$T%~s?cEz(uhZ*y^yFq@HuiwLB zroY$LewGTfCZs(;@5CJCb!UioZLMYf)FZ?~mi6PYvjZrJ^Qd|v(N_q*n!C3Vz&WCQ z6(lJ9``NJA*+5pbdtbJ?tjpZGS_c=|G?|WkE;7zn3I4ziQSImCDEqzThQ)?^nV6W! ze((nM9HyL^a)^8dF#K|3IH@e)R+mJc_2b%?D7Q)-8~}<}HoOd5GD!!)R}vAtD_Pha zOjYr`tYEjQ;Sd+B9=4cjt<`({MaOH!>On#7WDH0Sn!()b(aj<)wyRlObJ_N|!oFn# z2h(^>LPZ4}?j)>1O$Wh?PdG8)J|9aUhCSsy5mgxHczr})bxxfJ*o^9D!K^9!U`x0* zd?t3Y6eb)@+~m1U^mNc|=@+JBH(4yI`l4Z>u)qiNDZj2tI81~111F0Ebb0z(4)pZ$ zn+uj5!p}jIDo6&6l&gTZ1nz#cq?&TR=+{Dqljf`OaBIms7qI*hFA5d&$Mj7_MJ|M= zLYYPRaS`J?=b9U;uMTBj59L@?ow>q&dCmzAn4O6A?B1 zD|Fp?21h1ev>11Xw41W zXQ*?5boPtS`{I{VlqcG{5>65p>M?-H^+plfYt4*qD(DFx57XPS2K~wfjcwmD&zh2= zO`g4K>LM1YJ|{(zwQmkIpC6sLBXLz?<`yeB6f6>Rr*swTT)8Zm#|tPwK8*{WPN3sC zIP3`nU%UC7o%y)oY#-syF#uf!M|gWPsZ)}SW%wcL#g4*sc2w4X>D*{g z9P(bXvqucF_j(k*oH$Bj|6q1{Rz@mFdSh@UBapim)b(`$eOk}%`ZwEREQ^wfVqX+s z+d(2y^*#!O@5`lwkFC`r;HNS^-#U%QtWb{wHWYDB4_|saU=hSWbw~2l!aZDeR^g(}l<$r4~9a9+d>Fgw`Kt-pBGF z?)j=mKhhqXIFhnZPPt0l-UWzC)L9b(8z`_i7@Wje>&7+?cZkE;g`K=6hcp(WZS}^P zvB_OJY%loDX8P=#eV+~%89F=Z?qqU#9*>(D)wOE$^EvQY_^Iw~?j&NAR}_j*&`PZT zeK$VX)EG~E%uc{pAP|{Km(1>IRG#~x(XS}>k|I8Bj?T_ z4>9p9U(Pb_8#VM$U%@mZINQvbP6X@g%y{orzoa)fuF#;?{ZV4#oUH*0{xQA(2I)5EtMvNxBQ7e9|wPVJ89*ARtZ+V6OHN8RPJ^) zvwHSf*0Rd=(X|ha1;Nt=ns5%b-N?cod@z(of1}#E%1baJ=?Fxa0zrgYbD2PRHs6}d5uKs2F=JkOuuJi_8`U0PdR+zl=$piEtJqoe+JcaqMX77JqY-vk~s?Z zFY|WQve>p z&r>vxt)E5$s%|%I+%V((kAv6}vGE5Pei-~mMEhc`j71SwUnQRh04DbV=+6ZLY+J$v z#WmP56{|rUo9szy z>bwGtf<)SB5A>=+Xrgf6*-qsRw)P_EW8w_u2U0 z(w2zzH-;rU?X>wd$1Z7IgysWv}-Y9e*D53(XH>SKx}6(lF8Ssk|vvyPEAU-l(gh zIa7??&v&(>Z~Y|JamU-0F^#tq&WW#=fpRC2CnkgL-+taRsTVuh^hZ5Q`}3aVsYW%v z4WjgswuU=m1M01e&cRN7@Dip98mNp7Is=qv&Dy(2q(q;|j&x4;zGd@}b=xKFFyeiK zHPwZYh`y#DPQ8%{Q(%{|(SZZH2=w{dD@~hcQ(f^952@iZqa%SzMHhUF?qE5l&70X;G{x@;WbB=)Cths%h z;77fw$FZ(Uwl#gd-z@i_#^{sgPZxcWqt6E#GbzuO`DRC>zxKLuKszmw!l|eCY-5`< z1g{K9%(7ZYB*Or6>B(-@UYo46+^bfUbfUB<|C!aPFb3soL1Xo%1*$ZXClA~qTGEpV z5~xO(D3+#_9z!PL8{C{#7tt$avAhRVMk*ngO2-H68`wh;<6Zd{OAjMfc>|%7ceaA_s1rixeB=tA_n}!?l^Y9qE25Yrj|<+Yx8eWeL7q%?K7j z));u0@6%f~?EDS!3ETL00_TOS#@QHG`gy1E1lv5ao_*R^#NAyMxc*y6D~bbCn5lxQ zWc=Y=Gg2Nna;FicgEKZHhE`|_pot@I#*-8mZw5nMyKqJcttk?QHzQf8 z5-<{jMe&whB%2Yk#mMYfN`~y_btXFMYMcL>l#PUqP|2aS_x^p}5tIoHU#pgm;sm|P zDZlEKHCP*a4z-1zm^xg61DZd*&Nkhq=# zoOo={Z)qUvEHXUSAiZeJrN#&;hW4-DE(0h*jrUHcu*!#ts;PqD;Bl-9GVkyaEc@Ey zbpGE`>f_ptG6WEiVKYcUU{JdIm~dXC>okL0!I{>?IKz}+8h|MtJ1QyjV~~(oB`+?& zW9_KpwKLkS$*W9wKXpR{yx|+^UIeL=o zE=@DE*f8H`T(d*tl89?#wZKHtn>wE)ZDTI0}g43_?mo48fc%~ zn^j65@@~>jzWRp)F!vs1g=Osn>Eb}Upi{Ccr1;n^@wE0JxwbDP`iI30ib9)Zvpg%UiZBL@?d;6vwN zfuP{j6(08L2aZB)$;KTQ^>IBLI2qXCy|=SEbNxrhz*Z zejNVvlR?S@>^ywyBqcDWMHw!4$>{!8;XnyH;l=O+k8{hJ168_kmJ8pS&~{vbON!mf zEm3$&m0zKFqZ_|$8sPq2M{l^GND}Ecufst3f^cC_ugkYyBi0tf>)2mfN&>@&k${=Y zfMs#S5D=^CZhnX}d@w?AW?w#oqCKhGRUsQOLkHj_s}iC}#sc+6NO8ZZQJxG_pc+e* zeImB$K+(Bn-}%dd*^U(D*y^)+&FZg`cT0m3M3sHR-Jid9*r49pZhtXe^Yete*Z^w; z+)4;KS7alWJmM%Q`pr8CBws!1%gMiI?Tg$fy8EV@zQN1dRX4nX1ELGUoOgV@`tPuX za1;zlk*4>Q2(Bu$k&r7A6M}HKkh60SI~5&8$ItAA(FNix>E4uI9|p<;b4DB{dA}`2 zapdhUWRt(CUk9ZPw;6~|Cq*YfiI#DO9j7M1cguJuQ`8jm9vOjIm=|F9nEyH=M`8JM zx`Dt0vf(SE7lgTkdN0uT+&l+;(NTRd%e|@y9q@1LN}>m0p z@bM{;ZF`r4vS@I2GF~=M3>+BA1L7^G7D_aE3CFxMv7o`8eYx-ZJ>1~urzQ4a@}+Ff z0IS}9qey99j_0ebpefxXRX2yx4NzgDJTC zRK*PE;kwgN#6vh1i3FTzxYsY1W1w@m!QYsI*ga+r{~x2-hgIWr3r z<_FJ(ZLzs4Fkan(dx1yFr=~0papd?soQlIW;b<82RCV1-=%R+1pSzx?Ci$t%uvbS~ zX|5_^vRZFivQ)FLPQ{!*{AAc=Ee85rc#JgxiM|y{eSa{QL|Z=I8N3^Wf_rdkp{NkhX9ZMGJifkG+uG#7m8%{Cys)LO-i& z-FnveX7(Vt5`Lw2ev&a*nCPHl1)3`akza0?Wvko%ywo&HiF8a?bJTvbH}Wua8n7Xp zHxo+LwQ_OuwfvMr%acu%{c3oO%jz(v zUhOy`^8|H7b&X8r;TIA{yujWUqw{GZv$?iZ3N=0#sGywS8fnX`jATSP?~)#FbA3ZR zfloY1)1q@Y_PYJ}$+oxUb+~jw**84T#R#1{X9|V+F-xoOk9aAM&R%O#-+ulnao*Vf zcFf)Mdt*N}LHStk#qed9Z^e!JmV+C;ESf!z_-Q9!INYlm44jr^$YcHL-;u;%{Df6`J;yTfkrGno z)pT(?&LPqbrn!1&Zu%E{_O)NZ`*hCn>RiJN5faylrhH~!y0u>{BzLX1IR17tm;OoA zesf!at!6;SejpoDK>4-V{k;D(wpa5JsV=3BCKFkoZTb@hMDGaanG7EMyykX~=NjMQ z2F+>l$ryGl)rzv~G*T3@WR$@@m2g(@Ogc5?Z?(~&!;C77mn?-wA6B;o-ympe>Q3Lw(WFagpYf7!PNM|d7iJb z52ZrTw~8~}gN?txD83t0ea|L8By>Lq$3#rX{nfPK&?t<8n2-8?>^uT&xAYE%_r|y% z3Od^sw^=3q;ap6%**i2PKV+g<6NwlVJ1%2=y*uVETI$(J_2;Uao>S&u=$zY1K7j$3 z9zITqw#k}g`%yjL>`>tAoLHz5w3=~UF)S|SU^9pLx0B0n4M6FxyN~p;Zk~Xd?)%~+ z#Q*V!DT!(=g$jAL_s3VpYjO*wL45b0uexN%smdTA3CAj5qalS-cW-@M=Dh*mSPv<;p&xqSUdMy+sQ*6S0RP z*<}pIXH3r%S0ay|p6vu+7#;JVbp$WZW|Hc9{r0ut^tXC(Fa6PfrV(eo`4<#!6lM53 zun*p{)sMVdu0pCVZmk*$wBbIE>@AIupa9X<`<@D&$KT|>SUPQEc}`P55c(Sj49HLh z#I~+2eQ?+ayWeB&SyvmwKD5z&`^)&kX!4f_MgDI9G2Hrh$q?aspzWyV^M~huXubSF Sja#qNVhs`r26(Uq2mcQSi~A}7 literal 0 HcmV?d00001 diff --git a/client/data/sounds/slime_attack1.ogg b/client/data/sounds/slime_attack1.ogg new file mode 100644 index 0000000000000000000000000000000000000000..d02d32b3c5a8c149108599cb49532186d0b16c35 GIT binary patch literal 8443 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 GDE=SF+4DI7 literal 0 HcmV?d00001 diff --git a/client/data/sounds/slime_attack2.ogg b/client/data/sounds/slime_attack2.ogg new file mode 100644 index 0000000000000000000000000000000000000000..b70ff5089c26ccd12fadc8e9769c3b7e8a4733c7 GIT binary patch literal 7559 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 literal 0 HcmV?d00001 diff --git a/client/data/sounds/slime_big1.ogg b/client/data/sounds/slime_big1.ogg new file mode 100644 index 0000000000000000000000000000000000000000..db963675192f49863cdb2afd302e901e1e049d90 GIT binary patch literal 10680 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 literal 0 HcmV?d00001 diff --git a/client/data/sounds/slime_big3.ogg b/client/data/sounds/slime_big3.ogg new file mode 100644 index 0000000000000000000000000000000000000000..ded5b71132fa1e8d631b8db3cd41c4d33b6aede2 GIT binary patch literal 9820 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 literal 0 HcmV?d00001 diff --git a/client/data/sounds/slime_big4.ogg b/client/data/sounds/slime_big4.ogg new file mode 100644 index 0000000000000000000000000000000000000000..5d9b6762fa40084a01a0ea2172f8d277002aaeb3 GIT binary patch literal 10433 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 D*+5W0 literal 0 HcmV?d00001 diff --git a/client/data/sounds/slime_small2.ogg b/client/data/sounds/slime_small2.ogg new file mode 100644 index 0000000000000000000000000000000000000000..94439fdaf60860a7cb9ca171ddfd2c1bd56e9aa8 GIT binary patch literal 5774 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 literal 0 HcmV?d00001 diff --git a/client/data/sounds/slime_small3.ogg b/client/data/sounds/slime_small3.ogg new file mode 100644 index 0000000000000000000000000000000000000000..0879955b6f31e95672a9880ff494d0caa58f79df GIT binary patch literal 5640 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 literal 0 HcmV?d00001 diff --git a/client/data/sounds/snow2.ogg b/client/data/sounds/snow2.ogg new file mode 100644 index 0000000000000000000000000000000000000000..c955f916cea9019f98715b243bd67879a9398cd4 GIT binary patch literal 6883 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 O@8^on{&5pP0{;gO@Cg?H literal 0 HcmV?d00001 diff --git a/client/data/sounds/snow4.ogg b/client/data/sounds/snow4.ogg new file mode 100644 index 0000000000000000000000000000000000000000..63fbd6612fcd1c478905d5466b4d60728ed29295 GIT binary patch literal 6986 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 literal 0 HcmV?d00001 diff --git a/client/data/sounds/splash.ogg b/client/data/sounds/splash.ogg new file mode 100644 index 0000000000000000000000000000000000000000..4b69fb623573794ead6d9ee713570e8ed3bba8a1 GIT binary patch literal 14398 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 literal 0 HcmV?d00001 diff --git a/client/data/sounds/stone1.ogg b/client/data/sounds/stone1.ogg new file mode 100644 index 0000000000000000000000000000000000000000..16cd3666d4a188d50e45e2e3f3397fa2d19b8467 GIT binary patch literal 7126 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 Ivc(GgAB}=1@&Et; literal 0 HcmV?d00001 diff --git a/client/data/sounds/teleport.ogg b/client/data/sounds/teleport.ogg new file mode 100644 index 0000000000000000000000000000000000000000..1d49a1aa29ccbbe3c5d0e3af63cf7de8b6456a4e GIT binary patch literal 10384 zcmaiZbzBr()bP;VAuSC{D6zx}DjiENEFIFV)DjZX4bmm4EZq%)fYOb$fPi$PDA;}j zKF{;M?_b~j-JLme>YjVDYZTd|n zxe4bZdO3B9P$m&|lTj|uB(~y0xo8vKkf|gja3v5W>q{LTD~rz-&UM!?C5-1T2t~s{ zoZ}UaT<+hCBFq7#%HlJJZwg5ghiyxKWeQh>8IpszJ=SnCxwf3JDj3MjDW;+wh6~$c z3V$uY8yngu)J7YQEyf!kx+OF;8%87-ofD=i_LU*rUe=fP?--o2DoJ6uvO{#?O0u8@ zxUe?r@KM<^hHyR@{>^Y!s0|H}1OSE4d1IgR5|T4C5CTKsBFN}a54tlACo>J#GZEpF z7~z2H0N{gsDzU{XiCZcuoJJ{J*L^3ZLSVGvx{F+ks{nwu4zZ#;HQu$H4FKR5O2(oM zW6=(=yU~gG;gMCCKrjGcgTp}Ob)}Wl6ejhM3oWk8|Ers1*wSB%gFYmG>u6Vw8!d!I zk9)lipc%mwu|j>p|2jFC4o>=U@n{6Cg!zH29g^OYfwOt4&m;J@8< zU{#{9Vi4Jvz1$NbUcC{DYB&z0_ufb;xyI3^&2&lW+AQ2F;_70nh&=P?2) zEewV8m6tt_7a0|39J{{UIjU+Tl_D1IBbVo|?nCIhip?83pTKr=!kYArovWJ>a0ogL zL3r&yR?zoyxb!wjI#-&lq9LWZ9)x^lf8EJ?wKM>r^@(Ykg86^?N2W;%E*(m+3(km$ z&FCs3QML;iD5KUulf?+L%fMBze??guX4o42pZ<61V3MGUV4oC_+BxO@FkyBO1VTccq!M)1J*blsko02JIsE^1qU!+X z1OP8iWe-ke1g9bb1g^asOnl{CrZ>WziXH-^Z=rwZI8AjIbf|&X-%aD61polz;X3Nk zX(kOyt~rDtQde*ep*W|D{QotL8K?#o=vacQgq9IMVul-;Y!9O5l5T+oE=6fcbN zhUV^)3tMLmB826M2Qp;C({MniVFNl~UI`Bg_c3`)s2*@CPQdt>(E~8$@)xr@@cI&C zDLA@C&v`Q!d>r9L8>>|^qxGCC>Omm@5Bw1oO(oG_$WQ}72r+^X5|L�ohGLjKFr7 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≧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 Cvh>+$%VP zUODL%h(WV|IiSn;0rKuDEhwo0eI*O*)f%|BE{MlBsrJdCz;e@f+_c@P*}cfN!GF4# zs^&_OvYxj%onnae(XWYOilU6dW07@M5aBj3M-aDsfrpYsR0X}+HypD9c=y8Kg4t(B zDS@Ya=qh*afu@wc z$HvlTR<3CKybz2Z;JRe`Ei|(AmBz__%M|$p1M8kYOLza{df6fH$Kw!ziz=-e-{mE8 zsHSQ1_D_4*zE6lKH;0CFFe!W#G6d*~ECl#n;oG3N_DaBoLAokb0z?oJ;J9zm-FwUC z(dZK{cAJWr&O@gO8!IwWj*vQ=C&^=j#QfDX@r1c)qOW~X`;m`po#DE*aHVGESaf!) z<81B2=0I4K-hM|2YB8sWkUXanSAaUTK`K))BYX~pyIW2(C^_MB?}3|43#f$C7gp-8 zR`d5l(7AT*)Lj558t*?8Y_R#er5W(`Ml_CmIN#|vM-VS~Z#^&hbYdIwS+)*IW^R(Y z+Z<$0&EeDRqn5Eb9)+9)EDC&xZe_?zLoMv~4J2PMoVAmMoCm~uR&d(8;P z^y^!+<&7-g|FimTcUrjUklH`RdD*k}C#>RyXsFLfRTByF(7*?Q9QG2tjlq*P5eifd zDk$V>na4fo7W}hWp z*v1;lsCz9%uCN`C2E)v+Kx7A^S4dW5L?Y)`QennjQvelMyai9pLfH>Fl>GSsA7?YG1@f#Cm$cb9R{e*xG z*bUa3Iga)SidBsBp~&8vjC@t9vd?$T$$&Q@2yiIuPk#SbQc>w0g+=u)%6=ej0{&@U z5tlfP9tO6(W%Z>I@aD!g(Pm9eOfE-=sZy~TwI8+Qx%CaPeWU~$oS}I;9QMgAqCFCT zl}(`$;3cjB$_g8V_umarA#|MNEr}W}2yIhX+5VT@iIFKS4z6a;>{J#ylU!F*KvT#2 z=zcoCN8eSkG*0j}y~@@3&&1cv&RKq@kC87CDi!IPDVEOD8_ixzg$mgVZpS1BU=$s` z>|}~eIp&FhJa{2rM#K9n_%HU&C(Ls$HdGT6&m!kvQ_DAH zXOXQ;8TxBB1;lw45*z_hEod+y7_kas;>juM+sUqH&?bKnjW&4azuJ<}=$k;flUQJ? z%PdH%%_L4Wzy))5*ztg`EZ46)VtvQDbH_9FmyD96ch9cH@I~<1#F;~X|1rJHtRrM@ zqSgZObTzv#Wkv(CI3}q3(OC5XUP@wGm!g3V|9;WR zS@wf_fDiT2V%Q8M(^|@A{;6C50Frk;^ggtevr(VgFWXmnZ&wnEm6*Us$5t!L4KgeDV6R1K4E%%s; z5R6{F4fi~W{lVG6V7I^MLS_Q#D?!dY@G@*`l_!5h)tF${NOwUeaigV;t!I0+87eq` z@X>XOImb;)LDN+l!O8gXE}C$LtUD5$$j!gyg(5Xy(zD5*`tY(Hvv4Y6UCwU<=$)Zh z;ONh5I5WUg9E_$7_l!JkINXmVMSW|cSy>1f8+CLtgECJZNN(zZr`^x)v|*pibAM|W ze|j#%WjbjeqZswA%fN0u5X7rSnP@4GFJdvxtKTHOWmkDm!-;*u(Mz?FX;yjq61eE= zZ8*Ze;9^zzIRPBOxvvmeJ9!0rLXU93C#}D?U@gK4hfxr@Wx|VCm%1Se)!M{@_uT_~ zqZfI81AZ5D`;=_ccZab0vxoU8@lC>xD)wJx^PkX?$I3VRzuDK=hsL^}XLQwRJGE>4 zCld}KqOL%IIhhqA&A_Svb2&#qAIL@mB4dL|fQP#KFb;l%j_HZX^%F~v8Xh^YmzQcN z)`0rS^PTZH-P@tYxbqBr>9Fr=C{I4l|HLlp^OjW_O(gcE$3a&tCwcdR#P=l@sIwZ}u9cJXIsTn38~tw9(xjcT^WC8lv{ z2Dz=uC5FdN2 zd8AQ#^+E)XxSF1el_AE%ksa5J#A;075AAiH6&Gt!t!rVJNFc|C`=U$Aj6X*vJ;}yq zJi~=IVW49!Q8WeccyIj6E7|GM*tR=Gp`X0dZrBUkb;XwiS_U$h+X2)5Xo;hj`mlYF z4@L862aBAF?wPQMa5si=k zBmQZJYde7a#Wo%*N|n+dk7oTm3Cy0JiO}2TTM$ccHN5eDUd7c{t*b&s2&BrTdKwo} z)EW^jT?&3CR)(1Lq8a5XieP7Ndqegn35wAG2Y?W4&A4VO!Kpi=xg3jH8ScrKBQ^jm zmtwOCK>MaZQTYU94N=hypO|y+Tk)v$xg@z@ z#nR1w5Bv#~bRxI46b9|1Fdr_jwp|s?IG%r-MVtC7fue z<#(%iG4)u}AgxJ$$ok9hmD7>jo-3YLKwpnxijA+Yv ztGJN0!56%{6}+X7ls9X%&oMxhidZ$_4i6cu?t_tG=p?X-;&0eqgM)D;MloGm)Fi)O z*{qFml$(W)?)A->)OzHu06J2id5Cc!9@`7{`%h^6oq8lNv#!M8e9H6PYR3p{ZvEm9 zImfR5KDX(>x8=6o+2ajEB;=&4{m+|n1~ma}NpiTZiC|Vv4I9;2qw1~*(W`>!!wN(a z_G~*C(RT3%?4$K)k}5bL zn1KLxz(gQ_))*6k88}9!KK0;Je-rS&|9^QQ;QRu_0kgvHB>Aig{ z$6r~kF0v8&R1T>-Uvu67a$4&C5T%k@nQ^Ed+8sUVysYG+9uJTG!@{&%a$_r{T}bQkI0$zX;Tig|859s z1_y-VQ8-agN(Hw8Ia8T~RM31AgRrWHqeo=o;}OC7TuO*QEuq-yhbGkzpYHVb(xJwa zOa?LzEKMhv@&Zo1Ju*e7+ef2c6BV zy&jKZBNR%;bvT=IJ)*Q6C5h%>yj~E!8UCXI-1E#gu)-TL?)~ah^X}KBu|FR3>LzKF z6gqR9wze?TdH{HcLQbN@DoKk@GG-u2T|=LZYK28t(1gNXxJV<7BoEDie|XOR^^WHA zW)l3E$5r3w{Dl|Cz3yAYKj66J|D#i<5tw(wI~kX<)knKUrRL~mpF!wN@)vSyuzD(-~8A@mrc}O|`ji0*%XagVWaVP)qp5o$ATN zp;7yY6Nv@a36&j4E(>eJr6U$U1+2bozyWu$#`$+=_UrjT$?yXA9f0`3BZ|GtU~A!u zrmnp(pPax%7E#tSAOP4R04IfAyM^!!;2pol-2NSdElZ28s^)G@U87`v+4ey|LY2A4 z`Q6_Kc(vi>T6|T~U8v8fcTif(4p)!`VWwuwnUbu<5S_@H=$TxFm>|v&Fguk3jSdkH z=AHb;{Y#Q^qq8%PwmRhw(MR=#xyqy#L_JYi18|InAO}!$CJHXzfQk9Eu~BfvI1=Y) zY&@+9vB3GMM;BRNZsFft6}=ZZKc8FZ_7a(@E$uzNOPJh50C!*ZS_7%U&eFCQ1n_wm YNYPRc{YoH=?OCt}Le?`@$E*(cA1%L5j{pDw literal 0 HcmV?d00001 diff --git a/client/data/sounds/thunder2.ogg b/client/data/sounds/thunder2.ogg new file mode 100644 index 0000000000000000000000000000000000000000..4193f81721d4d97184917badecd25419c914552d GIT binary patch literal 38563 zcmagFWk6Ly6EJ)(-QA6}fOL0CH&W8wAl)6(-6^erAkwMQDc#)-A|d%5^m(55eSdxD zo_p?|jhWrqnc3OdxyqK7>Hrk*pNj?GMdmrFYN*jbzWYX^b-_xnOz;td241psOnf|t@IE_k6BMB*xhnT2o3cVG`M}E5Trw&laD00tq2HP4 zqk_9xoA5$mxaebow^;k9LXgEHvqEIKZiqrH#XRx;;h+|iNeF=x>n8}676W?#$Jc}t zIwV$36#9}6fjpFg(+n3#0DyuI^idz^kuZq9AOZaVfFY`i)8|YwkVrC6OM;Amssjto z1AqY5lZh&piQAG%qSi^G`FroY|Hw4-dbADyk?_&N%RY+nE6XLIH17iFQ

6v*C~=?8k(~W_KW}5t(Rs___sMoLyQS)iwd|%R%k-F zzw-cgBM>u+wL9>?L=Gg7L;HYO#kZQXS)hZKC0ENwnj=&1m6RRT%(t84GCHu6!!`=0 zKIG`2WP$Z|bGi$3kp89UYQ27Dy?oAd9^E&}!R!T7v{haSS+VtC3bx8RE=#@^OvyBR zsb$MQ=eazC`ujNO*(b@tets=)Z%)hp*#oAOd-qpzF#cENZ@s@n2FELk5gu#2#DFld zYegZAX+p%lFLu4hibxcaBYrTxXH}fSk3f^^tR_eIkKj;%C<0{|j+)GWA10BM;RNpn z8OjQRMimRZ znJ3w~Ce@`h-OOjx+;kfK^yb3!ul<(6`^L>!JI!3@|GEDS9Taj3klFtYgrS$fWteY| zItAmu!vrT3aKd^0m)~T+P|HtHk4!KrUvMg83#sBrO>%0EKRqx8CC8Xw-=dYm6=vvk;OPzdel;V z`2Tk!|7CD$0C1&#{f_#z8nu)fnD|TGK$K_dlKfz!mU_oDG{O0AjN{lsAVIZU|0#|C zOaK6&4AkHZjgu&1(M+o`YpOF(t4U3(YySUTij$m**dSpMp9S`(uFG&$dYsr^WqLn- zalxz--%j!DFnw^&E(V)vMxPp+1WIq3SZE3?NHiEg6_hKseztCsccZcg)Ka5-FG)*! z`CeBPO{vP&mg)+~l{9GBZsvfmgY+f3@}EdcG;BZCf{g%p@QYmdGXWPOiUR;aC~8Oy zVJRk~47&+xgM2$ACQ*E4Ii{n0^tma6d~~_VSPUiLE5mM1%Bbv4PV$5-J;)zj5b!Hb z&uJzFV9)_;P9%!SoQgO!ir7-hIQp~LQq!rNBb;2S8k&kYiqjgJI(UkjX*7x)ii$Xz z>ey16xSHx|ikkK2W1RN$8k);^n$r#DdRKm0X>Q9Liu2E}V5uAUs^4J0oc=#hnzI_3 zi`-x-m#VA2s;0RP2-#gj7Kg#=>Q7%P@4mdcYdJnlk)2d{?$ETPs-~h=y}i1dy&ksIEUxBsnv}X5 z2*uCP&3t}Va@rkNII2-ceoTlaEU#?MpLbX!i*Hw2sE zI~ejTbT|lpwl`fA{_>d$<#k65ll~%iONU~H+wvZ<#5zwn=j2y=5ZA@umJ-Qgyu*nh(+RrfU1BYG(oMKAat0I zfzU-woS`C2O)Z)rB!Q2X#zjevzOY0^PQEa7Mx3EGOikCWYC20dnk#fdm%gN4MJ~Fc zgh}W ziV0XSr)$^Tli@;N(vu`-M^mD$r@+@h;1c(YobE63l6o~Y+f)}d5R^HZ+)EIYoE#h2 zD-aZ#xEu&dT@LJ(2_wU_wwz5Z2uhx9Mnx?eERdID13@{|ZqJBWF&AT*($nOg%su@VPEZt9FfvrvLPL|6l z+s>T2EmtFfEr>%G1hq3`3K~DqXrOwaO$h?!9_m@{VJPL;;0nbe*>;OL5!iNeQli*) zDT>wDc1S|i*mo&XlGL74YDgu;Noux*DQapqRiNBMJo8+J{ziwxmeafM=K_5Ia0UYp z6hINbdCki}gv|7}SD@hr&aIdXWe5hil$Kzq$$`3&zzH-@|^>ZebIUy=)a#cMeG$0uq%TY<4iyH@r|2$d*M1TUr1f1X;P!7Ri zgSAP(#hIQ)?Qb5MI0B8?fAdOGV*b@bEJ;cFPd(6%VBakO+k$y&a(~+*Jg4^mm&fpI z+5RnMp!r{_BosrA{<$7VTMTjV@gFMxH!tabd1`9^%>$?EKlM`7WI+>@gcoF00x>#5 zO+4cwM0~Qqzx*o-065)m)Zgcd4YOHRP$ICESBT3ogtJKuQj{{NBTW|bBmt|a3M({#f`%asFGeTo^cA#j#m&NHIGJD~;8OuiHe7(3mVOILG^|Hz zp$FELa4q=N2|tE7MleSA27n~f^$n3n@I0JuX$>a#gBtwvegZH80CWK8gT=rcCy@^C zg?k;*2QLF!!{F5fbio5%lu(kAoDqqIwcp0q&mmZ#k@BAl1_tJD3gklo2Ik-HMzrH! z;q&h1Ilsrd1c?ntSKrvk&eG2I-8*+LA8$V|H!uH?ps={GnBe#C10#KWJUxB9Jm0yy zJ9s#{ySQ0<`HqI&C)k3`Z&r6c6%|n_UWNih4Q)AE!mjWqEM&G(`5tY@_XKpCPIgl) zLLRfs_(8?R{}5~cvR3Y8^Bv5yze8&@v=z)~N)Ds7{y-G%&n^IUZ9pB+D+7PX<;|r# z^jggo+6fx)gd%Im*+4!c^$aL1ZF)`3OwHzA$IJQ`8ru6;r~Ai3Y$q#*Jg`;2WE?i@ z_pbO1+wI-Q6&zsDOp#y-#@>^|#Cw&x@!OMG!Ue%>_P8^|4{FiP$z8(m@*!LUj}18^ z=m}_KDLf}x8;vqk5k!kN>o6VEY4AgiG@-HPyA9)&;;D-eZ# z>8;U;fA_w3!3pha*#v09?S7Y09R=5nbmVX48iIjE|p#ow_!+ek}-NVJ5rt24N?~x6j@WwMyJv5z^s)SRIZ*}I#hle#!CgH zXXst10qPIi*+o|(2RD6mw-d)R9i1f?Y>(PWSgdC212N@UO*}no$pZ+3#$Bu@ixT~Kz8eBRQMGD?N1V^yeOgQJf@tKJ-#sG zJqY)Vj6x{J>xC`BC8^1R|Lm~oP5ef5ZjJr-1v06Y6ALCg#zfvz?zjL6u~=NJZiCV8 zIB64Zez@uNpR}o%0Tc{e`=7Gj)vGUslLHOJ!cD)Acr<*1exo0hH7PR1Y4pjpq;vn3 zhR4l<9Cc1YhQkcJGyR6-+ta$;Tu?578;?6 zwj+KX(t+ov%j(^!tydxO)4tG+64h5WgMBmnXx%u8vH?9~;&Kp=#!`~j+GQ2U-h1Eb zEhs6d-#H3zUU~%=O390~Sz0s(!45<7!r=w^6oAWNM-ylF4(|p}`Hm;CA&aU+gD`p@ zEh@$FSA>FRW_Xu%SYwfyMExW@D|d9U)$E;ZNh39kAoBgA*v{P~^N+}lp7KDp&mLxP z*eB0Y(=IDsY&7)1a=^xX{GxIh6qXig9F}rPT;dFGljn_bwfVT zT-r23cb@vRqB~5$tny6DQ@aC3KjzuZjwPNk!))S1b27>A1?3L6CO6yKw5OcLACFH- zh3z_+&n@@@>%_5cjPN$34C4PM z<~K_L`P5|L`B>my0zV$5m1xRWs`{?y0Zw9Aq=cQ`z07$(=JfUFR0G8g#30wXQsO%w zflWqX|AYt;uI+DrkB~?gYo)uCx3oVrMjPicipSs_Ysh88Z?^otPznDe;1_Ft87PTt z7)Z1RnX1FqSfd6E_G319DE!L>3W=OoUvnDwk62}Let-q}62slwZRgc%Eb|=qIuh9P z44?a(8|J>gJ{HG?&}`Fv@tYp1cS4NiSKciItTdUOIqHg*OTV@472#mq9&bPBuMA5I zRKS)D23M9E$+}sh^ScSWv8SYih6|IWT%(#NUcpBKn%6Y+*XNPY%XY#+K4u zkFWeoUL6L7y5(JKzHEn+1?p3si=eA0Y@pi?BL)hb$PL4cSK+$cp@kI-p-<2r330cc zh(C7r->8ZT5nL}&O}laW>`f3BhJmEEoqHSm^f>&-hbIy1>6{__q1&F_0IoBwqM>eL zJ;Cc|sRHy2S!ahx!I>L62~E@xNjB^hJ9Jjmoi|QV-ps9fX1T^Zr+!g3-8XcP`}yBq zbA(+vBpl@$R9@LeB#+*TM^A`*Jgl86>Vj@Kl%X;Ln3;%~SSD)mh~TDMRK4{&Alb@g zQFm8=IQF}ZO^S9skIMGiii^0H03X|2ai{ouCD^-R8J2QosSj8EPG%Zzo}C^(SSc^W zAM$G0Ta7L9gt{1&F4X=z6HdPa%i&F z%dMxN75B=Um#XT5`uK^9i7aKIu_$;2WgLQLRR6t`4P6Yq5D+fJj zhoC=LP$nH1f&Y7qwr^in&2O z^;R~#dy25H(YMYMQF-;EsKb)rV=eahhs%oaR+WnoJQi5pt+VJHbo;2$AxX@^6O!Kp z3pP3LtCPM>FR1dKpHy*li4m1XPBabLsuTuHB2FmFzY>4T8p;9$c!fnn4eXMYL#+&5 z9+3kNkf#ERC1UR-GnsXnOhW0eAdwqd!fn;~ejB1zku+v+M5viMdi(6Wsqf_x2y0a# zYZcSI(iW99Hg;XLDX83!79{VI@3M*Q4c_}DL^=$oZ%JG*xA2E@h$U{@gIU5v^dyep z+(1Ua*qq>p|ow2lCaHg~UF5PvL;p)S>GPKgnw>m_Pz|z2|kv z2)mQJ?`>;yh0d^5Qd#5l%bpV4>cZwf})2u1PKJ(72Iwcx|w+{A4hUPxX(UN4AYD4FP^)7v*lAEa>aMrX= ziI12b4cgt;6psh;$gpD*+d~@@v>eS-pJsLaehhjqMosihm#C0aoX46VP;`)x5Qq`| zWDv8XUmk-hf+7ZlQBICnD1^Jnr(*6Ry(}9h+ov)MDeSrcKzl5w-%`TF_m#s~@9wd^ zI)lRthmv!-osGJ_*{@VH4}7o!l&FnOwBHMqihWH5C6ZiHwVBo5{=y#ra?zdX*JdZQ z?LSF(bn~^UKHHgFT1@70K=SN|hRvE%HR_85{EXb7J4J8cz5(lmGgNMFrC7s8ue2#}%??0Ozqdv`pFD;OSzFA!3 zONqfVs3H3dYsK&i>t;H7zU5kKdizb2qi$Wm`n~O^1ND%T(LrcsKgvd-@>>JkrpT&k z#6n}{{j)UDUrm0ia4qISCLz;YS~mEsqo*?_Hc@nLz~dq5{!^e4d|P2&6#hl{&&3aV z$yP?GC`Hit1ON~%_gZ8!Zgfecd6Z7^1OYR>Vj-u`J2HMF$VIhKc)G%mur#V@w)N30 zEyH*RUE+a|E;Xj_mis2qUjO|5_1mA?zebWb5%2BRop>}yP6lq3u+GB7J}m@)rVXmf z?G}%_OFQ=ou?<_F#CYz=$P;iB$TC&55g&7;O<(+0(GiZ*I27+UJ=l}I^Bxksjm*2~ z{Nc|hd$cZO1B#Amj;{|I>I4oy&~r7>V1BkF{je3tmLha@IG9{5<C- z42Nf!ALoQawLXOx#k8Uw(gNH*3@?fx;>cm`RBYXAIBFuJg1*C)VWFr8YsSEo++gW)bCzHpN zFUHEQK&lJs`9#mj347Kxu7(5`4VER44`OszGkW(%>#K74yz0QZ6T_K0>5QAmbxFH| zlJ*0e*^?+x5p6!L;K$GAP+gS3=Zqws0mx=+sGen(|e| z=Pg$)kfT|Mb_SCMwTAt8mpj}k+D@@5BE6AyF7UIjjl#r&8OH9~4oSKO9CT8BgpsYj zV#lo(|8DsF?N5#0EA`E&*b{@czD|Yxftg_?hCP|y^W)}8Hz=2?j`{k>7iC@iv2=w{ z9q&f#ZS)dTh?imj0qBz;pMF?>b!ZsjLSje<67VQbHYo!4o0QjZiK{2w{Ccl@W^sJR zotv`I^368{JaEJXt5)()yLhQ{JYIRLKl$)Y+dfXEbiC8AFeAXFxEas(q~^;X%Rj+m zl6A8n%iPMnN=qINA?Q0JNOK)|^Nnl^CX)R-s_&b1g1w4pVrViat;y(#REV%LxHjc& z28fDu-C2u{+#oJj@icG{eOQF*CtEP005^7k0oG(ZQXike?dlWqRWsQ@sX?nS`5is~ z)a{Lml=K;^tkSCh>jw2?bniQ+W^Lsw8%V|a>d-@2bUL$uvyDlZ zA{6GQv)BSE30S~ID3Dz-&=U$6j}!oS0+E47#=H>`v|-Ywd=-w9Y9G_a1{-svuJa{-_nvWx zZzYV7`R>~5>uHQS`%d0M)YnZ$dVu!e>{2_SL2C;{TH23a-r%t6CLn0VQDrAxvOEvx zsW>*409yQ1PP-u60s5~Y6d~wCe^HXub{bo!j8!t-Vxn5o#^h%B$DRf$?0fsYuPE`7 z-XTL(-L!rArBNEojI5YtujjPPB!Bn&piF08U!;qECc}p2L1R&a^V&^WU=iX3 zx2pviuA~N}0RugOZF$n~k!>JH&P5SFb;M2dBZh1b*`+mhM{>9|}1sxyrv zK=vnWB>>q+aAwKLmg^Xi=(C)ir1!@2zl;2n3COMMd4$o;ExdXE}cKXBtfA z_=`Yl5bas1V){z(oYx%jk&oWu7`G5+Ix@Dv@jL9mj{{i}89}p;h55*5?j?iDf!s#S zbd?23-I{`!FKl0y=^z@IQ6Gq=aUc)AapnLV&cH*OuJT9Xygd=LZisJT=?ya`PlHQ! zw!14-mpnF>C>9E6M(ew@9XI}>IiK~@OzXgr%`W^}eD#SuYit3rPymW6i0TV=4hwps z*2v4u^Vzpjn%H$l@t&VPMsDH}Lcg4dIpF!x==lo+q8SZG@d@5iMaT>&5Z4!l_dkri z34pE-*|0Btg?pW7AMd^2A2(9D0FwaPtblg1h+^D+=fg3<{)&}*hvA5H--uhEPUA~) z-U+LoPI>d}3JbfG*mIj{(gLAfuJVa{ANp;Qs#hqoM77Kej9H>`CS%ou6q-C{)Js26 zoq~u0DMg_{T{QOu*h4_N-iOv)Fv$q@vBo!GCCu}}$b!aDAj{r{?vRFB6YzXMGkPZ@s-g8<(mVcP0N!2`JMI zEA-T;m_wj0L`&--LzN zJXfOqW~9Cyf?vhtjppN5QtXL8#Xdq!4Pye2Ziop-J)*cRMoHzaUc>z;8O%Gha*Ft> zgd7aHLafF{Ke^=;>?A0_rTmcj_Y+_NPqhqVJ92|yj`pQ)#Q3BifUy6-5W@n^ULbnF z#{cca)vosVQ&QdT$|8%$x9rA^@3-#72$*^38J1Q@Py}N|q}@bPFN2#(g44v(Vse&G z5HS!j-D%$Liz(5hL^2C*dwQb5|Ufqy>hE-z5|yWX=49#MT0sl>72_Q^nSqr&IQ5ePS?Fx|V&T+M9>rS*&vmtSfThDwEr`BuXb6>6;juAW@t^?~n!z(*LM%MS{8L^c2!1vCl8M{X_@ zW&BWlc;luQzlP@}j#meR=lQc#XvsGZ#qI5-^56f^;cia5lzo)l<;>;P@cqQs`HuS` z0sDtfA=OA3iQ=2EP1}4Cw9=8RBm4b>t2Hs{k1=yEYP?CsPh3!>AwYQvap7-GGE`AG z>sMX0OIXi~R?ibq3w;-!b$(quauSDU-yMkpn8a(U%!2_`UE}p7``hh;HWP2GJMR${ z=im3M@op@~?A3j67W$;Izl2`Nke@4+TB5X;gDtBOS$=dX6=0UotFb0Tg5D>`5JxjY z2H-9x7{PG?Krv+P6B8r>`U0{i9jHZipL_NMw*lM@8KDz+NFF9iuqJWJika(xEVOR7 zYifO$Zuf!B;p*Daz{GddRI8UfpSVm}yS+@wg}plp)HkU$NJ?)>ry?igH& zSW1Me0rT!B(T~JuVcr_|PdT@4z0=rK@f*|;^bt6S3AF6rK7dW6j_4j*sRsUh{()T~ zrtnp&s6^OhN`2@BbqqcZ)vK8^VSQuDfcsb!2B!t)50Rb}%YuEp&`q1S8O$1`Op?o% zG+9BNq9gbXr+#nhg9JQ0f3cS5=B^g#v3KKJ2Yv=Lj&n~@J)Z;Y;EXy2eO!R zv_-;apfnCcPG1QFP=J2dx80AH4C1~P*zkEe#fj^S@EV)3ry-NG?Jy7^?FF^xA5zn0 z`E5Q`*pVm1x0|G^rANm;01OZpU{94|(WTX1pe0MPGXR+F3S1#P3SUD(1I#*C$lQWY z6^R*@23iL@#)FkZfa|e9Ep|u1H53%kPpKrZlxO%RCZp=*b&71qEZ*CFJzw7=#pH@Y zAdu6`AJ0(7#$6&V;@b6%PI&+tu)yzr7C^BHJgaoQ^(E)q&B5m36~_Vjk7Cd|)HWfY zwxDRIygh(&0-F;#W?5-f+bc zk1HEHw|$t0dyk6w#k|1;a5f#ATO4OxYWW`AE3{kE5+oYyA4IgqlCj^|I4?yZEVu&h zp_~ACo8H-L&iM(FuU^KGOcP{k*=JMewYJFRMRYH>;$%QfjoMQSnJcYO@SgF39*uHd z;fnIM*EF~8S`qeg1P)UCVj1cOw*+7Gt z_~a&ElyuEsV&rVkV%kg^g9KPJ4>#(53CgLBAu>TMy68wSl#79WU>d4R~cX4vm)zMfHigQ`E*Cw#q4Q+}3@|+Ap(6{`t!_Wwh z1376E_?&{ALf30g1ZNH!@XbTWv6*rQHw`YV41~pV?D>PO(Y#uWL!Bur7s?) zq&;4F60D>B8Sj9-=sDAlwk4-I?1NFZEt4a0^m2dU)iLWk+jmwtOwO8B_bEPV0eMUl z_CiC0JZOCjX6<5YxDL@O$0b~eYqgDW^Q-eA{Zb<)V1OdLEmC-g*5+7F=;63%m$~Id zlDQ0LO9W~c3={tJw%@ozpOHNl7w@Lu2M9ytS~1)ah&*4Om*K5m78-XH+M7fTD_~nt z$0tSfWx}u|OT8pylz3r2wpw>7QcBGHg9_+m0b;O0D#8E-7|ZI(RDe8yE4uy*+~XM7 zbu@K~9(6r{X0WA6UhE1U2Z?Tkgs4Th5d{R~@fogs`I&=@nB_(1aOKghG-W0tO=)k= zQ-^2+XLRx~r=_A7s!AVF*G-GiB${KJ9x*vZ^>$LFa6fPfnBD?vUA>jg0xw+m$oIb3 z!wVYDe+{0^SHe3)$XjH-4Uls9ZG?0^ndZ&vKS@UVx?#D2@7xTU0(%J#SLS&e*Yc_& zr(x#wcwUSA^^;!iXnqL7$xmAEQ1%(U-t3qYs z-ZqM5r_TL14jooot{w!@O7r13y_-Fa6+O?@p*IQT4ezMG7^L3C!huTlx`{}|8fs?Ui#;viLgare+)N)%nMMlJe^oxd@gETU!@X~ zO$T04>Qw6Tsk^XiL<+3`iLKcGa!*6kD^6b04$tzKNkdKhjq~ zMqb{(YPE7*{WvbN`_V|LE_baPJb>p6-36?ce#k-zALe#F!F5Bfh!13)({;MvFNrzE zopDI8CYXV|lyn6Dl&GO{*Iqd@bf|oBPQN=5gG7p z8*={8prYPZ^_k2?!r54IH#m%S5)OI*RNR5xPpx9oZIp_R{xMF;u<{M^_j+BuLYe`6 z9XQSlyx&#JduE40S0nsI3jOJ1+sk%M%ox1)@I0T_*Ry84<;8RN3+lvAHJ~>J&T7|E zh2#Rq2mmyw7)4-ZQGcmZRIuxzp~T`|@O8{m?rim|dQ^%+%Y_0cSMGmmwWsxju2#}wY}*H5TO|3nX20`wX-b6X{n{MB1j;# zR|~8GDc!KAc>lYwq0fQlh=o}8d&{7}2d2+aG=;MFMH?|{F&dJqS=`IXyk71iRUB`^ zw4maA23y|iAu|+b(<0;NzeWGbKmnVR-Lwj@dUJxhmp}M37Q!gjir&hkVgF2A?==`> zkv}D5HPbIiR&NS1^TsO|4FnZcXlJ|NboZX2h*G9SY1UEKaXV#LdtmUrM9Qu*S{UxK z*>}{RGVvkDFm(&?YDm%A9^=LGEPUPqz&nykvIcuU9TW))RJby@GcllxRt=JeEWFlf zWKzbp47wxE%eZ@HqKhmU0Yr9d1h^#7yAKe&=Se=!m(X7o9=OUCGxQhNcdz}^$is<> zHy|N?=&4yoWyMqUhcc1*M-cwE^x;6>nl~5egu;Mi zm`Fw;<0+x=+m2oliqSaQj@77g27i)wufNZQ2zlfHVbt4NB=s%Scdji0{f9XcsV?Bti+^zK$mXk%0i=IY415#ei?;a=Kw= zQIM+dNq;-N*Ud9Al+H?-bZvPt?j3G4zxjBSNWQ_GfY~q3xOlK1E0HdtGNyGv{%`Y?|5>y|;o8K@MgYH(GlP)nOInw4%lY-(0 zP=NYZ^qryJhEVsHg-5B{8QRzL&28~`$;0&~8$)&Q*RE=CJ1*G_m0B&aL+7>Wtxjx% zJz6m5`Y?)8a2xt)v2DIr>;ysJA4|I4Lo&3^Wjxy>Ek$(TZOTJf}vYJG9w)IVxB zdYQ*vF8X)l9C6QW#rkv|yLERQz&PRkCp&8q8o#<_LRKcIOg!|kMv=7JuDiqm{D+5H zU#~=Kz|k5=Y`|;y3I9?|73mj*kEmymKo8I-+5vC@kHj6t zBgVV}PS3Wo3}1x96f;XLBC;6^9)V0SXeS%x3)G%G4E#zuShYUFLfaP(fI$@O9x-72@~al#kOxo`y=nOtP0mQ$1zGOc`+eC z>YK*5O%1VhQF1$hzW(2KDT2{03`&77^$DKw`T2;lUbHw z=b&;vwJJC5nPrcuMj%N4HlP1K-4@r;Sr`4LSmSg^;m%<+YAQ51lNaNMiLCLHv_&(a za{25RIz_~xbbT`4XLv6F;YIz;fXH={g7(yMLc=kaSF*>vEo3gVcm>6EVz5bI9Z|zL zsRs6Y8+ONAQjhpNd<2-__KLi`C0p?nhVR3qOPPwQd)euR+wEsvFI~&I1}9lv9tn7l zk!bsdomK2B%@G;Jll5m>f7OF5qzsVh~ z7v2|+OYfPoGc@Rel5GH*b)nn)c83;*`iU3Rbx}=vOd8TJ3MnR=R-MK?>X9oaL#3`Ab>Eh4UG;xI z;ddfPL_9&U`u9SUy`Ci4GvC%QalWTv?~NpuR%_P#7<|p0C}@Xc61Hi~ zL6L<^aS1!G(e}Ye-y3)jkA1My=H4U_B!4*v2MYx;7$RMMg7`QX-LHMJ@U5~qT%s;v zg$5&ZlAxaPb=getxswb;nHA}y-(54|TGo~AUC1Zwdq$RK({Z!*?mM7d2P5Ry#97z; z!nP*NEz=Sa+}WV-*7v41GGS`xif496)rP_h)P(>afItX6$eN2FLf9pN@;mF}PYfsg zRB06aA;WWlL4SuAk?y@lb3t&$ypZKs&-QIfguJlNPb7IeM2>g+&&MRy;kyK{?sg5S z$*Nb(O>L}9Dck33Gx%DUhfVlif~EnEms2%vN+yx87B$d7Gz(BEQ2+zv**M(toE=l- zvrOS=0f4m+L=ErRf(6Yw2rzs&xWo)gSzWBJI@Ot@Nx&!sC;Nof62aj_sm4gI#KCXq z(>de4sgRua?(5$BxaE0=&IP{)1(M-PPvwRr`bsCntribnLr`hF10%cv14e_59itP{ ztzCRDCdFY{TA)TCQ;{Gz2rL5#P6u>W`AGTFZ&rS-jrd!+eV?=~#-It$-CeOkC`K77<;3Tu2IeVO3wxBBsW40Ey{=b)|Il)j z2*pYE#Gf;0@OVi}EqdxzeQ6L3jV&^`AU#_*TO|+EnQ@;VPZa`^R~!%7Pg&n@V*0QI z%C0Lw7^7SbXhF`9P2nSn_C3b2$6n3O!oXhfOYC2+G^?ps$Dpc~P;7j`s)YLp1zZA7 z0Rsp?hmHMCKE*XW(}jp>D{wlXgtXY4*j@({s1RoK4<+VDx?OJLRkwU;%Zy|*7VsZ8 zd_}%7hlTKI+T8CHm}{yhqsFwqYl&%h3ka-uO~}foXq0g&Ot{w_+tLb-ST-93qr$nD zLufKs4nRR!-GPfl# zm_edd_awDjX_h17l5bM>F@At#619r>(``^ibUf&0rD0kWf15wOq78?CfKqMLZQv+? zg-RDhprY0O`e&po7%2xAs0vxr1XRos43G^bIum9gm%E5uJzAXSCuSV>MrMGh1py51 z-xZjIZu3Uk;6tM3?nl{)olpK3q^cM%m84$4LCrBf;T8525YcRfW~wLgI#&F^Hs?KN z>ayjFdh2P3QC#y!%J|1(oYNf>0gvgAWho+n8*qZ*0{jIG4m!Kqp|8P!CJ|MRH;Z=m zCkQ~lL-4ar0|28`?`AdZ33^N2h3aJeB8cmW8QZZD2%Lv0GOH1*Vb&=zIQl7Cwfx!9 zn`v#I6oQepNR3J8K6^Gba}>dviw*4@-M%mtbET zGY3aIBkR0F{lO==ixW{F@NnIW{VNIzt!p7;2Hz+gw>?Ryof$Pl}_Mnw*w7lEg z6L3z`pQRy~Ud+rst*o`*!rfSf5;viv_0jWfhz-%UnH|*%wouiazfSFa{l#`4MtDMx z-J{${Vj`eF`-f_jgdg(()&^pY>-)~eP8YcOg(ODt(r63X2@3FUQQR;@xwbD@H7sX% zlw>ePx7IUi1l1>gqS3S2`y=w+{&UrcOD31?)o)9pWcNfc@K4jVo%AFB4()9rMZ#)xI2jf_Vec|)$F~TG-KvZaII2G-vn~_8UtV4h`*ffg2 zHre14#df1D7%kJY?6W`GKsDV^Mu7NyO3robfZhpH$Nsc@vl@~)cUFn}nI~*^=rtde zvTEa(oz~He8B6;(K*7_m)O zKD8FiZ2ufOg?-nmYlrP|M8F3Z2xaT>^{RF;(xxiN^e|B*@h1o4&4*xujUH**-?Hh+ z$YxtnX2h(95hn|+9Wa_!r6kR|9mZ|03B;2QP$+`%g(HZo!RyE_t7 z|0}r~dyuH!F&%9Z_9>qS@~%6aeb(zp9K~a%OEZ*26&pkwf3cA(Ay?kjkfg2$)fN9r zXw+Mv)N5E6>MTMGspzM4=yfSvJe;kwX^Wu}B%;^`h~jWNpw`HspmbQF7Qur6An#CU zLnNpU`U0f2a?QEd%r8U)WFYg`^V9>pcdm%GyoW>F*WEt!!hMk+^HisMOmw?hS7P|N zxK3gBXdFcOUW}P+dAJI8zUbygIia>ON}q9$9iziHDc)f*@$KguC0T-BSpw zq6_Y}`>#I&UEcvwmaZ%8vU*eE%GRSGatL8FL~s|kt@~UAkO4$toi6(yKQc0k&)3xA z%&G&N+wdKTd+-1vV1;(mI5X4s0^{+@B8`Lo4-X>KrjIY(bA&nxP!2cBM~_a}Z0^iW-3z!{7k7Xu#V zUb#Q0dzn@>eLn{;isV2&_Y*6^mDAgiAZc9qkQ7kZjQB+c(a%Q)kfDJAZTrY7|C_pV z==IyE9aj{y{oIb4)Ri)G7*{j^3rOg=I8EJbuJp>+zm|a_I#4{z7d`Is2mM#D0Kt4P z4E=r>C_Dg=GW04~QpR7T+LyXP$J|k{{%&mLme(Tx^W)Irty3@a^!+S1qnoAw{u_ox z-58PiI~-T_-Nr21?xjp6C+4spI|y!-cWQVfzoCB4?kgVd4EhrklL9uLVMww7e?IW& zy*%PrKvwV|<`*TBtn01`l0RAfn0A90JU6HNVX!E>|ZhZ1}+!FXS-Zf{#6IT7+ z$z)ZClU!8MSDv-FyS3w9)t)c}IgH1Gn!bQBF>Ncu0+5GLyKQ;1SY3$Fu+i21@GFKPtCe^ZxWT3*9Un-5yIG zd6MuYaKGR~mrPNd>38t4ygWWVex2hvuzk{smbL1;FU3y2T3W$*92gX_u_>-J=%Sc` z@y#FC1}KM*0fZS1Ms~Vf0OfLqlYI`!P?d-lGf9l+vDKj8&9H7G=#7~_kjL*%3ADGC zYE&t;Gn(!ZYNj*|bF&S4dXc5%UA3N!Pg!>jRcQzJ>|^1(AK$}U7*rM@+?QE|MNziS zL409B6O~waA|PQI9u>6uI|}Y1311vZBLFEVSkH)nnt(5%nI|l=2lLrC0#YMZtI2P^ zy1Q#b;fZTVMoxqn6y%>Un+Ut{tonPWY<KUcsRp{JpX8??KH zCIh+}p*z6MQjk|T=@%+>TI~d(sK962V(!PQD^A&WW`wKFiwl<@t0M@wA;c|E1?%e&1LVBdi?oq{`n(EnP322Q9SFD+ z-%5Ms3P{&rku~*J@VU^l`g3)lkOo5eni3mvL)J)v$A#ma=Y!ik74;>$%q0mwl6?eq zyuXUOp)z3Tu%S45jG81^VshY2ntEcdXxZ`8D};qraa@IJXcGnNCw5$F8FO|Srh&(xWZBF60n`V9ZJkXsI36(ymxz+o znbm(CB0!oW_4XLIF1%pfxT0|Iu_63{`c_defjFAl(hp z-F0YG5D<})?rxAcfP#e5NOwyrE#2MS-Q6V|xEtQ@o*%$4YtNc^=9yU}x?@ev zi%mtj<~@gT)J6ARLq*>URwYpV!JR&QE#_O&){fjPn*k5#7A_=;D-S99f#!GhN9D>k zVF9~O$r2k26gXIS9Ty9gT^uL7pPWu(4&fkyMKFz~ebh~vn`E~-=a}c^FS!Tu_9&hx=~$>F!AMK4-ndn+}sKLO~JVUbUhc!^dO$T zunrw=u?lyR8F!78Qs7mBu{4M$rO)2Z#deT8vi%6SzcANv&ls{?bc`3weHH7fzN@#- z>Y2NOd>--ehHuoyJHH^R$yd|T^x2l%=T~NvGcye)^JGYCTjx zR}5W#P9a^{V4tH10{lQQV?DtJT2(b9^fCd5Zc8ZFVs2vSMJSs|yRy&D*DH2%LK`@| zYbIaYRxB~#BLe>`fc&`_OmA6?zJLLAjqj_AczLayoMJW7N#>sHl5)Djzz^eAe8|b= z)Z?e1ks^kKB6^(%)HE|MT894Rd$B`{%vGX@u(pY!M3M5soh~h=gW^S#5IIFNnUY<^ z7jwWwGXap=o6@n_T=x`g5c~OrFs0Tz0bhkVYTrj3gkuR>y)&+|ry_Bv&?H+!f4}~% z)>d7QzdC#Q!e32XfN#V3eMHh0XHNs}kjvBoh6H--)%CaPg;rjtW^Xf+2#wtOcoi>^ z%TK=meMknFNiP;Q^och^{cOD)N*Haq-VO14_RzZ;Y5#{vSj&C#;Z{<@*S?&;$~_CV zFFX2*A5UuXW}I%~Zp+HqE_ThJxPfK1W9E8NKnou;TKK@%LJ7f}Yrw(3$tRwh?eLpK z=;l{zOLPNDrt{h_s%?CKzmNbB3=n|Sx!c5ALMRje#VFQ)N%x{q#wu_l9_)4yhJC-xn><@U5<&4M(LMKBJ_`G_WLGSopL_jvz@t3u zU^pxm1N@L*9^*~30#D$q%YMrJ9gOE7VeepHmlN*y&{k}|x`!8{nWHeCm(a=fjjPJJ zogw*10B5}^!h(mZFYe$exBuEds~hDX)V$*}@gamZ%7FK+X#3{!E!^hRAOHr?cTA}X z&XkkrfanY|h(dy-wos)9u@oxSQX3MSIiHAc`wn!F39ZBl$}HLhjh~cGu`2%9SUWEN zGOHuo<3(;lvT_kFRqYPx5xOl#rI8|A5S)65pNL!g`X*d+BoNQAQ?i z`|HPddeuWuEuA3^VD|`;4pFg9=Ec?(DHsj>qH~aWHg8RL_yz9yGZ0iN6dkieA7XB~ zFO*e0DQ$c0wt(gmU|I#xja5C(nrguA=a@i^c6;MY z0^7OldBcP)RHb3`HCcc^u_SsYAr{3q>mT?xrjd>xqph}BKYNgmoKX|_ZFhRBBq_>N z_YM##J^rgjApE8W!RFUd7fLt-F7Fhu=|n5vd~6lZAH+V6^Mqv^3P{cT`M|Rm426Bu zmQdJf(P&rln6lp6jwFWrC%6OrL3qSPyyqIankduARJOo8FHSB2t|~RqJ9CQ7x8L~* zqw|gP&lWM~3L$6TsTu4T>~SYR8MDNQ~%yC;P;1o#{0YGWRlJJ%8yIt zz?)#cUyp~kJZR~_027IGn*G=4m3WV0c|s)ezT!^72W!v2Z8p86m$rmgd5`R``Uy!U!vJeWfVvNY$ITAfQSyS+kR z-=LYc_7QMvS!!vJ(%as;MC222s5a}eOI^LI8nKSY1iVSaF7%d{;2!HLNxO!qqCTvI z%ttYR|5Y*n@2X?I`?W@UCpVGA80pm!WaM5~QLa}WhSmM8?%oNLsjI)*==wZE$#Np? zV$4zOI>$|pjzf5+zojUAllFq6SqAQjbuaX&;M^iaL1Wk@-9g-h#1X?qB%p(^IJg=@ zkY!0YTf1*`qbmQjNJCKhX!LT^s_E~ARmaP6^s$wj3_Z<&_sj_KqC4X@;hoQ;Wz>)p zy~nVss0_a;M5%RI78jMQ{NS?!?9u-Rqn?3P6!?3DQNjKpz%LZ6&S~cOotoU$#@Gtv z;u=_hpsAyYv4yFHshN?biMfM~wS|qfqlKlFmA$i_t&Nj|rJWebB2148$xZpuJJm5K z=?GA-8z7){4`V?d|0r;@dyppDPy9ZySc|uiHjfIv$HYUKs~#pKkt11wV{m`1iOuQk zMk+ogHCU;VmcP63^-``*iA#>9gxVFcR}jIs?Famy1<ZA@UiBiy{TCc%y7`N z;Q?b=!AGj+_Jkdg0G7saR7Y^mxRdjc-T9}o#gjD~kL^&OL<=32r3JT=vdyZ`spO?2 zziP!Q(CJ!KE>eP|x(B0r)~SJVUf8n#a#sqXmZNCe94jvTL~7W-*>DR+@%ZhXpKqBo z$l)U1-4agX1NQF;O!dPH1)~n%zZBUZ@oKAjfO`fAz?1Wkvrt=Y_IlYh#==hK87#r2 ze+z)~j-QxLv+g@&Ww2lQ8-sId$H|7LZtUTZ3;`%b7TPU76^CHjKl+&R6tDZM9@RmW zc!qyoS-QkD61mSGyTukvCd_;&F|YSik%)F5!9JH!S8t@7u%WRR{W_z!@QUrJ zJ9N)MuYSiC9umXEtBXJ_yH{6$Cx(e!b*7_E-E4b-%Hhc6=IebIU2{?r+_u8*(8zUTtGg8Aq@JU?1XNXXAiUl=rH|80lIY?66|(Lqg} zYD?fKvU|>dYHw0F9ko4xLSHq;ZNkT|SG%^iBEj)O0W`AZFoee2hMlEmZ(rEA#MP|2 zEh3{3Dz{WKK$(l?7bR$gv`c~XdAWL#;dTbLOAd81DYE%8KZFqE(q8Ibf8IVi?18 zRApWBHKgLmmHLY~g+6GCk`+jM#$!#PxW8Lir4O~psmM%jm|8N&^J*jYY@G`>H4+%f zSt$IvM_Ss~1=eG6=Wqo-T{G~WK^D4YHXM95%=K)@r` zIHeSfa9X7Mz11SLTNy{&XClLcp#*VJbo?^13d==!60^Q3XQyk2XX2fb2vSHVSGF;<3yjm&Nd)_od|CtyIk({})haC(Yp!2%Fj7)et<)R}e5N1RG zbUY_|N=n(dI>%@B*_@2)W{r=2`3JaaldIg9VSGuA`s0OAta4ZB$=P`yH4x>bLr!8e zB<+yTx*STUek^tEboY_MG?(~AR?4$bG)g$JI%uzwz7Oz_aUv5mjf-twXQBH%!oVDC zvVi5Fb=fR0+HE7}*InW%hj^{U?0zanVqFd*EVjILpYf&h86^kaadgAqMX0CDKJk1b z1FST{CNCu%iPMh41|#0}pUMQb3INOC+7lA*PCd#-vd7|mBIc}BA$)(5C={`t<8hAx zh<4%}{2VHWo#yFvWb2invn`5K=-J$P?R<+P3UM35%J=-hToCdb+eF=l94%He;@2fk z_kpK*-zgAq$t^u??fmN-a{9~EBldc(I!TR@#9W10CL-OhNGF_ zmS29uf7F!}`SSKJ`fZIRLB=2HAL_y9#^3VFO+p8=_ZTtL8=NV-Dez6Jc5Uz!c<7SzD(Z#77{6rJyAr8b9iOm!vV7K|4Ua8foa<3 z|Kjk~a0i!MGFAE#P{#7u|3xM-p9Hv8`)xRj>K*N|pfrT5eEVb+Ipk%gVyLVAb4Pq4 zMO9lbf#7qoaS7o5FC%ywJpk!zTG%piNjE#3P8~4*EcMOeq*BP8D^3TAilT%1t<`>{ z->|Dc)uW1lZ^oE<)Vy;ZLX%I(&D>JM-lXsqbbn}ZZcy`TIg@vn`|>nhiPyJ2&b9Tr z{c!CxMweyGJj#gPNeVy-=~}KJ>0C+0{e_IAdkdYQ(El%I*%cNxC%y1jV5fZw{OLWN zK4;b3eN{S1;b|UTO%EE?(kmE32Wn`=ftVtaY)7d%@CNvc&dMz^$h3K(*& zq4-g27sPsR`trYA;lcS9!vT%j-b!hbR1PRzpl9?^8z1?aWmN5HY-R|TVDXeN+mren zjjaaU-&D)7;Eb-6!%?0SbTBDX4E;!L@jjWtX_>E%&-M$k?ACir+$CInn8=H(z~RG= zrky$c{7cScLV}(|_7r?PzizMS0z2(dX-krcqJz>>g#)2vK#(rslQ#NeF7N8vgeda$Eu|u2M#|0G}u#op0ZcXsBnDi#x&OY3Rpox~jFDokzU#mTE6VIcS(sm?N znrF-2(U7%?96vi&Bj1DO>b<&+jHp-5%Kdwk+JG>=)j%B!ZvFy)!yM~6LztdkU1Yx> z`0jJ*^g=t9YlKHP)%O3g{yN3Uy7t~MKL1%i#fgEg<*G-F!|5?}yFzv| z+$W1q(v?4tBxXFW=k6GkjHMIQ!VeuLM?NdM zz~5~KE(FNE&fnDdB}MvnY7X)YHwR=pgO$CQLaXFo&S@TJqtT6@v4h&LD}p{ccfL4K zBe618t7T{#P0z=Lh88TT^6l_g&Ch5X(uk7xUh4?Xl{H2<R-tN{~5S>JcW&`~fJldwOoFlu7{csZL-Cizk|YKjxRW#j%S(2=Uk5h?jkReU0v)A>mqSsoT` zC9m*1?fE|rUW1~NqXZ7T#Ln{~94G4fZFA$XD(GeN=VI1D_{MHWBV)Nr#Nl5!L->d zWKU{ND}5&B(`C<^rUdrqWpbPPEsjYa5c=bbAE{StJmxNbWD`)D}Y*4F+IqC31N|$;? z+WYmHDr<;aTB!a;VqQ-<=aEXGT&idmsg{{~doIT&!93loVA|(42}r@m^;q~rKL?f3 z0I`42PW~ttQZVjO=L0|j)sqz8DZp2;VCapH`uBH!EbM=Ol@2W07PrmKBp4NIT}2(^ z3pnI4&_W6r17*EgRu}MkROq_iV>K2M*&G>WHL4qX&5YUFc%~=(=5-Eefuno|5W(pR zdH-XmN?kw(Z&TDWAVTvwI9m$F7d`b05-#No!b)JQc9hzIB9-k%h zHiKdl>h0N_#S#b=_LSLh{6&e_qcyS>w(Ey9iJ{ov2~0m8UhEWFGKLq0QAFf^Buu1) ze+K9#HdNYWYu0^~z3r^A7QE;04VIiTQ9!)sU~F=HBo^N{s_MR39Pxe;MG%ifTO$J@@D1fBk5 zR9+%D4k)e%$1n+0|KxbGOB}V)cS2|8*jl1_X3ey(Sw9G)8Wte3YW{7N(`jy= zA4w;80Ob~o6I}Nn?f{1tL&3h)E2>!Qy?^vAbWgX&vr)3$^l39_cTOWZe`5vS^Oopj3+ z!O{Lx5U}Q%X{f@~Uy=YjEvw>!=+g(Zw;Wi&=w;E9VPqSzn80&aK-sL)x@y*bY)@c8 zPtk%RGrvts$or3H{6f^uoh#HtXp>iT`Y~e_F2JT!fTx~})dP!RT^n*xyDt2DMbnLW z1E2%oicPUu=oN#qu>51QcLqP>g3~XapVs$fmffS5@=dl9xAw5%8Z$3aP7)&sw$4V8 zI-4o4PvMMW9w*u1xp1k)l;g;v#FMW`AtG#awarn~vWnTb6XWxl>SEwuDfg+B+a5$r zMF!xSWmb5JmXU$f9_UXLWt1S01yuq7<-Z7k1sBUlSr9m&`$vPM)@GP_Ah@u_v%pV3 zSyf@ruP5{Lle&jiANPea_1Nt~xF6in@0jmQRjf`&QiH+y5^=eW&!UHgbFN;OSdn6% z$SG@#k2<3g!*L=!J1#h`)`AcM-~?g65BqCF*CyE7<}Qls%lK6?DALAkCV zDf~ct=NjVbvS>8RL6G|A-0}6lgLuubmIfLmy(D>#%$U@k$Z#l?ePv90*qh*Y;cLfs zPPzwFqY@+8dX(w{!p0JZr(r}2ys^F&AngDqmZ~x5M$&-;CT3^B`yc1r2aAL)cM&Pe z!9p9<6}T1XbXP?qb-S@vdJq_zGbC-*obE`np6LoxV(M5|o8N8-NNFaK=-#6hXi2%Y zL|ce7NXJ9o>K{4!qa)*WCEb$yE0Fzo`b@ z_0L+Vm8NEkxNC}6NAK+FKrJK)Hw>H>XAav$C+|iy4E$)Fk4nTif-Gd%V=(f0$c@RE zwX`|K(vho*-}Tnt(OmVCib|NY?nCgilwb&T79eK1(5dw2>PL2mcut0H$I^GBt(?Iy z8VDc275zk%O?TC~WKlfpTjFF{+ZT1ERWtHG?U|(f(fj-(u%JwNa=znPzJ9ztO)&r| zGUutuU&@V!nRj+I`mrwc*_H;gipm!s`W`XQ!Ly~Os?&smVU4_Yp_d(N=yCPI-=!cg zEaQ1=@{F|qf?D57VN8$fshi?^T{5U68I-+?S(%yLoM%#HzIX1+#9tipMwcz(ViSl{ zgTBGWY?QF{4*Nf181|%+SL7Sohc|`wp7Pq2I4o&GN`ytY==$g{-fv2~UYn1vKL3qAOK#vuE5p1r zI6fG*d{~f}-%|A(CEtkdX-{|W3SjPA__U#TCQ=hUO~J%*3l0G_~_bPGqX@QTF;5ppZbnc|+iM9Ts^6>Ep>hO={3k(gtf z{MJv5>UlUR>kJO>kbUgmooGncb-me*M=ZV{xsKxGKS0|16i~t#Xw*;gIa1{RX`H{G zii0Qo@zMH47cFtv&FyU*og5q;zc|@A+q>D@+SuA#SUcG}SlOF7+dH~C+Ba}Le*zT;a!*{ecZ zvCWb@=KZ6C<_mfu?^)N$jGkCGzu>p)9B77l0bU&y85^d7*rnway?K(+nNr* z7ZQZh>xav<%32-gUaT6SBqKGCHk9wNiqaGfVJe18i92nWysNmpj*l?F`73g)ejw4u zvc0G;pm0e7SZg!;3WNDt0W{PueM$fN3)qXtlp82bs?&-m`ugng(?bmJ*LkCem&y*E z`7T^l>*oiZ)DdW+g0+lS76>p%4;KC~eb@AHpPTwMgq=E9srEtX?*aJI#mhLu&UvdX zA=EtTmK}{6M%iJE5GG_-4}e437lH+(dca<>)1F~Bix={U-Ab8SCa{)=seVP4XP0{Z zD7Bf(g=1ehyVA$;JEn|^Io@)SC)_BMMc zI<{K>$Co7Pm)4C+A)ntlzXgbYard}wKjVdbgVX=xjOksszygDta4Q0}Y;|(!#3q8o z$r&Rkb7`SIo$Bv3;WNv$twI>=rg-P{+=-wEBhQ;?d+f`!KE3MMhQ#QNc_q#3`!@_S zJE2OyjO?W4K5~#6TNrq-{Bz@ahrn5T$Y_Uy#hOa;18qRG7TiALEd(=HN{1?=hQ{qC z4B!^8fi8ZWo)PXzKP}Tzw^EgVUcA<0XY_|^)qyOme4X4nhlO6)As!tkOQH_8eW?#n zui`n&XCGj4jB#)L!LQBOLMQmK zgyS3WEx)JnO|sN-Z-@+W*21M5%iBD5%m53Siv4{5H5Uxd4L1Ho)Kp9L)tbBf4(6K^ z&x^lkKOw2yZSyI}ISeX;d}`L=TZBj0g#GnMn!Hx1mS37a{1_05qP2go2z&w%7y%j; zxJE#%0A|ikTS{X77_^FN`k=hCdn@tiBo+~INpan~z=xW*x+Q!t z_W# z<7p?Hv~p?AO&%w1&*m}l_#D%Y-UF5^Nzpa1WqQz7-mz`WTM7!J0kyq{4zb_MGEEy_UEQWSD*v3pDwHTBRVr!mUFr2E>;Zs z8O$eaxEXs(J10eroM4#|pB3g92 zC$cIwMTk59DFWz2FB3~^7sUq5g-4aF12(s65Cu}~^K@0dRVL)rpnX!Y+()4zkr`3W z5HphP$$D0O7L35*W5Coz+{v4dK9tt{>U=z|XqNu3FDFv7UTyR;;C1m-tfwYGvr(d^ zF^`B;0QTIHhgvsKzwwl%N!*zBApa1(+!HWObTL(#k~W%3CcRC;Cm5W`vv}4 zCF$SP((BBQH?bPgOjEt{!@3!r>Xdtg8Fu7Ntu2>mhw>_0_NL0{?MC}ARP|A=chf;C zPy$qef^u(|yWR%u7^;zDH#oYvPHzCd{rjkoaRHq>uhBk{PI1V7)@yNZt<)b|M#2FZ z$!S2!VRbMY+D@rT8Mir>V$bY61UY^xq;v6%aOKS4$w}au{TIfuv)|Y1be5 zsm}!mCNIa*URxm$Ui+hC5D#WiT791v-(uzdp*Ei`SB)_vrLVt|M3=6>DK%Lm7CTD1 zhyM|>Kg=4}X7U<>bNzZ3j$`p9@&nqVPp>8zehMHIn~^MMLhXOf*nrR}W%#Fl*~8jx z>|}+E<%GbpMwsigRu0i@LTAL=m9d&^E{mj3sTXc})vK}g7NfvIJ9bSpItt*3QR?rS zK|MZj9A$p@ftLtN=y*zSrH>h87X##Ppt%g@4coX6>ABaz3BJ6J!g6n3LIQf8I+v7G zv)n`;`otcA7pGHG74?TtNxBQ2he=O1|=;swf@ot-H z{EJE6sAb()ZVmm-ElkPnFk&}uCJqnobwa*mpcz#V5MzSIktmDf26q0?<|`J_DpSPp z<%z_8^y9vpH=bobiB3CIelJzzRcnW0QpH)qraf-e#*O0(R7_h@3B@QG`aA@c&FhcQ zljLsvwL5?8S-`up*4Ucl?2F8p;&vpDT=>@_p?+;f@-Bc`xY5odKgQvq@dRwE;glL3 zku_S0Nnjsd&|ZZe46Q)mSBFDPAa@A9mm{o|(Jng&U(3u=G4^?G_j9$eMtx|Kfzz$B5dC2Wf?hg!T&cmZ zB7R@8N7!o!f7a)-njvz0@s!=5R7$&BlFCbV^ zpu_O?fR)b!w#}FzA?_;V-A63R;g`g?I9m9Rw>ttoWs;?Fo!qjko_5K+@U6M}(T-$6 zHuZ9#*xoNHRB9;R?zcSidf0XfzKN@;pwQJBdjWy4fJ>MC^7tibwn7UsS(kN9*Bv4P zCco;eK+7L64$Z=Jk04K5tJ8$s93XS!`1vH`oE0pfI6z~7XzgDxy;o`2kuZM?@3GHE zgq40_dV9^BSFbc%O8A_zI4T%wPf?xDlD3Poj@mUCK4rXy$s|qZBH~$9_$0MQQfcU? zlP^C576oCXzX41z+Ce*&`UUr&k%oOiK#fSqz^^A}yMbK6fX9`Khpql3ntq>0*r#C^#R* zqMGttn~T$b0fur)K=dj}T0K30ks#=U2iG%Q4_Kux=lbv99dVw)5G5XV#tv+u!hySXj^7NiJ>Nc;lY+=w-Y4W2hD+(h= zPYX~Pj&t!t|J`%14KJNzguO|&+wR~TE(-*tcXjLj!?P1N+g zD^o3hrr>KQ<4sb*msGlTqaW5HMtP0AUKgj0z}}gm?9gA{Ai7{NlNyTWFH@6_iE|?A z7QiYS42I_*C*Y8>(qzqy;zG9dd!rFnjLQFB_7L%D6#2R>O48WL$h@^H>>u?|PhurZ zW4+R|UaFqkeL7W{*iC8n=AApkbT2IJTFi75g2N zk{#C#@vWO7?_@lrJ-bkRBJS+^Gdt^yXn^eR#fzz>m`_DNeC2T6gGMOzSjRufC{au! zR~_T6L%tpv0I9EG^6DD(8pjlgcQI;)Anz*c3p(oP>&MAKfMZLnGvD>W730V}x%`5+ zB$j+2+_MaB|ETgqVs&m;QUMA4Z>MKn5!X(cYDKpe-6I2uh8bo)@u`!iA#sAYcjgG8 zUcc;(5I$g5IT8b1AZoUIN5l?@YdM&E^*U6HyH5X#OqUoX9C>u;wQ5)GiEG9pJ{}$Y z*s9?V(Xl$wNiFH-w>qXJ_lFz_*aGW^Y2uBlZxgipejk0fHYAE0BRJa$LYy(T3Ug-3 zIW2GC+C#^?`5?s1$LJ>IfLaM}3obqLfN|?W>=C@vO{b#+bF9v1LtV9=l#39d^4=M( zop$dOWccbR>@%P%Uir}_Hwq_aHalgi^MzAIEQ6~R*R~x_Iq}h(4Njt8QTSO{c-(iABkOf}~kP_Hq6o==!rO3%$0ReRb=qcn< z#?Jqu@6lI>+x@<`OS@V9SY6Y&$0RmV7n2>s8rJQ-Hh`k_rhB^F@^gY6eyC2^}ocf^$Etygq2v^#En7FY8jrp!UL49hs=ltKs;GVU#sDW_t8 zaf;vfgqWyzTa~z8p^Y|uD-J29!M9VPNpfGCEb9SHw<+?iV4i2i7zaN=0z)C!2&C}9 zA{vZW7a(u;0S|WS7WKuXC|3jVBe2_?xFuj$Taq1>SA5JJ?W>;Vm<}sbR?Z)LGB0b! zD}VjzS1li#W{^{N!Z3OfX+tl2&313Zk+A{Q>PWc6(=nA4)j!oyO*E=iNgHtl<0%+p0`_DNOig{Dbp0ZRNSwYt0<&KQ4=8q@%|3ZuRI77`KJxX-J3WcNOrFv-%=Av}_CPH3!qyjMcuLj&&}GA3cg24fvdCU$j_zOxWL zwYhyvIRWO7FW!4W`i>Syw^;Y;0AWliEsA6NNddUe?|@Vyn8uO*9a5W5A&+}xn}JEM zfORj&WX*rH-S4-!DF>&T|T0#4cGF3*OAI|)v{e~!aUDZ(LRg@g% z3adZ;z@>dR(x)`^LvqZN%V?!l=5ir?*%0e8o8}tzLIe*PNslcR(N7Y^n+Rs9?MrYB zzI1jyMKtVDj&s%vqX>^W`n9d7Vv!W{*<8Oy>Ye*c@3LKk> zMB0ps)WV2WG5WqHqumi01Ww$NY3?$$nz7+A@Y+W!-UPv^9YnhUbS!#cR3(DhG9c?B z-1&LnT`A6FU65M0_YTkCKWX*$AFopQ!?n0G?aBz1b+Ih+W{deGZY#PC=4Rw-Zf2<< z)1(3)Z5biNLNRHp~Js-kJP{b3;C) zlH;fGK(RjhKB<0(YE{2mk>gglr&R3P`q4z6x&9E5^qP-ACoWly*v5Ju0o)P4bH^l{ zE{^-P0as6YGcqEn)P;z7_nUvGzdUFlfUoFmZ6?|UM!A`lR6|~2(U#$=;NO&z^u651 za?~ykhfcah-;iz3COkY|x8aGi;8uNFHgYS*cQvxhAmPirwlmJbTwW{#o^T279u3wo z4+lmx^ZCG#ET@i=#hTozSC2xv<2D@GY{yH5`&jQd6TQ z%odZ+CRmz^qbrIT>vk z6-d3gi*QSCNWVe3P@Si7yy{*Pzyg`kPs4e>V}S#G)huh$r)EBa4w<^7h4ge%r$T;? zda;>vX;o8|s|WH5>P4FMa4BQEbw>Vzp z!XHc2&b<+e>KU*O znKdq2Ele^PpW2NTh9Y|k5xnUcqPOBoOZ)dZyqGXbinidLjG>cbOjXB)SanuXGAmMy zSaZR8EU-ujO<-Ndl)ooZPBTyD4Hh`98p(vNy5tq zvH~KkTAz`C`)RLAR%P)g>`1B1^IUe&RoxgK!e3?bm}L3hKxHv`U+-@X6a?D02C-== z`AMozYKk^P&hz8(YJa~`@Wx>tj+JfC6#mruhW%6jV8ev5&Q{ytR34;*q~v*#OMn*M z7l8I&=nFW;A_%hp9TeI_PVPyJVa{RgpvZf-c6dsmxw6LsQeV(bgQrP-t9$I6uS!NK zQmvE41gBwJ>LC4m^|!1v^G8YeKKC+Q{2DV<>C~8qq|d1STUy7KLeTNwtNmOBLk5n z$#i11cdAFjcL+Im+^T7-oNlQRg=0}4f$k4a-U2{1Z9vid5E~zM4ej(*?8#T})=~M( zL{SPL%o`alZ~cy{qf8fnIbmPcFeV96*?Jh@%)Ho)|C!?R_A)#iLWzj?8Q!@II84VE zySaO%G(1fda*e>d_WZ1TB$Cen11OWC(|ixpSwOz{q36B=+uWv5$bW3)<_CVs(3JWei778PbC2!51gIFg0gdrPJ4zvc z`c}WE#(ujXwzoj+b%cund|Hot%L^ADW%3M5i3I1Xrsk}DzU6QYUFNzjN#XFIxyXZoA6io^R zjM`pW3cqM)@W*o6+)=4l_fjH(%=6DGPI}S;gYkEn|6H$$mIv?F*_*AKX~Cp==WfBy zcpGD!qLa77jQC<*q=G}b00-C&;bVNfPrkI{il>yJeD!B~-M848^UrqWg!A5>|si1hm zP&<&&HNvZP6bZb_2-1Jl21`mjZpT!!=}+W1V^VPn z2$=%aCi2MYfFT*`zUi6}ACU#`!PNkSiR20y+%AN2FxIe`nTJz&VS5pGji|LIaj z=J1Iht)Q)4r_{t{ne%+hN`SIHSkyE`hB8Kd0}6=E+~rfqPvceGr*xMv9;yz_V;H{g zLx0@o15TQ-ulP*7=Uid+xU>sIF<`z9+{3k`w*y80b`>Lw$KGRWf>=8;_&rT zGYUXetgGCiHX4-L%+t8pkKIyJ0i&g_%^<@T%dmhhv;(l2jzMiRm+q zQf_iQ3Ndgw&Ys?G{4Y|H|CIn3Ma6dRPW5~R(l_|K5?6n8vrNcfu%y8I@>D%>G=Sk( zYs8mLa>FUNamnb~Er}IZ3G1bbbl)bqxf#Cg&?u3QYHSQOdb_nWR!XfE8Gy?%(U(@< z8RQ4{jZo9Ub2h=FKX#PCPs5cq3`H?<2M1GBxZm$4k^Y%M^F5b@f6Tgo^aZ8Z%IDy_ zjoUCAPmC-d$gl3mn{J_e&!57_EyGrI?-@JBlbjDXQMvbW(Xm@R(npg>^0*KVx}v+B zsnN;j6tspzK_NAFOya&2>7M1_bc%jBT5+4fMe|p5>9i-17N8Yn*z{K4SSk!uZA^r+ zzx04kveBuAS6kclGREF{xt+PsWxI+{P)AUU46n?jJFgR!ULNhLZhtSW$`$}u@JWOJ z=;HNVm=fgB7aZSr+o0NP?&j=Pn0rK<0Lpy}o2p`u>5D~HA6skb&0>k^_px>9NR<-^ zDM~PjUs%x+zdb6Y1!j|!^~-}GG-dwGtEg|K6KZrs|1GYbv5xQ}Om$5Y1KxkV>M)gE ziHjdbCvlfj7ItUJ{|G0+!6%eFdlb`bvsE3pMmn+RMMEE$@)q5!BNXHN#C!XH9FtYX zAu4pq-TkW79|LQQJR|LsTg2@>J`umwra_|coV%PxMhD8<$}y5b!@4`B@SXnh4{RvC zs5D#`nM&y~{cmq4aN_D|4IL$J$^oCEE?-Xn)A=9cwcRR}a&rmE%f8h5E z&dtx3gGJv;x>K+}!jCu4Sa@nmUrBwb;DEoQ0Cl)4pomz{$niXZQylS_w6#X+>J?uS{ay>mE*WKMZD|Rg+|* zYkCR%l2u01b3gqB$|L3Z(cWk4bIIdh=MzAaQ-Pb+JDr@9lX zu;eo!q2?hC_12#L5I0X128jWR-Mm!qePi)^YU|p{UV+Z@uEs?===c$7E2E_z^~%1Y zD<+i8^ICqnx2+M{)*P&bh*qWH6+6G;RG7&zMI6EK+ldr`H&GXt)gV+2?M-O7kVarZ z7+8iYq#s3luV{XN!4pJR>39ihyW$at+i9D;ttt75i4LsU9l@F60CX~e0f?!yhHrObCF?tBO}zu zqgIAF0x_{SzM;h3wuR?6{ny>qF8IAyV@1jb?FW5DRR_18`K&?b>jW!2igrH}$cJP# z&11fk66NiWM8!oDTM_l3mao5VIRx}-Z3}@k%_mJ>RM|`aDV9r^CC$6d`%Bv2@4@q< z)Rrwd^V7lxdKE(VMs*gaz55E)`g{PJeKl=#A@z@i!|Tqqz~vyf%lBwW-YF4P{$Yj< z3{u^0Yn-X_V{Px{72MZ%PBqxo{qyNVY~A^yY2s^toWNZVy=Ys!qmM8cJ!hr3>-0;X zCo{&b+vYWhON^?f8JQ!oIor#g4?U9o?_a=~9H}UOG0mh|hij^J@?s7RU+oQD(N)7B z9_$@J^@vVd-?4d0-7RkIPU}ZM`H<*1;ab;xtJ26@>bg}0DPwEDpjGlEG%Sg@=O4dl z83r?!aS8_qW5zPLV69~D;_B?+?0n^ly^}4<+Q!z#!raWlR3CX(UFDRbw3LK6>^}lj zbM9IAqDz1SfN-dVinBbTAq)x@VjePDtAnrd>@#^My<72ejpd0*sT*sSFS0 z7{>KE)Id5WfoPi-^XpzcOZsuUyzMh4FrT>2e(<83T2rize52l*jQXSkcuT zI=PYZ>{s^{Dt0T*{ZWQOvO3QnAAj%&cTO0}AM2i-XP*y$IS4yrfXKvZJ6skY~USKClL6L<{d6GP7ISNSv@-2<#_Jx*4M^Ho(Prj!Qs^dwFA+E zlRHyr&BlqvBwC(Y(n(wH+`X)$J%vXj50+Xsaywy+ z{ycij7khGYRY&>96E}r@-D{<}yX8cJhw#y)$at+6<5CF^hMs1tl}S=a6YVSyz2(MN zE8=zZO~lKw96r!up^O&#QY^pFE`fF*AQuKFW1rjr`MJN_;1I?I(RYNYkmG98t1lmI zYzRzJ>SC|Eo0e164CcSlBsYRZSKWM9Tzb17JPhj3no&SZ9vAytZu#0zg{h~?8Gk|h zI3W}(L?qA*`EUHWT=4b|%Fj@`Bk@hVAURRbKnb$z36 zlt1&*D;H8SEUMev3G`;up~SuY$yHWqrY-rZ|M8(}xJ;D8Jq^a+CI7Sln z*YWib*H`5c5AWuSJ<7rl9jc}sS`1&z!6|tGUrY3~d=yzkcba|}0kU#Y^x;Jlf2W`;aV&+ED|wxd@v7^f~VnJ~TerAAd`Lw(9a)Vll3aWBCI4C z{cS*>>OMLW7B{;S$`iF7CLCna4g2&(fWVgv5(f`HztkmsBH(sP+P!zZVGV4+Ssn_1 z2K@a)2{bd29E?SiND8o!=ib^F1{HspVfL0yeeBN6g7>3}R!c*NtVkUe!=mffi) zUg_4x@s-x!FMif{;p*W<3z+YP2TVNVhO`N^M2wp&ft*#gQx3Kmj8$a&LEQV5Yz*&maQs!ln)XfD>y_&Wwe|@H8jk zhJ~E$vS}Xu(=Dwtv8oQTk0}CFC<@7}5Hhd)gp|*;G6%1;nRK%>RoNaEWE6w52@Vpb=Bm{A zCKjT+^u$I&SASD1#pt-_=2WpWQs_0TffL;e&(eqZMiKPR=@jUyXvArUaQOlqKg$(4 zHkoRt&2Z`i(NVR~foyez-|fH0CwF~Ocb*ddT44$JNbeL<6&PUEW>A9+K)QHZy>TRY z?)}Vi794ol%(A$}tAA(bf|#+%AZWd7ymxqLC50-O7?wJTk6V}U; zji-(0MGm6R)zUsaIS--;>+379@WB!|=ob`pX|V21UC)Xked&eegWwST9?22TU?T?Y zN;+G5VuQXf+iD1c*`(}q7}3Xqi(r<5pv=xE>jHHVS7qwia}*(HicjZQ^cE6qV&HF= zgqKL1S(Cd3ybH>m$|hahfkn#{;}xtTR@&o^31-J96fF+p6J?YLBfvL#`$1ego#`HX zA1&A9K>_*&5mSn#GiQA!Yk~wPUuTl>LNp72GplG*dp-;^Y^8UEs&w8E=2FTikZ;@W z>lE6#GwEbCbQy61G*CsOa`S6g02R(0D)t}lVS--paJWvchSUATQx~oHps^|%RzcpC z^E+UI;BE;Hi87Btz*Fyu!y2Ai(IgaXtZF1!N#2wB429V}`X>??x}XB^<6J-Ef6&vd jG3Bif{hRkc!T^G7F6RFSf^?%IU6p-=`(H5cUq${0n)wS^ literal 0 HcmV?d00001 diff --git a/client/data/sounds/thunder3.ogg b/client/data/sounds/thunder3.ogg new file mode 100644 index 0000000000000000000000000000000000000000..af4739362e16acec7e4af1bbacab48fb6e3e2359 GIT binary patch literal 41389 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 literal 0 HcmV?d00001 diff --git a/client/data/sounds/twinkle.ogg b/client/data/sounds/twinkle.ogg new file mode 100644 index 0000000000000000000000000000000000000000..41a8d4d2cf59ac92925e65a9273c1d802d97c357 GIT binary patch literal 15098 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

#!mRIfmM?Ep<4X2=_=c4=hkc-pQ+a

gSR($*^W}=Zvns!>k3N{TtNr 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

B_=wgps^ZUcKU)ul&!n%W|v~ZP-yB= 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 aK4{94x>Gn#XSoir1e-M>2m6rt000iy$xh(_ literal 0 HcmV?d00001 diff --git a/client/data/sounds/wolf_bark1.ogg b/client/data/sounds/wolf_bark1.ogg new file mode 100644 index 0000000000000000000000000000000000000000..a48f4261b4b2f1d17d7a0cdc57857228decf2f38 GIT binary patch literal 5919 zcmahNc|4R``;2u+(^x}8)J$finvrcvHDf6TVVG=9*_T8Z)2?f$30Ja2LsJ<$r81~5 zX|aT)>=&0Vp`s_*;$`p)mX=Y7tzopYY^Jm);`YabBc1jN9P(w8#QD+K>= z3B8EWL>xX8;T^;hA`sEHg)ac2O%S4Y9l~BH`Kt&eg%p#0owrbw@BdX|#Fx}8hg4gy z!~TZkjrztLNkpQMeKmaiLVXVT`bBJmL?1}pEFx+h4Dw!*Lr5;Y*O-~_K>!K>SeB~p zPCiQ|9<6TXpf-*%>kNLQW@alNi_y3BXveYAwF`M>$sYKau5<%Ks~CmGzOMxl^!QW zZB>omNrf|zBG)O!w^K{h<8{f%)$v*ezRDmS0N!Oh=Q3Uvt$tk=v;u&pI4ZS-V;-Hw zJgUYlLoRodg!=%Hkk5)!Xq7f$m4S83z=`VQ=`y|c>!PYJ61M`t!BNgKTuE9a=L-Om zXTssTa`=IqspK?dd}4(dhz39c4r5^MWV$QU;)ye(Ul20%U)3YqPfa8aZHRsr672(=MzlPK_%QmXk)u^CT;SA`r?{-nN0VGq zCxk9@-Q@Bh-xT*D&rNm-(y2bym8UDjg?GO62uW53rRCXFL&&QB z82y5c5XTa#5;d=yUShb4!fwf(`s@o`O%Sqge)%UC{fkA!Co(czF9n^L>NQM2KAQ^E z+9~g?uK$ucKTVWTkK>xXdO96gn7IXs%L=E{be0S*1}I4F1SPuF&&E4hJ5e>FjZn;s zrRkQITu#w%*SpanYPP(oxPjU#M|y}hUtjr@GUik`4ipb))5k*2O#^VJ#!{+MgLLt?{YiHfT_n$fZN$#|8i(_vo5Z`%{da0vd+hsn{{Hadw;S?35Tzik1vzhEuj3qsH%vLCBypV?>3~EAaD} zi*m_kk8HLZ6m}t%4ZBQ1$VkpFRg8XT#*h)D8ahTY9T|RZQ1fA?TR+34FA8ezb+Q{& zW-ziDgS~!?Z1(<0#>gJ#U_ZmHFKVbSVSiuL{gSd

0)F<<~0~uWwwu_4ak9b+@f> zLcJD_3_F*a5GQtshoWV_GNU)!(uobVMD1t$4fb0+Wm__`{Debh`7w|9xzs|D5XRxC z(MTpUhs|{L_n1%UX0w@DexojaZu5T3mOl3AyluC@uD_Sv&0vrAv0vnd3@t!0HX}P> zKjiCAcz!H&WMzRPgFTYT+z-W8hVD21qaoDvYKYI!_Ul*I%I#{nrpFvIy47HJo;@Ebsy&v2QGf|GbY7d5KN=%0rsPwdUk_nMF5 zzgw2Y5G24EOq~y5x}F-J{?ecy$@YM<)g290rnkc*6Su>dm%;!bW{Ve3NUT7Dza)Ta zJlEWonyeHDj{-t`I{l$)dCmQq>c?vX-H`Y|}C2C53Ko`VFa%7$hrPz_EqoXc}B zhlJn*)suOw_oT@Ir(nZc)nGV=J5)8<=L3@;aTGir)@8=PxEB+~y@WQ6Bz1|JOqwb* zK$0f8nHUf15fQFa{6nJ^E6hiz=gL*xkOwfdpbgEg ztj;_0>GWVypF8XQot!@J3d5=4IQ0FSNbT* z{BYb1OfdJRkf$``XYNUR0dOQv99YDrZmz)QE2l}V6s{I21GLcIaD%xp4&kyPHwIqL zcpP1XLzy9QzCUsN%#V+D zcp)FOE!qq=Kdk%{m+=cnr~kykt@^>2NwZ3sw!1SjiKUoMP{XDw8(!c04P1& z<8(To+Cd5^)kcy^O3i45M3Q-%RuRETRy#qP#nBeK)U?N@30~}I34nwqAW|HN;y@0C z-Y!kmp@iLp*{zvxqLqQ3M3QtCkS8ev>^l5}7$u>}@{cCTNVT!pjqkRg&Cs#vhkpTC ztHygW#-<+KzAkPv;{NX%_tA_~85g!n&C?R8hsDB%?sl$GRO zC^&zao00Q-6r#hy{=$xiVs(T>p>GFzhN!eTyJfvfb5dKa4Nh4-S=s#e(FJphO>29c zE{28Fi2>egp!GoStdl6F zVOat^M*m_KpiEK&111!Ht25|W+f?{CL8hfEb=Oc5$X&zP_~HDc6KW1tyvD$PEHGMX zPySGrl^g$kRP(XLyUk*Vjc*$t4D2m++`8_-KGU5c?Q2|&LN0TP^tv;izrPF?Sj(KG zz;<%;KZm|O|JU)sjNK*5-`&F{L7;{kh;{rT4uY>P2PGNz1t;ODRZA)BubQ*v4UnIj zH^PsR1gsl^A|Hc(TIfIvtsCmywfhfJ>?W4P1gMouY~Q~p7kjfCGd}h8jJKBj!QveU z`47OR`!6pn16n?eXt&G@^98!I9C4g> z2GL*N3vLEfQ>5BzM~h>cj#jL)m3A$D-SsZ$uVBPCWkg_>z>}wO!QW18kF2AcUK z7YS*r{YcOJizXVmH&gb)8{%vIKR)YH+!8fQwLO~UJv_hEDTB#bKZ)ds8tt#28cD#^ zwW1vf)KxL}SC71qMvW<)3YwH^;J?@!nS07Wr=#_DHR?R3n*Xi*gyu|fYi3>ab*~cR zelrj)=^yQDF1uO|eB+%gy}4F%Fpv14e&5^Eu?)~q7H02u1ReymkWFv*Qpyr2&wUy{ zmVMgOP9(~g*h-_HTbFL}nzN_el*lUqQsoVn%+^ApOUK2BM~E=;WwfJ`%qRl68THR6 zFuWA8FSw6o^)PfPE5XSv#jPRb%_kD{q7^`aYUiOh9=DFRCJlKQd1SoCwuT?9EdCO< zBDwP*Qp;E(zEcZ$hN}NXp~;33!GX^=YN}oaeO|bTEdEltlVt>6j=sG*ntSpR)a)@a z{KfuFTARkKZl24NI4(sqk7O(xj`ak^bGZdmwN(O(?qL?^cz%5w(N7Wlnetv5RrKa_ zhnJOXW6y(p`0}=k)mVp_@>hMS0!| z3j;RB0FR8O?@ry<)OkSgbiAgxQ4*Lt2-!U zQ-p(6-?3BMaj26WbP#d*^HGFoh=<}1sM`ugds{99)l`B-G}vdXp?b3F3p?lP#k~(UX5Z|z zMH#(*GPT*2u#$cyC}oGac;lLDjnSLEnw}j0{$cs!@Wj59o6X*xqo|9{KEZ0!e?Gf* z%hR8~_5|t^HlT(4E?2+(81lq5GQxcpf5h&aRkq&ACY5yUb+1ngx~XV+lLilGi}Lpx z&8XEe(ZCR3C03*~6O)&R#a#SzuOcAc+a5stZY8_8kB)s=-;CI&QOa2LewT8`)Jli088BWrN?? zF1rtZiGkY#DaMU9(Ju;QIu&fn1&;q(WA0DSMI8C9A?RQJlNL7>RFL7vt^AIDnw4BT zy(_BemhsNzZCyR+$J!ybBcY9~!?Iy?afS0Hs=)Y)xu@Kbd-5=w@!YPleacx{@EnVZ z3V7}EAhNso&B;%hO63!BJjC5TTrfl^{%6((};4(B`XF0{c3%+sr#U z=dJ{c<+_}?)7*zJby~~b&l;yb+4>3DVY8rhd{}J4et!Ai)wiQ}+-)REmR)~a;5eBq z_xmw_tI$>OPghnkd#y(u=mev~!K)4quj@oo{322Q(Wrc__oL#5dCQ0;Vw$zsk2zi9 zC1-joN>yH_5oJ~v&uV8In?4cv4thpU<`#x>XqFY(uddG9)!r$!eQ(w=9lu|59v* z3Tmsj*KtdvzkPA&e;}*A=}?i@b_@aFDJq~-7sv8dK8^#L0*eQ8O$O*l|5vgTk(}L4 zcIyN;j!0>pbBINr1-d-Rt%dE~H=lg^B)A)v*zl#&Yjba6T zJN;ix-{9sxRxL=Jy^%4TzsM=TH`uWwF-<$fj?_f{@MVzPki#JO17tcm|~iq!j`z^_>0<2lG=_A6|Xps;ud5siO(Sa!B@R&k28ad78UO$Q literal 0 HcmV?d00001 diff --git a/client/data/sounds/wolf_bark2.ogg b/client/data/sounds/wolf_bark2.ogg new file mode 100644 index 0000000000000000000000000000000000000000..5eea29b0ce48c7a2ef46e698d16a083ca7f83d7e GIT binary patch literal 5918 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 E2LYwS!~g&Q literal 0 HcmV?d00001 diff --git a/client/data/sounds/wolf_bark3.ogg b/client/data/sounds/wolf_bark3.ogg new file mode 100644 index 0000000000000000000000000000000000000000..c97bea4668cdb61db6abe87d4170f0135e937d3f GIT binary patch literal 6216 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 literal 0 HcmV?d00001 diff --git a/client/data/sounds/wolf_growl1.ogg b/client/data/sounds/wolf_growl1.ogg new file mode 100644 index 0000000000000000000000000000000000000000..6af013e0d3ebc1765832fd49a432685a2eb21597 GIT binary patch literal 15490 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 bvu|hdKv;SJ^rZl_w4ftwkU-fn{;%?17sN-7 literal 0 HcmV?d00001 diff --git a/client/data/sounds/wolf_growl2.ogg b/client/data/sounds/wolf_growl2.ogg new file mode 100644 index 0000000000000000000000000000000000000000..f47dbbcb5d5bea835870a96d234c60222ce979ce GIT binary patch literal 12094 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 L>x&GB0?_^+2=QzC literal 0 HcmV?d00001 diff --git a/client/data/sounds/wolf_hurt1.ogg b/client/data/sounds/wolf_hurt1.ogg new file mode 100644 index 0000000000000000000000000000000000000000..5c16ef7897954ab113638c3f9c508069b3c177ea GIT binary patch literal 6748 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ΠePb7^4)umj>+0E*FynEKvApFBKRXXI{`L3wY&>Q=!^$yvhV}* zuB&r1vU~xhU;Pp92^u*7;j!5DZ)Qy84{kw6+N)*r&bG2CT0PKT-IFu!dkFL(R$Q-6 z>vuCkMt;Fe7HZ)309ALRqM^xTivwP1@a*jmIm&mU0s4EH2zF%>+50sUI-R&QkVheD zZjHhqd#B04s2Ure%Wl%}BMQ91D`sR+k?U6t0n`8joar$Ody6-FQ9h)^30MB{$IAYjIp0(_ z8OMFTcHee01Mgs$1;Fbq4hUr9B0V+N;0H(GE!4J!O!+gCEyAg@?Ng#&TtdOVTnONs z7A@kj??cII&`UvtcT;&lDd?M4@c~^RIL^d3>ulu!kD3c7n0t1S@8&^*zTkNr>QGRU z#w(QE;jOZYmBG2O+6V_5%V;}5%iwyw_C6|oVHfw)?#D;e7M`hUX%rZ$OY=XA&YJcD zyETtKyEVTvbbj4LmKv>yc(i0VB#;CD#sB8qW|jDJU~h$P zO(9=Cu??KO-Bhv9;x|76Cv9Z>|W;4Np#5evZ4utY&CpxAWv418lG&Pgm!m*=O- z2(a19q=MG_QElvIQ>mty@4-GhAMfP-ns9G(_Ir}tzFV6gO(6kYnqS;r^@Rw?<{_GH zVe=pAlsH;FYH%yIf4j&bi(g9}89ze=x=$Q65L3f>0$t!=YPesbGrnLx8|nAsV6M;L zqQ8*+c?Xf%rn%C}dd=OpcK0&5-bnW&ew~{L8oGmsia9B_PS8=dnG+VGO{NyQKUYR_ z65bBwtq114j=F#HW<~Qh1Ky{579(AbET5hw>@tvU))4}>$}>Rbs=dJ zS66E8yhD#i#<99dEy|;-#hZ-54`O@OebMh{brQ=fHghbysS4yO5!BxmVP-2ThkH-s yj&5gifrTE&Cw5=Y>Iz)*irqnLy!QI9??n#n@7mfv62oqH)kmIeDS4W~hxk8)0&1WD literal 0 HcmV?d00001 diff --git a/client/data/sounds/wolf_hurt2.ogg b/client/data/sounds/wolf_hurt2.ogg new file mode 100644 index 0000000000000000000000000000000000000000..12ffc4f946a3d4f94970e0f1219bf44c342aaf63 GIT binary patch literal 6549 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 literal 0 HcmV?d00001 diff --git a/client/data/sounds/wolf_hurt3.ogg b/client/data/sounds/wolf_hurt3.ogg new file mode 100644 index 0000000000000000000000000000000000000000..41057099ef069a9c9c705d55bd314dac09adfc20 GIT binary patch literal 7334 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� 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 literal 0 HcmV?d00001 diff --git a/client/data/sounds/wolf_shake.ogg b/client/data/sounds/wolf_shake.ogg new file mode 100644 index 0000000000000000000000000000000000000000..bf01cc3e66ec05811f0acbda85709891d1ca8bec GIT binary patch literal 16145 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